From 758b0f708224053359cd190d60d3fa50f4401e89 Mon Sep 17 00:00:00 2001 From: Shubham Jain Date: Sat, 8 Apr 2023 21:37:57 +0530 Subject: [PATCH] chore: vendor dependencies to improve compatibility (#186) Signed-off-by: Shubham Jain --- .gitignore | 1 - .../github.com/99designs/gqlgen/.dockerignore | 3 + .../github.com/99designs/gqlgen/.editorconfig | 20 + .../99designs/gqlgen/.gitattributes | 3 + vendor/github.com/99designs/gqlgen/.gitignore | 15 + .../github.com/99designs/gqlgen/.golangci.yml | 39 + .../github.com/99designs/gqlgen/CHANGELOG.md | 8294 + .../99designs/gqlgen/CONTRIBUTING.md | 27 + vendor/github.com/99designs/gqlgen/LICENSE | 19 + vendor/github.com/99designs/gqlgen/README.md | 150 + vendor/github.com/99designs/gqlgen/TESTING.md | 40 + .../99designs/gqlgen/api/generate.go | 125 + .../github.com/99designs/gqlgen/api/option.go | 40 + .../99designs/gqlgen/cmd/ambient.go | 10 + vendor/github.com/99designs/gqlgen/cmd/gen.go | 43 + .../github.com/99designs/gqlgen/cmd/init.go | 198 + .../github.com/99designs/gqlgen/cmd/root.go | 45 + .../99designs/gqlgen/cmd/version.go | 17 + .../99designs/gqlgen/codegen/args.go | 118 + .../99designs/gqlgen/codegen/args.gotpl | 36 + .../99designs/gqlgen/codegen/complexity.go | 11 + .../99designs/gqlgen/codegen/config/binder.go | 494 + .../99designs/gqlgen/codegen/config/config.go | 647 + .../99designs/gqlgen/codegen/config/exec.go | 97 + .../gqlgen/codegen/config/package.go | 62 + .../gqlgen/codegen/config/resolver.go | 100 + .../99designs/gqlgen/codegen/data.go | 185 + .../99designs/gqlgen/codegen/directive.go | 174 + .../99designs/gqlgen/codegen/directives.gotpl | 149 + .../99designs/gqlgen/codegen/field.go | 556 + .../99designs/gqlgen/codegen/field.gotpl | 129 + .../99designs/gqlgen/codegen/generate.go | 214 + .../99designs/gqlgen/codegen/generated!.gotpl | 235 + .../99designs/gqlgen/codegen/input.gotpl | 72 + .../99designs/gqlgen/codegen/interface.go | 87 + .../99designs/gqlgen/codegen/interface.gotpl | 21 + .../99designs/gqlgen/codegen/object.go | 169 + .../99designs/gqlgen/codegen/object.gotpl | 113 + .../99designs/gqlgen/codegen/root_.gotpl | 201 + .../gqlgen/codegen/templates/import.go | 139 + .../gqlgen/codegen/templates/templates.go | 611 + .../99designs/gqlgen/codegen/type.go | 32 + .../99designs/gqlgen/codegen/type.gotpl | 192 + .../99designs/gqlgen/codegen/util.go | 46 + .../99designs/gqlgen/complexity/complexity.go | 109 + vendor/github.com/99designs/gqlgen/go.mod | 24 + vendor/github.com/99designs/gqlgen/go.sum | 98 + .../99designs/gqlgen/graphql/any.go | 19 + .../99designs/gqlgen/graphql/bool.go | 27 + .../99designs/gqlgen/graphql/cache.go | 29 + .../99designs/gqlgen/graphql/coercion.go | 56 + .../99designs/gqlgen/graphql/context_field.go | 94 + .../gqlgen/graphql/context_operation.go | 115 + .../99designs/gqlgen/graphql/context_path.go | 77 + .../gqlgen/graphql/context_response.go | 153 + .../gqlgen/graphql/context_root_field.go | 25 + .../99designs/gqlgen/graphql/errcode/codes.go | 51 + .../99designs/gqlgen/graphql/error.go | 32 + .../gqlgen/graphql/executable_schema.go | 162 + .../gqlgen/graphql/executable_schema_mock.go | 172 + .../gqlgen/graphql/executor/executor.go | 192 + .../gqlgen/graphql/executor/extensions.go | 195 + .../99designs/gqlgen/graphql/fieldset.go | 63 + .../99designs/gqlgen/graphql/float.go | 47 + .../99designs/gqlgen/graphql/handler.go | 130 + .../gqlgen/graphql/handler/extension/apq.go | 114 + .../graphql/handler/extension/complexity.go | 88 + .../handler/extension/introspection.go | 29 + .../gqlgen/graphql/handler/lru/lru.go | 32 + .../gqlgen/graphql/handler/server.go | 185 + .../gqlgen/graphql/handler/transport/error.go | 26 + .../graphql/handler/transport/http_form.go | 208 + .../graphql/handler/transport/http_get.go | 87 + .../graphql/handler/transport/http_post.go | 53 + .../graphql/handler/transport/options.go | 26 + .../graphql/handler/transport/reader.go | 25 + .../gqlgen/graphql/handler/transport/util.go | 30 + .../graphql/handler/transport/websocket.go | 365 + .../transport/websocket_close_reason.go | 22 + .../websocket_graphql_transport_ws.go | 149 + .../handler/transport/websocket_graphqlws.go | 169 + .../handler/transport/websocket_init.go | 57 + .../transport/websocket_subprotocol.go | 116 + .../github.com/99designs/gqlgen/graphql/id.go | 58 + .../99designs/gqlgen/graphql/int.go | 79 + .../graphql/introspection/introspection.go | 73 + .../gqlgen/graphql/introspection/query.go | 104 + .../gqlgen/graphql/introspection/schema.go | 86 + .../gqlgen/graphql/introspection/type.go | 180 + .../99designs/gqlgen/graphql/jsonw.go | 93 + .../99designs/gqlgen/graphql/map.go | 24 + .../99designs/gqlgen/graphql/oneshot.go | 16 + .../gqlgen/graphql/playground/playground.go | 70 + .../99designs/gqlgen/graphql/recovery.go | 20 + .../99designs/gqlgen/graphql/response.go | 24 + .../99designs/gqlgen/graphql/root.go | 7 + .../99designs/gqlgen/graphql/stats.go | 60 + .../99designs/gqlgen/graphql/string.go | 70 + .../99designs/gqlgen/graphql/time.go | 25 + .../99designs/gqlgen/graphql/uint.go | 81 + .../99designs/gqlgen/graphql/upload.go | 27 + .../99designs/gqlgen/graphql/version.go | 3 + .../99designs/gqlgen/handler/handler.go | 256 + .../99designs/gqlgen/internal/code/compare.go | 161 + .../99designs/gqlgen/internal/code/imports.go | 151 + .../gqlgen/internal/code/packages.go | 206 + .../99designs/gqlgen/internal/code/util.go | 61 + .../gqlgen/internal/imports/prune.go | 100 + .../gqlgen/internal/rewrite/rewriter.go | 195 + vendor/github.com/99designs/gqlgen/main.go | 9 + .../gqlgen/plugin/federation/federation.go | 361 + .../gqlgen/plugin/federation/federation.gotpl | 261 + .../plugin/federation/fieldset/fieldset.go | 193 + .../gqlgen/plugin/federation/readme.md | 39 + .../gqlgen/plugin/modelgen/models.go | 288 + .../gqlgen/plugin/modelgen/models.gotpl | 85 + .../99designs/gqlgen/plugin/plugin.go | 31 + .../gqlgen/plugin/resolvergen/resolver.go | 208 + .../gqlgen/plugin/resolvergen/resolver.gotpl | 45 + .../gqlgen/plugin/servergen/server.go | 52 + .../gqlgen/plugin/servergen/server.gotpl | 23 + vendor/github.com/99designs/gqlgen/tools.go | 8 + .../agnivade/levenshtein/.gitignore | 5 + .../agnivade/levenshtein/.travis.yml | 23 + .../agnivade/levenshtein/License.txt | 21 + .../github.com/agnivade/levenshtein/Makefile | 15 + .../github.com/agnivade/levenshtein/README.md | 80 + vendor/github.com/agnivade/levenshtein/go.mod | 8 + vendor/github.com/agnivade/levenshtein/go.sum | 4 + .../agnivade/levenshtein/levenshtein.go | 89 + vendor/github.com/andybalholm/brotli/LICENSE | 19 + .../github.com/andybalholm/brotli/README.md | 7 + .../andybalholm/brotli/backward_references.go | 185 + .../brotli/backward_references_hq.go | 796 + .../github.com/andybalholm/brotli/bit_cost.go | 436 + .../andybalholm/brotli/bit_reader.go | 266 + .../andybalholm/brotli/block_splitter.go | 144 + .../brotli/block_splitter_command.go | 434 + .../brotli/block_splitter_distance.go | 433 + .../brotli/block_splitter_literal.go | 433 + .../andybalholm/brotli/brotli_bit_stream.go | 1300 + .../github.com/andybalholm/brotli/cluster.go | 30 + .../andybalholm/brotli/cluster_command.go | 164 + .../andybalholm/brotli/cluster_distance.go | 326 + .../andybalholm/brotli/cluster_literal.go | 326 + .../github.com/andybalholm/brotli/command.go | 254 + .../andybalholm/brotli/compress_fragment.go | 834 + .../brotli/compress_fragment_two_pass.go | 748 + .../andybalholm/brotli/constants.go | 77 + .../github.com/andybalholm/brotli/context.go | 2176 + .../github.com/andybalholm/brotli/decode.go | 2581 + .../andybalholm/brotli/dictionary.go | 122890 +++++++++++++++ .../andybalholm/brotli/dictionary_hash.go | 32779 ++++ .../github.com/andybalholm/brotli/encode.go | 1220 + .../andybalholm/brotli/encoder_dict.go | 22 + .../andybalholm/brotli/entropy_encode.go | 592 + .../brotli/entropy_encode_static.go | 4394 + .../github.com/andybalholm/brotli/fast_log.go | 290 + .../andybalholm/brotli/find_match_length.go | 45 + vendor/github.com/andybalholm/brotli/go.mod | 5 + vendor/github.com/andybalholm/brotli/go.sum | 0 vendor/github.com/andybalholm/brotli/h10.go | 287 + vendor/github.com/andybalholm/brotli/h5.go | 214 + vendor/github.com/andybalholm/brotli/h6.go | 216 + vendor/github.com/andybalholm/brotli/hash.go | 342 + .../andybalholm/brotli/hash_composite.go | 93 + .../brotli/hash_forgetful_chain.go | 252 + .../brotli/hash_longest_match_quickly.go | 214 + .../andybalholm/brotli/hash_rolling.go | 168 + .../andybalholm/brotli/histogram.go | 226 + vendor/github.com/andybalholm/brotli/http.go | 192 + .../github.com/andybalholm/brotli/huffman.go | 653 + .../andybalholm/brotli/literal_cost.go | 182 + .../github.com/andybalholm/brotli/memory.go | 66 + .../andybalholm/brotli/metablock.go | 574 + .../andybalholm/brotli/metablock_command.go | 165 + .../andybalholm/brotli/metablock_distance.go | 165 + .../andybalholm/brotli/metablock_literal.go | 165 + .../github.com/andybalholm/brotli/params.go | 37 + .../github.com/andybalholm/brotli/platform.go | 103 + .../github.com/andybalholm/brotli/prefix.go | 30 + .../andybalholm/brotli/prefix_dec.go | 723 + .../github.com/andybalholm/brotli/quality.go | 196 + .../github.com/andybalholm/brotli/reader.go | 108 + .../andybalholm/brotli/ringbuffer.go | 134 + vendor/github.com/andybalholm/brotli/state.go | 294 + .../andybalholm/brotli/static_dict.go | 662 + .../andybalholm/brotli/static_dict_lut.go | 75094 +++++++++ .../andybalholm/brotli/symbol_list.go | 22 + .../andybalholm/brotli/transform.go | 641 + .../andybalholm/brotli/utf8_util.go | 70 + vendor/github.com/andybalholm/brotli/util.go | 7 + .../andybalholm/brotli/write_bits.go | 52 + .../github.com/andybalholm/brotli/writer.go | 119 + .../github.com/araddon/dateparse/.travis.yml | 13 + vendor/github.com/araddon/dateparse/LICENSE | 21 + vendor/github.com/araddon/dateparse/README.md | 323 + vendor/github.com/araddon/dateparse/go.mod | 9 + vendor/github.com/araddon/dateparse/go.sum | 18 + .../github.com/araddon/dateparse/parseany.go | 2189 + vendor/github.com/aws/aws-sdk-go/LICENSE.txt | 202 + vendor/github.com/aws/aws-sdk-go/NOTICE.txt | 3 + .../aws/aws-sdk-go/aws/awserr/error.go | 164 + .../aws/aws-sdk-go/aws/awserr/types.go | 221 + .../aws/aws-sdk-go/aws/awsutil/copy.go | 108 + .../aws/aws-sdk-go/aws/awsutil/equal.go | 27 + .../aws/aws-sdk-go/aws/awsutil/path_value.go | 221 + .../aws/aws-sdk-go/aws/awsutil/prettify.go | 123 + .../aws-sdk-go/aws/awsutil/string_value.go | 90 + .../aws/aws-sdk-go/aws/client/client.go | 94 + .../aws-sdk-go/aws/client/default_retryer.go | 177 + .../aws/aws-sdk-go/aws/client/logger.go | 206 + .../aws/client/metadata/client_info.go | 15 + .../aws-sdk-go/aws/client/no_op_retryer.go | 28 + .../github.com/aws/aws-sdk-go/aws/config.go | 628 + .../aws/aws-sdk-go/aws/context_1_5.go | 38 + .../aws/aws-sdk-go/aws/context_1_9.go | 12 + .../aws-sdk-go/aws/context_background_1_5.go | 23 + .../aws-sdk-go/aws/context_background_1_7.go | 21 + .../aws/aws-sdk-go/aws/context_sleep.go | 24 + .../aws/aws-sdk-go/aws/convert_types.go | 918 + .../aws/credentials/chain_provider.go | 100 + .../credentials/context_background_go1.5.go | 23 + .../credentials/context_background_go1.7.go | 21 + .../aws/credentials/context_go1.5.go | 40 + .../aws/credentials/context_go1.9.go | 14 + .../aws-sdk-go/aws/credentials/credentials.go | 383 + .../aws/credentials/env_provider.go | 74 + .../aws-sdk-go/aws/credentials/example.ini | 12 + .../shared_credentials_provider.go | 151 + .../aws/credentials/static_provider.go | 57 + .../aws/aws-sdk-go/aws/crr/cache.go | 122 + .../aws/aws-sdk-go/aws/crr/endpoint.go | 132 + .../aws/aws-sdk-go/aws/crr/sync_map.go | 30 + .../aws/aws-sdk-go/aws/crr/sync_map_1_8.go | 49 + vendor/github.com/aws/aws-sdk-go/aws/doc.go | 56 + .../aws/aws-sdk-go/aws/endpoints/decode.go | 193 + .../aws/aws-sdk-go/aws/endpoints/defaults.go | 28572 ++++ .../aws/endpoints/dep_service_ids.go | 141 + .../aws/aws-sdk-go/aws/endpoints/doc.go | 66 + .../aws/aws-sdk-go/aws/endpoints/endpoints.go | 706 + .../aws/endpoints/legacy_regions.go | 24 + .../aws/aws-sdk-go/aws/endpoints/v3model.go | 594 + .../aws/endpoints/v3model_codegen.go | 412 + .../github.com/aws/aws-sdk-go/aws/errors.go | 13 + .../aws/aws-sdk-go/aws/jsonvalue.go | 12 + .../github.com/aws/aws-sdk-go/aws/logger.go | 121 + .../aws/request/connection_reset_error.go | 19 + .../aws/aws-sdk-go/aws/request/handlers.go | 343 + .../aws-sdk-go/aws/request/http_request.go | 24 + .../aws-sdk-go/aws/request/offset_reader.go | 65 + .../aws/aws-sdk-go/aws/request/request.go | 713 + .../aws/aws-sdk-go/aws/request/request_1_7.go | 40 + .../aws/aws-sdk-go/aws/request/request_1_8.go | 37 + .../aws-sdk-go/aws/request/request_context.go | 15 + .../aws/request/request_context_1_6.go | 15 + .../aws/request/request_pagination.go | 266 + .../aws/aws-sdk-go/aws/request/retryer.go | 309 + .../aws/request/timeout_read_closer.go | 94 + .../aws/aws-sdk-go/aws/request/validation.go | 286 + .../aws/aws-sdk-go/aws/request/waiter.go | 295 + .../aws-sdk-go/aws/signer/v4/header_rules.go | 81 + .../aws/aws-sdk-go/aws/signer/v4/options.go | 7 + .../aws/signer/v4/request_context_go1.5.go | 14 + .../aws/signer/v4/request_context_go1.7.go | 14 + .../aws/aws-sdk-go/aws/signer/v4/stream.go | 63 + .../aws/aws-sdk-go/aws/signer/v4/uri_path.go | 25 + .../aws/aws-sdk-go/aws/signer/v4/v4.go | 854 + vendor/github.com/aws/aws-sdk-go/aws/types.go | 264 + vendor/github.com/aws/aws-sdk-go/aws/url.go | 13 + .../github.com/aws/aws-sdk-go/aws/url_1_7.go | 30 + .../github.com/aws/aws-sdk-go/aws/version.go | 8 + .../internal/context/background_go1.5.go | 41 + .../aws/aws-sdk-go/internal/ini/ast.go | 120 + .../aws-sdk-go/internal/ini/comma_token.go | 11 + .../aws-sdk-go/internal/ini/comment_token.go | 35 + .../aws/aws-sdk-go/internal/ini/doc.go | 42 + .../aws-sdk-go/internal/ini/empty_token.go | 4 + .../aws/aws-sdk-go/internal/ini/expression.go | 24 + .../aws/aws-sdk-go/internal/ini/fuzz.go | 18 + .../aws/aws-sdk-go/internal/ini/ini.go | 51 + .../aws/aws-sdk-go/internal/ini/ini_lexer.go | 165 + .../aws/aws-sdk-go/internal/ini/ini_parser.go | 350 + .../aws-sdk-go/internal/ini/literal_tokens.go | 340 + .../aws-sdk-go/internal/ini/newline_token.go | 30 + .../aws-sdk-go/internal/ini/number_helper.go | 152 + .../aws/aws-sdk-go/internal/ini/op_tokens.go | 39 + .../aws-sdk-go/internal/ini/parse_error.go | 43 + .../aws-sdk-go/internal/ini/parse_stack.go | 60 + .../aws/aws-sdk-go/internal/ini/sep_tokens.go | 41 + .../aws/aws-sdk-go/internal/ini/skipper.go | 45 + .../aws/aws-sdk-go/internal/ini/statement.go | 35 + .../aws/aws-sdk-go/internal/ini/value_util.go | 284 + .../aws/aws-sdk-go/internal/ini/visitor.go | 169 + .../aws/aws-sdk-go/internal/ini/walker.go | 25 + .../aws/aws-sdk-go/internal/ini/ws_token.go | 24 + .../aws/aws-sdk-go/internal/sdkio/byte.go | 12 + .../aws/aws-sdk-go/internal/sdkio/io_go1.6.go | 11 + .../aws/aws-sdk-go/internal/sdkio/io_go1.7.go | 13 + .../aws/aws-sdk-go/internal/sdkmath/floor.go | 16 + .../internal/sdkmath/floor_go1.9.go | 57 + .../internal/sdkrand/locked_source.go | 29 + .../aws/aws-sdk-go/internal/sdkrand/read.go | 12 + .../aws-sdk-go/internal/sdkrand/read_1_5.go | 25 + .../internal/shareddefaults/ecs_container.go | 12 + .../internal/shareddefaults/shared_config.go | 40 + .../aws-sdk-go/internal/strings/strings.go | 11 + .../internal/sync/singleflight/LICENSE | 27 + .../sync/singleflight/singleflight.go | 120 + .../aws/aws-sdk-go/private/protocol/host.go | 104 + .../private/protocol/host_prefix.go | 54 + .../private/protocol/idempotency.go | 75 + .../private/protocol/json/jsonutil/build.go | 298 + .../protocol/json/jsonutil/unmarshal.go | 304 + .../private/protocol/jsonrpc/jsonrpc.go | 87 + .../protocol/jsonrpc/unmarshal_error.go | 107 + .../aws-sdk-go/private/protocol/jsonvalue.go | 76 + .../aws-sdk-go/private/protocol/payload.go | 81 + .../aws-sdk-go/private/protocol/protocol.go | 49 + .../aws-sdk-go/private/protocol/rest/build.go | 310 + .../private/protocol/rest/payload.go | 54 + .../private/protocol/rest/unmarshal.go | 257 + .../aws-sdk-go/private/protocol/timestamp.go | 134 + .../aws-sdk-go/private/protocol/unmarshal.go | 27 + .../private/protocol/unmarshal_error.go | 65 + .../aws/aws-sdk-go/service/dynamodb/api.go | 25348 +++ .../service/dynamodb/customizations.go | 98 + .../aws/aws-sdk-go/service/dynamodb/doc.go | 45 + .../aws-sdk-go/service/dynamodb/doc_custom.go | 27 + .../aws/aws-sdk-go/service/dynamodb/errors.go | 327 + .../aws-sdk-go/service/dynamodb/service.go | 107 + .../aws-sdk-go/service/dynamodb/waiters.go | 107 + vendor/github.com/benbjohnson/clock/LICENSE | 21 + vendor/github.com/benbjohnson/clock/README.md | 104 + vendor/github.com/benbjohnson/clock/clock.go | 340 + vendor/github.com/benbjohnson/clock/go.mod | 3 + .../github.com/bnkamalesh/webgo/v4/.gitignore | 87 + .../bnkamalesh/webgo/v4/.travis.yml | 18 + .../bnkamalesh/webgo/v4/CODE_OF_CONDUCT.md | 46 + .../bnkamalesh/webgo/v4/CONTRIBUTING.md | 24 + vendor/github.com/bnkamalesh/webgo/v4/LICENSE | 21 + .../github.com/bnkamalesh/webgo/v4/README.md | 363 + .../bnkamalesh/webgo/v4/_config.yml | 1 + .../github.com/bnkamalesh/webgo/v4/config.go | 66 + .../bnkamalesh/webgo/v4/contributors.txt | 1 + .../github.com/bnkamalesh/webgo/v4/errors.go | 145 + vendor/github.com/bnkamalesh/webgo/v4/go.mod | 3 + .../bnkamalesh/webgo/v4/responses.go | 171 + .../github.com/bnkamalesh/webgo/v4/route.go | 184 + .../github.com/bnkamalesh/webgo/v4/router.go | 389 + .../github.com/bnkamalesh/webgo/v4/webgo.go | 144 + .../github.com/bnkamalesh/webgo/v6/.gitignore | 87 + .../bnkamalesh/webgo/v6/.travis.yml | 18 + .../bnkamalesh/webgo/v6/CODE_OF_CONDUCT.md | 46 + .../bnkamalesh/webgo/v6/CONTRIBUTING.md | 24 + vendor/github.com/bnkamalesh/webgo/v6/LICENSE | 21 + .../github.com/bnkamalesh/webgo/v6/README.md | 219 + .../bnkamalesh/webgo/v6/_config.yml | 1 + .../github.com/bnkamalesh/webgo/v6/config.go | 66 + .../github.com/bnkamalesh/webgo/v6/errors.go | 145 + vendor/github.com/bnkamalesh/webgo/v6/go.mod | 3 + .../bnkamalesh/webgo/v6/responses.go | 160 + .../github.com/bnkamalesh/webgo/v6/route.go | 247 + .../github.com/bnkamalesh/webgo/v6/router.go | 410 + .../github.com/bnkamalesh/webgo/v6/webgo.go | 188 + .../github.com/cespare/xxhash/v2/LICENSE.txt | 22 + vendor/github.com/cespare/xxhash/v2/README.md | 69 + vendor/github.com/cespare/xxhash/v2/go.mod | 3 + vendor/github.com/cespare/xxhash/v2/go.sum | 0 vendor/github.com/cespare/xxhash/v2/xxhash.go | 235 + .../cespare/xxhash/v2/xxhash_amd64.go | 13 + .../cespare/xxhash/v2/xxhash_amd64.s | 215 + .../cespare/xxhash/v2/xxhash_other.go | 76 + .../cespare/xxhash/v2/xxhash_safe.go | 15 + .../cespare/xxhash/v2/xxhash_unsafe.go | 57 + .../cpuguy83/go-md2man/v2/LICENSE.md | 21 + .../cpuguy83/go-md2man/v2/md2man/md2man.go | 14 + .../cpuguy83/go-md2man/v2/md2man/roff.go | 336 + vendor/github.com/creasty/defaults/.gitignore | 1 + vendor/github.com/creasty/defaults/LICENSE | 22 + vendor/github.com/creasty/defaults/Makefile | 30 + vendor/github.com/creasty/defaults/README.md | 73 + .../github.com/creasty/defaults/defaults.go | 221 + vendor/github.com/creasty/defaults/go.mod | 3 + vendor/github.com/creasty/defaults/go.sum | 0 vendor/github.com/creasty/defaults/setter.go | 12 + .../decred/dcrd/dcrec/secp256k1/v4/LICENSE | 17 + .../decred/dcrd/dcrec/secp256k1/v4/README.md | 72 + .../secp256k1/v4/compressedbytepoints.go | 11 + .../decred/dcrd/dcrec/secp256k1/v4/curve.go | 943 + .../decred/dcrd/dcrec/secp256k1/v4/doc.go | 58 + .../decred/dcrd/dcrec/secp256k1/v4/ecdh.go | 21 + .../dcrec/secp256k1/v4/ellipticadaptor.go | 255 + .../decred/dcrd/dcrec/secp256k1/v4/error.go | 67 + .../decred/dcrd/dcrec/secp256k1/v4/field.go | 1680 + .../dcrd/dcrec/secp256k1/v4/genstatics.go | 195 + .../decred/dcrd/dcrec/secp256k1/v4/go.mod | 5 + .../decred/dcrd/dcrec/secp256k1/v4/go.sum | 2 + .../dcrec/secp256k1/v4/loadprecomputed.go | 91 + .../dcrd/dcrec/secp256k1/v4/modnscalar.go | 1088 + .../decred/dcrd/dcrec/secp256k1/v4/nonce.go | 263 + .../decred/dcrd/dcrec/secp256k1/v4/privkey.go | 77 + .../decred/dcrd/dcrec/secp256k1/v4/pubkey.go | 232 + .../github.com/dgryski/go-rendezvous/LICENSE | 21 + .../github.com/dgryski/go-rendezvous/rdv.go | 79 + .../fullstorydev/grpcurl/.gitignore | 3 + .../fullstorydev/grpcurl/.goreleaser.yml | 40 + .../fullstorydev/grpcurl/Dockerfile | 36 + .../github.com/fullstorydev/grpcurl/LICENSE | 21 + .../github.com/fullstorydev/grpcurl/Makefile | 78 + .../github.com/fullstorydev/grpcurl/README.md | 242 + .../fullstorydev/grpcurl/desc_source.go | 304 + .../github.com/fullstorydev/grpcurl/format.go | 529 + vendor/github.com/fullstorydev/grpcurl/go.mod | 13 + vendor/github.com/fullstorydev/grpcurl/go.sum | 358 + .../fullstorydev/grpcurl/grpcurl.go | 699 + .../github.com/fullstorydev/grpcurl/invoke.go | 405 + .../fullstorydev/grpcurl/mk-test-files.sh | 57 + vendor/github.com/gin-contrib/sse/.travis.yml | 26 + vendor/github.com/gin-contrib/sse/LICENSE | 21 + vendor/github.com/gin-contrib/sse/README.md | 58 + vendor/github.com/gin-contrib/sse/go.mod | 5 + vendor/github.com/gin-contrib/sse/go.sum | 7 + .../github.com/gin-contrib/sse/sse-decoder.go | 116 + .../github.com/gin-contrib/sse/sse-encoder.go | 110 + vendor/github.com/gin-contrib/sse/writer.go | 24 + vendor/github.com/gin-gonic/gin/.gitignore | 7 + vendor/github.com/gin-gonic/gin/.golangci.yml | 39 + .../github.com/gin-gonic/gin/.goreleaser.yaml | 57 + vendor/github.com/gin-gonic/gin/AUTHORS.md | 406 + vendor/github.com/gin-gonic/gin/BENCHMARKS.md | 666 + vendor/github.com/gin-gonic/gin/CHANGELOG.md | 502 + .../gin-gonic/gin/CODE_OF_CONDUCT.md | 46 + .../github.com/gin-gonic/gin/CONTRIBUTING.md | 13 + vendor/github.com/gin-gonic/gin/LICENSE | 21 + vendor/github.com/gin-gonic/gin/Makefile | 77 + vendor/github.com/gin-gonic/gin/README.md | 2348 + vendor/github.com/gin-gonic/gin/any.go | 10 + vendor/github.com/gin-gonic/gin/auth.go | 91 + .../github.com/gin-gonic/gin/binding/any.go | 10 + .../gin-gonic/gin/binding/binding.go | 122 + .../gin/binding/binding_nomsgpack.go | 116 + .../gin/binding/default_validator.go | 97 + .../github.com/gin-gonic/gin/binding/form.go | 62 + .../gin-gonic/gin/binding/form_mapping.go | 403 + .../gin-gonic/gin/binding/header.go | 38 + .../github.com/gin-gonic/gin/binding/json.go | 56 + .../gin-gonic/gin/binding/msgpack.go | 38 + .../gin/binding/multipart_form_mapping.go | 74 + .../gin-gonic/gin/binding/protobuf.go | 41 + .../github.com/gin-gonic/gin/binding/query.go | 21 + .../github.com/gin-gonic/gin/binding/toml.go | 35 + .../github.com/gin-gonic/gin/binding/uri.go | 18 + .../github.com/gin-gonic/gin/binding/xml.go | 33 + .../github.com/gin-gonic/gin/binding/yaml.go | 35 + vendor/github.com/gin-gonic/gin/codecov.yml | 5 + vendor/github.com/gin-gonic/gin/context.go | 1202 + .../gin-gonic/gin/context_appengine.go | 12 + vendor/github.com/gin-gonic/gin/debug.go | 101 + vendor/github.com/gin-gonic/gin/deprecated.go | 21 + vendor/github.com/gin-gonic/gin/doc.go | 6 + vendor/github.com/gin-gonic/gin/errors.go | 174 + vendor/github.com/gin-gonic/gin/fs.go | 45 + vendor/github.com/gin-gonic/gin/gin.go | 704 + vendor/github.com/gin-gonic/gin/go.mod | 31 + vendor/github.com/gin-gonic/gin/go.sum | 84 + .../gin/internal/bytesconv/bytesconv.go | 24 + .../gin-gonic/gin/internal/json/go_json.go | 23 + .../gin-gonic/gin/internal/json/json.go | 23 + .../gin-gonic/gin/internal/json/jsoniter.go | 24 + vendor/github.com/gin-gonic/gin/logger.go | 270 + vendor/github.com/gin-gonic/gin/mode.go | 99 + vendor/github.com/gin-gonic/gin/path.go | 150 + vendor/github.com/gin-gonic/gin/recovery.go | 173 + vendor/github.com/gin-gonic/gin/render/any.go | 10 + .../github.com/gin-gonic/gin/render/data.go | 25 + .../github.com/gin-gonic/gin/render/html.go | 92 + .../github.com/gin-gonic/gin/render/json.go | 193 + .../gin-gonic/gin/render/msgpack.go | 44 + .../gin-gonic/gin/render/protobuf.go | 36 + .../github.com/gin-gonic/gin/render/reader.go | 48 + .../gin-gonic/gin/render/redirect.go | 29 + .../github.com/gin-gonic/gin/render/render.go | 41 + .../github.com/gin-gonic/gin/render/text.go | 41 + .../github.com/gin-gonic/gin/render/toml.go | 36 + vendor/github.com/gin-gonic/gin/render/xml.go | 28 + .../github.com/gin-gonic/gin/render/yaml.go | 36 + .../gin-gonic/gin/response_writer.go | 126 + .../github.com/gin-gonic/gin/routergroup.go | 248 + .../github.com/gin-gonic/gin/test_helpers.go | 16 + vendor/github.com/gin-gonic/gin/tree.go | 871 + vendor/github.com/gin-gonic/gin/utils.go | 164 + vendor/github.com/gin-gonic/gin/version.go | 8 + vendor/github.com/go-chi/chi/.gitignore | 3 + vendor/github.com/go-chi/chi/CHANGELOG.md | 269 + vendor/github.com/go-chi/chi/CONTRIBUTING.md | 31 + vendor/github.com/go-chi/chi/LICENSE | 20 + vendor/github.com/go-chi/chi/Makefile | 14 + vendor/github.com/go-chi/chi/README.md | 511 + vendor/github.com/go-chi/chi/chain.go | 49 + vendor/github.com/go-chi/chi/chi.go | 134 + vendor/github.com/go-chi/chi/context.go | 157 + vendor/github.com/go-chi/chi/go.mod | 3 + vendor/github.com/go-chi/chi/mux.go | 479 + vendor/github.com/go-chi/chi/tree.go | 866 + vendor/github.com/go-chi/cors/LICENSE | 21 + vendor/github.com/go-chi/cors/README.md | 39 + vendor/github.com/go-chi/cors/cors.go | 400 + vendor/github.com/go-chi/cors/go.mod | 3 + vendor/github.com/go-chi/cors/utils.go | 70 + vendor/github.com/go-chi/render/.travis.yml | 15 + vendor/github.com/go-chi/render/LICENSE | 20 + vendor/github.com/go-chi/render/README.md | 24 + .../github.com/go-chi/render/content_type.go | 84 + vendor/github.com/go-chi/render/decoder.go | 44 + vendor/github.com/go-chi/render/render.go | 143 + vendor/github.com/go-chi/render/responder.go | 234 + .../go-playground/locales/.gitignore | 24 + .../go-playground/locales/.travis.yml | 26 + .../github.com/go-playground/locales/LICENSE | 21 + .../go-playground/locales/README.md | 172 + .../locales/currency/currency.go | 311 + .../github.com/go-playground/locales/go.mod | 5 + .../github.com/go-playground/locales/go.sum | 3 + .../github.com/go-playground/locales/logo.png | Bin 0 -> 37360 bytes .../github.com/go-playground/locales/rules.go | 293 + .../universal-translator/.gitignore | 25 + .../universal-translator/.travis.yml | 27 + .../universal-translator/LICENSE | 21 + .../universal-translator/Makefile | 18 + .../universal-translator/README.md | 89 + .../universal-translator/errors.go | 148 + .../go-playground/universal-translator/go.mod | 5 + .../go-playground/universal-translator/go.sum | 7 + .../universal-translator/import_export.go | 276 + .../universal-translator/logo.png | Bin 0 -> 16598 bytes .../universal-translator/translator.go | 420 + .../universal_translator.go | 113 + .../go-playground/validator/v10/.gitignore | 30 + .../go-playground/validator/v10/LICENSE | 22 + .../validator/v10/MAINTAINERS.md | 16 + .../go-playground/validator/v10/Makefile | 18 + .../go-playground/validator/v10/README.md | 325 + .../go-playground/validator/v10/baked_in.go | 2438 + .../go-playground/validator/v10/cache.go | 322 + .../validator/v10/country_codes.go | 1132 + .../validator/v10/currency_codes.go | 79 + .../go-playground/validator/v10/doc.go | 1361 + .../go-playground/validator/v10/errors.go | 275 + .../validator/v10/field_level.go | 120 + .../go-playground/validator/v10/go.mod | 19 + .../go-playground/validator/v10/go.sum | 52 + .../go-playground/validator/v10/logo.png | Bin 0 -> 13443 bytes .../validator/v10/postcode_regexes.go | 173 + .../go-playground/validator/v10/regexes.go | 111 + .../validator/v10/struct_level.go | 175 + .../validator/v10/translations.go | 11 + .../go-playground/validator/v10/util.go | 288 + .../go-playground/validator/v10/validator.go | 477 + .../validator/v10/validator_instance.go | 658 + .../github.com/go-redis/redis/v8/.gitignore | 3 + .../go-redis/redis/v8/.golangci.yml | 4 + .../go-redis/redis/v8/.prettierrc.yml | 4 + .../github.com/go-redis/redis/v8/CHANGELOG.md | 177 + vendor/github.com/go-redis/redis/v8/LICENSE | 25 + vendor/github.com/go-redis/redis/v8/Makefile | 35 + vendor/github.com/go-redis/redis/v8/README.md | 175 + .../github.com/go-redis/redis/v8/RELEASING.md | 15 + .../github.com/go-redis/redis/v8/cluster.go | 1750 + .../go-redis/redis/v8/cluster_commands.go | 109 + .../github.com/go-redis/redis/v8/command.go | 3478 + .../github.com/go-redis/redis/v8/commands.go | 3475 + vendor/github.com/go-redis/redis/v8/doc.go | 4 + vendor/github.com/go-redis/redis/v8/error.go | 144 + vendor/github.com/go-redis/redis/v8/go.mod | 20 + vendor/github.com/go-redis/redis/v8/go.sum | 108 + .../go-redis/redis/v8/internal/arg.go | 56 + .../redis/v8/internal/hashtag/hashtag.go | 78 + .../go-redis/redis/v8/internal/hscan/hscan.go | 201 + .../redis/v8/internal/hscan/structmap.go | 93 + .../go-redis/redis/v8/internal/internal.go | 29 + .../go-redis/redis/v8/internal/log.go | 26 + .../go-redis/redis/v8/internal/once.go | 60 + .../go-redis/redis/v8/internal/pool/conn.go | 121 + .../go-redis/redis/v8/internal/pool/pool.go | 557 + .../redis/v8/internal/pool/pool_single.go | 58 + .../redis/v8/internal/pool/pool_sticky.go | 201 + .../redis/v8/internal/proto/reader.go | 332 + .../go-redis/redis/v8/internal/proto/scan.go | 180 + .../redis/v8/internal/proto/writer.go | 155 + .../go-redis/redis/v8/internal/rand/rand.go | 50 + .../go-redis/redis/v8/internal/safe.go | 12 + .../go-redis/redis/v8/internal/unsafe.go | 21 + .../go-redis/redis/v8/internal/util.go | 46 + .../go-redis/redis/v8/internal/util/safe.go | 12 + .../redis/v8/internal/util/strconv.go | 19 + .../go-redis/redis/v8/internal/util/unsafe.go | 23 + .../github.com/go-redis/redis/v8/iterator.go | 77 + .../github.com/go-redis/redis/v8/options.go | 429 + .../github.com/go-redis/redis/v8/package.json | 8 + .../github.com/go-redis/redis/v8/pipeline.go | 147 + vendor/github.com/go-redis/redis/v8/pubsub.go | 668 + vendor/github.com/go-redis/redis/v8/redis.go | 773 + vendor/github.com/go-redis/redis/v8/result.go | 180 + vendor/github.com/go-redis/redis/v8/ring.go | 736 + vendor/github.com/go-redis/redis/v8/script.go | 65 + .../github.com/go-redis/redis/v8/sentinel.go | 796 + vendor/github.com/go-redis/redis/v8/tx.go | 149 + .../github.com/go-redis/redis/v8/universal.go | 215 + .../github.com/go-redis/redis/v8/version.go | 6 + vendor/github.com/go-stack/stack/LICENSE.md | 21 + vendor/github.com/go-stack/stack/README.md | 38 + vendor/github.com/go-stack/stack/go.mod | 3 + vendor/github.com/go-stack/stack/stack.go | 400 + vendor/github.com/go-test/deep/.gitignore | 2 + vendor/github.com/go-test/deep/.travis.yml | 13 + vendor/github.com/go-test/deep/CHANGES.md | 47 + vendor/github.com/go-test/deep/LICENSE | 21 + vendor/github.com/go-test/deep/README.md | 51 + vendor/github.com/go-test/deep/SECURITY.md | 17 + vendor/github.com/go-test/deep/deep.go | 417 + vendor/github.com/go-test/deep/go.mod | 3 + vendor/github.com/go-test/deep/go.sum | 0 vendor/github.com/goccy/go-json/.codecov.yml | 32 + vendor/github.com/goccy/go-json/.gitignore | 2 + vendor/github.com/goccy/go-json/.golangci.yml | 83 + vendor/github.com/goccy/go-json/CHANGELOG.md | 339 + vendor/github.com/goccy/go-json/LICENSE | 21 + vendor/github.com/goccy/go-json/Makefile | 39 + vendor/github.com/goccy/go-json/README.md | 529 + vendor/github.com/goccy/go-json/color.go | 68 + vendor/github.com/goccy/go-json/decode.go | 232 + .../goccy/go-json/docker-compose.yml | 13 + vendor/github.com/goccy/go-json/encode.go | 326 + vendor/github.com/goccy/go-json/error.go | 39 + vendor/github.com/goccy/go-json/go.mod | 3 + vendor/github.com/goccy/go-json/go.sum | 0 .../internal/decoder/anonymous_field.go | 37 + .../goccy/go-json/internal/decoder/array.go | 169 + .../goccy/go-json/internal/decoder/bool.go | 78 + .../goccy/go-json/internal/decoder/bytes.go | 113 + .../goccy/go-json/internal/decoder/compile.go | 469 + .../internal/decoder/compile_norace.go | 29 + .../go-json/internal/decoder/compile_race.go | 37 + .../goccy/go-json/internal/decoder/context.go | 254 + .../goccy/go-json/internal/decoder/float.go | 158 + .../goccy/go-json/internal/decoder/func.go | 141 + .../goccy/go-json/internal/decoder/int.go | 242 + .../go-json/internal/decoder/interface.go | 458 + .../goccy/go-json/internal/decoder/invalid.go | 45 + .../goccy/go-json/internal/decoder/map.go | 187 + .../goccy/go-json/internal/decoder/number.go | 112 + .../goccy/go-json/internal/decoder/option.go | 15 + .../goccy/go-json/internal/decoder/ptr.go | 87 + .../goccy/go-json/internal/decoder/slice.go | 301 + .../goccy/go-json/internal/decoder/stream.go | 553 + .../goccy/go-json/internal/decoder/string.go | 414 + .../goccy/go-json/internal/decoder/struct.go | 819 + .../goccy/go-json/internal/decoder/type.go | 29 + .../goccy/go-json/internal/decoder/uint.go | 190 + .../internal/decoder/unmarshal_json.go | 99 + .../internal/decoder/unmarshal_text.go | 280 + .../internal/decoder/wrapped_string.go | 68 + .../goccy/go-json/internal/encoder/code.go | 1005 + .../goccy/go-json/internal/encoder/compact.go | 286 + .../go-json/internal/encoder/compiler.go | 913 + .../internal/encoder/compiler_norace.go | 32 + .../go-json/internal/encoder/compiler_race.go | 45 + .../goccy/go-json/internal/encoder/context.go | 105 + .../go-json/internal/encoder/decode_rune.go | 126 + .../goccy/go-json/internal/encoder/encoder.go | 596 + .../goccy/go-json/internal/encoder/indent.go | 211 + .../goccy/go-json/internal/encoder/int.go | 152 + .../goccy/go-json/internal/encoder/map112.go | 9 + .../goccy/go-json/internal/encoder/map113.go | 9 + .../goccy/go-json/internal/encoder/opcode.go | 669 + .../goccy/go-json/internal/encoder/option.go | 47 + .../goccy/go-json/internal/encoder/optype.go | 932 + .../goccy/go-json/internal/encoder/query.go | 135 + .../goccy/go-json/internal/encoder/string.go | 459 + .../go-json/internal/encoder/string_table.go | 415 + .../go-json/internal/encoder/vm/debug_vm.go | 35 + .../goccy/go-json/internal/encoder/vm/hack.go | 9 + .../goccy/go-json/internal/encoder/vm/util.go | 207 + .../goccy/go-json/internal/encoder/vm/vm.go | 4855 + .../internal/encoder/vm_color/debug_vm.go | 35 + .../go-json/internal/encoder/vm_color/hack.go | 9 + .../go-json/internal/encoder/vm_color/util.go | 274 + .../go-json/internal/encoder/vm_color/vm.go | 4855 + .../encoder/vm_color_indent/debug_vm.go | 35 + .../internal/encoder/vm_color_indent/util.go | 296 + .../internal/encoder/vm_color_indent/vm.go | 4855 + .../internal/encoder/vm_indent/debug_vm.go | 35 + .../internal/encoder/vm_indent/hack.go | 9 + .../internal/encoder/vm_indent/util.go | 229 + .../go-json/internal/encoder/vm_indent/vm.go | 4855 + .../goccy/go-json/internal/errors/error.go | 164 + .../goccy/go-json/internal/runtime/rtype.go | 263 + .../go-json/internal/runtime/struct_field.go | 87 + .../goccy/go-json/internal/runtime/type.go | 100 + vendor/github.com/goccy/go-json/json.go | 371 + vendor/github.com/goccy/go-json/option.go | 72 + vendor/github.com/goccy/go-json/query.go | 47 + vendor/github.com/golang/protobuf/AUTHORS | 3 + .../github.com/golang/protobuf/CONTRIBUTORS | 3 + vendor/github.com/golang/protobuf/LICENSE | 28 + .../golang/protobuf/jsonpb/decode.go | 524 + .../golang/protobuf/jsonpb/encode.go | 559 + .../github.com/golang/protobuf/jsonpb/json.go | 69 + .../golang/protobuf/proto/buffer.go | 324 + .../golang/protobuf/proto/defaults.go | 63 + .../golang/protobuf/proto/deprecated.go | 113 + .../golang/protobuf/proto/discard.go | 58 + .../golang/protobuf/proto/extensions.go | 356 + .../golang/protobuf/proto/properties.go | 306 + .../github.com/golang/protobuf/proto/proto.go | 167 + .../golang/protobuf/proto/registry.go | 317 + .../golang/protobuf/proto/text_decode.go | 801 + .../golang/protobuf/proto/text_encode.go | 560 + .../github.com/golang/protobuf/proto/wire.go | 78 + .../golang/protobuf/proto/wrappers.go | 34 + .../protoc-gen-go/descriptor/descriptor.pb.go | 200 + .../protoc-gen-go/plugin/plugin.pb.go | 75 + .../github.com/golang/protobuf/ptypes/any.go | 179 + .../golang/protobuf/ptypes/any/any.pb.go | 62 + .../github.com/golang/protobuf/ptypes/doc.go | 10 + .../golang/protobuf/ptypes/duration.go | 76 + .../protobuf/ptypes/duration/duration.pb.go | 63 + .../golang/protobuf/ptypes/empty/empty.pb.go | 62 + .../protobuf/ptypes/struct/struct.pb.go | 78 + .../golang/protobuf/ptypes/timestamp.go | 112 + .../protobuf/ptypes/timestamp/timestamp.pb.go | 64 + .../protobuf/ptypes/wrappers/wrappers.pb.go | 71 + vendor/github.com/golang/snappy/.gitignore | 16 + vendor/github.com/golang/snappy/AUTHORS | 18 + vendor/github.com/golang/snappy/CONTRIBUTORS | 41 + vendor/github.com/golang/snappy/LICENSE | 27 + vendor/github.com/golang/snappy/README | 107 + vendor/github.com/golang/snappy/decode.go | 264 + .../github.com/golang/snappy/decode_amd64.s | 490 + .../github.com/golang/snappy/decode_arm64.s | 494 + vendor/github.com/golang/snappy/decode_asm.go | 15 + .../github.com/golang/snappy/decode_other.go | 115 + vendor/github.com/golang/snappy/encode.go | 289 + .../github.com/golang/snappy/encode_amd64.s | 730 + .../github.com/golang/snappy/encode_arm64.s | 722 + vendor/github.com/golang/snappy/encode_asm.go | 30 + .../github.com/golang/snappy/encode_other.go | 238 + vendor/github.com/golang/snappy/go.mod | 1 + vendor/github.com/golang/snappy/snappy.go | 98 + vendor/github.com/google/uuid/.travis.yml | 9 + vendor/github.com/google/uuid/CONTRIBUTING.md | 10 + vendor/github.com/google/uuid/CONTRIBUTORS | 9 + vendor/github.com/google/uuid/LICENSE | 27 + vendor/github.com/google/uuid/README.md | 19 + vendor/github.com/google/uuid/dce.go | 80 + vendor/github.com/google/uuid/doc.go | 12 + vendor/github.com/google/uuid/go.mod | 1 + vendor/github.com/google/uuid/hash.go | 53 + vendor/github.com/google/uuid/marshal.go | 38 + vendor/github.com/google/uuid/node.go | 90 + vendor/github.com/google/uuid/node_js.go | 12 + vendor/github.com/google/uuid/node_net.go | 33 + vendor/github.com/google/uuid/null.go | 118 + vendor/github.com/google/uuid/sql.go | 59 + vendor/github.com/google/uuid/time.go | 123 + vendor/github.com/google/uuid/util.go | 43 + vendor/github.com/google/uuid/uuid.go | 294 + vendor/github.com/google/uuid/version1.go | 44 + vendor/github.com/google/uuid/version4.go | 76 + vendor/github.com/gorilla/mux/AUTHORS | 8 + vendor/github.com/gorilla/mux/LICENSE | 27 + vendor/github.com/gorilla/mux/README.md | 805 + vendor/github.com/gorilla/mux/doc.go | 306 + vendor/github.com/gorilla/mux/go.mod | 3 + vendor/github.com/gorilla/mux/middleware.go | 74 + vendor/github.com/gorilla/mux/mux.go | 606 + vendor/github.com/gorilla/mux/regexp.go | 388 + vendor/github.com/gorilla/mux/route.go | 736 + vendor/github.com/gorilla/mux/test_helpers.go | 19 + .../github.com/gorilla/websocket/.gitignore | 25 + vendor/github.com/gorilla/websocket/AUTHORS | 9 + vendor/github.com/gorilla/websocket/LICENSE | 22 + vendor/github.com/gorilla/websocket/README.md | 64 + vendor/github.com/gorilla/websocket/client.go | 395 + .../gorilla/websocket/client_clone.go | 16 + .../gorilla/websocket/client_clone_legacy.go | 38 + .../gorilla/websocket/compression.go | 148 + vendor/github.com/gorilla/websocket/conn.go | 1201 + .../gorilla/websocket/conn_write.go | 15 + .../gorilla/websocket/conn_write_legacy.go | 18 + vendor/github.com/gorilla/websocket/doc.go | 227 + vendor/github.com/gorilla/websocket/go.mod | 3 + vendor/github.com/gorilla/websocket/go.sum | 0 vendor/github.com/gorilla/websocket/join.go | 42 + vendor/github.com/gorilla/websocket/json.go | 60 + vendor/github.com/gorilla/websocket/mask.go | 54 + .../github.com/gorilla/websocket/mask_safe.go | 15 + .../github.com/gorilla/websocket/prepared.go | 102 + vendor/github.com/gorilla/websocket/proxy.go | 77 + vendor/github.com/gorilla/websocket/server.go | 363 + vendor/github.com/gorilla/websocket/trace.go | 19 + .../github.com/gorilla/websocket/trace_17.go | 12 + vendor/github.com/gorilla/websocket/util.go | 283 + .../gorilla/websocket/x_net_proxy.go | 473 + .../hashicorp/golang-lru/.gitignore | 23 + vendor/github.com/hashicorp/golang-lru/2q.go | 223 + .../github.com/hashicorp/golang-lru/LICENSE | 362 + .../github.com/hashicorp/golang-lru/README.md | 25 + vendor/github.com/hashicorp/golang-lru/arc.go | 257 + vendor/github.com/hashicorp/golang-lru/doc.go | 21 + vendor/github.com/hashicorp/golang-lru/go.mod | 3 + vendor/github.com/hashicorp/golang-lru/lru.go | 150 + .../hashicorp/golang-lru/simplelru/lru.go | 177 + .../golang-lru/simplelru/lru_interface.go | 39 + vendor/github.com/jhump/protoreflect/LICENSE | 202 + .../jhump/protoreflect/codec/codec.go | 217 + .../jhump/protoreflect/codec/decode_fields.go | 318 + .../jhump/protoreflect/codec/doc.go | 7 + .../jhump/protoreflect/codec/encode_fields.go | 288 + .../jhump/protoreflect/desc/convert.go | 233 + .../jhump/protoreflect/desc/descriptor.go | 1774 + .../protoreflect/desc/descriptor_no_unsafe.go | 30 + .../protoreflect/desc/descriptor_unsafe.go | 59 + .../github.com/jhump/protoreflect/desc/doc.go | 62 + .../jhump/protoreflect/desc/imports.go | 319 + .../desc/internal/proto3_optional.go | 74 + .../protoreflect/desc/internal/source_info.go | 107 + .../jhump/protoreflect/desc/internal/util.go | 293 + .../jhump/protoreflect/desc/load.go | 343 + .../protoreflect/desc/protoparse/.gitignore | 1 + .../jhump/protoreflect/desc/protoparse/ast.go | 205 + .../protoreflect/desc/protoparse/ast/doc.go | 27 + .../protoreflect/desc/protoparse/ast/enum.go | 154 + .../protoreflect/desc/protoparse/ast/field.go | 659 + .../protoreflect/desc/protoparse/ast/file.go | 234 + .../desc/protoparse/ast/identifiers.go | 134 + .../desc/protoparse/ast/message.go | 199 + .../desc/protoparse/ast/no_source.go | 103 + .../protoreflect/desc/protoparse/ast/node.go | 200 + .../desc/protoparse/ast/options.go | 361 + .../protoreflect/desc/protoparse/ast/print.go | 86 + .../desc/protoparse/ast/ranges.go | 305 + .../desc/protoparse/ast/service.go | 273 + .../desc/protoparse/ast/source_pos.go | 38 + .../desc/protoparse/ast/values.go | 569 + .../protoreflect/desc/protoparse/ast/walk.go | 492 + .../desc/protoparse/descriptor_protos.go | 588 + .../jhump/protoreflect/desc/protoparse/doc.go | 10 + .../protoreflect/desc/protoparse/errors.go | 181 + .../protoreflect/desc/protoparse/lexer.go | 809 + .../protoreflect/desc/protoparse/linker.go | 1326 + .../protoreflect/desc/protoparse/options.go | 1581 + .../protoreflect/desc/protoparse/parser.go | 847 + .../protoreflect/desc/protoparse/proto.y | 1205 + .../protoreflect/desc/protoparse/proto.y.go | 2588 + .../desc/protoparse/resolve_files.go | 175 + .../desc/protoparse/source_code_info.go | 544 + .../desc/protoparse/std_imports.go | 50 + .../desc/protoparse/test-source-info.txt | 6390 + .../protoreflect/desc/protoparse/validate.go | 383 + .../jhump/protoreflect/desc/protoprint/doc.go | 7 + .../protoreflect/desc/protoprint/print.go | 2656 + .../protoreflect/desc/protoprint/sort.go | 439 + .../protoreflect/desc/sourceinfo/locations.go | 207 + .../protoreflect/desc/sourceinfo/registry.go | 206 + .../protoreflect/desc/sourceinfo/wrappers.go | 508 + .../jhump/protoreflect/dynamic/binary.go | 185 + .../jhump/protoreflect/dynamic/doc.go | 159 + .../protoreflect/dynamic/dynamic_message.go | 2774 + .../jhump/protoreflect/dynamic/equal.go | 157 + .../jhump/protoreflect/dynamic/extension.go | 46 + .../dynamic/extension_registry.go | 241 + .../protoreflect/dynamic/grpcdynamic/stub.go | 310 + .../jhump/protoreflect/dynamic/indent.go | 76 + .../jhump/protoreflect/dynamic/json.go | 1256 + .../jhump/protoreflect/dynamic/maps_1.11.go | 130 + .../jhump/protoreflect/dynamic/maps_1.12.go | 138 + .../jhump/protoreflect/dynamic/merge.go | 100 + .../protoreflect/dynamic/message_factory.go | 207 + .../jhump/protoreflect/dynamic/text.go | 1177 + .../jhump/protoreflect/grpcreflect/client.go | 771 + .../jhump/protoreflect/grpcreflect/doc.go | 10 + .../grpc_reflection_v1/reflection.pb.go | 952 + .../grpc_reflection_v1/reflection.proto | 146 + .../grpc_reflection_v1/reflection_grpc.pb.go | 141 + .../internal/grpc_reflection_v1/svc_impl.go | 232 + .../jhump/protoreflect/grpcreflect/server.go | 67 + .../protoreflect/internal/codec/buffer.go | 118 + .../protoreflect/internal/codec/decode.go | 346 + .../protoreflect/internal/codec/encode.go | 147 + .../protoreflect/internal/standard_files.go | 127 + .../protoreflect/internal/unrecognized.go | 41 + .../jmespath/go-jmespath/.gitignore | 4 + .../jmespath/go-jmespath/.travis.yml | 28 + .../github.com/jmespath/go-jmespath/LICENSE | 13 + .../github.com/jmespath/go-jmespath/Makefile | 51 + .../github.com/jmespath/go-jmespath/README.md | 87 + vendor/github.com/jmespath/go-jmespath/api.go | 49 + .../go-jmespath/astnodetype_string.go | 16 + .../jmespath/go-jmespath/functions.go | 842 + vendor/github.com/jmespath/go-jmespath/go.mod | 5 + vendor/github.com/jmespath/go-jmespath/go.sum | 11 + .../jmespath/go-jmespath/interpreter.go | 418 + .../github.com/jmespath/go-jmespath/lexer.go | 420 + .../github.com/jmespath/go-jmespath/parser.go | 603 + .../jmespath/go-jmespath/toktype_string.go | 16 + .../github.com/jmespath/go-jmespath/util.go | 185 + .../github.com/json-iterator/go/.codecov.yml | 3 + vendor/github.com/json-iterator/go/.gitignore | 4 + .../github.com/json-iterator/go/.travis.yml | 14 + vendor/github.com/json-iterator/go/Gopkg.lock | 21 + vendor/github.com/json-iterator/go/Gopkg.toml | 26 + vendor/github.com/json-iterator/go/LICENSE | 21 + vendor/github.com/json-iterator/go/README.md | 85 + vendor/github.com/json-iterator/go/adapter.go | 150 + vendor/github.com/json-iterator/go/any.go | 325 + .../github.com/json-iterator/go/any_array.go | 278 + .../github.com/json-iterator/go/any_bool.go | 137 + .../github.com/json-iterator/go/any_float.go | 83 + .../github.com/json-iterator/go/any_int32.go | 74 + .../github.com/json-iterator/go/any_int64.go | 74 + .../json-iterator/go/any_invalid.go | 82 + vendor/github.com/json-iterator/go/any_nil.go | 69 + .../github.com/json-iterator/go/any_number.go | 123 + .../github.com/json-iterator/go/any_object.go | 374 + vendor/github.com/json-iterator/go/any_str.go | 166 + .../github.com/json-iterator/go/any_uint32.go | 74 + .../github.com/json-iterator/go/any_uint64.go | 74 + vendor/github.com/json-iterator/go/build.sh | 12 + vendor/github.com/json-iterator/go/config.go | 375 + .../go/fuzzy_mode_convert_table.md | 7 + vendor/github.com/json-iterator/go/go.mod | 11 + vendor/github.com/json-iterator/go/go.sum | 14 + vendor/github.com/json-iterator/go/iter.go | 349 + .../github.com/json-iterator/go/iter_array.go | 64 + .../github.com/json-iterator/go/iter_float.go | 342 + .../github.com/json-iterator/go/iter_int.go | 346 + .../json-iterator/go/iter_object.go | 267 + .../github.com/json-iterator/go/iter_skip.go | 130 + .../json-iterator/go/iter_skip_sloppy.go | 163 + .../json-iterator/go/iter_skip_strict.go | 99 + .../github.com/json-iterator/go/iter_str.go | 215 + .../github.com/json-iterator/go/jsoniter.go | 18 + vendor/github.com/json-iterator/go/pool.go | 42 + vendor/github.com/json-iterator/go/reflect.go | 337 + .../json-iterator/go/reflect_array.go | 104 + .../json-iterator/go/reflect_dynamic.go | 70 + .../json-iterator/go/reflect_extension.go | 483 + .../json-iterator/go/reflect_json_number.go | 112 + .../go/reflect_json_raw_message.go | 76 + .../json-iterator/go/reflect_map.go | 346 + .../json-iterator/go/reflect_marshaler.go | 225 + .../json-iterator/go/reflect_native.go | 453 + .../json-iterator/go/reflect_optional.go | 129 + .../json-iterator/go/reflect_slice.go | 99 + .../go/reflect_struct_decoder.go | 1097 + .../go/reflect_struct_encoder.go | 211 + vendor/github.com/json-iterator/go/stream.go | 210 + .../json-iterator/go/stream_float.go | 111 + .../github.com/json-iterator/go/stream_int.go | 190 + .../github.com/json-iterator/go/stream_str.go | 372 + vendor/github.com/json-iterator/go/test.sh | 12 + .../k0kubun/pp/v3/.github_changelog_generator | 2 + vendor/github.com/k0kubun/pp/v3/CHANGELOG.md | 239 + vendor/github.com/k0kubun/pp/v3/LICENSE.txt | 21 + vendor/github.com/k0kubun/pp/v3/README.md | 107 + vendor/github.com/k0kubun/pp/v3/color.go | 124 + vendor/github.com/k0kubun/pp/v3/go.mod | 13 + vendor/github.com/k0kubun/pp/v3/go.sum | 10 + vendor/github.com/k0kubun/pp/v3/pp.go | 296 + vendor/github.com/k0kubun/pp/v3/printer.go | 533 + vendor/github.com/k0kubun/pp/v3/sort.go | 75 + .../kelseyhightower/envconfig/.travis.yml | 13 + .../kelseyhightower/envconfig/LICENSE | 19 + .../kelseyhightower/envconfig/MAINTAINERS | 2 + .../kelseyhightower/envconfig/README.md | 192 + .../kelseyhightower/envconfig/doc.go | 8 + .../kelseyhightower/envconfig/env_os.go | 7 + .../kelseyhightower/envconfig/env_syscall.go | 7 + .../kelseyhightower/envconfig/envconfig.go | 382 + .../kelseyhightower/envconfig/go.mod | 1 + .../kelseyhightower/envconfig/usage.go | 164 + .../klauspost/compress/.gitattributes | 2 + .../github.com/klauspost/compress/.gitignore | 32 + .../klauspost/compress/.goreleaser.yml | 141 + vendor/github.com/klauspost/compress/LICENSE | 304 + .../github.com/klauspost/compress/README.md | 560 + .../klauspost/compress/compressible.go | 85 + .../klauspost/compress/flate/deflate.go | 903 + .../klauspost/compress/flate/dict_decoder.go | 184 + .../klauspost/compress/flate/fast_encoder.go | 233 + .../compress/flate/huffman_bit_writer.go | 1185 + .../klauspost/compress/flate/huffman_code.go | 412 + .../compress/flate/huffman_sortByFreq.go | 178 + .../compress/flate/huffman_sortByLiteral.go | 201 + .../klauspost/compress/flate/inflate.go | 793 + .../klauspost/compress/flate/inflate_gen.go | 1283 + .../klauspost/compress/flate/level1.go | 240 + .../klauspost/compress/flate/level2.go | 213 + .../klauspost/compress/flate/level3.go | 240 + .../klauspost/compress/flate/level4.go | 220 + .../klauspost/compress/flate/level5.go | 302 + .../klauspost/compress/flate/level6.go | 315 + .../klauspost/compress/flate/regmask_amd64.go | 37 + .../klauspost/compress/flate/regmask_other.go | 40 + .../klauspost/compress/flate/stateless.go | 305 + .../klauspost/compress/flate/token.go | 379 + .../klauspost/compress/fse/README.md | 79 + .../klauspost/compress/fse/bitreader.go | 122 + .../klauspost/compress/fse/bitwriter.go | 168 + .../klauspost/compress/fse/bytereader.go | 47 + .../klauspost/compress/fse/compress.go | 683 + .../klauspost/compress/fse/decompress.go | 374 + .../github.com/klauspost/compress/fse/fse.go | 144 + vendor/github.com/klauspost/compress/gen.sh | 4 + vendor/github.com/klauspost/compress/go.mod | 3 + vendor/github.com/klauspost/compress/go.sum | 0 .../klauspost/compress/gzip/gunzip.go | 349 + .../klauspost/compress/gzip/gzip.go | 269 + .../klauspost/compress/huff0/.gitignore | 1 + .../klauspost/compress/huff0/README.md | 89 + .../klauspost/compress/huff0/bitreader.go | 233 + .../klauspost/compress/huff0/bitwriter.go | 95 + .../klauspost/compress/huff0/bytereader.go | 44 + .../klauspost/compress/huff0/compress.go | 730 + .../klauspost/compress/huff0/decompress.go | 1159 + .../compress/huff0/decompress_amd64.go | 222 + .../compress/huff0/decompress_amd64.s | 847 + .../compress/huff0/decompress_generic.go | 295 + .../klauspost/compress/huff0/huff0.go | 337 + .../compress/internal/cpuinfo/cpuinfo.go | 34 + .../internal/cpuinfo/cpuinfo_amd64.go | 11 + .../compress/internal/cpuinfo/cpuinfo_amd64.s | 36 + .../compress/internal/snapref/LICENSE | 27 + .../compress/internal/snapref/decode.go | 264 + .../compress/internal/snapref/decode_other.go | 113 + .../compress/internal/snapref/encode.go | 289 + .../compress/internal/snapref/encode_other.go | 236 + .../compress/internal/snapref/snappy.go | 98 + vendor/github.com/klauspost/compress/s2sx.mod | 4 + vendor/github.com/klauspost/compress/s2sx.sum | 0 .../klauspost/compress/zlib/reader.go | 183 + .../klauspost/compress/zlib/writer.go | 201 + .../klauspost/compress/zstd/README.md | 439 + .../klauspost/compress/zstd/bitreader.go | 140 + .../klauspost/compress/zstd/bitwriter.go | 113 + .../klauspost/compress/zstd/blockdec.go | 721 + .../klauspost/compress/zstd/blockenc.go | 871 + .../compress/zstd/blocktype_string.go | 85 + .../klauspost/compress/zstd/bytebuf.go | 132 + .../klauspost/compress/zstd/bytereader.go | 82 + .../klauspost/compress/zstd/decodeheader.go | 230 + .../klauspost/compress/zstd/decoder.go | 924 + .../compress/zstd/decoder_options.go | 123 + .../klauspost/compress/zstd/dict.go | 122 + .../klauspost/compress/zstd/enc_base.go | 188 + .../klauspost/compress/zstd/enc_best.go | 558 + .../klauspost/compress/zstd/enc_better.go | 1237 + .../klauspost/compress/zstd/enc_dfast.go | 1124 + .../klauspost/compress/zstd/enc_fast.go | 898 + .../klauspost/compress/zstd/encoder.go | 641 + .../compress/zstd/encoder_options.go | 317 + .../klauspost/compress/zstd/framedec.go | 419 + .../klauspost/compress/zstd/frameenc.go | 137 + .../klauspost/compress/zstd/fse_decoder.go | 307 + .../compress/zstd/fse_decoder_amd64.go | 64 + .../compress/zstd/fse_decoder_amd64.s | 127 + .../compress/zstd/fse_decoder_generic.go | 72 + .../klauspost/compress/zstd/fse_encoder.go | 701 + .../klauspost/compress/zstd/fse_predefined.go | 158 + .../klauspost/compress/zstd/hash.go | 35 + .../klauspost/compress/zstd/history.go | 119 + .../compress/zstd/internal/xxhash/LICENSE.txt | 22 + .../compress/zstd/internal/xxhash/README.md | 58 + .../compress/zstd/internal/xxhash/xxhash.go | 237 + .../zstd/internal/xxhash/xxhash_amd64.s | 216 + .../zstd/internal/xxhash/xxhash_arm64.s | 186 + .../zstd/internal/xxhash/xxhash_asm.go | 16 + .../zstd/internal/xxhash/xxhash_other.go | 77 + .../zstd/internal/xxhash/xxhash_safe.go | 11 + .../klauspost/compress/zstd/seqdec.go | 491 + .../klauspost/compress/zstd/seqdec_amd64.go | 368 + .../klauspost/compress/zstd/seqdec_amd64.s | 4100 + .../klauspost/compress/zstd/seqdec_generic.go | 237 + .../klauspost/compress/zstd/seqenc.go | 114 + .../klauspost/compress/zstd/snappy.go | 435 + .../github.com/klauspost/compress/zstd/zip.go | 141 + .../klauspost/compress/zstd/zstd.go | 152 + .../github.com/labstack/echo/v4/.editorconfig | 25 + .../labstack/echo/v4/.gitattributes | 20 + vendor/github.com/labstack/echo/v4/.gitignore | 8 + .../github.com/labstack/echo/v4/.travis.yml | 21 + .../github.com/labstack/echo/v4/CHANGELOG.md | 301 + vendor/github.com/labstack/echo/v4/LICENSE | 21 + vendor/github.com/labstack/echo/v4/Makefile | 34 + vendor/github.com/labstack/echo/v4/README.md | 139 + vendor/github.com/labstack/echo/v4/bind.go | 340 + vendor/github.com/labstack/echo/v4/binder.go | 1331 + .../github.com/labstack/echo/v4/codecov.yml | 11 + vendor/github.com/labstack/echo/v4/context.go | 638 + .../github.com/labstack/echo/v4/context_fs.go | 49 + vendor/github.com/labstack/echo/v4/echo.go | 984 + vendor/github.com/labstack/echo/v4/echo_fs.go | 175 + vendor/github.com/labstack/echo/v4/go.mod | 24 + vendor/github.com/labstack/echo/v4/go.sum | 45 + vendor/github.com/labstack/echo/v4/group.go | 126 + .../github.com/labstack/echo/v4/group_fs.go | 30 + vendor/github.com/labstack/echo/v4/ip.go | 263 + vendor/github.com/labstack/echo/v4/json.go | 31 + vendor/github.com/labstack/echo/v4/log.go | 41 + .../github.com/labstack/echo/v4/response.go | 104 + vendor/github.com/labstack/echo/v4/router.go | 698 + vendor/github.com/labstack/gommon/LICENSE | 22 + .../labstack/gommon/color/README.md | 86 + .../github.com/labstack/gommon/color/color.go | 407 + .../github.com/labstack/gommon/log/README.md | 5 + .../github.com/labstack/gommon/log/color.go | 13 + vendor/github.com/labstack/gommon/log/log.go | 416 + .../github.com/labstack/gommon/log/white.go | 12 + vendor/github.com/leodido/go-urn/.gitignore | 11 + vendor/github.com/leodido/go-urn/.travis.yml | 16 + vendor/github.com/leodido/go-urn/LICENSE | 21 + vendor/github.com/leodido/go-urn/README.md | 55 + vendor/github.com/leodido/go-urn/go.mod | 5 + vendor/github.com/leodido/go-urn/go.sum | 11 + vendor/github.com/leodido/go-urn/machine.go | 1691 + .../github.com/leodido/go-urn/machine.go.rl | 159 + vendor/github.com/leodido/go-urn/makefile | 39 + vendor/github.com/leodido/go-urn/urn.go | 86 + .../lestrrat-go/backoff/v2/.gitignore | 14 + .../lestrrat-go/backoff/v2/.golangci.yml | 7 + .../github.com/lestrrat-go/backoff/v2/Changes | 8 + .../github.com/lestrrat-go/backoff/v2/LICENSE | 21 + .../lestrrat-go/backoff/v2/README.md | 183 + .../lestrrat-go/backoff/v2/backoff.go | 31 + .../lestrrat-go/backoff/v2/constant.go | 66 + .../lestrrat-go/backoff/v2/controller.go | 99 + .../github.com/lestrrat-go/backoff/v2/doc.go | 6 + .../lestrrat-go/backoff/v2/exponential.go | 107 + .../github.com/lestrrat-go/backoff/v2/go.mod | 8 + .../github.com/lestrrat-go/backoff/v2/go.sum | 13 + .../lestrrat-go/backoff/v2/interface.go | 30 + .../lestrrat-go/backoff/v2/jitter.go | 59 + .../github.com/lestrrat-go/backoff/v2/null.go | 51 + .../lestrrat-go/backoff/v2/options.go | 127 + .../lestrrat-go/blackmagic/.gitignore | 15 + .../github.com/lestrrat-go/blackmagic/LICENSE | 21 + .../lestrrat-go/blackmagic/README.md | 3 + .../lestrrat-go/blackmagic/blackmagic.go | 55 + .../github.com/lestrrat-go/blackmagic/go.mod | 8 + .../github.com/lestrrat-go/blackmagic/go.sum | 13 + .../github.com/lestrrat-go/httpcc/.gitignore | 15 + vendor/github.com/lestrrat-go/httpcc/LICENSE | 21 + .../github.com/lestrrat-go/httpcc/README.md | 35 + .../lestrrat-go/httpcc/directives.go | 117 + vendor/github.com/lestrrat-go/httpcc/go.mod | 5 + vendor/github.com/lestrrat-go/httpcc/go.sum | 11 + .../github.com/lestrrat-go/httpcc/httpcc.go | 310 + vendor/github.com/lestrrat-go/iter/LICENSE | 21 + .../lestrrat-go/iter/arrayiter/arrayiter.go | 193 + .../lestrrat-go/iter/mapiter/mapiter.go | 196 + vendor/github.com/lestrrat-go/jwx/.gitignore | 35 + .../github.com/lestrrat-go/jwx/.golangci.yml | 92 + vendor/github.com/lestrrat-go/jwx/Changes | 723 + vendor/github.com/lestrrat-go/jwx/LICENSE | 22 + vendor/github.com/lestrrat-go/jwx/Makefile | 81 + vendor/github.com/lestrrat-go/jwx/README.md | 134 + vendor/github.com/lestrrat-go/jwx/format.go | 95 + .../lestrrat-go/jwx/formatkind_string_gen.go | 28 + vendor/github.com/lestrrat-go/jwx/gen.sh | 14 + vendor/github.com/lestrrat-go/jwx/go.mod | 18 + vendor/github.com/lestrrat-go/jwx/go.sum | 41 + .../lestrrat-go/jwx/internal/base64/base64.go | 66 + .../lestrrat-go/jwx/internal/ecutil/ecutil.go | 110 + .../lestrrat-go/jwx/internal/iter/mapiter.go | 36 + .../lestrrat-go/jwx/internal/json/goccy.go | 50 + .../lestrrat-go/jwx/internal/json/json.go | 105 + .../lestrrat-go/jwx/internal/json/registry.go | 53 + .../lestrrat-go/jwx/internal/json/stdlib.go | 49 + .../jwx/internal/keyconv/keyconv.go | 177 + .../lestrrat-go/jwx/internal/pool/pool.go | 61 + .../github.com/lestrrat-go/jwx/jwa/README.md | 3 + .../lestrrat-go/jwx/jwa/compression_gen.go | 73 + .../jwx/jwa/content_encryption_gen.go | 81 + .../lestrrat-go/jwx/jwa/elliptic_gen.go | 84 + vendor/github.com/lestrrat-go/jwx/jwa/gen.sh | 14 + vendor/github.com/lestrrat-go/jwx/jwa/jwa.go | 4 + .../lestrrat-go/jwx/jwa/key_encryption_gen.go | 112 + .../lestrrat-go/jwx/jwa/key_type_gen.go | 78 + .../lestrrat-go/jwx/jwa/secp2561k.go | 10 + .../lestrrat-go/jwx/jwa/signature_gen.go | 99 + .../github.com/lestrrat-go/jwx/jwe/README.md | 94 + .../lestrrat-go/jwx/jwe/compress.go | 41 + .../github.com/lestrrat-go/jwx/jwe/decrypt.go | 300 + .../github.com/lestrrat-go/jwx/jwe/encrypt.go | 145 + vendor/github.com/lestrrat-go/jwx/jwe/gen.sh | 14 + .../github.com/lestrrat-go/jwx/jwe/headers.go | 122 + .../lestrrat-go/jwx/jwe/headers_gen.go | 714 + .../lestrrat-go/jwx/jwe/interface.go | 101 + .../jwx/jwe/internal/aescbc/aescbc.go | 220 + .../jwx/jwe/internal/cipher/cipher.go | 162 + .../jwx/jwe/internal/cipher/interface.go | 34 + .../jwx/jwe/internal/concatkdf/concatkdf.go | 67 + .../internal/content_crypt/content_crypt.go | 42 + .../jwe/internal/content_crypt/interface.go | 20 + .../jwx/jwe/internal/keyenc/interface.go | 106 + .../jwx/jwe/internal/keyenc/keyenc.go | 661 + .../jwx/jwe/internal/keygen/interface.go | 73 + .../jwx/jwe/internal/keygen/keygen.go | 192 + vendor/github.com/lestrrat-go/jwx/jwe/io.go | 23 + vendor/github.com/lestrrat-go/jwx/jwe/jwe.go | 377 + .../github.com/lestrrat-go/jwx/jwe/message.go | 648 + .../github.com/lestrrat-go/jwx/jwe/options.go | 87 + .../lestrrat-go/jwx/jwe/serializer.go | 94 + .../github.com/lestrrat-go/jwx/jwk/README.md | 274 + .../lestrrat-go/jwx/jwk/certchain.go | 85 + .../github.com/lestrrat-go/jwx/jwk/ecdsa.go | 229 + .../lestrrat-go/jwx/jwk/ecdsa_gen.go | 1178 + .../github.com/lestrrat-go/jwx/jwk/es256k.go | 13 + vendor/github.com/lestrrat-go/jwx/jwk/gen.sh | 14 + .../lestrrat-go/jwx/jwk/interface.go | 160 + .../lestrrat-go/jwx/jwk/interface_gen.go | 111 + vendor/github.com/lestrrat-go/jwx/jwk/io.go | 29 + vendor/github.com/lestrrat-go/jwx/jwk/jwk.go | 719 + .../github.com/lestrrat-go/jwx/jwk/key_ops.go | 58 + vendor/github.com/lestrrat-go/jwx/jwk/okp.go | 184 + .../github.com/lestrrat-go/jwx/jwk/okp_gen.go | 1116 + .../github.com/lestrrat-go/jwx/jwk/option.go | 197 + .../github.com/lestrrat-go/jwx/jwk/refresh.go | 653 + vendor/github.com/lestrrat-go/jwx/jwk/rsa.go | 244 + .../github.com/lestrrat-go/jwx/jwk/rsa_gen.go | 1247 + vendor/github.com/lestrrat-go/jwx/jwk/set.go | 303 + .../lestrrat-go/jwx/jwk/symmetric.go | 61 + .../lestrrat-go/jwx/jwk/symmetric_gen.go | 519 + .../github.com/lestrrat-go/jwx/jwk/usage.go | 30 + .../lestrrat-go/jwx/jwk/whitelist.go | 69 + .../github.com/lestrrat-go/jwx/jws/README.md | 111 + .../github.com/lestrrat-go/jwx/jws/ecdsa.go | 194 + .../github.com/lestrrat-go/jwx/jws/eddsa.go | 73 + .../github.com/lestrrat-go/jwx/jws/es256k.go | 11 + vendor/github.com/lestrrat-go/jwx/jws/gen.sh | 14 + .../github.com/lestrrat-go/jwx/jws/headers.go | 71 + .../lestrrat-go/jwx/jws/headers_gen.go | 561 + vendor/github.com/lestrrat-go/jwx/jws/hmac.go | 77 + .../lestrrat-go/jwx/jws/interface.go | 106 + vendor/github.com/lestrrat-go/jwx/jws/io.go | 23 + vendor/github.com/lestrrat-go/jwx/jws/jws.go | 961 + .../github.com/lestrrat-go/jwx/jws/message.go | 448 + .../github.com/lestrrat-go/jwx/jws/option.go | 119 + vendor/github.com/lestrrat-go/jwx/jws/rsa.go | 142 + .../github.com/lestrrat-go/jwx/jws/signer.go | 68 + .../lestrrat-go/jwx/jws/verifier.go | 68 + .../github.com/lestrrat-go/jwx/jwt/README.md | 224 + .../lestrrat-go/jwx/jwt/builder_gen.go | 71 + vendor/github.com/lestrrat-go/jwx/jwt/gen.sh | 9 + vendor/github.com/lestrrat-go/jwx/jwt/http.go | 188 + .../lestrrat-go/jwx/jwt/interface.go | 14 + .../jwx/jwt/internal/types/date.go | 98 + .../jwx/jwt/internal/types/string.go | 43 + vendor/github.com/lestrrat-go/jwx/jwt/io.go | 29 + vendor/github.com/lestrrat-go/jwx/jwt/jwt.go | 561 + .../github.com/lestrrat-go/jwx/jwt/options.go | 538 + .../lestrrat-go/jwx/jwt/serialize.go | 239 + .../lestrrat-go/jwx/jwt/token_gen.go | 529 + .../lestrrat-go/jwx/jwt/validate.go | 385 + vendor/github.com/lestrrat-go/jwx/jwx.go | 43 + vendor/github.com/lestrrat-go/jwx/options.go | 30 + .../lestrrat-go/jwx/x25519/x25519.go | 116 + .../github.com/lestrrat-go/option/.gitignore | 15 + vendor/github.com/lestrrat-go/option/LICENSE | 21 + .../github.com/lestrrat-go/option/README.md | 136 + vendor/github.com/lestrrat-go/option/go.mod | 5 + vendor/github.com/lestrrat-go/option/go.sum | 11 + .../github.com/lestrrat-go/option/option.go | 32 + vendor/github.com/matryer/moq/.gitignore | 29 + vendor/github.com/matryer/moq/.goreleaser.yml | 34 + vendor/github.com/matryer/moq/LICENSE | 21 + vendor/github.com/matryer/moq/README.md | 135 + vendor/github.com/matryer/moq/go.mod | 8 + vendor/github.com/matryer/moq/go.sum | 24 + .../moq/internal/registry/method_scope.go | 135 + .../matryer/moq/internal/registry/package.go | 93 + .../matryer/moq/internal/registry/registry.go | 190 + .../matryer/moq/internal/registry/var.go | 146 + .../matryer/moq/internal/template/template.go | 190 + .../moq/internal/template/template_data.go | 125 + vendor/github.com/matryer/moq/main.go | 109 + .../github.com/matryer/moq/moq-logo-small.png | Bin 0 -> 32570 bytes vendor/github.com/matryer/moq/moq-logo.png | Bin 0 -> 29562 bytes .../matryer/moq/pkg/moq/formatter.go | 31 + vendor/github.com/matryer/moq/pkg/moq/moq.go | 171 + vendor/github.com/matryer/moq/preview.png | Bin 0 -> 743543 bytes vendor/github.com/matryer/moq/releasing.md | 36 + vendor/github.com/mattn/go-colorable/LICENSE | 21 + .../github.com/mattn/go-colorable/README.md | 48 + .../mattn/go-colorable/colorable_appengine.go | 38 + .../mattn/go-colorable/colorable_others.go | 38 + .../mattn/go-colorable/colorable_windows.go | 1047 + vendor/github.com/mattn/go-colorable/go.mod | 8 + vendor/github.com/mattn/go-colorable/go.sum | 5 + .../github.com/mattn/go-colorable/go.test.sh | 12 + .../mattn/go-colorable/noncolorable.go | 57 + vendor/github.com/mattn/go-isatty/LICENSE | 9 + vendor/github.com/mattn/go-isatty/README.md | 50 + vendor/github.com/mattn/go-isatty/doc.go | 2 + vendor/github.com/mattn/go-isatty/go.mod | 5 + vendor/github.com/mattn/go-isatty/go.sum | 2 + vendor/github.com/mattn/go-isatty/go.test.sh | 12 + .../github.com/mattn/go-isatty/isatty_bsd.go | 19 + .../mattn/go-isatty/isatty_others.go | 16 + .../mattn/go-isatty/isatty_plan9.go | 23 + .../mattn/go-isatty/isatty_solaris.go | 21 + .../mattn/go-isatty/isatty_tcgets.go | 19 + .../mattn/go-isatty/isatty_windows.go | 125 + .../mitchellh/mapstructure/CHANGELOG.md | 83 + .../github.com/mitchellh/mapstructure/LICENSE | 21 + .../mitchellh/mapstructure/README.md | 46 + .../mitchellh/mapstructure/decode_hooks.go | 257 + .../mitchellh/mapstructure/error.go | 50 + .../github.com/mitchellh/mapstructure/go.mod | 3 + .../mitchellh/mapstructure/mapstructure.go | 1467 + .../github.com/modern-go/concurrent/LICENSE | 201 + .../github.com/modern-go/concurrent/README.md | 2 + .../modern-go/concurrent/executor.go | 7 + .../modern-go/concurrent/go_above_19.go | 13 + .../modern-go/concurrent/go_below_19.go | 30 + .../concurrent/unbounded_executor.go | 99 + .../github.com/modern-go/reflect2/.gitignore | 2 + .../github.com/modern-go/reflect2/.travis.yml | 15 + .../github.com/modern-go/reflect2/Gopkg.lock | 9 + .../github.com/modern-go/reflect2/Gopkg.toml | 31 + vendor/github.com/modern-go/reflect2/LICENSE | 201 + .../github.com/modern-go/reflect2/README.md | 71 + vendor/github.com/modern-go/reflect2/go.mod | 3 + .../modern-go/reflect2/go_above_118.go | 23 + .../modern-go/reflect2/go_above_19.go | 17 + .../modern-go/reflect2/go_below_118.go | 21 + .../github.com/modern-go/reflect2/reflect2.go | 300 + .../modern-go/reflect2/reflect2_amd64.s | 0 .../modern-go/reflect2/reflect2_kind.go | 30 + .../modern-go/reflect2/relfect2_386.s | 0 .../modern-go/reflect2/relfect2_amd64p32.s | 0 .../modern-go/reflect2/relfect2_arm.s | 0 .../modern-go/reflect2/relfect2_arm64.s | 0 .../modern-go/reflect2/relfect2_mips64x.s | 0 .../modern-go/reflect2/relfect2_mipsx.s | 0 .../modern-go/reflect2/relfect2_ppc64x.s | 0 .../modern-go/reflect2/relfect2_s390x.s | 0 .../modern-go/reflect2/safe_field.go | 58 + .../github.com/modern-go/reflect2/safe_map.go | 101 + .../modern-go/reflect2/safe_slice.go | 92 + .../modern-go/reflect2/safe_struct.go | 29 + .../modern-go/reflect2/safe_type.go | 78 + .../github.com/modern-go/reflect2/type_map.go | 70 + .../modern-go/reflect2/unsafe_array.go | 65 + .../modern-go/reflect2/unsafe_eface.go | 59 + .../modern-go/reflect2/unsafe_field.go | 74 + .../modern-go/reflect2/unsafe_iface.go | 64 + .../modern-go/reflect2/unsafe_link.go | 76 + .../modern-go/reflect2/unsafe_map.go | 130 + .../modern-go/reflect2/unsafe_ptr.go | 46 + .../modern-go/reflect2/unsafe_slice.go | 177 + .../modern-go/reflect2/unsafe_struct.go | 59 + .../modern-go/reflect2/unsafe_type.go | 85 + .../pelletier/go-toml/v2/.dockerignore | 2 + .../pelletier/go-toml/v2/.gitattributes | 4 + .../pelletier/go-toml/v2/.gitignore | 6 + .../pelletier/go-toml/v2/.golangci.toml | 84 + .../pelletier/go-toml/v2/.goreleaser.yaml | 111 + .../pelletier/go-toml/v2/CONTRIBUTING.md | 196 + .../pelletier/go-toml/v2/Dockerfile | 5 + .../github.com/pelletier/go-toml/v2/LICENSE | 21 + .../github.com/pelletier/go-toml/v2/README.md | 552 + .../pelletier/go-toml/v2/SECURITY.md | 19 + vendor/github.com/pelletier/go-toml/v2/ci.sh | 279 + .../github.com/pelletier/go-toml/v2/decode.go | 544 + vendor/github.com/pelletier/go-toml/v2/doc.go | 2 + .../github.com/pelletier/go-toml/v2/errors.go | 269 + vendor/github.com/pelletier/go-toml/v2/go.mod | 5 + vendor/github.com/pelletier/go-toml/v2/go.sum | 11 + .../pelletier/go-toml/v2/internal/ast/ast.go | 144 + .../go-toml/v2/internal/ast/builder.go | 51 + .../pelletier/go-toml/v2/internal/ast/kind.go | 69 + .../go-toml/v2/internal/danger/danger.go | 65 + .../go-toml/v2/internal/danger/typeid.go | 23 + .../go-toml/v2/internal/tracker/key.go | 50 + .../go-toml/v2/internal/tracker/seen.go | 356 + .../go-toml/v2/internal/tracker/tracker.go | 1 + .../pelletier/go-toml/v2/localtime.go | 120 + .../pelletier/go-toml/v2/marshaler.go | 962 + .../github.com/pelletier/go-toml/v2/parser.go | 1086 + .../pelletier/go-toml/v2/scanner.go | 269 + .../github.com/pelletier/go-toml/v2/strict.go | 107 + .../github.com/pelletier/go-toml/v2/toml.abnf | 243 + .../github.com/pelletier/go-toml/v2/types.go | 14 + .../pelletier/go-toml/v2/unmarshaler.go | 1205 + .../github.com/pelletier/go-toml/v2/utf8.go | 240 + vendor/github.com/pkg/errors/.gitignore | 24 + vendor/github.com/pkg/errors/.travis.yml | 10 + vendor/github.com/pkg/errors/LICENSE | 23 + vendor/github.com/pkg/errors/Makefile | 44 + vendor/github.com/pkg/errors/README.md | 59 + vendor/github.com/pkg/errors/appveyor.yml | 32 + vendor/github.com/pkg/errors/errors.go | 288 + vendor/github.com/pkg/errors/go113.go | 38 + vendor/github.com/pkg/errors/stack.go | 177 + .../russross/blackfriday/v2/.gitignore | 8 + .../russross/blackfriday/v2/.travis.yml | 17 + .../russross/blackfriday/v2/LICENSE.txt | 29 + .../russross/blackfriday/v2/README.md | 335 + .../russross/blackfriday/v2/block.go | 1612 + .../github.com/russross/blackfriday/v2/doc.go | 46 + .../russross/blackfriday/v2/entities.go | 2236 + .../github.com/russross/blackfriday/v2/esc.go | 70 + .../github.com/russross/blackfriday/v2/go.mod | 1 + .../russross/blackfriday/v2/html.go | 952 + .../russross/blackfriday/v2/inline.go | 1228 + .../russross/blackfriday/v2/markdown.go | 950 + .../russross/blackfriday/v2/node.go | 360 + .../russross/blackfriday/v2/smartypants.go | 457 + vendor/github.com/soheilhy/cmux/.gitignore | 24 + vendor/github.com/soheilhy/cmux/.travis.yml | 29 + vendor/github.com/soheilhy/cmux/CONTRIBUTORS | 12 + vendor/github.com/soheilhy/cmux/LICENSE | 202 + vendor/github.com/soheilhy/cmux/README.md | 83 + vendor/github.com/soheilhy/cmux/buffer.go | 67 + vendor/github.com/soheilhy/cmux/cmux.go | 307 + vendor/github.com/soheilhy/cmux/doc.go | 18 + vendor/github.com/soheilhy/cmux/go.mod | 5 + vendor/github.com/soheilhy/cmux/go.sum | 12 + vendor/github.com/soheilhy/cmux/matchers.go | 267 + vendor/github.com/soheilhy/cmux/patricia.go | 179 + vendor/github.com/tidwall/gjson/LICENSE | 20 + vendor/github.com/tidwall/gjson/README.md | 497 + vendor/github.com/tidwall/gjson/SYNTAX.md | 342 + vendor/github.com/tidwall/gjson/gjson.go | 3359 + vendor/github.com/tidwall/gjson/go.mod | 8 + vendor/github.com/tidwall/gjson/go.sum | 4 + vendor/github.com/tidwall/gjson/logo.png | Bin 0 -> 15936 bytes vendor/github.com/tidwall/match/LICENSE | 20 + vendor/github.com/tidwall/match/README.md | 29 + vendor/github.com/tidwall/match/go.mod | 3 + vendor/github.com/tidwall/match/match.go | 237 + vendor/github.com/tidwall/pretty/LICENSE | 20 + vendor/github.com/tidwall/pretty/README.md | 122 + vendor/github.com/tidwall/pretty/go.mod | 3 + vendor/github.com/tidwall/pretty/pretty.go | 682 + .../ugorji/go/codec/0_importpath.go | 7 + vendor/github.com/ugorji/go/codec/LICENSE | 22 + vendor/github.com/ugorji/go/codec/README.md | 283 + vendor/github.com/ugorji/go/codec/binc.go | 1311 + vendor/github.com/ugorji/go/codec/build.sh | 368 + vendor/github.com/ugorji/go/codec/cbor.go | 952 + vendor/github.com/ugorji/go/codec/codecgen.go | 17 + vendor/github.com/ugorji/go/codec/decimal.go | 499 + vendor/github.com/ugorji/go/codec/decode.go | 2350 + vendor/github.com/ugorji/go/codec/doc.go | 228 + vendor/github.com/ugorji/go/codec/encode.go | 1479 + .../ugorji/go/codec/fast-path.generated.go | 6157 + .../ugorji/go/codec/fast-path.go.tmpl | 555 + .../ugorji/go/codec/fast-path.not.go | 41 + .../ugorji/go/codec/gen-dec-array.go.tmpl | 90 + .../ugorji/go/codec/gen-dec-map.go.tmpl | 58 + .../ugorji/go/codec/gen-enc-chan.go.tmpl | 27 + .../ugorji/go/codec/gen-helper.generated.go | 277 + .../ugorji/go/codec/gen-helper.go.tmpl | 249 + .../ugorji/go/codec/gen.generated.go | 192 + vendor/github.com/ugorji/go/codec/gen.go | 2801 + vendor/github.com/ugorji/go/codec/go.mod | 5 + .../go/codec/goversion_arrayof_gte_go15.go | 15 + .../go/codec/goversion_arrayof_lt_go15.go | 20 + .../go/codec/goversion_fmt_time_gte_go15.go | 13 + .../go/codec/goversion_fmt_time_lt_go15.go | 16 + .../go/codec/goversion_makemap_lt_go110.go | 13 + .../goversion_makemap_not_unsafe_gte_go110.go | 14 + .../goversion_makemap_unsafe_gte_go110.go | 25 + .../go/codec/goversion_maprange_gte_go112.go | 41 + .../go/codec/goversion_maprange_lt_go112.go | 45 + ...version_unexportedembeddedptr_gte_go110.go | 9 + ...oversion_unexportedembeddedptr_lt_go110.go | 9 + .../go/codec/goversion_unsupported_lt_go14.go | 22 + .../go/codec/goversion_vendor_eq_go15.go | 11 + .../go/codec/goversion_vendor_eq_go16.go | 11 + .../go/codec/goversion_vendor_gte_go17.go | 9 + .../go/codec/goversion_vendor_lt_go15.go | 9 + vendor/github.com/ugorji/go/codec/helper.go | 2987 + vendor/github.com/ugorji/go/codec/helper.s | 0 .../ugorji/go/codec/helper_internal.go | 147 + .../ugorji/go/codec/helper_not_unsafe.go | 670 + .../go/codec/helper_not_unsafe_not_gc.go | 19 + .../ugorji/go/codec/helper_unsafe.go | 1302 + .../go/codec/helper_unsafe_compiler_gc.go | 171 + .../go/codec/helper_unsafe_compiler_not_gc.go | 80 + vendor/github.com/ugorji/go/codec/json.go | 1457 + .../ugorji/go/codec/mammoth-test.go.tmpl | 235 + .../ugorji/go/codec/mammoth2-test.go.tmpl | 101 + vendor/github.com/ugorji/go/codec/msgpack.go | 1232 + vendor/github.com/ugorji/go/codec/reader.go | 818 + .../ugorji/go/codec/register_ext.go | 38 + vendor/github.com/ugorji/go/codec/rpc.go | 232 + vendor/github.com/ugorji/go/codec/simple.go | 750 + .../ugorji/go/codec/sort-slice.generated.go | 158 + .../ugorji/go/codec/sort-slice.go.tmpl | 66 + .../ugorji/go/codec/test-cbor-goldens.json | 639 + vendor/github.com/ugorji/go/codec/test.py | 138 + vendor/github.com/ugorji/go/codec/writer.go | 289 + vendor/github.com/urfave/cli/v2/.flake8 | 2 + vendor/github.com/urfave/cli/v2/.gitignore | 7 + .../urfave/cli/v2/CODE_OF_CONDUCT.md | 74 + vendor/github.com/urfave/cli/v2/LICENSE | 21 + vendor/github.com/urfave/cli/v2/README.md | 70 + vendor/github.com/urfave/cli/v2/app.go | 540 + vendor/github.com/urfave/cli/v2/args.go | 54 + vendor/github.com/urfave/cli/v2/category.go | 79 + vendor/github.com/urfave/cli/v2/cli.go | 23 + vendor/github.com/urfave/cli/v2/command.go | 300 + vendor/github.com/urfave/cli/v2/context.go | 273 + vendor/github.com/urfave/cli/v2/docs.go | 148 + vendor/github.com/urfave/cli/v2/errors.go | 141 + vendor/github.com/urfave/cli/v2/fish.go | 196 + vendor/github.com/urfave/cli/v2/flag.go | 388 + vendor/github.com/urfave/cli/v2/flag_bool.go | 106 + .../github.com/urfave/cli/v2/flag_duration.go | 105 + .../github.com/urfave/cli/v2/flag_float64.go | 106 + .../urfave/cli/v2/flag_float64_slice.go | 163 + .../github.com/urfave/cli/v2/flag_generic.go | 108 + vendor/github.com/urfave/cli/v2/flag_int.go | 106 + vendor/github.com/urfave/cli/v2/flag_int64.go | 105 + .../urfave/cli/v2/flag_int64_slice.go | 159 + .../urfave/cli/v2/flag_int_slice.go | 173 + vendor/github.com/urfave/cli/v2/flag_path.go | 95 + .../github.com/urfave/cli/v2/flag_string.go | 95 + .../urfave/cli/v2/flag_string_slice.go | 180 + .../urfave/cli/v2/flag_timestamp.go | 154 + vendor/github.com/urfave/cli/v2/flag_uint.go | 105 + .../github.com/urfave/cli/v2/flag_uint64.go | 105 + vendor/github.com/urfave/cli/v2/funcs.go | 44 + vendor/github.com/urfave/cli/v2/go.mod | 9 + vendor/github.com/urfave/cli/v2/go.sum | 14 + vendor/github.com/urfave/cli/v2/help.go | 386 + vendor/github.com/urfave/cli/v2/parse.go | 94 + vendor/github.com/urfave/cli/v2/sort.go | 29 + vendor/github.com/urfave/cli/v2/template.go | 120 + .../valyala/bytebufferpool/.travis.yml | 15 + .../github.com/valyala/bytebufferpool/LICENSE | 22 + .../valyala/bytebufferpool/README.md | 21 + .../valyala/bytebufferpool/bytebuffer.go | 111 + .../github.com/valyala/bytebufferpool/doc.go | 7 + .../github.com/valyala/bytebufferpool/pool.go | 151 + vendor/github.com/valyala/fasthttp/.gitignore | 8 + vendor/github.com/valyala/fasthttp/LICENSE | 9 + vendor/github.com/valyala/fasthttp/README.md | 638 + .../github.com/valyala/fasthttp/SECURITY.md | 115 + vendor/github.com/valyala/fasthttp/TODO | 4 + vendor/github.com/valyala/fasthttp/args.go | 644 + vendor/github.com/valyala/fasthttp/brotli.go | 193 + .../github.com/valyala/fasthttp/bytesconv.go | 381 + .../valyala/fasthttp/bytesconv_32.go | 8 + .../valyala/fasthttp/bytesconv_64.go | 8 + .../valyala/fasthttp/bytesconv_table.go | 10 + vendor/github.com/valyala/fasthttp/client.go | 2889 + .../github.com/valyala/fasthttp/coarseTime.go | 13 + .../github.com/valyala/fasthttp/compress.go | 447 + vendor/github.com/valyala/fasthttp/cookie.go | 556 + vendor/github.com/valyala/fasthttp/doc.go | 55 + .../fasthttp/fasthttpadaptor/adaptor.go | 113 + .../fasthttp/fasthttpadaptor/request.go | 72 + .../valyala/fasthttp/fasthttputil/doc.go | 2 + .../fasthttputil/inmemory_listener.go | 134 + .../fasthttp/fasthttputil/pipeconns.go | 346 + .../valyala/fasthttp/fasthttputil/rsa.key | 28 + .../valyala/fasthttp/fasthttputil/rsa.pem | 17 + vendor/github.com/valyala/fasthttp/fs.go | 1453 + vendor/github.com/valyala/fasthttp/go.mod | 13 + vendor/github.com/valyala/fasthttp/go.sum | 24 + vendor/github.com/valyala/fasthttp/header.go | 3390 + vendor/github.com/valyala/fasthttp/headers.go | 165 + vendor/github.com/valyala/fasthttp/http.go | 2301 + .../github.com/valyala/fasthttp/lbclient.go | 204 + vendor/github.com/valyala/fasthttp/methods.go | 14 + vendor/github.com/valyala/fasthttp/nocopy.go | 11 + .../github.com/valyala/fasthttp/peripconn.go | 102 + vendor/github.com/valyala/fasthttp/server.go | 2961 + .../valyala/fasthttp/stackless/doc.go | 3 + .../valyala/fasthttp/stackless/func.go | 79 + .../valyala/fasthttp/stackless/writer.go | 138 + vendor/github.com/valyala/fasthttp/status.go | 177 + vendor/github.com/valyala/fasthttp/stream.go | 54 + .../github.com/valyala/fasthttp/streaming.go | 109 + vendor/github.com/valyala/fasthttp/strings.go | 94 + vendor/github.com/valyala/fasthttp/tcp.go | 13 + .../valyala/fasthttp/tcp_windows.go | 13 + .../github.com/valyala/fasthttp/tcpdialer.go | 456 + vendor/github.com/valyala/fasthttp/timer.go | 54 + vendor/github.com/valyala/fasthttp/tls.go | 60 + vendor/github.com/valyala/fasthttp/uri.go | 910 + .../github.com/valyala/fasthttp/uri_unix.go | 13 + .../valyala/fasthttp/uri_windows.go | 13 + .../github.com/valyala/fasthttp/userdata.go | 104 + .../github.com/valyala/fasthttp/workerpool.go | 251 + .../github.com/valyala/fasttemplate/LICENSE | 22 + .../github.com/valyala/fasttemplate/README.md | 85 + vendor/github.com/valyala/fasttemplate/go.mod | 5 + vendor/github.com/valyala/fasttemplate/go.sum | 2 + .../valyala/fasttemplate/template.go | 437 + .../github.com/valyala/fasttemplate/unsafe.go | 21 + .../valyala/fasttemplate/unsafe_gae.go | 11 + .../github.com/vektah/gqlparser/v2/.gitignore | 5 + vendor/github.com/vektah/gqlparser/v2/LICENSE | 19 + .../vektah/gqlparser/v2/ast/argmap.go | 37 + .../vektah/gqlparser/v2/ast/collections.go | 148 + .../vektah/gqlparser/v2/ast/definition.go | 94 + .../vektah/gqlparser/v2/ast/directive.go | 43 + .../vektah/gqlparser/v2/ast/document.go | 67 + .../vektah/gqlparser/v2/ast/dumper.go | 159 + .../vektah/gqlparser/v2/ast/fragment.go | 38 + .../vektah/gqlparser/v2/ast/operation.go | 30 + .../vektah/gqlparser/v2/ast/path.go | 67 + .../vektah/gqlparser/v2/ast/selection.go | 39 + .../vektah/gqlparser/v2/ast/source.go | 19 + .../vektah/gqlparser/v2/ast/type.go | 68 + .../vektah/gqlparser/v2/ast/value.go | 120 + vendor/github.com/vektah/gqlparser/v2/go.mod | 12 + vendor/github.com/vektah/gqlparser/v2/go.sum | 30 + .../vektah/gqlparser/v2/gqlerror/error.go | 145 + .../vektah/gqlparser/v2/gqlparser.go | 42 + .../vektah/gqlparser/v2/lexer/blockstring.go | 58 + .../vektah/gqlparser/v2/lexer/lexer.go | 510 + .../vektah/gqlparser/v2/lexer/lexer_test.yml | 672 + .../vektah/gqlparser/v2/lexer/token.go | 148 + .../vektah/gqlparser/v2/parser/parser.go | 136 + .../vektah/gqlparser/v2/parser/query.go | 350 + .../vektah/gqlparser/v2/parser/query_test.yml | 544 + .../vektah/gqlparser/v2/parser/schema.go | 534 + .../gqlparser/v2/parser/schema_test.yml | 604 + .../github.com/vektah/gqlparser/v2/readme.md | 17 + .../vektah/gqlparser/v2/validator/error.go | 55 + .../gqlparser/v2/validator/messaging.go | 39 + .../vektah/gqlparser/v2/validator/prelude.go | 9 + .../gqlparser/v2/validator/prelude.graphql | 121 + .../validator/rules/fields_on_correct_type.go | 86 + .../rules/fragments_on_composite_types.go | 39 + .../validator/rules/known_argument_names.go | 57 + .../v2/validator/rules/known_directives.go | 31 + .../validator/rules/known_fragment_names.go | 19 + .../v2/validator/rules/known_type_names.go | 61 + .../rules/lone_anonymous_operation.go | 19 + .../v2/validator/rules/no_fragment_cycles.go | 93 + .../validator/rules/no_undefined_variables.go | 28 + .../v2/validator/rules/no_unused_fragments.go | 30 + .../v2/validator/rules/no_unused_variables.go | 30 + .../rules/overlapping_fields_can_be_merged.go | 557 + .../rules/possible_fragment_spreads.go | 68 + .../rules/provided_required_arguments.go | 63 + .../v2/validator/rules/scalar_leafs.go | 36 + .../rules/single_field_subscriptions.go | 30 + .../validator/rules/unique_argument_names.go | 33 + .../rules/unique_directives_per_location.go | 24 + .../validator/rules/unique_fragment_names.go | 22 + .../rules/unique_input_field_names.go | 27 + .../validator/rules/unique_operation_names.go | 22 + .../validator/rules/unique_variable_names.go | 23 + .../validator/rules/values_of_correct_type.go | 130 + .../rules/variables_are_input_types.go | 28 + .../rules/variables_in_allowed_position.go | 36 + .../vektah/gqlparser/v2/validator/schema.go | 428 + .../gqlparser/v2/validator/schema_test.yml | 617 + .../gqlparser/v2/validator/suggestionList.go | 69 + .../gqlparser/v2/validator/validator.go | 44 + .../vektah/gqlparser/v2/validator/vars.go | 218 + .../vektah/gqlparser/v2/validator/walk.go | 286 + vendor/github.com/wI2L/jsondiff/.codecov.yml | 8 + vendor/github.com/wI2L/jsondiff/.gitignore | 55 + .../github.com/wI2L/jsondiff/.golangci.yaml | 46 + .../github.com/wI2L/jsondiff/.goreleaser.yml | 11 + vendor/github.com/wI2L/jsondiff/CHANGELOG.md | 15 + vendor/github.com/wI2L/jsondiff/LICENSE | 21 + vendor/github.com/wI2L/jsondiff/README.md | 361 + vendor/github.com/wI2L/jsondiff/compare.go | 80 + vendor/github.com/wI2L/jsondiff/differ.go | 357 + vendor/github.com/wI2L/jsondiff/equal.go | 90 + vendor/github.com/wI2L/jsondiff/go.mod | 10 + vendor/github.com/wI2L/jsondiff/go.sum | 7 + vendor/github.com/wI2L/jsondiff/hash.go | 53 + vendor/github.com/wI2L/jsondiff/operation.go | 156 + vendor/github.com/wI2L/jsondiff/option.go | 31 + vendor/github.com/wI2L/jsondiff/pointer.go | 57 + vendor/github.com/xdg-go/pbkdf2/.gitignore | 12 + vendor/github.com/xdg-go/pbkdf2/LICENSE | 175 + vendor/github.com/xdg-go/pbkdf2/README.md | 17 + vendor/github.com/xdg-go/pbkdf2/go.mod | 3 + vendor/github.com/xdg-go/pbkdf2/pbkdf2.go | 76 + vendor/github.com/xdg-go/scram/.gitignore | 0 vendor/github.com/xdg-go/scram/CHANGELOG.md | 18 + vendor/github.com/xdg-go/scram/LICENSE | 175 + vendor/github.com/xdg-go/scram/README.md | 72 + vendor/github.com/xdg-go/scram/client.go | 130 + vendor/github.com/xdg-go/scram/client_conv.go | 149 + vendor/github.com/xdg-go/scram/common.go | 97 + vendor/github.com/xdg-go/scram/doc.go | 26 + vendor/github.com/xdg-go/scram/go.mod | 8 + vendor/github.com/xdg-go/scram/go.sum | 7 + vendor/github.com/xdg-go/scram/parse.go | 205 + vendor/github.com/xdg-go/scram/scram.go | 71 + vendor/github.com/xdg-go/scram/server.go | 50 + vendor/github.com/xdg-go/scram/server_conv.go | 151 + .../github.com/xdg-go/stringprep/.gitignore | 0 .../github.com/xdg-go/stringprep/CHANGELOG.md | 22 + vendor/github.com/xdg-go/stringprep/LICENSE | 175 + vendor/github.com/xdg-go/stringprep/README.md | 28 + vendor/github.com/xdg-go/stringprep/bidi.go | 73 + vendor/github.com/xdg-go/stringprep/doc.go | 10 + vendor/github.com/xdg-go/stringprep/error.go | 14 + vendor/github.com/xdg-go/stringprep/go.mod | 5 + vendor/github.com/xdg-go/stringprep/go.sum | 3 + vendor/github.com/xdg-go/stringprep/map.go | 21 + .../github.com/xdg-go/stringprep/profile.go | 75 + .../github.com/xdg-go/stringprep/saslprep.go | 52 + vendor/github.com/xdg-go/stringprep/set.go | 36 + vendor/github.com/xdg-go/stringprep/tables.go | 3215 + vendor/github.com/youmark/pkcs8/.gitignore | 23 + vendor/github.com/youmark/pkcs8/.travis.yml | 14 + vendor/github.com/youmark/pkcs8/LICENSE | 21 + vendor/github.com/youmark/pkcs8/README | 1 + vendor/github.com/youmark/pkcs8/README.md | 22 + vendor/github.com/youmark/pkcs8/cipher.go | 60 + .../github.com/youmark/pkcs8/cipher_3des.go | 24 + vendor/github.com/youmark/pkcs8/cipher_aes.go | 84 + vendor/github.com/youmark/pkcs8/go.mod | 5 + vendor/github.com/youmark/pkcs8/go.sum | 7 + vendor/github.com/youmark/pkcs8/kdf_pbkdf2.go | 91 + vendor/github.com/youmark/pkcs8/kdf_scrypt.go | 62 + vendor/github.com/youmark/pkcs8/pkcs8.go | 309 + vendor/go.keploy.io/server/LICENSE | 201 + vendor/go.keploy.io/server/graph/ext.graphqls | 2 + .../server/graph/ext.resolvers.go | 17 + .../server/graph/generated/generated.go | 8423 + .../server/graph/model/models_gen.go | 406 + vendor/go.keploy.io/server/graph/resolver.go | 29 + .../go.keploy.io/server/graph/schema.graphqls | 226 + .../server/graph/schema.resolvers.go | 176 + vendor/go.keploy.io/server/graph/tools.go | 6 + vendor/go.keploy.io/server/graph/utils.go | 314 + .../server/grpc/grpcserver/server.go | 416 + vendor/go.keploy.io/server/grpc/mock/mock.go | 407 + .../server/grpc/regression/services.pb.go | 3403 + .../server/grpc/regression/services.proto | 248 + .../grpc/regression/services_grpc.pb.go | 429 + .../go.keploy.io/server/grpc/utils/utils.go | 38 + .../server/http/browserMock/browser-mock.go | 58 + .../server/http/browserMock/request.go | 31 + .../server/http/regression/helpers.go | 30 + .../server/http/regression/regression.go | 301 + .../server/http/regression/request.go | 19 + vendor/go.keploy.io/server/pkg/match.go | 141 + vendor/go.keploy.io/server/pkg/models/app.go | 16 + .../server/pkg/models/body-segment.go | 33 + .../server/pkg/models/browser-mock.go | 26 + vendor/go.keploy.io/server/pkg/models/dep.go | 17 + .../go.keploy.io/server/pkg/models/event.go | 11 + vendor/go.keploy.io/server/pkg/models/http.go | 38 + .../server/pkg/models/logs-color.go | 33 + vendor/go.keploy.io/server/pkg/models/mock.go | 139 + vendor/go.keploy.io/server/pkg/models/tc.go | 103 + .../go.keploy.io/server/pkg/models/testrun.go | 130 + .../server/pkg/platform/fs/mock.go | 313 + .../server/pkg/platform/fs/tele.go | 79 + .../server/pkg/platform/fs/testReport.go | 100 + .../server/pkg/platform/mgo/browser-mockdb.go | 69 + .../server/pkg/platform/mgo/mongo.go | 17 + .../server/pkg/platform/mgo/rdb.go | 199 + .../server/pkg/platform/mgo/tdb.go | 278 + .../server/pkg/platform/mgo/teledb.go | 66 + .../server/pkg/platform/telemetry/service.go | 35 + .../pkg/platform/telemetry/telemetry.go | 204 + .../server/pkg/platform/telemetry/utils.go | 53 + .../pkg/service/browserMock/browser-mock.go | 32 + .../server/pkg/service/browserMock/service.go | 12 + .../server/pkg/service/mock/mock.go | 420 + .../server/pkg/service/mock/service.go | 20 + .../pkg/service/regression/regression.go | 939 + .../server/pkg/service/regression/service.go | 38 + .../server/pkg/service/testCase/service.go | 18 + .../server/pkg/service/testCase/testCase.go | 573 + vendor/go.keploy.io/server/pkg/utils.go | 426 + vendor/go.keploy.io/server/server/const.go | 5 + vendor/go.keploy.io/server/server/server.go | 219 + .../go.keploy.io/server/web/public/README.md | 1 + .../go.keploy.io/server/web/public/index.html | 108 + vendor/go.keploy.io/server/web/web.go | 16 + vendor/go.mongodb.org/mongo-driver/LICENSE | 201 + .../go.mongodb.org/mongo-driver/bson/bson.go | 50 + .../bson/bsoncodec/array_codec.go | 50 + .../mongo-driver/bson/bsoncodec/bsoncodec.go | 216 + .../bson/bsoncodec/byte_slice_codec.go | 111 + .../bson/bsoncodec/cond_addr_codec.go | 63 + .../bson/bsoncodec/default_value_decoders.go | 1717 + .../bson/bsoncodec/default_value_encoders.go | 766 + .../mongo-driver/bson/bsoncodec/doc.go | 84 + .../bson/bsoncodec/empty_interface_codec.go | 140 + .../mongo-driver/bson/bsoncodec/map_codec.go | 288 + .../mongo-driver/bson/bsoncodec/mode.go | 65 + .../bson/bsoncodec/pointer_codec.go | 109 + .../mongo-driver/bson/bsoncodec/proxy.go | 14 + .../mongo-driver/bson/bsoncodec/registry.go | 468 + .../bson/bsoncodec/slice_codec.go | 199 + .../bson/bsoncodec/string_codec.go | 119 + .../bson/bsoncodec/struct_codec.go | 664 + .../bson/bsoncodec/struct_tag_parser.go | 139 + .../mongo-driver/bson/bsoncodec/time_codec.go | 127 + .../mongo-driver/bson/bsoncodec/types.go | 57 + .../mongo-driver/bson/bsoncodec/uint_codec.go | 173 + .../bsonoptions/byte_slice_codec_options.go | 38 + .../empty_interface_codec_options.go | 38 + .../bson/bsonoptions/map_codec_options.go | 67 + .../bson/bsonoptions/slice_codec_options.go | 38 + .../bson/bsonoptions/string_codec_options.go | 41 + .../bson/bsonoptions/struct_codec_options.go | 87 + .../bson/bsonoptions/time_codec_options.go | 38 + .../bson/bsonoptions/uint_codec_options.go | 38 + .../mongo-driver/bson/bsonrw/copier.go | 445 + .../mongo-driver/bson/bsonrw/doc.go | 9 + .../bson/bsonrw/extjson_parser.go | 806 + .../bson/bsonrw/extjson_reader.go | 644 + .../bson/bsonrw/extjson_tables.go | 223 + .../bson/bsonrw/extjson_wrappers.go | 492 + .../bson/bsonrw/extjson_writer.go | 732 + .../mongo-driver/bson/bsonrw/json_scanner.go | 528 + .../mongo-driver/bson/bsonrw/mode.go | 108 + .../mongo-driver/bson/bsonrw/reader.go | 63 + .../mongo-driver/bson/bsonrw/value_reader.go | 867 + .../mongo-driver/bson/bsonrw/value_writer.go | 606 + .../mongo-driver/bson/bsonrw/writer.go | 78 + .../mongo-driver/bson/bsontype/bsontype.go | 97 + .../mongo-driver/bson/decoder.go | 118 + .../go.mongodb.org/mongo-driver/bson/doc.go | 138 + .../mongo-driver/bson/encoder.go | 99 + .../mongo-driver/bson/marshal.go | 245 + .../mongo-driver/bson/primitive/decimal.go | 424 + .../mongo-driver/bson/primitive/objectid.go | 204 + .../mongo-driver/bson/primitive/primitive.go | 217 + .../mongo-driver/bson/primitive_codecs.go | 92 + .../go.mongodb.org/mongo-driver/bson/raw.go | 85 + .../mongo-driver/bson/raw_element.go | 51 + .../mongo-driver/bson/raw_value.go | 309 + .../mongo-driver/bson/registry.go | 24 + .../go.mongodb.org/mongo-driver/bson/types.go | 36 + .../mongo-driver/bson/unmarshal.go | 101 + .../go.mongodb.org/mongo-driver/event/doc.go | 56 + .../mongo-driver/event/monitoring.go | 187 + .../internal/background_context.go | 34 + .../internal/cancellation_listener.go | 47 + .../mongo-driver/internal/const.go | 24 + .../mongo-driver/internal/error.go | 119 + .../internal/randutil/randutil.go | 54 + .../mongo-driver/internal/string_util.go | 45 + .../internal/uri_validation_errors.go | 22 + .../mongo-driver/mongo/address/addr.go | 49 + .../mongo-driver/mongo/batch_cursor.go | 42 + .../mongo-driver/mongo/bulk_write.go | 496 + .../mongo-driver/mongo/bulk_write_models.go | 305 + .../mongo-driver/mongo/change_stream.go | 626 + .../mongo/change_stream_deployment.go | 50 + .../mongo-driver/mongo/client.go | 1015 + .../mongo-driver/mongo/client_encryption.go | 141 + .../mongo-driver/mongo/collection.go | 1691 + .../mongo-driver/mongo/crypt_retrievers.go | 65 + .../mongo-driver/mongo/cursor.go | 280 + .../mongo-driver/mongo/database.go | 650 + .../mongo/description/description.go | 10 + .../mongo-driver/mongo/description/server.go | 485 + .../mongo/description/server_kind.go | 46 + .../mongo/description/server_selector.go | 336 + .../mongo/description/topology.go | 142 + .../mongo/description/topology_kind.go | 40 + .../mongo/description/topology_version.go | 66 + .../mongo/description/version_range.go | 42 + .../go.mongodb.org/mongo-driver/mongo/doc.go | 145 + .../mongo-driver/mongo/errors.go | 600 + .../mongo/index_options_builder.go | 176 + .../mongo-driver/mongo/index_view.go | 504 + .../mongo-driver/mongo/mongo.go | 413 + .../mongo-driver/mongo/mongocryptd.go | 156 + .../mongo/options/aggregateoptions.go | 152 + .../mongo/options/autoencryptionoptions.go | 148 + .../mongo/options/bulkwriteoptions.go | 60 + .../mongo/options/changestreamoptions.go | 132 + .../mongo/options/clientencryptionoptions.go | 138 + .../mongo/options/clientoptions.go | 1101 + .../mongo/options/collectionoptions.go | 88 + .../mongo/options/countoptions.go | 95 + .../mongo/options/createcollectionoptions.go | 283 + .../mongo/options/datakeyoptions.go | 82 + .../mongo-driver/mongo/options/dboptions.go | 88 + .../mongo/options/deleteoptions.go | 58 + .../mongo/options/distinctoptions.go | 57 + .../mongo/options/encryptoptions.go | 64 + .../mongo/options/estimatedcountoptions.go | 44 + .../mongo-driver/mongo/options/findoptions.go | 956 + .../mongo/options/gridfsoptions.go | 321 + .../mongo/options/indexoptions.go | 455 + .../mongo/options/insertoptions.go | 93 + .../mongo/options/listcollectionsoptions.go | 52 + .../mongo/options/listdatabasesoptions.go | 55 + .../mongo/options/mongooptions.go | 159 + .../mongo/options/replaceoptions.go | 87 + .../mongo/options/runcmdoptions.go | 42 + .../mongo/options/serverapioptions.go | 60 + .../mongo/options/sessionoptions.go | 122 + .../mongo/options/transactionoptions.go | 92 + .../mongo/options/updateoptions.go | 100 + .../mongo/readconcern/readconcern.go | 82 + .../mongo-driver/mongo/readpref/mode.go | 88 + .../mongo-driver/mongo/readpref/options.go | 71 + .../mongo-driver/mongo/readpref/readpref.go | 131 + .../mongo-driver/mongo/results.go | 264 + .../mongo-driver/mongo/session.go | 370 + .../mongo-driver/mongo/single_result.go | 95 + .../go.mongodb.org/mongo-driver/mongo/util.go | 7 + .../mongo/writeconcern/writeconcern.go | 216 + vendor/go.mongodb.org/mongo-driver/tag/tag.go | 79 + .../mongo-driver/version/version.go | 10 + .../mongo-driver/x/bsonx/array.go | 97 + .../mongo-driver/x/bsonx/bsoncore/array.go | 164 + .../x/bsonx/bsoncore/bson_arraybuilder.go | 201 + .../x/bsonx/bsoncore/bson_documentbuilder.go | 189 + .../mongo-driver/x/bsonx/bsoncore/bsoncore.go | 862 + .../mongo-driver/x/bsonx/bsoncore/document.go | 410 + .../x/bsonx/bsoncore/document_sequence.go | 183 + .../mongo-driver/x/bsonx/bsoncore/element.go | 152 + .../mongo-driver/x/bsonx/bsoncore/tables.go | 223 + .../mongo-driver/x/bsonx/bsoncore/value.go | 980 + .../mongo-driver/x/bsonx/constructor.go | 166 + .../mongo-driver/x/bsonx/document.go | 305 + .../mongo-driver/x/bsonx/element.go | 51 + .../mongo-driver/x/bsonx/mdocument.go | 231 + .../mongo-driver/x/bsonx/primitive_codecs.go | 637 + .../x/bsonx/reflectionfree_d_codec.go | 1025 + .../mongo-driver/x/bsonx/registry.go | 22 + .../mongo-driver/x/bsonx/value.go | 866 + .../mongo-driver/x/mongo/driver/DESIGN.md | 23 + .../mongo-driver/x/mongo/driver/auth/auth.go | 225 + .../x/mongo/driver/auth/aws_conv.go | 347 + .../x/mongo/driver/auth/conversation.go | 31 + .../mongo-driver/x/mongo/driver/auth/cred.go | 16 + .../x/mongo/driver/auth/default.go | 98 + .../mongo-driver/x/mongo/driver/auth/doc.go | 23 + .../x/mongo/driver/auth/gssapi.go | 58 + .../x/mongo/driver/auth/gssapi_not_enabled.go | 16 + .../mongo/driver/auth/gssapi_not_supported.go | 21 + .../driver/auth/internal/awsv4/credentials.go | 63 + .../x/mongo/driver/auth/internal/awsv4/doc.go | 15 + .../driver/auth/internal/awsv4/request.go | 80 + .../mongo/driver/auth/internal/awsv4/rest.go | 46 + .../mongo/driver/auth/internal/awsv4/rules.go | 98 + .../driver/auth/internal/awsv4/signer.go | 472 + .../mongo/driver/auth/internal/gssapi/gss.go | 166 + .../driver/auth/internal/gssapi/gss_wrapper.c | 248 + .../driver/auth/internal/gssapi/gss_wrapper.h | 66 + .../mongo/driver/auth/internal/gssapi/sspi.go | 352 + .../auth/internal/gssapi/sspi_wrapper.c | 243 + .../auth/internal/gssapi/sspi_wrapper.h | 58 + .../x/mongo/driver/auth/mongodbaws.go | 76 + .../x/mongo/driver/auth/mongodbcr.go | 110 + .../mongo-driver/x/mongo/driver/auth/plain.go | 55 + .../mongo-driver/x/mongo/driver/auth/sasl.go | 174 + .../mongo-driver/x/mongo/driver/auth/scram.go | 130 + .../mongo-driver/x/mongo/driver/auth/util.go | 30 + .../mongo-driver/x/mongo/driver/auth/x509.go | 85 + .../x/mongo/driver/batch_cursor.go | 437 + .../mongo-driver/x/mongo/driver/batches.go | 70 + .../x/mongo/driver/compression.go | 105 + .../x/mongo/driver/connstring/connstring.go | 1023 + .../mongo-driver/x/mongo/driver/crypt.go | 335 + .../mongo-driver/x/mongo/driver/dns/dns.go | 144 + .../mongo-driver/x/mongo/driver/driver.go | 243 + .../mongo-driver/x/mongo/driver/errors.go | 487 + .../mongo-driver/x/mongo/driver/legacy.go | 16 + .../driver/list_collections_batch_cursor.go | 129 + .../x/mongo/driver/mongocrypt/binary.go | 55 + .../x/mongo/driver/mongocrypt/errors.go | 43 + .../driver/mongocrypt/errors_not_enabled.go | 20 + .../x/mongo/driver/mongocrypt/mongocrypt.go | 246 + .../driver/mongocrypt/mongocrypt_context.go | 103 + .../mongocrypt_context_not_enabled.go | 56 + .../mongocrypt/mongocrypt_kms_context.go | 75 + .../mongocrypt_kms_context_not_enabled.go | 38 + .../mongocrypt/mongocrypt_not_enabled.go | 54 + .../options/mongocrypt_context_options.go | 65 + .../mongocrypt/options/mongocrypt_options.go | 34 + .../x/mongo/driver/mongocrypt/state.go | 43 + .../mongo-driver/x/mongo/driver/ocsp/cache.go | 121 + .../x/mongo/driver/ocsp/config.go | 60 + .../mongo-driver/x/mongo/driver/ocsp/ocsp.go | 353 + .../x/mongo/driver/ocsp/options.go | 13 + .../mongo-driver/x/mongo/driver/operation.go | 1563 + .../driver/operation/abort_transaction.go | 199 + .../x/mongo/driver/operation/aggregate.go | 393 + .../x/mongo/driver/operation/command.go | 207 + .../driver/operation/commit_transaction.go | 202 + .../x/mongo/driver/operation/count.go | 314 + .../x/mongo/driver/operation/create.go | 358 + .../x/mongo/driver/operation/createIndexes.go | 266 + .../x/mongo/driver/operation/delete.go | 271 + .../x/mongo/driver/operation/distinct.go | 284 + .../mongo/driver/operation/drop_collection.go | 208 + .../x/mongo/driver/operation/drop_database.go | 154 + .../x/mongo/driver/operation/drop_indexes.go | 231 + .../x/mongo/driver/operation/end_sessions.go | 161 + .../x/mongo/driver/operation/errors.go | 13 + .../x/mongo/driver/operation/find.go | 523 + .../mongo/driver/operation/find_and_modify.go | 438 + .../x/mongo/driver/operation/hello.go | 256 + .../x/mongo/driver/operation/insert.go | 264 + .../x/mongo/driver/operation/listDatabases.go | 313 + .../driver/operation/list_collections.go | 238 + .../x/mongo/driver/operation/list_indexes.go | 223 + .../x/mongo/driver/operation/update.go | 359 + .../x/mongo/driver/operation_exhaust.go | 38 + .../x/mongo/driver/operation_legacy.go | 719 + .../x/mongo/driver/serverapioptions.go | 36 + .../x/mongo/driver/session/client_session.go | 531 + .../x/mongo/driver/session/cluster_clock.go | 36 + .../x/mongo/driver/session/options.go | 62 + .../x/mongo/driver/session/server_session.go | 74 + .../x/mongo/driver/session/session_pool.go | 190 + .../x/mongo/driver/topology/DESIGN.md | 40 + .../driver/topology/cancellation_listener.go | 14 + .../x/mongo/driver/topology/connection.go | 846 + .../driver/topology/connection_legacy.go | 1 + .../driver/topology/connection_options.go | 221 + .../x/mongo/driver/topology/diff.go | 73 + .../x/mongo/driver/topology/errors.go | 92 + .../x/mongo/driver/topology/fsm.go | 393 + .../x/mongo/driver/topology/pool.go | 929 + .../topology/pool_generation_counter.go | 135 + .../x/mongo/driver/topology/rtt_monitor.go | 211 + .../x/mongo/driver/topology/server.go | 925 + .../x/mongo/driver/topology/server_options.go | 195 + .../driver/topology/tls_connection_source.go | 36 + .../x/mongo/driver/topology/topology.go | 786 + .../mongo/driver/topology/topology_options.go | 450 + .../mongo-driver/x/mongo/driver/uuid/uuid.go | 43 + .../x/mongo/driver/wiremessage/wiremessage.go | 578 + vendor/go.uber.org/atomic/.codecov.yml | 19 + vendor/go.uber.org/atomic/.gitignore | 15 + vendor/go.uber.org/atomic/CHANGELOG.md | 100 + vendor/go.uber.org/atomic/LICENSE.txt | 19 + vendor/go.uber.org/atomic/Makefile | 79 + vendor/go.uber.org/atomic/README.md | 63 + vendor/go.uber.org/atomic/bool.go | 81 + vendor/go.uber.org/atomic/bool_ext.go | 53 + vendor/go.uber.org/atomic/doc.go | 23 + vendor/go.uber.org/atomic/duration.go | 82 + vendor/go.uber.org/atomic/duration_ext.go | 40 + vendor/go.uber.org/atomic/error.go | 51 + vendor/go.uber.org/atomic/error_ext.go | 39 + vendor/go.uber.org/atomic/float64.go | 77 + vendor/go.uber.org/atomic/float64_ext.go | 69 + vendor/go.uber.org/atomic/gen.go | 27 + vendor/go.uber.org/atomic/go.mod | 8 + vendor/go.uber.org/atomic/go.sum | 8 + vendor/go.uber.org/atomic/int32.go | 102 + vendor/go.uber.org/atomic/int64.go | 102 + vendor/go.uber.org/atomic/nocmp.go | 35 + vendor/go.uber.org/atomic/string.go | 54 + vendor/go.uber.org/atomic/string_ext.go | 45 + vendor/go.uber.org/atomic/time.go | 55 + vendor/go.uber.org/atomic/time_ext.go | 36 + vendor/go.uber.org/atomic/uint32.go | 102 + vendor/go.uber.org/atomic/uint64.go | 102 + vendor/go.uber.org/atomic/uintptr.go | 102 + vendor/go.uber.org/atomic/unsafe_pointer.go | 58 + vendor/go.uber.org/atomic/value.go | 31 + vendor/go.uber.org/multierr/.codecov.yml | 15 + vendor/go.uber.org/multierr/.gitignore | 4 + vendor/go.uber.org/multierr/CHANGELOG.md | 66 + vendor/go.uber.org/multierr/LICENSE.txt | 19 + vendor/go.uber.org/multierr/Makefile | 38 + vendor/go.uber.org/multierr/README.md | 23 + vendor/go.uber.org/multierr/error.go | 639 + vendor/go.uber.org/multierr/glide.yaml | 8 + vendor/go.uber.org/multierr/go.mod | 9 + vendor/go.uber.org/multierr/go.sum | 16 + vendor/go.uber.org/zap/.codecov.yml | 17 + vendor/go.uber.org/zap/.gitignore | 32 + vendor/go.uber.org/zap/.readme.tmpl | 109 + vendor/go.uber.org/zap/CHANGELOG.md | 592 + vendor/go.uber.org/zap/CODE_OF_CONDUCT.md | 75 + vendor/go.uber.org/zap/CONTRIBUTING.md | 70 + vendor/go.uber.org/zap/FAQ.md | 164 + vendor/go.uber.org/zap/LICENSE.txt | 19 + vendor/go.uber.org/zap/Makefile | 73 + vendor/go.uber.org/zap/README.md | 133 + vendor/go.uber.org/zap/array.go | 320 + vendor/go.uber.org/zap/array_go118.go | 124 + vendor/go.uber.org/zap/buffer/buffer.go | 141 + vendor/go.uber.org/zap/buffer/pool.go | 49 + vendor/go.uber.org/zap/checklicense.sh | 17 + vendor/go.uber.org/zap/config.go | 264 + vendor/go.uber.org/zap/doc.go | 117 + vendor/go.uber.org/zap/encoder.go | 79 + vendor/go.uber.org/zap/error.go | 80 + vendor/go.uber.org/zap/field.go | 549 + vendor/go.uber.org/zap/flag.go | 39 + vendor/go.uber.org/zap/glide.yaml | 34 + vendor/go.uber.org/zap/global.go | 169 + vendor/go.uber.org/zap/go.mod | 18 + vendor/go.uber.org/zap/go.sum | 58 + vendor/go.uber.org/zap/http_handler.go | 133 + .../zap/internal/bufferpool/bufferpool.go | 31 + .../go.uber.org/zap/internal/color/color.go | 44 + vendor/go.uber.org/zap/internal/exit/exit.go | 66 + vendor/go.uber.org/zap/level.go | 149 + vendor/go.uber.org/zap/logger.go | 393 + vendor/go.uber.org/zap/options.go | 166 + vendor/go.uber.org/zap/sink.go | 161 + vendor/go.uber.org/zap/stacktrace.go | 176 + vendor/go.uber.org/zap/sugar.go | 393 + vendor/go.uber.org/zap/time.go | 27 + vendor/go.uber.org/zap/writer.go | 98 + .../zap/zapcore/buffered_write_syncer.go | 219 + vendor/go.uber.org/zap/zapcore/clock.go | 48 + .../zap/zapcore/console_encoder.go | 157 + vendor/go.uber.org/zap/zapcore/core.go | 113 + vendor/go.uber.org/zap/zapcore/doc.go | 24 + vendor/go.uber.org/zap/zapcore/encoder.go | 451 + vendor/go.uber.org/zap/zapcore/entry.go | 299 + vendor/go.uber.org/zap/zapcore/error.go | 132 + vendor/go.uber.org/zap/zapcore/field.go | 233 + vendor/go.uber.org/zap/zapcore/hook.go | 68 + .../go.uber.org/zap/zapcore/increase_level.go | 66 + .../go.uber.org/zap/zapcore/json_encoder.go | 562 + vendor/go.uber.org/zap/zapcore/level.go | 187 + .../go.uber.org/zap/zapcore/level_strings.go | 46 + vendor/go.uber.org/zap/zapcore/marshaler.go | 61 + .../go.uber.org/zap/zapcore/memory_encoder.go | 179 + .../zap/zapcore/reflected_encoder.go | 41 + vendor/go.uber.org/zap/zapcore/sampler.go | 221 + vendor/go.uber.org/zap/zapcore/tee.go | 81 + .../go.uber.org/zap/zapcore/write_syncer.go | 122 + vendor/golang.org/x/crypto/AUTHORS | 3 + vendor/golang.org/x/crypto/CONTRIBUTORS | 3 + vendor/golang.org/x/crypto/LICENSE | 27 + vendor/golang.org/x/crypto/PATENTS | 22 + vendor/golang.org/x/crypto/acme/acme.go | 818 + .../x/crypto/acme/autocert/autocert.go | 1198 + .../x/crypto/acme/autocert/cache.go | 136 + .../x/crypto/acme/autocert/listener.go | 155 + .../x/crypto/acme/autocert/renewal.go | 156 + vendor/golang.org/x/crypto/acme/http.go | 325 + vendor/golang.org/x/crypto/acme/jws.go | 257 + vendor/golang.org/x/crypto/acme/rfc8555.go | 477 + vendor/golang.org/x/crypto/acme/types.go | 614 + .../golang.org/x/crypto/acme/version_go112.go | 28 + .../x/crypto/curve25519/curve25519.go | 146 + .../x/crypto/curve25519/internal/field/README | 7 + .../x/crypto/curve25519/internal/field/fe.go | 416 + .../curve25519/internal/field/fe_amd64.go | 16 + .../curve25519/internal/field/fe_amd64.s | 379 + .../internal/field/fe_amd64_noasm.go | 12 + .../curve25519/internal/field/fe_arm64.go | 16 + .../curve25519/internal/field/fe_arm64.s | 43 + .../internal/field/fe_arm64_noasm.go | 12 + .../curve25519/internal/field/fe_generic.go | 264 + .../curve25519/internal/field/sync.checkpoint | 1 + .../crypto/curve25519/internal/field/sync.sh | 19 + vendor/golang.org/x/crypto/ed25519/ed25519.go | 71 + vendor/golang.org/x/crypto/ocsp/ocsp.go | 792 + vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go | 77 + vendor/golang.org/x/crypto/scrypt/scrypt.go | 212 + vendor/golang.org/x/crypto/sha3/doc.go | 62 + vendor/golang.org/x/crypto/sha3/hashes.go | 97 + .../x/crypto/sha3/hashes_generic.go | 28 + vendor/golang.org/x/crypto/sha3/keccakf.go | 413 + .../golang.org/x/crypto/sha3/keccakf_amd64.go | 14 + .../golang.org/x/crypto/sha3/keccakf_amd64.s | 391 + vendor/golang.org/x/crypto/sha3/register.go | 19 + vendor/golang.org/x/crypto/sha3/sha3.go | 193 + vendor/golang.org/x/crypto/sha3/sha3_s390x.go | 287 + vendor/golang.org/x/crypto/sha3/sha3_s390x.s | 34 + vendor/golang.org/x/crypto/sha3/shake.go | 173 + .../golang.org/x/crypto/sha3/shake_generic.go | 20 + vendor/golang.org/x/crypto/sha3/xor.go | 24 + .../golang.org/x/crypto/sha3/xor_generic.go | 28 + .../golang.org/x/crypto/sha3/xor_unaligned.go | 68 + vendor/golang.org/x/mod/LICENSE | 27 + vendor/golang.org/x/mod/PATENTS | 22 + .../x/mod/internal/lazyregexp/lazyre.go | 78 + vendor/golang.org/x/mod/module/module.go | 844 + vendor/golang.org/x/mod/module/pseudo.go | 250 + vendor/golang.org/x/mod/semver/semver.go | 411 + vendor/golang.org/x/net/LICENSE | 27 + vendor/golang.org/x/net/PATENTS | 22 + vendor/golang.org/x/net/http/httpguts/guts.go | 50 + .../golang.org/x/net/http/httpguts/httplex.go | 352 + vendor/golang.org/x/net/http2/.gitignore | 2 + vendor/golang.org/x/net/http2/Dockerfile | 51 + vendor/golang.org/x/net/http2/Makefile | 3 + vendor/golang.org/x/net/http2/ascii.go | 53 + vendor/golang.org/x/net/http2/ciphers.go | 641 + .../x/net/http2/client_conn_pool.go | 311 + vendor/golang.org/x/net/http2/databuffer.go | 146 + vendor/golang.org/x/net/http2/errors.go | 145 + vendor/golang.org/x/net/http2/flow.go | 52 + vendor/golang.org/x/net/http2/frame.go | 1649 + vendor/golang.org/x/net/http2/go111.go | 30 + vendor/golang.org/x/net/http2/go115.go | 27 + vendor/golang.org/x/net/http2/go118.go | 17 + vendor/golang.org/x/net/http2/gotrack.go | 170 + vendor/golang.org/x/net/http2/h2c/h2c.go | 225 + vendor/golang.org/x/net/http2/headermap.go | 87 + vendor/golang.org/x/net/http2/hpack/encode.go | 240 + vendor/golang.org/x/net/http2/hpack/hpack.go | 504 + .../golang.org/x/net/http2/hpack/huffman.go | 226 + vendor/golang.org/x/net/http2/hpack/tables.go | 479 + vendor/golang.org/x/net/http2/http2.go | 385 + vendor/golang.org/x/net/http2/not_go111.go | 21 + vendor/golang.org/x/net/http2/not_go115.go | 31 + vendor/golang.org/x/net/http2/not_go118.go | 17 + vendor/golang.org/x/net/http2/pipe.go | 179 + vendor/golang.org/x/net/http2/server.go | 3131 + vendor/golang.org/x/net/http2/transport.go | 3066 + vendor/golang.org/x/net/http2/write.go | 370 + vendor/golang.org/x/net/http2/writesched.go | 250 + .../x/net/http2/writesched_priority.go | 451 + .../x/net/http2/writesched_random.go | 77 + vendor/golang.org/x/net/idna/go118.go | 14 + vendor/golang.org/x/net/idna/idna10.0.0.go | 770 + vendor/golang.org/x/net/idna/idna9.0.0.go | 718 + vendor/golang.org/x/net/idna/pre_go118.go | 12 + vendor/golang.org/x/net/idna/punycode.go | 217 + vendor/golang.org/x/net/idna/tables10.0.0.go | 4560 + vendor/golang.org/x/net/idna/tables11.0.0.go | 4654 + vendor/golang.org/x/net/idna/tables12.0.0.go | 4734 + vendor/golang.org/x/net/idna/tables13.0.0.go | 4840 + vendor/golang.org/x/net/idna/tables9.0.0.go | 4487 + vendor/golang.org/x/net/idna/trie.go | 72 + vendor/golang.org/x/net/idna/trieval.go | 119 + .../x/net/internal/timeseries/timeseries.go | 525 + vendor/golang.org/x/net/trace/events.go | 532 + vendor/golang.org/x/net/trace/histogram.go | 365 + vendor/golang.org/x/net/trace/trace.go | 1130 + vendor/golang.org/x/sync/LICENSE | 27 + vendor/golang.org/x/sync/PATENTS | 22 + vendor/golang.org/x/sync/errgroup/errgroup.go | 132 + vendor/golang.org/x/sys/LICENSE | 27 + vendor/golang.org/x/sys/PATENTS | 22 + vendor/golang.org/x/sys/cpu/asm_aix_ppc64.s | 18 + vendor/golang.org/x/sys/cpu/byteorder.go | 66 + vendor/golang.org/x/sys/cpu/cpu.go | 287 + vendor/golang.org/x/sys/cpu/cpu_aix.go | 34 + vendor/golang.org/x/sys/cpu/cpu_arm.go | 73 + vendor/golang.org/x/sys/cpu/cpu_arm64.go | 172 + vendor/golang.org/x/sys/cpu/cpu_arm64.s | 32 + vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go | 12 + vendor/golang.org/x/sys/cpu/cpu_gc_s390x.go | 22 + vendor/golang.org/x/sys/cpu/cpu_gc_x86.go | 17 + .../golang.org/x/sys/cpu/cpu_gccgo_arm64.go | 12 + .../golang.org/x/sys/cpu/cpu_gccgo_s390x.go | 23 + vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.c | 38 + vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.go | 33 + vendor/golang.org/x/sys/cpu/cpu_linux.go | 16 + vendor/golang.org/x/sys/cpu/cpu_linux_arm.go | 39 + .../golang.org/x/sys/cpu/cpu_linux_arm64.go | 71 + .../golang.org/x/sys/cpu/cpu_linux_mips64x.go | 24 + .../golang.org/x/sys/cpu/cpu_linux_noinit.go | 10 + .../golang.org/x/sys/cpu/cpu_linux_ppc64x.go | 32 + .../golang.org/x/sys/cpu/cpu_linux_s390x.go | 40 + vendor/golang.org/x/sys/cpu/cpu_loong64.go | 13 + vendor/golang.org/x/sys/cpu/cpu_mips64x.go | 16 + vendor/golang.org/x/sys/cpu/cpu_mipsx.go | 12 + .../golang.org/x/sys/cpu/cpu_netbsd_arm64.go | 173 + vendor/golang.org/x/sys/cpu/cpu_other_arm.go | 10 + .../golang.org/x/sys/cpu/cpu_other_arm64.go | 10 + .../golang.org/x/sys/cpu/cpu_other_mips64x.go | 13 + .../golang.org/x/sys/cpu/cpu_other_riscv64.go | 12 + vendor/golang.org/x/sys/cpu/cpu_ppc64x.go | 17 + vendor/golang.org/x/sys/cpu/cpu_riscv64.go | 12 + vendor/golang.org/x/sys/cpu/cpu_s390x.go | 172 + vendor/golang.org/x/sys/cpu/cpu_s390x.s | 58 + vendor/golang.org/x/sys/cpu/cpu_wasm.go | 18 + vendor/golang.org/x/sys/cpu/cpu_x86.go | 145 + vendor/golang.org/x/sys/cpu/cpu_x86.s | 28 + vendor/golang.org/x/sys/cpu/cpu_zos.go | 10 + vendor/golang.org/x/sys/cpu/cpu_zos_s390x.go | 25 + vendor/golang.org/x/sys/cpu/hwcap_linux.go | 56 + .../golang.org/x/sys/cpu/syscall_aix_gccgo.go | 27 + .../x/sys/cpu/syscall_aix_ppc64_gc.go | 36 + vendor/golang.org/x/sys/execabs/execabs.go | 102 + .../golang.org/x/sys/execabs/execabs_go118.go | 12 + .../golang.org/x/sys/execabs/execabs_go119.go | 15 + .../sys/internal/unsafeheader/unsafeheader.go | 30 + vendor/golang.org/x/sys/unix/.gitignore | 2 + vendor/golang.org/x/sys/unix/README.md | 184 + .../golang.org/x/sys/unix/affinity_linux.go | 86 + vendor/golang.org/x/sys/unix/aliases.go | 15 + vendor/golang.org/x/sys/unix/asm_aix_ppc64.s | 18 + vendor/golang.org/x/sys/unix/asm_bsd_386.s | 29 + vendor/golang.org/x/sys/unix/asm_bsd_amd64.s | 29 + vendor/golang.org/x/sys/unix/asm_bsd_arm.s | 29 + vendor/golang.org/x/sys/unix/asm_bsd_arm64.s | 29 + .../golang.org/x/sys/unix/asm_bsd_riscv64.s | 29 + vendor/golang.org/x/sys/unix/asm_linux_386.s | 66 + .../golang.org/x/sys/unix/asm_linux_amd64.s | 58 + vendor/golang.org/x/sys/unix/asm_linux_arm.s | 57 + .../golang.org/x/sys/unix/asm_linux_arm64.s | 53 + .../golang.org/x/sys/unix/asm_linux_loong64.s | 54 + .../golang.org/x/sys/unix/asm_linux_mips64x.s | 57 + .../golang.org/x/sys/unix/asm_linux_mipsx.s | 55 + .../golang.org/x/sys/unix/asm_linux_ppc64x.s | 45 + .../golang.org/x/sys/unix/asm_linux_riscv64.s | 49 + .../golang.org/x/sys/unix/asm_linux_s390x.s | 57 + .../x/sys/unix/asm_openbsd_mips64.s | 30 + .../golang.org/x/sys/unix/asm_solaris_amd64.s | 18 + vendor/golang.org/x/sys/unix/asm_zos_s390x.s | 426 + .../golang.org/x/sys/unix/bluetooth_linux.go | 36 + vendor/golang.org/x/sys/unix/cap_freebsd.go | 196 + vendor/golang.org/x/sys/unix/constants.go | 14 + vendor/golang.org/x/sys/unix/dev_aix_ppc.go | 27 + vendor/golang.org/x/sys/unix/dev_aix_ppc64.go | 29 + vendor/golang.org/x/sys/unix/dev_darwin.go | 24 + vendor/golang.org/x/sys/unix/dev_dragonfly.go | 30 + vendor/golang.org/x/sys/unix/dev_freebsd.go | 30 + vendor/golang.org/x/sys/unix/dev_linux.go | 42 + vendor/golang.org/x/sys/unix/dev_netbsd.go | 29 + vendor/golang.org/x/sys/unix/dev_openbsd.go | 29 + vendor/golang.org/x/sys/unix/dev_zos.go | 29 + vendor/golang.org/x/sys/unix/dirent.go | 103 + vendor/golang.org/x/sys/unix/endian_big.go | 10 + vendor/golang.org/x/sys/unix/endian_little.go | 10 + vendor/golang.org/x/sys/unix/env_unix.go | 32 + vendor/golang.org/x/sys/unix/epoll_zos.go | 221 + vendor/golang.org/x/sys/unix/fcntl.go | 37 + vendor/golang.org/x/sys/unix/fcntl_darwin.go | 24 + .../x/sys/unix/fcntl_linux_32bit.go | 14 + vendor/golang.org/x/sys/unix/fdset.go | 30 + vendor/golang.org/x/sys/unix/fstatfs_zos.go | 164 + vendor/golang.org/x/sys/unix/gccgo.go | 60 + vendor/golang.org/x/sys/unix/gccgo_c.c | 45 + .../x/sys/unix/gccgo_linux_amd64.go | 21 + vendor/golang.org/x/sys/unix/ifreq_linux.go | 142 + vendor/golang.org/x/sys/unix/ioctl.go | 75 + vendor/golang.org/x/sys/unix/ioctl_linux.go | 219 + vendor/golang.org/x/sys/unix/ioctl_zos.go | 74 + vendor/golang.org/x/sys/unix/mkall.sh | 236 + vendor/golang.org/x/sys/unix/mkerrors.sh | 778 + vendor/golang.org/x/sys/unix/pagesize_unix.go | 16 + .../golang.org/x/sys/unix/pledge_openbsd.go | 163 + vendor/golang.org/x/sys/unix/ptrace_darwin.go | 12 + vendor/golang.org/x/sys/unix/ptrace_ios.go | 12 + vendor/golang.org/x/sys/unix/race.go | 31 + vendor/golang.org/x/sys/unix/race0.go | 26 + .../x/sys/unix/readdirent_getdents.go | 13 + .../x/sys/unix/readdirent_getdirentries.go | 20 + .../x/sys/unix/sockcmsg_dragonfly.go | 16 + .../golang.org/x/sys/unix/sockcmsg_linux.go | 85 + vendor/golang.org/x/sys/unix/sockcmsg_unix.go | 93 + .../x/sys/unix/sockcmsg_unix_other.go | 47 + vendor/golang.org/x/sys/unix/str.go | 27 + vendor/golang.org/x/sys/unix/syscall.go | 95 + vendor/golang.org/x/sys/unix/syscall_aix.go | 600 + .../golang.org/x/sys/unix/syscall_aix_ppc.go | 54 + .../x/sys/unix/syscall_aix_ppc64.go | 85 + vendor/golang.org/x/sys/unix/syscall_bsd.go | 625 + .../x/sys/unix/syscall_darwin.1_12.go | 32 + .../x/sys/unix/syscall_darwin.1_13.go | 108 + .../golang.org/x/sys/unix/syscall_darwin.go | 740 + .../x/sys/unix/syscall_darwin_amd64.go | 51 + .../x/sys/unix/syscall_darwin_arm64.go | 51 + .../x/sys/unix/syscall_darwin_libSystem.go | 27 + .../x/sys/unix/syscall_dragonfly.go | 544 + .../x/sys/unix/syscall_dragonfly_amd64.go | 57 + .../golang.org/x/sys/unix/syscall_freebsd.go | 614 + .../x/sys/unix/syscall_freebsd_386.go | 67 + .../x/sys/unix/syscall_freebsd_amd64.go | 67 + .../x/sys/unix/syscall_freebsd_arm.go | 63 + .../x/sys/unix/syscall_freebsd_arm64.go | 63 + .../x/sys/unix/syscall_freebsd_riscv64.go | 63 + .../golang.org/x/sys/unix/syscall_illumos.go | 185 + vendor/golang.org/x/sys/unix/syscall_linux.go | 2455 + .../x/sys/unix/syscall_linux_386.go | 346 + .../x/sys/unix/syscall_linux_alarm.go | 14 + .../x/sys/unix/syscall_linux_amd64.go | 151 + .../x/sys/unix/syscall_linux_amd64_gc.go | 13 + .../x/sys/unix/syscall_linux_arm.go | 248 + .../x/sys/unix/syscall_linux_arm64.go | 199 + .../golang.org/x/sys/unix/syscall_linux_gc.go | 15 + .../x/sys/unix/syscall_linux_gc_386.go | 17 + .../x/sys/unix/syscall_linux_gc_arm.go | 14 + .../x/sys/unix/syscall_linux_gccgo_386.go | 31 + .../x/sys/unix/syscall_linux_gccgo_arm.go | 21 + .../x/sys/unix/syscall_linux_loong64.go | 226 + .../x/sys/unix/syscall_linux_mips64x.go | 195 + .../x/sys/unix/syscall_linux_mipsx.go | 207 + .../x/sys/unix/syscall_linux_ppc.go | 236 + .../x/sys/unix/syscall_linux_ppc64x.go | 122 + .../x/sys/unix/syscall_linux_riscv64.go | 184 + .../x/sys/unix/syscall_linux_s390x.go | 302 + .../x/sys/unix/syscall_linux_sparc64.go | 118 + .../golang.org/x/sys/unix/syscall_netbsd.go | 609 + .../x/sys/unix/syscall_netbsd_386.go | 38 + .../x/sys/unix/syscall_netbsd_amd64.go | 38 + .../x/sys/unix/syscall_netbsd_arm.go | 38 + .../x/sys/unix/syscall_netbsd_arm64.go | 38 + .../golang.org/x/sys/unix/syscall_openbsd.go | 389 + .../x/sys/unix/syscall_openbsd_386.go | 42 + .../x/sys/unix/syscall_openbsd_amd64.go | 42 + .../x/sys/unix/syscall_openbsd_arm.go | 42 + .../x/sys/unix/syscall_openbsd_arm64.go | 42 + .../x/sys/unix/syscall_openbsd_mips64.go | 39 + .../golang.org/x/sys/unix/syscall_solaris.go | 1005 + .../x/sys/unix/syscall_solaris_amd64.go | 28 + vendor/golang.org/x/sys/unix/syscall_unix.go | 556 + .../golang.org/x/sys/unix/syscall_unix_gc.go | 18 + .../x/sys/unix/syscall_unix_gc_ppc64x.go | 25 + .../x/sys/unix/syscall_zos_s390x.go | 1823 + vendor/golang.org/x/sys/unix/sysvshm_linux.go | 21 + vendor/golang.org/x/sys/unix/sysvshm_unix.go | 61 + .../x/sys/unix/sysvshm_unix_other.go | 14 + vendor/golang.org/x/sys/unix/timestruct.go | 77 + .../golang.org/x/sys/unix/unveil_openbsd.go | 42 + vendor/golang.org/x/sys/unix/xattr_bsd.go | 241 + .../golang.org/x/sys/unix/zerrors_aix_ppc.go | 1385 + .../x/sys/unix/zerrors_aix_ppc64.go | 1386 + .../x/sys/unix/zerrors_darwin_amd64.go | 1892 + .../x/sys/unix/zerrors_darwin_arm64.go | 1892 + .../x/sys/unix/zerrors_dragonfly_amd64.go | 1738 + .../x/sys/unix/zerrors_freebsd_386.go | 2043 + .../x/sys/unix/zerrors_freebsd_amd64.go | 2040 + .../x/sys/unix/zerrors_freebsd_arm.go | 2034 + .../x/sys/unix/zerrors_freebsd_arm64.go | 2034 + .../x/sys/unix/zerrors_freebsd_riscv64.go | 2148 + vendor/golang.org/x/sys/unix/zerrors_linux.go | 3457 + .../x/sys/unix/zerrors_linux_386.go | 828 + .../x/sys/unix/zerrors_linux_amd64.go | 828 + .../x/sys/unix/zerrors_linux_arm.go | 834 + .../x/sys/unix/zerrors_linux_arm64.go | 826 + .../x/sys/unix/zerrors_linux_loong64.go | 818 + .../x/sys/unix/zerrors_linux_mips.go | 835 + .../x/sys/unix/zerrors_linux_mips64.go | 835 + .../x/sys/unix/zerrors_linux_mips64le.go | 835 + .../x/sys/unix/zerrors_linux_mipsle.go | 835 + .../x/sys/unix/zerrors_linux_ppc.go | 887 + .../x/sys/unix/zerrors_linux_ppc64.go | 891 + .../x/sys/unix/zerrors_linux_ppc64le.go | 891 + .../x/sys/unix/zerrors_linux_riscv64.go | 815 + .../x/sys/unix/zerrors_linux_s390x.go | 890 + .../x/sys/unix/zerrors_linux_sparc64.go | 885 + .../x/sys/unix/zerrors_netbsd_386.go | 1780 + .../x/sys/unix/zerrors_netbsd_amd64.go | 1770 + .../x/sys/unix/zerrors_netbsd_arm.go | 1759 + .../x/sys/unix/zerrors_netbsd_arm64.go | 1770 + .../x/sys/unix/zerrors_openbsd_386.go | 1668 + .../x/sys/unix/zerrors_openbsd_amd64.go | 1775 + .../x/sys/unix/zerrors_openbsd_arm.go | 1670 + .../x/sys/unix/zerrors_openbsd_arm64.go | 1798 + .../x/sys/unix/zerrors_openbsd_mips64.go | 1863 + .../x/sys/unix/zerrors_solaris_amd64.go | 1557 + .../x/sys/unix/zerrors_zos_s390x.go | 860 + .../x/sys/unix/zptrace_armnn_linux.go | 42 + .../x/sys/unix/zptrace_linux_arm64.go | 17 + .../x/sys/unix/zptrace_mipsnn_linux.go | 51 + .../x/sys/unix/zptrace_mipsnnle_linux.go | 51 + .../x/sys/unix/zptrace_x86_linux.go | 81 + .../golang.org/x/sys/unix/zsyscall_aix_ppc.go | 1485 + .../x/sys/unix/zsyscall_aix_ppc64.go | 1443 + .../x/sys/unix/zsyscall_aix_ppc64_gc.go | 1192 + .../x/sys/unix/zsyscall_aix_ppc64_gccgo.go | 1070 + .../x/sys/unix/zsyscall_darwin_amd64.1_13.go | 40 + .../x/sys/unix/zsyscall_darwin_amd64.1_13.s | 25 + .../x/sys/unix/zsyscall_darwin_amd64.go | 2519 + .../x/sys/unix/zsyscall_darwin_amd64.s | 889 + .../x/sys/unix/zsyscall_darwin_arm64.1_13.go | 40 + .../x/sys/unix/zsyscall_darwin_arm64.1_13.s | 25 + .../x/sys/unix/zsyscall_darwin_arm64.go | 2519 + .../x/sys/unix/zsyscall_darwin_arm64.s | 889 + .../x/sys/unix/zsyscall_dragonfly_amd64.go | 1679 + .../x/sys/unix/zsyscall_freebsd_386.go | 1889 + .../x/sys/unix/zsyscall_freebsd_amd64.go | 1889 + .../x/sys/unix/zsyscall_freebsd_arm.go | 1889 + .../x/sys/unix/zsyscall_freebsd_arm64.go | 1889 + .../x/sys/unix/zsyscall_freebsd_riscv64.go | 1889 + .../x/sys/unix/zsyscall_illumos_amd64.go | 128 + .../golang.org/x/sys/unix/zsyscall_linux.go | 2153 + .../x/sys/unix/zsyscall_linux_386.go | 537 + .../x/sys/unix/zsyscall_linux_amd64.go | 704 + .../x/sys/unix/zsyscall_linux_arm.go | 652 + .../x/sys/unix/zsyscall_linux_arm64.go | 603 + .../x/sys/unix/zsyscall_linux_loong64.go | 527 + .../x/sys/unix/zsyscall_linux_mips.go | 704 + .../x/sys/unix/zsyscall_linux_mips64.go | 698 + .../x/sys/unix/zsyscall_linux_mips64le.go | 687 + .../x/sys/unix/zsyscall_linux_mipsle.go | 704 + .../x/sys/unix/zsyscall_linux_ppc.go | 709 + .../x/sys/unix/zsyscall_linux_ppc64.go | 755 + .../x/sys/unix/zsyscall_linux_ppc64le.go | 755 + .../x/sys/unix/zsyscall_linux_riscv64.go | 583 + .../x/sys/unix/zsyscall_linux_s390x.go | 546 + .../x/sys/unix/zsyscall_linux_sparc64.go | 699 + .../x/sys/unix/zsyscall_netbsd_386.go | 1850 + .../x/sys/unix/zsyscall_netbsd_amd64.go | 1850 + .../x/sys/unix/zsyscall_netbsd_arm.go | 1850 + .../x/sys/unix/zsyscall_netbsd_arm64.go | 1850 + .../x/sys/unix/zsyscall_openbsd_386.go | 1693 + .../x/sys/unix/zsyscall_openbsd_amd64.go | 1693 + .../x/sys/unix/zsyscall_openbsd_arm.go | 1693 + .../x/sys/unix/zsyscall_openbsd_arm64.go | 1693 + .../x/sys/unix/zsyscall_openbsd_mips64.go | 1693 + .../x/sys/unix/zsyscall_solaris_amd64.go | 2067 + .../x/sys/unix/zsyscall_zos_s390x.go | 1255 + .../x/sys/unix/zsysctl_openbsd_386.go | 274 + .../x/sys/unix/zsysctl_openbsd_amd64.go | 272 + .../x/sys/unix/zsysctl_openbsd_arm.go | 274 + .../x/sys/unix/zsysctl_openbsd_arm64.go | 276 + .../x/sys/unix/zsysctl_openbsd_mips64.go | 280 + .../x/sys/unix/zsysnum_darwin_amd64.go | 440 + .../x/sys/unix/zsysnum_darwin_arm64.go | 438 + .../x/sys/unix/zsysnum_dragonfly_amd64.go | 317 + .../x/sys/unix/zsysnum_freebsd_386.go | 394 + .../x/sys/unix/zsysnum_freebsd_amd64.go | 394 + .../x/sys/unix/zsysnum_freebsd_arm.go | 394 + .../x/sys/unix/zsysnum_freebsd_arm64.go | 394 + .../x/sys/unix/zsysnum_freebsd_riscv64.go | 394 + .../x/sys/unix/zsysnum_linux_386.go | 450 + .../x/sys/unix/zsysnum_linux_amd64.go | 372 + .../x/sys/unix/zsysnum_linux_arm.go | 414 + .../x/sys/unix/zsysnum_linux_arm64.go | 317 + .../x/sys/unix/zsysnum_linux_loong64.go | 311 + .../x/sys/unix/zsysnum_linux_mips.go | 434 + .../x/sys/unix/zsysnum_linux_mips64.go | 364 + .../x/sys/unix/zsysnum_linux_mips64le.go | 364 + .../x/sys/unix/zsysnum_linux_mipsle.go | 434 + .../x/sys/unix/zsysnum_linux_ppc.go | 441 + .../x/sys/unix/zsysnum_linux_ppc64.go | 413 + .../x/sys/unix/zsysnum_linux_ppc64le.go | 413 + .../x/sys/unix/zsysnum_linux_riscv64.go | 316 + .../x/sys/unix/zsysnum_linux_s390x.go | 378 + .../x/sys/unix/zsysnum_linux_sparc64.go | 392 + .../x/sys/unix/zsysnum_netbsd_386.go | 275 + .../x/sys/unix/zsysnum_netbsd_amd64.go | 275 + .../x/sys/unix/zsysnum_netbsd_arm.go | 275 + .../x/sys/unix/zsysnum_netbsd_arm64.go | 275 + .../x/sys/unix/zsysnum_openbsd_386.go | 219 + .../x/sys/unix/zsysnum_openbsd_amd64.go | 219 + .../x/sys/unix/zsysnum_openbsd_arm.go | 219 + .../x/sys/unix/zsysnum_openbsd_arm64.go | 218 + .../x/sys/unix/zsysnum_openbsd_mips64.go | 221 + .../x/sys/unix/zsysnum_zos_s390x.go | 2670 + .../golang.org/x/sys/unix/ztypes_aix_ppc.go | 354 + .../golang.org/x/sys/unix/ztypes_aix_ppc64.go | 358 + .../x/sys/unix/ztypes_darwin_amd64.go | 795 + .../x/sys/unix/ztypes_darwin_arm64.go | 795 + .../x/sys/unix/ztypes_dragonfly_amd64.go | 474 + .../x/sys/unix/ztypes_freebsd_386.go | 640 + .../x/sys/unix/ztypes_freebsd_amd64.go | 644 + .../x/sys/unix/ztypes_freebsd_arm.go | 630 + .../x/sys/unix/ztypes_freebsd_arm64.go | 624 + .../x/sys/unix/ztypes_freebsd_riscv64.go | 626 + .../x/sys/unix/ztypes_illumos_amd64.go | 42 + vendor/golang.org/x/sys/unix/ztypes_linux.go | 5601 + .../golang.org/x/sys/unix/ztypes_linux_386.go | 690 + .../x/sys/unix/ztypes_linux_amd64.go | 705 + .../golang.org/x/sys/unix/ztypes_linux_arm.go | 685 + .../x/sys/unix/ztypes_linux_arm64.go | 684 + .../x/sys/unix/ztypes_linux_loong64.go | 685 + .../x/sys/unix/ztypes_linux_mips.go | 690 + .../x/sys/unix/ztypes_linux_mips64.go | 687 + .../x/sys/unix/ztypes_linux_mips64le.go | 687 + .../x/sys/unix/ztypes_linux_mipsle.go | 690 + .../golang.org/x/sys/unix/ztypes_linux_ppc.go | 698 + .../x/sys/unix/ztypes_linux_ppc64.go | 693 + .../x/sys/unix/ztypes_linux_ppc64le.go | 693 + .../x/sys/unix/ztypes_linux_riscv64.go | 712 + .../x/sys/unix/ztypes_linux_s390x.go | 707 + .../x/sys/unix/ztypes_linux_sparc64.go | 688 + .../x/sys/unix/ztypes_netbsd_386.go | 502 + .../x/sys/unix/ztypes_netbsd_amd64.go | 510 + .../x/sys/unix/ztypes_netbsd_arm.go | 507 + .../x/sys/unix/ztypes_netbsd_arm64.go | 510 + .../x/sys/unix/ztypes_openbsd_386.go | 574 + .../x/sys/unix/ztypes_openbsd_amd64.go | 574 + .../x/sys/unix/ztypes_openbsd_arm.go | 575 + .../x/sys/unix/ztypes_openbsd_arm64.go | 568 + .../x/sys/unix/ztypes_openbsd_mips64.go | 568 + .../x/sys/unix/ztypes_solaris_amd64.go | 482 + .../golang.org/x/sys/unix/ztypes_zos_s390x.go | 406 + vendor/golang.org/x/text/AUTHORS | 3 + vendor/golang.org/x/text/CONTRIBUTORS | 3 + vendor/golang.org/x/text/LICENSE | 27 + vendor/golang.org/x/text/PATENTS | 22 + .../x/text/feature/plural/common.go | 70 + .../x/text/feature/plural/message.go | 244 + .../x/text/feature/plural/plural.go | 261 + .../x/text/feature/plural/tables.go | 552 + .../x/text/internal/catmsg/catmsg.go | 415 + .../x/text/internal/catmsg/codec.go | 407 + .../x/text/internal/catmsg/varint.go | 62 + .../x/text/internal/format/format.go | 41 + .../x/text/internal/format/parser.go | 358 + vendor/golang.org/x/text/internal/internal.go | 49 + .../x/text/internal/language/common.go | 16 + .../x/text/internal/language/compact.go | 29 + .../text/internal/language/compact/compact.go | 61 + .../internal/language/compact/language.go | 260 + .../text/internal/language/compact/parents.go | 120 + .../text/internal/language/compact/tables.go | 1015 + .../x/text/internal/language/compact/tags.go | 91 + .../x/text/internal/language/compose.go | 167 + .../x/text/internal/language/coverage.go | 28 + .../x/text/internal/language/language.go | 627 + .../x/text/internal/language/lookup.go | 412 + .../x/text/internal/language/match.go | 226 + .../x/text/internal/language/parse.go | 604 + .../x/text/internal/language/tables.go | 3464 + .../x/text/internal/language/tags.go | 48 + vendor/golang.org/x/text/internal/match.go | 67 + .../x/text/internal/number/common.go | 55 + .../x/text/internal/number/decimal.go | 498 + .../x/text/internal/number/format.go | 535 + .../x/text/internal/number/number.go | 152 + .../x/text/internal/number/pattern.go | 485 + .../internal/number/roundingmode_string.go | 30 + .../x/text/internal/number/tables.go | 1219 + .../x/text/internal/stringset/set.go | 86 + vendor/golang.org/x/text/internal/tag/tag.go | 100 + vendor/golang.org/x/text/language/coverage.go | 187 + vendor/golang.org/x/text/language/doc.go | 102 + vendor/golang.org/x/text/language/go1_1.go | 39 + vendor/golang.org/x/text/language/go1_2.go | 12 + vendor/golang.org/x/text/language/language.go | 605 + vendor/golang.org/x/text/language/match.go | 735 + vendor/golang.org/x/text/language/parse.go | 250 + vendor/golang.org/x/text/language/tables.go | 298 + vendor/golang.org/x/text/language/tags.go | 145 + vendor/golang.org/x/text/message/catalog.go | 36 + .../x/text/message/catalog/catalog.go | 370 + .../golang.org/x/text/message/catalog/dict.go | 129 + .../golang.org/x/text/message/catalog/go19.go | 16 + .../x/text/message/catalog/gopre19.go | 24 + vendor/golang.org/x/text/message/doc.go | 101 + vendor/golang.org/x/text/message/format.go | 510 + vendor/golang.org/x/text/message/message.go | 193 + vendor/golang.org/x/text/message/print.go | 984 + .../x/text/secure/bidirule/bidirule.go | 336 + .../x/text/secure/bidirule/bidirule10.0.0.go | 12 + .../x/text/secure/bidirule/bidirule9.0.0.go | 15 + .../golang.org/x/text/transform/transform.go | 709 + vendor/golang.org/x/text/unicode/bidi/bidi.go | 359 + .../golang.org/x/text/unicode/bidi/bracket.go | 335 + vendor/golang.org/x/text/unicode/bidi/core.go | 1071 + vendor/golang.org/x/text/unicode/bidi/prop.go | 206 + .../x/text/unicode/bidi/tables10.0.0.go | 1816 + .../x/text/unicode/bidi/tables11.0.0.go | 1888 + .../x/text/unicode/bidi/tables12.0.0.go | 1924 + .../x/text/unicode/bidi/tables13.0.0.go | 1956 + .../x/text/unicode/bidi/tables9.0.0.go | 1782 + .../golang.org/x/text/unicode/bidi/trieval.go | 60 + .../x/text/unicode/norm/composition.go | 512 + .../x/text/unicode/norm/forminfo.go | 278 + .../golang.org/x/text/unicode/norm/input.go | 109 + vendor/golang.org/x/text/unicode/norm/iter.go | 458 + .../x/text/unicode/norm/normalize.go | 609 + .../x/text/unicode/norm/readwriter.go | 125 + .../x/text/unicode/norm/tables10.0.0.go | 7658 + .../x/text/unicode/norm/tables11.0.0.go | 7694 + .../x/text/unicode/norm/tables12.0.0.go | 7711 + .../x/text/unicode/norm/tables13.0.0.go | 7761 + .../x/text/unicode/norm/tables9.0.0.go | 7638 + .../x/text/unicode/norm/transform.go | 88 + vendor/golang.org/x/text/unicode/norm/trie.go | 54 + vendor/golang.org/x/tools/AUTHORS | 3 + vendor/golang.org/x/tools/CONTRIBUTORS | 3 + vendor/golang.org/x/tools/LICENSE | 27 + vendor/golang.org/x/tools/PATENTS | 22 + .../x/tools/go/ast/astutil/enclosing.go | 639 + .../x/tools/go/ast/astutil/imports.go | 482 + .../x/tools/go/ast/astutil/rewrite.go | 483 + .../golang.org/x/tools/go/ast/astutil/util.go | 18 + .../x/tools/go/gcexportdata/gcexportdata.go | 146 + .../x/tools/go/gcexportdata/importer.go | 73 + .../x/tools/go/internal/gcimporter/bexport.go | 851 + .../x/tools/go/internal/gcimporter/bimport.go | 1053 + .../go/internal/gcimporter/exportdata.go | 99 + .../go/internal/gcimporter/gcimporter.go | 1084 + .../x/tools/go/internal/gcimporter/iexport.go | 1007 + .../x/tools/go/internal/gcimporter/iimport.go | 875 + .../go/internal/gcimporter/newInterface10.go | 22 + .../go/internal/gcimporter/newInterface11.go | 14 + .../go/internal/gcimporter/support_go117.go | 16 + .../go/internal/gcimporter/support_go118.go | 23 + .../tools/go/internal/packagesdriver/sizes.go | 49 + vendor/golang.org/x/tools/go/packages/doc.go | 221 + .../x/tools/go/packages/external.go | 101 + .../golang.org/x/tools/go/packages/golist.go | 1099 + .../x/tools/go/packages/golist_overlay.go | 575 + .../x/tools/go/packages/loadmode_string.go | 57 + .../x/tools/go/packages/packages.go | 1244 + .../golang.org/x/tools/go/packages/visit.go | 59 + vendor/golang.org/x/tools/imports/forward.go | 77 + .../x/tools/internal/event/core/event.go | 85 + .../x/tools/internal/event/core/export.go | 70 + .../x/tools/internal/event/core/fast.go | 77 + .../golang.org/x/tools/internal/event/doc.go | 7 + .../x/tools/internal/event/event.go | 127 + .../x/tools/internal/event/keys/keys.go | 564 + .../x/tools/internal/event/keys/standard.go | 22 + .../x/tools/internal/event/label/label.go | 215 + .../x/tools/internal/fastwalk/fastwalk.go | 196 + .../fastwalk/fastwalk_dirent_fileno.go | 14 + .../internal/fastwalk/fastwalk_dirent_ino.go | 15 + .../fastwalk/fastwalk_dirent_namlen_bsd.go | 14 + .../fastwalk/fastwalk_dirent_namlen_linux.go | 29 + .../internal/fastwalk/fastwalk_portable.go | 38 + .../tools/internal/fastwalk/fastwalk_unix.go | 153 + .../x/tools/internal/gocommand/invoke.go | 273 + .../x/tools/internal/gocommand/vendor.go | 107 + .../x/tools/internal/gocommand/version.go | 51 + .../x/tools/internal/gopathwalk/walk.go | 264 + .../x/tools/internal/imports/fix.go | 1730 + .../x/tools/internal/imports/imports.go | 346 + .../x/tools/internal/imports/mod.go | 695 + .../x/tools/internal/imports/mod_cache.go | 236 + .../x/tools/internal/imports/sortimports.go | 291 + .../x/tools/internal/imports/zstdlib.go | 10756 ++ .../internal/packagesinternal/packages.go | 28 + .../x/tools/internal/typeparams/common.go | 79 + .../internal/typeparams/enabled_go117.go | 12 + .../internal/typeparams/enabled_go118.go | 15 + .../x/tools/internal/typeparams/normalize.go | 216 + .../x/tools/internal/typeparams/termlist.go | 172 + .../internal/typeparams/typeparams_go117.go | 192 + .../internal/typeparams/typeparams_go118.go | 146 + .../x/tools/internal/typeparams/typeterm.go | 170 + .../tools/internal/typesinternal/errorcode.go | 1368 + .../typesinternal/errorcode_string.go | 153 + .../x/tools/internal/typesinternal/types.go | 50 + vendor/golang.org/x/xerrors/LICENSE | 27 + vendor/golang.org/x/xerrors/PATENTS | 22 + vendor/golang.org/x/xerrors/README | 2 + vendor/golang.org/x/xerrors/adaptor.go | 193 + vendor/golang.org/x/xerrors/codereview.cfg | 1 + vendor/golang.org/x/xerrors/doc.go | 22 + vendor/golang.org/x/xerrors/errors.go | 33 + vendor/golang.org/x/xerrors/fmt.go | 187 + vendor/golang.org/x/xerrors/format.go | 34 + vendor/golang.org/x/xerrors/frame.go | 56 + vendor/golang.org/x/xerrors/go.mod | 3 + .../golang.org/x/xerrors/internal/internal.go | 8 + vendor/golang.org/x/xerrors/wrap.go | 106 + vendor/google.golang.org/genproto/LICENSE | 202 + .../googleapis/rpc/status/status.pb.go | 206 + .../genproto/protobuf/api/api.go | 25 + .../protobuf/field_mask/field_mask.go | 23 + .../genproto/protobuf/ptype/type.go | 82 + .../protobuf/source_context/source_context.go | 23 + vendor/google.golang.org/grpc/AUTHORS | 1 + .../google.golang.org/grpc/CODE-OF-CONDUCT.md | 3 + vendor/google.golang.org/grpc/CONTRIBUTING.md | 60 + vendor/google.golang.org/grpc/GOVERNANCE.md | 1 + vendor/google.golang.org/grpc/LICENSE | 202 + vendor/google.golang.org/grpc/MAINTAINERS.md | 28 + vendor/google.golang.org/grpc/Makefile | 46 + vendor/google.golang.org/grpc/NOTICE.txt | 13 + vendor/google.golang.org/grpc/README.md | 141 + vendor/google.golang.org/grpc/SECURITY.md | 3 + .../grpc/attributes/attributes.go | 101 + vendor/google.golang.org/grpc/backoff.go | 61 + .../google.golang.org/grpc/backoff/backoff.go | 52 + .../grpc/balancer/balancer.go | 426 + .../grpc/balancer/base/balancer.go | 254 + .../grpc/balancer/base/base.go | 71 + .../grpc/balancer/grpclb/state/state.go | 51 + .../grpc/balancer/roundrobin/roundrobin.go | 83 + .../grpc/balancer_conn_wrappers.go | 416 + .../grpc_binarylog_v1/binarylog.pb.go | 1187 + vendor/google.golang.org/grpc/call.go | 74 + .../grpc/channelz/channelz.go | 36 + vendor/google.golang.org/grpc/clientconn.go | 1687 + vendor/google.golang.org/grpc/codec.go | 50 + vendor/google.golang.org/grpc/codegen.sh | 17 + .../grpc/codes/code_string.go | 62 + vendor/google.golang.org/grpc/codes/codes.go | 244 + .../grpc/connectivity/connectivity.go | 94 + .../grpc/credentials/credentials.go | 291 + .../grpc/credentials/insecure/insecure.go | 98 + .../google.golang.org/grpc/credentials/tls.go | 236 + vendor/google.golang.org/grpc/dialoptions.go | 606 + vendor/google.golang.org/grpc/doc.go | 26 + .../grpc/encoding/encoding.go | 130 + .../grpc/encoding/proto/proto.go | 58 + vendor/google.golang.org/grpc/go.mod | 19 + vendor/google.golang.org/grpc/go.sum | 141 + .../grpc/grpclog/component.go | 117 + .../google.golang.org/grpc/grpclog/grpclog.go | 132 + .../google.golang.org/grpc/grpclog/logger.go | 87 + .../grpc/grpclog/loggerv2.go | 259 + vendor/google.golang.org/grpc/interceptor.go | 104 + .../grpc/internal/backoff/backoff.go | 73 + .../balancer/gracefulswitch/gracefulswitch.go | 384 + .../grpc/internal/balancerload/load.go | 46 + .../grpc/internal/binarylog/binarylog.go | 189 + .../internal/binarylog/binarylog_testutil.go | 42 + .../grpc/internal/binarylog/env_config.go | 208 + .../grpc/internal/binarylog/method_logger.go | 432 + .../grpc/internal/binarylog/sink.go | 170 + .../grpc/internal/buffer/unbounded.go | 85 + .../grpc/internal/channelz/funcs.go | 789 + .../grpc/internal/channelz/id.go | 75 + .../grpc/internal/channelz/logging.go | 79 + .../grpc/internal/channelz/types.go | 722 + .../grpc/internal/channelz/types_linux.go | 51 + .../grpc/internal/channelz/types_nonlinux.go | 43 + .../grpc/internal/channelz/util_linux.go | 37 + .../grpc/internal/channelz/util_nonlinux.go | 27 + .../grpc/internal/credentials/credentials.go | 49 + .../grpc/internal/credentials/spiffe.go | 75 + .../grpc/internal/credentials/syscallconn.go | 58 + .../grpc/internal/credentials/util.go | 52 + .../grpc/internal/envconfig/envconfig.go | 35 + .../grpc/internal/envconfig/xds.go | 101 + .../grpc/internal/grpclog/grpclog.go | 126 + .../grpc/internal/grpclog/prefixLogger.go | 81 + .../grpc/internal/grpcrand/grpcrand.go | 67 + .../grpc/internal/grpcsync/event.go | 61 + .../grpc/internal/grpcutil/encode_duration.go | 63 + .../grpc/internal/grpcutil/grpcutil.go | 20 + .../grpc/internal/grpcutil/metadata.go | 40 + .../grpc/internal/grpcutil/method.go | 84 + .../grpc/internal/grpcutil/regex.go | 31 + .../grpc/internal/internal.go | 163 + .../grpc/internal/metadata/metadata.go | 120 + .../grpc/internal/pretty/pretty.go | 82 + .../grpc/internal/resolver/config_selector.go | 167 + .../internal/resolver/dns/dns_resolver.go | 458 + .../resolver/passthrough/passthrough.go | 57 + .../grpc/internal/resolver/unix/unix.go | 73 + .../internal/serviceconfig/serviceconfig.go | 180 + .../grpc/internal/status/status.go | 166 + .../grpc/internal/syscall/syscall_linux.go | 112 + .../grpc/internal/syscall/syscall_nonlinux.go | 77 + .../grpc/internal/transport/bdp_estimator.go | 141 + .../grpc/internal/transport/controlbuf.go | 990 + .../grpc/internal/transport/defaults.go | 49 + .../grpc/internal/transport/flowcontrol.go | 215 + .../grpc/internal/transport/handler_server.go | 462 + .../grpc/internal/transport/http2_client.go | 1698 + .../grpc/internal/transport/http2_server.go | 1441 + .../grpc/internal/transport/http_util.go | 419 + .../transport/networktype/networktype.go | 46 + .../grpc/internal/transport/proxy.go | 142 + .../grpc/internal/transport/transport.go | 813 + .../grpc/internal/xds_handshake_cluster.go | 40 + .../grpc/keepalive/keepalive.go | 85 + .../grpc/metadata/metadata.go | 251 + vendor/google.golang.org/grpc/peer/peer.go | 51 + .../google.golang.org/grpc/picker_wrapper.go | 183 + vendor/google.golang.org/grpc/pickfirst.go | 183 + vendor/google.golang.org/grpc/preloader.go | 67 + .../grpc/reflection/README.md | 18 + .../grpc_reflection_v1alpha/reflection.pb.go | 953 + .../grpc_reflection_v1alpha/reflection.proto | 138 + .../reflection_grpc.pb.go | 139 + .../grpc/reflection/serverreflection.go | 324 + vendor/google.golang.org/grpc/regenerate.sh | 126 + vendor/google.golang.org/grpc/resolver/map.go | 138 + .../grpc/resolver/resolver.go | 292 + .../grpc/resolver_conn_wrapper.go | 176 + vendor/google.golang.org/grpc/rpc_util.go | 914 + vendor/google.golang.org/grpc/server.go | 1903 + .../google.golang.org/grpc/service_config.go | 407 + .../grpc/serviceconfig/serviceconfig.go | 44 + .../google.golang.org/grpc/stats/handlers.go | 63 + vendor/google.golang.org/grpc/stats/stats.go | 319 + .../google.golang.org/grpc/status/status.go | 135 + vendor/google.golang.org/grpc/stream.go | 1655 + vendor/google.golang.org/grpc/tap/tap.go | 56 + vendor/google.golang.org/grpc/trace.go | 123 + vendor/google.golang.org/grpc/version.go | 22 + vendor/google.golang.org/grpc/vet.sh | 211 + vendor/google.golang.org/protobuf/LICENSE | 27 + vendor/google.golang.org/protobuf/PATENTS | 22 + .../protobuf/encoding/protojson/decode.go | 665 + .../protobuf/encoding/protojson/doc.go | 11 + .../protobuf/encoding/protojson/encode.go | 343 + .../encoding/protojson/well_known_types.go | 889 + .../protobuf/encoding/prototext/decode.go | 770 + .../protobuf/encoding/prototext/doc.go | 7 + .../protobuf/encoding/prototext/encode.go | 370 + .../protobuf/encoding/protowire/wire.go | 551 + .../protobuf/internal/descfmt/stringer.go | 318 + .../protobuf/internal/descopts/options.go | 29 + .../protobuf/internal/detrand/rand.go | 69 + .../internal/encoding/defval/default.go | 213 + .../protobuf/internal/encoding/json/decode.go | 340 + .../internal/encoding/json/decode_number.go | 254 + .../internal/encoding/json/decode_string.go | 91 + .../internal/encoding/json/decode_token.go | 192 + .../protobuf/internal/encoding/json/encode.go | 276 + .../encoding/messageset/messageset.go | 242 + .../protobuf/internal/encoding/tag/tag.go | 207 + .../protobuf/internal/encoding/text/decode.go | 685 + .../internal/encoding/text/decode_number.go | 192 + .../internal/encoding/text/decode_string.go | 161 + .../internal/encoding/text/decode_token.go | 373 + .../protobuf/internal/encoding/text/doc.go | 29 + .../protobuf/internal/encoding/text/encode.go | 270 + .../protobuf/internal/errors/errors.go | 89 + .../protobuf/internal/errors/is_go112.go | 40 + .../protobuf/internal/errors/is_go113.go | 13 + .../protobuf/internal/filedesc/build.go | 157 + .../protobuf/internal/filedesc/desc.go | 633 + .../protobuf/internal/filedesc/desc_init.go | 471 + .../protobuf/internal/filedesc/desc_lazy.go | 704 + .../protobuf/internal/filedesc/desc_list.go | 457 + .../internal/filedesc/desc_list_gen.go | 356 + .../protobuf/internal/filedesc/placeholder.go | 109 + .../protobuf/internal/filetype/build.go | 296 + .../protobuf/internal/flags/flags.go | 24 + .../internal/flags/proto_legacy_disable.go | 10 + .../internal/flags/proto_legacy_enable.go | 10 + .../protobuf/internal/genid/any_gen.go | 34 + .../protobuf/internal/genid/api_gen.go | 106 + .../protobuf/internal/genid/descriptor_gen.go | 829 + .../protobuf/internal/genid/doc.go | 11 + .../protobuf/internal/genid/duration_gen.go | 34 + .../protobuf/internal/genid/empty_gen.go | 19 + .../protobuf/internal/genid/field_mask_gen.go | 31 + .../protobuf/internal/genid/goname.go | 25 + .../protobuf/internal/genid/map_entry.go | 16 + .../internal/genid/source_context_gen.go | 31 + .../protobuf/internal/genid/struct_gen.go | 116 + .../protobuf/internal/genid/timestamp_gen.go | 34 + .../protobuf/internal/genid/type_gen.go | 184 + .../protobuf/internal/genid/wrappers.go | 13 + .../protobuf/internal/genid/wrappers_gen.go | 175 + .../protobuf/internal/impl/api_export.go | 177 + .../protobuf/internal/impl/checkinit.go | 141 + .../protobuf/internal/impl/codec_extension.go | 223 + .../protobuf/internal/impl/codec_field.go | 830 + .../protobuf/internal/impl/codec_gen.go | 5637 + .../protobuf/internal/impl/codec_map.go | 388 + .../protobuf/internal/impl/codec_map_go111.go | 38 + .../protobuf/internal/impl/codec_map_go112.go | 12 + .../protobuf/internal/impl/codec_message.go | 217 + .../internal/impl/codec_messageset.go | 123 + .../protobuf/internal/impl/codec_reflect.go | 210 + .../protobuf/internal/impl/codec_tables.go | 557 + .../protobuf/internal/impl/codec_unsafe.go | 18 + .../protobuf/internal/impl/convert.go | 496 + .../protobuf/internal/impl/convert_list.go | 141 + .../protobuf/internal/impl/convert_map.go | 121 + .../protobuf/internal/impl/decode.go | 285 + .../protobuf/internal/impl/encode.go | 201 + .../protobuf/internal/impl/enum.go | 21 + .../protobuf/internal/impl/extension.go | 156 + .../protobuf/internal/impl/legacy_enum.go | 218 + .../protobuf/internal/impl/legacy_export.go | 92 + .../internal/impl/legacy_extension.go | 176 + .../protobuf/internal/impl/legacy_file.go | 81 + .../protobuf/internal/impl/legacy_message.go | 563 + .../protobuf/internal/impl/merge.go | 176 + .../protobuf/internal/impl/merge_gen.go | 209 + .../protobuf/internal/impl/message.go | 279 + .../protobuf/internal/impl/message_reflect.go | 463 + .../internal/impl/message_reflect_field.go | 543 + .../internal/impl/message_reflect_gen.go | 249 + .../protobuf/internal/impl/pointer_reflect.go | 179 + .../protobuf/internal/impl/pointer_unsafe.go | 175 + .../protobuf/internal/impl/validate.go | 576 + .../protobuf/internal/impl/weak.go | 74 + .../protobuf/internal/order/order.go | 89 + .../protobuf/internal/order/range.go | 115 + .../protobuf/internal/pragma/pragma.go | 29 + .../protobuf/internal/set/ints.go | 58 + .../protobuf/internal/strs/strings.go | 196 + .../protobuf/internal/strs/strings_pure.go | 28 + .../protobuf/internal/strs/strings_unsafe.go | 95 + .../protobuf/internal/version/version.go | 79 + .../protobuf/proto/checkinit.go | 71 + .../protobuf/proto/decode.go | 294 + .../protobuf/proto/decode_gen.go | 603 + .../google.golang.org/protobuf/proto/doc.go | 89 + .../protobuf/proto/encode.go | 322 + .../protobuf/proto/encode_gen.go | 97 + .../google.golang.org/protobuf/proto/equal.go | 171 + .../protobuf/proto/extension.go | 92 + .../google.golang.org/protobuf/proto/merge.go | 139 + .../protobuf/proto/messageset.go | 93 + .../google.golang.org/protobuf/proto/proto.go | 43 + .../protobuf/proto/proto_methods.go | 20 + .../protobuf/proto/proto_reflect.go | 20 + .../google.golang.org/protobuf/proto/reset.go | 43 + .../google.golang.org/protobuf/proto/size.go | 97 + .../protobuf/proto/size_gen.go | 55 + .../protobuf/proto/wrappers.go | 29 + .../protobuf/reflect/protodesc/desc.go | 276 + .../protobuf/reflect/protodesc/desc_init.go | 248 + .../reflect/protodesc/desc_resolve.go | 286 + .../reflect/protodesc/desc_validate.go | 374 + .../protobuf/reflect/protodesc/proto.go | 252 + .../protobuf/reflect/protoreflect/methods.go | 78 + .../protobuf/reflect/protoreflect/proto.go | 508 + .../protobuf/reflect/protoreflect/source.go | 129 + .../reflect/protoreflect/source_gen.go | 461 + .../protobuf/reflect/protoreflect/type.go | 666 + .../protobuf/reflect/protoreflect/value.go | 285 + .../reflect/protoreflect/value_pure.go | 60 + .../reflect/protoreflect/value_union.go | 438 + .../reflect/protoreflect/value_unsafe.go | 99 + .../reflect/protoregistry/registry.go | 882 + .../protobuf/runtime/protoiface/legacy.go | 15 + .../protobuf/runtime/protoiface/methods.go | 168 + .../protobuf/runtime/protoimpl/impl.go | 44 + .../protobuf/runtime/protoimpl/version.go | 60 + .../types/descriptorpb/descriptor.pb.go | 3957 + .../protobuf/types/known/anypb/any.pb.go | 498 + .../protobuf/types/known/apipb/api.pb.go | 577 + .../types/known/durationpb/duration.pb.go | 379 + .../protobuf/types/known/emptypb/empty.pb.go | 168 + .../types/known/fieldmaskpb/field_mask.pb.go | 591 + .../sourcecontextpb/source_context.pb.go | 176 + .../types/known/structpb/struct.pb.go | 810 + .../types/known/timestamppb/timestamp.pb.go | 390 + .../protobuf/types/known/typepb/type.pb.go | 964 + .../types/known/wrapperspb/wrappers.pb.go | 760 + .../protobuf/types/pluginpb/plugin.pb.go | 653 + vendor/gopkg.in/yaml.v2/.travis.yml | 17 + vendor/gopkg.in/yaml.v2/LICENSE | 201 + vendor/gopkg.in/yaml.v2/LICENSE.libyaml | 31 + vendor/gopkg.in/yaml.v2/NOTICE | 13 + vendor/gopkg.in/yaml.v2/README.md | 133 + vendor/gopkg.in/yaml.v2/apic.go | 744 + vendor/gopkg.in/yaml.v2/decode.go | 815 + vendor/gopkg.in/yaml.v2/emitterc.go | 1685 + vendor/gopkg.in/yaml.v2/encode.go | 390 + vendor/gopkg.in/yaml.v2/go.mod | 5 + vendor/gopkg.in/yaml.v2/parserc.go | 1095 + vendor/gopkg.in/yaml.v2/readerc.go | 412 + vendor/gopkg.in/yaml.v2/resolve.go | 258 + vendor/gopkg.in/yaml.v2/scannerc.go | 2711 + vendor/gopkg.in/yaml.v2/sorter.go | 113 + vendor/gopkg.in/yaml.v2/writerc.go | 26 + vendor/gopkg.in/yaml.v2/yaml.go | 478 + vendor/gopkg.in/yaml.v2/yamlh.go | 739 + vendor/gopkg.in/yaml.v2/yamlprivateh.go | 173 + vendor/gopkg.in/yaml.v3/LICENSE | 50 + vendor/gopkg.in/yaml.v3/NOTICE | 13 + vendor/gopkg.in/yaml.v3/README.md | 150 + vendor/gopkg.in/yaml.v3/apic.go | 747 + vendor/gopkg.in/yaml.v3/decode.go | 1000 + vendor/gopkg.in/yaml.v3/emitterc.go | 2020 + vendor/gopkg.in/yaml.v3/encode.go | 577 + vendor/gopkg.in/yaml.v3/go.mod | 5 + vendor/gopkg.in/yaml.v3/parserc.go | 1258 + vendor/gopkg.in/yaml.v3/readerc.go | 434 + vendor/gopkg.in/yaml.v3/resolve.go | 326 + vendor/gopkg.in/yaml.v3/scannerc.go | 3038 + vendor/gopkg.in/yaml.v3/sorter.go | 134 + vendor/gopkg.in/yaml.v3/writerc.go | 48 + vendor/gopkg.in/yaml.v3/yaml.go | 698 + vendor/gopkg.in/yaml.v3/yamlh.go | 807 + vendor/gopkg.in/yaml.v3/yamlprivateh.go | 198 + vendor/modules.txt | 535 + 3065 files changed, 1191539 insertions(+), 1 deletion(-) create mode 100644 vendor/github.com/99designs/gqlgen/.dockerignore create mode 100644 vendor/github.com/99designs/gqlgen/.editorconfig create mode 100644 vendor/github.com/99designs/gqlgen/.gitattributes create mode 100644 vendor/github.com/99designs/gqlgen/.gitignore create mode 100644 vendor/github.com/99designs/gqlgen/.golangci.yml create mode 100644 vendor/github.com/99designs/gqlgen/CHANGELOG.md create mode 100644 vendor/github.com/99designs/gqlgen/CONTRIBUTING.md create mode 100644 vendor/github.com/99designs/gqlgen/LICENSE create mode 100644 vendor/github.com/99designs/gqlgen/README.md create mode 100644 vendor/github.com/99designs/gqlgen/TESTING.md create mode 100644 vendor/github.com/99designs/gqlgen/api/generate.go create mode 100644 vendor/github.com/99designs/gqlgen/api/option.go create mode 100644 vendor/github.com/99designs/gqlgen/cmd/ambient.go create mode 100644 vendor/github.com/99designs/gqlgen/cmd/gen.go create mode 100644 vendor/github.com/99designs/gqlgen/cmd/init.go create mode 100644 vendor/github.com/99designs/gqlgen/cmd/root.go create mode 100644 vendor/github.com/99designs/gqlgen/cmd/version.go create mode 100644 vendor/github.com/99designs/gqlgen/codegen/args.go create mode 100644 vendor/github.com/99designs/gqlgen/codegen/args.gotpl create mode 100644 vendor/github.com/99designs/gqlgen/codegen/complexity.go create mode 100644 vendor/github.com/99designs/gqlgen/codegen/config/binder.go create mode 100644 vendor/github.com/99designs/gqlgen/codegen/config/config.go create mode 100644 vendor/github.com/99designs/gqlgen/codegen/config/exec.go create mode 100644 vendor/github.com/99designs/gqlgen/codegen/config/package.go create mode 100644 vendor/github.com/99designs/gqlgen/codegen/config/resolver.go create mode 100644 vendor/github.com/99designs/gqlgen/codegen/data.go create mode 100644 vendor/github.com/99designs/gqlgen/codegen/directive.go create mode 100644 vendor/github.com/99designs/gqlgen/codegen/directives.gotpl create mode 100644 vendor/github.com/99designs/gqlgen/codegen/field.go create mode 100644 vendor/github.com/99designs/gqlgen/codegen/field.gotpl create mode 100644 vendor/github.com/99designs/gqlgen/codegen/generate.go create mode 100644 vendor/github.com/99designs/gqlgen/codegen/generated!.gotpl create mode 100644 vendor/github.com/99designs/gqlgen/codegen/input.gotpl create mode 100644 vendor/github.com/99designs/gqlgen/codegen/interface.go create mode 100644 vendor/github.com/99designs/gqlgen/codegen/interface.gotpl create mode 100644 vendor/github.com/99designs/gqlgen/codegen/object.go create mode 100644 vendor/github.com/99designs/gqlgen/codegen/object.gotpl create mode 100644 vendor/github.com/99designs/gqlgen/codegen/root_.gotpl create mode 100644 vendor/github.com/99designs/gqlgen/codegen/templates/import.go create mode 100644 vendor/github.com/99designs/gqlgen/codegen/templates/templates.go create mode 100644 vendor/github.com/99designs/gqlgen/codegen/type.go create mode 100644 vendor/github.com/99designs/gqlgen/codegen/type.gotpl create mode 100644 vendor/github.com/99designs/gqlgen/codegen/util.go create mode 100644 vendor/github.com/99designs/gqlgen/complexity/complexity.go create mode 100644 vendor/github.com/99designs/gqlgen/go.mod create mode 100644 vendor/github.com/99designs/gqlgen/go.sum create mode 100644 vendor/github.com/99designs/gqlgen/graphql/any.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/bool.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/cache.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/coercion.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/context_field.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/context_operation.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/context_path.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/context_response.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/context_root_field.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/errcode/codes.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/error.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/executable_schema.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/executable_schema_mock.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/executor/executor.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/executor/extensions.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/fieldset.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/float.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/handler.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/handler/extension/apq.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/handler/extension/complexity.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/handler/extension/introspection.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/handler/lru/lru.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/handler/server.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/handler/transport/error.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_form.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_get.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_post.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/handler/transport/options.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/handler/transport/reader.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/handler/transport/util.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_close_reason.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_graphql_transport_ws.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_graphqlws.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_init.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_subprotocol.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/id.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/int.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/introspection/introspection.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/introspection/query.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/introspection/schema.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/introspection/type.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/jsonw.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/map.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/oneshot.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/playground/playground.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/recovery.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/response.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/root.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/stats.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/string.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/time.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/uint.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/upload.go create mode 100644 vendor/github.com/99designs/gqlgen/graphql/version.go create mode 100644 vendor/github.com/99designs/gqlgen/handler/handler.go create mode 100644 vendor/github.com/99designs/gqlgen/internal/code/compare.go create mode 100644 vendor/github.com/99designs/gqlgen/internal/code/imports.go create mode 100644 vendor/github.com/99designs/gqlgen/internal/code/packages.go create mode 100644 vendor/github.com/99designs/gqlgen/internal/code/util.go create mode 100644 vendor/github.com/99designs/gqlgen/internal/imports/prune.go create mode 100644 vendor/github.com/99designs/gqlgen/internal/rewrite/rewriter.go create mode 100644 vendor/github.com/99designs/gqlgen/main.go create mode 100644 vendor/github.com/99designs/gqlgen/plugin/federation/federation.go create mode 100644 vendor/github.com/99designs/gqlgen/plugin/federation/federation.gotpl create mode 100644 vendor/github.com/99designs/gqlgen/plugin/federation/fieldset/fieldset.go create mode 100644 vendor/github.com/99designs/gqlgen/plugin/federation/readme.md create mode 100644 vendor/github.com/99designs/gqlgen/plugin/modelgen/models.go create mode 100644 vendor/github.com/99designs/gqlgen/plugin/modelgen/models.gotpl create mode 100644 vendor/github.com/99designs/gqlgen/plugin/plugin.go create mode 100644 vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.go create mode 100644 vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.gotpl create mode 100644 vendor/github.com/99designs/gqlgen/plugin/servergen/server.go create mode 100644 vendor/github.com/99designs/gqlgen/plugin/servergen/server.gotpl create mode 100644 vendor/github.com/99designs/gqlgen/tools.go create mode 100644 vendor/github.com/agnivade/levenshtein/.gitignore create mode 100644 vendor/github.com/agnivade/levenshtein/.travis.yml create mode 100644 vendor/github.com/agnivade/levenshtein/License.txt create mode 100644 vendor/github.com/agnivade/levenshtein/Makefile create mode 100644 vendor/github.com/agnivade/levenshtein/README.md create mode 100644 vendor/github.com/agnivade/levenshtein/go.mod create mode 100644 vendor/github.com/agnivade/levenshtein/go.sum create mode 100644 vendor/github.com/agnivade/levenshtein/levenshtein.go create mode 100644 vendor/github.com/andybalholm/brotli/LICENSE create mode 100644 vendor/github.com/andybalholm/brotli/README.md create mode 100644 vendor/github.com/andybalholm/brotli/backward_references.go create mode 100644 vendor/github.com/andybalholm/brotli/backward_references_hq.go create mode 100644 vendor/github.com/andybalholm/brotli/bit_cost.go create mode 100644 vendor/github.com/andybalholm/brotli/bit_reader.go create mode 100644 vendor/github.com/andybalholm/brotli/block_splitter.go create mode 100644 vendor/github.com/andybalholm/brotli/block_splitter_command.go create mode 100644 vendor/github.com/andybalholm/brotli/block_splitter_distance.go create mode 100644 vendor/github.com/andybalholm/brotli/block_splitter_literal.go create mode 100644 vendor/github.com/andybalholm/brotli/brotli_bit_stream.go create mode 100644 vendor/github.com/andybalholm/brotli/cluster.go create mode 100644 vendor/github.com/andybalholm/brotli/cluster_command.go create mode 100644 vendor/github.com/andybalholm/brotli/cluster_distance.go create mode 100644 vendor/github.com/andybalholm/brotli/cluster_literal.go create mode 100644 vendor/github.com/andybalholm/brotli/command.go create mode 100644 vendor/github.com/andybalholm/brotli/compress_fragment.go create mode 100644 vendor/github.com/andybalholm/brotli/compress_fragment_two_pass.go create mode 100644 vendor/github.com/andybalholm/brotli/constants.go create mode 100644 vendor/github.com/andybalholm/brotli/context.go create mode 100644 vendor/github.com/andybalholm/brotli/decode.go create mode 100644 vendor/github.com/andybalholm/brotli/dictionary.go create mode 100644 vendor/github.com/andybalholm/brotli/dictionary_hash.go create mode 100644 vendor/github.com/andybalholm/brotli/encode.go create mode 100644 vendor/github.com/andybalholm/brotli/encoder_dict.go create mode 100644 vendor/github.com/andybalholm/brotli/entropy_encode.go create mode 100644 vendor/github.com/andybalholm/brotli/entropy_encode_static.go create mode 100644 vendor/github.com/andybalholm/brotli/fast_log.go create mode 100644 vendor/github.com/andybalholm/brotli/find_match_length.go create mode 100644 vendor/github.com/andybalholm/brotli/go.mod create mode 100644 vendor/github.com/andybalholm/brotli/go.sum create mode 100644 vendor/github.com/andybalholm/brotli/h10.go create mode 100644 vendor/github.com/andybalholm/brotli/h5.go create mode 100644 vendor/github.com/andybalholm/brotli/h6.go create mode 100644 vendor/github.com/andybalholm/brotli/hash.go create mode 100644 vendor/github.com/andybalholm/brotli/hash_composite.go create mode 100644 vendor/github.com/andybalholm/brotli/hash_forgetful_chain.go create mode 100644 vendor/github.com/andybalholm/brotli/hash_longest_match_quickly.go create mode 100644 vendor/github.com/andybalholm/brotli/hash_rolling.go create mode 100644 vendor/github.com/andybalholm/brotli/histogram.go create mode 100644 vendor/github.com/andybalholm/brotli/http.go create mode 100644 vendor/github.com/andybalholm/brotli/huffman.go create mode 100644 vendor/github.com/andybalholm/brotli/literal_cost.go create mode 100644 vendor/github.com/andybalholm/brotli/memory.go create mode 100644 vendor/github.com/andybalholm/brotli/metablock.go create mode 100644 vendor/github.com/andybalholm/brotli/metablock_command.go create mode 100644 vendor/github.com/andybalholm/brotli/metablock_distance.go create mode 100644 vendor/github.com/andybalholm/brotli/metablock_literal.go create mode 100644 vendor/github.com/andybalholm/brotli/params.go create mode 100644 vendor/github.com/andybalholm/brotli/platform.go create mode 100644 vendor/github.com/andybalholm/brotli/prefix.go create mode 100644 vendor/github.com/andybalholm/brotli/prefix_dec.go create mode 100644 vendor/github.com/andybalholm/brotli/quality.go create mode 100644 vendor/github.com/andybalholm/brotli/reader.go create mode 100644 vendor/github.com/andybalholm/brotli/ringbuffer.go create mode 100644 vendor/github.com/andybalholm/brotli/state.go create mode 100644 vendor/github.com/andybalholm/brotli/static_dict.go create mode 100644 vendor/github.com/andybalholm/brotli/static_dict_lut.go create mode 100644 vendor/github.com/andybalholm/brotli/symbol_list.go create mode 100644 vendor/github.com/andybalholm/brotli/transform.go create mode 100644 vendor/github.com/andybalholm/brotli/utf8_util.go create mode 100644 vendor/github.com/andybalholm/brotli/util.go create mode 100644 vendor/github.com/andybalholm/brotli/write_bits.go create mode 100644 vendor/github.com/andybalholm/brotli/writer.go create mode 100644 vendor/github.com/araddon/dateparse/.travis.yml create mode 100644 vendor/github.com/araddon/dateparse/LICENSE create mode 100644 vendor/github.com/araddon/dateparse/README.md create mode 100644 vendor/github.com/araddon/dateparse/go.mod create mode 100644 vendor/github.com/araddon/dateparse/go.sum create mode 100644 vendor/github.com/araddon/dateparse/parseany.go create mode 100644 vendor/github.com/aws/aws-sdk-go/LICENSE.txt create mode 100644 vendor/github.com/aws/aws-sdk-go/NOTICE.txt create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/awserr/error.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/awserr/types.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/awsutil/copy.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/awsutil/equal.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/awsutil/prettify.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/awsutil/string_value.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/client/client.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/client/logger.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/client/metadata/client_info.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/client/no_op_retryer.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/config.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/context_1_5.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/context_1_9.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/context_background_1_5.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/context_background_1_7.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/context_sleep.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/convert_types.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/chain_provider.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/context_background_go1.5.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/context_background_go1.7.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/context_go1.5.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/context_go1.9.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/credentials.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/env_provider.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/example.ini create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/crr/cache.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/crr/endpoint.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/crr/sync_map.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/crr/sync_map_1_8.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/doc.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/endpoints/decode.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/endpoints/dep_service_ids.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/endpoints/doc.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/endpoints/endpoints.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/endpoints/legacy_regions.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model_codegen.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/errors.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/jsonvalue.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/logger.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/handlers.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/http_request.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/offset_reader.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/request.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/request_1_7.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/request_1_8.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/request_context.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/request_context_1_6.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/timeout_read_closer.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/validation.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/waiter.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/signer/v4/header_rules.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/signer/v4/options.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/signer/v4/request_context_go1.5.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/signer/v4/request_context_go1.7.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/signer/v4/stream.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/signer/v4/uri_path.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/types.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/url.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/url_1_7.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/version.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/context/background_go1.5.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/ast.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/comma_token.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/comment_token.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/doc.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/empty_token.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/expression.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/fuzz.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/ini.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/ini_lexer.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/ini_parser.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/literal_tokens.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/newline_token.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/number_helper.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/op_tokens.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/parse_error.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/parse_stack.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/sep_tokens.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/skipper.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/statement.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/value_util.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/visitor.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/walker.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/ws_token.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/sdkio/byte.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/sdkio/io_go1.6.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/sdkio/io_go1.7.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/sdkmath/floor.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/sdkmath/floor_go1.9.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/sdkrand/locked_source.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/sdkrand/read.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/sdkrand/read_1_5.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/shareddefaults/ecs_container.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/shareddefaults/shared_config.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/strings/strings.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/sync/singleflight/LICENSE create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/sync/singleflight/singleflight.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/host.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/host_prefix.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/idempotency.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/build.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/unmarshal.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/jsonrpc/jsonrpc.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/jsonrpc/unmarshal_error.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/jsonvalue.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/payload.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/protocol.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/rest/payload.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/rest/unmarshal.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/timestamp.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/unmarshal.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/unmarshal_error.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/dynamodb/api.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/dynamodb/customizations.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/dynamodb/doc.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/dynamodb/doc_custom.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/dynamodb/errors.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/dynamodb/service.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/dynamodb/waiters.go create mode 100644 vendor/github.com/benbjohnson/clock/LICENSE create mode 100644 vendor/github.com/benbjohnson/clock/README.md create mode 100644 vendor/github.com/benbjohnson/clock/clock.go create mode 100644 vendor/github.com/benbjohnson/clock/go.mod create mode 100644 vendor/github.com/bnkamalesh/webgo/v4/.gitignore create mode 100644 vendor/github.com/bnkamalesh/webgo/v4/.travis.yml create mode 100644 vendor/github.com/bnkamalesh/webgo/v4/CODE_OF_CONDUCT.md create mode 100644 vendor/github.com/bnkamalesh/webgo/v4/CONTRIBUTING.md create mode 100644 vendor/github.com/bnkamalesh/webgo/v4/LICENSE create mode 100644 vendor/github.com/bnkamalesh/webgo/v4/README.md create mode 100644 vendor/github.com/bnkamalesh/webgo/v4/_config.yml create mode 100644 vendor/github.com/bnkamalesh/webgo/v4/config.go create mode 100644 vendor/github.com/bnkamalesh/webgo/v4/contributors.txt create mode 100644 vendor/github.com/bnkamalesh/webgo/v4/errors.go create mode 100644 vendor/github.com/bnkamalesh/webgo/v4/go.mod create mode 100644 vendor/github.com/bnkamalesh/webgo/v4/responses.go create mode 100644 vendor/github.com/bnkamalesh/webgo/v4/route.go create mode 100644 vendor/github.com/bnkamalesh/webgo/v4/router.go create mode 100644 vendor/github.com/bnkamalesh/webgo/v4/webgo.go create mode 100644 vendor/github.com/bnkamalesh/webgo/v6/.gitignore create mode 100644 vendor/github.com/bnkamalesh/webgo/v6/.travis.yml create mode 100644 vendor/github.com/bnkamalesh/webgo/v6/CODE_OF_CONDUCT.md create mode 100644 vendor/github.com/bnkamalesh/webgo/v6/CONTRIBUTING.md create mode 100644 vendor/github.com/bnkamalesh/webgo/v6/LICENSE create mode 100644 vendor/github.com/bnkamalesh/webgo/v6/README.md create mode 100644 vendor/github.com/bnkamalesh/webgo/v6/_config.yml create mode 100644 vendor/github.com/bnkamalesh/webgo/v6/config.go create mode 100644 vendor/github.com/bnkamalesh/webgo/v6/errors.go create mode 100644 vendor/github.com/bnkamalesh/webgo/v6/go.mod create mode 100644 vendor/github.com/bnkamalesh/webgo/v6/responses.go create mode 100644 vendor/github.com/bnkamalesh/webgo/v6/route.go create mode 100644 vendor/github.com/bnkamalesh/webgo/v6/router.go create mode 100644 vendor/github.com/bnkamalesh/webgo/v6/webgo.go create mode 100644 vendor/github.com/cespare/xxhash/v2/LICENSE.txt create mode 100644 vendor/github.com/cespare/xxhash/v2/README.md create mode 100644 vendor/github.com/cespare/xxhash/v2/go.mod create mode 100644 vendor/github.com/cespare/xxhash/v2/go.sum create mode 100644 vendor/github.com/cespare/xxhash/v2/xxhash.go create mode 100644 vendor/github.com/cespare/xxhash/v2/xxhash_amd64.go create mode 100644 vendor/github.com/cespare/xxhash/v2/xxhash_amd64.s create mode 100644 vendor/github.com/cespare/xxhash/v2/xxhash_other.go create mode 100644 vendor/github.com/cespare/xxhash/v2/xxhash_safe.go create mode 100644 vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go create mode 100644 vendor/github.com/cpuguy83/go-md2man/v2/LICENSE.md create mode 100644 vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go create mode 100644 vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go create mode 100644 vendor/github.com/creasty/defaults/.gitignore create mode 100644 vendor/github.com/creasty/defaults/LICENSE create mode 100644 vendor/github.com/creasty/defaults/Makefile create mode 100644 vendor/github.com/creasty/defaults/README.md create mode 100644 vendor/github.com/creasty/defaults/defaults.go create mode 100644 vendor/github.com/creasty/defaults/go.mod create mode 100644 vendor/github.com/creasty/defaults/go.sum create mode 100644 vendor/github.com/creasty/defaults/setter.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/LICENSE create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/README.md create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/compressedbytepoints.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/doc.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdh.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ellipticadaptor.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/error.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/field.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/genstatics.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/go.mod create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/go.sum create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/loadprecomputed.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/modnscalar.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/nonce.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/privkey.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/pubkey.go create mode 100644 vendor/github.com/dgryski/go-rendezvous/LICENSE create mode 100644 vendor/github.com/dgryski/go-rendezvous/rdv.go create mode 100644 vendor/github.com/fullstorydev/grpcurl/.gitignore create mode 100644 vendor/github.com/fullstorydev/grpcurl/.goreleaser.yml create mode 100644 vendor/github.com/fullstorydev/grpcurl/Dockerfile create mode 100644 vendor/github.com/fullstorydev/grpcurl/LICENSE create mode 100644 vendor/github.com/fullstorydev/grpcurl/Makefile create mode 100644 vendor/github.com/fullstorydev/grpcurl/README.md create mode 100644 vendor/github.com/fullstorydev/grpcurl/desc_source.go create mode 100644 vendor/github.com/fullstorydev/grpcurl/format.go create mode 100644 vendor/github.com/fullstorydev/grpcurl/go.mod create mode 100644 vendor/github.com/fullstorydev/grpcurl/go.sum create mode 100644 vendor/github.com/fullstorydev/grpcurl/grpcurl.go create mode 100644 vendor/github.com/fullstorydev/grpcurl/invoke.go create mode 100644 vendor/github.com/fullstorydev/grpcurl/mk-test-files.sh create mode 100644 vendor/github.com/gin-contrib/sse/.travis.yml create mode 100644 vendor/github.com/gin-contrib/sse/LICENSE create mode 100644 vendor/github.com/gin-contrib/sse/README.md create mode 100644 vendor/github.com/gin-contrib/sse/go.mod create mode 100644 vendor/github.com/gin-contrib/sse/go.sum create mode 100644 vendor/github.com/gin-contrib/sse/sse-decoder.go create mode 100644 vendor/github.com/gin-contrib/sse/sse-encoder.go create mode 100644 vendor/github.com/gin-contrib/sse/writer.go create mode 100644 vendor/github.com/gin-gonic/gin/.gitignore create mode 100644 vendor/github.com/gin-gonic/gin/.golangci.yml create mode 100644 vendor/github.com/gin-gonic/gin/.goreleaser.yaml create mode 100644 vendor/github.com/gin-gonic/gin/AUTHORS.md create mode 100644 vendor/github.com/gin-gonic/gin/BENCHMARKS.md create mode 100644 vendor/github.com/gin-gonic/gin/CHANGELOG.md create mode 100644 vendor/github.com/gin-gonic/gin/CODE_OF_CONDUCT.md create mode 100644 vendor/github.com/gin-gonic/gin/CONTRIBUTING.md create mode 100644 vendor/github.com/gin-gonic/gin/LICENSE create mode 100644 vendor/github.com/gin-gonic/gin/Makefile create mode 100644 vendor/github.com/gin-gonic/gin/README.md create mode 100644 vendor/github.com/gin-gonic/gin/any.go create mode 100644 vendor/github.com/gin-gonic/gin/auth.go create mode 100644 vendor/github.com/gin-gonic/gin/binding/any.go create mode 100644 vendor/github.com/gin-gonic/gin/binding/binding.go create mode 100644 vendor/github.com/gin-gonic/gin/binding/binding_nomsgpack.go create mode 100644 vendor/github.com/gin-gonic/gin/binding/default_validator.go create mode 100644 vendor/github.com/gin-gonic/gin/binding/form.go create mode 100644 vendor/github.com/gin-gonic/gin/binding/form_mapping.go create mode 100644 vendor/github.com/gin-gonic/gin/binding/header.go create mode 100644 vendor/github.com/gin-gonic/gin/binding/json.go create mode 100644 vendor/github.com/gin-gonic/gin/binding/msgpack.go create mode 100644 vendor/github.com/gin-gonic/gin/binding/multipart_form_mapping.go create mode 100644 vendor/github.com/gin-gonic/gin/binding/protobuf.go create mode 100644 vendor/github.com/gin-gonic/gin/binding/query.go create mode 100644 vendor/github.com/gin-gonic/gin/binding/toml.go create mode 100644 vendor/github.com/gin-gonic/gin/binding/uri.go create mode 100644 vendor/github.com/gin-gonic/gin/binding/xml.go create mode 100644 vendor/github.com/gin-gonic/gin/binding/yaml.go create mode 100644 vendor/github.com/gin-gonic/gin/codecov.yml create mode 100644 vendor/github.com/gin-gonic/gin/context.go create mode 100644 vendor/github.com/gin-gonic/gin/context_appengine.go create mode 100644 vendor/github.com/gin-gonic/gin/debug.go create mode 100644 vendor/github.com/gin-gonic/gin/deprecated.go create mode 100644 vendor/github.com/gin-gonic/gin/doc.go create mode 100644 vendor/github.com/gin-gonic/gin/errors.go create mode 100644 vendor/github.com/gin-gonic/gin/fs.go create mode 100644 vendor/github.com/gin-gonic/gin/gin.go create mode 100644 vendor/github.com/gin-gonic/gin/go.mod create mode 100644 vendor/github.com/gin-gonic/gin/go.sum create mode 100644 vendor/github.com/gin-gonic/gin/internal/bytesconv/bytesconv.go create mode 100644 vendor/github.com/gin-gonic/gin/internal/json/go_json.go create mode 100644 vendor/github.com/gin-gonic/gin/internal/json/json.go create mode 100644 vendor/github.com/gin-gonic/gin/internal/json/jsoniter.go create mode 100644 vendor/github.com/gin-gonic/gin/logger.go create mode 100644 vendor/github.com/gin-gonic/gin/mode.go create mode 100644 vendor/github.com/gin-gonic/gin/path.go create mode 100644 vendor/github.com/gin-gonic/gin/recovery.go create mode 100644 vendor/github.com/gin-gonic/gin/render/any.go create mode 100644 vendor/github.com/gin-gonic/gin/render/data.go create mode 100644 vendor/github.com/gin-gonic/gin/render/html.go create mode 100644 vendor/github.com/gin-gonic/gin/render/json.go create mode 100644 vendor/github.com/gin-gonic/gin/render/msgpack.go create mode 100644 vendor/github.com/gin-gonic/gin/render/protobuf.go create mode 100644 vendor/github.com/gin-gonic/gin/render/reader.go create mode 100644 vendor/github.com/gin-gonic/gin/render/redirect.go create mode 100644 vendor/github.com/gin-gonic/gin/render/render.go create mode 100644 vendor/github.com/gin-gonic/gin/render/text.go create mode 100644 vendor/github.com/gin-gonic/gin/render/toml.go create mode 100644 vendor/github.com/gin-gonic/gin/render/xml.go create mode 100644 vendor/github.com/gin-gonic/gin/render/yaml.go create mode 100644 vendor/github.com/gin-gonic/gin/response_writer.go create mode 100644 vendor/github.com/gin-gonic/gin/routergroup.go create mode 100644 vendor/github.com/gin-gonic/gin/test_helpers.go create mode 100644 vendor/github.com/gin-gonic/gin/tree.go create mode 100644 vendor/github.com/gin-gonic/gin/utils.go create mode 100644 vendor/github.com/gin-gonic/gin/version.go create mode 100644 vendor/github.com/go-chi/chi/.gitignore create mode 100644 vendor/github.com/go-chi/chi/CHANGELOG.md create mode 100644 vendor/github.com/go-chi/chi/CONTRIBUTING.md create mode 100644 vendor/github.com/go-chi/chi/LICENSE create mode 100644 vendor/github.com/go-chi/chi/Makefile create mode 100644 vendor/github.com/go-chi/chi/README.md create mode 100644 vendor/github.com/go-chi/chi/chain.go create mode 100644 vendor/github.com/go-chi/chi/chi.go create mode 100644 vendor/github.com/go-chi/chi/context.go create mode 100644 vendor/github.com/go-chi/chi/go.mod create mode 100644 vendor/github.com/go-chi/chi/mux.go create mode 100644 vendor/github.com/go-chi/chi/tree.go create mode 100644 vendor/github.com/go-chi/cors/LICENSE create mode 100644 vendor/github.com/go-chi/cors/README.md create mode 100644 vendor/github.com/go-chi/cors/cors.go create mode 100644 vendor/github.com/go-chi/cors/go.mod create mode 100644 vendor/github.com/go-chi/cors/utils.go create mode 100644 vendor/github.com/go-chi/render/.travis.yml create mode 100644 vendor/github.com/go-chi/render/LICENSE create mode 100644 vendor/github.com/go-chi/render/README.md create mode 100644 vendor/github.com/go-chi/render/content_type.go create mode 100644 vendor/github.com/go-chi/render/decoder.go create mode 100644 vendor/github.com/go-chi/render/render.go create mode 100644 vendor/github.com/go-chi/render/responder.go create mode 100644 vendor/github.com/go-playground/locales/.gitignore create mode 100644 vendor/github.com/go-playground/locales/.travis.yml create mode 100644 vendor/github.com/go-playground/locales/LICENSE create mode 100644 vendor/github.com/go-playground/locales/README.md create mode 100644 vendor/github.com/go-playground/locales/currency/currency.go create mode 100644 vendor/github.com/go-playground/locales/go.mod create mode 100644 vendor/github.com/go-playground/locales/go.sum create mode 100644 vendor/github.com/go-playground/locales/logo.png create mode 100644 vendor/github.com/go-playground/locales/rules.go create mode 100644 vendor/github.com/go-playground/universal-translator/.gitignore create mode 100644 vendor/github.com/go-playground/universal-translator/.travis.yml create mode 100644 vendor/github.com/go-playground/universal-translator/LICENSE create mode 100644 vendor/github.com/go-playground/universal-translator/Makefile create mode 100644 vendor/github.com/go-playground/universal-translator/README.md create mode 100644 vendor/github.com/go-playground/universal-translator/errors.go create mode 100644 vendor/github.com/go-playground/universal-translator/go.mod create mode 100644 vendor/github.com/go-playground/universal-translator/go.sum create mode 100644 vendor/github.com/go-playground/universal-translator/import_export.go create mode 100644 vendor/github.com/go-playground/universal-translator/logo.png create mode 100644 vendor/github.com/go-playground/universal-translator/translator.go create mode 100644 vendor/github.com/go-playground/universal-translator/universal_translator.go create mode 100644 vendor/github.com/go-playground/validator/v10/.gitignore create mode 100644 vendor/github.com/go-playground/validator/v10/LICENSE create mode 100644 vendor/github.com/go-playground/validator/v10/MAINTAINERS.md create mode 100644 vendor/github.com/go-playground/validator/v10/Makefile create mode 100644 vendor/github.com/go-playground/validator/v10/README.md create mode 100644 vendor/github.com/go-playground/validator/v10/baked_in.go create mode 100644 vendor/github.com/go-playground/validator/v10/cache.go create mode 100644 vendor/github.com/go-playground/validator/v10/country_codes.go create mode 100644 vendor/github.com/go-playground/validator/v10/currency_codes.go create mode 100644 vendor/github.com/go-playground/validator/v10/doc.go create mode 100644 vendor/github.com/go-playground/validator/v10/errors.go create mode 100644 vendor/github.com/go-playground/validator/v10/field_level.go create mode 100644 vendor/github.com/go-playground/validator/v10/go.mod create mode 100644 vendor/github.com/go-playground/validator/v10/go.sum create mode 100644 vendor/github.com/go-playground/validator/v10/logo.png create mode 100644 vendor/github.com/go-playground/validator/v10/postcode_regexes.go create mode 100644 vendor/github.com/go-playground/validator/v10/regexes.go create mode 100644 vendor/github.com/go-playground/validator/v10/struct_level.go create mode 100644 vendor/github.com/go-playground/validator/v10/translations.go create mode 100644 vendor/github.com/go-playground/validator/v10/util.go create mode 100644 vendor/github.com/go-playground/validator/v10/validator.go create mode 100644 vendor/github.com/go-playground/validator/v10/validator_instance.go create mode 100644 vendor/github.com/go-redis/redis/v8/.gitignore create mode 100644 vendor/github.com/go-redis/redis/v8/.golangci.yml create mode 100644 vendor/github.com/go-redis/redis/v8/.prettierrc.yml create mode 100644 vendor/github.com/go-redis/redis/v8/CHANGELOG.md create mode 100644 vendor/github.com/go-redis/redis/v8/LICENSE create mode 100644 vendor/github.com/go-redis/redis/v8/Makefile create mode 100644 vendor/github.com/go-redis/redis/v8/README.md create mode 100644 vendor/github.com/go-redis/redis/v8/RELEASING.md create mode 100644 vendor/github.com/go-redis/redis/v8/cluster.go create mode 100644 vendor/github.com/go-redis/redis/v8/cluster_commands.go create mode 100644 vendor/github.com/go-redis/redis/v8/command.go create mode 100644 vendor/github.com/go-redis/redis/v8/commands.go create mode 100644 vendor/github.com/go-redis/redis/v8/doc.go create mode 100644 vendor/github.com/go-redis/redis/v8/error.go create mode 100644 vendor/github.com/go-redis/redis/v8/go.mod create mode 100644 vendor/github.com/go-redis/redis/v8/go.sum create mode 100644 vendor/github.com/go-redis/redis/v8/internal/arg.go create mode 100644 vendor/github.com/go-redis/redis/v8/internal/hashtag/hashtag.go create mode 100644 vendor/github.com/go-redis/redis/v8/internal/hscan/hscan.go create mode 100644 vendor/github.com/go-redis/redis/v8/internal/hscan/structmap.go create mode 100644 vendor/github.com/go-redis/redis/v8/internal/internal.go create mode 100644 vendor/github.com/go-redis/redis/v8/internal/log.go create mode 100644 vendor/github.com/go-redis/redis/v8/internal/once.go create mode 100644 vendor/github.com/go-redis/redis/v8/internal/pool/conn.go create mode 100644 vendor/github.com/go-redis/redis/v8/internal/pool/pool.go create mode 100644 vendor/github.com/go-redis/redis/v8/internal/pool/pool_single.go create mode 100644 vendor/github.com/go-redis/redis/v8/internal/pool/pool_sticky.go create mode 100644 vendor/github.com/go-redis/redis/v8/internal/proto/reader.go create mode 100644 vendor/github.com/go-redis/redis/v8/internal/proto/scan.go create mode 100644 vendor/github.com/go-redis/redis/v8/internal/proto/writer.go create mode 100644 vendor/github.com/go-redis/redis/v8/internal/rand/rand.go create mode 100644 vendor/github.com/go-redis/redis/v8/internal/safe.go create mode 100644 vendor/github.com/go-redis/redis/v8/internal/unsafe.go create mode 100644 vendor/github.com/go-redis/redis/v8/internal/util.go create mode 100644 vendor/github.com/go-redis/redis/v8/internal/util/safe.go create mode 100644 vendor/github.com/go-redis/redis/v8/internal/util/strconv.go create mode 100644 vendor/github.com/go-redis/redis/v8/internal/util/unsafe.go create mode 100644 vendor/github.com/go-redis/redis/v8/iterator.go create mode 100644 vendor/github.com/go-redis/redis/v8/options.go create mode 100644 vendor/github.com/go-redis/redis/v8/package.json create mode 100644 vendor/github.com/go-redis/redis/v8/pipeline.go create mode 100644 vendor/github.com/go-redis/redis/v8/pubsub.go create mode 100644 vendor/github.com/go-redis/redis/v8/redis.go create mode 100644 vendor/github.com/go-redis/redis/v8/result.go create mode 100644 vendor/github.com/go-redis/redis/v8/ring.go create mode 100644 vendor/github.com/go-redis/redis/v8/script.go create mode 100644 vendor/github.com/go-redis/redis/v8/sentinel.go create mode 100644 vendor/github.com/go-redis/redis/v8/tx.go create mode 100644 vendor/github.com/go-redis/redis/v8/universal.go create mode 100644 vendor/github.com/go-redis/redis/v8/version.go create mode 100644 vendor/github.com/go-stack/stack/LICENSE.md create mode 100644 vendor/github.com/go-stack/stack/README.md create mode 100644 vendor/github.com/go-stack/stack/go.mod create mode 100644 vendor/github.com/go-stack/stack/stack.go create mode 100644 vendor/github.com/go-test/deep/.gitignore create mode 100644 vendor/github.com/go-test/deep/.travis.yml create mode 100644 vendor/github.com/go-test/deep/CHANGES.md create mode 100644 vendor/github.com/go-test/deep/LICENSE create mode 100644 vendor/github.com/go-test/deep/README.md create mode 100644 vendor/github.com/go-test/deep/SECURITY.md create mode 100644 vendor/github.com/go-test/deep/deep.go create mode 100644 vendor/github.com/go-test/deep/go.mod create mode 100644 vendor/github.com/go-test/deep/go.sum create mode 100644 vendor/github.com/goccy/go-json/.codecov.yml create mode 100644 vendor/github.com/goccy/go-json/.gitignore create mode 100644 vendor/github.com/goccy/go-json/.golangci.yml create mode 100644 vendor/github.com/goccy/go-json/CHANGELOG.md create mode 100644 vendor/github.com/goccy/go-json/LICENSE create mode 100644 vendor/github.com/goccy/go-json/Makefile create mode 100644 vendor/github.com/goccy/go-json/README.md create mode 100644 vendor/github.com/goccy/go-json/color.go create mode 100644 vendor/github.com/goccy/go-json/decode.go create mode 100644 vendor/github.com/goccy/go-json/docker-compose.yml create mode 100644 vendor/github.com/goccy/go-json/encode.go create mode 100644 vendor/github.com/goccy/go-json/error.go create mode 100644 vendor/github.com/goccy/go-json/go.mod create mode 100644 vendor/github.com/goccy/go-json/go.sum create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/anonymous_field.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/array.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/bool.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/bytes.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/compile.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/compile_norace.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/compile_race.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/context.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/float.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/func.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/int.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/interface.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/invalid.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/map.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/number.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/option.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/ptr.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/slice.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/stream.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/string.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/struct.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/type.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/uint.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/unmarshal_json.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/unmarshal_text.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/wrapped_string.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/code.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/compact.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/compiler.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/compiler_norace.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/compiler_race.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/context.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/decode_rune.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/encoder.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/indent.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/int.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/map112.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/map113.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/opcode.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/option.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/optype.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/query.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/string.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/string_table.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm/debug_vm.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm/hack.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm/util.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm/vm.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_color/debug_vm.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_color/hack.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_color/util.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_color/vm.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/debug_vm.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/util.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/vm.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_indent/debug_vm.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_indent/hack.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_indent/util.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_indent/vm.go create mode 100644 vendor/github.com/goccy/go-json/internal/errors/error.go create mode 100644 vendor/github.com/goccy/go-json/internal/runtime/rtype.go create mode 100644 vendor/github.com/goccy/go-json/internal/runtime/struct_field.go create mode 100644 vendor/github.com/goccy/go-json/internal/runtime/type.go create mode 100644 vendor/github.com/goccy/go-json/json.go create mode 100644 vendor/github.com/goccy/go-json/option.go create mode 100644 vendor/github.com/goccy/go-json/query.go create mode 100644 vendor/github.com/golang/protobuf/AUTHORS create mode 100644 vendor/github.com/golang/protobuf/CONTRIBUTORS create mode 100644 vendor/github.com/golang/protobuf/LICENSE create mode 100644 vendor/github.com/golang/protobuf/jsonpb/decode.go create mode 100644 vendor/github.com/golang/protobuf/jsonpb/encode.go create mode 100644 vendor/github.com/golang/protobuf/jsonpb/json.go create mode 100644 vendor/github.com/golang/protobuf/proto/buffer.go create mode 100644 vendor/github.com/golang/protobuf/proto/defaults.go create mode 100644 vendor/github.com/golang/protobuf/proto/deprecated.go create mode 100644 vendor/github.com/golang/protobuf/proto/discard.go create mode 100644 vendor/github.com/golang/protobuf/proto/extensions.go create mode 100644 vendor/github.com/golang/protobuf/proto/properties.go create mode 100644 vendor/github.com/golang/protobuf/proto/proto.go create mode 100644 vendor/github.com/golang/protobuf/proto/registry.go create mode 100644 vendor/github.com/golang/protobuf/proto/text_decode.go create mode 100644 vendor/github.com/golang/protobuf/proto/text_encode.go create mode 100644 vendor/github.com/golang/protobuf/proto/wire.go create mode 100644 vendor/github.com/golang/protobuf/proto/wrappers.go create mode 100644 vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.pb.go create mode 100644 vendor/github.com/golang/protobuf/protoc-gen-go/plugin/plugin.pb.go create mode 100644 vendor/github.com/golang/protobuf/ptypes/any.go create mode 100644 vendor/github.com/golang/protobuf/ptypes/any/any.pb.go create mode 100644 vendor/github.com/golang/protobuf/ptypes/doc.go create mode 100644 vendor/github.com/golang/protobuf/ptypes/duration.go create mode 100644 vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go create mode 100644 vendor/github.com/golang/protobuf/ptypes/empty/empty.pb.go create mode 100644 vendor/github.com/golang/protobuf/ptypes/struct/struct.pb.go create mode 100644 vendor/github.com/golang/protobuf/ptypes/timestamp.go create mode 100644 vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go create mode 100644 vendor/github.com/golang/protobuf/ptypes/wrappers/wrappers.pb.go create mode 100644 vendor/github.com/golang/snappy/.gitignore create mode 100644 vendor/github.com/golang/snappy/AUTHORS create mode 100644 vendor/github.com/golang/snappy/CONTRIBUTORS create mode 100644 vendor/github.com/golang/snappy/LICENSE create mode 100644 vendor/github.com/golang/snappy/README create mode 100644 vendor/github.com/golang/snappy/decode.go create mode 100644 vendor/github.com/golang/snappy/decode_amd64.s create mode 100644 vendor/github.com/golang/snappy/decode_arm64.s create mode 100644 vendor/github.com/golang/snappy/decode_asm.go create mode 100644 vendor/github.com/golang/snappy/decode_other.go create mode 100644 vendor/github.com/golang/snappy/encode.go create mode 100644 vendor/github.com/golang/snappy/encode_amd64.s create mode 100644 vendor/github.com/golang/snappy/encode_arm64.s create mode 100644 vendor/github.com/golang/snappy/encode_asm.go create mode 100644 vendor/github.com/golang/snappy/encode_other.go create mode 100644 vendor/github.com/golang/snappy/go.mod create mode 100644 vendor/github.com/golang/snappy/snappy.go create mode 100644 vendor/github.com/google/uuid/.travis.yml create mode 100644 vendor/github.com/google/uuid/CONTRIBUTING.md create mode 100644 vendor/github.com/google/uuid/CONTRIBUTORS create mode 100644 vendor/github.com/google/uuid/LICENSE create mode 100644 vendor/github.com/google/uuid/README.md create mode 100644 vendor/github.com/google/uuid/dce.go create mode 100644 vendor/github.com/google/uuid/doc.go create mode 100644 vendor/github.com/google/uuid/go.mod create mode 100644 vendor/github.com/google/uuid/hash.go create mode 100644 vendor/github.com/google/uuid/marshal.go create mode 100644 vendor/github.com/google/uuid/node.go create mode 100644 vendor/github.com/google/uuid/node_js.go create mode 100644 vendor/github.com/google/uuid/node_net.go create mode 100644 vendor/github.com/google/uuid/null.go create mode 100644 vendor/github.com/google/uuid/sql.go create mode 100644 vendor/github.com/google/uuid/time.go create mode 100644 vendor/github.com/google/uuid/util.go create mode 100644 vendor/github.com/google/uuid/uuid.go create mode 100644 vendor/github.com/google/uuid/version1.go create mode 100644 vendor/github.com/google/uuid/version4.go create mode 100644 vendor/github.com/gorilla/mux/AUTHORS create mode 100644 vendor/github.com/gorilla/mux/LICENSE create mode 100644 vendor/github.com/gorilla/mux/README.md create mode 100644 vendor/github.com/gorilla/mux/doc.go create mode 100644 vendor/github.com/gorilla/mux/go.mod create mode 100644 vendor/github.com/gorilla/mux/middleware.go create mode 100644 vendor/github.com/gorilla/mux/mux.go create mode 100644 vendor/github.com/gorilla/mux/regexp.go create mode 100644 vendor/github.com/gorilla/mux/route.go create mode 100644 vendor/github.com/gorilla/mux/test_helpers.go create mode 100644 vendor/github.com/gorilla/websocket/.gitignore create mode 100644 vendor/github.com/gorilla/websocket/AUTHORS create mode 100644 vendor/github.com/gorilla/websocket/LICENSE create mode 100644 vendor/github.com/gorilla/websocket/README.md create mode 100644 vendor/github.com/gorilla/websocket/client.go create mode 100644 vendor/github.com/gorilla/websocket/client_clone.go create mode 100644 vendor/github.com/gorilla/websocket/client_clone_legacy.go create mode 100644 vendor/github.com/gorilla/websocket/compression.go create mode 100644 vendor/github.com/gorilla/websocket/conn.go create mode 100644 vendor/github.com/gorilla/websocket/conn_write.go create mode 100644 vendor/github.com/gorilla/websocket/conn_write_legacy.go create mode 100644 vendor/github.com/gorilla/websocket/doc.go create mode 100644 vendor/github.com/gorilla/websocket/go.mod create mode 100644 vendor/github.com/gorilla/websocket/go.sum create mode 100644 vendor/github.com/gorilla/websocket/join.go create mode 100644 vendor/github.com/gorilla/websocket/json.go create mode 100644 vendor/github.com/gorilla/websocket/mask.go create mode 100644 vendor/github.com/gorilla/websocket/mask_safe.go create mode 100644 vendor/github.com/gorilla/websocket/prepared.go create mode 100644 vendor/github.com/gorilla/websocket/proxy.go create mode 100644 vendor/github.com/gorilla/websocket/server.go create mode 100644 vendor/github.com/gorilla/websocket/trace.go create mode 100644 vendor/github.com/gorilla/websocket/trace_17.go create mode 100644 vendor/github.com/gorilla/websocket/util.go create mode 100644 vendor/github.com/gorilla/websocket/x_net_proxy.go create mode 100644 vendor/github.com/hashicorp/golang-lru/.gitignore create mode 100644 vendor/github.com/hashicorp/golang-lru/2q.go create mode 100644 vendor/github.com/hashicorp/golang-lru/LICENSE create mode 100644 vendor/github.com/hashicorp/golang-lru/README.md create mode 100644 vendor/github.com/hashicorp/golang-lru/arc.go create mode 100644 vendor/github.com/hashicorp/golang-lru/doc.go create mode 100644 vendor/github.com/hashicorp/golang-lru/go.mod create mode 100644 vendor/github.com/hashicorp/golang-lru/lru.go create mode 100644 vendor/github.com/hashicorp/golang-lru/simplelru/lru.go create mode 100644 vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go create mode 100644 vendor/github.com/jhump/protoreflect/LICENSE create mode 100644 vendor/github.com/jhump/protoreflect/codec/codec.go create mode 100644 vendor/github.com/jhump/protoreflect/codec/decode_fields.go create mode 100644 vendor/github.com/jhump/protoreflect/codec/doc.go create mode 100644 vendor/github.com/jhump/protoreflect/codec/encode_fields.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/convert.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/descriptor.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/descriptor_no_unsafe.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/descriptor_unsafe.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/doc.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/imports.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/internal/proto3_optional.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/internal/source_info.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/internal/util.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/load.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoparse/.gitignore create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoparse/ast.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoparse/ast/doc.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoparse/ast/enum.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoparse/ast/field.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoparse/ast/file.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoparse/ast/identifiers.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoparse/ast/message.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoparse/ast/no_source.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoparse/ast/node.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoparse/ast/options.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoparse/ast/print.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoparse/ast/ranges.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoparse/ast/service.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoparse/ast/source_pos.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoparse/ast/values.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoparse/ast/walk.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoparse/descriptor_protos.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoparse/doc.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoparse/errors.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoparse/lexer.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoparse/linker.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoparse/options.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoparse/parser.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoparse/proto.y create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoparse/proto.y.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoparse/resolve_files.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoparse/source_code_info.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoparse/std_imports.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoparse/test-source-info.txt create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoparse/validate.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoprint/doc.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoprint/print.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/protoprint/sort.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/sourceinfo/locations.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/sourceinfo/registry.go create mode 100644 vendor/github.com/jhump/protoreflect/desc/sourceinfo/wrappers.go create mode 100644 vendor/github.com/jhump/protoreflect/dynamic/binary.go create mode 100644 vendor/github.com/jhump/protoreflect/dynamic/doc.go create mode 100644 vendor/github.com/jhump/protoreflect/dynamic/dynamic_message.go create mode 100644 vendor/github.com/jhump/protoreflect/dynamic/equal.go create mode 100644 vendor/github.com/jhump/protoreflect/dynamic/extension.go create mode 100644 vendor/github.com/jhump/protoreflect/dynamic/extension_registry.go create mode 100644 vendor/github.com/jhump/protoreflect/dynamic/grpcdynamic/stub.go create mode 100644 vendor/github.com/jhump/protoreflect/dynamic/indent.go create mode 100644 vendor/github.com/jhump/protoreflect/dynamic/json.go create mode 100644 vendor/github.com/jhump/protoreflect/dynamic/maps_1.11.go create mode 100644 vendor/github.com/jhump/protoreflect/dynamic/maps_1.12.go create mode 100644 vendor/github.com/jhump/protoreflect/dynamic/merge.go create mode 100644 vendor/github.com/jhump/protoreflect/dynamic/message_factory.go create mode 100644 vendor/github.com/jhump/protoreflect/dynamic/text.go create mode 100644 vendor/github.com/jhump/protoreflect/grpcreflect/client.go create mode 100644 vendor/github.com/jhump/protoreflect/grpcreflect/doc.go create mode 100644 vendor/github.com/jhump/protoreflect/grpcreflect/internal/grpc_reflection_v1/reflection.pb.go create mode 100644 vendor/github.com/jhump/protoreflect/grpcreflect/internal/grpc_reflection_v1/reflection.proto create mode 100644 vendor/github.com/jhump/protoreflect/grpcreflect/internal/grpc_reflection_v1/reflection_grpc.pb.go create mode 100644 vendor/github.com/jhump/protoreflect/grpcreflect/internal/grpc_reflection_v1/svc_impl.go create mode 100644 vendor/github.com/jhump/protoreflect/grpcreflect/server.go create mode 100644 vendor/github.com/jhump/protoreflect/internal/codec/buffer.go create mode 100644 vendor/github.com/jhump/protoreflect/internal/codec/decode.go create mode 100644 vendor/github.com/jhump/protoreflect/internal/codec/encode.go create mode 100644 vendor/github.com/jhump/protoreflect/internal/standard_files.go create mode 100644 vendor/github.com/jhump/protoreflect/internal/unrecognized.go create mode 100644 vendor/github.com/jmespath/go-jmespath/.gitignore create mode 100644 vendor/github.com/jmespath/go-jmespath/.travis.yml create mode 100644 vendor/github.com/jmespath/go-jmespath/LICENSE create mode 100644 vendor/github.com/jmespath/go-jmespath/Makefile create mode 100644 vendor/github.com/jmespath/go-jmespath/README.md create mode 100644 vendor/github.com/jmespath/go-jmespath/api.go create mode 100644 vendor/github.com/jmespath/go-jmespath/astnodetype_string.go create mode 100644 vendor/github.com/jmespath/go-jmespath/functions.go create mode 100644 vendor/github.com/jmespath/go-jmespath/go.mod create mode 100644 vendor/github.com/jmespath/go-jmespath/go.sum create mode 100644 vendor/github.com/jmespath/go-jmespath/interpreter.go create mode 100644 vendor/github.com/jmespath/go-jmespath/lexer.go create mode 100644 vendor/github.com/jmespath/go-jmespath/parser.go create mode 100644 vendor/github.com/jmespath/go-jmespath/toktype_string.go create mode 100644 vendor/github.com/jmespath/go-jmespath/util.go create mode 100644 vendor/github.com/json-iterator/go/.codecov.yml create mode 100644 vendor/github.com/json-iterator/go/.gitignore create mode 100644 vendor/github.com/json-iterator/go/.travis.yml create mode 100644 vendor/github.com/json-iterator/go/Gopkg.lock create mode 100644 vendor/github.com/json-iterator/go/Gopkg.toml create mode 100644 vendor/github.com/json-iterator/go/LICENSE create mode 100644 vendor/github.com/json-iterator/go/README.md create mode 100644 vendor/github.com/json-iterator/go/adapter.go create mode 100644 vendor/github.com/json-iterator/go/any.go create mode 100644 vendor/github.com/json-iterator/go/any_array.go create mode 100644 vendor/github.com/json-iterator/go/any_bool.go create mode 100644 vendor/github.com/json-iterator/go/any_float.go create mode 100644 vendor/github.com/json-iterator/go/any_int32.go create mode 100644 vendor/github.com/json-iterator/go/any_int64.go create mode 100644 vendor/github.com/json-iterator/go/any_invalid.go create mode 100644 vendor/github.com/json-iterator/go/any_nil.go create mode 100644 vendor/github.com/json-iterator/go/any_number.go create mode 100644 vendor/github.com/json-iterator/go/any_object.go create mode 100644 vendor/github.com/json-iterator/go/any_str.go create mode 100644 vendor/github.com/json-iterator/go/any_uint32.go create mode 100644 vendor/github.com/json-iterator/go/any_uint64.go create mode 100644 vendor/github.com/json-iterator/go/build.sh create mode 100644 vendor/github.com/json-iterator/go/config.go create mode 100644 vendor/github.com/json-iterator/go/fuzzy_mode_convert_table.md create mode 100644 vendor/github.com/json-iterator/go/go.mod create mode 100644 vendor/github.com/json-iterator/go/go.sum create mode 100644 vendor/github.com/json-iterator/go/iter.go create mode 100644 vendor/github.com/json-iterator/go/iter_array.go create mode 100644 vendor/github.com/json-iterator/go/iter_float.go create mode 100644 vendor/github.com/json-iterator/go/iter_int.go create mode 100644 vendor/github.com/json-iterator/go/iter_object.go create mode 100644 vendor/github.com/json-iterator/go/iter_skip.go create mode 100644 vendor/github.com/json-iterator/go/iter_skip_sloppy.go create mode 100644 vendor/github.com/json-iterator/go/iter_skip_strict.go create mode 100644 vendor/github.com/json-iterator/go/iter_str.go create mode 100644 vendor/github.com/json-iterator/go/jsoniter.go create mode 100644 vendor/github.com/json-iterator/go/pool.go create mode 100644 vendor/github.com/json-iterator/go/reflect.go create mode 100644 vendor/github.com/json-iterator/go/reflect_array.go create mode 100644 vendor/github.com/json-iterator/go/reflect_dynamic.go create mode 100644 vendor/github.com/json-iterator/go/reflect_extension.go create mode 100644 vendor/github.com/json-iterator/go/reflect_json_number.go create mode 100644 vendor/github.com/json-iterator/go/reflect_json_raw_message.go create mode 100644 vendor/github.com/json-iterator/go/reflect_map.go create mode 100644 vendor/github.com/json-iterator/go/reflect_marshaler.go create mode 100644 vendor/github.com/json-iterator/go/reflect_native.go create mode 100644 vendor/github.com/json-iterator/go/reflect_optional.go create mode 100644 vendor/github.com/json-iterator/go/reflect_slice.go create mode 100644 vendor/github.com/json-iterator/go/reflect_struct_decoder.go create mode 100644 vendor/github.com/json-iterator/go/reflect_struct_encoder.go create mode 100644 vendor/github.com/json-iterator/go/stream.go create mode 100644 vendor/github.com/json-iterator/go/stream_float.go create mode 100644 vendor/github.com/json-iterator/go/stream_int.go create mode 100644 vendor/github.com/json-iterator/go/stream_str.go create mode 100644 vendor/github.com/json-iterator/go/test.sh create mode 100644 vendor/github.com/k0kubun/pp/v3/.github_changelog_generator create mode 100644 vendor/github.com/k0kubun/pp/v3/CHANGELOG.md create mode 100644 vendor/github.com/k0kubun/pp/v3/LICENSE.txt create mode 100644 vendor/github.com/k0kubun/pp/v3/README.md create mode 100644 vendor/github.com/k0kubun/pp/v3/color.go create mode 100644 vendor/github.com/k0kubun/pp/v3/go.mod create mode 100644 vendor/github.com/k0kubun/pp/v3/go.sum create mode 100644 vendor/github.com/k0kubun/pp/v3/pp.go create mode 100644 vendor/github.com/k0kubun/pp/v3/printer.go create mode 100644 vendor/github.com/k0kubun/pp/v3/sort.go create mode 100644 vendor/github.com/kelseyhightower/envconfig/.travis.yml create mode 100644 vendor/github.com/kelseyhightower/envconfig/LICENSE create mode 100644 vendor/github.com/kelseyhightower/envconfig/MAINTAINERS create mode 100644 vendor/github.com/kelseyhightower/envconfig/README.md create mode 100644 vendor/github.com/kelseyhightower/envconfig/doc.go create mode 100644 vendor/github.com/kelseyhightower/envconfig/env_os.go create mode 100644 vendor/github.com/kelseyhightower/envconfig/env_syscall.go create mode 100644 vendor/github.com/kelseyhightower/envconfig/envconfig.go create mode 100644 vendor/github.com/kelseyhightower/envconfig/go.mod create mode 100644 vendor/github.com/kelseyhightower/envconfig/usage.go create mode 100644 vendor/github.com/klauspost/compress/.gitattributes create mode 100644 vendor/github.com/klauspost/compress/.gitignore create mode 100644 vendor/github.com/klauspost/compress/.goreleaser.yml create mode 100644 vendor/github.com/klauspost/compress/LICENSE create mode 100644 vendor/github.com/klauspost/compress/README.md create mode 100644 vendor/github.com/klauspost/compress/compressible.go create mode 100644 vendor/github.com/klauspost/compress/flate/deflate.go create mode 100644 vendor/github.com/klauspost/compress/flate/dict_decoder.go create mode 100644 vendor/github.com/klauspost/compress/flate/fast_encoder.go create mode 100644 vendor/github.com/klauspost/compress/flate/huffman_bit_writer.go create mode 100644 vendor/github.com/klauspost/compress/flate/huffman_code.go create mode 100644 vendor/github.com/klauspost/compress/flate/huffman_sortByFreq.go create mode 100644 vendor/github.com/klauspost/compress/flate/huffman_sortByLiteral.go create mode 100644 vendor/github.com/klauspost/compress/flate/inflate.go create mode 100644 vendor/github.com/klauspost/compress/flate/inflate_gen.go create mode 100644 vendor/github.com/klauspost/compress/flate/level1.go create mode 100644 vendor/github.com/klauspost/compress/flate/level2.go create mode 100644 vendor/github.com/klauspost/compress/flate/level3.go create mode 100644 vendor/github.com/klauspost/compress/flate/level4.go create mode 100644 vendor/github.com/klauspost/compress/flate/level5.go create mode 100644 vendor/github.com/klauspost/compress/flate/level6.go create mode 100644 vendor/github.com/klauspost/compress/flate/regmask_amd64.go create mode 100644 vendor/github.com/klauspost/compress/flate/regmask_other.go create mode 100644 vendor/github.com/klauspost/compress/flate/stateless.go create mode 100644 vendor/github.com/klauspost/compress/flate/token.go create mode 100644 vendor/github.com/klauspost/compress/fse/README.md create mode 100644 vendor/github.com/klauspost/compress/fse/bitreader.go create mode 100644 vendor/github.com/klauspost/compress/fse/bitwriter.go create mode 100644 vendor/github.com/klauspost/compress/fse/bytereader.go create mode 100644 vendor/github.com/klauspost/compress/fse/compress.go create mode 100644 vendor/github.com/klauspost/compress/fse/decompress.go create mode 100644 vendor/github.com/klauspost/compress/fse/fse.go create mode 100644 vendor/github.com/klauspost/compress/gen.sh create mode 100644 vendor/github.com/klauspost/compress/go.mod create mode 100644 vendor/github.com/klauspost/compress/go.sum create mode 100644 vendor/github.com/klauspost/compress/gzip/gunzip.go create mode 100644 vendor/github.com/klauspost/compress/gzip/gzip.go create mode 100644 vendor/github.com/klauspost/compress/huff0/.gitignore create mode 100644 vendor/github.com/klauspost/compress/huff0/README.md create mode 100644 vendor/github.com/klauspost/compress/huff0/bitreader.go create mode 100644 vendor/github.com/klauspost/compress/huff0/bitwriter.go create mode 100644 vendor/github.com/klauspost/compress/huff0/bytereader.go create mode 100644 vendor/github.com/klauspost/compress/huff0/compress.go create mode 100644 vendor/github.com/klauspost/compress/huff0/decompress.go create mode 100644 vendor/github.com/klauspost/compress/huff0/decompress_amd64.go create mode 100644 vendor/github.com/klauspost/compress/huff0/decompress_amd64.s create mode 100644 vendor/github.com/klauspost/compress/huff0/decompress_generic.go create mode 100644 vendor/github.com/klauspost/compress/huff0/huff0.go create mode 100644 vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo.go create mode 100644 vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo_amd64.go create mode 100644 vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo_amd64.s create mode 100644 vendor/github.com/klauspost/compress/internal/snapref/LICENSE create mode 100644 vendor/github.com/klauspost/compress/internal/snapref/decode.go create mode 100644 vendor/github.com/klauspost/compress/internal/snapref/decode_other.go create mode 100644 vendor/github.com/klauspost/compress/internal/snapref/encode.go create mode 100644 vendor/github.com/klauspost/compress/internal/snapref/encode_other.go create mode 100644 vendor/github.com/klauspost/compress/internal/snapref/snappy.go create mode 100644 vendor/github.com/klauspost/compress/s2sx.mod create mode 100644 vendor/github.com/klauspost/compress/s2sx.sum create mode 100644 vendor/github.com/klauspost/compress/zlib/reader.go create mode 100644 vendor/github.com/klauspost/compress/zlib/writer.go create mode 100644 vendor/github.com/klauspost/compress/zstd/README.md create mode 100644 vendor/github.com/klauspost/compress/zstd/bitreader.go create mode 100644 vendor/github.com/klauspost/compress/zstd/bitwriter.go create mode 100644 vendor/github.com/klauspost/compress/zstd/blockdec.go create mode 100644 vendor/github.com/klauspost/compress/zstd/blockenc.go create mode 100644 vendor/github.com/klauspost/compress/zstd/blocktype_string.go create mode 100644 vendor/github.com/klauspost/compress/zstd/bytebuf.go create mode 100644 vendor/github.com/klauspost/compress/zstd/bytereader.go create mode 100644 vendor/github.com/klauspost/compress/zstd/decodeheader.go create mode 100644 vendor/github.com/klauspost/compress/zstd/decoder.go create mode 100644 vendor/github.com/klauspost/compress/zstd/decoder_options.go create mode 100644 vendor/github.com/klauspost/compress/zstd/dict.go create mode 100644 vendor/github.com/klauspost/compress/zstd/enc_base.go create mode 100644 vendor/github.com/klauspost/compress/zstd/enc_best.go create mode 100644 vendor/github.com/klauspost/compress/zstd/enc_better.go create mode 100644 vendor/github.com/klauspost/compress/zstd/enc_dfast.go create mode 100644 vendor/github.com/klauspost/compress/zstd/enc_fast.go create mode 100644 vendor/github.com/klauspost/compress/zstd/encoder.go create mode 100644 vendor/github.com/klauspost/compress/zstd/encoder_options.go create mode 100644 vendor/github.com/klauspost/compress/zstd/framedec.go create mode 100644 vendor/github.com/klauspost/compress/zstd/frameenc.go create mode 100644 vendor/github.com/klauspost/compress/zstd/fse_decoder.go create mode 100644 vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.go create mode 100644 vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.s create mode 100644 vendor/github.com/klauspost/compress/zstd/fse_decoder_generic.go create mode 100644 vendor/github.com/klauspost/compress/zstd/fse_encoder.go create mode 100644 vendor/github.com/klauspost/compress/zstd/fse_predefined.go create mode 100644 vendor/github.com/klauspost/compress/zstd/hash.go create mode 100644 vendor/github.com/klauspost/compress/zstd/history.go create mode 100644 vendor/github.com/klauspost/compress/zstd/internal/xxhash/LICENSE.txt create mode 100644 vendor/github.com/klauspost/compress/zstd/internal/xxhash/README.md create mode 100644 vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash.go create mode 100644 vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_amd64.s create mode 100644 vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_arm64.s create mode 100644 vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_asm.go create mode 100644 vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_other.go create mode 100644 vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_safe.go create mode 100644 vendor/github.com/klauspost/compress/zstd/seqdec.go create mode 100644 vendor/github.com/klauspost/compress/zstd/seqdec_amd64.go create mode 100644 vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s create mode 100644 vendor/github.com/klauspost/compress/zstd/seqdec_generic.go create mode 100644 vendor/github.com/klauspost/compress/zstd/seqenc.go create mode 100644 vendor/github.com/klauspost/compress/zstd/snappy.go create mode 100644 vendor/github.com/klauspost/compress/zstd/zip.go create mode 100644 vendor/github.com/klauspost/compress/zstd/zstd.go create mode 100644 vendor/github.com/labstack/echo/v4/.editorconfig create mode 100644 vendor/github.com/labstack/echo/v4/.gitattributes create mode 100644 vendor/github.com/labstack/echo/v4/.gitignore create mode 100644 vendor/github.com/labstack/echo/v4/.travis.yml create mode 100644 vendor/github.com/labstack/echo/v4/CHANGELOG.md create mode 100644 vendor/github.com/labstack/echo/v4/LICENSE create mode 100644 vendor/github.com/labstack/echo/v4/Makefile create mode 100644 vendor/github.com/labstack/echo/v4/README.md create mode 100644 vendor/github.com/labstack/echo/v4/bind.go create mode 100644 vendor/github.com/labstack/echo/v4/binder.go create mode 100644 vendor/github.com/labstack/echo/v4/codecov.yml create mode 100644 vendor/github.com/labstack/echo/v4/context.go create mode 100644 vendor/github.com/labstack/echo/v4/context_fs.go create mode 100644 vendor/github.com/labstack/echo/v4/echo.go create mode 100644 vendor/github.com/labstack/echo/v4/echo_fs.go create mode 100644 vendor/github.com/labstack/echo/v4/go.mod create mode 100644 vendor/github.com/labstack/echo/v4/go.sum create mode 100644 vendor/github.com/labstack/echo/v4/group.go create mode 100644 vendor/github.com/labstack/echo/v4/group_fs.go create mode 100644 vendor/github.com/labstack/echo/v4/ip.go create mode 100644 vendor/github.com/labstack/echo/v4/json.go create mode 100644 vendor/github.com/labstack/echo/v4/log.go create mode 100644 vendor/github.com/labstack/echo/v4/response.go create mode 100644 vendor/github.com/labstack/echo/v4/router.go create mode 100644 vendor/github.com/labstack/gommon/LICENSE create mode 100644 vendor/github.com/labstack/gommon/color/README.md create mode 100644 vendor/github.com/labstack/gommon/color/color.go create mode 100644 vendor/github.com/labstack/gommon/log/README.md create mode 100644 vendor/github.com/labstack/gommon/log/color.go create mode 100644 vendor/github.com/labstack/gommon/log/log.go create mode 100644 vendor/github.com/labstack/gommon/log/white.go create mode 100644 vendor/github.com/leodido/go-urn/.gitignore create mode 100644 vendor/github.com/leodido/go-urn/.travis.yml create mode 100644 vendor/github.com/leodido/go-urn/LICENSE create mode 100644 vendor/github.com/leodido/go-urn/README.md create mode 100644 vendor/github.com/leodido/go-urn/go.mod create mode 100644 vendor/github.com/leodido/go-urn/go.sum create mode 100644 vendor/github.com/leodido/go-urn/machine.go create mode 100644 vendor/github.com/leodido/go-urn/machine.go.rl create mode 100644 vendor/github.com/leodido/go-urn/makefile create mode 100644 vendor/github.com/leodido/go-urn/urn.go create mode 100644 vendor/github.com/lestrrat-go/backoff/v2/.gitignore create mode 100644 vendor/github.com/lestrrat-go/backoff/v2/.golangci.yml create mode 100644 vendor/github.com/lestrrat-go/backoff/v2/Changes create mode 100644 vendor/github.com/lestrrat-go/backoff/v2/LICENSE create mode 100644 vendor/github.com/lestrrat-go/backoff/v2/README.md create mode 100644 vendor/github.com/lestrrat-go/backoff/v2/backoff.go create mode 100644 vendor/github.com/lestrrat-go/backoff/v2/constant.go create mode 100644 vendor/github.com/lestrrat-go/backoff/v2/controller.go create mode 100644 vendor/github.com/lestrrat-go/backoff/v2/doc.go create mode 100644 vendor/github.com/lestrrat-go/backoff/v2/exponential.go create mode 100644 vendor/github.com/lestrrat-go/backoff/v2/go.mod create mode 100644 vendor/github.com/lestrrat-go/backoff/v2/go.sum create mode 100644 vendor/github.com/lestrrat-go/backoff/v2/interface.go create mode 100644 vendor/github.com/lestrrat-go/backoff/v2/jitter.go create mode 100644 vendor/github.com/lestrrat-go/backoff/v2/null.go create mode 100644 vendor/github.com/lestrrat-go/backoff/v2/options.go create mode 100644 vendor/github.com/lestrrat-go/blackmagic/.gitignore create mode 100644 vendor/github.com/lestrrat-go/blackmagic/LICENSE create mode 100644 vendor/github.com/lestrrat-go/blackmagic/README.md create mode 100644 vendor/github.com/lestrrat-go/blackmagic/blackmagic.go create mode 100644 vendor/github.com/lestrrat-go/blackmagic/go.mod create mode 100644 vendor/github.com/lestrrat-go/blackmagic/go.sum create mode 100644 vendor/github.com/lestrrat-go/httpcc/.gitignore create mode 100644 vendor/github.com/lestrrat-go/httpcc/LICENSE create mode 100644 vendor/github.com/lestrrat-go/httpcc/README.md create mode 100644 vendor/github.com/lestrrat-go/httpcc/directives.go create mode 100644 vendor/github.com/lestrrat-go/httpcc/go.mod create mode 100644 vendor/github.com/lestrrat-go/httpcc/go.sum create mode 100644 vendor/github.com/lestrrat-go/httpcc/httpcc.go create mode 100644 vendor/github.com/lestrrat-go/iter/LICENSE create mode 100644 vendor/github.com/lestrrat-go/iter/arrayiter/arrayiter.go create mode 100644 vendor/github.com/lestrrat-go/iter/mapiter/mapiter.go create mode 100644 vendor/github.com/lestrrat-go/jwx/.gitignore create mode 100644 vendor/github.com/lestrrat-go/jwx/.golangci.yml create mode 100644 vendor/github.com/lestrrat-go/jwx/Changes create mode 100644 vendor/github.com/lestrrat-go/jwx/LICENSE create mode 100644 vendor/github.com/lestrrat-go/jwx/Makefile create mode 100644 vendor/github.com/lestrrat-go/jwx/README.md create mode 100644 vendor/github.com/lestrrat-go/jwx/format.go create mode 100644 vendor/github.com/lestrrat-go/jwx/formatkind_string_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/gen.sh create mode 100644 vendor/github.com/lestrrat-go/jwx/go.mod create mode 100644 vendor/github.com/lestrrat-go/jwx/go.sum create mode 100644 vendor/github.com/lestrrat-go/jwx/internal/base64/base64.go create mode 100644 vendor/github.com/lestrrat-go/jwx/internal/ecutil/ecutil.go create mode 100644 vendor/github.com/lestrrat-go/jwx/internal/iter/mapiter.go create mode 100644 vendor/github.com/lestrrat-go/jwx/internal/json/goccy.go create mode 100644 vendor/github.com/lestrrat-go/jwx/internal/json/json.go create mode 100644 vendor/github.com/lestrrat-go/jwx/internal/json/registry.go create mode 100644 vendor/github.com/lestrrat-go/jwx/internal/json/stdlib.go create mode 100644 vendor/github.com/lestrrat-go/jwx/internal/keyconv/keyconv.go create mode 100644 vendor/github.com/lestrrat-go/jwx/internal/pool/pool.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwa/README.md create mode 100644 vendor/github.com/lestrrat-go/jwx/jwa/compression_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwa/content_encryption_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwa/elliptic_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwa/gen.sh create mode 100644 vendor/github.com/lestrrat-go/jwx/jwa/jwa.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwa/key_encryption_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwa/key_type_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwa/secp2561k.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwa/signature_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwe/README.md create mode 100644 vendor/github.com/lestrrat-go/jwx/jwe/compress.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwe/decrypt.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwe/encrypt.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwe/gen.sh create mode 100644 vendor/github.com/lestrrat-go/jwx/jwe/headers.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwe/headers_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwe/interface.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwe/internal/aescbc/aescbc.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwe/internal/cipher/cipher.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwe/internal/cipher/interface.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwe/internal/concatkdf/concatkdf.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwe/internal/content_crypt/content_crypt.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwe/internal/content_crypt/interface.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwe/internal/keyenc/interface.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwe/internal/keyenc/keyenc.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwe/internal/keygen/interface.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwe/internal/keygen/keygen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwe/io.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwe/jwe.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwe/message.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwe/options.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwe/serializer.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwk/README.md create mode 100644 vendor/github.com/lestrrat-go/jwx/jwk/certchain.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwk/ecdsa.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwk/ecdsa_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwk/es256k.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwk/gen.sh create mode 100644 vendor/github.com/lestrrat-go/jwx/jwk/interface.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwk/interface_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwk/io.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwk/jwk.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwk/key_ops.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwk/okp.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwk/okp_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwk/option.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwk/refresh.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwk/rsa.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwk/rsa_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwk/set.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwk/symmetric.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwk/symmetric_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwk/usage.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwk/whitelist.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jws/README.md create mode 100644 vendor/github.com/lestrrat-go/jwx/jws/ecdsa.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jws/eddsa.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jws/es256k.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jws/gen.sh create mode 100644 vendor/github.com/lestrrat-go/jwx/jws/headers.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jws/headers_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jws/hmac.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jws/interface.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jws/io.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jws/jws.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jws/message.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jws/option.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jws/rsa.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jws/signer.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jws/verifier.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwt/README.md create mode 100644 vendor/github.com/lestrrat-go/jwx/jwt/builder_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwt/gen.sh create mode 100644 vendor/github.com/lestrrat-go/jwx/jwt/http.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwt/interface.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwt/internal/types/date.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwt/internal/types/string.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwt/io.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwt/jwt.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwt/options.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwt/serialize.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwt/token_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwt/validate.go create mode 100644 vendor/github.com/lestrrat-go/jwx/jwx.go create mode 100644 vendor/github.com/lestrrat-go/jwx/options.go create mode 100644 vendor/github.com/lestrrat-go/jwx/x25519/x25519.go create mode 100644 vendor/github.com/lestrrat-go/option/.gitignore create mode 100644 vendor/github.com/lestrrat-go/option/LICENSE create mode 100644 vendor/github.com/lestrrat-go/option/README.md create mode 100644 vendor/github.com/lestrrat-go/option/go.mod create mode 100644 vendor/github.com/lestrrat-go/option/go.sum create mode 100644 vendor/github.com/lestrrat-go/option/option.go create mode 100644 vendor/github.com/matryer/moq/.gitignore create mode 100644 vendor/github.com/matryer/moq/.goreleaser.yml create mode 100644 vendor/github.com/matryer/moq/LICENSE create mode 100644 vendor/github.com/matryer/moq/README.md create mode 100644 vendor/github.com/matryer/moq/go.mod create mode 100644 vendor/github.com/matryer/moq/go.sum create mode 100644 vendor/github.com/matryer/moq/internal/registry/method_scope.go create mode 100644 vendor/github.com/matryer/moq/internal/registry/package.go create mode 100644 vendor/github.com/matryer/moq/internal/registry/registry.go create mode 100644 vendor/github.com/matryer/moq/internal/registry/var.go create mode 100644 vendor/github.com/matryer/moq/internal/template/template.go create mode 100644 vendor/github.com/matryer/moq/internal/template/template_data.go create mode 100644 vendor/github.com/matryer/moq/main.go create mode 100644 vendor/github.com/matryer/moq/moq-logo-small.png create mode 100644 vendor/github.com/matryer/moq/moq-logo.png create mode 100644 vendor/github.com/matryer/moq/pkg/moq/formatter.go create mode 100644 vendor/github.com/matryer/moq/pkg/moq/moq.go create mode 100644 vendor/github.com/matryer/moq/preview.png create mode 100644 vendor/github.com/matryer/moq/releasing.md create mode 100644 vendor/github.com/mattn/go-colorable/LICENSE create mode 100644 vendor/github.com/mattn/go-colorable/README.md create mode 100644 vendor/github.com/mattn/go-colorable/colorable_appengine.go create mode 100644 vendor/github.com/mattn/go-colorable/colorable_others.go create mode 100644 vendor/github.com/mattn/go-colorable/colorable_windows.go create mode 100644 vendor/github.com/mattn/go-colorable/go.mod create mode 100644 vendor/github.com/mattn/go-colorable/go.sum create mode 100644 vendor/github.com/mattn/go-colorable/go.test.sh create mode 100644 vendor/github.com/mattn/go-colorable/noncolorable.go create mode 100644 vendor/github.com/mattn/go-isatty/LICENSE create mode 100644 vendor/github.com/mattn/go-isatty/README.md create mode 100644 vendor/github.com/mattn/go-isatty/doc.go create mode 100644 vendor/github.com/mattn/go-isatty/go.mod create mode 100644 vendor/github.com/mattn/go-isatty/go.sum create mode 100644 vendor/github.com/mattn/go-isatty/go.test.sh create mode 100644 vendor/github.com/mattn/go-isatty/isatty_bsd.go create mode 100644 vendor/github.com/mattn/go-isatty/isatty_others.go create mode 100644 vendor/github.com/mattn/go-isatty/isatty_plan9.go create mode 100644 vendor/github.com/mattn/go-isatty/isatty_solaris.go create mode 100644 vendor/github.com/mattn/go-isatty/isatty_tcgets.go create mode 100644 vendor/github.com/mattn/go-isatty/isatty_windows.go create mode 100644 vendor/github.com/mitchellh/mapstructure/CHANGELOG.md create mode 100644 vendor/github.com/mitchellh/mapstructure/LICENSE create mode 100644 vendor/github.com/mitchellh/mapstructure/README.md create mode 100644 vendor/github.com/mitchellh/mapstructure/decode_hooks.go create mode 100644 vendor/github.com/mitchellh/mapstructure/error.go create mode 100644 vendor/github.com/mitchellh/mapstructure/go.mod create mode 100644 vendor/github.com/mitchellh/mapstructure/mapstructure.go create mode 100644 vendor/github.com/modern-go/concurrent/LICENSE create mode 100644 vendor/github.com/modern-go/concurrent/README.md create mode 100644 vendor/github.com/modern-go/concurrent/executor.go create mode 100644 vendor/github.com/modern-go/concurrent/go_above_19.go create mode 100644 vendor/github.com/modern-go/concurrent/go_below_19.go create mode 100644 vendor/github.com/modern-go/concurrent/unbounded_executor.go create mode 100644 vendor/github.com/modern-go/reflect2/.gitignore create mode 100644 vendor/github.com/modern-go/reflect2/.travis.yml create mode 100644 vendor/github.com/modern-go/reflect2/Gopkg.lock create mode 100644 vendor/github.com/modern-go/reflect2/Gopkg.toml create mode 100644 vendor/github.com/modern-go/reflect2/LICENSE create mode 100644 vendor/github.com/modern-go/reflect2/README.md create mode 100644 vendor/github.com/modern-go/reflect2/go.mod create mode 100644 vendor/github.com/modern-go/reflect2/go_above_118.go create mode 100644 vendor/github.com/modern-go/reflect2/go_above_19.go create mode 100644 vendor/github.com/modern-go/reflect2/go_below_118.go create mode 100644 vendor/github.com/modern-go/reflect2/reflect2.go create mode 100644 vendor/github.com/modern-go/reflect2/reflect2_amd64.s create mode 100644 vendor/github.com/modern-go/reflect2/reflect2_kind.go create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_386.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_amd64p32.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_arm.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_arm64.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_mips64x.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_mipsx.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_ppc64x.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_s390x.s create mode 100644 vendor/github.com/modern-go/reflect2/safe_field.go create mode 100644 vendor/github.com/modern-go/reflect2/safe_map.go create mode 100644 vendor/github.com/modern-go/reflect2/safe_slice.go create mode 100644 vendor/github.com/modern-go/reflect2/safe_struct.go create mode 100644 vendor/github.com/modern-go/reflect2/safe_type.go create mode 100644 vendor/github.com/modern-go/reflect2/type_map.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_array.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_eface.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_field.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_iface.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_link.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_map.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_ptr.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_slice.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_struct.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_type.go create mode 100644 vendor/github.com/pelletier/go-toml/v2/.dockerignore create mode 100644 vendor/github.com/pelletier/go-toml/v2/.gitattributes create mode 100644 vendor/github.com/pelletier/go-toml/v2/.gitignore create mode 100644 vendor/github.com/pelletier/go-toml/v2/.golangci.toml create mode 100644 vendor/github.com/pelletier/go-toml/v2/.goreleaser.yaml create mode 100644 vendor/github.com/pelletier/go-toml/v2/CONTRIBUTING.md create mode 100644 vendor/github.com/pelletier/go-toml/v2/Dockerfile create mode 100644 vendor/github.com/pelletier/go-toml/v2/LICENSE create mode 100644 vendor/github.com/pelletier/go-toml/v2/README.md create mode 100644 vendor/github.com/pelletier/go-toml/v2/SECURITY.md create mode 100644 vendor/github.com/pelletier/go-toml/v2/ci.sh create mode 100644 vendor/github.com/pelletier/go-toml/v2/decode.go create mode 100644 vendor/github.com/pelletier/go-toml/v2/doc.go create mode 100644 vendor/github.com/pelletier/go-toml/v2/errors.go create mode 100644 vendor/github.com/pelletier/go-toml/v2/go.mod create mode 100644 vendor/github.com/pelletier/go-toml/v2/go.sum create mode 100644 vendor/github.com/pelletier/go-toml/v2/internal/ast/ast.go create mode 100644 vendor/github.com/pelletier/go-toml/v2/internal/ast/builder.go create mode 100644 vendor/github.com/pelletier/go-toml/v2/internal/ast/kind.go create mode 100644 vendor/github.com/pelletier/go-toml/v2/internal/danger/danger.go create mode 100644 vendor/github.com/pelletier/go-toml/v2/internal/danger/typeid.go create mode 100644 vendor/github.com/pelletier/go-toml/v2/internal/tracker/key.go create mode 100644 vendor/github.com/pelletier/go-toml/v2/internal/tracker/seen.go create mode 100644 vendor/github.com/pelletier/go-toml/v2/internal/tracker/tracker.go create mode 100644 vendor/github.com/pelletier/go-toml/v2/localtime.go create mode 100644 vendor/github.com/pelletier/go-toml/v2/marshaler.go create mode 100644 vendor/github.com/pelletier/go-toml/v2/parser.go create mode 100644 vendor/github.com/pelletier/go-toml/v2/scanner.go create mode 100644 vendor/github.com/pelletier/go-toml/v2/strict.go create mode 100644 vendor/github.com/pelletier/go-toml/v2/toml.abnf create mode 100644 vendor/github.com/pelletier/go-toml/v2/types.go create mode 100644 vendor/github.com/pelletier/go-toml/v2/unmarshaler.go create mode 100644 vendor/github.com/pelletier/go-toml/v2/utf8.go create mode 100644 vendor/github.com/pkg/errors/.gitignore create mode 100644 vendor/github.com/pkg/errors/.travis.yml create mode 100644 vendor/github.com/pkg/errors/LICENSE create mode 100644 vendor/github.com/pkg/errors/Makefile create mode 100644 vendor/github.com/pkg/errors/README.md create mode 100644 vendor/github.com/pkg/errors/appveyor.yml create mode 100644 vendor/github.com/pkg/errors/errors.go create mode 100644 vendor/github.com/pkg/errors/go113.go create mode 100644 vendor/github.com/pkg/errors/stack.go create mode 100644 vendor/github.com/russross/blackfriday/v2/.gitignore create mode 100644 vendor/github.com/russross/blackfriday/v2/.travis.yml create mode 100644 vendor/github.com/russross/blackfriday/v2/LICENSE.txt create mode 100644 vendor/github.com/russross/blackfriday/v2/README.md create mode 100644 vendor/github.com/russross/blackfriday/v2/block.go create mode 100644 vendor/github.com/russross/blackfriday/v2/doc.go create mode 100644 vendor/github.com/russross/blackfriday/v2/entities.go create mode 100644 vendor/github.com/russross/blackfriday/v2/esc.go create mode 100644 vendor/github.com/russross/blackfriday/v2/go.mod create mode 100644 vendor/github.com/russross/blackfriday/v2/html.go create mode 100644 vendor/github.com/russross/blackfriday/v2/inline.go create mode 100644 vendor/github.com/russross/blackfriday/v2/markdown.go create mode 100644 vendor/github.com/russross/blackfriday/v2/node.go create mode 100644 vendor/github.com/russross/blackfriday/v2/smartypants.go create mode 100644 vendor/github.com/soheilhy/cmux/.gitignore create mode 100644 vendor/github.com/soheilhy/cmux/.travis.yml create mode 100644 vendor/github.com/soheilhy/cmux/CONTRIBUTORS create mode 100644 vendor/github.com/soheilhy/cmux/LICENSE create mode 100644 vendor/github.com/soheilhy/cmux/README.md create mode 100644 vendor/github.com/soheilhy/cmux/buffer.go create mode 100644 vendor/github.com/soheilhy/cmux/cmux.go create mode 100644 vendor/github.com/soheilhy/cmux/doc.go create mode 100644 vendor/github.com/soheilhy/cmux/go.mod create mode 100644 vendor/github.com/soheilhy/cmux/go.sum create mode 100644 vendor/github.com/soheilhy/cmux/matchers.go create mode 100644 vendor/github.com/soheilhy/cmux/patricia.go create mode 100644 vendor/github.com/tidwall/gjson/LICENSE create mode 100644 vendor/github.com/tidwall/gjson/README.md create mode 100644 vendor/github.com/tidwall/gjson/SYNTAX.md create mode 100644 vendor/github.com/tidwall/gjson/gjson.go create mode 100644 vendor/github.com/tidwall/gjson/go.mod create mode 100644 vendor/github.com/tidwall/gjson/go.sum create mode 100644 vendor/github.com/tidwall/gjson/logo.png create mode 100644 vendor/github.com/tidwall/match/LICENSE create mode 100644 vendor/github.com/tidwall/match/README.md create mode 100644 vendor/github.com/tidwall/match/go.mod create mode 100644 vendor/github.com/tidwall/match/match.go create mode 100644 vendor/github.com/tidwall/pretty/LICENSE create mode 100644 vendor/github.com/tidwall/pretty/README.md create mode 100644 vendor/github.com/tidwall/pretty/go.mod create mode 100644 vendor/github.com/tidwall/pretty/pretty.go create mode 100644 vendor/github.com/ugorji/go/codec/0_importpath.go create mode 100644 vendor/github.com/ugorji/go/codec/LICENSE create mode 100644 vendor/github.com/ugorji/go/codec/README.md create mode 100644 vendor/github.com/ugorji/go/codec/binc.go create mode 100644 vendor/github.com/ugorji/go/codec/build.sh create mode 100644 vendor/github.com/ugorji/go/codec/cbor.go create mode 100644 vendor/github.com/ugorji/go/codec/codecgen.go create mode 100644 vendor/github.com/ugorji/go/codec/decimal.go create mode 100644 vendor/github.com/ugorji/go/codec/decode.go create mode 100644 vendor/github.com/ugorji/go/codec/doc.go create mode 100644 vendor/github.com/ugorji/go/codec/encode.go create mode 100644 vendor/github.com/ugorji/go/codec/fast-path.generated.go create mode 100644 vendor/github.com/ugorji/go/codec/fast-path.go.tmpl create mode 100644 vendor/github.com/ugorji/go/codec/fast-path.not.go create mode 100644 vendor/github.com/ugorji/go/codec/gen-dec-array.go.tmpl create mode 100644 vendor/github.com/ugorji/go/codec/gen-dec-map.go.tmpl create mode 100644 vendor/github.com/ugorji/go/codec/gen-enc-chan.go.tmpl create mode 100644 vendor/github.com/ugorji/go/codec/gen-helper.generated.go create mode 100644 vendor/github.com/ugorji/go/codec/gen-helper.go.tmpl create mode 100644 vendor/github.com/ugorji/go/codec/gen.generated.go create mode 100644 vendor/github.com/ugorji/go/codec/gen.go create mode 100644 vendor/github.com/ugorji/go/codec/go.mod create mode 100644 vendor/github.com/ugorji/go/codec/goversion_arrayof_gte_go15.go create mode 100644 vendor/github.com/ugorji/go/codec/goversion_arrayof_lt_go15.go create mode 100644 vendor/github.com/ugorji/go/codec/goversion_fmt_time_gte_go15.go create mode 100644 vendor/github.com/ugorji/go/codec/goversion_fmt_time_lt_go15.go create mode 100644 vendor/github.com/ugorji/go/codec/goversion_makemap_lt_go110.go create mode 100644 vendor/github.com/ugorji/go/codec/goversion_makemap_not_unsafe_gte_go110.go create mode 100644 vendor/github.com/ugorji/go/codec/goversion_makemap_unsafe_gte_go110.go create mode 100644 vendor/github.com/ugorji/go/codec/goversion_maprange_gte_go112.go create mode 100644 vendor/github.com/ugorji/go/codec/goversion_maprange_lt_go112.go create mode 100644 vendor/github.com/ugorji/go/codec/goversion_unexportedembeddedptr_gte_go110.go create mode 100644 vendor/github.com/ugorji/go/codec/goversion_unexportedembeddedptr_lt_go110.go create mode 100644 vendor/github.com/ugorji/go/codec/goversion_unsupported_lt_go14.go create mode 100644 vendor/github.com/ugorji/go/codec/goversion_vendor_eq_go15.go create mode 100644 vendor/github.com/ugorji/go/codec/goversion_vendor_eq_go16.go create mode 100644 vendor/github.com/ugorji/go/codec/goversion_vendor_gte_go17.go create mode 100644 vendor/github.com/ugorji/go/codec/goversion_vendor_lt_go15.go create mode 100644 vendor/github.com/ugorji/go/codec/helper.go create mode 100644 vendor/github.com/ugorji/go/codec/helper.s create mode 100644 vendor/github.com/ugorji/go/codec/helper_internal.go create mode 100644 vendor/github.com/ugorji/go/codec/helper_not_unsafe.go create mode 100644 vendor/github.com/ugorji/go/codec/helper_not_unsafe_not_gc.go create mode 100644 vendor/github.com/ugorji/go/codec/helper_unsafe.go create mode 100644 vendor/github.com/ugorji/go/codec/helper_unsafe_compiler_gc.go create mode 100644 vendor/github.com/ugorji/go/codec/helper_unsafe_compiler_not_gc.go create mode 100644 vendor/github.com/ugorji/go/codec/json.go create mode 100644 vendor/github.com/ugorji/go/codec/mammoth-test.go.tmpl create mode 100644 vendor/github.com/ugorji/go/codec/mammoth2-test.go.tmpl create mode 100644 vendor/github.com/ugorji/go/codec/msgpack.go create mode 100644 vendor/github.com/ugorji/go/codec/reader.go create mode 100644 vendor/github.com/ugorji/go/codec/register_ext.go create mode 100644 vendor/github.com/ugorji/go/codec/rpc.go create mode 100644 vendor/github.com/ugorji/go/codec/simple.go create mode 100644 vendor/github.com/ugorji/go/codec/sort-slice.generated.go create mode 100644 vendor/github.com/ugorji/go/codec/sort-slice.go.tmpl create mode 100644 vendor/github.com/ugorji/go/codec/test-cbor-goldens.json create mode 100644 vendor/github.com/ugorji/go/codec/test.py create mode 100644 vendor/github.com/ugorji/go/codec/writer.go create mode 100644 vendor/github.com/urfave/cli/v2/.flake8 create mode 100644 vendor/github.com/urfave/cli/v2/.gitignore create mode 100644 vendor/github.com/urfave/cli/v2/CODE_OF_CONDUCT.md create mode 100644 vendor/github.com/urfave/cli/v2/LICENSE create mode 100644 vendor/github.com/urfave/cli/v2/README.md create mode 100644 vendor/github.com/urfave/cli/v2/app.go create mode 100644 vendor/github.com/urfave/cli/v2/args.go create mode 100644 vendor/github.com/urfave/cli/v2/category.go create mode 100644 vendor/github.com/urfave/cli/v2/cli.go create mode 100644 vendor/github.com/urfave/cli/v2/command.go create mode 100644 vendor/github.com/urfave/cli/v2/context.go create mode 100644 vendor/github.com/urfave/cli/v2/docs.go create mode 100644 vendor/github.com/urfave/cli/v2/errors.go create mode 100644 vendor/github.com/urfave/cli/v2/fish.go create mode 100644 vendor/github.com/urfave/cli/v2/flag.go create mode 100644 vendor/github.com/urfave/cli/v2/flag_bool.go create mode 100644 vendor/github.com/urfave/cli/v2/flag_duration.go create mode 100644 vendor/github.com/urfave/cli/v2/flag_float64.go create mode 100644 vendor/github.com/urfave/cli/v2/flag_float64_slice.go create mode 100644 vendor/github.com/urfave/cli/v2/flag_generic.go create mode 100644 vendor/github.com/urfave/cli/v2/flag_int.go create mode 100644 vendor/github.com/urfave/cli/v2/flag_int64.go create mode 100644 vendor/github.com/urfave/cli/v2/flag_int64_slice.go create mode 100644 vendor/github.com/urfave/cli/v2/flag_int_slice.go create mode 100644 vendor/github.com/urfave/cli/v2/flag_path.go create mode 100644 vendor/github.com/urfave/cli/v2/flag_string.go create mode 100644 vendor/github.com/urfave/cli/v2/flag_string_slice.go create mode 100644 vendor/github.com/urfave/cli/v2/flag_timestamp.go create mode 100644 vendor/github.com/urfave/cli/v2/flag_uint.go create mode 100644 vendor/github.com/urfave/cli/v2/flag_uint64.go create mode 100644 vendor/github.com/urfave/cli/v2/funcs.go create mode 100644 vendor/github.com/urfave/cli/v2/go.mod create mode 100644 vendor/github.com/urfave/cli/v2/go.sum create mode 100644 vendor/github.com/urfave/cli/v2/help.go create mode 100644 vendor/github.com/urfave/cli/v2/parse.go create mode 100644 vendor/github.com/urfave/cli/v2/sort.go create mode 100644 vendor/github.com/urfave/cli/v2/template.go create mode 100644 vendor/github.com/valyala/bytebufferpool/.travis.yml create mode 100644 vendor/github.com/valyala/bytebufferpool/LICENSE create mode 100644 vendor/github.com/valyala/bytebufferpool/README.md create mode 100644 vendor/github.com/valyala/bytebufferpool/bytebuffer.go create mode 100644 vendor/github.com/valyala/bytebufferpool/doc.go create mode 100644 vendor/github.com/valyala/bytebufferpool/pool.go create mode 100644 vendor/github.com/valyala/fasthttp/.gitignore create mode 100644 vendor/github.com/valyala/fasthttp/LICENSE create mode 100644 vendor/github.com/valyala/fasthttp/README.md create mode 100644 vendor/github.com/valyala/fasthttp/SECURITY.md create mode 100644 vendor/github.com/valyala/fasthttp/TODO create mode 100644 vendor/github.com/valyala/fasthttp/args.go create mode 100644 vendor/github.com/valyala/fasthttp/brotli.go create mode 100644 vendor/github.com/valyala/fasthttp/bytesconv.go create mode 100644 vendor/github.com/valyala/fasthttp/bytesconv_32.go create mode 100644 vendor/github.com/valyala/fasthttp/bytesconv_64.go create mode 100644 vendor/github.com/valyala/fasthttp/bytesconv_table.go create mode 100644 vendor/github.com/valyala/fasthttp/client.go create mode 100644 vendor/github.com/valyala/fasthttp/coarseTime.go create mode 100644 vendor/github.com/valyala/fasthttp/compress.go create mode 100644 vendor/github.com/valyala/fasthttp/cookie.go create mode 100644 vendor/github.com/valyala/fasthttp/doc.go create mode 100644 vendor/github.com/valyala/fasthttp/fasthttpadaptor/adaptor.go create mode 100644 vendor/github.com/valyala/fasthttp/fasthttpadaptor/request.go create mode 100644 vendor/github.com/valyala/fasthttp/fasthttputil/doc.go create mode 100644 vendor/github.com/valyala/fasthttp/fasthttputil/inmemory_listener.go create mode 100644 vendor/github.com/valyala/fasthttp/fasthttputil/pipeconns.go create mode 100644 vendor/github.com/valyala/fasthttp/fasthttputil/rsa.key create mode 100644 vendor/github.com/valyala/fasthttp/fasthttputil/rsa.pem create mode 100644 vendor/github.com/valyala/fasthttp/fs.go create mode 100644 vendor/github.com/valyala/fasthttp/go.mod create mode 100644 vendor/github.com/valyala/fasthttp/go.sum create mode 100644 vendor/github.com/valyala/fasthttp/header.go create mode 100644 vendor/github.com/valyala/fasthttp/headers.go create mode 100644 vendor/github.com/valyala/fasthttp/http.go create mode 100644 vendor/github.com/valyala/fasthttp/lbclient.go create mode 100644 vendor/github.com/valyala/fasthttp/methods.go create mode 100644 vendor/github.com/valyala/fasthttp/nocopy.go create mode 100644 vendor/github.com/valyala/fasthttp/peripconn.go create mode 100644 vendor/github.com/valyala/fasthttp/server.go create mode 100644 vendor/github.com/valyala/fasthttp/stackless/doc.go create mode 100644 vendor/github.com/valyala/fasthttp/stackless/func.go create mode 100644 vendor/github.com/valyala/fasthttp/stackless/writer.go create mode 100644 vendor/github.com/valyala/fasthttp/status.go create mode 100644 vendor/github.com/valyala/fasthttp/stream.go create mode 100644 vendor/github.com/valyala/fasthttp/streaming.go create mode 100644 vendor/github.com/valyala/fasthttp/strings.go create mode 100644 vendor/github.com/valyala/fasthttp/tcp.go create mode 100644 vendor/github.com/valyala/fasthttp/tcp_windows.go create mode 100644 vendor/github.com/valyala/fasthttp/tcpdialer.go create mode 100644 vendor/github.com/valyala/fasthttp/timer.go create mode 100644 vendor/github.com/valyala/fasthttp/tls.go create mode 100644 vendor/github.com/valyala/fasthttp/uri.go create mode 100644 vendor/github.com/valyala/fasthttp/uri_unix.go create mode 100644 vendor/github.com/valyala/fasthttp/uri_windows.go create mode 100644 vendor/github.com/valyala/fasthttp/userdata.go create mode 100644 vendor/github.com/valyala/fasthttp/workerpool.go create mode 100644 vendor/github.com/valyala/fasttemplate/LICENSE create mode 100644 vendor/github.com/valyala/fasttemplate/README.md create mode 100644 vendor/github.com/valyala/fasttemplate/go.mod create mode 100644 vendor/github.com/valyala/fasttemplate/go.sum create mode 100644 vendor/github.com/valyala/fasttemplate/template.go create mode 100644 vendor/github.com/valyala/fasttemplate/unsafe.go create mode 100644 vendor/github.com/valyala/fasttemplate/unsafe_gae.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/.gitignore create mode 100644 vendor/github.com/vektah/gqlparser/v2/LICENSE create mode 100644 vendor/github.com/vektah/gqlparser/v2/ast/argmap.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/ast/collections.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/ast/definition.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/ast/directive.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/ast/document.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/ast/dumper.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/ast/fragment.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/ast/operation.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/ast/path.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/ast/selection.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/ast/source.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/ast/type.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/ast/value.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/go.mod create mode 100644 vendor/github.com/vektah/gqlparser/v2/go.sum create mode 100644 vendor/github.com/vektah/gqlparser/v2/gqlerror/error.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/gqlparser.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/lexer/blockstring.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/lexer/lexer.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/lexer/lexer_test.yml create mode 100644 vendor/github.com/vektah/gqlparser/v2/lexer/token.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/parser/parser.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/parser/query.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/parser/query_test.yml create mode 100644 vendor/github.com/vektah/gqlparser/v2/parser/schema.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/parser/schema_test.yml create mode 100644 vendor/github.com/vektah/gqlparser/v2/readme.md create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/error.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/messaging.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/prelude.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/prelude.graphql create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/rules/fields_on_correct_type.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/rules/fragments_on_composite_types.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/rules/known_argument_names.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/rules/known_directives.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/rules/known_fragment_names.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/rules/known_type_names.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/rules/lone_anonymous_operation.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/rules/no_fragment_cycles.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/rules/no_undefined_variables.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/rules/no_unused_fragments.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/rules/no_unused_variables.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/rules/overlapping_fields_can_be_merged.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/rules/possible_fragment_spreads.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/rules/provided_required_arguments.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/rules/scalar_leafs.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/rules/single_field_subscriptions.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_argument_names.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_directives_per_location.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_fragment_names.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_input_field_names.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_operation_names.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_variable_names.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/rules/values_of_correct_type.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/rules/variables_are_input_types.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/rules/variables_in_allowed_position.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/schema.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/schema_test.yml create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/suggestionList.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/validator.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/vars.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/walk.go create mode 100644 vendor/github.com/wI2L/jsondiff/.codecov.yml create mode 100644 vendor/github.com/wI2L/jsondiff/.gitignore create mode 100644 vendor/github.com/wI2L/jsondiff/.golangci.yaml create mode 100644 vendor/github.com/wI2L/jsondiff/.goreleaser.yml create mode 100644 vendor/github.com/wI2L/jsondiff/CHANGELOG.md create mode 100644 vendor/github.com/wI2L/jsondiff/LICENSE create mode 100644 vendor/github.com/wI2L/jsondiff/README.md create mode 100644 vendor/github.com/wI2L/jsondiff/compare.go create mode 100644 vendor/github.com/wI2L/jsondiff/differ.go create mode 100644 vendor/github.com/wI2L/jsondiff/equal.go create mode 100644 vendor/github.com/wI2L/jsondiff/go.mod create mode 100644 vendor/github.com/wI2L/jsondiff/go.sum create mode 100644 vendor/github.com/wI2L/jsondiff/hash.go create mode 100644 vendor/github.com/wI2L/jsondiff/operation.go create mode 100644 vendor/github.com/wI2L/jsondiff/option.go create mode 100644 vendor/github.com/wI2L/jsondiff/pointer.go create mode 100644 vendor/github.com/xdg-go/pbkdf2/.gitignore create mode 100644 vendor/github.com/xdg-go/pbkdf2/LICENSE create mode 100644 vendor/github.com/xdg-go/pbkdf2/README.md create mode 100644 vendor/github.com/xdg-go/pbkdf2/go.mod create mode 100644 vendor/github.com/xdg-go/pbkdf2/pbkdf2.go create mode 100644 vendor/github.com/xdg-go/scram/.gitignore create mode 100644 vendor/github.com/xdg-go/scram/CHANGELOG.md create mode 100644 vendor/github.com/xdg-go/scram/LICENSE create mode 100644 vendor/github.com/xdg-go/scram/README.md create mode 100644 vendor/github.com/xdg-go/scram/client.go create mode 100644 vendor/github.com/xdg-go/scram/client_conv.go create mode 100644 vendor/github.com/xdg-go/scram/common.go create mode 100644 vendor/github.com/xdg-go/scram/doc.go create mode 100644 vendor/github.com/xdg-go/scram/go.mod create mode 100644 vendor/github.com/xdg-go/scram/go.sum create mode 100644 vendor/github.com/xdg-go/scram/parse.go create mode 100644 vendor/github.com/xdg-go/scram/scram.go create mode 100644 vendor/github.com/xdg-go/scram/server.go create mode 100644 vendor/github.com/xdg-go/scram/server_conv.go create mode 100644 vendor/github.com/xdg-go/stringprep/.gitignore create mode 100644 vendor/github.com/xdg-go/stringprep/CHANGELOG.md create mode 100644 vendor/github.com/xdg-go/stringprep/LICENSE create mode 100644 vendor/github.com/xdg-go/stringprep/README.md create mode 100644 vendor/github.com/xdg-go/stringprep/bidi.go create mode 100644 vendor/github.com/xdg-go/stringprep/doc.go create mode 100644 vendor/github.com/xdg-go/stringprep/error.go create mode 100644 vendor/github.com/xdg-go/stringprep/go.mod create mode 100644 vendor/github.com/xdg-go/stringprep/go.sum create mode 100644 vendor/github.com/xdg-go/stringprep/map.go create mode 100644 vendor/github.com/xdg-go/stringprep/profile.go create mode 100644 vendor/github.com/xdg-go/stringprep/saslprep.go create mode 100644 vendor/github.com/xdg-go/stringprep/set.go create mode 100644 vendor/github.com/xdg-go/stringprep/tables.go create mode 100644 vendor/github.com/youmark/pkcs8/.gitignore create mode 100644 vendor/github.com/youmark/pkcs8/.travis.yml create mode 100644 vendor/github.com/youmark/pkcs8/LICENSE create mode 100644 vendor/github.com/youmark/pkcs8/README create mode 100644 vendor/github.com/youmark/pkcs8/README.md create mode 100644 vendor/github.com/youmark/pkcs8/cipher.go create mode 100644 vendor/github.com/youmark/pkcs8/cipher_3des.go create mode 100644 vendor/github.com/youmark/pkcs8/cipher_aes.go create mode 100644 vendor/github.com/youmark/pkcs8/go.mod create mode 100644 vendor/github.com/youmark/pkcs8/go.sum create mode 100644 vendor/github.com/youmark/pkcs8/kdf_pbkdf2.go create mode 100644 vendor/github.com/youmark/pkcs8/kdf_scrypt.go create mode 100644 vendor/github.com/youmark/pkcs8/pkcs8.go create mode 100644 vendor/go.keploy.io/server/LICENSE create mode 100644 vendor/go.keploy.io/server/graph/ext.graphqls create mode 100644 vendor/go.keploy.io/server/graph/ext.resolvers.go create mode 100644 vendor/go.keploy.io/server/graph/generated/generated.go create mode 100644 vendor/go.keploy.io/server/graph/model/models_gen.go create mode 100644 vendor/go.keploy.io/server/graph/resolver.go create mode 100644 vendor/go.keploy.io/server/graph/schema.graphqls create mode 100644 vendor/go.keploy.io/server/graph/schema.resolvers.go create mode 100644 vendor/go.keploy.io/server/graph/tools.go create mode 100644 vendor/go.keploy.io/server/graph/utils.go create mode 100644 vendor/go.keploy.io/server/grpc/grpcserver/server.go create mode 100644 vendor/go.keploy.io/server/grpc/mock/mock.go create mode 100644 vendor/go.keploy.io/server/grpc/regression/services.pb.go create mode 100644 vendor/go.keploy.io/server/grpc/regression/services.proto create mode 100644 vendor/go.keploy.io/server/grpc/regression/services_grpc.pb.go create mode 100644 vendor/go.keploy.io/server/grpc/utils/utils.go create mode 100644 vendor/go.keploy.io/server/http/browserMock/browser-mock.go create mode 100644 vendor/go.keploy.io/server/http/browserMock/request.go create mode 100644 vendor/go.keploy.io/server/http/regression/helpers.go create mode 100644 vendor/go.keploy.io/server/http/regression/regression.go create mode 100644 vendor/go.keploy.io/server/http/regression/request.go create mode 100644 vendor/go.keploy.io/server/pkg/match.go create mode 100644 vendor/go.keploy.io/server/pkg/models/app.go create mode 100644 vendor/go.keploy.io/server/pkg/models/body-segment.go create mode 100644 vendor/go.keploy.io/server/pkg/models/browser-mock.go create mode 100644 vendor/go.keploy.io/server/pkg/models/dep.go create mode 100644 vendor/go.keploy.io/server/pkg/models/event.go create mode 100644 vendor/go.keploy.io/server/pkg/models/http.go create mode 100644 vendor/go.keploy.io/server/pkg/models/logs-color.go create mode 100644 vendor/go.keploy.io/server/pkg/models/mock.go create mode 100644 vendor/go.keploy.io/server/pkg/models/tc.go create mode 100644 vendor/go.keploy.io/server/pkg/models/testrun.go create mode 100644 vendor/go.keploy.io/server/pkg/platform/fs/mock.go create mode 100644 vendor/go.keploy.io/server/pkg/platform/fs/tele.go create mode 100644 vendor/go.keploy.io/server/pkg/platform/fs/testReport.go create mode 100644 vendor/go.keploy.io/server/pkg/platform/mgo/browser-mockdb.go create mode 100644 vendor/go.keploy.io/server/pkg/platform/mgo/mongo.go create mode 100644 vendor/go.keploy.io/server/pkg/platform/mgo/rdb.go create mode 100644 vendor/go.keploy.io/server/pkg/platform/mgo/tdb.go create mode 100644 vendor/go.keploy.io/server/pkg/platform/mgo/teledb.go create mode 100644 vendor/go.keploy.io/server/pkg/platform/telemetry/service.go create mode 100644 vendor/go.keploy.io/server/pkg/platform/telemetry/telemetry.go create mode 100644 vendor/go.keploy.io/server/pkg/platform/telemetry/utils.go create mode 100644 vendor/go.keploy.io/server/pkg/service/browserMock/browser-mock.go create mode 100644 vendor/go.keploy.io/server/pkg/service/browserMock/service.go create mode 100644 vendor/go.keploy.io/server/pkg/service/mock/mock.go create mode 100644 vendor/go.keploy.io/server/pkg/service/mock/service.go create mode 100644 vendor/go.keploy.io/server/pkg/service/regression/regression.go create mode 100644 vendor/go.keploy.io/server/pkg/service/regression/service.go create mode 100644 vendor/go.keploy.io/server/pkg/service/testCase/service.go create mode 100644 vendor/go.keploy.io/server/pkg/service/testCase/testCase.go create mode 100644 vendor/go.keploy.io/server/pkg/utils.go create mode 100644 vendor/go.keploy.io/server/server/const.go create mode 100644 vendor/go.keploy.io/server/server/server.go create mode 100644 vendor/go.keploy.io/server/web/public/README.md create mode 100644 vendor/go.keploy.io/server/web/public/index.html create mode 100644 vendor/go.keploy.io/server/web/web.go create mode 100644 vendor/go.mongodb.org/mongo-driver/LICENSE create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bson.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/array_codec.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/bsoncodec.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/byte_slice_codec.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/cond_addr_codec.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_decoders.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_encoders.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/doc.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/empty_interface_codec.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/map_codec.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/mode.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/pointer_codec.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/proxy.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/registry.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/slice_codec.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/string_codec.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_codec.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_tag_parser.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/time_codec.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/types.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/uint_codec.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/byte_slice_codec_options.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/empty_interface_codec_options.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/map_codec_options.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/slice_codec_options.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/string_codec_options.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/struct_codec_options.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/time_codec_options.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/uint_codec_options.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsonrw/copier.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsonrw/doc.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_parser.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_reader.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_tables.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_wrappers.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_writer.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsonrw/json_scanner.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsonrw/mode.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsonrw/reader.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsonrw/value_reader.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsonrw/value_writer.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsonrw/writer.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsontype/bsontype.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/decoder.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/doc.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/encoder.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/marshal.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/primitive/decimal.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/primitive/objectid.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/primitive/primitive.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/primitive_codecs.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/raw.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/raw_element.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/raw_value.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/registry.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/types.go create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/unmarshal.go create mode 100644 vendor/go.mongodb.org/mongo-driver/event/doc.go create mode 100644 vendor/go.mongodb.org/mongo-driver/event/monitoring.go create mode 100644 vendor/go.mongodb.org/mongo-driver/internal/background_context.go create mode 100644 vendor/go.mongodb.org/mongo-driver/internal/cancellation_listener.go create mode 100644 vendor/go.mongodb.org/mongo-driver/internal/const.go create mode 100644 vendor/go.mongodb.org/mongo-driver/internal/error.go create mode 100644 vendor/go.mongodb.org/mongo-driver/internal/randutil/randutil.go create mode 100644 vendor/go.mongodb.org/mongo-driver/internal/string_util.go create mode 100644 vendor/go.mongodb.org/mongo-driver/internal/uri_validation_errors.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/address/addr.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/batch_cursor.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/bulk_write.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/bulk_write_models.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/change_stream.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/change_stream_deployment.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/client.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/client_encryption.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/collection.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/crypt_retrievers.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/cursor.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/database.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/description/description.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/description/server.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/description/server_kind.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/description/server_selector.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/description/topology.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/description/topology_kind.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/description/topology_version.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/description/version_range.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/doc.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/errors.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/index_options_builder.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/index_view.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/mongo.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/mongocryptd.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/options/aggregateoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/options/autoencryptionoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/options/bulkwriteoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/options/changestreamoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/options/clientencryptionoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/options/clientoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/options/collectionoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/options/countoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/options/createcollectionoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/options/datakeyoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/options/dboptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/options/deleteoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/options/distinctoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/options/encryptoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/options/estimatedcountoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/options/findoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/options/gridfsoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/options/indexoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/options/insertoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/options/listcollectionsoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/options/listdatabasesoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/options/mongooptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/options/replaceoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/options/runcmdoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/options/serverapioptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/options/sessionoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/options/transactionoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/options/updateoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/readconcern/readconcern.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/readpref/mode.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/readpref/options.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/readpref/readpref.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/results.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/session.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/single_result.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/util.go create mode 100644 vendor/go.mongodb.org/mongo-driver/mongo/writeconcern/writeconcern.go create mode 100644 vendor/go.mongodb.org/mongo-driver/tag/tag.go create mode 100644 vendor/go.mongodb.org/mongo-driver/version/version.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/bsonx/array.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/array.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/bson_arraybuilder.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/bson_documentbuilder.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/bsoncore.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/document.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/document_sequence.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/element.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/tables.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/value.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/bsonx/constructor.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/bsonx/document.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/bsonx/element.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/bsonx/mdocument.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/bsonx/primitive_codecs.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/bsonx/reflectionfree_d_codec.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/bsonx/registry.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/bsonx/value.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/DESIGN.md create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/auth.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/aws_conv.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/conversation.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/cred.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/default.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/doc.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/gssapi.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/gssapi_not_enabled.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/gssapi_not_supported.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/awsv4/credentials.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/awsv4/doc.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/awsv4/request.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/awsv4/rest.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/awsv4/rules.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/awsv4/signer.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/gssapi/gss.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/gssapi/gss_wrapper.c create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/gssapi/gss_wrapper.h create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/gssapi/sspi.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/gssapi/sspi_wrapper.c create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/gssapi/sspi_wrapper.h create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/mongodbaws.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/mongodbcr.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/plain.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/sasl.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/scram.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/util.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/x509.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/batch_cursor.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/batches.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/compression.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/connstring/connstring.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/crypt.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/dns/dns.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/driver.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/errors.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/legacy.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/list_collections_batch_cursor.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/binary.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/errors.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/errors_not_enabled.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_context.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_context_not_enabled.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_kms_context.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_kms_context_not_enabled.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_not_enabled.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/options/mongocrypt_context_options.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/options/mongocrypt_options.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/state.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/ocsp/cache.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/ocsp/config.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/ocsp/ocsp.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/ocsp/options.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/abort_transaction.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/aggregate.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/command.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/commit_transaction.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/count.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/create.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/createIndexes.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/delete.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/distinct.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/drop_collection.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/drop_database.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/drop_indexes.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/end_sessions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/errors.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/find.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/find_and_modify.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/hello.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/insert.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/listDatabases.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/list_collections.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/list_indexes.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/update.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation_exhaust.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation_legacy.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/serverapioptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/session/client_session.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/session/cluster_clock.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/session/options.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/session/server_session.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/session/session_pool.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/DESIGN.md create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/cancellation_listener.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/connection.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/connection_legacy.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/connection_options.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/diff.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/errors.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/fsm.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/pool.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/pool_generation_counter.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/rtt_monitor.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/server.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/server_options.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/tls_connection_source.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/topology.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/topology_options.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/uuid/uuid.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/mongo/driver/wiremessage/wiremessage.go create mode 100644 vendor/go.uber.org/atomic/.codecov.yml create mode 100644 vendor/go.uber.org/atomic/.gitignore create mode 100644 vendor/go.uber.org/atomic/CHANGELOG.md create mode 100644 vendor/go.uber.org/atomic/LICENSE.txt create mode 100644 vendor/go.uber.org/atomic/Makefile create mode 100644 vendor/go.uber.org/atomic/README.md create mode 100644 vendor/go.uber.org/atomic/bool.go create mode 100644 vendor/go.uber.org/atomic/bool_ext.go create mode 100644 vendor/go.uber.org/atomic/doc.go create mode 100644 vendor/go.uber.org/atomic/duration.go create mode 100644 vendor/go.uber.org/atomic/duration_ext.go create mode 100644 vendor/go.uber.org/atomic/error.go create mode 100644 vendor/go.uber.org/atomic/error_ext.go create mode 100644 vendor/go.uber.org/atomic/float64.go create mode 100644 vendor/go.uber.org/atomic/float64_ext.go create mode 100644 vendor/go.uber.org/atomic/gen.go create mode 100644 vendor/go.uber.org/atomic/go.mod create mode 100644 vendor/go.uber.org/atomic/go.sum create mode 100644 vendor/go.uber.org/atomic/int32.go create mode 100644 vendor/go.uber.org/atomic/int64.go create mode 100644 vendor/go.uber.org/atomic/nocmp.go create mode 100644 vendor/go.uber.org/atomic/string.go create mode 100644 vendor/go.uber.org/atomic/string_ext.go create mode 100644 vendor/go.uber.org/atomic/time.go create mode 100644 vendor/go.uber.org/atomic/time_ext.go create mode 100644 vendor/go.uber.org/atomic/uint32.go create mode 100644 vendor/go.uber.org/atomic/uint64.go create mode 100644 vendor/go.uber.org/atomic/uintptr.go create mode 100644 vendor/go.uber.org/atomic/unsafe_pointer.go create mode 100644 vendor/go.uber.org/atomic/value.go create mode 100644 vendor/go.uber.org/multierr/.codecov.yml create mode 100644 vendor/go.uber.org/multierr/.gitignore create mode 100644 vendor/go.uber.org/multierr/CHANGELOG.md create mode 100644 vendor/go.uber.org/multierr/LICENSE.txt create mode 100644 vendor/go.uber.org/multierr/Makefile create mode 100644 vendor/go.uber.org/multierr/README.md create mode 100644 vendor/go.uber.org/multierr/error.go create mode 100644 vendor/go.uber.org/multierr/glide.yaml create mode 100644 vendor/go.uber.org/multierr/go.mod create mode 100644 vendor/go.uber.org/multierr/go.sum create mode 100644 vendor/go.uber.org/zap/.codecov.yml create mode 100644 vendor/go.uber.org/zap/.gitignore create mode 100644 vendor/go.uber.org/zap/.readme.tmpl create mode 100644 vendor/go.uber.org/zap/CHANGELOG.md create mode 100644 vendor/go.uber.org/zap/CODE_OF_CONDUCT.md create mode 100644 vendor/go.uber.org/zap/CONTRIBUTING.md create mode 100644 vendor/go.uber.org/zap/FAQ.md create mode 100644 vendor/go.uber.org/zap/LICENSE.txt create mode 100644 vendor/go.uber.org/zap/Makefile create mode 100644 vendor/go.uber.org/zap/README.md create mode 100644 vendor/go.uber.org/zap/array.go create mode 100644 vendor/go.uber.org/zap/array_go118.go create mode 100644 vendor/go.uber.org/zap/buffer/buffer.go create mode 100644 vendor/go.uber.org/zap/buffer/pool.go create mode 100644 vendor/go.uber.org/zap/checklicense.sh create mode 100644 vendor/go.uber.org/zap/config.go create mode 100644 vendor/go.uber.org/zap/doc.go create mode 100644 vendor/go.uber.org/zap/encoder.go create mode 100644 vendor/go.uber.org/zap/error.go create mode 100644 vendor/go.uber.org/zap/field.go create mode 100644 vendor/go.uber.org/zap/flag.go create mode 100644 vendor/go.uber.org/zap/glide.yaml create mode 100644 vendor/go.uber.org/zap/global.go create mode 100644 vendor/go.uber.org/zap/go.mod create mode 100644 vendor/go.uber.org/zap/go.sum create mode 100644 vendor/go.uber.org/zap/http_handler.go create mode 100644 vendor/go.uber.org/zap/internal/bufferpool/bufferpool.go create mode 100644 vendor/go.uber.org/zap/internal/color/color.go create mode 100644 vendor/go.uber.org/zap/internal/exit/exit.go create mode 100644 vendor/go.uber.org/zap/level.go create mode 100644 vendor/go.uber.org/zap/logger.go create mode 100644 vendor/go.uber.org/zap/options.go create mode 100644 vendor/go.uber.org/zap/sink.go create mode 100644 vendor/go.uber.org/zap/stacktrace.go create mode 100644 vendor/go.uber.org/zap/sugar.go create mode 100644 vendor/go.uber.org/zap/time.go create mode 100644 vendor/go.uber.org/zap/writer.go create mode 100644 vendor/go.uber.org/zap/zapcore/buffered_write_syncer.go create mode 100644 vendor/go.uber.org/zap/zapcore/clock.go create mode 100644 vendor/go.uber.org/zap/zapcore/console_encoder.go create mode 100644 vendor/go.uber.org/zap/zapcore/core.go create mode 100644 vendor/go.uber.org/zap/zapcore/doc.go create mode 100644 vendor/go.uber.org/zap/zapcore/encoder.go create mode 100644 vendor/go.uber.org/zap/zapcore/entry.go create mode 100644 vendor/go.uber.org/zap/zapcore/error.go create mode 100644 vendor/go.uber.org/zap/zapcore/field.go create mode 100644 vendor/go.uber.org/zap/zapcore/hook.go create mode 100644 vendor/go.uber.org/zap/zapcore/increase_level.go create mode 100644 vendor/go.uber.org/zap/zapcore/json_encoder.go create mode 100644 vendor/go.uber.org/zap/zapcore/level.go create mode 100644 vendor/go.uber.org/zap/zapcore/level_strings.go create mode 100644 vendor/go.uber.org/zap/zapcore/marshaler.go create mode 100644 vendor/go.uber.org/zap/zapcore/memory_encoder.go create mode 100644 vendor/go.uber.org/zap/zapcore/reflected_encoder.go create mode 100644 vendor/go.uber.org/zap/zapcore/sampler.go create mode 100644 vendor/go.uber.org/zap/zapcore/tee.go create mode 100644 vendor/go.uber.org/zap/zapcore/write_syncer.go create mode 100644 vendor/golang.org/x/crypto/AUTHORS create mode 100644 vendor/golang.org/x/crypto/CONTRIBUTORS create mode 100644 vendor/golang.org/x/crypto/LICENSE create mode 100644 vendor/golang.org/x/crypto/PATENTS create mode 100644 vendor/golang.org/x/crypto/acme/acme.go create mode 100644 vendor/golang.org/x/crypto/acme/autocert/autocert.go create mode 100644 vendor/golang.org/x/crypto/acme/autocert/cache.go create mode 100644 vendor/golang.org/x/crypto/acme/autocert/listener.go create mode 100644 vendor/golang.org/x/crypto/acme/autocert/renewal.go create mode 100644 vendor/golang.org/x/crypto/acme/http.go create mode 100644 vendor/golang.org/x/crypto/acme/jws.go create mode 100644 vendor/golang.org/x/crypto/acme/rfc8555.go create mode 100644 vendor/golang.org/x/crypto/acme/types.go create mode 100644 vendor/golang.org/x/crypto/acme/version_go112.go create mode 100644 vendor/golang.org/x/crypto/curve25519/curve25519.go create mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/README create mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/fe.go create mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.go create mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.s create mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64_noasm.go create mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.go create mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.s create mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64_noasm.go create mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/fe_generic.go create mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/sync.checkpoint create mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/sync.sh create mode 100644 vendor/golang.org/x/crypto/ed25519/ed25519.go create mode 100644 vendor/golang.org/x/crypto/ocsp/ocsp.go create mode 100644 vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go create mode 100644 vendor/golang.org/x/crypto/scrypt/scrypt.go create mode 100644 vendor/golang.org/x/crypto/sha3/doc.go create mode 100644 vendor/golang.org/x/crypto/sha3/hashes.go create mode 100644 vendor/golang.org/x/crypto/sha3/hashes_generic.go create mode 100644 vendor/golang.org/x/crypto/sha3/keccakf.go create mode 100644 vendor/golang.org/x/crypto/sha3/keccakf_amd64.go create mode 100644 vendor/golang.org/x/crypto/sha3/keccakf_amd64.s create mode 100644 vendor/golang.org/x/crypto/sha3/register.go create mode 100644 vendor/golang.org/x/crypto/sha3/sha3.go create mode 100644 vendor/golang.org/x/crypto/sha3/sha3_s390x.go create mode 100644 vendor/golang.org/x/crypto/sha3/sha3_s390x.s create mode 100644 vendor/golang.org/x/crypto/sha3/shake.go create mode 100644 vendor/golang.org/x/crypto/sha3/shake_generic.go create mode 100644 vendor/golang.org/x/crypto/sha3/xor.go create mode 100644 vendor/golang.org/x/crypto/sha3/xor_generic.go create mode 100644 vendor/golang.org/x/crypto/sha3/xor_unaligned.go create mode 100644 vendor/golang.org/x/mod/LICENSE create mode 100644 vendor/golang.org/x/mod/PATENTS create mode 100644 vendor/golang.org/x/mod/internal/lazyregexp/lazyre.go create mode 100644 vendor/golang.org/x/mod/module/module.go create mode 100644 vendor/golang.org/x/mod/module/pseudo.go create mode 100644 vendor/golang.org/x/mod/semver/semver.go create mode 100644 vendor/golang.org/x/net/LICENSE create mode 100644 vendor/golang.org/x/net/PATENTS create mode 100644 vendor/golang.org/x/net/http/httpguts/guts.go create mode 100644 vendor/golang.org/x/net/http/httpguts/httplex.go create mode 100644 vendor/golang.org/x/net/http2/.gitignore create mode 100644 vendor/golang.org/x/net/http2/Dockerfile create mode 100644 vendor/golang.org/x/net/http2/Makefile create mode 100644 vendor/golang.org/x/net/http2/ascii.go create mode 100644 vendor/golang.org/x/net/http2/ciphers.go create mode 100644 vendor/golang.org/x/net/http2/client_conn_pool.go create mode 100644 vendor/golang.org/x/net/http2/databuffer.go create mode 100644 vendor/golang.org/x/net/http2/errors.go create mode 100644 vendor/golang.org/x/net/http2/flow.go create mode 100644 vendor/golang.org/x/net/http2/frame.go create mode 100644 vendor/golang.org/x/net/http2/go111.go create mode 100644 vendor/golang.org/x/net/http2/go115.go create mode 100644 vendor/golang.org/x/net/http2/go118.go create mode 100644 vendor/golang.org/x/net/http2/gotrack.go create mode 100644 vendor/golang.org/x/net/http2/h2c/h2c.go create mode 100644 vendor/golang.org/x/net/http2/headermap.go create mode 100644 vendor/golang.org/x/net/http2/hpack/encode.go create mode 100644 vendor/golang.org/x/net/http2/hpack/hpack.go create mode 100644 vendor/golang.org/x/net/http2/hpack/huffman.go create mode 100644 vendor/golang.org/x/net/http2/hpack/tables.go create mode 100644 vendor/golang.org/x/net/http2/http2.go create mode 100644 vendor/golang.org/x/net/http2/not_go111.go create mode 100644 vendor/golang.org/x/net/http2/not_go115.go create mode 100644 vendor/golang.org/x/net/http2/not_go118.go create mode 100644 vendor/golang.org/x/net/http2/pipe.go create mode 100644 vendor/golang.org/x/net/http2/server.go create mode 100644 vendor/golang.org/x/net/http2/transport.go create mode 100644 vendor/golang.org/x/net/http2/write.go create mode 100644 vendor/golang.org/x/net/http2/writesched.go create mode 100644 vendor/golang.org/x/net/http2/writesched_priority.go create mode 100644 vendor/golang.org/x/net/http2/writesched_random.go create mode 100644 vendor/golang.org/x/net/idna/go118.go create mode 100644 vendor/golang.org/x/net/idna/idna10.0.0.go create mode 100644 vendor/golang.org/x/net/idna/idna9.0.0.go create mode 100644 vendor/golang.org/x/net/idna/pre_go118.go create mode 100644 vendor/golang.org/x/net/idna/punycode.go create mode 100644 vendor/golang.org/x/net/idna/tables10.0.0.go create mode 100644 vendor/golang.org/x/net/idna/tables11.0.0.go create mode 100644 vendor/golang.org/x/net/idna/tables12.0.0.go create mode 100644 vendor/golang.org/x/net/idna/tables13.0.0.go create mode 100644 vendor/golang.org/x/net/idna/tables9.0.0.go create mode 100644 vendor/golang.org/x/net/idna/trie.go create mode 100644 vendor/golang.org/x/net/idna/trieval.go create mode 100644 vendor/golang.org/x/net/internal/timeseries/timeseries.go create mode 100644 vendor/golang.org/x/net/trace/events.go create mode 100644 vendor/golang.org/x/net/trace/histogram.go create mode 100644 vendor/golang.org/x/net/trace/trace.go create mode 100644 vendor/golang.org/x/sync/LICENSE create mode 100644 vendor/golang.org/x/sync/PATENTS create mode 100644 vendor/golang.org/x/sync/errgroup/errgroup.go create mode 100644 vendor/golang.org/x/sys/LICENSE create mode 100644 vendor/golang.org/x/sys/PATENTS create mode 100644 vendor/golang.org/x/sys/cpu/asm_aix_ppc64.s create mode 100644 vendor/golang.org/x/sys/cpu/byteorder.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_aix.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_arm.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_arm64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_arm64.s create mode 100644 vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_gc_s390x.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_gc_x86.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_gccgo_s390x.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.c create mode 100644 vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux_arm.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux_mips64x.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux_ppc64x.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux_s390x.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_loong64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_mips64x.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_mipsx.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_netbsd_arm64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_other_arm.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_other_arm64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_other_mips64x.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_other_riscv64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_ppc64x.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_riscv64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_s390x.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_s390x.s create mode 100644 vendor/golang.org/x/sys/cpu/cpu_wasm.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_x86.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_x86.s create mode 100644 vendor/golang.org/x/sys/cpu/cpu_zos.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_zos_s390x.go create mode 100644 vendor/golang.org/x/sys/cpu/hwcap_linux.go create mode 100644 vendor/golang.org/x/sys/cpu/syscall_aix_gccgo.go create mode 100644 vendor/golang.org/x/sys/cpu/syscall_aix_ppc64_gc.go create mode 100644 vendor/golang.org/x/sys/execabs/execabs.go create mode 100644 vendor/golang.org/x/sys/execabs/execabs_go118.go create mode 100644 vendor/golang.org/x/sys/execabs/execabs_go119.go create mode 100644 vendor/golang.org/x/sys/internal/unsafeheader/unsafeheader.go create mode 100644 vendor/golang.org/x/sys/unix/.gitignore create mode 100644 vendor/golang.org/x/sys/unix/README.md create mode 100644 vendor/golang.org/x/sys/unix/affinity_linux.go create mode 100644 vendor/golang.org/x/sys/unix/aliases.go create mode 100644 vendor/golang.org/x/sys/unix/asm_aix_ppc64.s create mode 100644 vendor/golang.org/x/sys/unix/asm_bsd_386.s create mode 100644 vendor/golang.org/x/sys/unix/asm_bsd_amd64.s create mode 100644 vendor/golang.org/x/sys/unix/asm_bsd_arm.s create mode 100644 vendor/golang.org/x/sys/unix/asm_bsd_arm64.s create mode 100644 vendor/golang.org/x/sys/unix/asm_bsd_riscv64.s create mode 100644 vendor/golang.org/x/sys/unix/asm_linux_386.s create mode 100644 vendor/golang.org/x/sys/unix/asm_linux_amd64.s create mode 100644 vendor/golang.org/x/sys/unix/asm_linux_arm.s create mode 100644 vendor/golang.org/x/sys/unix/asm_linux_arm64.s create mode 100644 vendor/golang.org/x/sys/unix/asm_linux_loong64.s create mode 100644 vendor/golang.org/x/sys/unix/asm_linux_mips64x.s create mode 100644 vendor/golang.org/x/sys/unix/asm_linux_mipsx.s create mode 100644 vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s create mode 100644 vendor/golang.org/x/sys/unix/asm_linux_riscv64.s create mode 100644 vendor/golang.org/x/sys/unix/asm_linux_s390x.s create mode 100644 vendor/golang.org/x/sys/unix/asm_openbsd_mips64.s create mode 100644 vendor/golang.org/x/sys/unix/asm_solaris_amd64.s create mode 100644 vendor/golang.org/x/sys/unix/asm_zos_s390x.s create mode 100644 vendor/golang.org/x/sys/unix/bluetooth_linux.go create mode 100644 vendor/golang.org/x/sys/unix/cap_freebsd.go create mode 100644 vendor/golang.org/x/sys/unix/constants.go create mode 100644 vendor/golang.org/x/sys/unix/dev_aix_ppc.go create mode 100644 vendor/golang.org/x/sys/unix/dev_aix_ppc64.go create mode 100644 vendor/golang.org/x/sys/unix/dev_darwin.go create mode 100644 vendor/golang.org/x/sys/unix/dev_dragonfly.go create mode 100644 vendor/golang.org/x/sys/unix/dev_freebsd.go create mode 100644 vendor/golang.org/x/sys/unix/dev_linux.go create mode 100644 vendor/golang.org/x/sys/unix/dev_netbsd.go create mode 100644 vendor/golang.org/x/sys/unix/dev_openbsd.go create mode 100644 vendor/golang.org/x/sys/unix/dev_zos.go create mode 100644 vendor/golang.org/x/sys/unix/dirent.go create mode 100644 vendor/golang.org/x/sys/unix/endian_big.go create mode 100644 vendor/golang.org/x/sys/unix/endian_little.go create mode 100644 vendor/golang.org/x/sys/unix/env_unix.go create mode 100644 vendor/golang.org/x/sys/unix/epoll_zos.go create mode 100644 vendor/golang.org/x/sys/unix/fcntl.go create mode 100644 vendor/golang.org/x/sys/unix/fcntl_darwin.go create mode 100644 vendor/golang.org/x/sys/unix/fcntl_linux_32bit.go create mode 100644 vendor/golang.org/x/sys/unix/fdset.go create mode 100644 vendor/golang.org/x/sys/unix/fstatfs_zos.go create mode 100644 vendor/golang.org/x/sys/unix/gccgo.go create mode 100644 vendor/golang.org/x/sys/unix/gccgo_c.c create mode 100644 vendor/golang.org/x/sys/unix/gccgo_linux_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/ifreq_linux.go create mode 100644 vendor/golang.org/x/sys/unix/ioctl.go create mode 100644 vendor/golang.org/x/sys/unix/ioctl_linux.go create mode 100644 vendor/golang.org/x/sys/unix/ioctl_zos.go create mode 100644 vendor/golang.org/x/sys/unix/mkall.sh create mode 100644 vendor/golang.org/x/sys/unix/mkerrors.sh create mode 100644 vendor/golang.org/x/sys/unix/pagesize_unix.go create mode 100644 vendor/golang.org/x/sys/unix/pledge_openbsd.go create mode 100644 vendor/golang.org/x/sys/unix/ptrace_darwin.go create mode 100644 vendor/golang.org/x/sys/unix/ptrace_ios.go create mode 100644 vendor/golang.org/x/sys/unix/race.go create mode 100644 vendor/golang.org/x/sys/unix/race0.go create mode 100644 vendor/golang.org/x/sys/unix/readdirent_getdents.go create mode 100644 vendor/golang.org/x/sys/unix/readdirent_getdirentries.go create mode 100644 vendor/golang.org/x/sys/unix/sockcmsg_dragonfly.go create mode 100644 vendor/golang.org/x/sys/unix/sockcmsg_linux.go create mode 100644 vendor/golang.org/x/sys/unix/sockcmsg_unix.go create mode 100644 vendor/golang.org/x/sys/unix/sockcmsg_unix_other.go create mode 100644 vendor/golang.org/x/sys/unix/str.go create mode 100644 vendor/golang.org/x/sys/unix/syscall.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_aix.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_aix_ppc.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_aix_ppc64.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_bsd.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin.1_12.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_dragonfly.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_dragonfly_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_freebsd.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_freebsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_freebsd_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_freebsd_riscv64.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_illumos.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_386.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_alarm.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_amd64_gc.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_arm.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_gc.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_gc_386.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_gc_arm.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_gccgo_386.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_gccgo_arm.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_loong64.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_ppc.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_s390x.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_netbsd.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_netbsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_netbsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_netbsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_netbsd_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_openbsd.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_openbsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_openbsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_openbsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_openbsd_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_openbsd_mips64.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_solaris.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_solaris_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_unix.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_unix_gc.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_unix_gc_ppc64x.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_zos_s390x.go create mode 100644 vendor/golang.org/x/sys/unix/sysvshm_linux.go create mode 100644 vendor/golang.org/x/sys/unix/sysvshm_unix.go create mode 100644 vendor/golang.org/x/sys/unix/sysvshm_unix_other.go create mode 100644 vendor/golang.org/x/sys/unix/timestruct.go create mode 100644 vendor/golang.org/x/sys/unix/unveil_openbsd.go create mode 100644 vendor/golang.org/x/sys/unix/xattr_bsd.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_aix_ppc.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_aix_ppc64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_dragonfly_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_freebsd_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_freebsd_riscv64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_386.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_arm.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_mips.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_netbsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_netbsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_netbsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_netbsd_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_openbsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_openbsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_openbsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_openbsd_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_openbsd_mips64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_solaris_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_zos_s390x.go create mode 100644 vendor/golang.org/x/sys/unix/zptrace_armnn_linux.go create mode 100644 vendor/golang.org/x/sys/unix/zptrace_linux_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/zptrace_mipsnn_linux.go create mode 100644 vendor/golang.org/x/sys/unix/zptrace_mipsnnle_linux.go create mode 100644 vendor/golang.org/x/sys/unix/zptrace_x86_linux.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_aix_ppc.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gc.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gccgo.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.s create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.s create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_freebsd_riscv64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_386.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_loong64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_ppc.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_zos_s390x.go create mode 100644 vendor/golang.org/x/sys/unix/zsysctl_openbsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/zsysctl_openbsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysctl_openbsd_mips64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_darwin_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_dragonfly_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_freebsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_freebsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_freebsd_riscv64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_386.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_netbsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_netbsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_openbsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_openbsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_openbsd_mips64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_zos_s390x.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_aix_ppc.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_aix_ppc64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_freebsd_riscv64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_illumos_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_386.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_arm.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_mips.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_netbsd_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_openbsd_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_openbsd_mips64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_zos_s390x.go create mode 100644 vendor/golang.org/x/text/AUTHORS create mode 100644 vendor/golang.org/x/text/CONTRIBUTORS create mode 100644 vendor/golang.org/x/text/LICENSE create mode 100644 vendor/golang.org/x/text/PATENTS create mode 100644 vendor/golang.org/x/text/feature/plural/common.go create mode 100644 vendor/golang.org/x/text/feature/plural/message.go create mode 100644 vendor/golang.org/x/text/feature/plural/plural.go create mode 100644 vendor/golang.org/x/text/feature/plural/tables.go create mode 100644 vendor/golang.org/x/text/internal/catmsg/catmsg.go create mode 100644 vendor/golang.org/x/text/internal/catmsg/codec.go create mode 100644 vendor/golang.org/x/text/internal/catmsg/varint.go create mode 100644 vendor/golang.org/x/text/internal/format/format.go create mode 100644 vendor/golang.org/x/text/internal/format/parser.go create mode 100644 vendor/golang.org/x/text/internal/internal.go create mode 100644 vendor/golang.org/x/text/internal/language/common.go create mode 100644 vendor/golang.org/x/text/internal/language/compact.go create mode 100644 vendor/golang.org/x/text/internal/language/compact/compact.go create mode 100644 vendor/golang.org/x/text/internal/language/compact/language.go create mode 100644 vendor/golang.org/x/text/internal/language/compact/parents.go create mode 100644 vendor/golang.org/x/text/internal/language/compact/tables.go create mode 100644 vendor/golang.org/x/text/internal/language/compact/tags.go create mode 100644 vendor/golang.org/x/text/internal/language/compose.go create mode 100644 vendor/golang.org/x/text/internal/language/coverage.go create mode 100644 vendor/golang.org/x/text/internal/language/language.go create mode 100644 vendor/golang.org/x/text/internal/language/lookup.go create mode 100644 vendor/golang.org/x/text/internal/language/match.go create mode 100644 vendor/golang.org/x/text/internal/language/parse.go create mode 100644 vendor/golang.org/x/text/internal/language/tables.go create mode 100644 vendor/golang.org/x/text/internal/language/tags.go create mode 100644 vendor/golang.org/x/text/internal/match.go create mode 100644 vendor/golang.org/x/text/internal/number/common.go create mode 100644 vendor/golang.org/x/text/internal/number/decimal.go create mode 100644 vendor/golang.org/x/text/internal/number/format.go create mode 100644 vendor/golang.org/x/text/internal/number/number.go create mode 100644 vendor/golang.org/x/text/internal/number/pattern.go create mode 100644 vendor/golang.org/x/text/internal/number/roundingmode_string.go create mode 100644 vendor/golang.org/x/text/internal/number/tables.go create mode 100644 vendor/golang.org/x/text/internal/stringset/set.go create mode 100644 vendor/golang.org/x/text/internal/tag/tag.go create mode 100644 vendor/golang.org/x/text/language/coverage.go create mode 100644 vendor/golang.org/x/text/language/doc.go create mode 100644 vendor/golang.org/x/text/language/go1_1.go create mode 100644 vendor/golang.org/x/text/language/go1_2.go create mode 100644 vendor/golang.org/x/text/language/language.go create mode 100644 vendor/golang.org/x/text/language/match.go create mode 100644 vendor/golang.org/x/text/language/parse.go create mode 100644 vendor/golang.org/x/text/language/tables.go create mode 100644 vendor/golang.org/x/text/language/tags.go create mode 100644 vendor/golang.org/x/text/message/catalog.go create mode 100644 vendor/golang.org/x/text/message/catalog/catalog.go create mode 100644 vendor/golang.org/x/text/message/catalog/dict.go create mode 100644 vendor/golang.org/x/text/message/catalog/go19.go create mode 100644 vendor/golang.org/x/text/message/catalog/gopre19.go create mode 100644 vendor/golang.org/x/text/message/doc.go create mode 100644 vendor/golang.org/x/text/message/format.go create mode 100644 vendor/golang.org/x/text/message/message.go create mode 100644 vendor/golang.org/x/text/message/print.go create mode 100644 vendor/golang.org/x/text/secure/bidirule/bidirule.go create mode 100644 vendor/golang.org/x/text/secure/bidirule/bidirule10.0.0.go create mode 100644 vendor/golang.org/x/text/secure/bidirule/bidirule9.0.0.go create mode 100644 vendor/golang.org/x/text/transform/transform.go create mode 100644 vendor/golang.org/x/text/unicode/bidi/bidi.go create mode 100644 vendor/golang.org/x/text/unicode/bidi/bracket.go create mode 100644 vendor/golang.org/x/text/unicode/bidi/core.go create mode 100644 vendor/golang.org/x/text/unicode/bidi/prop.go create mode 100644 vendor/golang.org/x/text/unicode/bidi/tables10.0.0.go create mode 100644 vendor/golang.org/x/text/unicode/bidi/tables11.0.0.go create mode 100644 vendor/golang.org/x/text/unicode/bidi/tables12.0.0.go create mode 100644 vendor/golang.org/x/text/unicode/bidi/tables13.0.0.go create mode 100644 vendor/golang.org/x/text/unicode/bidi/tables9.0.0.go create mode 100644 vendor/golang.org/x/text/unicode/bidi/trieval.go create mode 100644 vendor/golang.org/x/text/unicode/norm/composition.go create mode 100644 vendor/golang.org/x/text/unicode/norm/forminfo.go create mode 100644 vendor/golang.org/x/text/unicode/norm/input.go create mode 100644 vendor/golang.org/x/text/unicode/norm/iter.go create mode 100644 vendor/golang.org/x/text/unicode/norm/normalize.go create mode 100644 vendor/golang.org/x/text/unicode/norm/readwriter.go create mode 100644 vendor/golang.org/x/text/unicode/norm/tables10.0.0.go create mode 100644 vendor/golang.org/x/text/unicode/norm/tables11.0.0.go create mode 100644 vendor/golang.org/x/text/unicode/norm/tables12.0.0.go create mode 100644 vendor/golang.org/x/text/unicode/norm/tables13.0.0.go create mode 100644 vendor/golang.org/x/text/unicode/norm/tables9.0.0.go create mode 100644 vendor/golang.org/x/text/unicode/norm/transform.go create mode 100644 vendor/golang.org/x/text/unicode/norm/trie.go create mode 100644 vendor/golang.org/x/tools/AUTHORS create mode 100644 vendor/golang.org/x/tools/CONTRIBUTORS create mode 100644 vendor/golang.org/x/tools/LICENSE create mode 100644 vendor/golang.org/x/tools/PATENTS create mode 100644 vendor/golang.org/x/tools/go/ast/astutil/enclosing.go create mode 100644 vendor/golang.org/x/tools/go/ast/astutil/imports.go create mode 100644 vendor/golang.org/x/tools/go/ast/astutil/rewrite.go create mode 100644 vendor/golang.org/x/tools/go/ast/astutil/util.go create mode 100644 vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go create mode 100644 vendor/golang.org/x/tools/go/gcexportdata/importer.go create mode 100644 vendor/golang.org/x/tools/go/internal/gcimporter/bexport.go create mode 100644 vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go create mode 100644 vendor/golang.org/x/tools/go/internal/gcimporter/exportdata.go create mode 100644 vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go create mode 100644 vendor/golang.org/x/tools/go/internal/gcimporter/iexport.go create mode 100644 vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go create mode 100644 vendor/golang.org/x/tools/go/internal/gcimporter/newInterface10.go create mode 100644 vendor/golang.org/x/tools/go/internal/gcimporter/newInterface11.go create mode 100644 vendor/golang.org/x/tools/go/internal/gcimporter/support_go117.go create mode 100644 vendor/golang.org/x/tools/go/internal/gcimporter/support_go118.go create mode 100644 vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go create mode 100644 vendor/golang.org/x/tools/go/packages/doc.go create mode 100644 vendor/golang.org/x/tools/go/packages/external.go create mode 100644 vendor/golang.org/x/tools/go/packages/golist.go create mode 100644 vendor/golang.org/x/tools/go/packages/golist_overlay.go create mode 100644 vendor/golang.org/x/tools/go/packages/loadmode_string.go create mode 100644 vendor/golang.org/x/tools/go/packages/packages.go create mode 100644 vendor/golang.org/x/tools/go/packages/visit.go create mode 100644 vendor/golang.org/x/tools/imports/forward.go create mode 100644 vendor/golang.org/x/tools/internal/event/core/event.go create mode 100644 vendor/golang.org/x/tools/internal/event/core/export.go create mode 100644 vendor/golang.org/x/tools/internal/event/core/fast.go create mode 100644 vendor/golang.org/x/tools/internal/event/doc.go create mode 100644 vendor/golang.org/x/tools/internal/event/event.go create mode 100644 vendor/golang.org/x/tools/internal/event/keys/keys.go create mode 100644 vendor/golang.org/x/tools/internal/event/keys/standard.go create mode 100644 vendor/golang.org/x/tools/internal/event/label/label.go create mode 100644 vendor/golang.org/x/tools/internal/fastwalk/fastwalk.go create mode 100644 vendor/golang.org/x/tools/internal/fastwalk/fastwalk_dirent_fileno.go create mode 100644 vendor/golang.org/x/tools/internal/fastwalk/fastwalk_dirent_ino.go create mode 100644 vendor/golang.org/x/tools/internal/fastwalk/fastwalk_dirent_namlen_bsd.go create mode 100644 vendor/golang.org/x/tools/internal/fastwalk/fastwalk_dirent_namlen_linux.go create mode 100644 vendor/golang.org/x/tools/internal/fastwalk/fastwalk_portable.go create mode 100644 vendor/golang.org/x/tools/internal/fastwalk/fastwalk_unix.go create mode 100644 vendor/golang.org/x/tools/internal/gocommand/invoke.go create mode 100644 vendor/golang.org/x/tools/internal/gocommand/vendor.go create mode 100644 vendor/golang.org/x/tools/internal/gocommand/version.go create mode 100644 vendor/golang.org/x/tools/internal/gopathwalk/walk.go create mode 100644 vendor/golang.org/x/tools/internal/imports/fix.go create mode 100644 vendor/golang.org/x/tools/internal/imports/imports.go create mode 100644 vendor/golang.org/x/tools/internal/imports/mod.go create mode 100644 vendor/golang.org/x/tools/internal/imports/mod_cache.go create mode 100644 vendor/golang.org/x/tools/internal/imports/sortimports.go create mode 100644 vendor/golang.org/x/tools/internal/imports/zstdlib.go create mode 100644 vendor/golang.org/x/tools/internal/packagesinternal/packages.go create mode 100644 vendor/golang.org/x/tools/internal/typeparams/common.go create mode 100644 vendor/golang.org/x/tools/internal/typeparams/enabled_go117.go create mode 100644 vendor/golang.org/x/tools/internal/typeparams/enabled_go118.go create mode 100644 vendor/golang.org/x/tools/internal/typeparams/normalize.go create mode 100644 vendor/golang.org/x/tools/internal/typeparams/termlist.go create mode 100644 vendor/golang.org/x/tools/internal/typeparams/typeparams_go117.go create mode 100644 vendor/golang.org/x/tools/internal/typeparams/typeparams_go118.go create mode 100644 vendor/golang.org/x/tools/internal/typeparams/typeterm.go create mode 100644 vendor/golang.org/x/tools/internal/typesinternal/errorcode.go create mode 100644 vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go create mode 100644 vendor/golang.org/x/tools/internal/typesinternal/types.go create mode 100644 vendor/golang.org/x/xerrors/LICENSE create mode 100644 vendor/golang.org/x/xerrors/PATENTS create mode 100644 vendor/golang.org/x/xerrors/README create mode 100644 vendor/golang.org/x/xerrors/adaptor.go create mode 100644 vendor/golang.org/x/xerrors/codereview.cfg create mode 100644 vendor/golang.org/x/xerrors/doc.go create mode 100644 vendor/golang.org/x/xerrors/errors.go create mode 100644 vendor/golang.org/x/xerrors/fmt.go create mode 100644 vendor/golang.org/x/xerrors/format.go create mode 100644 vendor/golang.org/x/xerrors/frame.go create mode 100644 vendor/golang.org/x/xerrors/go.mod create mode 100644 vendor/golang.org/x/xerrors/internal/internal.go create mode 100644 vendor/golang.org/x/xerrors/wrap.go create mode 100644 vendor/google.golang.org/genproto/LICENSE create mode 100644 vendor/google.golang.org/genproto/googleapis/rpc/status/status.pb.go create mode 100644 vendor/google.golang.org/genproto/protobuf/api/api.go create mode 100644 vendor/google.golang.org/genproto/protobuf/field_mask/field_mask.go create mode 100644 vendor/google.golang.org/genproto/protobuf/ptype/type.go create mode 100644 vendor/google.golang.org/genproto/protobuf/source_context/source_context.go create mode 100644 vendor/google.golang.org/grpc/AUTHORS create mode 100644 vendor/google.golang.org/grpc/CODE-OF-CONDUCT.md create mode 100644 vendor/google.golang.org/grpc/CONTRIBUTING.md create mode 100644 vendor/google.golang.org/grpc/GOVERNANCE.md create mode 100644 vendor/google.golang.org/grpc/LICENSE create mode 100644 vendor/google.golang.org/grpc/MAINTAINERS.md create mode 100644 vendor/google.golang.org/grpc/Makefile create mode 100644 vendor/google.golang.org/grpc/NOTICE.txt create mode 100644 vendor/google.golang.org/grpc/README.md create mode 100644 vendor/google.golang.org/grpc/SECURITY.md create mode 100644 vendor/google.golang.org/grpc/attributes/attributes.go create mode 100644 vendor/google.golang.org/grpc/backoff.go create mode 100644 vendor/google.golang.org/grpc/backoff/backoff.go create mode 100644 vendor/google.golang.org/grpc/balancer/balancer.go create mode 100644 vendor/google.golang.org/grpc/balancer/base/balancer.go create mode 100644 vendor/google.golang.org/grpc/balancer/base/base.go create mode 100644 vendor/google.golang.org/grpc/balancer/grpclb/state/state.go create mode 100644 vendor/google.golang.org/grpc/balancer/roundrobin/roundrobin.go create mode 100644 vendor/google.golang.org/grpc/balancer_conn_wrappers.go create mode 100644 vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go create mode 100644 vendor/google.golang.org/grpc/call.go create mode 100644 vendor/google.golang.org/grpc/channelz/channelz.go create mode 100644 vendor/google.golang.org/grpc/clientconn.go create mode 100644 vendor/google.golang.org/grpc/codec.go create mode 100644 vendor/google.golang.org/grpc/codegen.sh create mode 100644 vendor/google.golang.org/grpc/codes/code_string.go create mode 100644 vendor/google.golang.org/grpc/codes/codes.go create mode 100644 vendor/google.golang.org/grpc/connectivity/connectivity.go create mode 100644 vendor/google.golang.org/grpc/credentials/credentials.go create mode 100644 vendor/google.golang.org/grpc/credentials/insecure/insecure.go create mode 100644 vendor/google.golang.org/grpc/credentials/tls.go create mode 100644 vendor/google.golang.org/grpc/dialoptions.go create mode 100644 vendor/google.golang.org/grpc/doc.go create mode 100644 vendor/google.golang.org/grpc/encoding/encoding.go create mode 100644 vendor/google.golang.org/grpc/encoding/proto/proto.go create mode 100644 vendor/google.golang.org/grpc/go.mod create mode 100644 vendor/google.golang.org/grpc/go.sum create mode 100644 vendor/google.golang.org/grpc/grpclog/component.go create mode 100644 vendor/google.golang.org/grpc/grpclog/grpclog.go create mode 100644 vendor/google.golang.org/grpc/grpclog/logger.go create mode 100644 vendor/google.golang.org/grpc/grpclog/loggerv2.go create mode 100644 vendor/google.golang.org/grpc/interceptor.go create mode 100644 vendor/google.golang.org/grpc/internal/backoff/backoff.go create mode 100644 vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/gracefulswitch.go create mode 100644 vendor/google.golang.org/grpc/internal/balancerload/load.go create mode 100644 vendor/google.golang.org/grpc/internal/binarylog/binarylog.go create mode 100644 vendor/google.golang.org/grpc/internal/binarylog/binarylog_testutil.go create mode 100644 vendor/google.golang.org/grpc/internal/binarylog/env_config.go create mode 100644 vendor/google.golang.org/grpc/internal/binarylog/method_logger.go create mode 100644 vendor/google.golang.org/grpc/internal/binarylog/sink.go create mode 100644 vendor/google.golang.org/grpc/internal/buffer/unbounded.go create mode 100644 vendor/google.golang.org/grpc/internal/channelz/funcs.go create mode 100644 vendor/google.golang.org/grpc/internal/channelz/id.go create mode 100644 vendor/google.golang.org/grpc/internal/channelz/logging.go create mode 100644 vendor/google.golang.org/grpc/internal/channelz/types.go create mode 100644 vendor/google.golang.org/grpc/internal/channelz/types_linux.go create mode 100644 vendor/google.golang.org/grpc/internal/channelz/types_nonlinux.go create mode 100644 vendor/google.golang.org/grpc/internal/channelz/util_linux.go create mode 100644 vendor/google.golang.org/grpc/internal/channelz/util_nonlinux.go create mode 100644 vendor/google.golang.org/grpc/internal/credentials/credentials.go create mode 100644 vendor/google.golang.org/grpc/internal/credentials/spiffe.go create mode 100644 vendor/google.golang.org/grpc/internal/credentials/syscallconn.go create mode 100644 vendor/google.golang.org/grpc/internal/credentials/util.go create mode 100644 vendor/google.golang.org/grpc/internal/envconfig/envconfig.go create mode 100644 vendor/google.golang.org/grpc/internal/envconfig/xds.go create mode 100644 vendor/google.golang.org/grpc/internal/grpclog/grpclog.go create mode 100644 vendor/google.golang.org/grpc/internal/grpclog/prefixLogger.go create mode 100644 vendor/google.golang.org/grpc/internal/grpcrand/grpcrand.go create mode 100644 vendor/google.golang.org/grpc/internal/grpcsync/event.go create mode 100644 vendor/google.golang.org/grpc/internal/grpcutil/encode_duration.go create mode 100644 vendor/google.golang.org/grpc/internal/grpcutil/grpcutil.go create mode 100644 vendor/google.golang.org/grpc/internal/grpcutil/metadata.go create mode 100644 vendor/google.golang.org/grpc/internal/grpcutil/method.go create mode 100644 vendor/google.golang.org/grpc/internal/grpcutil/regex.go create mode 100644 vendor/google.golang.org/grpc/internal/internal.go create mode 100644 vendor/google.golang.org/grpc/internal/metadata/metadata.go create mode 100644 vendor/google.golang.org/grpc/internal/pretty/pretty.go create mode 100644 vendor/google.golang.org/grpc/internal/resolver/config_selector.go create mode 100644 vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go create mode 100644 vendor/google.golang.org/grpc/internal/resolver/passthrough/passthrough.go create mode 100644 vendor/google.golang.org/grpc/internal/resolver/unix/unix.go create mode 100644 vendor/google.golang.org/grpc/internal/serviceconfig/serviceconfig.go create mode 100644 vendor/google.golang.org/grpc/internal/status/status.go create mode 100644 vendor/google.golang.org/grpc/internal/syscall/syscall_linux.go create mode 100644 vendor/google.golang.org/grpc/internal/syscall/syscall_nonlinux.go create mode 100644 vendor/google.golang.org/grpc/internal/transport/bdp_estimator.go create mode 100644 vendor/google.golang.org/grpc/internal/transport/controlbuf.go create mode 100644 vendor/google.golang.org/grpc/internal/transport/defaults.go create mode 100644 vendor/google.golang.org/grpc/internal/transport/flowcontrol.go create mode 100644 vendor/google.golang.org/grpc/internal/transport/handler_server.go create mode 100644 vendor/google.golang.org/grpc/internal/transport/http2_client.go create mode 100644 vendor/google.golang.org/grpc/internal/transport/http2_server.go create mode 100644 vendor/google.golang.org/grpc/internal/transport/http_util.go create mode 100644 vendor/google.golang.org/grpc/internal/transport/networktype/networktype.go create mode 100644 vendor/google.golang.org/grpc/internal/transport/proxy.go create mode 100644 vendor/google.golang.org/grpc/internal/transport/transport.go create mode 100644 vendor/google.golang.org/grpc/internal/xds_handshake_cluster.go create mode 100644 vendor/google.golang.org/grpc/keepalive/keepalive.go create mode 100644 vendor/google.golang.org/grpc/metadata/metadata.go create mode 100644 vendor/google.golang.org/grpc/peer/peer.go create mode 100644 vendor/google.golang.org/grpc/picker_wrapper.go create mode 100644 vendor/google.golang.org/grpc/pickfirst.go create mode 100644 vendor/google.golang.org/grpc/preloader.go create mode 100644 vendor/google.golang.org/grpc/reflection/README.md create mode 100644 vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection.pb.go create mode 100644 vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection.proto create mode 100644 vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection_grpc.pb.go create mode 100644 vendor/google.golang.org/grpc/reflection/serverreflection.go create mode 100644 vendor/google.golang.org/grpc/regenerate.sh create mode 100644 vendor/google.golang.org/grpc/resolver/map.go create mode 100644 vendor/google.golang.org/grpc/resolver/resolver.go create mode 100644 vendor/google.golang.org/grpc/resolver_conn_wrapper.go create mode 100644 vendor/google.golang.org/grpc/rpc_util.go create mode 100644 vendor/google.golang.org/grpc/server.go create mode 100644 vendor/google.golang.org/grpc/service_config.go create mode 100644 vendor/google.golang.org/grpc/serviceconfig/serviceconfig.go create mode 100644 vendor/google.golang.org/grpc/stats/handlers.go create mode 100644 vendor/google.golang.org/grpc/stats/stats.go create mode 100644 vendor/google.golang.org/grpc/status/status.go create mode 100644 vendor/google.golang.org/grpc/stream.go create mode 100644 vendor/google.golang.org/grpc/tap/tap.go create mode 100644 vendor/google.golang.org/grpc/trace.go create mode 100644 vendor/google.golang.org/grpc/version.go create mode 100644 vendor/google.golang.org/grpc/vet.sh create mode 100644 vendor/google.golang.org/protobuf/LICENSE create mode 100644 vendor/google.golang.org/protobuf/PATENTS create mode 100644 vendor/google.golang.org/protobuf/encoding/protojson/decode.go create mode 100644 vendor/google.golang.org/protobuf/encoding/protojson/doc.go create mode 100644 vendor/google.golang.org/protobuf/encoding/protojson/encode.go create mode 100644 vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go create mode 100644 vendor/google.golang.org/protobuf/encoding/prototext/decode.go create mode 100644 vendor/google.golang.org/protobuf/encoding/prototext/doc.go create mode 100644 vendor/google.golang.org/protobuf/encoding/prototext/encode.go create mode 100644 vendor/google.golang.org/protobuf/encoding/protowire/wire.go create mode 100644 vendor/google.golang.org/protobuf/internal/descfmt/stringer.go create mode 100644 vendor/google.golang.org/protobuf/internal/descopts/options.go create mode 100644 vendor/google.golang.org/protobuf/internal/detrand/rand.go create mode 100644 vendor/google.golang.org/protobuf/internal/encoding/defval/default.go create mode 100644 vendor/google.golang.org/protobuf/internal/encoding/json/decode.go create mode 100644 vendor/google.golang.org/protobuf/internal/encoding/json/decode_number.go create mode 100644 vendor/google.golang.org/protobuf/internal/encoding/json/decode_string.go create mode 100644 vendor/google.golang.org/protobuf/internal/encoding/json/decode_token.go create mode 100644 vendor/google.golang.org/protobuf/internal/encoding/json/encode.go create mode 100644 vendor/google.golang.org/protobuf/internal/encoding/messageset/messageset.go create mode 100644 vendor/google.golang.org/protobuf/internal/encoding/tag/tag.go create mode 100644 vendor/google.golang.org/protobuf/internal/encoding/text/decode.go create mode 100644 vendor/google.golang.org/protobuf/internal/encoding/text/decode_number.go create mode 100644 vendor/google.golang.org/protobuf/internal/encoding/text/decode_string.go create mode 100644 vendor/google.golang.org/protobuf/internal/encoding/text/decode_token.go create mode 100644 vendor/google.golang.org/protobuf/internal/encoding/text/doc.go create mode 100644 vendor/google.golang.org/protobuf/internal/encoding/text/encode.go create mode 100644 vendor/google.golang.org/protobuf/internal/errors/errors.go create mode 100644 vendor/google.golang.org/protobuf/internal/errors/is_go112.go create mode 100644 vendor/google.golang.org/protobuf/internal/errors/is_go113.go create mode 100644 vendor/google.golang.org/protobuf/internal/filedesc/build.go create mode 100644 vendor/google.golang.org/protobuf/internal/filedesc/desc.go create mode 100644 vendor/google.golang.org/protobuf/internal/filedesc/desc_init.go create mode 100644 vendor/google.golang.org/protobuf/internal/filedesc/desc_lazy.go create mode 100644 vendor/google.golang.org/protobuf/internal/filedesc/desc_list.go create mode 100644 vendor/google.golang.org/protobuf/internal/filedesc/desc_list_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/filedesc/placeholder.go create mode 100644 vendor/google.golang.org/protobuf/internal/filetype/build.go create mode 100644 vendor/google.golang.org/protobuf/internal/flags/flags.go create mode 100644 vendor/google.golang.org/protobuf/internal/flags/proto_legacy_disable.go create mode 100644 vendor/google.golang.org/protobuf/internal/flags/proto_legacy_enable.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/any_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/api_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/descriptor_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/doc.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/duration_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/empty_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/field_mask_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/goname.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/map_entry.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/source_context_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/struct_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/timestamp_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/type_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/wrappers.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/wrappers_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/api_export.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/checkinit.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_extension.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_field.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_map.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_map_go111.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_map_go112.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_message.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_messageset.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_reflect.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_tables.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_unsafe.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/convert.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/convert_list.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/convert_map.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/decode.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/encode.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/enum.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/extension.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/legacy_enum.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/legacy_export.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/legacy_extension.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/legacy_file.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/legacy_message.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/merge.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/merge_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/message.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/message_reflect.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/message_reflect_field.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/message_reflect_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/pointer_reflect.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/pointer_unsafe.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/validate.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/weak.go create mode 100644 vendor/google.golang.org/protobuf/internal/order/order.go create mode 100644 vendor/google.golang.org/protobuf/internal/order/range.go create mode 100644 vendor/google.golang.org/protobuf/internal/pragma/pragma.go create mode 100644 vendor/google.golang.org/protobuf/internal/set/ints.go create mode 100644 vendor/google.golang.org/protobuf/internal/strs/strings.go create mode 100644 vendor/google.golang.org/protobuf/internal/strs/strings_pure.go create mode 100644 vendor/google.golang.org/protobuf/internal/strs/strings_unsafe.go create mode 100644 vendor/google.golang.org/protobuf/internal/version/version.go create mode 100644 vendor/google.golang.org/protobuf/proto/checkinit.go create mode 100644 vendor/google.golang.org/protobuf/proto/decode.go create mode 100644 vendor/google.golang.org/protobuf/proto/decode_gen.go create mode 100644 vendor/google.golang.org/protobuf/proto/doc.go create mode 100644 vendor/google.golang.org/protobuf/proto/encode.go create mode 100644 vendor/google.golang.org/protobuf/proto/encode_gen.go create mode 100644 vendor/google.golang.org/protobuf/proto/equal.go create mode 100644 vendor/google.golang.org/protobuf/proto/extension.go create mode 100644 vendor/google.golang.org/protobuf/proto/merge.go create mode 100644 vendor/google.golang.org/protobuf/proto/messageset.go create mode 100644 vendor/google.golang.org/protobuf/proto/proto.go create mode 100644 vendor/google.golang.org/protobuf/proto/proto_methods.go create mode 100644 vendor/google.golang.org/protobuf/proto/proto_reflect.go create mode 100644 vendor/google.golang.org/protobuf/proto/reset.go create mode 100644 vendor/google.golang.org/protobuf/proto/size.go create mode 100644 vendor/google.golang.org/protobuf/proto/size_gen.go create mode 100644 vendor/google.golang.org/protobuf/proto/wrappers.go create mode 100644 vendor/google.golang.org/protobuf/reflect/protodesc/desc.go create mode 100644 vendor/google.golang.org/protobuf/reflect/protodesc/desc_init.go create mode 100644 vendor/google.golang.org/protobuf/reflect/protodesc/desc_resolve.go create mode 100644 vendor/google.golang.org/protobuf/reflect/protodesc/desc_validate.go create mode 100644 vendor/google.golang.org/protobuf/reflect/protodesc/proto.go create mode 100644 vendor/google.golang.org/protobuf/reflect/protoreflect/methods.go create mode 100644 vendor/google.golang.org/protobuf/reflect/protoreflect/proto.go create mode 100644 vendor/google.golang.org/protobuf/reflect/protoreflect/source.go create mode 100644 vendor/google.golang.org/protobuf/reflect/protoreflect/source_gen.go create mode 100644 vendor/google.golang.org/protobuf/reflect/protoreflect/type.go create mode 100644 vendor/google.golang.org/protobuf/reflect/protoreflect/value.go create mode 100644 vendor/google.golang.org/protobuf/reflect/protoreflect/value_pure.go create mode 100644 vendor/google.golang.org/protobuf/reflect/protoreflect/value_union.go create mode 100644 vendor/google.golang.org/protobuf/reflect/protoreflect/value_unsafe.go create mode 100644 vendor/google.golang.org/protobuf/reflect/protoregistry/registry.go create mode 100644 vendor/google.golang.org/protobuf/runtime/protoiface/legacy.go create mode 100644 vendor/google.golang.org/protobuf/runtime/protoiface/methods.go create mode 100644 vendor/google.golang.org/protobuf/runtime/protoimpl/impl.go create mode 100644 vendor/google.golang.org/protobuf/runtime/protoimpl/version.go create mode 100644 vendor/google.golang.org/protobuf/types/descriptorpb/descriptor.pb.go create mode 100644 vendor/google.golang.org/protobuf/types/known/anypb/any.pb.go create mode 100644 vendor/google.golang.org/protobuf/types/known/apipb/api.pb.go create mode 100644 vendor/google.golang.org/protobuf/types/known/durationpb/duration.pb.go create mode 100644 vendor/google.golang.org/protobuf/types/known/emptypb/empty.pb.go create mode 100644 vendor/google.golang.org/protobuf/types/known/fieldmaskpb/field_mask.pb.go create mode 100644 vendor/google.golang.org/protobuf/types/known/sourcecontextpb/source_context.pb.go create mode 100644 vendor/google.golang.org/protobuf/types/known/structpb/struct.pb.go create mode 100644 vendor/google.golang.org/protobuf/types/known/timestamppb/timestamp.pb.go create mode 100644 vendor/google.golang.org/protobuf/types/known/typepb/type.pb.go create mode 100644 vendor/google.golang.org/protobuf/types/known/wrapperspb/wrappers.pb.go create mode 100644 vendor/google.golang.org/protobuf/types/pluginpb/plugin.pb.go create mode 100644 vendor/gopkg.in/yaml.v2/.travis.yml create mode 100644 vendor/gopkg.in/yaml.v2/LICENSE create mode 100644 vendor/gopkg.in/yaml.v2/LICENSE.libyaml create mode 100644 vendor/gopkg.in/yaml.v2/NOTICE create mode 100644 vendor/gopkg.in/yaml.v2/README.md create mode 100644 vendor/gopkg.in/yaml.v2/apic.go create mode 100644 vendor/gopkg.in/yaml.v2/decode.go create mode 100644 vendor/gopkg.in/yaml.v2/emitterc.go create mode 100644 vendor/gopkg.in/yaml.v2/encode.go create mode 100644 vendor/gopkg.in/yaml.v2/go.mod create mode 100644 vendor/gopkg.in/yaml.v2/parserc.go create mode 100644 vendor/gopkg.in/yaml.v2/readerc.go create mode 100644 vendor/gopkg.in/yaml.v2/resolve.go create mode 100644 vendor/gopkg.in/yaml.v2/scannerc.go create mode 100644 vendor/gopkg.in/yaml.v2/sorter.go create mode 100644 vendor/gopkg.in/yaml.v2/writerc.go create mode 100644 vendor/gopkg.in/yaml.v2/yaml.go create mode 100644 vendor/gopkg.in/yaml.v2/yamlh.go create mode 100644 vendor/gopkg.in/yaml.v2/yamlprivateh.go create mode 100644 vendor/gopkg.in/yaml.v3/LICENSE create mode 100644 vendor/gopkg.in/yaml.v3/NOTICE create mode 100644 vendor/gopkg.in/yaml.v3/README.md create mode 100644 vendor/gopkg.in/yaml.v3/apic.go create mode 100644 vendor/gopkg.in/yaml.v3/decode.go create mode 100644 vendor/gopkg.in/yaml.v3/emitterc.go create mode 100644 vendor/gopkg.in/yaml.v3/encode.go create mode 100644 vendor/gopkg.in/yaml.v3/go.mod create mode 100644 vendor/gopkg.in/yaml.v3/parserc.go create mode 100644 vendor/gopkg.in/yaml.v3/readerc.go create mode 100644 vendor/gopkg.in/yaml.v3/resolve.go create mode 100644 vendor/gopkg.in/yaml.v3/scannerc.go create mode 100644 vendor/gopkg.in/yaml.v3/sorter.go create mode 100644 vendor/gopkg.in/yaml.v3/writerc.go create mode 100644 vendor/gopkg.in/yaml.v3/yaml.go create mode 100644 vendor/gopkg.in/yaml.v3/yamlh.go create mode 100644 vendor/gopkg.in/yaml.v3/yamlprivateh.go create mode 100644 vendor/modules.txt diff --git a/.gitignore b/.gitignore index 689bd7e..069f738 100644 --- a/.gitignore +++ b/.gitignore @@ -23,7 +23,6 @@ # vendor/ ### Go Patch ### -/vendor/ /Godeps/ ### Linux ### diff --git a/vendor/github.com/99designs/gqlgen/.dockerignore b/vendor/github.com/99designs/gqlgen/.dockerignore new file mode 100644 index 0000000..c8aadf3 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/.dockerignore @@ -0,0 +1,3 @@ +/**/node_modules +/codegen/tests/gen +/vendor diff --git a/vendor/github.com/99designs/gqlgen/.editorconfig b/vendor/github.com/99designs/gqlgen/.editorconfig new file mode 100644 index 0000000..feba8bb --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/.editorconfig @@ -0,0 +1,20 @@ +root = true + +[*] +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +indent_style = space +indent_size = 4 + +[*.{go,gotpl}] +indent_style = tab + +[*.yml] +indent_size = 2 + +# These often end up with go code inside, so lets keep tabs +[*.{html,md}] +indent_size = 2 +indent_style = tab diff --git a/vendor/github.com/99designs/gqlgen/.gitattributes b/vendor/github.com/99designs/gqlgen/.gitattributes new file mode 100644 index 0000000..df1ea74 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/.gitattributes @@ -0,0 +1,3 @@ +/codegen/templates/data.go linguist-generated +/example/dataloader/*_gen.go linguist-generated +generated.go linguist-generated diff --git a/vendor/github.com/99designs/gqlgen/.gitignore b/vendor/github.com/99designs/gqlgen/.gitignore new file mode 100644 index 0000000..a2017ef --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/.gitignore @@ -0,0 +1,15 @@ +/vendor +/docs/public +/example/chat/node_modules +/integration/node_modules +/integration/schema-fetched.graphql +/example/chat/package-lock.json +/example/federation/package-lock.json +/example/federation/node_modules +/codegen/gen +/gen + +/.vscode +.idea/ +*.test +*.out diff --git a/vendor/github.com/99designs/gqlgen/.golangci.yml b/vendor/github.com/99designs/gqlgen/.golangci.yml new file mode 100644 index 0000000..21099b6 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/.golangci.yml @@ -0,0 +1,39 @@ +run: + tests: true + skip-dirs: + - bin + +linters-settings: + errcheck: + ignore: fmt:.*,[rR]ead|[wW]rite|[cC]lose,io:Copy + +linters: + disable-all: true + enable: + - bodyclose + - deadcode + - depguard + - dupl + - errcheck + - gocritic + - gofmt + - goimports + - gosimple + - govet + - ineffassign + - misspell + - nakedret + - prealloc + - staticcheck + - structcheck + - typecheck + - unconvert + - unused + - varcheck + +issues: + exclude-rules: + # Exclude some linters from running on tests files. + - path: _test\.go + linters: + - dupl diff --git a/vendor/github.com/99designs/gqlgen/CHANGELOG.md b/vendor/github.com/99designs/gqlgen/CHANGELOG.md new file mode 100644 index 0000000..48d47f8 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/CHANGELOG.md @@ -0,0 +1,8294 @@ +# CHANGELOG +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + + +## [Unreleased](https://github.com/99designs/gqlgen/compare/v0.15.1...HEAD) + + + + +## [v0.15.1](https://github.com/99designs/gqlgen/compare/v0.15.0...v0.15.1) - 2022-01-16 +
2b8f50b3 Fix #1765](https://github.com/99designs/gqlgen/issues/1765): Sometimes module info not exists or not loaded. ([#1767) + +* Remove failing test + +
+ +- 46502e5e fixed broken link (#1768) + + + + + + +## [v0.15.0](https://github.com/99designs/gqlgen/compare/v0.14.0...v0.15.0) - 2022-01-14 +- 99be1951 Prepare for release + +
931271a2 Fix #1762](https://github.com/99designs/gqlgen/issues/1762): Reload packages before merging type systems ([#1763) + +* run gofmt on file + +
+ +- e5b5e832 Improve performance of MarshalBoolean (#1757) + +
57664bf0 Migrate playgrounds to GraphiQL (#1751) + +* migrate to GraphiQL playground + +* fix lint + +
+ +
b2a832d5 Avoid problems with `val` being undefined in the federation template. (#1760) + +* Avoid problems with `val` being undefined in the federation template. + +When running gqlgen over our schema, we were seeing errors like: +``` +assignments/generated/graphql/service.go:300:4: val declared but not used +``` + +The generated code looks like this: +``` +func entityResolverNameForMobileNavigation(ctx context.Context, rep map[string]interface{}) (string, error) { + for { + var ( + m map[string]interface{} + val interface{} + ok bool + ) + m = rep + if _, ok = m["kaid"]; !ok { + break + } + m = rep + if _, ok = m["language"]; !ok { + break + } + return "findMobileNavigationByKaidAndLanguage", nil + } + return "", fmt.Errorf("%w for MobileNavigation", ErrTypeNotFound) +} +``` + +Looking at the code, it's pretty clear that this happens when there +are multiple key-fields, but each of them has only one keyField.Field +entry. This is because the old code looked at `len(keyFields)` to +decide whether to declare the `val` variable, but looks at +`len(keyField.Field)` for each keyField to decide whether to use the +`val` variable. + +The easiest solution, and the one I do in this PR, is to just declare +`val` all the time, and use a null-assignment to quiet the compiler +when it's not used. + +* run go generate to update generated files + +* run go generate to update moar generated files + +* Adding a test for verify that this fixes the issue. + +From `plugins/federation`, run the following command and verify that no errors are produced + +``` +go run github.com/99designs/gqlgen --config testdata/entityresolver/gqlgen.yml +``` + +
+ +
47015f12 Added pointer to a solution for `no Go files` err (#1747) + +While following the instructions in this getting started guide I run into this error `package github.com/99designs/gqlgen: no Go files` which was pretty annoying to fix. Its a golang issue but for people who are unfamiliar with how the `go generate` command works in vendored projects its a blocker trying to follow the rest of this guide. It will be really nice to at least have a pointer in the guide for people to find a possible solution to the issue while going through the guide. I'm sure many folks have run into this issue given vendoring is now very popular with the latest go releases. + +
+ +- 27a2b210 Downgrade to Go 1.16 (#1743) + +
14cfee70 Support for multiple @key](https://github.com/key) directives in federation (reworked) ([#1723) + +* address review comments + +- reworked code generation for federation.go +- better checking for missing/incorrect parameters to entity resolver functions +- better tests for generated entity resolvers + +Still missing: +- suggested test for autobind vs non-autobind generation +- could probably clean up generated code spacing, etc + +
+ +- 2747bd5f Add CSV and PDF to common initialisms (#1741) + +
44beadc1 Fix list coercion when using graphql variables (#1740) + +* fix(codegen): support coercion of lists in graphql variables + +This was broken by an upstream dependency `gqlparser` coercing variables during validation. this has broken the existing coercion process withing `gqlgen` + +* test: add list coercion integration tests + +* chore: regenerate generated code + +* test: update expected schema for integration tests + +* chore: run goimports + +* chore: regenerate examples + +
+ +
bd8938d8 fix: automatically register built-in directive goTag (#1737) + +* fix: automatically register built-in tag goTag + +* doc: add directive config documentation + +
+ +
497227fa Close Websocket Connection on Context close/cancel (#1728) + +* Added code to the web socket so it closes when the context is cancelled (with an optional close reason). + +* Added a test. + +* go fmt + + +* Fix linter issues about the cancel function being thrown away. + +
+ +- 4581fccd Don't loose field arguments when none match (#1725) + +
213ecd93 Add support for graphql-transport-ws with duplex ping-pong (#1578) + +* Add support for graphql-transport-ws with duplex ping-pong + +* Add tests for the duplex ping-pong + +
+ +- ae92c83d add federation tests (#1719) + +- f591c8f7 Fix plugin addition (#1717) + +- 8fa6470f Fix #1704](https://github.com/99designs/gqlgen/issues/1704): handle [@required](https://github.com/required) nested fields as in [@key](https://github.com/key) ([#1706) + +
af33b7cd Cleaning up extra return in federation generated code (#1713) + +In PR 1709, I introduced GetMany semantics for resolving federated entities. But I left a couple of extra return statements in the generated code that are not necessary. So Im just cleaning those up here. + +Also added `go:generate` in federation entity resolver tests to make it simpler to test. + +To test: +``` +go generate ./... && cd example/ && go generate ./... && cd .. +go test -race ./... && cd example && go test -race ./... && cd .. +``` + +
+ +
402a2259 Optimize performance for binder, imports and packages (Rebased from sbalabanov/master) (#1711) + +* Cache go.mod resolution for module name search + +* Optimize binder.FindObject() for performance by eliminating repeatitive constructs + +* Optimize allocations in packages.Load() function + +* Optimize binder.FindObject() by indexing object definitions for each loaded package + +* goimports to fix linting + +
+ +- 237a7e6a Separate golangci-lint from other jobs (#1712) + +
50292e99 Resolve multiple federated entities in a single entityResolve call (#1709) + +* Resolve multiple federated entities in a single entityResolve call + +Entity resolver functions can only process one entity at a time. But often we want to resolve all the entities at once so that we can optimize things like database calls. And to do that you need to add you'd need to add batching with abstractions like dataloadgen or batchloader. The drawback here is that the resolver code (the domain logic) gets more complex to implement, test, and debug. + +An alternative is to have entity resolvers that can process all the representations in a single call so that domain logic can have access to all the representations up front, which is what Im adding in this PR. + +There are a few moving pieces here: +3. When that's configured, the federation plugin will create an entity resolver that will take a list of representations. + +Please note that this is very specific to federation and entity resolvers. This does not add support for resolving fields in an entity. + +Some of the implementation details worth noting. In order to efficiently process batches of entities, I group them by type so that we can process groups of entities at the same time. The resolution of groups of entities run concurrently in Go routines. If there is _only_ one type, then that's just processed without concurrency. Entities that don't have multiget enabled will still continue to resolve concurrently with Go routines, and entities that have multiget enabled just get the entire list of representations. + +The list of representations that are passed to entity resolvers are strongly types, and the type is generated for you. + +There are lots of new tests to ensure that there are no regressions and that the new functionality still functions as expected. To test: +1. Go to `plugin/federation` +2. Generate files with `go run github.com/99designs/gqlgen --config testdata/entityresolver/gqlgen.yml` +3. And run `go test ./...`. Verify they all pass. + +You can look at the federated code in `plugin/federation/testdata/entityresolver/gederated/federation.go` + +* Added `InputType` in entity to centralize logic for generating types for multiget resolvers. + +* reformat and regenerate + +
+ +
80713b84 Adding entity resolver tests for errors, entities with different type… (#1708) + +* Adding entity resolver tests for errors, entities with different types, and requires + +The tests in this PR are for ensuring we get the expected errors from entity resolvers, that we also handle resolving entities where the representations are for different types, and that requires directive works correctly. + +To run tests: +1. Go to `plugin/federation` +2. Generate files with `go run github.com/99designs/gqlgen --config testdata/entityresolver/gqlgen.yml` +3. And run `go test ./...`. Verify they all pass. + +* Fixed test for errors + +
+ +- ed2d6998 Replace ! with _ in root.generated file to avoid build conflicts (#1701) + +
828820af transport: implement `graphql-transport-ws` ws sub-protocol (#1507) + +* websocket: create `messageExchanger` to handle subprotocol messages + +* remove unused type + +* typo in comments + +* change `graphqlwsMessageType` type to string + +* add support for `graphql-transport-ws` subprotocol + +* fix chat app example + +* update example chat app dependencies + +* improve chat app exmaple to use the recommended ws library + +* add tests + +* removed unused const in tests + +* Update example/chat/readme.md + +
+ +- 28caa6ce Ignore generated files from test coverage (#1699) + +- 7ac988de Fix linting issue + +
01d3c4f8 Entity resolver tests (#1697) + +* Moving federation tests to their own folders + +Reorganizing the tests in the federation plugin a little bit so make it simpler to add more safely without testdata colliding. This is in anticipation for a follow up PR for adding entity resolver tests. + +Run the tests with `go test ./plugin/federation/...` and verify they all pass. Also verify that the testdata/allthething directory has a `generated` directory specific to that test. + +NOTE: There is a catch all type of test that I moved to the directory `allthething`. Open to suggestions for a better name! One potential thing to considere here is to split up the tests that use that testdata and break them down into more specific tests. E.g. Add a multikey test in the testdata/entity. For now, Im leaving that as a TODO. + +* Adding entity resolver tests in the federation plugin + +The tests work by sending `_entities` queries with `representation` variables directly to the mocked server, which will allow us to test generated federation code end to end. For context, the format of the entity query is something like: + +``` +query($representations:[_Any!]!){_entities(representations:$representations){ ...on Hello{secondary} }} +``` + +And `representations` are the list of federated keys for the entities being resovled, and they look like + +``` +representations: [{ + "__typename": "Hello", + "name": "federated key value 1", +}, { + "__typename": "Hello", + "name": "federated key value 2", +}] +``` + +The entity resolver tests are in `plugin/federation/federation_entityresolver_test.go` and they rely on `plugin/federation/testdata/entityresolver`. + +To run the tests: +1. Build the entityresolver testdata + - From plugin/federation, run `go run github.com/99designs/gqlgen --config testdata/entityresolver/gqlgen.yml` +2. Run the tests with `go test ./...` or similar + +
+ +
b7db36d3 Revert "Support for multiple @key](https://github.com/key) directives in federation ([#1684](https://github.com/99designs/gqlgen/issues/1684))" ([#1698) + +This reverts commit 47de912f56cd4bd6da9b74929cd67b8881617026. + +
+ +- 4a4b5601 DOC: Fixed indention in example code. (#1693) + +
47de912f Support for multiple @key](https://github.com/key) directives in federation ([#1684) + +* add more unit test coverage to plugin/federation + +
+ +
59a30919 Reimplement goTag using FieldMutateHook (#1682) + +* Reimplement goTag using a FieldMutateHook + +This change does not change the logic of goTag, merely reimplements it using a FieldMutateHook and sets it as the default FieldMutateHook for the modelgen plugin. + +* Add repeated tag test + +
+ +
37a4e7ee Rename `@extraTag](https://github.com/extraTag)` directive to `[@goTag](https://github.com/goTag)` and make repeatable ([#1680) + +* Allow Repeatable `goTag` Directive + +* Default to field name if none provided + +* Update Docs + +
+ +
87f9e436 Fix nil pointer dereference when an invalid import is bound to a model (#1676) + +* Fixes remaining Name field in singlefile test + +* Fixes nill pointer dereference when an invalid import is bound to a model + +* Only return error if we failed to find type + +* Revert "Fixes remaining Name field in singlefile test" + +This reverts commit e43ebf7aa80f884afdb3feca90867b1eff593f01. + +* Undo change of log.Println -> fmt.Println + +Totally accidental, sorry! + +
+ +
6c65e8f1 Update getting-started.md (#1674) + +missing an 's' on quoted filename default + +
+ +- 3bbc2a34 feat: generate resolvers for inputs if fields are missing (#1404) + +
7db941a5 Fix 1138: nested fieldset support (#1669) + +* formatting + +* update federation schema to latest Apollo spec + + +also: +handle extra spaces in FieldSet +upgrade deps in federation integration tests + +
+ +
488a31fc ContextMarshaler (#1652) + +* Add interface and detection for ContextMarshaler + +* Test error on float marshalling + +* Revert prettier changes + +* Rename context test + +* Only use the erroring float printer + +* Test that context is passed to marshal functions + +* Update scalar docs to include the context + +* Generate the examples + +* Move ContextMarshaller test code to new followschema + +* Resolve conflict a little more + + +* Replicate sclar test for singlefile + +
+ +- a626d9b4 Add ICMP to common initialisms (#1666) + +- db4b5eb7 Merge Inline Fragment Nested Interface Fields (#1663) + +
8b973717 Update directives doc page (#1660) + +* Update directives doc page + +* Add back one beloved piece of jargon + +
+ +
1f500016 Add follow-schema layout for exec (#1309) (closes #1265) + +* Define ExecConfig separate from PackageConfig + +When support for writing generated code to a directory instead of +a single file is added, ExecConfig will need additional fields +that will not be relevant to other users of PackageConfig. + +* Add single-file, follow-schema layouts + +When `ExecLayout` is set to `follow-schema`, output generated code to a +directory instead of a single file. Each file in the output directory +will correspond to a single *.graphql schema file (plus a +root!.generated.go file containing top-level definitions that are not +specific to a single schema file). + +`ExecLayout` defaults to `single-file`, which is the current behavior, so +this new functionality is opt-in. + +These layouts expose similar functionality to the `ResolverLayout`s with +the same name, just applied to `exec` instead of `resolver`. + + +* Rebase, regenerate + +
+ +
12978359 Update GQLgen test client to work with multipart form data (take 2) (#1661) + +* Update GQLgen test client to work with multipart form data + +Update the GQLgen to support multipart form data, like those present +within the fileupload examples. + +- Add missing space between "unsupported encoding " and failing + content-type header error + +(cherry picked from commit 101842f73fb79b10c1299bb40506080e08543ec6) + +* Add WithFiles client option for fileupload GQLgen client tests + +Add a `WithFiles` GQLgen client option to support the fileupload input +within tests, using the core Golang `os` package and File type, which +converts `os.File`s to their appropriate multipart form data within a +request. + +- If there are no files this should just simply convert a + `application/json` Content-Type to supported `multipart/form-data` + +(cherry picked from commit 08ef942416c98a2cadf61223308a3ff3c879d1c9) + +* Update fileupload test to use GQLgen test client + +Update the fileupload test to use the GQLgen test client and `WithFiles` +option to remove the need for `createUploadRequest` helper with raw http +posts + +- Fix setting the Content Type by using the appropriate `http` package + function to dectect it + + + https://godoc.org/net/http#DetectContentType + +(cherry picked from commit 5e573d51440eba9d457adb4186772577b28ef085) + +* Update WithFiles option test with multipart Reader + +(cherry picked from commit 6dfa3cbe0647138e80a59a0c1d55dd9c900f96f2) + +* Update file upload tests `WithFiles` option + +Update the file upload tests to use the GQL test client and its +`WithFiles` option to remove the need for a custom raw HTTP post request +builder `createUploadRequest`. + +- Also update `WithFiles` option to group & map identical files; e.g. + + ``` + { "0": ["variables.req.0.file", "variables.req.1.file"] } + ``` + +(cherry picked from commit 486d9f1b2b200701f9ce6b386736a633547c1441) + +* Make sure `WithFiles` does not add duplicates to multipart form data + +(cherry picked from commit 0c2364d8495553051d97ab805618b006fcd9eddb) + +* Fix use of byte vs string in `WithFiles` tests + +(cherry picked from commit ba10b5b1c52a74e63e825ee57c235254e8821e0d) + +* Fix strict withFiles option test for race conditions + +Fix a problem with how strict the test's expected response was for tests +with files in their request, since it always expected a strict order of +files input that is somewhat random or dependent on what OS it is +running the test on and/or race condition + +
+ +
7435403c Adds RootFieldInterceptor to extension interfaces (#1647) + +* Adds RootFieldInterceptor to extension interfaces + + +* Regenerates example folder + + +* Re-generate after changes + +
+ +- 8b25c9e0 Add a config option to skip running "go mod tidy" on code generation (#1644) + +
658195b7 Revert "Update GQLgen test client to work with multipart form data (#1418](https://github.com/99designs/gqlgen/issues/1418))" ([#1659) + +This reverts commit 1318f12792e86c76a2cdff9132ebac5b3e30e148. + +
+ +- 41c86765 Revert 1595 (#1658) + +- 8359f974 Allow custom websocket upgrader (#1595) + +
1318f127 Update GQLgen test client to work with multipart form data (#1418) + +* Update GQLgen test client to work with multipart form data + +Update the GQLgen to support multipart form data, like those present +within the fileupload examples. + +- Add missing space between "unsupported encoding " and failing + content-type header error + +* Add WithFiles client option for fileupload GQLgen client tests + +Add a `WithFiles` GQLgen client option to support the fileupload input +within tests, using the core Golang `os` package and File type, which +converts `os.File`s to their appropriate multipart form data within a +request. + +- If there are no files this should just simply convert a + `application/json` Content-Type to supported `multipart/form-data` + +* Update fileupload test to use GQLgen test client + +Update the fileupload test to use the GQLgen test client and `WithFiles` +option to remove the need for `createUploadRequest` helper with raw http +posts + +- Fix setting the Content Type by using the appropriate `http` package + function to dectect it + + + https://godoc.org/net/http#DetectContentType + +* Update WithFiles option test with multipart Reader + +* Update file upload tests `WithFiles` option + +Update the file upload tests to use the GQL test client and its +`WithFiles` option to remove the need for a custom raw HTTP post request +builder `createUploadRequest`. + +- Also update `WithFiles` option to group & map identical files; e.g. + + ``` + { "0": ["variables.req.0.file", "variables.req.1.file"] } + ``` + +* Make sure `WithFiles` does not add duplicates to multipart form data + +* Fix use of byte vs string in `WithFiles` tests + +
+ +- 6758654c raise panic when nested @requires](https://github.com/requires) are used on federation ([#1655) + +
f6c35be2 Add ReplacePlugin option to replace a specific plugin (#1657) + +* Add Helper Option for replacing plugins + +* Update recipe to use ReplacePlugin instead of NoPlugin and AddPlugin + +* fix linting issue on comment + +
+ +
f8c46600 fix double indirect bug (#1604) (closes #1587) + +* invalid code generated + +* update code generation for pointer-to-pointer updating + +
+ +- 629c91a2 remove extra WithOperationContext call (#1641) + +- 35199c49 codegen: ensure Elem present before using (#1317) + +
bfea93cd Reload config packages after generating models (#1491) + +If models are generated in a package that has already been loaded, and +that package refers to another package that has already been loaded, we +can find ourselves in a position where it appears that a GQL `union` is +not satisfied. + +For example, if we have: + +``` +union Subject = User +``` + +with this gqlgen.yml in github.com/wendorf/gqlgen-error/gql: + +``` +schema: +- schema.graphql +exec: + filename: generated.go +model: + + filename: models_gen.go +models: + User: + model: github.com/wendorf/gqlgen-error/gql.User + Subject: + model: github.com/wendorf/gqlgen-error/models.Subject +``` + +Note that our User model is in the github.com/wendorf/gqlgen-error.gql +package, and our models_gen.go will be generated in that same package. + +When we try to run gqlgen, we get this error: + +``` +merging type systems failed: unable to bind to interface: github.com/wendorf/gqlgen-error/gql.User does not satisfy the interface github.com/wendorf/gqlgen-error/models.Subject +``` + +Digging deeper, it's because we use types.Implements in +codegen/interface.go, which does a shallow object comparison. Because +the type has been reloaded, it refers to a _different_ interface type +object than the one we're comparing against, and get a false negative. + +By clearing the package cache and repopulating it, the whole package +cache is generated at the same time, and comparisons across packages +work. + +To see a demo of this, check out +https://github.com/wendorf/gqlgen-error and try the following: + +1. Checkout the works-with-v0.10.2 branch and `go generate ./...` to see + that it works +2. Checkout the breaks-with-v0.13.0 branch (or run go get + to see errors +3. Checkout the works-with-pull-request branch and `go generate ./...` + to see that it works again. This branch adds a go.mod replace + directive to use the gqlgen code in this PR. + +The demo starts at v0.10.2 since it is the last release without this +problem. https://github.com/99designs/gqlgen/pull/1020 introduces the +code that fails in this scenario. + +
+ +
9e0817cd Add graphql schema aware field level hook to modelgen (#1650) + +* Add ast aware field level hook to modelgen + +Currently, the only mechanism for extending the model generation is to use a BuildMutateHook at the end of the model generation process. This can be quite limiting as the hook only has scope of the model build and not the graphql schema which has been parsed. + +This change adds a hook at the end of the field creation process which provides access to the parsed graphql type definition and field definition. This allows for more flexibility for example adding additional tags to the model based off custom directives + +* Add recipe for using the modelgen FieldMutateHook + +* fix goimport linting issue in models_test + +
+ +
af2ac061 handling unconventional naming used in type names (#1549) + +* handling unconventional naming used in type names + +* Fix merge resolution mistake + +* Fix merge resolution mistake + +
+ +- 393f7554 add extraTag directive (#1173) + +- fd1bd7c9 adding support for sending extension with gqlgen client (#1633) + +
589a7742 Enable lowercase type names in GraphQL schema to properly render (#1359) + +The difficulty with lowercased type names is that in go code any lowercased name is not exported. +This change makes the names title case for go code while preserving the proper case when interacting with the GraphQL schema. + +
+ +- 50f6a2aa Fixes #1653](https://github.com/99designs/gqlgen/issues/1653): update docs and wrap error if not *gqlerror.Error ([#1654) + +
7081dedb Bump tmpl from 1.0.4 to 1.0.5 in /integration (#1627) + +Bumps [tmpl](https://github.com/daaku/nodejs-tmpl) from 1.0.4 to 1.0.5. +- [Release notes](https://github.com/daaku/nodejs-tmpl/releases) +- [Commits](https://github.com/daaku/nodejs-tmpl/commits/v1.0.5) + +--- +updated-dependencies: +- dependency-name: tmpl + dependency-type: indirect +... + +
+ +
5287e4e5 Add QR and KVK to common initialisms (#1419) + +* Add QR and KVK to common initialisms + +* Update templates.go + +* Sort commonInitialisms + +
+ +
f9df1a46 Update time format for `Time` scalar (#1648) + +* Use more precise time format + +* update test + +* update docs + +* Apply suggestions from code review + +* Update scalars.md + +
+ +
77c757f0 Merge pull request #1640 from minus7/master + +Fix example run instructions + +
+ +
e60dc7af Merge pull request #1619 from Khan/benkraft.mod-tidy-stdout + +Forward `go mod tidy` stdout/stderr + +
+ +
0c63f1d1 Merge pull request #1515 from OpenSourceProjects/time + +Marshaling & Unmarshaling time return initial value + +
+ +- a3d9e8ce Remove redundant favicon (#1638) + +- 210c1aa6 Appropriately Handle Falsy Default Field Values (#1623) + +
47ce074a Fix example run instructions (closes #1607) + +Making ./example a separate Go module [1] broke the `go run` invocations +listed in a few example readmes [2]. Using relative paths from the +respective example directory should be clear enough. + +[2]: +example/todo/server/server.go:10:2: no required module provides package github.com/99designs/gqlgen/example/todo; to add it: + go get github.com/99designs/gqlgen/example/todo + +
+ +- 1a0b19fe Update README.md + +
d9998283 Merge pull request #1628 from robertmarsal/patch-1 + +Fix typo in the getting-started docs + +
+ +- f93f73ac Fix typo in the getting-started docs + +
2f6919ff Merge pull request #1624 from FlymeDllVa/master + +Update disabling Introspection + +
+ +- c53bc0e5 Update disabling Introspection + +- 880cd73d Update README.md + +- eec81df0 Update README.md + +
43b56cba Forward `go mod tidy` stdout/stderr + +This is a command that can fail (in my case I think for stupid reasons +in a hell of my own construction, but nonetheless). Right now we just +get +``` +$ go run github.com/Khan/webapp/dev/cmd/gqlgen +tidy failed: go mod tidy failed: exit status 1 +exit status 3 +``` +which is not the most informative. Now, instead, we'll forward its +output to our own stdout/stderr rather than devnull. + +
+ +- ce7a8ee4 Fix link in docs + +- 488cf7e8 Update docs/content/getting-started.md + +- 73809f69 Update getting started + +- b938e558 Update README.md + +- cacd49a6 Update README.md + +
7d549d64 Merge pull request #1617 from 99designs/update-docs-for-go1.17 + +Update docs for getting started + +
+ +- 5c52f27c Update docs for getting started + +- 41d6926f Replace gitter with discord in contributing.md + +- 24d4edcf Update README.md + +- 2272e05b Update README.md + +
ef4d4a38 Merge pull request #1614 from 99designs/go-1.16 + +Also test against 1.16 + +
+ +- 00ed6fb1 Also test against 1.16 + +
473f0671 Merge pull request #1613 from 99designs/bump-non-module-deps + +Clean up non-module deps + +
+ +- 6960c0c2 Bump non-module deps + +
bf9b34aa Merge pull request #1612 from 99designs/update-linter + +Update golangci linter + +
+ +- 85e7a4a0 Linting fixes + +- 777dabde Update the linter + +
85dd47bb Merge pull request #1607 from 99designs/example-module + +[POC/RFC] Split examples into separate go module + +
+ +- f93fb248 Split examples into separate go module + +
890f5f66 Merge pull request #1610 from 99designs/go-1.17 + +Update to go 1.17 + +
+ +- 9162c53f Fix newlines in error messages + +- f67a5b26 Update github.com/urfave/cli/v2 + +
1116ea6c Merge pull request #1608 from jjmengze/patch-1 + +fix Options response header + +
+ +- 71e57843 Simplify init + +- a8903ca2 Wrap errors + +- a644175b Update error checks for go 1.17 + +- c6b9f292 go mod tidy + +- 1c63cfff Add missing model package file + +- 59da23fe Create a temporary file on init so go recognises the directory as a package + +
682a7d66 fix Options response header + +operatee the header of ResponseWriter should before WriteHeader called + +
+ +- ed8054b0 Update to a post-release version + +- 5216db58 Fix TestAutobinding test failure by checking the module + +- 90c5eb59 go generate + +- 402f4495 go fmt + +- 10bb1ef2 Go mod tidy + +- ed210385 Update to go 1.17 + +- 5c7acc1b Fix imports + +- d7473870 Update plugin/servergen/server.go + +- a6c6de6b Update plugin/resolvergen/resolver.go + +- de7d19c8 Update codegen/config/config_test.go + +- 60d80d4a Update cmd/gen.go + +- a991e3e7 Update errors to use go1.13 semantics + +
8f179be9 Merge pull request #1581 from tsh96/master + +Bypass complexity limit on __Schema queries. + +
+ +
5048f992 Merge pull request #1525 from Code-Hex/fix/support-input-object + +support input object directive + +
+ +
1e2b303a Merge pull request #1526 from epulze/fix/allow-more-types + +allow more than 10 different import sources with types + +
+ +
e7df3e5c Merge pull request #1405 from alexsn/subsciption-complete-on-panic + +subscriptions: send complete message on resolver panic + +
+ +
06e4fe88 Merge pull request #1529 from mathieupost/master + +Return type loading errors in config.Binder.FindObject + +
+ +
a557c90c Merge pull request #1340 from bickyeric/master + +serialize ID just like String + +
+ +
522cab59 Merge pull request #1285 from Khan/benkraft.federation + +Resolve requests for federation entities in parallel + +
+ +- 5adb73bb add bypass __schema field test case + +- 54cef3dd Bypass complexity limit on __Schema queries. + +- f0ccab79 Return type loading errors in config.Binder.FindObject + +- 91b54787 generated go code + +- 1efc152e supported INPUT_OBJECT directive + +- e82b401d allow more than 10 different import sources with types + +
481a4e44 Marshaling & Unmarshaling time return initial value + +There was a lack of symmetry that would prevent times for being +symmetrical. That is because time.Parse actually parses an RFC3339Nano +implicitly, thereby allowing nanosecond resolution on unmarshaling a +time. Therefore we now marshal into nanoseconds, getting more +information into GraphQL times when querying for a time, and restoring +the symmetry + +
+ +
95653193 Resolve requests for federation entities in parallel (closes #1278) + +In apollo federation, we may be asked for data about a list of entities. +These can typically be resolved in parallel, just as with sibling fields +in ordinary GraphQL queries. Now we do! + +I also changed the behavior such that if one lookup fails, we don't +cancel the others. This is more consistent with the behavior of other +resolvers, and is more natural now that they execute in parallel. This, +plus panic handling, required a little refactoring. + +The examples probably give the clearest picture of the changes. (And the +clearest test; the changed functionality is already exercised by +`integration-test.js` as watching the test server logs will attest.) + +
+ +- f00e2c3f subscriptions: send complete message on resolver panic + +- fa371b9b serialize ID just like String + + + + + + +## [v0.14.0](https://github.com/99designs/gqlgen/compare/v0.13.0...v0.14.0) - 2021-09-08 +- 56451d92 release v0.14.0 + +
8e97969b Merge pull request #1358 from mtsmfm/patch-1 + +Create package declaration to run dataloaden + +
+ +
b978593c Merge pull request #1387 from Khan/benkraft.config + +codegen/config: Add a new API to finish an already-validated config + +
+ +
71507dfc Merge pull request #1408 from max107/patch-1 + +int64 support graphql/string.go + +
+ +
23577b69 Merge pull request #1460 from snxk/edit-docs-recipe-gin + +Edited the Gin-Gonic Recipe Docs + +
+ +- db6154b9 Update README.md + +
cecda160 Merge pull request #1464 from frederikhors/patch-1 + +Add goreportcard badge + +
+ +- cc957171 Merge branch 'master' into patch-1 + +
023f66df Merge pull request #1465 from frederikhors/patch-2 + +Add coveralls badge + +
+ +
50c2028a Merge pull request #1497 from polytomic/stable-introspection + +Return introspection document in stable order + +
+ +
a0232dd2 Merge pull request #1603 from 99designs/dependabot/npm_and_yarn/integration/normalize-url-4.5.1 + +Bump normalize-url from 4.5.0 to 4.5.1 in /integration + +
+ +
4e059eba Merge pull request #1602 from 99designs/dependabot/npm_and_yarn/integration/ini-1.3.8 + +Bump ini from 1.3.5 to 1.3.8 in /integration + +
+ +
43705d45 Merge pull request #1601 from 99designs/dependabot/npm_and_yarn/integration/y18n-3.2.2 + +Bump y18n from 3.2.1 to 3.2.2 in /integration + +
+ +
1f2465c6 Merge pull request #1600 from 99designs/dependabot/npm_and_yarn/integration/browserslist-4.17.0 + +Bump browserslist from 4.14.0 to 4.17.0 in /integration + +
+ +
bbdebd4c Merge pull request #1599 from 99designs/dependabot/npm_and_yarn/integration/hosted-git-info-2.8.9 + +Bump hosted-git-info from 2.8.5 to 2.8.9 in /integration + +
+ +
900a37af Merge pull request #1598 from 99designs/dependabot/npm_and_yarn/integration/node-fetch-2.6.1 + +Bump node-fetch from 2.6.0 to 2.6.1 in /integration + +
+ +
9d334cdd Merge pull request #1597 from 99designs/dependabot/npm_and_yarn/integration/ws-7.4.6 + +Bump ws from 7.3.1 to 7.4.6 in /integration + +
+ +
56181e8a Merge pull request #1365 from frederikhors/add-uint,-uint64,-uint32-types-in-graphql + +add uint, uint64, uint32 types in graphql pkg + +
+ +
fd133c0b Bump normalize-url from 4.5.0 to 4.5.1 in /integration + +Bumps [normalize-url](https://github.com/sindresorhus/normalize-url) from 4.5.0 to 4.5.1. +- [Release notes](https://github.com/sindresorhus/normalize-url/releases) +- [Commits](https://github.com/sindresorhus/normalize-url/commits) + +--- +updated-dependencies: +- dependency-name: normalize-url + dependency-type: indirect +... + +
+ +
24d8c703 Bump ini from 1.3.5 to 1.3.8 in /integration + +Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.8. +- [Release notes](https://github.com/isaacs/ini/releases) +- [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.8) + +--- +updated-dependencies: +- dependency-name: ini + dependency-type: indirect +... + +
+ +
de89d3a6 Bump y18n from 3.2.1 to 3.2.2 in /integration + +Bumps [y18n](https://github.com/yargs/y18n) from 3.2.1 to 3.2.2. +- [Release notes](https://github.com/yargs/y18n/releases) +- [Changelog](https://github.com/yargs/y18n/blob/master/CHANGELOG.md) +- [Commits](https://github.com/yargs/y18n/commits) + +--- +updated-dependencies: +- dependency-name: y18n + dependency-type: indirect +... + +
+ +
13db6111 Bump browserslist from 4.14.0 to 4.17.0 in /integration + +Bumps [browserslist](https://github.com/browserslist/browserslist) from 4.14.0 to 4.17.0. +- [Release notes](https://github.com/browserslist/browserslist/releases) +- [Changelog](https://github.com/browserslist/browserslist/blob/main/CHANGELOG.md) +- [Commits](https://github.com/browserslist/browserslist/compare/4.14.0...4.17.0) + +--- +updated-dependencies: +- dependency-name: browserslist + dependency-type: indirect +... + +
+ +
94e9406e Bump hosted-git-info from 2.8.5 to 2.8.9 in /integration + +Bumps [hosted-git-info](https://github.com/npm/hosted-git-info) from 2.8.5 to 2.8.9. +- [Release notes](https://github.com/npm/hosted-git-info/releases) +- [Changelog](https://github.com/npm/hosted-git-info/blob/v2.8.9/CHANGELOG.md) +- [Commits](https://github.com/npm/hosted-git-info/compare/v2.8.5...v2.8.9) + +--- +updated-dependencies: +- dependency-name: hosted-git-info + dependency-type: indirect +... + +
+ +
36be94ff Bump node-fetch from 2.6.0 to 2.6.1 in /integration + +Bumps [node-fetch](https://github.com/node-fetch/node-fetch) from 2.6.0 to 2.6.1. +- [Release notes](https://github.com/node-fetch/node-fetch/releases) +- [Changelog](https://github.com/node-fetch/node-fetch/blob/main/docs/CHANGELOG.md) +- [Commits](https://github.com/node-fetch/node-fetch/compare/v2.6.0...v2.6.1) + +--- +updated-dependencies: +- dependency-name: node-fetch + dependency-type: direct:development +... + +
+ +
721158f3 Bump ws from 7.3.1 to 7.4.6 in /integration + +Bumps [ws](https://github.com/websockets/ws) from 7.3.1 to 7.4.6. +- [Release notes](https://github.com/websockets/ws/releases) +- [Commits](https://github.com/websockets/ws/compare/7.3.1...7.4.6) + +--- +updated-dependencies: +- dependency-name: ws + dependency-type: direct:development +... + +
+ +
2b3b7212 Merge pull request #1594 from 99designs/dependabot/npm_and_yarn/integration/tar-6.1.11 + +Bump tar from 6.0.5 to 6.1.11 in /integration + +
+ +
5b43833d Merge pull request #1582 from 99designs/dependabot/npm_and_yarn/integration/path-parse-1.0.7 + +Bump path-parse from 1.0.6 to 1.0.7 in /integration + +
+ +
55b028ca Merge pull request #1584 from nullism/patch-1 + +Fix spaces -> tabs typo in authentication.md + +
+ +
edf630a3 Bump tar from 6.0.5 to 6.1.11 in /integration + +Bumps [tar](https://github.com/npm/node-tar) from 6.0.5 to 6.1.11. +- [Release notes](https://github.com/npm/node-tar/releases) +- [Changelog](https://github.com/npm/node-tar/blob/main/CHANGELOG.md) +- [Commits](https://github.com/npm/node-tar/compare/v6.0.5...v6.1.11) + +--- +updated-dependencies: +- dependency-name: tar + dependency-type: indirect +... + +
+ +
29133c11 Fix spaces -> tabs typo in authentication.md + +The indentation here was supposed to be a tab rather than spaces so the readme was off. + +
+ +
01b25c55 Bump path-parse from 1.0.6 to 1.0.7 in /integration + +Bumps [path-parse](https://github.com/jbgutierrez/path-parse) from 1.0.6 to 1.0.7. +- [Release notes](https://github.com/jbgutierrez/path-parse/releases) +- [Commits](https://github.com/jbgutierrez/path-parse/commits/v1.0.7) + +--- +updated-dependencies: +- dependency-name: path-parse + dependency-type: indirect +... + +
+ +
9a214e80 Merge pull request #1451 from sanjeevchopra/patch-1 + +doc only change: updated sample code for disabling introspection + +
+ +
01197437 Merge pull request #1417 from RicCu/patch-1 + +Use mutation instead of query in 'Changesets' doc example + +
+ +
e3293b53 Merge pull request #1444 from lisowskibraeden/patch-1 + +Update cors.md + +
+ +
a4d67855 Merge pull request #1517 from ShivangGoswami/patch-1 + +Update apq.md function definition mismatch + +
+ +
eb36f04f Return introspection document in stable order + +This avoids spurious changes when generating client code using +something like graphql-codegen. + +
+ +
7e38dd46 Merge pull request #1568 from DanyHenriquez/patch-1 + +Update apq.md + +
+ +
88f2b8a7 Merge pull request #1572 from talhaguy/dataloaders-doc-casing + +Correct minor casing issue + +
+ +- be9a0791 Update apq.md + +- 3e45ddc1 Correct minor casing issue + +- 145101e4 Update apq.md + +
843edd9e Update apq.md function definition mismatch + +line 67: cache, err := NewCache(cfg.RedisAddress, 24*time.Hour) +line 41: func NewCache(redisAddress string, password string,ttl time.Duration) (*Cache, error) + +either password should be removed from 41 or added in line 67 +Proposed the first one for now. + +
+ +
5ad012e3 Revert "Merge pull request #1511 from a8m/a8m/restore-cwd" + +This reverts commit f4bf1f591b6a3884041876deb64ce0dd70c3c883, reversing +changes made to 3f68ea27a1a9fea2064caf877f7e24d00aa439e6. + +Reverting this because it will break existing setups, moving where +generated files get put. + +
+ +- bb59cc43 Add a CHANGELOG.md (#1512) + +- 058a365a Merge pull request #1456 from skaji/issue-1455 + +
bf2fdf44 Merge pull request #1514 from 99designs/bump-gqlparser + +Bump gqlparser to v2.2.0 + +
+ +- 4e881981 Bump to gqlparser v2.2.0 + +- 1d768a29 Add test covering single element -> slice coercion + +- f57d1a02 Bump gqlparser to master & support repeated directives + +
f4bf1f59 Merge pull request #1511 from a8m/a8m/restore-cwd + +codegen/config: restore current working directory after changing it + +
+ +- 3f68ea27 Special handling for pointers to slices (#1363) + +
c920bdeb Merge pull request #1449 from steebchen/feat-prisma-compat + +feat(codegen): handle (v, ok) methods + +
+ +
3cfc5b14 codegen/config: restore current working directory after changing it + +Before this commit, a call to config.LoadConfigFromDefaultLocations changed +the working directory to the directory that contains the gqlgen config +file. + +This commit changes the implementation to restore the working directory +after loading the config. + +
+ +
35b80a72 Merge pull request #1495 from Niennienzz/improve-apq-doc + +Update apq.md + +
+ +
463debae Merge pull request #1503 from nana4gonta/resolve-vulnerability + +Resolve indirect dependency vulnerability in example + +
+ +
29e7bccb Merge pull request #1501 from 99designs/fix-init-1.16 + +Run go mod tidy after code generation + +
+ +
9a4c80ab Merge pull request #1502 from 99designs/rm-chi + +Remove chi from dataloader example + +
+ +- 5f21f9d9 Remove chi from dataloader example + +- e02db808 Run go mod tidy after code generation + +- 8c3e64e1 Improve APQ documentation + +- 03b57f3e Run go mod tidy + +- 54e387c4 Resolve indirect dependency vulnerability in example + +- 7985db44 Mention math.rand for the todo ID (#1489) + +- b995f7f1 Make spacing consistent (#1488) + +
52ded951 Merge pull request #1459 from aaronArinder/getting-started-server-section + +getting started: make running server own section + +
+ +- 82a8e1bf Make it clearer what happened on init. (#1487) + +
7258af5f Merge pull request #1458 from aaronArinder/getting-started-wording + +getting started: making the resolver fn section clearer + +
+ +
4fead489 Merge pull request #1452 from fmyd/fix/formatted-query-indent + +prettified some indentation + +
+ +
58e3225e Merge pull request #1480 from wilhelmeek/double-bubble + +Bubble Null from List Element to Nearest Nullable Ancestor + +
+ +- 1fac78e9 Add test case for nullable field + +- 469e31bd Fix bad test case + +- 635b1aef Add Test Case + +- 0b5da15c Check in generated code + +- 55b774ba Fix type ref + +- 45903a65 Handle nillable list elements + +- c4bf36c5 Add coveralls badge + +- 269a58ad Add goreportcard badge + +- 971da82c Updated gin.md + +- 41ad51ce Edited the Gin-Gonic Recipe Docs + +- 67e652ad getting started: separate example mutation/query + +- 31d339ab getting started: make running server own section + +- aa531ed8 getting started: more wording updates + +- 5b2531ae getting started: wording update + +- ada1b928 getting started: updating wording around implementing unimpl fns + +- 23eec791 go generate ./... + +
18678b15 Fix data race + +The argument of unmarshalInput may be the same for concurrent use if it pass as graphql "variables". +So we have to copy it before setting default values + +
+ +- 02b14003 fomatted query indent + +- 0e9d9c3a updated sample code for disabling introspection + +- 478c3f08 feat(codegen): handle (v, ok) methods + +
5ef5d14f Update cors.md + +I had problems reading this page and applying it to my project. With these changes it worked on my end + +
+ +
997da421 Merge pull request #1436 from ddouglas/patch-1 + +Upgrade graphql-playground to 1.7.26 + +
+ +- be4514c6 Upgrade graphql-playground to 1.7.26 + +- 918801ea Change 'Changeset' doc example to mutation + +
862762c7 Merge pull request #1409 from zikaeroh/chi-mod + +Upgrade go-chi to v1.5.1 with module support + +
+ +- c30ff3dd Upgrade go-chi to v1.5.1 with module support + +- a9c8fabf int64 support + +
b484fc27 Merge pull request #1401 from oseifrimpong/patch-1 + +fix typo + +
+ +
4cc031af Merge pull request #1394 from j2gg0s/fix-default-recover-func + +bugfix: Default Recover func should return gqlerror.Error + +
+ +
2af51336 Merge pull request #1400 from 99designs/sanstale + +Remove stale bot + +
+ +
34a442c7 Merge pull request #1399 from 99designs/prevent-possible-error-deadlock + +Dont hold error lock when calling into error presenters + +
+ +
1123ba0d Update gin.md + +Changed this: +`In your router file, define the handlers for the GraphQL and Playground endpoints in two different methods and tie then together in the Gin router: +` +to: +`In your router file, define the handlers for the GraphQL and Playground endpoints in two different methods and tie them together in the Gin router: +` + +
+ +
89a9f743 Remove stale bot + +We tried it, but it's just causing more work both for maintainers and reporters of errors. + +
+ +
4628ef84 Dont hold error lock when calling into error presenters + +This can result in a deadlock if error handling code calls GetErrors. + +
+ +- d0d5f7db bugfix: Default Recover func should return gqlerror.Error + +
18b5df19 codegen/config: Add a new API to finish an already-validated config + +LoadConfig parses the config from yaml, but it does a bunch of other +things too. We want to parse the config ourselves, so that we can have +extra fields which will be passed to our plugins. Right now, that means +we either have to duplicate all of LoadConfig, or write the config back +to disk only to ask gqlgen re-parse it. + +In this commit, I expose a new function that does all the parts of +LoadConfig other than the actual YAML-reading: that way, a caller who +wants to parse the YAML themselves (or otherwise programmatically +compute the config) can do so without having to write it back to disk. + +An alternative would be to move all this logic to Config.Init(), but +that could break existing clients. Either way would work for us. + +
+ +
0e12bfbf Merge pull request #1269 from dqn/new-line-at-the-end-of-file + +Add a new line to end of the file schema.graphqls + +
+ +
22c5d1f5 Merge pull request #1303 from kunalpowar/inline-directives-doc + +Update README.md + +
+ +
88cffee4 Merge pull request #1356 from maapteh/chore/chat-example-update + +Chore: update Chat example + +
+ +- 1e8c34e5 Dont export Input + +
de8af66c Merge pull request #1360 from Captain-K-101/master + +Update introspection.md + +
+ +- 09756915 Update introspection docs + +
651eda40 Merge pull request #1374 from rudylee/docs-file-upload-small-typo + +Fix small typo in file upload docs + +
+ +- 94252e04 singleUpload consistency + +- c9d346f5 Fix small typo in file upload docs + +- 9f851619 add uint, uint64, uint32 types in graphql + +
0625525f Update introspection.md + +updated disabling interospect + +
+ +- c6a93aa7 split layout components to their own part, makes sample more readable + +- 7904ef6f channel is switchable too + +- 13752055 add some layout for demo :) + +
82ca6e24 Create package declaration to run dataloaden + +ref: https://github.com/vektah/dataloaden/issues/35 + +
+ +- bf549136 use Apollo docs styling for the gql var uppercase + +- 36045a37 do not autofocus + +- 0502228a chore: update example to React hooks and latest Apollo client + +- e6e64224 update deps + +
3a31a752 Merge pull request #1345 from abeltay/fix-alignment + +Fix tab spacing in cors.md + +
+ +
0c68337c Merge pull request #1346 from abeltay/fix-typo + +Fix typo in migration guide + +
+ +- 436a88ad Fix typo in migration guide + +- 3791f71d Fix tab spacing in cors.md + +
819e751c Merge pull request #1341 from dgraph-io/rajas/fix-gqlgen-1299 + +Rajas/fix gqlgen 1299 + +
+ +- 789d02f5 Requested changes + +- 130ed3f7 Fix different alias with same name in inline fragment + +- f4669ba9 v0.13.0 postrelease bump + +- 07c06594 Update README.md + +- 1c9f24b2 remove triming space for schemaDefault + + + + + + +## [v0.13.0](https://github.com/99designs/gqlgen/compare/v0.12.2...v0.13.0) - 2020-09-21 +- 07c1f93b release v0.13.0 + +- 259f2711 Bump to gqlparser to v2.1.0 Error unwrapping release + +
669a1668 Merge pull request #1312 from 99designs/error-wrapping + +Always wrap user errors + +
+ +
9b948a5f Merge pull request #1316 from skaji/is-resolver + +Add IsResolver to FieldContext + +
+ +- 77aeb477 Point latest docs to v0.12.2 + +
e821b97b Always wrap user errors (closes #1305) + +Requires use of go 1.13 error unwrapping. + +On measure I think I prefer this approach, even though it's a bigger BC break: +- There's less mutex juggling +- It has never felt right to me that we make the user deal with path when overriding the error presenter +- The default error presenter is now incredibly simple + +Questions: +- Are we comfortable with supporting 1.13 and up? +- Should we change the signature of `ErrorPresenterFunc` to `func(ctx context.Context, err *gqlerror.Error) *gqlerror.Error`? + - It always is now, and breaking BC will force users to address the requirement for `errors.As` + +
+ +
51b580de Merge pull request #1324 from bemasher/patch-1 + +Fix typos in README.md + +
+ +- 8b2a023c Fix typos in README.md + +- 3e5dd956 add test for FieldContext.IsResolver + +- 1524989b go generate + +- 55951163 add IsResolver to FieldContext + +
622316e7 Merge pull request #1295 from a-oz/a-oz-patch-1 + +Update getting-started.md + +
+ +
4c11d9fa Update getting-started.md + +fix typo + +
+ +- b4375b04 v0.12.2 postrelease bump + + + + + + +## [v0.12.2](https://github.com/99designs/gqlgen/compare/v0.12.1...v0.12.2) - 2020-08-18 +- 03cebf20 release v0.12.2 + +
e3ce560d Merge pull request #1288 from alexsn/nopath-field-noerror + +avoid computing field path when getting field errors + +
+ +
108975c3 Merge pull request #1284 from dgraph-io/jatin/sameFieldSameTypeGettingIgnored + +fix same field name in two different fragments + +
+ +
eb424a22 Merge pull request #1294 from 99designs/fix-init + +Allow rewriter to work on empty but potentially importable packages + +
+ +- a87c54ad Allow rewriter to work on empty but potentially importable ckages + +- 8a7f3e64 clean code + +- fd0f97ce avoid computing field path when getting field errors + +- 2d59b684 ran fmt on test + +- 3a153075 ran fmt + +- defd7119 added test + +- 9fcdbcd1 fix panic test + +- 473d63c0 change name to alias + +- 849e3eac added check for object defination name + +- 08eee0fc v0.12.1 postrelease bump + + + + + + +## [v0.12.1](https://github.com/99designs/gqlgen/compare/v0.12.0...v0.12.1) - 2020-08-14 +- 0d5f462b release v0.12.1 + +- e076b1b0 Regenerate test server + +- c952e0de v0.12.0 postrelease bump + + + + + + +## [v0.12.0](https://github.com/99designs/gqlgen/compare/v0.11.3...v0.12.0) - 2020-08-14 +- 70302123 Version 0.12.0 + +
3b633dfa Merge pull request #1267 from ImKcat/master + +Fixed transport not support issue + +
+ +
c9a27ae3 Merge pull request #1255 from s-ichikawa/fix-object-directive-bug + +Fix bug about OBJECT directive + +
+ +
e9863af1 Merge pull request #1276 from Ghvstcode/master + +Documentation Fixes + +
+ +
04f6a691 Merge pull request #1277 from 99designs/direct-pointer-binding + +Support pointers in un/marshal functions + +
+ +- bef9c8bf Add comments and docs for pointer scalars + +
997efd03 Reintroduce special cast case for string enums + +This reverts commit 89960664d05f0e93ed629a22753b9e30ced2698f. + +
+ +- 8561c056 Replace awkward loop in buildTypes with recursion + +- d65b04f9 Clean up generated code + +- e1c463a4 Linting + +- 89960664 Remove unused special cast case for string enums + +- 196954bc Bind directly to pointer types when possible, instead of always binding to value types + +- 5b3d08db Update README.md + +- efd33dab Update README.md + +- f35b162f Fixed transport not support issue + +
39a12e0f Merge pull request #1134 from seriousben/fix-default-config-no-ast-sources + +Add LoadDefaultConfig to load the schema by default + +
+ +
1b23cf15 Merge pull request #1264 from 99designs/go-1.14 + +Target multiple go versions for CI + +
+ +- dbbda22e go 1.14 + +
ce964c1f Merge pull request #1115 from bowd/add-input-path-for-unmarshaling + +Add input path in unmarshaling errors + +
+ +- bde4291c shadow context to ensure scoped context use + +- c43990a0 Merge remote-tracking branch 'origin/master' into HEAD + +- 6be2e9df fix fileupload example + +
ad675f00 Allow custom resolver filenames using `filename_template` option (closes #1085) + +resolve merge conflicts. + +
+ +- fbfdd41c Merge pull request #1262 from sateeshpnv/gqlparser-alias (closes #1258) + +- 99fafc9f issue [#1258] explicitly add gqlparser alias to vektah/gqlparser/v2 import + +- 49291f23 fix bug in OBJECT directive + +
0fbf293f Merge pull request #1248 from sotoslammer/master + +close the connection when run returns + +
+ +
d7eabafb Merge pull request #1246 from arkhvoid/master + +Fix typo cause memory problem on upload + +
+ +- 21b223b8 Fix typo cause memory problem on upload + +- cc9c520f close the connection when run returns + +
8494028e Merge pull request #1243 from 99designs/nilable-nullable-unnmarshal + +Remove a bunch of unneeded nil checks from non-nullable graphql type unmarshalling + +
+ +- b81138da Add test for nillable input slice + +- 14d1a4dc Only return nil for nilable types when the graphql spec would allow it + +
3e59a10d Merge pull request #1215 from ddouglas/master + +Adding Missing Header to response + +
+ +
1650c499 Merge pull request #1242 from 99designs/named_map_references + +Do not use pointers on named map types + +
+ +- d11f6021 Do not use pointers on named map types + +
acaee361 Merge pull request #1121 from Khan/extern-only + +Do not require a resolver for "empty" extended types. + +
+ +
555db6d2 Merge pull request #1224 from frederikhors/patch-1 + +Indentation misprint + +
+ +- 77b37bb2 Indentation misprint + +
a3c38c65 Merge pull request #1221 from longngn/patch-1 + +Update dataloaders.md + +
+ +- 71182de8 Update dataloaders.md + +
d81baeed Merge pull request #1218 from StevenACoffman/patch-1 + +Update feature comparison for federation + +
+ +- 2c1f2345 Update feature comparison for federation (closes #5) + +- e19d43bc Adding test + +- 4a62f012 Adding ContentType header to GET request responses + +- f5de4731 Add timeout to integration test + +
a21a6633 Merge pull request #1189 from RichardLindhout/patch-1 + +Upgrade to OperationContext and remove duplicate fields to fix https:… + +
+ +
543317a2 Merge pull request #1170 from alexsn/apollotracing/nopanic + +apollotracing: skip field interceptor when on no tracing extension + +
+ +- d347d972 Update stale.yml + +
032854bb Merge pull request #1154 from gsgalloway/master + +Add operation context when dispatching + +
+ +
ccc4eb1d Merge pull request #1188 from k-yomo/update-errors-doc + +Update outdated examples in errors doc + +
+ +
628b83c1 Merge pull request #1198 from ddevault/pgp + +codegen: add PGP to common initialisms + +
+ +
d881559b Merge pull request #1202 from whereswaldon/patch-1 + +doc: fix typo in embedded struct example + +
+ +
b6ce42a7 Merge pull request #1207 from k-yomo/update-gorilla-websocket + +Update gorilla/websocket to v1.4.2 to resolve vulnerability + +
+ +- c5bfe9d3 Update gorilla/websocket to v1.4.2 to resolve vulnerability + +- 55c16e93 doc: fix typo in embedded struct example + +- 89eb1993 codegen: add PGP to common initialisms + +- 9ab7294d apollotracing: skip field interceptor when on no tracing extension + +
40570d1b Merge pull request #1163 from fwojciec/master + +fix redundant type warning + +
+ +
3f7f60bf Merge pull request #1181 from tmc/patch-1 + +Update getting-started.md + +
+ +- 6518d839 Upgrade to OperationContext and remove duplicate fields to fix https://github.com/99designs/gqlgen/pull/1161 + +- 632904ad Update outdated examples in errors doc + +- 0921915d Update getting-started.md + +
0a404813 Merge pull request #1117 from s-ichikawa/object-directive + +Add support for OBJECT directive + +
+ +
90ee8ded Merge pull request #1137 from ddevault/master + +Replace ~ with א in package names + +
+ +
e4c699dc Merge pull request #1147 from ddevault/docs + +Add links to godoc to the README and docsite + +
+ +
73746621 Merge pull request #1131 from muraoka/fix-typo + +Fix typo in authentication docs + +
+ +
ace558b4 Merge pull request #1124 from OpenSourceProjects/update-apq-documentation + +Update APQ example to reflect newer API + +
+ +
3c126f9e Merge pull request #1119 from skaji/patch-1 + +type Person -> type Person struct + +
+ +- 1610039e updated generated code + +- 905e1aad fix redundant type warning + +- 39ded924 fix ctx + +- e7798ff2 insert operation context + +- 6f78c6ac Add links to godoc to the README and docsite + +- 9b823a34 Replace ~ with א in package names (closes #1136) + +- 35a90482 Add LoadDefaultConfig to load the schema by default + +- 07a5494b Fix typo in docs + +
04b120c9 Update APQ example to reflect newer API + +The example in APQ relates to the old handlers. This brings it up to +show how extensions can be used - and uses the new API for registering +plugins that come in the graph. + +The cache example now implements the graphql.Cache interface + +
+ +- 55e0f0db Check in a place where `Entity` might be nil now. + +
1ecd0749 Handle the case that all entities are "empty extend". + +In that case, there are no resolvers to write, so we shouldn't emit +any. + +
+ +- 0e2666fb Run `go fmt` + +
36b5ed83 Actually, we need to check all-external, not all-key. + +We might well be defining our own type that has only key-fields, but +if they're not external then we're the primary provider of the type + +Test plan: +go test ./plugin/federation/ + +
+ +
7e3f5844 Do not require a resolver for "empty" extended types. + +Summary: +If our schema has a field with a type defined in another service, then +we need to define an "empty extend" of that type in this service, so +this service knows what the type is like. But the graphql-server will +never ask us to actually resolve this "empty extend", so we don't +require a resolver function for it. Example: +``` + type MyType { + myvar: TypeDefinedInOtherService + } + + // Federation needs this type, but it doesn't need a resolver for + // it! graphql-server will never ask *us* to resolve a + // TypeDefinedInOtherService; it will ask the other service. + extend TypeDefinedInOtherService @key(fields: "id") { + id: ID @extends + } +``` + +Test Plan: +I manually tested this on a service (`assignments`) that we have that +fell afoul of this problem. But I had a hard time adding tests inside +gqlgen because the error happens at validation-time, and the +federation tests are not set up to go that far down the processing +path. + +Reviewers: benkraft, lizfaubell, dhruv + +Subscribers: #graphql + +Differential Revision: https://phabricator.khanacademy.org/D61883 + +
+ +- 9c80bb5b type Person -> type Person struct + +- ea210929 add test for object directive + +- 5c3812cb merge object directives to field directives + +- 8ea5ba2b Fix additional missed tests + +- 65be2a6e Run generate + +- fd615cf6 Fix linting + +- 61fa9903 Add documentation for scalad error handling + +- 1aa20f25 Add test to highlight usecase + +- d98ff1b0 Modify templates to include deeper context nesting + +
a1a02615 Merge pull request #1104 from oshalygin/docs/update-query-complexity-initialization + +Update Query Complexity Documentation + +
+ +
c68df3c6 Merge pull request #1112 from s-ichikawa/delete-unused-code + +delete unused code + +
+ +
dfb6558a run CI on PRs + +PRs from outside the org arent running CI, hopefully this fixes it. + +
+ +- 5149231c delete unused code + +
6f81ff92 Update Query Complexity Documentation + +- This pass at the documentation updates the + appropriate section regarding query complexity, + specifically in the way that the http.Handler + is created. +- The deprecated handler.GraphQL calls were replaced + with NewDefaultServer. +- Instead of passing along the fixed query complexity + as a second argument to the now deprecated handler.GraphQL + func, extension.FixedComplexityLimit is used instead. + +
+ +- f0cd7a70 update doc site to point to latest version + +- 224ff345 v0.11.3 postrelease bump + + + + + + +## [v0.11.3](https://github.com/99designs/gqlgen/compare/v0.11.2...v0.11.3) - 2020-03-13 +- 4d735356 release v0.11.3 + +- 4b949f2e remove copyright notice at bottom of doc pages + +
c5039196 Merge pull request #1094 from 99designs/update-upload-docs + +Update file upload docs with Apollo client usage + +
+ +- 5e3cef24 revert #1079 + +
793b0672 Merge pull request #1100 from sonatard/fast + +Gnerate to fast by exec codegen.GenerateCode before plugin GenerateCode + +
+ +
6ac2d1cd Merge pull request #1097 from 86/86/update-federation-doc + +Add Enable federation section in federation doc + +
+ +- 97896eeb exec codegen.GenerateCode before plugin GenerateCode to fast + +- 44f8ba9f Update licence + +- 94701fb7 add Enable federation section in federation doc + +- 64190309 Update upload docs with Apollo usage + +- a5381191 v0.11.2 postrelease bump + + + + + + +## [v0.11.2](https://github.com/99designs/gqlgen/compare/v0.11.1...v0.11.2) - 2020-03-05 +- 2ccc0aa6 release v0.11.2 + +
78f3da22 Merge pull request #1050 from technoweenie/executor + +Executor + +
+ +- b82ee517 Fix CI badge + +
42eff5a9 Merge pull request #1057 from RichardLindhout/master + +Upgrade to github.com/urfave/cli/v2 + +
+ +
bb5cb8a3 Merge pull request #1086 from 99designs/github-actions + +Use GitHub Actions + +
+ +- cd2b53f2 remove os.Exits + +
587bc81c Merge pull request #1074 from yudppp/feature/add_contenttype_for_upload + +Add ContentType to graphql.Upload + +
+ +- a84d6577 graphql/handler: revive the existing around func types + +- f9bb017b graphql/executor_test: ensure operation trace is started before every query + +- 57dd8d9c graphql/gqlgen: remove unnecessary convenience method + +- fb86f7b9 graphql/executor: remove the naked return + +- 9ae6bc0b graphql/executor: reinit all extension values on every Use() call + +- f3909a8a graphql/executor: make ext funcs private + +- df9e7ce3 Run CI on push only + +- ed76bc92 Update badge + +- 5a1a5446 Coveralls fixes + +- 41acc753 Fix windows line endings + +- 390cea4f Replace Appveyor with Github Actions + +- 85be072f Replace CircleCI with Github Actions + +- 8d540db3 fix: Add Upload.ContentType test + +- f21832af fix: Fixed Upload type document + +
b165568c Merge pull request #1071 from kandros/fix-server-path + +fix server path + +
+ +
9d7648aa Merge pull request #1072 from wtask/patch-1 + +Fix a typo in sql example + +
+ +
24400c9b Merge pull request #1079 from sonatard/remove-unused + +Remove unused code + +
+ +
a7c79891 Merge pull request #1081 from sonatard/fix-plugin-test + +Fix unlink file path in resolvergen test + +
+ +
e7bf7548 Merge pull request #1080 from sonatard/fix-testdata + +Fix test data + +
+ +- 3a61dc00 Fix unlink file path in resolvergen test + +- df5ac929 Fix test data + +- b2843f67 Remove unused code + +- cff73f71 Add ContentType to Upload + +
f0ebc0df Fix a typo in sql example + +I think todo is referenced to user by user_id field, not by todo.id + +
+ +- 22a43d77 fix server path + +
b788cce5 Merge pull request #1054 from 99designs/golint-free-resolvers + +suppress golint messages + +
+ +
c515d403 Merge pull request #1053 from RichardLindhout/patch-3 + +Add practical example of getting all the requested fields + +
+ +
e57cd445 Merge pull request #1061 from halvdan/patch-1 + +Fix mismatching documentation of Todo struct + +
+ +
1388fa94 Fix mismatching documentation of Todo struct + +Mismatch between the code and the getting started documentation. + +
+ +- 294884ad Rollback go.sum and go.mod as per feedback of [@vektah](https://github.com/vektah) + +- d8acf165 Upgrade to github.com/urfave/cli/v2 + +- 81bcbe75 suppress golint messages + +
24813079 Add practical example of getting all the requested fields + +Based on this https://github.com/99designs/gqlgen/issues/954 was tagged as 'need documentation' + +
+ +
a53ce377 Merge pull request #1051 from 99designs/has-operation-context + +Add function to check presense of operation context + +
+ +- 95e453bf Add function to check presense of operation context + +- 36365c41 graphql/executor: move setExtensions() + +- 3acc9421 graphql/executor: ensure Executor implements graphql.GraphExecutor. + +- f89b973b graphql/executor: merge ExtensionList into Executor + +- c16a77c3 graphql/handler: replace internal executor type + +- 8fa26cec graphql/executor: extract an Executor type from graphql/handler + +- d5d780c5 Point latest docs to 0.11.1 + +- abaa0a04 v0.11.1 postrelease bump + + + + + + +## [v0.11.1](https://github.com/99designs/gqlgen/compare/v0.11.0...v0.11.1) - 2020-02-19 +- 11af15a1 release v0.11.1 + +
bc07188c Merge pull request #1038 from 99designs/feat-check-len + +check slice length + +
+ +- 2c3853c8 fix whitespace in comparison + +
07a13861 Merge pull request #1043 from 99designs/ensure-panic-handlers-get-applied + +Ensure panic handlers get applied + +
+ +
156d306d Merge pull request #1046 from appleboy/patch + +docs(gin): missing import playground + +
+ +- 26ee1aa1 docs(gin): missing import playground + +- 3abe5b32 add test + +- 6ecdb88d Merge branch 'master' into feat-check-len + +- 2340f7a7 Ensure panic handlers get applied + +
25d16761 Merge pull request #1039 from VitaliiLakusta/patch-1 + +Fix link to examples directory in Federation docs + +
+ +- 4c47ad16 Fix link to examples directory in Federation docs + +- 2506dce0 check slice len + +- 1a68df34 fix origin/master reference in switcher + +- 199cfedf remove old docs that no longer run with new layout + +- 556c8484 fix paths + +- 282100c8 use current layout to build old doc content + +- 4c38b8b4 v0.11.0 postrelease bump + + + + + + +## [v0.11.0](https://github.com/99designs/gqlgen/compare/v0.10.2...v0.11.0) - 2020-02-17 +- 368597aa release v0.11.0 + +
e65d6228 Merge pull request #1036 from 99designs/update-v011-docs + +Update 0.11 migration docs + +
+ +- 11f97936 Update 0.11 migration docs + +
2b3eed30 Merge pull request #1034 from 99designs/strip-underscores-from-entity-interfaces + +Trim underscores from around go identifiers + +
+ +- b2d9bfcb Update stale.yml + +- 1ac8b5ae Update stale.yml + +- 4b9dfa61 trim underscores from around go identifiers + +
7cac3610 Merge pull request #1027 from sonatard/response-errors + +propagate resolver errors to response error in ResponseMiddleware + +
+ +
14dccc57 Merge pull request #1022 from 99designs/feat-gqlparser-117 + +example about apply https://github.com/vektah/gqlparser/pull/117 + +
+ +- cf6f7683 bump to gqlparser v2 + +
4ece3857 Merge pull request #1028 from abhimanyusinghgaur/master + +Respect includeDeprecated for EnumValues + +
+ +- 9638ce0f Fix format + +- 51b921fa Fix format + +- 07ffcc82 Respect includeDeprecated for EnuValues + +- d58434c9 propagate resolver errors to response error in ResponseMiddleware + +- 59855925 go mod tidy + +- e4530da6 apply https://github.com/vektah/gqlparser/pull/117 + +
30e23757 Merge pull request #1020 from 99designs/handle-interfaces-implementing-interfaces + +Handle interfaces that implement interfaces + +
+ +- b7a58a1c Handle interfaces that implement interfaces + +
ab8d62b6 Merge pull request #1019 from 99designs/remove-source-reprinting + +Remove source reprinting + +
+ +- 2f0fa0ef handle schema loading error better + +- aacc9b1f Remove source reprinting + +
e289aaa0 Merge pull request #1018 from 99designs/federation-docs + +Federation docs and examples + +
+ +- 3045b2cf Federation docs and examples + +
656a07d1 Merge pull request #1016 from 99designs/federation-entity-type + +Create a non generated federation _Entity type + +
+ +- 8850a527 Create a non generated federation _Entity type + +
1d41c2eb Merge pull request #1012 from 99designs/federation-config + +Allow configuring the federation output file location + +
+ +
afa9a150 Merge pull request #1013 from 99designs/feat-error-dispatch + +propagate errors to response context in DispatchError + +
+ +- 652aa2fb propagate errors to response context in DispatchError + +
0fe1af8c Merge pull request #1011 from Khan/compound-keys + +Compound key support in federation + +
+ +- ad3c1c81 Allow configuring the federation output file location + +
b4a00e6c Merge pull request #1010 from Khan/query-exists + +Make sure there's a Query node before trying to add a field to it. + +
+ +
65401637 Adding type with multiple keys to federation test + +Summary: The current federation test schema only has types with single keys (or no keys). Adding a type with multiple keys, including one non-String key, to test compound key federation code gen. + +Test Plan: - go test + +Reviewers: csilvers, miguel + +Differential Revision: https://phabricator.khanacademy.org/D60715 + +
+ +
3f714a46 Extending federation to support compound keys per Apollo spec + +Summary: +Compound keys are not yet supported for federation in gqlgen. This diff adds support by modifying the federation plugin to handle a list of key fields on an entity rather than a single top-level key field. It will now look for "findBy..." in the resolver, rather than the original "FindBy". The federation plugin does not yet support more complicated FieldSets in the key, such as nested selections. + +References: +- Apollo federation spec: https://www.apollographql.com/docs/apollo-server/federation/federation-spec/ +- Selection sets: https://graphql.github.io/graphql-spec/draft/#sec-Selection-Sets + +Will update https://phabricator.khanacademy.org/D59469 with multiple key changes. + +Test Plan: +- Tested Go GQL services using both single- and multiple-key federated types (assignments and content-library in webapp/services) +- Ran gqlgen on non-federated services in webapp to ensure regular generation still works (donations service) +- WIP: creating unit tests; will submit as separate diff + +Reviewers: briangenisio, dhruv, csilvers, O4 go-vernors + +Reviewed By: dhruv, csilvers, O4 go-vernors + +Differential Revision: https://phabricator.khanacademy.org/D59569 + +
+ +
9f2a624b Make sure there's a Query node before trying to add a field to it. + +Federation adds some queries to the schema. There already existed +code to insert a Query node if none existed previously. But that code +was only put on addEntityToSchema(), and not the other place we update +the query, addServiceToSchema(). + +Almost always the old code was good enough, since we call +addEntityToSchema() before addServiceToSchema(). But there's on +addServiceToSchema(), so we need to do the query-existence check there +too. + +
+ +
b941b970 Merge pull request #1007 from 99designs/handle-invalid-autoload-path + +Give an appropriate error message when autoload isnt a valid package + +
+ +- 95b10809 bump appveyor go version for consistent behavour + +- 91a9ff97 fix bad copy from template + +- d5d6f830 Give an appropriate error message when autoload isnt a valid package + +
f7667e12 Merge pull request #1009 from 99designs/interface-regression + +Interface regression + +
+ +- ffc419f3 Fix interfaces used as normal object types + +- 44cfb926 Test example for interface regression + +
0ddb3ef3 Merge pull request #1006 from ravisastryk/entity-directives-lookup + +skip searching directives when entity is found + +
+ +- 395e1d73 skip searching directives when entity is found + +- e1f2282e bump to go 1.13 in ci + +
34c92eba Merge pull request #1003 from 99designs/fix-chat-example + +fix chat example + +
+ +- 6bf88417 fix chat example + +
8ed2ec59 Merge pull request #988 from 99designs/package-cache + +Cache all packages.Load calls in a central object + +
+ +- 9ccd7ed7 Cache all packages.Load calls in a central object + +
565619a8 Merge pull request #993 from 99designs/resolver-generator-v2 + +Resolver regenerator + +
+ +- cf4a3eb4 keep imports when scattering resolvers between files + +- da7c1e45 Update getting started docs + +- c233876e fix windows test paths + +- 93713a29 Add tests for code persistence + +- 3e507e0d separate resolver stubs by 1 empty line + +- 8a208af5 add tests covering ResolverConfig + +- f8e61961 set init to use new resolvers by default + +- dbaf355d copy through any unknown data + +- e7255580 copy old imports through before gofmt prunes + +- 6ec36504 Copy existing resolver bodies when regenerating new resolvers + +- 9e3b399d add resolver layout = follow-schema + +- 8a18895e Update to latest golangci-lint + +- f7a67722 Merge pull request #985 from Khan/no-key-needed + +
fa884991 Correctly generate a federated schema when no entity has a `[@key](https://github.com/key)`. + +Normally, when a service is taking part in graphql federation, it will +services can link to (that is, have an edge pointing to) the type that +this service provides. The previous federation code assumed that was +the case. + +types. It might seem that would mean the service is unreachable, +since there is no possibility of edges into the service, but there are +and top level Mutation edges. That is, if a service only provides a +top-level query or top-level mutation, it might not need to define a + +This commit updates the federation code to support that use case. + +
+ +
36aae4aa Merge pull request #994 from 99designs/feat-cache-ctx + +Add context.Context to graphql.Cache interface's methods + +
+ +
61e060bd Merge pull request #995 from alexsn/directiveroot_empty_lines + +Remove empty lines on DirectiveRoot generation + +
+ +- 30c295c4 Remove empty lines on DirectiveRoot generation + +- 85cfa8a3 Add context.Context to graphql.Cache interface's methods + +
a6c7aafb Merge pull request #931 from fridolin-koch/master + +Fix for Panic if only interfaces shall be generated + +
+ +
ec4f6b15 Merge pull request #989 from 99designs/fix-intermittent-test-ka-failure + +Fix intermittent websocket ka test failure + +
+ +- 76035df5 Fix intermittent websocket ka test failure + +
aa407b1f Merge pull request #979 from 99designs/capture-read-times + +Capture read times + +
+ +- 4dd10086 fix test race by only stubbing now where we need to + +- 8dbce3cf Capture the time spent reading requests from the client + +
c6b3e2a1 Merge pull request #983 from vikstrous/name-for-package-global + +single packages.Load for NameForPackage + +
+ +
ae79e75b Merge pull request #978 from 99designs/pluggable-error-code + +Allow customizing http and websocket status codes for errors + +
+ +- 7f6f1667 bump x/tools for consistent import formatting + +- 842fcc11 review feedback + +- f0bea5ff Allow customizing http and websocket status codes for errors + +- bd50bbcb single packages.Load for NameForPackage + +
28c032d1 Merge pull request #982 from DavidJFelix/patch-1 + +fix: explicitly exclude trailing comma from link + +
+ +
ac67050a fix: explicitly exclude trailing comma from link + +- this looks dumb, but when the page is rendered, the link resolves with the comma, despite the comma being excluded in github rendering. + +
+ +- 4e95b363 fix some version switcher paths + +- 08369dfe add missing trailing slash on paths + +- ea347ca7 fetch all tags + +- 8c1a8f57 fix branch switching + +- 324efc5c add origin if missing + +- cfa2907a Generate docs for all tags + +
8218c734 Merge pull request #851 from marwan-at-work/federation + +Apollo Federation MVP + +
+ +- 48dc29c1 go 1.12 generate, 1.14 failed + +- b2e81787 update gqlparse to v1.2.1 + +- d2a13d33 update go.mod + +
0eef2fe2 Merge pull request #970 from spiffyjr/master + +Fix extra trimspace on nillable Unmarshals + +
+ +
56b8eef2 Merge pull request #974 from oshalygin/docs/gqlgen-pg-example-repo + +Add Link to Sample Project with GQLGen and Postgres + +
+ +
f49936eb Add Link to Sample Project with GQLGen and Postgres + +This is a very straightforward project with numerous details in the README and the official +documentation, but questions continue to pop up around how to use this project, organize the files +and ultimately make data calls to some persistent layer. + +The `https://github.com/oshalygin/gqlgen-pg-todo-example` was built in order to show newcomers the +following: +- How to organize their graphql schema, resolvers, dataloaders and models +- How to create a new dataloader +- How to resolve with a dataloader and how to avoid some of the pitfalls(inconsistent db query to keys array order) +- How to map models from a gql schema to structs + +While the examples in this project are helpful, they could benefit from more elaborate explanations in the +code as well as the README to help newcomers get started. This PR is not intended to portray any of the examples +negatively and should not be interpreted as such. There are many findings/lessons learned from the work that folks +put together in those examples. + +README which covers a ton of the details on how to use this project: +- [README](https://github.com/oshalygin/gqlgen-pg-todo-example) + +
+ +- db499561 force rebuild + +- 0985a78e remove debug comments + +- 7f648425 add preliminary test_data + +- c9d6d94b add preliminary tests + +- 2345936e fix integration + +- aae7486d go generate + +- 555a9546 go generate + remove directives nil check + +- 368d546d Apollo Federation MVP + +- 21e0e676 Fix extra trimspace on nillable Unmarshals + +- f869f5a8 remove deprected handler call + +- f0b83cb1 fix merge conflict + +- cdf96721 update generated code + +- 21356ce3 markdown cleanup + +
412a72fe Merge pull request #885 from 99designs/handler-refactor + +Refactor handler package + +
+ +- bac79c54 force clean git checkout + +- dca9e4a5 Add migration docs + +
5106480b Merge pull request #947 from 99designs/handler-oc-handling + +always return OperationContext for postpone process + +
+ +- 922db1e3 always return OperationContext for postpone process + +- 8794f03e v0.10.2 postrelease bump + +- 14dbf1aa use new handler package in new test + +- a339a042 panic if operation context is missing when requested + +- a13a0f5f add docs on extension name conventions + +- 458fa0de Add more interface assertions + +- d0836b72 Expose APQ stats + +- cf14cf10 fix: Fix no code generation for only interfaces + +- dc76d029 Merge remote-tracking branch 'origin/master' into handler-refactor + +- 572fb419 remove all references to deprecated handler package + +- dc622346 Tune allocs for benchmarks + +- a6f94626 Merge remote-tracking branch 'origin/master' into handler-refactor + +- c3f93810 fix benchmark + +- 631b48a5 remove automatic field stat collection to reduce time calls + +- a77d9fc2 Add generated stanzas back in + +- 0ee185b8 fix duplicate header sends + +- 7cbd75db fix APQ signature + +- 67fa2104 allow extensions to declare their own stats + +- e9502ae0 Make extensions validatable + +- fc727c9c Add a signpost method to handler extension interface + +- 0a39ae20 add fixed complexity limit + +- f2ef5ec3 more deprecations and more compat + +- 2898a622 rename ResolverContext to FieldContext + +- 092ed95f collect field timing in generated code + +- 848c627c remove DirectiveMiddleware + +- 40f08868 add NewDefaultServer + +- 1b57bc3e Rename RequestContext to OperationContext + +- 3476ac44 fix linting issues + +- 479abbef update generated code + +- bc981569 Combine root handlers in ExecutableSchema into a single Exec method + +- 473a0d25 Implement bc shim for old handler package + +- 631142cf move writer all the way back to the transport + +- c7bb03a8 merge executable schema entrypoints + +- e7e913d9 Remove remains of old handler package + +- 8c5340c1 Add complexity limit plugin + +- 0965420a Add query document caching + +- aede7d1c Add multipart from transport + +- 64cfc9ad extract shared handler test server stubs + +- a70e93bc consistently name transports + +- 9d1d77e6 split context.go into 3 files + +- 72c47c98 rename result handler to response handler + +- 4a69bcd0 Bring operation middleware inline with other handler interfaces + +- ab5665ad Add result context + +- c3dbcf83 Add apollo tracing + +- f00e5fa0 use plugins instead of middleware so multiple hooks can be configured + +- a7c5e660 build middleware graph once at startup + +- 2e0c9cab mark validation and parse errors separately to execution errors + +- cb99b42e Add websocket transport + +- eed1515c Split middlware out of handler package + +- b5089cac Split transports into subpackage + +- d0f68303 port json post + +- afe241b5 port over tracing + +- 311887d6 convert APQ to middleware + +- da986181 port over the setter request context middleware + +- 249b602d Start drafting new handler interfaces + + + + + + +## [v0.10.2](https://github.com/99designs/gqlgen/compare/v0.10.1...v0.10.2) - 2019-11-28 +- f276a4e6 release v0.10.2 + +
9e989d94 Merge pull request #929 from nmaquet/check-nil-interface-ptrs + +Don't crash when interface resolver returns a typed nil + +
+ +
6f20101c Merge pull request #940 from vikstrous/optional-modelgen + +make model generation optional + +
+ +
9b9dd562 Merge pull request #942 from vikstrous/disable-validation + +add skip_validation flag + +
+ +
f9f2063a Merge pull request #941 from vikstrous/qualify-package-path-faster + +shortcut QualifyPackagePath in go module mode + +
+ +- 4db0e6ec keep function private + +- c06f05b3 add doc + +- bd353b3e add skip_validation flag + +- b829628d shortcut QualifyPackagePath in go module mode + +- 3a05d2dd add mention in the docs + +- c2c2d7de make model generation optional + +
d3f63844 Merge pull request #939 from mjarkk/patch-1 + +(docs) graph-gophers now supports Struct Field resolving + +
+ +- ba3d0189 graph-gophers now supports Struct Field resolvers + +
e747d923 Merge pull request #938 from lulucas/master + +modelgen hook docs fixed + +
+ +
63be1d5e Merge pull request [#1](https://github.com/99designs/gqlgen/issues/1) from lulucas/modelgen-hook-patch-1 + +modelgen hook docs use plugin poitner + +
+ +
33fc16b1 modelgen hook docs use plugin poitner + +and add modelgen package to ModelBuild type + +
+ +- fcfe595e Add a comment + +
59946087 Add unit test for the interface resolver / typed nil interaction + +This added test shows that the `_Dog_species` automatically generated +resolver will crash unless the extra nil check is added in +`interface.gotpl`. + +
+ +- 201768f0 Regenerate examples + +
85ca9efe Return graphql.Null in interface resolver when passed a typed nil + +Go's dreaded _typed nil_ strikes again. Nil pointers of struct types +aren't equal to nil interface pointers. + +See https://golang.org/doc/faq#nil_error + +
+ +
15b30588 Merge pull request #894 from 99designs/enum-var-value-coercion + +Improve enum value (with vars) validation timing + +
+ +- 568433a2 fix ci failed + +- 0ccfc7e0 Merge branch 'master' into enum-var-value-coercion + +
9cfd817e Merge pull request #897 from mskrip/modelgen-hook + +Add possibility to hook into modelgen plugin + +
+ +- c1e64148 Merge pull request #900 from zannen/master (closes #896) + +- 8a8f0a0f Add autogenerated files (#896) + +- 531729df Move test schema file from example dir into codegen/testserver (#896) + +- 5144775f Add example to check for regression of #896 + +- 3b5df4ce Add check for obviously different TypeReferences (#896) + +- fb96756a Update generated content (#896) + +
fd201a8c Update UniquenessKey for when Element is/isn't nullable (#896) + +With a schema: +type Query { + things1: [Thing] # Note the lack of "!" +} + +type Subscription { + things2: [Thing!] # Note the "!" +} + +the UniquenessKey for the two lists is the same, which causes non-deterministic output. + +
+ +- 2a269dd3 Add modelgen hook recipe + +- 6ceb76b6 Test tag generation only by looking up extected tag strings + +
1f272d1b Add possibility to hook into modelgen plugin (closes #876) + +This change introduces option to implement custom hook for model +generation plugin without the need to completly copy the whole `modelgen` plugin. + +that can be: + +```golang +func mutateHook(b *ModelBuild) *ModelBuild { + for _, model := range b.Models { + for _, field := range model.Fields { + field.Tag += ` orm_binding:"` + model.Name + `.` + field.Name + `"` + } + } + + return b +} + +... + +func main() { + p := modelgen.Plugin { + MutateHook: mutateHook, + } + + ... +} + +``` + +
+ +
99a55da2 Merge pull request #927 from matiasanaya/feature/bind-to-embedded-interface + +Bind to embedded interface + +
+ +- 70e860cc Bind to embedded interface method + +- a745dc78 Fixes #843: Bind to embedded struct method or field + +
f80cab06 Merge pull request #923 from 99designs/gqlparser-1.2.0 + +Update to gqlparser-1.2.0 + +
+ +- 7508f4e5 Update to gqlparser-1.2.0 + +
7653a681 Merge pull request #916 from karthikraobr/patch-1 + +3->4 scalars + +
+ +
8faa0e3a Merge pull request #917 from colelawrence/patch-1 + +docs: Fix typo in title of "Resolvers" + +
+ +- f7d888f9 Merge branch 'master' into patch-1 + +- d722ac66 Update scalars.md + +
1172128c Merge pull request #904 from cfilby/fix-config-docs + +Minor Documentation Tweaks + +
+ +- 935f11ed Fix typo in title + +- 026d029c 3->4 scalars + +- 5eb6bef6 Fix weird indending + +- 756dcf6b Merge pull request #907 from lian-yue/patch-1 (closes #860) + +- 2a943eed Update directive.go (closes #860) + +
adbceeea Merge pull request #902 from cfilby/fix-int64-marshalling + +Add support for int64 IDs + +
+ +- 13c3d922 Update id function + +- 37191779 Add more tests + +- 0968e0cb Fix VSCode Weirdness, validate formatting + +- a20c96d5 More edits + +- e9e88b41 Stop double indending + +- 9f4df68e More minor doc fixes + +- 7abf0ac3 Fix documentation bug + +- e9730ab9 gofmt + +- c3930f57 Remove redundant paren, add test + +- 395fc85e Add support for int64 ids + +
dbc88428 Merge pull request #889 from thnt/fix-init-with-schema-arg + +fix init not use custom schema filename + +
+ +- fc4e513f add test for https://github.com/vektah/gqlparser/pull/109 + +- dd98bb13 fix init not use custom schema + +
4c35356c Merge pull request #883 from 99designs/handle-invalid-types + +Gracefully handle invalid types from invalid go packages + +
+ +- 25b70271 Gracefully handle invalid types from invalid go packages + +
046054db Merge pull request #882 from 99designs/testserver-autobind + +Use autobinding in testserver + +
+ +- 12c963a4 Use autobinding in testserver + +
305116a0 Merge pull request #879 from coderste/patch-1 + +Fixed broken GitHub link within the APQ page + +
+ +
b4867b3f Fixed broken GitHub link within the APQ page + +Small documentation change to fix a broken GitHub link. + +
+ +- 9f6b0ee4 v0.10.1 postrelease bump + + + + + + +## [v0.10.1](https://github.com/99designs/gqlgen/compare/v0.10.0...v0.10.1) - 2019-09-25 +- efb6efe0 release v0.10.1 + +
955f3499 Merge pull request #877 from 99designs/fix-websocket-client + +Fix websocket connections on test client + +
+ +- ef24a1cc Fix websocket connections on test client + +- c997ec0c v0.10.0 postrelease bump + + + + + + +## [v0.10.0](https://github.com/99designs/gqlgen/compare/v0.9.3...v0.10.0) - 2019-09-24 +- 75a83752 release v0.10.0 + +
0bc3cc86 Merge pull request #875 from 99designs/fix-clientwide-opts + +Fix client global options + +
+ +
b43edf5d Merge pull request #874 from 99designs/configurable-slice-element-pointers + +Add config option to omit pointers to slice elements + +
+ +- 921aa9cf Fix client global options + +- d0098e60 Add config option to omit pointers to slice elements + +
01893280 Merge pull request #819 from 99designs/fix-directive-interface-nils + +Fix directives returning nils from optional interfaces + +
+ +- 34d10975 Fix directives returning nils from optional interfaces + +
eea38e55 Merge pull request #862 from qhenkart/fixes-shareable-link-setting + +fixes shareable link button in playground + +
+ +
b5e78342 Merge pull request #870 from 99designs/ws-init-ctx + +Allow changing context in websocket init func + +
+ +
034aa627 Merge pull request #871 from 99designs/subscription-middleware + +Call middleware and directives for subscriptions + +
+ +
7b41ca3c Merge pull request #872 from 99designs/autobind-prefix + +Allow prefixes when using autobind + +
+ +
de8e559f Merge pull request #854 from wabain/nested-map-interface + +Fix for nested fields backed by map or interface + +
+ +
cc64f331 Merge pull request #828 from 99designs/feat-rc + +introduce RequestContext#Validate and use it instead of NewRequestContext function + +
+ +- ed2a8536 Allow prefixes when using autobind + +- 819cc71b Call middleware and directives for subscriptions + +- 5a7c5903 Allow changing context in websocket init func + +
17f32d28 Merge pull request #861 from 99designs/refactor-test-client + +Refactor test client + +
+ +
ed14cf04 Update playground.go + +fix formatting + +
+ +
ee8d7a17 Update playground.go + +fix formatting + +
+ +- 27389951 fixes shareable link button in playground + +- 4162d11e Refactor test client + +- 8ed6ffc7 Fix for nested fields backed by map or interface + +- 55b21442 Update stale.yml + +- feebee7d stalebot + +
7e643fdc Merge pull request #838 from 99designs/fix-directive-nil + +fix directives return nil handling + +
+ +- f33e09e8 Merge branch 'master' into fix-directive-nil + +
8590edef Merge pull request #839 from 99designs/fix-nil-directive + +refactor unimplemented directive handling + +
+ +- 1f7ed0d5 refactor unimplemented directive handling + +- 94ad3f2e fix directives return nil handling + +- 5c644a6f v0.9.3 postrelease bump + +- 82758be8 fix error + +- edde2d03 add OperationName field to RequestContext + +- 830e466e introduce RequestContext#Validate and use it instead of NewRequestContext function + + + + + + +## [v0.9.3](https://github.com/99designs/gqlgen/compare/v0.9.2...v0.9.3) - 2019-08-16 +- a7bc468c release v0.9.3 + +
fc02cfe8 Merge pull request #829 from 99designs/fix-2directives + +fix go syntax issue when field has 2 directives + +
+ +
924f620c Merge pull request #831 from yudppp/patch-1 + +Fixed scalar reference documentation + +
+ +- ca4cc732 Fixed scalar documents + +- cc9fe145 fix go syntax issue when field has 2 directives + +- 6b70be03 v0.9.2 postrelease bump + + + + + + +## [v0.9.2](https://github.com/99designs/gqlgen/compare/v0.9.1...v0.9.2) - 2019-08-08 +- 4eeacc6e release v0.9.2 + +
5628169d Merge pull request #822 from 99designs/windows-import-path-loop + +fix for windows infinite loop + +
+ +- a861aa52 lint fix + +- 6348a563 fix for windows infinite loop + +
12893fa4 Merge pull request #821 from 99designs/fix-init + +Fix config loading during gqlgen init + +
+ +- 5fafe79c Fix config loading during gqlgen init + +
2599f560 Merge pull request #820 from 99designs/keepalive-on-init + +send keepalive on init + +
+ +- 139e4e8d More directive docs + +- f93df340 send keepalive on init + +
8f0d9b48 Merge pull request #816 from nii236/patch-1 + +Update cors.md to allow CORS for websockets + +
+ +- 297e09c4 change origin check + +
410d8322 Merge pull request #805 from andrey1s/golangci + +enable-all linters on golangci-lint + +
+ +- 504a96bc set enabled linters + +- 91966ef4 add example to lint + +- bcddd7aa fix typo in readme + +- cce06f1d update lint in circleci + +
da1c208e Merge pull request #795 from oshalygin/feature/issue-794-resolve-dead-readme-link + +Update GraphQL Reference Link + +
+ +
8343c32c Merge pull request #784 from y15e/add-missing-header + +Add a missing "Upload" header + +
+ +
8302463f Merge pull request #797 from muesli/format-fixes + +Format import order using goimports + +
+ +
f2825e09 Merge pull request #801 from Schparky/patch-1 + +Documentation: getting-started edits + +
+ +
3db5627f Merge pull request #807 from flrossetto/patch-1 + +Fix doc + +
+ +- ab228f1b Update cors.md to allow CORS for websockets + +
c4ac9347 Fix doc + +map[string]{interface} -> map[string]interface{} + +
+ +- fbbed5b8 use alias when invalid pkg name + +- 2591ea36 fix lint prealloc + +- 3b0e44fe fix lint misspell + +- 6ff62b61 fix lint gocritic + +- cb7f482b fix lint unparam + +- 620552be fix lint goimports + +- 477e804e update config golangci + +- 5b203bcc clarify where the go:generate line should be added + +- 2a3df24e Replace the -v flag as described below. + +- f3eeb639 Clarify that the schema file will be generated + +- 3ac17960 Missing '*' in Todos resolver example + +- bd598c2c Format import order using goimports + +
419f966d Update GraphQL Reference Link (closes #794) + +- The link in the readme has been updated to reference a post by + Iván Corrales Solera, "Dive into GraphQL". The previous link + does not resolve, likely because the personal site is no longer + hosted. + +
+ +
373359de Merge pull request #781 from 99designs/fix-default-directives-init + +Set default directives after parsing config + +
+ +- ca8b21e3 Add a missing header + +- 8cab5fba Set default directives after parsing config + +
d2c5bf2a Merge pull request #780 from zdebra/master + +fixed generating a description to golang comments for enum type + +
+ +
bf2cc90e Merge pull request #768 from 99designs/fix-ptr-from-directive + +Fix pointer returns from directive + +
+ +- 446c3df3 fixed generating a description to golang comments for enum type + +- 414a4d34 Merge pull request #771 from sunfmin/master + +- 4d1484b0 Fix doc for how to use [@goField](https://github.com/goField) directives forceResolver option + +- 6f3d7310 Fix pointer returns from directive + +- 21b65112 v0.9.1 postrelease bump + + + + + + +## [v0.9.1](https://github.com/99designs/gqlgen/compare/v0.9.0...v0.9.1) - 2019-06-27 +- b128a291 release v0.9.1 + +
1bbc0cd6 Update release process to keep tags on master + +this was affecting the version shown in go modules when using commits + +
+ +
5ffc2975 Merge pull request #764 from 99designs/fix-field-directives-on-roots + +fix field schema directives applied to roots + +
+ +- ef3830b5 fix field schema directives applied to roots + +
17ee40ba Merge pull request #761 from 99designs/autobinding + +Autobind models + +
+ +- b716bfac Autobind models + +
fc3755f1 Merge pull request #732 from 99designs/schemaconfig-plugin + +Add a plugin for configuring gqlgen via directives + +
+ +- c14f8650 Add docs + +- 64aca616 Merge remote-tracking branch 'origin/master' into schemaconfig-plugin + +
5e7e94c8 Merge pull request #756 from andrey1s/field + +generate field defenition and execute field directive + +
+ +
ad2ca304 Merge pull request #759 from 99designs/circle-workflows + +CircleCI workflows + +
+ +- 0fc822ca CircleCI workflows + +
2dc8423b Merge pull request #758 from franxois/patch-1 + +Update dataloaders.md + +
+ +
d0db28ab Update dataloaders.md + +Make SQL request use requested IDs + +
+ +- a58ecfe9 add example and test field directive + +- 526beecb update generate field + +- 6e9d7dab generate types directive by location + +- dfec7b68 define fieldDefinition template + +- be890ab9 use UnmarshalFunc in args directives implement + +- dd162f04 define implDirectives template + +
56f3f92b Merge pull request #755 from 99designs/fix-globbing-windows + +fix globbing on windows + +
+ +- a4480fb0 fix globbing on windows + +
ba176e2e Merge pull request #754 from 99designs/coveralls + +Add coveralls + +
+ +- f28ed264 Add coveralls + +
f4a69ab5 Merge pull request #744 from andrey1s/directive + +add Execute QUERY/MUTATION/SUBSCRIPTION Directives + +
+ +- dbd2cc6e simplify resolver test + +
7fed71b6 Merge pull request #728 from fgallina/make-generated-resolver-dependent-types-follow-configured-type + +resolvergen: use the resolver type as base name for dependent types + +
+ +
cb284c56 Merge pull request #734 from DBL-Lee/master + +Automatic Persisted Queries + +
+ +
726a94f4 Merge pull request #750 from 99designs/ws-connection-param-check + +[websocket] Add a config to reject initial connection + +
+ +- 69d7e282 move directive to directives.gotpl + +
090f0bd9 Merge pull request #722 from marwan-at-work/deps + +resolve all pkg dependencies + +
+ +- c397be0c Update websocketInitFunc to return error instead of boolean + +- be18ae1f Add a test + +- a6508b6d Update typing, function name and small code refactor + +- e6d791a9 Add websocketOnConnectFunc as a config that can be used to validate websocket init requests + +
c5acbead resolvergen: use the resolver type as base name for dependent types + +The template was outputing invalid code since the resolver type was +not used in places like the embedding at {query,mutation}Resolver. + +This change also ensures that objects like {query,mutation}Resolver +also use the user provided type name as suffix. + +Here's the resulting diff on the code generation with `type: +GeneratedResolver` in the resolver config: + +``` +diff -u resolver.go resolvernew.go +--- resolver.go 2019-05-26 20:04:15.361969755 -0300 ++++ resolvernew.go 2019-05-26 20:04:54.170737786 -0300 +@@ -7,20 +7,20 @@ + type GeneratedResolver struct{} + + func (r *GeneratedResolver) Mutation() MutationResolver { +- return &mutationResolver{r} ++ return &mutationGeneratedResolver{r} + } + func (r *GeneratedResolver) Query() QueryResolver { +- return &queryResolver{r} ++ return &queryGeneratedResolver{r} + } + +-type mutationResolver struct{ *Resolver } ++type mutationGeneratedResolver struct{ *GeneratedResolver } + +-func (r *mutationResolver) CreateTodo(ctx context.Context, input NewTodo) (*Todo, error) { ++func (r *mutationGeneratedResolver) CreateTodo(ctx context.Context, input NewTodo) (*Todo, error) { + panic("not implemented") + } + +-type queryResolver struct{ *Resolver } ++type queryGeneratedResolver struct{ *GeneratedResolver } + +-func (r *queryResolver) Todos(ctx context.Context) ([]*Todo, error) { ++func (r *queryGeneratedResolver) Todos(ctx context.Context) ([]*Todo, error) { + panic("not implemented") + } +``` + +
+ +- cfdbc39a update QueryDirectives + +- f32571ee add SUBSCRIPTION Directive + +- 32462d0f update example todo add directive with location QUERY and MUTATION + +- 3eec887a add Execute QUERY/MUTATION/SUBSCRIPTION Directives + +- 8fcc1868 format + +
e0e1e318 Merge pull request [#1](https://github.com/99designs/gqlgen/issues/1) from radev/master + +Support for external APQ cache + +
+ +- 9873d998 Add APQ documentation with example + +- 48292c10 Support pluggable APQ cache implementations. + +- 694f90aa Merge pull request #717 from cbelsole/schema_file_globbing (closes #631) + +- 9be5aad0 Don't inject builtins during schema config + +- 8dc17b47 support GET for apq + +- d36932c5 support automatic persisted query + +- de75743c Add plugin for providing config via schema directives + +- 17a82c37 Provide config to skip generating runtime for a directive + +
ba7092c5 Merge pull request #724 from saint1991/patch-1 + +added a missing close bracket + +
+ +- 9c1f8f2a added a missing close bracket + +- 3dd8baf5 resolve all pkg dependencies + +- 1617ff28 Merge pull request #718 from hh/fix-docs (closes #714) + +- 9d332a7d Fixing getting-started documentation + +- 39db1477 updated docs + +- e32c82be cleanup + +- e9389ef8 added schema file globbing fixes #631 + +
4f163cbc Merge pull request #713 from 99designs/faq + +Add faq section + +
+ +- 3a21b369 Add faq section + + + + + + +## [v0.9.0](https://github.com/99designs/gqlgen/compare/v0.8.3...v0.9.0) - 2019-05-15 +- ea4652d2 release v0.9.0 + +
f3c8406d Merge pull request #710 from 99designs/slice-pointers + +Use pointers to structs inside slices + +
+ +- e669d476 fix imports for vendor based projects + +- 315141d9 Use pointers to structs inside slices + +
9a6a10ab Merge pull request #706 from 99designs/mapping-primitive + +Fix mapping object types onto go primitives + +
+ +- a5120054 fix binding to primitive non leaf types + +- b0cd95a1 Test mapping object types onto go string + +
eaa61bb5 Merge pull request #707 from 99designs/gomodules-performance + +make gqlgen generate 10x faster in some projects + +
+ +
ab961ce0 Merge pull request #705 from 99designs/fix-error-race + +Fix a data race when handling concurrent resolver errors + +
+ +- 71cc8554 make gqlgen generate 10x faster in projects with cgo + +- cab4babe Test mapping object types onto go primitives + +- 962470de Fix a data race when handling concurrent resolver errors + +
9ca43ba9 Merge pull request #701 from 99designs/modelgen-pointers + +Use pointers when embedding structs in generated structs + +
+ +- 4f5e9cf0 always use pointers when refering to structs in generated models + +
e2ac8480 Merge pull request #704 from tul/doc-typo + +Fix typo + +
+ +- 80ebe644 Fix typo + +
0bd90809 Merge pull request #700 from 99designs/fix-interface-caseing + +Fix interface casing + +
+ +
5586ee2c Merge pull request #702 from 99designs/drop-automatic-zeroisnull + +Drop automatic conversion of IsZero to null + +
+ +- 75aa99ad Drop automatic conversion of IsZero to null + +- 46c40b74 Fix interface casing (closes #694) + +
e49d44f7 Merge pull request #689 from tgwizard/enforce-request-content-type + +Enforce content type for POST requests + +
+ +- 78f277e9 run go generate + +- d4b3de3a Merge remote-tracking branch 'origin/master' into enforce-request-content-type + +
f8ef6d2e Merge pull request #668 from mbranch/complexity + +Fix: complexity case selection + +
+ +
c4805049 Merge pull request #655 from hantonelli/file-upload + +File upload + +
+ +- 5d1dea0a run go generate + +- 8a0c34a4 Merge branch 'master' into file-upload + +
4e359aa2 Merge pull request #686 from qhenkart/master + +Adds default custom scalar of interface{} + +
+ +- aeccbce0 Update test include an example that uses io.Read interface directly + +- d9dca642 Improve documentation + +- f30f1c31 Fix fmt + +- 54226cdb Add bytesReader to reuse read byte array + +
02e9dd8e Fix complexity case selection + +Use the GraphQL field name rather than the Go field name in the generated +`Complexity` func. + +Before this patch, overloading complexity funcs was ineffective because they +were never executed. + +It also ensures that overlapping fields are now generated; mapping all possible +field names to the associated complexity func. + +
+ +- bf2d07a4 moves naming convention to a non-go standard + +
d1e8acda Merge pull request #687 from stereosteve/fix-includeDeprecated + +Fix: omit deprecated fields when includeDeprecated=false + +
+ +- f7d0b9c8 Enforce content type for POST requests + +- 7d0b8eec Fix: omit deprecated fields when includeDeprecated=false + +- 89c87345 fix grammar in docs + +- 85643f5d fix import + +- ca96a155 update docs + +- 1de25d0c adds interface scalar type + +- 43fc53f9 Improve variable name + +- b961d34e Remove wrapper that is now not required + +- bb023476 Lint code + +- f8484159 Modify graphql.Upload to use io.ReadCloser. Change the way upload files are managed. + +
0306783e Revert "Change graphql.Upload File field to FileData." + +This reverts commit 7ade7c2 + +
+ +
afe33f73 Merge pull request #680 from asp24/collect-fields-performance + +Better CollectFields performance + +
+ +- 7ba1b3b2 graphql.CollectFields now accept *RequestContext as first arg It was done because RequestContext is a part of executionContext and can be passed directly without extraction from ctx. This is increasing performance when model depth is high + +- 5dfa2285 Pre-allocate mem for collectFields() method result slice + +- 88cdbdf1 Rename getOrCreateField to getOrCreateAndAppendField to describe behaviour + +- a74abc47 Early return in shouldIncludeNode if directives empty + +- 7ade7c21 Change graphql.Upload File field to FileData. + +- da52e810 Extend test and don't close form file. + +
1c95d42a Merge pull request #678 from jonatasbaldin/gin-context-recipe + +Fix unset key and comment block at Gin recipe docs + +
+ +- 0b39c445 Fix unset key and comment block + +
5aa6a20b Merge pull request #673 from marwan-at-work/tpl + +codegen/templates: allow templates to be passed in options instead of… + +
+ +- 37fd067e fix typo + +- e69b7399 add docs to the templates package + +
8cae895b Merge pull request #676 from jonatasbaldin/gin-context-recipe + +Add recipe to use gin.Context + +
+ +- 40c7b952 update test name + +- 5418a290 Add recipe to use gin.Context + +- 16f392ee add unit test + +- a0ee7172 codegen/templates: allow templates to be passed in options instead of os files + +- 2cf7f452 Fix comments (add request size limit, remove useless comments, improve decoding and function signature, improve documentation) + +
5ff60925 Merge pull request #665 from ezeql/patch-1 + +update README.md + +
+ +
b42e1ba6 update README.md + +fix link + +
+ +- d3770395 Fix tests. + +- 2c1f8573 Fix lint errors. + +- 73b3a536 Fmt graphql.go + +- 83cde4b6 Fix tests. Improve code format. + +- 425849a6 Improve fileupload example readme. Update scalars.md. Add file-upload.md + +- 849d4b1e Make uploadMaxMemory configurable + +- fc318364 Improve format, inline const. + +- 662dc337 Move Upload to injected if defined in the schema as scalars + +- f244442e Fix merge. Remove regexp check. + +
bf79bc92 Merge branch 'master' into next + +# Conflicts: +# codegen/config/config.go +# handler/graphql.go +# handler/graphql_test.go + +
+ +- bd4aeaa6 Merge remote-tracking branch 'upstream/master' + +- 3a6f2fb7 Improve test code + +- 239bc46f Add comments + +- be8d6d12 Improve test + +- 4d92696b Clean up code and add tests + +- 2c414edc Improve and add tests + +- 68446e17 Revert change to websocket_test + +- 61c1cb9c Improve examples + +- 493d9375 Improve examples + +- 3c5f8bb9 Improve some examples + +- db7a03b1 Improve tests and names + +- c493d1b9 Revert changing to websocket_test + +- 998f7674 Revert changing the stub file + +- a7e95c59 Fix tests. Improve file generation + +- 10beedb3 Remove not required file + +- 5afb6b40 Add file upload to default schema + +- 9c17ce33 Add file upload + +- b454621d Add support to upload files. + + + + + + +## [v0.8.3](https://github.com/99designs/gqlgen/compare/v0.8.2...v0.8.3) - 2019-04-03 +- 010a79b6 release v0.8.3 + +
3623f7fc Merge pull request #650 from andcan/plugin-funcmap + +Allow plugins to provide additional template funcs + +
+ +
a2e59362 Merge pull request #652 from andrey1s/extraBuiltins + +add extra builtins types when no type exists + +
+ +
c93d92ba Merge pull request #654 from sharkyze/fix-introscpetion-doc + +doc: fix mistake on introspection doc page + +
+ +- 93e72b58 doc: fix error on introspection doc page + +
ef2e51ba Merge pull request #637 from 99designs/fix-is-slice + +Fix Mapping Custom Scalar to Slice + +
+ +- e5ff6bc2 add extra builtins types when no type exists + +- 8225f63a Allow plugins to provide additional template funcs + +- 7b533df1 Update ISSUE_TEMPLATE.md + +- 055157f9 Update ISSUE_TEMPLATE.md + +
a148229c Merge pull request #644 from Sauraus/master + +Fix Gin installation instruction + +
+ +
52624e53 Fix Gin installation instruction + +Current `go get gin` instruction results in an error from Go: `package gin: unrecognized import path "gin" (import path does not begin with hostname)` + +
+ +- 515f2254 Add test case for custom scalar to slice + +
2284a3eb Improve IsSlice logic to check GQL def + +Currently TypeReference.IsSlice only looks at the Go type to decide. +This should also take into account the GraphQL type as well, to cover +cases such as a scalar mapping to []byte + +
+ + + + + + +## [v0.8.2](https://github.com/99designs/gqlgen/compare/v0.8.1...v0.8.2) - 2019-03-18 +- ee06517c release v0.8.2 + +
8ac8a1f8 Merge pull request #635 from 99designs/fix-inject-builtin-scalars + +Only Inject Builtin Scalars if Defined in Schema + +
+ +- d10e048e Add docs for built-in scalar implementations + +- d27e6eb6 Add example case for object type overriding builtin scalar + +- d567d5c8 Inject non-spec builtin values only if defined + +
3e39b57a Merge pull request #634 from 99designs/fallback-to-string + +Use graphql.String for types wrapping a basic string + +
+ +- a2cce0d1 Use graphql.String for types wrapping a basic string + +
fc05501b Merge pull request #633 from 99designs/fix-union-pointers + +Fix Having Pointers to Union Types + +
+ +- f02dabb7 Add test case for union pointer + +
8257d423 Check Go type rather than GQL type for ptr + +This is probably a more correct way to check whether we should wrap the +type in a pointer or not, rather than looking at the GrapQL definition. +There may be use-cases where a GraphQL interface/union might be mapped +to a Go stuct. + +
+ +
5df0938f Merge pull request #628 from 99designs/fix-ambient-imports + +Move ambient imports into cmd package + +
+ +
8e1590d7 Move ambient imports into cmd package + +The getting started docs for dep suggest creating a local gqlgen script, +however these ambient import are in the root, so dep misses them. + +This was changed in 0.8 but the ambient imports weren't moved. + +
+ +
58744de9 Merge pull request #622 from 99designs/handle-complexity-root-collisions + +Handle colliding fields in complexity root gracefully + +
+ +- c889b314 Handle colliding fields in complexity root gracefully + +
26c395b0 Merge pull request #620 from codyleyhan/cl/error + +Allow user to supply path to gqlerror + +
+ +- 12cf01aa Allow user to supply path to gqlerror + +
932322b6 Merge pull request #619 from 99designs/nil-slices + +Support returning nulls from slices + +
+ +- a48c55b2 Support returning nulls from slices + +
2b270e4d Merge pull request #618 from codyleyhan/cl/method + +Adds way to determine if a resolver is a function call or value + +
+ +- af6dc16d Add test for IsMethod in resolver + +- 27e97535 Expose IsMethod to resolver context + +- f52726de Update README.md + +
ac2422e3 Merge pull request #614 from wesovilabs/master + +Adding entry for workshop + +
+ +
db4f7255 Merge pull request #613 from icco/patch-2 + +Upgrade graphql-playground to 1.7.20 + +
+ +
163bfc76 Merge pull request #612 from 99designs/maps-changesets + +Maps as changesets + +
+ +- 6aa9dfc6 Adding entry for workshop + +
08f936e1 Upgrade graphql-playground to 1.7.20 + +CSS didn't change but js did. + +
+ +
8fb1fafd Merge pull request #611 from 99designs/gqlparser-1.1.2 + +Bump gqlparser to 1.1.2 + +
+ +- 37983a5f remove some invalid test schema + +- 765ff738 Add some docs on maps + +- 0a92ca46 Support map[string]interface{} in return types + +
ac56112b Merge pull request #610 from tgwizard/dynamic-complexity + +Allow configuring the complexity limit dynamically per request + +
+ +- a89050aa Bump gqlparser to 1.1.2 + +- dd288145 Allow configuring the complexity limit dynamically per request + +
485ddf30 Merge pull request #605 from 99designs/fix-default-scalars + +Fix default scalars + +
+ +
3ca2599a Merge pull request #606 from jonatasbaldin/add-gin-recipe + +Add Gin recipe + +
+ +- 386eede9 Add Gin recipe + +
22be59d1 Merge pull request #604 from cevou/arg-scalar + +Fix directives on args with custom type + +
+ +- d02736dc Added test for fix directives on args with custom type + +- 30d235bc Fix default scalars + +
d7b5dc28 Merge pull request #591 from 99designs/fix-577 + +Fix mixed case name handling in ToGo, ToGoPrivate + +
+ +- bef6c0a9 Fix directives on args with custom type + +- bc386d79 Fix mixed case name handling in ToGo, ToGoPrivate + + + + + + +## [v0.8.1](https://github.com/99designs/gqlgen/compare/v0.8.0...v0.8.1) - 2019-03-07 +- 229185e4 release v0.8.1 + +
d872af63 Merge pull request #582 from demdxx/master + +Load the playground sources from HTTPS by default + +
+ +
8e66832f Merge pull request #589 from 99designs/fix-autocasing-modelgen-bugs + +Fix autocasing modelgen bugs + +
+ +- de3b7cb8 Fix autocasing modelgen bugs + +
8e00703e Merge pull request #588 from 99designs/fix-default-scalar-implementation-regression + +Fix default scalar implementation regression + +
+ +- b27139ed Fix default scalar implementation regression + +
737a59a3 Merge pull request #579 from 99designs/fix-camelcase + +Take care about commonInitialisms in ToGo + +
+ +- 52838cca fix ci + +- 2c3783f1 some refactoring + +- eb453674 address comment + +- dcd208d9 Merge pull request #584 from 99designs/fix-deprecated-directive + +
5ba8c8ea Add builtin flag for build directives + +These have an internal implementation and should be excluded from the +DirectiveRoot. In the future this may be a func that plugins could use +to add custom implementations. + +
+ +
b8526698 Load the playground sources from HTTPS by default + +For some browsers on non-secure domains resources from CDN doesn't loads, so I made all cdn.jsdelivr.net resources of the playground by HTTPS by default + +
+ +- 6ea48ff6 Take care about commonInitialisms in ToCamel + +
1968a7bc Merge pull request #576 from jflam/patch-1 + +Update README.md + +
+ +
44becbbe Update README.md + +Fixed typo in MD link ttps -> https + +
+ + + + + + +## [v0.8.0](https://github.com/99designs/gqlgen/compare/v0.7.2...v0.8.0) - 2019-03-04 +- f24e79d0 release v0.8.0 + +
55df9b8d Merge pull request #574 from 99designs/next + +v0.8.0 + +
+ +
aedcc68a Merge pull request #573 from 99designs/plugin-docs + +Very rough first pass at plugin docs + +
+ +- 8f91cf56 Very rough first pass at plugin docs + +
3d9ad75e Merge pull request #572 from 99designs/handle-nonexistant-directories-when-genreating-packagenames + +Handle non-existant directories when generating default package names + +
+ +- 08923334 Handle non-existant directories when generating default package names + +
2ef4b443 Merge pull request #571 from 99designs/automatically-bind-to-int32-int64 + +Automatically bind to int32 and int64 + +
+ +
2888e96c Merge pull request #570 from 99designs/vendor-packages-workaround + +Workaround for using packages with vendored code + +
+ +- fb87dc39 Automatically bind to int32 and int64 + +
f2d9c3f7 Merge pull request #569 from 99designs/improve-introduction + +Introduction Improvements + +
+ +- 1e7aab63 Workaround for using packages with vendored code + +- 5c692e29 User README as canonical introduction + +- 25bdf3d6 Consolidate Introduction documents + +- d81670d8 Add initial contributing guidelines + +- d9a9a532 playground: secure CDN resources with Subresource Integrity + +
cb38b4be Merge pull request #568 from MichaelMure/secured-playground + +playground: secure CDN resources with Subresource Integrity + +
+ +
0258e1a2 Merge pull request #565 from steebchen/next + +Fix cli config getters + +
+ +- 6ad1d97e Move feature comparison + +- 37cbbd6d playground: secure CDN resources with Subresource Integrity + +- da12fd11 Fix cli config getters + +
51266b8f Merge pull request #554 from 99designs/fix-missing-recover + +Recover from panics in unlikly places + +
+ +- 67795c95 Recover from panics in unlikly places + +
56163b45 Merge pull request #553 from 99designs/getting-started-0.8 + +Update Getting Started for 0.8 and Go Modules + +
+ +- 0bd120b5 Update dep code as well + +- 6c576032 Update getting started with 0.8 generated code + +- ba761dcf Reintroduce main package in root + +- cdc575a2 Update getting started with Go Modules support + +- 378510e5 Move Getting Started above Configuration + +- d261b3fb Fix navigation font weights + +
327a1a34 Merge pull request #551 from 99designs/improved-collect-fields-api + +Improved Collect Fields API and Documentation + +
+ +
6439f197 Merge pull request #552 from 99designs/always-return-struct-pointers + +Always return *Thing from resolvers for structs + +
+ +- 318639bb Always return *Thing from resolvers for structs + +- e61b3e0b Add Field Collection docs + +
ef0223cf Merge pull request #541 from 99designs/fix-underscore-only-fields + +Allow underscore only fields and naming collisions to be aliased explicitly + +
+ +- 58b2c74f drive by config fix + +- f6c52666 Add a test for aliasing different cases (closes #376) + +- 8c2d15ee Fix underscore only fields (closes #473) + +- 0eb8b5c1 Merge remote-tracking branch 'origin/master' into HEAD + +
015d02eb Merge pull request #542 from Elgarni/add-more-validation-checks-on-yml-config-file + +Add more validation checks on .yml config file + +
+ +
647c62a5 Merge pull request #550 from 99designs/fix-unstable-marshaler-func + +Fix unstable external marshaler funcs with same name as type + +
+ +- 3a8bf33f Add CollectAllFields test cases + +- 9ebe7717 Fix unstable external marshaler funcs with same name as type + +
a1195843 Merge pull request #544 from enjoylife/fix-directive + +Fix directives on fields with custom scalars + +
+ +- dc925c46 Added a test for config checking + +- b56cb659 Refactored config check so that it runs after being normalized + +- dc6a7a36 Add CollectAllFields helper method + +
a2e61b3d Added a model and used directive on an input field within the integration schema + +Added to the integration schema such that the build will catch the directive bug in question. + +
+ +- 0b0e4a91 Fix directives on fields with custom scalars + +- 8ac0f6e4 Removed redundant semicolons + +- 3645cd3e Add more validation checks on .yml config file + +
1b8b1ea1 Fix typo in README + +Fix typo in README in selection example directory to point to the selection example, not the todo example. + +
+ +
66120d8f Merge pull request #535 from awiede/master + +Fix typo in README + +
+ +- fcacf200 Merge remote-tracking branch 'origin/master' into HEAD + +
b9819b21 Merge pull request #540 from 99designs/check-is-zero + +Automatically convert IsZero to null + +
+ +
03a655dc Merge pull request #526 from 99designs/union-fragment-bug + +Union Fragment Bug Fix + +
+ +- 99e9f41f Use Implements for type Implementors in codegen + +
ccca823f Separate out conditionals in collect fields + +These conditions are not really related, and I missed the second +conditional when reading through the first time. + +
+ +- efe8b026 Add reproducable test cases + +- 306da15f Automatically convert IsZero to null + +- f81c61d3 Merge pull request #539 from 99designs/test-nullable-interface-pointers (closes #484) + +
f5200c80 Merge pull request #498 from vilterp/playground-content-type + +add `content-type: text/html` header to playground handler + +
+ +- de148d13 Test for #484 + +- 9a48a007 Merge pull request #538 from 99designs/test-input-marshalling (closes #487) + +- 7a82ab43 Test for #487 + +
48a7e07f Merge pull request #537 from 99designs/stub-generation + +Stub generation + +
+ +- 787b38d8 Break testserver tests down into smaller files using stubs + +- c5e3dd44 add stub generation plugin + +
43db679a Merge pull request #534 from 99designs/multiple-bind-types + +Multiple bind types + +
+ +- b26b915e Move input validation into gqlparser see https://github.com/vektah/gqlparser/pull/96 + +
7d394222 Fix typo in README + +Fix typo in README in selection example directory to point to the selection example, not the todo example. + +
+ +- 42131868 Linting fixes + +- 956d0306 Arg type binding + +- 6af3d85d Allow multiple field bind types + +- 3015624b Regen dataloader with correct version + +- 50f7d9c8 Add input field directives back in + +- 8047b82a Fix nullability checks in new marshalling + +- b3f139c9 Cleanup field/method bind code + +- cf94d3ba Removed named types + +
82ded321 Merge pull request #532 from 99designs/fix-missing-json-content-type + +Fix set header to JSON earlier in GraphQL response + +Update the GraphQL handler to set the Response Header to JSON earlier for +error messages to be returned as JSON and not text/html. + +Fixes https://github.com/99designs/gqlgen/issues/519 + +## Notes: +- Add checks for JSON Content-Type checks in decode bad queries tests + +
+ +
b4c5a074 Fix set header to JSON earlier in GraphQL response + +Update the GraphQL handler to set the Response Header to JSON earlier for +error messages to be returned as JSON and not text/html. + +Fixes https://github.com/99designs/gqlgen/issues/519 + +== Notes: +- Add checks for JSON Content-Type checks in decode bad queries tests + +
+ +- 533b08b6 remove wonky input directives + +- 60473555 Shared arg unmarshaling logic + +
a7c8abe6 Merge pull request #529 from 99designs/websocket-keepalive + +Add websocket keepalive support + +
+ +- 555d7468 Remove TypeDefinition from interface building + +- cfa012de Enable websocket connection keepalive by default + +
c5b9b5a8 Use constant tick rate for websocket keepalive + +Some clients (e.g. apollographql/subscriptions-transport-ws) expect a +constant tick rate for the keepalive, not just a keepalive after x +duration of inactivity. + +
+ +- 693753fc Add websocket keepalive support + +- 162afad7 enums dont exist in runtime + +
d0b6485b Merge pull request #525 from 99designs/stop-grc-panic + +Stop GetResolverContext from panicking when missing + +
+ +
78cfff48 Merge pull request #528 from 99designs/fix-todo-directive + +Fix Todo Example Directive + +
+ +
5e1bcfaf Remove parent check in directive + +This should always be true, and currently has a bug when comparing +pointers to structs. Can just be removed. + +
+ +- c1b50cec Stop GetResolverContext from panicking when missing + +- 44aabbd3 Move all build steps back into file containing defs + +- 4e49d489 Merge object build and bind + +- 97764aec move generated gotpl to top + +- d380eccf promote args partial to full template + +- 1bc51010 Everything is a plugin + +
055fb4bc Merge pull request #514 from 99designs/gomod + +Add support for go modules + +
+ +- 48eb6c52 Update appveyor + +- 9e02a977 fix integration test + +- 251e8514 Add support for go modules + +
62175eab Merge pull request #502 from 99designs/model-plugin + +Model plugin + +
+ +- 0f884493 linting fixes + +- c6eb1a85 Extract model generation into a plugin + +
d3f1195c add `content-type: text/html` header to playground handler + +This ensures that the browser doesn't think it should download the page +instead of rendering it, if the handler goes through a gzipping +middleware. + +
+ +
f94b4b78 Merge pull request #497 from azavorotnii/small_fixes + +Small fixes + +
+ +- 21769d93 Ensure no side affect from preceding tests in wont_leak_goroutines test + +- 10f4ccde newRequestContext: remove redundant else part + +- a76e0228 Add cache usage for websocket connection + +- 940db1f9 Fix cacheSize usage in handler + +
fba9a378 Merge pull request #492 from 99designs/unified-merge-pass + +Unified merge pass + +
+ +- a7f719a3 update appveyour to not rely on main + +- f46b7c8e Reclaim main package for public interface to code generator + +- 6b829037 Extract builder object + +- 87b37b0c Replace string based type comparisons with recursive types.Type check + +
82b1917d Merge pull request #490 from 99designs/bind-directly-to-types + +Bind directly to AST types, instead of copying out random bits + +
+ +- 1d86f988 extract argument construction + +- 4b85d1b0 Merge buildInput into buildObject + +- db33d7b7 Extract graphql go merge into its own package + +- afc773b1 Use ast definition directly, instead of copying + +- 8298acb0 bind to types.Types in field / arg references too + +- 38add2c2 Remove definition embedding, use normal field instead + +- 950ff42c Bind to types.Type directly to remove TypeImplementation + +- 70c852eb Add lookup by go type to import collection + +- eb101161 Remove aliased types, to be replaced by allowing multiple backing types + +
e79252b0 Merge pull request #488 from 99designs/refactor-config + +Refactor config + +
+ +- 4138a372 rename generator receiver + +- bec38c7e Extract config into its own package + +- 34b87871 Rename core types to have clearer meanings + +- f10fc649 Merge remote-tracking branch 'origin/next' into HEAD + +
dd972081 Merge pull request #486 from nicovogelaar/feature/list-of-enums + +add list of enums + +
+ +- 1140dd85 add unit test for list of enums + +- 1e3e5e9b add list of enums + +- f87ea6e8 Merge remote-tracking branch 'origin/master' into HEAD + +
473f4f0c Merge pull request #465 from 99designs/performance-improvments + +Performance improvments + +
+ +- f9ee6ce0 return arg in middleware + +
5c8b1e24 Avoid unnessicary goroutines + +goos: linux +goarch: amd64 +pkg: github.com/99designs/gqlgen/example/starwars +BenchmarkSimpleQueryNoArgs-8 300000 25093 ns/op 6453 B/op 114 allocs/op +PASS +ok github.com/99designs/gqlgen/example/starwars 10.807s + +
+ +
b0ffa22a Remove strconv.Quote call in hot path to avoid some allocs + +go test -benchtime=5s -bench=. -benchmem +goos: linux +goarch: amd64 +pkg: github.com/99designs/gqlgen/example/starwars +BenchmarkSimpleQueryNoArgs-8 200000 32125 ns/op 6277 B/op 118 allocs/op +PASS +ok github.com/99designs/gqlgen/example/starwars 9.768s + +
+ +
2cf5a5b8 Add a benchmark + +go test -benchtime=5s -bench=. -benchmem +goos: linux +goarch: amd64 +pkg: github.com/99designs/gqlgen/example/starwars +BenchmarkSimpleQueryNoArgs-8 200000 32680 ns/op 6357 B/op 126 allocs/op +PASS +ok github.com/99designs/gqlgen/example/starwars 9.901s + +
+ +- 5e0456fe fix fmt anf metalint generated code + +- b32ebe14 check nullable value for go1.10 + +- d586bb61 use arg value for the ResolveArgs + +- e201bcb5 set default nil arg to ResolverContext + +- 6fa63640 remove empty line in generated files + +- 139ed9fb fix go10 assign exist variable by eq + +- 428c6300 add nullable argument to directives + +- 74096033 move chainFieldMiddleware to generate code for BC + +- be51904c check nullable arguments + +- 6b005094 add test directives generate + +- 047f2ebc update inline template + +- a13b31e9 metalinter + +- 526bef0b generate servers and add path to error + +- 29770d64 resolve = in template + +- 3a729cc3 update recursive middleware + +- 8b3e634e update tempate and set Dump public + +- e268bb75 Merge remote-tracking branch 'upstream/master' into directives + +- e8f0578d add execute ARGUMENT_DEFINITION and INPUT_FIELD_DEFINITION directive + + + + + + +## [v0.7.2](https://github.com/99designs/gqlgen/compare/v0.7.1...v0.7.2) - 2019-02-05 +- da1e07f5 release v0.7.2 + +
8c0562c1 Merge pull request #530 from 99designs/websocket-keepalive-master + +Add websocket keepalive support + +
+ +- 43fdb7da Suppress staticcheck lint check on circleci + +
9c4b877a Use constant tick rate for websocket keepalive + +Some clients (e.g. apollographql/subscriptions-transport-ws) expect a +constant tick rate for the keepalive, not just a keepalive after x +duration of inactivity. + +
+ +- d36d3dc5 Add websocket keepalive support + +
39216361 Merge pull request #476 from svanburen/patch-1 + +Update config.md + +
+ +
9f6f2bb8 Update config.md + +Add a missed word and add an apostrophe + +
+ +- c033f5fc Fix edit link positioning + +- b3f163d8 Add not about relative generate path + +- 675ba773 Update errors.md + +
5c870a48 Merge pull request #461 from ryota548/patch-1 + +Update getting-started.md + +
+ +
9bcd27c1 Update getting-started.md + +modify `graph/graph.go` to `resolver.go` + +
+ + + + + + +## [v0.7.1](https://github.com/99designs/gqlgen/compare/v0.7.0...v0.7.1) - 2018-11-29 +
3a7f37c7 Merge pull request #455 from 99designs/fix-deprecated-fields + +Fix deprecated fields + +
+ +- b365333b Fix graphiql deprecating all fields + +- 99610be9 Get chat example up to date + + + + + + +## [v0.7.0](https://github.com/99designs/gqlgen/compare/v0.6.0...v0.7.0) - 2018-11-28 +- a81fe503 release v0.7.0 + +
4bfc82d7 Merge pull request #453 from 99designs/deprecate-binary + +Add Deprecation Warning to Binary + +
+ +
8dd29b85 Merge pull request #454 from 99designs/update-gqlparser + +Update gqlparser to latest + +
+ +- 747c3f9c Update gqlparser to latest + +
d6d9885f Merge pull request #416 from 99designs/improved-getting-started + +Improve Getting Started Documentation — No Binary Approach + +
+ +- d22f03c6 Add deprecation warning + +- 878f3945 Minor fixes to getting started code examples + +
6a02657c Merge pull request #447 from 99designs/disable-introspection + +Add config option to disable introspection + +
+ +- b9fbb642 Mention recursive-ness of generate ./... + +- e236d8f3 Remove generate command from resolver.go + +- 04a72430 Re-add final touches section to getting started + +- 3a7a5062 Add handler import to root cmd + +- 9dba96d5 Fix GraphQL capitalisation + +- 1dfaf637 Minor updates to getting started from feedback + +- 94b95d97 Some CSS fixes + +- a36fffd2 Updated getting started with new no-binary approach + +- 601354b3 Add blockquote breakout style + +
6bea1d88 Merge remote-tracking branch 'origin/master' into disable-introspection + +Regenerate + +
+ +
e4bad0e6 Merge pull request #449 from 99designs/increase-float-precision + +Increase float precision + +
+ +
c5589792 Merge pull request #450 from 99designs/import-refactor + +Refactor import handling + +
+ +- 62f0d085 Edit copy for introspection docs + +
63fc2753 Merge pull request #452 from cemremengu/patch-1 + +Fix typo in directives.md + +
+ +
da31e8ed Update directives.md + +Fix small typo + +
+ +- 83e33c13 Remove a debug print + +- 6c575914 fix doc indentation + +- f03b32d3 Use new import handling code + +- c45546e5 Increase float precision + +- 77f2e284 Start moving import management to templates + +- c114346d Decouple loader creation from schema + +
9d636e78 Merge pull request #448 from 99designs/update-gqlparser + +Update to latest gqlparser + +
+ +- d6ce42df Update to latest gqlparser + +- b0acd078 Add config option to disable introspection + +
f9c880b6 Merge pull request #446 from 99designs/fix-flakey-test + +Fix flakey goroutine test + +
+ +
5461e967 Merge pull request #445 from 99designs/remove-graphqlgen + +Remove graphqlgen link + +
+ +- 8a5039d8 Fix flakey goroutine test + +
4b082518 Merge pull request #439 from snormore/pointer-slice + +Fix type binding validation for slices of pointers like []*foo + +
+ +- 293b9eaf Remove graphqlgen link + +
77b27884 Merge pull request #443 from mgutz/patch-1 + +fix generate stubs sentence + +
+ +- ae1c7732 fix generate stubs sentence + +- 827dac5e Fix type binding validation for slices of pointers like []*foo + +
f7932b40 Merge pull request #435 from matiasanaya/update-readme + +Update README.md comparison with graph-gophers + +
+ +- a816208b Update README.md comparison with graph-gophers + +
d25e3b4b Merge pull request #422 from gracenoah/model-method-context + +accept an optional ctx parameter on model methods + +
+ +
0ac6fa57 Merge pull request #434 from urakozz/patch-1 + +Tracer: fixed nil pointer issue + +
+ +- d4f7c954 Update context.go + +
4c4ccf47 Update context.go + +Right now code generated with latest master fails since there are usages of Trace but there is no any single write to this variable + +
+ +- 5faf3a2b re-generate + +- 6fed8947 rebase fixes + +- 4c10ba55 fix generated code + +- 8066edb7 add tests + +- 9862c30f mention contexts on model methods in docs + +- 602a83d6 make ctx method resolvers concurrent + +- 49755120 accept an optional ctx parameter on model methods + +
02a19352 Merge pull request #429 from 99designs/refactor-gofmt + +apply go fmt ./... + +
+ +- 6a77af13 apply gofmt on ./.circleci/test.sh + +- c656dc31 apply go fmt ./... + +
3f598bdc Merge pull request #427 from anurag/patch-1 + +Fix docs typo + +
+ +- cac61bb2 Fix docs typo + +
9f4afe3a Merge pull request #425 from 99designs/render + +Switch to hosting docs on render.com + +
+ +
9875e74b Switch to hosting docs on render.com + +Render.com has offered to host our static site for free, and have +a pretty simple setup for rebuilding on merge to master. I've +switched the DNS records and updated the docs. + +
+ +
981fd10a Merge pull request #419 from 99designs/fix-capture-ctx + +fix unexpected ctx variable capture on Tracing + +
+ +- 027803d2 address comment + +- 2b090de9 address comment + +- d3238d54 chore + +- a2c33f13 write ctx behavior test & refactoring tracer test + +- 5c28d011 fix unexpected ctx variable capture on Tracing + +
4bda3bc1 Merge pull request #411 from 99designs/feat-geterrors + +add GetErrors to RequestContext + +
+ +- a4eaa400 add tests for RequestContext#GetErrors + +
53f33f77 Merge pull request #410 from 99designs/move-tracing-to-contrib + +Move tracing to contrib + +
+ +- 19403832 add GetErrors to RequestContext + +- f0dbce5a Move tracing to contrib + +
a3a92775 Merge pull request #409 from 99designs/graphql-playground-1.7.8 + +Bump to the latest version of graphql-playground + +
+ +
d2648580 Merge pull request #402 from 99designs/feat-opencensus + +add Tracer for OpenCensus + +
+ +- 7286e244 fix shadowing + +- af38cc5a Bump to the latest version of graphql-playground + +- 8bbb5eb7 fix some tests + +- 256e741f add complexityLimit and operationComplexity to StartOperationExecution + +- 4e7e6a1c Merge branch 'master' into feat-opencensus + +
926ad17a Merge pull request #403 from 99designs/feat-complexity + +copy complexity to RequestContext + +
+ +- 2d3026cb Merge branch 'master' into feat-complexity + +- 59ef91ad merge master + +- c9368904 Merge branch 'master' into feat-opencensus + +
b26ee6b4 Merge pull request #404 from 99designs/feat-apollo-tracing + +add apollo-tracing support + +
+ +- fd4f5587 fix timing issue + +- 91e3e88d address comment + +- a905efa8 fix lint warning + +- b2ba5f86 address comment + +- 561be1c0 add Apollo Tracing sample implementation + +- 83c7b2cb add Start/EndOperationParsing & Start/EndOperationValidation methods to Tracer + +- b5305d75 address comment + +- 784dc01f oops... + +- a027ac21 copy complexity to RequestContext + +- ececa23c add Tracer for OpenCensus + +
0d5c65b6 Merge pull request #400 from 99designs/fix-ci + +fix Circle CI test + +
+ +- 00d11794 add mutex to logger + +- 884d35c6 fix race condition + +- f70cedc2 fix Circle CI test + +
1b17b5a2 Merge pull request #392 from 99designs/feat-tracer + +Add Tracer layer + +
+ +
184e48cb Merge pull request #396 from 99designs/remove-ci-exclusion + +Run generate ./... and test ./... in circle + +
+ +
fd5d9eca Merge pull request #395 from 99designs/feat-extension-example + +add Type System Extension syntax example + +
+ +- 686c71a4 Run generate ./... and test ./... in circle + +- 304d3495 fix https://github.com/99designs/gqlgen + +- 85322586 address comment + +
195f952b fix CI failed + +AppVeyor handle this test, But Circle CI is not + +
+ +- b5b767c4 address comment + +- d723844b add Type System Extension syntax example + +- df685ef7 change timing of EndFieldExecution calling + +- 94b7ab02 refactor Tracer interface signature that fit to apollo-tracing specs + +
8eb2675a Revert "change field marshaler return process that make it easy to insert other processing" + +This reverts commit 583f98047f5d1b6604d87e7b8d6f8fd38082d459. + +
+ +- c8af48cd rename Tracer method name + +- a3060e80 refactor Tracer signature + +- d319afe6 add support request level tracer + +- 1c5aedde add support field level tracer + +- 583f9804 change field marshaler return process that make it easy to insert other processing + +- ab4752c2 Update README.md + +
3447dd2d Merge pull request #389 from 99designs/multiple-schemas + +Support multiple schemas + +
+ +- a230eb04 Support multiple schemas + +
20a5b6c7 Merge pull request #369 from vetcher/master + +reverse errors and data order in response + +
+ +- f1f043b9 reverse 'data' and 'error' fields order in failure tests + +
3eab22a3 Merge pull request #370 from rodrigo-brito/fix-underscore + +Underscore on field name finder + +
+ +- 0ad3d3ce fix on struct name finder + +- 42e11045 reverse errors and data order in response + + + + + + +## [v0.6.0](https://github.com/99designs/gqlgen/compare/v0.5.1...v0.6.0) - 2018-10-03 +- 6f486bde release v0.6.0 + +
7833d0cb Merge pull request #365 from 99designs/dont-guess-imports + +Don't let goimports guess import paths + +
+ +- 732be395 Don't let goimports guess import paths + +
926eb9d8 Merge pull request #364 from 99designs/query-cache-test + +Add a stress test on query cache + +
+ +- bab70df5 Add a stress test on query cache + +
84481761 Merge pull request #362 from 99designs/fix-error-docs + +fix error docs + +
+ +- 23b58f6d fix error docs + +
8f0ef777 Merge pull request #361 from 99designs/revert-360-revert-335-typed-interfaces + +Revert "Revert "Generate typed interfaces for gql interfaces & unions"" + +
+ +- 77257d1e Revert "Revert "Generate typed interfaces for gql interfaces & unions"" + +
1cae19bb Merge pull request #359 from 99designs/fix-null-arg-error + +Fix Issue With Argument Pointer Type + +
+ +
ee862717 Merge pull request #360 from 99designs/revert-335-typed-interfaces + +Revert "Generate typed interfaces for gql interfaces & unions" + +
+ +- 02658647 Revert "Generate typed interfaces for gql interfaces & unions" + +
bc35d730 Merge pull request #335 from 99designs/typed-interfaces + +Generate typed interfaces for gql interfaces & unions + +
+ +- 48724dea Removed redundant file + +- 2432ab3c Fix other tests with pointer change + +- 20add126 Fix test case + +
f5c03401 Do not strip ptr for args with defaults + +This fails if a client still sends a null value. If an arg is nullable +but has a default, then null is still a valid value to send through. + +
+ +- 0c399270 Add test case + +
b836a976 Merge pull request #358 from 99designs/fix-embedded-pointer + +Fix Embedded Pointer + +
+ +- d3e27553 Bump gqlparser to latest master + +- b8af0c81 Use types.Implements to check if an interface implementor accepts value recievers + +
2ab05daf Merge pull request #353 from 99designs/resolver-ctx-parenting + +Parent middleware generated contexts + +
+ +- faf0416b Parent resolver generated contexts + +- caa474c6 Check for embedded pointer when finding field on struct + +- f302b408 Added reproduce test case + +
14cf46bc Merge pull request #348 from gissleh/feat-websocket-initpayload + +Added parsing of the websocket init message payload + +
+ +- 3147d914 Updated example in docs to use handler.GetInitPayload instead of graphql.GetInitPayload + +- 32f0b843 Moved InitPayload from graphql to handler package, updated test to import it from there. + +- 01923de6 Moved initPayload to wsConnection member, changed wsConnection.init to return false on invalid payload + +- 25268ef9 Added information about it under recipes/authentication doc + +- 575f28e0 Fixed graphql.GetInitPayload panic if payload is nil. + +
380828fa Added parsing of the websocket init message payload, and making it available via the context passed to resolvers. + +* Added GetInitPayload(ctx) function to graphql +* Added WithInitPayload(ctx) function to graphql +* Added WebsocketWithPayload method to client.Client (Websocket calls it with a nil payload for backwards compability) +* Added tests for these changes in codegen/testserver/generated_test + +
+ +
2bd1cc2e Merge pull request #334 from 99designs/support-response-extensions + +Support Extensions in Response + +
+ +- 8fdf4fbb Add test case for extension response + +- 60196b87 Add extensions to response struct + +- cbde0ea9 Generate typed interfaces for gql interfaces & unions + + + + + + +## [v0.5.1](https://github.com/99designs/gqlgen/compare/v0.5.0...v0.5.1) - 2018-09-13 +- 636435b6 release v0.5.1 + +- bfb48f2f Update README.md + +
869215a7 Merge pull request #339 from 99designs/fix-subscription-goroutine-leak + +Fix gouroutine leak when using subscriptions + +
+ +
535dd24b Merge pull request #338 from codyleyhan/cl/docs + +Adds docs for how resolvers are bound + +
+ +- baa99fc5 cleaned up resolver doc + +
647fbbc9 Merge pull request #340 from chris-ramon/patch-1 + +README.md: Updates `graphql-go/graphql` features. + +
+ +
729e09c8 README.md: Updates `graphql-go/graphql` features. + +- Subscription support: https://github.com/graphql-go/graphql/issues/49#issuecomment-404909227 +- Concurrency support: https://github.com/graphql-go/graphql/issues/389 +- Dataloading support: https://github.com/graphql-go/graphql/pull/388 + +
+ +- 229a81be Fix gouroutine leak when using subscriptions + +- c15a70ff Adds docs for how resolvers are bound + +- 35c15c94 Add link to talk by Christopher Biscardi + +
72edf98a Merge pull request #331 from edsrzf/arg-refactor + +Refactor arg codegen + +
+ +- 31505ff4 Use arg function for generated Complexity method + +- ebdbeba0 Just realized "if not" is allow in templates + +- 861a805c Regenerate code + +
639727b6 Refactor arg codegen + +Now a function is generated for each field and directive that has +arguments. This function can be used by both field methods as well as +the `Complexity` method. + +The `args.gotpl` template now generates the code for this function, so +its purpose is a little different than it used to be. + +
+ +
8026e63b Merge pull request #330 from edsrzf/string-compare + +Use built-in less than operator instead of strings.Compare + +
+ +- c770b4e7 Use built-in less than operator instead of strings.Compare + + + + + + +## [v0.5.0](https://github.com/99designs/gqlgen/compare/v0.4.4...v0.5.0) - 2018-08-31 +- 5bc4665f release v0.5.0 + +
b48c6b92 Merge pull request #326 from 99designs/version + +Add version const + +
+ +- 14587a5f Add version const + +
7d44dd6b Merge pull request #315 from edsrzf/query-complexity + +Query complexity calculation and limits + +
+ +- 2ab857ee Merge branch 'master' into query-complexity + +- 6e408d5d Interfaces take max complexity of implementors + +
d08b9c4a Merge pull request #325 from edsrzf/no-get-mutations + +Only allow query operations on GET requests + +
+ +
82a28b57 Only allow query operations on GET requests (closes #317) + +This mitigates the risk of CSRF attacks. + +
+ +- 239b1d22 Don't emit complexity fields for reserved objects + +- 8da5d61b Generate complexity for all fields. Fix bugs. Re-generate examples. + +
40943c6d Merge pull request #322 from 99designs/drop-old-flags + +Drop old cli flags + +
+ +
8c17eea9 Merge pull request #320 from andrioid/master + +Description added to generated Model code + +
+ +
988b367a Merge pull request #316 from 99designs/feat-concurrent-each-element + +use goroutine about processing each array elements + +
+ +- e5265ac2 Fix complexity template bug + +- 7c040045 now with field values + +- 08ab33be starting to look better + +- e834f6b9 Query complexity docs + +- a0158a4e Drop old cli flags + +- bb78d2fa go generate ./.. + +- 2488e1b3 Merge branch 'master' of https://github.com/99designs/gqlgen + +
f6a733ae Merge pull request #308 from codyleyhan/tags + +Finds fields by configurable struct tag + +
+ +
f7aeb88a Merge pull request #321 from 99designs/remove-typemap + +Remove support for the old json typemap + +
+ +- d63449b9 Remove support for the old json typemap + +- fce4c722 address comment + +- 8c3aed7d Merge branch 'master' into query-complexity + +
cecd84c6 Add complexity package tests + +Also some small behavior fixes to complexity calculations. + +
+ +
002ea476 Merge pull request #318 from edsrzf/query-cache + +Add query cache + +
+ +- fcd700b6 Panic on lru cache creation error + +
78c57079 Add query cache + +This commit adds a query cache with a configurable maximum size. +Past this size, queries are evicted from the cache on an LRU basis. + +The default cache size is 1000, chosen fairly arbitrarily. If the size +is configured with a non-positive value, then the cache is disabled. + +Also ran `dep ensure` to add the new dependency to `Gopkg.lock`. + +
+ +- 076f9eac removed dirt + +- 6ae82383 trying to get description with generated models + +- 7d6f8ed4 fixes case where embeded structs would cause no field to be found + +- 02873495 use goroutine about processing each array elements + +- 40f904a6 Merge branch 'master' of github.com:99designs/gqlgen into tags + +- 56768d6b adds tests for findField + +- 556b93ac Run go generate ./... + +
2dcb2dd8 Merge pull request #314 from 99designs/directive-obj + +Add obj to Directives + +
+ +- 0e2aaa9e Merge branch 'master' of github.com:99designs/gqlgen into tags + +- 7cfd9772 fixes field selection priority + +- 238a7e2f Add complexity support to codegen, handler + +- 95ed529b New complexity package + +- 1fda3ede Add obj to Directives + +
9b247102 Merge pull request #301 from 99designs/feat-directive-parent + +add Result field to ResolverContext + +
+ +- 9ec385d1 Merge branch 'tags' of github.com:codyleyhan/gqlgen into tags + +- c5849929 adds binding by passed tag + +- 6ef2035b refactor set Result timing + +- 568a72e9 add some refactor + +
50588a8a Merge pull request #299 from 99designs/test-init-on-windows + +Test gqlgen init on windows + +
+ +- 9148adfc Test gqlgen init on windows + +- c7fd8416 Merge branch 'master' into feat-directive-parent + +
3f8a601b Merge pull request #312 from 99designs/validate-gopath + +Validate gopath when running gqlgen + +
+ +
77e69552 Merge pull request #310 from 99designs/sitemap-404s + +Remove 404s from sitemap + +
+ +
0b6cedfb Merge pull request #311 from jekaspekas/fix-mapstructure-err + +fix mapstructure unit test error + +
+ +- b07736ef Validate gopath when running gqlgen + +
b082227d fix mapstructure unit test error + +fix unit test error "mapstructure: result must be a pointer". It appears instead of resolver returned error. + +
+ +- 25b12cb6 Remove 404s from sitemap + +
4a6f505d Merge pull request #309 from 99designs/pr-template + +Add a PR template + +
+ +- 64f3518e run generate + +- a81147df Add a PR template + +- 15d8d4ad Merge branch 'introspection-directive-args' into HEAD + +- 12efa2d5 add tests + +- 95b6f323 finds fields by json struct tag + +- 07ee49f3 Added args to introspection scheme directives. + +- e57464fe refactor ResolverContext#indicies and suppress lint error + +- 09e4bf8c add Result field instead of ParentObject field + +
b8695fb5 Merge pull request #304 from 99designs/newline-for-init-response + +Put newline at end of `gqlgen init` output + +
+ +- fabc6f8f Merge branch 'master' into feat-directive-parent + +- e53d224e Merge branch 'master' into feat-directive-parent + +
de750645 Merge pull request #298 from 99designs/handle-response-nulls + +Nulls in required fields should cause errors and bubble + +
+ +- c8552729 Put newline at end of gqlgen init output + +- 072363c7 add ParentObject field to ResolverContext + +
e15d7890 Merge pull request #300 from 99designs/fix-starwars-connection-example + +fix connection example + +
+ +- d6acec16 fix connection example + +- 7d1cdaca Nulls in required fields should cause errors and bubble + +
2c4e6cbf Merge pull request #294 from 99designs/simplfy-concurrent-resolvers + +Simplfy concurrent resolver logic + +
+ +- 7926c688 Simplfy concurrent resolver logic + + + + + + +## [v0.4.4](https://github.com/99designs/gqlgen/compare/0.4.3...v0.4.4) - 2018-08-21 +- 6f6622c6 Bump gqlparser to latest version + +
72659af4 Merge pull request #297 from 99designs/fix-dep-pruning + +Explicitly import ambient imports so dep doesn't prune them + +
+ +- cac3c729 Explicitly import ambient imports so dep doesn't prune them + +
e6af26e0 Merge pull request #296 from heww/master + +sort directives by name when gen + +
+ +- fd09cd99 sort directives by name when gen + +
71917267 Merge pull request #292 from m4ppi/fix-doc + +Fix broken links in docs + +
+ +- 05c73d9f Fix broken links in docs + +
5a0b56aa Merge pull request #285 from 99designs/fix-force-type + +Stop force resolver from picking up types from matching fields + +
+ +- 31478cf4 Stop force resolver from picking up types from matching fields + +
ebdcf740 Merge pull request #283 from 99designs/speed-up-tests + +Speed up tests + +
+ +- 36e84073 Speed up tests + + + + + + +## [0.4.3](https://github.com/99designs/gqlgen/compare/0.4.2...0.4.3) - 2018-08-10 +
3575c289 Merge pull request #281 from 99designs/introspection-default-args + +Fix missing default args on types + +
+ +- b808253f Fix missing default args on types + +
bf235296 Merge pull request #282 from 99designs/flakey-tests + +Remove sleeps in tests + +
+ +- e9c68f08 make appveyor less flakey + + + + + + +## [0.4.2](https://github.com/99designs/gqlgen/compare/0.4.1...0.4.2) - 2018-08-10 +- 06b00d45 Update README.md + +
5c379a33 Merge pull request #279 from 99designs/integration-tests + +Integration tests + +
+ +- 7f20bdef disable tty for jest + +- bb0a89a0 exclude generated code from tests + +- c2bcff79 regenerate + +- 45e22cb1 Add introspection schema check + +
53109cd0 Merge pull request #270 from 99designs/feat-handlers + +stop pickup "github.com/vektah/gqlgen/handler" from GOPATH + +
+ +- ae82b94a convert existing tests to jest + +- f04820b1 address comment + +- 88730e2c Convert test directory into integration test server + +- f372b1c9 Use docker in docker for the existing testsuite + +
0eb08ab9 Merge pull request #274 from 99designs/fix-variable-validation-data + +Prevent executing queries on variable validation failures + +
+ +- 47a7ac35 Prevent executing queries on variable validation failures + +- e6e323d0 stop pickup "github.com/vektah/gqlgen/handler" from GOPATH + +- e6005f6b fix mobile nav + +
5cdbc975 Merge pull request #267 from 99designs/authentication-docs + +Authentication docs + +
+ +- 1871c4ce Add bold variant of Roboto to docs + +- fc9fba09 Some minor edits to authentication docs + +- d151ec8d Add docs on user authentication + +- 8db3c143 Add structure to menu + +
c57619e0 Merge pull request #260 from 99designs/init-improvements + +Init Config Improvement + +
+ +
336b62ec Merge pull request #266 from 99designs/lint-friendly-decollision + +Make keyword decollision more lint friendly + +
+ +- 2acbc245 Make keyword decollision more lint friendly + +
f12f08a7 Merge pull request #264 from 99designs/docs + +CORS docs + +
+ +- a2a7c0e7 Eliminate font resize popin + +- 8a7ed618 Fix errors docs + +- 96e6aab2 Add CORS docs + +
0ab1c685 Merge pull request #263 from 99designs/add-logo + +Add logo to doc site + +
+ +- 6d39f868 Add logo to doc site + +- d7241728 Better error on init if file exists + +- fb03bad9 Run init even if config is found + +- 52b78793 Fix hard-coded server filename in init + + + + + + +## [0.4.1](https://github.com/99designs/gqlgen/compare/0.4.0...0.4.1) - 2018-08-04 +
42f10ec9 Merge pull request #255 from 99designs/introspection-fixes + +Fix introspection api + +
+ +- 7400221c Fix introspection api + +
b35804ba Merge pull request #254 from oskanberg/patch-1 + +Fix typo in introduction docs + +
+ +- 84552437 Fix typo in introduction docs + +- b5a48e3e Update README.md + +- c20bb134 update badges + + + + + + +## [0.4.0](https://github.com/99designs/gqlgen/compare/0.3.0...0.4.0) - 2018-08-03 +
7b5a3d74 Merge pull request #247 from 99designs/next + +0.4.0 Release + +
+ +
c0be9c99 Merge pull request #251 from 99designs/rewrite-imports + +Rewrite import paths + +
+ +- 4361401a Rewrite import paths + +
f042328a Merge pull request #252 from 99designs/move-doc-site + +Move doc site + +
+ +- 658a24d9 Move doc site + +
07b7e6ca Merge pull request #248 from 99designs/json-usenumber + +use json.Decoder.UseNumber() when unmarshalling vars + +
+ +- 95fe07fe use json.Decoder.UseNumber() when unmarshalling vars + +
c555f54c Merge pull request #245 from vektah/new-feature-docs + +New feature docs + +
+ +
825840aa Merge pull request #244 from vektah/array-coercion + +Add implicit value to array coercion + +
+ +
90b40769 Merge pull request #246 from vektah/fix-introspection + +Fix introspection + +
+ +- ef208c76 add docs for resolver generation + +- e44d798d Add directives docs + +- 62d4c8aa Ignore __ fields in instrospection + +- bc204c64 Update getting started guide + +- b38c580a Return the correct mutation & subscription type + +- 9397920c Add field name config docs + +- d2265f3d Add implicit value to array coercion + +
191c8ba0 Merge pull request #239 from vektah/directive-args + +Directive args + +
+ +- 3bef596d regenerate + +- 4f37d170 Add directive args + +
f78a6046 Merge pull request #241 from vektah/feat-lintfree + +Make more golint free generated code + +
+ +- 19b58175 Merge remote-tracking branch 'origin/master' into HEAD + +- c3fa1a55 Merge branch 'next' into feat-lintfree + +
17bfa2cb Merge pull request #240 from vektah/doc-fonts + +Use fonts from golang styleguide + +
+ +- 64ef0571 Use fonts from golang styleguide + +
6b532383 Merge pull request #237 from vektah/feat-fieldmapping + +Add model field mapping + +
+ +- 4fb721ae address comment + +- bf43ab3d Merge branch 'next' into feat-fieldmapping + +- 353319ca Refactor GoVarName and GoMethodName to GoFieldName etc... + +- d7e24664 Add method support + +
17bcb322 Merge pull request #236 from vektah/generate-handler-on-init + +Generate server on running init + +
+ +
600f4675 Merge pull request #238 from vektah/variable-validation + +Add missing variable validation + +
+ +- d6a76254 Add missing variable validation + +- 121e8db4 Generate server on running init + +- 108bb6b4 Rename govarname to modelField + +- f7f6f916 Make more lint friendly + +- 69eab938 Add model field mapping + +
ffee020c Merge pull request #235 from vektah/generate-resolver-on-init + +Generate resolver on init + +
+ +- df95f003 Generate code after init + +- 58831ac1 Generate resolver if configured + +
7031264d Merge pull request #229 from vektah/fix-init-command + +Fixing init command + +
+ +
078bc985 Fixing init command + +The init command always return file already exists if there are no +configFilename specified + +This is caused by codegen.LoadDefaultConfig() hiding the loading details +and always return the default config with no error while the init +command code expects it to tell us if config exists in default +locations. + +To avoid confusion I have splitted the loading config from default +locations out into its own method so we can handle different cases +better. + +Additionally I also moved default config into a method so we always +generating new a config instead of passing it around and potentially +mutating the default config. + +
+ +
803711e9 Merge pull request #221 from vektah/middleware-stack + +Implement FieldMiddleware Stack + +
+ +- 0ec918bf Switch GoName to Name|ucFirst + +- 5dc104eb Add middleware example for Todo + +- 73a8e3a3 Fix some issues with directive middlewares + +- 84163247 Regenerate + +
0e16f1fc Generate FieldMiddleware + +Moves it off of RequestContext and into generated land. This change +has a basic implementation of how directive middlewares might work. + +
+ +- 2748a19b Require Config object into NewExecutableSchema + +- 09242061 Add Directives to Build + +
69e790c2 Add *Field to CollectedField + +We need the Field Definition so that we can run directive middlewares +for this field. + +
+ +- d6813f6d Generarte + +
764c6fda Refactor ResolverMiddleware to FieldMiddleware + +This will allow us to include DirectiveMiddleware in the same middleware +setup, that will run after Resolver middlewares. + +
+ +
7226e573 Merge pull request #225 from rongfengliang/patch-1 + +Update getting-started.md + +
+ +- 66593ffe Merge remote-tracking branch 'origin/master' into HEAD + +- 8714f7fb hush metalinter + +
0dfb92a7 Update getting-started.md + +CreateTodo UserID input should be UserId not User + +
+ +
0fa7977f Merge pull request #217 from vektah/resolver-middleware-all + +Run Resolver Middleware For All Fields + +
+ +
7292be78 Rename CastType to AliasedType + +This field stores a Ref if a type is a builtin that has been aliased. In +most cases if this is set, we want to use this as the type signature +instead of the named type resolved from the schema. + +
+ +- ec928cad Regenerate examples + +
97f13184 Remove comment about ResolverMiddleware + +Not true anymore! + +
+ +- b512176c Run resolver middleware for all fields + +
f67f8390 Merge pull request #218 from vektah/remove-old-resolvers + +Remove old resolvers + +
+ +
1a3e4e99 Merge pull request #220 from vektah/feat-race + +turn back -race option + +
+ +- 40989b19 turn back -race option + +
1ba61fcb Update test & examples to use new resolver pattern + +* chat +* dataloader +* scalar +* selection +* starwars +* todo + +
+ +
38708961 Stop generating two types of resolvers + +In recent refactor we introduced a new pattern of resolvers which is +better structured and more readable. To keep Gqlgen backward compatible +we started generate two styles of resolvers side by side. + +It is now time to sunset the old resolver. This commit removes the old +resolver and update the generation code to use the new resolver +directly. + +
+ +- ffe42658 Merge pull request #208 from vektah/directives-skip-include + +
a69071e3 Pass context to CollectFields instead of RequestContext + +Internally it can still get to RequestContext as required. + +
+ +- d02d17ae Add method for generating method name from field + +- c7ff3208 Update gqlparser version to include default resolution + +- ce17cd90 Add default value test case + +
cbfae3d3 Add skip/include test cases + +Adds a set of test cases for skip and include directives to the todo +example. Also now conforms to spec if both are included. + +
+ +
ea0f821c Add skip/include directive implementation + +This is a snowflake implementation for skip/include directives based on +the graphql-js implementation. Skip takes precedence here. + +
+ +- ebfde103 Pass request context through to CollectFields + +
bab7abb2 Merge pull request #210 from vektah/feat-init + +introduce gen & init subcommand + +
+ +
6ba508f9 Merge pull request #214 from vektah/gqlparser-schema-validation + +Bump gqlparser to get schema validation + +
+ +- 138b4cea Bump gqlparser to get schema validation + +- 08d7f7d0 Merge branch 'next' into feat-init + +- 39f9dbf6 fix error from breaking change + +- 41147f6f update Gopkg.lock + +- 87d8fbea remove unused flag + +- eff49d04 support init subcommand + +- c5810170 introduce cobra library + +- c3c20f8f Merge remote-tracking branch 'origin/master' into HEAD + +
90df37f6 Merge pull request #205 from vektah/forward-credential-to-graphql-endpoint + +Use original credential for query request in playground + +
+ +
52343745 Merge pull request #206 from vektah/validation-locations + +Update gqlparser for validation locations + +
+ +- f4d31aa4 Update gqlparser for validation locations + +
9d473f8b Merge pull request #203 from vektah/99designs-announcement + +Announcement: 99designs is now sponsoring gqlgen + +
+ +
c2f1570d Merge pull request #204 from vektah/gqlparser-prelude + +Use shared prelude + +
+ +- 004ec6a9 Add 99designs sponsorship news + +- 548aed14 Use shared prelude + +
edb3ea4e Use original credential for query request in playg + +Currently the playground doesn't forward any credentials when making +query calls. This can cause problems if your playground requires +credential logins. + +
+ +
f855a89c Merge pull request #201 from cocorambo/remove-trailing-println + +Remove trailing Println + +
+ +- c41a6c36 Remove trailing Println + +
2692d3e0 Merge pull request #197 from vektah/new-parser + +Integrate gqlparser + +
+ +- 5796d47d Integrate gqlparser + +- 55179a61 Update badges + +
01a4c677 Merge pull request #195 from jonstaryuk/master + +Update playground version + +
+ +- c52f24af Update playground version to 1.6.2 + + + + + + +## [0.3.0](https://github.com/99designs/gqlgen/compare/0.2.5...0.3.0) - 2018-07-14 +
381b3469 Merge pull request #194 from vektah/multiline-comments + +Fix multiline comments + +
+ +- 112d68a6 only build master branch + +- 4b3778e3 Fix multiline comments + +
eb44925c Merge pull request #193 from vektah/validate-method-returns + +validate method return types + +
+ +- 164acaed validate method return types + +
f478f816 Merge pull request #192 from vektah/strict-config + +Strict config + +
+ +- a1c02e7b Strict config + +
533dcba7 Merge pull request #191 from vektah/nullable-list-elements + +Support nullable list elements + +
+ +- e0bf6afd Support nullable list elements + +
0780bf2e Merge pull request #190 from vektah/generated-forced-resolvers + +Allow forcing resolvers on generated types + +
+ +- bf1823cd Allow forcing resolvers on generated types + +
febd0358 Merge pull request #186 from vektah/error-redux + +Error redux + +
+ +- b884239a clarify error response ordering + +- 58e32bbf Drop custom graphql error methods + +- d390f9c6 Errors redux + + + + + + +## [0.2.5](https://github.com/99designs/gqlgen/compare/0.2.4...0.2.5) - 2018-07-13 +
0a9709db Merge pull request #188 from vektah/fix-windows-gopath + +Fix windows gopath issue + +
+ +- ea4f26c6 more fixes + +- 1066953d Appveyor config + +- f08d8b61 Fix windows gopath issue + +- 9ade6b7a Update gettingstarted to use new resolvers + + + + + + +## [0.2.4](https://github.com/99designs/gqlgen/compare/0.2.3...0.2.4) - 2018-07-10 +
ac9e5a66 Merge pull request #180 from vektah/import-alias-before-finalize + +Fix a bug custom scalar marshallers in external packages + +
+ +- 160ebab5 Fix a bug custom scalar marshallers in external packages + +
43212c04 Merge pull request #179 from vektah/models-config-error + +Improve Output Filename and Package Handling + +
+ +- 936bc76e Better handling of generated package name + +- 5d3c8ed2 Inline ImportPath strings + +- fc43a92a Check that exec and model filenames end in *.go + +- 6d38f77d Handle package name mismatch with dirname + +- ebf1b2a5 Add error message when specifying path in package name + +- c8355f48 Check models config for package-only specs + + + + + + +## [0.2.3](https://github.com/99designs/gqlgen/compare/0.2.2...0.2.3) - 2018-07-08 +- 6391596d Add some basic docs on the new config file + +
a9c3af86 Merge pull request #176 from vektah/config-search-paths + +Search for config + +
+ +- 25cfbf08 Search for config + +
bff3356b Merge pull request #175 from vektah/lint-all-packages + +gometalinter should cover all packages + +
+ +- 61f37173 gometalinter should cover all packages + +
ce657044 Merge pull request #173 from vvakame/feat-resolver-hint + +add resolver option support to field + +
+ +
57b8279e Merge pull request #172 from vvakame/feat-newconfig + +switch to .gqlgen.yml + +
+ +- fcfceefb add resolver option support to field + +- c7ce1cbb update docs + +- 42948153 move to .gqlgen.yml + +
325c45a4 Merge pull request #171 from vvakame/add-gitignore + +add .idea/ to .gitignore + +
+ +- aa4cec9b add .idea/ to .gitignore + + + + + + +## [0.2.2](https://github.com/99designs/gqlgen/compare/0.2.1...0.2.2) - 2018-07-05 +- f79b6a52 cleanup new config + +
f0a08617 Merge pull request #163 from vvakame/feat-types-json + +support .gqlgen.yml + +
+ +
faf095fc Merge pull request #166 from vektah/validate-at-end + +Validate at end + +
+ +- fca1e08e shh errcheck + +- cc78971e Dont show compilation errors until after codegen + +- 9f6ff0cf Convert todo example to new resolver syntax + +- 8577ceab address comment + +- 86dcce73 Add format check to -typemap argument + +- 5debbc6a Implement types.yaml parsing + +- ecf56003 Refactor types.json parsing + +
b16e8429 Merge pull request #159 from vektah/enum-only-generation + +Dont skip model generation if there are enums defined + +
+ +- 3f751a40 Dont skip model generation if there are enums defined + +- 588aeacb more tutorial fixes + +
dc472965 Merge pull request #157 from johncurley/fix-docs-argument + +Updated mutation to take correct argument + +
+ +- 88a84f83 Updated mutation to take correct argument + +
404f0b0d Merge pull request #151 from qdentity/fix-longer-gopath + +Fix bug with multiple GOPATH full package name resolving + +
+ +
f66e2b3b Fix bug with multiple GOPATH full package name resolving + +This commit fixes the bug where GOPATH values that are longer than the input package name cause 'slice bounds out of range' errors. + +
+ + + + + + +## [0.2.1](https://github.com/99designs/gqlgen/compare/0.2.0...0.2.1) - 2018-06-26 +
cb87a2cb Merge pull request #147 from vektah/import-overhaul + +Improve import handling + +
+ +
9fa3f0fb Merge pull request #134 from mastercactapus/small-interfaces + +add lint-friendly small interfaces option for resolvers + +
+ +
e8c30acd fix template error on generated defaults (#146) + +* fix template error on generated defaults + +* go fmt + +* add test for default fix + +* . + +* add key sort for default values + +
+ +- 769a97e2 fix race in chat example test - t.Parallel() doesn't guarantee parallel execution - moved goroutine so the test can execute independently + +- 5b77e4c2 remove deprecation warning for now + +- 59a5d752 remove trailing S + +- b04846f6 fix time race in scalar test + +- a80b720f name updates, deprecation, some code comments + +- 2bbbe054 Merge branch 'master' into small-interfaces + +- 4ffa2b24 case insensitive compare to determine self package + +- c0158f54 make sure colliding imports are stable + +- abf85a10 get package name from package source + +- a39c63a5 remove a random json tag from tutorial + +- f48cbf03 tutorial fixes + +
0a85d4f2 Update generated headers to match convention. (#139) + +* Update generated.gotpl + +* Update models.gotpl + +* Update data.go + +* update go generate + +* revert code changes + +
+ +- 4a6827bd Update getting started guide + +- a21f3273 Use recognized `Code generated` header + +- 038c6fd2 change from `ShortResolver` to `ShortResolvers` - prevents possible collision with an object type named `Short` + +- 0bc592cd run go generate + +- db2cec07 fix template formatting + +- 59ee1b5c from probably makes more sense + +- 620f7fb4 add "short" resolver interface + + + + + + +## [0.2.0](https://github.com/99designs/gqlgen/releases/tag/0.2.0) - 2018-06-21 +
d26ef2a2 Merge pull request #136 from tianhai82/master + +fix GOPATH case mismatch issue + +
+ +
a34b4de4 Merge pull request #137 from appleboy/patch-1 + +fix example links + +
+ +
c1cde36c Merge pull request #133 from mastercactapus/skip-type-mismatch + +skip struct fields with incompatible types + +
+ +- c1b4574c fix example links + +- 63976d5f fix GOPATH case mismatch issue + +- 8771065f skip fields with incompatible types + +
40d9a11b Merge pull request #127 from jon-walton/windows-path-slash + +convert windows input path separators to slash + +
+ +- 7db9d122 convert windows input path separators to slash + +
a5f72601 Merge pull request #122 from vektah/json-encoding-fixes + +Fix json string encoding + +
+ +- f207c62c review feedback + +- 578d8415 Fix json string encoding + +
e9b40666 Merge pull request #123 from vektah/drop-fk-generation + +BC Break: Stop generating foreign keys in models + +
+ +
a8419e20 Merge pull request #124 from vektah/fix-backtick-escaping + +Fix backtick escaping + +
+ +- 47eaff4d Fix backtick escaping + +- a5c02e6c BC Break: Stop generating foreign keys in models + +
94d5c89e Merge pull request #120 from andrewmunro/bugfix/fix-panic-on-invalid-array-type + +Fixing panic when non array value is passed to array type + +
+ +- 5680ee49 Adding dataloader test to confirm no panic on malformed array query + +- 55cc161f Fixing panic when non array value is passed to array type + +- 6b3b338d Add gitter link to readme + +- 6c823beb add doc publish script + +
a25232d8 Merge pull request #113 from mikeifomin/patch-1 + +Fix typo in url dataloaden + +
+ +- 3a129c77 Fix typo in url dataloaden + +- e1fd79fe Merge pull request #111 from imiskolee/master (closes #110) + +- e38cb497 1. fix bug: #110 + +
3990eacf Merge pull request #108 from imiskolee/master + +generate json tag to model field by gql name. + +
+ +- abb7502a 1. run go generate + +- e1f90946 1. add json tag in models_gen.go 2. use gqlname to model filed json tag. + +
35e09717 Merge pull request #107 from vektah/fix-vendor-normalization + +Fix vendor normalization + +
+ +
63ee4199 Fix vendor normalization + +When refering to vendored types in fields a type assertion would fail. This +PR makes sure that both paths are normalized to not include the vendor +directory. + +
+ +
2a437c23 Merge pull request #105 from vektah/keyword-input-args + +Automatically add a _ suffix to reserved words + +
+ +
26ac13ff Merge pull request #104 from vektah/new-request-context + +Add a NewRequestContext method + +
+ +- 309e5c6d Automatically add a _ suffix to reserved words + +- a2fb1421 Add a NewRequestContext method + +
ab6e65bd Merge pull request #97 from vektah/add-input-defaults + +Default values for input unmarshalers + +
+ +- 1cd80c4a Default values for input unmarshalers + +
79c69d15 Merge pull request #96 from vektah/refactor-tests + +Refactor tests + +
+ +- 7b1c8198 Refactor tests + +
0c7bdfc6 Merge pull request #95 from vektah/custom-error-types + +Custom error types + +
+ +- 4bdc1e1f regenerate + +- 20250f18 Add fully customizable resolver errors + +- a0f66c88 Update README.md + +- 8f62d505 Update README.md + +- a1043da6 Add feature comparison table to readme + +
22128e0e Merge pull request #93 from vektah/input-type-error-handling + +Input type error handling + +
+ +- e7539f11 Add an error message when using types inside inputs + +- a780ce69 Add a better error message when passing a type into an input + +- 0424f043 Refactor main so tests can execute the generator + +
ab3803a6 Merge pull request #89 from vektah/opentracing-parent-span + +Add parent opentracing span around root query/mutation/resolvers + +
+ +
d157ac35 Add context to recover func + +This makes the request and resolver contexts available during panic +so that you can log the incoming query, user info etc with your bug +tracker + +
+ +- 3ceaa189 add request middleware + +- 877f75a0 remove debugging trace (closes #81) + +
091d25ab Merge pull request #87 from jon-walton/windows-paths + +fix package paths on windows + +
+ +- 53a6e814 fix package paths on windows + +
546b7b76 Merge pull request #84 from yamitzky/master + +Fix collectFields to handle aliased fields properly + +
+ +- ba2ecb16 Add test case for aliased field + +- 78f3a56c Fix collectFields to handle aliased fields + +
4d2eece0 Merge pull request #77 from vektah/opentracing + +Add resolver middleware Add opentracing support + +
+ +- f0def668 better opentracing tags + +- 600bff7a bump metalinter deadline + +- 2e32c121 regenerate code + +- 5b908507 opentracing middleware + +- 57adb244 Add resolver middleware + +- 28d0c81f capture args in map + +
e266fab9 Merge pull request #75 from mathewbyrne/fix-import-dash + +Replace Invalid Characters in Package Name with an Underscore + +
+ +
b0d79115 Replace invalid package characters with an underscore + +This will sanatise local import names to a valid go identifier by +replacing any non-word characters with an underscore. + +
+ +
66a91503 Merge pull request #72 from vektah/custom-enum + +Add support for custom enums + +
+ +- 61a34a74 Add support for custom enums + +- 74ac827a move docs to new domain + +
ebcc94d1 Merge pull request #70 from vektah/models-in-separate-package + +Allow generated models to go into their own package + +
+ +- 9a532131 Allow generated models to go into their own package + +
6129fd26 Merge pull request #69 from vektah/support-options + +Support OPTIONS requests + +
+ +- af38cf05 Support OPTIONS requests + +
893ead12 Merge pull request #67 from vektah/raw-schema-string + +Use a raw string for schema + +
+ +- af6178a7 Use a raw string for schema + +
c0753bed Merge pull request #66 from vektah/generate-enums + +Generate enums + +
+ +- 85a51268 Generate enums + +
71c4e265 Merge pull request #65 from vektah/context + +Make field selections available in context + +
+ +- c60336bf regenerate + +- c5ccfe4e Add an example for getting the selection sets from ctx + +- e7007746 add fields to resolver context + +- 40918d52 move request scoped data into context + +
4e13262e Merge pull request #64 from vektah/vendor-gen-path + +Fix vendored import paths in generated models + +
+ +- 2ff9f32f Fix vendored import paths + +- 630a3cfc failing test + +- 99dec54c fix missing deps + +- 652c567e Remove missing field warning and add test for scalar resolvers (closes #63) + +- 3dc87e1b gtm + +- c76c3434 Add dataloader tutorial + +- 449fe8f8 Optimize frontmatter + +- b90ae60e flatten menus + +
a508ecb0 Merge pull request #45 from dvic/fix-resolver-public-errors + +Retain orignal resolver error and support overriding error message + +
+ +- ab4e7010 Retain orignal resolver error and support overriding error message (closes #38) + +
a05a18d5 Merge pull request #61 from vektah/import-resolver-collisions + +Deal with import collisions better + +
+ +- d81ea2c2 Deal with import collisions better + +
fb131a94 Merge pull request #59 from vektah/map-support + +Add map[string]interface{} escape hatch + +
+ +- 49d92164 Add map[string]interface{} escape hatch + +
5abdba16 Merge pull request #57 from vektah/null-input-fields + +Null input fields + +
+ +- f8add9d2 remove more unneeded whitespace + +- 84b06617 Allow nulls in input fields + +
54fbe16a Merge pull request #56 from vektah/getting-started-fixes + +Getting started fixes + +
+ +- 17fd17a4 Update the tutorial + +- e65d2a5a detect correct FK type + +- b66cfa03 small fixes to entry point + +- 0b62315a Create ISSUE_TEMPLATE.md + +
f3a70dac Merge pull request #55 from vektah/fix-input-ptr-unpacking + +Fix ptr unpacking in input fields + +
+ +- 10541f19 Fix ptr unpacking in input fields + +
15b3af2d Fix value receivers for unions too + +fixes 42 + +
+ +
46103bdc Merge pull request #53 from vektah/docs + +Docs + +
+ +- d0211a0a Custom scalar docs + +- e6ed4de5 Update readme link + +- 51f08a9e start of docs + +
ac832dea Merge pull request #51 from vektah/support-embedding + +Support embedding in models + +
+ +- 9d710712 add embedding support + +- 0980df0e Embedding example + +
cb34e6db Merge pull request #50 from vektah/valuer-receiver + +Don't generate value receivers for types that cant fit the interface + +
+ +- ec5f5e66 check for valuer receivers before generating type switch + +- dc898409 add test case + +
8ef253cb Merge pull request #49 from vektah/default-entrypoints + +default to Query / Mutation / Subscription if no entry points are specified + +
+ +- 302058a7 Use default entry points for Query/Mutation/Subscription + +
13949fdf Merge pull request #37 from vektah/generate-interfaces + +generate interfaces + +
+ +- acc45bf0 generate interfaces + +
e47d5038 Merge pull request #34 from vektah/root-types-only + +Only bind to types in the root package scope + +
+ +- ffe972a8 Only bind to types in the root package scope + +
0e78c0ae Merge pull request #33 from vektah/unset-arguments + +Allow unset arguments + +
+ +- bc9e0e54 Allow unset arguments + +
94718351 Merge pull request #31 from vektah/recover-handler + +Customizable recover func + +
+ +- e4e249ea Customizable recover func + +
69277045 Merge pull request #30 from vektah/complex-input-types + +Fix complex input types + +
+ +- 9b64dd22 Fix complex input types + +
1d074b89 Merge pull request #29 from vektah/multi-stage-model-build + +Split model generation into its own stage + +
+ +- cf580c24 Split model generation into its own stage + +
926384db Merge pull request #28 from vektah/default-args + +add default args + +
+ +- 68c54a14 add default args + +- d63128f6 appease the linting gods + +
7b6b124e Merge pull request #20 from vektah/codegen-cleanup + +Codegen cleanup + +
+ +- 78c34cb3 regenerate + +- 5ebd157c Only use one gofunc per subscription + +- 79a70376 Move generated field resolvers into separate methods + +
e676abe4 Merge pull request #19 from vektah/generate-input-types + +Generate input models too + +
+ +- f094e79c Generate input models too + +- 1634f088 Add a missed error check + +
4feb1689 Merge pull request #18 from vektah/array-input-args + +Fix input array processing + +
+ +- 98176297 Fix input array processing + +
4880497f Merge pull request #16 from vektah/better-templates + +Better templates + +
+ +- 278df9de Better templates + +
f3731c73 Merge pull request #14 from vektah/autogenerate-models + +Autogenerate models + +
+ +- cfe902a0 Autogenerate models + +- 287bf7f4 more docs + +
9d896f40 Merge pull request #13 from vektah/autocast + +Automatically add type conversions around wrapped types + +
+ +- 85fa63b9 Automatically add type conversions around wrapped types + +
c8c2e40f Merge pull request #11 from vektah/subscriptions + +Add support for subscriptions + +
+ +- d514b829 Add some go tests to the chat app + +- ec2916d9 chat example for subscriptions using CRA+apollo + +- 8f93bf8d get arg errors working in both contexts + +- 62a18ff1 Update generator to build a new ExecutableSchema interface + +- c082c3a4 prevent concurrent writes in subscriptions + +- f555aec6 switch to graphql playground for better subscription support + +- 18219541 add websocket support to the handler + +- d4c7f3b9 update resolver definition to use channels for subscriptions + +
d0244d24 Merge pull request #10 from vektah/newtypes + +User defined custom types + +
+ +- 5d86eeb6 fix jsonw test + +- 944ee088 regenerate + +- 4722a855 add scalar example + +- 83b001ae rename marshaler methods + +- e0b7c25f move collectFields out of generated code + +- 146c6538 generate input object unpackers + +- d94cfb1f allow primitive scalars to be redefined + +- 402e0730 rename jsonw to graphql + +- 3e7d80df Update README.md + +- 9c77e7a0 Update dataloaden dep + +- 530f7895 Make gql client work with older versions of mapstructure + +- 5c04d1ad __typename support + +
51292db9 Merge pull request [#4](https://github.com/99designs/gqlgen/issues/4) from vektah/cleanup-type-binding + +Cleanup schema binding code + +
+ +- c89a8774 Cleanup schema binding code + +
030954a5 Merge pull request [#2](https://github.com/99designs/gqlgen/issues/2) from ulrikstrid/patch-1 + +Fix typo in README + +
+ +- cb507bd0 Fix typo in README + +- e3167785 Fix template loading from inside vendor + +- 261b52ce fix an error handling bug + +- 1da57f59 Split starwars models out from resolvers + +- 743b2cf9 fix indenting + +- fb2d5817 use gorunpkg to vendor go generate binaries + +- 7f4d0405 encourage dep use + +- 3276c782 Do not bind to unexported vars or methods + +- 5fabffaf heading tweaks + +- e032c1d5 Prior art + +- 45b79a1e Add a test for multidimensional arrays + +- ec73a50a fix race + +- 75a3a05c Dont execute mutations concurrently + +- 3900a41d tidy up json writing + +- 0dcf7f6b add circle ci badge + +- 2c9bf21c get dataloaden + +- 4fff3241 install dataloaden in ci + +- 951f41b2 circle ci + +- 8fa5f628 less whitespace + +- c76f3b98 clean up template layout + +- 4a6cea5e readme fixes + +- b814ad52 rename repo + +- 9c79a37a Cleanup and add tests + +- 5afb5caa update dataloaden + +- d00fae08 Add dataloader example + +- 86cdf3a0 Fix package resolution + +- 41306cba Better readme + +- ce5e38ed Add GET query param support to handler + +- dd9a8e4d parallel execution + +- 4468127e pointer juggling + +- 9e99c149 Use go templates to generate code + +- 41f74970 Support go versions earlier than 1.9 + +- c20ef3d0 add missing nulls + +- bb753776 Use goimports instead of gofmt on generated code + +- c2cf3835 coerce types between similar types + +- 5297dd40 Add support for RFC3339 formatted Time as time.Time + +- 61291ce9 support vendor + +- 6d437d7e allow map[string]interface{} arg types + +- 39a8090a cleanup + +- a9352e32 gometalinter pass + +- 9ab81d67 Finish fleshing out the connection example + +- e04b1e50 inline supporting runtime funcs + +- 9cedf012 complex arg handling + +- 0c9c009f Clean up json writer + +- e7e18c40 much cleaner generated code + +- 6a76bbf6 Interfaces and starwars example + +- 29110e76 Generate ESS to remove it interface{} casts completly + +- 2f358e7d graphiql autocomplete working + +- 2e2c3135 create separate type objects in prep for fragment support + +- 22c0ad0a Add basic introspection support + +- c1c2cb64 Code generation + +- 4be5ac84 args + +- bde800e1 imports + +- 596554da start of code generator + +- 62fa8184 split generated vs exec code + +- 0ea104cd remove internal package + +- f81371e8 Args + +- 01896b3b Hand written codegen example + +- 5a756bda Rewrite paths and add readme + +
b4663703 trace: Log graphql.variables rather than tag + +According to the OT documentation tag values can be numeric types, strings, or +bools. The behavior of other tag value types is undefined at the OpenTracing +level. For example `github.com/lightstep/lightstep-tracer-go` generates error +events. + +
+ +- 5d3b13f2 Support context injection in testing + +
beff0841 Separate literal arg parsing cases (int, float) + +This change allows the ID scalar implementation to more semantically +handle the case for unmarshalling integer IDs. + +
+ +
ab1dd4b5 Add tests for ID scalar input + +This commit adds two tests cases for ID scalar input: +- a string literal +- an integer literal + +Both of these literal types are covered by the GraphQL specification as +valid input for the ID scalar. + +Reference the ID section of the spec for more information: +http://facebook.github.io/graphql/October2016/#sec-ID + +
+ +
d8c57437 Extract ID scalar implmentation + +This change moves the ID scalar implementation out of `graphql.go` and +into its own file `id.go` for consistency with the Time scalar +implementation. + +
+ +- 10eb949b cleaned up example to use MustParseSchema + +
52080e1f Rename friendsConenctionArgs to friendsConnectionArgs + +Fix spelling error in friendsConnectionArgs type + +
+ +- 3965041f Update GraphiQL interface (add history) + +
6b9bc3e2 Add `(*Schema).Validate` (#99) + +* Add `(*Schema).Validate` + +This adds a `Validate` method to the schema, which allows you to find out if a query is valid without actually running it. This is valuable when you have a client with static queries and want to statically determine whether they are valid. + +* Fix Validate doc string + +
+ +- 7f3f7120 Set content-type header to `application/json` + +- c76ff4d8 moved packer into separate package + +- 073edccd updated tests from graphql-js + +- 3a9ac368 validation: improved overlap check + +- f86c8b01 allow multiple schemas in tests + +- 77750960 validation: OverlappingFieldsCanBeMerged + +- e7ca4fde refactor: remove SelectionSet type + +- 7aad6ba7 refactor: use schema.NamedType + +- fddcbcb7 resolves #92: fix processing of negative scalars during parse literals + +- 48c1a0fb Small fix based on feedback. + +- e90d1089 allow custom types as input arguments + +- dd3d39e2 fix panic when variable name not declared + +- c2bc105f validation: NoUnusedVariables + +- 4aff2976 refactor + +- 0933d241 validation: VariablesInAllowedPosition + +- 83e2f31a validation: NoUndefinedVariables + +- c39ffeca validation: PossibleFragmentSpreads + +- 47c5cde7 validation: UniqueInputFieldNames + +- 94cb2918 big refactoring around literals + +- 3d63ae80 some refactoring + +- 969dab9d merged lexer into package "common" + +- a9de6171 renamed lexer.Literal to lexer.BasicLit + +- 88c492bb validation: NoFragmentCycles (closes #38) + +- d39712c8 refactor addErrMultiLoc + +- ee5e1c3b validation: updated tests + +- 490ad6b2 validation: NoUnusedFragments + +- da85f09d add path to errors on resolver error or panic (closes #86) + +- 04cb2550 allow structs without pointers (closes #78) + +- 4c40b305 show all locations in error string + +- 5c26f320 fix limiter + +- dbc3f0a0 fix composing of fragments (closes #75) + +
213a5d01 Warn if an interface's resolver has a ToTYPE implementation that does not return two values. + +Currently this instead crashes fairly inscrutably at runtime here: https://github.com/neelance/graphql-go/blob/master/internal/exec/exec.go#L117 + +An alternate fix would be to check len(out) there and perhaps rely on out[0] being nil to continue if there's only one return value. + +
+ +- 00c4c574 Fix panic when resolver is not a pointer + +- d0df6d8a small cleanup + +- 036945e2 fix hang on panic (fixes #82) + +- 01ab5128 Add supports for snake case (#77) + +
67e6f91d use encoding/json to encode scalars + +There are some edge cases that are better handled by the proven encoder of encoding/json, for example special characters in strings. + +
+ +- 3f1cb6f8 implement user defined logger (with sensible defaults) + +- b357f464 built-in json encoding + +- 2d828770 refactor: collect fields to resolve + +- 32f8b6ba refactor: replaced MetaField + +- b95c566e simplify schema introspection + +- 4200a584 split internal/exec into multiple packages + +- c11687a7 refactored internal/exec + +- bd742d84 WIP + +- d09dd543 added SchemaOpt + +- 1dcc5753 fix Schema.ToJSON + +- 4f07e397 pass variable types to tracer + +- 36e6c97e readme: remove outdated section about opentracing + +- 0b143cca refactor: apply before exec + +
a9920602 pluggable tracer + +Improved performance while keeping flexibility. + +
+ +- 58d3d5b8 refactored exec.Request + +- 9dd714ec refactored execField some more + +- a43ef241 refactor: meta fields + +- 48931d17 refactor fieldExec + +- ee95710d small cleanup + +- 84baade5 perf: create span label only once + +- a16ed600 improved concurrency architecture + +
aef3d9cf Add testing.go into its own package (gqltesting) + +This is done so that "testing" (and especially its registered cli flags) +aren't included in any production builds. + +
+ +- f78108a3 validation: meta fields + +- c6ab2374 added empty file to make CI happy + +- d59c1709 fix introspection of default value + +- 42608a03 clean up now unnecessary check + +- e45f26dd validation: UniqueDirectivesPerLocation + +- dcf7e59f validation: UniqueFragmentNames + +- eeaa510b validation: UniqueOperationNames + +- a5a11604 refactor: Loc on Field + +- b5919db4 validation: UniqueVariableNames + +- 8632753a validation: ScalarLeafs + +- 45844984 validation: ProvidedNonNullArguments + +- c741ea84 validation: VariablesAreInputTypes + +- 0875d74f validation: UniqueArgumentNames + +- 1fdab07f validation: LoneAnonymousOperation + +- 090df527 validation: KnownTypeNames + +- f99ca95e refactor: validation context + +- 8aac2817 validation: KnownFragmentNames + +- eae3efc9 validation: KnownDirectives + +- 70581168 refactor: separate InlineFragment and FragmentSpread + +- d6aec0d6 renamed schema.Directive to DirectiveDecl + +- b616eeca validation: KnownArgumentNames + +- 885af607 refactor: Location without pointer + +- 5a40251c tests: filter errors to currently tested rule + +- 9c054f53 refactor: lexer.Ident + +- 254afa8a validation: fragment type + +- b6ef81af added test export script + +- 95a4ecd8 validation: fields + +- c387449f validation: default values + +- 44c6e634 validation: arguments + +- 30dcc339 directive arguments as slice + +- d331ac27 input values as slice + +- 615afd61 fields as slice + +- 60759904 arguments as slice + +- f7d9ff4e refactor literals + +- 2e1fef01 keep track of location of arguments + +- 29e0b375 added EnumValue type + +- aa868e8d resolve fragments early + +- adeb53d6 remove resolver from query package + +- 2e23573f parse directive decl without arguments + +- 36f8ba8b fix introspection of default value (closes #65) + +- e06f5855 support for "deprecated" directive on enum values + +- 498fe396 support for @deprecated](https://github.com/deprecated) directive on fields (fixes [#64) + +- 93ddece9 refactor: DirectiveArgs + +- 8f5605a1 refactor directives + +- faf5384a simplify parseArguments + +- b2c2e906 some more docs + +- f4516523 added some method documentations + +- 91bd7f88 improved meta schema + +- 10dc8ee6 added support for directive declarations in schema + +- 28028f66 readme: more info on current project status + +- e9afca38 hint in error if method only exists on pointer type (fixes #60) + +- 356ebd93 nicer error messages (fixes #56) + +- e413f4ed make gocyclo happy + +- 6e92795e fix spelling + +- 306e27ef gofmt -s + +- 612317b2 fix ToJSON + +- 728e57a9 improved doc for MaxParallelism + +- e8590a10 don't execute any further resolvers after context got cancelled + +- 644435cc added MaxParallelism + +- 21802a33 readme: add Sourcegraph badge + +- 5b2978fc added support for recursive input values + +- 8c84afb1 improved structure of "make exec" code + +- d5a6ca49 make sure internal types don't get exposed + +- c9d4d865 fixed some null handling + +- a336dd4b added request.resolveVar + +- 943f80f4 added unmarshalerPacker type + +- f77f7339 refactored non-null handling in packer + +- ae0f1689 remove hasDefault flag from makePacker + +- 9cbad485 allow Unmarshaler for all types, not just scalars + +- f565a119 refactored "make exec" code + +- 07a09e5d properly check scalar types of result values + +- ecceddec Add ResolverError field to QueryError for post processing + +- b7c59ab9 renamed type + +- 5817d300 moved some introspection code into new package, added Schema.Introspect + +
cdef8563 removed SchemaBuilder + +It is not necessary any more. Simpler API wins. + +
+ +
518a5fe7 Merge pull request #45 from nicksrandall/master + +fix wrong import statement + +
+ +- 8112e719 fix wrong import statement + +- 7fafcc6e allow single value as implicit list (fixes #41) + +- 2b513d7e improved custom types + +- 191422c4 merged code for value coercion and packing + +- 232356b3 introspection for "skip" and "include" directives (fixes #30) + +- 2e10f7b8 readme: spec version and link (fixes #35) + +- 61eca4c7 pretty print SchemaBuilder.ToJSON + +- 5e09ced1 fix "null" value for empty descriptions of types + +- 33cd194f SchemaBuilder.ToJSON instead of SchemaToJSON (fixes #29) + +- fff173bc proper error message when using non-input type as input (#19) + +- b94f2afe improved support for null + +- 4130d540 added support for input object literals + +- 663e466f moved some code into separate file + +- 728e071e added support for lists as input values (fixes #19) + +- 86f0f145 fix Float literals + +- b07f277b raise error on unexported input field (fixes #24) + +- 4838c6f3 fix optional input fields (fixes #25) + +- a15deed4 better way to implement GraphQL interfaces (#23) + +- 7a66d0e0 add support for description comments (fixes #20) + +- 0b3be40c improved tracing + +- da879f4f small improvements to readme + +- f3f24cf6 added some documentation + +- 38598d83 added CI badge to readme + +- bab81332 starwars example: fix pagination panic (#12) + +- 5ce3ca69 testing: proper error on invalid ExpectedResult + +- 8f7d2b1e added relay.Handler + +- fce75a50 properly coerce Int input values ([#8](https://github.com/99designs/gqlgen/issues/8)) + +- 0dd38747 star wars example: pass operation name and variables ([#8](https://github.com/99designs/gqlgen/issues/8)) + +- 3b7efd5c fix __typename for concrete object types (fixes [#9](https://github.com/99designs/gqlgen/issues/9)) + +- 35667eda testing tools + +- 84571820 only create schema once for tests + +- de113f96 added MustParseSchema + +- d5e5f609 improved structure for tests + +- 947a1a3a added package with tools for Relay + +- 65f3e2b1 fix SchemaToJSON + +- cec7cea1 better error handling + +- e3386b06 improved type coercion and explicit ID type + +- 2ab9d765 support for custom scalars (fixes [#3](https://github.com/99designs/gqlgen/issues/3)) + +- bdfd5ce3 use custom error type less + +- 0a7a37d1 more flexible API for creating a schema + +- bd20a165 improved type handling + +- ffa9fea4 renamed GraphQLError to QueryError + +- fcfa135a refactor + +- c28891d8 added support for OpenTracing + +- 2cf7fcc8 added SchemaToJSON + +- f6b498ac stricter type mapping for input values + +- 3c15e177 execute mutations serially + +- 1faf6661 fix missing error + +- de9b7fed add support for mutations + +- 094061d8 improved error handling a bit + +- cdb088d6 refactor: args as input object + +- b06d3941 refactor: values + +- 4fd33958 refactor: improved type system + +
1d03e667 refactor: new package "common" + +package "query" does not depend on "schema" any more + +
+ +- 1a959516 refactor + +- f8cb11c1 example/starwars: use interface base type to make type assertions nicer + +- 746da4b8 star wars example: friendsConnection + +- bec45364 parse type in query + +- be87a8fa remove unused code + +- 042e306a simpler way to resolve type refs in schema + +- 7cbf85fb improved type checking of arguments + +- 2b6460ae type check for scalars + +- 17034fe7 improved null handling + +- e6b6fbca small cleanup + +- 7b8cd1bc meta schema from graphql-js + +- 9333c0b3 introspection: inputFields + +- c4faac56 introspection: ofType + +- 86da8492 introspection: interfaces and possibleTypes + +- 20dbb845 proper nil support for lists + +- 2e3369ae resolve types in schema package + +- 7da95f4a introspection: enum values + +- cb423e6e improved handling of scalar types + +- 5b07780f introspection: original order for fields and args + +- 1e2d180c introspection: arguments + +- f21131bb refactored schema to be more in line with introspection + +- 0152d4f2 introspection: currently no descriptions and deprecations + +- ad5689bb field introspection + +- 2749d814 removed query.TypeReference + +
2eb105ec Revert "resolve scalar types in exec" + +This reverts commit fb3a6fc969b0c8c286c7d024a108f5696627639c. + +
+ +- 40682d68 removed exec.typeRefExec + +- 64ea90fe makeWithType + +- 2966f213 added nonNilExec + +- c12a8ad3 added support for ints and floats in query + +- 0f85412b improved example + +- 22ce46d1 support for optional error result + +- 0fe56128 optional context parameter + +- f1bc9b21 syntax errors with proper line and column + +- ae299efc proper response format + +- 9619721b added support for contexts + +- 267fc631 refactor + +- 2e56e7ea renamed NewSchema to ParseSchema + +- 356b6e6b added godoc badge + +- 03f2e72d added README.md + +- 1134562a added non-null type + +- 8fa41551 renamed Input to InputObject + +- 6f2399aa introspection: type kind + +- e2c58f2f refactor: schema types for interface and input + +- 0c8c9436 introspection: __type + +- 99a37521 refactoring: calculate "implemented by" in schema package + +- 1cac7e56 introspection: queryType + +- cc348faf first bit of introspection + +- fb3a6fc9 resolve scalar types in exec + +- 4cb8dcc0 panic handlers + +- c7a528d4 proper error handling when creating schema + +- ae37381c add support for __typename + +- 4057080f add support for union types + +- d304a418 attribute source of star wars schema + +- 0fcab871 added LICENSE + +- 0dc0116d support for inline fragments + +- f5e7d070 support for type assertions + +- fcb853c6 refactoring: addResultFn + +- 741343f8 explicit fragment spread exec + +- 73759258 all missing stubs for star wars example + +- edc78e2b parallelism + +- fb633714 collect fields + +- 08f02a2b execs + +- d70d16c4 added server example + +- 6f9a89db separate example/starwars package + +- e4060db5 added support for directives + +- 89b06652 added support for variables + +- 78065ecb added support for enums + +- 18645e60 added support for query fragments + +- 84f532b9 added support for aliases + +- 59d2a619 improved support for arguments + +- edce4ec8 proper star wars data + +- d6ffc01d syntax support for full star wars schema + +- b5824104 support for comments + +- 2f9ce9b4 support for entry points + +- 0b3d1038 support for arguments + +- cff8b302 support for arrays + +- 565e59f5 schema package + +- 1ae71ba2 query package + +- 42c13e7a named types, complex objects + +- bf64e5da initial commit + + + + + + + diff --git a/vendor/github.com/99designs/gqlgen/CONTRIBUTING.md b/vendor/github.com/99designs/gqlgen/CONTRIBUTING.md new file mode 100644 index 0000000..3919b2a --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/CONTRIBUTING.md @@ -0,0 +1,27 @@ +# Contribution Guidelines + +Want to contribute to gqlgen? Here are some guidelines for how we accept help. + +## Getting in Touch + +Our [discord](https://discord.gg/DYEq3EMs4U) server is the best place to ask questions or get advice on using gqlgen. + +## Reporting Bugs and Issues + + We use [GitHub Issues](https://github.com/99designs/gqlgen/issues) to track bugs, so please do a search before submitting to ensure your problem isn't already tracked. + +### New Issues + +Please provide the expected and observed behaviours in your issue. A minimal GraphQL schema or configuration file should be provided where appropriate. + +## Proposing a Change + +If you intend to implement a feature for gqlgen, or make a non-trivial change to the current implementation, we recommend [first filing an issue](https://github.com/99designs/gqlgen/issues/new) marked with the `proposal` tag, so that the engineering team can provide guidance and feedback on the direction of an implementation. This also help ensure that other people aren't also working on the same thing. + +Bug fixes are welcome and should come with appropriate test coverage. + +New features should be made against the `next` branch. + +### License + +By contributing to gqlgen, you agree that your contributions will be licensed under its MIT license. diff --git a/vendor/github.com/99designs/gqlgen/LICENSE b/vendor/github.com/99designs/gqlgen/LICENSE new file mode 100644 index 0000000..10bb21c --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2020 gqlgen authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/99designs/gqlgen/README.md b/vendor/github.com/99designs/gqlgen/README.md new file mode 100644 index 0000000..fc039f8 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/README.md @@ -0,0 +1,150 @@ +![gqlgen](https://user-images.githubusercontent.com/980499/133180111-d064b38c-6eb9-444b-a60f-7005a6e68222.png) + + +# gqlgen [![Integration](https://github.com/99designs/gqlgen/actions/workflows/integration.yml/badge.svg)](https://github.com/99designs/gqlgen/actions) [![Coverage Status](https://coveralls.io/repos/github/99designs/gqlgen/badge.svg?branch=master)](https://coveralls.io/github/99designs/gqlgen?branch=master) [![Go Report Card](https://goreportcard.com/badge/github.com/99designs/gqlgen)](https://goreportcard.com/report/github.com/99designs/gqlgen) [![Go Reference](https://pkg.go.dev/badge/github.com/99designs/gqlgen.svg)](https://pkg.go.dev/github.com/99designs/gqlgen) [![Read the Docs](https://badgen.net/badge/docs/available/green)](http://gqlgen.com/) + +## What is gqlgen? + +[gqlgen](https://github.com/99designs/gqlgen) is a Go library for building GraphQL servers without any fuss.
+ +- **gqlgen is based on a Schema first approach** — You get to Define your API using the GraphQL [Schema Definition Language](http://graphql.org/learn/schema/). +- **gqlgen prioritizes Type safety** — You should never see `map[string]interface{}` here. +- **gqlgen enables Codegen** — We generate the boring bits, so you can focus on building your app quickly. + +Still not convinced enough to use **gqlgen**? Compare **gqlgen** with other Go graphql [implementations](https://gqlgen.com/feature-comparison/) + +## Quick start +1. [Initialise a new go module](https://golang.org/doc/tutorial/create-module) + + mkdir example + cd example + go mod init example + +2. Add `github.com/99designs/gqlgen` to your [project's tools.go](https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module) + + printf '// +build tools\npackage tools\nimport _ "github.com/99designs/gqlgen"' | gofmt > tools.go + go mod tidy + +3. Initialise gqlgen config and generate models + + go run github.com/99designs/gqlgen init + +4. Start the graphql server + + go run server.go + +More help to get started: + - [Getting started tutorial](https://gqlgen.com/getting-started/) - a comprehensive guide to help you get started + - [Real-world examples](https://github.com/99designs/gqlgen/tree/master/example) show how to create GraphQL applications + - [Reference docs](https://pkg.go.dev/github.com/99designs/gqlgen) for the APIs + +## Reporting Issues + +If you think you've found a bug, or something isn't behaving the way you think it should, please raise an [issue](https://github.com/99designs/gqlgen/issues) on GitHub. + +## Contributing + +We welcome contributions, Read our [Contribution Guidelines](https://github.com/99designs/gqlgen/blob/master/CONTRIBUTING.md) to learn more about contributing to **gqlgen** +## Frequently asked questions + +### How do I prevent fetching child objects that might not be used? + +When you have nested or recursive schema like this: + +```graphql +type User { + id: ID! + name: String! + friends: [User!]! +} +``` + +You need to tell gqlgen that it should only fetch friends if the user requested it. There are two ways to do this; + +- #### Using Custom Models + +Write a custom model that omits the friends field: + +```go +type User struct { + ID int + Name string +} +``` + +And reference the model in `gqlgen.yml`: + +```yaml +# gqlgen.yml +models: + User: + model: github.com/you/pkg/model.User # go import path to the User struct above +``` + +- #### Using Explicit Resolvers + +If you want to Keep using the generated model, mark the field as requiring a resolver explicitly in `gqlgen.yml` like this: + +```yaml +# gqlgen.yml +models: + User: + fields: + friends: + resolver: true # force a resolver to be generated +``` + +After doing either of the above and running generate we will need to provide a resolver for friends: + +```go +func (r *userResolver) Friends(ctx context.Context, obj *User) ([]*User, error) { + // select * from user where friendid = obj.ID + return friends, nil +} +``` + +You can also use inline config with directives to achieve the same result + +```graphql +directive @goModel(model: String, models: [String!]) on OBJECT + | INPUT_OBJECT + | SCALAR + | ENUM + | INTERFACE + | UNION + +directive @goField(forceResolver: Boolean, name: String) on INPUT_FIELD_DEFINITION + | FIELD_DEFINITION + +type User @goModel(model: "github.com/you/pkg/model.User") { + id: ID! @goField(name: "todoId") + friends: [User!]! @goField(forceResolver: true) +} +``` + +### Can I change the type of the ID from type String to Type Int? + +Yes! You can by remapping it in config as seen below: + +```yaml +models: + ID: # The GraphQL type ID is backed by + model: + - github.com/99designs/gqlgen/graphql.IntID # An go integer + - github.com/99designs/gqlgen/graphql.ID # or a go string +``` + +This means gqlgen will be able to automatically bind to strings or ints for models you have written yourself, but the +first model in this list is used as the default type and it will always be used when: + +- Generating models based on schema +- As arguments in resolvers + +There isn't any way around this, gqlgen has no way to know what you want in a given context. + +## Other Resources + +- [Christopher Biscardi @ Gophercon UK 2018](https://youtu.be/FdURVezcdcw) +- [Introducing gqlgen: a GraphQL Server Generator for Go](https://99designs.com.au/blog/engineering/gqlgen-a-graphql-server-generator-for-go/) +- [Dive into GraphQL by Iván Corrales Solera](https://medium.com/@ivan.corrales.solera/dive-into-graphql-9bfedf22e1a) +- [Sample Project built on gqlgen with Postgres by Oleg Shalygin](https://github.com/oshalygin/gqlgen-pg-todo-example) diff --git a/vendor/github.com/99designs/gqlgen/TESTING.md b/vendor/github.com/99designs/gqlgen/TESTING.md new file mode 100644 index 0000000..72ba060 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/TESTING.md @@ -0,0 +1,40 @@ +How to write tests for gqlgen +=== + +Testing generated code is a little tricky, heres how its currently set up. + +### Testing responses from a server + +There is a server in `codegen/testserver` that is generated as part +of `go generate ./...`, and tests written against it. + +There are also a bunch of tests in against the examples, feel free to take examples from there. + + +### Testing the errors generated by the binary + +These tests are **really** slow, because they need to run the whole codegen step. Use them very sparingly. If you can, find a way to unit test it instead. + +Take a look at `codegen/testserver/input_test.go` for an example. + +### Testing introspection + +Introspection is tested by diffing the output of `graphql get-schema` against an expected output. + +Setting up the integration environment is a little tricky: +```bash +cd integration +go generate ./... +go run ./server/server.go +``` +in another terminal +```bash +cd integration +npm install +SERVER_URL=http://localhost:8080/query ./node_modules/.bin/graphql get-schema +``` + +will write the schema to `integration/schema-fetched.graphql`, compare that with `schema-expected.graphql` + +CI will run this and fail the build if the two files dont match. + diff --git a/vendor/github.com/99designs/gqlgen/api/generate.go b/vendor/github.com/99designs/gqlgen/api/generate.go new file mode 100644 index 0000000..6a85cd9 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/api/generate.go @@ -0,0 +1,125 @@ +package api + +import ( + "fmt" + "syscall" + + "github.com/99designs/gqlgen/codegen" + "github.com/99designs/gqlgen/codegen/config" + "github.com/99designs/gqlgen/plugin" + "github.com/99designs/gqlgen/plugin/federation" + "github.com/99designs/gqlgen/plugin/modelgen" + "github.com/99designs/gqlgen/plugin/resolvergen" +) + +func Generate(cfg *config.Config, option ...Option) error { + _ = syscall.Unlink(cfg.Exec.Filename) + if cfg.Model.IsDefined() { + _ = syscall.Unlink(cfg.Model.Filename) + } + + plugins := []plugin.Plugin{} + if cfg.Model.IsDefined() { + plugins = append(plugins, modelgen.New()) + } + plugins = append(plugins, resolvergen.New()) + if cfg.Federation.IsDefined() { + plugins = append([]plugin.Plugin{federation.New()}, plugins...) + } + + for _, o := range option { + o(cfg, &plugins) + } + + for _, p := range plugins { + if inj, ok := p.(plugin.EarlySourceInjector); ok { + if s := inj.InjectSourceEarly(); s != nil { + cfg.Sources = append(cfg.Sources, s) + } + } + } + + if err := cfg.LoadSchema(); err != nil { + return fmt.Errorf("failed to load schema: %w", err) + } + + for _, p := range plugins { + if inj, ok := p.(plugin.LateSourceInjector); ok { + if s := inj.InjectSourceLate(cfg.Schema); s != nil { + cfg.Sources = append(cfg.Sources, s) + } + } + } + + // LoadSchema again now we have everything + if err := cfg.LoadSchema(); err != nil { + return fmt.Errorf("failed to load schema: %w", err) + } + + if err := cfg.Init(); err != nil { + return fmt.Errorf("generating core failed: %w", err) + } + + for _, p := range plugins { + if mut, ok := p.(plugin.ConfigMutator); ok { + err := mut.MutateConfig(cfg) + if err != nil { + return fmt.Errorf("%s: %w", p.Name(), err) + } + } + } + // Merge again now that the generated models have been injected into the typemap + data, err := codegen.BuildData(cfg) + if err != nil { + return fmt.Errorf("merging type systems failed: %w", err) + } + + if err = codegen.GenerateCode(data); err != nil { + return fmt.Errorf("generating core failed: %w", err) + } + + if !cfg.SkipModTidy { + if err = cfg.Packages.ModTidy(); err != nil { + return fmt.Errorf("tidy failed: %w", err) + } + } + + for _, p := range plugins { + if mut, ok := p.(plugin.CodeGenerator); ok { + err := mut.GenerateCode(data) + if err != nil { + return fmt.Errorf("%s: %w", p.Name(), err) + } + } + } + + if err = codegen.GenerateCode(data); err != nil { + return fmt.Errorf("generating core failed: %w", err) + } + + if !cfg.SkipValidation { + if err := validate(cfg); err != nil { + return fmt.Errorf("validation failed: %w", err) + } + } + + return nil +} + +func validate(cfg *config.Config) error { + roots := []string{cfg.Exec.ImportPath()} + if cfg.Model.IsDefined() { + roots = append(roots, cfg.Model.ImportPath()) + } + + if cfg.Resolver.IsDefined() { + roots = append(roots, cfg.Resolver.ImportPath()) + } + + cfg.Packages.LoadAll(roots...) + errs := cfg.Packages.Errors() + if len(errs) > 0 { + return errs + } + return nil +} diff --git a/vendor/github.com/99designs/gqlgen/api/option.go b/vendor/github.com/99designs/gqlgen/api/option.go new file mode 100644 index 0000000..e1a750f --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/api/option.go @@ -0,0 +1,40 @@ +package api + +import ( + "github.com/99designs/gqlgen/codegen/config" + "github.com/99designs/gqlgen/plugin" +) + +type Option func(cfg *config.Config, plugins *[]plugin.Plugin) + +func NoPlugins() Option { + return func(cfg *config.Config, plugins *[]plugin.Plugin) { + *plugins = nil + } +} + +func AddPlugin(p plugin.Plugin) Option { + return func(cfg *config.Config, plugins *[]plugin.Plugin) { + *plugins = append([]plugin.Plugin{p}, *plugins...) + } +} + +// ReplacePlugin replaces any existing plugin with a matching plugin name +func ReplacePlugin(p plugin.Plugin) Option { + return func(cfg *config.Config, plugins *[]plugin.Plugin) { + if plugins != nil { + found := false + ps := *plugins + for i, o := range ps { + if p.Name() == o.Name() { + ps[i] = p + found = true + } + } + if !found { + ps = append(ps, p) + } + *plugins = ps + } + } +} diff --git a/vendor/github.com/99designs/gqlgen/cmd/ambient.go b/vendor/github.com/99designs/gqlgen/cmd/ambient.go new file mode 100644 index 0000000..0f3655d --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/cmd/ambient.go @@ -0,0 +1,10 @@ +package cmd + +import ( + // Import and ignore the ambient imports listed below so dependency managers + // don't prune unused code for us. Both lists should be kept in sync. + _ "github.com/99designs/gqlgen/graphql" + _ "github.com/99designs/gqlgen/graphql/introspection" + _ "github.com/vektah/gqlparser/v2" + _ "github.com/vektah/gqlparser/v2/ast" +) diff --git a/vendor/github.com/99designs/gqlgen/cmd/gen.go b/vendor/github.com/99designs/gqlgen/cmd/gen.go new file mode 100644 index 0000000..f973cc2 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/cmd/gen.go @@ -0,0 +1,43 @@ +package cmd + +import ( + "errors" + "io/fs" + + "github.com/99designs/gqlgen/api" + "github.com/99designs/gqlgen/codegen/config" + "github.com/urfave/cli/v2" +) + +var genCmd = &cli.Command{ + Name: "generate", + Usage: "generate a graphql server based on schema", + Flags: []cli.Flag{ + &cli.BoolFlag{Name: "verbose, v", Usage: "show logs"}, + &cli.StringFlag{Name: "config, c", Usage: "the config filename"}, + }, + Action: func(ctx *cli.Context) error { + var cfg *config.Config + var err error + if configFilename := ctx.String("config"); configFilename != "" { + cfg, err = config.LoadConfig(configFilename) + if err != nil { + return err + } + } else { + cfg, err = config.LoadConfigFromDefaultLocations() + if errors.Is(err, fs.ErrNotExist) { + cfg, err = config.LoadDefaultConfig() + } + + if err != nil { + return err + } + } + + if err = api.Generate(cfg); err != nil { + return err + } + return nil + }, +} diff --git a/vendor/github.com/99designs/gqlgen/cmd/init.go b/vendor/github.com/99designs/gqlgen/cmd/init.go new file mode 100644 index 0000000..34576d4 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/cmd/init.go @@ -0,0 +1,198 @@ +package cmd + +import ( + "bytes" + "errors" + "fmt" + "html/template" + "io/fs" + "io/ioutil" + "os" + "path/filepath" + + "github.com/99designs/gqlgen/api" + "github.com/99designs/gqlgen/codegen/config" + "github.com/99designs/gqlgen/internal/code" + "github.com/99designs/gqlgen/plugin/servergen" + "github.com/urfave/cli/v2" +) + +var configTemplate = template.Must(template.New("name").Parse( + `# Where are all the schema files located? globs are supported eg src/**/*.graphqls +schema: + - graph/*.graphqls + +# Where should the generated server code go? +exec: + filename: graph/generated/generated.go + package: generated + +# Uncomment to enable federation +# federation: +# filename: graph/generated/federation.go +# package: generated + +# Where should any generated models go? +model: + filename: graph/model/models_gen.go + package: model + +# Where should the resolver implementations go? +resolver: + layout: follow-schema + dir: graph + package: graph + +# Optional: turn on use ` + "`" + `gqlgen:"fieldName"` + "`" + ` tags in your models +# struct_tag: json + +# Optional: turn on to use []Thing instead of []*Thing +# omit_slice_element_pointers: false + +# Optional: set to speed up generation time by not performing a final validation pass. +# skip_validation: true + +# gqlgen will search for any type names in the schema in these go packages +# if they match it will use them, otherwise it will generate them. +autobind: + - "{{.}}/graph/model" + +# This section declares type mapping between the GraphQL and go type systems +# +# The first line in each type will be used as defaults for resolver arguments and +# modelgen, the others will be allowed when binding to fields. Configure them to +# your liking +models: + ID: + model: + - github.com/99designs/gqlgen/graphql.ID + - github.com/99designs/gqlgen/graphql.Int + - github.com/99designs/gqlgen/graphql.Int64 + - github.com/99designs/gqlgen/graphql.Int32 + Int: + model: + - github.com/99designs/gqlgen/graphql.Int + - github.com/99designs/gqlgen/graphql.Int64 + - github.com/99designs/gqlgen/graphql.Int32 +`)) + +var schemaDefault = `# GraphQL schema example +# +# https://gqlgen.com/getting-started/ + +type Todo { + id: ID! + text: String! + done: Boolean! + user: User! +} + +type User { + id: ID! + name: String! +} + +type Query { + todos: [Todo!]! +} + +input NewTodo { + text: String! + userId: String! +} + +type Mutation { + createTodo(input: NewTodo!): Todo! +} +` + +var initCmd = &cli.Command{ + Name: "init", + Usage: "create a new gqlgen project", + Flags: []cli.Flag{ + &cli.BoolFlag{Name: "verbose, v", Usage: "show logs"}, + &cli.StringFlag{Name: "config, c", Usage: "the config filename", Value: "gqlgen.yml"}, + &cli.StringFlag{Name: "server", Usage: "where to write the server stub to", Value: "server.go"}, + &cli.StringFlag{Name: "schema", Usage: "where to write the schema stub to", Value: "graph/schema.graphqls"}, + }, + Action: func(ctx *cli.Context) error { + configFilename := ctx.String("config") + serverFilename := ctx.String("server") + schemaFilename := ctx.String("schema") + + pkgName := code.ImportPathForDir(".") + if pkgName == "" { + return fmt.Errorf("unable to determine import path for current directory, you probably need to run go mod init first") + } + + // check schema and config don't already exist + for _, filename := range []string{configFilename, schemaFilename, serverFilename} { + if fileExists(filename) { + return fmt.Errorf("%s already exists", filename) + } + } + _, err := config.LoadConfigFromDefaultLocations() + if err == nil { + return fmt.Errorf("gqlgen.yml already exists in a parent directory\n") + } + + // create config + fmt.Println("Creating", configFilename) + if err := initFile(configFilename, executeConfigTemplate(pkgName)); err != nil { + return err + } + + // create schema + fmt.Println("Creating", schemaFilename) + if err := initFile(schemaFilename, schemaDefault); err != nil { + return err + } + + // create the package directory with a temporary file so that go recognises it as a package + // and autobinding doesn't error out + tmpPackageNameFile := "graph/model/_tmp_gqlgen_init.go" + if err := initFile(tmpPackageNameFile, "package model"); err != nil { + return err + } + defer os.Remove(tmpPackageNameFile) + + var cfg *config.Config + if cfg, err = config.LoadConfig(configFilename); err != nil { + panic(err) + } + + fmt.Println("Creating", serverFilename) + fmt.Println("Generating...") + if err := api.Generate(cfg, api.AddPlugin(servergen.New(serverFilename))); err != nil { + fmt.Fprintln(os.Stderr, err.Error()) + } + + fmt.Printf("\nExec \"go run ./%s\" to start GraphQL server\n", serverFilename) + return nil + }, +} + +func executeConfigTemplate(pkgName string) string { + var buf bytes.Buffer + if err := configTemplate.Execute(&buf, pkgName); err != nil { + panic(err) + } + + return buf.String() +} + +func fileExists(filename string) bool { + _, err := os.Stat(filename) + return !errors.Is(err, fs.ErrNotExist) +} + +func initFile(filename, contents string) error { + if err := os.MkdirAll(filepath.Dir(filename), 0o755); err != nil { + return fmt.Errorf("unable to create directory for file '%s': %w\n", filename, err) + } + if err := ioutil.WriteFile(filename, []byte(contents), 0o644); err != nil { + return fmt.Errorf("unable to write file '%s': %w\n", filename, err) + } + + return nil +} diff --git a/vendor/github.com/99designs/gqlgen/cmd/root.go b/vendor/github.com/99designs/gqlgen/cmd/root.go new file mode 100644 index 0000000..ce96c1b --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/cmd/root.go @@ -0,0 +1,45 @@ +package cmd + +import ( + "fmt" + "io/ioutil" + "log" + "os" + + "github.com/99designs/gqlgen/graphql" + "github.com/urfave/cli/v2" + + // Required since otherwise dep will prune away these unused packages before codegen has a chance to run + _ "github.com/99designs/gqlgen/graphql/handler" + _ "github.com/99designs/gqlgen/handler" +) + +func Execute() { + app := cli.NewApp() + app.Name = "gqlgen" + app.Usage = genCmd.Usage + app.Description = "This is a library for quickly creating strictly typed graphql servers in golang. See https://gqlgen.com/ for a getting started guide." + app.HideVersion = true + app.Flags = genCmd.Flags + app.Version = graphql.Version + app.Before = func(context *cli.Context) error { + if context.Bool("verbose") { + log.SetFlags(0) + } else { + log.SetOutput(ioutil.Discard) + } + return nil + } + + app.Action = genCmd.Action + app.Commands = []*cli.Command{ + genCmd, + initCmd, + versionCmd, + } + + if err := app.Run(os.Args); err != nil { + fmt.Fprint(os.Stderr, err.Error()+"\n") + os.Exit(1) + } +} diff --git a/vendor/github.com/99designs/gqlgen/cmd/version.go b/vendor/github.com/99designs/gqlgen/cmd/version.go new file mode 100644 index 0000000..d3a05de --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/cmd/version.go @@ -0,0 +1,17 @@ +package cmd + +import ( + "fmt" + + "github.com/99designs/gqlgen/graphql" + "github.com/urfave/cli/v2" +) + +var versionCmd = &cli.Command{ + Name: "version", + Usage: "print the version string", + Action: func(ctx *cli.Context) error { + fmt.Println(graphql.Version) + return nil + }, +} diff --git a/vendor/github.com/99designs/gqlgen/codegen/args.go b/vendor/github.com/99designs/gqlgen/codegen/args.go new file mode 100644 index 0000000..8c08d92 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/codegen/args.go @@ -0,0 +1,118 @@ +package codegen + +import ( + "fmt" + "go/types" + "strings" + + "github.com/99designs/gqlgen/codegen/config" + "github.com/99designs/gqlgen/codegen/templates" + "github.com/vektah/gqlparser/v2/ast" +) + +type ArgSet struct { + Args []*FieldArgument + FuncDecl string +} + +type FieldArgument struct { + *ast.ArgumentDefinition + TypeReference *config.TypeReference + VarName string // The name of the var in go + Object *Object // A link back to the parent object + Default interface{} // The default value + Directives []*Directive + Value interface{} // value set in Data +} + +// ImplDirectives get not Builtin and location ARGUMENT_DEFINITION directive +func (f *FieldArgument) ImplDirectives() []*Directive { + d := make([]*Directive, 0) + for i := range f.Directives { + if !f.Directives[i].Builtin && f.Directives[i].IsLocation(ast.LocationArgumentDefinition) { + d = append(d, f.Directives[i]) + } + } + + return d +} + +func (f *FieldArgument) DirectiveObjName() string { + return "rawArgs" +} + +func (f *FieldArgument) Stream() bool { + return f.Object != nil && f.Object.Stream +} + +func (b *builder) buildArg(obj *Object, arg *ast.ArgumentDefinition) (*FieldArgument, error) { + tr, err := b.Binder.TypeReference(arg.Type, nil) + if err != nil { + return nil, err + } + + argDirs, err := b.getDirectives(arg.Directives) + if err != nil { + return nil, err + } + newArg := FieldArgument{ + ArgumentDefinition: arg, + TypeReference: tr, + Object: obj, + VarName: templates.ToGoPrivate(arg.Name), + Directives: argDirs, + } + + if arg.DefaultValue != nil { + newArg.Default, err = arg.DefaultValue.Value(nil) + if err != nil { + return nil, fmt.Errorf("default value is not valid: %w", err) + } + } + + return &newArg, nil +} + +func (b *builder) bindArgs(field *Field, params *types.Tuple) ([]*FieldArgument, error) { + var newArgs []*FieldArgument + +nextArg: + for j := 0; j < params.Len(); j++ { + param := params.At(j) + for _, oldArg := range field.Args { + if strings.EqualFold(oldArg.Name, param.Name()) { + tr, err := b.Binder.TypeReference(oldArg.Type, param.Type()) + if err != nil { + return nil, err + } + oldArg.TypeReference = tr + + newArgs = append(newArgs, oldArg) + continue nextArg + } + } + + // no matching arg found, abort + return nil, fmt.Errorf("arg %s not in schema", param.Name()) + } + + return newArgs, nil +} + +func (a *Data) Args() map[string][]*FieldArgument { + ret := map[string][]*FieldArgument{} + for _, o := range a.Objects { + for _, f := range o.Fields { + if len(f.Args) > 0 { + ret[f.ArgsFunc()] = f.Args + } + } + } + + for _, d := range a.Directives() { + if len(d.Args) > 0 { + ret[d.ArgsFunc()] = d.Args + } + } + return ret +} diff --git a/vendor/github.com/99designs/gqlgen/codegen/args.gotpl b/vendor/github.com/99designs/gqlgen/codegen/args.gotpl new file mode 100644 index 0000000..7b541ae --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/codegen/args.gotpl @@ -0,0 +1,36 @@ +{{ range $name, $args := .Args }} +func (ec *executionContext) {{ $name }}(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + {{- range $i, $arg := . }} + var arg{{$i}} {{ $arg.TypeReference.GO | ref}} + if tmp, ok := rawArgs[{{$arg.Name|quote}}]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField({{$arg.Name|quote}})) + {{- if $arg.ImplDirectives }} + directive0 := func(ctx context.Context) (interface{}, error) { return ec.{{ $arg.TypeReference.UnmarshalFunc }}(ctx, tmp) } + {{ template "implDirectives" $arg }} + tmp, err = directive{{$arg.ImplDirectives|len}}(ctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if data, ok := tmp.({{ $arg.TypeReference.GO | ref }}) ; ok { + arg{{$i}} = data + {{- if $arg.TypeReference.IsNilable }} + } else if tmp == nil { + arg{{$i}} = nil + {{- end }} + } else { + return nil, graphql.ErrorOnPath(ctx, fmt.Errorf(`unexpected type %T from directive, should be {{ $arg.TypeReference.GO }}`, tmp)) + } + {{- else }} + arg{{$i}}, err = ec.{{ $arg.TypeReference.UnmarshalFunc }}(ctx, tmp) + if err != nil { + return nil, err + } + {{- end }} + } + args[{{$arg.Name|quote}}] = arg{{$i}} + {{- end }} + return args, nil +} +{{ end }} diff --git a/vendor/github.com/99designs/gqlgen/codegen/complexity.go b/vendor/github.com/99designs/gqlgen/codegen/complexity.go new file mode 100644 index 0000000..e9c6a20 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/codegen/complexity.go @@ -0,0 +1,11 @@ +package codegen + +func (o *Object) UniqueFields() map[string][]*Field { + m := map[string][]*Field{} + + for _, f := range o.Fields { + m[f.GoFieldName] = append(m[f.GoFieldName], f) + } + + return m +} diff --git a/vendor/github.com/99designs/gqlgen/codegen/config/binder.go b/vendor/github.com/99designs/gqlgen/codegen/config/binder.go new file mode 100644 index 0000000..90820de --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/codegen/config/binder.go @@ -0,0 +1,494 @@ +package config + +import ( + "errors" + "fmt" + "go/token" + "go/types" + + "golang.org/x/tools/go/packages" + + "github.com/99designs/gqlgen/codegen/templates" + "github.com/99designs/gqlgen/internal/code" + "github.com/vektah/gqlparser/v2/ast" +) + +var ErrTypeNotFound = errors.New("unable to find type") + +// Binder connects graphql types to golang types using static analysis +type Binder struct { + pkgs *code.Packages + schema *ast.Schema + cfg *Config + References []*TypeReference + SawInvalid bool + objectCache map[string]map[string]types.Object +} + +func (c *Config) NewBinder() *Binder { + return &Binder{ + pkgs: c.Packages, + schema: c.Schema, + cfg: c, + } +} + +func (b *Binder) TypePosition(typ types.Type) token.Position { + named, isNamed := typ.(*types.Named) + if !isNamed { + return token.Position{ + Filename: "unknown", + } + } + + return b.ObjectPosition(named.Obj()) +} + +func (b *Binder) ObjectPosition(typ types.Object) token.Position { + if typ == nil { + return token.Position{ + Filename: "unknown", + } + } + pkg := b.pkgs.Load(typ.Pkg().Path()) + return pkg.Fset.Position(typ.Pos()) +} + +func (b *Binder) FindTypeFromName(name string) (types.Type, error) { + pkgName, typeName := code.PkgAndType(name) + return b.FindType(pkgName, typeName) +} + +func (b *Binder) FindType(pkgName string, typeName string) (types.Type, error) { + if pkgName == "" { + if typeName == "map[string]interface{}" { + return MapType, nil + } + + if typeName == "interface{}" { + return InterfaceType, nil + } + } + + obj, err := b.FindObject(pkgName, typeName) + if err != nil { + return nil, err + } + + if fun, isFunc := obj.(*types.Func); isFunc { + return fun.Type().(*types.Signature).Params().At(0).Type(), nil + } + return obj.Type(), nil +} + +var ( + MapType = types.NewMap(types.Typ[types.String], types.NewInterfaceType(nil, nil).Complete()) + InterfaceType = types.NewInterfaceType(nil, nil) +) + +func (b *Binder) DefaultUserObject(name string) (types.Type, error) { + models := b.cfg.Models[name].Model + if len(models) == 0 { + return nil, fmt.Errorf(name + " not found in typemap") + } + + if models[0] == "map[string]interface{}" { + return MapType, nil + } + + if models[0] == "interface{}" { + return InterfaceType, nil + } + + pkgName, typeName := code.PkgAndType(models[0]) + if pkgName == "" { + return nil, fmt.Errorf("missing package name for %s", name) + } + + obj, err := b.FindObject(pkgName, typeName) + if err != nil { + return nil, err + } + + return obj.Type(), nil +} + +func (b *Binder) FindObject(pkgName string, typeName string) (types.Object, error) { + if pkgName == "" { + return nil, fmt.Errorf("package cannot be nil") + } + + pkg := b.pkgs.LoadWithTypes(pkgName) + if pkg == nil { + err := b.pkgs.Errors() + if err != nil { + return nil, fmt.Errorf("package could not be loaded: %s.%s: %w", pkgName, typeName, err) + } + return nil, fmt.Errorf("required package was not loaded: %s.%s", pkgName, typeName) + } + + if b.objectCache == nil { + b.objectCache = make(map[string]map[string]types.Object, b.pkgs.Count()) + } + + defsIndex, ok := b.objectCache[pkgName] + if !ok { + defsIndex = indexDefs(pkg) + b.objectCache[pkgName] = defsIndex + } + + // function based marshalers take precedence + if val, ok := defsIndex["Marshal"+typeName]; ok { + return val, nil + } + + if val, ok := defsIndex[typeName]; ok { + return val, nil + } + + return nil, fmt.Errorf("%w: %s.%s", ErrTypeNotFound, pkgName, typeName) +} + +func indexDefs(pkg *packages.Package) map[string]types.Object { + res := make(map[string]types.Object) + + scope := pkg.Types.Scope() + for astNode, def := range pkg.TypesInfo.Defs { + // only look at defs in the top scope + if def == nil { + continue + } + parent := def.Parent() + if parent == nil || parent != scope { + continue + } + + if _, ok := res[astNode.Name]; !ok { + // The above check may not be really needed, it is only here to have a consistent behavior with + // previous implementation of FindObject() function which only honored the first inclusion of a def. + // If this is still needed, we can consider something like sync.Map.LoadOrStore() to avoid two lookups. + res[astNode.Name] = def + } + } + + return res +} + +func (b *Binder) PointerTo(ref *TypeReference) *TypeReference { + newRef := *ref + newRef.GO = types.NewPointer(ref.GO) + b.References = append(b.References, &newRef) + return &newRef +} + +// TypeReference is used by args and field types. The Definition can refer to both input and output types. +type TypeReference struct { + Definition *ast.Definition + GQL *ast.Type + GO types.Type // Type of the field being bound. Could be a pointer or a value type of Target. + Target types.Type // The actual type that we know how to bind to. May require pointer juggling when traversing to fields. + CastType types.Type // Before calling marshalling functions cast from/to this base type + Marshaler *types.Func // When using external marshalling functions this will point to the Marshal function + Unmarshaler *types.Func // When using external marshalling functions this will point to the Unmarshal function + IsMarshaler bool // Does the type implement graphql.Marshaler and graphql.Unmarshaler + IsContext bool // Is the Marshaler/Unmarshaller the context version; applies to either the method or interface variety. +} + +func (ref *TypeReference) Elem() *TypeReference { + if p, isPtr := ref.GO.(*types.Pointer); isPtr { + newRef := *ref + newRef.GO = p.Elem() + return &newRef + } + + if ref.IsSlice() { + newRef := *ref + newRef.GO = ref.GO.(*types.Slice).Elem() + newRef.GQL = ref.GQL.Elem + return &newRef + } + return nil +} + +func (t *TypeReference) IsPtr() bool { + _, isPtr := t.GO.(*types.Pointer) + return isPtr +} + +// fix for https://github.com/golang/go/issues/31103 may make it possible to remove this (may still be useful) +// +func (t *TypeReference) IsPtrToPtr() bool { + if p, isPtr := t.GO.(*types.Pointer); isPtr { + _, isPtr := p.Elem().(*types.Pointer) + return isPtr + } + return false +} + +func (t *TypeReference) IsNilable() bool { + return IsNilable(t.GO) +} + +func (t *TypeReference) IsSlice() bool { + _, isSlice := t.GO.(*types.Slice) + return t.GQL.Elem != nil && isSlice +} + +func (t *TypeReference) IsPtrToSlice() bool { + if t.IsPtr() { + _, isPointerToSlice := t.GO.(*types.Pointer).Elem().(*types.Slice) + return isPointerToSlice + } + return false +} + +func (t *TypeReference) IsNamed() bool { + _, isSlice := t.GO.(*types.Named) + return isSlice +} + +func (t *TypeReference) IsStruct() bool { + _, isStruct := t.GO.Underlying().(*types.Struct) + return isStruct +} + +func (t *TypeReference) IsScalar() bool { + return t.Definition.Kind == ast.Scalar +} + +func (t *TypeReference) UniquenessKey() string { + nullability := "O" + if t.GQL.NonNull { + nullability = "N" + } + + elemNullability := "" + if t.GQL.Elem != nil && t.GQL.Elem.NonNull { + // Fix for #896 + elemNullability = "ᚄ" + } + return nullability + t.Definition.Name + "2" + templates.TypeIdentifier(t.GO) + elemNullability +} + +func (t *TypeReference) MarshalFunc() string { + if t.Definition == nil { + panic(errors.New("Definition missing for " + t.GQL.Name())) + } + + if t.Definition.Kind == ast.InputObject { + return "" + } + + return "marshal" + t.UniquenessKey() +} + +func (t *TypeReference) UnmarshalFunc() string { + if t.Definition == nil { + panic(errors.New("Definition missing for " + t.GQL.Name())) + } + + if !t.Definition.IsInputType() { + return "" + } + + return "unmarshal" + t.UniquenessKey() +} + +func (t *TypeReference) IsTargetNilable() bool { + return IsNilable(t.Target) +} + +func (b *Binder) PushRef(ret *TypeReference) { + b.References = append(b.References, ret) +} + +func isMap(t types.Type) bool { + if t == nil { + return true + } + _, ok := t.(*types.Map) + return ok +} + +func isIntf(t types.Type) bool { + if t == nil { + return true + } + _, ok := t.(*types.Interface) + return ok +} + +func (b *Binder) TypeReference(schemaType *ast.Type, bindTarget types.Type) (ret *TypeReference, err error) { + if !isValid(bindTarget) { + b.SawInvalid = true + return nil, fmt.Errorf("%s has an invalid type", schemaType.Name()) + } + + var pkgName, typeName string + def := b.schema.Types[schemaType.Name()] + defer func() { + if err == nil && ret != nil { + b.PushRef(ret) + } + }() + + if len(b.cfg.Models[schemaType.Name()].Model) == 0 { + return nil, fmt.Errorf("%s was not found", schemaType.Name()) + } + + for _, model := range b.cfg.Models[schemaType.Name()].Model { + if model == "map[string]interface{}" { + if !isMap(bindTarget) { + continue + } + return &TypeReference{ + Definition: def, + GQL: schemaType, + GO: MapType, + }, nil + } + + if model == "interface{}" { + if !isIntf(bindTarget) { + continue + } + return &TypeReference{ + Definition: def, + GQL: schemaType, + GO: InterfaceType, + }, nil + } + + pkgName, typeName = code.PkgAndType(model) + if pkgName == "" { + return nil, fmt.Errorf("missing package name for %s", schemaType.Name()) + } + + ref := &TypeReference{ + Definition: def, + GQL: schemaType, + } + + obj, err := b.FindObject(pkgName, typeName) + if err != nil { + return nil, err + } + + if fun, isFunc := obj.(*types.Func); isFunc { + ref.GO = fun.Type().(*types.Signature).Params().At(0).Type() + ref.IsContext = fun.Type().(*types.Signature).Results().At(0).Type().String() == "github.com/99designs/gqlgen/graphql.ContextMarshaler" + ref.Marshaler = fun + ref.Unmarshaler = types.NewFunc(0, fun.Pkg(), "Unmarshal"+typeName, nil) + } else if hasMethod(obj.Type(), "MarshalGQLContext") && hasMethod(obj.Type(), "UnmarshalGQLContext") { + ref.GO = obj.Type() + ref.IsContext = true + ref.IsMarshaler = true + } else if hasMethod(obj.Type(), "MarshalGQL") && hasMethod(obj.Type(), "UnmarshalGQL") { + ref.GO = obj.Type() + ref.IsMarshaler = true + } else if underlying := basicUnderlying(obj.Type()); def.IsLeafType() && underlying != nil && underlying.Kind() == types.String { + // TODO delete before v1. Backwards compatibility case for named types wrapping strings (see #595) + + ref.GO = obj.Type() + ref.CastType = underlying + + underlyingRef, err := b.TypeReference(&ast.Type{NamedType: "String"}, nil) + if err != nil { + return nil, err + } + + ref.Marshaler = underlyingRef.Marshaler + ref.Unmarshaler = underlyingRef.Unmarshaler + } else { + ref.GO = obj.Type() + } + + ref.Target = ref.GO + ref.GO = b.CopyModifiersFromAst(schemaType, ref.GO) + + if bindTarget != nil { + if err = code.CompatibleTypes(ref.GO, bindTarget); err != nil { + continue + } + ref.GO = bindTarget + } + + return ref, nil + } + + return nil, fmt.Errorf("%s is incompatible with %s", schemaType.Name(), bindTarget.String()) +} + +func isValid(t types.Type) bool { + basic, isBasic := t.(*types.Basic) + if !isBasic { + return true + } + return basic.Kind() != types.Invalid +} + +func (b *Binder) CopyModifiersFromAst(t *ast.Type, base types.Type) types.Type { + if t.Elem != nil { + child := b.CopyModifiersFromAst(t.Elem, base) + if _, isStruct := child.Underlying().(*types.Struct); isStruct && !b.cfg.OmitSliceElementPointers { + child = types.NewPointer(child) + } + return types.NewSlice(child) + } + + var isInterface bool + if named, ok := base.(*types.Named); ok { + _, isInterface = named.Underlying().(*types.Interface) + } + + if !isInterface && !IsNilable(base) && !t.NonNull { + return types.NewPointer(base) + } + + return base +} + +func IsNilable(t types.Type) bool { + if namedType, isNamed := t.(*types.Named); isNamed { + return IsNilable(namedType.Underlying()) + } + _, isPtr := t.(*types.Pointer) + _, isMap := t.(*types.Map) + _, isInterface := t.(*types.Interface) + _, isSlice := t.(*types.Slice) + _, isChan := t.(*types.Chan) + return isPtr || isMap || isInterface || isSlice || isChan +} + +func hasMethod(it types.Type, name string) bool { + if ptr, isPtr := it.(*types.Pointer); isPtr { + it = ptr.Elem() + } + namedType, ok := it.(*types.Named) + if !ok { + return false + } + + for i := 0; i < namedType.NumMethods(); i++ { + if namedType.Method(i).Name() == name { + return true + } + } + return false +} + +func basicUnderlying(it types.Type) *types.Basic { + if ptr, isPtr := it.(*types.Pointer); isPtr { + it = ptr.Elem() + } + namedType, ok := it.(*types.Named) + if !ok { + return nil + } + + if basic, ok := namedType.Underlying().(*types.Basic); ok { + return basic + } + + return nil +} diff --git a/vendor/github.com/99designs/gqlgen/codegen/config/config.go b/vendor/github.com/99designs/gqlgen/codegen/config/config.go new file mode 100644 index 0000000..77d92bd --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/codegen/config/config.go @@ -0,0 +1,647 @@ +package config + +import ( + "fmt" + "io/ioutil" + "os" + "path/filepath" + "regexp" + "sort" + "strings" + + "github.com/99designs/gqlgen/internal/code" + "github.com/vektah/gqlparser/v2" + "github.com/vektah/gqlparser/v2/ast" + "gopkg.in/yaml.v2" +) + +type Config struct { + SchemaFilename StringList `yaml:"schema,omitempty"` + Exec ExecConfig `yaml:"exec"` + Model PackageConfig `yaml:"model,omitempty"` + Federation PackageConfig `yaml:"federation,omitempty"` + Resolver ResolverConfig `yaml:"resolver,omitempty"` + AutoBind []string `yaml:"autobind"` + Models TypeMap `yaml:"models,omitempty"` + StructTag string `yaml:"struct_tag,omitempty"` + Directives map[string]DirectiveConfig `yaml:"directives,omitempty"` + OmitSliceElementPointers bool `yaml:"omit_slice_element_pointers,omitempty"` + SkipValidation bool `yaml:"skip_validation,omitempty"` + SkipModTidy bool `yaml:"skip_mod_tidy,omitempty"` + Sources []*ast.Source `yaml:"-"` + Packages *code.Packages `yaml:"-"` + Schema *ast.Schema `yaml:"-"` + + // Deprecated: use Federation instead. Will be removed next release + Federated bool `yaml:"federated,omitempty"` +} + +var cfgFilenames = []string{".gqlgen.yml", "gqlgen.yml", "gqlgen.yaml"} + +// DefaultConfig creates a copy of the default config +func DefaultConfig() *Config { + return &Config{ + SchemaFilename: StringList{"schema.graphql"}, + Model: PackageConfig{Filename: "models_gen.go"}, + Exec: ExecConfig{Filename: "generated.go"}, + Directives: map[string]DirectiveConfig{}, + Models: TypeMap{}, + } +} + +// LoadDefaultConfig loads the default config so that it is ready to be used +func LoadDefaultConfig() (*Config, error) { + config := DefaultConfig() + + for _, filename := range config.SchemaFilename { + filename = filepath.ToSlash(filename) + var err error + var schemaRaw []byte + schemaRaw, err = ioutil.ReadFile(filename) + if err != nil { + return nil, fmt.Errorf("unable to open schema: %w", err) + } + + config.Sources = append(config.Sources, &ast.Source{Name: filename, Input: string(schemaRaw)}) + } + + return config, nil +} + +// LoadConfigFromDefaultLocations looks for a config file in the current directory, and all parent directories +// walking up the tree. The closest config file will be returned. +func LoadConfigFromDefaultLocations() (*Config, error) { + cfgFile, err := findCfg() + if err != nil { + return nil, err + } + + err = os.Chdir(filepath.Dir(cfgFile)) + if err != nil { + return nil, fmt.Errorf("unable to enter config dir: %w", err) + } + return LoadConfig(cfgFile) +} + +var path2regex = strings.NewReplacer( + `.`, `\.`, + `*`, `.+`, + `\`, `[\\/]`, + `/`, `[\\/]`, +) + +// LoadConfig reads the gqlgen.yml config file +func LoadConfig(filename string) (*Config, error) { + config := DefaultConfig() + + b, err := ioutil.ReadFile(filename) + if err != nil { + return nil, fmt.Errorf("unable to read config: %w", err) + } + + if err := yaml.UnmarshalStrict(b, config); err != nil { + return nil, fmt.Errorf("unable to parse config: %w", err) + } + + if err := CompleteConfig(config); err != nil { + return nil, err + } + + return config, nil +} + +// CompleteConfig fills in the schema and other values to a config loaded from +// YAML. +func CompleteConfig(config *Config) error { + defaultDirectives := map[string]DirectiveConfig{ + "skip": {SkipRuntime: true}, + "include": {SkipRuntime: true}, + "deprecated": {SkipRuntime: true}, + } + + for key, value := range defaultDirectives { + if _, defined := config.Directives[key]; !defined { + config.Directives[key] = value + } + } + + preGlobbing := config.SchemaFilename + config.SchemaFilename = StringList{} + for _, f := range preGlobbing { + var matches []string + + // for ** we want to override default globbing patterns and walk all + // subdirectories to match schema files. + if strings.Contains(f, "**") { + pathParts := strings.SplitN(f, "**", 2) + rest := strings.TrimPrefix(strings.TrimPrefix(pathParts[1], `\`), `/`) + // turn the rest of the glob into a regex, anchored only at the end because ** allows + // for any number of dirs in between and walk will let us match against the full path name + globRe := regexp.MustCompile(path2regex.Replace(rest) + `$`) + + if err := filepath.Walk(pathParts[0], func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + if globRe.MatchString(strings.TrimPrefix(path, pathParts[0])) { + matches = append(matches, path) + } + + return nil + }); err != nil { + return fmt.Errorf("failed to walk schema at root %s: %w", pathParts[0], err) + } + } else { + var err error + matches, err = filepath.Glob(f) + if err != nil { + return fmt.Errorf("failed to glob schema filename %s: %w", f, err) + } + } + + for _, m := range matches { + if config.SchemaFilename.Has(m) { + continue + } + config.SchemaFilename = append(config.SchemaFilename, m) + } + } + + for _, filename := range config.SchemaFilename { + filename = filepath.ToSlash(filename) + var err error + var schemaRaw []byte + schemaRaw, err = ioutil.ReadFile(filename) + if err != nil { + return fmt.Errorf("unable to open schema: %w", err) + } + + config.Sources = append(config.Sources, &ast.Source{Name: filename, Input: string(schemaRaw)}) + } + return nil +} + +func (c *Config) Init() error { + if c.Packages == nil { + c.Packages = &code.Packages{} + } + + if c.Schema == nil { + if err := c.LoadSchema(); err != nil { + return err + } + } + + err := c.injectTypesFromSchema() + if err != nil { + return err + } + + err = c.autobind() + if err != nil { + return err + } + + c.injectBuiltins() + // prefetch all packages in one big packages.Load call + c.Packages.LoadAll(c.packageList()...) + + // check everything is valid on the way out + err = c.check() + if err != nil { + return err + } + + return nil +} + +func (c *Config) packageList() []string { + pkgs := []string{ + "github.com/99designs/gqlgen/graphql", + "github.com/99designs/gqlgen/graphql/introspection", + } + pkgs = append(pkgs, c.Models.ReferencedPackages()...) + pkgs = append(pkgs, c.AutoBind...) + return pkgs +} + +func (c *Config) ReloadAllPackages() { + c.Packages.ReloadAll(c.packageList()...) +} + +func (c *Config) injectTypesFromSchema() error { + c.Directives["goModel"] = DirectiveConfig{ + SkipRuntime: true, + } + + c.Directives["goField"] = DirectiveConfig{ + SkipRuntime: true, + } + + c.Directives["goTag"] = DirectiveConfig{ + SkipRuntime: true, + } + + for _, schemaType := range c.Schema.Types { + if schemaType == c.Schema.Query || schemaType == c.Schema.Mutation || schemaType == c.Schema.Subscription { + continue + } + + if bd := schemaType.Directives.ForName("goModel"); bd != nil { + if ma := bd.Arguments.ForName("model"); ma != nil { + if mv, err := ma.Value.Value(nil); err == nil { + c.Models.Add(schemaType.Name, mv.(string)) + } + } + if ma := bd.Arguments.ForName("models"); ma != nil { + if mvs, err := ma.Value.Value(nil); err == nil { + for _, mv := range mvs.([]interface{}) { + c.Models.Add(schemaType.Name, mv.(string)) + } + } + } + } + + if schemaType.Kind == ast.Object || schemaType.Kind == ast.InputObject { + for _, field := range schemaType.Fields { + if fd := field.Directives.ForName("goField"); fd != nil { + forceResolver := c.Models[schemaType.Name].Fields[field.Name].Resolver + fieldName := c.Models[schemaType.Name].Fields[field.Name].FieldName + + if ra := fd.Arguments.ForName("forceResolver"); ra != nil { + if fr, err := ra.Value.Value(nil); err == nil { + forceResolver = fr.(bool) + } + } + + if na := fd.Arguments.ForName("name"); na != nil { + if fr, err := na.Value.Value(nil); err == nil { + fieldName = fr.(string) + } + } + + if c.Models[schemaType.Name].Fields == nil { + c.Models[schemaType.Name] = TypeMapEntry{ + Model: c.Models[schemaType.Name].Model, + Fields: map[string]TypeMapField{}, + } + } + + c.Models[schemaType.Name].Fields[field.Name] = TypeMapField{ + FieldName: fieldName, + Resolver: forceResolver, + } + } + } + } + } + + return nil +} + +type TypeMapEntry struct { + Model StringList `yaml:"model"` + Fields map[string]TypeMapField `yaml:"fields,omitempty"` +} + +type TypeMapField struct { + Resolver bool `yaml:"resolver"` + FieldName string `yaml:"fieldName"` + GeneratedMethod string `yaml:"-"` +} + +type StringList []string + +func (a *StringList) UnmarshalYAML(unmarshal func(interface{}) error) error { + var single string + err := unmarshal(&single) + if err == nil { + *a = []string{single} + return nil + } + + var multi []string + err = unmarshal(&multi) + if err != nil { + return err + } + + *a = multi + return nil +} + +func (a StringList) Has(file string) bool { + for _, existing := range a { + if existing == file { + return true + } + } + return false +} + +func (c *Config) check() error { + if c.Models == nil { + c.Models = TypeMap{} + } + + type FilenamePackage struct { + Filename string + Package string + Declaree string + } + + fileList := map[string][]FilenamePackage{} + + if err := c.Models.Check(); err != nil { + return fmt.Errorf("config.models: %w", err) + } + if err := c.Exec.Check(); err != nil { + return fmt.Errorf("config.exec: %w", err) + } + fileList[c.Exec.ImportPath()] = append(fileList[c.Exec.ImportPath()], FilenamePackage{ + Filename: c.Exec.Filename, + Package: c.Exec.Package, + Declaree: "exec", + }) + + if c.Model.IsDefined() { + if err := c.Model.Check(); err != nil { + return fmt.Errorf("config.model: %w", err) + } + fileList[c.Model.ImportPath()] = append(fileList[c.Model.ImportPath()], FilenamePackage{ + Filename: c.Model.Filename, + Package: c.Model.Package, + Declaree: "model", + }) + } + if c.Resolver.IsDefined() { + if err := c.Resolver.Check(); err != nil { + return fmt.Errorf("config.resolver: %w", err) + } + fileList[c.Resolver.ImportPath()] = append(fileList[c.Resolver.ImportPath()], FilenamePackage{ + Filename: c.Resolver.Filename, + Package: c.Resolver.Package, + Declaree: "resolver", + }) + } + if c.Federation.IsDefined() { + if err := c.Federation.Check(); err != nil { + return fmt.Errorf("config.federation: %w", err) + } + fileList[c.Federation.ImportPath()] = append(fileList[c.Federation.ImportPath()], FilenamePackage{ + Filename: c.Federation.Filename, + Package: c.Federation.Package, + Declaree: "federation", + }) + if c.Federation.ImportPath() != c.Exec.ImportPath() { + return fmt.Errorf("federation and exec must be in the same package") + } + } + if c.Federated { + return fmt.Errorf("federated has been removed, instead use\nfederation:\n filename: path/to/federated.go") + } + + for importPath, pkg := range fileList { + for _, file1 := range pkg { + for _, file2 := range pkg { + if file1.Package != file2.Package { + return fmt.Errorf("%s and %s define the same import path (%s) with different package names (%s vs %s)", + file1.Declaree, + file2.Declaree, + importPath, + file1.Package, + file2.Package, + ) + } + } + } + } + + return nil +} + +type TypeMap map[string]TypeMapEntry + +func (tm TypeMap) Exists(typeName string) bool { + _, ok := tm[typeName] + return ok +} + +func (tm TypeMap) UserDefined(typeName string) bool { + m, ok := tm[typeName] + return ok && len(m.Model) > 0 +} + +func (tm TypeMap) Check() error { + for typeName, entry := range tm { + for _, model := range entry.Model { + if strings.LastIndex(model, ".") < strings.LastIndex(model, "/") { + return fmt.Errorf("model %s: invalid type specifier \"%s\" - you need to specify a struct to map to", typeName, entry.Model) + } + } + } + return nil +} + +func (tm TypeMap) ReferencedPackages() []string { + var pkgs []string + + for _, typ := range tm { + for _, model := range typ.Model { + if model == "map[string]interface{}" || model == "interface{}" { + continue + } + pkg, _ := code.PkgAndType(model) + if pkg == "" || inStrSlice(pkgs, pkg) { + continue + } + pkgs = append(pkgs, code.QualifyPackagePath(pkg)) + } + } + + sort.Slice(pkgs, func(i, j int) bool { + return pkgs[i] > pkgs[j] + }) + return pkgs +} + +func (tm TypeMap) Add(name string, goType string) { + modelCfg := tm[name] + modelCfg.Model = append(modelCfg.Model, goType) + tm[name] = modelCfg +} + +type DirectiveConfig struct { + SkipRuntime bool `yaml:"skip_runtime"` +} + +func inStrSlice(haystack []string, needle string) bool { + for _, v := range haystack { + if needle == v { + return true + } + } + + return false +} + +// findCfg searches for the config file in this directory and all parents up the tree +// looking for the closest match +func findCfg() (string, error) { + dir, err := os.Getwd() + if err != nil { + return "", fmt.Errorf("unable to get working dir to findCfg: %w", err) + } + + cfg := findCfgInDir(dir) + + for cfg == "" && dir != filepath.Dir(dir) { + dir = filepath.Dir(dir) + cfg = findCfgInDir(dir) + } + + if cfg == "" { + return "", os.ErrNotExist + } + + return cfg, nil +} + +func findCfgInDir(dir string) string { + for _, cfgName := range cfgFilenames { + path := filepath.Join(dir, cfgName) + if _, err := os.Stat(path); err == nil { + return path + } + } + return "" +} + +func (c *Config) autobind() error { + if len(c.AutoBind) == 0 { + return nil + } + + ps := c.Packages.LoadAll(c.AutoBind...) + + for _, t := range c.Schema.Types { + if c.Models.UserDefined(t.Name) { + continue + } + + for i, p := range ps { + if p == nil { + return fmt.Errorf("unable to load %s - make sure you're using an import path to a package that exists", c.AutoBind[i]) + } + if t := p.Types.Scope().Lookup(t.Name); t != nil { + c.Models.Add(t.Name(), t.Pkg().Path()+"."+t.Name()) + break + } + } + } + + for i, t := range c.Models { + for j, m := range t.Model { + pkg, typename := code.PkgAndType(m) + + // skip anything that looks like an import path + if strings.Contains(pkg, "/") { + continue + } + + for _, p := range ps { + if p.Name != pkg { + continue + } + if t := p.Types.Scope().Lookup(typename); t != nil { + c.Models[i].Model[j] = t.Pkg().Path() + "." + t.Name() + break + } + } + } + } + + return nil +} + +func (c *Config) injectBuiltins() { + builtins := TypeMap{ + "__Directive": {Model: StringList{"github.com/99designs/gqlgen/graphql/introspection.Directive"}}, + "__DirectiveLocation": {Model: StringList{"github.com/99designs/gqlgen/graphql.String"}}, + "__Type": {Model: StringList{"github.com/99designs/gqlgen/graphql/introspection.Type"}}, + "__TypeKind": {Model: StringList{"github.com/99designs/gqlgen/graphql.String"}}, + "__Field": {Model: StringList{"github.com/99designs/gqlgen/graphql/introspection.Field"}}, + "__EnumValue": {Model: StringList{"github.com/99designs/gqlgen/graphql/introspection.EnumValue"}}, + "__InputValue": {Model: StringList{"github.com/99designs/gqlgen/graphql/introspection.InputValue"}}, + "__Schema": {Model: StringList{"github.com/99designs/gqlgen/graphql/introspection.Schema"}}, + "Float": {Model: StringList{"github.com/99designs/gqlgen/graphql.FloatContext"}}, + "String": {Model: StringList{"github.com/99designs/gqlgen/graphql.String"}}, + "Boolean": {Model: StringList{"github.com/99designs/gqlgen/graphql.Boolean"}}, + "Int": {Model: StringList{ + "github.com/99designs/gqlgen/graphql.Int", + "github.com/99designs/gqlgen/graphql.Int32", + "github.com/99designs/gqlgen/graphql.Int64", + }}, + "ID": { + Model: StringList{ + "github.com/99designs/gqlgen/graphql.ID", + "github.com/99designs/gqlgen/graphql.IntID", + }, + }, + } + + for typeName, entry := range builtins { + if !c.Models.Exists(typeName) { + c.Models[typeName] = entry + } + } + + // These are additional types that are injected if defined in the schema as scalars. + extraBuiltins := TypeMap{ + "Time": {Model: StringList{"github.com/99designs/gqlgen/graphql.Time"}}, + "Map": {Model: StringList{"github.com/99designs/gqlgen/graphql.Map"}}, + "Upload": {Model: StringList{"github.com/99designs/gqlgen/graphql.Upload"}}, + "Any": {Model: StringList{"github.com/99designs/gqlgen/graphql.Any"}}, + } + + for typeName, entry := range extraBuiltins { + if t, ok := c.Schema.Types[typeName]; !c.Models.Exists(typeName) && ok && t.Kind == ast.Scalar { + c.Models[typeName] = entry + } + } +} + +func (c *Config) LoadSchema() error { + if c.Packages != nil { + c.Packages = &code.Packages{} + } + + if err := c.check(); err != nil { + return err + } + + schema, err := gqlparser.LoadSchema(c.Sources...) + if err != nil { + return err + } + + if schema.Query == nil { + schema.Query = &ast.Definition{ + Kind: ast.Object, + Name: "Query", + } + schema.Types["Query"] = schema.Query + } + + c.Schema = schema + return nil +} + +func abs(path string) string { + absPath, err := filepath.Abs(path) + if err != nil { + panic(err) + } + return filepath.ToSlash(absPath) +} diff --git a/vendor/github.com/99designs/gqlgen/codegen/config/exec.go b/vendor/github.com/99designs/gqlgen/codegen/config/exec.go new file mode 100644 index 0000000..fe1dccd --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/codegen/config/exec.go @@ -0,0 +1,97 @@ +package config + +import ( + "fmt" + "go/types" + "path/filepath" + "strings" + + "github.com/99designs/gqlgen/internal/code" +) + +type ExecConfig struct { + Package string `yaml:"package,omitempty"` + Layout ExecLayout `yaml:"layout,omitempty"` // Default: single-file + + // Only for single-file layout: + Filename string `yaml:"filename,omitempty"` + + // Only for follow-schema layout: + FilenameTemplate string `yaml:"filename_template,omitempty"` // String template with {name} as placeholder for base name. + DirName string `yaml:"dir"` +} + +type ExecLayout string + +var ( + // Write all generated code to a single file. + ExecLayoutSingleFile ExecLayout = "single-file" + // Write generated code to a directory, generating one Go source file for each GraphQL schema file. + ExecLayoutFollowSchema ExecLayout = "follow-schema" +) + +func (r *ExecConfig) Check() error { + if r.Layout == "" { + r.Layout = ExecLayoutSingleFile + } + + switch r.Layout { + case ExecLayoutSingleFile: + if r.Filename == "" { + return fmt.Errorf("filename must be specified when using single-file layout") + } + if !strings.HasSuffix(r.Filename, ".go") { + return fmt.Errorf("filename should be path to a go source file when using single-file layout") + } + r.Filename = abs(r.Filename) + case ExecLayoutFollowSchema: + if r.DirName == "" { + return fmt.Errorf("dir must be specified when using follow-schema layout") + } + r.DirName = abs(r.DirName) + default: + return fmt.Errorf("invalid layout %s", r.Layout) + } + + if strings.ContainsAny(r.Package, "./\\") { + return fmt.Errorf("package should be the output package name only, do not include the output filename") + } + + if r.Package == "" && r.Dir() != "" { + r.Package = code.NameForDir(r.Dir()) + } + + return nil +} + +func (r *ExecConfig) ImportPath() string { + if r.Dir() == "" { + return "" + } + return code.ImportPathForDir(r.Dir()) +} + +func (r *ExecConfig) Dir() string { + switch r.Layout { + case ExecLayoutSingleFile: + if r.Filename == "" { + return "" + } + return filepath.Dir(r.Filename) + case ExecLayoutFollowSchema: + return abs(r.DirName) + default: + panic("invalid layout " + r.Layout) + } +} + +func (r *ExecConfig) Pkg() *types.Package { + if r.Dir() == "" { + return nil + } + return types.NewPackage(r.ImportPath(), r.Package) +} + +func (r *ExecConfig) IsDefined() bool { + return r.Filename != "" || r.DirName != "" +} diff --git a/vendor/github.com/99designs/gqlgen/codegen/config/package.go b/vendor/github.com/99designs/gqlgen/codegen/config/package.go new file mode 100644 index 0000000..a964593 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/codegen/config/package.go @@ -0,0 +1,62 @@ +package config + +import ( + "fmt" + "go/types" + "path/filepath" + "strings" + + "github.com/99designs/gqlgen/internal/code" +) + +type PackageConfig struct { + Filename string `yaml:"filename,omitempty"` + Package string `yaml:"package,omitempty"` +} + +func (c *PackageConfig) ImportPath() string { + if !c.IsDefined() { + return "" + } + return code.ImportPathForDir(c.Dir()) +} + +func (c *PackageConfig) Dir() string { + if !c.IsDefined() { + return "" + } + return filepath.Dir(c.Filename) +} + +func (c *PackageConfig) Pkg() *types.Package { + if !c.IsDefined() { + return nil + } + return types.NewPackage(c.ImportPath(), c.Package) +} + +func (c *PackageConfig) IsDefined() bool { + return c.Filename != "" +} + +func (c *PackageConfig) Check() error { + if strings.ContainsAny(c.Package, "./\\") { + return fmt.Errorf("package should be the output package name only, do not include the output filename") + } + if c.Filename == "" { + return fmt.Errorf("filename must be specified") + } + if !strings.HasSuffix(c.Filename, ".go") { + return fmt.Errorf("filename should be path to a go source file") + } + + c.Filename = abs(c.Filename) + + // If Package is not set, first attempt to load the package at the output dir. If that fails + // fallback to just the base dir name of the output filename. + if c.Package == "" { + c.Package = code.NameForDir(c.Dir()) + } + + return nil +} diff --git a/vendor/github.com/99designs/gqlgen/codegen/config/resolver.go b/vendor/github.com/99designs/gqlgen/codegen/config/resolver.go new file mode 100644 index 0000000..cd03f18 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/codegen/config/resolver.go @@ -0,0 +1,100 @@ +package config + +import ( + "fmt" + "go/types" + "path/filepath" + "strings" + + "github.com/99designs/gqlgen/internal/code" +) + +type ResolverConfig struct { + Filename string `yaml:"filename,omitempty"` + FilenameTemplate string `yaml:"filename_template,omitempty"` + Package string `yaml:"package,omitempty"` + Type string `yaml:"type,omitempty"` + Layout ResolverLayout `yaml:"layout,omitempty"` + DirName string `yaml:"dir"` +} + +type ResolverLayout string + +var ( + LayoutSingleFile ResolverLayout = "single-file" + LayoutFollowSchema ResolverLayout = "follow-schema" +) + +func (r *ResolverConfig) Check() error { + if r.Layout == "" { + r.Layout = LayoutSingleFile + } + if r.Type == "" { + r.Type = "Resolver" + } + + switch r.Layout { + case LayoutSingleFile: + if r.Filename == "" { + return fmt.Errorf("filename must be specified with layout=%s", r.Layout) + } + if !strings.HasSuffix(r.Filename, ".go") { + return fmt.Errorf("filename should be path to a go source file with layout=%s", r.Layout) + } + r.Filename = abs(r.Filename) + case LayoutFollowSchema: + if r.DirName == "" { + return fmt.Errorf("dirname must be specified with layout=%s", r.Layout) + } + r.DirName = abs(r.DirName) + if r.Filename == "" { + r.Filename = filepath.Join(r.DirName, "resolver.go") + } else { + r.Filename = abs(r.Filename) + } + default: + return fmt.Errorf("invalid layout %s. must be %s or %s", r.Layout, LayoutSingleFile, LayoutFollowSchema) + } + + if strings.ContainsAny(r.Package, "./\\") { + return fmt.Errorf("package should be the output package name only, do not include the output filename") + } + + if r.Package == "" && r.Dir() != "" { + r.Package = code.NameForDir(r.Dir()) + } + + return nil +} + +func (r *ResolverConfig) ImportPath() string { + if r.Dir() == "" { + return "" + } + return code.ImportPathForDir(r.Dir()) +} + +func (r *ResolverConfig) Dir() string { + switch r.Layout { + case LayoutSingleFile: + if r.Filename == "" { + return "" + } + return filepath.Dir(r.Filename) + case LayoutFollowSchema: + return r.DirName + default: + panic("invalid layout " + r.Layout) + } +} + +func (r *ResolverConfig) Pkg() *types.Package { + if r.Dir() == "" { + return nil + } + return types.NewPackage(r.ImportPath(), r.Package) +} + +func (r *ResolverConfig) IsDefined() bool { + return r.Filename != "" || r.DirName != "" +} diff --git a/vendor/github.com/99designs/gqlgen/codegen/data.go b/vendor/github.com/99designs/gqlgen/codegen/data.go new file mode 100644 index 0000000..e12fb10 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/codegen/data.go @@ -0,0 +1,185 @@ +package codegen + +import ( + "fmt" + "sort" + + "github.com/vektah/gqlparser/v2/ast" + + "github.com/99designs/gqlgen/codegen/config" +) + +// Data is a unified model of the code to be generated. Plugins may modify this structure to do things like implement +// resolvers or directives automatically (eg grpc, validation) +type Data struct { + Config *config.Config + Schema *ast.Schema + // If a schema is broken up into multiple Data instance, each representing part of the schema, + // AllDirectives should contain the directives for the entire schema. Directives() can + // then be used to get the directives that were defined in this Data instance's sources. + // If a single Data instance is used for the entire schema, AllDirectives and Directives() + // will be identical. + // AllDirectives should rarely be used directly. + AllDirectives DirectiveList + Objects Objects + Inputs Objects + Interfaces map[string]*Interface + ReferencedTypes map[string]*config.TypeReference + ComplexityRoots map[string]*Object + + QueryRoot *Object + MutationRoot *Object + SubscriptionRoot *Object +} + +type builder struct { + Config *config.Config + Schema *ast.Schema + Binder *config.Binder + Directives map[string]*Directive +} + +// Get only the directives which are defined in the config's sources. +func (d *Data) Directives() DirectiveList { + res := DirectiveList{} + for k, directive := range d.AllDirectives { + for _, s := range d.Config.Sources { + if directive.Position.Src.Name == s.Name { + res[k] = directive + break + } + } + } + return res +} + +func BuildData(cfg *config.Config) (*Data, error) { + // We reload all packages to allow packages to be compared correctly. + cfg.ReloadAllPackages() + + b := builder{ + Config: cfg, + Schema: cfg.Schema, + } + + b.Binder = b.Config.NewBinder() + + var err error + b.Directives, err = b.buildDirectives() + if err != nil { + return nil, err + } + + dataDirectives := make(map[string]*Directive) + for name, d := range b.Directives { + if !d.Builtin { + dataDirectives[name] = d + } + } + + s := Data{ + Config: cfg, + AllDirectives: dataDirectives, + Schema: b.Schema, + Interfaces: map[string]*Interface{}, + } + + for _, schemaType := range b.Schema.Types { + switch schemaType.Kind { + case ast.Object: + obj, err := b.buildObject(schemaType) + if err != nil { + return nil, fmt.Errorf("unable to build object definition: %w", err) + } + + s.Objects = append(s.Objects, obj) + case ast.InputObject: + input, err := b.buildObject(schemaType) + if err != nil { + return nil, fmt.Errorf("unable to build input definition: %w", err) + } + + s.Inputs = append(s.Inputs, input) + + case ast.Union, ast.Interface: + s.Interfaces[schemaType.Name], err = b.buildInterface(schemaType) + if err != nil { + return nil, fmt.Errorf("unable to bind to interface: %w", err) + } + } + } + + if s.Schema.Query != nil { + s.QueryRoot = s.Objects.ByName(s.Schema.Query.Name) + } else { + return nil, fmt.Errorf("query entry point missing") + } + + if s.Schema.Mutation != nil { + s.MutationRoot = s.Objects.ByName(s.Schema.Mutation.Name) + } + + if s.Schema.Subscription != nil { + s.SubscriptionRoot = s.Objects.ByName(s.Schema.Subscription.Name) + } + + if err := b.injectIntrospectionRoots(&s); err != nil { + return nil, err + } + + s.ReferencedTypes = b.buildTypes() + + sort.Slice(s.Objects, func(i, j int) bool { + return s.Objects[i].Definition.Name < s.Objects[j].Definition.Name + }) + + sort.Slice(s.Inputs, func(i, j int) bool { + return s.Inputs[i].Definition.Name < s.Inputs[j].Definition.Name + }) + + if b.Binder.SawInvalid { + // if we have a syntax error, show it + err := cfg.Packages.Errors() + if len(err) > 0 { + return nil, err + } + + // otherwise show a generic error message + return nil, fmt.Errorf("invalid types were encountered while traversing the go source code, this probably means the invalid code generated isnt correct. add try adding -v to debug") + } + + return &s, nil +} + +func (b *builder) injectIntrospectionRoots(s *Data) error { + obj := s.Objects.ByName(b.Schema.Query.Name) + if obj == nil { + return fmt.Errorf("root query type must be defined") + } + + __type, err := b.buildField(obj, &ast.FieldDefinition{ + Name: "__type", + Type: ast.NamedType("__Type", nil), + Arguments: []*ast.ArgumentDefinition{ + { + Name: "name", + Type: ast.NonNullNamedType("String", nil), + }, + }, + }) + if err != nil { + return err + } + + __schema, err := b.buildField(obj, &ast.FieldDefinition{ + Name: "__schema", + Type: ast.NamedType("__Schema", nil), + }) + if err != nil { + return err + } + + obj.Fields = append(obj.Fields, __type, __schema) + + return nil +} diff --git a/vendor/github.com/99designs/gqlgen/codegen/directive.go b/vendor/github.com/99designs/gqlgen/codegen/directive.go new file mode 100644 index 0000000..9730611 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/codegen/directive.go @@ -0,0 +1,174 @@ +package codegen + +import ( + "fmt" + "strconv" + "strings" + + "github.com/99designs/gqlgen/codegen/templates" + "github.com/vektah/gqlparser/v2/ast" +) + +type DirectiveList map[string]*Directive + +// LocationDirectives filter directives by location +func (dl DirectiveList) LocationDirectives(location string) DirectiveList { + return locationDirectives(dl, ast.DirectiveLocation(location)) +} + +type Directive struct { + *ast.DirectiveDefinition + Name string + Args []*FieldArgument + Builtin bool +} + +// IsLocation check location directive +func (d *Directive) IsLocation(location ...ast.DirectiveLocation) bool { + for _, l := range d.Locations { + for _, a := range location { + if l == a { + return true + } + } + } + + return false +} + +func locationDirectives(directives DirectiveList, location ...ast.DirectiveLocation) map[string]*Directive { + mDirectives := make(map[string]*Directive) + for name, d := range directives { + if d.IsLocation(location...) { + mDirectives[name] = d + } + } + return mDirectives +} + +func (b *builder) buildDirectives() (map[string]*Directive, error) { + directives := make(map[string]*Directive, len(b.Schema.Directives)) + + for name, dir := range b.Schema.Directives { + if _, ok := directives[name]; ok { + return nil, fmt.Errorf("directive with name %s already exists", name) + } + + var args []*FieldArgument + for _, arg := range dir.Arguments { + tr, err := b.Binder.TypeReference(arg.Type, nil) + if err != nil { + return nil, err + } + + newArg := &FieldArgument{ + ArgumentDefinition: arg, + TypeReference: tr, + VarName: templates.ToGoPrivate(arg.Name), + } + + if arg.DefaultValue != nil { + var err error + newArg.Default, err = arg.DefaultValue.Value(nil) + if err != nil { + return nil, fmt.Errorf("default value for directive argument %s(%s) is not valid: %w", dir.Name, arg.Name, err) + } + } + args = append(args, newArg) + } + + directives[name] = &Directive{ + DirectiveDefinition: dir, + Name: name, + Args: args, + Builtin: b.Config.Directives[name].SkipRuntime, + } + } + + return directives, nil +} + +func (b *builder) getDirectives(list ast.DirectiveList) ([]*Directive, error) { + dirs := make([]*Directive, len(list)) + for i, d := range list { + argValues := make(map[string]interface{}, len(d.Arguments)) + for _, da := range d.Arguments { + val, err := da.Value.Value(nil) + if err != nil { + return nil, err + } + argValues[da.Name] = val + } + def, ok := b.Directives[d.Name] + if !ok { + return nil, fmt.Errorf("directive %s not found", d.Name) + } + + var args []*FieldArgument + for _, a := range def.Args { + value := a.Default + if argValue, ok := argValues[a.Name]; ok { + value = argValue + } + args = append(args, &FieldArgument{ + ArgumentDefinition: a.ArgumentDefinition, + Value: value, + VarName: a.VarName, + TypeReference: a.TypeReference, + }) + } + dirs[i] = &Directive{ + Name: d.Name, + Args: args, + DirectiveDefinition: list[i].Definition, + Builtin: b.Config.Directives[d.Name].SkipRuntime, + } + + } + + return dirs, nil +} + +func (d *Directive) ArgsFunc() string { + if len(d.Args) == 0 { + return "" + } + + return "dir_" + d.Name + "_args" +} + +func (d *Directive) CallArgs() string { + args := []string{"ctx", "obj", "n"} + + for _, arg := range d.Args { + args = append(args, "args["+strconv.Quote(arg.Name)+"].("+templates.CurrentImports.LookupType(arg.TypeReference.GO)+")") + } + + return strings.Join(args, ", ") +} + +func (d *Directive) ResolveArgs(obj string, next int) string { + args := []string{"ctx", obj, fmt.Sprintf("directive%d", next)} + + for _, arg := range d.Args { + dArg := arg.VarName + if arg.Value == nil && arg.Default == nil { + dArg = "nil" + } + + args = append(args, dArg) + } + + return strings.Join(args, ", ") +} + +func (d *Directive) Declaration() string { + res := ucFirst(d.Name) + " func(ctx context.Context, obj interface{}, next graphql.Resolver" + + for _, arg := range d.Args { + res += fmt.Sprintf(", %s %s", templates.ToGoPrivate(arg.Name), templates.CurrentImports.LookupType(arg.TypeReference.GO)) + } + + res += ") (res interface{}, err error)" + return res +} diff --git a/vendor/github.com/99designs/gqlgen/codegen/directives.gotpl b/vendor/github.com/99designs/gqlgen/codegen/directives.gotpl new file mode 100644 index 0000000..e6d2455 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/codegen/directives.gotpl @@ -0,0 +1,149 @@ +{{ define "implDirectives" }}{{ $in := .DirectiveObjName }} + {{- range $i, $directive := .ImplDirectives -}} + directive{{add $i 1}} := func(ctx context.Context) (interface{}, error) { + {{- range $arg := $directive.Args }} + {{- if notNil "Value" $arg }} + {{ $arg.VarName }}, err := ec.{{ $arg.TypeReference.UnmarshalFunc }}(ctx, {{ $arg.Value | dump }}) + if err != nil{ + return nil, err + } + {{- else if notNil "Default" $arg }} + {{ $arg.VarName }}, err := ec.{{ $arg.TypeReference.UnmarshalFunc }}(ctx, {{ $arg.Default | dump }}) + if err != nil{ + return nil, err + } + {{- end }} + {{- end }} + if ec.directives.{{$directive.Name|ucFirst}} == nil { + return nil, errors.New("directive {{$directive.Name}} is not implemented") + } + return ec.directives.{{$directive.Name|ucFirst}}({{$directive.ResolveArgs $in $i }}) + } + {{ end -}} +{{ end }} + +{{define "queryDirectives"}} + for _, d := range obj.Directives { + switch d.Name { + {{- range $directive := . }} + case "{{$directive.Name}}": + {{- if $directive.Args }} + rawArgs := d.ArgumentMap(ec.Variables) + args, err := ec.{{ $directive.ArgsFunc }}(ctx,rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + {{- end }} + n := next + next = func(ctx context.Context) (interface{}, error) { + if ec.directives.{{$directive.Name|ucFirst}} == nil { + return nil, errors.New("directive {{$directive.Name}} is not implemented") + } + return ec.directives.{{$directive.Name|ucFirst}}({{$directive.CallArgs}}) + } + {{- end }} + } + } + tmp, err := next(ctx) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if data, ok := tmp.(graphql.Marshaler); ok { + return data + } + ec.Errorf(ctx, `unexpected type %T from directive, should be graphql.Marshaler`, tmp) + return graphql.Null +{{end}} + +{{ if .Directives.LocationDirectives "QUERY" }} +func (ec *executionContext) _queryMiddleware(ctx context.Context, obj *ast.OperationDefinition, next func(ctx context.Context) (interface{}, error)) graphql.Marshaler { + {{ template "queryDirectives" .Directives.LocationDirectives "QUERY" }} +} +{{ end }} + +{{ if .Directives.LocationDirectives "MUTATION" }} +func (ec *executionContext) _mutationMiddleware(ctx context.Context, obj *ast.OperationDefinition, next func(ctx context.Context) (interface{}, error)) graphql.Marshaler { + {{ template "queryDirectives" .Directives.LocationDirectives "MUTATION" }} +} +{{ end }} + +{{ if .Directives.LocationDirectives "SUBSCRIPTION" }} +func (ec *executionContext) _subscriptionMiddleware(ctx context.Context, obj *ast.OperationDefinition, next func(ctx context.Context) (interface{}, error)) func() graphql.Marshaler { + for _, d := range obj.Directives { + switch d.Name { + {{- range $directive := .Directives.LocationDirectives "SUBSCRIPTION" }} + case "{{$directive.Name}}": + {{- if $directive.Args }} + rawArgs := d.ArgumentMap(ec.Variables) + args, err := ec.{{ $directive.ArgsFunc }}(ctx,rawArgs) + if err != nil { + ec.Error(ctx, err) + return func() graphql.Marshaler { + return graphql.Null + } + } + {{- end }} + n := next + next = func(ctx context.Context) (interface{}, error) { + if ec.directives.{{$directive.Name|ucFirst}} == nil { + return nil, errors.New("directive {{$directive.Name}} is not implemented") + } + return ec.directives.{{$directive.Name|ucFirst}}({{$directive.CallArgs}}) + } + {{- end }} + } + } + tmp, err := next(ctx) + if err != nil { + ec.Error(ctx, err) + return func() graphql.Marshaler { + return graphql.Null + } + } + if data, ok := tmp.(func() graphql.Marshaler); ok { + return data + } + ec.Errorf(ctx, `unexpected type %T from directive, should be graphql.Marshaler`, tmp) + return func() graphql.Marshaler { + return graphql.Null + } +} +{{ end }} + +{{ if .Directives.LocationDirectives "FIELD" }} + func (ec *executionContext) _fieldMiddleware(ctx context.Context, obj interface{}, next graphql.Resolver) interface{} { + {{- if .Directives.LocationDirectives "FIELD" }} + fc := graphql.GetFieldContext(ctx) + for _, d := range fc.Field.Directives { + switch d.Name { + {{- range $directive := .Directives.LocationDirectives "FIELD" }} + case "{{$directive.Name}}": + {{- if $directive.Args }} + rawArgs := d.ArgumentMap(ec.Variables) + args, err := ec.{{ $directive.ArgsFunc }}(ctx,rawArgs) + if err != nil { + ec.Error(ctx, err) + return nil + } + {{- end }} + n := next + next = func(ctx context.Context) (interface{}, error) { + if ec.directives.{{$directive.Name|ucFirst}} == nil { + return nil, errors.New("directive {{$directive.Name}} is not implemented") + } + return ec.directives.{{$directive.Name|ucFirst}}({{$directive.CallArgs}}) + } + {{- end }} + } + } + {{- end }} + res, err := ec.ResolverMiddleware(ctx, next) + if err != nil { + ec.Error(ctx, err) + return nil + } + return res + } +{{ end }} diff --git a/vendor/github.com/99designs/gqlgen/codegen/field.go b/vendor/github.com/99designs/gqlgen/codegen/field.go new file mode 100644 index 0000000..867215e --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/codegen/field.go @@ -0,0 +1,556 @@ +package codegen + +import ( + "errors" + "fmt" + "go/types" + "log" + "reflect" + "strconv" + "strings" + + "github.com/99designs/gqlgen/codegen/config" + "github.com/99designs/gqlgen/codegen/templates" + "github.com/vektah/gqlparser/v2/ast" +) + +type Field struct { + *ast.FieldDefinition + + TypeReference *config.TypeReference + GoFieldType GoFieldType // The field type in go, if any + GoReceiverName string // The name of method & var receiver in go, if any + GoFieldName string // The name of the method or var in go, if any + IsResolver bool // Does this field need a resolver + Args []*FieldArgument // A list of arguments to be passed to this field + MethodHasContext bool // If this is bound to a go method, does the method also take a context + NoErr bool // If this is bound to a go method, does that method have an error as the second argument + VOkFunc bool // If this is bound to a go method, is it of shape (interface{}, bool) + Object *Object // A link back to the parent object + Default interface{} // The default value + Stream bool // does this field return a channel? + Directives []*Directive +} + +func (b *builder) buildField(obj *Object, field *ast.FieldDefinition) (*Field, error) { + dirs, err := b.getDirectives(field.Directives) + if err != nil { + return nil, err + } + + f := Field{ + FieldDefinition: field, + Object: obj, + Directives: dirs, + GoFieldName: templates.ToGo(field.Name), + GoFieldType: GoFieldVariable, + GoReceiverName: "obj", + } + + if field.DefaultValue != nil { + var err error + f.Default, err = field.DefaultValue.Value(nil) + if err != nil { + return nil, fmt.Errorf("default value %s is not valid: %w", field.Name, err) + } + } + + for _, arg := range field.Arguments { + newArg, err := b.buildArg(obj, arg) + if err != nil { + return nil, err + } + f.Args = append(f.Args, newArg) + } + + if err = b.bindField(obj, &f); err != nil { + f.IsResolver = true + if errors.Is(err, config.ErrTypeNotFound) { + return nil, err + } + log.Println(err.Error()) + } + + if f.IsResolver && !f.TypeReference.IsPtr() && f.TypeReference.IsStruct() { + f.TypeReference = b.Binder.PointerTo(f.TypeReference) + } + + return &f, nil +} + +func (b *builder) bindField(obj *Object, f *Field) (errret error) { + defer func() { + if f.TypeReference == nil { + tr, err := b.Binder.TypeReference(f.Type, nil) + if err != nil { + errret = err + } + f.TypeReference = tr + } + if f.TypeReference != nil { + dirs, err := b.getDirectives(f.TypeReference.Definition.Directives) + if err != nil { + errret = err + } + for _, dir := range obj.Directives { + if dir.IsLocation(ast.LocationInputObject) { + dirs = append(dirs, dir) + } + } + f.Directives = append(dirs, f.Directives...) + } + }() + + f.Stream = obj.Stream + + switch { + case f.Name == "__schema": + f.GoFieldType = GoFieldMethod + f.GoReceiverName = "ec" + f.GoFieldName = "introspectSchema" + return nil + case f.Name == "__type": + f.GoFieldType = GoFieldMethod + f.GoReceiverName = "ec" + f.GoFieldName = "introspectType" + return nil + case f.Name == "_entities": + f.GoFieldType = GoFieldMethod + f.GoReceiverName = "ec" + f.GoFieldName = "__resolve_entities" + f.MethodHasContext = true + f.NoErr = true + return nil + case f.Name == "_service": + f.GoFieldType = GoFieldMethod + f.GoReceiverName = "ec" + f.GoFieldName = "__resolve__service" + f.MethodHasContext = true + return nil + case obj.Root: + f.IsResolver = true + return nil + case b.Config.Models[obj.Name].Fields[f.Name].Resolver: + f.IsResolver = true + return nil + case obj.Type == config.MapType: + f.GoFieldType = GoFieldMap + return nil + case b.Config.Models[obj.Name].Fields[f.Name].FieldName != "": + f.GoFieldName = b.Config.Models[obj.Name].Fields[f.Name].FieldName + } + + target, err := b.findBindTarget(obj.Type.(*types.Named), f.GoFieldName) + if err != nil { + return err + } + + pos := b.Binder.ObjectPosition(target) + + switch target := target.(type) { + case nil: + objPos := b.Binder.TypePosition(obj.Type) + return fmt.Errorf( + "%s:%d adding resolver method for %s.%s, nothing matched", + objPos.Filename, + objPos.Line, + obj.Name, + f.Name, + ) + + case *types.Func: + sig := target.Type().(*types.Signature) + if sig.Results().Len() == 1 { + f.NoErr = true + } else if s := sig.Results(); s.Len() == 2 && s.At(1).Type().String() == "bool" { + f.VOkFunc = true + } else if sig.Results().Len() != 2 { + return fmt.Errorf("method has wrong number of args") + } + params := sig.Params() + // If the first argument is the context, remove it from the comparison and set + // the MethodHasContext flag so that the context will be passed to this model's method + if params.Len() > 0 && params.At(0).Type().String() == "context.Context" { + f.MethodHasContext = true + vars := make([]*types.Var, params.Len()-1) + for i := 1; i < params.Len(); i++ { + vars[i-1] = params.At(i) + } + params = types.NewTuple(vars...) + } + + // Try to match target function's arguments with GraphQL field arguments + newArgs, err := b.bindArgs(f, params) + if err != nil { + return fmt.Errorf("%s:%d: %w", pos.Filename, pos.Line, err) + } + + // Try to match target function's return types with GraphQL field return type + result := sig.Results().At(0) + tr, err := b.Binder.TypeReference(f.Type, result.Type()) + if err != nil { + return err + } + + // success, args and return type match. Bind to method + f.GoFieldType = GoFieldMethod + f.GoReceiverName = "obj" + f.GoFieldName = target.Name() + f.Args = newArgs + f.TypeReference = tr + + return nil + + case *types.Var: + tr, err := b.Binder.TypeReference(f.Type, target.Type()) + if err != nil { + return err + } + + // success, bind to var + f.GoFieldType = GoFieldVariable + f.GoReceiverName = "obj" + f.GoFieldName = target.Name() + f.TypeReference = tr + + return nil + default: + panic(fmt.Errorf("unknown bind target %T for %s", target, f.Name)) + } +} + +// findBindTarget attempts to match the name to a field or method on a Type +// with the following priorites: +// 1. Any Fields with a struct tag (see config.StructTag). Errors if more than one match is found +// 2. Any method or field with a matching name. Errors if more than one match is found +// 3. Same logic again for embedded fields +func (b *builder) findBindTarget(t types.Type, name string) (types.Object, error) { + // NOTE: a struct tag will override both methods and fields + // Bind to struct tag + found, err := b.findBindStructTagTarget(t, name) + if found != nil || err != nil { + return found, err + } + + // Search for a method to bind to + foundMethod, err := b.findBindMethodTarget(t, name) + if err != nil { + return nil, err + } + + // Search for a field to bind to + foundField, err := b.findBindFieldTarget(t, name) + if err != nil { + return nil, err + } + + switch { + case foundField == nil && foundMethod != nil: + // Bind to method + return foundMethod, nil + case foundField != nil && foundMethod == nil: + // Bind to field + return foundField, nil + case foundField != nil && foundMethod != nil: + // Error + return nil, fmt.Errorf("found more than one way to bind for %s", name) + } + + // Search embeds + return b.findBindEmbedsTarget(t, name) +} + +func (b *builder) findBindStructTagTarget(in types.Type, name string) (types.Object, error) { + if b.Config.StructTag == "" { + return nil, nil + } + + switch t := in.(type) { + case *types.Named: + return b.findBindStructTagTarget(t.Underlying(), name) + case *types.Struct: + var found types.Object + for i := 0; i < t.NumFields(); i++ { + field := t.Field(i) + if !field.Exported() || field.Embedded() { + continue + } + tags := reflect.StructTag(t.Tag(i)) + if val, ok := tags.Lookup(b.Config.StructTag); ok && equalFieldName(val, name) { + if found != nil { + return nil, fmt.Errorf("tag %s is ambigious; multiple fields have the same tag value of %s", b.Config.StructTag, val) + } + + found = field + } + } + + return found, nil + } + + return nil, nil +} + +func (b *builder) findBindMethodTarget(in types.Type, name string) (types.Object, error) { + switch t := in.(type) { + case *types.Named: + if _, ok := t.Underlying().(*types.Interface); ok { + return b.findBindMethodTarget(t.Underlying(), name) + } + + return b.findBindMethoderTarget(t.Method, t.NumMethods(), name) + case *types.Interface: + // FIX-ME: Should use ExplicitMethod here? What's the difference? + return b.findBindMethoderTarget(t.Method, t.NumMethods(), name) + } + + return nil, nil +} + +func (b *builder) findBindMethoderTarget(methodFunc func(i int) *types.Func, methodCount int, name string) (types.Object, error) { + var found types.Object + for i := 0; i < methodCount; i++ { + method := methodFunc(i) + if !method.Exported() || !strings.EqualFold(method.Name(), name) { + continue + } + + if found != nil { + return nil, fmt.Errorf("found more than one matching method to bind for %s", name) + } + + found = method + } + + return found, nil +} + +func (b *builder) findBindFieldTarget(in types.Type, name string) (types.Object, error) { + switch t := in.(type) { + case *types.Named: + return b.findBindFieldTarget(t.Underlying(), name) + case *types.Struct: + var found types.Object + for i := 0; i < t.NumFields(); i++ { + field := t.Field(i) + if !field.Exported() || !equalFieldName(field.Name(), name) { + continue + } + + if found != nil { + return nil, fmt.Errorf("found more than one matching field to bind for %s", name) + } + + found = field + } + + return found, nil + } + + return nil, nil +} + +func (b *builder) findBindEmbedsTarget(in types.Type, name string) (types.Object, error) { + switch t := in.(type) { + case *types.Named: + return b.findBindEmbedsTarget(t.Underlying(), name) + case *types.Struct: + return b.findBindStructEmbedsTarget(t, name) + case *types.Interface: + return b.findBindInterfaceEmbedsTarget(t, name) + } + + return nil, nil +} + +func (b *builder) findBindStructEmbedsTarget(strukt *types.Struct, name string) (types.Object, error) { + var found types.Object + for i := 0; i < strukt.NumFields(); i++ { + field := strukt.Field(i) + if !field.Embedded() { + continue + } + + fieldType := field.Type() + if ptr, ok := fieldType.(*types.Pointer); ok { + fieldType = ptr.Elem() + } + + f, err := b.findBindTarget(fieldType, name) + if err != nil { + return nil, err + } + + if f != nil && found != nil { + return nil, fmt.Errorf("found more than one way to bind for %s", name) + } + + if f != nil { + found = f + } + } + + return found, nil +} + +func (b *builder) findBindInterfaceEmbedsTarget(iface *types.Interface, name string) (types.Object, error) { + var found types.Object + for i := 0; i < iface.NumEmbeddeds(); i++ { + embeddedType := iface.EmbeddedType(i) + + f, err := b.findBindTarget(embeddedType, name) + if err != nil { + return nil, err + } + + if f != nil && found != nil { + return nil, fmt.Errorf("found more than one way to bind for %s", name) + } + + if f != nil { + found = f + } + } + + return found, nil +} + +func (f *Field) HasDirectives() bool { + return len(f.ImplDirectives()) > 0 +} + +func (f *Field) DirectiveObjName() string { + if f.Object.Root { + return "nil" + } + return f.GoReceiverName +} + +func (f *Field) ImplDirectives() []*Directive { + var d []*Directive + loc := ast.LocationFieldDefinition + if f.Object.IsInputType() { + loc = ast.LocationInputFieldDefinition + } + for i := range f.Directives { + if !f.Directives[i].Builtin && + (f.Directives[i].IsLocation(loc, ast.LocationObject) || f.Directives[i].IsLocation(loc, ast.LocationInputObject)) { + d = append(d, f.Directives[i]) + } + } + return d +} + +func (f *Field) IsReserved() bool { + return strings.HasPrefix(f.Name, "__") +} + +func (f *Field) IsMethod() bool { + return f.GoFieldType == GoFieldMethod +} + +func (f *Field) IsVariable() bool { + return f.GoFieldType == GoFieldVariable +} + +func (f *Field) IsMap() bool { + return f.GoFieldType == GoFieldMap +} + +func (f *Field) IsConcurrent() bool { + if f.Object.DisableConcurrency { + return false + } + return f.MethodHasContext || f.IsResolver +} + +func (f *Field) GoNameUnexported() string { + return templates.ToGoPrivate(f.Name) +} + +func (f *Field) ShortInvocation() string { + if f.Object.Kind == ast.InputObject { + return fmt.Sprintf("%s().%s(ctx, &it, data)", strings.Title(f.Object.Definition.Name), f.GoFieldName) + } + return fmt.Sprintf("%s().%s(%s)", strings.Title(f.Object.Definition.Name), f.GoFieldName, f.CallArgs()) +} + +func (f *Field) ArgsFunc() string { + if len(f.Args) == 0 { + return "" + } + + return "field_" + f.Object.Definition.Name + "_" + f.Name + "_args" +} + +func (f *Field) ResolverType() string { + if !f.IsResolver { + return "" + } + + return fmt.Sprintf("%s().%s(%s)", f.Object.Definition.Name, f.GoFieldName, f.CallArgs()) +} + +func (f *Field) ShortResolverDeclaration() string { + if f.Object.Kind == ast.InputObject { + return fmt.Sprintf("(ctx context.Context, obj %s, data %s) error", + templates.CurrentImports.LookupType(f.Object.Reference()), + templates.CurrentImports.LookupType(f.TypeReference.GO), + ) + } + + res := "(ctx context.Context" + + if !f.Object.Root { + res += fmt.Sprintf(", obj %s", templates.CurrentImports.LookupType(f.Object.Reference())) + } + for _, arg := range f.Args { + res += fmt.Sprintf(", %s %s", arg.VarName, templates.CurrentImports.LookupType(arg.TypeReference.GO)) + } + + result := templates.CurrentImports.LookupType(f.TypeReference.GO) + if f.Object.Stream { + result = "<-chan " + result + } + + res += fmt.Sprintf(") (%s, error)", result) + return res +} + +func (f *Field) ComplexitySignature() string { + res := "func(childComplexity int" + for _, arg := range f.Args { + res += fmt.Sprintf(", %s %s", arg.VarName, templates.CurrentImports.LookupType(arg.TypeReference.GO)) + } + res += ") int" + return res +} + +func (f *Field) ComplexityArgs() string { + args := make([]string, len(f.Args)) + for i, arg := range f.Args { + args[i] = "args[" + strconv.Quote(arg.Name) + "].(" + templates.CurrentImports.LookupType(arg.TypeReference.GO) + ")" + } + + return strings.Join(args, ", ") +} + +func (f *Field) CallArgs() string { + args := make([]string, 0, len(f.Args)+2) + + if f.IsResolver { + args = append(args, "rctx") + + if !f.Object.Root { + args = append(args, "obj") + } + } else if f.MethodHasContext { + args = append(args, "ctx") + } + + for _, arg := range f.Args { + args = append(args, "args["+strconv.Quote(arg.Name)+"].("+templates.CurrentImports.LookupType(arg.TypeReference.GO)+")") + } + + return strings.Join(args, ", ") +} diff --git a/vendor/github.com/99designs/gqlgen/codegen/field.gotpl b/vendor/github.com/99designs/gqlgen/codegen/field.gotpl new file mode 100644 index 0000000..0c6beca --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/codegen/field.gotpl @@ -0,0 +1,129 @@ +{{- range $object := .Objects }}{{- range $field := $object.Fields }} + +func (ec *executionContext) _{{$object.Name}}_{{$field.Name}}(ctx context.Context, field graphql.CollectedField{{ if not $object.Root }}, obj {{$object.Reference | ref}}{{end}}) (ret {{ if $object.Stream }}func(){{ end }}graphql.Marshaler) { + {{- $null := "graphql.Null" }} + {{- if $object.Stream }} + {{- $null = "nil" }} + {{- end }} + defer func () { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = {{ $null }} + } + }() + fc := &graphql.FieldContext{ + Object: {{$object.Name|quote}}, + Field: field, + Args: nil, + IsMethod: {{or $field.IsMethod $field.IsResolver}}, + IsResolver: {{ $field.IsResolver }}, + } + + ctx = graphql.WithFieldContext(ctx, fc) + {{- if $field.Args }} + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.{{ $field.ArgsFunc }}(ctx,rawArgs) + if err != nil { + ec.Error(ctx, err) + return {{ $null }} + } + fc.Args = args + {{- end }} + {{- if $.AllDirectives.LocationDirectives "FIELD" }} + resTmp := ec._fieldMiddleware(ctx, {{if $object.Root}}nil{{else}}obj{{end}}, func(rctx context.Context) (interface{}, error) { + {{ template "field" $field }} + }) + {{ else }} + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + {{ template "field" $field }} + }) + if err != nil { + ec.Error(ctx, err) + return {{ $null }} + } + {{- end }} + if resTmp == nil { + {{- if $field.TypeReference.GQL.NonNull }} + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + {{- end }} + return {{ $null }} + } + {{- if $object.Stream }} + return func() graphql.Marshaler { + res, ok := <-resTmp.(<-chan {{$field.TypeReference.GO | ref}}) + if !ok { + return nil + } + return graphql.WriterFunc(func(w io.Writer) { + w.Write([]byte{'{'}) + graphql.MarshalString(field.Alias).MarshalGQL(w) + w.Write([]byte{':'}) + ec.{{ $field.TypeReference.MarshalFunc }}(ctx, field.Selections, res).MarshalGQL(w) + w.Write([]byte{'}'}) + }) + } + {{- else }} + res := resTmp.({{$field.TypeReference.GO | ref}}) + fc.Result = res + return ec.{{ $field.TypeReference.MarshalFunc }}(ctx, field.Selections, res) + {{- end }} +} + +{{- end }}{{- end}} + +{{ define "field" }} + {{- if .HasDirectives -}} + directive0 := func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + {{ template "fieldDefinition" . }} + } + {{ template "implDirectives" . }} + tmp, err := directive{{.ImplDirectives|len}}(rctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if tmp == nil { + return nil, nil + } + if data, ok := tmp.({{if .Stream}}<-chan {{end}}{{ .TypeReference.GO | ref }}) ; ok { + return data, nil + } + return nil, fmt.Errorf(`unexpected type %T from directive, should be {{if .Stream}}<-chan {{end}}{{ .TypeReference.GO }}`, tmp) + {{- else -}} + ctx = rctx // use context from middleware stack in children + {{ template "fieldDefinition" . }} + {{- end -}} +{{ end }} + +{{ define "fieldDefinition" }} + {{- if .IsResolver -}} + return ec.resolvers.{{ .ShortInvocation }} + {{- else if .IsMap -}} + switch v := {{.GoReceiverName}}[{{.Name|quote}}].(type) { + case {{if .Stream}}<-chan {{end}}{{.TypeReference.GO | ref}}: + return v, nil + case {{if .Stream}}<-chan {{end}}{{.TypeReference.Elem.GO | ref}}: + return &v, nil + case nil: + return ({{.TypeReference.GO | ref}})(nil), nil + default: + return nil, fmt.Errorf("unexpected type %T for field %s", v, {{ .Name | quote}}) + } + {{- else if .IsMethod -}} + {{- if .VOkFunc -}} + v, ok := {{.GoReceiverName}}.{{.GoFieldName}}({{ .CallArgs }}) + if !ok { + return nil, nil + } + return v, nil + {{- else if .NoErr -}} + return {{.GoReceiverName}}.{{.GoFieldName}}({{ .CallArgs }}), nil + {{- else -}} + return {{.GoReceiverName}}.{{.GoFieldName}}({{ .CallArgs }}) + {{- end -}} + {{- else if .IsVariable -}} + return {{.GoReceiverName}}.{{.GoFieldName}}, nil + {{- end }} +{{- end }} diff --git a/vendor/github.com/99designs/gqlgen/codegen/generate.go b/vendor/github.com/99designs/gqlgen/codegen/generate.go new file mode 100644 index 0000000..cd558fd --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/codegen/generate.go @@ -0,0 +1,214 @@ +package codegen + +import ( + "errors" + "fmt" + "io/ioutil" + "path/filepath" + "runtime" + "strings" + + "github.com/vektah/gqlparser/v2/ast" + + "github.com/99designs/gqlgen/codegen/config" + "github.com/99designs/gqlgen/codegen/templates" +) + +func GenerateCode(data *Data) error { + if !data.Config.Exec.IsDefined() { + return fmt.Errorf("missing exec config") + } + + switch data.Config.Exec.Layout { + case config.ExecLayoutSingleFile: + return generateSingleFile(data) + case config.ExecLayoutFollowSchema: + return generatePerSchema(data) + } + + return fmt.Errorf("unrecognized exec layout %s", data.Config.Exec.Layout) +} + +func generateSingleFile(data *Data) error { + return templates.Render(templates.Options{ + PackageName: data.Config.Exec.Package, + Filename: data.Config.Exec.Filename, + Data: data, + RegionTags: true, + GeneratedHeader: true, + Packages: data.Config.Packages, + }) +} + +func generatePerSchema(data *Data) error { + err := generateRootFile(data) + if err != nil { + return err + } + + builds := map[string]*Data{} + + err = addObjects(data, &builds) + if err != nil { + return err + } + + err = addInputs(data, &builds) + if err != nil { + return err + } + + err = addInterfaces(data, &builds) + if err != nil { + return err + } + + err = addReferencedTypes(data, &builds) + if err != nil { + return err + } + + for filename, build := range builds { + if filename == "" { + continue + } + + dir := data.Config.Exec.DirName + path := filepath.Join(dir, filename) + + err = templates.Render(templates.Options{ + PackageName: data.Config.Exec.Package, + Filename: path, + Data: build, + RegionTags: true, + GeneratedHeader: true, + Packages: data.Config.Packages, + }) + if err != nil { + return err + } + } + + return nil +} + +func filename(p *ast.Position, config *config.Config) string { + name := "common!" + if p != nil && p.Src != nil { + gqlname := filepath.Base(p.Src.Name) + ext := filepath.Ext(p.Src.Name) + name = strings.TrimSuffix(gqlname, ext) + } + + filenameTempl := config.Exec.FilenameTemplate + if filenameTempl == "" { + filenameTempl = "{name}.generated.go" + } + + return strings.ReplaceAll(filenameTempl, "{name}", name) +} + +func addBuild(filename string, p *ast.Position, data *Data, builds *map[string]*Data) { + buildConfig := *data.Config + if p != nil { + buildConfig.Sources = []*ast.Source{p.Src} + } + + (*builds)[filename] = &Data{ + Config: &buildConfig, + QueryRoot: data.QueryRoot, + MutationRoot: data.MutationRoot, + SubscriptionRoot: data.SubscriptionRoot, + AllDirectives: data.AllDirectives, + } +} + +// Root file contains top-level definitions that should not be duplicated across the generated +// files for each schema file. +func generateRootFile(data *Data) error { + dir := data.Config.Exec.DirName + path := filepath.Join(dir, "root_.generated.go") + + _, thisFile, _, _ := runtime.Caller(0) + rootDir := filepath.Dir(thisFile) + templatePath := filepath.Join(rootDir, "root_.gotpl") + templateBytes, err := ioutil.ReadFile(templatePath) + if err != nil { + return err + } + template := string(templateBytes) + + return templates.Render(templates.Options{ + PackageName: data.Config.Exec.Package, + Template: template, + Filename: path, + Data: data, + RegionTags: false, + GeneratedHeader: true, + Packages: data.Config.Packages, + }) +} + +func addObjects(data *Data, builds *map[string]*Data) error { + for _, o := range data.Objects { + filename := filename(o.Position, data.Config) + if (*builds)[filename] == nil { + addBuild(filename, o.Position, data, builds) + } + + (*builds)[filename].Objects = append((*builds)[filename].Objects, o) + } + return nil +} + +func addInputs(data *Data, builds *map[string]*Data) error { + for _, in := range data.Inputs { + filename := filename(in.Position, data.Config) + if (*builds)[filename] == nil { + addBuild(filename, in.Position, data, builds) + } + + (*builds)[filename].Inputs = append((*builds)[filename].Inputs, in) + } + return nil +} + +func addInterfaces(data *Data, builds *map[string]*Data) error { + for k, inf := range data.Interfaces { + filename := filename(inf.Position, data.Config) + if (*builds)[filename] == nil { + addBuild(filename, inf.Position, data, builds) + } + build := (*builds)[filename] + + if build.Interfaces == nil { + build.Interfaces = map[string]*Interface{} + } + if build.Interfaces[k] != nil { + return errors.New("conflicting interface keys") + } + + build.Interfaces[k] = inf + } + return nil +} + +func addReferencedTypes(data *Data, builds *map[string]*Data) error { + for k, rt := range data.ReferencedTypes { + filename := filename(rt.Definition.Position, data.Config) + if (*builds)[filename] == nil { + addBuild(filename, rt.Definition.Position, data, builds) + } + build := (*builds)[filename] + + if build.ReferencedTypes == nil { + build.ReferencedTypes = map[string]*config.TypeReference{} + } + if build.ReferencedTypes[k] != nil { + return errors.New("conflicting referenced type keys") + } + + build.ReferencedTypes[k] = rt + } + return nil +} diff --git a/vendor/github.com/99designs/gqlgen/codegen/generated!.gotpl b/vendor/github.com/99designs/gqlgen/codegen/generated!.gotpl new file mode 100644 index 0000000..bf59dac --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/codegen/generated!.gotpl @@ -0,0 +1,235 @@ +{{ reserveImport "context" }} +{{ reserveImport "fmt" }} +{{ reserveImport "io" }} +{{ reserveImport "strconv" }} +{{ reserveImport "time" }} +{{ reserveImport "sync" }} +{{ reserveImport "sync/atomic" }} +{{ reserveImport "errors" }} +{{ reserveImport "bytes" }} + +{{ reserveImport "github.com/vektah/gqlparser/v2" "gqlparser" }} +{{ reserveImport "github.com/vektah/gqlparser/v2/ast" }} +{{ reserveImport "github.com/99designs/gqlgen/graphql" }} +{{ reserveImport "github.com/99designs/gqlgen/graphql/introspection" }} + + +{{ if eq .Config.Exec.Layout "single-file" }} + // NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface. + func NewExecutableSchema(cfg Config) graphql.ExecutableSchema { + return &executableSchema{ + resolvers: cfg.Resolvers, + directives: cfg.Directives, + complexity: cfg.Complexity, + } + } + + type Config struct { + Resolvers ResolverRoot + Directives DirectiveRoot + Complexity ComplexityRoot + } + + type ResolverRoot interface { + {{- range $object := .Objects -}} + {{ if $object.HasResolvers -}} + {{ucFirst $object.Name}}() {{ucFirst $object.Name}}Resolver + {{ end }} + {{- end }} + {{- range $object := .Inputs -}} + {{ if $object.HasResolvers -}} + {{ucFirst $object.Name}}() {{ucFirst $object.Name}}Resolver + {{ end }} +{{- end }} +} + + type DirectiveRoot struct { + {{ range $directive := .Directives }} + {{- $directive.Declaration }} + {{ end }} + } + + type ComplexityRoot struct { + {{ range $object := .Objects }} + {{ if not $object.IsReserved -}} + {{ ucFirst $object.Name }} struct { + {{ range $_, $fields := $object.UniqueFields }} + {{- $field := index $fields 0 -}} + {{ if not $field.IsReserved -}} + {{ $field.GoFieldName }} {{ $field.ComplexitySignature }} + {{ end }} + {{- end }} + } + {{- end }} + {{ end }} + } +{{ end }} + +{{ range $object := .Objects -}} + {{ if $object.HasResolvers }} + type {{ucFirst $object.Name}}Resolver interface { + {{ range $field := $object.Fields -}} + {{- if $field.IsResolver }} + {{- $field.GoFieldName}}{{ $field.ShortResolverDeclaration }} + {{- end }} + {{ end }} + } + {{- end }} +{{- end }} + +{{ range $object := .Inputs -}} + {{ if $object.HasResolvers }} + type {{$object.Name}}Resolver interface { + {{ range $field := $object.Fields -}} + {{- if $field.IsResolver }} + {{- $field.GoFieldName}}{{ $field.ShortResolverDeclaration }} + {{- end }} + {{ end }} + } + {{- end }} +{{- end }} + +{{ if eq .Config.Exec.Layout "single-file" }} + type executableSchema struct { + resolvers ResolverRoot + directives DirectiveRoot + complexity ComplexityRoot + } + + func (e *executableSchema) Schema() *ast.Schema { + return parsedSchema + } + + func (e *executableSchema) Complexity(typeName, field string, childComplexity int, rawArgs map[string]interface{}) (int, bool) { + ec := executionContext{nil, e} + _ = ec + switch typeName + "." + field { + {{ range $object := .Objects }} + {{ if not $object.IsReserved }} + {{ range $_, $fields := $object.UniqueFields }} + {{- $len := len $fields }} + {{- range $i, $field := $fields }} + {{- $last := eq (add $i 1) $len }} + {{- if not $field.IsReserved }} + {{- if eq $i 0 }}case {{ end }}"{{$object.Name}}.{{$field.Name}}"{{ if not $last }},{{ else }}: + if e.complexity.{{ucFirst $object.Name}}.{{$field.GoFieldName}} == nil { + break + } + {{ if $field.Args }} + args, err := ec.{{ $field.ArgsFunc }}(context.TODO(),rawArgs) + if err != nil { + return 0, false + } + {{ end }} + return e.complexity.{{ucFirst $object.Name}}.{{$field.GoFieldName}}(childComplexity{{if $field.Args}}, {{$field.ComplexityArgs}} {{ end }}), true + {{ end }} + {{- end }} + {{- end }} + {{ end }} + {{ end }} + {{ end }} + } + return 0, false + } + + func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { + rc := graphql.GetOperationContext(ctx) + ec := executionContext{rc, e} + first := true + + switch rc.Operation.Operation { + {{- if .QueryRoot }} case ast.Query: + return func(ctx context.Context) *graphql.Response { + if !first { return nil } + first = false + {{ if .Directives.LocationDirectives "QUERY" -}} + data := ec._queryMiddleware(ctx, rc.Operation, func(ctx context.Context) (interface{}, error){ + return ec._{{.QueryRoot.Name}}(ctx, rc.Operation.SelectionSet), nil + }) + {{- else -}} + data := ec._{{.QueryRoot.Name}}(ctx, rc.Operation.SelectionSet) + {{- end }} + var buf bytes.Buffer + data.MarshalGQL(&buf) + + return &graphql.Response{ + Data: buf.Bytes(), + } + } + {{ end }} + + {{- if .MutationRoot }} case ast.Mutation: + return func(ctx context.Context) *graphql.Response { + if !first { return nil } + first = false + {{ if .Directives.LocationDirectives "MUTATION" -}} + data := ec._mutationMiddleware(ctx, rc.Operation, func(ctx context.Context) (interface{}, error){ + return ec._{{.MutationRoot.Name}}(ctx, rc.Operation.SelectionSet), nil + }) + {{- else -}} + data := ec._{{.MutationRoot.Name}}(ctx, rc.Operation.SelectionSet) + {{- end }} + var buf bytes.Buffer + data.MarshalGQL(&buf) + + return &graphql.Response{ + Data: buf.Bytes(), + } + } + {{ end }} + + {{- if .SubscriptionRoot }} case ast.Subscription: + {{ if .Directives.LocationDirectives "SUBSCRIPTION" -}} + next := ec._subscriptionMiddleware(ctx, rc.Operation, func(ctx context.Context) (interface{}, error){ + return ec._{{.SubscriptionRoot.Name}}(ctx, rc.Operation.SelectionSet),nil + }) + {{- else -}} + next := ec._{{.SubscriptionRoot.Name}}(ctx, rc.Operation.SelectionSet) + {{- end }} + + var buf bytes.Buffer + return func(ctx context.Context) *graphql.Response { + buf.Reset() + data := next() + + if data == nil { + return nil + } + data.MarshalGQL(&buf) + + return &graphql.Response{ + Data: buf.Bytes(), + } + } + {{ end }} + default: + return graphql.OneShot(graphql.ErrorResponse(ctx, "unsupported GraphQL operation")) + } + } + + type executionContext struct { + *graphql.OperationContext + *executableSchema + } + + func (ec *executionContext) introspectSchema() (*introspection.Schema, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapSchema(parsedSchema), nil + } + + func (ec *executionContext) introspectType(name string) (*introspection.Type, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapTypeFromDef(parsedSchema, parsedSchema.Types[name]), nil + } + + var sources = []*ast.Source{ + {{- range $source := .Config.Sources }} + {Name: {{$source.Name|quote}}, Input: {{$source.Input|rawQuote}}, BuiltIn: {{$source.BuiltIn}}}, + {{- end }} + } + var parsedSchema = gqlparser.MustLoadSchema(sources...) +{{ end }} diff --git a/vendor/github.com/99designs/gqlgen/codegen/input.gotpl b/vendor/github.com/99designs/gqlgen/codegen/input.gotpl new file mode 100644 index 0000000..5694bcd --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/codegen/input.gotpl @@ -0,0 +1,72 @@ +{{- range $input := .Inputs }} + {{- if not .HasUnmarshal }} + func (ec *executionContext) unmarshalInput{{ .Name }}(ctx context.Context, obj interface{}) ({{.Type | ref}}, error) { + var it {{.Type | ref}} + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + {{ range $field := .Fields}} + {{- if notNil "Default" $field }} + if _, present := asMap[{{$field.Name|quote}}] ; !present { + asMap[{{$field.Name|quote}}] = {{ $field.Default | dump }} + } + {{- end}} + {{- end }} + + for k, v := range asMap { + switch k { + {{- range $field := .Fields }} + case {{$field.Name|quote}}: + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField({{$field.Name|quote}})) + {{- if $field.ImplDirectives }} + directive0 := func(ctx context.Context) (interface{}, error) { return ec.{{ $field.TypeReference.UnmarshalFunc }}(ctx, v) } + {{ template "implDirectives" $field }} + tmp, err := directive{{$field.ImplDirectives|len}}(ctx) + if err != nil { + return it, graphql.ErrorOnPath(ctx, err) + } + if data, ok := tmp.({{ $field.TypeReference.GO | ref }}) ; ok { + {{- if $field.IsResolver }} + if err = ec.resolvers.{{ $field.ShortInvocation }}; err != nil { + return it, err + } + {{- else }} + it.{{$field.GoFieldName}} = data + {{- end }} + {{- if $field.TypeReference.IsNilable }} + {{- if not $field.IsResolver }} + } else if tmp == nil { + it.{{$field.GoFieldName}} = nil + {{- end }} + {{- end }} + } else { + err := fmt.Errorf(`unexpected type %T from directive, should be {{ $field.TypeReference.GO }}`, tmp) + return it, graphql.ErrorOnPath(ctx, err) + } + {{- else }} + {{- if $field.IsResolver }} + data, err := ec.{{ $field.TypeReference.UnmarshalFunc }}(ctx, v) + if err != nil { + return it, err + } + if err = ec.resolvers.{{ $field.ShortInvocation }}; err != nil { + return it, err + } + {{- else }} + it.{{$field.GoFieldName}}, err = ec.{{ $field.TypeReference.UnmarshalFunc }}(ctx, v) + if err != nil { + return it, err + } + {{- end }} + {{- end }} + {{- end }} + } + } + + return it, nil + } + {{- end }} +{{ end }} diff --git a/vendor/github.com/99designs/gqlgen/codegen/interface.go b/vendor/github.com/99designs/gqlgen/codegen/interface.go new file mode 100644 index 0000000..cdc4d4d --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/codegen/interface.go @@ -0,0 +1,87 @@ +package codegen + +import ( + "fmt" + "go/types" + + "github.com/vektah/gqlparser/v2/ast" + + "github.com/99designs/gqlgen/codegen/config" +) + +type Interface struct { + *ast.Definition + Type types.Type + Implementors []InterfaceImplementor + InTypemap bool +} + +type InterfaceImplementor struct { + *ast.Definition + + Type types.Type + TakeRef bool +} + +func (b *builder) buildInterface(typ *ast.Definition) (*Interface, error) { + obj, err := b.Binder.DefaultUserObject(typ.Name) + if err != nil { + panic(err) + } + + i := &Interface{ + Definition: typ, + Type: obj, + InTypemap: b.Config.Models.UserDefined(typ.Name), + } + + interfaceType, err := findGoInterface(i.Type) + if interfaceType == nil || err != nil { + return nil, fmt.Errorf("%s is not an interface", i.Type) + } + + for _, implementor := range b.Schema.GetPossibleTypes(typ) { + obj, err := b.Binder.DefaultUserObject(implementor.Name) + if err != nil { + return nil, fmt.Errorf("%s has no backing go type", implementor.Name) + } + + implementorType, err := findGoNamedType(obj) + if err != nil { + return nil, fmt.Errorf("can not find backing go type %s: %w", obj.String(), err) + } else if implementorType == nil { + return nil, fmt.Errorf("can not find backing go type %s", obj.String()) + } + + anyValid := false + + // first check if the value receiver can be nil, eg can we type switch on case Thing: + if types.Implements(implementorType, interfaceType) { + i.Implementors = append(i.Implementors, InterfaceImplementor{ + Definition: implementor, + Type: obj, + TakeRef: !types.IsInterface(obj), + }) + anyValid = true + } + + // then check if the pointer receiver can be nil, eg can we type switch on case *Thing: + if types.Implements(types.NewPointer(implementorType), interfaceType) { + i.Implementors = append(i.Implementors, InterfaceImplementor{ + Definition: implementor, + Type: types.NewPointer(obj), + }) + anyValid = true + } + + if !anyValid { + return nil, fmt.Errorf("%s does not satisfy the interface %s", implementorType.String(), i.Type.String()) + } + } + + return i, nil +} + +func (i *InterfaceImplementor) CanBeNil() bool { + return config.IsNilable(i.Type) +} diff --git a/vendor/github.com/99designs/gqlgen/codegen/interface.gotpl b/vendor/github.com/99designs/gqlgen/codegen/interface.gotpl new file mode 100644 index 0000000..e9d560c --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/codegen/interface.gotpl @@ -0,0 +1,21 @@ +{{- range $interface := .Interfaces }} + +func (ec *executionContext) _{{$interface.Name}}(ctx context.Context, sel ast.SelectionSet, obj {{$interface.Type | ref}}) graphql.Marshaler { + switch obj := (obj).(type) { + case nil: + return graphql.Null + {{- range $implementor := $interface.Implementors }} + case {{$implementor.Type | ref}}: + {{- if $implementor.CanBeNil }} + if obj == nil { + return graphql.Null + } + {{- end }} + return ec._{{$implementor.Name}}(ctx, sel, {{ if $implementor.TakeRef }}&{{ end }}obj) + {{- end }} + default: + panic(fmt.Errorf("unexpected type %T", obj)) + } +} + +{{- end }} diff --git a/vendor/github.com/99designs/gqlgen/codegen/object.go b/vendor/github.com/99designs/gqlgen/codegen/object.go new file mode 100644 index 0000000..6cf922d --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/codegen/object.go @@ -0,0 +1,169 @@ +package codegen + +import ( + "fmt" + "go/types" + "strconv" + "strings" + "unicode" + + "github.com/99designs/gqlgen/codegen/config" + "github.com/vektah/gqlparser/v2/ast" +) + +type GoFieldType int + +const ( + GoFieldUndefined GoFieldType = iota + GoFieldMethod + GoFieldVariable + GoFieldMap +) + +type Object struct { + *ast.Definition + + Type types.Type + ResolverInterface types.Type + Root bool + Fields []*Field + Implements []*ast.Definition + DisableConcurrency bool + Stream bool + Directives []*Directive +} + +func (b *builder) buildObject(typ *ast.Definition) (*Object, error) { + dirs, err := b.getDirectives(typ.Directives) + if err != nil { + return nil, fmt.Errorf("%s: %w", typ.Name, err) + } + + obj := &Object{ + Definition: typ, + Root: b.Schema.Query == typ || b.Schema.Mutation == typ || b.Schema.Subscription == typ, + DisableConcurrency: typ == b.Schema.Mutation, + Stream: typ == b.Schema.Subscription, + Directives: dirs, + ResolverInterface: types.NewNamed( + types.NewTypeName(0, b.Config.Exec.Pkg(), strings.Title(typ.Name)+"Resolver", nil), + nil, + nil, + ), + } + + if !obj.Root { + goObject, err := b.Binder.DefaultUserObject(typ.Name) + if err != nil { + return nil, err + } + obj.Type = goObject + } + + for _, intf := range b.Schema.GetImplements(typ) { + obj.Implements = append(obj.Implements, b.Schema.Types[intf.Name]) + } + + for _, field := range typ.Fields { + if strings.HasPrefix(field.Name, "__") { + continue + } + + var f *Field + f, err = b.buildField(obj, field) + if err != nil { + return nil, err + } + + obj.Fields = append(obj.Fields, f) + } + + return obj, nil +} + +func (o *Object) Reference() types.Type { + if config.IsNilable(o.Type) { + return o.Type + } + return types.NewPointer(o.Type) +} + +type Objects []*Object + +func (o *Object) Implementors() string { + satisfiedBy := strconv.Quote(o.Name) + for _, s := range o.Implements { + satisfiedBy += ", " + strconv.Quote(s.Name) + } + return "[]string{" + satisfiedBy + "}" +} + +func (o *Object) HasResolvers() bool { + for _, f := range o.Fields { + if f.IsResolver { + return true + } + } + return false +} + +func (o *Object) HasUnmarshal() bool { + if o.Type == config.MapType { + return true + } + for i := 0; i < o.Type.(*types.Named).NumMethods(); i++ { + if o.Type.(*types.Named).Method(i).Name() == "UnmarshalGQL" { + return true + } + } + return false +} + +func (o *Object) HasDirectives() bool { + if len(o.Directives) > 0 { + return true + } + for _, f := range o.Fields { + if f.HasDirectives() { + return true + } + } + + return false +} + +func (o *Object) IsConcurrent() bool { + for _, f := range o.Fields { + if f.IsConcurrent() { + return true + } + } + return false +} + +func (o *Object) IsReserved() bool { + return strings.HasPrefix(o.Definition.Name, "__") +} + +func (o *Object) Description() string { + return o.Definition.Description +} + +func (os Objects) ByName(name string) *Object { + for i, o := range os { + if strings.EqualFold(o.Definition.Name, name) { + return os[i] + } + } + return nil +} + +func ucFirst(s string) string { + if s == "" { + return "" + } + + r := []rune(s) + r[0] = unicode.ToUpper(r[0]) + return string(r) +} diff --git a/vendor/github.com/99designs/gqlgen/codegen/object.gotpl b/vendor/github.com/99designs/gqlgen/codegen/object.gotpl new file mode 100644 index 0000000..8cb9d28 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/codegen/object.gotpl @@ -0,0 +1,113 @@ +{{- range $object := .Objects }} + +var {{ $object.Name|lcFirst}}Implementors = {{$object.Implementors}} + +{{- if .Stream }} +func (ec *executionContext) _{{$object.Name}}(ctx context.Context, sel ast.SelectionSet) func() graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, {{$object.Name|lcFirst}}Implementors) + ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ + Object: {{$object.Name|quote}}, + }) + if len(fields) != 1 { + ec.Errorf(ctx, "must subscribe to exactly one stream") + return nil + } + + switch fields[0].Name { + {{- range $field := $object.Fields }} + case "{{$field.Name}}": + return ec._{{$object.Name}}_{{$field.Name}}(ctx, fields[0]) + {{- end }} + default: + panic("unknown field " + strconv.Quote(fields[0].Name)) + } +} +{{- else }} +func (ec *executionContext) _{{$object.Name}}(ctx context.Context, sel ast.SelectionSet{{ if not $object.Root }},obj {{$object.Reference | ref }}{{ end }}) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, {{$object.Name|lcFirst}}Implementors) + {{- if $object.Root }} + ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ + Object: {{$object.Name|quote}}, + }) + {{end}} + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + {{- if $object.Root }} + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + {{end}} + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString({{$object.Name|quote}}) + {{- range $field := $object.Fields }} + case "{{$field.Name}}": + {{- if $field.IsConcurrent }} + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._{{$object.Name}}_{{$field.Name}}(ctx, field{{if not $object.Root}}, obj{{end}}) + {{- if $field.TypeReference.GQL.NonNull }} + if res == graphql.Null { + {{- if $object.IsConcurrent }} + atomic.AddUint32(&invalids, 1) + {{- else }} + invalids++ + {{- end }} + } + {{- end }} + return res + } + + {{if $object.Root}} + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + {{end}} + + out.Concurrently(i, func() graphql.Marshaler { + {{- if $object.Root -}} + return rrm(innerCtx) + {{- else -}} + return innerFunc(ctx) + {{end}} + }) + {{- else }} + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._{{$object.Name}}_{{$field.Name}}(ctx, field{{if not $object.Root}}, obj{{end}}) + } + {{if $object.Root}} + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + {{else}} + out.Values[i] = innerFunc(ctx) + {{end}} + + {{- if $field.TypeReference.GQL.NonNull }} + if out.Values[i] == graphql.Null { + {{- if $object.IsConcurrent }} + atomic.AddUint32(&invalids, 1) + {{- else }} + invalids++ + {{- end }} + } + {{- end }} + {{- end }} + {{- end }} + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { return graphql.Null } + return out +} +{{- end }} + +{{- end }} diff --git a/vendor/github.com/99designs/gqlgen/codegen/root_.gotpl b/vendor/github.com/99designs/gqlgen/codegen/root_.gotpl new file mode 100644 index 0000000..13d7796 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/codegen/root_.gotpl @@ -0,0 +1,201 @@ +{{ reserveImport "context" }} +{{ reserveImport "fmt" }} +{{ reserveImport "io" }} +{{ reserveImport "strconv" }} +{{ reserveImport "time" }} +{{ reserveImport "sync" }} +{{ reserveImport "sync/atomic" }} +{{ reserveImport "errors" }} +{{ reserveImport "bytes" }} + +{{ reserveImport "github.com/vektah/gqlparser/v2" "gqlparser" }} +{{ reserveImport "github.com/vektah/gqlparser/v2/ast" }} +{{ reserveImport "github.com/99designs/gqlgen/graphql" }} +{{ reserveImport "github.com/99designs/gqlgen/graphql/introspection" }} + +// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface. +func NewExecutableSchema(cfg Config) graphql.ExecutableSchema { + return &executableSchema{ + resolvers: cfg.Resolvers, + directives: cfg.Directives, + complexity: cfg.Complexity, + } +} + +type Config struct { + Resolvers ResolverRoot + Directives DirectiveRoot + Complexity ComplexityRoot +} + +type ResolverRoot interface { +{{- range $object := .Objects -}} + {{ if $object.HasResolvers -}} + {{ucFirst $object.Name}}() {{ucFirst $object.Name}}Resolver + {{ end }} +{{- end }} +} + +type DirectiveRoot struct { +{{ range $directive := .Directives }} + {{- $directive.Declaration }} +{{ end }} +} + +type ComplexityRoot struct { +{{ range $object := .Objects }} + {{ if not $object.IsReserved -}} + {{ ucFirst $object.Name }} struct { + {{ range $_, $fields := $object.UniqueFields }} + {{- $field := index $fields 0 -}} + {{ if not $field.IsReserved -}} + {{ $field.GoFieldName }} {{ $field.ComplexitySignature }} + {{ end }} + {{- end }} + } + {{- end }} +{{ end }} +} + +type executableSchema struct { + resolvers ResolverRoot + directives DirectiveRoot + complexity ComplexityRoot +} + +func (e *executableSchema) Schema() *ast.Schema { + return parsedSchema +} + +func (e *executableSchema) Complexity(typeName, field string, childComplexity int, rawArgs map[string]interface{}) (int, bool) { + ec := executionContext{nil, e} + _ = ec + switch typeName + "." + field { + {{ range $object := .Objects }} + {{ if not $object.IsReserved }} + {{ range $_, $fields := $object.UniqueFields }} + {{- $len := len $fields }} + {{- range $i, $field := $fields }} + {{- $last := eq (add $i 1) $len }} + {{- if not $field.IsReserved }} + {{- if eq $i 0 }}case {{ end }}"{{$object.Name}}.{{$field.Name}}"{{ if not $last }},{{ else }}: + if e.complexity.{{ucFirst $object.Name }}.{{$field.GoFieldName}} == nil { + break + } + {{ if $field.Args }} + args, err := ec.{{ $field.ArgsFunc }}(context.TODO(),rawArgs) + if err != nil { + return 0, false + } + {{ end }} + return e.complexity.{{ucFirst $object.Name}}.{{$field.GoFieldName}}(childComplexity{{if $field.Args}}, {{$field.ComplexityArgs}} {{ end }}), true + {{ end }} + {{- end }} + {{- end }} + {{ end }} + {{ end }} + {{ end }} + } + return 0, false +} + +func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { + rc := graphql.GetOperationContext(ctx) + ec := executionContext{rc, e} + first := true + + switch rc.Operation.Operation { + {{- if .QueryRoot }} case ast.Query: + return func(ctx context.Context) *graphql.Response { + if !first { return nil } + first = false + {{ if .Directives.LocationDirectives "QUERY" -}} + data := ec._queryMiddleware(ctx, rc.Operation, func(ctx context.Context) (interface{}, error){ + return ec._{{.QueryRoot.Name}}(ctx, rc.Operation.SelectionSet), nil + }) + {{- else -}} + data := ec._{{.QueryRoot.Name}}(ctx, rc.Operation.SelectionSet) + {{- end }} + var buf bytes.Buffer + data.MarshalGQL(&buf) + + return &graphql.Response{ + Data: buf.Bytes(), + } + } + {{ end }} + + {{- if .MutationRoot }} case ast.Mutation: + return func(ctx context.Context) *graphql.Response { + if !first { return nil } + first = false + {{ if .Directives.LocationDirectives "MUTATION" -}} + data := ec._mutationMiddleware(ctx, rc.Operation, func(ctx context.Context) (interface{}, error){ + return ec._{{.MutationRoot.Name}}(ctx, rc.Operation.SelectionSet), nil + }) + {{- else -}} + data := ec._{{.MutationRoot.Name}}(ctx, rc.Operation.SelectionSet) + {{- end }} + var buf bytes.Buffer + data.MarshalGQL(&buf) + + return &graphql.Response{ + Data: buf.Bytes(), + } + } + {{ end }} + + {{- if .SubscriptionRoot }} case ast.Subscription: + {{ if .Directives.LocationDirectives "SUBSCRIPTION" -}} + next := ec._subscriptionMiddleware(ctx, rc.Operation, func(ctx context.Context) (interface{}, error){ + return ec._{{.SubscriptionRoot.Name}}(ctx, rc.Operation.SelectionSet),nil + }) + {{- else -}} + next := ec._{{.SubscriptionRoot.Name}}(ctx, rc.Operation.SelectionSet) + {{- end }} + + var buf bytes.Buffer + return func(ctx context.Context) *graphql.Response { + buf.Reset() + data := next() + + if data == nil { + return nil + } + data.MarshalGQL(&buf) + + return &graphql.Response{ + Data: buf.Bytes(), + } + } + {{ end }} + default: + return graphql.OneShot(graphql.ErrorResponse(ctx, "unsupported GraphQL operation")) + } +} + +type executionContext struct { + *graphql.OperationContext + *executableSchema +} + +func (ec *executionContext) introspectSchema() (*introspection.Schema, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapSchema(parsedSchema), nil +} + +func (ec *executionContext) introspectType(name string) (*introspection.Type, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapTypeFromDef(parsedSchema, parsedSchema.Types[name]), nil +} + +var sources = []*ast.Source{ +{{- range $source := .Config.Sources }} + {Name: {{$source.Name|quote}}, Input: {{$source.Input|rawQuote}}, BuiltIn: {{$source.BuiltIn}}}, +{{- end }} +} +var parsedSchema = gqlparser.MustLoadSchema(sources...) diff --git a/vendor/github.com/99designs/gqlgen/codegen/templates/import.go b/vendor/github.com/99designs/gqlgen/codegen/templates/import.go new file mode 100644 index 0000000..00a82ea --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/codegen/templates/import.go @@ -0,0 +1,139 @@ +package templates + +import ( + "fmt" + "go/types" + "strconv" + "strings" + + "github.com/99designs/gqlgen/internal/code" +) + +type Import struct { + Name string + Path string + Alias string +} + +type Imports struct { + imports []*Import + destDir string + packages *code.Packages +} + +func (i *Import) String() string { + if strings.HasSuffix(i.Path, i.Alias) { + return strconv.Quote(i.Path) + } + + return i.Alias + " " + strconv.Quote(i.Path) +} + +func (s *Imports) String() string { + res := "" + for i, imp := range s.imports { + if i != 0 { + res += "\n" + } + res += imp.String() + } + return res +} + +func (s *Imports) Reserve(path string, aliases ...string) (string, error) { + if path == "" { + panic("empty ambient import") + } + + // if we are referencing our own package we dont need an import + if code.ImportPathForDir(s.destDir) == path { + return "", nil + } + + name := s.packages.NameForPackage(path) + var alias string + if len(aliases) != 1 { + alias = name + } else { + alias = aliases[0] + } + + if existing := s.findByPath(path); existing != nil { + if existing.Alias == alias { + return "", nil + } + return "", fmt.Errorf("ambient import already exists") + } + + if alias := s.findByAlias(alias); alias != nil { + return "", fmt.Errorf("ambient import collides on an alias") + } + + s.imports = append(s.imports, &Import{ + Name: name, + Path: path, + Alias: alias, + }) + + return "", nil +} + +func (s *Imports) Lookup(path string) string { + if path == "" { + return "" + } + + path = code.NormalizeVendor(path) + + // if we are referencing our own package we dont need an import + if code.ImportPathForDir(s.destDir) == path { + return "" + } + + if existing := s.findByPath(path); existing != nil { + return existing.Alias + } + + imp := &Import{ + Name: s.packages.NameForPackage(path), + Path: path, + } + s.imports = append(s.imports, imp) + + alias := imp.Name + i := 1 + for s.findByAlias(alias) != nil { + alias = imp.Name + strconv.Itoa(i) + i++ + if i > 1000 { + panic(fmt.Errorf("too many collisions, last attempt was %s", alias)) + } + } + imp.Alias = alias + + return imp.Alias +} + +func (s *Imports) LookupType(t types.Type) string { + return types.TypeString(t, func(i *types.Package) string { + return s.Lookup(i.Path()) + }) +} + +func (s Imports) findByPath(importPath string) *Import { + for _, imp := range s.imports { + if imp.Path == importPath { + return imp + } + } + return nil +} + +func (s Imports) findByAlias(alias string) *Import { + for _, imp := range s.imports { + if imp.Alias == alias { + return imp + } + } + return nil +} diff --git a/vendor/github.com/99designs/gqlgen/codegen/templates/templates.go b/vendor/github.com/99designs/gqlgen/codegen/templates/templates.go new file mode 100644 index 0000000..0ea3c87 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/codegen/templates/templates.go @@ -0,0 +1,611 @@ +package templates + +import ( + "bytes" + "fmt" + "go/types" + "io/ioutil" + "os" + "path/filepath" + "reflect" + "runtime" + "sort" + "strconv" + "strings" + "text/template" + "unicode" + + "github.com/99designs/gqlgen/internal/code" + + "github.com/99designs/gqlgen/internal/imports" +) + +// CurrentImports keeps track of all the import declarations that are needed during the execution of a plugin. +// this is done with a global because subtemplates currently get called in functions. Lets aim to remove this eventually. +var CurrentImports *Imports + +// Options specify various parameters to rendering a template. +type Options struct { + // PackageName is a helper that specifies the package header declaration. + // In other words, when you write the template you don't need to specify `package X` + // at the top of the file. By providing PackageName in the Options, the Render + // function will do that for you. + PackageName string + // Template is a string of the entire template that + // will be parsed and rendered. If it's empty, + // the plugin processor will look for .gotpl files + // in the same directory of where you wrote the plugin. + Template string + // Filename is the name of the file that will be + // written to the system disk once the template is rendered. + Filename string + RegionTags bool + GeneratedHeader bool + // PackageDoc is documentation written above the package line + PackageDoc string + // FileNotice is notice written below the package line + FileNotice string + // Data will be passed to the template execution. + Data interface{} + Funcs template.FuncMap + + // Packages cache, you can find me on config.Config + Packages *code.Packages +} + +// Render renders a gql plugin template from the given Options. Render is an +// abstraction of the text/template package that makes it easier to write gqlgen +// plugins. If Options.Template is empty, the Render function will look for `.gotpl` +// files inside the directory where you wrote the plugin. +func Render(cfg Options) error { + if CurrentImports != nil { + panic(fmt.Errorf("recursive or concurrent call to RenderToFile detected")) + } + CurrentImports = &Imports{packages: cfg.Packages, destDir: filepath.Dir(cfg.Filename)} + + // load path relative to calling source file + _, callerFile, _, _ := runtime.Caller(1) + rootDir := filepath.Dir(callerFile) + + funcs := Funcs() + for n, f := range cfg.Funcs { + funcs[n] = f + } + t := template.New("").Funcs(funcs) + + var roots []string + if cfg.Template != "" { + var err error + t, err = t.New("template.gotpl").Parse(cfg.Template) + if err != nil { + return fmt.Errorf("error with provided template: %w", err) + } + roots = append(roots, "template.gotpl") + } else { + // load all the templates in the directory + err := filepath.Walk(rootDir, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + name := filepath.ToSlash(strings.TrimPrefix(path, rootDir+string(os.PathSeparator))) + if !strings.HasSuffix(info.Name(), ".gotpl") { + return nil + } + // omit any templates with "_" at the end of their name, which are meant for specific contexts only + if strings.HasSuffix(info.Name(), "_.gotpl") { + return nil + } + b, err := ioutil.ReadFile(path) + if err != nil { + return err + } + + t, err = t.New(name).Parse(string(b)) + if err != nil { + return fmt.Errorf("%s: %w", cfg.Filename, err) + } + + roots = append(roots, name) + + return nil + }) + if err != nil { + return fmt.Errorf("locating templates: %w", err) + } + } + + // then execute all the important looking ones in order, adding them to the same file + sort.Slice(roots, func(i, j int) bool { + // important files go first + if strings.HasSuffix(roots[i], "!.gotpl") { + return true + } + if strings.HasSuffix(roots[j], "!.gotpl") { + return false + } + return roots[i] < roots[j] + }) + var buf bytes.Buffer + for _, root := range roots { + if cfg.RegionTags { + buf.WriteString("\n// region " + center(70, "*", " "+root+" ") + "\n") + } + err := t.Lookup(root).Execute(&buf, cfg.Data) + if err != nil { + return fmt.Errorf("%s: %w", root, err) + } + if cfg.RegionTags { + buf.WriteString("\n// endregion " + center(70, "*", " "+root+" ") + "\n") + } + } + + var result bytes.Buffer + if cfg.GeneratedHeader { + result.WriteString("// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.\n\n") + } + if cfg.PackageDoc != "" { + result.WriteString(cfg.PackageDoc + "\n") + } + result.WriteString("package ") + result.WriteString(cfg.PackageName) + result.WriteString("\n\n") + if cfg.FileNotice != "" { + result.WriteString(cfg.FileNotice) + result.WriteString("\n\n") + } + result.WriteString("import (\n") + result.WriteString(CurrentImports.String()) + result.WriteString(")\n") + _, err := buf.WriteTo(&result) + if err != nil { + return err + } + CurrentImports = nil + + err = write(cfg.Filename, result.Bytes(), cfg.Packages) + if err != nil { + return err + } + + cfg.Packages.Evict(code.ImportPathForDir(filepath.Dir(cfg.Filename))) + return nil +} + +func center(width int, pad string, s string) string { + if len(s)+2 > width { + return s + } + lpad := (width - len(s)) / 2 + rpad := width - (lpad + len(s)) + return strings.Repeat(pad, lpad) + s + strings.Repeat(pad, rpad) +} + +func Funcs() template.FuncMap { + return template.FuncMap{ + "ucFirst": UcFirst, + "lcFirst": LcFirst, + "quote": strconv.Quote, + "rawQuote": rawQuote, + "dump": Dump, + "ref": ref, + "ts": TypeIdentifier, + "call": Call, + "prefixLines": prefixLines, + "notNil": notNil, + "reserveImport": CurrentImports.Reserve, + "lookupImport": CurrentImports.Lookup, + "go": ToGo, + "goPrivate": ToGoPrivate, + "add": func(a, b int) int { + return a + b + }, + "render": func(filename string, tpldata interface{}) (*bytes.Buffer, error) { + return render(resolveName(filename, 0), tpldata) + }, + } +} + +func UcFirst(s string) string { + if s == "" { + return "" + } + r := []rune(s) + r[0] = unicode.ToUpper(r[0]) + return string(r) +} + +func LcFirst(s string) string { + if s == "" { + return "" + } + + r := []rune(s) + r[0] = unicode.ToLower(r[0]) + return string(r) +} + +func isDelimiter(c rune) bool { + return c == '-' || c == '_' || unicode.IsSpace(c) +} + +func ref(p types.Type) string { + return CurrentImports.LookupType(p) +} + +var pkgReplacer = strings.NewReplacer( + "/", "ᚋ", + ".", "ᚗ", + "-", "ᚑ", + "~", "א", +) + +func TypeIdentifier(t types.Type) string { + res := "" + for { + switch it := t.(type) { + case *types.Pointer: + t.Underlying() + res += "ᚖ" + t = it.Elem() + case *types.Slice: + res += "ᚕ" + t = it.Elem() + case *types.Named: + res += pkgReplacer.Replace(it.Obj().Pkg().Path()) + res += "ᚐ" + res += it.Obj().Name() + return res + case *types.Basic: + res += it.Name() + return res + case *types.Map: + res += "map" + return res + case *types.Interface: + res += "interface" + return res + default: + panic(fmt.Errorf("unexpected type %T", it)) + } + } +} + +func Call(p *types.Func) string { + pkg := CurrentImports.Lookup(p.Pkg().Path()) + + if pkg != "" { + pkg += "." + } + + if p.Type() != nil { + // make sure the returned type is listed in our imports. + ref(p.Type().(*types.Signature).Results().At(0).Type()) + } + + return pkg + p.Name() +} + +func ToGo(name string) string { + if name == "_" { + return "_" + } + runes := make([]rune, 0, len(name)) + + wordWalker(name, func(info *wordInfo) { + word := info.Word + if info.MatchCommonInitial { + word = strings.ToUpper(word) + } else if !info.HasCommonInitial { + if strings.ToUpper(word) == word || strings.ToLower(word) == word { + // FOO or foo → Foo + // FOo → FOo + word = UcFirst(strings.ToLower(word)) + } + } + runes = append(runes, []rune(word)...) + }) + + return string(runes) +} + +func ToGoPrivate(name string) string { + if name == "_" { + return "_" + } + runes := make([]rune, 0, len(name)) + + first := true + wordWalker(name, func(info *wordInfo) { + word := info.Word + switch { + case first: + if strings.ToUpper(word) == word || strings.ToLower(word) == word { + // ID → id, CAMEL → camel + word = strings.ToLower(info.Word) + } else { + // ITicket → iTicket + word = LcFirst(info.Word) + } + first = false + case info.MatchCommonInitial: + word = strings.ToUpper(word) + case !info.HasCommonInitial: + word = UcFirst(strings.ToLower(word)) + } + runes = append(runes, []rune(word)...) + }) + + return sanitizeKeywords(string(runes)) +} + +type wordInfo struct { + Word string + MatchCommonInitial bool + HasCommonInitial bool +} + +// This function is based on the following code. +// https://github.com/golang/lint/blob/06c8688daad7faa9da5a0c2f163a3d14aac986ca/lint.go#L679 +func wordWalker(str string, f func(*wordInfo)) { + runes := []rune(strings.TrimFunc(str, isDelimiter)) + w, i := 0, 0 // index of start of word, scan + hasCommonInitial := false + for i+1 <= len(runes) { + eow := false // whether we hit the end of a word + switch { + case i+1 == len(runes): + eow = true + case isDelimiter(runes[i+1]): + // underscore; shift the remainder forward over any run of underscores + eow = true + n := 1 + for i+n+1 < len(runes) && isDelimiter(runes[i+n+1]) { + n++ + } + + // Leave at most one underscore if the underscore is between two digits + if i+n+1 < len(runes) && unicode.IsDigit(runes[i]) && unicode.IsDigit(runes[i+n+1]) { + n-- + } + + copy(runes[i+1:], runes[i+n+1:]) + runes = runes[:len(runes)-n] + case unicode.IsLower(runes[i]) && !unicode.IsLower(runes[i+1]): + // lower->non-lower + eow = true + } + i++ + + // [w,i) is a word. + word := string(runes[w:i]) + if !eow && commonInitialisms[word] && !unicode.IsLower(runes[i]) { + // through + // split IDFoo → ID, Foo + // but URLs → URLs + } else if !eow { + if commonInitialisms[word] { + hasCommonInitial = true + } + continue + } + + matchCommonInitial := false + if commonInitialisms[strings.ToUpper(word)] { + hasCommonInitial = true + matchCommonInitial = true + } + + f(&wordInfo{ + Word: word, + MatchCommonInitial: matchCommonInitial, + HasCommonInitial: hasCommonInitial, + }) + hasCommonInitial = false + w = i + } +} + +var keywords = []string{ + "break", + "default", + "func", + "interface", + "select", + "case", + "defer", + "go", + "map", + "struct", + "chan", + "else", + "goto", + "package", + "switch", + "const", + "fallthrough", + "if", + "range", + "type", + "continue", + "for", + "import", + "return", + "var", + "_", +} + +// sanitizeKeywords prevents collisions with go keywords for arguments to resolver functions +func sanitizeKeywords(name string) string { + for _, k := range keywords { + if name == k { + return name + "Arg" + } + } + return name +} + +// commonInitialisms is a set of common initialisms. +// Only add entries that are highly unlikely to be non-initialisms. +// For instance, "ID" is fine (Freudian code is rare), but "AND" is not. +var commonInitialisms = map[string]bool{ + "ACL": true, + "API": true, + "ASCII": true, + "CPU": true, + "CSS": true, + "CSV": true, + "DNS": true, + "EOF": true, + "GUID": true, + "HTML": true, + "HTTP": true, + "HTTPS": true, + "ICMP": true, + "ID": true, + "IP": true, + "JSON": true, + "KVK": true, + "LHS": true, + "PDF": true, + "PGP": true, + "QPS": true, + "QR": true, + "RAM": true, + "RHS": true, + "RPC": true, + "SLA": true, + "SMTP": true, + "SQL": true, + "SSH": true, + "SVG": true, + "TCP": true, + "TLS": true, + "TTL": true, + "UDP": true, + "UI": true, + "UID": true, + "URI": true, + "URL": true, + "UTF8": true, + "UUID": true, + "VM": true, + "XML": true, + "XMPP": true, + "XSRF": true, + "XSS": true, +} + +func rawQuote(s string) string { + return "`" + strings.ReplaceAll(s, "`", "`+\"`\"+`") + "`" +} + +func notNil(field string, data interface{}) bool { + v := reflect.ValueOf(data) + + if v.Kind() == reflect.Ptr { + v = v.Elem() + } + if v.Kind() != reflect.Struct { + return false + } + val := v.FieldByName(field) + + return val.IsValid() && !val.IsNil() +} + +func Dump(val interface{}) string { + switch val := val.(type) { + case int: + return strconv.Itoa(val) + case int64: + return fmt.Sprintf("%d", val) + case float64: + return fmt.Sprintf("%f", val) + case string: + return strconv.Quote(val) + case bool: + return strconv.FormatBool(val) + case nil: + return "nil" + case []interface{}: + var parts []string + for _, part := range val { + parts = append(parts, Dump(part)) + } + return "[]interface{}{" + strings.Join(parts, ",") + "}" + case map[string]interface{}: + buf := bytes.Buffer{} + buf.WriteString("map[string]interface{}{") + var keys []string + for key := range val { + keys = append(keys, key) + } + sort.Strings(keys) + + for _, key := range keys { + data := val[key] + + buf.WriteString(strconv.Quote(key)) + buf.WriteString(":") + buf.WriteString(Dump(data)) + buf.WriteString(",") + } + buf.WriteString("}") + return buf.String() + default: + panic(fmt.Errorf("unsupported type %T", val)) + } +} + +func prefixLines(prefix, s string) string { + return prefix + strings.ReplaceAll(s, "\n", "\n"+prefix) +} + +func resolveName(name string, skip int) string { + if name[0] == '.' { + // load path relative to calling source file + _, callerFile, _, _ := runtime.Caller(skip + 1) + return filepath.Join(filepath.Dir(callerFile), name[1:]) + } + + // load path relative to this directory + _, callerFile, _, _ := runtime.Caller(0) + return filepath.Join(filepath.Dir(callerFile), name) +} + +func render(filename string, tpldata interface{}) (*bytes.Buffer, error) { + t := template.New("").Funcs(Funcs()) + + b, err := ioutil.ReadFile(filename) + if err != nil { + return nil, err + } + + t, err = t.New(filepath.Base(filename)).Parse(string(b)) + if err != nil { + panic(err) + } + + buf := &bytes.Buffer{} + return buf, t.Execute(buf, tpldata) +} + +func write(filename string, b []byte, packages *code.Packages) error { + err := os.MkdirAll(filepath.Dir(filename), 0o755) + if err != nil { + return fmt.Errorf("failed to create directory: %w", err) + } + + formatted, err := imports.Prune(filename, b, packages) + if err != nil { + fmt.Fprintf(os.Stderr, "gofmt failed on %s: %s\n", filepath.Base(filename), err.Error()) + formatted = b + } + + err = ioutil.WriteFile(filename, formatted, 0o644) + if err != nil { + return fmt.Errorf("failed to write %s: %w", filename, err) + } + + return nil +} diff --git a/vendor/github.com/99designs/gqlgen/codegen/type.go b/vendor/github.com/99designs/gqlgen/codegen/type.go new file mode 100644 index 0000000..20b09dc --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/codegen/type.go @@ -0,0 +1,32 @@ +package codegen + +import ( + "fmt" + + "github.com/99designs/gqlgen/codegen/config" +) + +func (b *builder) buildTypes() map[string]*config.TypeReference { + ret := map[string]*config.TypeReference{} + for _, ref := range b.Binder.References { + processType(ret, ref) + } + return ret +} + +func processType(ret map[string]*config.TypeReference, ref *config.TypeReference) { + key := ref.UniquenessKey() + if existing, found := ret[key]; found { + // Simplistic check of content which is obviously different. + existingGQL := fmt.Sprintf("%v", existing.GQL) + newGQL := fmt.Sprintf("%v", ref.GQL) + if existingGQL != newGQL { + panic(fmt.Sprintf("non-unique key \"%s\", trying to replace %s with %s", key, existingGQL, newGQL)) + } + } + ret[key] = ref + + if ref.IsSlice() || ref.IsPtrToSlice() || ref.IsPtrToPtr() { + processType(ret, ref.Elem()) + } +} diff --git a/vendor/github.com/99designs/gqlgen/codegen/type.gotpl b/vendor/github.com/99designs/gqlgen/codegen/type.gotpl new file mode 100644 index 0000000..1fc6319 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/codegen/type.gotpl @@ -0,0 +1,192 @@ +{{- range $type := .ReferencedTypes }} + {{ with $type.UnmarshalFunc }} + func (ec *executionContext) {{ . }}(ctx context.Context, v interface{}) ({{ $type.GO | ref }}, error) { + {{- if and $type.IsNilable (not $type.GQL.NonNull) (not $type.IsPtrToPtr) }} + if v == nil { return nil, nil } + {{- end }} + {{- if $type.IsPtrToSlice }} + res, err := ec.{{ $type.Elem.UnmarshalFunc }}(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) + {{- else if $type.IsSlice }} + var vSlice []interface{} + if v != nil { + vSlice = graphql.CoerceList(v) + } + var err error + res := make([]{{$type.GO.Elem | ref}}, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.{{ $type.Elem.UnmarshalFunc }}(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil + {{- else if and $type.IsPtrToPtr (not $type.Unmarshaler) (not $type.IsMarshaler) }} + var pres {{ $type.Elem.GO | ref }} + if v != nil { + res, err := ec.{{ $type.Elem.UnmarshalFunc }}(ctx, v) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + pres = res + } + return &pres, nil + {{- else }} + {{- if $type.Unmarshaler }} + {{- if $type.CastType }} + {{- if $type.IsContext }} + tmp, err := {{ $type.Unmarshaler | call }}(ctx, v) + {{- else }} + tmp, err := {{ $type.Unmarshaler | call }}(v) + {{- end }} + {{- if and $type.IsNilable $type.Elem }} + res := {{ $type.Elem.GO | ref }}(tmp) + {{- else}} + res := {{ $type.GO | ref }}(tmp) + {{- end }} + {{- else}} + {{- if $type.IsContext }} + res, err := {{ $type.Unmarshaler | call }}(ctx, v) + {{- else }} + res, err := {{ $type.Unmarshaler | call }}(v) + {{- end }} + {{- end }} + {{- if and $type.IsTargetNilable (not $type.IsNilable) }} + return *res, graphql.ErrorOnPath(ctx, err) + {{- else if and (not $type.IsTargetNilable) $type.IsNilable }} + return &res, graphql.ErrorOnPath(ctx, err) + {{- else}} + return res, graphql.ErrorOnPath(ctx, err) + {{- end }} + {{- else if eq ($type.GO | ref) "map[string]interface{}" }} + return v.(map[string]interface{}), nil + {{- else if $type.IsMarshaler }} + {{- if and $type.IsNilable $type.Elem }} + var res = new({{ $type.Elem.GO | ref }}) + {{- else}} + var res {{ $type.GO | ref }} + {{- end }} + {{- if $type.IsContext }} + err := res.UnmarshalGQLContext(ctx, v) + {{- else }} + err := res.UnmarshalGQL(v) + {{- end }} + return res, graphql.ErrorOnPath(ctx, err) + {{- else }} + res, err := ec.unmarshalInput{{ $type.GQL.Name }}(ctx, v) + {{- if $type.IsNilable }} + return &res, graphql.ErrorOnPath(ctx, err) + {{- else}} + return res, graphql.ErrorOnPath(ctx, err) + {{- end }} + {{- end }} + {{- end }} + } + {{- end }} + + {{ with $type.MarshalFunc }} + func (ec *executionContext) {{ . }}(ctx context.Context, sel ast.SelectionSet, v {{ $type.GO | ref }}) graphql.Marshaler { + {{- if $type.IsPtrToSlice }} + return ec.{{ $type.Elem.MarshalFunc }}(ctx, sel, *v) + {{- else if $type.IsSlice }} + {{- if not $type.GQL.NonNull }} + if v == nil { + return graphql.Null + } + {{- end }} + ret := make(graphql.Array, len(v)) + {{- if not $type.IsScalar }} + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + {{- end }} + for i := range v { + {{- if not $type.IsScalar }} + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.{{ $type.Elem.MarshalFunc }}(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + {{ else }} + ret[i] = ec.{{ $type.Elem.MarshalFunc }}(ctx, sel, v[i]) + {{- end }} + } + {{ if not $type.IsScalar }} wg.Wait() {{ end }} + {{ if $type.Elem.GQL.NonNull }} + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + {{ end }} + return ret + {{- else if and $type.IsPtrToPtr (not $type.Unmarshaler) (not $type.IsMarshaler) }} + if v == nil { + return graphql.Null + } + return ec.{{ $type.Elem.MarshalFunc }}(ctx, sel, *v) + {{- else }} + {{- if $type.IsNilable }} + if v == nil { + {{- if $type.GQL.NonNull }} + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + {{- end }} + return graphql.Null + } + {{- end }} + {{- if $type.IsMarshaler }} + {{- if $type.IsContext }} + return graphql.WrapContextMarshaler(ctx, v) + {{- else }} + return v + {{- end }} + {{- else if $type.Marshaler }} + {{- $v := "v" }} + {{- if and $type.IsTargetNilable (not $type.IsNilable) }} + {{- $v = "&v" }} + {{- else if and (not $type.IsTargetNilable) $type.IsNilable }} + {{- $v = "*v" }} + {{- end }} + res := {{ $type.Marshaler | call }}({{- if $type.CastType }}{{ $type.CastType | ref }}({{ $v }}){{else}}{{ $v }}{{- end }}) + {{- if $type.GQL.NonNull }} + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + } + {{- end }} + {{- if $type.IsContext }} + return graphql.WrapContextMarshaler(ctx, res) + {{- else }} + return res + {{- end }} + {{- else }} + return ec._{{$type.Definition.Name}}(ctx, sel, {{ if not $type.IsNilable}}&{{end}} v) + {{- end }} + {{- end }} + } + {{- end }} +{{- end }} diff --git a/vendor/github.com/99designs/gqlgen/codegen/util.go b/vendor/github.com/99designs/gqlgen/codegen/util.go new file mode 100644 index 0000000..fa2ceed --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/codegen/util.go @@ -0,0 +1,46 @@ +package codegen + +import ( + "fmt" + "go/types" + "strings" +) + +func findGoNamedType(def types.Type) (*types.Named, error) { + if def == nil { + return nil, nil + } + + namedType, ok := def.(*types.Named) + if !ok { + return nil, fmt.Errorf("expected %s to be a named type, instead found %T\n", def.String(), def) + } + + return namedType, nil +} + +func findGoInterface(def types.Type) (*types.Interface, error) { + if def == nil { + return nil, nil + } + namedType, err := findGoNamedType(def) + if err != nil { + return nil, err + } + if namedType == nil { + return nil, nil + } + + underlying, ok := namedType.Underlying().(*types.Interface) + if !ok { + return nil, fmt.Errorf("expected %s to be a named interface, instead found %s", def.String(), namedType.String()) + } + + return underlying, nil +} + +func equalFieldName(source, target string) bool { + source = strings.ReplaceAll(source, "_", "") + target = strings.ReplaceAll(target, "_", "") + return strings.EqualFold(source, target) +} diff --git a/vendor/github.com/99designs/gqlgen/complexity/complexity.go b/vendor/github.com/99designs/gqlgen/complexity/complexity.go new file mode 100644 index 0000000..e3ecf76 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/complexity/complexity.go @@ -0,0 +1,109 @@ +package complexity + +import ( + "github.com/99designs/gqlgen/graphql" + "github.com/vektah/gqlparser/v2/ast" +) + +func Calculate(es graphql.ExecutableSchema, op *ast.OperationDefinition, vars map[string]interface{}) int { + walker := complexityWalker{ + es: es, + schema: es.Schema(), + vars: vars, + } + return walker.selectionSetComplexity(op.SelectionSet) +} + +type complexityWalker struct { + es graphql.ExecutableSchema + schema *ast.Schema + vars map[string]interface{} +} + +func (cw complexityWalker) selectionSetComplexity(selectionSet ast.SelectionSet) int { + var complexity int + for _, selection := range selectionSet { + switch s := selection.(type) { + case *ast.Field: + fieldDefinition := cw.schema.Types[s.Definition.Type.Name()] + + if fieldDefinition.Name == "__Schema" { + continue + } + + var childComplexity int + switch fieldDefinition.Kind { + case ast.Object, ast.Interface, ast.Union: + childComplexity = cw.selectionSetComplexity(s.SelectionSet) + } + + args := s.ArgumentMap(cw.vars) + var fieldComplexity int + if s.ObjectDefinition.Kind == ast.Interface { + fieldComplexity = cw.interfaceFieldComplexity(s.ObjectDefinition, s.Name, childComplexity, args) + } else { + fieldComplexity = cw.fieldComplexity(s.ObjectDefinition.Name, s.Name, childComplexity, args) + } + complexity = safeAdd(complexity, fieldComplexity) + + case *ast.FragmentSpread: + complexity = safeAdd(complexity, cw.selectionSetComplexity(s.Definition.SelectionSet)) + + case *ast.InlineFragment: + complexity = safeAdd(complexity, cw.selectionSetComplexity(s.SelectionSet)) + } + } + return complexity +} + +func (cw complexityWalker) interfaceFieldComplexity(def *ast.Definition, field string, childComplexity int, args map[string]interface{}) int { + // Interfaces don't have their own separate field costs, so they have to assume the worst case. + // We iterate over all implementors and choose the most expensive one. + maxComplexity := 0 + implementors := cw.schema.GetPossibleTypes(def) + for _, t := range implementors { + fieldComplexity := cw.fieldComplexity(t.Name, field, childComplexity, args) + if fieldComplexity > maxComplexity { + maxComplexity = fieldComplexity + } + } + return maxComplexity +} + +func (cw complexityWalker) fieldComplexity(object, field string, childComplexity int, args map[string]interface{}) int { + if customComplexity, ok := cw.es.Complexity(object, field, childComplexity, args); ok && customComplexity >= childComplexity { + return customComplexity + } + // default complexity calculation + return safeAdd(1, childComplexity) +} + +const maxInt = int(^uint(0) >> 1) + +// safeAdd is a saturating add of a and b that ignores negative operands. +// If a + b would overflow through normal Go addition, +// it returns the maximum integer value instead. +// +// Adding complexities with this function prevents attackers from intentionally +// overflowing the complexity calculation to allow overly-complex queries. +// +// It also helps mitigate the impact of custom complexities that accidentally +// return negative values. +func safeAdd(a, b int) int { + // Ignore negative operands. + if a < 0 { + if b < 0 { + return 1 + } + return b + } else if b < 0 { + return a + } + + c := a + b + if c < a { + // Set c to maximum integer instead of overflowing. + c = maxInt + } + return c +} diff --git a/vendor/github.com/99designs/gqlgen/go.mod b/vendor/github.com/99designs/gqlgen/go.mod new file mode 100644 index 0000000..6108576 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/go.mod @@ -0,0 +1,24 @@ +module github.com/99designs/gqlgen + +go 1.16 + +require ( + github.com/gorilla/websocket v1.4.2 + github.com/hashicorp/golang-lru v0.5.0 + github.com/kevinmbeaulieu/eq-go v1.0.0 + github.com/logrusorgru/aurora/v3 v3.0.0 + github.com/matryer/moq v0.2.3 + github.com/mattn/go-colorable v0.1.4 + github.com/mattn/go-isatty v0.0.12 + github.com/mitchellh/mapstructure v1.2.3 + github.com/stretchr/testify v1.4.0 + github.com/urfave/cli/v2 v2.3.0 + github.com/vektah/gqlparser/v2 v2.2.0 + golang.org/x/tools v0.1.5 + gopkg.in/yaml.v2 v2.2.4 +) + +require ( + github.com/agnivade/levenshtein v1.1.0 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect +) diff --git a/vendor/github.com/99designs/gqlgen/go.sum b/vendor/github.com/99designs/gqlgen/go.sum new file mode 100644 index 0000000..457b6c1 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/go.sum @@ -0,0 +1,98 @@ +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= +github.com/agnivade/levenshtein v1.1.0 h1:n6qGwyHG61v3ABce1rPVZklEYRT8NFpCMrpZdBUbYGM= +github.com/agnivade/levenshtein v1.1.0/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= +github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= +github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU= +github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g= +github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/kevinmbeaulieu/eq-go v1.0.0 h1:AQgYHURDOmnVJ62jnEk0W/7yFKEn+Lv8RHN6t7mB0Zo= +github.com/kevinmbeaulieu/eq-go v1.0.0/go.mod h1:G3S8ajA56gKBZm4UB9AOyoOS37JO3roToPzKNM8dtdM= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/logrusorgru/aurora/v3 v3.0.0 h1:R6zcoZZbvVcGMvDCKo45A9U/lzYyzl5NfYIvznmDfE4= +github.com/logrusorgru/aurora/v3 v3.0.0/go.mod h1:vsR12bk5grlLvLXAYrBsb5Oc/N+LxAlxggSjiwMnCUc= +github.com/matryer/moq v0.2.3 h1:Q06vEqnBYjjfx5KKgHfYRKE/lvlRu+Nj+xodG4YdHnU= +github.com/matryer/moq v0.2.3/go.mod h1:9RtPYjTnH1bSBIkpvtHkFN7nbWAnO7oRpdJkEIn6UtE= +github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mitchellh/mapstructure v1.2.3 h1:f/MjBEBDLttYCGfRaKBbKSRVF5aV2O6fnBpzknuE3jU= +github.com/mitchellh/mapstructure v1.2.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= +github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= +github.com/vektah/gqlparser/v2 v2.2.0 h1:bAc3slekAAJW6sZTi07aGq0OrfaCjj4jxARAaC7g2EM= +github.com/vektah/gqlparser/v2 v2.2.0/go.mod h1:i3mQIGIrbK2PD1RrCeMTlVbkF2FJ6WkU1KJlJlC+3F4= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200815165600-90abf76919f3/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/99designs/gqlgen/graphql/any.go b/vendor/github.com/99designs/gqlgen/graphql/any.go new file mode 100644 index 0000000..6ea8bf2 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/any.go @@ -0,0 +1,19 @@ +package graphql + +import ( + "encoding/json" + "io" +) + +func MarshalAny(v interface{}) Marshaler { + return WriterFunc(func(w io.Writer) { + err := json.NewEncoder(w).Encode(v) + if err != nil { + panic(err) + } + }) +} + +func UnmarshalAny(v interface{}) (interface{}, error) { + return v, nil +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/bool.go b/vendor/github.com/99designs/gqlgen/graphql/bool.go new file mode 100644 index 0000000..f435e0c --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/bool.go @@ -0,0 +1,27 @@ +package graphql + +import ( + "fmt" + "io" + "strings" +) + +func MarshalBoolean(b bool) Marshaler { + if b { + return WriterFunc(func(w io.Writer) { w.Write(trueLit) }) + } + return WriterFunc(func(w io.Writer) { w.Write(falseLit) }) +} + +func UnmarshalBoolean(v interface{}) (bool, error) { + switch v := v.(type) { + case string: + return strings.ToLower(v) == "true", nil + case int: + return v != 0, nil + case bool: + return v, nil + default: + return false, fmt.Errorf("%T is not a bool", v) + } +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/cache.go b/vendor/github.com/99designs/gqlgen/graphql/cache.go new file mode 100644 index 0000000..fe86ca3 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/cache.go @@ -0,0 +1,29 @@ +package graphql + +import "context" + +// Cache is a shared store for APQ and query AST caching +type Cache interface { + // Get looks up a key's value from the cache. + Get(ctx context.Context, key string) (value interface{}, ok bool) + + // Add adds a value to the cache. + Add(ctx context.Context, key string, value interface{}) +} + +// MapCache is the simplest implementation of a cache, because it can not evict it should only be used in tests +type MapCache map[string]interface{} + +// Get looks up a key's value from the cache. +func (m MapCache) Get(ctx context.Context, key string) (value interface{}, ok bool) { + v, ok := m[key] + return v, ok +} + +// Add adds a value to the cache. +func (m MapCache) Add(ctx context.Context, key string, value interface{}) { m[key] = value } + +type NoCache struct{} + +func (n NoCache) Get(ctx context.Context, key string) (value interface{}, ok bool) { return nil, false } +func (n NoCache) Add(ctx context.Context, key string, value interface{}) {} diff --git a/vendor/github.com/99designs/gqlgen/graphql/coercion.go b/vendor/github.com/99designs/gqlgen/graphql/coercion.go new file mode 100644 index 0000000..d3d3c18 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/coercion.go @@ -0,0 +1,56 @@ +package graphql + +import ( + "encoding/json" +) + +// CoerceList applies coercion from a single value to a list. +func CoerceList(v interface{}) []interface{} { + var vSlice []interface{} + if v != nil { + switch v := v.(type) { + case []interface{}: + // already a slice no coercion required + vSlice = v + case []string: + if len(v) > 0 { + vSlice = []interface{}{v[0]} + } + case []json.Number: + if len(v) > 0 { + vSlice = []interface{}{v[0]} + } + case []bool: + if len(v) > 0 { + vSlice = []interface{}{v[0]} + } + case []map[string]interface{}: + if len(v) > 0 { + vSlice = []interface{}{v[0]} + } + case []float64: + if len(v) > 0 { + vSlice = []interface{}{v[0]} + } + case []float32: + if len(v) > 0 { + vSlice = []interface{}{v[0]} + } + case []int: + if len(v) > 0 { + vSlice = []interface{}{v[0]} + } + case []int32: + if len(v) > 0 { + vSlice = []interface{}{v[0]} + } + case []int64: + if len(v) > 0 { + vSlice = []interface{}{v[0]} + } + default: + vSlice = []interface{}{v} + } + } + return vSlice +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/context_field.go b/vendor/github.com/99designs/gqlgen/graphql/context_field.go new file mode 100644 index 0000000..c06118b --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/context_field.go @@ -0,0 +1,94 @@ +package graphql + +import ( + "context" + "time" + + "github.com/vektah/gqlparser/v2/ast" +) + +type key string + +const resolverCtx key = "resolver_context" + +// Deprecated: Use FieldContext instead +type ResolverContext = FieldContext + +type FieldContext struct { + Parent *FieldContext + // The name of the type this field belongs to + Object string + // These are the args after processing, they can be mutated in middleware to change what the resolver will get. + Args map[string]interface{} + // The raw field + Field CollectedField + // The index of array in path. + Index *int + // The result object of resolver + Result interface{} + // IsMethod indicates if the resolver is a method + IsMethod bool + // IsResolver indicates if the field has a user-specified resolver + IsResolver bool +} + +type FieldStats struct { + // When field execution started + Started time.Time + + // When argument marshaling finished + ArgumentsCompleted time.Time + + // When the field completed running all middleware. Not available inside field middleware! + Completed time.Time +} + +func (r *FieldContext) Path() ast.Path { + var path ast.Path + for it := r; it != nil; it = it.Parent { + if it.Index != nil { + path = append(path, ast.PathIndex(*it.Index)) + } else if it.Field.Field != nil { + path = append(path, ast.PathName(it.Field.Alias)) + } + } + + // because we are walking up the chain, all the elements are backwards, do an inplace flip. + for i := len(path)/2 - 1; i >= 0; i-- { + opp := len(path) - 1 - i + path[i], path[opp] = path[opp], path[i] + } + + return path +} + +// Deprecated: Use GetFieldContext instead +func GetResolverContext(ctx context.Context) *ResolverContext { + return GetFieldContext(ctx) +} + +func GetFieldContext(ctx context.Context) *FieldContext { + if val, ok := ctx.Value(resolverCtx).(*FieldContext); ok { + return val + } + return nil +} + +func WithFieldContext(ctx context.Context, rc *FieldContext) context.Context { + rc.Parent = GetFieldContext(ctx) + return context.WithValue(ctx, resolverCtx, rc) +} + +func equalPath(a ast.Path, b ast.Path) bool { + if len(a) != len(b) { + return false + } + + for i := 0; i < len(a); i++ { + if a[i] != b[i] { + return false + } + } + + return true +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/context_operation.go b/vendor/github.com/99designs/gqlgen/graphql/context_operation.go new file mode 100644 index 0000000..bfbbc5c --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/context_operation.go @@ -0,0 +1,115 @@ +package graphql + +import ( + "context" + "errors" + + "github.com/vektah/gqlparser/v2/ast" +) + +// Deprecated: Please update all references to OperationContext instead +type RequestContext = OperationContext + +type OperationContext struct { + RawQuery string + Variables map[string]interface{} + OperationName string + Doc *ast.QueryDocument + + Operation *ast.OperationDefinition + DisableIntrospection bool + RecoverFunc RecoverFunc + ResolverMiddleware FieldMiddleware + RootResolverMiddleware RootFieldMiddleware + + Stats Stats +} + +func (c *OperationContext) Validate(ctx context.Context) error { + if c.Doc == nil { + return errors.New("field 'Doc'is required") + } + if c.RawQuery == "" { + return errors.New("field 'RawQuery' is required") + } + if c.Variables == nil { + c.Variables = make(map[string]interface{}) + } + if c.ResolverMiddleware == nil { + return errors.New("field 'ResolverMiddleware' is required") + } + if c.RootResolverMiddleware == nil { + return errors.New("field 'RootResolverMiddleware' is required") + } + if c.RecoverFunc == nil { + c.RecoverFunc = DefaultRecover + } + + return nil +} + +const operationCtx key = "operation_context" + +// Deprecated: Please update all references to GetOperationContext instead +func GetRequestContext(ctx context.Context) *RequestContext { + return GetOperationContext(ctx) +} + +func GetOperationContext(ctx context.Context) *OperationContext { + if val, ok := ctx.Value(operationCtx).(*OperationContext); ok && val != nil { + return val + } + panic("missing operation context") +} + +func WithOperationContext(ctx context.Context, rc *OperationContext) context.Context { + return context.WithValue(ctx, operationCtx, rc) +} + +// HasOperationContext checks if the given context is part of an ongoing operation +// +// Some errors can happen outside of an operation, eg json unmarshal errors. +func HasOperationContext(ctx context.Context) bool { + _, ok := ctx.Value(operationCtx).(*OperationContext) + return ok +} + +// This is just a convenient wrapper method for CollectFields +func CollectFieldsCtx(ctx context.Context, satisfies []string) []CollectedField { + resctx := GetFieldContext(ctx) + return CollectFields(GetOperationContext(ctx), resctx.Field.Selections, satisfies) +} + +// CollectAllFields returns a slice of all GraphQL field names that were selected for the current resolver context. +// The slice will contain the unique set of all field names requested regardless of fragment type conditions. +func CollectAllFields(ctx context.Context) []string { + resctx := GetFieldContext(ctx) + collected := CollectFields(GetOperationContext(ctx), resctx.Field.Selections, nil) + uniq := make([]string, 0, len(collected)) +Next: + for _, f := range collected { + for _, name := range uniq { + if name == f.Name { + continue Next + } + } + uniq = append(uniq, f.Name) + } + return uniq +} + +// Errorf sends an error string to the client, passing it through the formatter. +// Deprecated: use graphql.AddErrorf(ctx, err) instead +func (c *OperationContext) Errorf(ctx context.Context, format string, args ...interface{}) { + AddErrorf(ctx, format, args...) +} + +// Error sends an error to the client, passing it through the formatter. +// Deprecated: use graphql.AddError(ctx, err) instead +func (c *OperationContext) Error(ctx context.Context, err error) { + AddError(ctx, err) +} + +func (c *OperationContext) Recover(ctx context.Context, err interface{}) error { + return ErrorOnPath(ctx, c.RecoverFunc(ctx, err)) +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/context_path.go b/vendor/github.com/99designs/gqlgen/graphql/context_path.go new file mode 100644 index 0000000..a46ed83 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/context_path.go @@ -0,0 +1,77 @@ +package graphql + +import ( + "context" + + "github.com/vektah/gqlparser/v2/ast" +) + +const fieldInputCtx key = "path_context" + +type PathContext struct { + ParentField *FieldContext + Parent *PathContext + Field *string + Index *int +} + +func (fic *PathContext) Path() ast.Path { + var path ast.Path + for it := fic; it != nil; it = it.Parent { + if it.Index != nil { + path = append(path, ast.PathIndex(*it.Index)) + } else if it.Field != nil { + path = append(path, ast.PathName(*it.Field)) + } + } + + // because we are walking up the chain, all the elements are backwards, do an inplace flip. + for i := len(path)/2 - 1; i >= 0; i-- { + opp := len(path) - 1 - i + path[i], path[opp] = path[opp], path[i] + } + + if fic.ParentField != nil { + fieldPath := fic.ParentField.Path() + return append(fieldPath, path...) + + } + + return path +} + +func NewPathWithField(field string) *PathContext { + return &PathContext{Field: &field} +} + +func NewPathWithIndex(index int) *PathContext { + return &PathContext{Index: &index} +} + +func WithPathContext(ctx context.Context, fic *PathContext) context.Context { + if fieldContext := GetFieldContext(ctx); fieldContext != nil { + fic.ParentField = fieldContext + } + if fieldInputContext := GetPathContext(ctx); fieldInputContext != nil { + fic.Parent = fieldInputContext + } + + return context.WithValue(ctx, fieldInputCtx, fic) +} + +func GetPathContext(ctx context.Context) *PathContext { + if val, ok := ctx.Value(fieldInputCtx).(*PathContext); ok { + return val + } + return nil +} + +func GetPath(ctx context.Context) ast.Path { + if pc := GetPathContext(ctx); pc != nil { + return pc.Path() + } + if fc := GetFieldContext(ctx); fc != nil { + return fc.Path() + } + return nil +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/context_response.go b/vendor/github.com/99designs/gqlgen/graphql/context_response.go new file mode 100644 index 0000000..c128fdb --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/context_response.go @@ -0,0 +1,153 @@ +package graphql + +import ( + "context" + "fmt" + "sync" + + "github.com/vektah/gqlparser/v2/gqlerror" +) + +type responseContext struct { + errorPresenter ErrorPresenterFunc + recover RecoverFunc + + errors gqlerror.List + errorsMu sync.Mutex + + extensions map[string]interface{} + extensionsMu sync.Mutex +} + +const resultCtx key = "result_context" + +func getResponseContext(ctx context.Context) *responseContext { + val, ok := ctx.Value(resultCtx).(*responseContext) + if !ok { + panic("missing response context") + } + return val +} + +func WithResponseContext(ctx context.Context, presenterFunc ErrorPresenterFunc, recoverFunc RecoverFunc) context.Context { + return context.WithValue(ctx, resultCtx, &responseContext{ + errorPresenter: presenterFunc, + recover: recoverFunc, + }) +} + +// AddErrorf writes a formatted error to the client, first passing it through the error presenter. +func AddErrorf(ctx context.Context, format string, args ...interface{}) { + AddError(ctx, fmt.Errorf(format, args...)) +} + +// AddError sends an error to the client, first passing it through the error presenter. +func AddError(ctx context.Context, err error) { + c := getResponseContext(ctx) + + presentedError := c.errorPresenter(ctx, ErrorOnPath(ctx, err)) + + c.errorsMu.Lock() + defer c.errorsMu.Unlock() + c.errors = append(c.errors, presentedError) +} + +func Recover(ctx context.Context, err interface{}) (userMessage error) { + c := getResponseContext(ctx) + return ErrorOnPath(ctx, c.recover(ctx, err)) +} + +// HasFieldError returns true if the given field has already errored +func HasFieldError(ctx context.Context, rctx *FieldContext) bool { + c := getResponseContext(ctx) + + c.errorsMu.Lock() + defer c.errorsMu.Unlock() + + if len(c.errors) == 0 { + return false + } + + path := rctx.Path() + for _, err := range c.errors { + if equalPath(err.Path, path) { + return true + } + } + return false +} + +// GetFieldErrors returns a list of errors that occurred in the given field +func GetFieldErrors(ctx context.Context, rctx *FieldContext) gqlerror.List { + c := getResponseContext(ctx) + + c.errorsMu.Lock() + defer c.errorsMu.Unlock() + + if len(c.errors) == 0 { + return nil + } + + path := rctx.Path() + var errs gqlerror.List + for _, err := range c.errors { + if equalPath(err.Path, path) { + errs = append(errs, err) + } + } + return errs +} + +func GetErrors(ctx context.Context) gqlerror.List { + resCtx := getResponseContext(ctx) + resCtx.errorsMu.Lock() + defer resCtx.errorsMu.Unlock() + + if len(resCtx.errors) == 0 { + return nil + } + + errs := resCtx.errors + cpy := make(gqlerror.List, len(errs)) + for i := range errs { + errCpy := *errs[i] + cpy[i] = &errCpy + } + return cpy +} + +// RegisterExtension allows you to add a new extension into the graphql response +func RegisterExtension(ctx context.Context, key string, value interface{}) { + c := getResponseContext(ctx) + c.extensionsMu.Lock() + defer c.extensionsMu.Unlock() + + if c.extensions == nil { + c.extensions = make(map[string]interface{}) + } + + if _, ok := c.extensions[key]; ok { + panic(fmt.Errorf("extension already registered for key %s", key)) + } + + c.extensions[key] = value +} + +// GetExtensions returns any extensions registered in the current result context +func GetExtensions(ctx context.Context) map[string]interface{} { + ext := getResponseContext(ctx).extensions + if ext == nil { + return map[string]interface{}{} + } + + return ext +} + +func GetExtension(ctx context.Context, name string) interface{} { + ext := getResponseContext(ctx).extensions + if ext == nil { + return nil + } + + return ext[name] +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/context_root_field.go b/vendor/github.com/99designs/gqlgen/graphql/context_root_field.go new file mode 100644 index 0000000..1bf4d13 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/context_root_field.go @@ -0,0 +1,25 @@ +package graphql + +import ( + "context" +) + +const rootResolverCtx key = "root_resolver_context" + +type RootFieldContext struct { + // The name of the type this field belongs to + Object string + // The raw field + Field CollectedField +} + +func GetRootFieldContext(ctx context.Context) *RootFieldContext { + if val, ok := ctx.Value(rootResolverCtx).(*RootFieldContext); ok { + return val + } + return nil +} + +func WithRootFieldContext(ctx context.Context, rc *RootFieldContext) context.Context { + return context.WithValue(ctx, rootResolverCtx, rc) +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/errcode/codes.go b/vendor/github.com/99designs/gqlgen/graphql/errcode/codes.go new file mode 100644 index 0000000..98b95d0 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/errcode/codes.go @@ -0,0 +1,51 @@ +package errcode + +import ( + "github.com/vektah/gqlparser/v2/gqlerror" +) + +const ( + ValidationFailed = "GRAPHQL_VALIDATION_FAILED" + ParseFailed = "GRAPHQL_PARSE_FAILED" +) + +type ErrorKind int + +const ( + // issues with graphql (validation, parsing). 422s in http, GQL_ERROR in websocket + KindProtocol ErrorKind = iota + // user errors, 200s in http, GQL_DATA in websocket + KindUser +) + +var codeType = map[string]ErrorKind{ + ValidationFailed: KindProtocol, + ParseFailed: KindProtocol, +} + +// RegisterErrorType should be called by extensions that want to customize the http status codes for errors they return +func RegisterErrorType(code string, kind ErrorKind) { + codeType[code] = kind +} + +// Set the error code on a given graphql error extension +func Set(err *gqlerror.Error, value string) { + if err.Extensions == nil { + err.Extensions = map[string]interface{}{} + } + + err.Extensions["code"] = value +} + +// get the kind of the first non User error, defaults to User if no errors have a custom extension +func GetErrorKind(errs gqlerror.List) ErrorKind { + for _, err := range errs { + if code, ok := err.Extensions["code"].(string); ok { + if kind, ok := codeType[code]; ok && kind != KindUser { + return kind + } + } + } + + return KindUser +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/error.go b/vendor/github.com/99designs/gqlgen/graphql/error.go new file mode 100644 index 0000000..4fe520b --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/error.go @@ -0,0 +1,32 @@ +package graphql + +import ( + "context" + "errors" + + "github.com/vektah/gqlparser/v2/gqlerror" +) + +type ErrorPresenterFunc func(ctx context.Context, err error) *gqlerror.Error + +func DefaultErrorPresenter(ctx context.Context, err error) *gqlerror.Error { + var gqlErr *gqlerror.Error + if errors.As(err, &gqlErr) { + return gqlErr + } + return gqlerror.WrapPath(GetPath(ctx), err) +} + +func ErrorOnPath(ctx context.Context, err error) error { + if err == nil { + return nil + } + var gqlErr *gqlerror.Error + if errors.As(err, &gqlErr) { + if gqlErr.Path == nil { + gqlErr.Path = GetPath(ctx) + } + return gqlErr + } + return gqlerror.WrapPath(GetPath(ctx), err) +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/executable_schema.go b/vendor/github.com/99designs/gqlgen/graphql/executable_schema.go new file mode 100644 index 0000000..541b65f --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/executable_schema.go @@ -0,0 +1,162 @@ +//go:generate go run github.com/matryer/moq -out executable_schema_mock.go . ExecutableSchema + +package graphql + +import ( + "context" + "fmt" + + "github.com/vektah/gqlparser/v2/ast" +) + +type ExecutableSchema interface { + Schema() *ast.Schema + + Complexity(typeName, fieldName string, childComplexity int, args map[string]interface{}) (int, bool) + Exec(ctx context.Context) ResponseHandler +} + +// CollectFields returns the set of fields from an ast.SelectionSet where all collected fields satisfy at least one of the GraphQL types +// passed through satisfies. Providing an empty or nil slice for satisfies will return collect all fields regardless of fragment +// type conditions. +func CollectFields(reqCtx *OperationContext, selSet ast.SelectionSet, satisfies []string) []CollectedField { + return collectFields(reqCtx, selSet, satisfies, map[string]bool{}) +} + +func collectFields(reqCtx *OperationContext, selSet ast.SelectionSet, satisfies []string, visited map[string]bool) []CollectedField { + groupedFields := make([]CollectedField, 0, len(selSet)) + + for _, sel := range selSet { + switch sel := sel.(type) { + case *ast.Field: + if !shouldIncludeNode(sel.Directives, reqCtx.Variables) { + continue + } + f := getOrCreateAndAppendField(&groupedFields, sel.Name, sel.Alias, sel.ObjectDefinition, func() CollectedField { + return CollectedField{Field: sel} + }) + + f.Selections = append(f.Selections, sel.SelectionSet...) + + case *ast.InlineFragment: + if !shouldIncludeNode(sel.Directives, reqCtx.Variables) { + continue + } + if len(satisfies) > 0 && !instanceOf(sel.TypeCondition, satisfies) { + continue + } + for _, childField := range collectFields(reqCtx, sel.SelectionSet, satisfies, visited) { + f := getOrCreateAndAppendField(&groupedFields, childField.Name, childField.Alias, childField.ObjectDefinition, func() CollectedField { return childField }) + f.Selections = append(f.Selections, childField.Selections...) + } + + case *ast.FragmentSpread: + if !shouldIncludeNode(sel.Directives, reqCtx.Variables) { + continue + } + fragmentName := sel.Name + if _, seen := visited[fragmentName]; seen { + continue + } + visited[fragmentName] = true + + fragment := reqCtx.Doc.Fragments.ForName(fragmentName) + if fragment == nil { + // should never happen, validator has already run + panic(fmt.Errorf("missing fragment %s", fragmentName)) + } + + if len(satisfies) > 0 && !instanceOf(fragment.TypeCondition, satisfies) { + continue + } + + for _, childField := range collectFields(reqCtx, fragment.SelectionSet, satisfies, visited) { + f := getOrCreateAndAppendField(&groupedFields, childField.Name, childField.Alias, childField.ObjectDefinition, func() CollectedField { return childField }) + f.Selections = append(f.Selections, childField.Selections...) + } + + default: + panic(fmt.Errorf("unsupported %T", sel)) + } + } + + return groupedFields +} + +type CollectedField struct { + *ast.Field + + Selections ast.SelectionSet +} + +func instanceOf(val string, satisfies []string) bool { + for _, s := range satisfies { + if val == s { + return true + } + } + return false +} + +func getOrCreateAndAppendField(c *[]CollectedField, name string, alias string, objectDefinition *ast.Definition, creator func() CollectedField) *CollectedField { + for i, cf := range *c { + if cf.Name == name && cf.Alias == alias { + if cf.ObjectDefinition == objectDefinition { + return &(*c)[i] + } + + if cf.ObjectDefinition == nil || objectDefinition == nil { + continue + } + + if cf.ObjectDefinition.Name == objectDefinition.Name { + return &(*c)[i] + } + + for _, ifc := range objectDefinition.Interfaces { + if ifc == cf.ObjectDefinition.Name { + return &(*c)[i] + } + } + } + } + + f := creator() + + *c = append(*c, f) + return &(*c)[len(*c)-1] +} + +func shouldIncludeNode(directives ast.DirectiveList, variables map[string]interface{}) bool { + if len(directives) == 0 { + return true + } + + skip, include := false, true + + if d := directives.ForName("skip"); d != nil { + skip = resolveIfArgument(d, variables) + } + + if d := directives.ForName("include"); d != nil { + include = resolveIfArgument(d, variables) + } + + return !skip && include +} + +func resolveIfArgument(d *ast.Directive, variables map[string]interface{}) bool { + arg := d.Arguments.ForName("if") + if arg == nil { + panic(fmt.Sprintf("%s: argument 'if' not defined", d.Name)) + } + value, err := arg.Value.Value(variables) + if err != nil { + panic(err) + } + ret, ok := value.(bool) + if !ok { + panic(fmt.Sprintf("%s: argument 'if' is not a boolean", d.Name)) + } + return ret +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/executable_schema_mock.go b/vendor/github.com/99designs/gqlgen/graphql/executable_schema_mock.go new file mode 100644 index 0000000..5d74331 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/executable_schema_mock.go @@ -0,0 +1,172 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package graphql + +import ( + "context" + "github.com/vektah/gqlparser/v2/ast" + "sync" +) + +// Ensure, that ExecutableSchemaMock does implement ExecutableSchema. +// If this is not the case, regenerate this file with moq. +var _ ExecutableSchema = &ExecutableSchemaMock{} + +// ExecutableSchemaMock is a mock implementation of ExecutableSchema. +// +// func TestSomethingThatUsesExecutableSchema(t *testing.T) { +// +// // make and configure a mocked ExecutableSchema +// mockedExecutableSchema := &ExecutableSchemaMock{ +// ComplexityFunc: func(typeName string, fieldName string, childComplexity int, args map[string]interface{}) (int, bool) { +// panic("mock out the Complexity method") +// }, +// ExecFunc: func(ctx context.Context) ResponseHandler { +// panic("mock out the Exec method") +// }, +// SchemaFunc: func() *ast.Schema { +// panic("mock out the Schema method") +// }, +// } +// +// // use mockedExecutableSchema in code that requires ExecutableSchema +// // and then make assertions. +// +// } +type ExecutableSchemaMock struct { + // ComplexityFunc mocks the Complexity method. + ComplexityFunc func(typeName string, fieldName string, childComplexity int, args map[string]interface{}) (int, bool) + + // ExecFunc mocks the Exec method. + ExecFunc func(ctx context.Context) ResponseHandler + + // SchemaFunc mocks the Schema method. + SchemaFunc func() *ast.Schema + + // calls tracks calls to the methods. + calls struct { + // Complexity holds details about calls to the Complexity method. + Complexity []struct { + // TypeName is the typeName argument value. + TypeName string + // FieldName is the fieldName argument value. + FieldName string + // ChildComplexity is the childComplexity argument value. + ChildComplexity int + // Args is the args argument value. + Args map[string]interface{} + } + // Exec holds details about calls to the Exec method. + Exec []struct { + // Ctx is the ctx argument value. + Ctx context.Context + } + // Schema holds details about calls to the Schema method. + Schema []struct { + } + } + lockComplexity sync.RWMutex + lockExec sync.RWMutex + lockSchema sync.RWMutex +} + +// Complexity calls ComplexityFunc. +func (mock *ExecutableSchemaMock) Complexity(typeName string, fieldName string, childComplexity int, args map[string]interface{}) (int, bool) { + if mock.ComplexityFunc == nil { + panic("ExecutableSchemaMock.ComplexityFunc: method is nil but ExecutableSchema.Complexity was just called") + } + callInfo := struct { + TypeName string + FieldName string + ChildComplexity int + Args map[string]interface{} + }{ + TypeName: typeName, + FieldName: fieldName, + ChildComplexity: childComplexity, + Args: args, + } + mock.lockComplexity.Lock() + mock.calls.Complexity = append(mock.calls.Complexity, callInfo) + mock.lockComplexity.Unlock() + return mock.ComplexityFunc(typeName, fieldName, childComplexity, args) +} + +// ComplexityCalls gets all the calls that were made to Complexity. +// Check the length with: +// len(mockedExecutableSchema.ComplexityCalls()) +func (mock *ExecutableSchemaMock) ComplexityCalls() []struct { + TypeName string + FieldName string + ChildComplexity int + Args map[string]interface{} +} { + var calls []struct { + TypeName string + FieldName string + ChildComplexity int + Args map[string]interface{} + } + mock.lockComplexity.RLock() + calls = mock.calls.Complexity + mock.lockComplexity.RUnlock() + return calls +} + +// Exec calls ExecFunc. +func (mock *ExecutableSchemaMock) Exec(ctx context.Context) ResponseHandler { + if mock.ExecFunc == nil { + panic("ExecutableSchemaMock.ExecFunc: method is nil but ExecutableSchema.Exec was just called") + } + callInfo := struct { + Ctx context.Context + }{ + Ctx: ctx, + } + mock.lockExec.Lock() + mock.calls.Exec = append(mock.calls.Exec, callInfo) + mock.lockExec.Unlock() + return mock.ExecFunc(ctx) +} + +// ExecCalls gets all the calls that were made to Exec. +// Check the length with: +// len(mockedExecutableSchema.ExecCalls()) +func (mock *ExecutableSchemaMock) ExecCalls() []struct { + Ctx context.Context +} { + var calls []struct { + Ctx context.Context + } + mock.lockExec.RLock() + calls = mock.calls.Exec + mock.lockExec.RUnlock() + return calls +} + +// Schema calls SchemaFunc. +func (mock *ExecutableSchemaMock) Schema() *ast.Schema { + if mock.SchemaFunc == nil { + panic("ExecutableSchemaMock.SchemaFunc: method is nil but ExecutableSchema.Schema was just called") + } + callInfo := struct { + }{} + mock.lockSchema.Lock() + mock.calls.Schema = append(mock.calls.Schema, callInfo) + mock.lockSchema.Unlock() + return mock.SchemaFunc() +} + +// SchemaCalls gets all the calls that were made to Schema. +// Check the length with: +// len(mockedExecutableSchema.SchemaCalls()) +func (mock *ExecutableSchemaMock) SchemaCalls() []struct { +} { + var calls []struct { + } + mock.lockSchema.RLock() + calls = mock.calls.Schema + mock.lockSchema.RUnlock() + return calls +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/executor/executor.go b/vendor/github.com/99designs/gqlgen/graphql/executor/executor.go new file mode 100644 index 0000000..95a2803 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/executor/executor.go @@ -0,0 +1,192 @@ +package executor + +import ( + "context" + + "github.com/99designs/gqlgen/graphql" + "github.com/99designs/gqlgen/graphql/errcode" + "github.com/vektah/gqlparser/v2/ast" + "github.com/vektah/gqlparser/v2/gqlerror" + "github.com/vektah/gqlparser/v2/parser" + "github.com/vektah/gqlparser/v2/validator" +) + +// Executor executes graphql queries against a schema. +type Executor struct { + es graphql.ExecutableSchema + extensions []graphql.HandlerExtension + ext extensions + + errorPresenter graphql.ErrorPresenterFunc + recoverFunc graphql.RecoverFunc + queryCache graphql.Cache +} + +var _ graphql.GraphExecutor = &Executor{} + +// New creates a new Executor with the given schema, and a default error and +// recovery callbacks, and no query cache or extensions. +func New(es graphql.ExecutableSchema) *Executor { + e := &Executor{ + es: es, + errorPresenter: graphql.DefaultErrorPresenter, + recoverFunc: graphql.DefaultRecover, + queryCache: graphql.NoCache{}, + ext: processExtensions(nil), + } + return e +} + +func (e *Executor) CreateOperationContext(ctx context.Context, params *graphql.RawParams) (*graphql.OperationContext, gqlerror.List) { + rc := &graphql.OperationContext{ + DisableIntrospection: true, + RecoverFunc: e.recoverFunc, + ResolverMiddleware: e.ext.fieldMiddleware, + RootResolverMiddleware: e.ext.rootFieldMiddleware, + Stats: graphql.Stats{ + Read: params.ReadTime, + OperationStart: graphql.GetStartTime(ctx), + }, + } + ctx = graphql.WithOperationContext(ctx, rc) + + for _, p := range e.ext.operationParameterMutators { + if err := p.MutateOperationParameters(ctx, params); err != nil { + return rc, gqlerror.List{err} + } + } + + rc.RawQuery = params.Query + rc.OperationName = params.OperationName + + var listErr gqlerror.List + rc.Doc, listErr = e.parseQuery(ctx, &rc.Stats, params.Query) + if len(listErr) != 0 { + return rc, listErr + } + + rc.Operation = rc.Doc.Operations.ForName(params.OperationName) + if rc.Operation == nil { + return rc, gqlerror.List{gqlerror.Errorf("operation %s not found", params.OperationName)} + } + + var err *gqlerror.Error + rc.Variables, err = validator.VariableValues(e.es.Schema(), rc.Operation, params.Variables) + if err != nil { + errcode.Set(err, errcode.ValidationFailed) + return rc, gqlerror.List{err} + } + rc.Stats.Validation.End = graphql.Now() + + for _, p := range e.ext.operationContextMutators { + if err := p.MutateOperationContext(ctx, rc); err != nil { + return rc, gqlerror.List{err} + } + } + + return rc, nil +} + +func (e *Executor) DispatchOperation(ctx context.Context, rc *graphql.OperationContext) (graphql.ResponseHandler, context.Context) { + ctx = graphql.WithOperationContext(ctx, rc) + + var innerCtx context.Context + res := e.ext.operationMiddleware(ctx, func(ctx context.Context) graphql.ResponseHandler { + innerCtx = ctx + + tmpResponseContext := graphql.WithResponseContext(ctx, e.errorPresenter, e.recoverFunc) + responses := e.es.Exec(tmpResponseContext) + if errs := graphql.GetErrors(tmpResponseContext); errs != nil { + return graphql.OneShot(&graphql.Response{Errors: errs}) + } + + return func(ctx context.Context) *graphql.Response { + ctx = graphql.WithResponseContext(ctx, e.errorPresenter, e.recoverFunc) + resp := e.ext.responseMiddleware(ctx, func(ctx context.Context) *graphql.Response { + resp := responses(ctx) + if resp == nil { + return nil + } + resp.Errors = append(resp.Errors, graphql.GetErrors(ctx)...) + resp.Extensions = graphql.GetExtensions(ctx) + return resp + }) + if resp == nil { + return nil + } + + return resp + } + }) + + return res, innerCtx +} + +func (e *Executor) DispatchError(ctx context.Context, list gqlerror.List) *graphql.Response { + ctx = graphql.WithResponseContext(ctx, e.errorPresenter, e.recoverFunc) + for _, gErr := range list { + graphql.AddError(ctx, gErr) + } + + resp := e.ext.responseMiddleware(ctx, func(ctx context.Context) *graphql.Response { + resp := &graphql.Response{ + Errors: list, + } + resp.Extensions = graphql.GetExtensions(ctx) + return resp + }) + + return resp +} + +func (e *Executor) PresentRecoveredError(ctx context.Context, err interface{}) *gqlerror.Error { + return e.errorPresenter(ctx, e.recoverFunc(ctx, err)) +} + +func (e *Executor) SetQueryCache(cache graphql.Cache) { + e.queryCache = cache +} + +func (e *Executor) SetErrorPresenter(f graphql.ErrorPresenterFunc) { + e.errorPresenter = f +} + +func (e *Executor) SetRecoverFunc(f graphql.RecoverFunc) { + e.recoverFunc = f +} + +// parseQuery decodes the incoming query and validates it, pulling from cache if present. +// +// NOTE: This should NOT look at variables, they will change per request. It should only parse and validate +// the raw query string. +func (e *Executor) parseQuery(ctx context.Context, stats *graphql.Stats, query string) (*ast.QueryDocument, gqlerror.List) { + stats.Parsing.Start = graphql.Now() + + if doc, ok := e.queryCache.Get(ctx, query); ok { + now := graphql.Now() + + stats.Parsing.End = now + stats.Validation.Start = now + return doc.(*ast.QueryDocument), nil + } + + doc, err := parser.ParseQuery(&ast.Source{Input: query}) + if err != nil { + errcode.Set(err, errcode.ParseFailed) + return nil, gqlerror.List{err} + } + stats.Parsing.End = graphql.Now() + + stats.Validation.Start = graphql.Now() + listErr := validator.Validate(e.es.Schema(), doc) + if len(listErr) != 0 { + for _, e := range listErr { + errcode.Set(e, errcode.ValidationFailed) + } + return nil, listErr + } + + e.queryCache.Add(ctx, query, doc) + + return doc, nil +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/executor/extensions.go b/vendor/github.com/99designs/gqlgen/graphql/executor/extensions.go new file mode 100644 index 0000000..a8eebf1 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/executor/extensions.go @@ -0,0 +1,195 @@ +package executor + +import ( + "context" + "fmt" + + "github.com/99designs/gqlgen/graphql" +) + +// Use adds the given extension to this Executor. +func (e *Executor) Use(extension graphql.HandlerExtension) { + if err := extension.Validate(e.es); err != nil { + panic(err) + } + + switch extension.(type) { + case graphql.OperationParameterMutator, + graphql.OperationContextMutator, + graphql.OperationInterceptor, + graphql.RootFieldInterceptor, + graphql.FieldInterceptor, + graphql.ResponseInterceptor: + e.extensions = append(e.extensions, extension) + e.ext = processExtensions(e.extensions) + + default: + panic(fmt.Errorf("cannot Use %T as a gqlgen handler extension because it does not implement any extension hooks", extension)) + } +} + +// AroundFields is a convenience method for creating an extension that only implements field middleware +func (e *Executor) AroundFields(f graphql.FieldMiddleware) { + e.Use(aroundFieldFunc(f)) +} + +// AroundRootFields is a convenience method for creating an extension that only implements root field middleware +func (e *Executor) AroundRootFields(f graphql.RootFieldMiddleware) { + e.Use(aroundRootFieldFunc(f)) +} + +// AroundOperations is a convenience method for creating an extension that only implements operation middleware +func (e *Executor) AroundOperations(f graphql.OperationMiddleware) { + e.Use(aroundOpFunc(f)) +} + +// AroundResponses is a convenience method for creating an extension that only implements response middleware +func (e *Executor) AroundResponses(f graphql.ResponseMiddleware) { + e.Use(aroundRespFunc(f)) +} + +type extensions struct { + operationMiddleware graphql.OperationMiddleware + responseMiddleware graphql.ResponseMiddleware + rootFieldMiddleware graphql.RootFieldMiddleware + fieldMiddleware graphql.FieldMiddleware + operationParameterMutators []graphql.OperationParameterMutator + operationContextMutators []graphql.OperationContextMutator +} + +func processExtensions(exts []graphql.HandlerExtension) extensions { + e := extensions{ + operationMiddleware: func(ctx context.Context, next graphql.OperationHandler) graphql.ResponseHandler { + return next(ctx) + }, + responseMiddleware: func(ctx context.Context, next graphql.ResponseHandler) *graphql.Response { + return next(ctx) + }, + rootFieldMiddleware: func(ctx context.Context, next graphql.RootResolver) graphql.Marshaler { + return next(ctx) + }, + fieldMiddleware: func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { + return next(ctx) + }, + } + + // this loop goes backwards so the first extension is the outer most middleware and runs first. + for i := len(exts) - 1; i >= 0; i-- { + p := exts[i] + if p, ok := p.(graphql.OperationInterceptor); ok { + previous := e.operationMiddleware + e.operationMiddleware = func(ctx context.Context, next graphql.OperationHandler) graphql.ResponseHandler { + return p.InterceptOperation(ctx, func(ctx context.Context) graphql.ResponseHandler { + return previous(ctx, next) + }) + } + } + + if p, ok := p.(graphql.ResponseInterceptor); ok { + previous := e.responseMiddleware + e.responseMiddleware = func(ctx context.Context, next graphql.ResponseHandler) *graphql.Response { + return p.InterceptResponse(ctx, func(ctx context.Context) *graphql.Response { + return previous(ctx, next) + }) + } + } + + if p, ok := p.(graphql.RootFieldInterceptor); ok { + previous := e.rootFieldMiddleware + e.rootFieldMiddleware = func(ctx context.Context, next graphql.RootResolver) graphql.Marshaler { + return p.InterceptRootField(ctx, func(ctx context.Context) graphql.Marshaler { + return previous(ctx, next) + }) + } + } + + if p, ok := p.(graphql.FieldInterceptor); ok { + previous := e.fieldMiddleware + e.fieldMiddleware = func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { + return p.InterceptField(ctx, func(ctx context.Context) (res interface{}, err error) { + return previous(ctx, next) + }) + } + } + } + + for _, p := range exts { + if p, ok := p.(graphql.OperationParameterMutator); ok { + e.operationParameterMutators = append(e.operationParameterMutators, p) + } + + if p, ok := p.(graphql.OperationContextMutator); ok { + e.operationContextMutators = append(e.operationContextMutators, p) + } + } + + return e +} + +type aroundOpFunc func(ctx context.Context, next graphql.OperationHandler) graphql.ResponseHandler + +func (r aroundOpFunc) ExtensionName() string { + return "InlineOperationFunc" +} + +func (r aroundOpFunc) Validate(schema graphql.ExecutableSchema) error { + if r == nil { + return fmt.Errorf("OperationFunc can not be nil") + } + return nil +} + +func (r aroundOpFunc) InterceptOperation(ctx context.Context, next graphql.OperationHandler) graphql.ResponseHandler { + return r(ctx, next) +} + +type aroundRespFunc func(ctx context.Context, next graphql.ResponseHandler) *graphql.Response + +func (r aroundRespFunc) ExtensionName() string { + return "InlineResponseFunc" +} + +func (r aroundRespFunc) Validate(schema graphql.ExecutableSchema) error { + if r == nil { + return fmt.Errorf("ResponseFunc can not be nil") + } + return nil +} + +func (r aroundRespFunc) InterceptResponse(ctx context.Context, next graphql.ResponseHandler) *graphql.Response { + return r(ctx, next) +} + +type aroundFieldFunc func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) + +func (f aroundFieldFunc) ExtensionName() string { + return "InlineFieldFunc" +} + +func (f aroundFieldFunc) Validate(schema graphql.ExecutableSchema) error { + if f == nil { + return fmt.Errorf("FieldFunc can not be nil") + } + return nil +} + +func (f aroundFieldFunc) InterceptField(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { + return f(ctx, next) +} + +type aroundRootFieldFunc func(ctx context.Context, next graphql.RootResolver) graphql.Marshaler + +func (f aroundRootFieldFunc) ExtensionName() string { + return "InlineRootFieldFunc" +} + +func (f aroundRootFieldFunc) Validate(schema graphql.ExecutableSchema) error { + if f == nil { + return fmt.Errorf("RootFieldFunc can not be nil") + } + return nil +} + +func (f aroundRootFieldFunc) InterceptRootField(ctx context.Context, next graphql.RootResolver) graphql.Marshaler { + return f(ctx, next) +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/fieldset.go b/vendor/github.com/99designs/gqlgen/graphql/fieldset.go new file mode 100644 index 0000000..351e266 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/fieldset.go @@ -0,0 +1,63 @@ +package graphql + +import ( + "io" + "sync" +) + +type FieldSet struct { + fields []CollectedField + Values []Marshaler + delayed []delayedResult +} + +type delayedResult struct { + i int + f func() Marshaler +} + +func NewFieldSet(fields []CollectedField) *FieldSet { + return &FieldSet{ + fields: fields, + Values: make([]Marshaler, len(fields)), + } +} + +func (m *FieldSet) Concurrently(i int, f func() Marshaler) { + m.delayed = append(m.delayed, delayedResult{i: i, f: f}) +} + +func (m *FieldSet) Dispatch() { + if len(m.delayed) == 1 { + // only one concurrent task, no need to spawn a goroutine or deal create waitgroups + d := m.delayed[0] + m.Values[d.i] = d.f() + } else if len(m.delayed) > 1 { + // more than one concurrent task, use the main goroutine to do one, only spawn goroutines for the others + + var wg sync.WaitGroup + for _, d := range m.delayed[1:] { + wg.Add(1) + go func(d delayedResult) { + m.Values[d.i] = d.f() + wg.Done() + }(d) + } + + m.Values[m.delayed[0].i] = m.delayed[0].f() + wg.Wait() + } +} + +func (m *FieldSet) MarshalGQL(writer io.Writer) { + writer.Write(openBrace) + for i, field := range m.fields { + if i != 0 { + writer.Write(comma) + } + writeQuotedString(writer, field.Alias) + writer.Write(colon) + m.Values[i].MarshalGQL(writer) + } + writer.Write(closeBrace) +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/float.go b/vendor/github.com/99designs/gqlgen/graphql/float.go new file mode 100644 index 0000000..ccb825d --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/float.go @@ -0,0 +1,47 @@ +package graphql + +import ( + "context" + "encoding/json" + "fmt" + "io" + "math" + "strconv" +) + +func MarshalFloat(f float64) Marshaler { + return WriterFunc(func(w io.Writer) { + io.WriteString(w, fmt.Sprintf("%g", f)) + }) +} + +func UnmarshalFloat(v interface{}) (float64, error) { + switch v := v.(type) { + case string: + return strconv.ParseFloat(v, 64) + case int: + return float64(v), nil + case int64: + return float64(v), nil + case float64: + return v, nil + case json.Number: + return strconv.ParseFloat(string(v), 64) + default: + return 0, fmt.Errorf("%T is not an float", v) + } +} + +func MarshalFloatContext(f float64) ContextMarshaler { + return ContextWriterFunc(func(ctx context.Context, w io.Writer) error { + if math.IsInf(f, 0) || math.IsNaN(f) { + return fmt.Errorf("cannot marshal infinite no NaN float values") + } + io.WriteString(w, fmt.Sprintf("%g", f)) + return nil + }) +} + +func UnmarshalFloatContext(ctx context.Context, v interface{}) (float64, error) { + return UnmarshalFloat(v) +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler.go b/vendor/github.com/99designs/gqlgen/graphql/handler.go new file mode 100644 index 0000000..9211659 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/handler.go @@ -0,0 +1,130 @@ +package graphql + +import ( + "context" + "net/http" + "strconv" + "strings" + + "github.com/vektah/gqlparser/v2/gqlerror" +) + +type ( + OperationMiddleware func(ctx context.Context, next OperationHandler) ResponseHandler + OperationHandler func(ctx context.Context) ResponseHandler + + ResponseHandler func(ctx context.Context) *Response + ResponseMiddleware func(ctx context.Context, next ResponseHandler) *Response + + Resolver func(ctx context.Context) (res interface{}, err error) + FieldMiddleware func(ctx context.Context, next Resolver) (res interface{}, err error) + + RootResolver func(ctx context.Context) Marshaler + RootFieldMiddleware func(ctx context.Context, next RootResolver) Marshaler + + RawParams struct { + Query string `json:"query"` + OperationName string `json:"operationName"` + Variables map[string]interface{} `json:"variables"` + Extensions map[string]interface{} `json:"extensions"` + + ReadTime TraceTiming `json:"-"` + } + + GraphExecutor interface { + CreateOperationContext(ctx context.Context, params *RawParams) (*OperationContext, gqlerror.List) + DispatchOperation(ctx context.Context, rc *OperationContext) (ResponseHandler, context.Context) + DispatchError(ctx context.Context, list gqlerror.List) *Response + } + + // HandlerExtension adds functionality to the http handler. See the list of possible hook points below + // Its important to understand the lifecycle of a graphql request and the terminology we use in gqlgen + // before working with these + // + // +--- REQUEST POST /graphql --------------------------------------------+ + // | +- OPERATION query OpName { viewer { name } } -----------------------+ | + // | | RESPONSE { "data": { "viewer": { "name": "bob" } } } | | + // | +- OPERATION subscription OpName2 { chat { message } } --------------+ | + // | | RESPONSE { "data": { "chat": { "message": "hello" } } } | | + // | | RESPONSE { "data": { "chat": { "message": "byee" } } } | | + // | +--------------------------------------------------------------------+ | + // +------------------------------------------------------------------------+ + HandlerExtension interface { + // ExtensionName should be a CamelCase string version of the extension which may be shown in stats and logging. + ExtensionName() string + // Validate is called when adding an extension to the server, it allows validation against the servers schema. + Validate(schema ExecutableSchema) error + } + + // OperationParameterMutator is called before creating a request context. allows manipulating the raw query + // on the way in. + OperationParameterMutator interface { + MutateOperationParameters(ctx context.Context, request *RawParams) *gqlerror.Error + } + + // OperationContextMutator is called after creating the request context, but before executing the root resolver. + OperationContextMutator interface { + MutateOperationContext(ctx context.Context, rc *OperationContext) *gqlerror.Error + } + + // OperationInterceptor is called for each incoming query, for basic requests the writer will be invoked once, + // for subscriptions it will be invoked multiple times. + OperationInterceptor interface { + InterceptOperation(ctx context.Context, next OperationHandler) ResponseHandler + } + + // ResponseInterceptor is called around each graphql operation response. This can be called many times for a single + // operation the case of subscriptions. + ResponseInterceptor interface { + InterceptResponse(ctx context.Context, next ResponseHandler) *Response + } + + RootFieldInterceptor interface { + InterceptRootField(ctx context.Context, next RootResolver) Marshaler + } + + // FieldInterceptor called around each field + FieldInterceptor interface { + InterceptField(ctx context.Context, next Resolver) (res interface{}, err error) + } + + // Transport provides support for different wire level encodings of graphql requests, eg Form, Get, Post, Websocket + Transport interface { + Supports(r *http.Request) bool + Do(w http.ResponseWriter, r *http.Request, exec GraphExecutor) + } +) + +type Status int + +func (p *RawParams) AddUpload(upload Upload, key, path string) *gqlerror.Error { + if !strings.HasPrefix(path, "variables.") { + return gqlerror.Errorf("invalid operations paths for key %s", key) + } + + var ptr interface{} = p.Variables + parts := strings.Split(path, ".") + + // skip the first part (variables) because we started there + for i, p := range parts[1:] { + last := i == len(parts)-2 + if ptr == nil { + return gqlerror.Errorf("path is missing \"variables.\" prefix, key: %s, path: %s", key, path) + } + if index, parseNbrErr := strconv.Atoi(p); parseNbrErr == nil { + if last { + ptr.([]interface{})[index] = upload + } else { + ptr = ptr.([]interface{})[index] + } + } else { + if last { + ptr.(map[string]interface{})[p] = upload + } else { + ptr = ptr.(map[string]interface{})[p] + } + } + } + + return nil +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/extension/apq.go b/vendor/github.com/99designs/gqlgen/graphql/handler/extension/apq.go new file mode 100644 index 0000000..866276e --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/extension/apq.go @@ -0,0 +1,114 @@ +package extension + +import ( + "context" + "crypto/sha256" + "encoding/hex" + "fmt" + + "github.com/99designs/gqlgen/graphql/errcode" + + "github.com/vektah/gqlparser/v2/gqlerror" + + "github.com/99designs/gqlgen/graphql" + "github.com/mitchellh/mapstructure" +) + +const ( + errPersistedQueryNotFound = "PersistedQueryNotFound" + errPersistedQueryNotFoundCode = "PERSISTED_QUERY_NOT_FOUND" +) + +// AutomaticPersistedQuery saves client upload by optimistically sending only the hashes of queries, if the server +// does not yet know what the query is for the hash it will respond telling the client to send the query along with the +// hash in the next request. +// see https://github.com/apollographql/apollo-link-persisted-queries +type AutomaticPersistedQuery struct { + Cache graphql.Cache +} + +type ApqStats struct { + // The hash of the incoming query + Hash string + + // SentQuery is true if the incoming request sent the full query + SentQuery bool +} + +const apqExtension = "APQ" + +var _ interface { + graphql.OperationParameterMutator + graphql.HandlerExtension +} = AutomaticPersistedQuery{} + +func (a AutomaticPersistedQuery) ExtensionName() string { + return "AutomaticPersistedQuery" +} + +func (a AutomaticPersistedQuery) Validate(schema graphql.ExecutableSchema) error { + if a.Cache == nil { + return fmt.Errorf("AutomaticPersistedQuery.Cache can not be nil") + } + return nil +} + +func (a AutomaticPersistedQuery) MutateOperationParameters(ctx context.Context, rawParams *graphql.RawParams) *gqlerror.Error { + if rawParams.Extensions["persistedQuery"] == nil { + return nil + } + + var extension struct { + Sha256 string `mapstructure:"sha256Hash"` + Version int64 `mapstructure:"version"` + } + + if err := mapstructure.Decode(rawParams.Extensions["persistedQuery"], &extension); err != nil { + return gqlerror.Errorf("invalid APQ extension data") + } + + if extension.Version != 1 { + return gqlerror.Errorf("unsupported APQ version") + } + + fullQuery := false + if rawParams.Query == "" { + // client sent optimistic query hash without query string, get it from the cache + query, ok := a.Cache.Get(ctx, extension.Sha256) + if !ok { + err := gqlerror.Errorf(errPersistedQueryNotFound) + errcode.Set(err, errPersistedQueryNotFoundCode) + return err + } + rawParams.Query = query.(string) + } else { + // client sent optimistic query hash with query string, verify and store it + if computeQueryHash(rawParams.Query) != extension.Sha256 { + return gqlerror.Errorf("provided APQ hash does not match query") + } + a.Cache.Add(ctx, extension.Sha256, rawParams.Query) + fullQuery = true + } + + graphql.GetOperationContext(ctx).Stats.SetExtension(apqExtension, &ApqStats{ + Hash: extension.Sha256, + SentQuery: fullQuery, + }) + + return nil +} + +func GetApqStats(ctx context.Context) *ApqStats { + rc := graphql.GetOperationContext(ctx) + if rc == nil { + return nil + } + + s, _ := rc.Stats.GetExtension(apqExtension).(*ApqStats) + return s +} + +func computeQueryHash(query string) string { + b := sha256.Sum256([]byte(query)) + return hex.EncodeToString(b[:]) +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/extension/complexity.go b/vendor/github.com/99designs/gqlgen/graphql/handler/extension/complexity.go new file mode 100644 index 0000000..2d85380 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/extension/complexity.go @@ -0,0 +1,88 @@ +package extension + +import ( + "context" + "fmt" + + "github.com/99designs/gqlgen/complexity" + "github.com/99designs/gqlgen/graphql" + "github.com/99designs/gqlgen/graphql/errcode" + "github.com/vektah/gqlparser/v2/gqlerror" +) + +const errComplexityLimit = "COMPLEXITY_LIMIT_EXCEEDED" + +// ComplexityLimit allows you to define a limit on query complexity +// +// If a query is submitted that exceeds the limit, a 422 status code will be returned. +type ComplexityLimit struct { + Func func(ctx context.Context, rc *graphql.OperationContext) int + + es graphql.ExecutableSchema +} + +var _ interface { + graphql.OperationContextMutator + graphql.HandlerExtension +} = &ComplexityLimit{} + +const complexityExtension = "ComplexityLimit" + +type ComplexityStats struct { + // The calculated complexity for this request + Complexity int + + // The complexity limit for this request returned by the extension func + ComplexityLimit int +} + +// FixedComplexityLimit sets a complexity limit that does not change +func FixedComplexityLimit(limit int) *ComplexityLimit { + return &ComplexityLimit{ + Func: func(ctx context.Context, rc *graphql.OperationContext) int { + return limit + }, + } +} + +func (c ComplexityLimit) ExtensionName() string { + return complexityExtension +} + +func (c *ComplexityLimit) Validate(schema graphql.ExecutableSchema) error { + if c.Func == nil { + return fmt.Errorf("ComplexityLimit func can not be nil") + } + c.es = schema + return nil +} + +func (c ComplexityLimit) MutateOperationContext(ctx context.Context, rc *graphql.OperationContext) *gqlerror.Error { + op := rc.Doc.Operations.ForName(rc.OperationName) + complexity := complexity.Calculate(c.es, op, rc.Variables) + + limit := c.Func(ctx, rc) + + rc.Stats.SetExtension(complexityExtension, &ComplexityStats{ + Complexity: complexity, + ComplexityLimit: limit, + }) + + if complexity > limit { + err := gqlerror.Errorf("operation has complexity %d, which exceeds the limit of %d", complexity, limit) + errcode.Set(err, errComplexityLimit) + return err + } + + return nil +} + +func GetComplexityStats(ctx context.Context) *ComplexityStats { + rc := graphql.GetOperationContext(ctx) + if rc == nil { + return nil + } + + s, _ := rc.Stats.GetExtension(complexityExtension).(*ComplexityStats) + return s +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/extension/introspection.go b/vendor/github.com/99designs/gqlgen/graphql/handler/extension/introspection.go new file mode 100644 index 0000000..acc5db2 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/extension/introspection.go @@ -0,0 +1,29 @@ +package extension + +import ( + "context" + + "github.com/99designs/gqlgen/graphql" + "github.com/vektah/gqlparser/v2/gqlerror" +) + +// EnableIntrospection enables clients to reflect all of the types available on the graph. +type Introspection struct{} + +var _ interface { + graphql.OperationContextMutator + graphql.HandlerExtension +} = Introspection{} + +func (c Introspection) ExtensionName() string { + return "Introspection" +} + +func (c Introspection) Validate(schema graphql.ExecutableSchema) error { + return nil +} + +func (c Introspection) MutateOperationContext(ctx context.Context, rc *graphql.OperationContext) *gqlerror.Error { + rc.DisableIntrospection = false + return nil +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/lru/lru.go b/vendor/github.com/99designs/gqlgen/graphql/handler/lru/lru.go new file mode 100644 index 0000000..e2b1561 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/lru/lru.go @@ -0,0 +1,32 @@ +package lru + +import ( + "context" + + "github.com/99designs/gqlgen/graphql" + lru "github.com/hashicorp/golang-lru" +) + +type LRU struct { + lru *lru.Cache +} + +var _ graphql.Cache = &LRU{} + +func New(size int) *LRU { + cache, err := lru.New(size) + if err != nil { + // An error is only returned for non-positive cache size + // and we already checked for that. + panic("unexpected error creating cache: " + err.Error()) + } + return &LRU{cache} +} + +func (l LRU) Get(ctx context.Context, key string) (value interface{}, ok bool) { + return l.lru.Get(key) +} + +func (l LRU) Add(ctx context.Context, key string, value interface{}) { + l.lru.Add(key, value) +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/server.go b/vendor/github.com/99designs/gqlgen/graphql/handler/server.go new file mode 100644 index 0000000..69530bb --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/server.go @@ -0,0 +1,185 @@ +package handler + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "time" + + "github.com/99designs/gqlgen/graphql" + "github.com/99designs/gqlgen/graphql/executor" + "github.com/99designs/gqlgen/graphql/handler/extension" + "github.com/99designs/gqlgen/graphql/handler/lru" + "github.com/99designs/gqlgen/graphql/handler/transport" + "github.com/vektah/gqlparser/v2/gqlerror" +) + +type ( + Server struct { + transports []graphql.Transport + exec *executor.Executor + } +) + +func New(es graphql.ExecutableSchema) *Server { + return &Server{ + exec: executor.New(es), + } +} + +func NewDefaultServer(es graphql.ExecutableSchema) *Server { + srv := New(es) + + srv.AddTransport(transport.Websocket{ + KeepAlivePingInterval: 10 * time.Second, + }) + srv.AddTransport(transport.Options{}) + srv.AddTransport(transport.GET{}) + srv.AddTransport(transport.POST{}) + srv.AddTransport(transport.MultipartForm{}) + + srv.SetQueryCache(lru.New(1000)) + + srv.Use(extension.Introspection{}) + srv.Use(extension.AutomaticPersistedQuery{ + Cache: lru.New(100), + }) + + return srv +} + +func (s *Server) AddTransport(transport graphql.Transport) { + s.transports = append(s.transports, transport) +} + +func (s *Server) SetErrorPresenter(f graphql.ErrorPresenterFunc) { + s.exec.SetErrorPresenter(f) +} + +func (s *Server) SetRecoverFunc(f graphql.RecoverFunc) { + s.exec.SetRecoverFunc(f) +} + +func (s *Server) SetQueryCache(cache graphql.Cache) { + s.exec.SetQueryCache(cache) +} + +func (s *Server) Use(extension graphql.HandlerExtension) { + s.exec.Use(extension) +} + +// AroundFields is a convenience method for creating an extension that only implements field middleware +func (s *Server) AroundFields(f graphql.FieldMiddleware) { + s.exec.AroundFields(f) +} + +// AroundRootFields is a convenience method for creating an extension that only implements field middleware +func (s *Server) AroundRootFields(f graphql.RootFieldMiddleware) { + s.exec.AroundRootFields(f) +} + +// AroundOperations is a convenience method for creating an extension that only implements operation middleware +func (s *Server) AroundOperations(f graphql.OperationMiddleware) { + s.exec.AroundOperations(f) +} + +// AroundResponses is a convenience method for creating an extension that only implements response middleware +func (s *Server) AroundResponses(f graphql.ResponseMiddleware) { + s.exec.AroundResponses(f) +} + +func (s *Server) getTransport(r *http.Request) graphql.Transport { + for _, t := range s.transports { + if t.Supports(r) { + return t + } + } + return nil +} + +func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { + defer func() { + if err := recover(); err != nil { + err := s.exec.PresentRecoveredError(r.Context(), err) + resp := &graphql.Response{Errors: []*gqlerror.Error{err}} + b, _ := json.Marshal(resp) + w.WriteHeader(http.StatusUnprocessableEntity) + w.Write(b) + } + }() + + r = r.WithContext(graphql.StartOperationTrace(r.Context())) + + transport := s.getTransport(r) + if transport == nil { + sendErrorf(w, http.StatusBadRequest, "transport not supported") + return + } + + transport.Do(w, r, s.exec) +} + +func sendError(w http.ResponseWriter, code int, errors ...*gqlerror.Error) { + w.WriteHeader(code) + b, err := json.Marshal(&graphql.Response{Errors: errors}) + if err != nil { + panic(err) + } + w.Write(b) +} + +func sendErrorf(w http.ResponseWriter, code int, format string, args ...interface{}) { + sendError(w, code, &gqlerror.Error{Message: fmt.Sprintf(format, args...)}) +} + +type OperationFunc func(ctx context.Context, next graphql.OperationHandler) graphql.ResponseHandler + +func (r OperationFunc) ExtensionName() string { + return "InlineOperationFunc" +} + +func (r OperationFunc) Validate(schema graphql.ExecutableSchema) error { + if r == nil { + return fmt.Errorf("OperationFunc can not be nil") + } + return nil +} + +func (r OperationFunc) InterceptOperation(ctx context.Context, next graphql.OperationHandler) graphql.ResponseHandler { + return r(ctx, next) +} + +type ResponseFunc func(ctx context.Context, next graphql.ResponseHandler) *graphql.Response + +func (r ResponseFunc) ExtensionName() string { + return "InlineResponseFunc" +} + +func (r ResponseFunc) Validate(schema graphql.ExecutableSchema) error { + if r == nil { + return fmt.Errorf("ResponseFunc can not be nil") + } + return nil +} + +func (r ResponseFunc) InterceptResponse(ctx context.Context, next graphql.ResponseHandler) *graphql.Response { + return r(ctx, next) +} + +type FieldFunc func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) + +func (f FieldFunc) ExtensionName() string { + return "InlineFieldFunc" +} + +func (f FieldFunc) Validate(schema graphql.ExecutableSchema) error { + if f == nil { + return fmt.Errorf("FieldFunc can not be nil") + } + return nil +} + +func (f FieldFunc) InterceptField(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { + return f(ctx, next) +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/error.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/error.go new file mode 100644 index 0000000..b1aeaf1 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/error.go @@ -0,0 +1,26 @@ +package transport + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/99designs/gqlgen/graphql" + "github.com/vektah/gqlparser/v2/gqlerror" +) + +// SendError sends a best effort error to a raw response writer. It assumes the client can understand the standard +// json error response +func SendError(w http.ResponseWriter, code int, errors ...*gqlerror.Error) { + w.WriteHeader(code) + b, err := json.Marshal(&graphql.Response{Errors: errors}) + if err != nil { + panic(err) + } + w.Write(b) +} + +// SendErrorf wraps SendError to add formatted messages +func SendErrorf(w http.ResponseWriter, code int, format string, args ...interface{}) { + SendError(w, code, &gqlerror.Error{Message: fmt.Sprintf(format, args...)}) +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_form.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_form.go new file mode 100644 index 0000000..3874eef --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_form.go @@ -0,0 +1,208 @@ +package transport + +import ( + "encoding/json" + "io" + "io/ioutil" + "mime" + "net/http" + "os" + "strings" + + "github.com/99designs/gqlgen/graphql" +) + +// MultipartForm the Multipart request spec https://github.com/jaydenseric/graphql-multipart-request-spec +type MultipartForm struct { + // MaxUploadSize sets the maximum number of bytes used to parse a request body + // as multipart/form-data. + MaxUploadSize int64 + + // MaxMemory defines the maximum number of bytes used to parse a request body + // as multipart/form-data in memory, with the remainder stored on disk in + // temporary files. + MaxMemory int64 +} + +var _ graphql.Transport = MultipartForm{} + +func (f MultipartForm) Supports(r *http.Request) bool { + if r.Header.Get("Upgrade") != "" { + return false + } + + mediaType, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + if err != nil { + return false + } + + return r.Method == "POST" && mediaType == "multipart/form-data" +} + +func (f MultipartForm) maxUploadSize() int64 { + if f.MaxUploadSize == 0 { + return 32 << 20 + } + return f.MaxUploadSize +} + +func (f MultipartForm) maxMemory() int64 { + if f.MaxMemory == 0 { + return 32 << 20 + } + return f.MaxMemory +} + +func (f MultipartForm) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecutor) { + w.Header().Set("Content-Type", "application/json") + + start := graphql.Now() + + var err error + if r.ContentLength > f.maxUploadSize() { + writeJsonError(w, "failed to parse multipart form, request body too large") + return + } + r.Body = http.MaxBytesReader(w, r.Body, f.maxUploadSize()) + if err = r.ParseMultipartForm(f.maxMemory()); err != nil { + w.WriteHeader(http.StatusUnprocessableEntity) + if strings.Contains(err.Error(), "request body too large") { + writeJsonError(w, "failed to parse multipart form, request body too large") + return + } + writeJsonError(w, "failed to parse multipart form") + return + } + defer r.Body.Close() + + var params graphql.RawParams + + if err = jsonDecode(strings.NewReader(r.Form.Get("operations")), ¶ms); err != nil { + w.WriteHeader(http.StatusUnprocessableEntity) + writeJsonError(w, "operations form field could not be decoded") + return + } + + uploadsMap := map[string][]string{} + if err = json.Unmarshal([]byte(r.Form.Get("map")), &uploadsMap); err != nil { + w.WriteHeader(http.StatusUnprocessableEntity) + writeJsonError(w, "map form field could not be decoded") + return + } + + var upload graphql.Upload + for key, paths := range uploadsMap { + if len(paths) == 0 { + w.WriteHeader(http.StatusUnprocessableEntity) + writeJsonErrorf(w, "invalid empty operations paths list for key %s", key) + return + } + file, header, err := r.FormFile(key) + if err != nil { + w.WriteHeader(http.StatusUnprocessableEntity) + writeJsonErrorf(w, "failed to get key %s from form", key) + return + } + defer file.Close() + + if len(paths) == 1 { + upload = graphql.Upload{ + File: file, + Size: header.Size, + Filename: header.Filename, + ContentType: header.Header.Get("Content-Type"), + } + + if err := params.AddUpload(upload, key, paths[0]); err != nil { + w.WriteHeader(http.StatusUnprocessableEntity) + writeJsonGraphqlError(w, err) + return + } + } else { + if r.ContentLength < f.maxMemory() { + fileBytes, err := ioutil.ReadAll(file) + if err != nil { + w.WriteHeader(http.StatusUnprocessableEntity) + writeJsonErrorf(w, "failed to read file for key %s", key) + return + } + for _, path := range paths { + upload = graphql.Upload{ + File: &bytesReader{s: &fileBytes, i: 0, prevRune: -1}, + Size: header.Size, + Filename: header.Filename, + ContentType: header.Header.Get("Content-Type"), + } + + if err := params.AddUpload(upload, key, path); err != nil { + w.WriteHeader(http.StatusUnprocessableEntity) + writeJsonGraphqlError(w, err) + return + } + } + } else { + tmpFile, err := ioutil.TempFile(os.TempDir(), "gqlgen-") + if err != nil { + w.WriteHeader(http.StatusUnprocessableEntity) + writeJsonErrorf(w, "failed to create temp file for key %s", key) + return + } + tmpName := tmpFile.Name() + defer func() { + _ = os.Remove(tmpName) + }() + _, err = io.Copy(tmpFile, file) + if err != nil { + w.WriteHeader(http.StatusUnprocessableEntity) + if err := tmpFile.Close(); err != nil { + writeJsonErrorf(w, "failed to copy to temp file and close temp file for key %s", key) + return + } + writeJsonErrorf(w, "failed to copy to temp file for key %s", key) + return + } + if err := tmpFile.Close(); err != nil { + w.WriteHeader(http.StatusUnprocessableEntity) + writeJsonErrorf(w, "failed to close temp file for key %s", key) + return + } + for _, path := range paths { + pathTmpFile, err := os.Open(tmpName) + if err != nil { + w.WriteHeader(http.StatusUnprocessableEntity) + writeJsonErrorf(w, "failed to open temp file for key %s", key) + return + } + defer pathTmpFile.Close() + upload = graphql.Upload{ + File: pathTmpFile, + Size: header.Size, + Filename: header.Filename, + ContentType: header.Header.Get("Content-Type"), + } + + if err := params.AddUpload(upload, key, path); err != nil { + w.WriteHeader(http.StatusUnprocessableEntity) + writeJsonGraphqlError(w, err) + return + } + } + } + } + } + + params.ReadTime = graphql.TraceTiming{ + Start: start, + End: graphql.Now(), + } + + rc, gerr := exec.CreateOperationContext(r.Context(), ¶ms) + if gerr != nil { + resp := exec.DispatchError(graphql.WithOperationContext(r.Context(), rc), gerr) + w.WriteHeader(statusFor(gerr)) + writeJson(w, resp) + return + } + responses, ctx := exec.DispatchOperation(r.Context(), rc) + writeJson(w, responses(ctx)) +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_get.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_get.go new file mode 100644 index 0000000..d97c89c --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_get.go @@ -0,0 +1,87 @@ +package transport + +import ( + "encoding/json" + "io" + "net/http" + "strings" + + "github.com/99designs/gqlgen/graphql" + "github.com/99designs/gqlgen/graphql/errcode" + "github.com/vektah/gqlparser/v2/ast" + "github.com/vektah/gqlparser/v2/gqlerror" +) + +// GET implements the GET side of the default HTTP transport +// defined in https://github.com/APIs-guru/graphql-over-http#get +type GET struct{} + +var _ graphql.Transport = GET{} + +func (h GET) Supports(r *http.Request) bool { + if r.Header.Get("Upgrade") != "" { + return false + } + + return r.Method == "GET" +} + +func (h GET) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecutor) { + w.Header().Set("Content-Type", "application/json") + + raw := &graphql.RawParams{ + Query: r.URL.Query().Get("query"), + OperationName: r.URL.Query().Get("operationName"), + } + raw.ReadTime.Start = graphql.Now() + + if variables := r.URL.Query().Get("variables"); variables != "" { + if err := jsonDecode(strings.NewReader(variables), &raw.Variables); err != nil { + w.WriteHeader(http.StatusBadRequest) + writeJsonError(w, "variables could not be decoded") + return + } + } + + if extensions := r.URL.Query().Get("extensions"); extensions != "" { + if err := jsonDecode(strings.NewReader(extensions), &raw.Extensions); err != nil { + w.WriteHeader(http.StatusBadRequest) + writeJsonError(w, "extensions could not be decoded") + return + } + } + + raw.ReadTime.End = graphql.Now() + + rc, err := exec.CreateOperationContext(r.Context(), raw) + if err != nil { + w.WriteHeader(statusFor(err)) + resp := exec.DispatchError(graphql.WithOperationContext(r.Context(), rc), err) + writeJson(w, resp) + return + } + op := rc.Doc.Operations.ForName(rc.OperationName) + if op.Operation != ast.Query { + w.WriteHeader(http.StatusNotAcceptable) + writeJsonError(w, "GET requests only allow query operations") + return + } + + responses, ctx := exec.DispatchOperation(r.Context(), rc) + writeJson(w, responses(ctx)) +} + +func jsonDecode(r io.Reader, val interface{}) error { + dec := json.NewDecoder(r) + dec.UseNumber() + return dec.Decode(val) +} + +func statusFor(errs gqlerror.List) int { + switch errcode.GetErrorKind(errs) { + case errcode.KindProtocol: + return http.StatusUnprocessableEntity + default: + return http.StatusOK + } +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_post.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_post.go new file mode 100644 index 0000000..deefeb3 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_post.go @@ -0,0 +1,53 @@ +package transport + +import ( + "mime" + "net/http" + + "github.com/99designs/gqlgen/graphql" +) + +// POST implements the POST side of the default HTTP transport +// defined in https://github.com/APIs-guru/graphql-over-http#post +type POST struct{} + +var _ graphql.Transport = POST{} + +func (h POST) Supports(r *http.Request) bool { + if r.Header.Get("Upgrade") != "" { + return false + } + + mediaType, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + if err != nil { + return false + } + + return r.Method == "POST" && mediaType == "application/json" +} + +func (h POST) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecutor) { + w.Header().Set("Content-Type", "application/json") + + var params *graphql.RawParams + start := graphql.Now() + if err := jsonDecode(r.Body, ¶ms); err != nil { + w.WriteHeader(http.StatusBadRequest) + writeJsonErrorf(w, "json body could not be decoded: "+err.Error()) + return + } + params.ReadTime = graphql.TraceTiming{ + Start: start, + End: graphql.Now(), + } + + rc, err := exec.CreateOperationContext(r.Context(), params) + if err != nil { + w.WriteHeader(statusFor(err)) + resp := exec.DispatchError(graphql.WithOperationContext(r.Context(), rc), err) + writeJson(w, resp) + return + } + responses, ctx := exec.DispatchOperation(r.Context(), rc) + writeJson(w, responses(ctx)) +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/options.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/options.go new file mode 100644 index 0000000..6b725ff --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/options.go @@ -0,0 +1,26 @@ +package transport + +import ( + "net/http" + + "github.com/99designs/gqlgen/graphql" +) + +// Options responds to http OPTIONS and HEAD requests +type Options struct{} + +var _ graphql.Transport = Options{} + +func (o Options) Supports(r *http.Request) bool { + return r.Method == "HEAD" || r.Method == "OPTIONS" +} + +func (o Options) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecutor) { + switch r.Method { + case http.MethodOptions: + w.Header().Set("Allow", "OPTIONS, GET, POST") + w.WriteHeader(http.StatusOK) + case http.MethodHead: + w.WriteHeader(http.StatusMethodNotAllowed) + } +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/reader.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/reader.go new file mode 100644 index 0000000..d3261e2 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/reader.go @@ -0,0 +1,25 @@ +package transport + +import ( + "errors" + "io" +) + +type bytesReader struct { + s *[]byte + i int64 // current reading index + prevRune int // index of previous rune; or < 0 +} + +func (r *bytesReader) Read(b []byte) (n int, err error) { + if r.s == nil { + return 0, errors.New("byte slice pointer is nil") + } + if r.i >= int64(len(*r.s)) { + return 0, io.EOF + } + r.prevRune = -1 + n = copy(b, (*r.s)[r.i:]) + r.i += int64(n) + return +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/util.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/util.go new file mode 100644 index 0000000..ce845c1 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/util.go @@ -0,0 +1,30 @@ +package transport + +import ( + "encoding/json" + "fmt" + "io" + + "github.com/99designs/gqlgen/graphql" + "github.com/vektah/gqlparser/v2/gqlerror" +) + +func writeJson(w io.Writer, response *graphql.Response) { + b, err := json.Marshal(response) + if err != nil { + panic(err) + } + w.Write(b) +} + +func writeJsonError(w io.Writer, msg string) { + writeJson(w, &graphql.Response{Errors: gqlerror.List{{Message: msg}}}) +} + +func writeJsonErrorf(w io.Writer, format string, args ...interface{}) { + writeJson(w, &graphql.Response{Errors: gqlerror.List{{Message: fmt.Sprintf(format, args...)}}}) +} + +func writeJsonGraphqlError(w io.Writer, err ...*gqlerror.Error) { + writeJson(w, &graphql.Response{Errors: err}) +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket.go new file mode 100644 index 0000000..c91d9cc --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket.go @@ -0,0 +1,365 @@ +package transport + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "log" + "net/http" + "sync" + "time" + + "github.com/99designs/gqlgen/graphql" + "github.com/99designs/gqlgen/graphql/errcode" + "github.com/gorilla/websocket" + "github.com/vektah/gqlparser/v2/gqlerror" +) + +type ( + Websocket struct { + Upgrader websocket.Upgrader + InitFunc WebsocketInitFunc + KeepAlivePingInterval time.Duration + PingPongInterval time.Duration + + didInjectSubprotocols bool + } + wsConnection struct { + Websocket + ctx context.Context + conn *websocket.Conn + me messageExchanger + active map[string]context.CancelFunc + mu sync.Mutex + keepAliveTicker *time.Ticker + pingPongTicker *time.Ticker + exec graphql.GraphExecutor + + initPayload InitPayload + } + + WebsocketInitFunc func(ctx context.Context, initPayload InitPayload) (context.Context, error) +) + +var _ graphql.Transport = Websocket{} + +func (t Websocket) Supports(r *http.Request) bool { + return r.Header.Get("Upgrade") != "" +} + +func (t Websocket) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecutor) { + t.injectGraphQLWSSubprotocols() + ws, err := t.Upgrader.Upgrade(w, r, http.Header{}) + if err != nil { + log.Printf("unable to upgrade %T to websocket %s: ", w, err.Error()) + SendErrorf(w, http.StatusBadRequest, "unable to upgrade") + return + } + + var me messageExchanger + switch ws.Subprotocol() { + default: + msg := websocket.FormatCloseMessage(websocket.CloseProtocolError, fmt.Sprintf("unsupported negotiated subprotocol %s", ws.Subprotocol())) + ws.WriteMessage(websocket.CloseMessage, msg) + return + case graphqlwsSubprotocol, "": + // clients are required to send a subprotocol, to be backward compatible with the previous implementation we select + // "graphql-ws" by default + me = graphqlwsMessageExchanger{c: ws} + case graphqltransportwsSubprotocol: + me = graphqltransportwsMessageExchanger{c: ws} + } + + conn := wsConnection{ + active: map[string]context.CancelFunc{}, + conn: ws, + ctx: r.Context(), + exec: exec, + me: me, + Websocket: t, + } + + if !conn.init() { + return + } + + conn.run() +} + +func (c *wsConnection) init() bool { + m, err := c.me.NextMessage() + if err != nil { + if err == errInvalidMsg { + c.sendConnectionError("invalid json") + } + + c.close(websocket.CloseProtocolError, "decoding error") + return false + } + + switch m.t { + case initMessageType: + if len(m.payload) > 0 { + c.initPayload = make(InitPayload) + err := json.Unmarshal(m.payload, &c.initPayload) + if err != nil { + return false + } + } + + if c.InitFunc != nil { + ctx, err := c.InitFunc(c.ctx, c.initPayload) + if err != nil { + c.sendConnectionError(err.Error()) + c.close(websocket.CloseNormalClosure, "terminated") + return false + } + c.ctx = ctx + } + + c.write(&message{t: connectionAckMessageType}) + c.write(&message{t: keepAliveMessageType}) + case connectionCloseMessageType: + c.close(websocket.CloseNormalClosure, "terminated") + return false + default: + c.sendConnectionError("unexpected message %s", m.t) + c.close(websocket.CloseProtocolError, "unexpected message") + return false + } + + return true +} + +func (c *wsConnection) write(msg *message) { + c.mu.Lock() + // TODO: missing error handling here, err from previous implementation + // was ignored + _ = c.me.Send(msg) + c.mu.Unlock() +} + +func (c *wsConnection) run() { + // We create a cancellation that will shutdown the keep-alive when we leave + // this function. + ctx, cancel := context.WithCancel(c.ctx) + defer func() { + cancel() + c.close(websocket.CloseAbnormalClosure, "unexpected closure") + }() + + // Create a timer that will fire every interval to keep the connection alive. + if c.KeepAlivePingInterval != 0 { + c.mu.Lock() + c.keepAliveTicker = time.NewTicker(c.KeepAlivePingInterval) + c.mu.Unlock() + + go c.keepAlive(ctx) + } + + // Create a timer that will fire every interval a ping message that should + // receive a pong (SetPongHandler in init() function) + if c.PingPongInterval != 0 { + c.mu.Lock() + c.pingPongTicker = time.NewTicker(c.PingPongInterval) + c.mu.Unlock() + + c.conn.SetReadDeadline(time.Now().UTC().Add(2 * c.PingPongInterval)) + go c.ping(ctx) + } + + // Close the connection when the context is cancelled. + // Will optionally send a "close reason" that is retrieved from the context. + go c.closeOnCancel(ctx) + + for { + start := graphql.Now() + m, err := c.me.NextMessage() + if err != nil { + // TODO: better error handling here + return + } + + switch m.t { + case startMessageType: + c.subscribe(start, &m) + case stopMessageType: + c.mu.Lock() + closer := c.active[m.id] + c.mu.Unlock() + if closer != nil { + closer() + } + case connectionCloseMessageType: + c.close(websocket.CloseNormalClosure, "terminated") + return + case pingMesageType: + c.write(&message{t: pongMessageType, payload: m.payload}) + case pongMessageType: + c.conn.SetReadDeadline(time.Now().UTC().Add(2 * c.PingPongInterval)) + default: + c.sendConnectionError("unexpected message %s", m.t) + c.close(websocket.CloseProtocolError, "unexpected message") + return + } + } +} + +func (c *wsConnection) keepAlive(ctx context.Context) { + for { + select { + case <-ctx.Done(): + c.keepAliveTicker.Stop() + return + case <-c.keepAliveTicker.C: + c.write(&message{t: keepAliveMessageType}) + } + } +} + +func (c *wsConnection) ping(ctx context.Context) { + for { + select { + case <-ctx.Done(): + c.pingPongTicker.Stop() + return + case <-c.pingPongTicker.C: + c.write(&message{t: pingMesageType, payload: json.RawMessage{}}) + } + } +} + +func (c *wsConnection) closeOnCancel(ctx context.Context) { + <-ctx.Done() + + if r := closeReasonForContext(ctx); r != "" { + c.sendConnectionError(r) + } + c.close(websocket.CloseNormalClosure, "terminated") +} + +func (c *wsConnection) subscribe(start time.Time, msg *message) { + ctx := graphql.StartOperationTrace(c.ctx) + var params *graphql.RawParams + if err := jsonDecode(bytes.NewReader(msg.payload), ¶ms); err != nil { + c.sendError(msg.id, &gqlerror.Error{Message: "invalid json"}) + c.complete(msg.id) + return + } + + params.ReadTime = graphql.TraceTiming{ + Start: start, + End: graphql.Now(), + } + + rc, err := c.exec.CreateOperationContext(ctx, params) + if err != nil { + resp := c.exec.DispatchError(graphql.WithOperationContext(ctx, rc), err) + switch errcode.GetErrorKind(err) { + case errcode.KindProtocol: + c.sendError(msg.id, resp.Errors...) + default: + c.sendResponse(msg.id, &graphql.Response{Errors: err}) + } + + c.complete(msg.id) + return + } + + ctx = graphql.WithOperationContext(ctx, rc) + + if c.initPayload != nil { + ctx = withInitPayload(ctx, c.initPayload) + } + + ctx, cancel := context.WithCancel(ctx) + c.mu.Lock() + c.active[msg.id] = cancel + c.mu.Unlock() + + go func() { + defer func() { + if r := recover(); r != nil { + err := rc.Recover(ctx, r) + var gqlerr *gqlerror.Error + if !errors.As(err, &gqlerr) { + gqlerr = &gqlerror.Error{} + if err != nil { + gqlerr.Message = err.Error() + } + } + c.sendError(msg.id, gqlerr) + } + c.complete(msg.id) + c.mu.Lock() + delete(c.active, msg.id) + c.mu.Unlock() + cancel() + }() + + responses, ctx := c.exec.DispatchOperation(ctx, rc) + for { + response := responses(ctx) + if response == nil { + break + } + + c.sendResponse(msg.id, response) + } + c.complete(msg.id) + + c.mu.Lock() + delete(c.active, msg.id) + c.mu.Unlock() + cancel() + }() +} + +func (c *wsConnection) sendResponse(id string, response *graphql.Response) { + b, err := json.Marshal(response) + if err != nil { + panic(err) + } + c.write(&message{ + payload: b, + id: id, + t: dataMessageType, + }) +} + +func (c *wsConnection) complete(id string) { + c.write(&message{id: id, t: completeMessageType}) +} + +func (c *wsConnection) sendError(id string, errors ...*gqlerror.Error) { + errs := make([]error, len(errors)) + for i, err := range errors { + errs[i] = err + } + b, err := json.Marshal(errs) + if err != nil { + panic(err) + } + c.write(&message{t: errorMessageType, id: id, payload: b}) +} + +func (c *wsConnection) sendConnectionError(format string, args ...interface{}) { + b, err := json.Marshal(&gqlerror.Error{Message: fmt.Sprintf(format, args...)}) + if err != nil { + panic(err) + } + + c.write(&message{t: connectionErrorMessageType, payload: b}) +} + +func (c *wsConnection) close(closeCode int, message string) { + c.mu.Lock() + _ = c.conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(closeCode, message)) + for _, closer := range c.active { + closer() + } + c.mu.Unlock() + _ = c.conn.Close() +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_close_reason.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_close_reason.go new file mode 100644 index 0000000..c8217de --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_close_reason.go @@ -0,0 +1,22 @@ +package transport + +import ( + "context" +) + +// A private key for context that only this package can access. This is important +// to prevent collisions between different context uses +var closeReasonCtxKey = &wsCloseReasonContextKey{"close-reason"} + +type wsCloseReasonContextKey struct { + name string +} + +func AppendCloseReason(ctx context.Context, reason string) context.Context { + return context.WithValue(ctx, closeReasonCtxKey, reason) +} + +func closeReasonForContext(ctx context.Context) string { + reason, _ := ctx.Value(closeReasonCtxKey).(string) + return reason +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_graphql_transport_ws.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_graphql_transport_ws.go new file mode 100644 index 0000000..a5b6e3a --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_graphql_transport_ws.go @@ -0,0 +1,149 @@ +package transport + +import ( + "encoding/json" + "fmt" + + "github.com/gorilla/websocket" +) + +// https://github.com/enisdenjo/graphql-ws/blob/master/PROTOCOL.md +const ( + graphqltransportwsSubprotocol = "graphql-transport-ws" + + graphqltransportwsConnectionInitMsg = graphqltransportwsMessageType("connection_init") + graphqltransportwsConnectionAckMsg = graphqltransportwsMessageType("connection_ack") + graphqltransportwsSubscribeMsg = graphqltransportwsMessageType("subscribe") + graphqltransportwsNextMsg = graphqltransportwsMessageType("next") + graphqltransportwsErrorMsg = graphqltransportwsMessageType("error") + graphqltransportwsCompleteMsg = graphqltransportwsMessageType("complete") + graphqltransportwsPingMsg = graphqltransportwsMessageType("ping") + graphqltransportwsPongMsg = graphqltransportwsMessageType("pong") +) + +var allGraphqltransportwsMessageTypes = []graphqltransportwsMessageType{ + graphqltransportwsConnectionInitMsg, + graphqltransportwsConnectionAckMsg, + graphqltransportwsSubscribeMsg, + graphqltransportwsNextMsg, + graphqltransportwsErrorMsg, + graphqltransportwsCompleteMsg, + graphqltransportwsPingMsg, + graphqltransportwsPongMsg, +} + +type ( + graphqltransportwsMessageExchanger struct { + c *websocket.Conn + } + + graphqltransportwsMessage struct { + Payload json.RawMessage `json:"payload,omitempty"` + ID string `json:"id,omitempty"` + Type graphqltransportwsMessageType `json:"type"` + noOp bool + } + + graphqltransportwsMessageType string +) + +func (me graphqltransportwsMessageExchanger) NextMessage() (message, error) { + _, r, err := me.c.NextReader() + if err != nil { + return message{}, handleNextReaderError(err) + } + + var graphqltransportwsMessage graphqltransportwsMessage + if err := jsonDecode(r, &graphqltransportwsMessage); err != nil { + return message{}, errInvalidMsg + } + + return graphqltransportwsMessage.toMessage() +} + +func (me graphqltransportwsMessageExchanger) Send(m *message) error { + msg := &graphqltransportwsMessage{} + if err := msg.fromMessage(m); err != nil { + return err + } + + if msg.noOp { + return nil + } + + return me.c.WriteJSON(msg) +} + +func (t *graphqltransportwsMessageType) UnmarshalText(text []byte) (err error) { + var found bool + for _, candidate := range allGraphqltransportwsMessageTypes { + if string(candidate) == string(text) { + *t = candidate + found = true + break + } + } + + if !found { + err = fmt.Errorf("invalid message type %s", string(text)) + } + + return err +} + +func (t graphqltransportwsMessageType) MarshalText() ([]byte, error) { + return []byte(string(t)), nil +} + +func (m graphqltransportwsMessage) toMessage() (message, error) { + var t messageType + var err error + switch m.Type { + default: + err = fmt.Errorf("invalid client->server message type %s", m.Type) + case graphqltransportwsConnectionInitMsg: + t = initMessageType + case graphqltransportwsSubscribeMsg: + t = startMessageType + case graphqltransportwsCompleteMsg: + t = stopMessageType + case graphqltransportwsPingMsg: + t = pingMesageType + case graphqltransportwsPongMsg: + t = pongMessageType + } + + return message{ + payload: m.Payload, + id: m.ID, + t: t, + }, err +} + +func (m *graphqltransportwsMessage) fromMessage(msg *message) (err error) { + m.ID = msg.id + m.Payload = msg.payload + + switch msg.t { + default: + err = fmt.Errorf("invalid server->client message type %s", msg.t) + case connectionAckMessageType: + m.Type = graphqltransportwsConnectionAckMsg + case keepAliveMessageType: + m.noOp = true + case connectionErrorMessageType: + m.noOp = true + case dataMessageType: + m.Type = graphqltransportwsNextMsg + case completeMessageType: + m.Type = graphqltransportwsCompleteMsg + case errorMessageType: + m.Type = graphqltransportwsErrorMsg + case pingMesageType: + m.Type = graphqltransportwsPingMsg + case pongMessageType: + m.Type = graphqltransportwsPongMsg + } + + return err +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_graphqlws.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_graphqlws.go new file mode 100644 index 0000000..3e8845c --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_graphqlws.go @@ -0,0 +1,169 @@ +package transport + +import ( + "encoding/json" + "fmt" + + "github.com/gorilla/websocket" +) + +// https://github.com/apollographql/subscriptions-transport-ws/blob/master/PROTOCOL.md +const ( + graphqlwsSubprotocol = "graphql-ws" + + graphqlwsConnectionInitMsg = graphqlwsMessageType("connection_init") + graphqlwsConnectionTerminateMsg = graphqlwsMessageType("connection_terminate") + graphqlwsStartMsg = graphqlwsMessageType("start") + graphqlwsStopMsg = graphqlwsMessageType("stop") + graphqlwsConnectionAckMsg = graphqlwsMessageType("connection_ack") + graphqlwsConnectionErrorMsg = graphqlwsMessageType("connection_error") + graphqlwsDataMsg = graphqlwsMessageType("data") + graphqlwsErrorMsg = graphqlwsMessageType("error") + graphqlwsCompleteMsg = graphqlwsMessageType("complete") + graphqlwsConnectionKeepAliveMsg = graphqlwsMessageType("ka") +) + +var allGraphqlwsMessageTypes = []graphqlwsMessageType{ + graphqlwsConnectionInitMsg, + graphqlwsConnectionTerminateMsg, + graphqlwsStartMsg, + graphqlwsStopMsg, + graphqlwsConnectionAckMsg, + graphqlwsConnectionErrorMsg, + graphqlwsDataMsg, + graphqlwsErrorMsg, + graphqlwsCompleteMsg, + graphqlwsConnectionKeepAliveMsg, +} + +type ( + graphqlwsMessageExchanger struct { + c *websocket.Conn + } + + graphqlwsMessage struct { + Payload json.RawMessage `json:"payload,omitempty"` + ID string `json:"id,omitempty"` + Type graphqlwsMessageType `json:"type"` + } + + graphqlwsMessageType string +) + +func (me graphqlwsMessageExchanger) NextMessage() (message, error) { + _, r, err := me.c.NextReader() + if err != nil { + return message{}, handleNextReaderError(err) + } + + var graphqlwsMessage graphqlwsMessage + if err := jsonDecode(r, &graphqlwsMessage); err != nil { + return message{}, errInvalidMsg + } + + return graphqlwsMessage.toMessage() +} + +func (me graphqlwsMessageExchanger) Send(m *message) error { + msg := &graphqlwsMessage{} + if err := msg.fromMessage(m); err != nil { + return err + } + + return me.c.WriteJSON(msg) +} + +func (t *graphqlwsMessageType) UnmarshalText(text []byte) (err error) { + var found bool + for _, candidate := range allGraphqlwsMessageTypes { + if string(candidate) == string(text) { + *t = candidate + found = true + break + } + } + + if !found { + err = fmt.Errorf("invalid message type %s", string(text)) + } + + return err +} + +func (t graphqlwsMessageType) MarshalText() ([]byte, error) { + return []byte(string(t)), nil +} + +func (t graphqlwsMessageType) toMessageType() (mt messageType, err error) { + switch t { + default: + err = fmt.Errorf("unknown message type mapping for %s", t) + case graphqlwsConnectionInitMsg: + mt = initMessageType + case graphqlwsConnectionTerminateMsg: + mt = connectionCloseMessageType + case graphqlwsStartMsg: + mt = startMessageType + case graphqlwsStopMsg: + mt = stopMessageType + case graphqlwsConnectionAckMsg: + mt = connectionAckMessageType + case graphqlwsConnectionErrorMsg: + mt = connectionErrorMessageType + case graphqlwsDataMsg: + mt = dataMessageType + case graphqlwsErrorMsg: + mt = errorMessageType + case graphqlwsCompleteMsg: + mt = completeMessageType + case graphqlwsConnectionKeepAliveMsg: + mt = keepAliveMessageType + } + + return mt, err +} + +func (t *graphqlwsMessageType) fromMessageType(mt messageType) (err error) { + switch mt { + default: + err = fmt.Errorf("failed to convert message %s to %s subprotocol", mt, graphqlwsSubprotocol) + case initMessageType: + *t = graphqlwsConnectionInitMsg + case connectionAckMessageType: + *t = graphqlwsConnectionAckMsg + case keepAliveMessageType: + *t = graphqlwsConnectionKeepAliveMsg + case connectionErrorMessageType: + *t = graphqlwsConnectionErrorMsg + case connectionCloseMessageType: + *t = graphqlwsConnectionTerminateMsg + case startMessageType: + *t = graphqlwsStartMsg + case stopMessageType: + *t = graphqlwsStopMsg + case dataMessageType: + *t = graphqlwsDataMsg + case completeMessageType: + *t = graphqlwsCompleteMsg + case errorMessageType: + *t = graphqlwsErrorMsg + } + + return err +} + +func (m graphqlwsMessage) toMessage() (message, error) { + mt, err := m.Type.toMessageType() + return message{ + payload: m.Payload, + id: m.ID, + t: mt, + }, err +} + +func (m *graphqlwsMessage) fromMessage(msg *message) (err error) { + err = m.Type.fromMessageType(msg.t) + m.ID = msg.id + m.Payload = msg.payload + return err +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_init.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_init.go new file mode 100644 index 0000000..a5f84ba --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_init.go @@ -0,0 +1,57 @@ +package transport + +import "context" + +type key string + +const ( + initpayload key = "ws_initpayload_context" +) + +// InitPayload is a structure that is parsed from the websocket init message payload. TO use +// request headers for non-websocket, instead wrap the graphql handler in a middleware. +type InitPayload map[string]interface{} + +// GetString safely gets a string value from the payload. It returns an empty string if the +// payload is nil or the value isn't set. +func (p InitPayload) GetString(key string) string { + if p == nil { + return "" + } + + if value, ok := p[key]; ok { + res, _ := value.(string) + return res + } + + return "" +} + +// Authorization is a short hand for getting the Authorization header from the +// payload. +func (p InitPayload) Authorization() string { + if value := p.GetString("Authorization"); value != "" { + return value + } + + if value := p.GetString("authorization"); value != "" { + return value + } + + return "" +} + +func withInitPayload(ctx context.Context, payload InitPayload) context.Context { + return context.WithValue(ctx, initpayload, payload) +} + +// GetInitPayload gets a map of the data sent with the connection_init message, which is used by +// graphql clients as a stand-in for HTTP headers. +func GetInitPayload(ctx context.Context) InitPayload { + payload, ok := ctx.Value(initpayload).(InitPayload) + if !ok { + return nil + } + + return payload +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_subprotocol.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_subprotocol.go new file mode 100644 index 0000000..83639e3 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_subprotocol.go @@ -0,0 +1,116 @@ +package transport + +import ( + "encoding/json" + "errors" + + "github.com/gorilla/websocket" +) + +const ( + initMessageType messageType = iota + connectionAckMessageType + keepAliveMessageType + connectionErrorMessageType + connectionCloseMessageType + startMessageType + stopMessageType + dataMessageType + completeMessageType + errorMessageType + pingMesageType + pongMessageType +) + +var ( + supportedSubprotocols = []string{ + graphqlwsSubprotocol, + graphqltransportwsSubprotocol, + } + + errWsConnClosed = errors.New("websocket connection closed") + errInvalidMsg = errors.New("invalid message received") +) + +type ( + messageType int + message struct { + payload json.RawMessage + id string + t messageType + } + messageExchanger interface { + NextMessage() (message, error) + Send(m *message) error + } +) + +func (t messageType) String() string { + var text string + switch t { + default: + text = "unknown" + case initMessageType: + text = "init" + case connectionAckMessageType: + text = "connection ack" + case keepAliveMessageType: + text = "keep alive" + case connectionErrorMessageType: + text = "connection error" + case connectionCloseMessageType: + text = "connection close" + case startMessageType: + text = "start" + case stopMessageType: + text = "stop subscription" + case dataMessageType: + text = "data" + case completeMessageType: + text = "complete" + case errorMessageType: + text = "error" + case pingMesageType: + text = "ping" + case pongMessageType: + text = "pong" + } + return text +} + +func contains(list []string, elem string) bool { + for _, e := range list { + if e == elem { + return true + } + } + + return false +} + +func (t *Websocket) injectGraphQLWSSubprotocols() { + // the list of subprotocols is specified by the consumer of the Websocket struct, + // in order to preserve backward compatibility, we inject the graphql specific subprotocols + // at runtime + if !t.didInjectSubprotocols { + defer func() { + t.didInjectSubprotocols = true + }() + + for _, subprotocol := range supportedSubprotocols { + if !contains(t.Upgrader.Subprotocols, subprotocol) { + t.Upgrader.Subprotocols = append(t.Upgrader.Subprotocols, subprotocol) + } + } + } +} + +func handleNextReaderError(err error) error { + // TODO: should we consider all closure scenarios here for the ws connection? + // for now we only list the error codes from the previous implementation + if websocket.IsCloseError(err, websocket.CloseNormalClosure, websocket.CloseNoStatusReceived) { + return errWsConnClosed + } + + return err +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/id.go b/vendor/github.com/99designs/gqlgen/graphql/id.go new file mode 100644 index 0000000..b24605d --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/id.go @@ -0,0 +1,58 @@ +package graphql + +import ( + "encoding/json" + "fmt" + "io" + "strconv" +) + +func MarshalID(s string) Marshaler { + return MarshalString(s) +} + +func UnmarshalID(v interface{}) (string, error) { + switch v := v.(type) { + case string: + return v, nil + case json.Number: + return string(v), nil + case int: + return strconv.Itoa(v), nil + case int64: + return strconv.FormatInt(v, 10), nil + case float64: + return fmt.Sprintf("%f", v), nil + case bool: + if v { + return "true", nil + } else { + return "false", nil + } + case nil: + return "null", nil + default: + return "", fmt.Errorf("%T is not a string", v) + } +} + +func MarshalIntID(i int) Marshaler { + return WriterFunc(func(w io.Writer) { + writeQuotedString(w, strconv.Itoa(i)) + }) +} + +func UnmarshalIntID(v interface{}) (int, error) { + switch v := v.(type) { + case string: + return strconv.Atoi(v) + case int: + return v, nil + case int64: + return int(v), nil + case json.Number: + return strconv.Atoi(string(v)) + default: + return 0, fmt.Errorf("%T is not an int", v) + } +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/int.go b/vendor/github.com/99designs/gqlgen/graphql/int.go new file mode 100644 index 0000000..57d0d58 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/int.go @@ -0,0 +1,79 @@ +package graphql + +import ( + "encoding/json" + "fmt" + "io" + "strconv" +) + +func MarshalInt(i int) Marshaler { + return WriterFunc(func(w io.Writer) { + io.WriteString(w, strconv.Itoa(i)) + }) +} + +func UnmarshalInt(v interface{}) (int, error) { + switch v := v.(type) { + case string: + return strconv.Atoi(v) + case int: + return v, nil + case int64: + return int(v), nil + case json.Number: + return strconv.Atoi(string(v)) + default: + return 0, fmt.Errorf("%T is not an int", v) + } +} + +func MarshalInt64(i int64) Marshaler { + return WriterFunc(func(w io.Writer) { + io.WriteString(w, strconv.FormatInt(i, 10)) + }) +} + +func UnmarshalInt64(v interface{}) (int64, error) { + switch v := v.(type) { + case string: + return strconv.ParseInt(v, 10, 64) + case int: + return int64(v), nil + case int64: + return v, nil + case json.Number: + return strconv.ParseInt(string(v), 10, 64) + default: + return 0, fmt.Errorf("%T is not an int", v) + } +} + +func MarshalInt32(i int32) Marshaler { + return WriterFunc(func(w io.Writer) { + io.WriteString(w, strconv.FormatInt(int64(i), 10)) + }) +} + +func UnmarshalInt32(v interface{}) (int32, error) { + switch v := v.(type) { + case string: + iv, err := strconv.ParseInt(v, 10, 32) + if err != nil { + return 0, err + } + return int32(iv), nil + case int: + return int32(v), nil + case int64: + return int32(v), nil + case json.Number: + iv, err := strconv.ParseInt(string(v), 10, 32) + if err != nil { + return 0, err + } + return int32(iv), nil + default: + return 0, fmt.Errorf("%T is not an int", v) + } +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/introspection/introspection.go b/vendor/github.com/99designs/gqlgen/graphql/introspection/introspection.go new file mode 100644 index 0000000..709fa96 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/introspection/introspection.go @@ -0,0 +1,73 @@ +// introspection implements the spec defined in https://github.com/facebook/graphql/blob/master/spec/Section%204%20--%20Introspection.md#schema-introspection +package introspection + +import "github.com/vektah/gqlparser/v2/ast" + +type ( + Directive struct { + Name string + Description string + Locations []string + Args []InputValue + IsRepeatable bool + } + + EnumValue struct { + Name string + Description string + deprecation *ast.Directive + } + + Field struct { + Name string + Description string + Type *Type + Args []InputValue + deprecation *ast.Directive + } + + InputValue struct { + Name string + Description string + DefaultValue *string + Type *Type + } +) + +func WrapSchema(schema *ast.Schema) *Schema { + return &Schema{schema: schema} +} + +func (f *EnumValue) IsDeprecated() bool { + return f.deprecation != nil +} + +func (f *EnumValue) DeprecationReason() *string { + if f.deprecation == nil { + return nil + } + + reason := f.deprecation.Arguments.ForName("reason") + if reason == nil { + return nil + } + + return &reason.Value.Raw +} + +func (f *Field) IsDeprecated() bool { + return f.deprecation != nil +} + +func (f *Field) DeprecationReason() *string { + if f.deprecation == nil { + return nil + } + + reason := f.deprecation.Arguments.ForName("reason") + if reason == nil { + return nil + } + + return &reason.Value.Raw +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/introspection/query.go b/vendor/github.com/99designs/gqlgen/graphql/introspection/query.go new file mode 100644 index 0000000..b1e4fbc --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/introspection/query.go @@ -0,0 +1,104 @@ +package introspection + +// Query is the query generated by graphiql to determine type information +const Query = ` +query IntrospectionQuery { + __schema { + queryType { + name + } + mutationType { + name + } + subscriptionType { + name + } + types { + ...FullType + } + directives { + name + description + locations + args { + ...InputValue + } + } + } +} + +fragment FullType on __Type { + kind + name + description + fields(includeDeprecated: true) { + name + description + args { + ...InputValue + } + type { + ...TypeRef + } + isDeprecated + deprecationReason + } + inputFields { + ...InputValue + } + interfaces { + ...TypeRef + } + enumValues(includeDeprecated: true) { + name + description + isDeprecated + deprecationReason + } + possibleTypes { + ...TypeRef + } +} + +fragment InputValue on __InputValue { + name + description + type { + ...TypeRef + } + defaultValue +} + +fragment TypeRef on __Type { + kind + name + ofType { + kind + name + ofType { + kind + name + ofType { + kind + name + ofType { + kind + name + ofType { + kind + name + ofType { + kind + name + ofType { + kind + name + } + } + } + } + } + } + } +} +` diff --git a/vendor/github.com/99designs/gqlgen/graphql/introspection/schema.go b/vendor/github.com/99designs/gqlgen/graphql/introspection/schema.go new file mode 100644 index 0000000..bf2b99a --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/introspection/schema.go @@ -0,0 +1,86 @@ +package introspection + +import ( + "sort" + "strings" + + "github.com/vektah/gqlparser/v2/ast" +) + +type Schema struct { + schema *ast.Schema +} + +func (s *Schema) Types() []Type { + typeIndex := map[string]Type{} + typeNames := make([]string, 0, len(s.schema.Types)) + for _, typ := range s.schema.Types { + if strings.HasPrefix(typ.Name, "__") { + continue + } + typeNames = append(typeNames, typ.Name) + typeIndex[typ.Name] = *WrapTypeFromDef(s.schema, typ) + } + sort.Strings(typeNames) + + types := make([]Type, len(typeNames)) + for i, t := range typeNames { + types[i] = typeIndex[t] + } + return types +} + +func (s *Schema) QueryType() *Type { + return WrapTypeFromDef(s.schema, s.schema.Query) +} + +func (s *Schema) MutationType() *Type { + return WrapTypeFromDef(s.schema, s.schema.Mutation) +} + +func (s *Schema) SubscriptionType() *Type { + return WrapTypeFromDef(s.schema, s.schema.Subscription) +} + +func (s *Schema) Directives() []Directive { + dIndex := map[string]Directive{} + dNames := make([]string, 0, len(s.schema.Directives)) + + for _, d := range s.schema.Directives { + dNames = append(dNames, d.Name) + dIndex[d.Name] = s.directiveFromDef(d) + } + sort.Strings(dNames) + + res := make([]Directive, len(dNames)) + for i, d := range dNames { + res[i] = dIndex[d] + } + + return res +} + +func (s *Schema) directiveFromDef(d *ast.DirectiveDefinition) Directive { + locs := make([]string, len(d.Locations)) + for i, loc := range d.Locations { + locs[i] = string(loc) + } + + args := make([]InputValue, len(d.Arguments)) + for i, arg := range d.Arguments { + args[i] = InputValue{ + Name: arg.Name, + Description: arg.Description, + DefaultValue: defaultValue(arg.DefaultValue), + Type: WrapTypeFromType(s.schema, arg.Type), + } + } + + return Directive{ + Name: d.Name, + Description: d.Description, + Locations: locs, + Args: args, + IsRepeatable: d.IsRepeatable, + } +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/introspection/type.go b/vendor/github.com/99designs/gqlgen/graphql/introspection/type.go new file mode 100644 index 0000000..f842fa6 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/introspection/type.go @@ -0,0 +1,180 @@ +package introspection + +import ( + "strings" + + "github.com/vektah/gqlparser/v2/ast" +) + +type Type struct { + schema *ast.Schema + def *ast.Definition + typ *ast.Type +} + +func WrapTypeFromDef(s *ast.Schema, def *ast.Definition) *Type { + if def == nil { + return nil + } + return &Type{schema: s, def: def} +} + +func WrapTypeFromType(s *ast.Schema, typ *ast.Type) *Type { + if typ == nil { + return nil + } + + if !typ.NonNull && typ.NamedType != "" { + return &Type{schema: s, def: s.Types[typ.NamedType]} + } + return &Type{schema: s, typ: typ} +} + +func (t *Type) Kind() string { + if t.typ != nil { + if t.typ.NonNull { + return "NON_NULL" + } + + if t.typ.Elem != nil { + return "LIST" + } + } else { + return string(t.def.Kind) + } + + panic("UNKNOWN") +} + +func (t *Type) Name() *string { + if t.def == nil { + return nil + } + return &t.def.Name +} + +func (t *Type) Description() string { + if t.def == nil { + return "" + } + return t.def.Description +} + +func (t *Type) Fields(includeDeprecated bool) []Field { + if t.def == nil || (t.def.Kind != ast.Object && t.def.Kind != ast.Interface) { + return []Field{} + } + fields := []Field{} + for _, f := range t.def.Fields { + if strings.HasPrefix(f.Name, "__") { + continue + } + + if !includeDeprecated && f.Directives.ForName("deprecated") != nil { + continue + } + + var args []InputValue + for _, arg := range f.Arguments { + args = append(args, InputValue{ + Type: WrapTypeFromType(t.schema, arg.Type), + Name: arg.Name, + Description: arg.Description, + DefaultValue: defaultValue(arg.DefaultValue), + }) + } + + fields = append(fields, Field{ + Name: f.Name, + Description: f.Description, + Args: args, + Type: WrapTypeFromType(t.schema, f.Type), + deprecation: f.Directives.ForName("deprecated"), + }) + } + return fields +} + +func (t *Type) InputFields() []InputValue { + if t.def == nil || t.def.Kind != ast.InputObject { + return []InputValue{} + } + + res := []InputValue{} + for _, f := range t.def.Fields { + res = append(res, InputValue{ + Name: f.Name, + Description: f.Description, + Type: WrapTypeFromType(t.schema, f.Type), + DefaultValue: defaultValue(f.DefaultValue), + }) + } + return res +} + +func defaultValue(value *ast.Value) *string { + if value == nil { + return nil + } + val := value.String() + return &val +} + +func (t *Type) Interfaces() []Type { + if t.def == nil || t.def.Kind != ast.Object { + return []Type{} + } + + res := []Type{} + for _, intf := range t.def.Interfaces { + res = append(res, *WrapTypeFromDef(t.schema, t.schema.Types[intf])) + } + + return res +} + +func (t *Type) PossibleTypes() []Type { + if t.def == nil || (t.def.Kind != ast.Interface && t.def.Kind != ast.Union) { + return []Type{} + } + + res := []Type{} + for _, pt := range t.schema.GetPossibleTypes(t.def) { + res = append(res, *WrapTypeFromDef(t.schema, pt)) + } + return res +} + +func (t *Type) EnumValues(includeDeprecated bool) []EnumValue { + if t.def == nil || t.def.Kind != ast.Enum { + return []EnumValue{} + } + + res := []EnumValue{} + for _, val := range t.def.EnumValues { + if !includeDeprecated && val.Directives.ForName("deprecated") != nil { + continue + } + + res = append(res, EnumValue{ + Name: val.Name, + Description: val.Description, + deprecation: val.Directives.ForName("deprecated"), + }) + } + return res +} + +func (t *Type) OfType() *Type { + if t.typ == nil { + return nil + } + if t.typ.NonNull { + // fake non null nodes + cpy := *t.typ + cpy.NonNull = false + + return WrapTypeFromType(t.schema, &cpy) + } + return WrapTypeFromType(t.schema, t.typ.Elem) +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/jsonw.go b/vendor/github.com/99designs/gqlgen/graphql/jsonw.go new file mode 100644 index 0000000..54e293f --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/jsonw.go @@ -0,0 +1,93 @@ +package graphql + +import ( + "context" + "io" +) + +var ( + nullLit = []byte(`null`) + trueLit = []byte(`true`) + falseLit = []byte(`false`) + openBrace = []byte(`{`) + closeBrace = []byte(`}`) + openBracket = []byte(`[`) + closeBracket = []byte(`]`) + colon = []byte(`:`) + comma = []byte(`,`) +) + +var ( + Null = &lit{nullLit} + True = &lit{trueLit} + False = &lit{falseLit} +) + +type Marshaler interface { + MarshalGQL(w io.Writer) +} + +type Unmarshaler interface { + UnmarshalGQL(v interface{}) error +} + +type ContextMarshaler interface { + MarshalGQLContext(ctx context.Context, w io.Writer) error +} + +type ContextUnmarshaler interface { + UnmarshalGQLContext(ctx context.Context, v interface{}) error +} + +type contextMarshalerAdapter struct { + Context context.Context + ContextMarshaler +} + +func WrapContextMarshaler(ctx context.Context, m ContextMarshaler) Marshaler { + return contextMarshalerAdapter{Context: ctx, ContextMarshaler: m} +} + +func (a contextMarshalerAdapter) MarshalGQL(w io.Writer) { + err := a.MarshalGQLContext(a.Context, w) + if err != nil { + AddError(a.Context, err) + Null.MarshalGQL(w) + } +} + +type WriterFunc func(writer io.Writer) + +func (f WriterFunc) MarshalGQL(w io.Writer) { + f(w) +} + +type ContextWriterFunc func(ctx context.Context, writer io.Writer) error + +func (f ContextWriterFunc) MarshalGQLContext(ctx context.Context, w io.Writer) error { + return f(ctx, w) +} + +type Array []Marshaler + +func (a Array) MarshalGQL(writer io.Writer) { + writer.Write(openBracket) + for i, val := range a { + if i != 0 { + writer.Write(comma) + } + val.MarshalGQL(writer) + } + writer.Write(closeBracket) +} + +type lit struct{ b []byte } + +func (l lit) MarshalGQL(w io.Writer) { + w.Write(l.b) +} + +func (l lit) MarshalGQLContext(ctx context.Context, w io.Writer) error { + w.Write(l.b) + return nil +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/map.go b/vendor/github.com/99designs/gqlgen/graphql/map.go new file mode 100644 index 0000000..1e91d1d --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/map.go @@ -0,0 +1,24 @@ +package graphql + +import ( + "encoding/json" + "fmt" + "io" +) + +func MarshalMap(val map[string]interface{}) Marshaler { + return WriterFunc(func(w io.Writer) { + err := json.NewEncoder(w).Encode(val) + if err != nil { + panic(err) + } + }) +} + +func UnmarshalMap(v interface{}) (map[string]interface{}, error) { + if m, ok := v.(map[string]interface{}); ok { + return m, nil + } + + return nil, fmt.Errorf("%T is not a map", v) +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/oneshot.go b/vendor/github.com/99designs/gqlgen/graphql/oneshot.go new file mode 100644 index 0000000..01fa15f --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/oneshot.go @@ -0,0 +1,16 @@ +package graphql + +import "context" + +func OneShot(resp *Response) ResponseHandler { + var oneshot bool + + return func(context context.Context) *Response { + if oneshot { + return nil + } + oneshot = true + + return resp + } +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/playground/playground.go b/vendor/github.com/99designs/gqlgen/graphql/playground/playground.go new file mode 100644 index 0000000..eec10d5 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/playground/playground.go @@ -0,0 +1,70 @@ +package playground + +import ( + "html/template" + "net/http" +) + +var page = template.Must(template.New("graphiql").Parse(` + + + {{.title}} + + + +
+ + + + + + + + +`)) + +func Handler(title string, endpoint string) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + w.Header().Add("Content-Type", "text/html") + err := page.Execute(w, map[string]string{ + "title": title, + "endpoint": endpoint, + "version": "1.5.16", + "cssSRI": "sha256-HADQowUuFum02+Ckkv5Yu5ygRoLllHZqg0TFZXY7NHI=", + "jsSRI": "sha256-uHp12yvpXC4PC9+6JmITxKuLYwjlW9crq9ywPE5Rxco=", + "reactSRI": "sha256-Ipu/TQ50iCCVZBUsZyNJfxrDk0E2yhaEIz0vqI+kFG8=", + "reactDOMSRI": "sha256-nbMykgB6tsOFJ7OdVmPpdqMFVk4ZsqWocT6issAPUF0=", + }) + if err != nil { + panic(err) + } + } +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/recovery.go b/vendor/github.com/99designs/gqlgen/graphql/recovery.go new file mode 100644 index 0000000..9bc0e47 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/recovery.go @@ -0,0 +1,20 @@ +package graphql + +import ( + "context" + "fmt" + "os" + "runtime/debug" + + "github.com/vektah/gqlparser/v2/gqlerror" +) + +type RecoverFunc func(ctx context.Context, err interface{}) (userMessage error) + +func DefaultRecover(ctx context.Context, err interface{}) error { + fmt.Fprintln(os.Stderr, err) + fmt.Fprintln(os.Stderr) + debug.PrintStack() + + return gqlerror.Errorf("internal system error") +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/response.go b/vendor/github.com/99designs/gqlgen/graphql/response.go new file mode 100644 index 0000000..0d36049 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/response.go @@ -0,0 +1,24 @@ +package graphql + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/vektah/gqlparser/v2/gqlerror" +) + +// Errors are intentionally serialized first based on the advice in +// https://github.com/facebook/graphql/commit/7b40390d48680b15cb93e02d46ac5eb249689876#diff-757cea6edf0288677a9eea4cfc801d87R107 +// and https://github.com/facebook/graphql/pull/384 +type Response struct { + Errors gqlerror.List `json:"errors,omitempty"` + Data json.RawMessage `json:"data"` + Extensions map[string]interface{} `json:"extensions,omitempty"` +} + +func ErrorResponse(ctx context.Context, messagef string, args ...interface{}) *Response { + return &Response{ + Errors: gqlerror.List{{Message: fmt.Sprintf(messagef, args...)}}, + } +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/root.go b/vendor/github.com/99designs/gqlgen/graphql/root.go new file mode 100644 index 0000000..3405d18 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/root.go @@ -0,0 +1,7 @@ +package graphql + +type Query struct{} + +type Mutation struct{} + +type Subscription struct{} diff --git a/vendor/github.com/99designs/gqlgen/graphql/stats.go b/vendor/github.com/99designs/gqlgen/graphql/stats.go new file mode 100644 index 0000000..a52e143 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/stats.go @@ -0,0 +1,60 @@ +package graphql + +import ( + "context" + "fmt" + "time" +) + +type Stats struct { + OperationStart time.Time + Read TraceTiming + Parsing TraceTiming + Validation TraceTiming + + // Stats collected by handler extensions. Dont use directly, the extension should provide a type safe way to + // access this. + extension map[string]interface{} +} + +type TraceTiming struct { + Start time.Time + End time.Time +} + +var ctxTraceStart key = "trace_start" + +// StartOperationTrace captures the current time and stores it in context. This will eventually be added to request +// context but we want to grab it as soon as possible. For transports that can only handle a single graphql query +// per http requests you dont need to call this at all, the server will do it for you. For transports that handle +// multiple (eg batching, subscriptions) this should be called before decoding each request. +func StartOperationTrace(ctx context.Context) context.Context { + return context.WithValue(ctx, ctxTraceStart, Now()) +} + +// GetStartTime should only be called by the handler package, it will be set into request context +// as Stats.Start +func GetStartTime(ctx context.Context) time.Time { + t, ok := ctx.Value(ctxTraceStart).(time.Time) + if !ok { + panic(fmt.Sprintf("missing start time: %T", ctx.Value(ctxTraceStart))) + } + return t +} + +func (c *Stats) SetExtension(name string, data interface{}) { + if c.extension == nil { + c.extension = map[string]interface{}{} + } + c.extension[name] = data +} + +func (c *Stats) GetExtension(name string) interface{} { + if c.extension == nil { + return nil + } + return c.extension[name] +} + +// Now is time.Now, except in tests. Then it can be whatever you want it to be. +var Now = time.Now diff --git a/vendor/github.com/99designs/gqlgen/graphql/string.go b/vendor/github.com/99designs/gqlgen/graphql/string.go new file mode 100644 index 0000000..742e50c --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/string.go @@ -0,0 +1,70 @@ +package graphql + +import ( + "fmt" + "io" + "strconv" +) + +const encodeHex = "0123456789ABCDEF" + +func MarshalString(s string) Marshaler { + return WriterFunc(func(w io.Writer) { + writeQuotedString(w, s) + }) +} + +func writeQuotedString(w io.Writer, s string) { + start := 0 + io.WriteString(w, `"`) + + for i, c := range s { + if c < 0x20 || c == '\\' || c == '"' { + io.WriteString(w, s[start:i]) + + switch c { + case '\t': + io.WriteString(w, `\t`) + case '\r': + io.WriteString(w, `\r`) + case '\n': + io.WriteString(w, `\n`) + case '\\': + io.WriteString(w, `\\`) + case '"': + io.WriteString(w, `\"`) + default: + io.WriteString(w, `\u00`) + w.Write([]byte{encodeHex[c>>4], encodeHex[c&0xf]}) + } + + start = i + 1 + } + } + + io.WriteString(w, s[start:]) + io.WriteString(w, `"`) +} + +func UnmarshalString(v interface{}) (string, error) { + switch v := v.(type) { + case string: + return v, nil + case int: + return strconv.Itoa(v), nil + case int64: + return strconv.FormatInt(v, 10), nil + case float64: + return fmt.Sprintf("%f", v), nil + case bool: + if v { + return "true", nil + } else { + return "false", nil + } + case nil: + return "null", nil + default: + return "", fmt.Errorf("%T is not a string", v) + } +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/time.go b/vendor/github.com/99designs/gqlgen/graphql/time.go new file mode 100644 index 0000000..ef3d17d --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/time.go @@ -0,0 +1,25 @@ +package graphql + +import ( + "errors" + "io" + "strconv" + "time" +) + +func MarshalTime(t time.Time) Marshaler { + if t.IsZero() { + return Null + } + + return WriterFunc(func(w io.Writer) { + io.WriteString(w, strconv.Quote(t.Format(time.RFC3339Nano))) + }) +} + +func UnmarshalTime(v interface{}) (time.Time, error) { + if tmpStr, ok := v.(string); ok { + return time.Parse(time.RFC3339Nano, tmpStr) + } + return time.Time{}, errors.New("time should be RFC3339Nano formatted string") +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/uint.go b/vendor/github.com/99designs/gqlgen/graphql/uint.go new file mode 100644 index 0000000..9349c2f --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/uint.go @@ -0,0 +1,81 @@ +package graphql + +import ( + "encoding/json" + "fmt" + "io" + "strconv" +) + +func MarshalUint(i uint) Marshaler { + return WriterFunc(func(w io.Writer) { + _, _ = io.WriteString(w, strconv.FormatUint(uint64(i), 10)) + }) +} + +func UnmarshalUint(v interface{}) (uint, error) { + switch v := v.(type) { + case string: + u64, err := strconv.ParseUint(v, 10, 64) + return uint(u64), err + case int: + return uint(v), nil + case int64: + return uint(v), nil + case json.Number: + u64, err := strconv.ParseUint(string(v), 10, 64) + return uint(u64), err + default: + return 0, fmt.Errorf("%T is not an uint", v) + } +} + +func MarshalUint64(i uint64) Marshaler { + return WriterFunc(func(w io.Writer) { + _, _ = io.WriteString(w, strconv.FormatUint(i, 10)) + }) +} + +func UnmarshalUint64(v interface{}) (uint64, error) { + switch v := v.(type) { + case string: + return strconv.ParseUint(v, 10, 64) + case int: + return uint64(v), nil + case int64: + return uint64(v), nil + case json.Number: + return strconv.ParseUint(string(v), 10, 64) + default: + return 0, fmt.Errorf("%T is not an uint", v) + } +} + +func MarshalUint32(i uint32) Marshaler { + return WriterFunc(func(w io.Writer) { + _, _ = io.WriteString(w, strconv.FormatUint(uint64(i), 10)) + }) +} + +func UnmarshalUint32(v interface{}) (uint32, error) { + switch v := v.(type) { + case string: + iv, err := strconv.ParseInt(v, 10, 32) + if err != nil { + return 0, err + } + return uint32(iv), nil + case int: + return uint32(v), nil + case int64: + return uint32(v), nil + case json.Number: + iv, err := strconv.ParseUint(string(v), 10, 32) + if err != nil { + return 0, err + } + return uint32(iv), nil + default: + return 0, fmt.Errorf("%T is not an uint", v) + } +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/upload.go b/vendor/github.com/99designs/gqlgen/graphql/upload.go new file mode 100644 index 0000000..62f71c0 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/upload.go @@ -0,0 +1,27 @@ +package graphql + +import ( + "fmt" + "io" +) + +type Upload struct { + File io.Reader + Filename string + Size int64 + ContentType string +} + +func MarshalUpload(f Upload) Marshaler { + return WriterFunc(func(w io.Writer) { + io.Copy(w, f.File) + }) +} + +func UnmarshalUpload(v interface{}) (Upload, error) { + upload, ok := v.(Upload) + if !ok { + return Upload{}, fmt.Errorf("%T is not an Upload", v) + } + return upload, nil +} diff --git a/vendor/github.com/99designs/gqlgen/graphql/version.go b/vendor/github.com/99designs/gqlgen/graphql/version.go new file mode 100644 index 0000000..b44ff9e --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/graphql/version.go @@ -0,0 +1,3 @@ +package graphql + +const Version = "v0.14.0-dev" diff --git a/vendor/github.com/99designs/gqlgen/handler/handler.go b/vendor/github.com/99designs/gqlgen/handler/handler.go new file mode 100644 index 0000000..386b194 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/handler/handler.go @@ -0,0 +1,256 @@ +package handler + +import ( + "context" + "net/http" + "time" + + "github.com/99designs/gqlgen/graphql" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/99designs/gqlgen/graphql/handler/extension" + "github.com/99designs/gqlgen/graphql/handler/lru" + "github.com/99designs/gqlgen/graphql/handler/transport" + "github.com/99designs/gqlgen/graphql/playground" + "github.com/gorilla/websocket" +) + +// Deprecated: switch to graphql/handler.New +func GraphQL(exec graphql.ExecutableSchema, options ...Option) http.HandlerFunc { + var cfg Config + cfg.cacheSize = 1000 + + for _, option := range options { + option(&cfg) + } + + srv := handler.New(exec) + + srv.AddTransport(transport.Websocket{ + Upgrader: cfg.upgrader, + InitFunc: cfg.websocketInitFunc, + KeepAlivePingInterval: cfg.connectionKeepAlivePingInterval, + PingPongInterval: cfg.connectionPingPongInterval, + }) + srv.AddTransport(transport.Options{}) + srv.AddTransport(transport.GET{}) + srv.AddTransport(transport.POST{}) + srv.AddTransport(transport.MultipartForm{ + MaxUploadSize: cfg.uploadMaxSize, + MaxMemory: cfg.uploadMaxMemory, + }) + + if cfg.cacheSize != 0 { + srv.SetQueryCache(lru.New(cfg.cacheSize)) + } + if cfg.recover != nil { + srv.SetRecoverFunc(cfg.recover) + } + if cfg.errorPresenter != nil { + srv.SetErrorPresenter(cfg.errorPresenter) + } + for _, hook := range cfg.fieldHooks { + srv.AroundFields(hook) + } + for _, hook := range cfg.requestHooks { + srv.AroundResponses(hook) + } + if cfg.complexityLimit != 0 { + srv.Use(extension.FixedComplexityLimit(cfg.complexityLimit)) + } else if cfg.complexityLimitFunc != nil { + srv.Use(&extension.ComplexityLimit{ + Func: func(ctx context.Context, rc *graphql.OperationContext) int { + return cfg.complexityLimitFunc(graphql.WithOperationContext(ctx, rc)) + }, + }) + } + if !cfg.disableIntrospection { + srv.Use(extension.Introspection{}) + } + if cfg.apqCache != nil { + srv.Use(extension.AutomaticPersistedQuery{Cache: apqAdapter{cfg.apqCache}}) + } + return srv.ServeHTTP +} + +// Deprecated: switch to graphql/handler.New +type Config struct { + cacheSize int + upgrader websocket.Upgrader + websocketInitFunc transport.WebsocketInitFunc + connectionKeepAlivePingInterval time.Duration + connectionPingPongInterval time.Duration + recover graphql.RecoverFunc + errorPresenter graphql.ErrorPresenterFunc + fieldHooks []graphql.FieldMiddleware + requestHooks []graphql.ResponseMiddleware + complexityLimit int + complexityLimitFunc func(ctx context.Context) int + disableIntrospection bool + uploadMaxMemory int64 + uploadMaxSize int64 + apqCache PersistedQueryCache +} + +// Deprecated: switch to graphql/handler.New +type Option func(cfg *Config) + +// Deprecated: switch to graphql/handler.New +func WebsocketUpgrader(upgrader websocket.Upgrader) Option { + return func(cfg *Config) { + cfg.upgrader = upgrader + } +} + +// Deprecated: switch to graphql/handler.New +func RecoverFunc(recover graphql.RecoverFunc) Option { + return func(cfg *Config) { + cfg.recover = recover + } +} + +// ErrorPresenter transforms errors found while resolving into errors that will be returned to the user. It provides +// a good place to add any extra fields, like error.type, that might be desired by your frontend. Check the default +// implementation in graphql.DefaultErrorPresenter for an example. +// Deprecated: switch to graphql/handler.New +func ErrorPresenter(f graphql.ErrorPresenterFunc) Option { + return func(cfg *Config) { + cfg.errorPresenter = f + } +} + +// IntrospectionEnabled = false will forbid clients from calling introspection endpoints. Can be useful in prod when you dont +// want clients introspecting the full schema. +// Deprecated: switch to graphql/handler.New +func IntrospectionEnabled(enabled bool) Option { + return func(cfg *Config) { + cfg.disableIntrospection = !enabled + } +} + +// ComplexityLimit sets a maximum query complexity that is allowed to be executed. +// If a query is submitted that exceeds the limit, a 422 status code will be returned. +// Deprecated: switch to graphql/handler.New +func ComplexityLimit(limit int) Option { + return func(cfg *Config) { + cfg.complexityLimit = limit + } +} + +// ComplexityLimitFunc allows you to define a function to dynamically set the maximum query complexity that is allowed +// to be executed. +// If a query is submitted that exceeds the limit, a 422 status code will be returned. +// Deprecated: switch to graphql/handler.New +func ComplexityLimitFunc(complexityLimitFunc func(ctx context.Context) int) Option { + return func(cfg *Config) { + cfg.complexityLimitFunc = complexityLimitFunc + } +} + +// ResolverMiddleware allows you to define a function that will be called around every resolver, +// useful for logging. +// Deprecated: switch to graphql/handler.New +func ResolverMiddleware(middleware graphql.FieldMiddleware) Option { + return func(cfg *Config) { + cfg.fieldHooks = append(cfg.fieldHooks, middleware) + } +} + +// RequestMiddleware allows you to define a function that will be called around the root request, +// after the query has been parsed. This is useful for logging +// Deprecated: switch to graphql/handler.New +func RequestMiddleware(middleware graphql.ResponseMiddleware) Option { + return func(cfg *Config) { + cfg.requestHooks = append(cfg.requestHooks, middleware) + } +} + +// WebsocketInitFunc is called when the server receives connection init message from the client. +// This can be used to check initial payload to see whether to accept the websocket connection. +// Deprecated: switch to graphql/handler.New +func WebsocketInitFunc(websocketInitFunc transport.WebsocketInitFunc) Option { + return func(cfg *Config) { + cfg.websocketInitFunc = websocketInitFunc + } +} + +// CacheSize sets the maximum size of the query cache. +// If size is less than or equal to 0, the cache is disabled. +// Deprecated: switch to graphql/handler.New +func CacheSize(size int) Option { + return func(cfg *Config) { + cfg.cacheSize = size + } +} + +// UploadMaxSize sets the maximum number of bytes used to parse a request body +// as multipart/form-data. +// Deprecated: switch to graphql/handler.New +func UploadMaxSize(size int64) Option { + return func(cfg *Config) { + cfg.uploadMaxSize = size + } +} + +// UploadMaxMemory sets the maximum number of bytes used to parse a request body +// as multipart/form-data in memory, with the remainder stored on disk in +// temporary files. +// Deprecated: switch to graphql/handler.New +func UploadMaxMemory(size int64) Option { + return func(cfg *Config) { + cfg.uploadMaxMemory = size + } +} + +// WebsocketKeepAliveDuration allows you to reconfigure the keepalive behavior. +// By default, keepalive is enabled with a DefaultConnectionKeepAlivePingInterval +// duration. Set handler.connectionKeepAlivePingInterval = 0 to disable keepalive +// altogether. +// Deprecated: switch to graphql/handler.New +func WebsocketKeepAliveDuration(duration time.Duration) Option { + return func(cfg *Config) { + cfg.connectionKeepAlivePingInterval = duration + } +} + +func WebsocketPingPongDuration(duration time.Duration) Option { + return func(cfg *Config) { + cfg.connectionPingPongInterval = duration + } +} + +// Add cache that will hold queries for automatic persisted queries (APQ) +// Deprecated: switch to graphql/handler.New +func EnablePersistedQueryCache(cache PersistedQueryCache) Option { + return func(cfg *Config) { + cfg.apqCache = cache + } +} + +func GetInitPayload(ctx context.Context) transport.InitPayload { + return transport.GetInitPayload(ctx) +} + +type apqAdapter struct { + PersistedQueryCache +} + +func (a apqAdapter) Get(ctx context.Context, key string) (value interface{}, ok bool) { + return a.PersistedQueryCache.Get(ctx, key) +} + +func (a apqAdapter) Add(ctx context.Context, key string, value interface{}) { + a.PersistedQueryCache.Add(ctx, key, value.(string)) +} + +type PersistedQueryCache interface { + Add(ctx context.Context, hash string, query string) + Get(ctx context.Context, hash string) (string, bool) +} + +// Deprecated: use playground.Handler instead +func Playground(title string, endpoint string) http.HandlerFunc { + return playground.Handler(title, endpoint) +} + +// Deprecated: use transport.InitPayload instead +type InitPayload = transport.InitPayload diff --git a/vendor/github.com/99designs/gqlgen/internal/code/compare.go b/vendor/github.com/99designs/gqlgen/internal/code/compare.go new file mode 100644 index 0000000..1150a24 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/internal/code/compare.go @@ -0,0 +1,161 @@ +package code + +import ( + "fmt" + "go/types" +) + +// CompatibleTypes isnt a strict comparison, it allows for pointer differences +func CompatibleTypes(expected types.Type, actual types.Type) error { + // Special case to deal with pointer mismatches + { + expectedPtr, expectedIsPtr := expected.(*types.Pointer) + actualPtr, actualIsPtr := actual.(*types.Pointer) + + if expectedIsPtr && actualIsPtr { + return CompatibleTypes(expectedPtr.Elem(), actualPtr.Elem()) + } + if expectedIsPtr && !actualIsPtr { + return CompatibleTypes(expectedPtr.Elem(), actual) + } + if !expectedIsPtr && actualIsPtr { + return CompatibleTypes(expected, actualPtr.Elem()) + } + } + + switch expected := expected.(type) { + case *types.Slice: + if actual, ok := actual.(*types.Slice); ok { + return CompatibleTypes(expected.Elem(), actual.Elem()) + } + + case *types.Array: + if actual, ok := actual.(*types.Array); ok { + if expected.Len() != actual.Len() { + return fmt.Errorf("array length differs") + } + + return CompatibleTypes(expected.Elem(), actual.Elem()) + } + + case *types.Basic: + if actual, ok := actual.(*types.Basic); ok { + if actual.Kind() != expected.Kind() { + return fmt.Errorf("basic kind differs, %s != %s", expected.Name(), actual.Name()) + } + + return nil + } + + case *types.Struct: + if actual, ok := actual.(*types.Struct); ok { + if expected.NumFields() != actual.NumFields() { + return fmt.Errorf("number of struct fields differ") + } + + for i := 0; i < expected.NumFields(); i++ { + if expected.Field(i).Name() != actual.Field(i).Name() { + return fmt.Errorf("struct field %d name differs, %s != %s", i, expected.Field(i).Name(), actual.Field(i).Name()) + } + if err := CompatibleTypes(expected.Field(i).Type(), actual.Field(i).Type()); err != nil { + return err + } + } + return nil + } + + case *types.Tuple: + if actual, ok := actual.(*types.Tuple); ok { + if expected.Len() != actual.Len() { + return fmt.Errorf("tuple length differs, %d != %d", expected.Len(), actual.Len()) + } + + for i := 0; i < expected.Len(); i++ { + if err := CompatibleTypes(expected.At(i).Type(), actual.At(i).Type()); err != nil { + return err + } + } + + return nil + } + + case *types.Signature: + if actual, ok := actual.(*types.Signature); ok { + if err := CompatibleTypes(expected.Params(), actual.Params()); err != nil { + return err + } + if err := CompatibleTypes(expected.Results(), actual.Results()); err != nil { + return err + } + + return nil + } + case *types.Interface: + if actual, ok := actual.(*types.Interface); ok { + if expected.NumMethods() != actual.NumMethods() { + return fmt.Errorf("interface method count differs, %d != %d", expected.NumMethods(), actual.NumMethods()) + } + + for i := 0; i < expected.NumMethods(); i++ { + if expected.Method(i).Name() != actual.Method(i).Name() { + return fmt.Errorf("interface method %d name differs, %s != %s", i, expected.Method(i).Name(), actual.Method(i).Name()) + } + if err := CompatibleTypes(expected.Method(i).Type(), actual.Method(i).Type()); err != nil { + return err + } + } + + return nil + } + + case *types.Map: + if actual, ok := actual.(*types.Map); ok { + if err := CompatibleTypes(expected.Key(), actual.Key()); err != nil { + return err + } + + if err := CompatibleTypes(expected.Elem(), actual.Elem()); err != nil { + return err + } + + return nil + } + + case *types.Chan: + if actual, ok := actual.(*types.Chan); ok { + return CompatibleTypes(expected.Elem(), actual.Elem()) + } + + case *types.Named: + if actual, ok := actual.(*types.Named); ok { + if NormalizeVendor(expected.Obj().Pkg().Path()) != NormalizeVendor(actual.Obj().Pkg().Path()) { + return fmt.Errorf( + "package name of named type differs, %s != %s", + NormalizeVendor(expected.Obj().Pkg().Path()), + NormalizeVendor(actual.Obj().Pkg().Path()), + ) + } + + if expected.Obj().Name() != actual.Obj().Name() { + return fmt.Errorf( + "named type name differs, %s != %s", + NormalizeVendor(expected.Obj().Name()), + NormalizeVendor(actual.Obj().Name()), + ) + } + + return nil + } + + // Before models are generated all missing references will be Invalid Basic references. + // lets assume these are valid too. + if actual, ok := actual.(*types.Basic); ok && actual.Kind() == types.Invalid { + return nil + } + + default: + return fmt.Errorf("missing support for %T", expected) + } + + return fmt.Errorf("type mismatch %T != %T", expected, actual) +} diff --git a/vendor/github.com/99designs/gqlgen/internal/code/imports.go b/vendor/github.com/99designs/gqlgen/internal/code/imports.go new file mode 100644 index 0000000..a46ad2c --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/internal/code/imports.go @@ -0,0 +1,151 @@ +package code + +import ( + "go/build" + "go/parser" + "go/token" + "io/ioutil" + "path/filepath" + "regexp" + "strings" +) + +var gopaths []string + +func init() { + gopaths = filepath.SplitList(build.Default.GOPATH) + for i, p := range gopaths { + gopaths[i] = filepath.ToSlash(filepath.Join(p, "src")) + } +} + +// NameForDir manually looks for package stanzas in files located in the given directory. This can be +// much faster than having to consult go list, because we already know exactly where to look. +func NameForDir(dir string) string { + dir, err := filepath.Abs(dir) + if err != nil { + return SanitizePackageName(filepath.Base(dir)) + } + files, err := ioutil.ReadDir(dir) + if err != nil { + return SanitizePackageName(filepath.Base(dir)) + } + fset := token.NewFileSet() + for _, file := range files { + if !strings.HasSuffix(strings.ToLower(file.Name()), ".go") { + continue + } + + filename := filepath.Join(dir, file.Name()) + if src, err := parser.ParseFile(fset, filename, nil, parser.PackageClauseOnly); err == nil { + return src.Name.Name + } + } + + return SanitizePackageName(filepath.Base(dir)) +} + +type goModuleSearchResult struct { + path string + goModPath string + moduleName string +} + +var goModuleRootCache = map[string]goModuleSearchResult{} + +// goModuleRoot returns the root of the current go module if there is a go.mod file in the directory tree +// If not, it returns false +func goModuleRoot(dir string) (string, bool) { + dir, err := filepath.Abs(dir) + if err != nil { + panic(err) + } + dir = filepath.ToSlash(dir) + + dirs := []string{dir} + result := goModuleSearchResult{} + + for { + modDir := dirs[len(dirs)-1] + + if val, ok := goModuleRootCache[dir]; ok { + result = val + break + } + + if content, err := ioutil.ReadFile(filepath.Join(modDir, "go.mod")); err == nil { + moduleName := string(modregex.FindSubmatch(content)[1]) + result = goModuleSearchResult{ + path: moduleName, + goModPath: modDir, + moduleName: moduleName, + } + goModuleRootCache[modDir] = result + break + } + + if modDir == "" || modDir == "." || modDir == "/" || strings.HasSuffix(modDir, "\\") { + // Reached the top of the file tree which means go.mod file is not found + // Set root folder with a sentinel cache value + goModuleRootCache[modDir] = result + break + } + + dirs = append(dirs, filepath.Dir(modDir)) + } + + // create a cache for each path in a tree traversed, except the top one as it is already cached + for _, d := range dirs[:len(dirs)-1] { + if result.moduleName == "" { + // go.mod is not found in the tree, so the same sentinel value fits all the directories in a tree + goModuleRootCache[d] = result + } else { + if relPath, err := filepath.Rel(result.goModPath, d); err != nil { + panic(err) + } else { + path := result.moduleName + relPath := filepath.ToSlash(relPath) + if !strings.HasSuffix(relPath, "/") { + path += "/" + } + path += relPath + + goModuleRootCache[d] = goModuleSearchResult{ + path: path, + goModPath: result.goModPath, + moduleName: result.moduleName, + } + } + } + } + + res := goModuleRootCache[dir] + if res.moduleName == "" { + return "", false + } + return res.path, true +} + +// ImportPathForDir takes a path and returns a golang import path for the package +func ImportPathForDir(dir string) (res string) { + dir, err := filepath.Abs(dir) + if err != nil { + panic(err) + } + dir = filepath.ToSlash(dir) + + modDir, ok := goModuleRoot(dir) + if ok { + return modDir + } + + for _, gopath := range gopaths { + if len(gopath) < len(dir) && strings.EqualFold(gopath, dir[0:len(gopath)]) { + return dir[len(gopath)+1:] + } + } + + return "" +} + +var modregex = regexp.MustCompile(`module ([^\s]*)`) diff --git a/vendor/github.com/99designs/gqlgen/internal/code/packages.go b/vendor/github.com/99designs/gqlgen/internal/code/packages.go new file mode 100644 index 0000000..b622135 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/internal/code/packages.go @@ -0,0 +1,206 @@ +package code + +import ( + "bytes" + "errors" + "fmt" + "os" + "os/exec" + "path/filepath" + + "golang.org/x/tools/go/packages" +) + +var mode = packages.NeedName | + packages.NeedFiles | + packages.NeedImports | + packages.NeedTypes | + packages.NeedSyntax | + packages.NeedTypesInfo | + packages.NeedModule + +// Packages is a wrapper around x/tools/go/packages that maintains a (hopefully prewarmed) cache of packages +// that can be invalidated as writes are made and packages are known to change. +type Packages struct { + packages map[string]*packages.Package + importToName map[string]string + loadErrors []error + + numLoadCalls int // stupid test steam. ignore. + numNameCalls int // stupid test steam. ignore. +} + +// ReloadAll will call LoadAll after clearing the package cache, so we can reload +// packages in the case that the packages have changed +func (p *Packages) ReloadAll(importPaths ...string) []*packages.Package { + p.packages = nil + return p.LoadAll(importPaths...) +} + +// LoadAll will call packages.Load and return the package data for the given packages, +// but if the package already have been loaded it will return cached values instead. +func (p *Packages) LoadAll(importPaths ...string) []*packages.Package { + if p.packages == nil { + p.packages = map[string]*packages.Package{} + } + + missing := make([]string, 0, len(importPaths)) + for _, path := range importPaths { + if _, ok := p.packages[path]; ok { + continue + } + missing = append(missing, path) + } + + if len(missing) > 0 { + p.numLoadCalls++ + pkgs, err := packages.Load(&packages.Config{Mode: mode}, missing...) + if err != nil { + p.loadErrors = append(p.loadErrors, err) + } + + for _, pkg := range pkgs { + p.addToCache(pkg) + } + } + + res := make([]*packages.Package, 0, len(importPaths)) + for _, path := range importPaths { + res = append(res, p.packages[NormalizeVendor(path)]) + } + return res +} + +func (p *Packages) addToCache(pkg *packages.Package) { + imp := NormalizeVendor(pkg.PkgPath) + p.packages[imp] = pkg + for _, imp := range pkg.Imports { + if _, found := p.packages[NormalizeVendor(imp.PkgPath)]; !found { + p.addToCache(imp) + } + } +} + +// Load works the same as LoadAll, except a single package at a time. +func (p *Packages) Load(importPath string) *packages.Package { + // Quick cache check first to avoid expensive allocations of LoadAll() + if p.packages != nil { + if pkg, ok := p.packages[importPath]; ok { + return pkg + } + } + + pkgs := p.LoadAll(importPath) + if len(pkgs) == 0 { + return nil + } + return pkgs[0] +} + +// LoadWithTypes tries a standard load, which may not have enough type info (TypesInfo== nil) available if the imported package is a +// second order dependency. Fortunately this doesnt happen very often, so we can just issue a load when we detect it. +func (p *Packages) LoadWithTypes(importPath string) *packages.Package { + pkg := p.Load(importPath) + if pkg == nil || pkg.TypesInfo == nil { + p.numLoadCalls++ + pkgs, err := packages.Load(&packages.Config{Mode: mode}, importPath) + if err != nil { + p.loadErrors = append(p.loadErrors, err) + return nil + } + p.addToCache(pkgs[0]) + pkg = pkgs[0] + } + return pkg +} + +// NameForPackage looks up the package name from the package stanza in the go files at the given import path. +func (p *Packages) NameForPackage(importPath string) string { + if importPath == "" { + panic(errors.New("import path can not be empty")) + } + if p.importToName == nil { + p.importToName = map[string]string{} + } + + importPath = NormalizeVendor(importPath) + + // if its in the name cache use it + if name := p.importToName[importPath]; name != "" { + return name + } + + // otherwise we might have already loaded the full package data for it cached + pkg := p.packages[importPath] + + if pkg == nil { + // otherwise do a name only lookup for it but dont put it in the package cache. + p.numNameCalls++ + pkgs, err := packages.Load(&packages.Config{Mode: packages.NeedName}, importPath) + if err != nil { + p.loadErrors = append(p.loadErrors, err) + } else { + pkg = pkgs[0] + } + } + + if pkg == nil || pkg.Name == "" { + return SanitizePackageName(filepath.Base(importPath)) + } + + p.importToName[importPath] = pkg.Name + + return pkg.Name +} + +// Evict removes a given package import path from the cache, along with any packages that depend on it. Further calls +// to Load will fetch it from disk. +func (p *Packages) Evict(importPath string) { + delete(p.packages, importPath) + + for _, pkg := range p.packages { + for _, imported := range pkg.Imports { + if imported.PkgPath == importPath { + p.Evict(pkg.PkgPath) + } + } + } +} + +func (p *Packages) ModTidy() error { + p.packages = nil + tidyCmd := exec.Command("go", "mod", "tidy") + tidyCmd.Stdout = os.Stdout + tidyCmd.Stderr = os.Stdout + if err := tidyCmd.Run(); err != nil { + return fmt.Errorf("go mod tidy failed: %w", err) + } + return nil +} + +// Errors returns any errors that were returned by Load, either from the call itself or any of the loaded packages. +func (p *Packages) Errors() PkgErrors { + var res []error //nolint:prealloc + res = append(res, p.loadErrors...) + for _, pkg := range p.packages { + for _, err := range pkg.Errors { + res = append(res, err) + } + } + return res +} + +func (p *Packages) Count() int { + return len(p.packages) +} + +type PkgErrors []error + +func (p PkgErrors) Error() string { + var b bytes.Buffer + b.WriteString("packages.Load: ") + for _, e := range p { + b.WriteString(e.Error() + "\n") + } + return b.String() +} diff --git a/vendor/github.com/99designs/gqlgen/internal/code/util.go b/vendor/github.com/99designs/gqlgen/internal/code/util.go new file mode 100644 index 0000000..cbe4085 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/internal/code/util.go @@ -0,0 +1,61 @@ +package code + +import ( + "go/build" + "os" + "path/filepath" + "regexp" + "strings" +) + +// take a string in the form github.com/package/blah.Type and split it into package and type +func PkgAndType(name string) (string, string) { + parts := strings.Split(name, ".") + if len(parts) == 1 { + return "", name + } + + return strings.Join(parts[:len(parts)-1], "."), parts[len(parts)-1] +} + +var modsRegex = regexp.MustCompile(`^(\*|\[\])*`) + +// NormalizeVendor takes a qualified package path and turns it into normal one. +// eg . +// github.com/foo/vendor/github.com/99designs/gqlgen/graphql becomes +// github.com/99designs/gqlgen/graphql +func NormalizeVendor(pkg string) string { + modifiers := modsRegex.FindAllString(pkg, 1)[0] + pkg = strings.TrimPrefix(pkg, modifiers) + parts := strings.Split(pkg, "/vendor/") + return modifiers + parts[len(parts)-1] +} + +// QualifyPackagePath takes an import and fully qualifies it with a vendor dir, if one is required. +// eg . +// github.com/99designs/gqlgen/graphql becomes +// github.com/foo/vendor/github.com/99designs/gqlgen/graphql +// +// x/tools/packages only supports 'qualified package paths' so this will need to be done prior to calling it +// See https://github.com/golang/go/issues/30289 +func QualifyPackagePath(importPath string) string { + wd, _ := os.Getwd() + + // in go module mode, the import path doesn't need fixing + if _, ok := goModuleRoot(wd); ok { + return importPath + } + + pkg, err := build.Import(importPath, wd, 0) + if err != nil { + return importPath + } + + return pkg.ImportPath +} + +var invalidPackageNameChar = regexp.MustCompile(`[^\w]`) + +func SanitizePackageName(pkg string) string { + return invalidPackageNameChar.ReplaceAllLiteralString(filepath.Base(pkg), "_") +} diff --git a/vendor/github.com/99designs/gqlgen/internal/imports/prune.go b/vendor/github.com/99designs/gqlgen/internal/imports/prune.go new file mode 100644 index 0000000..d42a415 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/internal/imports/prune.go @@ -0,0 +1,100 @@ +// Wrapper around x/tools/imports that only removes imports, never adds new ones. + +package imports + +import ( + "bytes" + "go/ast" + "go/parser" + "go/printer" + "go/token" + "strings" + + "github.com/99designs/gqlgen/internal/code" + + "golang.org/x/tools/go/ast/astutil" + "golang.org/x/tools/imports" +) + +type visitFn func(node ast.Node) + +func (fn visitFn) Visit(node ast.Node) ast.Visitor { + fn(node) + return fn +} + +// Prune removes any unused imports +func Prune(filename string, src []byte, packages *code.Packages) ([]byte, error) { + fset := token.NewFileSet() + + file, err := parser.ParseFile(fset, filename, src, parser.ParseComments|parser.AllErrors) + if err != nil { + return nil, err + } + + unused := getUnusedImports(file, packages) + for ipath, name := range unused { + astutil.DeleteNamedImport(fset, file, name, ipath) + } + printConfig := &printer.Config{Mode: printer.TabIndent, Tabwidth: 8} + + var buf bytes.Buffer + if err := printConfig.Fprint(&buf, fset, file); err != nil { + return nil, err + } + + return imports.Process(filename, buf.Bytes(), &imports.Options{FormatOnly: true, Comments: true, TabIndent: true, TabWidth: 8}) +} + +func getUnusedImports(file ast.Node, packages *code.Packages) map[string]string { + imported := map[string]*ast.ImportSpec{} + used := map[string]bool{} + + ast.Walk(visitFn(func(node ast.Node) { + if node == nil { + return + } + switch v := node.(type) { + case *ast.ImportSpec: + if v.Name != nil { + imported[v.Name.Name] = v + break + } + ipath := strings.Trim(v.Path.Value, `"`) + if ipath == "C" { + break + } + + local := packages.NameForPackage(ipath) + + imported[local] = v + case *ast.SelectorExpr: + xident, ok := v.X.(*ast.Ident) + if !ok { + break + } + if xident.Obj != nil { + // if the parser can resolve it, it's not a package ref + break + } + used[xident.Name] = true + } + }), file) + + for pkg := range used { + delete(imported, pkg) + } + + unusedImport := map[string]string{} + for pkg, is := range imported { + if !used[pkg] && pkg != "_" && pkg != "." { + name := "" + if is.Name != nil { + name = is.Name.Name + } + unusedImport[strings.Trim(is.Path.Value, `"`)] = name + } + } + + return unusedImport +} diff --git a/vendor/github.com/99designs/gqlgen/internal/rewrite/rewriter.go b/vendor/github.com/99designs/gqlgen/internal/rewrite/rewriter.go new file mode 100644 index 0000000..f70fbdc --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/internal/rewrite/rewriter.go @@ -0,0 +1,195 @@ +package rewrite + +import ( + "bytes" + "fmt" + "go/ast" + "go/token" + "io/ioutil" + "path/filepath" + "strconv" + "strings" + + "github.com/99designs/gqlgen/internal/code" + "golang.org/x/tools/go/packages" +) + +type Rewriter struct { + pkg *packages.Package + files map[string]string + copied map[ast.Decl]bool +} + +func New(dir string) (*Rewriter, error) { + importPath := code.ImportPathForDir(dir) + if importPath == "" { + return nil, fmt.Errorf("import path not found for directory: %q", dir) + } + pkgs, err := packages.Load(&packages.Config{ + Mode: packages.NeedSyntax | packages.NeedTypes, + }, importPath) + if err != nil { + return nil, err + } + if len(pkgs) == 0 { + return nil, fmt.Errorf("package not found for importPath: %s", importPath) + } + + return &Rewriter{ + pkg: pkgs[0], + files: map[string]string{}, + copied: map[ast.Decl]bool{}, + }, nil +} + +func (r *Rewriter) getSource(start, end token.Pos) string { + startPos := r.pkg.Fset.Position(start) + endPos := r.pkg.Fset.Position(end) + + if startPos.Filename != endPos.Filename { + panic("cant get source spanning multiple files") + } + + file := r.getFile(startPos.Filename) + return file[startPos.Offset:endPos.Offset] +} + +func (r *Rewriter) getFile(filename string) string { + if _, ok := r.files[filename]; !ok { + b, err := ioutil.ReadFile(filename) + if err != nil { + panic(fmt.Errorf("unable to load file, already exists: %w", err)) + } + + r.files[filename] = string(b) + + } + + return r.files[filename] +} + +func (r *Rewriter) GetMethodBody(structname string, methodname string) string { + for _, f := range r.pkg.Syntax { + for _, d := range f.Decls { + d, isFunc := d.(*ast.FuncDecl) + if !isFunc { + continue + } + if d.Name.Name != methodname { + continue + } + if d.Recv == nil || len(d.Recv.List) == 0 { + continue + } + recv := d.Recv.List[0].Type + if star, isStar := recv.(*ast.StarExpr); isStar { + recv = star.X + } + ident, ok := recv.(*ast.Ident) + if !ok { + continue + } + + if ident.Name != structname { + continue + } + + r.copied[d] = true + + return r.getSource(d.Body.Pos()+1, d.Body.End()-1) + } + } + + return "" +} + +func (r *Rewriter) MarkStructCopied(name string) { + for _, f := range r.pkg.Syntax { + for _, d := range f.Decls { + d, isGen := d.(*ast.GenDecl) + if !isGen { + continue + } + if d.Tok != token.TYPE || len(d.Specs) == 0 { + continue + } + + spec, isTypeSpec := d.Specs[0].(*ast.TypeSpec) + if !isTypeSpec { + continue + } + + if spec.Name.Name != name { + continue + } + + r.copied[d] = true + } + } +} + +func (r *Rewriter) ExistingImports(filename string) []Import { + filename, err := filepath.Abs(filename) + if err != nil { + panic(err) + } + for _, f := range r.pkg.Syntax { + pos := r.pkg.Fset.Position(f.Pos()) + + if filename != pos.Filename { + continue + } + + var imps []Import + for _, i := range f.Imports { + name := "" + if i.Name != nil { + name = i.Name.Name + } + path, err := strconv.Unquote(i.Path.Value) + if err != nil { + panic(err) + } + imps = append(imps, Import{name, path}) + } + return imps + } + return nil +} + +func (r *Rewriter) RemainingSource(filename string) string { + filename, err := filepath.Abs(filename) + if err != nil { + panic(err) + } + for _, f := range r.pkg.Syntax { + pos := r.pkg.Fset.Position(f.Pos()) + + if filename != pos.Filename { + continue + } + + var buf bytes.Buffer + + for _, d := range f.Decls { + if r.copied[d] { + continue + } + + if d, isGen := d.(*ast.GenDecl); isGen && d.Tok == token.IMPORT { + continue + } + + buf.WriteString(r.getSource(d.Pos(), d.End())) + buf.WriteString("\n") + } + + return strings.TrimSpace(buf.String()) + } + return "" +} + +type Import struct { + Alias string + ImportPath string +} diff --git a/vendor/github.com/99designs/gqlgen/main.go b/vendor/github.com/99designs/gqlgen/main.go new file mode 100644 index 0000000..dbc2413 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/main.go @@ -0,0 +1,9 @@ +package main + +import ( + "github.com/99designs/gqlgen/cmd" +) + +func main() { + cmd.Execute() +} diff --git a/vendor/github.com/99designs/gqlgen/plugin/federation/federation.go b/vendor/github.com/99designs/gqlgen/plugin/federation/federation.go new file mode 100644 index 0000000..8e7705d --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/plugin/federation/federation.go @@ -0,0 +1,361 @@ +package federation + +import ( + "fmt" + "sort" + "strings" + + "github.com/vektah/gqlparser/v2/ast" + + "github.com/99designs/gqlgen/codegen" + "github.com/99designs/gqlgen/codegen/config" + "github.com/99designs/gqlgen/codegen/templates" + "github.com/99designs/gqlgen/plugin" + "github.com/99designs/gqlgen/plugin/federation/fieldset" +) + +type federation struct { + Entities []*Entity +} + +// New returns a federation plugin that injects +// federated directives and types into the schema +func New() plugin.Plugin { + return &federation{} +} + +// Name returns the plugin name +func (f *federation) Name() string { + return "federation" +} + +// MutateConfig mutates the configuration +func (f *federation) MutateConfig(cfg *config.Config) error { + builtins := config.TypeMap{ + "_Service": { + Model: config.StringList{ + "github.com/99designs/gqlgen/plugin/federation/fedruntime.Service", + }, + }, + "_Entity": { + Model: config.StringList{ + "github.com/99designs/gqlgen/plugin/federation/fedruntime.Entity", + }, + }, + "Entity": { + Model: config.StringList{ + "github.com/99designs/gqlgen/plugin/federation/fedruntime.Entity", + }, + }, + "_Any": { + Model: config.StringList{"github.com/99designs/gqlgen/graphql.Map"}, + }, + } + for typeName, entry := range builtins { + if cfg.Models.Exists(typeName) { + return fmt.Errorf("%v already exists which must be reserved when Federation is enabled", typeName) + } + cfg.Models[typeName] = entry + } + cfg.Directives["external"] = config.DirectiveConfig{SkipRuntime: true} + cfg.Directives["requires"] = config.DirectiveConfig{SkipRuntime: true} + cfg.Directives["provides"] = config.DirectiveConfig{SkipRuntime: true} + cfg.Directives["key"] = config.DirectiveConfig{SkipRuntime: true} + cfg.Directives["extends"] = config.DirectiveConfig{SkipRuntime: true} + + return nil +} + +func (f *federation) InjectSourceEarly() *ast.Source { + return &ast.Source{ + Name: "federation/directives.graphql", + Input: ` +scalar _Any +scalar _FieldSet + +directive @external on FIELD_DEFINITION +directive @requires(fields: _FieldSet!) on FIELD_DEFINITION +directive @provides(fields: _FieldSet!) on FIELD_DEFINITION +directive @key(fields: _FieldSet!) repeatable on OBJECT | INTERFACE +directive @extends on OBJECT | INTERFACE +`, + BuiltIn: true, + } +} + +// InjectSources creates a GraphQL Entity type with all +// the fields that had the @key directive +func (f *federation) InjectSourceLate(schema *ast.Schema) *ast.Source { + f.setEntities(schema) + + entities := "" + resolvers := "" + entityResolverInputDefinitions := "" + for i, e := range f.Entities { + if i != 0 { + entities += " | " + } + entities += e.Name + + for _, r := range e.Resolvers { + if e.Multi { + entityResolverInputDefinitions += "input " + r.InputType + " {\n" + for _, keyField := range r.KeyFields { + entityResolverInputDefinitions += fmt.Sprintf("\t%s: %s\n", keyField.Field.ToGo(), keyField.Definition.Type.String()) + } + entityResolverInputDefinitions += "}\n" + resolvers += fmt.Sprintf("\t%s(reps: [%s!]!): [%s]\n", r.ResolverName, r.InputType, e.Name) + } else { + resolverArgs := "" + for _, keyField := range r.KeyFields { + resolverArgs += fmt.Sprintf("%s: %s,", keyField.Field.ToGoPrivate(), keyField.Definition.Type.String()) + } + resolvers += fmt.Sprintf("\t%s(%s): %s!\n", r.ResolverName, resolverArgs, e.Name) + } + } + } + + if len(f.Entities) == 0 { + // It's unusual for a service not to have any entities, but + // possible if it only exports top-level queries and mutations. + return nil + } + + // resolvers can be empty if a service defines only "empty + // extend" types. This should be rare. + if resolvers != "" { + resolvers = entityResolverInputDefinitions + ` +# fake type to build resolver interfaces for users to implement +type Entity { + ` + resolvers + ` +} +` + } + + return &ast.Source{ + Name: "federation/entity.graphql", + BuiltIn: true, + Input: ` +# a union of all types that use the @key directive +union _Entity = ` + entities + ` +` + resolvers + ` +type _Service { + sdl: String +} + +extend type Query { + _entities(representations: [_Any!]!): [_Entity]! + _service: _Service! +} +`, + } +} + +// Entity represents a federated type +// that was declared in the GQL schema. +type Entity struct { + Name string // The same name as the type declaration + Def *ast.Definition + Resolvers []*EntityResolver + Requires []*Requires + Multi bool +} + +type EntityResolver struct { + ResolverName string // The resolver name, such as FindUserByID + KeyFields []*KeyField // The fields declared in @key. + InputType string // The Go generated input type for multi entity resolvers +} + +type KeyField struct { + Definition *ast.FieldDefinition + Field fieldset.Field // len > 1 for nested fields + Type *config.TypeReference // The Go representation of that field type +} + +// Requires represents an @requires clause +type Requires struct { + Name string // the name of the field + Field fieldset.Field // source Field, len > 1 for nested fields + Type *config.TypeReference // The Go representation of that field type +} + +func (e *Entity) allFieldsAreExternal() bool { + for _, field := range e.Def.Fields { + if field.Directives.ForName("external") == nil { + return false + } + } + return true +} + +func (f *federation) GenerateCode(data *codegen.Data) error { + if len(f.Entities) > 0 { + if data.Objects.ByName("Entity") != nil { + data.Objects.ByName("Entity").Root = true + } + for _, e := range f.Entities { + obj := data.Objects.ByName(e.Def.Name) + + for _, r := range e.Resolvers { + // fill in types for key fields + // + for _, keyField := range r.KeyFields { + if len(keyField.Field) == 0 { + fmt.Println( + "skipping @key field " + keyField.Definition.Name + " in " + r.ResolverName + " in " + e.Def.Name, + ) + continue + } + cgField := keyField.Field.TypeReference(obj, data.Objects) + keyField.Type = cgField.TypeReference + } + } + + // fill in types for requires fields + // + for _, reqField := range e.Requires { + if len(reqField.Field) == 0 { + fmt.Println("skipping @requires field " + reqField.Name + " in " + e.Def.Name) + continue + } + cgField := reqField.Field.TypeReference(obj, data.Objects) + reqField.Type = cgField.TypeReference + } + } + } + + return templates.Render(templates.Options{ + PackageName: data.Config.Federation.Package, + Filename: data.Config.Federation.Filename, + Data: f, + GeneratedHeader: true, + Packages: data.Config.Packages, + }) +} + +func (f *federation) setEntities(schema *ast.Schema) { + for _, schemaType := range schema.Types { + keys, ok := isFederatedEntity(schemaType) + if !ok { + continue + } + e := &Entity{ + Name: schemaType.Name, + Def: schemaType, + Resolvers: nil, + Requires: nil, + } + + // Let's process custom entity resolver settings. + dir := schemaType.Directives.ForName("entityResolver") + if dir != nil { + if dirArg := dir.Arguments.ForName("multi"); dirArg != nil { + if dirVal, err := dirArg.Value.Value(nil); err == nil { + e.Multi = dirVal.(bool) + } + } + } + + // If our schema has a field with a type defined in + // another service, then we need to define an "empty + // extend" of that type in this service, so this service + // knows what the type is like. But the graphql-server + // will never ask us to actually resolve this "empty + // extend", so we don't require a resolver function for + // it. (Well, it will never ask in practice; it's + // unclear whether the spec guarantees this. See + // https://github.com/apollographql/apollo-server/issues/3852 + // ). Example: + // type MyType { + // myvar: TypeDefinedInOtherService + // } + // // Federation needs this type, but + // // it doesn't need a resolver for it! + // extend TypeDefinedInOtherService @key(fields: "id") { + // id: ID @external + // } + if !e.allFieldsAreExternal() { + for _, dir := range keys { + if len(dir.Arguments) != 1 || dir.Arguments[0].Name != "fields" { + panic("Exactly one `fields` argument needed for @key declaration.") + } + arg := dir.Arguments[0] + keyFieldSet := fieldset.New(arg.Value.Raw, nil) + + keyFields := make([]*KeyField, len(keyFieldSet)) + resolverFields := []string{} + for i, field := range keyFieldSet { + def := field.FieldDefinition(schemaType, schema) + + if def == nil { + panic(fmt.Sprintf("no field for %v", field)) + } + + keyFields[i] = &KeyField{Definition: def, Field: field} + resolverFields = append(resolverFields, keyFields[i].Field.ToGo()) + } + + resolverFieldsToGo := schemaType.Name + "By" + strings.Join(resolverFields, "And") + var resolverName string + if e.Multi { + resolverFieldsToGo += "s" // Pluralize for better API readability + resolverName = fmt.Sprintf("findMany%s", resolverFieldsToGo) + } else { + resolverName = fmt.Sprintf("find%s", resolverFieldsToGo) + } + + e.Resolvers = append(e.Resolvers, &EntityResolver{ + ResolverName: resolverName, + KeyFields: keyFields, + InputType: resolverFieldsToGo + "Input", + }) + } + + e.Requires = []*Requires{} + for _, f := range schemaType.Fields { + dir := f.Directives.ForName("requires") + if dir == nil { + continue + } + if len(dir.Arguments) != 1 || dir.Arguments[0].Name != "fields" { + panic("Exactly one `fields` argument needed for @requires declaration.") + } + requiresFieldSet := fieldset.New(dir.Arguments[0].Value.Raw, nil) + for _, field := range requiresFieldSet { + e.Requires = append(e.Requires, &Requires{ + Name: field.ToGoPrivate(), + Field: field, + }) + } + } + } + f.Entities = append(f.Entities, e) + } + + // make sure order remains stable across multiple builds + sort.Slice(f.Entities, func(i, j int) bool { + return f.Entities[i].Name < f.Entities[j].Name + }) +} + +func isFederatedEntity(schemaType *ast.Definition) ([]*ast.Directive, bool) { + switch schemaType.Kind { + case ast.Object: + keys := schemaType.Directives.ForNames("key") + if len(keys) > 0 { + return keys, true + } + case ast.Interface: + // TODO: support @key and @extends for interfaces + if dir := schemaType.Directives.ForName("key"); dir != nil { + panic("@key directive is not currently supported for interfaces.") + } + if dir := schemaType.Directives.ForName("extends"); dir != nil { + panic("@extends directive is not currently supported for interfaces.") + } + default: + // ignore + } + return nil, false +} diff --git a/vendor/github.com/99designs/gqlgen/plugin/federation/federation.gotpl b/vendor/github.com/99designs/gqlgen/plugin/federation/federation.gotpl new file mode 100644 index 0000000..b35fb3b --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/plugin/federation/federation.gotpl @@ -0,0 +1,261 @@ +{{ reserveImport "context" }} +{{ reserveImport "errors" }} +{{ reserveImport "fmt" }} +{{ reserveImport "strings" }} +{{ reserveImport "sync" }} + +{{ reserveImport "github.com/99designs/gqlgen/plugin/federation/fedruntime" }} + +var ( + ErrUnknownType = errors.New("unknown type") + ErrTypeNotFound = errors.New("type not found") +) + +func (ec *executionContext) __resolve__service(ctx context.Context) (fedruntime.Service, error) { + if ec.DisableIntrospection { + return fedruntime.Service{}, errors.New("federated introspection disabled") + } + + var sdl []string + + for _, src := range sources { + if src.BuiltIn { + continue + } + sdl = append(sdl, src.Input) + } + + return fedruntime.Service{ + SDL: strings.Join(sdl, "\n"), + }, nil +} + +{{if .Entities}} +func (ec *executionContext) __resolve_entities(ctx context.Context, representations []map[string]interface{}) []fedruntime.Entity { + list := make([]fedruntime.Entity, len(representations)) + + repsMap := map[string]struct { + i []int + r []map[string]interface{} + }{} + + // We group entities by typename so that we can parallelize their resolution. + // This is particularly helpful when there are entity groups in multi mode. + buildRepresentationGroups := func(reps []map[string]interface{}) { + for i, rep := range reps { + typeName, ok := rep["__typename"].(string) + if !ok { + // If there is no __typename, we just skip the representation; + // we just won't be resolving these unknown types. + ec.Error(ctx, errors.New("__typename must be an existing string")) + continue + } + + _r := repsMap[typeName] + _r.i = append(_r.i, i) + _r.r = append(_r.r, rep) + repsMap[typeName] = _r + } + } + + isMulti := func(typeName string) bool { + switch typeName { + {{- range .Entities -}} + {{- if .Resolvers -}} + {{- if .Multi -}} + case "{{.Def.Name}}": + return true + {{ end }} + {{- end -}} + {{- end -}} + default: + return false + } + } + + resolveEntity := func(ctx context.Context, typeName string, rep map[string]interface{}, idx []int, i int) (err error) { + // we need to do our own panic handling, because we may be called in a + // goroutine, where the usual panic handling can't catch us + defer func () { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + } + }() + + switch typeName { + {{ range $_, $entity := .Entities }} + {{- if and .Resolvers (not .Multi) -}} + case "{{.Def.Name}}": + resolverName, err := entityResolverNameFor{{.Def.Name}}(ctx, rep) + if err != nil { + return fmt.Errorf(`finding resolver for Entity "{{.Def.Name}}": %w`, err) + } + switch resolverName { + {{ range $i, $resolver := .Resolvers }} + case "{{.ResolverName}}": + {{- range $j, $keyField := .KeyFields }} + id{{$j}}, err := ec.{{.Type.UnmarshalFunc}}(ctx, rep["{{.Field.Join `"].(map[string]interface{})["`}}"]) + if err != nil { + return fmt.Errorf(`unmarshalling param {{$j}} for {{$resolver.ResolverName}}(): %w`, err) + } + {{- end}} + entity, err := ec.resolvers.Entity().{{.ResolverName | go}}(ctx, {{- range $j, $_ := .KeyFields -}} id{{$j}}, {{end}}) + if err != nil { + return fmt.Errorf(`resolving Entity "{{$entity.Def.Name}}": %w`, err) + } + {{ range $entity.Requires }} + entity.{{.Field.JoinGo `.`}}, err = ec.{{.Type.UnmarshalFunc}}(ctx, rep["{{.Field.Join `"].(map[string]interface{})["`}}"]) + if err != nil { + return err + } + {{- end }} + list[idx[i]] = entity + return nil + {{- end }} + } + {{ end }} + {{- end }} + } + return fmt.Errorf("%w: %s", ErrUnknownType, typeName) + } + + resolveManyEntities := func(ctx context.Context, typeName string, reps []map[string]interface{}, idx []int) (err error) { + // we need to do our own panic handling, because we may be called in a + // goroutine, where the usual panic handling can't catch us + defer func () { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + } + }() + + switch typeName { + {{ range $_, $entity := .Entities }} + {{ if and .Resolvers .Multi -}} + case "{{.Def.Name}}": + {{range $i, $_ := .Resolvers -}} + _reps := make([]*{{.InputType}}, len(reps)) + + for i, rep := range reps { + {{ range $i, $keyField := .KeyFields -}} + id{{$i}}, err := ec.{{.Type.UnmarshalFunc}}(ctx, rep["{{.Field.Join `"].(map[string]interface{})["`}}"]) + if err != nil { + return errors.New(fmt.Sprintf("Field %s undefined in schema.", "{{.Definition.Name}}")) + } + {{end}} + + _reps[i] = &{{.InputType}} { + {{ range $i, $keyField := .KeyFields -}} + {{$keyField.Field.ToGo}}: id{{$i}}, + {{end}} + } + } + + entities, err := ec.resolvers.Entity().{{.ResolverName | go}}(ctx, _reps) + if err != nil { + return err + } + + for i, entity := range entities { + {{- range $entity.Requires -}} + {{- range .Fields -}} + entity.{{.NameGo}}, err = ec.{{.TypeReference.UnmarshalFunc}}(ctx, reps[i]["{{.Name}}"]) + if err != nil { + return err + } + {{- end -}} + {{- end -}} + list[idx[i]] = entity + } + return nil + {{ end }} + {{ end }} + {{- end }} + default: + return errors.New("unknown type: "+typeName) + } + } + + resolveEntityGroup := func(typeName string, reps []map[string]interface{}, idx []int) { + if isMulti(typeName) { + err := resolveManyEntities(ctx, typeName, reps, idx) + if err != nil { + ec.Error(ctx, err) + } + } else { + // if there are multiple entities to resolve, parallelize (similar to + // graphql.FieldSet.Dispatch) + var e sync.WaitGroup + e.Add(len(reps)) + for i, rep := range reps { + i, rep := i, rep + go func(i int, rep map[string]interface{}) { + err := resolveEntity(ctx, typeName, rep, idx, i) + if err != nil { + ec.Error(ctx, err) + } + e.Done() + }(i, rep) + } + e.Wait() + } + } + buildRepresentationGroups(representations) + + switch len(repsMap) { + case 0: + return list + case 1: + for typeName, reps := range repsMap { + resolveEntityGroup(typeName, reps.r, reps.i) + } + return list + default: + var g sync.WaitGroup + g.Add(len(repsMap)) + for typeName, reps := range repsMap { + go func(typeName string, reps []map[string]interface{}, idx []int) { + resolveEntityGroup(typeName, reps, idx) + g.Done() + }(typeName, reps.r, reps.i) + } + g.Wait() + return list + } +} + +{{- /* Make sure the required fields are in the given entity representation and return the name of the proper resolver. */ -}} + +{{ range $_, $entity := .Entities }} + {{- if .Resolvers }} + + func entityResolverNameFor{{$entity.Name}}(ctx context.Context, rep map[string]interface{}) (string, error) { + {{- range .Resolvers }} + for { + var ( + m map[string]interface{} + val interface{} + ok bool + ) + _ = val + {{- range $_, $keyField := .KeyFields }} + m = rep + {{- range $i, $field := .Field }} + if {{ if (ne $i $keyField.Field.LastIndex ) -}}val{{- else -}}_{{- end -}}, ok = m["{{.}}"]; !ok { + break + } + {{- if (ne $i $keyField.Field.LastIndex ) }} + if m, ok = val.(map[string]interface{}); !ok { + break + } + {{- end}} + {{- end}} + {{- end }} + return "{{.ResolverName}}", nil + } + {{- end }} + return "", fmt.Errorf("%w for {{$entity.Name}}", ErrTypeNotFound) + } + {{- end }} +{{- end }} + +{{end}} diff --git a/vendor/github.com/99designs/gqlgen/plugin/federation/fieldset/fieldset.go b/vendor/github.com/99designs/gqlgen/plugin/federation/fieldset/fieldset.go new file mode 100644 index 0000000..35616cb --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/plugin/federation/fieldset/fieldset.go @@ -0,0 +1,193 @@ +package fieldset + +import ( + "fmt" + "strings" + + "github.com/99designs/gqlgen/codegen" + "github.com/99designs/gqlgen/codegen/templates" + "github.com/vektah/gqlparser/v2/ast" +) + +// Set represents a FieldSet that is used in federation directives @key and @requires. +// Would be happier to reuse FieldSet parsing from gqlparser, but this suits for now. +// +type Set []Field + +// Field represents a single field in a FieldSet +// +type Field []string + +// New parses a FieldSet string into a TinyFieldSet. +// +func New(raw string, prefix []string) Set { + if !strings.Contains(raw, "{") { + return parseUnnestedKeyFieldSet(raw, prefix) + } + + var ( + ret = Set{} + subPrefix = prefix + ) + before, during, after := extractSubs(raw) + + if before != "" { + befores := New(before, prefix) + if len(befores) > 0 { + subPrefix = befores[len(befores)-1] + ret = append(ret, befores[:len(befores)-1]...) + } + } + if during != "" { + ret = append(ret, New(during, subPrefix)...) + } + if after != "" { + ret = append(ret, New(after, prefix)...) + } + return ret +} + +// FieldDefinition looks up a field in the type. +// +func (f Field) FieldDefinition(schemaType *ast.Definition, schema *ast.Schema) *ast.FieldDefinition { + objType := schemaType + def := objType.Fields.ForName(f[0]) + + for _, part := range f[1:] { + if objType.Kind != ast.Object { + panic(fmt.Sprintf(`invalid sub-field reference "%s" in %v: `, objType.Name, f)) + } + x := def.Type.Name() + objType = schema.Types[x] + if objType == nil { + panic("invalid schema type: " + x) + } + def = objType.Fields.ForName(part) + } + if def == nil { + return nil + } + ret := *def // shallow copy + ret.Name = f.ToGoPrivate() + + return &ret +} + +// TypeReference looks up the type of a field. +// +func (f Field) TypeReference(obj *codegen.Object, objects codegen.Objects) *codegen.Field { + var def *codegen.Field + + for _, part := range f { + def = fieldByName(obj, part) + if def == nil { + panic("unable to find field " + f[0]) + } + obj = objects.ByName(def.TypeReference.Definition.Name) + } + return def +} + +// ToGo converts a (possibly nested) field into a proper public Go name. +// +func (f Field) ToGo() string { + var ret string + + for _, field := range f { + ret += templates.ToGo(field) + } + return ret +} + +// ToGoPrivate converts a (possibly nested) field into a proper private Go name. +// +func (f Field) ToGoPrivate() string { + var ret string + + for i, field := range f { + if i == 0 { + ret += templates.ToGoPrivate(field) + continue + } + ret += templates.ToGo(field) + } + return ret +} + +// Join concatenates the field parts with a string separator between. Useful in templates. +// +func (f Field) Join(str string) string { + return strings.Join(f, str) +} + +// JoinGo concatenates the Go name of field parts with a string separator between. Useful in templates. +// +func (f Field) JoinGo(str string) string { + strs := []string{} + + for _, s := range f { + strs = append(strs, templates.ToGo(s)) + } + return strings.Join(strs, str) +} + +func (f Field) LastIndex() int { + return len(f) - 1 +} + +// local functions + +// parseUnnestedKeyFieldSet // handles simple case where none of the fields are nested. +// +func parseUnnestedKeyFieldSet(raw string, prefix []string) Set { + ret := Set{} + + for _, s := range strings.Fields(raw) { + next := append(prefix[:], s) //nolint:gocritic // slicing out on purpose + ret = append(ret, next) + } + return ret +} + +// extractSubs splits out and trims sub-expressions from before, inside, and after "{}". +// +func extractSubs(str string) (string, string, string) { + start := strings.Index(str, "{") + end := matchingBracketIndex(str, start) + + if start < 0 || end < 0 { + panic("invalid key fieldSet: " + str) + } + return strings.TrimSpace(str[:start]), strings.TrimSpace(str[start+1 : end]), strings.TrimSpace(str[end+1:]) +} + +// matchingBracketIndex returns the index of the closing bracket, assuming an open bracket at start. +// +func matchingBracketIndex(str string, start int) int { + if start < 0 || len(str) <= start+1 { + return -1 + } + var depth int + + for i, c := range str[start+1:] { + switch c { + case '{': + depth++ + case '}': + if depth == 0 { + return start + 1 + i + } + depth-- + } + } + return -1 +} + +func fieldByName(obj *codegen.Object, name string) *codegen.Field { + for _, field := range obj.Fields { + if field.Name == name { + return field + } + } + return nil +} diff --git a/vendor/github.com/99designs/gqlgen/plugin/federation/readme.md b/vendor/github.com/99designs/gqlgen/plugin/federation/readme.md new file mode 100644 index 0000000..4333ed4 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/plugin/federation/readme.md @@ -0,0 +1,39 @@ +# Federation plugin + +Add support for graphql federation in your graphql Go server! + +TODO(miguel): add details. + +# Tests +There are several different tests. Some will process the configuration file directly. You can see those in the `federation_test.go`. There are also tests for entity resolvers, which will simulate requests from a federation server like Apollo Federation. + +Running entity resolver tests. +1. Go to `plugin/federation` +2. Run the command `go generate` +3. Run the tests with `go test ./...`. + +# Architecture + +TODO(miguel): add details. + +# Entity resolvers - GetMany entities + +The federation plugin implements `GetMany` semantics in which entity resolvers get the entire list of representations that need to be resolved. This functionality is currently optin tho, and to enable it you need to specify the directive `@entityResolver` in the federated entity you want this feature for. E.g. + +``` +directive @entityResolver(multi: Boolean) on OBJECT + +type MultiHello @key(fields: "name") @entityResolver(multi: true) { + name: String! +} +``` + +That allows the federation plugin to generate `GetMany` resolver function that can take a list of representations to be resolved. + +From that entity type, the resolver function would be + +``` +func (r *entityResolver) FindManyMultiHellosByName(ctx context.Context, reps []*generated.ManyMultiHellosByNameInput) ([]*generated.MultiHello, error) { + /// +} +``` diff --git a/vendor/github.com/99designs/gqlgen/plugin/modelgen/models.go b/vendor/github.com/99designs/gqlgen/plugin/modelgen/models.go new file mode 100644 index 0000000..0b8d90c --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/plugin/modelgen/models.go @@ -0,0 +1,288 @@ +package modelgen + +import ( + "fmt" + "go/types" + "sort" + "strings" + + "github.com/99designs/gqlgen/codegen/config" + "github.com/99designs/gqlgen/codegen/templates" + "github.com/99designs/gqlgen/plugin" + "github.com/vektah/gqlparser/v2/ast" +) + +type BuildMutateHook = func(b *ModelBuild) *ModelBuild + +type FieldMutateHook = func(td *ast.Definition, fd *ast.FieldDefinition, f *Field) (*Field, error) + +// defaultFieldMutateHook is the default hook for the Plugin which applies the GoTagFieldHook. +func defaultFieldMutateHook(td *ast.Definition, fd *ast.FieldDefinition, f *Field) (*Field, error) { + return GoTagFieldHook(td, fd, f) +} + +func defaultBuildMutateHook(b *ModelBuild) *ModelBuild { + return b +} + +type ModelBuild struct { + PackageName string + Interfaces []*Interface + Models []*Object + Enums []*Enum + Scalars []string +} + +type Interface struct { + Description string + Name string +} + +type Object struct { + Description string + Name string + Fields []*Field + Implements []string +} + +type Field struct { + Description string + Name string + Type types.Type + Tag string +} + +type Enum struct { + Description string + Name string + Values []*EnumValue +} + +type EnumValue struct { + Description string + Name string +} + +func New() plugin.Plugin { + return &Plugin{ + MutateHook: defaultBuildMutateHook, + FieldHook: defaultFieldMutateHook, + } +} + +type Plugin struct { + MutateHook BuildMutateHook + FieldHook FieldMutateHook +} + +var _ plugin.ConfigMutator = &Plugin{} + +func (m *Plugin) Name() string { + return "modelgen" +} + +func (m *Plugin) MutateConfig(cfg *config.Config) error { + binder := cfg.NewBinder() + + b := &ModelBuild{ + PackageName: cfg.Model.Package, + } + + for _, schemaType := range cfg.Schema.Types { + if cfg.Models.UserDefined(schemaType.Name) { + continue + } + switch schemaType.Kind { + case ast.Interface, ast.Union: + it := &Interface{ + Description: schemaType.Description, + Name: schemaType.Name, + } + + b.Interfaces = append(b.Interfaces, it) + case ast.Object, ast.InputObject: + if schemaType == cfg.Schema.Query || schemaType == cfg.Schema.Mutation || schemaType == cfg.Schema.Subscription { + continue + } + it := &Object{ + Description: schemaType.Description, + Name: schemaType.Name, + } + for _, implementor := range cfg.Schema.GetImplements(schemaType) { + it.Implements = append(it.Implements, implementor.Name) + } + + for _, field := range schemaType.Fields { + var typ types.Type + fieldDef := cfg.Schema.Types[field.Type.Name()] + + if cfg.Models.UserDefined(field.Type.Name()) { + var err error + typ, err = binder.FindTypeFromName(cfg.Models[field.Type.Name()].Model[0]) + if err != nil { + return err + } + } else { + switch fieldDef.Kind { + case ast.Scalar: + // no user defined model, referencing a default scalar + typ = types.NewNamed( + types.NewTypeName(0, cfg.Model.Pkg(), "string", nil), + nil, + nil, + ) + + case ast.Interface, ast.Union: + // no user defined model, referencing a generated interface type + typ = types.NewNamed( + types.NewTypeName(0, cfg.Model.Pkg(), templates.ToGo(field.Type.Name()), nil), + types.NewInterfaceType([]*types.Func{}, []types.Type{}), + nil, + ) + + case ast.Enum: + // no user defined model, must reference a generated enum + typ = types.NewNamed( + types.NewTypeName(0, cfg.Model.Pkg(), templates.ToGo(field.Type.Name()), nil), + nil, + nil, + ) + + case ast.Object, ast.InputObject: + // no user defined model, must reference a generated struct + typ = types.NewNamed( + types.NewTypeName(0, cfg.Model.Pkg(), templates.ToGo(field.Type.Name()), nil), + types.NewStruct(nil, nil), + nil, + ) + + default: + panic(fmt.Errorf("unknown ast type %s", fieldDef.Kind)) + } + } + + name := field.Name + if nameOveride := cfg.Models[schemaType.Name].Fields[field.Name].FieldName; nameOveride != "" { + name = nameOveride + } + + typ = binder.CopyModifiersFromAst(field.Type, typ) + + if isStruct(typ) && (fieldDef.Kind == ast.Object || fieldDef.Kind == ast.InputObject) { + typ = types.NewPointer(typ) + } + + f := &Field{ + Name: name, + Type: typ, + Description: field.Description, + Tag: `json:"` + field.Name + `"`, + } + + if m.FieldHook != nil { + mf, err := m.FieldHook(schemaType, field, f) + if err != nil { + return fmt.Errorf("generror: field %v.%v: %w", it.Name, field.Name, err) + } + f = mf + } + + it.Fields = append(it.Fields, f) + } + + b.Models = append(b.Models, it) + case ast.Enum: + it := &Enum{ + Name: schemaType.Name, + Description: schemaType.Description, + } + + for _, v := range schemaType.EnumValues { + it.Values = append(it.Values, &EnumValue{ + Name: v.Name, + Description: v.Description, + }) + } + + b.Enums = append(b.Enums, it) + case ast.Scalar: + b.Scalars = append(b.Scalars, schemaType.Name) + } + } + sort.Slice(b.Enums, func(i, j int) bool { return b.Enums[i].Name < b.Enums[j].Name }) + sort.Slice(b.Models, func(i, j int) bool { return b.Models[i].Name < b.Models[j].Name }) + sort.Slice(b.Interfaces, func(i, j int) bool { return b.Interfaces[i].Name < b.Interfaces[j].Name }) + + for _, it := range b.Enums { + cfg.Models.Add(it.Name, cfg.Model.ImportPath()+"."+templates.ToGo(it.Name)) + } + for _, it := range b.Models { + cfg.Models.Add(it.Name, cfg.Model.ImportPath()+"."+templates.ToGo(it.Name)) + } + for _, it := range b.Interfaces { + cfg.Models.Add(it.Name, cfg.Model.ImportPath()+"."+templates.ToGo(it.Name)) + } + for _, it := range b.Scalars { + cfg.Models.Add(it, "github.com/99designs/gqlgen/graphql.String") + } + + if len(b.Models) == 0 && len(b.Enums) == 0 && len(b.Interfaces) == 0 && len(b.Scalars) == 0 { + return nil + } + + if m.MutateHook != nil { + b = m.MutateHook(b) + } + + err := templates.Render(templates.Options{ + PackageName: cfg.Model.Package, + Filename: cfg.Model.Filename, + Data: b, + GeneratedHeader: true, + Packages: cfg.Packages, + }) + if err != nil { + return err + } + + // We may have generated code in a package we already loaded, so we reload all packages + // to allow packages to be compared correctly + cfg.ReloadAllPackages() + + return nil +} + +// GoTagFieldHook applies the goTag directive to the generated Field f. When applying the Tag to the field, the field +// name is used when no value argument is present. +func GoTagFieldHook(td *ast.Definition, fd *ast.FieldDefinition, f *Field) (*Field, error) { + args := make([]string, 0) + for _, goTag := range fd.Directives.ForNames("goTag") { + key := "" + value := fd.Name + + if arg := goTag.Arguments.ForName("key"); arg != nil { + if k, err := arg.Value.Value(nil); err == nil { + key = k.(string) + } + } + + if arg := goTag.Arguments.ForName("value"); arg != nil { + if v, err := arg.Value.Value(nil); err == nil { + value = v.(string) + } + } + + args = append(args, key+":\""+value+"\"") + } + + if len(args) > 0 { + f.Tag = f.Tag + " " + strings.Join(args, " ") + } + + return f, nil +} + +func isStruct(t types.Type) bool { + _, is := t.Underlying().(*types.Struct) + return is +} diff --git a/vendor/github.com/99designs/gqlgen/plugin/modelgen/models.gotpl b/vendor/github.com/99designs/gqlgen/plugin/modelgen/models.gotpl new file mode 100644 index 0000000..e58d5b2 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/plugin/modelgen/models.gotpl @@ -0,0 +1,85 @@ +{{ reserveImport "context" }} +{{ reserveImport "fmt" }} +{{ reserveImport "io" }} +{{ reserveImport "strconv" }} +{{ reserveImport "time" }} +{{ reserveImport "sync" }} +{{ reserveImport "errors" }} +{{ reserveImport "bytes" }} + +{{ reserveImport "github.com/vektah/gqlparser/v2" }} +{{ reserveImport "github.com/vektah/gqlparser/v2/ast" }} +{{ reserveImport "github.com/99designs/gqlgen/graphql" }} +{{ reserveImport "github.com/99designs/gqlgen/graphql/introspection" }} + +{{- range $model := .Interfaces }} + {{ with .Description }} {{.|prefixLines "// "}} {{ end }} + type {{.Name|go }} interface { + Is{{.Name|go }}() + } +{{- end }} + +{{ range $model := .Models }} + {{with .Description }} {{.|prefixLines "// "}} {{end}} + type {{ .Name|go }} struct { + {{- range $field := .Fields }} + {{- with .Description }} + {{.|prefixLines "// "}} + {{- end}} + {{ $field.Name|go }} {{$field.Type | ref}} `{{$field.Tag}}` + {{- end }} + } + + {{- range $iface := .Implements }} + func ({{ $model.Name|go }}) Is{{ $iface|go }}() {} + {{- end }} +{{- end}} + +{{ range $enum := .Enums }} + {{ with .Description }} {{.|prefixLines "// "}} {{end}} + type {{.Name|go }} string + const ( + {{- range $value := .Values}} + {{- with .Description}} + {{.|prefixLines "// "}} + {{- end}} + {{ $enum.Name|go }}{{ .Name|go }} {{$enum.Name|go }} = {{.Name|quote}} + {{- end }} + ) + + var All{{.Name|go }} = []{{ .Name|go }}{ + {{- range $value := .Values}} + {{$enum.Name|go }}{{ .Name|go }}, + {{- end }} + } + + func (e {{.Name|go }}) IsValid() bool { + switch e { + case {{ range $index, $element := .Values}}{{if $index}},{{end}}{{ $enum.Name|go }}{{ $element.Name|go }}{{end}}: + return true + } + return false + } + + func (e {{.Name|go }}) String() string { + return string(e) + } + + func (e *{{.Name|go }}) UnmarshalGQL(v interface{}) error { + str, ok := v.(string) + if !ok { + return fmt.Errorf("enums must be strings") + } + + *e = {{ .Name|go }}(str) + if !e.IsValid() { + return fmt.Errorf("%s is not a valid {{ .Name }}", str) + } + return nil + } + + func (e {{.Name|go }}) MarshalGQL(w io.Writer) { + fmt.Fprint(w, strconv.Quote(e.String())) + } + +{{- end }} diff --git a/vendor/github.com/99designs/gqlgen/plugin/plugin.go b/vendor/github.com/99designs/gqlgen/plugin/plugin.go new file mode 100644 index 0000000..7de36bd --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/plugin/plugin.go @@ -0,0 +1,31 @@ +// plugin package interfaces are EXPERIMENTAL. + +package plugin + +import ( + "github.com/99designs/gqlgen/codegen" + "github.com/99designs/gqlgen/codegen/config" + "github.com/vektah/gqlparser/v2/ast" +) + +type Plugin interface { + Name() string +} + +type ConfigMutator interface { + MutateConfig(cfg *config.Config) error +} + +type CodeGenerator interface { + GenerateCode(cfg *codegen.Data) error +} + +// EarlySourceInjector is used to inject things that are required for user schema files to compile. +type EarlySourceInjector interface { + InjectSourceEarly() *ast.Source +} + +// LateSourceInjector is used to inject more sources, after we have loaded the users schema. +type LateSourceInjector interface { + InjectSourceLate(schema *ast.Schema) *ast.Source +} diff --git a/vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.go b/vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.go new file mode 100644 index 0000000..857f5ea --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.go @@ -0,0 +1,208 @@ +package resolvergen + +import ( + "errors" + "io/fs" + "os" + "path/filepath" + "strings" + + "github.com/99designs/gqlgen/codegen" + "github.com/99designs/gqlgen/codegen/config" + "github.com/99designs/gqlgen/codegen/templates" + "github.com/99designs/gqlgen/internal/rewrite" + "github.com/99designs/gqlgen/plugin" +) + +func New() plugin.Plugin { + return &Plugin{} +} + +type Plugin struct{} + +var _ plugin.CodeGenerator = &Plugin{} + +func (m *Plugin) Name() string { + return "resolvergen" +} + +func (m *Plugin) GenerateCode(data *codegen.Data) error { + if !data.Config.Resolver.IsDefined() { + return nil + } + + switch data.Config.Resolver.Layout { + case config.LayoutSingleFile: + return m.generateSingleFile(data) + case config.LayoutFollowSchema: + return m.generatePerSchema(data) + } + + return nil +} + +func (m *Plugin) generateSingleFile(data *codegen.Data) error { + file := File{} + + if _, err := os.Stat(data.Config.Resolver.Filename); err == nil { + // file already exists and we dont support updating resolvers with layout = single so just return + return nil + } + + for _, o := range data.Objects { + if o.HasResolvers() { + file.Objects = append(file.Objects, o) + } + for _, f := range o.Fields { + if !f.IsResolver { + continue + } + + resolver := Resolver{o, f, `panic("not implemented")`} + file.Resolvers = append(file.Resolvers, &resolver) + } + } + + resolverBuild := &ResolverBuild{ + File: &file, + PackageName: data.Config.Resolver.Package, + ResolverType: data.Config.Resolver.Type, + HasRoot: true, + } + + return templates.Render(templates.Options{ + PackageName: data.Config.Resolver.Package, + FileNotice: `// THIS CODE IS A STARTING POINT ONLY. IT WILL NOT BE UPDATED WITH SCHEMA CHANGES.`, + Filename: data.Config.Resolver.Filename, + Data: resolverBuild, + Packages: data.Config.Packages, + }) +} + +func (m *Plugin) generatePerSchema(data *codegen.Data) error { + rewriter, err := rewrite.New(data.Config.Resolver.Dir()) + if err != nil { + return err + } + + files := map[string]*File{} + + for _, o := range data.Objects { + if o.HasResolvers() { + fn := gqlToResolverName(data.Config.Resolver.Dir(), o.Position.Src.Name, data.Config.Resolver.FilenameTemplate) + if files[fn] == nil { + files[fn] = &File{} + } + + rewriter.MarkStructCopied(templates.LcFirst(o.Name) + templates.UcFirst(data.Config.Resolver.Type)) + rewriter.GetMethodBody(data.Config.Resolver.Type, strings.Title(o.Name)) + files[fn].Objects = append(files[fn].Objects, o) + } + for _, f := range o.Fields { + if !f.IsResolver { + continue + } + + structName := templates.LcFirst(o.Name) + templates.UcFirst(data.Config.Resolver.Type) + implementation := strings.TrimSpace(rewriter.GetMethodBody(structName, f.GoFieldName)) + if implementation == "" { + implementation = `panic(fmt.Errorf("not implemented"))` + } + + resolver := Resolver{o, f, implementation} + fn := gqlToResolverName(data.Config.Resolver.Dir(), f.Position.Src.Name, data.Config.Resolver.FilenameTemplate) + if files[fn] == nil { + files[fn] = &File{} + } + + files[fn].Resolvers = append(files[fn].Resolvers, &resolver) + } + } + + for filename, file := range files { + file.imports = rewriter.ExistingImports(filename) + file.RemainingSource = rewriter.RemainingSource(filename) + } + + for filename, file := range files { + resolverBuild := &ResolverBuild{ + File: file, + PackageName: data.Config.Resolver.Package, + ResolverType: data.Config.Resolver.Type, + } + + err := templates.Render(templates.Options{ + PackageName: data.Config.Resolver.Package, + FileNotice: ` + // This file will be automatically regenerated based on the schema, any resolver implementations + // will be copied through when generating and any unknown code will be moved to the end.`, + Filename: filename, + Data: resolverBuild, + Packages: data.Config.Packages, + }) + if err != nil { + return err + } + } + + if _, err := os.Stat(data.Config.Resolver.Filename); errors.Is(err, fs.ErrNotExist) { + err := templates.Render(templates.Options{ + PackageName: data.Config.Resolver.Package, + FileNotice: ` + // This file will not be regenerated automatically. + // + // It serves as dependency injection for your app, add any dependencies you require here.`, + Template: `type {{.}} struct {}`, + Filename: data.Config.Resolver.Filename, + Data: data.Config.Resolver.Type, + Packages: data.Config.Packages, + }) + if err != nil { + return err + } + } + return nil +} + +type ResolverBuild struct { + *File + HasRoot bool + PackageName string + ResolverType string +} + +type File struct { + // These are separated because the type definition of the resolver object may live in a different file from the + // resolver method implementations, for example when extending a type in a different graphql schema file + Objects []*codegen.Object + Resolvers []*Resolver + imports []rewrite.Import + RemainingSource string +} + +func (f *File) Imports() string { + for _, imp := range f.imports { + if imp.Alias == "" { + _, _ = templates.CurrentImports.Reserve(imp.ImportPath) + } else { + _, _ = templates.CurrentImports.Reserve(imp.ImportPath, imp.Alias) + } + } + return "" +} + +type Resolver struct { + Object *codegen.Object + Field *codegen.Field + Implementation string +} + +func gqlToResolverName(base string, gqlname, filenameTmpl string) string { + gqlname = filepath.Base(gqlname) + ext := filepath.Ext(gqlname) + if filenameTmpl == "" { + filenameTmpl = "{name}.resolvers.go" + } + filename := strings.ReplaceAll(filenameTmpl, "{name}", strings.TrimSuffix(gqlname, ext)) + return filepath.Join(base, filename) +} diff --git a/vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.gotpl b/vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.gotpl new file mode 100644 index 0000000..16c684d --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.gotpl @@ -0,0 +1,45 @@ +{{ reserveImport "context" }} +{{ reserveImport "fmt" }} +{{ reserveImport "io" }} +{{ reserveImport "strconv" }} +{{ reserveImport "time" }} +{{ reserveImport "sync" }} +{{ reserveImport "errors" }} +{{ reserveImport "bytes" }} + +{{ reserveImport "github.com/vektah/gqlparser/v2" }} +{{ reserveImport "github.com/vektah/gqlparser/v2/ast" }} +{{ reserveImport "github.com/99designs/gqlgen/graphql" }} +{{ reserveImport "github.com/99designs/gqlgen/graphql/introspection" }} + +{{ .Imports }} + +{{ if .HasRoot }} + type {{.ResolverType}} struct {} +{{ end }} + +{{ range $resolver := .Resolvers -}} + func (r *{{lcFirst $resolver.Object.Name}}{{ucFirst $.ResolverType}}) {{$resolver.Field.GoFieldName}}{{ $resolver.Field.ShortResolverDeclaration }} { + {{ $resolver.Implementation }} + } + +{{ end }} + +{{ range $object := .Objects -}} + // {{ucFirst $object.Name}} returns {{ $object.ResolverInterface | ref }} implementation. + func (r *{{$.ResolverType}}) {{ucFirst $object.Name}}() {{ $object.ResolverInterface | ref }} { return &{{lcFirst $object.Name}}{{ucFirst $.ResolverType}}{r} } +{{ end }} + +{{ range $object := .Objects -}} + type {{lcFirst $object.Name}}{{ucFirst $.ResolverType}} struct { *{{$.ResolverType}} } +{{ end }} + +{{ if (ne .RemainingSource "") }} + // !!! WARNING !!! + // The code below was going to be deleted when updating resolvers. It has been copied here so you have + // one last chance to move it out of harms way if you want. There are two reasons this happens: + // - When renaming or deleting a resolver the old code will be put in here. You can safely delete + // it when you're done. + // - You have helper methods in this file. Move them out to keep these resolver files clean. + {{ .RemainingSource }} +{{ end }} diff --git a/vendor/github.com/99designs/gqlgen/plugin/servergen/server.go b/vendor/github.com/99designs/gqlgen/plugin/servergen/server.go new file mode 100644 index 0000000..d9b35fe --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/plugin/servergen/server.go @@ -0,0 +1,52 @@ +package servergen + +import ( + "errors" + "io/fs" + "log" + "os" + + "github.com/99designs/gqlgen/codegen" + "github.com/99designs/gqlgen/codegen/templates" + "github.com/99designs/gqlgen/plugin" +) + +func New(filename string) plugin.Plugin { + return &Plugin{filename} +} + +type Plugin struct { + filename string +} + +var _ plugin.CodeGenerator = &Plugin{} + +func (m *Plugin) Name() string { + return "servergen" +} + +func (m *Plugin) GenerateCode(data *codegen.Data) error { + serverBuild := &ServerBuild{ + ExecPackageName: data.Config.Exec.ImportPath(), + ResolverPackageName: data.Config.Resolver.ImportPath(), + } + + if _, err := os.Stat(m.filename); errors.Is(err, fs.ErrNotExist) { + return templates.Render(templates.Options{ + PackageName: "main", + Filename: m.filename, + Data: serverBuild, + Packages: data.Config.Packages, + }) + } + + log.Printf("Skipped server: %s already exists\n", m.filename) + return nil +} + +type ServerBuild struct { + codegen.Data + + ExecPackageName string + ResolverPackageName string +} diff --git a/vendor/github.com/99designs/gqlgen/plugin/servergen/server.gotpl b/vendor/github.com/99designs/gqlgen/plugin/servergen/server.gotpl new file mode 100644 index 0000000..a3ae2a8 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/plugin/servergen/server.gotpl @@ -0,0 +1,23 @@ +{{ reserveImport "context" }} +{{ reserveImport "log" }} +{{ reserveImport "net/http" }} +{{ reserveImport "os" }} +{{ reserveImport "github.com/99designs/gqlgen/graphql/playground" }} +{{ reserveImport "github.com/99designs/gqlgen/graphql/handler" }} + +const defaultPort = "8080" + +func main() { + port := os.Getenv("PORT") + if port == "" { + port = defaultPort + } + + srv := handler.NewDefaultServer({{ lookupImport .ExecPackageName }}.NewExecutableSchema({{ lookupImport .ExecPackageName}}.Config{Resolvers: &{{ lookupImport .ResolverPackageName}}.Resolver{}})) + + http.Handle("/", playground.Handler("GraphQL playground", "/query")) + http.Handle("/query", srv) + + log.Printf("connect to http://localhost:%s/ for GraphQL playground", port) + log.Fatal(http.ListenAndServe(":" + port, nil)) +} diff --git a/vendor/github.com/99designs/gqlgen/tools.go b/vendor/github.com/99designs/gqlgen/tools.go new file mode 100644 index 0000000..ef46208 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/tools.go @@ -0,0 +1,8 @@ +//go:build tools +// +build tools + +package main + +import ( + _ "github.com/matryer/moq" +) diff --git a/vendor/github.com/agnivade/levenshtein/.gitignore b/vendor/github.com/agnivade/levenshtein/.gitignore new file mode 100644 index 0000000..345780a --- /dev/null +++ b/vendor/github.com/agnivade/levenshtein/.gitignore @@ -0,0 +1,5 @@ +coverage.txt +fuzz/fuzz-fuzz.zip +fuzz/corpus/corpus/* +fuzz/corpus/suppressions/* +fuzz/corpus/crashes/* diff --git a/vendor/github.com/agnivade/levenshtein/.travis.yml b/vendor/github.com/agnivade/levenshtein/.travis.yml new file mode 100644 index 0000000..0873fa9 --- /dev/null +++ b/vendor/github.com/agnivade/levenshtein/.travis.yml @@ -0,0 +1,23 @@ +language: go + +# See https://travis-ci.community/t/goos-js-goarch-wasm-go-run-fails-panic-newosproc-not-implemented/1651 +#addons: +# chrome: stable + +before_install: +- export GO111MODULE=on + +#install: +#- go get github.com/agnivade/wasmbrowsertest +#- mv $GOPATH/bin/wasmbrowsertest $GOPATH/bin/go_js_wasm_exec +#- export PATH=$GOPATH/bin:$PATH + +go: +- 1.13.x +- 1.14.x +- 1.15.x +- tip + +script: +#- GOOS=js GOARCH=wasm go test -v +- go test -v diff --git a/vendor/github.com/agnivade/levenshtein/License.txt b/vendor/github.com/agnivade/levenshtein/License.txt new file mode 100644 index 0000000..54b51f4 --- /dev/null +++ b/vendor/github.com/agnivade/levenshtein/License.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Agniva De Sarker + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/agnivade/levenshtein/Makefile b/vendor/github.com/agnivade/levenshtein/Makefile new file mode 100644 index 0000000..5f6890d --- /dev/null +++ b/vendor/github.com/agnivade/levenshtein/Makefile @@ -0,0 +1,15 @@ +all: test install + +install: + go install + +lint: + gofmt -l -s -w . && go vet . && golint -set_exit_status=1 . + +test: # The first 2 go gets are to support older Go versions + go get github.com/arbovm/levenshtein + go get github.com/dgryski/trifles/leven + GO111MODULE=on go test -race -v -coverprofile=coverage.txt -covermode=atomic + +bench: + go test -run=XXX -bench=. -benchmem -count=5 diff --git a/vendor/github.com/agnivade/levenshtein/README.md b/vendor/github.com/agnivade/levenshtein/README.md new file mode 100644 index 0000000..13c52a2 --- /dev/null +++ b/vendor/github.com/agnivade/levenshtein/README.md @@ -0,0 +1,80 @@ +levenshtein [![Build Status](https://travis-ci.org/agnivade/levenshtein.svg?branch=master)](https://travis-ci.org/agnivade/levenshtein) [![Go Report Card](https://goreportcard.com/badge/github.com/agnivade/levenshtein)](https://goreportcard.com/report/github.com/agnivade/levenshtein) [![PkgGoDev](https://pkg.go.dev/badge/github.com/agnivade/levenshtein)](https://pkg.go.dev/github.com/agnivade/levenshtein) +=========== + +[Go](http://golang.org) package to calculate the [Levenshtein Distance](http://en.wikipedia.org/wiki/Levenshtein_distance) + +The library is fully capable of working with non-ascii strings. But the strings are not normalized. That is left as a user-dependant use case. Please normalize the strings before passing it to the library if you have such a requirement. +- https://blog.golang.org/normalization + +#### Limitation + +As a performance optimization, the library can handle strings only up to 65536 characters (runes). If you need to handle strings larger than that, please pin to version 1.0.3. + +Install +------- + + go get github.com/agnivade/levenshtein + +Example +------- + +```go +package main + +import ( + "fmt" + "github.com/agnivade/levenshtein" +) + +func main() { + s1 := "kitten" + s2 := "sitting" + distance := levenshtein.ComputeDistance(s1, s2) + fmt.Printf("The distance between %s and %s is %d.\n", s1, s2, distance) + // Output: + // The distance between kitten and sitting is 3. +} + +``` + +Benchmarks +---------- + +``` +name time/op +Simple/ASCII-4 330ns ± 2% +Simple/French-4 617ns ± 2% +Simple/Nordic-4 1.16µs ± 4% +Simple/Tibetan-4 1.05µs ± 1% + +name alloc/op +Simple/ASCII-4 96.0B ± 0% +Simple/French-4 128B ± 0% +Simple/Nordic-4 192B ± 0% +Simple/Tibetan-4 144B ± 0% + +name allocs/op +Simple/ASCII-4 1.00 ± 0% +Simple/French-4 1.00 ± 0% +Simple/Nordic-4 1.00 ± 0% +Simple/Tibetan-4 1.00 ± 0% +``` + +Comparisons with other libraries +-------------------------------- + +``` +name time/op +Leven/ASCII/agniva-4 353ns ± 1% +Leven/ASCII/arbovm-4 485ns ± 1% +Leven/ASCII/dgryski-4 395ns ± 0% +Leven/French/agniva-4 648ns ± 1% +Leven/French/arbovm-4 791ns ± 0% +Leven/French/dgryski-4 682ns ± 0% +Leven/Nordic/agniva-4 1.28µs ± 1% +Leven/Nordic/arbovm-4 1.52µs ± 1% +Leven/Nordic/dgryski-4 1.32µs ± 1% +Leven/Tibetan/agniva-4 1.12µs ± 1% +Leven/Tibetan/arbovm-4 1.31µs ± 0% +Leven/Tibetan/dgryski-4 1.16µs ± 0% +``` diff --git a/vendor/github.com/agnivade/levenshtein/go.mod b/vendor/github.com/agnivade/levenshtein/go.mod new file mode 100644 index 0000000..4fcfe43 --- /dev/null +++ b/vendor/github.com/agnivade/levenshtein/go.mod @@ -0,0 +1,8 @@ +module github.com/agnivade/levenshtein + +go 1.13 + +require ( + github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 + github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 +) diff --git a/vendor/github.com/agnivade/levenshtein/go.sum b/vendor/github.com/agnivade/levenshtein/go.sum new file mode 100644 index 0000000..74d92aa --- /dev/null +++ b/vendor/github.com/agnivade/levenshtein/go.sum @@ -0,0 +1,4 @@ +github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= +github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= +github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g= +github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= diff --git a/vendor/github.com/agnivade/levenshtein/levenshtein.go b/vendor/github.com/agnivade/levenshtein/levenshtein.go new file mode 100644 index 0000000..f727a66 --- /dev/null +++ b/vendor/github.com/agnivade/levenshtein/levenshtein.go @@ -0,0 +1,89 @@ +// Package levenshtein is a Go implementation to calculate Levenshtein Distance. +// +// Implementation taken from +// https://gist.github.com/andrei-m/982927#gistcomment-1931258 +package levenshtein + +import "unicode/utf8" + +// minLengthThreshold is the length of the string beyond which +// an allocation will be made. Strings smaller than this will be +// zero alloc. +const minLengthThreshold = 32 + +// ComputeDistance computes the levenshtein distance between the two +// strings passed as an argument. The return value is the levenshtein distance +// +// Works on runes (Unicode code points) but does not normalize +// the input strings. See https://blog.golang.org/normalization +// and the golang.org/x/text/unicode/norm package. +func ComputeDistance(a, b string) int { + if len(a) == 0 { + return utf8.RuneCountInString(b) + } + + if len(b) == 0 { + return utf8.RuneCountInString(a) + } + + if a == b { + return 0 + } + + // We need to convert to []rune if the strings are non-ASCII. + // This could be avoided by using utf8.RuneCountInString + // and then doing some juggling with rune indices, + // but leads to far more bounds checks. It is a reasonable trade-off. + s1 := []rune(a) + s2 := []rune(b) + + // swap to save some memory O(min(a,b)) instead of O(a) + if len(s1) > len(s2) { + s1, s2 = s2, s1 + } + lenS1 := len(s1) + lenS2 := len(s2) + + // Init the row. + var x []uint16 + if lenS1+1 > minLengthThreshold { + x = make([]uint16, lenS1+1) + } else { + // We make a small optimization here for small strings. + // Because a slice of constant length is effectively an array, + // it does not allocate. So we can re-slice it to the right length + // as long as it is below a desired threshold. + x = make([]uint16, minLengthThreshold) + x = x[:lenS1+1] + } + + // we start from 1 because index 0 is already 0. + for i := 1; i < len(x); i++ { + x[i] = uint16(i) + } + + // make a dummy bounds check to prevent the 2 bounds check down below. + // The one inside the loop is particularly costly. + _ = x[lenS1] + // fill in the rest + for i := 1; i <= lenS2; i++ { + prev := uint16(i) + for j := 1; j <= lenS1; j++ { + current := x[j-1] // match + if s2[i-1] != s1[j-1] { + current = min(min(x[j-1]+1, prev+1), x[j]+1) + } + x[j-1] = prev + prev = current + } + x[lenS1] = prev + } + return int(x[lenS1]) +} + +func min(a, b uint16) uint16 { + if a < b { + return a + } + return b +} diff --git a/vendor/github.com/andybalholm/brotli/LICENSE b/vendor/github.com/andybalholm/brotli/LICENSE new file mode 100644 index 0000000..33b7cdd --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/andybalholm/brotli/README.md b/vendor/github.com/andybalholm/brotli/README.md new file mode 100644 index 0000000..1ea7fdb --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/README.md @@ -0,0 +1,7 @@ +This package is a brotli compressor and decompressor implemented in Go. +It was translated from the reference implementation (https://github.com/google/brotli) +with the `c2go` tool at https://github.com/andybalholm/c2go. + +I am using it in production with https://github.com/andybalholm/redwood. + +API documentation is found at https://pkg.go.dev/github.com/andybalholm/brotli?tab=doc. diff --git a/vendor/github.com/andybalholm/brotli/backward_references.go b/vendor/github.com/andybalholm/brotli/backward_references.go new file mode 100644 index 0000000..008c054 --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/backward_references.go @@ -0,0 +1,185 @@ +package brotli + +import ( + "sync" +) + +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Function to find backward reference copies. */ + +func computeDistanceCode(distance uint, max_distance uint, dist_cache []int) uint { + if distance <= max_distance { + var distance_plus_3 uint = distance + 3 + var offset0 uint = distance_plus_3 - uint(dist_cache[0]) + var offset1 uint = distance_plus_3 - uint(dist_cache[1]) + if distance == uint(dist_cache[0]) { + return 0 + } else if distance == uint(dist_cache[1]) { + return 1 + } else if offset0 < 7 { + return (0x9750468 >> (4 * offset0)) & 0xF + } else if offset1 < 7 { + return (0xFDB1ACE >> (4 * offset1)) & 0xF + } else if distance == uint(dist_cache[2]) { + return 2 + } else if distance == uint(dist_cache[3]) { + return 3 + } + } + + return distance + numDistanceShortCodes - 1 +} + +var hasherSearchResultPool sync.Pool + +func createBackwardReferences(num_bytes uint, position uint, ringbuffer []byte, ringbuffer_mask uint, params *encoderParams, hasher hasherHandle, dist_cache []int, last_insert_len *uint, commands *[]command, num_literals *uint) { + var max_backward_limit uint = maxBackwardLimit(params.lgwin) + var insert_length uint = *last_insert_len + var pos_end uint = position + num_bytes + var store_end uint + if num_bytes >= hasher.StoreLookahead() { + store_end = position + num_bytes - hasher.StoreLookahead() + 1 + } else { + store_end = position + } + var random_heuristics_window_size uint = literalSpreeLengthForSparseSearch(params) + var apply_random_heuristics uint = position + random_heuristics_window_size + var gap uint = 0 + /* Set maximum distance, see section 9.1. of the spec. */ + + const kMinScore uint = scoreBase + 100 + + /* For speed up heuristics for random data. */ + + /* Minimum score to accept a backward reference. */ + hasher.PrepareDistanceCache(dist_cache) + sr2, _ := hasherSearchResultPool.Get().(*hasherSearchResult) + if sr2 == nil { + sr2 = &hasherSearchResult{} + } + sr, _ := hasherSearchResultPool.Get().(*hasherSearchResult) + if sr == nil { + sr = &hasherSearchResult{} + } + + for position+hasher.HashTypeLength() < pos_end { + var max_length uint = pos_end - position + var max_distance uint = brotli_min_size_t(position, max_backward_limit) + sr.len = 0 + sr.len_code_delta = 0 + sr.distance = 0 + sr.score = kMinScore + hasher.FindLongestMatch(¶ms.dictionary, ringbuffer, ringbuffer_mask, dist_cache, position, max_length, max_distance, gap, params.dist.max_distance, sr) + if sr.score > kMinScore { + /* Found a match. Let's look for something even better ahead. */ + var delayed_backward_references_in_row int = 0 + max_length-- + for ; ; max_length-- { + var cost_diff_lazy uint = 175 + if params.quality < minQualityForExtensiveReferenceSearch { + sr2.len = brotli_min_size_t(sr.len-1, max_length) + } else { + sr2.len = 0 + } + sr2.len_code_delta = 0 + sr2.distance = 0 + sr2.score = kMinScore + max_distance = brotli_min_size_t(position+1, max_backward_limit) + hasher.FindLongestMatch(¶ms.dictionary, ringbuffer, ringbuffer_mask, dist_cache, position+1, max_length, max_distance, gap, params.dist.max_distance, sr2) + if sr2.score >= sr.score+cost_diff_lazy { + /* Ok, let's just write one byte for now and start a match from the + next byte. */ + position++ + + insert_length++ + *sr = *sr2 + delayed_backward_references_in_row++ + if delayed_backward_references_in_row < 4 && position+hasher.HashTypeLength() < pos_end { + continue + } + } + + break + } + + apply_random_heuristics = position + 2*sr.len + random_heuristics_window_size + max_distance = brotli_min_size_t(position, max_backward_limit) + { + /* The first 16 codes are special short-codes, + and the minimum offset is 1. */ + var distance_code uint = computeDistanceCode(sr.distance, max_distance+gap, dist_cache) + if (sr.distance <= (max_distance + gap)) && distance_code > 0 { + dist_cache[3] = dist_cache[2] + dist_cache[2] = dist_cache[1] + dist_cache[1] = dist_cache[0] + dist_cache[0] = int(sr.distance) + hasher.PrepareDistanceCache(dist_cache) + } + + *commands = append(*commands, makeCommand(¶ms.dist, insert_length, sr.len, sr.len_code_delta, distance_code)) + } + + *num_literals += insert_length + insert_length = 0 + /* Put the hash keys into the table, if there are enough bytes left. + Depending on the hasher implementation, it can push all positions + in the given range or only a subset of them. + Avoid hash poisoning with RLE data. */ + { + var range_start uint = position + 2 + var range_end uint = brotli_min_size_t(position+sr.len, store_end) + if sr.distance < sr.len>>2 { + range_start = brotli_min_size_t(range_end, brotli_max_size_t(range_start, position+sr.len-(sr.distance<<2))) + } + + hasher.StoreRange(ringbuffer, ringbuffer_mask, range_start, range_end) + } + + position += sr.len + } else { + insert_length++ + position++ + + /* If we have not seen matches for a long time, we can skip some + match lookups. Unsuccessful match lookups are very very expensive + and this kind of a heuristic speeds up compression quite + a lot. */ + if position > apply_random_heuristics { + /* Going through uncompressible data, jump. */ + if position > apply_random_heuristics+4*random_heuristics_window_size { + var kMargin uint = brotli_max_size_t(hasher.StoreLookahead()-1, 4) + /* It is quite a long time since we saw a copy, so we assume + that this data is not compressible, and store hashes less + often. Hashes of non compressible data are less likely to + turn out to be useful in the future, too, so we store less of + them to not to flood out the hash table of good compressible + data. */ + + var pos_jump uint = brotli_min_size_t(position+16, pos_end-kMargin) + for ; position < pos_jump; position += 4 { + hasher.Store(ringbuffer, ringbuffer_mask, position) + insert_length += 4 + } + } else { + var kMargin uint = brotli_max_size_t(hasher.StoreLookahead()-1, 2) + var pos_jump uint = brotli_min_size_t(position+8, pos_end-kMargin) + for ; position < pos_jump; position += 2 { + hasher.Store(ringbuffer, ringbuffer_mask, position) + insert_length += 2 + } + } + } + } + } + + insert_length += pos_end - position + *last_insert_len = insert_length + + hasherSearchResultPool.Put(sr) + hasherSearchResultPool.Put(sr2) +} diff --git a/vendor/github.com/andybalholm/brotli/backward_references_hq.go b/vendor/github.com/andybalholm/brotli/backward_references_hq.go new file mode 100644 index 0000000..21629c1 --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/backward_references_hq.go @@ -0,0 +1,796 @@ +package brotli + +import "math" + +type zopfliNode struct { + length uint32 + distance uint32 + dcode_insert_length uint32 + u struct { + cost float32 + next uint32 + shortcut uint32 + } +} + +const maxEffectiveDistanceAlphabetSize = 544 + +const kInfinity float32 = 1.7e38 /* ~= 2 ^ 127 */ + +var kDistanceCacheIndex = []uint32{0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1} + +var kDistanceCacheOffset = []int{0, 0, 0, 0, -1, 1, -2, 2, -3, 3, -1, 1, -2, 2, -3, 3} + +func initZopfliNodes(array []zopfliNode, length uint) { + var stub zopfliNode + var i uint + stub.length = 1 + stub.distance = 0 + stub.dcode_insert_length = 0 + stub.u.cost = kInfinity + for i = 0; i < length; i++ { + array[i] = stub + } +} + +func zopfliNodeCopyLength(self *zopfliNode) uint32 { + return self.length & 0x1FFFFFF +} + +func zopfliNodeLengthCode(self *zopfliNode) uint32 { + var modifier uint32 = self.length >> 25 + return zopfliNodeCopyLength(self) + 9 - modifier +} + +func zopfliNodeCopyDistance(self *zopfliNode) uint32 { + return self.distance +} + +func zopfliNodeDistanceCode(self *zopfliNode) uint32 { + var short_code uint32 = self.dcode_insert_length >> 27 + if short_code == 0 { + return zopfliNodeCopyDistance(self) + numDistanceShortCodes - 1 + } else { + return short_code - 1 + } +} + +func zopfliNodeCommandLength(self *zopfliNode) uint32 { + return zopfliNodeCopyLength(self) + (self.dcode_insert_length & 0x7FFFFFF) +} + +/* Histogram based cost model for zopflification. */ +type zopfliCostModel struct { + cost_cmd_ [numCommandSymbols]float32 + cost_dist_ []float32 + distance_histogram_size uint32 + literal_costs_ []float32 + min_cost_cmd_ float32 + num_bytes_ uint +} + +func initZopfliCostModel(self *zopfliCostModel, dist *distanceParams, num_bytes uint) { + var distance_histogram_size uint32 = dist.alphabet_size + if distance_histogram_size > maxEffectiveDistanceAlphabetSize { + distance_histogram_size = maxEffectiveDistanceAlphabetSize + } + + self.num_bytes_ = num_bytes + self.literal_costs_ = make([]float32, (num_bytes + 2)) + self.cost_dist_ = make([]float32, (dist.alphabet_size)) + self.distance_histogram_size = distance_histogram_size +} + +func cleanupZopfliCostModel(self *zopfliCostModel) { + self.literal_costs_ = nil + self.cost_dist_ = nil +} + +func setCost(histogram []uint32, histogram_size uint, literal_histogram bool, cost []float32) { + var sum uint = 0 + var missing_symbol_sum uint + var log2sum float32 + var missing_symbol_cost float32 + var i uint + for i = 0; i < histogram_size; i++ { + sum += uint(histogram[i]) + } + + log2sum = float32(fastLog2(sum)) + missing_symbol_sum = sum + if !literal_histogram { + for i = 0; i < histogram_size; i++ { + if histogram[i] == 0 { + missing_symbol_sum++ + } + } + } + + missing_symbol_cost = float32(fastLog2(missing_symbol_sum)) + 2 + for i = 0; i < histogram_size; i++ { + if histogram[i] == 0 { + cost[i] = missing_symbol_cost + continue + } + + /* Shannon bits for this symbol. */ + cost[i] = log2sum - float32(fastLog2(uint(histogram[i]))) + + /* Cannot be coded with less than 1 bit */ + if cost[i] < 1 { + cost[i] = 1 + } + } +} + +func zopfliCostModelSetFromCommands(self *zopfliCostModel, position uint, ringbuffer []byte, ringbuffer_mask uint, commands []command, last_insert_len uint) { + var histogram_literal [numLiteralSymbols]uint32 + var histogram_cmd [numCommandSymbols]uint32 + var histogram_dist [maxEffectiveDistanceAlphabetSize]uint32 + var cost_literal [numLiteralSymbols]float32 + var pos uint = position - last_insert_len + var min_cost_cmd float32 = kInfinity + var cost_cmd []float32 = self.cost_cmd_[:] + var literal_costs []float32 + + histogram_literal = [numLiteralSymbols]uint32{} + histogram_cmd = [numCommandSymbols]uint32{} + histogram_dist = [maxEffectiveDistanceAlphabetSize]uint32{} + + for i := range commands { + var inslength uint = uint(commands[i].insert_len_) + var copylength uint = uint(commandCopyLen(&commands[i])) + var distcode uint = uint(commands[i].dist_prefix_) & 0x3FF + var cmdcode uint = uint(commands[i].cmd_prefix_) + var j uint + + histogram_cmd[cmdcode]++ + if cmdcode >= 128 { + histogram_dist[distcode]++ + } + + for j = 0; j < inslength; j++ { + histogram_literal[ringbuffer[(pos+j)&ringbuffer_mask]]++ + } + + pos += inslength + copylength + } + + setCost(histogram_literal[:], numLiteralSymbols, true, cost_literal[:]) + setCost(histogram_cmd[:], numCommandSymbols, false, cost_cmd) + setCost(histogram_dist[:], uint(self.distance_histogram_size), false, self.cost_dist_) + + for i := 0; i < numCommandSymbols; i++ { + min_cost_cmd = brotli_min_float(min_cost_cmd, cost_cmd[i]) + } + + self.min_cost_cmd_ = min_cost_cmd + { + literal_costs = self.literal_costs_ + var literal_carry float32 = 0.0 + num_bytes := int(self.num_bytes_) + literal_costs[0] = 0.0 + for i := 0; i < num_bytes; i++ { + literal_carry += cost_literal[ringbuffer[(position+uint(i))&ringbuffer_mask]] + literal_costs[i+1] = literal_costs[i] + literal_carry + literal_carry -= literal_costs[i+1] - literal_costs[i] + } + } +} + +func zopfliCostModelSetFromLiteralCosts(self *zopfliCostModel, position uint, ringbuffer []byte, ringbuffer_mask uint) { + var literal_costs []float32 = self.literal_costs_ + var literal_carry float32 = 0.0 + var cost_dist []float32 = self.cost_dist_ + var cost_cmd []float32 = self.cost_cmd_[:] + var num_bytes uint = self.num_bytes_ + var i uint + estimateBitCostsForLiterals(position, num_bytes, ringbuffer_mask, ringbuffer, literal_costs[1:]) + literal_costs[0] = 0.0 + for i = 0; i < num_bytes; i++ { + literal_carry += literal_costs[i+1] + literal_costs[i+1] = literal_costs[i] + literal_carry + literal_carry -= literal_costs[i+1] - literal_costs[i] + } + + for i = 0; i < numCommandSymbols; i++ { + cost_cmd[i] = float32(fastLog2(uint(11 + uint32(i)))) + } + + for i = 0; uint32(i) < self.distance_histogram_size; i++ { + cost_dist[i] = float32(fastLog2(uint(20 + uint32(i)))) + } + + self.min_cost_cmd_ = float32(fastLog2(11)) +} + +func zopfliCostModelGetCommandCost(self *zopfliCostModel, cmdcode uint16) float32 { + return self.cost_cmd_[cmdcode] +} + +func zopfliCostModelGetDistanceCost(self *zopfliCostModel, distcode uint) float32 { + return self.cost_dist_[distcode] +} + +func zopfliCostModelGetLiteralCosts(self *zopfliCostModel, from uint, to uint) float32 { + return self.literal_costs_[to] - self.literal_costs_[from] +} + +func zopfliCostModelGetMinCostCmd(self *zopfliCostModel) float32 { + return self.min_cost_cmd_ +} + +/* REQUIRES: len >= 2, start_pos <= pos */ +/* REQUIRES: cost < kInfinity, nodes[start_pos].cost < kInfinity */ +/* Maintains the "ZopfliNode array invariant". */ +func updateZopfliNode(nodes []zopfliNode, pos uint, start_pos uint, len uint, len_code uint, dist uint, short_code uint, cost float32) { + var next *zopfliNode = &nodes[pos+len] + next.length = uint32(len | (len+9-len_code)<<25) + next.distance = uint32(dist) + next.dcode_insert_length = uint32(short_code<<27 | (pos - start_pos)) + next.u.cost = cost +} + +type posData struct { + pos uint + distance_cache [4]int + costdiff float32 + cost float32 +} + +/* Maintains the smallest 8 cost difference together with their positions */ +type startPosQueue struct { + q_ [8]posData + idx_ uint +} + +func initStartPosQueue(self *startPosQueue) { + self.idx_ = 0 +} + +func startPosQueueSize(self *startPosQueue) uint { + return brotli_min_size_t(self.idx_, 8) +} + +func startPosQueuePush(self *startPosQueue, posdata *posData) { + var offset uint = ^(self.idx_) & 7 + self.idx_++ + var len uint = startPosQueueSize(self) + var i uint + var q []posData = self.q_[:] + q[offset] = *posdata + + /* Restore the sorted order. In the list of |len| items at most |len - 1| + adjacent element comparisons / swaps are required. */ + for i = 1; i < len; i++ { + if q[offset&7].costdiff > q[(offset+1)&7].costdiff { + var tmp posData = q[offset&7] + q[offset&7] = q[(offset+1)&7] + q[(offset+1)&7] = tmp + } + + offset++ + } +} + +func startPosQueueAt(self *startPosQueue, k uint) *posData { + return &self.q_[(k-self.idx_)&7] +} + +/* Returns the minimum possible copy length that can improve the cost of any */ +/* future position. */ +func computeMinimumCopyLength(start_cost float32, nodes []zopfliNode, num_bytes uint, pos uint) uint { + var min_cost float32 = start_cost + var len uint = 2 + var next_len_bucket uint = 4 + /* Compute the minimum possible cost of reaching any future position. */ + + var next_len_offset uint = 10 + for pos+len <= num_bytes && nodes[pos+len].u.cost <= min_cost { + /* We already reached (pos + len) with no more cost than the minimum + possible cost of reaching anything from this pos, so there is no point in + looking for lengths <= len. */ + len++ + + if len == next_len_offset { + /* We reached the next copy length code bucket, so we add one more + extra bit to the minimum cost. */ + min_cost += 1.0 + + next_len_offset += next_len_bucket + next_len_bucket *= 2 + } + } + + return uint(len) +} + +/* REQUIRES: nodes[pos].cost < kInfinity + REQUIRES: nodes[0..pos] satisfies that "ZopfliNode array invariant". */ +func computeDistanceShortcut(block_start uint, pos uint, max_backward_limit uint, gap uint, nodes []zopfliNode) uint32 { + var clen uint = uint(zopfliNodeCopyLength(&nodes[pos])) + var ilen uint = uint(nodes[pos].dcode_insert_length & 0x7FFFFFF) + var dist uint = uint(zopfliNodeCopyDistance(&nodes[pos])) + + /* Since |block_start + pos| is the end position of the command, the copy part + starts from |block_start + pos - clen|. Distances that are greater than + this or greater than |max_backward_limit| + |gap| are static dictionary + references, and do not update the last distances. + Also distance code 0 (last distance) does not update the last distances. */ + if pos == 0 { + return 0 + } else if dist+clen <= block_start+pos+gap && dist <= max_backward_limit+gap && zopfliNodeDistanceCode(&nodes[pos]) > 0 { + return uint32(pos) + } else { + return nodes[pos-clen-ilen].u.shortcut + } +} + +/* Fills in dist_cache[0..3] with the last four distances (as defined by + Section 4. of the Spec) that would be used at (block_start + pos) if we + used the shortest path of commands from block_start, computed from + nodes[0..pos]. The last four distances at block_start are in + starting_dist_cache[0..3]. + REQUIRES: nodes[pos].cost < kInfinity + REQUIRES: nodes[0..pos] satisfies that "ZopfliNode array invariant". */ +func computeDistanceCache(pos uint, starting_dist_cache []int, nodes []zopfliNode, dist_cache []int) { + var idx int = 0 + var p uint = uint(nodes[pos].u.shortcut) + for idx < 4 && p > 0 { + var ilen uint = uint(nodes[p].dcode_insert_length & 0x7FFFFFF) + var clen uint = uint(zopfliNodeCopyLength(&nodes[p])) + var dist uint = uint(zopfliNodeCopyDistance(&nodes[p])) + dist_cache[idx] = int(dist) + idx++ + + /* Because of prerequisite, p >= clen + ilen >= 2. */ + p = uint(nodes[p-clen-ilen].u.shortcut) + } + + for ; idx < 4; idx++ { + dist_cache[idx] = starting_dist_cache[0] + starting_dist_cache = starting_dist_cache[1:] + } +} + +/* Maintains "ZopfliNode array invariant" and pushes node to the queue, if it + is eligible. */ +func evaluateNode(block_start uint, pos uint, max_backward_limit uint, gap uint, starting_dist_cache []int, model *zopfliCostModel, queue *startPosQueue, nodes []zopfliNode) { + /* Save cost, because ComputeDistanceCache invalidates it. */ + var node_cost float32 = nodes[pos].u.cost + nodes[pos].u.shortcut = computeDistanceShortcut(block_start, pos, max_backward_limit, gap, nodes) + if node_cost <= zopfliCostModelGetLiteralCosts(model, 0, pos) { + var posdata posData + posdata.pos = pos + posdata.cost = node_cost + posdata.costdiff = node_cost - zopfliCostModelGetLiteralCosts(model, 0, pos) + computeDistanceCache(pos, starting_dist_cache, nodes, posdata.distance_cache[:]) + startPosQueuePush(queue, &posdata) + } +} + +/* Returns longest copy length. */ +func updateNodes(num_bytes uint, block_start uint, pos uint, ringbuffer []byte, ringbuffer_mask uint, params *encoderParams, max_backward_limit uint, starting_dist_cache []int, num_matches uint, matches []backwardMatch, model *zopfliCostModel, queue *startPosQueue, nodes []zopfliNode) uint { + var cur_ix uint = block_start + pos + var cur_ix_masked uint = cur_ix & ringbuffer_mask + var max_distance uint = brotli_min_size_t(cur_ix, max_backward_limit) + var max_len uint = num_bytes - pos + var max_zopfli_len uint = maxZopfliLen(params) + var max_iters uint = maxZopfliCandidates(params) + var min_len uint + var result uint = 0 + var k uint + var gap uint = 0 + + evaluateNode(block_start, pos, max_backward_limit, gap, starting_dist_cache, model, queue, nodes) + { + var posdata *posData = startPosQueueAt(queue, 0) + var min_cost float32 = (posdata.cost + zopfliCostModelGetMinCostCmd(model) + zopfliCostModelGetLiteralCosts(model, posdata.pos, pos)) + min_len = computeMinimumCopyLength(min_cost, nodes, num_bytes, pos) + } + + /* Go over the command starting positions in order of increasing cost + difference. */ + for k = 0; k < max_iters && k < startPosQueueSize(queue); k++ { + var posdata *posData = startPosQueueAt(queue, k) + var start uint = posdata.pos + var inscode uint16 = getInsertLengthCode(pos - start) + var start_costdiff float32 = posdata.costdiff + var base_cost float32 = start_costdiff + float32(getInsertExtra(inscode)) + zopfliCostModelGetLiteralCosts(model, 0, pos) + var best_len uint = min_len - 1 + var j uint = 0 + /* Look for last distance matches using the distance cache from this + starting position. */ + for ; j < numDistanceShortCodes && best_len < max_len; j++ { + var idx uint = uint(kDistanceCacheIndex[j]) + var backward uint = uint(posdata.distance_cache[idx] + kDistanceCacheOffset[j]) + var prev_ix uint = cur_ix - backward + var len uint = 0 + var continuation byte = ringbuffer[cur_ix_masked+best_len] + if cur_ix_masked+best_len > ringbuffer_mask { + break + } + + if backward > max_distance+gap { + /* Word dictionary -> ignore. */ + continue + } + + if backward <= max_distance { + /* Regular backward reference. */ + if prev_ix >= cur_ix { + continue + } + + prev_ix &= ringbuffer_mask + if prev_ix+best_len > ringbuffer_mask || continuation != ringbuffer[prev_ix+best_len] { + continue + } + + len = findMatchLengthWithLimit(ringbuffer[prev_ix:], ringbuffer[cur_ix_masked:], max_len) + } else { + continue + } + { + var dist_cost float32 = base_cost + zopfliCostModelGetDistanceCost(model, j) + var l uint + for l = best_len + 1; l <= len; l++ { + var copycode uint16 = getCopyLengthCode(l) + var cmdcode uint16 = combineLengthCodes(inscode, copycode, j == 0) + var tmp float32 + if cmdcode < 128 { + tmp = base_cost + } else { + tmp = dist_cost + } + var cost float32 = tmp + float32(getCopyExtra(copycode)) + zopfliCostModelGetCommandCost(model, cmdcode) + if cost < nodes[pos+l].u.cost { + updateZopfliNode(nodes, pos, start, l, l, backward, j+1, cost) + result = brotli_max_size_t(result, l) + } + + best_len = l + } + } + } + + /* At higher iterations look only for new last distance matches, since + looking only for new command start positions with the same distances + does not help much. */ + if k >= 2 { + continue + } + { + /* Loop through all possible copy lengths at this position. */ + var len uint = min_len + for j = 0; j < num_matches; j++ { + var match backwardMatch = matches[j] + var dist uint = uint(match.distance) + var is_dictionary_match bool = (dist > max_distance+gap) + var dist_code uint = dist + numDistanceShortCodes - 1 + var dist_symbol uint16 + var distextra uint32 + var distnumextra uint32 + var dist_cost float32 + var max_match_len uint + /* We already tried all possible last distance matches, so we can use + normal distance code here. */ + prefixEncodeCopyDistance(dist_code, uint(params.dist.num_direct_distance_codes), uint(params.dist.distance_postfix_bits), &dist_symbol, &distextra) + + distnumextra = uint32(dist_symbol) >> 10 + dist_cost = base_cost + float32(distnumextra) + zopfliCostModelGetDistanceCost(model, uint(dist_symbol)&0x3FF) + + /* Try all copy lengths up until the maximum copy length corresponding + to this distance. If the distance refers to the static dictionary, or + the maximum length is long enough, try only one maximum length. */ + max_match_len = backwardMatchLength(&match) + + if len < max_match_len && (is_dictionary_match || max_match_len > max_zopfli_len) { + len = max_match_len + } + + for ; len <= max_match_len; len++ { + var len_code uint + if is_dictionary_match { + len_code = backwardMatchLengthCode(&match) + } else { + len_code = len + } + var copycode uint16 = getCopyLengthCode(len_code) + var cmdcode uint16 = combineLengthCodes(inscode, copycode, false) + var cost float32 = dist_cost + float32(getCopyExtra(copycode)) + zopfliCostModelGetCommandCost(model, cmdcode) + if cost < nodes[pos+len].u.cost { + updateZopfliNode(nodes, pos, start, uint(len), len_code, dist, 0, cost) + if len > result { + result = len + } + } + } + } + } + } + + return result +} + +func computeShortestPathFromNodes(num_bytes uint, nodes []zopfliNode) uint { + var index uint = num_bytes + var num_commands uint = 0 + for nodes[index].dcode_insert_length&0x7FFFFFF == 0 && nodes[index].length == 1 { + index-- + } + nodes[index].u.next = math.MaxUint32 + for index != 0 { + var len uint = uint(zopfliNodeCommandLength(&nodes[index])) + index -= uint(len) + nodes[index].u.next = uint32(len) + num_commands++ + } + + return num_commands +} + +/* REQUIRES: nodes != NULL and len(nodes) >= num_bytes + 1 */ +func zopfliCreateCommands(num_bytes uint, block_start uint, nodes []zopfliNode, dist_cache []int, last_insert_len *uint, params *encoderParams, commands *[]command, num_literals *uint) { + var max_backward_limit uint = maxBackwardLimit(params.lgwin) + var pos uint = 0 + var offset uint32 = nodes[0].u.next + var i uint + var gap uint = 0 + for i = 0; offset != math.MaxUint32; i++ { + var next *zopfliNode = &nodes[uint32(pos)+offset] + var copy_length uint = uint(zopfliNodeCopyLength(next)) + var insert_length uint = uint(next.dcode_insert_length & 0x7FFFFFF) + pos += insert_length + offset = next.u.next + if i == 0 { + insert_length += *last_insert_len + *last_insert_len = 0 + } + { + var distance uint = uint(zopfliNodeCopyDistance(next)) + var len_code uint = uint(zopfliNodeLengthCode(next)) + var max_distance uint = brotli_min_size_t(block_start+pos, max_backward_limit) + var is_dictionary bool = (distance > max_distance+gap) + var dist_code uint = uint(zopfliNodeDistanceCode(next)) + *commands = append(*commands, makeCommand(¶ms.dist, insert_length, copy_length, int(len_code)-int(copy_length), dist_code)) + + if !is_dictionary && dist_code > 0 { + dist_cache[3] = dist_cache[2] + dist_cache[2] = dist_cache[1] + dist_cache[1] = dist_cache[0] + dist_cache[0] = int(distance) + } + } + + *num_literals += insert_length + pos += copy_length + } + + *last_insert_len += num_bytes - pos +} + +func zopfliIterate(num_bytes uint, position uint, ringbuffer []byte, ringbuffer_mask uint, params *encoderParams, gap uint, dist_cache []int, model *zopfliCostModel, num_matches []uint32, matches []backwardMatch, nodes []zopfliNode) uint { + var max_backward_limit uint = maxBackwardLimit(params.lgwin) + var max_zopfli_len uint = maxZopfliLen(params) + var queue startPosQueue + var cur_match_pos uint = 0 + var i uint + nodes[0].length = 0 + nodes[0].u.cost = 0 + initStartPosQueue(&queue) + for i = 0; i+3 < num_bytes; i++ { + var skip uint = updateNodes(num_bytes, position, i, ringbuffer, ringbuffer_mask, params, max_backward_limit, dist_cache, uint(num_matches[i]), matches[cur_match_pos:], model, &queue, nodes) + if skip < longCopyQuickStep { + skip = 0 + } + cur_match_pos += uint(num_matches[i]) + if num_matches[i] == 1 && backwardMatchLength(&matches[cur_match_pos-1]) > max_zopfli_len { + skip = brotli_max_size_t(backwardMatchLength(&matches[cur_match_pos-1]), skip) + } + + if skip > 1 { + skip-- + for skip != 0 { + i++ + if i+3 >= num_bytes { + break + } + evaluateNode(position, i, max_backward_limit, gap, dist_cache, model, &queue, nodes) + cur_match_pos += uint(num_matches[i]) + skip-- + } + } + } + + return computeShortestPathFromNodes(num_bytes, nodes) +} + +/* Computes the shortest path of commands from position to at most + position + num_bytes. + + On return, path->size() is the number of commands found and path[i] is the + length of the i-th command (copy length plus insert length). + Note that the sum of the lengths of all commands can be less than num_bytes. + + On return, the nodes[0..num_bytes] array will have the following + "ZopfliNode array invariant": + For each i in [1..num_bytes], if nodes[i].cost < kInfinity, then + (1) nodes[i].copy_length() >= 2 + (2) nodes[i].command_length() <= i and + (3) nodes[i - nodes[i].command_length()].cost < kInfinity + + REQUIRES: nodes != nil and len(nodes) >= num_bytes + 1 */ +func zopfliComputeShortestPath(num_bytes uint, position uint, ringbuffer []byte, ringbuffer_mask uint, params *encoderParams, dist_cache []int, hasher *h10, nodes []zopfliNode) uint { + var max_backward_limit uint = maxBackwardLimit(params.lgwin) + var max_zopfli_len uint = maxZopfliLen(params) + var model zopfliCostModel + var queue startPosQueue + var matches [2 * (maxNumMatchesH10 + 64)]backwardMatch + var store_end uint + if num_bytes >= hasher.StoreLookahead() { + store_end = position + num_bytes - hasher.StoreLookahead() + 1 + } else { + store_end = position + } + var i uint + var gap uint = 0 + var lz_matches_offset uint = 0 + nodes[0].length = 0 + nodes[0].u.cost = 0 + initZopfliCostModel(&model, ¶ms.dist, num_bytes) + zopfliCostModelSetFromLiteralCosts(&model, position, ringbuffer, ringbuffer_mask) + initStartPosQueue(&queue) + for i = 0; i+hasher.HashTypeLength()-1 < num_bytes; i++ { + var pos uint = position + i + var max_distance uint = brotli_min_size_t(pos, max_backward_limit) + var skip uint + var num_matches uint + num_matches = findAllMatchesH10(hasher, ¶ms.dictionary, ringbuffer, ringbuffer_mask, pos, num_bytes-i, max_distance, gap, params, matches[lz_matches_offset:]) + if num_matches > 0 && backwardMatchLength(&matches[num_matches-1]) > max_zopfli_len { + matches[0] = matches[num_matches-1] + num_matches = 1 + } + + skip = updateNodes(num_bytes, position, i, ringbuffer, ringbuffer_mask, params, max_backward_limit, dist_cache, num_matches, matches[:], &model, &queue, nodes) + if skip < longCopyQuickStep { + skip = 0 + } + if num_matches == 1 && backwardMatchLength(&matches[0]) > max_zopfli_len { + skip = brotli_max_size_t(backwardMatchLength(&matches[0]), skip) + } + + if skip > 1 { + /* Add the tail of the copy to the hasher. */ + hasher.StoreRange(ringbuffer, ringbuffer_mask, pos+1, brotli_min_size_t(pos+skip, store_end)) + + skip-- + for skip != 0 { + i++ + if i+hasher.HashTypeLength()-1 >= num_bytes { + break + } + evaluateNode(position, i, max_backward_limit, gap, dist_cache, &model, &queue, nodes) + skip-- + } + } + } + + cleanupZopfliCostModel(&model) + return computeShortestPathFromNodes(num_bytes, nodes) +} + +func createZopfliBackwardReferences(num_bytes uint, position uint, ringbuffer []byte, ringbuffer_mask uint, params *encoderParams, hasher *h10, dist_cache []int, last_insert_len *uint, commands *[]command, num_literals *uint) { + var nodes []zopfliNode + nodes = make([]zopfliNode, (num_bytes + 1)) + initZopfliNodes(nodes, num_bytes+1) + zopfliComputeShortestPath(num_bytes, position, ringbuffer, ringbuffer_mask, params, dist_cache, hasher, nodes) + zopfliCreateCommands(num_bytes, position, nodes, dist_cache, last_insert_len, params, commands, num_literals) + nodes = nil +} + +func createHqZopfliBackwardReferences(num_bytes uint, position uint, ringbuffer []byte, ringbuffer_mask uint, params *encoderParams, hasher hasherHandle, dist_cache []int, last_insert_len *uint, commands *[]command, num_literals *uint) { + var max_backward_limit uint = maxBackwardLimit(params.lgwin) + var num_matches []uint32 = make([]uint32, num_bytes) + var matches_size uint = 4 * num_bytes + var store_end uint + if num_bytes >= hasher.StoreLookahead() { + store_end = position + num_bytes - hasher.StoreLookahead() + 1 + } else { + store_end = position + } + var cur_match_pos uint = 0 + var i uint + var orig_num_literals uint + var orig_last_insert_len uint + var orig_dist_cache [4]int + var orig_num_commands int + var model zopfliCostModel + var nodes []zopfliNode + var matches []backwardMatch = make([]backwardMatch, matches_size) + var gap uint = 0 + var shadow_matches uint = 0 + var new_array []backwardMatch + for i = 0; i+hasher.HashTypeLength()-1 < num_bytes; i++ { + var pos uint = position + i + var max_distance uint = brotli_min_size_t(pos, max_backward_limit) + var max_length uint = num_bytes - i + var num_found_matches uint + var cur_match_end uint + var j uint + + /* Ensure that we have enough free slots. */ + if matches_size < cur_match_pos+maxNumMatchesH10+shadow_matches { + var new_size uint = matches_size + if new_size == 0 { + new_size = cur_match_pos + maxNumMatchesH10 + shadow_matches + } + + for new_size < cur_match_pos+maxNumMatchesH10+shadow_matches { + new_size *= 2 + } + + new_array = make([]backwardMatch, new_size) + if matches_size != 0 { + copy(new_array, matches[:matches_size]) + } + + matches = new_array + matches_size = new_size + } + + num_found_matches = findAllMatchesH10(hasher.(*h10), ¶ms.dictionary, ringbuffer, ringbuffer_mask, pos, max_length, max_distance, gap, params, matches[cur_match_pos+shadow_matches:]) + cur_match_end = cur_match_pos + num_found_matches + for j = cur_match_pos; j+1 < cur_match_end; j++ { + assert(backwardMatchLength(&matches[j]) <= backwardMatchLength(&matches[j+1])) + } + + num_matches[i] = uint32(num_found_matches) + if num_found_matches > 0 { + var match_len uint = backwardMatchLength(&matches[cur_match_end-1]) + if match_len > maxZopfliLenQuality11 { + var skip uint = match_len - 1 + matches[cur_match_pos] = matches[cur_match_end-1] + cur_match_pos++ + num_matches[i] = 1 + + /* Add the tail of the copy to the hasher. */ + hasher.StoreRange(ringbuffer, ringbuffer_mask, pos+1, brotli_min_size_t(pos+match_len, store_end)) + var pos uint = i + for i := 0; i < int(skip); i++ { + num_matches[pos+1:][i] = 0 + } + i += skip + } else { + cur_match_pos = cur_match_end + } + } + } + + orig_num_literals = *num_literals + orig_last_insert_len = *last_insert_len + copy(orig_dist_cache[:], dist_cache[:4]) + orig_num_commands = len(*commands) + nodes = make([]zopfliNode, (num_bytes + 1)) + initZopfliCostModel(&model, ¶ms.dist, num_bytes) + for i = 0; i < 2; i++ { + initZopfliNodes(nodes, num_bytes+1) + if i == 0 { + zopfliCostModelSetFromLiteralCosts(&model, position, ringbuffer, ringbuffer_mask) + } else { + zopfliCostModelSetFromCommands(&model, position, ringbuffer, ringbuffer_mask, (*commands)[orig_num_commands:], orig_last_insert_len) + } + + *commands = (*commands)[:orig_num_commands] + *num_literals = orig_num_literals + *last_insert_len = orig_last_insert_len + copy(dist_cache, orig_dist_cache[:4]) + zopfliIterate(num_bytes, position, ringbuffer, ringbuffer_mask, params, gap, dist_cache, &model, num_matches, matches, nodes) + zopfliCreateCommands(num_bytes, position, nodes, dist_cache, last_insert_len, params, commands, num_literals) + } + + cleanupZopfliCostModel(&model) + nodes = nil + matches = nil + num_matches = nil +} diff --git a/vendor/github.com/andybalholm/brotli/bit_cost.go b/vendor/github.com/andybalholm/brotli/bit_cost.go new file mode 100644 index 0000000..0005fc1 --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/bit_cost.go @@ -0,0 +1,436 @@ +package brotli + +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Functions to estimate the bit cost of Huffman trees. */ +func shannonEntropy(population []uint32, size uint, total *uint) float64 { + var sum uint = 0 + var retval float64 = 0 + var population_end []uint32 = population[size:] + var p uint + for -cap(population) < -cap(population_end) { + p = uint(population[0]) + population = population[1:] + sum += p + retval -= float64(p) * fastLog2(p) + } + + if sum != 0 { + retval += float64(sum) * fastLog2(sum) + } + *total = sum + return retval +} + +func bitsEntropy(population []uint32, size uint) float64 { + var sum uint + var retval float64 = shannonEntropy(population, size, &sum) + if retval < float64(sum) { + /* At least one bit per literal is needed. */ + retval = float64(sum) + } + + return retval +} + +const kOneSymbolHistogramCost float64 = 12 +const kTwoSymbolHistogramCost float64 = 20 +const kThreeSymbolHistogramCost float64 = 28 +const kFourSymbolHistogramCost float64 = 37 + +func populationCostLiteral(histogram *histogramLiteral) float64 { + var data_size uint = histogramDataSizeLiteral() + var count int = 0 + var s [5]uint + var bits float64 = 0.0 + var i uint + if histogram.total_count_ == 0 { + return kOneSymbolHistogramCost + } + + for i = 0; i < data_size; i++ { + if histogram.data_[i] > 0 { + s[count] = i + count++ + if count > 4 { + break + } + } + } + + if count == 1 { + return kOneSymbolHistogramCost + } + + if count == 2 { + return kTwoSymbolHistogramCost + float64(histogram.total_count_) + } + + if count == 3 { + var histo0 uint32 = histogram.data_[s[0]] + var histo1 uint32 = histogram.data_[s[1]] + var histo2 uint32 = histogram.data_[s[2]] + var histomax uint32 = brotli_max_uint32_t(histo0, brotli_max_uint32_t(histo1, histo2)) + return kThreeSymbolHistogramCost + 2*(float64(histo0)+float64(histo1)+float64(histo2)) - float64(histomax) + } + + if count == 4 { + var histo [4]uint32 + var h23 uint32 + var histomax uint32 + for i = 0; i < 4; i++ { + histo[i] = histogram.data_[s[i]] + } + + /* Sort */ + for i = 0; i < 4; i++ { + var j uint + for j = i + 1; j < 4; j++ { + if histo[j] > histo[i] { + var tmp uint32 = histo[j] + histo[j] = histo[i] + histo[i] = tmp + } + } + } + + h23 = histo[2] + histo[3] + histomax = brotli_max_uint32_t(h23, histo[0]) + return kFourSymbolHistogramCost + 3*float64(h23) + 2*(float64(histo[0])+float64(histo[1])) - float64(histomax) + } + { + var max_depth uint = 1 + var depth_histo = [codeLengthCodes]uint32{0} + /* In this loop we compute the entropy of the histogram and simultaneously + build a simplified histogram of the code length codes where we use the + zero repeat code 17, but we don't use the non-zero repeat code 16. */ + + var log2total float64 = fastLog2(histogram.total_count_) + for i = 0; i < data_size; { + if histogram.data_[i] > 0 { + var log2p float64 = log2total - fastLog2(uint(histogram.data_[i])) + /* Compute -log2(P(symbol)) = -log2(count(symbol)/total_count) = + = log2(total_count) - log2(count(symbol)) */ + + var depth uint = uint(log2p + 0.5) + /* Approximate the bit depth by round(-log2(P(symbol))) */ + bits += float64(histogram.data_[i]) * log2p + + if depth > 15 { + depth = 15 + } + + if depth > max_depth { + max_depth = depth + } + + depth_histo[depth]++ + i++ + } else { + var reps uint32 = 1 + /* Compute the run length of zeros and add the appropriate number of 0 + and 17 code length codes to the code length code histogram. */ + + var k uint + for k = i + 1; k < data_size && histogram.data_[k] == 0; k++ { + reps++ + } + + i += uint(reps) + if i == data_size { + /* Don't add any cost for the last zero run, since these are encoded + only implicitly. */ + break + } + + if reps < 3 { + depth_histo[0] += reps + } else { + reps -= 2 + for reps > 0 { + depth_histo[repeatZeroCodeLength]++ + + /* Add the 3 extra bits for the 17 code length code. */ + bits += 3 + + reps >>= 3 + } + } + } + } + + /* Add the estimated encoding cost of the code length code histogram. */ + bits += float64(18 + 2*max_depth) + + /* Add the entropy of the code length code histogram. */ + bits += bitsEntropy(depth_histo[:], codeLengthCodes) + } + + return bits +} + +func populationCostCommand(histogram *histogramCommand) float64 { + var data_size uint = histogramDataSizeCommand() + var count int = 0 + var s [5]uint + var bits float64 = 0.0 + var i uint + if histogram.total_count_ == 0 { + return kOneSymbolHistogramCost + } + + for i = 0; i < data_size; i++ { + if histogram.data_[i] > 0 { + s[count] = i + count++ + if count > 4 { + break + } + } + } + + if count == 1 { + return kOneSymbolHistogramCost + } + + if count == 2 { + return kTwoSymbolHistogramCost + float64(histogram.total_count_) + } + + if count == 3 { + var histo0 uint32 = histogram.data_[s[0]] + var histo1 uint32 = histogram.data_[s[1]] + var histo2 uint32 = histogram.data_[s[2]] + var histomax uint32 = brotli_max_uint32_t(histo0, brotli_max_uint32_t(histo1, histo2)) + return kThreeSymbolHistogramCost + 2*(float64(histo0)+float64(histo1)+float64(histo2)) - float64(histomax) + } + + if count == 4 { + var histo [4]uint32 + var h23 uint32 + var histomax uint32 + for i = 0; i < 4; i++ { + histo[i] = histogram.data_[s[i]] + } + + /* Sort */ + for i = 0; i < 4; i++ { + var j uint + for j = i + 1; j < 4; j++ { + if histo[j] > histo[i] { + var tmp uint32 = histo[j] + histo[j] = histo[i] + histo[i] = tmp + } + } + } + + h23 = histo[2] + histo[3] + histomax = brotli_max_uint32_t(h23, histo[0]) + return kFourSymbolHistogramCost + 3*float64(h23) + 2*(float64(histo[0])+float64(histo[1])) - float64(histomax) + } + { + var max_depth uint = 1 + var depth_histo = [codeLengthCodes]uint32{0} + /* In this loop we compute the entropy of the histogram and simultaneously + build a simplified histogram of the code length codes where we use the + zero repeat code 17, but we don't use the non-zero repeat code 16. */ + + var log2total float64 = fastLog2(histogram.total_count_) + for i = 0; i < data_size; { + if histogram.data_[i] > 0 { + var log2p float64 = log2total - fastLog2(uint(histogram.data_[i])) + /* Compute -log2(P(symbol)) = -log2(count(symbol)/total_count) = + = log2(total_count) - log2(count(symbol)) */ + + var depth uint = uint(log2p + 0.5) + /* Approximate the bit depth by round(-log2(P(symbol))) */ + bits += float64(histogram.data_[i]) * log2p + + if depth > 15 { + depth = 15 + } + + if depth > max_depth { + max_depth = depth + } + + depth_histo[depth]++ + i++ + } else { + var reps uint32 = 1 + /* Compute the run length of zeros and add the appropriate number of 0 + and 17 code length codes to the code length code histogram. */ + + var k uint + for k = i + 1; k < data_size && histogram.data_[k] == 0; k++ { + reps++ + } + + i += uint(reps) + if i == data_size { + /* Don't add any cost for the last zero run, since these are encoded + only implicitly. */ + break + } + + if reps < 3 { + depth_histo[0] += reps + } else { + reps -= 2 + for reps > 0 { + depth_histo[repeatZeroCodeLength]++ + + /* Add the 3 extra bits for the 17 code length code. */ + bits += 3 + + reps >>= 3 + } + } + } + } + + /* Add the estimated encoding cost of the code length code histogram. */ + bits += float64(18 + 2*max_depth) + + /* Add the entropy of the code length code histogram. */ + bits += bitsEntropy(depth_histo[:], codeLengthCodes) + } + + return bits +} + +func populationCostDistance(histogram *histogramDistance) float64 { + var data_size uint = histogramDataSizeDistance() + var count int = 0 + var s [5]uint + var bits float64 = 0.0 + var i uint + if histogram.total_count_ == 0 { + return kOneSymbolHistogramCost + } + + for i = 0; i < data_size; i++ { + if histogram.data_[i] > 0 { + s[count] = i + count++ + if count > 4 { + break + } + } + } + + if count == 1 { + return kOneSymbolHistogramCost + } + + if count == 2 { + return kTwoSymbolHistogramCost + float64(histogram.total_count_) + } + + if count == 3 { + var histo0 uint32 = histogram.data_[s[0]] + var histo1 uint32 = histogram.data_[s[1]] + var histo2 uint32 = histogram.data_[s[2]] + var histomax uint32 = brotli_max_uint32_t(histo0, brotli_max_uint32_t(histo1, histo2)) + return kThreeSymbolHistogramCost + 2*(float64(histo0)+float64(histo1)+float64(histo2)) - float64(histomax) + } + + if count == 4 { + var histo [4]uint32 + var h23 uint32 + var histomax uint32 + for i = 0; i < 4; i++ { + histo[i] = histogram.data_[s[i]] + } + + /* Sort */ + for i = 0; i < 4; i++ { + var j uint + for j = i + 1; j < 4; j++ { + if histo[j] > histo[i] { + var tmp uint32 = histo[j] + histo[j] = histo[i] + histo[i] = tmp + } + } + } + + h23 = histo[2] + histo[3] + histomax = brotli_max_uint32_t(h23, histo[0]) + return kFourSymbolHistogramCost + 3*float64(h23) + 2*(float64(histo[0])+float64(histo[1])) - float64(histomax) + } + { + var max_depth uint = 1 + var depth_histo = [codeLengthCodes]uint32{0} + /* In this loop we compute the entropy of the histogram and simultaneously + build a simplified histogram of the code length codes where we use the + zero repeat code 17, but we don't use the non-zero repeat code 16. */ + + var log2total float64 = fastLog2(histogram.total_count_) + for i = 0; i < data_size; { + if histogram.data_[i] > 0 { + var log2p float64 = log2total - fastLog2(uint(histogram.data_[i])) + /* Compute -log2(P(symbol)) = -log2(count(symbol)/total_count) = + = log2(total_count) - log2(count(symbol)) */ + + var depth uint = uint(log2p + 0.5) + /* Approximate the bit depth by round(-log2(P(symbol))) */ + bits += float64(histogram.data_[i]) * log2p + + if depth > 15 { + depth = 15 + } + + if depth > max_depth { + max_depth = depth + } + + depth_histo[depth]++ + i++ + } else { + var reps uint32 = 1 + /* Compute the run length of zeros and add the appropriate number of 0 + and 17 code length codes to the code length code histogram. */ + + var k uint + for k = i + 1; k < data_size && histogram.data_[k] == 0; k++ { + reps++ + } + + i += uint(reps) + if i == data_size { + /* Don't add any cost for the last zero run, since these are encoded + only implicitly. */ + break + } + + if reps < 3 { + depth_histo[0] += reps + } else { + reps -= 2 + for reps > 0 { + depth_histo[repeatZeroCodeLength]++ + + /* Add the 3 extra bits for the 17 code length code. */ + bits += 3 + + reps >>= 3 + } + } + } + } + + /* Add the estimated encoding cost of the code length code histogram. */ + bits += float64(18 + 2*max_depth) + + /* Add the entropy of the code length code histogram. */ + bits += bitsEntropy(depth_histo[:], codeLengthCodes) + } + + return bits +} diff --git a/vendor/github.com/andybalholm/brotli/bit_reader.go b/vendor/github.com/andybalholm/brotli/bit_reader.go new file mode 100644 index 0000000..fba8687 --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/bit_reader.go @@ -0,0 +1,266 @@ +package brotli + +import "encoding/binary" + +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Bit reading helpers */ + +const shortFillBitWindowRead = (8 >> 1) + +var kBitMask = [33]uint32{ + 0x00000000, + 0x00000001, + 0x00000003, + 0x00000007, + 0x0000000F, + 0x0000001F, + 0x0000003F, + 0x0000007F, + 0x000000FF, + 0x000001FF, + 0x000003FF, + 0x000007FF, + 0x00000FFF, + 0x00001FFF, + 0x00003FFF, + 0x00007FFF, + 0x0000FFFF, + 0x0001FFFF, + 0x0003FFFF, + 0x0007FFFF, + 0x000FFFFF, + 0x001FFFFF, + 0x003FFFFF, + 0x007FFFFF, + 0x00FFFFFF, + 0x01FFFFFF, + 0x03FFFFFF, + 0x07FFFFFF, + 0x0FFFFFFF, + 0x1FFFFFFF, + 0x3FFFFFFF, + 0x7FFFFFFF, + 0xFFFFFFFF, +} + +func bitMask(n uint32) uint32 { + return kBitMask[n] +} + +type bitReader struct { + val_ uint64 + bit_pos_ uint32 + input []byte + input_len uint + byte_pos uint +} + +type bitReaderState struct { + val_ uint64 + bit_pos_ uint32 + input []byte + input_len uint + byte_pos uint +} + +/* Initializes the BrotliBitReader fields. */ + +/* Ensures that accumulator is not empty. + May consume up to sizeof(brotli_reg_t) - 1 bytes of input. + Returns false if data is required but there is no input available. + For BROTLI_ALIGNED_READ this function also prepares bit reader for aligned + reading. */ +func bitReaderSaveState(from *bitReader, to *bitReaderState) { + to.val_ = from.val_ + to.bit_pos_ = from.bit_pos_ + to.input = from.input + to.input_len = from.input_len + to.byte_pos = from.byte_pos +} + +func bitReaderRestoreState(to *bitReader, from *bitReaderState) { + to.val_ = from.val_ + to.bit_pos_ = from.bit_pos_ + to.input = from.input + to.input_len = from.input_len + to.byte_pos = from.byte_pos +} + +func getAvailableBits(br *bitReader) uint32 { + return 64 - br.bit_pos_ +} + +/* Returns amount of unread bytes the bit reader still has buffered from the + BrotliInput, including whole bytes in br->val_. */ +func getRemainingBytes(br *bitReader) uint { + return uint(uint32(br.input_len-br.byte_pos) + (getAvailableBits(br) >> 3)) +} + +/* Checks if there is at least |num| bytes left in the input ring-buffer + (excluding the bits remaining in br->val_). */ +func checkInputAmount(br *bitReader, num uint) bool { + return br.input_len-br.byte_pos >= num +} + +/* Guarantees that there are at least |n_bits| + 1 bits in accumulator. + Precondition: accumulator contains at least 1 bit. + |n_bits| should be in the range [1..24] for regular build. For portable + non-64-bit little-endian build only 16 bits are safe to request. */ +func fillBitWindow(br *bitReader, n_bits uint32) { + if br.bit_pos_ >= 32 { + br.val_ >>= 32 + br.bit_pos_ ^= 32 /* here same as -= 32 because of the if condition */ + br.val_ |= (uint64(binary.LittleEndian.Uint32(br.input[br.byte_pos:]))) << 32 + br.byte_pos += 4 + } +} + +/* Mostly like BrotliFillBitWindow, but guarantees only 16 bits and reads no + more than BROTLI_SHORT_FILL_BIT_WINDOW_READ bytes of input. */ +func fillBitWindow16(br *bitReader) { + fillBitWindow(br, 17) +} + +/* Tries to pull one byte of input to accumulator. + Returns false if there is no input available. */ +func pullByte(br *bitReader) bool { + if br.byte_pos == br.input_len { + return false + } + + br.val_ >>= 8 + br.val_ |= (uint64(br.input[br.byte_pos])) << 56 + br.bit_pos_ -= 8 + br.byte_pos++ + return true +} + +/* Returns currently available bits. + The number of valid bits could be calculated by BrotliGetAvailableBits. */ +func getBitsUnmasked(br *bitReader) uint64 { + return br.val_ >> br.bit_pos_ +} + +/* Like BrotliGetBits, but does not mask the result. + The result contains at least 16 valid bits. */ +func get16BitsUnmasked(br *bitReader) uint32 { + fillBitWindow(br, 16) + return uint32(getBitsUnmasked(br)) +} + +/* Returns the specified number of bits from |br| without advancing bit + position. */ +func getBits(br *bitReader, n_bits uint32) uint32 { + fillBitWindow(br, n_bits) + return uint32(getBitsUnmasked(br)) & bitMask(n_bits) +} + +/* Tries to peek the specified amount of bits. Returns false, if there + is not enough input. */ +func safeGetBits(br *bitReader, n_bits uint32, val *uint32) bool { + for getAvailableBits(br) < n_bits { + if !pullByte(br) { + return false + } + } + + *val = uint32(getBitsUnmasked(br)) & bitMask(n_bits) + return true +} + +/* Advances the bit pos by |n_bits|. */ +func dropBits(br *bitReader, n_bits uint32) { + br.bit_pos_ += n_bits +} + +func bitReaderUnload(br *bitReader) { + var unused_bytes uint32 = getAvailableBits(br) >> 3 + var unused_bits uint32 = unused_bytes << 3 + br.byte_pos -= uint(unused_bytes) + if unused_bits == 64 { + br.val_ = 0 + } else { + br.val_ <<= unused_bits + } + + br.bit_pos_ += unused_bits +} + +/* Reads the specified number of bits from |br| and advances the bit pos. + Precondition: accumulator MUST contain at least |n_bits|. */ +func takeBits(br *bitReader, n_bits uint32, val *uint32) { + *val = uint32(getBitsUnmasked(br)) & bitMask(n_bits) + dropBits(br, n_bits) +} + +/* Reads the specified number of bits from |br| and advances the bit pos. + Assumes that there is enough input to perform BrotliFillBitWindow. */ +func readBits(br *bitReader, n_bits uint32) uint32 { + var val uint32 + fillBitWindow(br, n_bits) + takeBits(br, n_bits, &val) + return val +} + +/* Tries to read the specified amount of bits. Returns false, if there + is not enough input. |n_bits| MUST be positive. */ +func safeReadBits(br *bitReader, n_bits uint32, val *uint32) bool { + for getAvailableBits(br) < n_bits { + if !pullByte(br) { + return false + } + } + + takeBits(br, n_bits, val) + return true +} + +/* Advances the bit reader position to the next byte boundary and verifies + that any skipped bits are set to zero. */ +func bitReaderJumpToByteBoundary(br *bitReader) bool { + var pad_bits_count uint32 = getAvailableBits(br) & 0x7 + var pad_bits uint32 = 0 + if pad_bits_count != 0 { + takeBits(br, pad_bits_count, &pad_bits) + } + + return pad_bits == 0 +} + +/* Copies remaining input bytes stored in the bit reader to the output. Value + |num| may not be larger than BrotliGetRemainingBytes. The bit reader must be + warmed up again after this. */ +func copyBytes(dest []byte, br *bitReader, num uint) { + for getAvailableBits(br) >= 8 && num > 0 { + dest[0] = byte(getBitsUnmasked(br)) + dropBits(br, 8) + dest = dest[1:] + num-- + } + + copy(dest, br.input[br.byte_pos:][:num]) + br.byte_pos += num +} + +func initBitReader(br *bitReader) { + br.val_ = 0 + br.bit_pos_ = 64 +} + +func warmupBitReader(br *bitReader) bool { + /* Fixing alignment after unaligned BrotliFillWindow would result accumulator + overflow. If unalignment is caused by BrotliSafeReadBits, then there is + enough space in accumulator to fix alignment. */ + if getAvailableBits(br) == 0 { + if !pullByte(br) { + return false + } + } + + return true +} diff --git a/vendor/github.com/andybalholm/brotli/block_splitter.go b/vendor/github.com/andybalholm/brotli/block_splitter.go new file mode 100644 index 0000000..978a131 --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/block_splitter.go @@ -0,0 +1,144 @@ +package brotli + +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Block split point selection utilities. */ + +type blockSplit struct { + num_types uint + num_blocks uint + types []byte + lengths []uint32 + types_alloc_size uint + lengths_alloc_size uint +} + +const ( + kMaxLiteralHistograms uint = 100 + kMaxCommandHistograms uint = 50 + kLiteralBlockSwitchCost float64 = 28.1 + kCommandBlockSwitchCost float64 = 13.5 + kDistanceBlockSwitchCost float64 = 14.6 + kLiteralStrideLength uint = 70 + kCommandStrideLength uint = 40 + kSymbolsPerLiteralHistogram uint = 544 + kSymbolsPerCommandHistogram uint = 530 + kSymbolsPerDistanceHistogram uint = 544 + kMinLengthForBlockSplitting uint = 128 + kIterMulForRefining uint = 2 + kMinItersForRefining uint = 100 +) + +func countLiterals(cmds []command) uint { + var total_length uint = 0 + /* Count how many we have. */ + + for i := range cmds { + total_length += uint(cmds[i].insert_len_) + } + + return total_length +} + +func copyLiteralsToByteArray(cmds []command, data []byte, offset uint, mask uint, literals []byte) { + var pos uint = 0 + var from_pos uint = offset & mask + for i := range cmds { + var insert_len uint = uint(cmds[i].insert_len_) + if from_pos+insert_len > mask { + var head_size uint = mask + 1 - from_pos + copy(literals[pos:], data[from_pos:][:head_size]) + from_pos = 0 + pos += head_size + insert_len -= head_size + } + + if insert_len > 0 { + copy(literals[pos:], data[from_pos:][:insert_len]) + pos += insert_len + } + + from_pos = uint((uint32(from_pos+insert_len) + commandCopyLen(&cmds[i])) & uint32(mask)) + } +} + +func myRand(seed *uint32) uint32 { + /* Initial seed should be 7. In this case, loop length is (1 << 29). */ + *seed *= 16807 + + return *seed +} + +func bitCost(count uint) float64 { + if count == 0 { + return -2.0 + } else { + return fastLog2(count) + } +} + +const histogramsPerBatch = 64 + +const clustersPerBatch = 16 + +func initBlockSplit(self *blockSplit) { + self.num_types = 0 + self.num_blocks = 0 + self.types = self.types[:0] + self.lengths = self.lengths[:0] + self.types_alloc_size = 0 + self.lengths_alloc_size = 0 +} + +func splitBlock(cmds []command, data []byte, pos uint, mask uint, params *encoderParams, literal_split *blockSplit, insert_and_copy_split *blockSplit, dist_split *blockSplit) { + { + var literals_count uint = countLiterals(cmds) + var literals []byte = make([]byte, literals_count) + + /* Create a continuous array of literals. */ + copyLiteralsToByteArray(cmds, data, pos, mask, literals) + + /* Create the block split on the array of literals. + Literal histograms have alphabet size 256. */ + splitByteVectorLiteral(literals, literals_count, kSymbolsPerLiteralHistogram, kMaxLiteralHistograms, kLiteralStrideLength, kLiteralBlockSwitchCost, params, literal_split) + + literals = nil + } + { + var insert_and_copy_codes []uint16 = make([]uint16, len(cmds)) + /* Compute prefix codes for commands. */ + + for i := range cmds { + insert_and_copy_codes[i] = cmds[i].cmd_prefix_ + } + + /* Create the block split on the array of command prefixes. */ + splitByteVectorCommand(insert_and_copy_codes, kSymbolsPerCommandHistogram, kMaxCommandHistograms, kCommandStrideLength, kCommandBlockSwitchCost, params, insert_and_copy_split) + + /* TODO: reuse for distances? */ + + insert_and_copy_codes = nil + } + { + var distance_prefixes []uint16 = make([]uint16, len(cmds)) + var j uint = 0 + /* Create a continuous array of distance prefixes. */ + + for i := range cmds { + var cmd *command = &cmds[i] + if commandCopyLen(cmd) != 0 && cmd.cmd_prefix_ >= 128 { + distance_prefixes[j] = cmd.dist_prefix_ & 0x3FF + j++ + } + } + + /* Create the block split on the array of distance prefixes. */ + splitByteVectorDistance(distance_prefixes, j, kSymbolsPerDistanceHistogram, kMaxCommandHistograms, kCommandStrideLength, kDistanceBlockSwitchCost, params, dist_split) + + distance_prefixes = nil + } +} diff --git a/vendor/github.com/andybalholm/brotli/block_splitter_command.go b/vendor/github.com/andybalholm/brotli/block_splitter_command.go new file mode 100644 index 0000000..9dec13e --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/block_splitter_command.go @@ -0,0 +1,434 @@ +package brotli + +import "math" + +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +func initialEntropyCodesCommand(data []uint16, length uint, stride uint, num_histograms uint, histograms []histogramCommand) { + var seed uint32 = 7 + var block_length uint = length / num_histograms + var i uint + clearHistogramsCommand(histograms, num_histograms) + for i = 0; i < num_histograms; i++ { + var pos uint = length * i / num_histograms + if i != 0 { + pos += uint(myRand(&seed) % uint32(block_length)) + } + + if pos+stride >= length { + pos = length - stride - 1 + } + + histogramAddVectorCommand(&histograms[i], data[pos:], stride) + } +} + +func randomSampleCommand(seed *uint32, data []uint16, length uint, stride uint, sample *histogramCommand) { + var pos uint = 0 + if stride >= length { + stride = length + } else { + pos = uint(myRand(seed) % uint32(length-stride+1)) + } + + histogramAddVectorCommand(sample, data[pos:], stride) +} + +func refineEntropyCodesCommand(data []uint16, length uint, stride uint, num_histograms uint, histograms []histogramCommand) { + var iters uint = kIterMulForRefining*length/stride + kMinItersForRefining + var seed uint32 = 7 + var iter uint + iters = ((iters + num_histograms - 1) / num_histograms) * num_histograms + for iter = 0; iter < iters; iter++ { + var sample histogramCommand + histogramClearCommand(&sample) + randomSampleCommand(&seed, data, length, stride, &sample) + histogramAddHistogramCommand(&histograms[iter%num_histograms], &sample) + } +} + +/* Assigns a block id from the range [0, num_histograms) to each data element + in data[0..length) and fills in block_id[0..length) with the assigned values. + Returns the number of blocks, i.e. one plus the number of block switches. */ +func findBlocksCommand(data []uint16, length uint, block_switch_bitcost float64, num_histograms uint, histograms []histogramCommand, insert_cost []float64, cost []float64, switch_signal []byte, block_id []byte) uint { + var data_size uint = histogramDataSizeCommand() + var bitmaplen uint = (num_histograms + 7) >> 3 + var num_blocks uint = 1 + var i uint + var j uint + assert(num_histograms <= 256) + if num_histograms <= 1 { + for i = 0; i < length; i++ { + block_id[i] = 0 + } + + return 1 + } + + for i := 0; i < int(data_size*num_histograms); i++ { + insert_cost[i] = 0 + } + for i = 0; i < num_histograms; i++ { + insert_cost[i] = fastLog2(uint(uint32(histograms[i].total_count_))) + } + + for i = data_size; i != 0; { + i-- + for j = 0; j < num_histograms; j++ { + insert_cost[i*num_histograms+j] = insert_cost[j] - bitCost(uint(histograms[j].data_[i])) + } + } + + for i := 0; i < int(num_histograms); i++ { + cost[i] = 0 + } + for i := 0; i < int(length*bitmaplen); i++ { + switch_signal[i] = 0 + } + + /* After each iteration of this loop, cost[k] will contain the difference + between the minimum cost of arriving at the current byte position using + entropy code k, and the minimum cost of arriving at the current byte + position. This difference is capped at the block switch cost, and if it + reaches block switch cost, it means that when we trace back from the last + position, we need to switch here. */ + for i = 0; i < length; i++ { + var byte_ix uint = i + var ix uint = byte_ix * bitmaplen + var insert_cost_ix uint = uint(data[byte_ix]) * num_histograms + var min_cost float64 = 1e99 + var block_switch_cost float64 = block_switch_bitcost + var k uint + for k = 0; k < num_histograms; k++ { + /* We are coding the symbol in data[byte_ix] with entropy code k. */ + cost[k] += insert_cost[insert_cost_ix+k] + + if cost[k] < min_cost { + min_cost = cost[k] + block_id[byte_ix] = byte(k) + } + } + + /* More blocks for the beginning. */ + if byte_ix < 2000 { + block_switch_cost *= 0.77 + 0.07*float64(byte_ix)/2000 + } + + for k = 0; k < num_histograms; k++ { + cost[k] -= min_cost + if cost[k] >= block_switch_cost { + var mask byte = byte(1 << (k & 7)) + cost[k] = block_switch_cost + assert(k>>3 < bitmaplen) + switch_signal[ix+(k>>3)] |= mask + /* Trace back from the last position and switch at the marked places. */ + } + } + } + { + var byte_ix uint = length - 1 + var ix uint = byte_ix * bitmaplen + var cur_id byte = block_id[byte_ix] + for byte_ix > 0 { + var mask byte = byte(1 << (cur_id & 7)) + assert(uint(cur_id)>>3 < bitmaplen) + byte_ix-- + ix -= bitmaplen + if switch_signal[ix+uint(cur_id>>3)]&mask != 0 { + if cur_id != block_id[byte_ix] { + cur_id = block_id[byte_ix] + num_blocks++ + } + } + + block_id[byte_ix] = cur_id + } + } + + return num_blocks +} + +var remapBlockIdsCommand_kInvalidId uint16 = 256 + +func remapBlockIdsCommand(block_ids []byte, length uint, new_id []uint16, num_histograms uint) uint { + var next_id uint16 = 0 + var i uint + for i = 0; i < num_histograms; i++ { + new_id[i] = remapBlockIdsCommand_kInvalidId + } + + for i = 0; i < length; i++ { + assert(uint(block_ids[i]) < num_histograms) + if new_id[block_ids[i]] == remapBlockIdsCommand_kInvalidId { + new_id[block_ids[i]] = next_id + next_id++ + } + } + + for i = 0; i < length; i++ { + block_ids[i] = byte(new_id[block_ids[i]]) + assert(uint(block_ids[i]) < num_histograms) + } + + assert(uint(next_id) <= num_histograms) + return uint(next_id) +} + +func buildBlockHistogramsCommand(data []uint16, length uint, block_ids []byte, num_histograms uint, histograms []histogramCommand) { + var i uint + clearHistogramsCommand(histograms, num_histograms) + for i = 0; i < length; i++ { + histogramAddCommand(&histograms[block_ids[i]], uint(data[i])) + } +} + +var clusterBlocksCommand_kInvalidIndex uint32 = math.MaxUint32 + +func clusterBlocksCommand(data []uint16, length uint, num_blocks uint, block_ids []byte, split *blockSplit) { + var histogram_symbols []uint32 = make([]uint32, num_blocks) + var block_lengths []uint32 = make([]uint32, num_blocks) + var expected_num_clusters uint = clustersPerBatch * (num_blocks + histogramsPerBatch - 1) / histogramsPerBatch + var all_histograms_size uint = 0 + var all_histograms_capacity uint = expected_num_clusters + var all_histograms []histogramCommand = make([]histogramCommand, all_histograms_capacity) + var cluster_size_size uint = 0 + var cluster_size_capacity uint = expected_num_clusters + var cluster_size []uint32 = make([]uint32, cluster_size_capacity) + var num_clusters uint = 0 + var histograms []histogramCommand = make([]histogramCommand, brotli_min_size_t(num_blocks, histogramsPerBatch)) + var max_num_pairs uint = histogramsPerBatch * histogramsPerBatch / 2 + var pairs_capacity uint = max_num_pairs + 1 + var pairs []histogramPair = make([]histogramPair, pairs_capacity) + var pos uint = 0 + var clusters []uint32 + var num_final_clusters uint + var new_index []uint32 + var i uint + var sizes = [histogramsPerBatch]uint32{0} + var new_clusters = [histogramsPerBatch]uint32{0} + var symbols = [histogramsPerBatch]uint32{0} + var remap = [histogramsPerBatch]uint32{0} + + for i := 0; i < int(num_blocks); i++ { + block_lengths[i] = 0 + } + { + var block_idx uint = 0 + for i = 0; i < length; i++ { + assert(block_idx < num_blocks) + block_lengths[block_idx]++ + if i+1 == length || block_ids[i] != block_ids[i+1] { + block_idx++ + } + } + + assert(block_idx == num_blocks) + } + + for i = 0; i < num_blocks; i += histogramsPerBatch { + var num_to_combine uint = brotli_min_size_t(num_blocks-i, histogramsPerBatch) + var num_new_clusters uint + var j uint + for j = 0; j < num_to_combine; j++ { + var k uint + histogramClearCommand(&histograms[j]) + for k = 0; uint32(k) < block_lengths[i+j]; k++ { + histogramAddCommand(&histograms[j], uint(data[pos])) + pos++ + } + + histograms[j].bit_cost_ = populationCostCommand(&histograms[j]) + new_clusters[j] = uint32(j) + symbols[j] = uint32(j) + sizes[j] = 1 + } + + num_new_clusters = histogramCombineCommand(histograms, sizes[:], symbols[:], new_clusters[:], []histogramPair(pairs), num_to_combine, num_to_combine, histogramsPerBatch, max_num_pairs) + if all_histograms_capacity < (all_histograms_size + num_new_clusters) { + var _new_size uint + if all_histograms_capacity == 0 { + _new_size = all_histograms_size + num_new_clusters + } else { + _new_size = all_histograms_capacity + } + var new_array []histogramCommand + for _new_size < (all_histograms_size + num_new_clusters) { + _new_size *= 2 + } + new_array = make([]histogramCommand, _new_size) + if all_histograms_capacity != 0 { + copy(new_array, all_histograms[:all_histograms_capacity]) + } + + all_histograms = new_array + all_histograms_capacity = _new_size + } + + brotli_ensure_capacity_uint32_t(&cluster_size, &cluster_size_capacity, cluster_size_size+num_new_clusters) + for j = 0; j < num_new_clusters; j++ { + all_histograms[all_histograms_size] = histograms[new_clusters[j]] + all_histograms_size++ + cluster_size[cluster_size_size] = sizes[new_clusters[j]] + cluster_size_size++ + remap[new_clusters[j]] = uint32(j) + } + + for j = 0; j < num_to_combine; j++ { + histogram_symbols[i+j] = uint32(num_clusters) + remap[symbols[j]] + } + + num_clusters += num_new_clusters + assert(num_clusters == cluster_size_size) + assert(num_clusters == all_histograms_size) + } + + histograms = nil + + max_num_pairs = brotli_min_size_t(64*num_clusters, (num_clusters/2)*num_clusters) + if pairs_capacity < max_num_pairs+1 { + pairs = nil + pairs = make([]histogramPair, (max_num_pairs + 1)) + } + + clusters = make([]uint32, num_clusters) + for i = 0; i < num_clusters; i++ { + clusters[i] = uint32(i) + } + + num_final_clusters = histogramCombineCommand(all_histograms, cluster_size, histogram_symbols, clusters, pairs, num_clusters, num_blocks, maxNumberOfBlockTypes, max_num_pairs) + pairs = nil + cluster_size = nil + + new_index = make([]uint32, num_clusters) + for i = 0; i < num_clusters; i++ { + new_index[i] = clusterBlocksCommand_kInvalidIndex + } + pos = 0 + { + var next_index uint32 = 0 + for i = 0; i < num_blocks; i++ { + var histo histogramCommand + var j uint + var best_out uint32 + var best_bits float64 + histogramClearCommand(&histo) + for j = 0; uint32(j) < block_lengths[i]; j++ { + histogramAddCommand(&histo, uint(data[pos])) + pos++ + } + + if i == 0 { + best_out = histogram_symbols[0] + } else { + best_out = histogram_symbols[i-1] + } + best_bits = histogramBitCostDistanceCommand(&histo, &all_histograms[best_out]) + for j = 0; j < num_final_clusters; j++ { + var cur_bits float64 = histogramBitCostDistanceCommand(&histo, &all_histograms[clusters[j]]) + if cur_bits < best_bits { + best_bits = cur_bits + best_out = clusters[j] + } + } + + histogram_symbols[i] = best_out + if new_index[best_out] == clusterBlocksCommand_kInvalidIndex { + new_index[best_out] = next_index + next_index++ + } + } + } + + clusters = nil + all_histograms = nil + brotli_ensure_capacity_uint8_t(&split.types, &split.types_alloc_size, num_blocks) + brotli_ensure_capacity_uint32_t(&split.lengths, &split.lengths_alloc_size, num_blocks) + { + var cur_length uint32 = 0 + var block_idx uint = 0 + var max_type byte = 0 + for i = 0; i < num_blocks; i++ { + cur_length += block_lengths[i] + if i+1 == num_blocks || histogram_symbols[i] != histogram_symbols[i+1] { + var id byte = byte(new_index[histogram_symbols[i]]) + split.types[block_idx] = id + split.lengths[block_idx] = cur_length + max_type = brotli_max_uint8_t(max_type, id) + cur_length = 0 + block_idx++ + } + } + + split.num_blocks = block_idx + split.num_types = uint(max_type) + 1 + } + + new_index = nil + block_lengths = nil + histogram_symbols = nil +} + +func splitByteVectorCommand(data []uint16, literals_per_histogram uint, max_histograms uint, sampling_stride_length uint, block_switch_cost float64, params *encoderParams, split *blockSplit) { + length := uint(len(data)) + var data_size uint = histogramDataSizeCommand() + var num_histograms uint = length/literals_per_histogram + 1 + var histograms []histogramCommand + if num_histograms > max_histograms { + num_histograms = max_histograms + } + + if length == 0 { + split.num_types = 1 + return + } else if length < kMinLengthForBlockSplitting { + brotli_ensure_capacity_uint8_t(&split.types, &split.types_alloc_size, split.num_blocks+1) + brotli_ensure_capacity_uint32_t(&split.lengths, &split.lengths_alloc_size, split.num_blocks+1) + split.num_types = 1 + split.types[split.num_blocks] = 0 + split.lengths[split.num_blocks] = uint32(length) + split.num_blocks++ + return + } + + histograms = make([]histogramCommand, num_histograms) + + /* Find good entropy codes. */ + initialEntropyCodesCommand(data, length, sampling_stride_length, num_histograms, histograms) + + refineEntropyCodesCommand(data, length, sampling_stride_length, num_histograms, histograms) + { + var block_ids []byte = make([]byte, length) + var num_blocks uint = 0 + var bitmaplen uint = (num_histograms + 7) >> 3 + var insert_cost []float64 = make([]float64, (data_size * num_histograms)) + var cost []float64 = make([]float64, num_histograms) + var switch_signal []byte = make([]byte, (length * bitmaplen)) + var new_id []uint16 = make([]uint16, num_histograms) + var iters uint + if params.quality < hqZopflificationQuality { + iters = 3 + } else { + iters = 10 + } + /* Find a good path through literals with the good entropy codes. */ + + var i uint + for i = 0; i < iters; i++ { + num_blocks = findBlocksCommand(data, length, block_switch_cost, num_histograms, histograms, insert_cost, cost, switch_signal, block_ids) + num_histograms = remapBlockIdsCommand(block_ids, length, new_id, num_histograms) + buildBlockHistogramsCommand(data, length, block_ids, num_histograms, histograms) + } + + insert_cost = nil + cost = nil + switch_signal = nil + new_id = nil + histograms = nil + clusterBlocksCommand(data, length, num_blocks, block_ids, split) + block_ids = nil + } +} diff --git a/vendor/github.com/andybalholm/brotli/block_splitter_distance.go b/vendor/github.com/andybalholm/brotli/block_splitter_distance.go new file mode 100644 index 0000000..953530d --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/block_splitter_distance.go @@ -0,0 +1,433 @@ +package brotli + +import "math" + +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +func initialEntropyCodesDistance(data []uint16, length uint, stride uint, num_histograms uint, histograms []histogramDistance) { + var seed uint32 = 7 + var block_length uint = length / num_histograms + var i uint + clearHistogramsDistance(histograms, num_histograms) + for i = 0; i < num_histograms; i++ { + var pos uint = length * i / num_histograms + if i != 0 { + pos += uint(myRand(&seed) % uint32(block_length)) + } + + if pos+stride >= length { + pos = length - stride - 1 + } + + histogramAddVectorDistance(&histograms[i], data[pos:], stride) + } +} + +func randomSampleDistance(seed *uint32, data []uint16, length uint, stride uint, sample *histogramDistance) { + var pos uint = 0 + if stride >= length { + stride = length + } else { + pos = uint(myRand(seed) % uint32(length-stride+1)) + } + + histogramAddVectorDistance(sample, data[pos:], stride) +} + +func refineEntropyCodesDistance(data []uint16, length uint, stride uint, num_histograms uint, histograms []histogramDistance) { + var iters uint = kIterMulForRefining*length/stride + kMinItersForRefining + var seed uint32 = 7 + var iter uint + iters = ((iters + num_histograms - 1) / num_histograms) * num_histograms + for iter = 0; iter < iters; iter++ { + var sample histogramDistance + histogramClearDistance(&sample) + randomSampleDistance(&seed, data, length, stride, &sample) + histogramAddHistogramDistance(&histograms[iter%num_histograms], &sample) + } +} + +/* Assigns a block id from the range [0, num_histograms) to each data element + in data[0..length) and fills in block_id[0..length) with the assigned values. + Returns the number of blocks, i.e. one plus the number of block switches. */ +func findBlocksDistance(data []uint16, length uint, block_switch_bitcost float64, num_histograms uint, histograms []histogramDistance, insert_cost []float64, cost []float64, switch_signal []byte, block_id []byte) uint { + var data_size uint = histogramDataSizeDistance() + var bitmaplen uint = (num_histograms + 7) >> 3 + var num_blocks uint = 1 + var i uint + var j uint + assert(num_histograms <= 256) + if num_histograms <= 1 { + for i = 0; i < length; i++ { + block_id[i] = 0 + } + + return 1 + } + + for i := 0; i < int(data_size*num_histograms); i++ { + insert_cost[i] = 0 + } + for i = 0; i < num_histograms; i++ { + insert_cost[i] = fastLog2(uint(uint32(histograms[i].total_count_))) + } + + for i = data_size; i != 0; { + i-- + for j = 0; j < num_histograms; j++ { + insert_cost[i*num_histograms+j] = insert_cost[j] - bitCost(uint(histograms[j].data_[i])) + } + } + + for i := 0; i < int(num_histograms); i++ { + cost[i] = 0 + } + for i := 0; i < int(length*bitmaplen); i++ { + switch_signal[i] = 0 + } + + /* After each iteration of this loop, cost[k] will contain the difference + between the minimum cost of arriving at the current byte position using + entropy code k, and the minimum cost of arriving at the current byte + position. This difference is capped at the block switch cost, and if it + reaches block switch cost, it means that when we trace back from the last + position, we need to switch here. */ + for i = 0; i < length; i++ { + var byte_ix uint = i + var ix uint = byte_ix * bitmaplen + var insert_cost_ix uint = uint(data[byte_ix]) * num_histograms + var min_cost float64 = 1e99 + var block_switch_cost float64 = block_switch_bitcost + var k uint + for k = 0; k < num_histograms; k++ { + /* We are coding the symbol in data[byte_ix] with entropy code k. */ + cost[k] += insert_cost[insert_cost_ix+k] + + if cost[k] < min_cost { + min_cost = cost[k] + block_id[byte_ix] = byte(k) + } + } + + /* More blocks for the beginning. */ + if byte_ix < 2000 { + block_switch_cost *= 0.77 + 0.07*float64(byte_ix)/2000 + } + + for k = 0; k < num_histograms; k++ { + cost[k] -= min_cost + if cost[k] >= block_switch_cost { + var mask byte = byte(1 << (k & 7)) + cost[k] = block_switch_cost + assert(k>>3 < bitmaplen) + switch_signal[ix+(k>>3)] |= mask + /* Trace back from the last position and switch at the marked places. */ + } + } + } + { + var byte_ix uint = length - 1 + var ix uint = byte_ix * bitmaplen + var cur_id byte = block_id[byte_ix] + for byte_ix > 0 { + var mask byte = byte(1 << (cur_id & 7)) + assert(uint(cur_id)>>3 < bitmaplen) + byte_ix-- + ix -= bitmaplen + if switch_signal[ix+uint(cur_id>>3)]&mask != 0 { + if cur_id != block_id[byte_ix] { + cur_id = block_id[byte_ix] + num_blocks++ + } + } + + block_id[byte_ix] = cur_id + } + } + + return num_blocks +} + +var remapBlockIdsDistance_kInvalidId uint16 = 256 + +func remapBlockIdsDistance(block_ids []byte, length uint, new_id []uint16, num_histograms uint) uint { + var next_id uint16 = 0 + var i uint + for i = 0; i < num_histograms; i++ { + new_id[i] = remapBlockIdsDistance_kInvalidId + } + + for i = 0; i < length; i++ { + assert(uint(block_ids[i]) < num_histograms) + if new_id[block_ids[i]] == remapBlockIdsDistance_kInvalidId { + new_id[block_ids[i]] = next_id + next_id++ + } + } + + for i = 0; i < length; i++ { + block_ids[i] = byte(new_id[block_ids[i]]) + assert(uint(block_ids[i]) < num_histograms) + } + + assert(uint(next_id) <= num_histograms) + return uint(next_id) +} + +func buildBlockHistogramsDistance(data []uint16, length uint, block_ids []byte, num_histograms uint, histograms []histogramDistance) { + var i uint + clearHistogramsDistance(histograms, num_histograms) + for i = 0; i < length; i++ { + histogramAddDistance(&histograms[block_ids[i]], uint(data[i])) + } +} + +var clusterBlocksDistance_kInvalidIndex uint32 = math.MaxUint32 + +func clusterBlocksDistance(data []uint16, length uint, num_blocks uint, block_ids []byte, split *blockSplit) { + var histogram_symbols []uint32 = make([]uint32, num_blocks) + var block_lengths []uint32 = make([]uint32, num_blocks) + var expected_num_clusters uint = clustersPerBatch * (num_blocks + histogramsPerBatch - 1) / histogramsPerBatch + var all_histograms_size uint = 0 + var all_histograms_capacity uint = expected_num_clusters + var all_histograms []histogramDistance = make([]histogramDistance, all_histograms_capacity) + var cluster_size_size uint = 0 + var cluster_size_capacity uint = expected_num_clusters + var cluster_size []uint32 = make([]uint32, cluster_size_capacity) + var num_clusters uint = 0 + var histograms []histogramDistance = make([]histogramDistance, brotli_min_size_t(num_blocks, histogramsPerBatch)) + var max_num_pairs uint = histogramsPerBatch * histogramsPerBatch / 2 + var pairs_capacity uint = max_num_pairs + 1 + var pairs []histogramPair = make([]histogramPair, pairs_capacity) + var pos uint = 0 + var clusters []uint32 + var num_final_clusters uint + var new_index []uint32 + var i uint + var sizes = [histogramsPerBatch]uint32{0} + var new_clusters = [histogramsPerBatch]uint32{0} + var symbols = [histogramsPerBatch]uint32{0} + var remap = [histogramsPerBatch]uint32{0} + + for i := 0; i < int(num_blocks); i++ { + block_lengths[i] = 0 + } + { + var block_idx uint = 0 + for i = 0; i < length; i++ { + assert(block_idx < num_blocks) + block_lengths[block_idx]++ + if i+1 == length || block_ids[i] != block_ids[i+1] { + block_idx++ + } + } + + assert(block_idx == num_blocks) + } + + for i = 0; i < num_blocks; i += histogramsPerBatch { + var num_to_combine uint = brotli_min_size_t(num_blocks-i, histogramsPerBatch) + var num_new_clusters uint + var j uint + for j = 0; j < num_to_combine; j++ { + var k uint + histogramClearDistance(&histograms[j]) + for k = 0; uint32(k) < block_lengths[i+j]; k++ { + histogramAddDistance(&histograms[j], uint(data[pos])) + pos++ + } + + histograms[j].bit_cost_ = populationCostDistance(&histograms[j]) + new_clusters[j] = uint32(j) + symbols[j] = uint32(j) + sizes[j] = 1 + } + + num_new_clusters = histogramCombineDistance(histograms, sizes[:], symbols[:], new_clusters[:], []histogramPair(pairs), num_to_combine, num_to_combine, histogramsPerBatch, max_num_pairs) + if all_histograms_capacity < (all_histograms_size + num_new_clusters) { + var _new_size uint + if all_histograms_capacity == 0 { + _new_size = all_histograms_size + num_new_clusters + } else { + _new_size = all_histograms_capacity + } + var new_array []histogramDistance + for _new_size < (all_histograms_size + num_new_clusters) { + _new_size *= 2 + } + new_array = make([]histogramDistance, _new_size) + if all_histograms_capacity != 0 { + copy(new_array, all_histograms[:all_histograms_capacity]) + } + + all_histograms = new_array + all_histograms_capacity = _new_size + } + + brotli_ensure_capacity_uint32_t(&cluster_size, &cluster_size_capacity, cluster_size_size+num_new_clusters) + for j = 0; j < num_new_clusters; j++ { + all_histograms[all_histograms_size] = histograms[new_clusters[j]] + all_histograms_size++ + cluster_size[cluster_size_size] = sizes[new_clusters[j]] + cluster_size_size++ + remap[new_clusters[j]] = uint32(j) + } + + for j = 0; j < num_to_combine; j++ { + histogram_symbols[i+j] = uint32(num_clusters) + remap[symbols[j]] + } + + num_clusters += num_new_clusters + assert(num_clusters == cluster_size_size) + assert(num_clusters == all_histograms_size) + } + + histograms = nil + + max_num_pairs = brotli_min_size_t(64*num_clusters, (num_clusters/2)*num_clusters) + if pairs_capacity < max_num_pairs+1 { + pairs = nil + pairs = make([]histogramPair, (max_num_pairs + 1)) + } + + clusters = make([]uint32, num_clusters) + for i = 0; i < num_clusters; i++ { + clusters[i] = uint32(i) + } + + num_final_clusters = histogramCombineDistance(all_histograms, cluster_size, histogram_symbols, clusters, pairs, num_clusters, num_blocks, maxNumberOfBlockTypes, max_num_pairs) + pairs = nil + cluster_size = nil + + new_index = make([]uint32, num_clusters) + for i = 0; i < num_clusters; i++ { + new_index[i] = clusterBlocksDistance_kInvalidIndex + } + pos = 0 + { + var next_index uint32 = 0 + for i = 0; i < num_blocks; i++ { + var histo histogramDistance + var j uint + var best_out uint32 + var best_bits float64 + histogramClearDistance(&histo) + for j = 0; uint32(j) < block_lengths[i]; j++ { + histogramAddDistance(&histo, uint(data[pos])) + pos++ + } + + if i == 0 { + best_out = histogram_symbols[0] + } else { + best_out = histogram_symbols[i-1] + } + best_bits = histogramBitCostDistanceDistance(&histo, &all_histograms[best_out]) + for j = 0; j < num_final_clusters; j++ { + var cur_bits float64 = histogramBitCostDistanceDistance(&histo, &all_histograms[clusters[j]]) + if cur_bits < best_bits { + best_bits = cur_bits + best_out = clusters[j] + } + } + + histogram_symbols[i] = best_out + if new_index[best_out] == clusterBlocksDistance_kInvalidIndex { + new_index[best_out] = next_index + next_index++ + } + } + } + + clusters = nil + all_histograms = nil + brotli_ensure_capacity_uint8_t(&split.types, &split.types_alloc_size, num_blocks) + brotli_ensure_capacity_uint32_t(&split.lengths, &split.lengths_alloc_size, num_blocks) + { + var cur_length uint32 = 0 + var block_idx uint = 0 + var max_type byte = 0 + for i = 0; i < num_blocks; i++ { + cur_length += block_lengths[i] + if i+1 == num_blocks || histogram_symbols[i] != histogram_symbols[i+1] { + var id byte = byte(new_index[histogram_symbols[i]]) + split.types[block_idx] = id + split.lengths[block_idx] = cur_length + max_type = brotli_max_uint8_t(max_type, id) + cur_length = 0 + block_idx++ + } + } + + split.num_blocks = block_idx + split.num_types = uint(max_type) + 1 + } + + new_index = nil + block_lengths = nil + histogram_symbols = nil +} + +func splitByteVectorDistance(data []uint16, length uint, literals_per_histogram uint, max_histograms uint, sampling_stride_length uint, block_switch_cost float64, params *encoderParams, split *blockSplit) { + var data_size uint = histogramDataSizeDistance() + var num_histograms uint = length/literals_per_histogram + 1 + var histograms []histogramDistance + if num_histograms > max_histograms { + num_histograms = max_histograms + } + + if length == 0 { + split.num_types = 1 + return + } else if length < kMinLengthForBlockSplitting { + brotli_ensure_capacity_uint8_t(&split.types, &split.types_alloc_size, split.num_blocks+1) + brotli_ensure_capacity_uint32_t(&split.lengths, &split.lengths_alloc_size, split.num_blocks+1) + split.num_types = 1 + split.types[split.num_blocks] = 0 + split.lengths[split.num_blocks] = uint32(length) + split.num_blocks++ + return + } + + histograms = make([]histogramDistance, num_histograms) + + /* Find good entropy codes. */ + initialEntropyCodesDistance(data, length, sampling_stride_length, num_histograms, histograms) + + refineEntropyCodesDistance(data, length, sampling_stride_length, num_histograms, histograms) + { + var block_ids []byte = make([]byte, length) + var num_blocks uint = 0 + var bitmaplen uint = (num_histograms + 7) >> 3 + var insert_cost []float64 = make([]float64, (data_size * num_histograms)) + var cost []float64 = make([]float64, num_histograms) + var switch_signal []byte = make([]byte, (length * bitmaplen)) + var new_id []uint16 = make([]uint16, num_histograms) + var iters uint + if params.quality < hqZopflificationQuality { + iters = 3 + } else { + iters = 10 + } + /* Find a good path through literals with the good entropy codes. */ + + var i uint + for i = 0; i < iters; i++ { + num_blocks = findBlocksDistance(data, length, block_switch_cost, num_histograms, histograms, insert_cost, cost, switch_signal, block_ids) + num_histograms = remapBlockIdsDistance(block_ids, length, new_id, num_histograms) + buildBlockHistogramsDistance(data, length, block_ids, num_histograms, histograms) + } + + insert_cost = nil + cost = nil + switch_signal = nil + new_id = nil + histograms = nil + clusterBlocksDistance(data, length, num_blocks, block_ids, split) + block_ids = nil + } +} diff --git a/vendor/github.com/andybalholm/brotli/block_splitter_literal.go b/vendor/github.com/andybalholm/brotli/block_splitter_literal.go new file mode 100644 index 0000000..1c895cf --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/block_splitter_literal.go @@ -0,0 +1,433 @@ +package brotli + +import "math" + +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +func initialEntropyCodesLiteral(data []byte, length uint, stride uint, num_histograms uint, histograms []histogramLiteral) { + var seed uint32 = 7 + var block_length uint = length / num_histograms + var i uint + clearHistogramsLiteral(histograms, num_histograms) + for i = 0; i < num_histograms; i++ { + var pos uint = length * i / num_histograms + if i != 0 { + pos += uint(myRand(&seed) % uint32(block_length)) + } + + if pos+stride >= length { + pos = length - stride - 1 + } + + histogramAddVectorLiteral(&histograms[i], data[pos:], stride) + } +} + +func randomSampleLiteral(seed *uint32, data []byte, length uint, stride uint, sample *histogramLiteral) { + var pos uint = 0 + if stride >= length { + stride = length + } else { + pos = uint(myRand(seed) % uint32(length-stride+1)) + } + + histogramAddVectorLiteral(sample, data[pos:], stride) +} + +func refineEntropyCodesLiteral(data []byte, length uint, stride uint, num_histograms uint, histograms []histogramLiteral) { + var iters uint = kIterMulForRefining*length/stride + kMinItersForRefining + var seed uint32 = 7 + var iter uint + iters = ((iters + num_histograms - 1) / num_histograms) * num_histograms + for iter = 0; iter < iters; iter++ { + var sample histogramLiteral + histogramClearLiteral(&sample) + randomSampleLiteral(&seed, data, length, stride, &sample) + histogramAddHistogramLiteral(&histograms[iter%num_histograms], &sample) + } +} + +/* Assigns a block id from the range [0, num_histograms) to each data element + in data[0..length) and fills in block_id[0..length) with the assigned values. + Returns the number of blocks, i.e. one plus the number of block switches. */ +func findBlocksLiteral(data []byte, length uint, block_switch_bitcost float64, num_histograms uint, histograms []histogramLiteral, insert_cost []float64, cost []float64, switch_signal []byte, block_id []byte) uint { + var data_size uint = histogramDataSizeLiteral() + var bitmaplen uint = (num_histograms + 7) >> 3 + var num_blocks uint = 1 + var i uint + var j uint + assert(num_histograms <= 256) + if num_histograms <= 1 { + for i = 0; i < length; i++ { + block_id[i] = 0 + } + + return 1 + } + + for i := 0; i < int(data_size*num_histograms); i++ { + insert_cost[i] = 0 + } + for i = 0; i < num_histograms; i++ { + insert_cost[i] = fastLog2(uint(uint32(histograms[i].total_count_))) + } + + for i = data_size; i != 0; { + i-- + for j = 0; j < num_histograms; j++ { + insert_cost[i*num_histograms+j] = insert_cost[j] - bitCost(uint(histograms[j].data_[i])) + } + } + + for i := 0; i < int(num_histograms); i++ { + cost[i] = 0 + } + for i := 0; i < int(length*bitmaplen); i++ { + switch_signal[i] = 0 + } + + /* After each iteration of this loop, cost[k] will contain the difference + between the minimum cost of arriving at the current byte position using + entropy code k, and the minimum cost of arriving at the current byte + position. This difference is capped at the block switch cost, and if it + reaches block switch cost, it means that when we trace back from the last + position, we need to switch here. */ + for i = 0; i < length; i++ { + var byte_ix uint = i + var ix uint = byte_ix * bitmaplen + var insert_cost_ix uint = uint(data[byte_ix]) * num_histograms + var min_cost float64 = 1e99 + var block_switch_cost float64 = block_switch_bitcost + var k uint + for k = 0; k < num_histograms; k++ { + /* We are coding the symbol in data[byte_ix] with entropy code k. */ + cost[k] += insert_cost[insert_cost_ix+k] + + if cost[k] < min_cost { + min_cost = cost[k] + block_id[byte_ix] = byte(k) + } + } + + /* More blocks for the beginning. */ + if byte_ix < 2000 { + block_switch_cost *= 0.77 + 0.07*float64(byte_ix)/2000 + } + + for k = 0; k < num_histograms; k++ { + cost[k] -= min_cost + if cost[k] >= block_switch_cost { + var mask byte = byte(1 << (k & 7)) + cost[k] = block_switch_cost + assert(k>>3 < bitmaplen) + switch_signal[ix+(k>>3)] |= mask + /* Trace back from the last position and switch at the marked places. */ + } + } + } + { + var byte_ix uint = length - 1 + var ix uint = byte_ix * bitmaplen + var cur_id byte = block_id[byte_ix] + for byte_ix > 0 { + var mask byte = byte(1 << (cur_id & 7)) + assert(uint(cur_id)>>3 < bitmaplen) + byte_ix-- + ix -= bitmaplen + if switch_signal[ix+uint(cur_id>>3)]&mask != 0 { + if cur_id != block_id[byte_ix] { + cur_id = block_id[byte_ix] + num_blocks++ + } + } + + block_id[byte_ix] = cur_id + } + } + + return num_blocks +} + +var remapBlockIdsLiteral_kInvalidId uint16 = 256 + +func remapBlockIdsLiteral(block_ids []byte, length uint, new_id []uint16, num_histograms uint) uint { + var next_id uint16 = 0 + var i uint + for i = 0; i < num_histograms; i++ { + new_id[i] = remapBlockIdsLiteral_kInvalidId + } + + for i = 0; i < length; i++ { + assert(uint(block_ids[i]) < num_histograms) + if new_id[block_ids[i]] == remapBlockIdsLiteral_kInvalidId { + new_id[block_ids[i]] = next_id + next_id++ + } + } + + for i = 0; i < length; i++ { + block_ids[i] = byte(new_id[block_ids[i]]) + assert(uint(block_ids[i]) < num_histograms) + } + + assert(uint(next_id) <= num_histograms) + return uint(next_id) +} + +func buildBlockHistogramsLiteral(data []byte, length uint, block_ids []byte, num_histograms uint, histograms []histogramLiteral) { + var i uint + clearHistogramsLiteral(histograms, num_histograms) + for i = 0; i < length; i++ { + histogramAddLiteral(&histograms[block_ids[i]], uint(data[i])) + } +} + +var clusterBlocksLiteral_kInvalidIndex uint32 = math.MaxUint32 + +func clusterBlocksLiteral(data []byte, length uint, num_blocks uint, block_ids []byte, split *blockSplit) { + var histogram_symbols []uint32 = make([]uint32, num_blocks) + var block_lengths []uint32 = make([]uint32, num_blocks) + var expected_num_clusters uint = clustersPerBatch * (num_blocks + histogramsPerBatch - 1) / histogramsPerBatch + var all_histograms_size uint = 0 + var all_histograms_capacity uint = expected_num_clusters + var all_histograms []histogramLiteral = make([]histogramLiteral, all_histograms_capacity) + var cluster_size_size uint = 0 + var cluster_size_capacity uint = expected_num_clusters + var cluster_size []uint32 = make([]uint32, cluster_size_capacity) + var num_clusters uint = 0 + var histograms []histogramLiteral = make([]histogramLiteral, brotli_min_size_t(num_blocks, histogramsPerBatch)) + var max_num_pairs uint = histogramsPerBatch * histogramsPerBatch / 2 + var pairs_capacity uint = max_num_pairs + 1 + var pairs []histogramPair = make([]histogramPair, pairs_capacity) + var pos uint = 0 + var clusters []uint32 + var num_final_clusters uint + var new_index []uint32 + var i uint + var sizes = [histogramsPerBatch]uint32{0} + var new_clusters = [histogramsPerBatch]uint32{0} + var symbols = [histogramsPerBatch]uint32{0} + var remap = [histogramsPerBatch]uint32{0} + + for i := 0; i < int(num_blocks); i++ { + block_lengths[i] = 0 + } + { + var block_idx uint = 0 + for i = 0; i < length; i++ { + assert(block_idx < num_blocks) + block_lengths[block_idx]++ + if i+1 == length || block_ids[i] != block_ids[i+1] { + block_idx++ + } + } + + assert(block_idx == num_blocks) + } + + for i = 0; i < num_blocks; i += histogramsPerBatch { + var num_to_combine uint = brotli_min_size_t(num_blocks-i, histogramsPerBatch) + var num_new_clusters uint + var j uint + for j = 0; j < num_to_combine; j++ { + var k uint + histogramClearLiteral(&histograms[j]) + for k = 0; uint32(k) < block_lengths[i+j]; k++ { + histogramAddLiteral(&histograms[j], uint(data[pos])) + pos++ + } + + histograms[j].bit_cost_ = populationCostLiteral(&histograms[j]) + new_clusters[j] = uint32(j) + symbols[j] = uint32(j) + sizes[j] = 1 + } + + num_new_clusters = histogramCombineLiteral(histograms, sizes[:], symbols[:], new_clusters[:], []histogramPair(pairs), num_to_combine, num_to_combine, histogramsPerBatch, max_num_pairs) + if all_histograms_capacity < (all_histograms_size + num_new_clusters) { + var _new_size uint + if all_histograms_capacity == 0 { + _new_size = all_histograms_size + num_new_clusters + } else { + _new_size = all_histograms_capacity + } + var new_array []histogramLiteral + for _new_size < (all_histograms_size + num_new_clusters) { + _new_size *= 2 + } + new_array = make([]histogramLiteral, _new_size) + if all_histograms_capacity != 0 { + copy(new_array, all_histograms[:all_histograms_capacity]) + } + + all_histograms = new_array + all_histograms_capacity = _new_size + } + + brotli_ensure_capacity_uint32_t(&cluster_size, &cluster_size_capacity, cluster_size_size+num_new_clusters) + for j = 0; j < num_new_clusters; j++ { + all_histograms[all_histograms_size] = histograms[new_clusters[j]] + all_histograms_size++ + cluster_size[cluster_size_size] = sizes[new_clusters[j]] + cluster_size_size++ + remap[new_clusters[j]] = uint32(j) + } + + for j = 0; j < num_to_combine; j++ { + histogram_symbols[i+j] = uint32(num_clusters) + remap[symbols[j]] + } + + num_clusters += num_new_clusters + assert(num_clusters == cluster_size_size) + assert(num_clusters == all_histograms_size) + } + + histograms = nil + + max_num_pairs = brotli_min_size_t(64*num_clusters, (num_clusters/2)*num_clusters) + if pairs_capacity < max_num_pairs+1 { + pairs = nil + pairs = make([]histogramPair, (max_num_pairs + 1)) + } + + clusters = make([]uint32, num_clusters) + for i = 0; i < num_clusters; i++ { + clusters[i] = uint32(i) + } + + num_final_clusters = histogramCombineLiteral(all_histograms, cluster_size, histogram_symbols, clusters, pairs, num_clusters, num_blocks, maxNumberOfBlockTypes, max_num_pairs) + pairs = nil + cluster_size = nil + + new_index = make([]uint32, num_clusters) + for i = 0; i < num_clusters; i++ { + new_index[i] = clusterBlocksLiteral_kInvalidIndex + } + pos = 0 + { + var next_index uint32 = 0 + for i = 0; i < num_blocks; i++ { + var histo histogramLiteral + var j uint + var best_out uint32 + var best_bits float64 + histogramClearLiteral(&histo) + for j = 0; uint32(j) < block_lengths[i]; j++ { + histogramAddLiteral(&histo, uint(data[pos])) + pos++ + } + + if i == 0 { + best_out = histogram_symbols[0] + } else { + best_out = histogram_symbols[i-1] + } + best_bits = histogramBitCostDistanceLiteral(&histo, &all_histograms[best_out]) + for j = 0; j < num_final_clusters; j++ { + var cur_bits float64 = histogramBitCostDistanceLiteral(&histo, &all_histograms[clusters[j]]) + if cur_bits < best_bits { + best_bits = cur_bits + best_out = clusters[j] + } + } + + histogram_symbols[i] = best_out + if new_index[best_out] == clusterBlocksLiteral_kInvalidIndex { + new_index[best_out] = next_index + next_index++ + } + } + } + + clusters = nil + all_histograms = nil + brotli_ensure_capacity_uint8_t(&split.types, &split.types_alloc_size, num_blocks) + brotli_ensure_capacity_uint32_t(&split.lengths, &split.lengths_alloc_size, num_blocks) + { + var cur_length uint32 = 0 + var block_idx uint = 0 + var max_type byte = 0 + for i = 0; i < num_blocks; i++ { + cur_length += block_lengths[i] + if i+1 == num_blocks || histogram_symbols[i] != histogram_symbols[i+1] { + var id byte = byte(new_index[histogram_symbols[i]]) + split.types[block_idx] = id + split.lengths[block_idx] = cur_length + max_type = brotli_max_uint8_t(max_type, id) + cur_length = 0 + block_idx++ + } + } + + split.num_blocks = block_idx + split.num_types = uint(max_type) + 1 + } + + new_index = nil + block_lengths = nil + histogram_symbols = nil +} + +func splitByteVectorLiteral(data []byte, length uint, literals_per_histogram uint, max_histograms uint, sampling_stride_length uint, block_switch_cost float64, params *encoderParams, split *blockSplit) { + var data_size uint = histogramDataSizeLiteral() + var num_histograms uint = length/literals_per_histogram + 1 + var histograms []histogramLiteral + if num_histograms > max_histograms { + num_histograms = max_histograms + } + + if length == 0 { + split.num_types = 1 + return + } else if length < kMinLengthForBlockSplitting { + brotli_ensure_capacity_uint8_t(&split.types, &split.types_alloc_size, split.num_blocks+1) + brotli_ensure_capacity_uint32_t(&split.lengths, &split.lengths_alloc_size, split.num_blocks+1) + split.num_types = 1 + split.types[split.num_blocks] = 0 + split.lengths[split.num_blocks] = uint32(length) + split.num_blocks++ + return + } + + histograms = make([]histogramLiteral, num_histograms) + + /* Find good entropy codes. */ + initialEntropyCodesLiteral(data, length, sampling_stride_length, num_histograms, histograms) + + refineEntropyCodesLiteral(data, length, sampling_stride_length, num_histograms, histograms) + { + var block_ids []byte = make([]byte, length) + var num_blocks uint = 0 + var bitmaplen uint = (num_histograms + 7) >> 3 + var insert_cost []float64 = make([]float64, (data_size * num_histograms)) + var cost []float64 = make([]float64, num_histograms) + var switch_signal []byte = make([]byte, (length * bitmaplen)) + var new_id []uint16 = make([]uint16, num_histograms) + var iters uint + if params.quality < hqZopflificationQuality { + iters = 3 + } else { + iters = 10 + } + /* Find a good path through literals with the good entropy codes. */ + + var i uint + for i = 0; i < iters; i++ { + num_blocks = findBlocksLiteral(data, length, block_switch_cost, num_histograms, histograms, insert_cost, cost, switch_signal, block_ids) + num_histograms = remapBlockIdsLiteral(block_ids, length, new_id, num_histograms) + buildBlockHistogramsLiteral(data, length, block_ids, num_histograms, histograms) + } + + insert_cost = nil + cost = nil + switch_signal = nil + new_id = nil + histograms = nil + clusterBlocksLiteral(data, length, num_blocks, block_ids, split) + block_ids = nil + } +} diff --git a/vendor/github.com/andybalholm/brotli/brotli_bit_stream.go b/vendor/github.com/andybalholm/brotli/brotli_bit_stream.go new file mode 100644 index 0000000..7acfb18 --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/brotli_bit_stream.go @@ -0,0 +1,1300 @@ +package brotli + +import ( + "math" + "sync" +) + +const maxHuffmanTreeSize = (2*numCommandSymbols + 1) + +/* The maximum size of Huffman dictionary for distances assuming that + NPOSTFIX = 0 and NDIRECT = 0. */ +const maxSimpleDistanceAlphabetSize = 140 + +/* Represents the range of values belonging to a prefix code: + [offset, offset + 2^nbits) */ +type prefixCodeRange struct { + offset uint32 + nbits uint32 +} + +var kBlockLengthPrefixCode = [numBlockLenSymbols]prefixCodeRange{ + prefixCodeRange{1, 2}, + prefixCodeRange{5, 2}, + prefixCodeRange{9, 2}, + prefixCodeRange{13, 2}, + prefixCodeRange{17, 3}, + prefixCodeRange{25, 3}, + prefixCodeRange{33, 3}, + prefixCodeRange{41, 3}, + prefixCodeRange{49, 4}, + prefixCodeRange{65, 4}, + prefixCodeRange{81, 4}, + prefixCodeRange{97, 4}, + prefixCodeRange{113, 5}, + prefixCodeRange{145, 5}, + prefixCodeRange{177, 5}, + prefixCodeRange{209, 5}, + prefixCodeRange{241, 6}, + prefixCodeRange{305, 6}, + prefixCodeRange{369, 7}, + prefixCodeRange{497, 8}, + prefixCodeRange{753, 9}, + prefixCodeRange{1265, 10}, + prefixCodeRange{2289, 11}, + prefixCodeRange{4337, 12}, + prefixCodeRange{8433, 13}, + prefixCodeRange{16625, 24}, +} + +func blockLengthPrefixCode(len uint32) uint32 { + var code uint32 + if len >= 177 { + if len >= 753 { + code = 20 + } else { + code = 14 + } + } else if len >= 41 { + code = 7 + } else { + code = 0 + } + for code < (numBlockLenSymbols-1) && len >= kBlockLengthPrefixCode[code+1].offset { + code++ + } + return code +} + +func getBlockLengthPrefixCode(len uint32, code *uint, n_extra *uint32, extra *uint32) { + *code = uint(blockLengthPrefixCode(uint32(len))) + *n_extra = kBlockLengthPrefixCode[*code].nbits + *extra = len - kBlockLengthPrefixCode[*code].offset +} + +type blockTypeCodeCalculator struct { + last_type uint + second_last_type uint +} + +func initBlockTypeCodeCalculator(self *blockTypeCodeCalculator) { + self.last_type = 1 + self.second_last_type = 0 +} + +func nextBlockTypeCode(calculator *blockTypeCodeCalculator, type_ byte) uint { + var type_code uint + if uint(type_) == calculator.last_type+1 { + type_code = 1 + } else if uint(type_) == calculator.second_last_type { + type_code = 0 + } else { + type_code = uint(type_) + 2 + } + calculator.second_last_type = calculator.last_type + calculator.last_type = uint(type_) + return type_code +} + +/* |nibblesbits| represents the 2 bits to encode MNIBBLES (0-3) + REQUIRES: length > 0 + REQUIRES: length <= (1 << 24) */ +func encodeMlen(length uint, bits *uint64, numbits *uint, nibblesbits *uint64) { + var lg uint + if length == 1 { + lg = 1 + } else { + lg = uint(log2FloorNonZero(uint(uint32(length-1)))) + 1 + } + var tmp uint + if lg < 16 { + tmp = 16 + } else { + tmp = (lg + 3) + } + var mnibbles uint = tmp / 4 + assert(length > 0) + assert(length <= 1<<24) + assert(lg <= 24) + *nibblesbits = uint64(mnibbles) - 4 + *numbits = mnibbles * 4 + *bits = uint64(length) - 1 +} + +func storeCommandExtra(cmd *command, storage_ix *uint, storage []byte) { + var copylen_code uint32 = commandCopyLenCode(cmd) + var inscode uint16 = getInsertLengthCode(uint(cmd.insert_len_)) + var copycode uint16 = getCopyLengthCode(uint(copylen_code)) + var insnumextra uint32 = getInsertExtra(inscode) + var insextraval uint64 = uint64(cmd.insert_len_) - uint64(getInsertBase(inscode)) + var copyextraval uint64 = uint64(copylen_code) - uint64(getCopyBase(copycode)) + var bits uint64 = copyextraval< 0 + REQUIRES: length <= (1 << 24) */ +func storeCompressedMetaBlockHeader(is_final_block bool, length uint, storage_ix *uint, storage []byte) { + var lenbits uint64 + var nlenbits uint + var nibblesbits uint64 + var is_final uint64 + if is_final_block { + is_final = 1 + } else { + is_final = 0 + } + + /* Write ISLAST bit. */ + writeBits(1, is_final, storage_ix, storage) + + /* Write ISEMPTY bit. */ + if is_final_block { + writeBits(1, 0, storage_ix, storage) + } + + encodeMlen(length, &lenbits, &nlenbits, &nibblesbits) + writeBits(2, nibblesbits, storage_ix, storage) + writeBits(nlenbits, lenbits, storage_ix, storage) + + if !is_final_block { + /* Write ISUNCOMPRESSED bit. */ + writeBits(1, 0, storage_ix, storage) + } +} + +/* Stores the uncompressed meta-block header. + REQUIRES: length > 0 + REQUIRES: length <= (1 << 24) */ +func storeUncompressedMetaBlockHeader(length uint, storage_ix *uint, storage []byte) { + var lenbits uint64 + var nlenbits uint + var nibblesbits uint64 + + /* Write ISLAST bit. + Uncompressed block cannot be the last one, so set to 0. */ + writeBits(1, 0, storage_ix, storage) + + encodeMlen(length, &lenbits, &nlenbits, &nibblesbits) + writeBits(2, nibblesbits, storage_ix, storage) + writeBits(nlenbits, lenbits, storage_ix, storage) + + /* Write ISUNCOMPRESSED bit. */ + writeBits(1, 1, storage_ix, storage) +} + +var storeHuffmanTreeOfHuffmanTreeToBitMask_kStorageOrder = [codeLengthCodes]byte{1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15} + +var storeHuffmanTreeOfHuffmanTreeToBitMask_kHuffmanBitLengthHuffmanCodeSymbols = [6]byte{0, 7, 3, 2, 1, 15} +var storeHuffmanTreeOfHuffmanTreeToBitMask_kHuffmanBitLengthHuffmanCodeBitLengths = [6]byte{2, 4, 3, 2, 2, 4} + +func storeHuffmanTreeOfHuffmanTreeToBitMask(num_codes int, code_length_bitdepth []byte, storage_ix *uint, storage []byte) { + var skip_some uint = 0 + var codes_to_store uint = codeLengthCodes + /* The bit lengths of the Huffman code over the code length alphabet + are compressed with the following static Huffman code: + Symbol Code + ------ ---- + 0 00 + 1 1110 + 2 110 + 3 01 + 4 10 + 5 1111 */ + + /* Throw away trailing zeros: */ + if num_codes > 1 { + for ; codes_to_store > 0; codes_to_store-- { + if code_length_bitdepth[storeHuffmanTreeOfHuffmanTreeToBitMask_kStorageOrder[codes_to_store-1]] != 0 { + break + } + } + } + + if code_length_bitdepth[storeHuffmanTreeOfHuffmanTreeToBitMask_kStorageOrder[0]] == 0 && code_length_bitdepth[storeHuffmanTreeOfHuffmanTreeToBitMask_kStorageOrder[1]] == 0 { + skip_some = 2 /* skips two. */ + if code_length_bitdepth[storeHuffmanTreeOfHuffmanTreeToBitMask_kStorageOrder[2]] == 0 { + skip_some = 3 /* skips three. */ + } + } + + writeBits(2, uint64(skip_some), storage_ix, storage) + { + var i uint + for i = skip_some; i < codes_to_store; i++ { + var l uint = uint(code_length_bitdepth[storeHuffmanTreeOfHuffmanTreeToBitMask_kStorageOrder[i]]) + writeBits(uint(storeHuffmanTreeOfHuffmanTreeToBitMask_kHuffmanBitLengthHuffmanCodeBitLengths[l]), uint64(storeHuffmanTreeOfHuffmanTreeToBitMask_kHuffmanBitLengthHuffmanCodeSymbols[l]), storage_ix, storage) + } + } +} + +func storeHuffmanTreeToBitMask(huffman_tree_size uint, huffman_tree []byte, huffman_tree_extra_bits []byte, code_length_bitdepth []byte, code_length_bitdepth_symbols []uint16, storage_ix *uint, storage []byte) { + var i uint + for i = 0; i < huffman_tree_size; i++ { + var ix uint = uint(huffman_tree[i]) + writeBits(uint(code_length_bitdepth[ix]), uint64(code_length_bitdepth_symbols[ix]), storage_ix, storage) + + /* Extra bits */ + switch ix { + case repeatPreviousCodeLength: + writeBits(2, uint64(huffman_tree_extra_bits[i]), storage_ix, storage) + + case repeatZeroCodeLength: + writeBits(3, uint64(huffman_tree_extra_bits[i]), storage_ix, storage) + } + } +} + +func storeSimpleHuffmanTree(depths []byte, symbols []uint, num_symbols uint, max_bits uint, storage_ix *uint, storage []byte) { + /* value of 1 indicates a simple Huffman code */ + writeBits(2, 1, storage_ix, storage) + + writeBits(2, uint64(num_symbols)-1, storage_ix, storage) /* NSYM - 1 */ + { + /* Sort */ + var i uint + for i = 0; i < num_symbols; i++ { + var j uint + for j = i + 1; j < num_symbols; j++ { + if depths[symbols[j]] < depths[symbols[i]] { + var tmp uint = symbols[j] + symbols[j] = symbols[i] + symbols[i] = tmp + } + } + } + } + + if num_symbols == 2 { + writeBits(max_bits, uint64(symbols[0]), storage_ix, storage) + writeBits(max_bits, uint64(symbols[1]), storage_ix, storage) + } else if num_symbols == 3 { + writeBits(max_bits, uint64(symbols[0]), storage_ix, storage) + writeBits(max_bits, uint64(symbols[1]), storage_ix, storage) + writeBits(max_bits, uint64(symbols[2]), storage_ix, storage) + } else { + writeBits(max_bits, uint64(symbols[0]), storage_ix, storage) + writeBits(max_bits, uint64(symbols[1]), storage_ix, storage) + writeBits(max_bits, uint64(symbols[2]), storage_ix, storage) + writeBits(max_bits, uint64(symbols[3]), storage_ix, storage) + + /* tree-select */ + var tmp int + if depths[symbols[0]] == 1 { + tmp = 1 + } else { + tmp = 0 + } + writeBits(1, uint64(tmp), storage_ix, storage) + } +} + +/* num = alphabet size + depths = symbol depths */ +func storeHuffmanTree(depths []byte, num uint, tree []huffmanTree, storage_ix *uint, storage []byte) { + var huffman_tree [numCommandSymbols]byte + var huffman_tree_extra_bits [numCommandSymbols]byte + var huffman_tree_size uint = 0 + var code_length_bitdepth = [codeLengthCodes]byte{0} + var code_length_bitdepth_symbols [codeLengthCodes]uint16 + var huffman_tree_histogram = [codeLengthCodes]uint32{0} + var i uint + var num_codes int = 0 + /* Write the Huffman tree into the brotli-representation. + The command alphabet is the largest, so this allocation will fit all + alphabets. */ + + var code uint = 0 + + assert(num <= numCommandSymbols) + + writeHuffmanTree(depths, num, &huffman_tree_size, huffman_tree[:], huffman_tree_extra_bits[:]) + + /* Calculate the statistics of the Huffman tree in brotli-representation. */ + for i = 0; i < huffman_tree_size; i++ { + huffman_tree_histogram[huffman_tree[i]]++ + } + + for i = 0; i < codeLengthCodes; i++ { + if huffman_tree_histogram[i] != 0 { + if num_codes == 0 { + code = i + num_codes = 1 + } else if num_codes == 1 { + num_codes = 2 + break + } + } + } + + /* Calculate another Huffman tree to use for compressing both the + earlier Huffman tree with. */ + createHuffmanTree(huffman_tree_histogram[:], codeLengthCodes, 5, tree, code_length_bitdepth[:]) + + convertBitDepthsToSymbols(code_length_bitdepth[:], codeLengthCodes, code_length_bitdepth_symbols[:]) + + /* Now, we have all the data, let's start storing it */ + storeHuffmanTreeOfHuffmanTreeToBitMask(num_codes, code_length_bitdepth[:], storage_ix, storage) + + if num_codes == 1 { + code_length_bitdepth[code] = 0 + } + + /* Store the real Huffman tree now. */ + storeHuffmanTreeToBitMask(huffman_tree_size, huffman_tree[:], huffman_tree_extra_bits[:], code_length_bitdepth[:], code_length_bitdepth_symbols[:], storage_ix, storage) +} + +/* Builds a Huffman tree from histogram[0:length] into depth[0:length] and + bits[0:length] and stores the encoded tree to the bit stream. */ +func buildAndStoreHuffmanTree(histogram []uint32, histogram_length uint, alphabet_size uint, tree []huffmanTree, depth []byte, bits []uint16, storage_ix *uint, storage []byte) { + var count uint = 0 + var s4 = [4]uint{0} + var i uint + var max_bits uint = 0 + for i = 0; i < histogram_length; i++ { + if histogram[i] != 0 { + if count < 4 { + s4[count] = i + } else if count > 4 { + break + } + + count++ + } + } + { + var max_bits_counter uint = alphabet_size - 1 + for max_bits_counter != 0 { + max_bits_counter >>= 1 + max_bits++ + } + } + + if count <= 1 { + writeBits(4, 1, storage_ix, storage) + writeBits(max_bits, uint64(s4[0]), storage_ix, storage) + depth[s4[0]] = 0 + bits[s4[0]] = 0 + return + } + + for i := 0; i < int(histogram_length); i++ { + depth[i] = 0 + } + createHuffmanTree(histogram, histogram_length, 15, tree, depth) + convertBitDepthsToSymbols(depth, histogram_length, bits) + + if count <= 4 { + storeSimpleHuffmanTree(depth, s4[:], count, max_bits, storage_ix, storage) + } else { + storeHuffmanTree(depth, histogram_length, tree, storage_ix, storage) + } +} + +func sortHuffmanTree1(v0 huffmanTree, v1 huffmanTree) bool { + return v0.total_count_ < v1.total_count_ +} + +var huffmanTreePool sync.Pool + +func buildAndStoreHuffmanTreeFast(histogram []uint32, histogram_total uint, max_bits uint, depth []byte, bits []uint16, storage_ix *uint, storage []byte) { + var count uint = 0 + var symbols = [4]uint{0} + var length uint = 0 + var total uint = histogram_total + for total != 0 { + if histogram[length] != 0 { + if count < 4 { + symbols[count] = length + } + + count++ + total -= uint(histogram[length]) + } + + length++ + } + + if count <= 1 { + writeBits(4, 1, storage_ix, storage) + writeBits(max_bits, uint64(symbols[0]), storage_ix, storage) + depth[symbols[0]] = 0 + bits[symbols[0]] = 0 + return + } + + for i := 0; i < int(length); i++ { + depth[i] = 0 + } + { + var max_tree_size uint = 2*length + 1 + tree, _ := huffmanTreePool.Get().(*[]huffmanTree) + if tree == nil || cap(*tree) < int(max_tree_size) { + tmp := make([]huffmanTree, max_tree_size) + tree = &tmp + } else { + *tree = (*tree)[:max_tree_size] + } + var count_limit uint32 + for count_limit = 1; ; count_limit *= 2 { + var node int = 0 + var l uint + for l = length; l != 0; { + l-- + if histogram[l] != 0 { + if histogram[l] >= count_limit { + initHuffmanTree(&(*tree)[node:][0], histogram[l], -1, int16(l)) + } else { + initHuffmanTree(&(*tree)[node:][0], count_limit, -1, int16(l)) + } + + node++ + } + } + { + var n int = node + /* Points to the next leaf node. */ /* Points to the next non-leaf node. */ + var sentinel huffmanTree + var i int = 0 + var j int = n + 1 + var k int + + sortHuffmanTreeItems(*tree, uint(n), huffmanTreeComparator(sortHuffmanTree1)) + + /* The nodes are: + [0, n): the sorted leaf nodes that we start with. + [n]: we add a sentinel here. + [n + 1, 2n): new parent nodes are added here, starting from + (n+1). These are naturally in ascending order. + [2n]: we add a sentinel at the end as well. + There will be (2n+1) elements at the end. */ + initHuffmanTree(&sentinel, math.MaxUint32, -1, -1) + + (*tree)[node] = sentinel + node++ + (*tree)[node] = sentinel + node++ + + for k = n - 1; k > 0; k-- { + var left int + var right int + if (*tree)[i].total_count_ <= (*tree)[j].total_count_ { + left = i + i++ + } else { + left = j + j++ + } + + if (*tree)[i].total_count_ <= (*tree)[j].total_count_ { + right = i + i++ + } else { + right = j + j++ + } + + /* The sentinel node becomes the parent node. */ + (*tree)[node-1].total_count_ = (*tree)[left].total_count_ + (*tree)[right].total_count_ + + (*tree)[node-1].index_left_ = int16(left) + (*tree)[node-1].index_right_or_value_ = int16(right) + + /* Add back the last sentinel node. */ + (*tree)[node] = sentinel + node++ + } + + if setDepth(2*n-1, *tree, depth, 14) { + /* We need to pack the Huffman tree in 14 bits. If this was not + successful, add fake entities to the lowest values and retry. */ + break + } + } + } + + huffmanTreePool.Put(tree) + } + + convertBitDepthsToSymbols(depth, length, bits) + if count <= 4 { + var i uint + + /* value of 1 indicates a simple Huffman code */ + writeBits(2, 1, storage_ix, storage) + + writeBits(2, uint64(count)-1, storage_ix, storage) /* NSYM - 1 */ + + /* Sort */ + for i = 0; i < count; i++ { + var j uint + for j = i + 1; j < count; j++ { + if depth[symbols[j]] < depth[symbols[i]] { + var tmp uint = symbols[j] + symbols[j] = symbols[i] + symbols[i] = tmp + } + } + } + + if count == 2 { + writeBits(max_bits, uint64(symbols[0]), storage_ix, storage) + writeBits(max_bits, uint64(symbols[1]), storage_ix, storage) + } else if count == 3 { + writeBits(max_bits, uint64(symbols[0]), storage_ix, storage) + writeBits(max_bits, uint64(symbols[1]), storage_ix, storage) + writeBits(max_bits, uint64(symbols[2]), storage_ix, storage) + } else { + writeBits(max_bits, uint64(symbols[0]), storage_ix, storage) + writeBits(max_bits, uint64(symbols[1]), storage_ix, storage) + writeBits(max_bits, uint64(symbols[2]), storage_ix, storage) + writeBits(max_bits, uint64(symbols[3]), storage_ix, storage) + + /* tree-select */ + var tmp int + if depth[symbols[0]] == 1 { + tmp = 1 + } else { + tmp = 0 + } + writeBits(1, uint64(tmp), storage_ix, storage) + } + } else { + var previous_value byte = 8 + var i uint + + /* Complex Huffman Tree */ + storeStaticCodeLengthCode(storage_ix, storage) + + /* Actual RLE coding. */ + for i = 0; i < length; { + var value byte = depth[i] + var reps uint = 1 + var k uint + for k = i + 1; k < length && depth[k] == value; k++ { + reps++ + } + + i += reps + if value == 0 { + writeBits(uint(kZeroRepsDepth[reps]), kZeroRepsBits[reps], storage_ix, storage) + } else { + if previous_value != value { + writeBits(uint(kCodeLengthDepth[value]), uint64(kCodeLengthBits[value]), storage_ix, storage) + reps-- + } + + if reps < 3 { + for reps != 0 { + reps-- + writeBits(uint(kCodeLengthDepth[value]), uint64(kCodeLengthBits[value]), storage_ix, storage) + } + } else { + reps -= 3 + writeBits(uint(kNonZeroRepsDepth[reps]), kNonZeroRepsBits[reps], storage_ix, storage) + } + + previous_value = value + } + } + } +} + +func indexOf(v []byte, v_size uint, value byte) uint { + var i uint = 0 + for ; i < v_size; i++ { + if v[i] == value { + return i + } + } + + return i +} + +func moveToFront(v []byte, index uint) { + var value byte = v[index] + var i uint + for i = index; i != 0; i-- { + v[i] = v[i-1] + } + + v[0] = value +} + +func moveToFrontTransform(v_in []uint32, v_size uint, v_out []uint32) { + var i uint + var mtf [256]byte + var max_value uint32 + if v_size == 0 { + return + } + + max_value = v_in[0] + for i = 1; i < v_size; i++ { + if v_in[i] > max_value { + max_value = v_in[i] + } + } + + assert(max_value < 256) + for i = 0; uint32(i) <= max_value; i++ { + mtf[i] = byte(i) + } + { + var mtf_size uint = uint(max_value + 1) + for i = 0; i < v_size; i++ { + var index uint = indexOf(mtf[:], mtf_size, byte(v_in[i])) + assert(index < mtf_size) + v_out[i] = uint32(index) + moveToFront(mtf[:], index) + } + } +} + +/* Finds runs of zeros in v[0..in_size) and replaces them with a prefix code of + the run length plus extra bits (lower 9 bits is the prefix code and the rest + are the extra bits). Non-zero values in v[] are shifted by + *max_length_prefix. Will not create prefix codes bigger than the initial + value of *max_run_length_prefix. The prefix code of run length L is simply + Log2Floor(L) and the number of extra bits is the same as the prefix code. */ +func runLengthCodeZeros(in_size uint, v []uint32, out_size *uint, max_run_length_prefix *uint32) { + var max_reps uint32 = 0 + var i uint + var max_prefix uint32 + for i = 0; i < in_size; { + var reps uint32 = 0 + for ; i < in_size && v[i] != 0; i++ { + } + for ; i < in_size && v[i] == 0; i++ { + reps++ + } + + max_reps = brotli_max_uint32_t(reps, max_reps) + } + + if max_reps > 0 { + max_prefix = log2FloorNonZero(uint(max_reps)) + } else { + max_prefix = 0 + } + max_prefix = brotli_min_uint32_t(max_prefix, *max_run_length_prefix) + *max_run_length_prefix = max_prefix + *out_size = 0 + for i = 0; i < in_size; { + assert(*out_size <= i) + if v[i] != 0 { + v[*out_size] = v[i] + *max_run_length_prefix + i++ + (*out_size)++ + } else { + var reps uint32 = 1 + var k uint + for k = i + 1; k < in_size && v[k] == 0; k++ { + reps++ + } + + i += uint(reps) + for reps != 0 { + if reps < 2< 0) + writeSingleBit(use_rle, storage_ix, storage) + if use_rle { + writeBits(4, uint64(max_run_length_prefix)-1, storage_ix, storage) + } + } + + buildAndStoreHuffmanTree(histogram[:], uint(uint32(num_clusters)+max_run_length_prefix), uint(uint32(num_clusters)+max_run_length_prefix), tree, depths[:], bits[:], storage_ix, storage) + for i = 0; i < num_rle_symbols; i++ { + var rle_symbol uint32 = rle_symbols[i] & encodeContextMap_kSymbolMask + var extra_bits_val uint32 = rle_symbols[i] >> symbolBits + writeBits(uint(depths[rle_symbol]), uint64(bits[rle_symbol]), storage_ix, storage) + if rle_symbol > 0 && rle_symbol <= max_run_length_prefix { + writeBits(uint(rle_symbol), uint64(extra_bits_val), storage_ix, storage) + } + } + + writeBits(1, 1, storage_ix, storage) /* use move-to-front */ + rle_symbols = nil +} + +/* Stores the block switch command with index block_ix to the bit stream. */ +func storeBlockSwitch(code *blockSplitCode, block_len uint32, block_type byte, is_first_block bool, storage_ix *uint, storage []byte) { + var typecode uint = nextBlockTypeCode(&code.type_code_calculator, block_type) + var lencode uint + var len_nextra uint32 + var len_extra uint32 + if !is_first_block { + writeBits(uint(code.type_depths[typecode]), uint64(code.type_bits[typecode]), storage_ix, storage) + } + + getBlockLengthPrefixCode(block_len, &lencode, &len_nextra, &len_extra) + + writeBits(uint(code.length_depths[lencode]), uint64(code.length_bits[lencode]), storage_ix, storage) + writeBits(uint(len_nextra), uint64(len_extra), storage_ix, storage) +} + +/* Builds a BlockSplitCode data structure from the block split given by the + vector of block types and block lengths and stores it to the bit stream. */ +func buildAndStoreBlockSplitCode(types []byte, lengths []uint32, num_blocks uint, num_types uint, tree []huffmanTree, code *blockSplitCode, storage_ix *uint, storage []byte) { + var type_histo [maxBlockTypeSymbols]uint32 + var length_histo [numBlockLenSymbols]uint32 + var i uint + var type_code_calculator blockTypeCodeCalculator + for i := 0; i < int(num_types+2); i++ { + type_histo[i] = 0 + } + length_histo = [numBlockLenSymbols]uint32{} + initBlockTypeCodeCalculator(&type_code_calculator) + for i = 0; i < num_blocks; i++ { + var type_code uint = nextBlockTypeCode(&type_code_calculator, types[i]) + if i != 0 { + type_histo[type_code]++ + } + length_histo[blockLengthPrefixCode(lengths[i])]++ + } + + storeVarLenUint8(num_types-1, storage_ix, storage) + if num_types > 1 { /* TODO: else? could StoreBlockSwitch occur? */ + buildAndStoreHuffmanTree(type_histo[0:], num_types+2, num_types+2, tree, code.type_depths[0:], code.type_bits[0:], storage_ix, storage) + buildAndStoreHuffmanTree(length_histo[0:], numBlockLenSymbols, numBlockLenSymbols, tree, code.length_depths[0:], code.length_bits[0:], storage_ix, storage) + storeBlockSwitch(code, lengths[0], types[0], true, storage_ix, storage) + } +} + +/* Stores a context map where the histogram type is always the block type. */ +func storeTrivialContextMap(num_types uint, context_bits uint, tree []huffmanTree, storage_ix *uint, storage []byte) { + storeVarLenUint8(num_types-1, storage_ix, storage) + if num_types > 1 { + var repeat_code uint = context_bits - 1 + var repeat_bits uint = (1 << repeat_code) - 1 + var alphabet_size uint = num_types + repeat_code + var histogram [maxContextMapSymbols]uint32 + var depths [maxContextMapSymbols]byte + var bits [maxContextMapSymbols]uint16 + var i uint + for i := 0; i < int(alphabet_size); i++ { + histogram[i] = 0 + } + + /* Write RLEMAX. */ + writeBits(1, 1, storage_ix, storage) + + writeBits(4, uint64(repeat_code)-1, storage_ix, storage) + histogram[repeat_code] = uint32(num_types) + histogram[0] = 1 + for i = context_bits; i < alphabet_size; i++ { + histogram[i] = 1 + } + + buildAndStoreHuffmanTree(histogram[:], alphabet_size, alphabet_size, tree, depths[:], bits[:], storage_ix, storage) + for i = 0; i < num_types; i++ { + var tmp uint + if i == 0 { + tmp = 0 + } else { + tmp = i + context_bits - 1 + } + var code uint = tmp + writeBits(uint(depths[code]), uint64(bits[code]), storage_ix, storage) + writeBits(uint(depths[repeat_code]), uint64(bits[repeat_code]), storage_ix, storage) + writeBits(repeat_code, uint64(repeat_bits), storage_ix, storage) + } + + /* Write IMTF (inverse-move-to-front) bit. */ + writeBits(1, 1, storage_ix, storage) + } +} + +/* Manages the encoding of one block category (literal, command or distance). */ +type blockEncoder struct { + histogram_length_ uint + num_block_types_ uint + block_types_ []byte + block_lengths_ []uint32 + num_blocks_ uint + block_split_code_ blockSplitCode + block_ix_ uint + block_len_ uint + entropy_ix_ uint + depths_ []byte + bits_ []uint16 +} + +var blockEncoderPool sync.Pool + +func getBlockEncoder(histogram_length uint, num_block_types uint, block_types []byte, block_lengths []uint32, num_blocks uint) *blockEncoder { + self, _ := blockEncoderPool.Get().(*blockEncoder) + + if self != nil { + self.block_ix_ = 0 + self.entropy_ix_ = 0 + self.depths_ = self.depths_[:0] + self.bits_ = self.bits_[:0] + } else { + self = &blockEncoder{} + } + + self.histogram_length_ = histogram_length + self.num_block_types_ = num_block_types + self.block_types_ = block_types + self.block_lengths_ = block_lengths + self.num_blocks_ = num_blocks + initBlockTypeCodeCalculator(&self.block_split_code_.type_code_calculator) + if num_blocks == 0 { + self.block_len_ = 0 + } else { + self.block_len_ = uint(block_lengths[0]) + } + + return self +} + +func cleanupBlockEncoder(self *blockEncoder) { + blockEncoderPool.Put(self) +} + +/* Creates entropy codes of block lengths and block types and stores them + to the bit stream. */ +func buildAndStoreBlockSwitchEntropyCodes(self *blockEncoder, tree []huffmanTree, storage_ix *uint, storage []byte) { + buildAndStoreBlockSplitCode(self.block_types_, self.block_lengths_, self.num_blocks_, self.num_block_types_, tree, &self.block_split_code_, storage_ix, storage) +} + +/* Stores the next symbol with the entropy code of the current block type. + Updates the block type and block length at block boundaries. */ +func storeSymbol(self *blockEncoder, symbol uint, storage_ix *uint, storage []byte) { + if self.block_len_ == 0 { + self.block_ix_++ + var block_ix uint = self.block_ix_ + var block_len uint32 = self.block_lengths_[block_ix] + var block_type byte = self.block_types_[block_ix] + self.block_len_ = uint(block_len) + self.entropy_ix_ = uint(block_type) * self.histogram_length_ + storeBlockSwitch(&self.block_split_code_, block_len, block_type, false, storage_ix, storage) + } + + self.block_len_-- + { + var ix uint = self.entropy_ix_ + symbol + writeBits(uint(self.depths_[ix]), uint64(self.bits_[ix]), storage_ix, storage) + } +} + +/* Stores the next symbol with the entropy code of the current block type and + context value. + Updates the block type and block length at block boundaries. */ +func storeSymbolWithContext(self *blockEncoder, symbol uint, context uint, context_map []uint32, storage_ix *uint, storage []byte, context_bits uint) { + if self.block_len_ == 0 { + self.block_ix_++ + var block_ix uint = self.block_ix_ + var block_len uint32 = self.block_lengths_[block_ix] + var block_type byte = self.block_types_[block_ix] + self.block_len_ = uint(block_len) + self.entropy_ix_ = uint(block_type) << context_bits + storeBlockSwitch(&self.block_split_code_, block_len, block_type, false, storage_ix, storage) + } + + self.block_len_-- + { + var histo_ix uint = uint(context_map[self.entropy_ix_+context]) + var ix uint = histo_ix*self.histogram_length_ + symbol + writeBits(uint(self.depths_[ix]), uint64(self.bits_[ix]), storage_ix, storage) + } +} + +func buildAndStoreEntropyCodesLiteral(self *blockEncoder, histograms []histogramLiteral, histograms_size uint, alphabet_size uint, tree []huffmanTree, storage_ix *uint, storage []byte) { + var table_size uint = histograms_size * self.histogram_length_ + if cap(self.depths_) < int(table_size) { + self.depths_ = make([]byte, table_size) + } else { + self.depths_ = self.depths_[:table_size] + } + if cap(self.bits_) < int(table_size) { + self.bits_ = make([]uint16, table_size) + } else { + self.bits_ = self.bits_[:table_size] + } + { + var i uint + for i = 0; i < histograms_size; i++ { + var ix uint = i * self.histogram_length_ + buildAndStoreHuffmanTree(histograms[i].data_[0:], self.histogram_length_, alphabet_size, tree, self.depths_[ix:], self.bits_[ix:], storage_ix, storage) + } + } +} + +func buildAndStoreEntropyCodesCommand(self *blockEncoder, histograms []histogramCommand, histograms_size uint, alphabet_size uint, tree []huffmanTree, storage_ix *uint, storage []byte) { + var table_size uint = histograms_size * self.histogram_length_ + if cap(self.depths_) < int(table_size) { + self.depths_ = make([]byte, table_size) + } else { + self.depths_ = self.depths_[:table_size] + } + if cap(self.bits_) < int(table_size) { + self.bits_ = make([]uint16, table_size) + } else { + self.bits_ = self.bits_[:table_size] + } + { + var i uint + for i = 0; i < histograms_size; i++ { + var ix uint = i * self.histogram_length_ + buildAndStoreHuffmanTree(histograms[i].data_[0:], self.histogram_length_, alphabet_size, tree, self.depths_[ix:], self.bits_[ix:], storage_ix, storage) + } + } +} + +func buildAndStoreEntropyCodesDistance(self *blockEncoder, histograms []histogramDistance, histograms_size uint, alphabet_size uint, tree []huffmanTree, storage_ix *uint, storage []byte) { + var table_size uint = histograms_size * self.histogram_length_ + if cap(self.depths_) < int(table_size) { + self.depths_ = make([]byte, table_size) + } else { + self.depths_ = self.depths_[:table_size] + } + if cap(self.bits_) < int(table_size) { + self.bits_ = make([]uint16, table_size) + } else { + self.bits_ = self.bits_[:table_size] + } + { + var i uint + for i = 0; i < histograms_size; i++ { + var ix uint = i * self.histogram_length_ + buildAndStoreHuffmanTree(histograms[i].data_[0:], self.histogram_length_, alphabet_size, tree, self.depths_[ix:], self.bits_[ix:], storage_ix, storage) + } + } +} + +func jumpToByteBoundary(storage_ix *uint, storage []byte) { + *storage_ix = (*storage_ix + 7) &^ 7 + storage[*storage_ix>>3] = 0 +} + +func storeMetaBlock(input []byte, start_pos uint, length uint, mask uint, prev_byte byte, prev_byte2 byte, is_last bool, params *encoderParams, literal_context_mode int, commands []command, mb *metaBlockSplit, storage_ix *uint, storage []byte) { + var pos uint = start_pos + var i uint + var num_distance_symbols uint32 = params.dist.alphabet_size + var num_effective_distance_symbols uint32 = num_distance_symbols + var tree []huffmanTree + var literal_context_lut contextLUT = getContextLUT(literal_context_mode) + var dist *distanceParams = ¶ms.dist + if params.large_window && num_effective_distance_symbols > numHistogramDistanceSymbols { + num_effective_distance_symbols = numHistogramDistanceSymbols + } + + storeCompressedMetaBlockHeader(is_last, length, storage_ix, storage) + + tree = make([]huffmanTree, maxHuffmanTreeSize) + literal_enc := getBlockEncoder(numLiteralSymbols, mb.literal_split.num_types, mb.literal_split.types, mb.literal_split.lengths, mb.literal_split.num_blocks) + command_enc := getBlockEncoder(numCommandSymbols, mb.command_split.num_types, mb.command_split.types, mb.command_split.lengths, mb.command_split.num_blocks) + distance_enc := getBlockEncoder(uint(num_effective_distance_symbols), mb.distance_split.num_types, mb.distance_split.types, mb.distance_split.lengths, mb.distance_split.num_blocks) + + buildAndStoreBlockSwitchEntropyCodes(literal_enc, tree, storage_ix, storage) + buildAndStoreBlockSwitchEntropyCodes(command_enc, tree, storage_ix, storage) + buildAndStoreBlockSwitchEntropyCodes(distance_enc, tree, storage_ix, storage) + + writeBits(2, uint64(dist.distance_postfix_bits), storage_ix, storage) + writeBits(4, uint64(dist.num_direct_distance_codes)>>dist.distance_postfix_bits, storage_ix, storage) + for i = 0; i < mb.literal_split.num_types; i++ { + writeBits(2, uint64(literal_context_mode), storage_ix, storage) + } + + if mb.literal_context_map_size == 0 { + storeTrivialContextMap(mb.literal_histograms_size, literalContextBits, tree, storage_ix, storage) + } else { + encodeContextMap(mb.literal_context_map, mb.literal_context_map_size, mb.literal_histograms_size, tree, storage_ix, storage) + } + + if mb.distance_context_map_size == 0 { + storeTrivialContextMap(mb.distance_histograms_size, distanceContextBits, tree, storage_ix, storage) + } else { + encodeContextMap(mb.distance_context_map, mb.distance_context_map_size, mb.distance_histograms_size, tree, storage_ix, storage) + } + + buildAndStoreEntropyCodesLiteral(literal_enc, mb.literal_histograms, mb.literal_histograms_size, numLiteralSymbols, tree, storage_ix, storage) + buildAndStoreEntropyCodesCommand(command_enc, mb.command_histograms, mb.command_histograms_size, numCommandSymbols, tree, storage_ix, storage) + buildAndStoreEntropyCodesDistance(distance_enc, mb.distance_histograms, mb.distance_histograms_size, uint(num_distance_symbols), tree, storage_ix, storage) + tree = nil + + for _, cmd := range commands { + var cmd_code uint = uint(cmd.cmd_prefix_) + storeSymbol(command_enc, cmd_code, storage_ix, storage) + storeCommandExtra(&cmd, storage_ix, storage) + if mb.literal_context_map_size == 0 { + var j uint + for j = uint(cmd.insert_len_); j != 0; j-- { + storeSymbol(literal_enc, uint(input[pos&mask]), storage_ix, storage) + pos++ + } + } else { + var j uint + for j = uint(cmd.insert_len_); j != 0; j-- { + var context uint = uint(getContext(prev_byte, prev_byte2, literal_context_lut)) + var literal byte = input[pos&mask] + storeSymbolWithContext(literal_enc, uint(literal), context, mb.literal_context_map, storage_ix, storage, literalContextBits) + prev_byte2 = prev_byte + prev_byte = literal + pos++ + } + } + + pos += uint(commandCopyLen(&cmd)) + if commandCopyLen(&cmd) != 0 { + prev_byte2 = input[(pos-2)&mask] + prev_byte = input[(pos-1)&mask] + if cmd.cmd_prefix_ >= 128 { + var dist_code uint = uint(cmd.dist_prefix_) & 0x3FF + var distnumextra uint32 = uint32(cmd.dist_prefix_) >> 10 + var distextra uint64 = uint64(cmd.dist_extra_) + if mb.distance_context_map_size == 0 { + storeSymbol(distance_enc, dist_code, storage_ix, storage) + } else { + var context uint = uint(commandDistanceContext(&cmd)) + storeSymbolWithContext(distance_enc, dist_code, context, mb.distance_context_map, storage_ix, storage, distanceContextBits) + } + + writeBits(uint(distnumextra), distextra, storage_ix, storage) + } + } + } + + cleanupBlockEncoder(distance_enc) + cleanupBlockEncoder(command_enc) + cleanupBlockEncoder(literal_enc) + if is_last { + jumpToByteBoundary(storage_ix, storage) + } +} + +func buildHistograms(input []byte, start_pos uint, mask uint, commands []command, lit_histo *histogramLiteral, cmd_histo *histogramCommand, dist_histo *histogramDistance) { + var pos uint = start_pos + for _, cmd := range commands { + var j uint + histogramAddCommand(cmd_histo, uint(cmd.cmd_prefix_)) + for j = uint(cmd.insert_len_); j != 0; j-- { + histogramAddLiteral(lit_histo, uint(input[pos&mask])) + pos++ + } + + pos += uint(commandCopyLen(&cmd)) + if commandCopyLen(&cmd) != 0 && cmd.cmd_prefix_ >= 128 { + histogramAddDistance(dist_histo, uint(cmd.dist_prefix_)&0x3FF) + } + } +} + +func storeDataWithHuffmanCodes(input []byte, start_pos uint, mask uint, commands []command, lit_depth []byte, lit_bits []uint16, cmd_depth []byte, cmd_bits []uint16, dist_depth []byte, dist_bits []uint16, storage_ix *uint, storage []byte) { + var pos uint = start_pos + for _, cmd := range commands { + var cmd_code uint = uint(cmd.cmd_prefix_) + var j uint + writeBits(uint(cmd_depth[cmd_code]), uint64(cmd_bits[cmd_code]), storage_ix, storage) + storeCommandExtra(&cmd, storage_ix, storage) + for j = uint(cmd.insert_len_); j != 0; j-- { + var literal byte = input[pos&mask] + writeBits(uint(lit_depth[literal]), uint64(lit_bits[literal]), storage_ix, storage) + pos++ + } + + pos += uint(commandCopyLen(&cmd)) + if commandCopyLen(&cmd) != 0 && cmd.cmd_prefix_ >= 128 { + var dist_code uint = uint(cmd.dist_prefix_) & 0x3FF + var distnumextra uint32 = uint32(cmd.dist_prefix_) >> 10 + var distextra uint32 = cmd.dist_extra_ + writeBits(uint(dist_depth[dist_code]), uint64(dist_bits[dist_code]), storage_ix, storage) + writeBits(uint(distnumextra), uint64(distextra), storage_ix, storage) + } + } +} + +func storeMetaBlockTrivial(input []byte, start_pos uint, length uint, mask uint, is_last bool, params *encoderParams, commands []command, storage_ix *uint, storage []byte) { + var lit_histo histogramLiteral + var cmd_histo histogramCommand + var dist_histo histogramDistance + var lit_depth [numLiteralSymbols]byte + var lit_bits [numLiteralSymbols]uint16 + var cmd_depth [numCommandSymbols]byte + var cmd_bits [numCommandSymbols]uint16 + var dist_depth [maxSimpleDistanceAlphabetSize]byte + var dist_bits [maxSimpleDistanceAlphabetSize]uint16 + var tree []huffmanTree + var num_distance_symbols uint32 = params.dist.alphabet_size + + storeCompressedMetaBlockHeader(is_last, length, storage_ix, storage) + + histogramClearLiteral(&lit_histo) + histogramClearCommand(&cmd_histo) + histogramClearDistance(&dist_histo) + + buildHistograms(input, start_pos, mask, commands, &lit_histo, &cmd_histo, &dist_histo) + + writeBits(13, 0, storage_ix, storage) + + tree = make([]huffmanTree, maxHuffmanTreeSize) + buildAndStoreHuffmanTree(lit_histo.data_[:], numLiteralSymbols, numLiteralSymbols, tree, lit_depth[:], lit_bits[:], storage_ix, storage) + buildAndStoreHuffmanTree(cmd_histo.data_[:], numCommandSymbols, numCommandSymbols, tree, cmd_depth[:], cmd_bits[:], storage_ix, storage) + buildAndStoreHuffmanTree(dist_histo.data_[:], maxSimpleDistanceAlphabetSize, uint(num_distance_symbols), tree, dist_depth[:], dist_bits[:], storage_ix, storage) + tree = nil + storeDataWithHuffmanCodes(input, start_pos, mask, commands, lit_depth[:], lit_bits[:], cmd_depth[:], cmd_bits[:], dist_depth[:], dist_bits[:], storage_ix, storage) + if is_last { + jumpToByteBoundary(storage_ix, storage) + } +} + +func storeMetaBlockFast(input []byte, start_pos uint, length uint, mask uint, is_last bool, params *encoderParams, commands []command, storage_ix *uint, storage []byte) { + var num_distance_symbols uint32 = params.dist.alphabet_size + var distance_alphabet_bits uint32 = log2FloorNonZero(uint(num_distance_symbols-1)) + 1 + + storeCompressedMetaBlockHeader(is_last, length, storage_ix, storage) + + writeBits(13, 0, storage_ix, storage) + + if len(commands) <= 128 { + var histogram = [numLiteralSymbols]uint32{0} + var pos uint = start_pos + var num_literals uint = 0 + var lit_depth [numLiteralSymbols]byte + var lit_bits [numLiteralSymbols]uint16 + for _, cmd := range commands { + var j uint + for j = uint(cmd.insert_len_); j != 0; j-- { + histogram[input[pos&mask]]++ + pos++ + } + + num_literals += uint(cmd.insert_len_) + pos += uint(commandCopyLen(&cmd)) + } + + buildAndStoreHuffmanTreeFast(histogram[:], num_literals, /* max_bits = */ + 8, lit_depth[:], lit_bits[:], storage_ix, storage) + + storeStaticCommandHuffmanTree(storage_ix, storage) + storeStaticDistanceHuffmanTree(storage_ix, storage) + storeDataWithHuffmanCodes(input, start_pos, mask, commands, lit_depth[:], lit_bits[:], kStaticCommandCodeDepth[:], kStaticCommandCodeBits[:], kStaticDistanceCodeDepth[:], kStaticDistanceCodeBits[:], storage_ix, storage) + } else { + var lit_histo histogramLiteral + var cmd_histo histogramCommand + var dist_histo histogramDistance + var lit_depth [numLiteralSymbols]byte + var lit_bits [numLiteralSymbols]uint16 + var cmd_depth [numCommandSymbols]byte + var cmd_bits [numCommandSymbols]uint16 + var dist_depth [maxSimpleDistanceAlphabetSize]byte + var dist_bits [maxSimpleDistanceAlphabetSize]uint16 + histogramClearLiteral(&lit_histo) + histogramClearCommand(&cmd_histo) + histogramClearDistance(&dist_histo) + buildHistograms(input, start_pos, mask, commands, &lit_histo, &cmd_histo, &dist_histo) + buildAndStoreHuffmanTreeFast(lit_histo.data_[:], lit_histo.total_count_, /* max_bits = */ + 8, lit_depth[:], lit_bits[:], storage_ix, storage) + + buildAndStoreHuffmanTreeFast(cmd_histo.data_[:], cmd_histo.total_count_, /* max_bits = */ + 10, cmd_depth[:], cmd_bits[:], storage_ix, storage) + + buildAndStoreHuffmanTreeFast(dist_histo.data_[:], dist_histo.total_count_, /* max_bits = */ + uint(distance_alphabet_bits), dist_depth[:], dist_bits[:], storage_ix, storage) + + storeDataWithHuffmanCodes(input, start_pos, mask, commands, lit_depth[:], lit_bits[:], cmd_depth[:], cmd_bits[:], dist_depth[:], dist_bits[:], storage_ix, storage) + } + + if is_last { + jumpToByteBoundary(storage_ix, storage) + } +} + +/* This is for storing uncompressed blocks (simple raw storage of + bytes-as-bytes). */ +func storeUncompressedMetaBlock(is_final_block bool, input []byte, position uint, mask uint, len uint, storage_ix *uint, storage []byte) { + var masked_pos uint = position & mask + storeUncompressedMetaBlockHeader(uint(len), storage_ix, storage) + jumpToByteBoundary(storage_ix, storage) + + if masked_pos+len > mask+1 { + var len1 uint = mask + 1 - masked_pos + copy(storage[*storage_ix>>3:], input[masked_pos:][:len1]) + *storage_ix += len1 << 3 + len -= len1 + masked_pos = 0 + } + + copy(storage[*storage_ix>>3:], input[masked_pos:][:len]) + *storage_ix += uint(len << 3) + + /* We need to clear the next 4 bytes to continue to be + compatible with BrotliWriteBits. */ + writeBitsPrepareStorage(*storage_ix, storage) + + /* Since the uncompressed block itself may not be the final block, add an + empty one after this. */ + if is_final_block { + writeBits(1, 1, storage_ix, storage) /* islast */ + writeBits(1, 1, storage_ix, storage) /* isempty */ + jumpToByteBoundary(storage_ix, storage) + } +} diff --git a/vendor/github.com/andybalholm/brotli/cluster.go b/vendor/github.com/andybalholm/brotli/cluster.go new file mode 100644 index 0000000..df8a328 --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/cluster.go @@ -0,0 +1,30 @@ +package brotli + +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Functions for clustering similar histograms together. */ + +type histogramPair struct { + idx1 uint32 + idx2 uint32 + cost_combo float64 + cost_diff float64 +} + +func histogramPairIsLess(p1 *histogramPair, p2 *histogramPair) bool { + if p1.cost_diff != p2.cost_diff { + return p1.cost_diff > p2.cost_diff + } + + return (p1.idx2 - p1.idx1) > (p2.idx2 - p2.idx1) +} + +/* Returns entropy reduction of the context map when we combine two clusters. */ +func clusterCostDiff(size_a uint, size_b uint) float64 { + var size_c uint = size_a + size_b + return float64(size_a)*fastLog2(size_a) + float64(size_b)*fastLog2(size_b) - float64(size_c)*fastLog2(size_c) +} diff --git a/vendor/github.com/andybalholm/brotli/cluster_command.go b/vendor/github.com/andybalholm/brotli/cluster_command.go new file mode 100644 index 0000000..45b569b --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/cluster_command.go @@ -0,0 +1,164 @@ +package brotli + +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Computes the bit cost reduction by combining out[idx1] and out[idx2] and if + it is below a threshold, stores the pair (idx1, idx2) in the *pairs queue. */ +func compareAndPushToQueueCommand(out []histogramCommand, cluster_size []uint32, idx1 uint32, idx2 uint32, max_num_pairs uint, pairs []histogramPair, num_pairs *uint) { + var is_good_pair bool = false + var p histogramPair + p.idx2 = 0 + p.idx1 = p.idx2 + p.cost_combo = 0 + p.cost_diff = p.cost_combo + if idx1 == idx2 { + return + } + + if idx2 < idx1 { + var t uint32 = idx2 + idx2 = idx1 + idx1 = t + } + + p.idx1 = idx1 + p.idx2 = idx2 + p.cost_diff = 0.5 * clusterCostDiff(uint(cluster_size[idx1]), uint(cluster_size[idx2])) + p.cost_diff -= out[idx1].bit_cost_ + p.cost_diff -= out[idx2].bit_cost_ + + if out[idx1].total_count_ == 0 { + p.cost_combo = out[idx2].bit_cost_ + is_good_pair = true + } else if out[idx2].total_count_ == 0 { + p.cost_combo = out[idx1].bit_cost_ + is_good_pair = true + } else { + var threshold float64 + if *num_pairs == 0 { + threshold = 1e99 + } else { + threshold = brotli_max_double(0.0, pairs[0].cost_diff) + } + var combo histogramCommand = out[idx1] + var cost_combo float64 + histogramAddHistogramCommand(&combo, &out[idx2]) + cost_combo = populationCostCommand(&combo) + if cost_combo < threshold-p.cost_diff { + p.cost_combo = cost_combo + is_good_pair = true + } + } + + if is_good_pair { + p.cost_diff += p.cost_combo + if *num_pairs > 0 && histogramPairIsLess(&pairs[0], &p) { + /* Replace the top of the queue if needed. */ + if *num_pairs < max_num_pairs { + pairs[*num_pairs] = pairs[0] + (*num_pairs)++ + } + + pairs[0] = p + } else if *num_pairs < max_num_pairs { + pairs[*num_pairs] = p + (*num_pairs)++ + } + } +} + +func histogramCombineCommand(out []histogramCommand, cluster_size []uint32, symbols []uint32, clusters []uint32, pairs []histogramPair, num_clusters uint, symbols_size uint, max_clusters uint, max_num_pairs uint) uint { + var cost_diff_threshold float64 = 0.0 + var min_cluster_size uint = 1 + var num_pairs uint = 0 + { + /* We maintain a vector of histogram pairs, with the property that the pair + with the maximum bit cost reduction is the first. */ + var idx1 uint + for idx1 = 0; idx1 < num_clusters; idx1++ { + var idx2 uint + for idx2 = idx1 + 1; idx2 < num_clusters; idx2++ { + compareAndPushToQueueCommand(out, cluster_size, clusters[idx1], clusters[idx2], max_num_pairs, pairs[0:], &num_pairs) + } + } + } + + for num_clusters > min_cluster_size { + var best_idx1 uint32 + var best_idx2 uint32 + var i uint + if pairs[0].cost_diff >= cost_diff_threshold { + cost_diff_threshold = 1e99 + min_cluster_size = max_clusters + continue + } + + /* Take the best pair from the top of heap. */ + best_idx1 = pairs[0].idx1 + + best_idx2 = pairs[0].idx2 + histogramAddHistogramCommand(&out[best_idx1], &out[best_idx2]) + out[best_idx1].bit_cost_ = pairs[0].cost_combo + cluster_size[best_idx1] += cluster_size[best_idx2] + for i = 0; i < symbols_size; i++ { + if symbols[i] == best_idx2 { + symbols[i] = best_idx1 + } + } + + for i = 0; i < num_clusters; i++ { + if clusters[i] == best_idx2 { + copy(clusters[i:], clusters[i+1:][:num_clusters-i-1]) + break + } + } + + num_clusters-- + { + /* Remove pairs intersecting the just combined best pair. */ + var copy_to_idx uint = 0 + for i = 0; i < num_pairs; i++ { + var p *histogramPair = &pairs[i] + if p.idx1 == best_idx1 || p.idx2 == best_idx1 || p.idx1 == best_idx2 || p.idx2 == best_idx2 { + /* Remove invalid pair from the queue. */ + continue + } + + if histogramPairIsLess(&pairs[0], p) { + /* Replace the top of the queue if needed. */ + var front histogramPair = pairs[0] + pairs[0] = *p + pairs[copy_to_idx] = front + } else { + pairs[copy_to_idx] = *p + } + + copy_to_idx++ + } + + num_pairs = copy_to_idx + } + + /* Push new pairs formed with the combined histogram to the heap. */ + for i = 0; i < num_clusters; i++ { + compareAndPushToQueueCommand(out, cluster_size, best_idx1, clusters[i], max_num_pairs, pairs[0:], &num_pairs) + } + } + + return num_clusters +} + +/* What is the bit cost of moving histogram from cur_symbol to candidate. */ +func histogramBitCostDistanceCommand(histogram *histogramCommand, candidate *histogramCommand) float64 { + if histogram.total_count_ == 0 { + return 0.0 + } else { + var tmp histogramCommand = *histogram + histogramAddHistogramCommand(&tmp, candidate) + return populationCostCommand(&tmp) - candidate.bit_cost_ + } +} diff --git a/vendor/github.com/andybalholm/brotli/cluster_distance.go b/vendor/github.com/andybalholm/brotli/cluster_distance.go new file mode 100644 index 0000000..1aaa86e --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/cluster_distance.go @@ -0,0 +1,326 @@ +package brotli + +import "math" + +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Computes the bit cost reduction by combining out[idx1] and out[idx2] and if + it is below a threshold, stores the pair (idx1, idx2) in the *pairs queue. */ +func compareAndPushToQueueDistance(out []histogramDistance, cluster_size []uint32, idx1 uint32, idx2 uint32, max_num_pairs uint, pairs []histogramPair, num_pairs *uint) { + var is_good_pair bool = false + var p histogramPair + p.idx2 = 0 + p.idx1 = p.idx2 + p.cost_combo = 0 + p.cost_diff = p.cost_combo + if idx1 == idx2 { + return + } + + if idx2 < idx1 { + var t uint32 = idx2 + idx2 = idx1 + idx1 = t + } + + p.idx1 = idx1 + p.idx2 = idx2 + p.cost_diff = 0.5 * clusterCostDiff(uint(cluster_size[idx1]), uint(cluster_size[idx2])) + p.cost_diff -= out[idx1].bit_cost_ + p.cost_diff -= out[idx2].bit_cost_ + + if out[idx1].total_count_ == 0 { + p.cost_combo = out[idx2].bit_cost_ + is_good_pair = true + } else if out[idx2].total_count_ == 0 { + p.cost_combo = out[idx1].bit_cost_ + is_good_pair = true + } else { + var threshold float64 + if *num_pairs == 0 { + threshold = 1e99 + } else { + threshold = brotli_max_double(0.0, pairs[0].cost_diff) + } + var combo histogramDistance = out[idx1] + var cost_combo float64 + histogramAddHistogramDistance(&combo, &out[idx2]) + cost_combo = populationCostDistance(&combo) + if cost_combo < threshold-p.cost_diff { + p.cost_combo = cost_combo + is_good_pair = true + } + } + + if is_good_pair { + p.cost_diff += p.cost_combo + if *num_pairs > 0 && histogramPairIsLess(&pairs[0], &p) { + /* Replace the top of the queue if needed. */ + if *num_pairs < max_num_pairs { + pairs[*num_pairs] = pairs[0] + (*num_pairs)++ + } + + pairs[0] = p + } else if *num_pairs < max_num_pairs { + pairs[*num_pairs] = p + (*num_pairs)++ + } + } +} + +func histogramCombineDistance(out []histogramDistance, cluster_size []uint32, symbols []uint32, clusters []uint32, pairs []histogramPair, num_clusters uint, symbols_size uint, max_clusters uint, max_num_pairs uint) uint { + var cost_diff_threshold float64 = 0.0 + var min_cluster_size uint = 1 + var num_pairs uint = 0 + { + /* We maintain a vector of histogram pairs, with the property that the pair + with the maximum bit cost reduction is the first. */ + var idx1 uint + for idx1 = 0; idx1 < num_clusters; idx1++ { + var idx2 uint + for idx2 = idx1 + 1; idx2 < num_clusters; idx2++ { + compareAndPushToQueueDistance(out, cluster_size, clusters[idx1], clusters[idx2], max_num_pairs, pairs[0:], &num_pairs) + } + } + } + + for num_clusters > min_cluster_size { + var best_idx1 uint32 + var best_idx2 uint32 + var i uint + if pairs[0].cost_diff >= cost_diff_threshold { + cost_diff_threshold = 1e99 + min_cluster_size = max_clusters + continue + } + + /* Take the best pair from the top of heap. */ + best_idx1 = pairs[0].idx1 + + best_idx2 = pairs[0].idx2 + histogramAddHistogramDistance(&out[best_idx1], &out[best_idx2]) + out[best_idx1].bit_cost_ = pairs[0].cost_combo + cluster_size[best_idx1] += cluster_size[best_idx2] + for i = 0; i < symbols_size; i++ { + if symbols[i] == best_idx2 { + symbols[i] = best_idx1 + } + } + + for i = 0; i < num_clusters; i++ { + if clusters[i] == best_idx2 { + copy(clusters[i:], clusters[i+1:][:num_clusters-i-1]) + break + } + } + + num_clusters-- + { + /* Remove pairs intersecting the just combined best pair. */ + var copy_to_idx uint = 0 + for i = 0; i < num_pairs; i++ { + var p *histogramPair = &pairs[i] + if p.idx1 == best_idx1 || p.idx2 == best_idx1 || p.idx1 == best_idx2 || p.idx2 == best_idx2 { + /* Remove invalid pair from the queue. */ + continue + } + + if histogramPairIsLess(&pairs[0], p) { + /* Replace the top of the queue if needed. */ + var front histogramPair = pairs[0] + pairs[0] = *p + pairs[copy_to_idx] = front + } else { + pairs[copy_to_idx] = *p + } + + copy_to_idx++ + } + + num_pairs = copy_to_idx + } + + /* Push new pairs formed with the combined histogram to the heap. */ + for i = 0; i < num_clusters; i++ { + compareAndPushToQueueDistance(out, cluster_size, best_idx1, clusters[i], max_num_pairs, pairs[0:], &num_pairs) + } + } + + return num_clusters +} + +/* What is the bit cost of moving histogram from cur_symbol to candidate. */ +func histogramBitCostDistanceDistance(histogram *histogramDistance, candidate *histogramDistance) float64 { + if histogram.total_count_ == 0 { + return 0.0 + } else { + var tmp histogramDistance = *histogram + histogramAddHistogramDistance(&tmp, candidate) + return populationCostDistance(&tmp) - candidate.bit_cost_ + } +} + +/* Find the best 'out' histogram for each of the 'in' histograms. + When called, clusters[0..num_clusters) contains the unique values from + symbols[0..in_size), but this property is not preserved in this function. + Note: we assume that out[]->bit_cost_ is already up-to-date. */ +func histogramRemapDistance(in []histogramDistance, in_size uint, clusters []uint32, num_clusters uint, out []histogramDistance, symbols []uint32) { + var i uint + for i = 0; i < in_size; i++ { + var best_out uint32 + if i == 0 { + best_out = symbols[0] + } else { + best_out = symbols[i-1] + } + var best_bits float64 = histogramBitCostDistanceDistance(&in[i], &out[best_out]) + var j uint + for j = 0; j < num_clusters; j++ { + var cur_bits float64 = histogramBitCostDistanceDistance(&in[i], &out[clusters[j]]) + if cur_bits < best_bits { + best_bits = cur_bits + best_out = clusters[j] + } + } + + symbols[i] = best_out + } + + /* Recompute each out based on raw and symbols. */ + for i = 0; i < num_clusters; i++ { + histogramClearDistance(&out[clusters[i]]) + } + + for i = 0; i < in_size; i++ { + histogramAddHistogramDistance(&out[symbols[i]], &in[i]) + } +} + +/* Reorders elements of the out[0..length) array and changes values in + symbols[0..length) array in the following way: + * when called, symbols[] contains indexes into out[], and has N unique + values (possibly N < length) + * on return, symbols'[i] = f(symbols[i]) and + out'[symbols'[i]] = out[symbols[i]], for each 0 <= i < length, + where f is a bijection between the range of symbols[] and [0..N), and + the first occurrences of values in symbols'[i] come in consecutive + increasing order. + Returns N, the number of unique values in symbols[]. */ + +var histogramReindexDistance_kInvalidIndex uint32 = math.MaxUint32 + +func histogramReindexDistance(out []histogramDistance, symbols []uint32, length uint) uint { + var new_index []uint32 = make([]uint32, length) + var next_index uint32 + var tmp []histogramDistance + var i uint + for i = 0; i < length; i++ { + new_index[i] = histogramReindexDistance_kInvalidIndex + } + + next_index = 0 + for i = 0; i < length; i++ { + if new_index[symbols[i]] == histogramReindexDistance_kInvalidIndex { + new_index[symbols[i]] = next_index + next_index++ + } + } + + /* TODO: by using idea of "cycle-sort" we can avoid allocation of + tmp and reduce the number of copying by the factor of 2. */ + tmp = make([]histogramDistance, next_index) + + next_index = 0 + for i = 0; i < length; i++ { + if new_index[symbols[i]] == next_index { + tmp[next_index] = out[symbols[i]] + next_index++ + } + + symbols[i] = new_index[symbols[i]] + } + + new_index = nil + for i = 0; uint32(i) < next_index; i++ { + out[i] = tmp[i] + } + + tmp = nil + return uint(next_index) +} + +func clusterHistogramsDistance(in []histogramDistance, in_size uint, max_histograms uint, out []histogramDistance, out_size *uint, histogram_symbols []uint32) { + var cluster_size []uint32 = make([]uint32, in_size) + var clusters []uint32 = make([]uint32, in_size) + var num_clusters uint = 0 + var max_input_histograms uint = 64 + var pairs_capacity uint = max_input_histograms * max_input_histograms / 2 + var pairs []histogramPair = make([]histogramPair, (pairs_capacity + 1)) + var i uint + + /* For the first pass of clustering, we allow all pairs. */ + for i = 0; i < in_size; i++ { + cluster_size[i] = 1 + } + + for i = 0; i < in_size; i++ { + out[i] = in[i] + out[i].bit_cost_ = populationCostDistance(&in[i]) + histogram_symbols[i] = uint32(i) + } + + for i = 0; i < in_size; i += max_input_histograms { + var num_to_combine uint = brotli_min_size_t(in_size-i, max_input_histograms) + var num_new_clusters uint + var j uint + for j = 0; j < num_to_combine; j++ { + clusters[num_clusters+j] = uint32(i + j) + } + + num_new_clusters = histogramCombineDistance(out, cluster_size, histogram_symbols[i:], clusters[num_clusters:], pairs, num_to_combine, num_to_combine, max_histograms, pairs_capacity) + num_clusters += num_new_clusters + } + { + /* For the second pass, we limit the total number of histogram pairs. + After this limit is reached, we only keep searching for the best pair. */ + var max_num_pairs uint = brotli_min_size_t(64*num_clusters, (num_clusters/2)*num_clusters) + if pairs_capacity < (max_num_pairs + 1) { + var _new_size uint + if pairs_capacity == 0 { + _new_size = max_num_pairs + 1 + } else { + _new_size = pairs_capacity + } + var new_array []histogramPair + for _new_size < (max_num_pairs + 1) { + _new_size *= 2 + } + new_array = make([]histogramPair, _new_size) + if pairs_capacity != 0 { + copy(new_array, pairs[:pairs_capacity]) + } + + pairs = new_array + pairs_capacity = _new_size + } + + /* Collapse similar histograms. */ + num_clusters = histogramCombineDistance(out, cluster_size, histogram_symbols, clusters, pairs, num_clusters, in_size, max_histograms, max_num_pairs) + } + + pairs = nil + cluster_size = nil + + /* Find the optimal map from original histograms to the final ones. */ + histogramRemapDistance(in, in_size, clusters, num_clusters, out, histogram_symbols) + + clusters = nil + + /* Convert the context map to a canonical form. */ + *out_size = histogramReindexDistance(out, histogram_symbols, in_size) +} diff --git a/vendor/github.com/andybalholm/brotli/cluster_literal.go b/vendor/github.com/andybalholm/brotli/cluster_literal.go new file mode 100644 index 0000000..6ba66f3 --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/cluster_literal.go @@ -0,0 +1,326 @@ +package brotli + +import "math" + +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Computes the bit cost reduction by combining out[idx1] and out[idx2] and if + it is below a threshold, stores the pair (idx1, idx2) in the *pairs queue. */ +func compareAndPushToQueueLiteral(out []histogramLiteral, cluster_size []uint32, idx1 uint32, idx2 uint32, max_num_pairs uint, pairs []histogramPair, num_pairs *uint) { + var is_good_pair bool = false + var p histogramPair + p.idx2 = 0 + p.idx1 = p.idx2 + p.cost_combo = 0 + p.cost_diff = p.cost_combo + if idx1 == idx2 { + return + } + + if idx2 < idx1 { + var t uint32 = idx2 + idx2 = idx1 + idx1 = t + } + + p.idx1 = idx1 + p.idx2 = idx2 + p.cost_diff = 0.5 * clusterCostDiff(uint(cluster_size[idx1]), uint(cluster_size[idx2])) + p.cost_diff -= out[idx1].bit_cost_ + p.cost_diff -= out[idx2].bit_cost_ + + if out[idx1].total_count_ == 0 { + p.cost_combo = out[idx2].bit_cost_ + is_good_pair = true + } else if out[idx2].total_count_ == 0 { + p.cost_combo = out[idx1].bit_cost_ + is_good_pair = true + } else { + var threshold float64 + if *num_pairs == 0 { + threshold = 1e99 + } else { + threshold = brotli_max_double(0.0, pairs[0].cost_diff) + } + var combo histogramLiteral = out[idx1] + var cost_combo float64 + histogramAddHistogramLiteral(&combo, &out[idx2]) + cost_combo = populationCostLiteral(&combo) + if cost_combo < threshold-p.cost_diff { + p.cost_combo = cost_combo + is_good_pair = true + } + } + + if is_good_pair { + p.cost_diff += p.cost_combo + if *num_pairs > 0 && histogramPairIsLess(&pairs[0], &p) { + /* Replace the top of the queue if needed. */ + if *num_pairs < max_num_pairs { + pairs[*num_pairs] = pairs[0] + (*num_pairs)++ + } + + pairs[0] = p + } else if *num_pairs < max_num_pairs { + pairs[*num_pairs] = p + (*num_pairs)++ + } + } +} + +func histogramCombineLiteral(out []histogramLiteral, cluster_size []uint32, symbols []uint32, clusters []uint32, pairs []histogramPair, num_clusters uint, symbols_size uint, max_clusters uint, max_num_pairs uint) uint { + var cost_diff_threshold float64 = 0.0 + var min_cluster_size uint = 1 + var num_pairs uint = 0 + { + /* We maintain a vector of histogram pairs, with the property that the pair + with the maximum bit cost reduction is the first. */ + var idx1 uint + for idx1 = 0; idx1 < num_clusters; idx1++ { + var idx2 uint + for idx2 = idx1 + 1; idx2 < num_clusters; idx2++ { + compareAndPushToQueueLiteral(out, cluster_size, clusters[idx1], clusters[idx2], max_num_pairs, pairs[0:], &num_pairs) + } + } + } + + for num_clusters > min_cluster_size { + var best_idx1 uint32 + var best_idx2 uint32 + var i uint + if pairs[0].cost_diff >= cost_diff_threshold { + cost_diff_threshold = 1e99 + min_cluster_size = max_clusters + continue + } + + /* Take the best pair from the top of heap. */ + best_idx1 = pairs[0].idx1 + + best_idx2 = pairs[0].idx2 + histogramAddHistogramLiteral(&out[best_idx1], &out[best_idx2]) + out[best_idx1].bit_cost_ = pairs[0].cost_combo + cluster_size[best_idx1] += cluster_size[best_idx2] + for i = 0; i < symbols_size; i++ { + if symbols[i] == best_idx2 { + symbols[i] = best_idx1 + } + } + + for i = 0; i < num_clusters; i++ { + if clusters[i] == best_idx2 { + copy(clusters[i:], clusters[i+1:][:num_clusters-i-1]) + break + } + } + + num_clusters-- + { + /* Remove pairs intersecting the just combined best pair. */ + var copy_to_idx uint = 0 + for i = 0; i < num_pairs; i++ { + var p *histogramPair = &pairs[i] + if p.idx1 == best_idx1 || p.idx2 == best_idx1 || p.idx1 == best_idx2 || p.idx2 == best_idx2 { + /* Remove invalid pair from the queue. */ + continue + } + + if histogramPairIsLess(&pairs[0], p) { + /* Replace the top of the queue if needed. */ + var front histogramPair = pairs[0] + pairs[0] = *p + pairs[copy_to_idx] = front + } else { + pairs[copy_to_idx] = *p + } + + copy_to_idx++ + } + + num_pairs = copy_to_idx + } + + /* Push new pairs formed with the combined histogram to the heap. */ + for i = 0; i < num_clusters; i++ { + compareAndPushToQueueLiteral(out, cluster_size, best_idx1, clusters[i], max_num_pairs, pairs[0:], &num_pairs) + } + } + + return num_clusters +} + +/* What is the bit cost of moving histogram from cur_symbol to candidate. */ +func histogramBitCostDistanceLiteral(histogram *histogramLiteral, candidate *histogramLiteral) float64 { + if histogram.total_count_ == 0 { + return 0.0 + } else { + var tmp histogramLiteral = *histogram + histogramAddHistogramLiteral(&tmp, candidate) + return populationCostLiteral(&tmp) - candidate.bit_cost_ + } +} + +/* Find the best 'out' histogram for each of the 'in' histograms. + When called, clusters[0..num_clusters) contains the unique values from + symbols[0..in_size), but this property is not preserved in this function. + Note: we assume that out[]->bit_cost_ is already up-to-date. */ +func histogramRemapLiteral(in []histogramLiteral, in_size uint, clusters []uint32, num_clusters uint, out []histogramLiteral, symbols []uint32) { + var i uint + for i = 0; i < in_size; i++ { + var best_out uint32 + if i == 0 { + best_out = symbols[0] + } else { + best_out = symbols[i-1] + } + var best_bits float64 = histogramBitCostDistanceLiteral(&in[i], &out[best_out]) + var j uint + for j = 0; j < num_clusters; j++ { + var cur_bits float64 = histogramBitCostDistanceLiteral(&in[i], &out[clusters[j]]) + if cur_bits < best_bits { + best_bits = cur_bits + best_out = clusters[j] + } + } + + symbols[i] = best_out + } + + /* Recompute each out based on raw and symbols. */ + for i = 0; i < num_clusters; i++ { + histogramClearLiteral(&out[clusters[i]]) + } + + for i = 0; i < in_size; i++ { + histogramAddHistogramLiteral(&out[symbols[i]], &in[i]) + } +} + +/* Reorders elements of the out[0..length) array and changes values in + symbols[0..length) array in the following way: + * when called, symbols[] contains indexes into out[], and has N unique + values (possibly N < length) + * on return, symbols'[i] = f(symbols[i]) and + out'[symbols'[i]] = out[symbols[i]], for each 0 <= i < length, + where f is a bijection between the range of symbols[] and [0..N), and + the first occurrences of values in symbols'[i] come in consecutive + increasing order. + Returns N, the number of unique values in symbols[]. */ + +var histogramReindexLiteral_kInvalidIndex uint32 = math.MaxUint32 + +func histogramReindexLiteral(out []histogramLiteral, symbols []uint32, length uint) uint { + var new_index []uint32 = make([]uint32, length) + var next_index uint32 + var tmp []histogramLiteral + var i uint + for i = 0; i < length; i++ { + new_index[i] = histogramReindexLiteral_kInvalidIndex + } + + next_index = 0 + for i = 0; i < length; i++ { + if new_index[symbols[i]] == histogramReindexLiteral_kInvalidIndex { + new_index[symbols[i]] = next_index + next_index++ + } + } + + /* TODO: by using idea of "cycle-sort" we can avoid allocation of + tmp and reduce the number of copying by the factor of 2. */ + tmp = make([]histogramLiteral, next_index) + + next_index = 0 + for i = 0; i < length; i++ { + if new_index[symbols[i]] == next_index { + tmp[next_index] = out[symbols[i]] + next_index++ + } + + symbols[i] = new_index[symbols[i]] + } + + new_index = nil + for i = 0; uint32(i) < next_index; i++ { + out[i] = tmp[i] + } + + tmp = nil + return uint(next_index) +} + +func clusterHistogramsLiteral(in []histogramLiteral, in_size uint, max_histograms uint, out []histogramLiteral, out_size *uint, histogram_symbols []uint32) { + var cluster_size []uint32 = make([]uint32, in_size) + var clusters []uint32 = make([]uint32, in_size) + var num_clusters uint = 0 + var max_input_histograms uint = 64 + var pairs_capacity uint = max_input_histograms * max_input_histograms / 2 + var pairs []histogramPair = make([]histogramPair, (pairs_capacity + 1)) + var i uint + + /* For the first pass of clustering, we allow all pairs. */ + for i = 0; i < in_size; i++ { + cluster_size[i] = 1 + } + + for i = 0; i < in_size; i++ { + out[i] = in[i] + out[i].bit_cost_ = populationCostLiteral(&in[i]) + histogram_symbols[i] = uint32(i) + } + + for i = 0; i < in_size; i += max_input_histograms { + var num_to_combine uint = brotli_min_size_t(in_size-i, max_input_histograms) + var num_new_clusters uint + var j uint + for j = 0; j < num_to_combine; j++ { + clusters[num_clusters+j] = uint32(i + j) + } + + num_new_clusters = histogramCombineLiteral(out, cluster_size, histogram_symbols[i:], clusters[num_clusters:], pairs, num_to_combine, num_to_combine, max_histograms, pairs_capacity) + num_clusters += num_new_clusters + } + { + /* For the second pass, we limit the total number of histogram pairs. + After this limit is reached, we only keep searching for the best pair. */ + var max_num_pairs uint = brotli_min_size_t(64*num_clusters, (num_clusters/2)*num_clusters) + if pairs_capacity < (max_num_pairs + 1) { + var _new_size uint + if pairs_capacity == 0 { + _new_size = max_num_pairs + 1 + } else { + _new_size = pairs_capacity + } + var new_array []histogramPair + for _new_size < (max_num_pairs + 1) { + _new_size *= 2 + } + new_array = make([]histogramPair, _new_size) + if pairs_capacity != 0 { + copy(new_array, pairs[:pairs_capacity]) + } + + pairs = new_array + pairs_capacity = _new_size + } + + /* Collapse similar histograms. */ + num_clusters = histogramCombineLiteral(out, cluster_size, histogram_symbols, clusters, pairs, num_clusters, in_size, max_histograms, max_num_pairs) + } + + pairs = nil + cluster_size = nil + + /* Find the optimal map from original histograms to the final ones. */ + histogramRemapLiteral(in, in_size, clusters, num_clusters, out, histogram_symbols) + + clusters = nil + + /* Convert the context map to a canonical form. */ + *out_size = histogramReindexLiteral(out, histogram_symbols, in_size) +} diff --git a/vendor/github.com/andybalholm/brotli/command.go b/vendor/github.com/andybalholm/brotli/command.go new file mode 100644 index 0000000..b1662a5 --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/command.go @@ -0,0 +1,254 @@ +package brotli + +var kInsBase = []uint32{ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 8, + 10, + 14, + 18, + 26, + 34, + 50, + 66, + 98, + 130, + 194, + 322, + 578, + 1090, + 2114, + 6210, + 22594, +} + +var kInsExtra = []uint32{ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 2, + 3, + 3, + 4, + 4, + 5, + 5, + 6, + 7, + 8, + 9, + 10, + 12, + 14, + 24, +} + +var kCopyBase = []uint32{ + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 12, + 14, + 18, + 22, + 30, + 38, + 54, + 70, + 102, + 134, + 198, + 326, + 582, + 1094, + 2118, +} + +var kCopyExtra = []uint32{ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 2, + 3, + 3, + 4, + 4, + 5, + 5, + 6, + 7, + 8, + 9, + 10, + 24, +} + +func getInsertLengthCode(insertlen uint) uint16 { + if insertlen < 6 { + return uint16(insertlen) + } else if insertlen < 130 { + var nbits uint32 = log2FloorNonZero(insertlen-2) - 1 + return uint16((nbits << 1) + uint32((insertlen-2)>>nbits) + 2) + } else if insertlen < 2114 { + return uint16(log2FloorNonZero(insertlen-66) + 10) + } else if insertlen < 6210 { + return 21 + } else if insertlen < 22594 { + return 22 + } else { + return 23 + } +} + +func getCopyLengthCode(copylen uint) uint16 { + if copylen < 10 { + return uint16(copylen - 2) + } else if copylen < 134 { + var nbits uint32 = log2FloorNonZero(copylen-6) - 1 + return uint16((nbits << 1) + uint32((copylen-6)>>nbits) + 4) + } else if copylen < 2118 { + return uint16(log2FloorNonZero(copylen-70) + 12) + } else { + return 23 + } +} + +func combineLengthCodes(inscode uint16, copycode uint16, use_last_distance bool) uint16 { + var bits64 uint16 = uint16(copycode&0x7 | (inscode&0x7)<<3) + if use_last_distance && inscode < 8 && copycode < 16 { + if copycode < 8 { + return bits64 + } else { + return bits64 | 64 + } + } else { + /* Specification: 5 Encoding of ... (last table) */ + /* offset = 2 * index, where index is in range [0..8] */ + var offset uint32 = 2 * ((uint32(copycode) >> 3) + 3*(uint32(inscode)>>3)) + + /* All values in specification are K * 64, + where K = [2, 3, 6, 4, 5, 8, 7, 9, 10], + i + 1 = [1, 2, 3, 4, 5, 6, 7, 8, 9], + K - i - 1 = [1, 1, 3, 0, 0, 2, 0, 1, 2] = D. + All values in D require only 2 bits to encode. + Magic constant is shifted 6 bits left, to avoid final multiplication. */ + offset = (offset << 5) + 0x40 + ((0x520D40 >> offset) & 0xC0) + + return uint16(offset | uint32(bits64)) + } +} + +func getLengthCode(insertlen uint, copylen uint, use_last_distance bool, code *uint16) { + var inscode uint16 = getInsertLengthCode(insertlen) + var copycode uint16 = getCopyLengthCode(copylen) + *code = combineLengthCodes(inscode, copycode, use_last_distance) +} + +func getInsertBase(inscode uint16) uint32 { + return kInsBase[inscode] +} + +func getInsertExtra(inscode uint16) uint32 { + return kInsExtra[inscode] +} + +func getCopyBase(copycode uint16) uint32 { + return kCopyBase[copycode] +} + +func getCopyExtra(copycode uint16) uint32 { + return kCopyExtra[copycode] +} + +type command struct { + insert_len_ uint32 + copy_len_ uint32 + dist_extra_ uint32 + cmd_prefix_ uint16 + dist_prefix_ uint16 +} + +/* distance_code is e.g. 0 for same-as-last short code, or 16 for offset 1. */ +func makeCommand(dist *distanceParams, insertlen uint, copylen uint, copylen_code_delta int, distance_code uint) (cmd command) { + /* Don't rely on signed int representation, use honest casts. */ + var delta uint32 = uint32(byte(int8(copylen_code_delta))) + cmd.insert_len_ = uint32(insertlen) + cmd.copy_len_ = uint32(uint32(copylen) | delta<<25) + + /* The distance prefix and extra bits are stored in this Command as if + npostfix and ndirect were 0, they are only recomputed later after the + clustering if needed. */ + prefixEncodeCopyDistance(distance_code, uint(dist.num_direct_distance_codes), uint(dist.distance_postfix_bits), &cmd.dist_prefix_, &cmd.dist_extra_) + getLengthCode(insertlen, uint(int(copylen)+copylen_code_delta), (cmd.dist_prefix_&0x3FF == 0), &cmd.cmd_prefix_) + + return cmd +} + +func makeInsertCommand(insertlen uint) (cmd command) { + cmd.insert_len_ = uint32(insertlen) + cmd.copy_len_ = 4 << 25 + cmd.dist_extra_ = 0 + cmd.dist_prefix_ = numDistanceShortCodes + getLengthCode(insertlen, 4, false, &cmd.cmd_prefix_) + return cmd +} + +func commandRestoreDistanceCode(self *command, dist *distanceParams) uint32 { + if uint32(self.dist_prefix_&0x3FF) < numDistanceShortCodes+dist.num_direct_distance_codes { + return uint32(self.dist_prefix_) & 0x3FF + } else { + var dcode uint32 = uint32(self.dist_prefix_) & 0x3FF + var nbits uint32 = uint32(self.dist_prefix_) >> 10 + var extra uint32 = self.dist_extra_ + var postfix_mask uint32 = (1 << dist.distance_postfix_bits) - 1 + var hcode uint32 = (dcode - dist.num_direct_distance_codes - numDistanceShortCodes) >> dist.distance_postfix_bits + var lcode uint32 = (dcode - dist.num_direct_distance_codes - numDistanceShortCodes) & postfix_mask + var offset uint32 = ((2 + (hcode & 1)) << nbits) - 4 + return ((offset + extra) << dist.distance_postfix_bits) + lcode + dist.num_direct_distance_codes + numDistanceShortCodes + } +} + +func commandDistanceContext(self *command) uint32 { + var r uint32 = uint32(self.cmd_prefix_) >> 6 + var c uint32 = uint32(self.cmd_prefix_) & 7 + if (r == 0 || r == 2 || r == 4 || r == 7) && (c <= 2) { + return c + } + + return 3 +} + +func commandCopyLen(self *command) uint32 { + return self.copy_len_ & 0x1FFFFFF +} + +func commandCopyLenCode(self *command) uint32 { + var modifier uint32 = self.copy_len_ >> 25 + var delta int32 = int32(int8(byte(modifier | (modifier&0x40)<<1))) + return uint32(int32(self.copy_len_&0x1FFFFFF) + delta) +} diff --git a/vendor/github.com/andybalholm/brotli/compress_fragment.go b/vendor/github.com/andybalholm/brotli/compress_fragment.go new file mode 100644 index 0000000..c9bd057 --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/compress_fragment.go @@ -0,0 +1,834 @@ +package brotli + +import "encoding/binary" + +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Function for fast encoding of an input fragment, independently from the input + history. This function uses one-pass processing: when we find a backward + match, we immediately emit the corresponding command and literal codes to + the bit stream. + + Adapted from the CompressFragment() function in + https://github.com/google/snappy/blob/master/snappy.cc */ + +const maxDistance_compress_fragment = 262128 + +func hash5(p []byte, shift uint) uint32 { + var h uint64 = (binary.LittleEndian.Uint64(p) << 24) * uint64(kHashMul32) + return uint32(h >> shift) +} + +func hashBytesAtOffset5(v uint64, offset int, shift uint) uint32 { + assert(offset >= 0) + assert(offset <= 3) + { + var h uint64 = ((v >> uint(8*offset)) << 24) * uint64(kHashMul32) + return uint32(h >> shift) + } +} + +func isMatch5(p1 []byte, p2 []byte) bool { + return binary.LittleEndian.Uint32(p1) == binary.LittleEndian.Uint32(p2) && + p1[4] == p2[4] +} + +/* Builds a literal prefix code into "depths" and "bits" based on the statistics + of the "input" string and stores it into the bit stream. + Note that the prefix code here is built from the pre-LZ77 input, therefore + we can only approximate the statistics of the actual literal stream. + Moreover, for long inputs we build a histogram from a sample of the input + and thus have to assign a non-zero depth for each literal. + Returns estimated compression ratio millibytes/char for encoding given input + with generated code. */ +func buildAndStoreLiteralPrefixCode(input []byte, input_size uint, depths []byte, bits []uint16, storage_ix *uint, storage []byte) uint { + var histogram = [256]uint32{0} + var histogram_total uint + var i uint + if input_size < 1<<15 { + for i = 0; i < input_size; i++ { + histogram[input[i]]++ + } + + histogram_total = input_size + for i = 0; i < 256; i++ { + /* We weigh the first 11 samples with weight 3 to account for the + balancing effect of the LZ77 phase on the histogram. */ + var adjust uint32 = 2 * brotli_min_uint32_t(histogram[i], 11) + histogram[i] += adjust + histogram_total += uint(adjust) + } + } else { + const kSampleRate uint = 29 + for i = 0; i < input_size; i += kSampleRate { + histogram[input[i]]++ + } + + histogram_total = (input_size + kSampleRate - 1) / kSampleRate + for i = 0; i < 256; i++ { + /* We add 1 to each population count to avoid 0 bit depths (since this is + only a sample and we don't know if the symbol appears or not), and we + weigh the first 11 samples with weight 3 to account for the balancing + effect of the LZ77 phase on the histogram (more frequent symbols are + more likely to be in backward references instead as literals). */ + var adjust uint32 = 1 + 2*brotli_min_uint32_t(histogram[i], 11) + histogram[i] += adjust + histogram_total += uint(adjust) + } + } + + buildAndStoreHuffmanTreeFast(histogram[:], histogram_total, /* max_bits = */ + 8, depths, bits, storage_ix, storage) + { + var literal_ratio uint = 0 + for i = 0; i < 256; i++ { + if histogram[i] != 0 { + literal_ratio += uint(histogram[i] * uint32(depths[i])) + } + } + + /* Estimated encoding ratio, millibytes per symbol. */ + return (literal_ratio * 125) / histogram_total + } +} + +/* Builds a command and distance prefix code (each 64 symbols) into "depth" and + "bits" based on "histogram" and stores it into the bit stream. */ +func buildAndStoreCommandPrefixCode1(histogram []uint32, depth []byte, bits []uint16, storage_ix *uint, storage []byte) { + var tree [129]huffmanTree + var cmd_depth = [numCommandSymbols]byte{0} + /* Tree size for building a tree over 64 symbols is 2 * 64 + 1. */ + + var cmd_bits [64]uint16 + + createHuffmanTree(histogram, 64, 15, tree[:], depth) + createHuffmanTree(histogram[64:], 64, 14, tree[:], depth[64:]) + + /* We have to jump through a few hoops here in order to compute + the command bits because the symbols are in a different order than in + the full alphabet. This looks complicated, but having the symbols + in this order in the command bits saves a few branches in the Emit* + functions. */ + copy(cmd_depth[:], depth[:24]) + + copy(cmd_depth[24:][:], depth[40:][:8]) + copy(cmd_depth[32:][:], depth[24:][:8]) + copy(cmd_depth[40:][:], depth[48:][:8]) + copy(cmd_depth[48:][:], depth[32:][:8]) + copy(cmd_depth[56:][:], depth[56:][:8]) + convertBitDepthsToSymbols(cmd_depth[:], 64, cmd_bits[:]) + copy(bits, cmd_bits[:24]) + copy(bits[24:], cmd_bits[32:][:8]) + copy(bits[32:], cmd_bits[48:][:8]) + copy(bits[40:], cmd_bits[24:][:8]) + copy(bits[48:], cmd_bits[40:][:8]) + copy(bits[56:], cmd_bits[56:][:8]) + convertBitDepthsToSymbols(depth[64:], 64, bits[64:]) + { + /* Create the bit length array for the full command alphabet. */ + var i uint + for i := 0; i < int(64); i++ { + cmd_depth[i] = 0 + } /* only 64 first values were used */ + copy(cmd_depth[:], depth[:8]) + copy(cmd_depth[64:][:], depth[8:][:8]) + copy(cmd_depth[128:][:], depth[16:][:8]) + copy(cmd_depth[192:][:], depth[24:][:8]) + copy(cmd_depth[384:][:], depth[32:][:8]) + for i = 0; i < 8; i++ { + cmd_depth[128+8*i] = depth[40+i] + cmd_depth[256+8*i] = depth[48+i] + cmd_depth[448+8*i] = depth[56+i] + } + + storeHuffmanTree(cmd_depth[:], numCommandSymbols, tree[:], storage_ix, storage) + } + + storeHuffmanTree(depth[64:], 64, tree[:], storage_ix, storage) +} + +/* REQUIRES: insertlen < 6210 */ +func emitInsertLen1(insertlen uint, depth []byte, bits []uint16, histo []uint32, storage_ix *uint, storage []byte) { + if insertlen < 6 { + var code uint = insertlen + 40 + writeBits(uint(depth[code]), uint64(bits[code]), storage_ix, storage) + histo[code]++ + } else if insertlen < 130 { + var tail uint = insertlen - 2 + var nbits uint32 = log2FloorNonZero(tail) - 1 + var prefix uint = tail >> nbits + var inscode uint = uint((nbits << 1) + uint32(prefix) + 42) + writeBits(uint(depth[inscode]), uint64(bits[inscode]), storage_ix, storage) + writeBits(uint(nbits), uint64(tail)-(uint64(prefix)<> nbits + var code uint = uint((nbits << 1) + uint32(prefix) + 20) + writeBits(uint(depth[code]), uint64(bits[code]), storage_ix, storage) + writeBits(uint(nbits), uint64(tail)-(uint64(prefix)<> nbits + var code uint = uint((nbits << 1) + uint32(prefix) + 4) + writeBits(uint(depth[code]), uint64(bits[code]), storage_ix, storage) + writeBits(uint(nbits), uint64(tail)-(uint64(prefix)<> 5) + 30 + writeBits(uint(depth[code]), uint64(bits[code]), storage_ix, storage) + writeBits(5, uint64(tail)&31, storage_ix, storage) + writeBits(uint(depth[64]), uint64(bits[64]), storage_ix, storage) + histo[code]++ + histo[64]++ + } else if copylen < 2120 { + var tail uint = copylen - 72 + var nbits uint32 = log2FloorNonZero(tail) + var code uint = uint(nbits + 28) + writeBits(uint(depth[code]), uint64(bits[code]), storage_ix, storage) + writeBits(uint(nbits), uint64(tail)-(uint64(uint(1))<> nbits) & 1 + var offset uint = (2 + prefix) << nbits + var distcode uint = uint(2*(nbits-1) + uint32(prefix) + 80) + writeBits(uint(depth[distcode]), uint64(bits[distcode]), storage_ix, storage) + writeBits(uint(nbits), uint64(d)-uint64(offset), storage_ix, storage) + histo[distcode]++ +} + +func emitLiterals(input []byte, len uint, depth []byte, bits []uint16, storage_ix *uint, storage []byte) { + var j uint + for j = 0; j < len; j++ { + var lit byte = input[j] + writeBits(uint(depth[lit]), uint64(bits[lit]), storage_ix, storage) + } +} + +/* REQUIRES: len <= 1 << 24. */ +func storeMetaBlockHeader1(len uint, is_uncompressed bool, storage_ix *uint, storage []byte) { + var nibbles uint = 6 + + /* ISLAST */ + writeBits(1, 0, storage_ix, storage) + + if len <= 1<<16 { + nibbles = 4 + } else if len <= 1<<20 { + nibbles = 5 + } + + writeBits(2, uint64(nibbles)-4, storage_ix, storage) + writeBits(nibbles*4, uint64(len)-1, storage_ix, storage) + + /* ISUNCOMPRESSED */ + writeSingleBit(is_uncompressed, storage_ix, storage) +} + +func updateBits(n_bits uint, bits uint32, pos uint, array []byte) { + for n_bits > 0 { + var byte_pos uint = pos >> 3 + var n_unchanged_bits uint = pos & 7 + var n_changed_bits uint = brotli_min_size_t(n_bits, 8-n_unchanged_bits) + var total_bits uint = n_unchanged_bits + n_changed_bits + var mask uint32 = (^((1 << total_bits) - 1)) | ((1 << n_unchanged_bits) - 1) + var unchanged_bits uint32 = uint32(array[byte_pos]) & mask + var changed_bits uint32 = bits & ((1 << n_changed_bits) - 1) + array[byte_pos] = byte(changed_bits<>= n_changed_bits + pos += n_changed_bits + } +} + +func rewindBitPosition1(new_storage_ix uint, storage_ix *uint, storage []byte) { + var bitpos uint = new_storage_ix & 7 + var mask uint = (1 << bitpos) - 1 + storage[new_storage_ix>>3] &= byte(mask) + *storage_ix = new_storage_ix +} + +var shouldMergeBlock_kSampleRate uint = 43 + +func shouldMergeBlock(data []byte, len uint, depths []byte) bool { + var histo = [256]uint{0} + var i uint + for i = 0; i < len; i += shouldMergeBlock_kSampleRate { + histo[data[i]]++ + } + { + var total uint = (len + shouldMergeBlock_kSampleRate - 1) / shouldMergeBlock_kSampleRate + var r float64 = (fastLog2(total)+0.5)*float64(total) + 200 + for i = 0; i < 256; i++ { + r -= float64(histo[i]) * (float64(depths[i]) + fastLog2(histo[i])) + } + + return r >= 0.0 + } +} + +func shouldUseUncompressedMode(metablock_start []byte, next_emit []byte, insertlen uint, literal_ratio uint) bool { + var compressed uint = uint(-cap(next_emit) + cap(metablock_start)) + if compressed*50 > insertlen { + return false + } else { + return literal_ratio > 980 + } +} + +func emitUncompressedMetaBlock1(begin []byte, end []byte, storage_ix_start uint, storage_ix *uint, storage []byte) { + var len uint = uint(-cap(end) + cap(begin)) + rewindBitPosition1(storage_ix_start, storage_ix, storage) + storeMetaBlockHeader1(uint(len), true, storage_ix, storage) + *storage_ix = (*storage_ix + 7) &^ 7 + copy(storage[*storage_ix>>3:], begin[:len]) + *storage_ix += uint(len << 3) + storage[*storage_ix>>3] = 0 +} + +var kCmdHistoSeed = [128]uint32{ + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, +} + +var compressFragmentFastImpl_kFirstBlockSize uint = 3 << 15 +var compressFragmentFastImpl_kMergeBlockSize uint = 1 << 16 + +func compressFragmentFastImpl(in []byte, input_size uint, is_last bool, table []int, table_bits uint, cmd_depth []byte, cmd_bits []uint16, cmd_code_numbits *uint, cmd_code []byte, storage_ix *uint, storage []byte) { + var cmd_histo [128]uint32 + var ip_end int + var next_emit int = 0 + var base_ip int = 0 + var input int = 0 + const kInputMarginBytes uint = windowGap + const kMinMatchLen uint = 5 + var metablock_start int = input + var block_size uint = brotli_min_size_t(input_size, compressFragmentFastImpl_kFirstBlockSize) + var total_block_size uint = block_size + var mlen_storage_ix uint = *storage_ix + 3 + var lit_depth [256]byte + var lit_bits [256]uint16 + var literal_ratio uint + var ip int + var last_distance int + var shift uint = 64 - table_bits + + /* "next_emit" is a pointer to the first byte that is not covered by a + previous copy. Bytes between "next_emit" and the start of the next copy or + the end of the input will be emitted as literal bytes. */ + + /* Save the start of the first block for position and distance computations. + */ + + /* Save the bit position of the MLEN field of the meta-block header, so that + we can update it later if we decide to extend this meta-block. */ + storeMetaBlockHeader1(block_size, false, storage_ix, storage) + + /* No block splits, no contexts. */ + writeBits(13, 0, storage_ix, storage) + + literal_ratio = buildAndStoreLiteralPrefixCode(in[input:], block_size, lit_depth[:], lit_bits[:], storage_ix, storage) + { + /* Store the pre-compressed command and distance prefix codes. */ + var i uint + for i = 0; i+7 < *cmd_code_numbits; i += 8 { + writeBits(8, uint64(cmd_code[i>>3]), storage_ix, storage) + } + } + + writeBits(*cmd_code_numbits&7, uint64(cmd_code[*cmd_code_numbits>>3]), storage_ix, storage) + + /* Initialize the command and distance histograms. We will gather + statistics of command and distance codes during the processing + of this block and use it to update the command and distance + prefix codes for the next block. */ +emit_commands: + copy(cmd_histo[:], kCmdHistoSeed[:]) + + /* "ip" is the input pointer. */ + ip = input + + last_distance = -1 + ip_end = int(uint(input) + block_size) + + if block_size >= kInputMarginBytes { + var len_limit uint = brotli_min_size_t(block_size-kMinMatchLen, input_size-kInputMarginBytes) + var ip_limit int = int(uint(input) + len_limit) + /* For the last block, we need to keep a 16 bytes margin so that we can be + sure that all distances are at most window size - 16. + For all other blocks, we only need to keep a margin of 5 bytes so that + we don't go over the block size with a copy. */ + + var next_hash uint32 + ip++ + for next_hash = hash5(in[ip:], shift); ; { + var skip uint32 = 32 + var next_ip int = ip + /* Step 1: Scan forward in the input looking for a 5-byte-long match. + If we get close to exhausting the input then goto emit_remainder. + + Heuristic match skipping: If 32 bytes are scanned with no matches + found, start looking only at every other byte. If 32 more bytes are + scanned, look at every third byte, etc.. When a match is found, + immediately go back to looking at every byte. This is a small loss + (~5% performance, ~0.1% density) for compressible data due to more + bookkeeping, but for non-compressible data (such as JPEG) it's a huge + win since the compressor quickly "realizes" the data is incompressible + and doesn't bother looking for matches everywhere. + + The "skip" variable keeps track of how many bytes there are since the + last match; dividing it by 32 (i.e. right-shifting by five) gives the + number of bytes to move ahead for each iteration. */ + + var candidate int + assert(next_emit < ip) + + trawl: + for { + var hash uint32 = next_hash + var bytes_between_hash_lookups uint32 = skip >> 5 + skip++ + assert(hash == hash5(in[next_ip:], shift)) + ip = next_ip + next_ip = int(uint32(ip) + bytes_between_hash_lookups) + if next_ip > ip_limit { + goto emit_remainder + } + + next_hash = hash5(in[next_ip:], shift) + candidate = ip - last_distance + if isMatch5(in[ip:], in[candidate:]) { + if candidate < ip { + table[hash] = int(ip - base_ip) + break + } + } + + candidate = base_ip + table[hash] + assert(candidate >= base_ip) + assert(candidate < ip) + + table[hash] = int(ip - base_ip) + if isMatch5(in[ip:], in[candidate:]) { + break + } + } + + /* Check copy distance. If candidate is not feasible, continue search. + Checking is done outside of hot loop to reduce overhead. */ + if ip-candidate > maxDistance_compress_fragment { + goto trawl + } + + /* Step 2: Emit the found match together with the literal bytes from + "next_emit" to the bit stream, and then see if we can find a next match + immediately afterwards. Repeat until we find no match for the input + without emitting some literal bytes. */ + { + var base int = ip + /* > 0 */ + var matched uint = 5 + findMatchLengthWithLimit(in[candidate+5:], in[ip+5:], uint(ip_end-ip)-5) + var distance int = int(base - candidate) + /* We have a 5-byte match at ip, and we need to emit bytes in + [next_emit, ip). */ + + var insert uint = uint(base - next_emit) + ip += int(matched) + if insert < 6210 { + emitInsertLen1(insert, cmd_depth, cmd_bits, cmd_histo[:], storage_ix, storage) + } else if shouldUseUncompressedMode(in[metablock_start:], in[next_emit:], insert, literal_ratio) { + emitUncompressedMetaBlock1(in[metablock_start:], in[base:], mlen_storage_ix-3, storage_ix, storage) + input_size -= uint(base - input) + input = base + next_emit = input + goto next_block + } else { + emitLongInsertLen(insert, cmd_depth, cmd_bits, cmd_histo[:], storage_ix, storage) + } + + emitLiterals(in[next_emit:], insert, lit_depth[:], lit_bits[:], storage_ix, storage) + if distance == last_distance { + writeBits(uint(cmd_depth[64]), uint64(cmd_bits[64]), storage_ix, storage) + cmd_histo[64]++ + } else { + emitDistance1(uint(distance), cmd_depth, cmd_bits, cmd_histo[:], storage_ix, storage) + last_distance = distance + } + + emitCopyLenLastDistance1(matched, cmd_depth, cmd_bits, cmd_histo[:], storage_ix, storage) + + next_emit = ip + if ip >= ip_limit { + goto emit_remainder + } + + /* We could immediately start working at ip now, but to improve + compression we first update "table" with the hashes of some positions + within the last copy. */ + { + var input_bytes uint64 = binary.LittleEndian.Uint64(in[ip-3:]) + var prev_hash uint32 = hashBytesAtOffset5(input_bytes, 0, shift) + var cur_hash uint32 = hashBytesAtOffset5(input_bytes, 3, shift) + table[prev_hash] = int(ip - base_ip - 3) + prev_hash = hashBytesAtOffset5(input_bytes, 1, shift) + table[prev_hash] = int(ip - base_ip - 2) + prev_hash = hashBytesAtOffset5(input_bytes, 2, shift) + table[prev_hash] = int(ip - base_ip - 1) + + candidate = base_ip + table[cur_hash] + table[cur_hash] = int(ip - base_ip) + } + } + + for isMatch5(in[ip:], in[candidate:]) { + var base int = ip + /* We have a 5-byte match at ip, and no need to emit any literal bytes + prior to ip. */ + + var matched uint = 5 + findMatchLengthWithLimit(in[candidate+5:], in[ip+5:], uint(ip_end-ip)-5) + if ip-candidate > maxDistance_compress_fragment { + break + } + ip += int(matched) + last_distance = int(base - candidate) /* > 0 */ + emitCopyLen1(matched, cmd_depth, cmd_bits, cmd_histo[:], storage_ix, storage) + emitDistance1(uint(last_distance), cmd_depth, cmd_bits, cmd_histo[:], storage_ix, storage) + + next_emit = ip + if ip >= ip_limit { + goto emit_remainder + } + + /* We could immediately start working at ip now, but to improve + compression we first update "table" with the hashes of some positions + within the last copy. */ + { + var input_bytes uint64 = binary.LittleEndian.Uint64(in[ip-3:]) + var prev_hash uint32 = hashBytesAtOffset5(input_bytes, 0, shift) + var cur_hash uint32 = hashBytesAtOffset5(input_bytes, 3, shift) + table[prev_hash] = int(ip - base_ip - 3) + prev_hash = hashBytesAtOffset5(input_bytes, 1, shift) + table[prev_hash] = int(ip - base_ip - 2) + prev_hash = hashBytesAtOffset5(input_bytes, 2, shift) + table[prev_hash] = int(ip - base_ip - 1) + + candidate = base_ip + table[cur_hash] + table[cur_hash] = int(ip - base_ip) + } + } + + ip++ + next_hash = hash5(in[ip:], shift) + } + } + +emit_remainder: + assert(next_emit <= ip_end) + input += int(block_size) + input_size -= block_size + block_size = brotli_min_size_t(input_size, compressFragmentFastImpl_kMergeBlockSize) + + /* Decide if we want to continue this meta-block instead of emitting the + last insert-only command. */ + if input_size > 0 && total_block_size+block_size <= 1<<20 && shouldMergeBlock(in[input:], block_size, lit_depth[:]) { + assert(total_block_size > 1<<16) + + /* Update the size of the current meta-block and continue emitting commands. + We can do this because the current size and the new size both have 5 + nibbles. */ + total_block_size += block_size + + updateBits(20, uint32(total_block_size-1), mlen_storage_ix, storage) + goto emit_commands + } + + /* Emit the remaining bytes as literals. */ + if next_emit < ip_end { + var insert uint = uint(ip_end - next_emit) + if insert < 6210 { + emitInsertLen1(insert, cmd_depth, cmd_bits, cmd_histo[:], storage_ix, storage) + emitLiterals(in[next_emit:], insert, lit_depth[:], lit_bits[:], storage_ix, storage) + } else if shouldUseUncompressedMode(in[metablock_start:], in[next_emit:], insert, literal_ratio) { + emitUncompressedMetaBlock1(in[metablock_start:], in[ip_end:], mlen_storage_ix-3, storage_ix, storage) + } else { + emitLongInsertLen(insert, cmd_depth, cmd_bits, cmd_histo[:], storage_ix, storage) + emitLiterals(in[next_emit:], insert, lit_depth[:], lit_bits[:], storage_ix, storage) + } + } + + next_emit = ip_end + + /* If we have more data, write a new meta-block header and prefix codes and + then continue emitting commands. */ +next_block: + if input_size > 0 { + metablock_start = input + block_size = brotli_min_size_t(input_size, compressFragmentFastImpl_kFirstBlockSize) + total_block_size = block_size + + /* Save the bit position of the MLEN field of the meta-block header, so that + we can update it later if we decide to extend this meta-block. */ + mlen_storage_ix = *storage_ix + 3 + + storeMetaBlockHeader1(block_size, false, storage_ix, storage) + + /* No block splits, no contexts. */ + writeBits(13, 0, storage_ix, storage) + + literal_ratio = buildAndStoreLiteralPrefixCode(in[input:], block_size, lit_depth[:], lit_bits[:], storage_ix, storage) + buildAndStoreCommandPrefixCode1(cmd_histo[:], cmd_depth, cmd_bits, storage_ix, storage) + goto emit_commands + } + + if !is_last { + /* If this is not the last block, update the command and distance prefix + codes for the next block and store the compressed forms. */ + cmd_code[0] = 0 + + *cmd_code_numbits = 0 + buildAndStoreCommandPrefixCode1(cmd_histo[:], cmd_depth, cmd_bits, cmd_code_numbits, cmd_code) + } +} + +/* Compresses "input" string to the "*storage" buffer as one or more complete + meta-blocks, and updates the "*storage_ix" bit position. + + If "is_last" is 1, emits an additional empty last meta-block. + + "cmd_depth" and "cmd_bits" contain the command and distance prefix codes + (see comment in encode.h) used for the encoding of this input fragment. + If "is_last" is 0, they are updated to reflect the statistics + of this input fragment, to be used for the encoding of the next fragment. + + "*cmd_code_numbits" is the number of bits of the compressed representation + of the command and distance prefix codes, and "cmd_code" is an array of + at least "(*cmd_code_numbits + 7) >> 3" size that contains the compressed + command and distance prefix codes. If "is_last" is 0, these are also + updated to represent the updated "cmd_depth" and "cmd_bits". + + REQUIRES: "input_size" is greater than zero, or "is_last" is 1. + REQUIRES: "input_size" is less or equal to maximal metablock size (1 << 24). + REQUIRES: All elements in "table[0..table_size-1]" are initialized to zero. + REQUIRES: "table_size" is an odd (9, 11, 13, 15) power of two + OUTPUT: maximal copy distance <= |input_size| + OUTPUT: maximal copy distance <= BROTLI_MAX_BACKWARD_LIMIT(18) */ +func compressFragmentFast(input []byte, input_size uint, is_last bool, table []int, table_size uint, cmd_depth []byte, cmd_bits []uint16, cmd_code_numbits *uint, cmd_code []byte, storage_ix *uint, storage []byte) { + var initial_storage_ix uint = *storage_ix + var table_bits uint = uint(log2FloorNonZero(table_size)) + + if input_size == 0 { + assert(is_last) + writeBits(1, 1, storage_ix, storage) /* islast */ + writeBits(1, 1, storage_ix, storage) /* isempty */ + *storage_ix = (*storage_ix + 7) &^ 7 + return + } + + compressFragmentFastImpl(input, input_size, is_last, table, table_bits, cmd_depth, cmd_bits, cmd_code_numbits, cmd_code, storage_ix, storage) + + /* If output is larger than single uncompressed block, rewrite it. */ + if *storage_ix-initial_storage_ix > 31+(input_size<<3) { + emitUncompressedMetaBlock1(input, input[input_size:], initial_storage_ix, storage_ix, storage) + } + + if is_last { + writeBits(1, 1, storage_ix, storage) /* islast */ + writeBits(1, 1, storage_ix, storage) /* isempty */ + *storage_ix = (*storage_ix + 7) &^ 7 + } +} diff --git a/vendor/github.com/andybalholm/brotli/compress_fragment_two_pass.go b/vendor/github.com/andybalholm/brotli/compress_fragment_two_pass.go new file mode 100644 index 0000000..172dc7f --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/compress_fragment_two_pass.go @@ -0,0 +1,748 @@ +package brotli + +import "encoding/binary" + +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Function for fast encoding of an input fragment, independently from the input + history. This function uses two-pass processing: in the first pass we save + the found backward matches and literal bytes into a buffer, and in the + second pass we emit them into the bit stream using prefix codes built based + on the actual command and literal byte histograms. */ + +const kCompressFragmentTwoPassBlockSize uint = 1 << 17 + +func hash1(p []byte, shift uint, length uint) uint32 { + var h uint64 = (binary.LittleEndian.Uint64(p) << ((8 - length) * 8)) * uint64(kHashMul32) + return uint32(h >> shift) +} + +func hashBytesAtOffset(v uint64, offset uint, shift uint, length uint) uint32 { + assert(offset <= 8-length) + { + var h uint64 = ((v >> (8 * offset)) << ((8 - length) * 8)) * uint64(kHashMul32) + return uint32(h >> shift) + } +} + +func isMatch1(p1 []byte, p2 []byte, length uint) bool { + if binary.LittleEndian.Uint32(p1) != binary.LittleEndian.Uint32(p2) { + return false + } + if length == 4 { + return true + } + return p1[4] == p2[4] && p1[5] == p2[5] +} + +/* Builds a command and distance prefix code (each 64 symbols) into "depth" and + "bits" based on "histogram" and stores it into the bit stream. */ +func buildAndStoreCommandPrefixCode(histogram []uint32, depth []byte, bits []uint16, storage_ix *uint, storage []byte) { + var tree [129]huffmanTree + var cmd_depth = [numCommandSymbols]byte{0} + /* Tree size for building a tree over 64 symbols is 2 * 64 + 1. */ + + var cmd_bits [64]uint16 + createHuffmanTree(histogram, 64, 15, tree[:], depth) + createHuffmanTree(histogram[64:], 64, 14, tree[:], depth[64:]) + + /* We have to jump through a few hoops here in order to compute + the command bits because the symbols are in a different order than in + the full alphabet. This looks complicated, but having the symbols + in this order in the command bits saves a few branches in the Emit* + functions. */ + copy(cmd_depth[:], depth[24:][:24]) + + copy(cmd_depth[24:][:], depth[:8]) + copy(cmd_depth[32:][:], depth[48:][:8]) + copy(cmd_depth[40:][:], depth[8:][:8]) + copy(cmd_depth[48:][:], depth[56:][:8]) + copy(cmd_depth[56:][:], depth[16:][:8]) + convertBitDepthsToSymbols(cmd_depth[:], 64, cmd_bits[:]) + copy(bits, cmd_bits[24:][:8]) + copy(bits[8:], cmd_bits[40:][:8]) + copy(bits[16:], cmd_bits[56:][:8]) + copy(bits[24:], cmd_bits[:24]) + copy(bits[48:], cmd_bits[32:][:8]) + copy(bits[56:], cmd_bits[48:][:8]) + convertBitDepthsToSymbols(depth[64:], 64, bits[64:]) + { + /* Create the bit length array for the full command alphabet. */ + var i uint + for i := 0; i < int(64); i++ { + cmd_depth[i] = 0 + } /* only 64 first values were used */ + copy(cmd_depth[:], depth[24:][:8]) + copy(cmd_depth[64:][:], depth[32:][:8]) + copy(cmd_depth[128:][:], depth[40:][:8]) + copy(cmd_depth[192:][:], depth[48:][:8]) + copy(cmd_depth[384:][:], depth[56:][:8]) + for i = 0; i < 8; i++ { + cmd_depth[128+8*i] = depth[i] + cmd_depth[256+8*i] = depth[8+i] + cmd_depth[448+8*i] = depth[16+i] + } + + storeHuffmanTree(cmd_depth[:], numCommandSymbols, tree[:], storage_ix, storage) + } + + storeHuffmanTree(depth[64:], 64, tree[:], storage_ix, storage) +} + +func emitInsertLen(insertlen uint32, commands *[]uint32) { + if insertlen < 6 { + (*commands)[0] = insertlen + } else if insertlen < 130 { + var tail uint32 = insertlen - 2 + var nbits uint32 = log2FloorNonZero(uint(tail)) - 1 + var prefix uint32 = tail >> nbits + var inscode uint32 = (nbits << 1) + prefix + 2 + var extra uint32 = tail - (prefix << nbits) + (*commands)[0] = inscode | extra<<8 + } else if insertlen < 2114 { + var tail uint32 = insertlen - 66 + var nbits uint32 = log2FloorNonZero(uint(tail)) + var code uint32 = nbits + 10 + var extra uint32 = tail - (1 << nbits) + (*commands)[0] = code | extra<<8 + } else if insertlen < 6210 { + var extra uint32 = insertlen - 2114 + (*commands)[0] = 21 | extra<<8 + } else if insertlen < 22594 { + var extra uint32 = insertlen - 6210 + (*commands)[0] = 22 | extra<<8 + } else { + var extra uint32 = insertlen - 22594 + (*commands)[0] = 23 | extra<<8 + } + + *commands = (*commands)[1:] +} + +func emitCopyLen(copylen uint, commands *[]uint32) { + if copylen < 10 { + (*commands)[0] = uint32(copylen + 38) + } else if copylen < 134 { + var tail uint = copylen - 6 + var nbits uint = uint(log2FloorNonZero(tail) - 1) + var prefix uint = tail >> nbits + var code uint = (nbits << 1) + prefix + 44 + var extra uint = tail - (prefix << nbits) + (*commands)[0] = uint32(code | extra<<8) + } else if copylen < 2118 { + var tail uint = copylen - 70 + var nbits uint = uint(log2FloorNonZero(tail)) + var code uint = nbits + 52 + var extra uint = tail - (uint(1) << nbits) + (*commands)[0] = uint32(code | extra<<8) + } else { + var extra uint = copylen - 2118 + (*commands)[0] = uint32(63 | extra<<8) + } + + *commands = (*commands)[1:] +} + +func emitCopyLenLastDistance(copylen uint, commands *[]uint32) { + if copylen < 12 { + (*commands)[0] = uint32(copylen + 20) + *commands = (*commands)[1:] + } else if copylen < 72 { + var tail uint = copylen - 8 + var nbits uint = uint(log2FloorNonZero(tail) - 1) + var prefix uint = tail >> nbits + var code uint = (nbits << 1) + prefix + 28 + var extra uint = tail - (prefix << nbits) + (*commands)[0] = uint32(code | extra<<8) + *commands = (*commands)[1:] + } else if copylen < 136 { + var tail uint = copylen - 8 + var code uint = (tail >> 5) + 54 + var extra uint = tail & 31 + (*commands)[0] = uint32(code | extra<<8) + *commands = (*commands)[1:] + (*commands)[0] = 64 + *commands = (*commands)[1:] + } else if copylen < 2120 { + var tail uint = copylen - 72 + var nbits uint = uint(log2FloorNonZero(tail)) + var code uint = nbits + 52 + var extra uint = tail - (uint(1) << nbits) + (*commands)[0] = uint32(code | extra<<8) + *commands = (*commands)[1:] + (*commands)[0] = 64 + *commands = (*commands)[1:] + } else { + var extra uint = copylen - 2120 + (*commands)[0] = uint32(63 | extra<<8) + *commands = (*commands)[1:] + (*commands)[0] = 64 + *commands = (*commands)[1:] + } +} + +func emitDistance(distance uint32, commands *[]uint32) { + var d uint32 = distance + 3 + var nbits uint32 = log2FloorNonZero(uint(d)) - 1 + var prefix uint32 = (d >> nbits) & 1 + var offset uint32 = (2 + prefix) << nbits + var distcode uint32 = 2*(nbits-1) + prefix + 80 + var extra uint32 = d - offset + (*commands)[0] = distcode | extra<<8 + *commands = (*commands)[1:] +} + +/* REQUIRES: len <= 1 << 24. */ +func storeMetaBlockHeader(len uint, is_uncompressed bool, storage_ix *uint, storage []byte) { + var nibbles uint = 6 + + /* ISLAST */ + writeBits(1, 0, storage_ix, storage) + + if len <= 1<<16 { + nibbles = 4 + } else if len <= 1<<20 { + nibbles = 5 + } + + writeBits(2, uint64(nibbles)-4, storage_ix, storage) + writeBits(nibbles*4, uint64(len)-1, storage_ix, storage) + + /* ISUNCOMPRESSED */ + writeSingleBit(is_uncompressed, storage_ix, storage) +} + +func createCommands(input []byte, block_size uint, input_size uint, base_ip_ptr []byte, table []int, table_bits uint, min_match uint, literals *[]byte, commands *[]uint32) { + var ip int = 0 + var shift uint = 64 - table_bits + var ip_end int = int(block_size) + var base_ip int = -cap(base_ip_ptr) + cap(input) + var next_emit int = 0 + var last_distance int = -1 + /* "ip" is the input pointer. */ + + const kInputMarginBytes uint = windowGap + + /* "next_emit" is a pointer to the first byte that is not covered by a + previous copy. Bytes between "next_emit" and the start of the next copy or + the end of the input will be emitted as literal bytes. */ + if block_size >= kInputMarginBytes { + var len_limit uint = brotli_min_size_t(block_size-min_match, input_size-kInputMarginBytes) + var ip_limit int = int(len_limit) + /* For the last block, we need to keep a 16 bytes margin so that we can be + sure that all distances are at most window size - 16. + For all other blocks, we only need to keep a margin of 5 bytes so that + we don't go over the block size with a copy. */ + + var next_hash uint32 + ip++ + for next_hash = hash1(input[ip:], shift, min_match); ; { + var skip uint32 = 32 + var next_ip int = ip + /* Step 1: Scan forward in the input looking for a 6-byte-long match. + If we get close to exhausting the input then goto emit_remainder. + + Heuristic match skipping: If 32 bytes are scanned with no matches + found, start looking only at every other byte. If 32 more bytes are + scanned, look at every third byte, etc.. When a match is found, + immediately go back to looking at every byte. This is a small loss + (~5% performance, ~0.1% density) for compressible data due to more + bookkeeping, but for non-compressible data (such as JPEG) it's a huge + win since the compressor quickly "realizes" the data is incompressible + and doesn't bother looking for matches everywhere. + + The "skip" variable keeps track of how many bytes there are since the + last match; dividing it by 32 (ie. right-shifting by five) gives the + number of bytes to move ahead for each iteration. */ + + var candidate int + + assert(next_emit < ip) + + trawl: + for { + var hash uint32 = next_hash + var bytes_between_hash_lookups uint32 = skip >> 5 + skip++ + ip = next_ip + assert(hash == hash1(input[ip:], shift, min_match)) + next_ip = int(uint32(ip) + bytes_between_hash_lookups) + if next_ip > ip_limit { + goto emit_remainder + } + + next_hash = hash1(input[next_ip:], shift, min_match) + candidate = ip - last_distance + if isMatch1(input[ip:], base_ip_ptr[candidate-base_ip:], min_match) { + if candidate < ip { + table[hash] = int(ip - base_ip) + break + } + } + + candidate = base_ip + table[hash] + assert(candidate >= base_ip) + assert(candidate < ip) + + table[hash] = int(ip - base_ip) + if isMatch1(input[ip:], base_ip_ptr[candidate-base_ip:], min_match) { + break + } + } + + /* Check copy distance. If candidate is not feasible, continue search. + Checking is done outside of hot loop to reduce overhead. */ + if ip-candidate > maxDistance_compress_fragment { + goto trawl + } + + /* Step 2: Emit the found match together with the literal bytes from + "next_emit", and then see if we can find a next match immediately + afterwards. Repeat until we find no match for the input + without emitting some literal bytes. */ + { + var base int = ip + /* > 0 */ + var matched uint = min_match + findMatchLengthWithLimit(base_ip_ptr[uint(candidate-base_ip)+min_match:], input[uint(ip)+min_match:], uint(ip_end-ip)-min_match) + var distance int = int(base - candidate) + /* We have a 6-byte match at ip, and we need to emit bytes in + [next_emit, ip). */ + + var insert int = int(base - next_emit) + ip += int(matched) + emitInsertLen(uint32(insert), commands) + copy(*literals, input[next_emit:][:uint(insert)]) + *literals = (*literals)[insert:] + if distance == last_distance { + (*commands)[0] = 64 + *commands = (*commands)[1:] + } else { + emitDistance(uint32(distance), commands) + last_distance = distance + } + + emitCopyLenLastDistance(matched, commands) + + next_emit = ip + if ip >= ip_limit { + goto emit_remainder + } + { + var input_bytes uint64 + var cur_hash uint32 + /* We could immediately start working at ip now, but to improve + compression we first update "table" with the hashes of some + positions within the last copy. */ + + var prev_hash uint32 + if min_match == 4 { + input_bytes = binary.LittleEndian.Uint64(input[ip-3:]) + cur_hash = hashBytesAtOffset(input_bytes, 3, shift, min_match) + prev_hash = hashBytesAtOffset(input_bytes, 0, shift, min_match) + table[prev_hash] = int(ip - base_ip - 3) + prev_hash = hashBytesAtOffset(input_bytes, 1, shift, min_match) + table[prev_hash] = int(ip - base_ip - 2) + prev_hash = hashBytesAtOffset(input_bytes, 0, shift, min_match) + table[prev_hash] = int(ip - base_ip - 1) + } else { + input_bytes = binary.LittleEndian.Uint64(input[ip-5:]) + prev_hash = hashBytesAtOffset(input_bytes, 0, shift, min_match) + table[prev_hash] = int(ip - base_ip - 5) + prev_hash = hashBytesAtOffset(input_bytes, 1, shift, min_match) + table[prev_hash] = int(ip - base_ip - 4) + prev_hash = hashBytesAtOffset(input_bytes, 2, shift, min_match) + table[prev_hash] = int(ip - base_ip - 3) + input_bytes = binary.LittleEndian.Uint64(input[ip-2:]) + cur_hash = hashBytesAtOffset(input_bytes, 2, shift, min_match) + prev_hash = hashBytesAtOffset(input_bytes, 0, shift, min_match) + table[prev_hash] = int(ip - base_ip - 2) + prev_hash = hashBytesAtOffset(input_bytes, 1, shift, min_match) + table[prev_hash] = int(ip - base_ip - 1) + } + + candidate = base_ip + table[cur_hash] + table[cur_hash] = int(ip - base_ip) + } + } + + for ip-candidate <= maxDistance_compress_fragment && isMatch1(input[ip:], base_ip_ptr[candidate-base_ip:], min_match) { + var base int = ip + /* We have a 6-byte match at ip, and no need to emit any + literal bytes prior to ip. */ + + var matched uint = min_match + findMatchLengthWithLimit(base_ip_ptr[uint(candidate-base_ip)+min_match:], input[uint(ip)+min_match:], uint(ip_end-ip)-min_match) + ip += int(matched) + last_distance = int(base - candidate) /* > 0 */ + emitCopyLen(matched, commands) + emitDistance(uint32(last_distance), commands) + + next_emit = ip + if ip >= ip_limit { + goto emit_remainder + } + { + var input_bytes uint64 + var cur_hash uint32 + /* We could immediately start working at ip now, but to improve + compression we first update "table" with the hashes of some + positions within the last copy. */ + + var prev_hash uint32 + if min_match == 4 { + input_bytes = binary.LittleEndian.Uint64(input[ip-3:]) + cur_hash = hashBytesAtOffset(input_bytes, 3, shift, min_match) + prev_hash = hashBytesAtOffset(input_bytes, 0, shift, min_match) + table[prev_hash] = int(ip - base_ip - 3) + prev_hash = hashBytesAtOffset(input_bytes, 1, shift, min_match) + table[prev_hash] = int(ip - base_ip - 2) + prev_hash = hashBytesAtOffset(input_bytes, 2, shift, min_match) + table[prev_hash] = int(ip - base_ip - 1) + } else { + input_bytes = binary.LittleEndian.Uint64(input[ip-5:]) + prev_hash = hashBytesAtOffset(input_bytes, 0, shift, min_match) + table[prev_hash] = int(ip - base_ip - 5) + prev_hash = hashBytesAtOffset(input_bytes, 1, shift, min_match) + table[prev_hash] = int(ip - base_ip - 4) + prev_hash = hashBytesAtOffset(input_bytes, 2, shift, min_match) + table[prev_hash] = int(ip - base_ip - 3) + input_bytes = binary.LittleEndian.Uint64(input[ip-2:]) + cur_hash = hashBytesAtOffset(input_bytes, 2, shift, min_match) + prev_hash = hashBytesAtOffset(input_bytes, 0, shift, min_match) + table[prev_hash] = int(ip - base_ip - 2) + prev_hash = hashBytesAtOffset(input_bytes, 1, shift, min_match) + table[prev_hash] = int(ip - base_ip - 1) + } + + candidate = base_ip + table[cur_hash] + table[cur_hash] = int(ip - base_ip) + } + } + + ip++ + next_hash = hash1(input[ip:], shift, min_match) + } + } + +emit_remainder: + assert(next_emit <= ip_end) + + /* Emit the remaining bytes as literals. */ + if next_emit < ip_end { + var insert uint32 = uint32(ip_end - next_emit) + emitInsertLen(insert, commands) + copy(*literals, input[next_emit:][:insert]) + *literals = (*literals)[insert:] + } +} + +var storeCommands_kNumExtraBits = [128]uint32{ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 2, + 3, + 3, + 4, + 4, + 5, + 5, + 6, + 7, + 8, + 9, + 10, + 12, + 14, + 24, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 2, + 3, + 3, + 4, + 4, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 2, + 3, + 3, + 4, + 4, + 5, + 5, + 6, + 7, + 8, + 9, + 10, + 24, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 2, + 3, + 3, + 4, + 4, + 5, + 5, + 6, + 6, + 7, + 7, + 8, + 8, + 9, + 9, + 10, + 10, + 11, + 11, + 12, + 12, + 13, + 13, + 14, + 14, + 15, + 15, + 16, + 16, + 17, + 17, + 18, + 18, + 19, + 19, + 20, + 20, + 21, + 21, + 22, + 22, + 23, + 23, + 24, + 24, +} +var storeCommands_kInsertOffset = [24]uint32{ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 8, + 10, + 14, + 18, + 26, + 34, + 50, + 66, + 98, + 130, + 194, + 322, + 578, + 1090, + 2114, + 6210, + 22594, +} + +func storeCommands(literals []byte, num_literals uint, commands []uint32, num_commands uint, storage_ix *uint, storage []byte) { + var lit_depths [256]byte + var lit_bits [256]uint16 + var lit_histo = [256]uint32{0} + var cmd_depths = [128]byte{0} + var cmd_bits = [128]uint16{0} + var cmd_histo = [128]uint32{0} + var i uint + for i = 0; i < num_literals; i++ { + lit_histo[literals[i]]++ + } + + buildAndStoreHuffmanTreeFast(lit_histo[:], num_literals, /* max_bits = */ + 8, lit_depths[:], lit_bits[:], storage_ix, storage) + + for i = 0; i < num_commands; i++ { + var code uint32 = commands[i] & 0xFF + assert(code < 128) + cmd_histo[code]++ + } + + cmd_histo[1] += 1 + cmd_histo[2] += 1 + cmd_histo[64] += 1 + cmd_histo[84] += 1 + buildAndStoreCommandPrefixCode(cmd_histo[:], cmd_depths[:], cmd_bits[:], storage_ix, storage) + + for i = 0; i < num_commands; i++ { + var cmd uint32 = commands[i] + var code uint32 = cmd & 0xFF + var extra uint32 = cmd >> 8 + assert(code < 128) + writeBits(uint(cmd_depths[code]), uint64(cmd_bits[code]), storage_ix, storage) + writeBits(uint(storeCommands_kNumExtraBits[code]), uint64(extra), storage_ix, storage) + if code < 24 { + var insert uint32 = storeCommands_kInsertOffset[code] + extra + var j uint32 + for j = 0; j < insert; j++ { + var lit byte = literals[0] + writeBits(uint(lit_depths[lit]), uint64(lit_bits[lit]), storage_ix, storage) + literals = literals[1:] + } + } + } +} + +/* Acceptable loss for uncompressible speedup is 2% */ +const minRatio = 0.98 + +const sampleRate = 43 + +func shouldCompress(input []byte, input_size uint, num_literals uint) bool { + var corpus_size float64 = float64(input_size) + if float64(num_literals) < minRatio*corpus_size { + return true + } else { + var literal_histo = [256]uint32{0} + var max_total_bit_cost float64 = corpus_size * 8 * minRatio / sampleRate + var i uint + for i = 0; i < input_size; i += sampleRate { + literal_histo[input[i]]++ + } + + return bitsEntropy(literal_histo[:], 256) < max_total_bit_cost + } +} + +func rewindBitPosition(new_storage_ix uint, storage_ix *uint, storage []byte) { + var bitpos uint = new_storage_ix & 7 + var mask uint = (1 << bitpos) - 1 + storage[new_storage_ix>>3] &= byte(mask) + *storage_ix = new_storage_ix +} + +func emitUncompressedMetaBlock(input []byte, input_size uint, storage_ix *uint, storage []byte) { + storeMetaBlockHeader(input_size, true, storage_ix, storage) + *storage_ix = (*storage_ix + 7) &^ 7 + copy(storage[*storage_ix>>3:], input[:input_size]) + *storage_ix += input_size << 3 + storage[*storage_ix>>3] = 0 +} + +func compressFragmentTwoPassImpl(input []byte, input_size uint, is_last bool, command_buf []uint32, literal_buf []byte, table []int, table_bits uint, min_match uint, storage_ix *uint, storage []byte) { + /* Save the start of the first block for position and distance computations. + */ + var base_ip []byte = input + + for input_size > 0 { + var block_size uint = brotli_min_size_t(input_size, kCompressFragmentTwoPassBlockSize) + var commands []uint32 = command_buf + var literals []byte = literal_buf + var num_literals uint + createCommands(input, block_size, input_size, base_ip, table, table_bits, min_match, &literals, &commands) + num_literals = uint(-cap(literals) + cap(literal_buf)) + if shouldCompress(input, block_size, num_literals) { + var num_commands uint = uint(-cap(commands) + cap(command_buf)) + storeMetaBlockHeader(block_size, false, storage_ix, storage) + + /* No block splits, no contexts. */ + writeBits(13, 0, storage_ix, storage) + + storeCommands(literal_buf, num_literals, command_buf, num_commands, storage_ix, storage) + } else { + /* Since we did not find many backward references and the entropy of + the data is close to 8 bits, we can simply emit an uncompressed block. + This makes compression speed of uncompressible data about 3x faster. */ + emitUncompressedMetaBlock(input, block_size, storage_ix, storage) + } + + input = input[block_size:] + input_size -= block_size + } +} + +/* Compresses "input" string to the "*storage" buffer as one or more complete + meta-blocks, and updates the "*storage_ix" bit position. + + If "is_last" is 1, emits an additional empty last meta-block. + + REQUIRES: "input_size" is greater than zero, or "is_last" is 1. + REQUIRES: "input_size" is less or equal to maximal metablock size (1 << 24). + REQUIRES: "command_buf" and "literal_buf" point to at least + kCompressFragmentTwoPassBlockSize long arrays. + REQUIRES: All elements in "table[0..table_size-1]" are initialized to zero. + REQUIRES: "table_size" is a power of two + OUTPUT: maximal copy distance <= |input_size| + OUTPUT: maximal copy distance <= BROTLI_MAX_BACKWARD_LIMIT(18) */ +func compressFragmentTwoPass(input []byte, input_size uint, is_last bool, command_buf []uint32, literal_buf []byte, table []int, table_size uint, storage_ix *uint, storage []byte) { + var initial_storage_ix uint = *storage_ix + var table_bits uint = uint(log2FloorNonZero(table_size)) + var min_match uint + if table_bits <= 15 { + min_match = 4 + } else { + min_match = 6 + } + compressFragmentTwoPassImpl(input, input_size, is_last, command_buf, literal_buf, table, table_bits, min_match, storage_ix, storage) + + /* If output is larger than single uncompressed block, rewrite it. */ + if *storage_ix-initial_storage_ix > 31+(input_size<<3) { + rewindBitPosition(initial_storage_ix, storage_ix, storage) + emitUncompressedMetaBlock(input, input_size, storage_ix, storage) + } + + if is_last { + writeBits(1, 1, storage_ix, storage) /* islast */ + writeBits(1, 1, storage_ix, storage) /* isempty */ + *storage_ix = (*storage_ix + 7) &^ 7 + } +} diff --git a/vendor/github.com/andybalholm/brotli/constants.go b/vendor/github.com/andybalholm/brotli/constants.go new file mode 100644 index 0000000..a880dff --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/constants.go @@ -0,0 +1,77 @@ +package brotli + +/* Copyright 2016 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Specification: 7.3. Encoding of the context map */ +const contextMapMaxRle = 16 + +/* Specification: 2. Compressed representation overview */ +const maxNumberOfBlockTypes = 256 + +/* Specification: 3.3. Alphabet sizes: insert-and-copy length */ +const numLiteralSymbols = 256 + +const numCommandSymbols = 704 + +const numBlockLenSymbols = 26 + +const maxContextMapSymbols = (maxNumberOfBlockTypes + contextMapMaxRle) + +const maxBlockTypeSymbols = (maxNumberOfBlockTypes + 2) + +/* Specification: 3.5. Complex prefix codes */ +const repeatPreviousCodeLength = 16 + +const repeatZeroCodeLength = 17 + +const codeLengthCodes = (repeatZeroCodeLength + 1) + +/* "code length of 8 is repeated" */ +const initialRepeatedCodeLength = 8 + +/* "Large Window Brotli" */ +const largeMaxDistanceBits = 62 + +const largeMinWbits = 10 + +const largeMaxWbits = 30 + +/* Specification: 4. Encoding of distances */ +const numDistanceShortCodes = 16 + +const maxNpostfix = 3 + +const maxNdirect = 120 + +const maxDistanceBits = 24 + +func distanceAlphabetSize(NPOSTFIX uint, NDIRECT uint, MAXNBITS uint) uint { + return numDistanceShortCodes + NDIRECT + uint(MAXNBITS<<(NPOSTFIX+1)) +} + +/* numDistanceSymbols == 1128 */ +const numDistanceSymbols = 1128 + +const maxDistance = 0x3FFFFFC + +const maxAllowedDistance = 0x7FFFFFFC + +/* 7.1. Context modes and context ID lookup for literals */ +/* "context IDs for literals are in the range of 0..63" */ +const literalContextBits = 6 + +/* 7.2. Context ID for distances */ +const distanceContextBits = 2 + +/* 9.1. Format of the Stream Header */ +/* Number of slack bytes for window size. Don't confuse + with BROTLI_NUM_DISTANCE_SHORT_CODES. */ +const windowGap = 16 + +func maxBackwardLimit(W uint) uint { + return (uint(1) << W) - windowGap +} diff --git a/vendor/github.com/andybalholm/brotli/context.go b/vendor/github.com/andybalholm/brotli/context.go new file mode 100644 index 0000000..884ff8a --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/context.go @@ -0,0 +1,2176 @@ +package brotli + +/* Lookup table to map the previous two bytes to a context id. + +There are four different context modeling modes defined here: + contextLSB6: context id is the least significant 6 bits of the last byte, + contextMSB6: context id is the most significant 6 bits of the last byte, + contextUTF8: second-order context model tuned for UTF8-encoded text, + contextSigned: second-order context model tuned for signed integers. + +If |p1| and |p2| are the previous two bytes, and |mode| is current context +mode, we calculate the context as: + + context = ContextLut(mode)[p1] | ContextLut(mode)[p2 + 256]. + +For contextUTF8 mode, if the previous two bytes are ASCII characters +(i.e. < 128), this will be equivalent to + + context = 4 * context1(p1) + context2(p2), + +where context1 is based on the previous byte in the following way: + + 0 : non-ASCII control + 1 : \t, \n, \r + 2 : space + 3 : other punctuation + 4 : " ' + 5 : % + 6 : ( < [ { + 7 : ) > ] } + 8 : , ; : + 9 : . + 10 : = + 11 : number + 12 : upper-case vowel + 13 : upper-case consonant + 14 : lower-case vowel + 15 : lower-case consonant + +and context2 is based on the second last byte: + + 0 : control, space + 1 : punctuation + 2 : upper-case letter, number + 3 : lower-case letter + +If the last byte is ASCII, and the second last byte is not (in a valid UTF8 +stream it will be a continuation byte, value between 128 and 191), the +context is the same as if the second last byte was an ASCII control or space. + +If the last byte is a UTF8 lead byte (value >= 192), then the next byte will +be a continuation byte and the context id is 2 or 3 depending on the LSB of +the last byte and to a lesser extent on the second last byte if it is ASCII. + +If the last byte is a UTF8 continuation byte, the second last byte can be: + - continuation byte: the next byte is probably ASCII or lead byte (assuming + 4-byte UTF8 characters are rare) and the context id is 0 or 1. + - lead byte (192 - 207): next byte is ASCII or lead byte, context is 0 or 1 + - lead byte (208 - 255): next byte is continuation byte, context is 2 or 3 + +The possible value combinations of the previous two bytes, the range of +context ids and the type of the next byte is summarized in the table below: + +|--------\-----------------------------------------------------------------| +| \ Last byte | +| Second \---------------------------------------------------------------| +| last byte \ ASCII | cont. byte | lead byte | +| \ (0-127) | (128-191) | (192-) | +|=============|===================|=====================|==================| +| ASCII | next: ASCII/lead | not valid | next: cont. | +| (0-127) | context: 4 - 63 | | context: 2 - 3 | +|-------------|-------------------|---------------------|------------------| +| cont. byte | next: ASCII/lead | next: ASCII/lead | next: cont. | +| (128-191) | context: 4 - 63 | context: 0 - 1 | context: 2 - 3 | +|-------------|-------------------|---------------------|------------------| +| lead byte | not valid | next: ASCII/lead | not valid | +| (192-207) | | context: 0 - 1 | | +|-------------|-------------------|---------------------|------------------| +| lead byte | not valid | next: cont. | not valid | +| (208-) | | context: 2 - 3 | | +|-------------|-------------------|---------------------|------------------| +*/ + +const ( + contextLSB6 = 0 + contextMSB6 = 1 + contextUTF8 = 2 + contextSigned = 3 +) + +/* Common context lookup table for all context modes. */ +var kContextLookup = [2048]byte{ + /* CONTEXT_LSB6, last byte. */ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + + /* CONTEXT_LSB6, second last byte, */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* CONTEXT_MSB6, last byte. */ + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 2, + 2, + 2, + 2, + 3, + 3, + 3, + 3, + 4, + 4, + 4, + 4, + 5, + 5, + 5, + 5, + 6, + 6, + 6, + 6, + 7, + 7, + 7, + 7, + 8, + 8, + 8, + 8, + 9, + 9, + 9, + 9, + 10, + 10, + 10, + 10, + 11, + 11, + 11, + 11, + 12, + 12, + 12, + 12, + 13, + 13, + 13, + 13, + 14, + 14, + 14, + 14, + 15, + 15, + 15, + 15, + 16, + 16, + 16, + 16, + 17, + 17, + 17, + 17, + 18, + 18, + 18, + 18, + 19, + 19, + 19, + 19, + 20, + 20, + 20, + 20, + 21, + 21, + 21, + 21, + 22, + 22, + 22, + 22, + 23, + 23, + 23, + 23, + 24, + 24, + 24, + 24, + 25, + 25, + 25, + 25, + 26, + 26, + 26, + 26, + 27, + 27, + 27, + 27, + 28, + 28, + 28, + 28, + 29, + 29, + 29, + 29, + 30, + 30, + 30, + 30, + 31, + 31, + 31, + 31, + 32, + 32, + 32, + 32, + 33, + 33, + 33, + 33, + 34, + 34, + 34, + 34, + 35, + 35, + 35, + 35, + 36, + 36, + 36, + 36, + 37, + 37, + 37, + 37, + 38, + 38, + 38, + 38, + 39, + 39, + 39, + 39, + 40, + 40, + 40, + 40, + 41, + 41, + 41, + 41, + 42, + 42, + 42, + 42, + 43, + 43, + 43, + 43, + 44, + 44, + 44, + 44, + 45, + 45, + 45, + 45, + 46, + 46, + 46, + 46, + 47, + 47, + 47, + 47, + 48, + 48, + 48, + 48, + 49, + 49, + 49, + 49, + 50, + 50, + 50, + 50, + 51, + 51, + 51, + 51, + 52, + 52, + 52, + 52, + 53, + 53, + 53, + 53, + 54, + 54, + 54, + 54, + 55, + 55, + 55, + 55, + 56, + 56, + 56, + 56, + 57, + 57, + 57, + 57, + 58, + 58, + 58, + 58, + 59, + 59, + 59, + 59, + 60, + 60, + 60, + 60, + 61, + 61, + 61, + 61, + 62, + 62, + 62, + 62, + 63, + 63, + 63, + 63, + + /* CONTEXT_MSB6, second last byte, */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* CONTEXT_UTF8, last byte. */ + /* ASCII range. */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 4, + 4, + 0, + 0, + 4, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8, + 12, + 16, + 12, + 12, + 20, + 12, + 16, + 24, + 28, + 12, + 12, + 32, + 12, + 36, + 12, + 44, + 44, + 44, + 44, + 44, + 44, + 44, + 44, + 44, + 44, + 32, + 32, + 24, + 40, + 28, + 12, + 12, + 48, + 52, + 52, + 52, + 48, + 52, + 52, + 52, + 48, + 52, + 52, + 52, + 52, + 52, + 48, + 52, + 52, + 52, + 52, + 52, + 48, + 52, + 52, + 52, + 52, + 52, + 24, + 12, + 28, + 12, + 12, + 12, + 56, + 60, + 60, + 60, + 56, + 60, + 60, + 60, + 56, + 60, + 60, + 60, + 60, + 60, + 56, + 60, + 60, + 60, + 60, + 60, + 56, + 60, + 60, + 60, + 60, + 60, + 24, + 12, + 28, + 12, + 0, + + /* UTF8 continuation byte range. */ + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + + /* UTF8 lead byte range. */ + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + 2, + 3, + + /* CONTEXT_UTF8 second last byte. */ + /* ASCII range. */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 1, + 1, + 1, + 1, + 1, + 1, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 1, + 1, + 1, + 1, + 0, + + /* UTF8 continuation byte range. */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* UTF8 lead byte range. */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + + /* CONTEXT_SIGNED, last byte, same as the above values shifted by 3 bits. */ + 0, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 40, + 48, + 48, + 48, + 48, + 48, + 48, + 48, + 48, + 48, + 48, + 48, + 48, + 48, + 48, + 48, + 56, + + /* CONTEXT_SIGNED, second last byte. */ + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 7, +} + +type contextLUT []byte + +func getContextLUT(mode int) contextLUT { + return kContextLookup[mode<<9:] +} + +func getContext(p1 byte, p2 byte, lut contextLUT) byte { + return lut[p1] | lut[256+int(p2)] +} diff --git a/vendor/github.com/andybalholm/brotli/decode.go b/vendor/github.com/andybalholm/brotli/decode.go new file mode 100644 index 0000000..9d9513b --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/decode.go @@ -0,0 +1,2581 @@ +package brotli + +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +const ( + decoderResultError = 0 + decoderResultSuccess = 1 + decoderResultNeedsMoreInput = 2 + decoderResultNeedsMoreOutput = 3 +) + +/** + * Error code for detailed logging / production debugging. + * + * See ::BrotliDecoderGetErrorCode and ::BROTLI_LAST_ERROR_CODE. + */ +const ( + decoderNoError = 0 + decoderSuccess = 1 + decoderNeedsMoreInput = 2 + decoderNeedsMoreOutput = 3 + decoderErrorFormatExuberantNibble = -1 + decoderErrorFormatReserved = -2 + decoderErrorFormatExuberantMetaNibble = -3 + decoderErrorFormatSimpleHuffmanAlphabet = -4 + decoderErrorFormatSimpleHuffmanSame = -5 + decoderErrorFormatClSpace = -6 + decoderErrorFormatHuffmanSpace = -7 + decoderErrorFormatContextMapRepeat = -8 + decoderErrorFormatBlockLength1 = -9 + decoderErrorFormatBlockLength2 = -10 + decoderErrorFormatTransform = -11 + decoderErrorFormatDictionary = -12 + decoderErrorFormatWindowBits = -13 + decoderErrorFormatPadding1 = -14 + decoderErrorFormatPadding2 = -15 + decoderErrorFormatDistance = -16 + decoderErrorDictionaryNotSet = -19 + decoderErrorInvalidArguments = -20 + decoderErrorAllocContextModes = -21 + decoderErrorAllocTreeGroups = -22 + decoderErrorAllocContextMap = -25 + decoderErrorAllocRingBuffer1 = -26 + decoderErrorAllocRingBuffer2 = -27 + decoderErrorAllocBlockTypeTrees = -30 + decoderErrorUnreachable = -31 +) + +const huffmanTableBits = 8 + +const huffmanTableMask = 0xFF + +/* We need the slack region for the following reasons: + - doing up to two 16-byte copies for fast backward copying + - inserting transformed dictionary word (5 prefix + 24 base + 8 suffix) */ +const kRingBufferWriteAheadSlack uint32 = 42 + +var kCodeLengthCodeOrder = [codeLengthCodes]byte{1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15} + +/* Static prefix code for the complex code length code lengths. */ +var kCodeLengthPrefixLength = [16]byte{2, 2, 2, 3, 2, 2, 2, 4, 2, 2, 2, 3, 2, 2, 2, 4} + +var kCodeLengthPrefixValue = [16]byte{0, 4, 3, 2, 0, 4, 3, 1, 0, 4, 3, 2, 0, 4, 3, 5} + +/* Saves error code and converts it to BrotliDecoderResult. */ +func saveErrorCode(s *Reader, e int) int { + s.error_code = int(e) + switch e { + case decoderSuccess: + return decoderResultSuccess + + case decoderNeedsMoreInput: + return decoderResultNeedsMoreInput + + case decoderNeedsMoreOutput: + return decoderResultNeedsMoreOutput + + default: + return decoderResultError + } +} + +/* Decodes WBITS by reading 1 - 7 bits, or 0x11 for "Large Window Brotli". + Precondition: bit-reader accumulator has at least 8 bits. */ +func decodeWindowBits(s *Reader, br *bitReader) int { + var n uint32 + var large_window bool = s.large_window + s.large_window = false + takeBits(br, 1, &n) + if n == 0 { + s.window_bits = 16 + return decoderSuccess + } + + takeBits(br, 3, &n) + if n != 0 { + s.window_bits = 17 + n + return decoderSuccess + } + + takeBits(br, 3, &n) + if n == 1 { + if large_window { + takeBits(br, 1, &n) + if n == 1 { + return decoderErrorFormatWindowBits + } + + s.large_window = true + return decoderSuccess + } else { + return decoderErrorFormatWindowBits + } + } + + if n != 0 { + s.window_bits = 8 + n + return decoderSuccess + } + + s.window_bits = 17 + return decoderSuccess +} + +/* Decodes a number in the range [0..255], by reading 1 - 11 bits. */ +func decodeVarLenUint8(s *Reader, br *bitReader, value *uint32) int { + var bits uint32 + switch s.substate_decode_uint8 { + case stateDecodeUint8None: + if !safeReadBits(br, 1, &bits) { + return decoderNeedsMoreInput + } + + if bits == 0 { + *value = 0 + return decoderSuccess + } + fallthrough + + /* Fall through. */ + case stateDecodeUint8Short: + if !safeReadBits(br, 3, &bits) { + s.substate_decode_uint8 = stateDecodeUint8Short + return decoderNeedsMoreInput + } + + if bits == 0 { + *value = 1 + s.substate_decode_uint8 = stateDecodeUint8None + return decoderSuccess + } + + /* Use output value as a temporary storage. It MUST be persisted. */ + *value = bits + fallthrough + + /* Fall through. */ + case stateDecodeUint8Long: + if !safeReadBits(br, *value, &bits) { + s.substate_decode_uint8 = stateDecodeUint8Long + return decoderNeedsMoreInput + } + + *value = (1 << *value) + bits + s.substate_decode_uint8 = stateDecodeUint8None + return decoderSuccess + + default: + return decoderErrorUnreachable + } +} + +/* Decodes a metablock length and flags by reading 2 - 31 bits. */ +func decodeMetaBlockLength(s *Reader, br *bitReader) int { + var bits uint32 + var i int + for { + switch s.substate_metablock_header { + case stateMetablockHeaderNone: + if !safeReadBits(br, 1, &bits) { + return decoderNeedsMoreInput + } + + if bits != 0 { + s.is_last_metablock = 1 + } else { + s.is_last_metablock = 0 + } + s.meta_block_remaining_len = 0 + s.is_uncompressed = 0 + s.is_metadata = 0 + if s.is_last_metablock == 0 { + s.substate_metablock_header = stateMetablockHeaderNibbles + break + } + + s.substate_metablock_header = stateMetablockHeaderEmpty + fallthrough + + /* Fall through. */ + case stateMetablockHeaderEmpty: + if !safeReadBits(br, 1, &bits) { + return decoderNeedsMoreInput + } + + if bits != 0 { + s.substate_metablock_header = stateMetablockHeaderNone + return decoderSuccess + } + + s.substate_metablock_header = stateMetablockHeaderNibbles + fallthrough + + /* Fall through. */ + case stateMetablockHeaderNibbles: + if !safeReadBits(br, 2, &bits) { + return decoderNeedsMoreInput + } + + s.size_nibbles = uint(byte(bits + 4)) + s.loop_counter = 0 + if bits == 3 { + s.is_metadata = 1 + s.substate_metablock_header = stateMetablockHeaderReserved + break + } + + s.substate_metablock_header = stateMetablockHeaderSize + fallthrough + + /* Fall through. */ + case stateMetablockHeaderSize: + i = s.loop_counter + + for ; i < int(s.size_nibbles); i++ { + if !safeReadBits(br, 4, &bits) { + s.loop_counter = i + return decoderNeedsMoreInput + } + + if uint(i+1) == s.size_nibbles && s.size_nibbles > 4 && bits == 0 { + return decoderErrorFormatExuberantNibble + } + + s.meta_block_remaining_len |= int(bits << uint(i*4)) + } + + s.substate_metablock_header = stateMetablockHeaderUncompressed + fallthrough + + /* Fall through. */ + case stateMetablockHeaderUncompressed: + if s.is_last_metablock == 0 { + if !safeReadBits(br, 1, &bits) { + return decoderNeedsMoreInput + } + + if bits != 0 { + s.is_uncompressed = 1 + } else { + s.is_uncompressed = 0 + } + } + + s.meta_block_remaining_len++ + s.substate_metablock_header = stateMetablockHeaderNone + return decoderSuccess + + case stateMetablockHeaderReserved: + if !safeReadBits(br, 1, &bits) { + return decoderNeedsMoreInput + } + + if bits != 0 { + return decoderErrorFormatReserved + } + + s.substate_metablock_header = stateMetablockHeaderBytes + fallthrough + + /* Fall through. */ + case stateMetablockHeaderBytes: + if !safeReadBits(br, 2, &bits) { + return decoderNeedsMoreInput + } + + if bits == 0 { + s.substate_metablock_header = stateMetablockHeaderNone + return decoderSuccess + } + + s.size_nibbles = uint(byte(bits)) + s.substate_metablock_header = stateMetablockHeaderMetadata + fallthrough + + /* Fall through. */ + case stateMetablockHeaderMetadata: + i = s.loop_counter + + for ; i < int(s.size_nibbles); i++ { + if !safeReadBits(br, 8, &bits) { + s.loop_counter = i + return decoderNeedsMoreInput + } + + if uint(i+1) == s.size_nibbles && s.size_nibbles > 1 && bits == 0 { + return decoderErrorFormatExuberantMetaNibble + } + + s.meta_block_remaining_len |= int(bits << uint(i*8)) + } + + s.meta_block_remaining_len++ + s.substate_metablock_header = stateMetablockHeaderNone + return decoderSuccess + + default: + return decoderErrorUnreachable + } + } +} + +/* Decodes the Huffman code. + This method doesn't read data from the bit reader, BUT drops the amount of + bits that correspond to the decoded symbol. + bits MUST contain at least 15 (BROTLI_HUFFMAN_MAX_CODE_LENGTH) valid bits. */ +func decodeSymbol(bits uint32, table []huffmanCode, br *bitReader) uint32 { + table = table[bits&huffmanTableMask:] + if table[0].bits > huffmanTableBits { + var nbits uint32 = uint32(table[0].bits) - huffmanTableBits + dropBits(br, huffmanTableBits) + table = table[uint32(table[0].value)+((bits>>huffmanTableBits)&bitMask(nbits)):] + } + + dropBits(br, uint32(table[0].bits)) + return uint32(table[0].value) +} + +/* Reads and decodes the next Huffman code from bit-stream. + This method peeks 16 bits of input and drops 0 - 15 of them. */ +func readSymbol(table []huffmanCode, br *bitReader) uint32 { + return decodeSymbol(get16BitsUnmasked(br), table, br) +} + +/* Same as DecodeSymbol, but it is known that there is less than 15 bits of + input are currently available. */ +func safeDecodeSymbol(table []huffmanCode, br *bitReader, result *uint32) bool { + var val uint32 + var available_bits uint32 = getAvailableBits(br) + if available_bits == 0 { + if table[0].bits == 0 { + *result = uint32(table[0].value) + return true + } + + return false /* No valid bits at all. */ + } + + val = uint32(getBitsUnmasked(br)) + table = table[val&huffmanTableMask:] + if table[0].bits <= huffmanTableBits { + if uint32(table[0].bits) <= available_bits { + dropBits(br, uint32(table[0].bits)) + *result = uint32(table[0].value) + return true + } else { + return false /* Not enough bits for the first level. */ + } + } + + if available_bits <= huffmanTableBits { + return false /* Not enough bits to move to the second level. */ + } + + /* Speculatively drop HUFFMAN_TABLE_BITS. */ + val = (val & bitMask(uint32(table[0].bits))) >> huffmanTableBits + + available_bits -= huffmanTableBits + table = table[uint32(table[0].value)+val:] + if available_bits < uint32(table[0].bits) { + return false /* Not enough bits for the second level. */ + } + + dropBits(br, huffmanTableBits+uint32(table[0].bits)) + *result = uint32(table[0].value) + return true +} + +func safeReadSymbol(table []huffmanCode, br *bitReader, result *uint32) bool { + var val uint32 + if safeGetBits(br, 15, &val) { + *result = decodeSymbol(val, table, br) + return true + } + + return safeDecodeSymbol(table, br, result) +} + +/* Makes a look-up in first level Huffman table. Peeks 8 bits. */ +func preloadSymbol(safe int, table []huffmanCode, br *bitReader, bits *uint32, value *uint32) { + if safe != 0 { + return + } + + table = table[getBits(br, huffmanTableBits):] + *bits = uint32(table[0].bits) + *value = uint32(table[0].value) +} + +/* Decodes the next Huffman code using data prepared by PreloadSymbol. + Reads 0 - 15 bits. Also peeks 8 following bits. */ +func readPreloadedSymbol(table []huffmanCode, br *bitReader, bits *uint32, value *uint32) uint32 { + var result uint32 = *value + var ext []huffmanCode + if *bits > huffmanTableBits { + var val uint32 = get16BitsUnmasked(br) + ext = table[val&huffmanTableMask:][*value:] + var mask uint32 = bitMask((*bits - huffmanTableBits)) + dropBits(br, huffmanTableBits) + ext = ext[(val>>huffmanTableBits)&mask:] + dropBits(br, uint32(ext[0].bits)) + result = uint32(ext[0].value) + } else { + dropBits(br, *bits) + } + + preloadSymbol(0, table, br, bits, value) + return result +} + +func log2Floor(x uint32) uint32 { + var result uint32 = 0 + for x != 0 { + x >>= 1 + result++ + } + + return result +} + +/* Reads (s->symbol + 1) symbols. + Totally 1..4 symbols are read, 1..11 bits each. + The list of symbols MUST NOT contain duplicates. */ +func readSimpleHuffmanSymbols(alphabet_size uint32, max_symbol uint32, s *Reader) int { + var br *bitReader = &s.br + var max_bits uint32 = log2Floor(alphabet_size - 1) + var i uint32 = s.sub_loop_counter + /* max_bits == 1..11; symbol == 0..3; 1..44 bits will be read. */ + + var num_symbols uint32 = s.symbol + for i <= num_symbols { + var v uint32 + if !safeReadBits(br, max_bits, &v) { + s.sub_loop_counter = i + s.substate_huffman = stateHuffmanSimpleRead + return decoderNeedsMoreInput + } + + if v >= max_symbol { + return decoderErrorFormatSimpleHuffmanAlphabet + } + + s.symbols_lists_array[i] = uint16(v) + i++ + } + + for i = 0; i < num_symbols; i++ { + var k uint32 = i + 1 + for ; k <= num_symbols; k++ { + if s.symbols_lists_array[i] == s.symbols_lists_array[k] { + return decoderErrorFormatSimpleHuffmanSame + } + } + } + + return decoderSuccess +} + +/* Process single decoded symbol code length: + A) reset the repeat variable + B) remember code length (if it is not 0) + C) extend corresponding index-chain + D) reduce the Huffman space + E) update the histogram */ +func processSingleCodeLength(code_len uint32, symbol *uint32, repeat *uint32, space *uint32, prev_code_len *uint32, symbol_lists symbolList, code_length_histo []uint16, next_symbol []int) { + *repeat = 0 + if code_len != 0 { /* code_len == 1..15 */ + symbolListPut(symbol_lists, next_symbol[code_len], uint16(*symbol)) + next_symbol[code_len] = int(*symbol) + *prev_code_len = code_len + *space -= 32768 >> code_len + code_length_histo[code_len]++ + } + + (*symbol)++ +} + +/* Process repeated symbol code length. + A) Check if it is the extension of previous repeat sequence; if the decoded + value is not BROTLI_REPEAT_PREVIOUS_CODE_LENGTH, then it is a new + symbol-skip + B) Update repeat variable + C) Check if operation is feasible (fits alphabet) + D) For each symbol do the same operations as in ProcessSingleCodeLength + + PRECONDITION: code_len == BROTLI_REPEAT_PREVIOUS_CODE_LENGTH or + code_len == BROTLI_REPEAT_ZERO_CODE_LENGTH */ +func processRepeatedCodeLength(code_len uint32, repeat_delta uint32, alphabet_size uint32, symbol *uint32, repeat *uint32, space *uint32, prev_code_len *uint32, repeat_code_len *uint32, symbol_lists symbolList, code_length_histo []uint16, next_symbol []int) { + var old_repeat uint32 /* for BROTLI_REPEAT_ZERO_CODE_LENGTH */ /* for BROTLI_REPEAT_ZERO_CODE_LENGTH */ + var extra_bits uint32 = 3 + var new_len uint32 = 0 + if code_len == repeatPreviousCodeLength { + new_len = *prev_code_len + extra_bits = 2 + } + + if *repeat_code_len != new_len { + *repeat = 0 + *repeat_code_len = new_len + } + + old_repeat = *repeat + if *repeat > 0 { + *repeat -= 2 + *repeat <<= extra_bits + } + + *repeat += repeat_delta + 3 + repeat_delta = *repeat - old_repeat + if *symbol+repeat_delta > alphabet_size { + *symbol = alphabet_size + *space = 0xFFFFF + return + } + + if *repeat_code_len != 0 { + var last uint = uint(*symbol + repeat_delta) + var next int = next_symbol[*repeat_code_len] + for { + symbolListPut(symbol_lists, next, uint16(*symbol)) + next = int(*symbol) + (*symbol)++ + if (*symbol) == uint32(last) { + break + } + } + + next_symbol[*repeat_code_len] = next + *space -= repeat_delta << (15 - *repeat_code_len) + code_length_histo[*repeat_code_len] = uint16(uint32(code_length_histo[*repeat_code_len]) + repeat_delta) + } else { + *symbol += repeat_delta + } +} + +/* Reads and decodes symbol codelengths. */ +func readSymbolCodeLengths(alphabet_size uint32, s *Reader) int { + var br *bitReader = &s.br + var symbol uint32 = s.symbol + var repeat uint32 = s.repeat + var space uint32 = s.space + var prev_code_len uint32 = s.prev_code_len + var repeat_code_len uint32 = s.repeat_code_len + var symbol_lists symbolList = s.symbol_lists + var code_length_histo []uint16 = s.code_length_histo[:] + var next_symbol []int = s.next_symbol[:] + if !warmupBitReader(br) { + return decoderNeedsMoreInput + } + var p []huffmanCode + for symbol < alphabet_size && space > 0 { + p = s.table[:] + var code_len uint32 + if !checkInputAmount(br, shortFillBitWindowRead) { + s.symbol = symbol + s.repeat = repeat + s.prev_code_len = prev_code_len + s.repeat_code_len = repeat_code_len + s.space = space + return decoderNeedsMoreInput + } + + fillBitWindow16(br) + p = p[getBitsUnmasked(br)&uint64(bitMask(huffmanMaxCodeLengthCodeLength)):] + dropBits(br, uint32(p[0].bits)) /* Use 1..5 bits. */ + code_len = uint32(p[0].value) /* code_len == 0..17 */ + if code_len < repeatPreviousCodeLength { + processSingleCodeLength(code_len, &symbol, &repeat, &space, &prev_code_len, symbol_lists, code_length_histo, next_symbol) /* code_len == 16..17, extra_bits == 2..3 */ + } else { + var extra_bits uint32 + if code_len == repeatPreviousCodeLength { + extra_bits = 2 + } else { + extra_bits = 3 + } + var repeat_delta uint32 = uint32(getBitsUnmasked(br)) & bitMask(extra_bits) + dropBits(br, extra_bits) + processRepeatedCodeLength(code_len, repeat_delta, alphabet_size, &symbol, &repeat, &space, &prev_code_len, &repeat_code_len, symbol_lists, code_length_histo, next_symbol) + } + } + + s.space = space + return decoderSuccess +} + +func safeReadSymbolCodeLengths(alphabet_size uint32, s *Reader) int { + var br *bitReader = &s.br + var get_byte bool = false + var p []huffmanCode + for s.symbol < alphabet_size && s.space > 0 { + p = s.table[:] + var code_len uint32 + var available_bits uint32 + var bits uint32 = 0 + if get_byte && !pullByte(br) { + return decoderNeedsMoreInput + } + get_byte = false + available_bits = getAvailableBits(br) + if available_bits != 0 { + bits = uint32(getBitsUnmasked(br)) + } + + p = p[bits&bitMask(huffmanMaxCodeLengthCodeLength):] + if uint32(p[0].bits) > available_bits { + get_byte = true + continue + } + + code_len = uint32(p[0].value) /* code_len == 0..17 */ + if code_len < repeatPreviousCodeLength { + dropBits(br, uint32(p[0].bits)) + processSingleCodeLength(code_len, &s.symbol, &s.repeat, &s.space, &s.prev_code_len, s.symbol_lists, s.code_length_histo[:], s.next_symbol[:]) /* code_len == 16..17, extra_bits == 2..3 */ + } else { + var extra_bits uint32 = code_len - 14 + var repeat_delta uint32 = (bits >> p[0].bits) & bitMask(extra_bits) + if available_bits < uint32(p[0].bits)+extra_bits { + get_byte = true + continue + } + + dropBits(br, uint32(p[0].bits)+extra_bits) + processRepeatedCodeLength(code_len, repeat_delta, alphabet_size, &s.symbol, &s.repeat, &s.space, &s.prev_code_len, &s.repeat_code_len, s.symbol_lists, s.code_length_histo[:], s.next_symbol[:]) + } + } + + return decoderSuccess +} + +/* Reads and decodes 15..18 codes using static prefix code. + Each code is 2..4 bits long. In total 30..72 bits are used. */ +func readCodeLengthCodeLengths(s *Reader) int { + var br *bitReader = &s.br + var num_codes uint32 = s.repeat + var space uint32 = s.space + var i uint32 = s.sub_loop_counter + for ; i < codeLengthCodes; i++ { + var code_len_idx byte = kCodeLengthCodeOrder[i] + var ix uint32 + var v uint32 + if !safeGetBits(br, 4, &ix) { + var available_bits uint32 = getAvailableBits(br) + if available_bits != 0 { + ix = uint32(getBitsUnmasked(br) & 0xF) + } else { + ix = 0 + } + + if uint32(kCodeLengthPrefixLength[ix]) > available_bits { + s.sub_loop_counter = i + s.repeat = num_codes + s.space = space + s.substate_huffman = stateHuffmanComplex + return decoderNeedsMoreInput + } + } + + v = uint32(kCodeLengthPrefixValue[ix]) + dropBits(br, uint32(kCodeLengthPrefixLength[ix])) + s.code_length_code_lengths[code_len_idx] = byte(v) + if v != 0 { + space = space - (32 >> v) + num_codes++ + s.code_length_histo[v]++ + if space-1 >= 32 { + /* space is 0 or wrapped around. */ + break + } + } + } + + if num_codes != 1 && space != 0 { + return decoderErrorFormatClSpace + } + + return decoderSuccess +} + +/* Decodes the Huffman tables. + There are 2 scenarios: + A) Huffman code contains only few symbols (1..4). Those symbols are read + directly; their code lengths are defined by the number of symbols. + For this scenario 4 - 49 bits will be read. + + B) 2-phase decoding: + B.1) Small Huffman table is decoded; it is specified with code lengths + encoded with predefined entropy code. 32 - 74 bits are used. + B.2) Decoded table is used to decode code lengths of symbols in resulting + Huffman table. In worst case 3520 bits are read. */ +func readHuffmanCode(alphabet_size uint32, max_symbol uint32, table []huffmanCode, opt_table_size *uint32, s *Reader) int { + var br *bitReader = &s.br + + /* Unnecessary masking, but might be good for safety. */ + alphabet_size &= 0x7FF + + /* State machine. */ + for { + switch s.substate_huffman { + case stateHuffmanNone: + if !safeReadBits(br, 2, &s.sub_loop_counter) { + return decoderNeedsMoreInput + } + + /* The value is used as follows: + 1 for simple code; + 0 for no skipping, 2 skips 2 code lengths, 3 skips 3 code lengths */ + if s.sub_loop_counter != 1 { + s.space = 32 + s.repeat = 0 /* num_codes */ + var i int + for i = 0; i <= huffmanMaxCodeLengthCodeLength; i++ { + s.code_length_histo[i] = 0 + } + + for i = 0; i < codeLengthCodes; i++ { + s.code_length_code_lengths[i] = 0 + } + + s.substate_huffman = stateHuffmanComplex + continue + } + fallthrough + + /* Read symbols, codes & code lengths directly. */ + case stateHuffmanSimpleSize: + if !safeReadBits(br, 2, &s.symbol) { /* num_symbols */ + s.substate_huffman = stateHuffmanSimpleSize + return decoderNeedsMoreInput + } + + s.sub_loop_counter = 0 + fallthrough + + case stateHuffmanSimpleRead: + { + var result int = readSimpleHuffmanSymbols(alphabet_size, max_symbol, s) + if result != decoderSuccess { + return result + } + } + fallthrough + + case stateHuffmanSimpleBuild: + var table_size uint32 + if s.symbol == 3 { + var bits uint32 + if !safeReadBits(br, 1, &bits) { + s.substate_huffman = stateHuffmanSimpleBuild + return decoderNeedsMoreInput + } + + s.symbol += bits + } + + table_size = buildSimpleHuffmanTable(table, huffmanTableBits, s.symbols_lists_array[:], s.symbol) + if opt_table_size != nil { + *opt_table_size = table_size + } + + s.substate_huffman = stateHuffmanNone + return decoderSuccess + + /* Decode Huffman-coded code lengths. */ + case stateHuffmanComplex: + { + var i uint32 + var result int = readCodeLengthCodeLengths(s) + if result != decoderSuccess { + return result + } + + buildCodeLengthsHuffmanTable(s.table[:], s.code_length_code_lengths[:], s.code_length_histo[:]) + for i = 0; i < 16; i++ { + s.code_length_histo[i] = 0 + } + + for i = 0; i <= huffmanMaxCodeLength; i++ { + s.next_symbol[i] = int(i) - (huffmanMaxCodeLength + 1) + symbolListPut(s.symbol_lists, s.next_symbol[i], 0xFFFF) + } + + s.symbol = 0 + s.prev_code_len = initialRepeatedCodeLength + s.repeat = 0 + s.repeat_code_len = 0 + s.space = 32768 + s.substate_huffman = stateHuffmanLengthSymbols + } + fallthrough + + case stateHuffmanLengthSymbols: + var table_size uint32 + var result int = readSymbolCodeLengths(max_symbol, s) + if result == decoderNeedsMoreInput { + result = safeReadSymbolCodeLengths(max_symbol, s) + } + + if result != decoderSuccess { + return result + } + + if s.space != 0 { + return decoderErrorFormatHuffmanSpace + } + + table_size = buildHuffmanTable(table, huffmanTableBits, s.symbol_lists, s.code_length_histo[:]) + if opt_table_size != nil { + *opt_table_size = table_size + } + + s.substate_huffman = stateHuffmanNone + return decoderSuccess + + default: + return decoderErrorUnreachable + } + } +} + +/* Decodes a block length by reading 3..39 bits. */ +func readBlockLength(table []huffmanCode, br *bitReader) uint32 { + var code uint32 + var nbits uint32 + code = readSymbol(table, br) + nbits = kBlockLengthPrefixCode[code].nbits /* nbits == 2..24 */ + return kBlockLengthPrefixCode[code].offset + readBits(br, nbits) +} + +/* WARNING: if state is not BROTLI_STATE_READ_BLOCK_LENGTH_NONE, then + reading can't be continued with ReadBlockLength. */ +func safeReadBlockLength(s *Reader, result *uint32, table []huffmanCode, br *bitReader) bool { + var index uint32 + if s.substate_read_block_length == stateReadBlockLengthNone { + if !safeReadSymbol(table, br, &index) { + return false + } + } else { + index = s.block_length_index + } + { + var bits uint32 /* nbits == 2..24 */ + var nbits uint32 = kBlockLengthPrefixCode[index].nbits + if !safeReadBits(br, nbits, &bits) { + s.block_length_index = index + s.substate_read_block_length = stateReadBlockLengthSuffix + return false + } + + *result = kBlockLengthPrefixCode[index].offset + bits + s.substate_read_block_length = stateReadBlockLengthNone + return true + } +} + +/* Transform: + 1) initialize list L with values 0, 1,... 255 + 2) For each input element X: + 2.1) let Y = L[X] + 2.2) remove X-th element from L + 2.3) prepend Y to L + 2.4) append Y to output + + In most cases max(Y) <= 7, so most of L remains intact. + To reduce the cost of initialization, we reuse L, remember the upper bound + of Y values, and reinitialize only first elements in L. + + Most of input values are 0 and 1. To reduce number of branches, we replace + inner for loop with do-while. */ +func inverseMoveToFrontTransform(v []byte, v_len uint32, state *Reader) { + var mtf [256]byte + var i int + for i = 1; i < 256; i++ { + mtf[i] = byte(i) + } + var mtf_1 byte + + /* Transform the input. */ + for i = 0; uint32(i) < v_len; i++ { + var index int = int(v[i]) + var value byte = mtf[index] + v[i] = value + mtf_1 = value + for index >= 1 { + index-- + mtf[index+1] = mtf[index] + } + + mtf[0] = mtf_1 + } +} + +/* Decodes a series of Huffman table using ReadHuffmanCode function. */ +func huffmanTreeGroupDecode(group *huffmanTreeGroup, s *Reader) int { + if s.substate_tree_group != stateTreeGroupLoop { + s.next = group.codes + s.htree_index = 0 + s.substate_tree_group = stateTreeGroupLoop + } + + for s.htree_index < int(group.num_htrees) { + var table_size uint32 + var result int = readHuffmanCode(uint32(group.alphabet_size), uint32(group.max_symbol), s.next, &table_size, s) + if result != decoderSuccess { + return result + } + group.htrees[s.htree_index] = s.next + s.next = s.next[table_size:] + s.htree_index++ + } + + s.substate_tree_group = stateTreeGroupNone + return decoderSuccess +} + +/* Decodes a context map. + Decoding is done in 4 phases: + 1) Read auxiliary information (6..16 bits) and allocate memory. + In case of trivial context map, decoding is finished at this phase. + 2) Decode Huffman table using ReadHuffmanCode function. + This table will be used for reading context map items. + 3) Read context map items; "0" values could be run-length encoded. + 4) Optionally, apply InverseMoveToFront transform to the resulting map. */ +func decodeContextMap(context_map_size uint32, num_htrees *uint32, context_map_arg *[]byte, s *Reader) int { + var br *bitReader = &s.br + var result int = decoderSuccess + + switch int(s.substate_context_map) { + case stateContextMapNone: + result = decodeVarLenUint8(s, br, num_htrees) + if result != decoderSuccess { + return result + } + + (*num_htrees)++ + s.context_index = 0 + *context_map_arg = make([]byte, uint(context_map_size)) + if *context_map_arg == nil { + return decoderErrorAllocContextMap + } + + if *num_htrees <= 1 { + for i := 0; i < int(context_map_size); i++ { + (*context_map_arg)[i] = 0 + } + return decoderSuccess + } + + s.substate_context_map = stateContextMapReadPrefix + fallthrough + /* Fall through. */ + case stateContextMapReadPrefix: + { + var bits uint32 + + /* In next stage ReadHuffmanCode uses at least 4 bits, so it is safe + to peek 4 bits ahead. */ + if !safeGetBits(br, 5, &bits) { + return decoderNeedsMoreInput + } + + if bits&1 != 0 { /* Use RLE for zeros. */ + s.max_run_length_prefix = (bits >> 1) + 1 + dropBits(br, 5) + } else { + s.max_run_length_prefix = 0 + dropBits(br, 1) + } + + s.substate_context_map = stateContextMapHuffman + } + fallthrough + + /* Fall through. */ + case stateContextMapHuffman: + { + var alphabet_size uint32 = *num_htrees + s.max_run_length_prefix + result = readHuffmanCode(alphabet_size, alphabet_size, s.context_map_table[:], nil, s) + if result != decoderSuccess { + return result + } + s.code = 0xFFFF + s.substate_context_map = stateContextMapDecode + } + fallthrough + + /* Fall through. */ + case stateContextMapDecode: + { + var context_index uint32 = s.context_index + var max_run_length_prefix uint32 = s.max_run_length_prefix + var context_map []byte = *context_map_arg + var code uint32 = s.code + var skip_preamble bool = (code != 0xFFFF) + for context_index < context_map_size || skip_preamble { + if !skip_preamble { + if !safeReadSymbol(s.context_map_table[:], br, &code) { + s.code = 0xFFFF + s.context_index = context_index + return decoderNeedsMoreInput + } + + if code == 0 { + context_map[context_index] = 0 + context_index++ + continue + } + + if code > max_run_length_prefix { + context_map[context_index] = byte(code - max_run_length_prefix) + context_index++ + continue + } + } else { + skip_preamble = false + } + + /* RLE sub-stage. */ + { + var reps uint32 + if !safeReadBits(br, code, &reps) { + s.code = code + s.context_index = context_index + return decoderNeedsMoreInput + } + + reps += 1 << code + if context_index+reps > context_map_size { + return decoderErrorFormatContextMapRepeat + } + + for { + context_map[context_index] = 0 + context_index++ + reps-- + if reps == 0 { + break + } + } + } + } + } + fallthrough + + case stateContextMapTransform: + var bits uint32 + if !safeReadBits(br, 1, &bits) { + s.substate_context_map = stateContextMapTransform + return decoderNeedsMoreInput + } + + if bits != 0 { + inverseMoveToFrontTransform(*context_map_arg, context_map_size, s) + } + + s.substate_context_map = stateContextMapNone + return decoderSuccess + + default: + return decoderErrorUnreachable + } +} + +/* Decodes a command or literal and updates block type ring-buffer. + Reads 3..54 bits. */ +func decodeBlockTypeAndLength(safe int, s *Reader, tree_type int) bool { + var max_block_type uint32 = s.num_block_types[tree_type] + type_tree := s.block_type_trees[tree_type*huffmanMaxSize258:] + len_tree := s.block_len_trees[tree_type*huffmanMaxSize26:] + var br *bitReader = &s.br + var ringbuffer []uint32 = s.block_type_rb[tree_type*2:] + var block_type uint32 + if max_block_type <= 1 { + return false + } + + /* Read 0..15 + 3..39 bits. */ + if safe == 0 { + block_type = readSymbol(type_tree, br) + s.block_length[tree_type] = readBlockLength(len_tree, br) + } else { + var memento bitReaderState + bitReaderSaveState(br, &memento) + if !safeReadSymbol(type_tree, br, &block_type) { + return false + } + if !safeReadBlockLength(s, &s.block_length[tree_type], len_tree, br) { + s.substate_read_block_length = stateReadBlockLengthNone + bitReaderRestoreState(br, &memento) + return false + } + } + + if block_type == 1 { + block_type = ringbuffer[1] + 1 + } else if block_type == 0 { + block_type = ringbuffer[0] + } else { + block_type -= 2 + } + + if block_type >= max_block_type { + block_type -= max_block_type + } + + ringbuffer[0] = ringbuffer[1] + ringbuffer[1] = block_type + return true +} + +func detectTrivialLiteralBlockTypes(s *Reader) { + var i uint + for i = 0; i < 8; i++ { + s.trivial_literal_contexts[i] = 0 + } + for i = 0; uint32(i) < s.num_block_types[0]; i++ { + var offset uint = i << literalContextBits + var error uint = 0 + var sample uint = uint(s.context_map[offset]) + var j uint + for j = 0; j < 1<>5] |= 1 << (i & 31) + } + } +} + +func prepareLiteralDecoding(s *Reader) { + var context_mode byte + var trivial uint + var block_type uint32 = s.block_type_rb[1] + var context_offset uint32 = block_type << literalContextBits + s.context_map_slice = s.context_map[context_offset:] + trivial = uint(s.trivial_literal_contexts[block_type>>5]) + s.trivial_literal_context = int((trivial >> (block_type & 31)) & 1) + s.literal_htree = []huffmanCode(s.literal_hgroup.htrees[s.context_map_slice[0]]) + context_mode = s.context_modes[block_type] & 3 + s.context_lookup = getContextLUT(int(context_mode)) +} + +/* Decodes the block type and updates the state for literal context. + Reads 3..54 bits. */ +func decodeLiteralBlockSwitchInternal(safe int, s *Reader) bool { + if !decodeBlockTypeAndLength(safe, s, 0) { + return false + } + + prepareLiteralDecoding(s) + return true +} + +func decodeLiteralBlockSwitch(s *Reader) { + decodeLiteralBlockSwitchInternal(0, s) +} + +func safeDecodeLiteralBlockSwitch(s *Reader) bool { + return decodeLiteralBlockSwitchInternal(1, s) +} + +/* Block switch for insert/copy length. + Reads 3..54 bits. */ +func decodeCommandBlockSwitchInternal(safe int, s *Reader) bool { + if !decodeBlockTypeAndLength(safe, s, 1) { + return false + } + + s.htree_command = []huffmanCode(s.insert_copy_hgroup.htrees[s.block_type_rb[3]]) + return true +} + +func decodeCommandBlockSwitch(s *Reader) { + decodeCommandBlockSwitchInternal(0, s) +} + +func safeDecodeCommandBlockSwitch(s *Reader) bool { + return decodeCommandBlockSwitchInternal(1, s) +} + +/* Block switch for distance codes. + Reads 3..54 bits. */ +func decodeDistanceBlockSwitchInternal(safe int, s *Reader) bool { + if !decodeBlockTypeAndLength(safe, s, 2) { + return false + } + + s.dist_context_map_slice = s.dist_context_map[s.block_type_rb[5]< s.ringbuffer_size { + pos = uint(s.ringbuffer_size) + } else { + pos = uint(s.pos) + } + var partial_pos_rb uint = (s.rb_roundtrips * uint(s.ringbuffer_size)) + pos + return partial_pos_rb - s.partial_pos_out +} + +/* Dumps output. + Returns BROTLI_DECODER_NEEDS_MORE_OUTPUT only if there is more output to push + and either ring-buffer is as big as window size, or |force| is true. */ +func writeRingBuffer(s *Reader, available_out *uint, next_out *[]byte, total_out *uint, force bool) int { + start := s.ringbuffer[s.partial_pos_out&uint(s.ringbuffer_mask):] + var to_write uint = unwrittenBytes(s, true) + var num_written uint = *available_out + if num_written > to_write { + num_written = to_write + } + + if s.meta_block_remaining_len < 0 { + return decoderErrorFormatBlockLength1 + } + + if next_out != nil && *next_out == nil { + *next_out = start + } else { + if next_out != nil { + copy(*next_out, start[:num_written]) + *next_out = (*next_out)[num_written:] + } + } + + *available_out -= num_written + s.partial_pos_out += num_written + if total_out != nil { + *total_out = s.partial_pos_out + } + + if num_written < to_write { + if s.ringbuffer_size == 1<= s.ringbuffer_size { + s.pos -= s.ringbuffer_size + s.rb_roundtrips++ + if uint(s.pos) != 0 { + s.should_wrap_ringbuffer = 1 + } else { + s.should_wrap_ringbuffer = 0 + } + } + + return decoderSuccess +} + +func wrapRingBuffer(s *Reader) { + if s.should_wrap_ringbuffer != 0 { + copy(s.ringbuffer, s.ringbuffer_end[:uint(s.pos)]) + s.should_wrap_ringbuffer = 0 + } +} + +/* Allocates ring-buffer. + + s->ringbuffer_size MUST be updated by BrotliCalculateRingBufferSize before + this function is called. + + Last two bytes of ring-buffer are initialized to 0, so context calculation + could be done uniformly for the first two and all other positions. */ +func ensureRingBuffer(s *Reader) bool { + var old_ringbuffer []byte + if s.ringbuffer_size == s.new_ringbuffer_size { + return true + } + spaceNeeded := int(s.new_ringbuffer_size) + int(kRingBufferWriteAheadSlack) + if len(s.ringbuffer) < spaceNeeded { + old_ringbuffer = s.ringbuffer + s.ringbuffer = make([]byte, spaceNeeded) + } + + s.ringbuffer[s.new_ringbuffer_size-2] = 0 + s.ringbuffer[s.new_ringbuffer_size-1] = 0 + + if old_ringbuffer != nil { + copy(s.ringbuffer, old_ringbuffer[:uint(s.pos)]) + } + + s.ringbuffer_size = s.new_ringbuffer_size + s.ringbuffer_mask = s.new_ringbuffer_size - 1 + s.ringbuffer_end = s.ringbuffer[s.ringbuffer_size:] + + return true +} + +func copyUncompressedBlockToOutput(available_out *uint, next_out *[]byte, total_out *uint, s *Reader) int { + /* TODO: avoid allocation for single uncompressed block. */ + if !ensureRingBuffer(s) { + return decoderErrorAllocRingBuffer1 + } + + /* State machine */ + for { + switch s.substate_uncompressed { + case stateUncompressedNone: + { + var nbytes int = int(getRemainingBytes(&s.br)) + if nbytes > s.meta_block_remaining_len { + nbytes = s.meta_block_remaining_len + } + + if s.pos+nbytes > s.ringbuffer_size { + nbytes = s.ringbuffer_size - s.pos + } + + /* Copy remaining bytes from s->br.buf_ to ring-buffer. */ + copyBytes(s.ringbuffer[s.pos:], &s.br, uint(nbytes)) + + s.pos += nbytes + s.meta_block_remaining_len -= nbytes + if s.pos < 1<>1 >= min_size { + new_ringbuffer_size >>= 1 + } + } + + s.new_ringbuffer_size = new_ringbuffer_size +} + +/* Reads 1..256 2-bit context modes. */ +func readContextModes(s *Reader) int { + var br *bitReader = &s.br + var i int = s.loop_counter + + for i < int(s.num_block_types[0]) { + var bits uint32 + if !safeReadBits(br, 2, &bits) { + s.loop_counter = i + return decoderNeedsMoreInput + } + + s.context_modes[i] = byte(bits) + i++ + } + + return decoderSuccess +} + +func takeDistanceFromRingBuffer(s *Reader) { + if s.distance_code == 0 { + s.dist_rb_idx-- + s.distance_code = s.dist_rb[s.dist_rb_idx&3] + + /* Compensate double distance-ring-buffer roll for dictionary items. */ + s.distance_context = 1 + } else { + var distance_code int = s.distance_code << 1 + const kDistanceShortCodeIndexOffset uint32 = 0xAAAFFF1B + const kDistanceShortCodeValueOffset uint32 = 0xFA5FA500 + var v int = (s.dist_rb_idx + int(kDistanceShortCodeIndexOffset>>uint(distance_code))) & 0x3 + /* kDistanceShortCodeIndexOffset has 2-bit values from LSB: + 3, 2, 1, 0, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 */ + + /* kDistanceShortCodeValueOffset has 2-bit values from LSB: + -0, 0,-0, 0,-1, 1,-2, 2,-3, 3,-1, 1,-2, 2,-3, 3 */ + s.distance_code = s.dist_rb[v] + + v = int(kDistanceShortCodeValueOffset>>uint(distance_code)) & 0x3 + if distance_code&0x3 != 0 { + s.distance_code += v + } else { + s.distance_code -= v + if s.distance_code <= 0 { + /* A huge distance will cause a () soon. + This is a little faster than failing here. */ + s.distance_code = 0x7FFFFFFF + } + } + } +} + +func safeReadBitsMaybeZero(br *bitReader, n_bits uint32, val *uint32) bool { + if n_bits != 0 { + return safeReadBits(br, n_bits, val) + } else { + *val = 0 + return true + } +} + +/* Precondition: s->distance_code < 0. */ +func readDistanceInternal(safe int, s *Reader, br *bitReader) bool { + var distval int + var memento bitReaderState + var distance_tree []huffmanCode = []huffmanCode(s.distance_hgroup.htrees[s.dist_htree_index]) + if safe == 0 { + s.distance_code = int(readSymbol(distance_tree, br)) + } else { + var code uint32 + bitReaderSaveState(br, &memento) + if !safeReadSymbol(distance_tree, br, &code) { + return false + } + + s.distance_code = int(code) + } + + /* Convert the distance code to the actual distance by possibly + looking up past distances from the s->ringbuffer. */ + s.distance_context = 0 + + if s.distance_code&^0xF == 0 { + takeDistanceFromRingBuffer(s) + s.block_length[2]-- + return true + } + + distval = s.distance_code - int(s.num_direct_distance_codes) + if distval >= 0 { + var nbits uint32 + var postfix int + var offset int + if safe == 0 && (s.distance_postfix_bits == 0) { + nbits = (uint32(distval) >> 1) + 1 + offset = ((2 + (distval & 1)) << nbits) - 4 + s.distance_code = int(s.num_direct_distance_codes) + offset + int(readBits(br, nbits)) + } else { + /* This branch also works well when s->distance_postfix_bits == 0. */ + var bits uint32 + postfix = distval & s.distance_postfix_mask + distval >>= s.distance_postfix_bits + nbits = (uint32(distval) >> 1) + 1 + if safe != 0 { + if !safeReadBitsMaybeZero(br, nbits, &bits) { + s.distance_code = -1 /* Restore precondition. */ + bitReaderRestoreState(br, &memento) + return false + } + } else { + bits = readBits(br, nbits) + } + + offset = ((2 + (distval & 1)) << nbits) - 4 + s.distance_code = int(s.num_direct_distance_codes) + ((offset + int(bits)) << s.distance_postfix_bits) + postfix + } + } + + s.distance_code = s.distance_code - numDistanceShortCodes + 1 + s.block_length[2]-- + return true +} + +func readDistance(s *Reader, br *bitReader) { + readDistanceInternal(0, s, br) +} + +func safeReadDistance(s *Reader, br *bitReader) bool { + return readDistanceInternal(1, s, br) +} + +func readCommandInternal(safe int, s *Reader, br *bitReader, insert_length *int) bool { + var cmd_code uint32 + var insert_len_extra uint32 = 0 + var copy_length uint32 + var v cmdLutElement + var memento bitReaderState + if safe == 0 { + cmd_code = readSymbol(s.htree_command, br) + } else { + bitReaderSaveState(br, &memento) + if !safeReadSymbol(s.htree_command, br, &cmd_code) { + return false + } + } + + v = kCmdLut[cmd_code] + s.distance_code = int(v.distance_code) + s.distance_context = int(v.context) + s.dist_htree_index = s.dist_context_map_slice[s.distance_context] + *insert_length = int(v.insert_len_offset) + if safe == 0 { + if v.insert_len_extra_bits != 0 { + insert_len_extra = readBits(br, uint32(v.insert_len_extra_bits)) + } + + copy_length = readBits(br, uint32(v.copy_len_extra_bits)) + } else { + if !safeReadBitsMaybeZero(br, uint32(v.insert_len_extra_bits), &insert_len_extra) || !safeReadBitsMaybeZero(br, uint32(v.copy_len_extra_bits), ©_length) { + bitReaderRestoreState(br, &memento) + return false + } + } + + s.copy_length = int(copy_length) + int(v.copy_len_offset) + s.block_length[1]-- + *insert_length += int(insert_len_extra) + return true +} + +func readCommand(s *Reader, br *bitReader, insert_length *int) { + readCommandInternal(0, s, br, insert_length) +} + +func safeReadCommand(s *Reader, br *bitReader, insert_length *int) bool { + return readCommandInternal(1, s, br, insert_length) +} + +func checkInputAmountMaybeSafe(safe int, br *bitReader, num uint) bool { + if safe != 0 { + return true + } + + return checkInputAmount(br, num) +} + +func processCommandsInternal(safe int, s *Reader) int { + var pos int = s.pos + var i int = s.loop_counter + var result int = decoderSuccess + var br *bitReader = &s.br + var hc []huffmanCode + + if !checkInputAmountMaybeSafe(safe, br, 28) { + result = decoderNeedsMoreInput + goto saveStateAndReturn + } + + if safe == 0 { + warmupBitReader(br) + } + + /* Jump into state machine. */ + if s.state == stateCommandBegin { + goto CommandBegin + } else if s.state == stateCommandInner { + goto CommandInner + } else if s.state == stateCommandPostDecodeLiterals { + goto CommandPostDecodeLiterals + } else if s.state == stateCommandPostWrapCopy { + goto CommandPostWrapCopy + } else { + return decoderErrorUnreachable + } + +CommandBegin: + if safe != 0 { + s.state = stateCommandBegin + } + + if !checkInputAmountMaybeSafe(safe, br, 28) { /* 156 bits + 7 bytes */ + s.state = stateCommandBegin + result = decoderNeedsMoreInput + goto saveStateAndReturn + } + + if s.block_length[1] == 0 { + if safe != 0 { + if !safeDecodeCommandBlockSwitch(s) { + result = decoderNeedsMoreInput + goto saveStateAndReturn + } + } else { + decodeCommandBlockSwitch(s) + } + + goto CommandBegin + } + + /* Read the insert/copy length in the command. */ + if safe != 0 { + if !safeReadCommand(s, br, &i) { + result = decoderNeedsMoreInput + goto saveStateAndReturn + } + } else { + readCommand(s, br, &i) + } + + if i == 0 { + goto CommandPostDecodeLiterals + } + + s.meta_block_remaining_len -= i + +CommandInner: + if safe != 0 { + s.state = stateCommandInner + } + + /* Read the literals in the command. */ + if s.trivial_literal_context != 0 { + var bits uint32 + var value uint32 + preloadSymbol(safe, s.literal_htree, br, &bits, &value) + for { + if !checkInputAmountMaybeSafe(safe, br, 28) { /* 162 bits + 7 bytes */ + s.state = stateCommandInner + result = decoderNeedsMoreInput + goto saveStateAndReturn + } + + if s.block_length[0] == 0 { + if safe != 0 { + if !safeDecodeLiteralBlockSwitch(s) { + result = decoderNeedsMoreInput + goto saveStateAndReturn + } + } else { + decodeLiteralBlockSwitch(s) + } + + preloadSymbol(safe, s.literal_htree, br, &bits, &value) + if s.trivial_literal_context == 0 { + goto CommandInner + } + } + + if safe == 0 { + s.ringbuffer[pos] = byte(readPreloadedSymbol(s.literal_htree, br, &bits, &value)) + } else { + var literal uint32 + if !safeReadSymbol(s.literal_htree, br, &literal) { + result = decoderNeedsMoreInput + goto saveStateAndReturn + } + + s.ringbuffer[pos] = byte(literal) + } + + s.block_length[0]-- + pos++ + if pos == s.ringbuffer_size { + s.state = stateCommandInnerWrite + i-- + goto saveStateAndReturn + } + i-- + if i == 0 { + break + } + } + } else { + var p1 byte = s.ringbuffer[(pos-1)&s.ringbuffer_mask] + var p2 byte = s.ringbuffer[(pos-2)&s.ringbuffer_mask] + for { + var context byte + if !checkInputAmountMaybeSafe(safe, br, 28) { /* 162 bits + 7 bytes */ + s.state = stateCommandInner + result = decoderNeedsMoreInput + goto saveStateAndReturn + } + + if s.block_length[0] == 0 { + if safe != 0 { + if !safeDecodeLiteralBlockSwitch(s) { + result = decoderNeedsMoreInput + goto saveStateAndReturn + } + } else { + decodeLiteralBlockSwitch(s) + } + + if s.trivial_literal_context != 0 { + goto CommandInner + } + } + + context = getContext(p1, p2, s.context_lookup) + hc = []huffmanCode(s.literal_hgroup.htrees[s.context_map_slice[context]]) + p2 = p1 + if safe == 0 { + p1 = byte(readSymbol(hc, br)) + } else { + var literal uint32 + if !safeReadSymbol(hc, br, &literal) { + result = decoderNeedsMoreInput + goto saveStateAndReturn + } + + p1 = byte(literal) + } + + s.ringbuffer[pos] = p1 + s.block_length[0]-- + pos++ + if pos == s.ringbuffer_size { + s.state = stateCommandInnerWrite + i-- + goto saveStateAndReturn + } + i-- + if i == 0 { + break + } + } + } + + if s.meta_block_remaining_len <= 0 { + s.state = stateMetablockDone + goto saveStateAndReturn + } + +CommandPostDecodeLiterals: + if safe != 0 { + s.state = stateCommandPostDecodeLiterals + } + + if s.distance_code >= 0 { + /* Implicit distance case. */ + if s.distance_code != 0 { + s.distance_context = 0 + } else { + s.distance_context = 1 + } + + s.dist_rb_idx-- + s.distance_code = s.dist_rb[s.dist_rb_idx&3] + } else { + /* Read distance code in the command, unless it was implicitly zero. */ + if s.block_length[2] == 0 { + if safe != 0 { + if !safeDecodeDistanceBlockSwitch(s) { + result = decoderNeedsMoreInput + goto saveStateAndReturn + } + } else { + decodeDistanceBlockSwitch(s) + } + } + + if safe != 0 { + if !safeReadDistance(s, br) { + result = decoderNeedsMoreInput + goto saveStateAndReturn + } + } else { + readDistance(s, br) + } + } + + if s.max_distance != s.max_backward_distance { + if pos < s.max_backward_distance { + s.max_distance = pos + } else { + s.max_distance = s.max_backward_distance + } + } + + i = s.copy_length + + /* Apply copy of LZ77 back-reference, or static dictionary reference if + the distance is larger than the max LZ77 distance */ + if s.distance_code > s.max_distance { + /* The maximum allowed distance is BROTLI_MAX_ALLOWED_DISTANCE = 0x7FFFFFFC. + With this choice, no signed overflow can occur after decoding + a special distance code (e.g., after adding 3 to the last distance). */ + if s.distance_code > maxAllowedDistance { + return decoderErrorFormatDistance + } + + if i >= minDictionaryWordLength && i <= maxDictionaryWordLength { + var address int = s.distance_code - s.max_distance - 1 + var words *dictionary = s.dictionary + var trans *transforms = s.transforms + var offset int = int(s.dictionary.offsets_by_length[i]) + var shift uint32 = uint32(s.dictionary.size_bits_by_length[i]) + var mask int = int(bitMask(shift)) + var word_idx int = address & mask + var transform_idx int = address >> shift + + /* Compensate double distance-ring-buffer roll. */ + s.dist_rb_idx += s.distance_context + + offset += word_idx * i + if words.data == nil { + return decoderErrorDictionaryNotSet + } + + if transform_idx < int(trans.num_transforms) { + word := words.data[offset:] + var len int = i + if transform_idx == int(trans.cutOffTransforms[0]) { + copy(s.ringbuffer[pos:], word[:uint(len)]) + } else { + len = transformDictionaryWord(s.ringbuffer[pos:], word, int(len), trans, transform_idx) + } + + pos += int(len) + s.meta_block_remaining_len -= int(len) + if pos >= s.ringbuffer_size { + s.state = stateCommandPostWrite1 + goto saveStateAndReturn + } + } else { + return decoderErrorFormatTransform + } + } else { + return decoderErrorFormatDictionary + } + } else { + var src_start int = (pos - s.distance_code) & s.ringbuffer_mask + copy_dst := s.ringbuffer[pos:] + copy_src := s.ringbuffer[src_start:] + var dst_end int = pos + i + var src_end int = src_start + i + + /* Update the recent distances cache. */ + s.dist_rb[s.dist_rb_idx&3] = s.distance_code + + s.dist_rb_idx++ + s.meta_block_remaining_len -= i + + /* There are 32+ bytes of slack in the ring-buffer allocation. + Also, we have 16 short codes, that make these 16 bytes irrelevant + in the ring-buffer. Let's copy over them as a first guess. */ + copy(copy_dst, copy_src[:16]) + + if src_end > pos && dst_end > src_start { + /* Regions intersect. */ + goto CommandPostWrapCopy + } + + if dst_end >= s.ringbuffer_size || src_end >= s.ringbuffer_size { + /* At least one region wraps. */ + goto CommandPostWrapCopy + } + + pos += i + if i > 16 { + if i > 32 { + copy(copy_dst[16:], copy_src[16:][:uint(i-16)]) + } else { + /* This branch covers about 45% cases. + Fixed size short copy allows more compiler optimizations. */ + copy(copy_dst[16:], copy_src[16:][:16]) + } + } + } + + if s.meta_block_remaining_len <= 0 { + /* Next metablock, if any. */ + s.state = stateMetablockDone + + goto saveStateAndReturn + } else { + goto CommandBegin + } +CommandPostWrapCopy: + { + var wrap_guard int = s.ringbuffer_size - pos + for { + i-- + if i < 0 { + break + } + s.ringbuffer[pos] = s.ringbuffer[(pos-s.distance_code)&s.ringbuffer_mask] + pos++ + wrap_guard-- + if wrap_guard == 0 { + s.state = stateCommandPostWrite2 + goto saveStateAndReturn + } + } + } + + if s.meta_block_remaining_len <= 0 { + /* Next metablock, if any. */ + s.state = stateMetablockDone + + goto saveStateAndReturn + } else { + goto CommandBegin + } + +saveStateAndReturn: + s.pos = pos + s.loop_counter = i + return result +} + +func processCommands(s *Reader) int { + return processCommandsInternal(0, s) +} + +func safeProcessCommands(s *Reader) int { + return processCommandsInternal(1, s) +} + +/* Returns the maximum number of distance symbols which can only represent + distances not exceeding BROTLI_MAX_ALLOWED_DISTANCE. */ + +var maxDistanceSymbol_bound = [maxNpostfix + 1]uint32{0, 4, 12, 28} +var maxDistanceSymbol_diff = [maxNpostfix + 1]uint32{73, 126, 228, 424} + +func maxDistanceSymbol(ndirect uint32, npostfix uint32) uint32 { + var postfix uint32 = 1 << npostfix + if ndirect < maxDistanceSymbol_bound[npostfix] { + return ndirect + maxDistanceSymbol_diff[npostfix] + postfix + } else if ndirect > maxDistanceSymbol_bound[npostfix]+postfix { + return ndirect + maxDistanceSymbol_diff[npostfix] + } else { + return maxDistanceSymbol_bound[npostfix] + maxDistanceSymbol_diff[npostfix] + postfix + } +} + +/* Invariant: input stream is never overconsumed: + - invalid input implies that the whole stream is invalid -> any amount of + input could be read and discarded + - when result is "needs more input", then at least one more byte is REQUIRED + to complete decoding; all input data MUST be consumed by decoder, so + client could swap the input buffer + - when result is "needs more output" decoder MUST ensure that it doesn't + hold more than 7 bits in bit reader; this saves client from swapping input + buffer ahead of time + - when result is "success" decoder MUST return all unused data back to input + buffer; this is possible because the invariant is held on enter */ +func decoderDecompressStream(s *Reader, available_in *uint, next_in *[]byte, available_out *uint, next_out *[]byte) int { + var result int = decoderSuccess + var br *bitReader = &s.br + + /* Do not try to process further in a case of unrecoverable error. */ + if int(s.error_code) < 0 { + return decoderResultError + } + + if *available_out != 0 && (next_out == nil || *next_out == nil) { + return saveErrorCode(s, decoderErrorInvalidArguments) + } + + if *available_out == 0 { + next_out = nil + } + if s.buffer_length == 0 { /* Just connect bit reader to input stream. */ + br.input_len = *available_in + br.input = *next_in + br.byte_pos = 0 + } else { + /* At least one byte of input is required. More than one byte of input may + be required to complete the transaction -> reading more data must be + done in a loop -> do it in a main loop. */ + result = decoderNeedsMoreInput + + br.input = s.buffer.u8[:] + br.byte_pos = 0 + } + + /* State machine */ + for { + if result != decoderSuccess { + /* Error, needs more input/output. */ + if result == decoderNeedsMoreInput { + if s.ringbuffer != nil { /* Pro-actively push output. */ + var intermediate_result int = writeRingBuffer(s, available_out, next_out, nil, true) + + /* WriteRingBuffer checks s->meta_block_remaining_len validity. */ + if int(intermediate_result) < 0 { + result = intermediate_result + break + } + } + + if s.buffer_length != 0 { /* Used with internal buffer. */ + if br.byte_pos == br.input_len { + /* Successfully finished read transaction. + Accumulator contains less than 8 bits, because internal buffer + is expanded byte-by-byte until it is enough to complete read. */ + s.buffer_length = 0 + + /* Switch to input stream and restart. */ + result = decoderSuccess + + br.input_len = *available_in + br.input = *next_in + br.byte_pos = 0 + continue + } else if *available_in != 0 { + /* Not enough data in buffer, but can take one more byte from + input stream. */ + result = decoderSuccess + + s.buffer.u8[s.buffer_length] = (*next_in)[0] + s.buffer_length++ + br.input_len = uint(s.buffer_length) + *next_in = (*next_in)[1:] + (*available_in)-- + + /* Retry with more data in buffer. */ + continue + } + + /* Can't finish reading and no more input. */ + break + /* Input stream doesn't contain enough input. */ + } else { + /* Copy tail to internal buffer and return. */ + *next_in = br.input[br.byte_pos:] + + *available_in = br.input_len - br.byte_pos + for *available_in != 0 { + s.buffer.u8[s.buffer_length] = (*next_in)[0] + s.buffer_length++ + *next_in = (*next_in)[1:] + (*available_in)-- + } + + break + } + } + + /* Unreachable. */ + + /* Fail or needs more output. */ + if s.buffer_length != 0 { + /* Just consumed the buffered input and produced some output. Otherwise + it would result in "needs more input". Reset internal buffer. */ + s.buffer_length = 0 + } else { + /* Using input stream in last iteration. When decoder switches to input + stream it has less than 8 bits in accumulator, so it is safe to + return unused accumulator bits there. */ + bitReaderUnload(br) + + *available_in = br.input_len - br.byte_pos + *next_in = br.input[br.byte_pos:] + } + + break + } + + switch s.state { + /* Prepare to the first read. */ + case stateUninited: + if !warmupBitReader(br) { + result = decoderNeedsMoreInput + break + } + + /* Decode window size. */ + result = decodeWindowBits(s, br) /* Reads 1..8 bits. */ + if result != decoderSuccess { + break + } + + if s.large_window { + s.state = stateLargeWindowBits + break + } + + s.state = stateInitialize + + case stateLargeWindowBits: + if !safeReadBits(br, 6, &s.window_bits) { + result = decoderNeedsMoreInput + break + } + + if s.window_bits < largeMinWbits || s.window_bits > largeMaxWbits { + result = decoderErrorFormatWindowBits + break + } + + s.state = stateInitialize + fallthrough + + /* Maximum distance, see section 9.1. of the spec. */ + /* Fall through. */ + case stateInitialize: + s.max_backward_distance = (1 << s.window_bits) - windowGap + + /* Allocate memory for both block_type_trees and block_len_trees. */ + s.block_type_trees = make([]huffmanCode, (3 * (huffmanMaxSize258 + huffmanMaxSize26))) + + if s.block_type_trees == nil { + result = decoderErrorAllocBlockTypeTrees + break + } + + s.block_len_trees = s.block_type_trees[3*huffmanMaxSize258:] + + s.state = stateMetablockBegin + fallthrough + + /* Fall through. */ + case stateMetablockBegin: + decoderStateMetablockBegin(s) + + s.state = stateMetablockHeader + fallthrough + + /* Fall through. */ + case stateMetablockHeader: + result = decodeMetaBlockLength(s, br) + /* Reads 2 - 31 bits. */ + if result != decoderSuccess { + break + } + + if s.is_metadata != 0 || s.is_uncompressed != 0 { + if !bitReaderJumpToByteBoundary(br) { + result = decoderErrorFormatPadding1 + break + } + } + + if s.is_metadata != 0 { + s.state = stateMetadata + break + } + + if s.meta_block_remaining_len == 0 { + s.state = stateMetablockDone + break + } + + calculateRingBufferSize(s) + if s.is_uncompressed != 0 { + s.state = stateUncompressed + break + } + + s.loop_counter = 0 + s.state = stateHuffmanCode0 + + case stateUncompressed: + result = copyUncompressedBlockToOutput(available_out, next_out, nil, s) + if result == decoderSuccess { + s.state = stateMetablockDone + } + + case stateMetadata: + for ; s.meta_block_remaining_len > 0; s.meta_block_remaining_len-- { + var bits uint32 + + /* Read one byte and ignore it. */ + if !safeReadBits(br, 8, &bits) { + result = decoderNeedsMoreInput + break + } + } + + if result == decoderSuccess { + s.state = stateMetablockDone + } + + case stateHuffmanCode0: + if s.loop_counter >= 3 { + s.state = stateMetablockHeader2 + break + } + + /* Reads 1..11 bits. */ + result = decodeVarLenUint8(s, br, &s.num_block_types[s.loop_counter]) + + if result != decoderSuccess { + break + } + + s.num_block_types[s.loop_counter]++ + if s.num_block_types[s.loop_counter] < 2 { + s.loop_counter++ + break + } + + s.state = stateHuffmanCode1 + fallthrough + + case stateHuffmanCode1: + { + var alphabet_size uint32 = s.num_block_types[s.loop_counter] + 2 + var tree_offset int = s.loop_counter * huffmanMaxSize258 + result = readHuffmanCode(alphabet_size, alphabet_size, s.block_type_trees[tree_offset:], nil, s) + if result != decoderSuccess { + break + } + s.state = stateHuffmanCode2 + } + fallthrough + + case stateHuffmanCode2: + { + var alphabet_size uint32 = numBlockLenSymbols + var tree_offset int = s.loop_counter * huffmanMaxSize26 + result = readHuffmanCode(alphabet_size, alphabet_size, s.block_len_trees[tree_offset:], nil, s) + if result != decoderSuccess { + break + } + s.state = stateHuffmanCode3 + } + fallthrough + + case stateHuffmanCode3: + var tree_offset int = s.loop_counter * huffmanMaxSize26 + if !safeReadBlockLength(s, &s.block_length[s.loop_counter], s.block_len_trees[tree_offset:], br) { + result = decoderNeedsMoreInput + break + } + + s.loop_counter++ + s.state = stateHuffmanCode0 + + case stateMetablockHeader2: + { + var bits uint32 + if !safeReadBits(br, 6, &bits) { + result = decoderNeedsMoreInput + break + } + + s.distance_postfix_bits = bits & bitMask(2) + bits >>= 2 + s.num_direct_distance_codes = numDistanceShortCodes + (bits << s.distance_postfix_bits) + s.distance_postfix_mask = int(bitMask(s.distance_postfix_bits)) + s.context_modes = make([]byte, uint(s.num_block_types[0])) + if s.context_modes == nil { + result = decoderErrorAllocContextModes + break + } + + s.loop_counter = 0 + s.state = stateContextModes + } + fallthrough + + case stateContextModes: + result = readContextModes(s) + + if result != decoderSuccess { + break + } + + s.state = stateContextMap1 + fallthrough + + case stateContextMap1: + result = decodeContextMap(s.num_block_types[0]<= 3 { + prepareLiteralDecoding(s) + s.dist_context_map_slice = s.dist_context_map + s.htree_command = []huffmanCode(s.insert_copy_hgroup.htrees[0]) + if !ensureRingBuffer(s) { + result = decoderErrorAllocRingBuffer2 + break + } + + s.state = stateCommandBegin + } + + case stateCommandBegin, stateCommandInner, stateCommandPostDecodeLiterals, stateCommandPostWrapCopy: + result = processCommands(s) + + if result == decoderNeedsMoreInput { + result = safeProcessCommands(s) + } + + case stateCommandInnerWrite, stateCommandPostWrite1, stateCommandPostWrite2: + result = writeRingBuffer(s, available_out, next_out, nil, false) + + if result != decoderSuccess { + break + } + + wrapRingBuffer(s) + if s.ringbuffer_size == 1<= uint64(block_size) { + return 0 + } + return block_size - uint(delta) +} + +/* Wraps 64-bit input position to 32-bit ring-buffer position preserving + "not-a-first-lap" feature. */ +func wrapPosition(position uint64) uint32 { + var result uint32 = uint32(position) + var gb uint64 = position >> 30 + if gb > 2 { + /* Wrap every 2GiB; The first 3GB are continuous. */ + result = result&((1<<30)-1) | (uint32((gb-1)&1)+1)<<30 + } + + return result +} + +func (s *Writer) getStorage(size int) []byte { + if len(s.storage) < size { + s.storage = make([]byte, size) + } + + return s.storage +} + +func hashTableSize(max_table_size uint, input_size uint) uint { + var htsize uint = 256 + for htsize < max_table_size && htsize < input_size { + htsize <<= 1 + } + + return htsize +} + +func getHashTable(s *Writer, quality int, input_size uint, table_size *uint) []int { + var max_table_size uint = maxHashTableSize(quality) + var htsize uint = hashTableSize(max_table_size, input_size) + /* Use smaller hash table when input.size() is smaller, since we + fill the table, incurring O(hash table size) overhead for + compression, and if the input is short, we won't need that + many hash table entries anyway. */ + + var table []int + assert(max_table_size >= 256) + if quality == fastOnePassCompressionQuality { + /* Only odd shifts are supported by fast-one-pass. */ + if htsize&0xAAAAA == 0 { + htsize <<= 1 + } + } + + if htsize <= uint(len(s.small_table_)) { + table = s.small_table_[:] + } else { + if htsize > s.large_table_size_ { + s.large_table_size_ = htsize + s.large_table_ = nil + s.large_table_ = make([]int, htsize) + } + + table = s.large_table_ + } + + *table_size = htsize + for i := 0; i < int(htsize); i++ { + table[i] = 0 + } + return table +} + +func encodeWindowBits(lgwin int, large_window bool, last_bytes *uint16, last_bytes_bits *byte) { + if large_window { + *last_bytes = uint16((lgwin&0x3F)<<8 | 0x11) + *last_bytes_bits = 14 + } else { + if lgwin == 16 { + *last_bytes = 0 + *last_bytes_bits = 1 + } else if lgwin == 17 { + *last_bytes = 1 + *last_bytes_bits = 7 + } else if lgwin > 17 { + *last_bytes = uint16((lgwin-17)<<1 | 0x01) + *last_bytes_bits = 4 + } else { + *last_bytes = uint16((lgwin-8)<<4 | 0x01) + *last_bytes_bits = 7 + } + } +} + +/* Decide about the context map based on the ability of the prediction + ability of the previous byte UTF8-prefix on the next byte. The + prediction ability is calculated as Shannon entropy. Here we need + Shannon entropy instead of 'BitsEntropy' since the prefix will be + encoded with the remaining 6 bits of the following byte, and + BitsEntropy will assume that symbol to be stored alone using Huffman + coding. */ + +var kStaticContextMapContinuation = [64]uint32{ + 1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +} +var kStaticContextMapSimpleUTF8 = [64]uint32{ + 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +} + +func chooseContextMap(quality int, bigram_histo []uint32, num_literal_contexts *uint, literal_context_map *[]uint32) { + var monogram_histo = [3]uint32{0} + var two_prefix_histo = [6]uint32{0} + var total uint + var i uint + var dummy uint + var entropy [4]float64 + for i = 0; i < 9; i++ { + monogram_histo[i%3] += bigram_histo[i] + two_prefix_histo[i%6] += bigram_histo[i] + } + + entropy[1] = shannonEntropy(monogram_histo[:], 3, &dummy) + entropy[2] = (shannonEntropy(two_prefix_histo[:], 3, &dummy) + shannonEntropy(two_prefix_histo[3:], 3, &dummy)) + entropy[3] = 0 + for i = 0; i < 3; i++ { + entropy[3] += shannonEntropy(bigram_histo[3*i:], 3, &dummy) + } + + total = uint(monogram_histo[0] + monogram_histo[1] + monogram_histo[2]) + assert(total != 0) + entropy[0] = 1.0 / float64(total) + entropy[1] *= entropy[0] + entropy[2] *= entropy[0] + entropy[3] *= entropy[0] + + if quality < minQualityForHqContextModeling { + /* 3 context models is a bit slower, don't use it at lower qualities. */ + entropy[3] = entropy[1] * 10 + } + + /* If expected savings by symbol are less than 0.2 bits, skip the + context modeling -- in exchange for faster decoding speed. */ + if entropy[1]-entropy[2] < 0.2 && entropy[1]-entropy[3] < 0.2 { + *num_literal_contexts = 1 + } else if entropy[2]-entropy[3] < 0.02 { + *num_literal_contexts = 2 + *literal_context_map = kStaticContextMapSimpleUTF8[:] + } else { + *num_literal_contexts = 3 + *literal_context_map = kStaticContextMapContinuation[:] + } +} + +/* Decide if we want to use a more complex static context map containing 13 + context values, based on the entropy reduction of histograms over the + first 5 bits of literals. */ + +var kStaticContextMapComplexUTF8 = [64]uint32{ + 11, 11, 12, 12, /* 0 special */ + 0, 0, 0, 0, /* 4 lf */ + 1, 1, 9, 9, /* 8 space */ + 2, 2, 2, 2, /* !, first after space/lf and after something else. */ + 1, 1, 1, 1, /* " */ + 8, 3, 3, 3, /* % */ + 1, 1, 1, 1, /* ({[ */ + 2, 2, 2, 2, /* }]) */ + 8, 4, 4, 4, /* :; */ + 8, 7, 4, 4, /* . */ + 8, 0, 0, 0, /* > */ + 3, 3, 3, 3, /* [0..9] */ + 5, 5, 10, 5, /* [A-Z] */ + 5, 5, 10, 5, + 6, 6, 6, 6, /* [a-z] */ + 6, 6, 6, 6, +} + +func shouldUseComplexStaticContextMap(input []byte, start_pos uint, length uint, mask uint, quality int, size_hint uint, num_literal_contexts *uint, literal_context_map *[]uint32) bool { + /* Try the more complex static context map only for long data. */ + if size_hint < 1<<20 { + return false + } else { + var end_pos uint = start_pos + length + var combined_histo = [32]uint32{0} + var context_histo = [13][32]uint32{[32]uint32{0}} + var total uint32 = 0 + var entropy [3]float64 + var dummy uint + var i uint + var utf8_lut contextLUT = getContextLUT(contextUTF8) + /* To make entropy calculations faster and to fit on the stack, we collect + histograms over the 5 most significant bits of literals. One histogram + without context and 13 additional histograms for each context value. */ + for ; start_pos+64 <= end_pos; start_pos += 4096 { + var stride_end_pos uint = start_pos + 64 + var prev2 byte = input[start_pos&mask] + var prev1 byte = input[(start_pos+1)&mask] + var pos uint + + /* To make the analysis of the data faster we only examine 64 byte long + strides at every 4kB intervals. */ + for pos = start_pos + 2; pos < stride_end_pos; pos++ { + var literal byte = input[pos&mask] + var context byte = byte(kStaticContextMapComplexUTF8[getContext(prev1, prev2, utf8_lut)]) + total++ + combined_histo[literal>>3]++ + context_histo[context][literal>>3]++ + prev2 = prev1 + prev1 = literal + } + } + + entropy[1] = shannonEntropy(combined_histo[:], 32, &dummy) + entropy[2] = 0 + for i = 0; i < 13; i++ { + entropy[2] += shannonEntropy(context_histo[i][0:], 32, &dummy) + } + + entropy[0] = 1.0 / float64(total) + entropy[1] *= entropy[0] + entropy[2] *= entropy[0] + + /* The triggering heuristics below were tuned by compressing the individual + files of the silesia corpus. If we skip this kind of context modeling + for not very well compressible input (i.e. entropy using context modeling + is 60% of maximal entropy) or if expected savings by symbol are less + than 0.2 bits, then in every case when it triggers, the final compression + ratio is improved. Note however that this heuristics might be too strict + for some cases and could be tuned further. */ + if entropy[2] > 3.0 || entropy[1]-entropy[2] < 0.2 { + return false + } else { + *num_literal_contexts = 13 + *literal_context_map = kStaticContextMapComplexUTF8[:] + return true + } + } +} + +func decideOverLiteralContextModeling(input []byte, start_pos uint, length uint, mask uint, quality int, size_hint uint, num_literal_contexts *uint, literal_context_map *[]uint32) { + if quality < minQualityForContextModeling || length < 64 { + return + } else if shouldUseComplexStaticContextMap(input, start_pos, length, mask, quality, size_hint, num_literal_contexts, literal_context_map) { + } else /* Context map was already set, nothing else to do. */ + { + var end_pos uint = start_pos + length + /* Gather bi-gram data of the UTF8 byte prefixes. To make the analysis of + UTF8 data faster we only examine 64 byte long strides at every 4kB + intervals. */ + + var bigram_prefix_histo = [9]uint32{0} + for ; start_pos+64 <= end_pos; start_pos += 4096 { + var lut = [4]int{0, 0, 1, 2} + var stride_end_pos uint = start_pos + 64 + var prev int = lut[input[start_pos&mask]>>6] * 3 + var pos uint + for pos = start_pos + 1; pos < stride_end_pos; pos++ { + var literal byte = input[pos&mask] + bigram_prefix_histo[prev+lut[literal>>6]]++ + prev = lut[literal>>6] * 3 + } + } + + chooseContextMap(quality, bigram_prefix_histo[0:], num_literal_contexts, literal_context_map) + } +} + +func shouldCompress_encode(data []byte, mask uint, last_flush_pos uint64, bytes uint, num_literals uint, num_commands uint) bool { + /* TODO: find more precise minimal block overhead. */ + if bytes <= 2 { + return false + } + if num_commands < (bytes>>8)+2 { + if float64(num_literals) > 0.99*float64(bytes) { + var literal_histo = [256]uint32{0} + const kSampleRate uint32 = 13 + const kMinEntropy float64 = 7.92 + var bit_cost_threshold float64 = float64(bytes) * kMinEntropy / float64(kSampleRate) + var t uint = uint((uint32(bytes) + kSampleRate - 1) / kSampleRate) + var pos uint32 = uint32(last_flush_pos) + var i uint + for i = 0; i < t; i++ { + literal_histo[data[pos&uint32(mask)]]++ + pos += kSampleRate + } + + if bitsEntropy(literal_histo[:], 256) > bit_cost_threshold { + return false + } + } + } + + return true +} + +/* Chooses the literal context mode for a metablock */ +func chooseContextMode(params *encoderParams, data []byte, pos uint, mask uint, length uint) int { + /* We only do the computation for the option of something else than + CONTEXT_UTF8 for the highest qualities */ + if params.quality >= minQualityForHqBlockSplitting && !isMostlyUTF8(data, pos, mask, length, kMinUTF8Ratio) { + return contextSigned + } + + return contextUTF8 +} + +func writeMetaBlockInternal(data []byte, mask uint, last_flush_pos uint64, bytes uint, is_last bool, literal_context_mode int, params *encoderParams, prev_byte byte, prev_byte2 byte, num_literals uint, commands []command, saved_dist_cache []int, dist_cache []int, storage_ix *uint, storage []byte) { + var wrapped_last_flush_pos uint32 = wrapPosition(last_flush_pos) + var last_bytes uint16 + var last_bytes_bits byte + var literal_context_lut contextLUT = getContextLUT(literal_context_mode) + var block_params encoderParams = *params + + if bytes == 0 { + /* Write the ISLAST and ISEMPTY bits. */ + writeBits(2, 3, storage_ix, storage) + + *storage_ix = (*storage_ix + 7) &^ 7 + return + } + + if !shouldCompress_encode(data, mask, last_flush_pos, bytes, num_literals, uint(len(commands))) { + /* Restore the distance cache, as its last update by + CreateBackwardReferences is now unused. */ + copy(dist_cache, saved_dist_cache[:4]) + + storeUncompressedMetaBlock(is_last, data, uint(wrapped_last_flush_pos), mask, bytes, storage_ix, storage) + return + } + + assert(*storage_ix <= 14) + last_bytes = uint16(storage[1])<<8 | uint16(storage[0]) + last_bytes_bits = byte(*storage_ix) + if params.quality <= maxQualityForStaticEntropyCodes { + storeMetaBlockFast(data, uint(wrapped_last_flush_pos), bytes, mask, is_last, params, commands, storage_ix, storage) + } else if params.quality < minQualityForBlockSplit { + storeMetaBlockTrivial(data, uint(wrapped_last_flush_pos), bytes, mask, is_last, params, commands, storage_ix, storage) + } else { + mb := getMetaBlockSplit() + if params.quality < minQualityForHqBlockSplitting { + var num_literal_contexts uint = 1 + var literal_context_map []uint32 = nil + if !params.disable_literal_context_modeling { + decideOverLiteralContextModeling(data, uint(wrapped_last_flush_pos), bytes, mask, params.quality, params.size_hint, &num_literal_contexts, &literal_context_map) + } + + buildMetaBlockGreedy(data, uint(wrapped_last_flush_pos), mask, prev_byte, prev_byte2, literal_context_lut, num_literal_contexts, literal_context_map, commands, mb) + } else { + buildMetaBlock(data, uint(wrapped_last_flush_pos), mask, &block_params, prev_byte, prev_byte2, commands, literal_context_mode, mb) + } + + if params.quality >= minQualityForOptimizeHistograms { + /* The number of distance symbols effectively used for distance + histograms. It might be less than distance alphabet size + for "Large Window Brotli" (32-bit). */ + var num_effective_dist_codes uint32 = block_params.dist.alphabet_size + if num_effective_dist_codes > numHistogramDistanceSymbols { + num_effective_dist_codes = numHistogramDistanceSymbols + } + + optimizeHistograms(num_effective_dist_codes, mb) + } + + storeMetaBlock(data, uint(wrapped_last_flush_pos), bytes, mask, prev_byte, prev_byte2, is_last, &block_params, literal_context_mode, commands, mb, storage_ix, storage) + freeMetaBlockSplit(mb) + } + + if bytes+4 < *storage_ix>>3 { + /* Restore the distance cache and last byte. */ + copy(dist_cache, saved_dist_cache[:4]) + + storage[0] = byte(last_bytes) + storage[1] = byte(last_bytes >> 8) + *storage_ix = uint(last_bytes_bits) + storeUncompressedMetaBlock(is_last, data, uint(wrapped_last_flush_pos), mask, bytes, storage_ix, storage) + } +} + +func chooseDistanceParams(params *encoderParams) { + var distance_postfix_bits uint32 = 0 + var num_direct_distance_codes uint32 = 0 + + if params.quality >= minQualityForNonzeroDistanceParams { + var ndirect_msb uint32 + if params.mode == modeFont { + distance_postfix_bits = 1 + num_direct_distance_codes = 12 + } else { + distance_postfix_bits = params.dist.distance_postfix_bits + num_direct_distance_codes = params.dist.num_direct_distance_codes + } + + ndirect_msb = (num_direct_distance_codes >> distance_postfix_bits) & 0x0F + if distance_postfix_bits > maxNpostfix || num_direct_distance_codes > maxNdirect || ndirect_msb<>25)), (last_command.dist_prefix_&0x3FF == 0), &last_command.cmd_prefix_) + } +} + +/* + Processes the accumulated input data and writes + the new output meta-block to s.dest, if one has been + created (otherwise the processed input data is buffered internally). + If |is_last| or |force_flush| is true, an output meta-block is + always created. However, until |is_last| is true encoder may retain up + to 7 bits of the last byte of output. To force encoder to dump the remaining + bits use WriteMetadata() to append an empty meta-data block. + Returns false if the size of the input data is larger than + input_block_size(). +*/ +func encodeData(s *Writer, is_last bool, force_flush bool) bool { + var delta uint64 = unprocessedInputSize(s) + var bytes uint32 = uint32(delta) + var wrapped_last_processed_pos uint32 = wrapPosition(s.last_processed_pos_) + var data []byte + var mask uint32 + var literal_context_mode int + + data = s.ringbuffer_.buffer_ + mask = s.ringbuffer_.mask_ + + /* Adding more blocks after "last" block is forbidden. */ + if s.is_last_block_emitted_ { + return false + } + if is_last { + s.is_last_block_emitted_ = true + } + + if delta > uint64(inputBlockSize(s)) { + return false + } + + if s.params.quality == fastTwoPassCompressionQuality { + if s.command_buf_ == nil || cap(s.command_buf_) < int(kCompressFragmentTwoPassBlockSize) { + s.command_buf_ = make([]uint32, kCompressFragmentTwoPassBlockSize) + s.literal_buf_ = make([]byte, kCompressFragmentTwoPassBlockSize) + } else { + s.command_buf_ = s.command_buf_[:kCompressFragmentTwoPassBlockSize] + s.literal_buf_ = s.literal_buf_[:kCompressFragmentTwoPassBlockSize] + } + } + + if s.params.quality == fastOnePassCompressionQuality || s.params.quality == fastTwoPassCompressionQuality { + var storage []byte + var storage_ix uint = uint(s.last_bytes_bits_) + var table_size uint + var table []int + + if delta == 0 && !is_last { + /* We have no new input data and we don't have to finish the stream, so + nothing to do. */ + return true + } + + storage = s.getStorage(int(2*bytes + 503)) + storage[0] = byte(s.last_bytes_) + storage[1] = byte(s.last_bytes_ >> 8) + table = getHashTable(s, s.params.quality, uint(bytes), &table_size) + if s.params.quality == fastOnePassCompressionQuality { + compressFragmentFast(data[wrapped_last_processed_pos&mask:], uint(bytes), is_last, table, table_size, s.cmd_depths_[:], s.cmd_bits_[:], &s.cmd_code_numbits_, s.cmd_code_[:], &storage_ix, storage) + } else { + compressFragmentTwoPass(data[wrapped_last_processed_pos&mask:], uint(bytes), is_last, s.command_buf_, s.literal_buf_, table, table_size, &storage_ix, storage) + } + + s.last_bytes_ = uint16(storage[storage_ix>>3]) + s.last_bytes_bits_ = byte(storage_ix & 7) + updateLastProcessedPos(s) + s.writeOutput(storage[:storage_ix>>3]) + return true + } + { + /* Theoretical max number of commands is 1 per 2 bytes. */ + newsize := len(s.commands) + int(bytes)/2 + 1 + if newsize > cap(s.commands) { + /* Reserve a bit more memory to allow merging with a next block + without reallocation: that would impact speed. */ + newsize += int(bytes/4) + 16 + + new_commands := make([]command, len(s.commands), newsize) + if s.commands != nil { + copy(new_commands, s.commands) + } + + s.commands = new_commands + } + } + + initOrStitchToPreviousBlock(&s.hasher_, data, uint(mask), &s.params, uint(wrapped_last_processed_pos), uint(bytes), is_last) + + literal_context_mode = chooseContextMode(&s.params, data, uint(wrapPosition(s.last_flush_pos_)), uint(mask), uint(s.input_pos_-s.last_flush_pos_)) + + if len(s.commands) != 0 && s.last_insert_len_ == 0 { + extendLastCommand(s, &bytes, &wrapped_last_processed_pos) + } + + if s.params.quality == zopflificationQuality { + assert(s.params.hasher.type_ == 10) + createZopfliBackwardReferences(uint(bytes), uint(wrapped_last_processed_pos), data, uint(mask), &s.params, s.hasher_.(*h10), s.dist_cache_[:], &s.last_insert_len_, &s.commands, &s.num_literals_) + } else if s.params.quality == hqZopflificationQuality { + assert(s.params.hasher.type_ == 10) + createHqZopfliBackwardReferences(uint(bytes), uint(wrapped_last_processed_pos), data, uint(mask), &s.params, s.hasher_, s.dist_cache_[:], &s.last_insert_len_, &s.commands, &s.num_literals_) + } else { + createBackwardReferences(uint(bytes), uint(wrapped_last_processed_pos), data, uint(mask), &s.params, s.hasher_, s.dist_cache_[:], &s.last_insert_len_, &s.commands, &s.num_literals_) + } + { + var max_length uint = maxMetablockSize(&s.params) + var max_literals uint = max_length / 8 + max_commands := int(max_length / 8) + var processed_bytes uint = uint(s.input_pos_ - s.last_flush_pos_) + var next_input_fits_metablock bool = (processed_bytes+inputBlockSize(s) <= max_length) + var should_flush bool = (s.params.quality < minQualityForBlockSplit && s.num_literals_+uint(len(s.commands)) >= maxNumDelayedSymbols) + /* If maximal possible additional block doesn't fit metablock, flush now. */ + /* TODO: Postpone decision until next block arrives? */ + + /* If block splitting is not used, then flush as soon as there is some + amount of commands / literals produced. */ + if !is_last && !force_flush && !should_flush && next_input_fits_metablock && s.num_literals_ < max_literals && len(s.commands) < max_commands { + /* Merge with next input block. Everything will happen later. */ + if updateLastProcessedPos(s) { + hasherReset(s.hasher_) + } + + return true + } + } + + /* Create the last insert-only command. */ + if s.last_insert_len_ > 0 { + s.commands = append(s.commands, makeInsertCommand(s.last_insert_len_)) + s.num_literals_ += s.last_insert_len_ + s.last_insert_len_ = 0 + } + + if !is_last && s.input_pos_ == s.last_flush_pos_ { + /* We have no new input data and we don't have to finish the stream, so + nothing to do. */ + return true + } + + assert(s.input_pos_ >= s.last_flush_pos_) + assert(s.input_pos_ > s.last_flush_pos_ || is_last) + assert(s.input_pos_-s.last_flush_pos_ <= 1<<24) + { + var metablock_size uint32 = uint32(s.input_pos_ - s.last_flush_pos_) + var storage []byte = s.getStorage(int(2*metablock_size + 503)) + var storage_ix uint = uint(s.last_bytes_bits_) + storage[0] = byte(s.last_bytes_) + storage[1] = byte(s.last_bytes_ >> 8) + writeMetaBlockInternal(data, uint(mask), s.last_flush_pos_, uint(metablock_size), is_last, literal_context_mode, &s.params, s.prev_byte_, s.prev_byte2_, s.num_literals_, s.commands, s.saved_dist_cache_[:], s.dist_cache_[:], &storage_ix, storage) + s.last_bytes_ = uint16(storage[storage_ix>>3]) + s.last_bytes_bits_ = byte(storage_ix & 7) + s.last_flush_pos_ = s.input_pos_ + if updateLastProcessedPos(s) { + hasherReset(s.hasher_) + } + + if s.last_flush_pos_ > 0 { + s.prev_byte_ = data[(uint32(s.last_flush_pos_)-1)&mask] + } + + if s.last_flush_pos_ > 1 { + s.prev_byte2_ = data[uint32(s.last_flush_pos_-2)&mask] + } + + s.commands = s.commands[:0] + s.num_literals_ = 0 + + /* Save the state of the distance cache in case we need to restore it for + emitting an uncompressed block. */ + copy(s.saved_dist_cache_[:], s.dist_cache_[:]) + + s.writeOutput(storage[:storage_ix>>3]) + return true + } +} + +/* Dumps remaining output bits and metadata header to |header|. + Returns number of produced bytes. + REQUIRED: |header| should be 8-byte aligned and at least 16 bytes long. + REQUIRED: |block_size| <= (1 << 24). */ +func writeMetadataHeader(s *Writer, block_size uint, header []byte) uint { + storage_ix := uint(s.last_bytes_bits_) + header[0] = byte(s.last_bytes_) + header[1] = byte(s.last_bytes_ >> 8) + s.last_bytes_ = 0 + s.last_bytes_bits_ = 0 + + writeBits(1, 0, &storage_ix, header) + writeBits(2, 3, &storage_ix, header) + writeBits(1, 0, &storage_ix, header) + if block_size == 0 { + writeBits(2, 0, &storage_ix, header) + } else { + var nbits uint32 + if block_size == 1 { + nbits = 0 + } else { + nbits = log2FloorNonZero(uint(uint32(block_size)-1)) + 1 + } + var nbytes uint32 = (nbits + 7) / 8 + writeBits(2, uint64(nbytes), &storage_ix, header) + writeBits(uint(8*nbytes), uint64(block_size)-1, &storage_ix, header) + } + + return (storage_ix + 7) >> 3 +} + +func injectBytePaddingBlock(s *Writer) { + var seal uint32 = uint32(s.last_bytes_) + var seal_bits uint = uint(s.last_bytes_bits_) + s.last_bytes_ = 0 + s.last_bytes_bits_ = 0 + + /* is_last = 0, data_nibbles = 11, reserved = 0, meta_nibbles = 00 */ + seal |= 0x6 << seal_bits + + seal_bits += 6 + + destination := s.tiny_buf_.u8[:] + + destination[0] = byte(seal) + if seal_bits > 8 { + destination[1] = byte(seal >> 8) + } + if seal_bits > 16 { + destination[2] = byte(seal >> 16) + } + s.writeOutput(destination[:(seal_bits+7)>>3]) +} + +func checkFlushComplete(s *Writer) { + if s.stream_state_ == streamFlushRequested && s.err == nil { + s.stream_state_ = streamProcessing + } +} + +func encoderCompressStreamFast(s *Writer, op int, available_in *uint, next_in *[]byte) bool { + var block_size_limit uint = uint(1) << s.params.lgwin + var buf_size uint = brotli_min_size_t(kCompressFragmentTwoPassBlockSize, brotli_min_size_t(*available_in, block_size_limit)) + var command_buf []uint32 = nil + var literal_buf []byte = nil + if s.params.quality != fastOnePassCompressionQuality && s.params.quality != fastTwoPassCompressionQuality { + return false + } + + if s.params.quality == fastTwoPassCompressionQuality { + if s.command_buf_ == nil || cap(s.command_buf_) < int(buf_size) { + s.command_buf_ = make([]uint32, buf_size) + s.literal_buf_ = make([]byte, buf_size) + } else { + s.command_buf_ = s.command_buf_[:buf_size] + s.literal_buf_ = s.literal_buf_[:buf_size] + } + + command_buf = s.command_buf_ + literal_buf = s.literal_buf_ + } + + for { + if s.stream_state_ == streamFlushRequested && s.last_bytes_bits_ != 0 { + injectBytePaddingBlock(s) + continue + } + + /* Compress block only when stream is not + finished, there is no pending flush request, and there is either + additional input or pending operation. */ + if s.stream_state_ == streamProcessing && (*available_in != 0 || op != int(operationProcess)) { + var block_size uint = brotli_min_size_t(block_size_limit, *available_in) + var is_last bool = (*available_in == block_size) && (op == int(operationFinish)) + var force_flush bool = (*available_in == block_size) && (op == int(operationFlush)) + var max_out_size uint = 2*block_size + 503 + var storage []byte = nil + var storage_ix uint = uint(s.last_bytes_bits_) + var table_size uint + var table []int + + if force_flush && block_size == 0 { + s.stream_state_ = streamFlushRequested + continue + } + + storage = s.getStorage(int(max_out_size)) + + storage[0] = byte(s.last_bytes_) + storage[1] = byte(s.last_bytes_ >> 8) + table = getHashTable(s, s.params.quality, block_size, &table_size) + + if s.params.quality == fastOnePassCompressionQuality { + compressFragmentFast(*next_in, block_size, is_last, table, table_size, s.cmd_depths_[:], s.cmd_bits_[:], &s.cmd_code_numbits_, s.cmd_code_[:], &storage_ix, storage) + } else { + compressFragmentTwoPass(*next_in, block_size, is_last, command_buf, literal_buf, table, table_size, &storage_ix, storage) + } + + *next_in = (*next_in)[block_size:] + *available_in -= block_size + var out_bytes uint = storage_ix >> 3 + s.writeOutput(storage[:out_bytes]) + + s.last_bytes_ = uint16(storage[storage_ix>>3]) + s.last_bytes_bits_ = byte(storage_ix & 7) + + if force_flush { + s.stream_state_ = streamFlushRequested + } + if is_last { + s.stream_state_ = streamFinished + } + continue + } + + break + } + + checkFlushComplete(s) + return true +} + +func processMetadata(s *Writer, available_in *uint, next_in *[]byte) bool { + if *available_in > 1<<24 { + return false + } + + /* Switch to metadata block workflow, if required. */ + if s.stream_state_ == streamProcessing { + s.remaining_metadata_bytes_ = uint32(*available_in) + s.stream_state_ = streamMetadataHead + } + + if s.stream_state_ != streamMetadataHead && s.stream_state_ != streamMetadataBody { + return false + } + + for { + if s.stream_state_ == streamFlushRequested && s.last_bytes_bits_ != 0 { + injectBytePaddingBlock(s) + continue + } + + if s.input_pos_ != s.last_flush_pos_ { + var result bool = encodeData(s, false, true) + if !result { + return false + } + continue + } + + if s.stream_state_ == streamMetadataHead { + n := writeMetadataHeader(s, uint(s.remaining_metadata_bytes_), s.tiny_buf_.u8[:]) + s.writeOutput(s.tiny_buf_.u8[:n]) + s.stream_state_ = streamMetadataBody + continue + } else { + /* Exit workflow only when there is no more input and no more output. + Otherwise client may continue producing empty metadata blocks. */ + if s.remaining_metadata_bytes_ == 0 { + s.remaining_metadata_bytes_ = math.MaxUint32 + s.stream_state_ = streamProcessing + break + } + + /* This guarantees progress in "TakeOutput" workflow. */ + var c uint32 = brotli_min_uint32_t(s.remaining_metadata_bytes_, 16) + copy(s.tiny_buf_.u8[:], (*next_in)[:c]) + *next_in = (*next_in)[c:] + *available_in -= uint(c) + s.remaining_metadata_bytes_ -= c + s.writeOutput(s.tiny_buf_.u8[:c]) + + continue + } + } + + return true +} + +func updateSizeHint(s *Writer, available_in uint) { + if s.params.size_hint == 0 { + var delta uint64 = unprocessedInputSize(s) + var tail uint64 = uint64(available_in) + var limit uint32 = 1 << 30 + var total uint32 + if (delta >= uint64(limit)) || (tail >= uint64(limit)) || ((delta + tail) >= uint64(limit)) { + total = limit + } else { + total = uint32(delta + tail) + } + + s.params.size_hint = uint(total) + } +} + +func encoderCompressStream(s *Writer, op int, available_in *uint, next_in *[]byte) bool { + if !ensureInitialized(s) { + return false + } + + /* Unfinished metadata block; check requirements. */ + if s.remaining_metadata_bytes_ != math.MaxUint32 { + if uint32(*available_in) != s.remaining_metadata_bytes_ { + return false + } + if op != int(operationEmitMetadata) { + return false + } + } + + if op == int(operationEmitMetadata) { + updateSizeHint(s, 0) /* First data metablock might be emitted here. */ + return processMetadata(s, available_in, next_in) + } + + if s.stream_state_ == streamMetadataHead || s.stream_state_ == streamMetadataBody { + return false + } + + if s.stream_state_ != streamProcessing && *available_in != 0 { + return false + } + + if s.params.quality == fastOnePassCompressionQuality || s.params.quality == fastTwoPassCompressionQuality { + return encoderCompressStreamFast(s, op, available_in, next_in) + } + + for { + var remaining_block_size uint = remainingInputBlockSize(s) + + if remaining_block_size != 0 && *available_in != 0 { + var copy_input_size uint = brotli_min_size_t(remaining_block_size, *available_in) + copyInputToRingBuffer(s, copy_input_size, *next_in) + *next_in = (*next_in)[copy_input_size:] + *available_in -= copy_input_size + continue + } + + if s.stream_state_ == streamFlushRequested && s.last_bytes_bits_ != 0 { + injectBytePaddingBlock(s) + continue + } + + /* Compress data only when stream is not + finished and there is no pending flush request. */ + if s.stream_state_ == streamProcessing { + if remaining_block_size == 0 || op != int(operationProcess) { + var is_last bool = ((*available_in == 0) && op == int(operationFinish)) + var force_flush bool = ((*available_in == 0) && op == int(operationFlush)) + var result bool + updateSizeHint(s, *available_in) + result = encodeData(s, is_last, force_flush) + if !result { + return false + } + if force_flush { + s.stream_state_ = streamFlushRequested + } + if is_last { + s.stream_state_ = streamFinished + } + continue + } + } + + break + } + + checkFlushComplete(s) + return true +} + +func (w *Writer) writeOutput(data []byte) { + if w.err != nil { + return + } + + _, w.err = w.dst.Write(data) + if w.err == nil { + checkFlushComplete(w) + } +} diff --git a/vendor/github.com/andybalholm/brotli/encoder_dict.go b/vendor/github.com/andybalholm/brotli/encoder_dict.go new file mode 100644 index 0000000..55c051c --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/encoder_dict.go @@ -0,0 +1,22 @@ +package brotli + +/* Dictionary data (words and transforms) for 1 possible context */ +type encoderDictionary struct { + words *dictionary + cutoffTransformsCount uint32 + cutoffTransforms uint64 + hash_table []uint16 + buckets []uint16 + dict_words []dictWord +} + +func initEncoderDictionary(dict *encoderDictionary) { + dict.words = getDictionary() + + dict.hash_table = kStaticDictionaryHash[:] + dict.buckets = kStaticDictionaryBuckets[:] + dict.dict_words = kStaticDictionaryWords[:] + + dict.cutoffTransformsCount = kCutoffTransformsCount + dict.cutoffTransforms = kCutoffTransforms +} diff --git a/vendor/github.com/andybalholm/brotli/entropy_encode.go b/vendor/github.com/andybalholm/brotli/entropy_encode.go new file mode 100644 index 0000000..3f469a3 --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/entropy_encode.go @@ -0,0 +1,592 @@ +package brotli + +import "math" + +/* Copyright 2010 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Entropy encoding (Huffman) utilities. */ + +/* A node of a Huffman tree. */ +type huffmanTree struct { + total_count_ uint32 + index_left_ int16 + index_right_or_value_ int16 +} + +func initHuffmanTree(self *huffmanTree, count uint32, left int16, right int16) { + self.total_count_ = count + self.index_left_ = left + self.index_right_or_value_ = right +} + +/* Input size optimized Shell sort. */ +type huffmanTreeComparator func(huffmanTree, huffmanTree) bool + +var sortHuffmanTreeItems_gaps = []uint{132, 57, 23, 10, 4, 1} + +func sortHuffmanTreeItems(items []huffmanTree, n uint, comparator huffmanTreeComparator) { + if n < 13 { + /* Insertion sort. */ + var i uint + for i = 1; i < n; i++ { + var tmp huffmanTree = items[i] + var k uint = i + var j uint = i - 1 + for comparator(tmp, items[j]) { + items[k] = items[j] + k = j + if j == 0 { + break + } + j-- + } + + items[k] = tmp + } + + return + } else { + var g int + if n < 57 { + g = 2 + } else { + g = 0 + } + for ; g < 6; g++ { + var gap uint = sortHuffmanTreeItems_gaps[g] + var i uint + for i = gap; i < n; i++ { + var j uint = i + var tmp huffmanTree = items[i] + for ; j >= gap && comparator(tmp, items[j-gap]); j -= gap { + items[j] = items[j-gap] + } + + items[j] = tmp + } + } + } +} + +/* Returns 1 if assignment of depths succeeded, otherwise 0. */ +func setDepth(p0 int, pool []huffmanTree, depth []byte, max_depth int) bool { + var stack [16]int + var level int = 0 + var p int = p0 + assert(max_depth <= 15) + stack[0] = -1 + for { + if pool[p].index_left_ >= 0 { + level++ + if level > max_depth { + return false + } + stack[level] = int(pool[p].index_right_or_value_) + p = int(pool[p].index_left_) + continue + } else { + depth[pool[p].index_right_or_value_] = byte(level) + } + + for level >= 0 && stack[level] == -1 { + level-- + } + if level < 0 { + return true + } + p = stack[level] + stack[level] = -1 + } +} + +/* Sort the root nodes, least popular first. */ +func sortHuffmanTree(v0 huffmanTree, v1 huffmanTree) bool { + if v0.total_count_ != v1.total_count_ { + return v0.total_count_ < v1.total_count_ + } + + return v0.index_right_or_value_ > v1.index_right_or_value_ +} + +/* This function will create a Huffman tree. + + The catch here is that the tree cannot be arbitrarily deep. + Brotli specifies a maximum depth of 15 bits for "code trees" + and 7 bits for "code length code trees." + + count_limit is the value that is to be faked as the minimum value + and this minimum value is raised until the tree matches the + maximum length requirement. + + This algorithm is not of excellent performance for very long data blocks, + especially when population counts are longer than 2**tree_limit, but + we are not planning to use this with extremely long blocks. + + See http://en.wikipedia.org/wiki/Huffman_coding */ +func createHuffmanTree(data []uint32, length uint, tree_limit int, tree []huffmanTree, depth []byte) { + var count_limit uint32 + var sentinel huffmanTree + initHuffmanTree(&sentinel, math.MaxUint32, -1, -1) + + /* For block sizes below 64 kB, we never need to do a second iteration + of this loop. Probably all of our block sizes will be smaller than + that, so this loop is mostly of academic interest. If we actually + would need this, we would be better off with the Katajainen algorithm. */ + for count_limit = 1; ; count_limit *= 2 { + var n uint = 0 + var i uint + var j uint + var k uint + for i = length; i != 0; { + i-- + if data[i] != 0 { + var count uint32 = brotli_max_uint32_t(data[i], count_limit) + initHuffmanTree(&tree[n], count, -1, int16(i)) + n++ + } + } + + if n == 1 { + depth[tree[0].index_right_or_value_] = 1 /* Only one element. */ + break + } + + sortHuffmanTreeItems(tree, n, huffmanTreeComparator(sortHuffmanTree)) + + /* The nodes are: + [0, n): the sorted leaf nodes that we start with. + [n]: we add a sentinel here. + [n + 1, 2n): new parent nodes are added here, starting from + (n+1). These are naturally in ascending order. + [2n]: we add a sentinel at the end as well. + There will be (2n+1) elements at the end. */ + tree[n] = sentinel + + tree[n+1] = sentinel + + i = 0 /* Points to the next leaf node. */ + j = n + 1 /* Points to the next non-leaf node. */ + for k = n - 1; k != 0; k-- { + var left uint + var right uint + if tree[i].total_count_ <= tree[j].total_count_ { + left = i + i++ + } else { + left = j + j++ + } + + if tree[i].total_count_ <= tree[j].total_count_ { + right = i + i++ + } else { + right = j + j++ + } + { + /* The sentinel node becomes the parent node. */ + var j_end uint = 2*n - k + tree[j_end].total_count_ = tree[left].total_count_ + tree[right].total_count_ + tree[j_end].index_left_ = int16(left) + tree[j_end].index_right_or_value_ = int16(right) + + /* Add back the last sentinel node. */ + tree[j_end+1] = sentinel + } + } + + if setDepth(int(2*n-1), tree[0:], depth, tree_limit) { + /* We need to pack the Huffman tree in tree_limit bits. If this was not + successful, add fake entities to the lowest values and retry. */ + break + } + } +} + +func reverse(v []byte, start uint, end uint) { + end-- + for start < end { + var tmp byte = v[start] + v[start] = v[end] + v[end] = tmp + start++ + end-- + } +} + +func writeHuffmanTreeRepetitions(previous_value byte, value byte, repetitions uint, tree_size *uint, tree []byte, extra_bits_data []byte) { + assert(repetitions > 0) + if previous_value != value { + tree[*tree_size] = value + extra_bits_data[*tree_size] = 0 + (*tree_size)++ + repetitions-- + } + + if repetitions == 7 { + tree[*tree_size] = value + extra_bits_data[*tree_size] = 0 + (*tree_size)++ + repetitions-- + } + + if repetitions < 3 { + var i uint + for i = 0; i < repetitions; i++ { + tree[*tree_size] = value + extra_bits_data[*tree_size] = 0 + (*tree_size)++ + } + } else { + var start uint = *tree_size + repetitions -= 3 + for { + tree[*tree_size] = repeatPreviousCodeLength + extra_bits_data[*tree_size] = byte(repetitions & 0x3) + (*tree_size)++ + repetitions >>= 2 + if repetitions == 0 { + break + } + + repetitions-- + } + + reverse(tree, start, *tree_size) + reverse(extra_bits_data, start, *tree_size) + } +} + +func writeHuffmanTreeRepetitionsZeros(repetitions uint, tree_size *uint, tree []byte, extra_bits_data []byte) { + if repetitions == 11 { + tree[*tree_size] = 0 + extra_bits_data[*tree_size] = 0 + (*tree_size)++ + repetitions-- + } + + if repetitions < 3 { + var i uint + for i = 0; i < repetitions; i++ { + tree[*tree_size] = 0 + extra_bits_data[*tree_size] = 0 + (*tree_size)++ + } + } else { + var start uint = *tree_size + repetitions -= 3 + for { + tree[*tree_size] = repeatZeroCodeLength + extra_bits_data[*tree_size] = byte(repetitions & 0x7) + (*tree_size)++ + repetitions >>= 3 + if repetitions == 0 { + break + } + + repetitions-- + } + + reverse(tree, start, *tree_size) + reverse(extra_bits_data, start, *tree_size) + } +} + +/* Change the population counts in a way that the consequent + Huffman tree compression, especially its RLE-part will be more + likely to compress this data more efficiently. + + length contains the size of the histogram. + counts contains the population counts. + good_for_rle is a buffer of at least length size */ +func optimizeHuffmanCountsForRLE(length uint, counts []uint32, good_for_rle []byte) { + var nonzero_count uint = 0 + var stride uint + var limit uint + var sum uint + var streak_limit uint = 1240 + var i uint + /* Let's make the Huffman code more compatible with RLE encoding. */ + for i = 0; i < length; i++ { + if counts[i] != 0 { + nonzero_count++ + } + } + + if nonzero_count < 16 { + return + } + + for length != 0 && counts[length-1] == 0 { + length-- + } + + if length == 0 { + return /* All zeros. */ + } + + /* Now counts[0..length - 1] does not have trailing zeros. */ + { + var nonzeros uint = 0 + var smallest_nonzero uint32 = 1 << 30 + for i = 0; i < length; i++ { + if counts[i] != 0 { + nonzeros++ + if smallest_nonzero > counts[i] { + smallest_nonzero = counts[i] + } + } + } + + if nonzeros < 5 { + /* Small histogram will model it well. */ + return + } + + if smallest_nonzero < 4 { + var zeros uint = length - nonzeros + if zeros < 6 { + for i = 1; i < length-1; i++ { + if counts[i-1] != 0 && counts[i] == 0 && counts[i+1] != 0 { + counts[i] = 1 + } + } + } + } + + if nonzeros < 28 { + return + } + } + + /* 2) Let's mark all population counts that already can be encoded + with an RLE code. */ + for i := 0; i < int(length); i++ { + good_for_rle[i] = 0 + } + { + var symbol uint32 = counts[0] + /* Let's not spoil any of the existing good RLE codes. + Mark any seq of 0's that is longer as 5 as a good_for_rle. + Mark any seq of non-0's that is longer as 7 as a good_for_rle. */ + + var step uint = 0 + for i = 0; i <= length; i++ { + if i == length || counts[i] != symbol { + if (symbol == 0 && step >= 5) || (symbol != 0 && step >= 7) { + var k uint + for k = 0; k < step; k++ { + good_for_rle[i-k-1] = 1 + } + } + + step = 1 + if i != length { + symbol = counts[i] + } + } else { + step++ + } + } + } + + /* 3) Let's replace those population counts that lead to more RLE codes. + Math here is in 24.8 fixed point representation. */ + stride = 0 + + limit = uint(256*(counts[0]+counts[1]+counts[2])/3 + 420) + sum = 0 + for i = 0; i <= length; i++ { + if i == length || good_for_rle[i] != 0 || (i != 0 && good_for_rle[i-1] != 0) || (256*counts[i]-uint32(limit)+uint32(streak_limit)) >= uint32(2*streak_limit) { + if stride >= 4 || (stride >= 3 && sum == 0) { + var k uint + var count uint = (sum + stride/2) / stride + /* The stride must end, collapse what we have, if we have enough (4). */ + if count == 0 { + count = 1 + } + + if sum == 0 { + /* Don't make an all zeros stride to be upgraded to ones. */ + count = 0 + } + + for k = 0; k < stride; k++ { + /* We don't want to change value at counts[i], + that is already belonging to the next stride. Thus - 1. */ + counts[i-k-1] = uint32(count) + } + } + + stride = 0 + sum = 0 + if i < length-2 { + /* All interesting strides have a count of at least 4, */ + /* at least when non-zeros. */ + limit = uint(256*(counts[i]+counts[i+1]+counts[i+2])/3 + 420) + } else if i < length { + limit = uint(256 * counts[i]) + } else { + limit = 0 + } + } + + stride++ + if i != length { + sum += uint(counts[i]) + if stride >= 4 { + limit = (256*sum + stride/2) / stride + } + + if stride == 4 { + limit += 120 + } + } + } +} + +func decideOverRLEUse(depth []byte, length uint, use_rle_for_non_zero *bool, use_rle_for_zero *bool) { + var total_reps_zero uint = 0 + var total_reps_non_zero uint = 0 + var count_reps_zero uint = 1 + var count_reps_non_zero uint = 1 + var i uint + for i = 0; i < length; { + var value byte = depth[i] + var reps uint = 1 + var k uint + for k = i + 1; k < length && depth[k] == value; k++ { + reps++ + } + + if reps >= 3 && value == 0 { + total_reps_zero += reps + count_reps_zero++ + } + + if reps >= 4 && value != 0 { + total_reps_non_zero += reps + count_reps_non_zero++ + } + + i += reps + } + + *use_rle_for_non_zero = total_reps_non_zero > count_reps_non_zero*2 + *use_rle_for_zero = total_reps_zero > count_reps_zero*2 +} + +/* Write a Huffman tree from bit depths into the bit-stream representation + of a Huffman tree. The generated Huffman tree is to be compressed once + more using a Huffman tree */ +func writeHuffmanTree(depth []byte, length uint, tree_size *uint, tree []byte, extra_bits_data []byte) { + var previous_value byte = initialRepeatedCodeLength + var i uint + var use_rle_for_non_zero bool = false + var use_rle_for_zero bool = false + var new_length uint = length + /* Throw away trailing zeros. */ + for i = 0; i < length; i++ { + if depth[length-i-1] == 0 { + new_length-- + } else { + break + } + } + + /* First gather statistics on if it is a good idea to do RLE. */ + if length > 50 { + /* Find RLE coding for longer codes. + Shorter codes seem not to benefit from RLE. */ + decideOverRLEUse(depth, new_length, &use_rle_for_non_zero, &use_rle_for_zero) + } + + /* Actual RLE coding. */ + for i = 0; i < new_length; { + var value byte = depth[i] + var reps uint = 1 + if (value != 0 && use_rle_for_non_zero) || (value == 0 && use_rle_for_zero) { + var k uint + for k = i + 1; k < new_length && depth[k] == value; k++ { + reps++ + } + } + + if value == 0 { + writeHuffmanTreeRepetitionsZeros(reps, tree_size, tree, extra_bits_data) + } else { + writeHuffmanTreeRepetitions(previous_value, value, reps, tree_size, tree, extra_bits_data) + previous_value = value + } + + i += reps + } +} + +var reverseBits_kLut = [16]uint{ + 0x00, + 0x08, + 0x04, + 0x0C, + 0x02, + 0x0A, + 0x06, + 0x0E, + 0x01, + 0x09, + 0x05, + 0x0D, + 0x03, + 0x0B, + 0x07, + 0x0F, +} + +func reverseBits(num_bits uint, bits uint16) uint16 { + var retval uint = reverseBits_kLut[bits&0x0F] + var i uint + for i = 4; i < num_bits; i += 4 { + retval <<= 4 + bits = uint16(bits >> 4) + retval |= reverseBits_kLut[bits&0x0F] + } + + retval >>= ((0 - num_bits) & 0x03) + return uint16(retval) +} + +/* 0..15 are values for bits */ +const maxHuffmanBits = 16 + +/* Get the actual bit values for a tree of bit depths. */ +func convertBitDepthsToSymbols(depth []byte, len uint, bits []uint16) { + var bl_count = [maxHuffmanBits]uint16{0} + var next_code [maxHuffmanBits]uint16 + var i uint + /* In Brotli, all bit depths are [1..15] + 0 bit depth means that the symbol does not exist. */ + + var code int = 0 + for i = 0; i < len; i++ { + bl_count[depth[i]]++ + } + + bl_count[0] = 0 + next_code[0] = 0 + for i = 1; i < maxHuffmanBits; i++ { + code = (code + int(bl_count[i-1])) << 1 + next_code[i] = uint16(code) + } + + for i = 0; i < len; i++ { + if depth[i] != 0 { + bits[i] = reverseBits(uint(depth[i]), next_code[depth[i]]) + next_code[depth[i]]++ + } + } +} diff --git a/vendor/github.com/andybalholm/brotli/entropy_encode_static.go b/vendor/github.com/andybalholm/brotli/entropy_encode_static.go new file mode 100644 index 0000000..5ddf3fc --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/entropy_encode_static.go @@ -0,0 +1,4394 @@ +package brotli + +var kCodeLengthDepth = [18]byte{4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 0, 4, 4} + +var kStaticCommandCodeDepth = [numCommandSymbols]byte{ + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 9, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 11, +} + +var kStaticDistanceCodeDepth = [64]byte{ + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, +} + +var kCodeLengthBits = [18]uint32{0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 15, 31, 0, 11, 7} + +func storeStaticCodeLengthCode(storage_ix *uint, storage []byte) { + writeBits(40, 0x0000FF55555554, storage_ix, storage) +} + +var kZeroRepsBits = [numCommandSymbols]uint64{ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000007, + 0x00000017, + 0x00000027, + 0x00000037, + 0x00000047, + 0x00000057, + 0x00000067, + 0x00000077, + 0x00000770, + 0x00000b87, + 0x00001387, + 0x00001b87, + 0x00002387, + 0x00002b87, + 0x00003387, + 0x00003b87, + 0x00000397, + 0x00000b97, + 0x00001397, + 0x00001b97, + 0x00002397, + 0x00002b97, + 0x00003397, + 0x00003b97, + 0x000003a7, + 0x00000ba7, + 0x000013a7, + 0x00001ba7, + 0x000023a7, + 0x00002ba7, + 0x000033a7, + 0x00003ba7, + 0x000003b7, + 0x00000bb7, + 0x000013b7, + 0x00001bb7, + 0x000023b7, + 0x00002bb7, + 0x000033b7, + 0x00003bb7, + 0x000003c7, + 0x00000bc7, + 0x000013c7, + 0x00001bc7, + 0x000023c7, + 0x00002bc7, + 0x000033c7, + 0x00003bc7, + 0x000003d7, + 0x00000bd7, + 0x000013d7, + 0x00001bd7, + 0x000023d7, + 0x00002bd7, + 0x000033d7, + 0x00003bd7, + 0x000003e7, + 0x00000be7, + 0x000013e7, + 0x00001be7, + 0x000023e7, + 0x00002be7, + 0x000033e7, + 0x00003be7, + 0x000003f7, + 0x00000bf7, + 0x000013f7, + 0x00001bf7, + 0x000023f7, + 0x00002bf7, + 0x000033f7, + 0x00003bf7, + 0x0001c387, + 0x0005c387, + 0x0009c387, + 0x000dc387, + 0x0011c387, + 0x0015c387, + 0x0019c387, + 0x001dc387, + 0x0001cb87, + 0x0005cb87, + 0x0009cb87, + 0x000dcb87, + 0x0011cb87, + 0x0015cb87, + 0x0019cb87, + 0x001dcb87, + 0x0001d387, + 0x0005d387, + 0x0009d387, + 0x000dd387, + 0x0011d387, + 0x0015d387, + 0x0019d387, + 0x001dd387, + 0x0001db87, + 0x0005db87, + 0x0009db87, + 0x000ddb87, + 0x0011db87, + 0x0015db87, + 0x0019db87, + 0x001ddb87, + 0x0001e387, + 0x0005e387, + 0x0009e387, + 0x000de387, + 0x0011e387, + 0x0015e387, + 0x0019e387, + 0x001de387, + 0x0001eb87, + 0x0005eb87, + 0x0009eb87, + 0x000deb87, + 0x0011eb87, + 0x0015eb87, + 0x0019eb87, + 0x001deb87, + 0x0001f387, + 0x0005f387, + 0x0009f387, + 0x000df387, + 0x0011f387, + 0x0015f387, + 0x0019f387, + 0x001df387, + 0x0001fb87, + 0x0005fb87, + 0x0009fb87, + 0x000dfb87, + 0x0011fb87, + 0x0015fb87, + 0x0019fb87, + 0x001dfb87, + 0x0001c397, + 0x0005c397, + 0x0009c397, + 0x000dc397, + 0x0011c397, + 0x0015c397, + 0x0019c397, + 0x001dc397, + 0x0001cb97, + 0x0005cb97, + 0x0009cb97, + 0x000dcb97, + 0x0011cb97, + 0x0015cb97, + 0x0019cb97, + 0x001dcb97, + 0x0001d397, + 0x0005d397, + 0x0009d397, + 0x000dd397, + 0x0011d397, + 0x0015d397, + 0x0019d397, + 0x001dd397, + 0x0001db97, + 0x0005db97, + 0x0009db97, + 0x000ddb97, + 0x0011db97, + 0x0015db97, + 0x0019db97, + 0x001ddb97, + 0x0001e397, + 0x0005e397, + 0x0009e397, + 0x000de397, + 0x0011e397, + 0x0015e397, + 0x0019e397, + 0x001de397, + 0x0001eb97, + 0x0005eb97, + 0x0009eb97, + 0x000deb97, + 0x0011eb97, + 0x0015eb97, + 0x0019eb97, + 0x001deb97, + 0x0001f397, + 0x0005f397, + 0x0009f397, + 0x000df397, + 0x0011f397, + 0x0015f397, + 0x0019f397, + 0x001df397, + 0x0001fb97, + 0x0005fb97, + 0x0009fb97, + 0x000dfb97, + 0x0011fb97, + 0x0015fb97, + 0x0019fb97, + 0x001dfb97, + 0x0001c3a7, + 0x0005c3a7, + 0x0009c3a7, + 0x000dc3a7, + 0x0011c3a7, + 0x0015c3a7, + 0x0019c3a7, + 0x001dc3a7, + 0x0001cba7, + 0x0005cba7, + 0x0009cba7, + 0x000dcba7, + 0x0011cba7, + 0x0015cba7, + 0x0019cba7, + 0x001dcba7, + 0x0001d3a7, + 0x0005d3a7, + 0x0009d3a7, + 0x000dd3a7, + 0x0011d3a7, + 0x0015d3a7, + 0x0019d3a7, + 0x001dd3a7, + 0x0001dba7, + 0x0005dba7, + 0x0009dba7, + 0x000ddba7, + 0x0011dba7, + 0x0015dba7, + 0x0019dba7, + 0x001ddba7, + 0x0001e3a7, + 0x0005e3a7, + 0x0009e3a7, + 0x000de3a7, + 0x0011e3a7, + 0x0015e3a7, + 0x0019e3a7, + 0x001de3a7, + 0x0001eba7, + 0x0005eba7, + 0x0009eba7, + 0x000deba7, + 0x0011eba7, + 0x0015eba7, + 0x0019eba7, + 0x001deba7, + 0x0001f3a7, + 0x0005f3a7, + 0x0009f3a7, + 0x000df3a7, + 0x0011f3a7, + 0x0015f3a7, + 0x0019f3a7, + 0x001df3a7, + 0x0001fba7, + 0x0005fba7, + 0x0009fba7, + 0x000dfba7, + 0x0011fba7, + 0x0015fba7, + 0x0019fba7, + 0x001dfba7, + 0x0001c3b7, + 0x0005c3b7, + 0x0009c3b7, + 0x000dc3b7, + 0x0011c3b7, + 0x0015c3b7, + 0x0019c3b7, + 0x001dc3b7, + 0x0001cbb7, + 0x0005cbb7, + 0x0009cbb7, + 0x000dcbb7, + 0x0011cbb7, + 0x0015cbb7, + 0x0019cbb7, + 0x001dcbb7, + 0x0001d3b7, + 0x0005d3b7, + 0x0009d3b7, + 0x000dd3b7, + 0x0011d3b7, + 0x0015d3b7, + 0x0019d3b7, + 0x001dd3b7, + 0x0001dbb7, + 0x0005dbb7, + 0x0009dbb7, + 0x000ddbb7, + 0x0011dbb7, + 0x0015dbb7, + 0x0019dbb7, + 0x001ddbb7, + 0x0001e3b7, + 0x0005e3b7, + 0x0009e3b7, + 0x000de3b7, + 0x0011e3b7, + 0x0015e3b7, + 0x0019e3b7, + 0x001de3b7, + 0x0001ebb7, + 0x0005ebb7, + 0x0009ebb7, + 0x000debb7, + 0x0011ebb7, + 0x0015ebb7, + 0x0019ebb7, + 0x001debb7, + 0x0001f3b7, + 0x0005f3b7, + 0x0009f3b7, + 0x000df3b7, + 0x0011f3b7, + 0x0015f3b7, + 0x0019f3b7, + 0x001df3b7, + 0x0001fbb7, + 0x0005fbb7, + 0x0009fbb7, + 0x000dfbb7, + 0x0011fbb7, + 0x0015fbb7, + 0x0019fbb7, + 0x001dfbb7, + 0x0001c3c7, + 0x0005c3c7, + 0x0009c3c7, + 0x000dc3c7, + 0x0011c3c7, + 0x0015c3c7, + 0x0019c3c7, + 0x001dc3c7, + 0x0001cbc7, + 0x0005cbc7, + 0x0009cbc7, + 0x000dcbc7, + 0x0011cbc7, + 0x0015cbc7, + 0x0019cbc7, + 0x001dcbc7, + 0x0001d3c7, + 0x0005d3c7, + 0x0009d3c7, + 0x000dd3c7, + 0x0011d3c7, + 0x0015d3c7, + 0x0019d3c7, + 0x001dd3c7, + 0x0001dbc7, + 0x0005dbc7, + 0x0009dbc7, + 0x000ddbc7, + 0x0011dbc7, + 0x0015dbc7, + 0x0019dbc7, + 0x001ddbc7, + 0x0001e3c7, + 0x0005e3c7, + 0x0009e3c7, + 0x000de3c7, + 0x0011e3c7, + 0x0015e3c7, + 0x0019e3c7, + 0x001de3c7, + 0x0001ebc7, + 0x0005ebc7, + 0x0009ebc7, + 0x000debc7, + 0x0011ebc7, + 0x0015ebc7, + 0x0019ebc7, + 0x001debc7, + 0x0001f3c7, + 0x0005f3c7, + 0x0009f3c7, + 0x000df3c7, + 0x0011f3c7, + 0x0015f3c7, + 0x0019f3c7, + 0x001df3c7, + 0x0001fbc7, + 0x0005fbc7, + 0x0009fbc7, + 0x000dfbc7, + 0x0011fbc7, + 0x0015fbc7, + 0x0019fbc7, + 0x001dfbc7, + 0x0001c3d7, + 0x0005c3d7, + 0x0009c3d7, + 0x000dc3d7, + 0x0011c3d7, + 0x0015c3d7, + 0x0019c3d7, + 0x001dc3d7, + 0x0001cbd7, + 0x0005cbd7, + 0x0009cbd7, + 0x000dcbd7, + 0x0011cbd7, + 0x0015cbd7, + 0x0019cbd7, + 0x001dcbd7, + 0x0001d3d7, + 0x0005d3d7, + 0x0009d3d7, + 0x000dd3d7, + 0x0011d3d7, + 0x0015d3d7, + 0x0019d3d7, + 0x001dd3d7, + 0x0001dbd7, + 0x0005dbd7, + 0x0009dbd7, + 0x000ddbd7, + 0x0011dbd7, + 0x0015dbd7, + 0x0019dbd7, + 0x001ddbd7, + 0x0001e3d7, + 0x0005e3d7, + 0x0009e3d7, + 0x000de3d7, + 0x0011e3d7, + 0x0015e3d7, + 0x0019e3d7, + 0x001de3d7, + 0x0001ebd7, + 0x0005ebd7, + 0x0009ebd7, + 0x000debd7, + 0x0011ebd7, + 0x0015ebd7, + 0x0019ebd7, + 0x001debd7, + 0x0001f3d7, + 0x0005f3d7, + 0x0009f3d7, + 0x000df3d7, + 0x0011f3d7, + 0x0015f3d7, + 0x0019f3d7, + 0x001df3d7, + 0x0001fbd7, + 0x0005fbd7, + 0x0009fbd7, + 0x000dfbd7, + 0x0011fbd7, + 0x0015fbd7, + 0x0019fbd7, + 0x001dfbd7, + 0x0001c3e7, + 0x0005c3e7, + 0x0009c3e7, + 0x000dc3e7, + 0x0011c3e7, + 0x0015c3e7, + 0x0019c3e7, + 0x001dc3e7, + 0x0001cbe7, + 0x0005cbe7, + 0x0009cbe7, + 0x000dcbe7, + 0x0011cbe7, + 0x0015cbe7, + 0x0019cbe7, + 0x001dcbe7, + 0x0001d3e7, + 0x0005d3e7, + 0x0009d3e7, + 0x000dd3e7, + 0x0011d3e7, + 0x0015d3e7, + 0x0019d3e7, + 0x001dd3e7, + 0x0001dbe7, + 0x0005dbe7, + 0x0009dbe7, + 0x000ddbe7, + 0x0011dbe7, + 0x0015dbe7, + 0x0019dbe7, + 0x001ddbe7, + 0x0001e3e7, + 0x0005e3e7, + 0x0009e3e7, + 0x000de3e7, + 0x0011e3e7, + 0x0015e3e7, + 0x0019e3e7, + 0x001de3e7, + 0x0001ebe7, + 0x0005ebe7, + 0x0009ebe7, + 0x000debe7, + 0x0011ebe7, + 0x0015ebe7, + 0x0019ebe7, + 0x001debe7, + 0x0001f3e7, + 0x0005f3e7, + 0x0009f3e7, + 0x000df3e7, + 0x0011f3e7, + 0x0015f3e7, + 0x0019f3e7, + 0x001df3e7, + 0x0001fbe7, + 0x0005fbe7, + 0x0009fbe7, + 0x000dfbe7, + 0x0011fbe7, + 0x0015fbe7, + 0x0019fbe7, + 0x001dfbe7, + 0x0001c3f7, + 0x0005c3f7, + 0x0009c3f7, + 0x000dc3f7, + 0x0011c3f7, + 0x0015c3f7, + 0x0019c3f7, + 0x001dc3f7, + 0x0001cbf7, + 0x0005cbf7, + 0x0009cbf7, + 0x000dcbf7, + 0x0011cbf7, + 0x0015cbf7, + 0x0019cbf7, + 0x001dcbf7, + 0x0001d3f7, + 0x0005d3f7, + 0x0009d3f7, + 0x000dd3f7, + 0x0011d3f7, + 0x0015d3f7, + 0x0019d3f7, + 0x001dd3f7, + 0x0001dbf7, + 0x0005dbf7, + 0x0009dbf7, + 0x000ddbf7, + 0x0011dbf7, + 0x0015dbf7, + 0x0019dbf7, + 0x001ddbf7, + 0x0001e3f7, + 0x0005e3f7, + 0x0009e3f7, + 0x000de3f7, + 0x0011e3f7, + 0x0015e3f7, + 0x0019e3f7, + 0x001de3f7, + 0x0001ebf7, + 0x0005ebf7, + 0x0009ebf7, + 0x000debf7, + 0x0011ebf7, + 0x0015ebf7, + 0x0019ebf7, + 0x001debf7, + 0x0001f3f7, + 0x0005f3f7, + 0x0009f3f7, + 0x000df3f7, + 0x0011f3f7, + 0x0015f3f7, + 0x0019f3f7, + 0x001df3f7, + 0x0001fbf7, + 0x0005fbf7, + 0x0009fbf7, + 0x000dfbf7, + 0x0011fbf7, + 0x0015fbf7, + 0x0019fbf7, + 0x001dfbf7, + 0x00e1c387, + 0x02e1c387, + 0x04e1c387, + 0x06e1c387, + 0x08e1c387, + 0x0ae1c387, + 0x0ce1c387, + 0x0ee1c387, + 0x00e5c387, + 0x02e5c387, + 0x04e5c387, + 0x06e5c387, + 0x08e5c387, + 0x0ae5c387, + 0x0ce5c387, + 0x0ee5c387, + 0x00e9c387, + 0x02e9c387, + 0x04e9c387, + 0x06e9c387, + 0x08e9c387, + 0x0ae9c387, + 0x0ce9c387, + 0x0ee9c387, + 0x00edc387, + 0x02edc387, + 0x04edc387, + 0x06edc387, + 0x08edc387, + 0x0aedc387, + 0x0cedc387, + 0x0eedc387, + 0x00f1c387, + 0x02f1c387, + 0x04f1c387, + 0x06f1c387, + 0x08f1c387, + 0x0af1c387, + 0x0cf1c387, + 0x0ef1c387, + 0x00f5c387, + 0x02f5c387, + 0x04f5c387, + 0x06f5c387, + 0x08f5c387, + 0x0af5c387, + 0x0cf5c387, + 0x0ef5c387, + 0x00f9c387, + 0x02f9c387, + 0x04f9c387, + 0x06f9c387, + 0x08f9c387, + 0x0af9c387, + 0x0cf9c387, + 0x0ef9c387, + 0x00fdc387, + 0x02fdc387, + 0x04fdc387, + 0x06fdc387, + 0x08fdc387, + 0x0afdc387, + 0x0cfdc387, + 0x0efdc387, + 0x00e1cb87, + 0x02e1cb87, + 0x04e1cb87, + 0x06e1cb87, + 0x08e1cb87, + 0x0ae1cb87, + 0x0ce1cb87, + 0x0ee1cb87, + 0x00e5cb87, + 0x02e5cb87, + 0x04e5cb87, + 0x06e5cb87, + 0x08e5cb87, + 0x0ae5cb87, + 0x0ce5cb87, + 0x0ee5cb87, + 0x00e9cb87, + 0x02e9cb87, + 0x04e9cb87, + 0x06e9cb87, + 0x08e9cb87, + 0x0ae9cb87, + 0x0ce9cb87, + 0x0ee9cb87, + 0x00edcb87, + 0x02edcb87, + 0x04edcb87, + 0x06edcb87, + 0x08edcb87, + 0x0aedcb87, + 0x0cedcb87, + 0x0eedcb87, + 0x00f1cb87, + 0x02f1cb87, + 0x04f1cb87, + 0x06f1cb87, + 0x08f1cb87, + 0x0af1cb87, + 0x0cf1cb87, + 0x0ef1cb87, + 0x00f5cb87, + 0x02f5cb87, + 0x04f5cb87, + 0x06f5cb87, + 0x08f5cb87, + 0x0af5cb87, + 0x0cf5cb87, + 0x0ef5cb87, + 0x00f9cb87, + 0x02f9cb87, + 0x04f9cb87, + 0x06f9cb87, + 0x08f9cb87, +} + +var kZeroRepsDepth = [numCommandSymbols]uint32{ + 0, + 4, + 8, + 7, + 7, + 7, + 7, + 7, + 7, + 7, + 7, + 11, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 14, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 21, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, + 28, +} + +var kNonZeroRepsBits = [numCommandSymbols]uint64{ + 0x0000000b, + 0x0000001b, + 0x0000002b, + 0x0000003b, + 0x000002cb, + 0x000006cb, + 0x00000acb, + 0x00000ecb, + 0x000002db, + 0x000006db, + 0x00000adb, + 0x00000edb, + 0x000002eb, + 0x000006eb, + 0x00000aeb, + 0x00000eeb, + 0x000002fb, + 0x000006fb, + 0x00000afb, + 0x00000efb, + 0x0000b2cb, + 0x0001b2cb, + 0x0002b2cb, + 0x0003b2cb, + 0x0000b6cb, + 0x0001b6cb, + 0x0002b6cb, + 0x0003b6cb, + 0x0000bacb, + 0x0001bacb, + 0x0002bacb, + 0x0003bacb, + 0x0000becb, + 0x0001becb, + 0x0002becb, + 0x0003becb, + 0x0000b2db, + 0x0001b2db, + 0x0002b2db, + 0x0003b2db, + 0x0000b6db, + 0x0001b6db, + 0x0002b6db, + 0x0003b6db, + 0x0000badb, + 0x0001badb, + 0x0002badb, + 0x0003badb, + 0x0000bedb, + 0x0001bedb, + 0x0002bedb, + 0x0003bedb, + 0x0000b2eb, + 0x0001b2eb, + 0x0002b2eb, + 0x0003b2eb, + 0x0000b6eb, + 0x0001b6eb, + 0x0002b6eb, + 0x0003b6eb, + 0x0000baeb, + 0x0001baeb, + 0x0002baeb, + 0x0003baeb, + 0x0000beeb, + 0x0001beeb, + 0x0002beeb, + 0x0003beeb, + 0x0000b2fb, + 0x0001b2fb, + 0x0002b2fb, + 0x0003b2fb, + 0x0000b6fb, + 0x0001b6fb, + 0x0002b6fb, + 0x0003b6fb, + 0x0000bafb, + 0x0001bafb, + 0x0002bafb, + 0x0003bafb, + 0x0000befb, + 0x0001befb, + 0x0002befb, + 0x0003befb, + 0x002cb2cb, + 0x006cb2cb, + 0x00acb2cb, + 0x00ecb2cb, + 0x002db2cb, + 0x006db2cb, + 0x00adb2cb, + 0x00edb2cb, + 0x002eb2cb, + 0x006eb2cb, + 0x00aeb2cb, + 0x00eeb2cb, + 0x002fb2cb, + 0x006fb2cb, + 0x00afb2cb, + 0x00efb2cb, + 0x002cb6cb, + 0x006cb6cb, + 0x00acb6cb, + 0x00ecb6cb, + 0x002db6cb, + 0x006db6cb, + 0x00adb6cb, + 0x00edb6cb, + 0x002eb6cb, + 0x006eb6cb, + 0x00aeb6cb, + 0x00eeb6cb, + 0x002fb6cb, + 0x006fb6cb, + 0x00afb6cb, + 0x00efb6cb, + 0x002cbacb, + 0x006cbacb, + 0x00acbacb, + 0x00ecbacb, + 0x002dbacb, + 0x006dbacb, + 0x00adbacb, + 0x00edbacb, + 0x002ebacb, + 0x006ebacb, + 0x00aebacb, + 0x00eebacb, + 0x002fbacb, + 0x006fbacb, + 0x00afbacb, + 0x00efbacb, + 0x002cbecb, + 0x006cbecb, + 0x00acbecb, + 0x00ecbecb, + 0x002dbecb, + 0x006dbecb, + 0x00adbecb, + 0x00edbecb, + 0x002ebecb, + 0x006ebecb, + 0x00aebecb, + 0x00eebecb, + 0x002fbecb, + 0x006fbecb, + 0x00afbecb, + 0x00efbecb, + 0x002cb2db, + 0x006cb2db, + 0x00acb2db, + 0x00ecb2db, + 0x002db2db, + 0x006db2db, + 0x00adb2db, + 0x00edb2db, + 0x002eb2db, + 0x006eb2db, + 0x00aeb2db, + 0x00eeb2db, + 0x002fb2db, + 0x006fb2db, + 0x00afb2db, + 0x00efb2db, + 0x002cb6db, + 0x006cb6db, + 0x00acb6db, + 0x00ecb6db, + 0x002db6db, + 0x006db6db, + 0x00adb6db, + 0x00edb6db, + 0x002eb6db, + 0x006eb6db, + 0x00aeb6db, + 0x00eeb6db, + 0x002fb6db, + 0x006fb6db, + 0x00afb6db, + 0x00efb6db, + 0x002cbadb, + 0x006cbadb, + 0x00acbadb, + 0x00ecbadb, + 0x002dbadb, + 0x006dbadb, + 0x00adbadb, + 0x00edbadb, + 0x002ebadb, + 0x006ebadb, + 0x00aebadb, + 0x00eebadb, + 0x002fbadb, + 0x006fbadb, + 0x00afbadb, + 0x00efbadb, + 0x002cbedb, + 0x006cbedb, + 0x00acbedb, + 0x00ecbedb, + 0x002dbedb, + 0x006dbedb, + 0x00adbedb, + 0x00edbedb, + 0x002ebedb, + 0x006ebedb, + 0x00aebedb, + 0x00eebedb, + 0x002fbedb, + 0x006fbedb, + 0x00afbedb, + 0x00efbedb, + 0x002cb2eb, + 0x006cb2eb, + 0x00acb2eb, + 0x00ecb2eb, + 0x002db2eb, + 0x006db2eb, + 0x00adb2eb, + 0x00edb2eb, + 0x002eb2eb, + 0x006eb2eb, + 0x00aeb2eb, + 0x00eeb2eb, + 0x002fb2eb, + 0x006fb2eb, + 0x00afb2eb, + 0x00efb2eb, + 0x002cb6eb, + 0x006cb6eb, + 0x00acb6eb, + 0x00ecb6eb, + 0x002db6eb, + 0x006db6eb, + 0x00adb6eb, + 0x00edb6eb, + 0x002eb6eb, + 0x006eb6eb, + 0x00aeb6eb, + 0x00eeb6eb, + 0x002fb6eb, + 0x006fb6eb, + 0x00afb6eb, + 0x00efb6eb, + 0x002cbaeb, + 0x006cbaeb, + 0x00acbaeb, + 0x00ecbaeb, + 0x002dbaeb, + 0x006dbaeb, + 0x00adbaeb, + 0x00edbaeb, + 0x002ebaeb, + 0x006ebaeb, + 0x00aebaeb, + 0x00eebaeb, + 0x002fbaeb, + 0x006fbaeb, + 0x00afbaeb, + 0x00efbaeb, + 0x002cbeeb, + 0x006cbeeb, + 0x00acbeeb, + 0x00ecbeeb, + 0x002dbeeb, + 0x006dbeeb, + 0x00adbeeb, + 0x00edbeeb, + 0x002ebeeb, + 0x006ebeeb, + 0x00aebeeb, + 0x00eebeeb, + 0x002fbeeb, + 0x006fbeeb, + 0x00afbeeb, + 0x00efbeeb, + 0x002cb2fb, + 0x006cb2fb, + 0x00acb2fb, + 0x00ecb2fb, + 0x002db2fb, + 0x006db2fb, + 0x00adb2fb, + 0x00edb2fb, + 0x002eb2fb, + 0x006eb2fb, + 0x00aeb2fb, + 0x00eeb2fb, + 0x002fb2fb, + 0x006fb2fb, + 0x00afb2fb, + 0x00efb2fb, + 0x002cb6fb, + 0x006cb6fb, + 0x00acb6fb, + 0x00ecb6fb, + 0x002db6fb, + 0x006db6fb, + 0x00adb6fb, + 0x00edb6fb, + 0x002eb6fb, + 0x006eb6fb, + 0x00aeb6fb, + 0x00eeb6fb, + 0x002fb6fb, + 0x006fb6fb, + 0x00afb6fb, + 0x00efb6fb, + 0x002cbafb, + 0x006cbafb, + 0x00acbafb, + 0x00ecbafb, + 0x002dbafb, + 0x006dbafb, + 0x00adbafb, + 0x00edbafb, + 0x002ebafb, + 0x006ebafb, + 0x00aebafb, + 0x00eebafb, + 0x002fbafb, + 0x006fbafb, + 0x00afbafb, + 0x00efbafb, + 0x002cbefb, + 0x006cbefb, + 0x00acbefb, + 0x00ecbefb, + 0x002dbefb, + 0x006dbefb, + 0x00adbefb, + 0x00edbefb, + 0x002ebefb, + 0x006ebefb, + 0x00aebefb, + 0x00eebefb, + 0x002fbefb, + 0x006fbefb, + 0x00afbefb, + 0x00efbefb, + 0x0b2cb2cb, + 0x1b2cb2cb, + 0x2b2cb2cb, + 0x3b2cb2cb, + 0x0b6cb2cb, + 0x1b6cb2cb, + 0x2b6cb2cb, + 0x3b6cb2cb, + 0x0bacb2cb, + 0x1bacb2cb, + 0x2bacb2cb, + 0x3bacb2cb, + 0x0becb2cb, + 0x1becb2cb, + 0x2becb2cb, + 0x3becb2cb, + 0x0b2db2cb, + 0x1b2db2cb, + 0x2b2db2cb, + 0x3b2db2cb, + 0x0b6db2cb, + 0x1b6db2cb, + 0x2b6db2cb, + 0x3b6db2cb, + 0x0badb2cb, + 0x1badb2cb, + 0x2badb2cb, + 0x3badb2cb, + 0x0bedb2cb, + 0x1bedb2cb, + 0x2bedb2cb, + 0x3bedb2cb, + 0x0b2eb2cb, + 0x1b2eb2cb, + 0x2b2eb2cb, + 0x3b2eb2cb, + 0x0b6eb2cb, + 0x1b6eb2cb, + 0x2b6eb2cb, + 0x3b6eb2cb, + 0x0baeb2cb, + 0x1baeb2cb, + 0x2baeb2cb, + 0x3baeb2cb, + 0x0beeb2cb, + 0x1beeb2cb, + 0x2beeb2cb, + 0x3beeb2cb, + 0x0b2fb2cb, + 0x1b2fb2cb, + 0x2b2fb2cb, + 0x3b2fb2cb, + 0x0b6fb2cb, + 0x1b6fb2cb, + 0x2b6fb2cb, + 0x3b6fb2cb, + 0x0bafb2cb, + 0x1bafb2cb, + 0x2bafb2cb, + 0x3bafb2cb, + 0x0befb2cb, + 0x1befb2cb, + 0x2befb2cb, + 0x3befb2cb, + 0x0b2cb6cb, + 0x1b2cb6cb, + 0x2b2cb6cb, + 0x3b2cb6cb, + 0x0b6cb6cb, + 0x1b6cb6cb, + 0x2b6cb6cb, + 0x3b6cb6cb, + 0x0bacb6cb, + 0x1bacb6cb, + 0x2bacb6cb, + 0x3bacb6cb, + 0x0becb6cb, + 0x1becb6cb, + 0x2becb6cb, + 0x3becb6cb, + 0x0b2db6cb, + 0x1b2db6cb, + 0x2b2db6cb, + 0x3b2db6cb, + 0x0b6db6cb, + 0x1b6db6cb, + 0x2b6db6cb, + 0x3b6db6cb, + 0x0badb6cb, + 0x1badb6cb, + 0x2badb6cb, + 0x3badb6cb, + 0x0bedb6cb, + 0x1bedb6cb, + 0x2bedb6cb, + 0x3bedb6cb, + 0x0b2eb6cb, + 0x1b2eb6cb, + 0x2b2eb6cb, + 0x3b2eb6cb, + 0x0b6eb6cb, + 0x1b6eb6cb, + 0x2b6eb6cb, + 0x3b6eb6cb, + 0x0baeb6cb, + 0x1baeb6cb, + 0x2baeb6cb, + 0x3baeb6cb, + 0x0beeb6cb, + 0x1beeb6cb, + 0x2beeb6cb, + 0x3beeb6cb, + 0x0b2fb6cb, + 0x1b2fb6cb, + 0x2b2fb6cb, + 0x3b2fb6cb, + 0x0b6fb6cb, + 0x1b6fb6cb, + 0x2b6fb6cb, + 0x3b6fb6cb, + 0x0bafb6cb, + 0x1bafb6cb, + 0x2bafb6cb, + 0x3bafb6cb, + 0x0befb6cb, + 0x1befb6cb, + 0x2befb6cb, + 0x3befb6cb, + 0x0b2cbacb, + 0x1b2cbacb, + 0x2b2cbacb, + 0x3b2cbacb, + 0x0b6cbacb, + 0x1b6cbacb, + 0x2b6cbacb, + 0x3b6cbacb, + 0x0bacbacb, + 0x1bacbacb, + 0x2bacbacb, + 0x3bacbacb, + 0x0becbacb, + 0x1becbacb, + 0x2becbacb, + 0x3becbacb, + 0x0b2dbacb, + 0x1b2dbacb, + 0x2b2dbacb, + 0x3b2dbacb, + 0x0b6dbacb, + 0x1b6dbacb, + 0x2b6dbacb, + 0x3b6dbacb, + 0x0badbacb, + 0x1badbacb, + 0x2badbacb, + 0x3badbacb, + 0x0bedbacb, + 0x1bedbacb, + 0x2bedbacb, + 0x3bedbacb, + 0x0b2ebacb, + 0x1b2ebacb, + 0x2b2ebacb, + 0x3b2ebacb, + 0x0b6ebacb, + 0x1b6ebacb, + 0x2b6ebacb, + 0x3b6ebacb, + 0x0baebacb, + 0x1baebacb, + 0x2baebacb, + 0x3baebacb, + 0x0beebacb, + 0x1beebacb, + 0x2beebacb, + 0x3beebacb, + 0x0b2fbacb, + 0x1b2fbacb, + 0x2b2fbacb, + 0x3b2fbacb, + 0x0b6fbacb, + 0x1b6fbacb, + 0x2b6fbacb, + 0x3b6fbacb, + 0x0bafbacb, + 0x1bafbacb, + 0x2bafbacb, + 0x3bafbacb, + 0x0befbacb, + 0x1befbacb, + 0x2befbacb, + 0x3befbacb, + 0x0b2cbecb, + 0x1b2cbecb, + 0x2b2cbecb, + 0x3b2cbecb, + 0x0b6cbecb, + 0x1b6cbecb, + 0x2b6cbecb, + 0x3b6cbecb, + 0x0bacbecb, + 0x1bacbecb, + 0x2bacbecb, + 0x3bacbecb, + 0x0becbecb, + 0x1becbecb, + 0x2becbecb, + 0x3becbecb, + 0x0b2dbecb, + 0x1b2dbecb, + 0x2b2dbecb, + 0x3b2dbecb, + 0x0b6dbecb, + 0x1b6dbecb, + 0x2b6dbecb, + 0x3b6dbecb, + 0x0badbecb, + 0x1badbecb, + 0x2badbecb, + 0x3badbecb, + 0x0bedbecb, + 0x1bedbecb, + 0x2bedbecb, + 0x3bedbecb, + 0x0b2ebecb, + 0x1b2ebecb, + 0x2b2ebecb, + 0x3b2ebecb, + 0x0b6ebecb, + 0x1b6ebecb, + 0x2b6ebecb, + 0x3b6ebecb, + 0x0baebecb, + 0x1baebecb, + 0x2baebecb, + 0x3baebecb, + 0x0beebecb, + 0x1beebecb, + 0x2beebecb, + 0x3beebecb, + 0x0b2fbecb, + 0x1b2fbecb, + 0x2b2fbecb, + 0x3b2fbecb, + 0x0b6fbecb, + 0x1b6fbecb, + 0x2b6fbecb, + 0x3b6fbecb, + 0x0bafbecb, + 0x1bafbecb, + 0x2bafbecb, + 0x3bafbecb, + 0x0befbecb, + 0x1befbecb, + 0x2befbecb, + 0x3befbecb, + 0x0b2cb2db, + 0x1b2cb2db, + 0x2b2cb2db, + 0x3b2cb2db, + 0x0b6cb2db, + 0x1b6cb2db, + 0x2b6cb2db, + 0x3b6cb2db, + 0x0bacb2db, + 0x1bacb2db, + 0x2bacb2db, + 0x3bacb2db, + 0x0becb2db, + 0x1becb2db, + 0x2becb2db, + 0x3becb2db, + 0x0b2db2db, + 0x1b2db2db, + 0x2b2db2db, + 0x3b2db2db, + 0x0b6db2db, + 0x1b6db2db, + 0x2b6db2db, + 0x3b6db2db, + 0x0badb2db, + 0x1badb2db, + 0x2badb2db, + 0x3badb2db, + 0x0bedb2db, + 0x1bedb2db, + 0x2bedb2db, + 0x3bedb2db, + 0x0b2eb2db, + 0x1b2eb2db, + 0x2b2eb2db, + 0x3b2eb2db, + 0x0b6eb2db, + 0x1b6eb2db, + 0x2b6eb2db, + 0x3b6eb2db, + 0x0baeb2db, + 0x1baeb2db, + 0x2baeb2db, + 0x3baeb2db, + 0x0beeb2db, + 0x1beeb2db, + 0x2beeb2db, + 0x3beeb2db, + 0x0b2fb2db, + 0x1b2fb2db, + 0x2b2fb2db, + 0x3b2fb2db, + 0x0b6fb2db, + 0x1b6fb2db, + 0x2b6fb2db, + 0x3b6fb2db, + 0x0bafb2db, + 0x1bafb2db, + 0x2bafb2db, + 0x3bafb2db, + 0x0befb2db, + 0x1befb2db, + 0x2befb2db, + 0x3befb2db, + 0x0b2cb6db, + 0x1b2cb6db, + 0x2b2cb6db, + 0x3b2cb6db, + 0x0b6cb6db, + 0x1b6cb6db, + 0x2b6cb6db, + 0x3b6cb6db, + 0x0bacb6db, + 0x1bacb6db, + 0x2bacb6db, + 0x3bacb6db, + 0x0becb6db, + 0x1becb6db, + 0x2becb6db, + 0x3becb6db, + 0x0b2db6db, + 0x1b2db6db, + 0x2b2db6db, + 0x3b2db6db, + 0x0b6db6db, + 0x1b6db6db, + 0x2b6db6db, + 0x3b6db6db, + 0x0badb6db, + 0x1badb6db, + 0x2badb6db, + 0x3badb6db, + 0x0bedb6db, + 0x1bedb6db, + 0x2bedb6db, + 0x3bedb6db, + 0x0b2eb6db, + 0x1b2eb6db, + 0x2b2eb6db, + 0x3b2eb6db, + 0x0b6eb6db, + 0x1b6eb6db, + 0x2b6eb6db, + 0x3b6eb6db, + 0x0baeb6db, + 0x1baeb6db, + 0x2baeb6db, + 0x3baeb6db, +} + +var kNonZeroRepsDepth = [numCommandSymbols]uint32{ + 6, + 6, + 6, + 6, + 12, + 12, + 12, + 12, + 12, + 12, + 12, + 12, + 12, + 12, + 12, + 12, + 12, + 12, + 12, + 12, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 18, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, +} + +var kStaticCommandCodeBits = [numCommandSymbols]uint16{ + 0, + 256, + 128, + 384, + 64, + 320, + 192, + 448, + 32, + 288, + 160, + 416, + 96, + 352, + 224, + 480, + 16, + 272, + 144, + 400, + 80, + 336, + 208, + 464, + 48, + 304, + 176, + 432, + 112, + 368, + 240, + 496, + 8, + 264, + 136, + 392, + 72, + 328, + 200, + 456, + 40, + 296, + 168, + 424, + 104, + 360, + 232, + 488, + 24, + 280, + 152, + 408, + 88, + 344, + 216, + 472, + 56, + 312, + 184, + 440, + 120, + 376, + 248, + 504, + 4, + 260, + 132, + 388, + 68, + 324, + 196, + 452, + 36, + 292, + 164, + 420, + 100, + 356, + 228, + 484, + 20, + 276, + 148, + 404, + 84, + 340, + 212, + 468, + 52, + 308, + 180, + 436, + 116, + 372, + 244, + 500, + 12, + 268, + 140, + 396, + 76, + 332, + 204, + 460, + 44, + 300, + 172, + 428, + 108, + 364, + 236, + 492, + 28, + 284, + 156, + 412, + 92, + 348, + 220, + 476, + 60, + 316, + 188, + 444, + 124, + 380, + 252, + 508, + 2, + 258, + 130, + 386, + 66, + 322, + 194, + 450, + 34, + 290, + 162, + 418, + 98, + 354, + 226, + 482, + 18, + 274, + 146, + 402, + 82, + 338, + 210, + 466, + 50, + 306, + 178, + 434, + 114, + 370, + 242, + 498, + 10, + 266, + 138, + 394, + 74, + 330, + 202, + 458, + 42, + 298, + 170, + 426, + 106, + 362, + 234, + 490, + 26, + 282, + 154, + 410, + 90, + 346, + 218, + 474, + 58, + 314, + 186, + 442, + 122, + 378, + 250, + 506, + 6, + 262, + 134, + 390, + 70, + 326, + 198, + 454, + 38, + 294, + 166, + 422, + 102, + 358, + 230, + 486, + 22, + 278, + 150, + 406, + 86, + 342, + 214, + 470, + 54, + 310, + 182, + 438, + 118, + 374, + 246, + 502, + 14, + 270, + 142, + 398, + 78, + 334, + 206, + 462, + 46, + 302, + 174, + 430, + 110, + 366, + 238, + 494, + 30, + 286, + 158, + 414, + 94, + 350, + 222, + 478, + 62, + 318, + 190, + 446, + 126, + 382, + 254, + 510, + 1, + 257, + 129, + 385, + 65, + 321, + 193, + 449, + 33, + 289, + 161, + 417, + 97, + 353, + 225, + 481, + 17, + 273, + 145, + 401, + 81, + 337, + 209, + 465, + 49, + 305, + 177, + 433, + 113, + 369, + 241, + 497, + 9, + 265, + 137, + 393, + 73, + 329, + 201, + 457, + 41, + 297, + 169, + 425, + 105, + 361, + 233, + 489, + 25, + 281, + 153, + 409, + 89, + 345, + 217, + 473, + 57, + 313, + 185, + 441, + 121, + 377, + 249, + 505, + 5, + 261, + 133, + 389, + 69, + 325, + 197, + 453, + 37, + 293, + 165, + 421, + 101, + 357, + 229, + 485, + 21, + 277, + 149, + 405, + 85, + 341, + 213, + 469, + 53, + 309, + 181, + 437, + 117, + 373, + 245, + 501, + 13, + 269, + 141, + 397, + 77, + 333, + 205, + 461, + 45, + 301, + 173, + 429, + 109, + 365, + 237, + 493, + 29, + 285, + 157, + 413, + 93, + 349, + 221, + 477, + 61, + 317, + 189, + 445, + 125, + 381, + 253, + 509, + 3, + 259, + 131, + 387, + 67, + 323, + 195, + 451, + 35, + 291, + 163, + 419, + 99, + 355, + 227, + 483, + 19, + 275, + 147, + 403, + 83, + 339, + 211, + 467, + 51, + 307, + 179, + 435, + 115, + 371, + 243, + 499, + 11, + 267, + 139, + 395, + 75, + 331, + 203, + 459, + 43, + 299, + 171, + 427, + 107, + 363, + 235, + 491, + 27, + 283, + 155, + 411, + 91, + 347, + 219, + 475, + 59, + 315, + 187, + 443, + 123, + 379, + 251, + 507, + 7, + 1031, + 519, + 1543, + 263, + 1287, + 775, + 1799, + 135, + 1159, + 647, + 1671, + 391, + 1415, + 903, + 1927, + 71, + 1095, + 583, + 1607, + 327, + 1351, + 839, + 1863, + 199, + 1223, + 711, + 1735, + 455, + 1479, + 967, + 1991, + 39, + 1063, + 551, + 1575, + 295, + 1319, + 807, + 1831, + 167, + 1191, + 679, + 1703, + 423, + 1447, + 935, + 1959, + 103, + 1127, + 615, + 1639, + 359, + 1383, + 871, + 1895, + 231, + 1255, + 743, + 1767, + 487, + 1511, + 999, + 2023, + 23, + 1047, + 535, + 1559, + 279, + 1303, + 791, + 1815, + 151, + 1175, + 663, + 1687, + 407, + 1431, + 919, + 1943, + 87, + 1111, + 599, + 1623, + 343, + 1367, + 855, + 1879, + 215, + 1239, + 727, + 1751, + 471, + 1495, + 983, + 2007, + 55, + 1079, + 567, + 1591, + 311, + 1335, + 823, + 1847, + 183, + 1207, + 695, + 1719, + 439, + 1463, + 951, + 1975, + 119, + 1143, + 631, + 1655, + 375, + 1399, + 887, + 1911, + 247, + 1271, + 759, + 1783, + 503, + 1527, + 1015, + 2039, + 15, + 1039, + 527, + 1551, + 271, + 1295, + 783, + 1807, + 143, + 1167, + 655, + 1679, + 399, + 1423, + 911, + 1935, + 79, + 1103, + 591, + 1615, + 335, + 1359, + 847, + 1871, + 207, + 1231, + 719, + 1743, + 463, + 1487, + 975, + 1999, + 47, + 1071, + 559, + 1583, + 303, + 1327, + 815, + 1839, + 175, + 1199, + 687, + 1711, + 431, + 1455, + 943, + 1967, + 111, + 1135, + 623, + 1647, + 367, + 1391, + 879, + 1903, + 239, + 1263, + 751, + 1775, + 495, + 1519, + 1007, + 2031, + 31, + 1055, + 543, + 1567, + 287, + 1311, + 799, + 1823, + 159, + 1183, + 671, + 1695, + 415, + 1439, + 927, + 1951, + 95, + 1119, + 607, + 1631, + 351, + 1375, + 863, + 1887, + 223, + 1247, + 735, + 1759, + 479, + 1503, + 991, + 2015, + 63, + 1087, + 575, + 1599, + 319, + 1343, + 831, + 1855, + 191, + 1215, + 703, + 1727, + 447, + 1471, + 959, + 1983, + 127, + 1151, + 639, + 1663, + 383, + 1407, + 895, + 1919, + 255, + 1279, + 767, + 1791, + 511, + 1535, + 1023, + 2047, +} + +func storeStaticCommandHuffmanTree(storage_ix *uint, storage []byte) { + writeBits(56, 0x92624416307003, storage_ix, storage) + writeBits(3, 0x00000000, storage_ix, storage) +} + +var kStaticDistanceCodeBits = [64]uint16{ + 0, + 32, + 16, + 48, + 8, + 40, + 24, + 56, + 4, + 36, + 20, + 52, + 12, + 44, + 28, + 60, + 2, + 34, + 18, + 50, + 10, + 42, + 26, + 58, + 6, + 38, + 22, + 54, + 14, + 46, + 30, + 62, + 1, + 33, + 17, + 49, + 9, + 41, + 25, + 57, + 5, + 37, + 21, + 53, + 13, + 45, + 29, + 61, + 3, + 35, + 19, + 51, + 11, + 43, + 27, + 59, + 7, + 39, + 23, + 55, + 15, + 47, + 31, + 63, +} + +func storeStaticDistanceHuffmanTree(storage_ix *uint, storage []byte) { + writeBits(28, 0x0369DC03, storage_ix, storage) +} diff --git a/vendor/github.com/andybalholm/brotli/fast_log.go b/vendor/github.com/andybalholm/brotli/fast_log.go new file mode 100644 index 0000000..9d6607f --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/fast_log.go @@ -0,0 +1,290 @@ +package brotli + +import ( + "math" + "math/bits" +) + +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Utilities for fast computation of logarithms. */ + +func log2FloorNonZero(n uint) uint32 { + return uint32(bits.Len(n)) - 1 +} + +/* A lookup table for small values of log2(int) to be used in entropy + computation. + + ", ".join(["%.16ff" % x for x in [0.0]+[log2(x) for x in range(1, 256)]]) */ +var kLog2Table = []float32{ + 0.0000000000000000, + 0.0000000000000000, + 1.0000000000000000, + 1.5849625007211563, + 2.0000000000000000, + 2.3219280948873622, + 2.5849625007211561, + 2.8073549220576042, + 3.0000000000000000, + 3.1699250014423126, + 3.3219280948873626, + 3.4594316186372978, + 3.5849625007211565, + 3.7004397181410922, + 3.8073549220576037, + 3.9068905956085187, + 4.0000000000000000, + 4.0874628412503400, + 4.1699250014423122, + 4.2479275134435852, + 4.3219280948873626, + 4.3923174227787607, + 4.4594316186372973, + 4.5235619560570131, + 4.5849625007211570, + 4.6438561897747244, + 4.7004397181410926, + 4.7548875021634691, + 4.8073549220576037, + 4.8579809951275728, + 4.9068905956085187, + 4.9541963103868758, + 5.0000000000000000, + 5.0443941193584534, + 5.0874628412503400, + 5.1292830169449664, + 5.1699250014423122, + 5.2094533656289501, + 5.2479275134435852, + 5.2854022188622487, + 5.3219280948873626, + 5.3575520046180838, + 5.3923174227787607, + 5.4262647547020979, + 5.4594316186372973, + 5.4918530963296748, + 5.5235619560570131, + 5.5545888516776376, + 5.5849625007211570, + 5.6147098441152083, + 5.6438561897747244, + 5.6724253419714961, + 5.7004397181410926, + 5.7279204545631996, + 5.7548875021634691, + 5.7813597135246599, + 5.8073549220576046, + 5.8328900141647422, + 5.8579809951275719, + 5.8826430493618416, + 5.9068905956085187, + 5.9307373375628867, + 5.9541963103868758, + 5.9772799234999168, + 6.0000000000000000, + 6.0223678130284544, + 6.0443941193584534, + 6.0660891904577721, + 6.0874628412503400, + 6.1085244567781700, + 6.1292830169449672, + 6.1497471195046822, + 6.1699250014423122, + 6.1898245588800176, + 6.2094533656289510, + 6.2288186904958804, + 6.2479275134435861, + 6.2667865406949019, + 6.2854022188622487, + 6.3037807481771031, + 6.3219280948873617, + 6.3398500028846252, + 6.3575520046180847, + 6.3750394313469254, + 6.3923174227787598, + 6.4093909361377026, + 6.4262647547020979, + 6.4429434958487288, + 6.4594316186372982, + 6.4757334309663976, + 6.4918530963296748, + 6.5077946401986964, + 6.5235619560570131, + 6.5391588111080319, + 6.5545888516776376, + 6.5698556083309478, + 6.5849625007211561, + 6.5999128421871278, + 6.6147098441152092, + 6.6293566200796095, + 6.6438561897747253, + 6.6582114827517955, + 6.6724253419714952, + 6.6865005271832185, + 6.7004397181410917, + 6.7142455176661224, + 6.7279204545631988, + 6.7414669864011465, + 6.7548875021634691, + 6.7681843247769260, + 6.7813597135246599, + 6.7944158663501062, + 6.8073549220576037, + 6.8201789624151887, + 6.8328900141647422, + 6.8454900509443757, + 6.8579809951275719, + 6.8703647195834048, + 6.8826430493618416, + 6.8948177633079437, + 6.9068905956085187, + 6.9188632372745955, + 6.9307373375628867, + 6.9425145053392399, + 6.9541963103868758, + 6.9657842846620879, + 6.9772799234999168, + 6.9886846867721664, + 7.0000000000000000, + 7.0112272554232540, + 7.0223678130284544, + 7.0334230015374501, + 7.0443941193584534, + 7.0552824355011898, + 7.0660891904577721, + 7.0768155970508317, + 7.0874628412503400, + 7.0980320829605272, + 7.1085244567781700, + 7.1189410727235076, + 7.1292830169449664, + 7.1395513523987937, + 7.1497471195046822, + 7.1598713367783891, + 7.1699250014423130, + 7.1799090900149345, + 7.1898245588800176, + 7.1996723448363644, + 7.2094533656289492, + 7.2191685204621621, + 7.2288186904958804, + 7.2384047393250794, + 7.2479275134435861, + 7.2573878426926521, + 7.2667865406949019, + 7.2761244052742384, + 7.2854022188622487, + 7.2946207488916270, + 7.3037807481771031, + 7.3128829552843557, + 7.3219280948873617, + 7.3309168781146177, + 7.3398500028846243, + 7.3487281542310781, + 7.3575520046180847, + 7.3663222142458151, + 7.3750394313469254, + 7.3837042924740528, + 7.3923174227787607, + 7.4008794362821844, + 7.4093909361377026, + 7.4178525148858991, + 7.4262647547020979, + 7.4346282276367255, + 7.4429434958487288, + 7.4512111118323299, + 7.4594316186372973, + 7.4676055500829976, + 7.4757334309663976, + 7.4838157772642564, + 7.4918530963296748, + 7.4998458870832057, + 7.5077946401986964, + 7.5156998382840436, + 7.5235619560570131, + 7.5313814605163119, + 7.5391588111080319, + 7.5468944598876373, + 7.5545888516776376, + 7.5622424242210728, + 7.5698556083309478, + 7.5774288280357487, + 7.5849625007211561, + 7.5924570372680806, + 7.5999128421871278, + 7.6073303137496113, + 7.6147098441152075, + 7.6220518194563764, + 7.6293566200796095, + 7.6366246205436488, + 7.6438561897747244, + 7.6510516911789290, + 7.6582114827517955, + 7.6653359171851765, + 7.6724253419714952, + 7.6794800995054464, + 7.6865005271832185, + 7.6934869574993252, + 7.7004397181410926, + 7.7073591320808825, + 7.7142455176661224, + 7.7210991887071856, + 7.7279204545631996, + 7.7347096202258392, + 7.7414669864011465, + 7.7481928495894596, + 7.7548875021634691, + 7.7615512324444795, + 7.7681843247769260, + 7.7747870596011737, + 7.7813597135246608, + 7.7879025593914317, + 7.7944158663501062, + 7.8008998999203047, + 7.8073549220576037, + 7.8137811912170374, + 7.8201789624151887, + 7.8265484872909159, + 7.8328900141647422, + 7.8392037880969445, + 7.8454900509443757, + 7.8517490414160571, + 7.8579809951275719, + 7.8641861446542798, + 7.8703647195834048, + 7.8765169465650002, + 7.8826430493618425, + 7.8887432488982601, + 7.8948177633079446, + 7.9008668079807496, + 7.9068905956085187, + 7.9128893362299619, + 7.9188632372745955, + 7.9248125036057813, + 7.9307373375628867, + 7.9366379390025719, + 7.9425145053392399, + 7.9483672315846778, + 7.9541963103868758, + 7.9600019320680806, + 7.9657842846620870, + 7.9715435539507720, + 7.9772799234999168, + 7.9829935746943104, + 7.9886846867721664, + 7.9943534368588578, +} + +/* Faster logarithm for small integers, with the property of log2(0) == 0. */ +func fastLog2(v uint) float64 { + if v < uint(len(kLog2Table)) { + return float64(kLog2Table[v]) + } + + return math.Log2(float64(v)) +} diff --git a/vendor/github.com/andybalholm/brotli/find_match_length.go b/vendor/github.com/andybalholm/brotli/find_match_length.go new file mode 100644 index 0000000..09d2ae6 --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/find_match_length.go @@ -0,0 +1,45 @@ +package brotli + +import ( + "encoding/binary" + "math/bits" + "runtime" +) + +/* Copyright 2010 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Function to find maximal matching prefixes of strings. */ +func findMatchLengthWithLimit(s1 []byte, s2 []byte, limit uint) uint { + var matched uint = 0 + _, _ = s1[limit-1], s2[limit-1] // bounds check + switch runtime.GOARCH { + case "amd64": + // Compare 8 bytes at at time. + for matched+8 <= limit { + w1 := binary.LittleEndian.Uint64(s1[matched:]) + w2 := binary.LittleEndian.Uint64(s2[matched:]) + if w1 != w2 { + return matched + uint(bits.TrailingZeros64(w1^w2)>>3) + } + matched += 8 + } + case "386": + // Compare 4 bytes at at time. + for matched+4 <= limit { + w1 := binary.LittleEndian.Uint32(s1[matched:]) + w2 := binary.LittleEndian.Uint32(s2[matched:]) + if w1 != w2 { + return matched + uint(bits.TrailingZeros32(w1^w2)>>3) + } + matched += 4 + } + } + for matched < limit && s1[matched] == s2[matched] { + matched++ + } + return matched +} diff --git a/vendor/github.com/andybalholm/brotli/go.mod b/vendor/github.com/andybalholm/brotli/go.mod new file mode 100644 index 0000000..1c94232 --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/go.mod @@ -0,0 +1,5 @@ +module github.com/andybalholm/brotli + +go 1.12 + +retract v1.0.1 // occasional panics and data corruption diff --git a/vendor/github.com/andybalholm/brotli/go.sum b/vendor/github.com/andybalholm/brotli/go.sum new file mode 100644 index 0000000..e69de29 diff --git a/vendor/github.com/andybalholm/brotli/h10.go b/vendor/github.com/andybalholm/brotli/h10.go new file mode 100644 index 0000000..5662fbb --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/h10.go @@ -0,0 +1,287 @@ +package brotli + +import "encoding/binary" + +/* Copyright 2016 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +func (*h10) HashTypeLength() uint { + return 4 +} + +func (*h10) StoreLookahead() uint { + return 128 +} + +func hashBytesH10(data []byte) uint32 { + var h uint32 = binary.LittleEndian.Uint32(data) * kHashMul32 + + /* The higher bits contain more mixture from the multiplication, + so we take our results from there. */ + return h >> (32 - 17) +} + +/* A (forgetful) hash table where each hash bucket contains a binary tree of + sequences whose first 4 bytes share the same hash code. + Each sequence is 128 long and is identified by its starting + position in the input data. The binary tree is sorted by the lexicographic + order of the sequences, and it is also a max-heap with respect to the + starting positions. */ +type h10 struct { + hasherCommon + window_mask_ uint + buckets_ [1 << 17]uint32 + invalid_pos_ uint32 + forest []uint32 +} + +func (h *h10) Initialize(params *encoderParams) { + h.window_mask_ = (1 << params.lgwin) - 1 + h.invalid_pos_ = uint32(0 - h.window_mask_) + var num_nodes uint = uint(1) << params.lgwin + h.forest = make([]uint32, 2*num_nodes) +} + +func (h *h10) Prepare(one_shot bool, input_size uint, data []byte) { + var invalid_pos uint32 = h.invalid_pos_ + var i uint32 + for i = 0; i < 1<<17; i++ { + h.buckets_[i] = invalid_pos + } +} + +func leftChildIndexH10(self *h10, pos uint) uint { + return 2 * (pos & self.window_mask_) +} + +func rightChildIndexH10(self *h10, pos uint) uint { + return 2*(pos&self.window_mask_) + 1 +} + +/* Stores the hash of the next 4 bytes and in a single tree-traversal, the + hash bucket's binary tree is searched for matches and is re-rooted at the + current position. + + If less than 128 data is available, the hash bucket of the + current position is searched for matches, but the state of the hash table + is not changed, since we can not know the final sorting order of the + current (incomplete) sequence. + + This function must be called with increasing cur_ix positions. */ +func storeAndFindMatchesH10(self *h10, data []byte, cur_ix uint, ring_buffer_mask uint, max_length uint, max_backward uint, best_len *uint, matches []backwardMatch) []backwardMatch { + var cur_ix_masked uint = cur_ix & ring_buffer_mask + var max_comp_len uint = brotli_min_size_t(max_length, 128) + var should_reroot_tree bool = (max_length >= 128) + var key uint32 = hashBytesH10(data[cur_ix_masked:]) + var forest []uint32 = self.forest + var prev_ix uint = uint(self.buckets_[key]) + var node_left uint = leftChildIndexH10(self, cur_ix) + var node_right uint = rightChildIndexH10(self, cur_ix) + var best_len_left uint = 0 + var best_len_right uint = 0 + var depth_remaining uint + /* The forest index of the rightmost node of the left subtree of the new + root, updated as we traverse and re-root the tree of the hash bucket. */ + + /* The forest index of the leftmost node of the right subtree of the new + root, updated as we traverse and re-root the tree of the hash bucket. */ + + /* The match length of the rightmost node of the left subtree of the new + root, updated as we traverse and re-root the tree of the hash bucket. */ + + /* The match length of the leftmost node of the right subtree of the new + root, updated as we traverse and re-root the tree of the hash bucket. */ + if should_reroot_tree { + self.buckets_[key] = uint32(cur_ix) + } + + for depth_remaining = 64; ; depth_remaining-- { + var backward uint = cur_ix - prev_ix + var prev_ix_masked uint = prev_ix & ring_buffer_mask + if backward == 0 || backward > max_backward || depth_remaining == 0 { + if should_reroot_tree { + forest[node_left] = self.invalid_pos_ + forest[node_right] = self.invalid_pos_ + } + + break + } + { + var cur_len uint = brotli_min_size_t(best_len_left, best_len_right) + var len uint + assert(cur_len <= 128) + len = cur_len + findMatchLengthWithLimit(data[cur_ix_masked+cur_len:], data[prev_ix_masked+cur_len:], max_length-cur_len) + if matches != nil && len > *best_len { + *best_len = uint(len) + initBackwardMatch(&matches[0], backward, uint(len)) + matches = matches[1:] + } + + if len >= max_comp_len { + if should_reroot_tree { + forest[node_left] = forest[leftChildIndexH10(self, prev_ix)] + forest[node_right] = forest[rightChildIndexH10(self, prev_ix)] + } + + break + } + + if data[cur_ix_masked+len] > data[prev_ix_masked+len] { + best_len_left = uint(len) + if should_reroot_tree { + forest[node_left] = uint32(prev_ix) + } + + node_left = rightChildIndexH10(self, prev_ix) + prev_ix = uint(forest[node_left]) + } else { + best_len_right = uint(len) + if should_reroot_tree { + forest[node_right] = uint32(prev_ix) + } + + node_right = leftChildIndexH10(self, prev_ix) + prev_ix = uint(forest[node_right]) + } + } + } + + return matches +} + +/* Finds all backward matches of &data[cur_ix & ring_buffer_mask] up to the + length of max_length and stores the position cur_ix in the hash table. + + Sets *num_matches to the number of matches found, and stores the found + matches in matches[0] to matches[*num_matches - 1]. The matches will be + sorted by strictly increasing length and (non-strictly) increasing + distance. */ +func findAllMatchesH10(handle *h10, dictionary *encoderDictionary, data []byte, ring_buffer_mask uint, cur_ix uint, max_length uint, max_backward uint, gap uint, params *encoderParams, matches []backwardMatch) uint { + var orig_matches []backwardMatch = matches + var cur_ix_masked uint = cur_ix & ring_buffer_mask + var best_len uint = 1 + var short_match_max_backward uint + if params.quality != hqZopflificationQuality { + short_match_max_backward = 16 + } else { + short_match_max_backward = 64 + } + var stop uint = cur_ix - short_match_max_backward + var dict_matches [maxStaticDictionaryMatchLen + 1]uint32 + var i uint + if cur_ix < short_match_max_backward { + stop = 0 + } + for i = cur_ix - 1; i > stop && best_len <= 2; i-- { + var prev_ix uint = i + var backward uint = cur_ix - prev_ix + if backward > max_backward { + break + } + + prev_ix &= ring_buffer_mask + if data[cur_ix_masked] != data[prev_ix] || data[cur_ix_masked+1] != data[prev_ix+1] { + continue + } + { + var len uint = findMatchLengthWithLimit(data[prev_ix:], data[cur_ix_masked:], max_length) + if len > best_len { + best_len = uint(len) + initBackwardMatch(&matches[0], backward, uint(len)) + matches = matches[1:] + } + } + } + + if best_len < max_length { + matches = storeAndFindMatchesH10(handle, data, cur_ix, ring_buffer_mask, max_length, max_backward, &best_len, matches) + } + + for i = 0; i <= maxStaticDictionaryMatchLen; i++ { + dict_matches[i] = kInvalidMatch + } + { + var minlen uint = brotli_max_size_t(4, best_len+1) + if findAllStaticDictionaryMatches(dictionary, data[cur_ix_masked:], minlen, max_length, dict_matches[0:]) { + var maxlen uint = brotli_min_size_t(maxStaticDictionaryMatchLen, max_length) + var l uint + for l = minlen; l <= maxlen; l++ { + var dict_id uint32 = dict_matches[l] + if dict_id < kInvalidMatch { + var distance uint = max_backward + gap + uint(dict_id>>5) + 1 + if distance <= params.dist.max_distance { + initDictionaryBackwardMatch(&matches[0], distance, l, uint(dict_id&31)) + matches = matches[1:] + } + } + } + } + } + + return uint(-cap(matches) + cap(orig_matches)) +} + +/* Stores the hash of the next 4 bytes and re-roots the binary tree at the + current sequence, without returning any matches. + REQUIRES: ix + 128 <= end-of-current-block */ +func (h *h10) Store(data []byte, mask uint, ix uint) { + var max_backward uint = h.window_mask_ - windowGap + 1 + /* Maximum distance is window size - 16, see section 9.1. of the spec. */ + storeAndFindMatchesH10(h, data, ix, mask, 128, max_backward, nil, nil) +} + +func (h *h10) StoreRange(data []byte, mask uint, ix_start uint, ix_end uint) { + var i uint = ix_start + var j uint = ix_start + if ix_start+63 <= ix_end { + i = ix_end - 63 + } + + if ix_start+512 <= i { + for ; j < i; j += 8 { + h.Store(data, mask, j) + } + } + + for ; i < ix_end; i++ { + h.Store(data, mask, i) + } +} + +func (h *h10) StitchToPreviousBlock(num_bytes uint, position uint, ringbuffer []byte, ringbuffer_mask uint) { + if num_bytes >= h.HashTypeLength()-1 && position >= 128 { + var i_start uint = position - 128 + 1 + var i_end uint = brotli_min_size_t(position, i_start+num_bytes) + /* Store the last `128 - 1` positions in the hasher. + These could not be calculated before, since they require knowledge + of both the previous and the current block. */ + + var i uint + for i = i_start; i < i_end; i++ { + /* Maximum distance is window size - 16, see section 9.1. of the spec. + Furthermore, we have to make sure that we don't look further back + from the start of the next block than the window size, otherwise we + could access already overwritten areas of the ring-buffer. */ + var max_backward uint = h.window_mask_ - brotli_max_size_t(windowGap-1, position-i) + + /* We know that i + 128 <= position + num_bytes, i.e. the + end of the current block and that we have at least + 128 tail in the ring-buffer. */ + storeAndFindMatchesH10(h, ringbuffer, i, ringbuffer_mask, 128, max_backward, nil, nil) + } + } +} + +/* MAX_NUM_MATCHES == 64 + MAX_TREE_SEARCH_DEPTH */ +const maxNumMatchesH10 = 128 + +func (*h10) FindLongestMatch(dictionary *encoderDictionary, data []byte, ring_buffer_mask uint, distance_cache []int, cur_ix uint, max_length uint, max_backward uint, gap uint, max_distance uint, out *hasherSearchResult) { + panic("unimplemented") +} + +func (*h10) PrepareDistanceCache(distance_cache []int) { + panic("unimplemented") +} diff --git a/vendor/github.com/andybalholm/brotli/h5.go b/vendor/github.com/andybalholm/brotli/h5.go new file mode 100644 index 0000000..f391b73 --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/h5.go @@ -0,0 +1,214 @@ +package brotli + +import "encoding/binary" + +/* Copyright 2010 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* A (forgetful) hash table to the data seen by the compressor, to + help create backward references to previous data. + + This is a hash map of fixed size (bucket_size_) to a ring buffer of + fixed size (block_size_). The ring buffer contains the last block_size_ + index positions of the given hash key in the compressed data. */ +func (*h5) HashTypeLength() uint { + return 4 +} + +func (*h5) StoreLookahead() uint { + return 4 +} + +/* HashBytes is the function that chooses the bucket to place the address in. */ +func hashBytesH5(data []byte, shift int) uint32 { + var h uint32 = binary.LittleEndian.Uint32(data) * kHashMul32 + + /* The higher bits contain more mixture from the multiplication, + so we take our results from there. */ + return uint32(h >> uint(shift)) +} + +type h5 struct { + hasherCommon + bucket_size_ uint + block_size_ uint + hash_shift_ int + block_mask_ uint32 + num []uint16 + buckets []uint32 +} + +func (h *h5) Initialize(params *encoderParams) { + h.hash_shift_ = 32 - h.params.bucket_bits + h.bucket_size_ = uint(1) << uint(h.params.bucket_bits) + h.block_size_ = uint(1) << uint(h.params.block_bits) + h.block_mask_ = uint32(h.block_size_ - 1) + h.num = make([]uint16, h.bucket_size_) + h.buckets = make([]uint32, h.block_size_*h.bucket_size_) +} + +func (h *h5) Prepare(one_shot bool, input_size uint, data []byte) { + var num []uint16 = h.num + var partial_prepare_threshold uint = h.bucket_size_ >> 6 + /* Partial preparation is 100 times slower (per socket). */ + if one_shot && input_size <= partial_prepare_threshold { + var i uint + for i = 0; i < input_size; i++ { + var key uint32 = hashBytesH5(data[i:], h.hash_shift_) + num[key] = 0 + } + } else { + for i := 0; i < int(h.bucket_size_); i++ { + num[i] = 0 + } + } +} + +/* Look at 4 bytes at &data[ix & mask]. + Compute a hash from these, and store the value of ix at that position. */ +func (h *h5) Store(data []byte, mask uint, ix uint) { + var num []uint16 = h.num + var key uint32 = hashBytesH5(data[ix&mask:], h.hash_shift_) + var minor_ix uint = uint(num[key]) & uint(h.block_mask_) + var offset uint = minor_ix + uint(key<= h.HashTypeLength()-1 && position >= 3 { + /* Prepare the hashes for three last bytes of the last write. + These could not be calculated before, since they require knowledge + of both the previous and the current block. */ + h.Store(ringbuffer, ringbuffer_mask, position-3) + h.Store(ringbuffer, ringbuffer_mask, position-2) + h.Store(ringbuffer, ringbuffer_mask, position-1) + } +} + +func (h *h5) PrepareDistanceCache(distance_cache []int) { + prepareDistanceCache(distance_cache, h.params.num_last_distances_to_check) +} + +/* Find a longest backward match of &data[cur_ix] up to the length of + max_length and stores the position cur_ix in the hash table. + + REQUIRES: PrepareDistanceCacheH5 must be invoked for current distance cache + values; if this method is invoked repeatedly with the same distance + cache values, it is enough to invoke PrepareDistanceCacheH5 once. + + Does not look for matches longer than max_length. + Does not look for matches further away than max_backward. + Writes the best match into |out|. + |out|->score is updated only if a better match is found. */ +func (h *h5) FindLongestMatch(dictionary *encoderDictionary, data []byte, ring_buffer_mask uint, distance_cache []int, cur_ix uint, max_length uint, max_backward uint, gap uint, max_distance uint, out *hasherSearchResult) { + var num []uint16 = h.num + var buckets []uint32 = h.buckets + var cur_ix_masked uint = cur_ix & ring_buffer_mask + var min_score uint = out.score + var best_score uint = out.score + var best_len uint = out.len + var i uint + var bucket []uint32 + /* Don't accept a short copy from far away. */ + out.len = 0 + + out.len_code_delta = 0 + + /* Try last distance first. */ + for i = 0; i < uint(h.params.num_last_distances_to_check); i++ { + var backward uint = uint(distance_cache[i]) + var prev_ix uint = uint(cur_ix - backward) + if prev_ix >= cur_ix { + continue + } + + if backward > max_backward { + continue + } + + prev_ix &= ring_buffer_mask + + if cur_ix_masked+best_len > ring_buffer_mask || prev_ix+best_len > ring_buffer_mask || data[cur_ix_masked+best_len] != data[prev_ix+best_len] { + continue + } + { + var len uint = findMatchLengthWithLimit(data[prev_ix:], data[cur_ix_masked:], max_length) + if len >= 3 || (len == 2 && i < 2) { + /* Comparing for >= 2 does not change the semantics, but just saves for + a few unnecessary binary logarithms in backward reference score, + since we are not interested in such short matches. */ + var score uint = backwardReferenceScoreUsingLastDistance(uint(len)) + if best_score < score { + if i != 0 { + score -= backwardReferencePenaltyUsingLastDistance(i) + } + if best_score < score { + best_score = score + best_len = uint(len) + out.len = best_len + out.distance = backward + out.score = best_score + } + } + } + } + } + { + var key uint32 = hashBytesH5(data[cur_ix_masked:], h.hash_shift_) + bucket = buckets[key< h.block_size_ { + down = uint(num[key]) - h.block_size_ + } else { + down = 0 + } + for i = uint(num[key]); i > down; { + var prev_ix uint + i-- + prev_ix = uint(bucket[uint32(i)&h.block_mask_]) + var backward uint = cur_ix - prev_ix + if backward > max_backward { + break + } + + prev_ix &= ring_buffer_mask + if cur_ix_masked+best_len > ring_buffer_mask || prev_ix+best_len > ring_buffer_mask || data[cur_ix_masked+best_len] != data[prev_ix+best_len] { + continue + } + { + var len uint = findMatchLengthWithLimit(data[prev_ix:], data[cur_ix_masked:], max_length) + if len >= 4 { + /* Comparing for >= 3 does not change the semantics, but just saves + for a few unnecessary binary logarithms in backward reference + score, since we are not interested in such short matches. */ + var score uint = backwardReferenceScore(uint(len), backward) + if best_score < score { + best_score = score + best_len = uint(len) + out.len = best_len + out.distance = backward + out.score = best_score + } + } + } + } + + bucket[uint32(num[key])&h.block_mask_] = uint32(cur_ix) + num[key]++ + } + + if min_score == out.score { + searchInStaticDictionary(dictionary, h, data[cur_ix_masked:], max_length, max_backward+gap, max_distance, out, false) + } +} diff --git a/vendor/github.com/andybalholm/brotli/h6.go b/vendor/github.com/andybalholm/brotli/h6.go new file mode 100644 index 0000000..80bb224 --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/h6.go @@ -0,0 +1,216 @@ +package brotli + +import "encoding/binary" + +/* Copyright 2010 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* A (forgetful) hash table to the data seen by the compressor, to + help create backward references to previous data. + + This is a hash map of fixed size (bucket_size_) to a ring buffer of + fixed size (block_size_). The ring buffer contains the last block_size_ + index positions of the given hash key in the compressed data. */ +func (*h6) HashTypeLength() uint { + return 8 +} + +func (*h6) StoreLookahead() uint { + return 8 +} + +/* HashBytes is the function that chooses the bucket to place the address in. */ +func hashBytesH6(data []byte, mask uint64, shift int) uint32 { + var h uint64 = (binary.LittleEndian.Uint64(data) & mask) * kHashMul64Long + + /* The higher bits contain more mixture from the multiplication, + so we take our results from there. */ + return uint32(h >> uint(shift)) +} + +type h6 struct { + hasherCommon + bucket_size_ uint + block_size_ uint + hash_shift_ int + hash_mask_ uint64 + block_mask_ uint32 + num []uint16 + buckets []uint32 +} + +func (h *h6) Initialize(params *encoderParams) { + h.hash_shift_ = 64 - h.params.bucket_bits + h.hash_mask_ = (^(uint64(0))) >> uint(64-8*h.params.hash_len) + h.bucket_size_ = uint(1) << uint(h.params.bucket_bits) + h.block_size_ = uint(1) << uint(h.params.block_bits) + h.block_mask_ = uint32(h.block_size_ - 1) + h.num = make([]uint16, h.bucket_size_) + h.buckets = make([]uint32, h.block_size_*h.bucket_size_) +} + +func (h *h6) Prepare(one_shot bool, input_size uint, data []byte) { + var num []uint16 = h.num + var partial_prepare_threshold uint = h.bucket_size_ >> 6 + /* Partial preparation is 100 times slower (per socket). */ + if one_shot && input_size <= partial_prepare_threshold { + var i uint + for i = 0; i < input_size; i++ { + var key uint32 = hashBytesH6(data[i:], h.hash_mask_, h.hash_shift_) + num[key] = 0 + } + } else { + for i := 0; i < int(h.bucket_size_); i++ { + num[i] = 0 + } + } +} + +/* Look at 4 bytes at &data[ix & mask]. + Compute a hash from these, and store the value of ix at that position. */ +func (h *h6) Store(data []byte, mask uint, ix uint) { + var num []uint16 = h.num + var key uint32 = hashBytesH6(data[ix&mask:], h.hash_mask_, h.hash_shift_) + var minor_ix uint = uint(num[key]) & uint(h.block_mask_) + var offset uint = minor_ix + uint(key<= h.HashTypeLength()-1 && position >= 3 { + /* Prepare the hashes for three last bytes of the last write. + These could not be calculated before, since they require knowledge + of both the previous and the current block. */ + h.Store(ringbuffer, ringbuffer_mask, position-3) + h.Store(ringbuffer, ringbuffer_mask, position-2) + h.Store(ringbuffer, ringbuffer_mask, position-1) + } +} + +func (h *h6) PrepareDistanceCache(distance_cache []int) { + prepareDistanceCache(distance_cache, h.params.num_last_distances_to_check) +} + +/* Find a longest backward match of &data[cur_ix] up to the length of + max_length and stores the position cur_ix in the hash table. + + REQUIRES: PrepareDistanceCacheH6 must be invoked for current distance cache + values; if this method is invoked repeatedly with the same distance + cache values, it is enough to invoke PrepareDistanceCacheH6 once. + + Does not look for matches longer than max_length. + Does not look for matches further away than max_backward. + Writes the best match into |out|. + |out|->score is updated only if a better match is found. */ +func (h *h6) FindLongestMatch(dictionary *encoderDictionary, data []byte, ring_buffer_mask uint, distance_cache []int, cur_ix uint, max_length uint, max_backward uint, gap uint, max_distance uint, out *hasherSearchResult) { + var num []uint16 = h.num + var buckets []uint32 = h.buckets + var cur_ix_masked uint = cur_ix & ring_buffer_mask + var min_score uint = out.score + var best_score uint = out.score + var best_len uint = out.len + var i uint + var bucket []uint32 + /* Don't accept a short copy from far away. */ + out.len = 0 + + out.len_code_delta = 0 + + /* Try last distance first. */ + for i = 0; i < uint(h.params.num_last_distances_to_check); i++ { + var backward uint = uint(distance_cache[i]) + var prev_ix uint = uint(cur_ix - backward) + if prev_ix >= cur_ix { + continue + } + + if backward > max_backward { + continue + } + + prev_ix &= ring_buffer_mask + + if cur_ix_masked+best_len > ring_buffer_mask || prev_ix+best_len > ring_buffer_mask || data[cur_ix_masked+best_len] != data[prev_ix+best_len] { + continue + } + { + var len uint = findMatchLengthWithLimit(data[prev_ix:], data[cur_ix_masked:], max_length) + if len >= 3 || (len == 2 && i < 2) { + /* Comparing for >= 2 does not change the semantics, but just saves for + a few unnecessary binary logarithms in backward reference score, + since we are not interested in such short matches. */ + var score uint = backwardReferenceScoreUsingLastDistance(uint(len)) + if best_score < score { + if i != 0 { + score -= backwardReferencePenaltyUsingLastDistance(i) + } + if best_score < score { + best_score = score + best_len = uint(len) + out.len = best_len + out.distance = backward + out.score = best_score + } + } + } + } + } + { + var key uint32 = hashBytesH6(data[cur_ix_masked:], h.hash_mask_, h.hash_shift_) + bucket = buckets[key< h.block_size_ { + down = uint(num[key]) - h.block_size_ + } else { + down = 0 + } + for i = uint(num[key]); i > down; { + var prev_ix uint + i-- + prev_ix = uint(bucket[uint32(i)&h.block_mask_]) + var backward uint = cur_ix - prev_ix + if backward > max_backward { + break + } + + prev_ix &= ring_buffer_mask + if cur_ix_masked+best_len > ring_buffer_mask || prev_ix+best_len > ring_buffer_mask || data[cur_ix_masked+best_len] != data[prev_ix+best_len] { + continue + } + { + var len uint = findMatchLengthWithLimit(data[prev_ix:], data[cur_ix_masked:], max_length) + if len >= 4 { + /* Comparing for >= 3 does not change the semantics, but just saves + for a few unnecessary binary logarithms in backward reference + score, since we are not interested in such short matches. */ + var score uint = backwardReferenceScore(uint(len), backward) + if best_score < score { + best_score = score + best_len = uint(len) + out.len = best_len + out.distance = backward + out.score = best_score + } + } + } + } + + bucket[uint32(num[key])&h.block_mask_] = uint32(cur_ix) + num[key]++ + } + + if min_score == out.score { + searchInStaticDictionary(dictionary, h, data[cur_ix_masked:], max_length, max_backward+gap, max_distance, out, false) + } +} diff --git a/vendor/github.com/andybalholm/brotli/hash.go b/vendor/github.com/andybalholm/brotli/hash.go new file mode 100644 index 0000000..00f812e --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/hash.go @@ -0,0 +1,342 @@ +package brotli + +import ( + "encoding/binary" + "fmt" +) + +type hasherCommon struct { + params hasherParams + is_prepared_ bool + dict_num_lookups uint + dict_num_matches uint +} + +func (h *hasherCommon) Common() *hasherCommon { + return h +} + +type hasherHandle interface { + Common() *hasherCommon + Initialize(params *encoderParams) + Prepare(one_shot bool, input_size uint, data []byte) + StitchToPreviousBlock(num_bytes uint, position uint, ringbuffer []byte, ringbuffer_mask uint) + HashTypeLength() uint + StoreLookahead() uint + PrepareDistanceCache(distance_cache []int) + FindLongestMatch(dictionary *encoderDictionary, data []byte, ring_buffer_mask uint, distance_cache []int, cur_ix uint, max_length uint, max_backward uint, gap uint, max_distance uint, out *hasherSearchResult) + StoreRange(data []byte, mask uint, ix_start uint, ix_end uint) + Store(data []byte, mask uint, ix uint) +} + +const kCutoffTransformsCount uint32 = 10 + +/* 0, 12, 27, 23, 42, 63, 56, 48, 59, 64 */ +/* 0+0, 4+8, 8+19, 12+11, 16+26, 20+43, 24+32, 28+20, 32+27, 36+28 */ +const kCutoffTransforms uint64 = 0x071B520ADA2D3200 + +type hasherSearchResult struct { + len uint + distance uint + score uint + len_code_delta int +} + +/* kHashMul32 multiplier has these properties: + * The multiplier must be odd. Otherwise we may lose the highest bit. + * No long streaks of ones or zeros. + * There is no effort to ensure that it is a prime, the oddity is enough + for this use. + * The number has been tuned heuristically against compression benchmarks. */ +const kHashMul32 uint32 = 0x1E35A7BD + +const kHashMul64 uint64 = 0x1E35A7BD1E35A7BD + +const kHashMul64Long uint64 = 0x1FE35A7BD3579BD3 + +func hash14(data []byte) uint32 { + var h uint32 = binary.LittleEndian.Uint32(data) * kHashMul32 + + /* The higher bits contain more mixture from the multiplication, + so we take our results from there. */ + return h >> (32 - 14) +} + +func prepareDistanceCache(distance_cache []int, num_distances int) { + if num_distances > 4 { + var last_distance int = distance_cache[0] + distance_cache[4] = last_distance - 1 + distance_cache[5] = last_distance + 1 + distance_cache[6] = last_distance - 2 + distance_cache[7] = last_distance + 2 + distance_cache[8] = last_distance - 3 + distance_cache[9] = last_distance + 3 + if num_distances > 10 { + var next_last_distance int = distance_cache[1] + distance_cache[10] = next_last_distance - 1 + distance_cache[11] = next_last_distance + 1 + distance_cache[12] = next_last_distance - 2 + distance_cache[13] = next_last_distance + 2 + distance_cache[14] = next_last_distance - 3 + distance_cache[15] = next_last_distance + 3 + } + } +} + +const literalByteScore = 135 + +const distanceBitPenalty = 30 + +/* Score must be positive after applying maximal penalty. */ +const scoreBase = (distanceBitPenalty * 8 * 8) + +/* Usually, we always choose the longest backward reference. This function + allows for the exception of that rule. + + If we choose a backward reference that is further away, it will + usually be coded with more bits. We approximate this by assuming + log2(distance). If the distance can be expressed in terms of the + last four distances, we use some heuristic constants to estimate + the bits cost. For the first up to four literals we use the bit + cost of the literals from the literal cost model, after that we + use the average bit cost of the cost model. + + This function is used to sometimes discard a longer backward reference + when it is not much longer and the bit cost for encoding it is more + than the saved literals. + + backward_reference_offset MUST be positive. */ +func backwardReferenceScore(copy_length uint, backward_reference_offset uint) uint { + return scoreBase + literalByteScore*uint(copy_length) - distanceBitPenalty*uint(log2FloorNonZero(backward_reference_offset)) +} + +func backwardReferenceScoreUsingLastDistance(copy_length uint) uint { + return literalByteScore*uint(copy_length) + scoreBase + 15 +} + +func backwardReferencePenaltyUsingLastDistance(distance_short_code uint) uint { + return uint(39) + ((0x1CA10 >> (distance_short_code & 0xE)) & 0xE) +} + +func testStaticDictionaryItem(dictionary *encoderDictionary, item uint, data []byte, max_length uint, max_backward uint, max_distance uint, out *hasherSearchResult) bool { + var len uint + var word_idx uint + var offset uint + var matchlen uint + var backward uint + var score uint + len = item & 0x1F + word_idx = item >> 5 + offset = uint(dictionary.words.offsets_by_length[len]) + len*word_idx + if len > max_length { + return false + } + + matchlen = findMatchLengthWithLimit(data, dictionary.words.data[offset:], uint(len)) + if matchlen+uint(dictionary.cutoffTransformsCount) <= len || matchlen == 0 { + return false + } + { + var cut uint = len - matchlen + var transform_id uint = (cut << 2) + uint((dictionary.cutoffTransforms>>(cut*6))&0x3F) + backward = max_backward + 1 + word_idx + (transform_id << dictionary.words.size_bits_by_length[len]) + } + + if backward > max_distance { + return false + } + + score = backwardReferenceScore(matchlen, backward) + if score < out.score { + return false + } + + out.len = matchlen + out.len_code_delta = int(len) - int(matchlen) + out.distance = backward + out.score = score + return true +} + +func searchInStaticDictionary(dictionary *encoderDictionary, handle hasherHandle, data []byte, max_length uint, max_backward uint, max_distance uint, out *hasherSearchResult, shallow bool) { + var key uint + var i uint + var self *hasherCommon = handle.Common() + if self.dict_num_matches < self.dict_num_lookups>>7 { + return + } + + key = uint(hash14(data) << 1) + for i = 0; ; (func() { i++; key++ })() { + var tmp uint + if shallow { + tmp = 1 + } else { + tmp = 2 + } + if i >= tmp { + break + } + var item uint = uint(dictionary.hash_table[key]) + self.dict_num_lookups++ + if item != 0 { + var item_matches bool = testStaticDictionaryItem(dictionary, item, data, max_length, max_backward, max_distance, out) + if item_matches { + self.dict_num_matches++ + } + } + } +} + +type backwardMatch struct { + distance uint32 + length_and_code uint32 +} + +func initBackwardMatch(self *backwardMatch, dist uint, len uint) { + self.distance = uint32(dist) + self.length_and_code = uint32(len << 5) +} + +func initDictionaryBackwardMatch(self *backwardMatch, dist uint, len uint, len_code uint) { + self.distance = uint32(dist) + var tmp uint + if len == len_code { + tmp = 0 + } else { + tmp = len_code + } + self.length_and_code = uint32(len<<5 | tmp) +} + +func backwardMatchLength(self *backwardMatch) uint { + return uint(self.length_and_code >> 5) +} + +func backwardMatchLengthCode(self *backwardMatch) uint { + var code uint = uint(self.length_and_code) & 31 + if code != 0 { + return code + } else { + return backwardMatchLength(self) + } +} + +func hasherReset(handle hasherHandle) { + if handle == nil { + return + } + handle.Common().is_prepared_ = false +} + +func newHasher(typ int) hasherHandle { + switch typ { + case 2: + return &hashLongestMatchQuickly{ + bucketBits: 16, + bucketSweep: 1, + hashLen: 5, + useDictionary: true, + } + case 3: + return &hashLongestMatchQuickly{ + bucketBits: 16, + bucketSweep: 2, + hashLen: 5, + useDictionary: false, + } + case 4: + return &hashLongestMatchQuickly{ + bucketBits: 17, + bucketSweep: 4, + hashLen: 5, + useDictionary: true, + } + case 5: + return new(h5) + case 6: + return new(h6) + case 10: + return new(h10) + case 35: + return &hashComposite{ + ha: newHasher(3), + hb: &hashRolling{jump: 4}, + } + case 40: + return &hashForgetfulChain{ + bucketBits: 15, + numBanks: 1, + bankBits: 16, + numLastDistancesToCheck: 4, + } + case 41: + return &hashForgetfulChain{ + bucketBits: 15, + numBanks: 1, + bankBits: 16, + numLastDistancesToCheck: 10, + } + case 42: + return &hashForgetfulChain{ + bucketBits: 15, + numBanks: 512, + bankBits: 9, + numLastDistancesToCheck: 16, + } + case 54: + return &hashLongestMatchQuickly{ + bucketBits: 20, + bucketSweep: 4, + hashLen: 7, + useDictionary: false, + } + case 55: + return &hashComposite{ + ha: newHasher(54), + hb: &hashRolling{jump: 4}, + } + case 65: + return &hashComposite{ + ha: newHasher(6), + hb: &hashRolling{jump: 1}, + } + } + + panic(fmt.Sprintf("unknown hasher type: %d", typ)) +} + +func hasherSetup(handle *hasherHandle, params *encoderParams, data []byte, position uint, input_size uint, is_last bool) { + var self hasherHandle = nil + var common *hasherCommon = nil + var one_shot bool = (position == 0 && is_last) + if *handle == nil { + chooseHasher(params, ¶ms.hasher) + self = newHasher(params.hasher.type_) + + *handle = self + common = self.Common() + common.params = params.hasher + self.Initialize(params) + } + + self = *handle + common = self.Common() + if !common.is_prepared_ { + self.Prepare(one_shot, input_size, data) + + if position == 0 { + common.dict_num_lookups = 0 + common.dict_num_matches = 0 + } + + common.is_prepared_ = true + } +} + +func initOrStitchToPreviousBlock(handle *hasherHandle, data []byte, mask uint, params *encoderParams, position uint, input_size uint, is_last bool) { + var self hasherHandle + hasherSetup(handle, params, data, position, input_size, is_last) + self = *handle + self.StitchToPreviousBlock(input_size, position, data, mask) +} diff --git a/vendor/github.com/andybalholm/brotli/hash_composite.go b/vendor/github.com/andybalholm/brotli/hash_composite.go new file mode 100644 index 0000000..a65fe2e --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/hash_composite.go @@ -0,0 +1,93 @@ +package brotli + +/* Copyright 2018 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +func (h *hashComposite) HashTypeLength() uint { + var a uint = h.ha.HashTypeLength() + var b uint = h.hb.HashTypeLength() + if a > b { + return a + } else { + return b + } +} + +func (h *hashComposite) StoreLookahead() uint { + var a uint = h.ha.StoreLookahead() + var b uint = h.hb.StoreLookahead() + if a > b { + return a + } else { + return b + } +} + +/* Composite hasher: This hasher allows to combine two other hashers, HASHER_A + and HASHER_B. */ +type hashComposite struct { + hasherCommon + ha hasherHandle + hb hasherHandle + params *encoderParams +} + +func (h *hashComposite) Initialize(params *encoderParams) { + h.params = params +} + +/* TODO: Initialize of the hashers is defered to Prepare (and params + remembered here) because we don't get the one_shot and input_size params + here that are needed to know the memory size of them. Instead provide + those params to all hashers InitializehashComposite */ +func (h *hashComposite) Prepare(one_shot bool, input_size uint, data []byte) { + if h.ha == nil { + var common_a *hasherCommon + var common_b *hasherCommon + + common_a = h.ha.Common() + common_a.params = h.params.hasher + common_a.is_prepared_ = false + common_a.dict_num_lookups = 0 + common_a.dict_num_matches = 0 + h.ha.Initialize(h.params) + + common_b = h.hb.Common() + common_b.params = h.params.hasher + common_b.is_prepared_ = false + common_b.dict_num_lookups = 0 + common_b.dict_num_matches = 0 + h.hb.Initialize(h.params) + } + + h.ha.Prepare(one_shot, input_size, data) + h.hb.Prepare(one_shot, input_size, data) +} + +func (h *hashComposite) Store(data []byte, mask uint, ix uint) { + h.ha.Store(data, mask, ix) + h.hb.Store(data, mask, ix) +} + +func (h *hashComposite) StoreRange(data []byte, mask uint, ix_start uint, ix_end uint) { + h.ha.StoreRange(data, mask, ix_start, ix_end) + h.hb.StoreRange(data, mask, ix_start, ix_end) +} + +func (h *hashComposite) StitchToPreviousBlock(num_bytes uint, position uint, ringbuffer []byte, ring_buffer_mask uint) { + h.ha.StitchToPreviousBlock(num_bytes, position, ringbuffer, ring_buffer_mask) + h.hb.StitchToPreviousBlock(num_bytes, position, ringbuffer, ring_buffer_mask) +} + +func (h *hashComposite) PrepareDistanceCache(distance_cache []int) { + h.ha.PrepareDistanceCache(distance_cache) + h.hb.PrepareDistanceCache(distance_cache) +} + +func (h *hashComposite) FindLongestMatch(dictionary *encoderDictionary, data []byte, ring_buffer_mask uint, distance_cache []int, cur_ix uint, max_length uint, max_backward uint, gap uint, max_distance uint, out *hasherSearchResult) { + h.ha.FindLongestMatch(dictionary, data, ring_buffer_mask, distance_cache, cur_ix, max_length, max_backward, gap, max_distance, out) + h.hb.FindLongestMatch(dictionary, data, ring_buffer_mask, distance_cache, cur_ix, max_length, max_backward, gap, max_distance, out) +} diff --git a/vendor/github.com/andybalholm/brotli/hash_forgetful_chain.go b/vendor/github.com/andybalholm/brotli/hash_forgetful_chain.go new file mode 100644 index 0000000..306e46d --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/hash_forgetful_chain.go @@ -0,0 +1,252 @@ +package brotli + +import "encoding/binary" + +/* Copyright 2016 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +func (*hashForgetfulChain) HashTypeLength() uint { + return 4 +} + +func (*hashForgetfulChain) StoreLookahead() uint { + return 4 +} + +/* HashBytes is the function that chooses the bucket to place the address in.*/ +func (h *hashForgetfulChain) HashBytes(data []byte) uint { + var hash uint32 = binary.LittleEndian.Uint32(data) * kHashMul32 + + /* The higher bits contain more mixture from the multiplication, + so we take our results from there. */ + return uint(hash >> (32 - h.bucketBits)) +} + +type slot struct { + delta uint16 + next uint16 +} + +/* A (forgetful) hash table to the data seen by the compressor, to + help create backward references to previous data. + + Hashes are stored in chains which are bucketed to groups. Group of chains + share a storage "bank". When more than "bank size" chain nodes are added, + oldest nodes are replaced; this way several chains may share a tail. */ +type hashForgetfulChain struct { + hasherCommon + + bucketBits uint + numBanks uint + bankBits uint + numLastDistancesToCheck int + + addr []uint32 + head []uint16 + tiny_hash [65536]byte + banks [][]slot + free_slot_idx []uint16 + max_hops uint +} + +func (h *hashForgetfulChain) Initialize(params *encoderParams) { + var q uint + if params.quality > 6 { + q = 7 + } else { + q = 8 + } + h.max_hops = q << uint(params.quality-4) + + bankSize := 1 << h.bankBits + bucketSize := 1 << h.bucketBits + + h.addr = make([]uint32, bucketSize) + h.head = make([]uint16, bucketSize) + h.banks = make([][]slot, h.numBanks) + for i := range h.banks { + h.banks[i] = make([]slot, bankSize) + } + h.free_slot_idx = make([]uint16, h.numBanks) +} + +func (h *hashForgetfulChain) Prepare(one_shot bool, input_size uint, data []byte) { + var partial_prepare_threshold uint = (1 << h.bucketBits) >> 6 + /* Partial preparation is 100 times slower (per socket). */ + if one_shot && input_size <= partial_prepare_threshold { + var i uint + for i = 0; i < input_size; i++ { + var bucket uint = h.HashBytes(data[i:]) + + /* See InitEmpty comment. */ + h.addr[bucket] = 0xCCCCCCCC + + h.head[bucket] = 0xCCCC + } + } else { + /* Fill |addr| array with 0xCCCCCCCC value. Because of wrapping, position + processed by hasher never reaches 3GB + 64M; this makes all new chains + to be terminated after the first node. */ + for i := range h.addr { + h.addr[i] = 0xCCCCCCCC + } + + for i := range h.head { + h.head[i] = 0 + } + } + + h.tiny_hash = [65536]byte{} + for i := range h.free_slot_idx { + h.free_slot_idx[i] = 0 + } +} + +/* Look at 4 bytes at &data[ix & mask]. Compute a hash from these, and prepend + node to corresponding chain; also update tiny_hash for current position. */ +func (h *hashForgetfulChain) Store(data []byte, mask uint, ix uint) { + var key uint = h.HashBytes(data[ix&mask:]) + var bank uint = key & (h.numBanks - 1) + idx := uint(h.free_slot_idx[bank]) & ((1 << h.bankBits) - 1) + h.free_slot_idx[bank]++ + var delta uint = ix - uint(h.addr[key]) + h.tiny_hash[uint16(ix)] = byte(key) + if delta > 0xFFFF { + delta = 0xFFFF + } + h.banks[bank][idx].delta = uint16(delta) + h.banks[bank][idx].next = h.head[key] + h.addr[key] = uint32(ix) + h.head[key] = uint16(idx) +} + +func (h *hashForgetfulChain) StoreRange(data []byte, mask uint, ix_start uint, ix_end uint) { + var i uint + for i = ix_start; i < ix_end; i++ { + h.Store(data, mask, i) + } +} + +func (h *hashForgetfulChain) StitchToPreviousBlock(num_bytes uint, position uint, ringbuffer []byte, ring_buffer_mask uint) { + if num_bytes >= h.HashTypeLength()-1 && position >= 3 { + /* Prepare the hashes for three last bytes of the last write. + These could not be calculated before, since they require knowledge + of both the previous and the current block. */ + h.Store(ringbuffer, ring_buffer_mask, position-3) + h.Store(ringbuffer, ring_buffer_mask, position-2) + h.Store(ringbuffer, ring_buffer_mask, position-1) + } +} + +func (h *hashForgetfulChain) PrepareDistanceCache(distance_cache []int) { + prepareDistanceCache(distance_cache, h.numLastDistancesToCheck) +} + +/* Find a longest backward match of &data[cur_ix] up to the length of + max_length and stores the position cur_ix in the hash table. + + REQUIRES: PrepareDistanceCachehashForgetfulChain must be invoked for current distance cache + values; if this method is invoked repeatedly with the same distance + cache values, it is enough to invoke PrepareDistanceCachehashForgetfulChain once. + + Does not look for matches longer than max_length. + Does not look for matches further away than max_backward. + Writes the best match into |out|. + |out|->score is updated only if a better match is found. */ +func (h *hashForgetfulChain) FindLongestMatch(dictionary *encoderDictionary, data []byte, ring_buffer_mask uint, distance_cache []int, cur_ix uint, max_length uint, max_backward uint, gap uint, max_distance uint, out *hasherSearchResult) { + var cur_ix_masked uint = cur_ix & ring_buffer_mask + var min_score uint = out.score + var best_score uint = out.score + var best_len uint = out.len + var key uint = h.HashBytes(data[cur_ix_masked:]) + var tiny_hash byte = byte(key) + /* Don't accept a short copy from far away. */ + out.len = 0 + + out.len_code_delta = 0 + + /* Try last distance first. */ + for i := 0; i < h.numLastDistancesToCheck; i++ { + var backward uint = uint(distance_cache[i]) + var prev_ix uint = (cur_ix - backward) + + /* For distance code 0 we want to consider 2-byte matches. */ + if i > 0 && h.tiny_hash[uint16(prev_ix)] != tiny_hash { + continue + } + if prev_ix >= cur_ix || backward > max_backward { + continue + } + + prev_ix &= ring_buffer_mask + { + var len uint = findMatchLengthWithLimit(data[prev_ix:], data[cur_ix_masked:], max_length) + if len >= 2 { + var score uint = backwardReferenceScoreUsingLastDistance(uint(len)) + if best_score < score { + if i != 0 { + score -= backwardReferencePenaltyUsingLastDistance(uint(i)) + } + if best_score < score { + best_score = score + best_len = uint(len) + out.len = best_len + out.distance = backward + out.score = best_score + } + } + } + } + } + { + var bank uint = key & (h.numBanks - 1) + var backward uint = 0 + var hops uint = h.max_hops + var delta uint = cur_ix - uint(h.addr[key]) + var slot uint = uint(h.head[key]) + for { + tmp6 := hops + hops-- + if tmp6 == 0 { + break + } + var prev_ix uint + var last uint = slot + backward += delta + if backward > max_backward { + break + } + prev_ix = (cur_ix - backward) & ring_buffer_mask + slot = uint(h.banks[bank][last].next) + delta = uint(h.banks[bank][last].delta) + if cur_ix_masked+best_len > ring_buffer_mask || prev_ix+best_len > ring_buffer_mask || data[cur_ix_masked+best_len] != data[prev_ix+best_len] { + continue + } + { + var len uint = findMatchLengthWithLimit(data[prev_ix:], data[cur_ix_masked:], max_length) + if len >= 4 { + /* Comparing for >= 3 does not change the semantics, but just saves + for a few unnecessary binary logarithms in backward reference + score, since we are not interested in such short matches. */ + var score uint = backwardReferenceScore(uint(len), backward) + if best_score < score { + best_score = score + best_len = uint(len) + out.len = best_len + out.distance = backward + out.score = best_score + } + } + } + } + + h.Store(data, ring_buffer_mask, cur_ix) + } + + if out.score == min_score { + searchInStaticDictionary(dictionary, h, data[cur_ix_masked:], max_length, max_backward+gap, max_distance, out, false) + } +} diff --git a/vendor/github.com/andybalholm/brotli/hash_longest_match_quickly.go b/vendor/github.com/andybalholm/brotli/hash_longest_match_quickly.go new file mode 100644 index 0000000..9375dc1 --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/hash_longest_match_quickly.go @@ -0,0 +1,214 @@ +package brotli + +import "encoding/binary" + +/* Copyright 2010 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* For BUCKET_SWEEP == 1, enabling the dictionary lookup makes compression + a little faster (0.5% - 1%) and it compresses 0.15% better on small text + and HTML inputs. */ + +func (*hashLongestMatchQuickly) HashTypeLength() uint { + return 8 +} + +func (*hashLongestMatchQuickly) StoreLookahead() uint { + return 8 +} + +/* HashBytes is the function that chooses the bucket to place + the address in. The HashLongestMatch and hashLongestMatchQuickly + classes have separate, different implementations of hashing. */ +func (h *hashLongestMatchQuickly) HashBytes(data []byte) uint32 { + var hash uint64 = ((binary.LittleEndian.Uint64(data) << (64 - 8*h.hashLen)) * kHashMul64) + + /* The higher bits contain more mixture from the multiplication, + so we take our results from there. */ + return uint32(hash >> (64 - h.bucketBits)) +} + +/* A (forgetful) hash table to the data seen by the compressor, to + help create backward references to previous data. + + This is a hash map of fixed size (1 << 16). Starting from the + given index, 1 buckets are used to store values of a key. */ +type hashLongestMatchQuickly struct { + hasherCommon + + bucketBits uint + bucketSweep int + hashLen uint + useDictionary bool + + buckets []uint32 +} + +func (h *hashLongestMatchQuickly) Initialize(params *encoderParams) { + h.buckets = make([]uint32, 1<> 7 + /* Partial preparation is 100 times slower (per socket). */ + if one_shot && input_size <= partial_prepare_threshold { + var i uint + for i = 0; i < input_size; i++ { + var key uint32 = h.HashBytes(data[i:]) + for j := 0; j < h.bucketSweep; j++ { + h.buckets[key+uint32(j)] = 0 + } + } + } else { + /* It is not strictly necessary to fill this buffer here, but + not filling will make the results of the compression stochastic + (but correct). This is because random data would cause the + system to find accidentally good backward references here and there. */ + for i := range h.buckets { + h.buckets[i] = 0 + } + } +} + +/* Look at 5 bytes at &data[ix & mask]. + Compute a hash from these, and store the value somewhere within + [ix .. ix+3]. */ +func (h *hashLongestMatchQuickly) Store(data []byte, mask uint, ix uint) { + var key uint32 = h.HashBytes(data[ix&mask:]) + var off uint32 = uint32(ix>>3) % uint32(h.bucketSweep) + /* Wiggle the value with the bucket sweep range. */ + h.buckets[key+off] = uint32(ix) +} + +func (h *hashLongestMatchQuickly) StoreRange(data []byte, mask uint, ix_start uint, ix_end uint) { + var i uint + for i = ix_start; i < ix_end; i++ { + h.Store(data, mask, i) + } +} + +func (h *hashLongestMatchQuickly) StitchToPreviousBlock(num_bytes uint, position uint, ringbuffer []byte, ringbuffer_mask uint) { + if num_bytes >= h.HashTypeLength()-1 && position >= 3 { + /* Prepare the hashes for three last bytes of the last write. + These could not be calculated before, since they require knowledge + of both the previous and the current block. */ + h.Store(ringbuffer, ringbuffer_mask, position-3) + h.Store(ringbuffer, ringbuffer_mask, position-2) + h.Store(ringbuffer, ringbuffer_mask, position-1) + } +} + +func (*hashLongestMatchQuickly) PrepareDistanceCache(distance_cache []int) { +} + +/* Find a longest backward match of &data[cur_ix & ring_buffer_mask] + up to the length of max_length and stores the position cur_ix in the + hash table. + + Does not look for matches longer than max_length. + Does not look for matches further away than max_backward. + Writes the best match into |out|. + |out|->score is updated only if a better match is found. */ +func (h *hashLongestMatchQuickly) FindLongestMatch(dictionary *encoderDictionary, data []byte, ring_buffer_mask uint, distance_cache []int, cur_ix uint, max_length uint, max_backward uint, gap uint, max_distance uint, out *hasherSearchResult) { + var best_len_in uint = out.len + var cur_ix_masked uint = cur_ix & ring_buffer_mask + var key uint32 = h.HashBytes(data[cur_ix_masked:]) + var compare_char int = int(data[cur_ix_masked+best_len_in]) + var min_score uint = out.score + var best_score uint = out.score + var best_len uint = best_len_in + var cached_backward uint = uint(distance_cache[0]) + var prev_ix uint = cur_ix - cached_backward + var bucket []uint32 + out.len_code_delta = 0 + if prev_ix < cur_ix { + prev_ix &= uint(uint32(ring_buffer_mask)) + if compare_char == int(data[prev_ix+best_len]) { + var len uint = findMatchLengthWithLimit(data[prev_ix:], data[cur_ix_masked:], max_length) + if len >= 4 { + var score uint = backwardReferenceScoreUsingLastDistance(uint(len)) + if best_score < score { + best_score = score + best_len = uint(len) + out.len = uint(len) + out.distance = cached_backward + out.score = best_score + compare_char = int(data[cur_ix_masked+best_len]) + if h.bucketSweep == 1 { + h.buckets[key] = uint32(cur_ix) + return + } + } + } + } + } + + if h.bucketSweep == 1 { + var backward uint + var len uint + + /* Only one to look for, don't bother to prepare for a loop. */ + prev_ix = uint(h.buckets[key]) + + h.buckets[key] = uint32(cur_ix) + backward = cur_ix - prev_ix + prev_ix &= uint(uint32(ring_buffer_mask)) + if compare_char != int(data[prev_ix+best_len_in]) { + return + } + + if backward == 0 || backward > max_backward { + return + } + + len = findMatchLengthWithLimit(data[prev_ix:], data[cur_ix_masked:], max_length) + if len >= 4 { + var score uint = backwardReferenceScore(uint(len), backward) + if best_score < score { + out.len = uint(len) + out.distance = backward + out.score = score + return + } + } + } else { + bucket = h.buckets[key:] + var i int + prev_ix = uint(bucket[0]) + bucket = bucket[1:] + for i = 0; i < h.bucketSweep; (func() { i++; tmp3 := bucket; bucket = bucket[1:]; prev_ix = uint(tmp3[0]) })() { + var backward uint = cur_ix - prev_ix + var len uint + prev_ix &= uint(uint32(ring_buffer_mask)) + if compare_char != int(data[prev_ix+best_len]) { + continue + } + + if backward == 0 || backward > max_backward { + continue + } + + len = findMatchLengthWithLimit(data[prev_ix:], data[cur_ix_masked:], max_length) + if len >= 4 { + var score uint = backwardReferenceScore(uint(len), backward) + if best_score < score { + best_score = score + best_len = uint(len) + out.len = best_len + out.distance = backward + out.score = score + compare_char = int(data[cur_ix_masked+best_len]) + } + } + } + } + + if h.useDictionary && min_score == out.score { + searchInStaticDictionary(dictionary, h, data[cur_ix_masked:], max_length, max_backward+gap, max_distance, out, true) + } + + h.buckets[key+uint32((cur_ix>>3)%uint(h.bucketSweep))] = uint32(cur_ix) +} diff --git a/vendor/github.com/andybalholm/brotli/hash_rolling.go b/vendor/github.com/andybalholm/brotli/hash_rolling.go new file mode 100644 index 0000000..6630fc0 --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/hash_rolling.go @@ -0,0 +1,168 @@ +package brotli + +/* Copyright 2018 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* NOTE: this hasher does not search in the dictionary. It is used as + backup-hasher, the main hasher already searches in it. */ + +const kRollingHashMul32 uint32 = 69069 + +const kInvalidPosHashRolling uint32 = 0xffffffff + +/* This hasher uses a longer forward length, but returning a higher value here + will hurt compression by the main hasher when combined with a composite + hasher. The hasher tests for forward itself instead. */ +func (*hashRolling) HashTypeLength() uint { + return 4 +} + +func (*hashRolling) StoreLookahead() uint { + return 4 +} + +/* Computes a code from a single byte. A lookup table of 256 values could be + used, but simply adding 1 works about as good. */ +func (*hashRolling) HashByte(b byte) uint32 { + return uint32(b) + 1 +} + +func (h *hashRolling) HashRollingFunctionInitial(state uint32, add byte, factor uint32) uint32 { + return uint32(factor*state + h.HashByte(add)) +} + +func (h *hashRolling) HashRollingFunction(state uint32, add byte, rem byte, factor uint32, factor_remove uint32) uint32 { + return uint32(factor*state + h.HashByte(add) - factor_remove*h.HashByte(rem)) +} + +/* Rolling hash for long distance long string matches. Stores one position + per bucket, bucket key is computed over a long region. */ +type hashRolling struct { + hasherCommon + + jump int + + state uint32 + table []uint32 + next_ix uint + factor uint32 + factor_remove uint32 +} + +func (h *hashRolling) Initialize(params *encoderParams) { + h.state = 0 + h.next_ix = 0 + + h.factor = kRollingHashMul32 + + /* Compute the factor of the oldest byte to remove: factor**steps modulo + 0xffffffff (the multiplications rely on 32-bit overflow) */ + h.factor_remove = 1 + + for i := 0; i < 32; i += h.jump { + h.factor_remove *= h.factor + } + + h.table = make([]uint32, 16777216) + for i := 0; i < 16777216; i++ { + h.table[i] = kInvalidPosHashRolling + } +} + +func (h *hashRolling) Prepare(one_shot bool, input_size uint, data []byte) { + /* Too small size, cannot use this hasher. */ + if input_size < 32 { + return + } + h.state = 0 + for i := 0; i < 32; i += h.jump { + h.state = h.HashRollingFunctionInitial(h.state, data[i], h.factor) + } +} + +func (*hashRolling) Store(data []byte, mask uint, ix uint) { +} + +func (*hashRolling) StoreRange(data []byte, mask uint, ix_start uint, ix_end uint) { +} + +func (h *hashRolling) StitchToPreviousBlock(num_bytes uint, position uint, ringbuffer []byte, ring_buffer_mask uint) { + var position_masked uint + /* In this case we must re-initialize the hasher from scratch from the + current position. */ + + var available uint = num_bytes + if position&uint(h.jump-1) != 0 { + var diff uint = uint(h.jump) - (position & uint(h.jump-1)) + if diff > available { + available = 0 + } else { + available = available - diff + } + position += diff + } + + position_masked = position & ring_buffer_mask + + /* wrapping around ringbuffer not handled. */ + if available > ring_buffer_mask-position_masked { + available = ring_buffer_mask - position_masked + } + + h.Prepare(false, available, ringbuffer[position&ring_buffer_mask:]) + h.next_ix = position +} + +func (*hashRolling) PrepareDistanceCache(distance_cache []int) { +} + +func (h *hashRolling) FindLongestMatch(dictionary *encoderDictionary, data []byte, ring_buffer_mask uint, distance_cache []int, cur_ix uint, max_length uint, max_backward uint, gap uint, max_distance uint, out *hasherSearchResult) { + var cur_ix_masked uint = cur_ix & ring_buffer_mask + var pos uint = h.next_ix + + if cur_ix&uint(h.jump-1) != 0 { + return + } + + /* Not enough lookahead */ + if max_length < 32 { + return + } + + for pos = h.next_ix; pos <= cur_ix; pos += uint(h.jump) { + var code uint32 = h.state & ((16777216 * 64) - 1) + var rem byte = data[pos&ring_buffer_mask] + var add byte = data[(pos+32)&ring_buffer_mask] + var found_ix uint = uint(kInvalidPosHashRolling) + + h.state = h.HashRollingFunction(h.state, add, rem, h.factor, h.factor_remove) + + if code < 16777216 { + found_ix = uint(h.table[code]) + h.table[code] = uint32(pos) + if pos == cur_ix && uint32(found_ix) != kInvalidPosHashRolling { + /* The cast to 32-bit makes backward distances up to 4GB work even + if cur_ix is above 4GB, despite using 32-bit values in the table. */ + var backward uint = uint(uint32(cur_ix - found_ix)) + if backward <= max_backward { + var found_ix_masked uint = found_ix & ring_buffer_mask + var len uint = findMatchLengthWithLimit(data[found_ix_masked:], data[cur_ix_masked:], max_length) + if len >= 4 && len > out.len { + var score uint = backwardReferenceScore(uint(len), backward) + if score > out.score { + out.len = uint(len) + out.distance = backward + out.score = score + out.len_code_delta = 0 + } + } + } + } + } + } + + h.next_ix = cur_ix + uint(h.jump) +} diff --git a/vendor/github.com/andybalholm/brotli/histogram.go b/vendor/github.com/andybalholm/brotli/histogram.go new file mode 100644 index 0000000..0346622 --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/histogram.go @@ -0,0 +1,226 @@ +package brotli + +import "math" + +/* The distance symbols effectively used by "Large Window Brotli" (32-bit). */ +const numHistogramDistanceSymbols = 544 + +type histogramLiteral struct { + data_ [numLiteralSymbols]uint32 + total_count_ uint + bit_cost_ float64 +} + +func histogramClearLiteral(self *histogramLiteral) { + self.data_ = [numLiteralSymbols]uint32{} + self.total_count_ = 0 + self.bit_cost_ = math.MaxFloat64 +} + +func clearHistogramsLiteral(array []histogramLiteral, length uint) { + var i uint + for i = 0; i < length; i++ { + histogramClearLiteral(&array[i:][0]) + } +} + +func histogramAddLiteral(self *histogramLiteral, val uint) { + self.data_[val]++ + self.total_count_++ +} + +func histogramAddVectorLiteral(self *histogramLiteral, p []byte, n uint) { + self.total_count_ += n + n += 1 + for { + n-- + if n == 0 { + break + } + self.data_[p[0]]++ + p = p[1:] + } +} + +func histogramAddHistogramLiteral(self *histogramLiteral, v *histogramLiteral) { + var i uint + self.total_count_ += v.total_count_ + for i = 0; i < numLiteralSymbols; i++ { + self.data_[i] += v.data_[i] + } +} + +func histogramDataSizeLiteral() uint { + return numLiteralSymbols +} + +type histogramCommand struct { + data_ [numCommandSymbols]uint32 + total_count_ uint + bit_cost_ float64 +} + +func histogramClearCommand(self *histogramCommand) { + self.data_ = [numCommandSymbols]uint32{} + self.total_count_ = 0 + self.bit_cost_ = math.MaxFloat64 +} + +func clearHistogramsCommand(array []histogramCommand, length uint) { + var i uint + for i = 0; i < length; i++ { + histogramClearCommand(&array[i:][0]) + } +} + +func histogramAddCommand(self *histogramCommand, val uint) { + self.data_[val]++ + self.total_count_++ +} + +func histogramAddVectorCommand(self *histogramCommand, p []uint16, n uint) { + self.total_count_ += n + n += 1 + for { + n-- + if n == 0 { + break + } + self.data_[p[0]]++ + p = p[1:] + } +} + +func histogramAddHistogramCommand(self *histogramCommand, v *histogramCommand) { + var i uint + self.total_count_ += v.total_count_ + for i = 0; i < numCommandSymbols; i++ { + self.data_[i] += v.data_[i] + } +} + +func histogramDataSizeCommand() uint { + return numCommandSymbols +} + +type histogramDistance struct { + data_ [numDistanceSymbols]uint32 + total_count_ uint + bit_cost_ float64 +} + +func histogramClearDistance(self *histogramDistance) { + self.data_ = [numDistanceSymbols]uint32{} + self.total_count_ = 0 + self.bit_cost_ = math.MaxFloat64 +} + +func clearHistogramsDistance(array []histogramDistance, length uint) { + var i uint + for i = 0; i < length; i++ { + histogramClearDistance(&array[i:][0]) + } +} + +func histogramAddDistance(self *histogramDistance, val uint) { + self.data_[val]++ + self.total_count_++ +} + +func histogramAddVectorDistance(self *histogramDistance, p []uint16, n uint) { + self.total_count_ += n + n += 1 + for { + n-- + if n == 0 { + break + } + self.data_[p[0]]++ + p = p[1:] + } +} + +func histogramAddHistogramDistance(self *histogramDistance, v *histogramDistance) { + var i uint + self.total_count_ += v.total_count_ + for i = 0; i < numDistanceSymbols; i++ { + self.data_[i] += v.data_[i] + } +} + +func histogramDataSizeDistance() uint { + return numDistanceSymbols +} + +type blockSplitIterator struct { + split_ *blockSplit + idx_ uint + type_ uint + length_ uint +} + +func initBlockSplitIterator(self *blockSplitIterator, split *blockSplit) { + self.split_ = split + self.idx_ = 0 + self.type_ = 0 + if len(split.lengths) > 0 { + self.length_ = uint(split.lengths[0]) + } else { + self.length_ = 0 + } +} + +func blockSplitIteratorNext(self *blockSplitIterator) { + if self.length_ == 0 { + self.idx_++ + self.type_ = uint(self.split_.types[self.idx_]) + self.length_ = uint(self.split_.lengths[self.idx_]) + } + + self.length_-- +} + +func buildHistogramsWithContext(cmds []command, literal_split *blockSplit, insert_and_copy_split *blockSplit, dist_split *blockSplit, ringbuffer []byte, start_pos uint, mask uint, prev_byte byte, prev_byte2 byte, context_modes []int, literal_histograms []histogramLiteral, insert_and_copy_histograms []histogramCommand, copy_dist_histograms []histogramDistance) { + var pos uint = start_pos + var literal_it blockSplitIterator + var insert_and_copy_it blockSplitIterator + var dist_it blockSplitIterator + + initBlockSplitIterator(&literal_it, literal_split) + initBlockSplitIterator(&insert_and_copy_it, insert_and_copy_split) + initBlockSplitIterator(&dist_it, dist_split) + for i := range cmds { + var cmd *command = &cmds[i] + var j uint + blockSplitIteratorNext(&insert_and_copy_it) + histogramAddCommand(&insert_and_copy_histograms[insert_and_copy_it.type_], uint(cmd.cmd_prefix_)) + + /* TODO: unwrap iterator blocks. */ + for j = uint(cmd.insert_len_); j != 0; j-- { + var context uint + blockSplitIteratorNext(&literal_it) + context = literal_it.type_ + if context_modes != nil { + var lut contextLUT = getContextLUT(context_modes[context]) + context = (context << literalContextBits) + uint(getContext(prev_byte, prev_byte2, lut)) + } + + histogramAddLiteral(&literal_histograms[context], uint(ringbuffer[pos&mask])) + prev_byte2 = prev_byte + prev_byte = ringbuffer[pos&mask] + pos++ + } + + pos += uint(commandCopyLen(cmd)) + if commandCopyLen(cmd) != 0 { + prev_byte2 = ringbuffer[(pos-2)&mask] + prev_byte = ringbuffer[(pos-1)&mask] + if cmd.cmd_prefix_ >= 128 { + var context uint + blockSplitIteratorNext(&dist_it) + context = uint(uint32(dist_it.type_< bestQ && + (spec.Value == "*" || spec.Value == offer) { + bestQ = spec.Q + bestOffer = offer + } + } + } + if bestQ == 0 { + bestOffer = "" + } + return bestOffer +} + +// acceptSpec describes an Accept* header. +type acceptSpec struct { + Value string + Q float64 +} + +// parseAccept parses Accept* headers. +func parseAccept(header http.Header, key string) (specs []acceptSpec) { +loop: + for _, s := range header[key] { + for { + var spec acceptSpec + spec.Value, s = expectTokenSlash(s) + if spec.Value == "" { + continue loop + } + spec.Q = 1.0 + s = skipSpace(s) + if strings.HasPrefix(s, ";") { + s = skipSpace(s[1:]) + if !strings.HasPrefix(s, "q=") { + continue loop + } + spec.Q, s = expectQuality(s[2:]) + if spec.Q < 0.0 { + continue loop + } + } + specs = append(specs, spec) + s = skipSpace(s) + if !strings.HasPrefix(s, ",") { + continue loop + } + s = skipSpace(s[1:]) + } + } + return +} + +func skipSpace(s string) (rest string) { + i := 0 + for ; i < len(s); i++ { + if octetTypes[s[i]]&isSpace == 0 { + break + } + } + return s[i:] +} + +func expectTokenSlash(s string) (token, rest string) { + i := 0 + for ; i < len(s); i++ { + b := s[i] + if (octetTypes[b]&isToken == 0) && b != '/' { + break + } + } + return s[:i], s[i:] +} + +func expectQuality(s string) (q float64, rest string) { + switch { + case len(s) == 0: + return -1, "" + case s[0] == '0': + q = 0 + case s[0] == '1': + q = 1 + default: + return -1, "" + } + s = s[1:] + if !strings.HasPrefix(s, ".") { + return q, s + } + s = s[1:] + i := 0 + n := 0 + d := 1 + for ; i < len(s); i++ { + b := s[i] + if b < '0' || b > '9' { + break + } + n = n*10 + int(b) - '0' + d *= 10 + } + return q + float64(n)/float64(d), s[i:] +} + +// Octet types from RFC 2616. +var octetTypes [256]octetType + +type octetType byte + +const ( + isToken octetType = 1 << iota + isSpace +) + +func init() { + // OCTET = + // CHAR = + // CTL = + // CR = + // LF = + // SP = + // HT = + // <"> = + // CRLF = CR LF + // LWS = [CRLF] 1*( SP | HT ) + // TEXT = + // separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | <"> + // | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT + // token = 1* + // qdtext = > + + for c := 0; c < 256; c++ { + var t octetType + isCtl := c <= 31 || c == 127 + isChar := 0 <= c && c <= 127 + isSeparator := strings.ContainsRune(" \t\"(),/:;<=>?@[]\\{}", rune(c)) + if strings.ContainsRune(" \t\r\n", rune(c)) { + t |= isSpace + } + if isChar && !isCtl && !isSeparator { + t |= isToken + } + octetTypes[c] = t + } +} diff --git a/vendor/github.com/andybalholm/brotli/huffman.go b/vendor/github.com/andybalholm/brotli/huffman.go new file mode 100644 index 0000000..182f3d2 --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/huffman.go @@ -0,0 +1,653 @@ +package brotli + +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Utilities for building Huffman decoding tables. */ + +const huffmanMaxCodeLength = 15 + +/* Maximum possible Huffman table size for an alphabet size of (index * 32), + max code length 15 and root table bits 8. */ +var kMaxHuffmanTableSize = []uint16{ + 256, + 402, + 436, + 468, + 500, + 534, + 566, + 598, + 630, + 662, + 694, + 726, + 758, + 790, + 822, + 854, + 886, + 920, + 952, + 984, + 1016, + 1048, + 1080, + 1112, + 1144, + 1176, + 1208, + 1240, + 1272, + 1304, + 1336, + 1368, + 1400, + 1432, + 1464, + 1496, + 1528, +} + +/* BROTLI_NUM_BLOCK_LEN_SYMBOLS == 26 */ +const huffmanMaxSize26 = 396 + +/* BROTLI_MAX_BLOCK_TYPE_SYMBOLS == 258 */ +const huffmanMaxSize258 = 632 + +/* BROTLI_MAX_CONTEXT_MAP_SYMBOLS == 272 */ +const huffmanMaxSize272 = 646 + +const huffmanMaxCodeLengthCodeLength = 5 + +/* Do not create this struct directly - use the ConstructHuffmanCode + * constructor below! */ +type huffmanCode struct { + bits byte + value uint16 +} + +func constructHuffmanCode(bits byte, value uint16) huffmanCode { + var h huffmanCode + h.bits = bits + h.value = value + return h +} + +/* Builds Huffman lookup table assuming code lengths are in symbol order. */ + +/* Builds Huffman lookup table assuming code lengths are in symbol order. + Returns size of resulting table. */ + +/* Builds a simple Huffman table. The |num_symbols| parameter is to be + interpreted as follows: 0 means 1 symbol, 1 means 2 symbols, + 2 means 3 symbols, 3 means 4 symbols with lengths [2, 2, 2, 2], + 4 means 4 symbols with lengths [1, 2, 3, 3]. */ + +/* Contains a collection of Huffman trees with the same alphabet size. */ +/* max_symbol is needed due to simple codes since log2(alphabet_size) could be + greater than log2(max_symbol). */ +type huffmanTreeGroup struct { + htrees [][]huffmanCode + codes []huffmanCode + alphabet_size uint16 + max_symbol uint16 + num_htrees uint16 +} + +const reverseBitsMax = 8 + +const reverseBitsBase = 0 + +var kReverseBits = [1 << reverseBitsMax]byte{ + 0x00, + 0x80, + 0x40, + 0xC0, + 0x20, + 0xA0, + 0x60, + 0xE0, + 0x10, + 0x90, + 0x50, + 0xD0, + 0x30, + 0xB0, + 0x70, + 0xF0, + 0x08, + 0x88, + 0x48, + 0xC8, + 0x28, + 0xA8, + 0x68, + 0xE8, + 0x18, + 0x98, + 0x58, + 0xD8, + 0x38, + 0xB8, + 0x78, + 0xF8, + 0x04, + 0x84, + 0x44, + 0xC4, + 0x24, + 0xA4, + 0x64, + 0xE4, + 0x14, + 0x94, + 0x54, + 0xD4, + 0x34, + 0xB4, + 0x74, + 0xF4, + 0x0C, + 0x8C, + 0x4C, + 0xCC, + 0x2C, + 0xAC, + 0x6C, + 0xEC, + 0x1C, + 0x9C, + 0x5C, + 0xDC, + 0x3C, + 0xBC, + 0x7C, + 0xFC, + 0x02, + 0x82, + 0x42, + 0xC2, + 0x22, + 0xA2, + 0x62, + 0xE2, + 0x12, + 0x92, + 0x52, + 0xD2, + 0x32, + 0xB2, + 0x72, + 0xF2, + 0x0A, + 0x8A, + 0x4A, + 0xCA, + 0x2A, + 0xAA, + 0x6A, + 0xEA, + 0x1A, + 0x9A, + 0x5A, + 0xDA, + 0x3A, + 0xBA, + 0x7A, + 0xFA, + 0x06, + 0x86, + 0x46, + 0xC6, + 0x26, + 0xA6, + 0x66, + 0xE6, + 0x16, + 0x96, + 0x56, + 0xD6, + 0x36, + 0xB6, + 0x76, + 0xF6, + 0x0E, + 0x8E, + 0x4E, + 0xCE, + 0x2E, + 0xAE, + 0x6E, + 0xEE, + 0x1E, + 0x9E, + 0x5E, + 0xDE, + 0x3E, + 0xBE, + 0x7E, + 0xFE, + 0x01, + 0x81, + 0x41, + 0xC1, + 0x21, + 0xA1, + 0x61, + 0xE1, + 0x11, + 0x91, + 0x51, + 0xD1, + 0x31, + 0xB1, + 0x71, + 0xF1, + 0x09, + 0x89, + 0x49, + 0xC9, + 0x29, + 0xA9, + 0x69, + 0xE9, + 0x19, + 0x99, + 0x59, + 0xD9, + 0x39, + 0xB9, + 0x79, + 0xF9, + 0x05, + 0x85, + 0x45, + 0xC5, + 0x25, + 0xA5, + 0x65, + 0xE5, + 0x15, + 0x95, + 0x55, + 0xD5, + 0x35, + 0xB5, + 0x75, + 0xF5, + 0x0D, + 0x8D, + 0x4D, + 0xCD, + 0x2D, + 0xAD, + 0x6D, + 0xED, + 0x1D, + 0x9D, + 0x5D, + 0xDD, + 0x3D, + 0xBD, + 0x7D, + 0xFD, + 0x03, + 0x83, + 0x43, + 0xC3, + 0x23, + 0xA3, + 0x63, + 0xE3, + 0x13, + 0x93, + 0x53, + 0xD3, + 0x33, + 0xB3, + 0x73, + 0xF3, + 0x0B, + 0x8B, + 0x4B, + 0xCB, + 0x2B, + 0xAB, + 0x6B, + 0xEB, + 0x1B, + 0x9B, + 0x5B, + 0xDB, + 0x3B, + 0xBB, + 0x7B, + 0xFB, + 0x07, + 0x87, + 0x47, + 0xC7, + 0x27, + 0xA7, + 0x67, + 0xE7, + 0x17, + 0x97, + 0x57, + 0xD7, + 0x37, + 0xB7, + 0x77, + 0xF7, + 0x0F, + 0x8F, + 0x4F, + 0xCF, + 0x2F, + 0xAF, + 0x6F, + 0xEF, + 0x1F, + 0x9F, + 0x5F, + 0xDF, + 0x3F, + 0xBF, + 0x7F, + 0xFF, +} + +const reverseBitsLowest = (uint64(1) << (reverseBitsMax - 1 + reverseBitsBase)) + +/* Returns reverse(num >> BROTLI_REVERSE_BITS_BASE, BROTLI_REVERSE_BITS_MAX), + where reverse(value, len) is the bit-wise reversal of the len least + significant bits of value. */ +func reverseBits8(num uint64) uint64 { + return uint64(kReverseBits[num]) +} + +/* Stores code in table[0], table[step], table[2*step], ..., table[end] */ +/* Assumes that end is an integer multiple of step */ +func replicateValue(table []huffmanCode, step int, end int, code huffmanCode) { + for { + end -= step + table[end] = code + if end <= 0 { + break + } + } +} + +/* Returns the table width of the next 2nd level table. |count| is the histogram + of bit lengths for the remaining symbols, |len| is the code length of the + next processed symbol. */ +func nextTableBitSize(count []uint16, len int, root_bits int) int { + var left int = 1 << uint(len-root_bits) + for len < huffmanMaxCodeLength { + left -= int(count[len]) + if left <= 0 { + break + } + len++ + left <<= 1 + } + + return len - root_bits +} + +func buildCodeLengthsHuffmanTable(table []huffmanCode, code_lengths []byte, count []uint16) { + var code huffmanCode /* current table entry */ /* symbol index in original or sorted table */ /* prefix code */ /* prefix code addend */ /* step size to replicate values in current table */ /* size of current table */ /* symbols sorted by code length */ + var symbol int + var key uint64 + var key_step uint64 + var step int + var table_size int + var sorted [codeLengthCodes]int + var offset [huffmanMaxCodeLengthCodeLength + 1]int + var bits int + var bits_count int + /* offsets in sorted table for each length */ + assert(huffmanMaxCodeLengthCodeLength <= reverseBitsMax) + + /* Generate offsets into sorted symbol table by code length. */ + symbol = -1 + + bits = 1 + var i int + for i = 0; i < huffmanMaxCodeLengthCodeLength; i++ { + symbol += int(count[bits]) + offset[bits] = symbol + bits++ + } + + /* Symbols with code length 0 are placed after all other symbols. */ + offset[0] = codeLengthCodes - 1 + + /* Sort symbols by length, by symbol order within each length. */ + symbol = codeLengthCodes + + for { + var i int + for i = 0; i < 6; i++ { + symbol-- + sorted[offset[code_lengths[symbol]]] = symbol + offset[code_lengths[symbol]]-- + } + if symbol == 0 { + break + } + } + + table_size = 1 << huffmanMaxCodeLengthCodeLength + + /* Special case: all symbols but one have 0 code length. */ + if offset[0] == 0 { + code = constructHuffmanCode(0, uint16(sorted[0])) + for key = 0; key < uint64(table_size); key++ { + table[key] = code + } + + return + } + + /* Fill in table. */ + key = 0 + + key_step = reverseBitsLowest + symbol = 0 + bits = 1 + step = 2 + for { + for bits_count = int(count[bits]); bits_count != 0; bits_count-- { + code = constructHuffmanCode(byte(bits), uint16(sorted[symbol])) + symbol++ + replicateValue(table[reverseBits8(key):], step, table_size, code) + key += key_step + } + + step <<= 1 + key_step >>= 1 + bits++ + if bits > huffmanMaxCodeLengthCodeLength { + break + } + } +} + +func buildHuffmanTable(root_table []huffmanCode, root_bits int, symbol_lists symbolList, count []uint16) uint32 { + var code huffmanCode /* current table entry */ /* next available space in table */ /* current code length */ /* symbol index in original or sorted table */ /* prefix code */ /* prefix code addend */ /* 2nd level table prefix code */ /* 2nd level table prefix code addend */ /* step size to replicate values in current table */ /* key length of current table */ /* size of current table */ /* sum of root table size and 2nd level table sizes */ + var table []huffmanCode + var len int + var symbol int + var key uint64 + var key_step uint64 + var sub_key uint64 + var sub_key_step uint64 + var step int + var table_bits int + var table_size int + var total_size int + var max_length int = -1 + var bits int + var bits_count int + + assert(root_bits <= reverseBitsMax) + assert(huffmanMaxCodeLength-root_bits <= reverseBitsMax) + + for symbolListGet(symbol_lists, max_length) == 0xFFFF { + max_length-- + } + max_length += huffmanMaxCodeLength + 1 + + table = root_table + table_bits = root_bits + table_size = 1 << uint(table_bits) + total_size = table_size + + /* Fill in the root table. Reduce the table size to if possible, + and create the repetitions by memcpy. */ + if table_bits > max_length { + table_bits = max_length + table_size = 1 << uint(table_bits) + } + + key = 0 + key_step = reverseBitsLowest + bits = 1 + step = 2 + for { + symbol = bits - (huffmanMaxCodeLength + 1) + for bits_count = int(count[bits]); bits_count != 0; bits_count-- { + symbol = int(symbolListGet(symbol_lists, symbol)) + code = constructHuffmanCode(byte(bits), uint16(symbol)) + replicateValue(table[reverseBits8(key):], step, table_size, code) + key += key_step + } + + step <<= 1 + key_step >>= 1 + bits++ + if bits > table_bits { + break + } + } + + /* If root_bits != table_bits then replicate to fill the remaining slots. */ + for total_size != table_size { + copy(table[table_size:], table[:uint(table_size)]) + table_size <<= 1 + } + + /* Fill in 2nd level tables and add pointers to root table. */ + key_step = reverseBitsLowest >> uint(root_bits-1) + + sub_key = reverseBitsLowest << 1 + sub_key_step = reverseBitsLowest + len = root_bits + 1 + step = 2 + for ; len <= max_length; len++ { + symbol = len - (huffmanMaxCodeLength + 1) + for ; count[len] != 0; count[len]-- { + if sub_key == reverseBitsLowest<<1 { + table = table[table_size:] + table_bits = nextTableBitSize(count, int(len), root_bits) + table_size = 1 << uint(table_bits) + total_size += table_size + sub_key = reverseBits8(key) + key += key_step + root_table[sub_key] = constructHuffmanCode(byte(table_bits+root_bits), uint16(uint64(uint(-cap(table)+cap(root_table)))-sub_key)) + sub_key = 0 + } + + symbol = int(symbolListGet(symbol_lists, symbol)) + code = constructHuffmanCode(byte(len-root_bits), uint16(symbol)) + replicateValue(table[reverseBits8(sub_key):], step, table_size, code) + sub_key += sub_key_step + } + + step <<= 1 + sub_key_step >>= 1 + } + + return uint32(total_size) +} + +func buildSimpleHuffmanTable(table []huffmanCode, root_bits int, val []uint16, num_symbols uint32) uint32 { + var table_size uint32 = 1 + var goal_size uint32 = 1 << uint(root_bits) + switch num_symbols { + case 0: + table[0] = constructHuffmanCode(0, val[0]) + + case 1: + if val[1] > val[0] { + table[0] = constructHuffmanCode(1, val[0]) + table[1] = constructHuffmanCode(1, val[1]) + } else { + table[0] = constructHuffmanCode(1, val[1]) + table[1] = constructHuffmanCode(1, val[0]) + } + + table_size = 2 + + case 2: + table[0] = constructHuffmanCode(1, val[0]) + table[2] = constructHuffmanCode(1, val[0]) + if val[2] > val[1] { + table[1] = constructHuffmanCode(2, val[1]) + table[3] = constructHuffmanCode(2, val[2]) + } else { + table[1] = constructHuffmanCode(2, val[2]) + table[3] = constructHuffmanCode(2, val[1]) + } + + table_size = 4 + + case 3: + var i int + var k int + for i = 0; i < 3; i++ { + for k = i + 1; k < 4; k++ { + if val[k] < val[i] { + var t uint16 = val[k] + val[k] = val[i] + val[i] = t + } + } + } + + table[0] = constructHuffmanCode(2, val[0]) + table[2] = constructHuffmanCode(2, val[1]) + table[1] = constructHuffmanCode(2, val[2]) + table[3] = constructHuffmanCode(2, val[3]) + table_size = 4 + + case 4: + if val[3] < val[2] { + var t uint16 = val[3] + val[3] = val[2] + val[2] = t + } + + table[0] = constructHuffmanCode(1, val[0]) + table[1] = constructHuffmanCode(2, val[1]) + table[2] = constructHuffmanCode(1, val[0]) + table[3] = constructHuffmanCode(3, val[2]) + table[4] = constructHuffmanCode(1, val[0]) + table[5] = constructHuffmanCode(2, val[1]) + table[6] = constructHuffmanCode(1, val[0]) + table[7] = constructHuffmanCode(3, val[3]) + table_size = 8 + } + + for table_size != goal_size { + copy(table[table_size:], table[:uint(table_size)]) + table_size <<= 1 + } + + return goal_size +} diff --git a/vendor/github.com/andybalholm/brotli/literal_cost.go b/vendor/github.com/andybalholm/brotli/literal_cost.go new file mode 100644 index 0000000..5a9ace9 --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/literal_cost.go @@ -0,0 +1,182 @@ +package brotli + +func utf8Position(last uint, c uint, clamp uint) uint { + if c < 128 { + return 0 /* Next one is the 'Byte 1' again. */ + } else if c >= 192 { /* Next one is the 'Byte 2' of utf-8 encoding. */ + return brotli_min_size_t(1, clamp) + } else { + /* Let's decide over the last byte if this ends the sequence. */ + if last < 0xE0 { + return 0 /* Completed two or three byte coding. */ /* Next one is the 'Byte 3' of utf-8 encoding. */ + } else { + return brotli_min_size_t(2, clamp) + } + } +} + +func decideMultiByteStatsLevel(pos uint, len uint, mask uint, data []byte) uint { + var counts = [3]uint{0} /* should be 2, but 1 compresses better. */ + var max_utf8 uint = 1 + var last_c uint = 0 + var i uint + for i = 0; i < len; i++ { + var c uint = uint(data[(pos+i)&mask]) + counts[utf8Position(last_c, c, 2)]++ + last_c = c + } + + if counts[2] < 500 { + max_utf8 = 1 + } + + if counts[1]+counts[2] < 25 { + max_utf8 = 0 + } + + return max_utf8 +} + +func estimateBitCostsForLiteralsUTF8(pos uint, len uint, mask uint, data []byte, cost []float32) { + var max_utf8 uint = decideMultiByteStatsLevel(pos, uint(len), mask, data) + /* Bootstrap histograms. */ + var histogram = [3][256]uint{[256]uint{0}} + var window_half uint = 495 + var in_window uint = brotli_min_size_t(window_half, uint(len)) + var in_window_utf8 = [3]uint{0} + /* max_utf8 is 0 (normal ASCII single byte modeling), + 1 (for 2-byte UTF-8 modeling), or 2 (for 3-byte UTF-8 modeling). */ + + var i uint + { + var last_c uint = 0 + var utf8_pos uint = 0 + for i = 0; i < in_window; i++ { + var c uint = uint(data[(pos+i)&mask]) + histogram[utf8_pos][c]++ + in_window_utf8[utf8_pos]++ + utf8_pos = utf8Position(last_c, c, max_utf8) + last_c = c + } + } + + /* Compute bit costs with sliding window. */ + for i = 0; i < len; i++ { + if i >= window_half { + var c uint + var last_c uint + if i < window_half+1 { + c = 0 + } else { + c = uint(data[(pos+i-window_half-1)&mask]) + } + if i < window_half+2 { + last_c = 0 + } else { + last_c = uint(data[(pos+i-window_half-2)&mask]) + } + /* Remove a byte in the past. */ + + var utf8_pos2 uint = utf8Position(last_c, c, max_utf8) + histogram[utf8_pos2][data[(pos+i-window_half)&mask]]-- + in_window_utf8[utf8_pos2]-- + } + + if i+window_half < len { + var c uint = uint(data[(pos+i+window_half-1)&mask]) + var last_c uint = uint(data[(pos+i+window_half-2)&mask]) + /* Add a byte in the future. */ + + var utf8_pos2 uint = utf8Position(last_c, c, max_utf8) + histogram[utf8_pos2][data[(pos+i+window_half)&mask]]++ + in_window_utf8[utf8_pos2]++ + } + { + var c uint + var last_c uint + if i < 1 { + c = 0 + } else { + c = uint(data[(pos+i-1)&mask]) + } + if i < 2 { + last_c = 0 + } else { + last_c = uint(data[(pos+i-2)&mask]) + } + var utf8_pos uint = utf8Position(last_c, c, max_utf8) + var masked_pos uint = (pos + i) & mask + var histo uint = histogram[utf8_pos][data[masked_pos]] + var lit_cost float64 + if histo == 0 { + histo = 1 + } + + lit_cost = fastLog2(in_window_utf8[utf8_pos]) - fastLog2(histo) + lit_cost += 0.02905 + if lit_cost < 1.0 { + lit_cost *= 0.5 + lit_cost += 0.5 + } + + /* Make the first bytes more expensive -- seems to help, not sure why. + Perhaps because the entropy source is changing its properties + rapidly in the beginning of the file, perhaps because the beginning + of the data is a statistical "anomaly". */ + if i < 2000 { + lit_cost += 0.7 - (float64(2000-i) / 2000.0 * 0.35) + } + + cost[i] = float32(lit_cost) + } + } +} + +func estimateBitCostsForLiterals(pos uint, len uint, mask uint, data []byte, cost []float32) { + if isMostlyUTF8(data, pos, mask, uint(len), kMinUTF8Ratio) { + estimateBitCostsForLiteralsUTF8(pos, uint(len), mask, data, cost) + return + } else { + var histogram = [256]uint{0} + var window_half uint = 2000 + var in_window uint = brotli_min_size_t(window_half, uint(len)) + var i uint + /* Bootstrap histogram. */ + for i = 0; i < in_window; i++ { + histogram[data[(pos+i)&mask]]++ + } + + /* Compute bit costs with sliding window. */ + for i = 0; i < len; i++ { + var histo uint + if i >= window_half { + /* Remove a byte in the past. */ + histogram[data[(pos+i-window_half)&mask]]-- + + in_window-- + } + + if i+window_half < len { + /* Add a byte in the future. */ + histogram[data[(pos+i+window_half)&mask]]++ + + in_window++ + } + + histo = histogram[data[(pos+i)&mask]] + if histo == 0 { + histo = 1 + } + { + var lit_cost float64 = fastLog2(in_window) - fastLog2(histo) + lit_cost += 0.029 + if lit_cost < 1.0 { + lit_cost *= 0.5 + lit_cost += 0.5 + } + + cost[i] = float32(lit_cost) + } + } + } +} diff --git a/vendor/github.com/andybalholm/brotli/memory.go b/vendor/github.com/andybalholm/brotli/memory.go new file mode 100644 index 0000000..a07c705 --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/memory.go @@ -0,0 +1,66 @@ +package brotli + +/* Copyright 2016 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* +Dynamically grows array capacity to at least the requested size +T: data type +A: array +C: capacity +R: requested size +*/ +func brotli_ensure_capacity_uint8_t(a *[]byte, c *uint, r uint) { + if *c < r { + var new_size uint = *c + if new_size == 0 { + new_size = r + } + + for new_size < r { + new_size *= 2 + } + + if cap(*a) < int(new_size) { + var new_array []byte = make([]byte, new_size) + if *c != 0 { + copy(new_array, (*a)[:*c]) + } + + *a = new_array + } else { + *a = (*a)[:new_size] + } + + *c = new_size + } +} + +func brotli_ensure_capacity_uint32_t(a *[]uint32, c *uint, r uint) { + var new_array []uint32 + if *c < r { + var new_size uint = *c + if new_size == 0 { + new_size = r + } + + for new_size < r { + new_size *= 2 + } + + if cap(*a) < int(new_size) { + new_array = make([]uint32, new_size) + if *c != 0 { + copy(new_array, (*a)[:*c]) + } + + *a = new_array + } else { + *a = (*a)[:new_size] + } + *c = new_size + } +} diff --git a/vendor/github.com/andybalholm/brotli/metablock.go b/vendor/github.com/andybalholm/brotli/metablock.go new file mode 100644 index 0000000..3014df8 --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/metablock.go @@ -0,0 +1,574 @@ +package brotli + +import ( + "sync" +) + +/* Copyright 2014 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Algorithms for distributing the literals and commands of a metablock between + block types and contexts. */ + +type metaBlockSplit struct { + literal_split blockSplit + command_split blockSplit + distance_split blockSplit + literal_context_map []uint32 + literal_context_map_size uint + distance_context_map []uint32 + distance_context_map_size uint + literal_histograms []histogramLiteral + literal_histograms_size uint + command_histograms []histogramCommand + command_histograms_size uint + distance_histograms []histogramDistance + distance_histograms_size uint +} + +var metaBlockPool sync.Pool + +func getMetaBlockSplit() *metaBlockSplit { + mb, _ := metaBlockPool.Get().(*metaBlockSplit) + + if mb == nil { + mb = &metaBlockSplit{} + } else { + initBlockSplit(&mb.literal_split) + initBlockSplit(&mb.command_split) + initBlockSplit(&mb.distance_split) + mb.literal_context_map = mb.literal_context_map[:0] + mb.literal_context_map_size = 0 + mb.distance_context_map = mb.distance_context_map[:0] + mb.distance_context_map_size = 0 + mb.literal_histograms = mb.literal_histograms[:0] + mb.command_histograms = mb.command_histograms[:0] + mb.distance_histograms = mb.distance_histograms[:0] + } + return mb +} + +func freeMetaBlockSplit(mb *metaBlockSplit) { + metaBlockPool.Put(mb) +} + +func initDistanceParams(params *encoderParams, npostfix uint32, ndirect uint32) { + var dist_params *distanceParams = ¶ms.dist + var alphabet_size uint32 + var max_distance uint32 + + dist_params.distance_postfix_bits = npostfix + dist_params.num_direct_distance_codes = ndirect + + alphabet_size = uint32(distanceAlphabetSize(uint(npostfix), uint(ndirect), maxDistanceBits)) + max_distance = ndirect + (1 << (maxDistanceBits + npostfix + 2)) - (1 << (npostfix + 2)) + + if params.large_window { + var bound = [maxNpostfix + 1]uint32{0, 4, 12, 28} + var postfix uint32 = 1 << npostfix + alphabet_size = uint32(distanceAlphabetSize(uint(npostfix), uint(ndirect), largeMaxDistanceBits)) + + /* The maximum distance is set so that no distance symbol used can encode + a distance larger than BROTLI_MAX_ALLOWED_DISTANCE with all + its extra bits set. */ + if ndirect < bound[npostfix] { + max_distance = maxAllowedDistance - (bound[npostfix] - ndirect) + } else if ndirect >= bound[npostfix]+postfix { + max_distance = (3 << 29) - 4 + (ndirect - bound[npostfix]) + } else { + max_distance = maxAllowedDistance + } + } + + dist_params.alphabet_size = alphabet_size + dist_params.max_distance = uint(max_distance) +} + +func recomputeDistancePrefixes(cmds []command, orig_params *distanceParams, new_params *distanceParams) { + if orig_params.distance_postfix_bits == new_params.distance_postfix_bits && orig_params.num_direct_distance_codes == new_params.num_direct_distance_codes { + return + } + + for i := range cmds { + var cmd *command = &cmds[i] + if commandCopyLen(cmd) != 0 && cmd.cmd_prefix_ >= 128 { + prefixEncodeCopyDistance(uint(commandRestoreDistanceCode(cmd, orig_params)), uint(new_params.num_direct_distance_codes), uint(new_params.distance_postfix_bits), &cmd.dist_prefix_, &cmd.dist_extra_) + } + } +} + +func computeDistanceCost(cmds []command, orig_params *distanceParams, new_params *distanceParams, cost *float64) bool { + var equal_params bool = false + var dist_prefix uint16 + var dist_extra uint32 + var extra_bits float64 = 0.0 + var histo histogramDistance + histogramClearDistance(&histo) + + if orig_params.distance_postfix_bits == new_params.distance_postfix_bits && orig_params.num_direct_distance_codes == new_params.num_direct_distance_codes { + equal_params = true + } + + for i := range cmds { + cmd := &cmds[i] + if commandCopyLen(cmd) != 0 && cmd.cmd_prefix_ >= 128 { + if equal_params { + dist_prefix = cmd.dist_prefix_ + } else { + var distance uint32 = commandRestoreDistanceCode(cmd, orig_params) + if distance > uint32(new_params.max_distance) { + return false + } + + prefixEncodeCopyDistance(uint(distance), uint(new_params.num_direct_distance_codes), uint(new_params.distance_postfix_bits), &dist_prefix, &dist_extra) + } + + histogramAddDistance(&histo, uint(dist_prefix)&0x3FF) + extra_bits += float64(dist_prefix >> 10) + } + } + + *cost = populationCostDistance(&histo) + extra_bits + return true +} + +var buildMetaBlock_kMaxNumberOfHistograms uint = 256 + +func buildMetaBlock(ringbuffer []byte, pos uint, mask uint, params *encoderParams, prev_byte byte, prev_byte2 byte, cmds []command, literal_context_mode int, mb *metaBlockSplit) { + var distance_histograms []histogramDistance + var literal_histograms []histogramLiteral + var literal_context_modes []int = nil + var literal_histograms_size uint + var distance_histograms_size uint + var i uint + var literal_context_multiplier uint = 1 + var npostfix uint32 + var ndirect_msb uint32 = 0 + var check_orig bool = true + var best_dist_cost float64 = 1e99 + var orig_params encoderParams = *params + /* Histogram ids need to fit in one byte. */ + + var new_params encoderParams = *params + + for npostfix = 0; npostfix <= maxNpostfix; npostfix++ { + for ; ndirect_msb < 16; ndirect_msb++ { + var ndirect uint32 = ndirect_msb << npostfix + var skip bool + var dist_cost float64 + initDistanceParams(&new_params, npostfix, ndirect) + if npostfix == orig_params.dist.distance_postfix_bits && ndirect == orig_params.dist.num_direct_distance_codes { + check_orig = false + } + + skip = !computeDistanceCost(cmds, &orig_params.dist, &new_params.dist, &dist_cost) + if skip || (dist_cost > best_dist_cost) { + break + } + + best_dist_cost = dist_cost + params.dist = new_params.dist + } + + if ndirect_msb > 0 { + ndirect_msb-- + } + ndirect_msb /= 2 + } + + if check_orig { + var dist_cost float64 + computeDistanceCost(cmds, &orig_params.dist, &orig_params.dist, &dist_cost) + if dist_cost < best_dist_cost { + /* NB: currently unused; uncomment when more param tuning is added. */ + /* best_dist_cost = dist_cost; */ + params.dist = orig_params.dist + } + } + + recomputeDistancePrefixes(cmds, &orig_params.dist, ¶ms.dist) + + splitBlock(cmds, ringbuffer, pos, mask, params, &mb.literal_split, &mb.command_split, &mb.distance_split) + + if !params.disable_literal_context_modeling { + literal_context_multiplier = 1 << literalContextBits + literal_context_modes = make([]int, (mb.literal_split.num_types)) + for i = 0; i < mb.literal_split.num_types; i++ { + literal_context_modes[i] = literal_context_mode + } + } + + literal_histograms_size = mb.literal_split.num_types * literal_context_multiplier + literal_histograms = make([]histogramLiteral, literal_histograms_size) + clearHistogramsLiteral(literal_histograms, literal_histograms_size) + + distance_histograms_size = mb.distance_split.num_types << distanceContextBits + distance_histograms = make([]histogramDistance, distance_histograms_size) + clearHistogramsDistance(distance_histograms, distance_histograms_size) + + mb.command_histograms_size = mb.command_split.num_types + if cap(mb.command_histograms) < int(mb.command_histograms_size) { + mb.command_histograms = make([]histogramCommand, (mb.command_histograms_size)) + } else { + mb.command_histograms = mb.command_histograms[:mb.command_histograms_size] + } + clearHistogramsCommand(mb.command_histograms, mb.command_histograms_size) + + buildHistogramsWithContext(cmds, &mb.literal_split, &mb.command_split, &mb.distance_split, ringbuffer, pos, mask, prev_byte, prev_byte2, literal_context_modes, literal_histograms, mb.command_histograms, distance_histograms) + literal_context_modes = nil + + mb.literal_context_map_size = mb.literal_split.num_types << literalContextBits + if cap(mb.literal_context_map) < int(mb.literal_context_map_size) { + mb.literal_context_map = make([]uint32, (mb.literal_context_map_size)) + } else { + mb.literal_context_map = mb.literal_context_map[:mb.literal_context_map_size] + } + + mb.literal_histograms_size = mb.literal_context_map_size + if cap(mb.literal_histograms) < int(mb.literal_histograms_size) { + mb.literal_histograms = make([]histogramLiteral, (mb.literal_histograms_size)) + } else { + mb.literal_histograms = mb.literal_histograms[:mb.literal_histograms_size] + } + + clusterHistogramsLiteral(literal_histograms, literal_histograms_size, buildMetaBlock_kMaxNumberOfHistograms, mb.literal_histograms, &mb.literal_histograms_size, mb.literal_context_map) + literal_histograms = nil + + if params.disable_literal_context_modeling { + /* Distribute assignment to all contexts. */ + for i = mb.literal_split.num_types; i != 0; { + var j uint = 0 + i-- + for ; j < 1< 0 { + var entropy [maxStaticContexts]float64 + var combined_histo []histogramLiteral = make([]histogramLiteral, (2 * num_contexts)) + var combined_entropy [2 * maxStaticContexts]float64 + var diff = [2]float64{0.0} + /* Try merging the set of histograms for the current block type with the + respective set of histograms for the last and second last block types. + Decide over the split based on the total reduction of entropy across + all contexts. */ + + var i uint + for i = 0; i < num_contexts; i++ { + var curr_histo_ix uint = self.curr_histogram_ix_ + i + var j uint + entropy[i] = bitsEntropy(histograms[curr_histo_ix].data_[:], self.alphabet_size_) + for j = 0; j < 2; j++ { + var jx uint = j*num_contexts + i + var last_histogram_ix uint = self.last_histogram_ix_[j] + i + combined_histo[jx] = histograms[curr_histo_ix] + histogramAddHistogramLiteral(&combined_histo[jx], &histograms[last_histogram_ix]) + combined_entropy[jx] = bitsEntropy(combined_histo[jx].data_[0:], self.alphabet_size_) + diff[j] += combined_entropy[jx] - entropy[i] - last_entropy[jx] + } + } + + if split.num_types < self.max_block_types_ && diff[0] > self.split_threshold_ && diff[1] > self.split_threshold_ { + /* Create new block. */ + split.lengths[self.num_blocks_] = uint32(self.block_size_) + + split.types[self.num_blocks_] = byte(split.num_types) + self.last_histogram_ix_[1] = self.last_histogram_ix_[0] + self.last_histogram_ix_[0] = split.num_types * num_contexts + for i = 0; i < num_contexts; i++ { + last_entropy[num_contexts+i] = last_entropy[i] + last_entropy[i] = entropy[i] + } + + self.num_blocks_++ + split.num_types++ + self.curr_histogram_ix_ += num_contexts + if self.curr_histogram_ix_ < *self.histograms_size_ { + clearHistogramsLiteral(self.histograms_[self.curr_histogram_ix_:], self.num_contexts_) + } + + self.block_size_ = 0 + self.merge_last_count_ = 0 + self.target_block_size_ = self.min_block_size_ + } else if diff[1] < diff[0]-20.0 { + split.lengths[self.num_blocks_] = uint32(self.block_size_) + split.types[self.num_blocks_] = split.types[self.num_blocks_-2] + /* Combine this block with second last block. */ + + var tmp uint = self.last_histogram_ix_[0] + self.last_histogram_ix_[0] = self.last_histogram_ix_[1] + self.last_histogram_ix_[1] = tmp + for i = 0; i < num_contexts; i++ { + histograms[self.last_histogram_ix_[0]+i] = combined_histo[num_contexts+i] + last_entropy[num_contexts+i] = last_entropy[i] + last_entropy[i] = combined_entropy[num_contexts+i] + histogramClearLiteral(&histograms[self.curr_histogram_ix_+i]) + } + + self.num_blocks_++ + self.block_size_ = 0 + self.merge_last_count_ = 0 + self.target_block_size_ = self.min_block_size_ + } else { + /* Combine this block with last block. */ + split.lengths[self.num_blocks_-1] += uint32(self.block_size_) + + for i = 0; i < num_contexts; i++ { + histograms[self.last_histogram_ix_[0]+i] = combined_histo[i] + last_entropy[i] = combined_entropy[i] + if split.num_types == 1 { + last_entropy[num_contexts+i] = last_entropy[i] + } + + histogramClearLiteral(&histograms[self.curr_histogram_ix_+i]) + } + + self.block_size_ = 0 + self.merge_last_count_++ + if self.merge_last_count_ > 1 { + self.target_block_size_ += self.min_block_size_ + } + } + + combined_histo = nil + } + + if is_final { + *self.histograms_size_ = split.num_types * num_contexts + split.num_blocks = self.num_blocks_ + } +} + +/* Adds the next symbol to the current block type and context. When the + current block reaches the target size, decides on merging the block. */ +func contextBlockSplitterAddSymbol(self *contextBlockSplitter, symbol uint, context uint) { + histogramAddLiteral(&self.histograms_[self.curr_histogram_ix_+context], symbol) + self.block_size_++ + if self.block_size_ == self.target_block_size_ { + contextBlockSplitterFinishBlock(self, false) /* is_final = */ + } +} + +func mapStaticContexts(num_contexts uint, static_context_map []uint32, mb *metaBlockSplit) { + var i uint + mb.literal_context_map_size = mb.literal_split.num_types << literalContextBits + if cap(mb.literal_context_map) < int(mb.literal_context_map_size) { + mb.literal_context_map = make([]uint32, (mb.literal_context_map_size)) + } else { + mb.literal_context_map = mb.literal_context_map[:mb.literal_context_map_size] + } + + for i = 0; i < mb.literal_split.num_types; i++ { + var offset uint32 = uint32(i * num_contexts) + var j uint + for j = 0; j < 1<= 128 { + blockSplitterAddSymbolDistance(&dist_blocks, uint(cmd.dist_prefix_)&0x3FF) + } + } + } + + if num_contexts == 1 { + blockSplitterFinishBlockLiteral(&lit_blocks.plain, true) /* is_final = */ + } else { + contextBlockSplitterFinishBlock(&lit_blocks.ctx, true) /* is_final = */ + } + + blockSplitterFinishBlockCommand(&cmd_blocks, true) /* is_final = */ + blockSplitterFinishBlockDistance(&dist_blocks, true) /* is_final = */ + + if num_contexts > 1 { + mapStaticContexts(num_contexts, static_context_map, mb) + } +} + +func buildMetaBlockGreedy(ringbuffer []byte, pos uint, mask uint, prev_byte byte, prev_byte2 byte, literal_context_lut contextLUT, num_contexts uint, static_context_map []uint32, commands []command, mb *metaBlockSplit) { + if num_contexts == 1 { + buildMetaBlockGreedyInternal(ringbuffer, pos, mask, prev_byte, prev_byte2, literal_context_lut, 1, nil, commands, mb) + } else { + buildMetaBlockGreedyInternal(ringbuffer, pos, mask, prev_byte, prev_byte2, literal_context_lut, num_contexts, static_context_map, commands, mb) + } +} + +func optimizeHistograms(num_distance_codes uint32, mb *metaBlockSplit) { + var good_for_rle [numCommandSymbols]byte + var i uint + for i = 0; i < mb.literal_histograms_size; i++ { + optimizeHuffmanCountsForRLE(256, mb.literal_histograms[i].data_[:], good_for_rle[:]) + } + + for i = 0; i < mb.command_histograms_size; i++ { + optimizeHuffmanCountsForRLE(numCommandSymbols, mb.command_histograms[i].data_[:], good_for_rle[:]) + } + + for i = 0; i < mb.distance_histograms_size; i++ { + optimizeHuffmanCountsForRLE(uint(num_distance_codes), mb.distance_histograms[i].data_[:], good_for_rle[:]) + } +} diff --git a/vendor/github.com/andybalholm/brotli/metablock_command.go b/vendor/github.com/andybalholm/brotli/metablock_command.go new file mode 100644 index 0000000..14c7b77 --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/metablock_command.go @@ -0,0 +1,165 @@ +package brotli + +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Greedy block splitter for one block category (literal, command or distance). + */ +type blockSplitterCommand struct { + alphabet_size_ uint + min_block_size_ uint + split_threshold_ float64 + num_blocks_ uint + split_ *blockSplit + histograms_ []histogramCommand + histograms_size_ *uint + target_block_size_ uint + block_size_ uint + curr_histogram_ix_ uint + last_histogram_ix_ [2]uint + last_entropy_ [2]float64 + merge_last_count_ uint +} + +func initBlockSplitterCommand(self *blockSplitterCommand, alphabet_size uint, min_block_size uint, split_threshold float64, num_symbols uint, split *blockSplit, histograms *[]histogramCommand, histograms_size *uint) { + var max_num_blocks uint = num_symbols/min_block_size + 1 + var max_num_types uint = brotli_min_size_t(max_num_blocks, maxNumberOfBlockTypes+1) + /* We have to allocate one more histogram than the maximum number of block + types for the current histogram when the meta-block is too big. */ + self.alphabet_size_ = alphabet_size + + self.min_block_size_ = min_block_size + self.split_threshold_ = split_threshold + self.num_blocks_ = 0 + self.split_ = split + self.histograms_size_ = histograms_size + self.target_block_size_ = min_block_size + self.block_size_ = 0 + self.curr_histogram_ix_ = 0 + self.merge_last_count_ = 0 + brotli_ensure_capacity_uint8_t(&split.types, &split.types_alloc_size, max_num_blocks) + brotli_ensure_capacity_uint32_t(&split.lengths, &split.lengths_alloc_size, max_num_blocks) + self.split_.num_blocks = max_num_blocks + *histograms_size = max_num_types + if histograms == nil || cap(*histograms) < int(*histograms_size) { + *histograms = make([]histogramCommand, (*histograms_size)) + } else { + *histograms = (*histograms)[:*histograms_size] + } + self.histograms_ = *histograms + + /* Clear only current histogram. */ + histogramClearCommand(&self.histograms_[0]) + + self.last_histogram_ix_[1] = 0 + self.last_histogram_ix_[0] = self.last_histogram_ix_[1] +} + +/* Does either of three things: + (1) emits the current block with a new block type; + (2) emits the current block with the type of the second last block; + (3) merges the current block with the last block. */ +func blockSplitterFinishBlockCommand(self *blockSplitterCommand, is_final bool) { + var split *blockSplit = self.split_ + var last_entropy []float64 = self.last_entropy_[:] + var histograms []histogramCommand = self.histograms_ + self.block_size_ = brotli_max_size_t(self.block_size_, self.min_block_size_) + if self.num_blocks_ == 0 { + /* Create first block. */ + split.lengths[0] = uint32(self.block_size_) + + split.types[0] = 0 + last_entropy[0] = bitsEntropy(histograms[0].data_[:], self.alphabet_size_) + last_entropy[1] = last_entropy[0] + self.num_blocks_++ + split.num_types++ + self.curr_histogram_ix_++ + if self.curr_histogram_ix_ < *self.histograms_size_ { + histogramClearCommand(&histograms[self.curr_histogram_ix_]) + } + self.block_size_ = 0 + } else if self.block_size_ > 0 { + var entropy float64 = bitsEntropy(histograms[self.curr_histogram_ix_].data_[:], self.alphabet_size_) + var combined_histo [2]histogramCommand + var combined_entropy [2]float64 + var diff [2]float64 + var j uint + for j = 0; j < 2; j++ { + var last_histogram_ix uint = self.last_histogram_ix_[j] + combined_histo[j] = histograms[self.curr_histogram_ix_] + histogramAddHistogramCommand(&combined_histo[j], &histograms[last_histogram_ix]) + combined_entropy[j] = bitsEntropy(combined_histo[j].data_[0:], self.alphabet_size_) + diff[j] = combined_entropy[j] - entropy - last_entropy[j] + } + + if split.num_types < maxNumberOfBlockTypes && diff[0] > self.split_threshold_ && diff[1] > self.split_threshold_ { + /* Create new block. */ + split.lengths[self.num_blocks_] = uint32(self.block_size_) + + split.types[self.num_blocks_] = byte(split.num_types) + self.last_histogram_ix_[1] = self.last_histogram_ix_[0] + self.last_histogram_ix_[0] = uint(byte(split.num_types)) + last_entropy[1] = last_entropy[0] + last_entropy[0] = entropy + self.num_blocks_++ + split.num_types++ + self.curr_histogram_ix_++ + if self.curr_histogram_ix_ < *self.histograms_size_ { + histogramClearCommand(&histograms[self.curr_histogram_ix_]) + } + self.block_size_ = 0 + self.merge_last_count_ = 0 + self.target_block_size_ = self.min_block_size_ + } else if diff[1] < diff[0]-20.0 { + split.lengths[self.num_blocks_] = uint32(self.block_size_) + split.types[self.num_blocks_] = split.types[self.num_blocks_-2] + /* Combine this block with second last block. */ + + var tmp uint = self.last_histogram_ix_[0] + self.last_histogram_ix_[0] = self.last_histogram_ix_[1] + self.last_histogram_ix_[1] = tmp + histograms[self.last_histogram_ix_[0]] = combined_histo[1] + last_entropy[1] = last_entropy[0] + last_entropy[0] = combined_entropy[1] + self.num_blocks_++ + self.block_size_ = 0 + histogramClearCommand(&histograms[self.curr_histogram_ix_]) + self.merge_last_count_ = 0 + self.target_block_size_ = self.min_block_size_ + } else { + /* Combine this block with last block. */ + split.lengths[self.num_blocks_-1] += uint32(self.block_size_) + + histograms[self.last_histogram_ix_[0]] = combined_histo[0] + last_entropy[0] = combined_entropy[0] + if split.num_types == 1 { + last_entropy[1] = last_entropy[0] + } + + self.block_size_ = 0 + histogramClearCommand(&histograms[self.curr_histogram_ix_]) + self.merge_last_count_++ + if self.merge_last_count_ > 1 { + self.target_block_size_ += self.min_block_size_ + } + } + } + + if is_final { + *self.histograms_size_ = split.num_types + split.num_blocks = self.num_blocks_ + } +} + +/* Adds the next symbol to the current histogram. When the current histogram + reaches the target size, decides on merging the block. */ +func blockSplitterAddSymbolCommand(self *blockSplitterCommand, symbol uint) { + histogramAddCommand(&self.histograms_[self.curr_histogram_ix_], symbol) + self.block_size_++ + if self.block_size_ == self.target_block_size_ { + blockSplitterFinishBlockCommand(self, false) /* is_final = */ + } +} diff --git a/vendor/github.com/andybalholm/brotli/metablock_distance.go b/vendor/github.com/andybalholm/brotli/metablock_distance.go new file mode 100644 index 0000000..5110a81 --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/metablock_distance.go @@ -0,0 +1,165 @@ +package brotli + +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Greedy block splitter for one block category (literal, command or distance). + */ +type blockSplitterDistance struct { + alphabet_size_ uint + min_block_size_ uint + split_threshold_ float64 + num_blocks_ uint + split_ *blockSplit + histograms_ []histogramDistance + histograms_size_ *uint + target_block_size_ uint + block_size_ uint + curr_histogram_ix_ uint + last_histogram_ix_ [2]uint + last_entropy_ [2]float64 + merge_last_count_ uint +} + +func initBlockSplitterDistance(self *blockSplitterDistance, alphabet_size uint, min_block_size uint, split_threshold float64, num_symbols uint, split *blockSplit, histograms *[]histogramDistance, histograms_size *uint) { + var max_num_blocks uint = num_symbols/min_block_size + 1 + var max_num_types uint = brotli_min_size_t(max_num_blocks, maxNumberOfBlockTypes+1) + /* We have to allocate one more histogram than the maximum number of block + types for the current histogram when the meta-block is too big. */ + self.alphabet_size_ = alphabet_size + + self.min_block_size_ = min_block_size + self.split_threshold_ = split_threshold + self.num_blocks_ = 0 + self.split_ = split + self.histograms_size_ = histograms_size + self.target_block_size_ = min_block_size + self.block_size_ = 0 + self.curr_histogram_ix_ = 0 + self.merge_last_count_ = 0 + brotli_ensure_capacity_uint8_t(&split.types, &split.types_alloc_size, max_num_blocks) + brotli_ensure_capacity_uint32_t(&split.lengths, &split.lengths_alloc_size, max_num_blocks) + self.split_.num_blocks = max_num_blocks + *histograms_size = max_num_types + if histograms == nil || cap(*histograms) < int(*histograms_size) { + *histograms = make([]histogramDistance, *histograms_size) + } else { + *histograms = (*histograms)[:*histograms_size] + } + self.histograms_ = *histograms + + /* Clear only current histogram. */ + histogramClearDistance(&self.histograms_[0]) + + self.last_histogram_ix_[1] = 0 + self.last_histogram_ix_[0] = self.last_histogram_ix_[1] +} + +/* Does either of three things: + (1) emits the current block with a new block type; + (2) emits the current block with the type of the second last block; + (3) merges the current block with the last block. */ +func blockSplitterFinishBlockDistance(self *blockSplitterDistance, is_final bool) { + var split *blockSplit = self.split_ + var last_entropy []float64 = self.last_entropy_[:] + var histograms []histogramDistance = self.histograms_ + self.block_size_ = brotli_max_size_t(self.block_size_, self.min_block_size_) + if self.num_blocks_ == 0 { + /* Create first block. */ + split.lengths[0] = uint32(self.block_size_) + + split.types[0] = 0 + last_entropy[0] = bitsEntropy(histograms[0].data_[:], self.alphabet_size_) + last_entropy[1] = last_entropy[0] + self.num_blocks_++ + split.num_types++ + self.curr_histogram_ix_++ + if self.curr_histogram_ix_ < *self.histograms_size_ { + histogramClearDistance(&histograms[self.curr_histogram_ix_]) + } + self.block_size_ = 0 + } else if self.block_size_ > 0 { + var entropy float64 = bitsEntropy(histograms[self.curr_histogram_ix_].data_[:], self.alphabet_size_) + var combined_histo [2]histogramDistance + var combined_entropy [2]float64 + var diff [2]float64 + var j uint + for j = 0; j < 2; j++ { + var last_histogram_ix uint = self.last_histogram_ix_[j] + combined_histo[j] = histograms[self.curr_histogram_ix_] + histogramAddHistogramDistance(&combined_histo[j], &histograms[last_histogram_ix]) + combined_entropy[j] = bitsEntropy(combined_histo[j].data_[0:], self.alphabet_size_) + diff[j] = combined_entropy[j] - entropy - last_entropy[j] + } + + if split.num_types < maxNumberOfBlockTypes && diff[0] > self.split_threshold_ && diff[1] > self.split_threshold_ { + /* Create new block. */ + split.lengths[self.num_blocks_] = uint32(self.block_size_) + + split.types[self.num_blocks_] = byte(split.num_types) + self.last_histogram_ix_[1] = self.last_histogram_ix_[0] + self.last_histogram_ix_[0] = uint(byte(split.num_types)) + last_entropy[1] = last_entropy[0] + last_entropy[0] = entropy + self.num_blocks_++ + split.num_types++ + self.curr_histogram_ix_++ + if self.curr_histogram_ix_ < *self.histograms_size_ { + histogramClearDistance(&histograms[self.curr_histogram_ix_]) + } + self.block_size_ = 0 + self.merge_last_count_ = 0 + self.target_block_size_ = self.min_block_size_ + } else if diff[1] < diff[0]-20.0 { + split.lengths[self.num_blocks_] = uint32(self.block_size_) + split.types[self.num_blocks_] = split.types[self.num_blocks_-2] + /* Combine this block with second last block. */ + + var tmp uint = self.last_histogram_ix_[0] + self.last_histogram_ix_[0] = self.last_histogram_ix_[1] + self.last_histogram_ix_[1] = tmp + histograms[self.last_histogram_ix_[0]] = combined_histo[1] + last_entropy[1] = last_entropy[0] + last_entropy[0] = combined_entropy[1] + self.num_blocks_++ + self.block_size_ = 0 + histogramClearDistance(&histograms[self.curr_histogram_ix_]) + self.merge_last_count_ = 0 + self.target_block_size_ = self.min_block_size_ + } else { + /* Combine this block with last block. */ + split.lengths[self.num_blocks_-1] += uint32(self.block_size_) + + histograms[self.last_histogram_ix_[0]] = combined_histo[0] + last_entropy[0] = combined_entropy[0] + if split.num_types == 1 { + last_entropy[1] = last_entropy[0] + } + + self.block_size_ = 0 + histogramClearDistance(&histograms[self.curr_histogram_ix_]) + self.merge_last_count_++ + if self.merge_last_count_ > 1 { + self.target_block_size_ += self.min_block_size_ + } + } + } + + if is_final { + *self.histograms_size_ = split.num_types + split.num_blocks = self.num_blocks_ + } +} + +/* Adds the next symbol to the current histogram. When the current histogram + reaches the target size, decides on merging the block. */ +func blockSplitterAddSymbolDistance(self *blockSplitterDistance, symbol uint) { + histogramAddDistance(&self.histograms_[self.curr_histogram_ix_], symbol) + self.block_size_++ + if self.block_size_ == self.target_block_size_ { + blockSplitterFinishBlockDistance(self, false) /* is_final = */ + } +} diff --git a/vendor/github.com/andybalholm/brotli/metablock_literal.go b/vendor/github.com/andybalholm/brotli/metablock_literal.go new file mode 100644 index 0000000..307f8da --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/metablock_literal.go @@ -0,0 +1,165 @@ +package brotli + +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Greedy block splitter for one block category (literal, command or distance). + */ +type blockSplitterLiteral struct { + alphabet_size_ uint + min_block_size_ uint + split_threshold_ float64 + num_blocks_ uint + split_ *blockSplit + histograms_ []histogramLiteral + histograms_size_ *uint + target_block_size_ uint + block_size_ uint + curr_histogram_ix_ uint + last_histogram_ix_ [2]uint + last_entropy_ [2]float64 + merge_last_count_ uint +} + +func initBlockSplitterLiteral(self *blockSplitterLiteral, alphabet_size uint, min_block_size uint, split_threshold float64, num_symbols uint, split *blockSplit, histograms *[]histogramLiteral, histograms_size *uint) { + var max_num_blocks uint = num_symbols/min_block_size + 1 + var max_num_types uint = brotli_min_size_t(max_num_blocks, maxNumberOfBlockTypes+1) + /* We have to allocate one more histogram than the maximum number of block + types for the current histogram when the meta-block is too big. */ + self.alphabet_size_ = alphabet_size + + self.min_block_size_ = min_block_size + self.split_threshold_ = split_threshold + self.num_blocks_ = 0 + self.split_ = split + self.histograms_size_ = histograms_size + self.target_block_size_ = min_block_size + self.block_size_ = 0 + self.curr_histogram_ix_ = 0 + self.merge_last_count_ = 0 + brotli_ensure_capacity_uint8_t(&split.types, &split.types_alloc_size, max_num_blocks) + brotli_ensure_capacity_uint32_t(&split.lengths, &split.lengths_alloc_size, max_num_blocks) + self.split_.num_blocks = max_num_blocks + *histograms_size = max_num_types + if histograms == nil || cap(*histograms) < int(*histograms_size) { + *histograms = make([]histogramLiteral, *histograms_size) + } else { + *histograms = (*histograms)[:*histograms_size] + } + self.histograms_ = *histograms + + /* Clear only current histogram. */ + histogramClearLiteral(&self.histograms_[0]) + + self.last_histogram_ix_[1] = 0 + self.last_histogram_ix_[0] = self.last_histogram_ix_[1] +} + +/* Does either of three things: + (1) emits the current block with a new block type; + (2) emits the current block with the type of the second last block; + (3) merges the current block with the last block. */ +func blockSplitterFinishBlockLiteral(self *blockSplitterLiteral, is_final bool) { + var split *blockSplit = self.split_ + var last_entropy []float64 = self.last_entropy_[:] + var histograms []histogramLiteral = self.histograms_ + self.block_size_ = brotli_max_size_t(self.block_size_, self.min_block_size_) + if self.num_blocks_ == 0 { + /* Create first block. */ + split.lengths[0] = uint32(self.block_size_) + + split.types[0] = 0 + last_entropy[0] = bitsEntropy(histograms[0].data_[:], self.alphabet_size_) + last_entropy[1] = last_entropy[0] + self.num_blocks_++ + split.num_types++ + self.curr_histogram_ix_++ + if self.curr_histogram_ix_ < *self.histograms_size_ { + histogramClearLiteral(&histograms[self.curr_histogram_ix_]) + } + self.block_size_ = 0 + } else if self.block_size_ > 0 { + var entropy float64 = bitsEntropy(histograms[self.curr_histogram_ix_].data_[:], self.alphabet_size_) + var combined_histo [2]histogramLiteral + var combined_entropy [2]float64 + var diff [2]float64 + var j uint + for j = 0; j < 2; j++ { + var last_histogram_ix uint = self.last_histogram_ix_[j] + combined_histo[j] = histograms[self.curr_histogram_ix_] + histogramAddHistogramLiteral(&combined_histo[j], &histograms[last_histogram_ix]) + combined_entropy[j] = bitsEntropy(combined_histo[j].data_[0:], self.alphabet_size_) + diff[j] = combined_entropy[j] - entropy - last_entropy[j] + } + + if split.num_types < maxNumberOfBlockTypes && diff[0] > self.split_threshold_ && diff[1] > self.split_threshold_ { + /* Create new block. */ + split.lengths[self.num_blocks_] = uint32(self.block_size_) + + split.types[self.num_blocks_] = byte(split.num_types) + self.last_histogram_ix_[1] = self.last_histogram_ix_[0] + self.last_histogram_ix_[0] = uint(byte(split.num_types)) + last_entropy[1] = last_entropy[0] + last_entropy[0] = entropy + self.num_blocks_++ + split.num_types++ + self.curr_histogram_ix_++ + if self.curr_histogram_ix_ < *self.histograms_size_ { + histogramClearLiteral(&histograms[self.curr_histogram_ix_]) + } + self.block_size_ = 0 + self.merge_last_count_ = 0 + self.target_block_size_ = self.min_block_size_ + } else if diff[1] < diff[0]-20.0 { + split.lengths[self.num_blocks_] = uint32(self.block_size_) + split.types[self.num_blocks_] = split.types[self.num_blocks_-2] + /* Combine this block with second last block. */ + + var tmp uint = self.last_histogram_ix_[0] + self.last_histogram_ix_[0] = self.last_histogram_ix_[1] + self.last_histogram_ix_[1] = tmp + histograms[self.last_histogram_ix_[0]] = combined_histo[1] + last_entropy[1] = last_entropy[0] + last_entropy[0] = combined_entropy[1] + self.num_blocks_++ + self.block_size_ = 0 + histogramClearLiteral(&histograms[self.curr_histogram_ix_]) + self.merge_last_count_ = 0 + self.target_block_size_ = self.min_block_size_ + } else { + /* Combine this block with last block. */ + split.lengths[self.num_blocks_-1] += uint32(self.block_size_) + + histograms[self.last_histogram_ix_[0]] = combined_histo[0] + last_entropy[0] = combined_entropy[0] + if split.num_types == 1 { + last_entropy[1] = last_entropy[0] + } + + self.block_size_ = 0 + histogramClearLiteral(&histograms[self.curr_histogram_ix_]) + self.merge_last_count_++ + if self.merge_last_count_ > 1 { + self.target_block_size_ += self.min_block_size_ + } + } + } + + if is_final { + *self.histograms_size_ = split.num_types + split.num_blocks = self.num_blocks_ + } +} + +/* Adds the next symbol to the current histogram. When the current histogram + reaches the target size, decides on merging the block. */ +func blockSplitterAddSymbolLiteral(self *blockSplitterLiteral, symbol uint) { + histogramAddLiteral(&self.histograms_[self.curr_histogram_ix_], symbol) + self.block_size_++ + if self.block_size_ == self.target_block_size_ { + blockSplitterFinishBlockLiteral(self, false) /* is_final = */ + } +} diff --git a/vendor/github.com/andybalholm/brotli/params.go b/vendor/github.com/andybalholm/brotli/params.go new file mode 100644 index 0000000..0a4c687 --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/params.go @@ -0,0 +1,37 @@ +package brotli + +/* Copyright 2017 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Parameters for the Brotli encoder with chosen quality levels. */ +type hasherParams struct { + type_ int + bucket_bits int + block_bits int + hash_len int + num_last_distances_to_check int +} + +type distanceParams struct { + distance_postfix_bits uint32 + num_direct_distance_codes uint32 + alphabet_size uint32 + max_distance uint +} + +/* Encoding parameters */ +type encoderParams struct { + mode int + quality int + lgwin uint + lgblock int + size_hint uint + disable_literal_context_modeling bool + large_window bool + hasher hasherParams + dist distanceParams + dictionary encoderDictionary +} diff --git a/vendor/github.com/andybalholm/brotli/platform.go b/vendor/github.com/andybalholm/brotli/platform.go new file mode 100644 index 0000000..4ebfb15 --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/platform.go @@ -0,0 +1,103 @@ +package brotli + +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +func brotli_min_double(a float64, b float64) float64 { + if a < b { + return a + } else { + return b + } +} + +func brotli_max_double(a float64, b float64) float64 { + if a > b { + return a + } else { + return b + } +} + +func brotli_min_float(a float32, b float32) float32 { + if a < b { + return a + } else { + return b + } +} + +func brotli_max_float(a float32, b float32) float32 { + if a > b { + return a + } else { + return b + } +} + +func brotli_min_int(a int, b int) int { + if a < b { + return a + } else { + return b + } +} + +func brotli_max_int(a int, b int) int { + if a > b { + return a + } else { + return b + } +} + +func brotli_min_size_t(a uint, b uint) uint { + if a < b { + return a + } else { + return b + } +} + +func brotli_max_size_t(a uint, b uint) uint { + if a > b { + return a + } else { + return b + } +} + +func brotli_min_uint32_t(a uint32, b uint32) uint32 { + if a < b { + return a + } else { + return b + } +} + +func brotli_max_uint32_t(a uint32, b uint32) uint32 { + if a > b { + return a + } else { + return b + } +} + +func brotli_min_uint8_t(a byte, b byte) byte { + if a < b { + return a + } else { + return b + } +} + +func brotli_max_uint8_t(a byte, b byte) byte { + if a > b { + return a + } else { + return b + } +} diff --git a/vendor/github.com/andybalholm/brotli/prefix.go b/vendor/github.com/andybalholm/brotli/prefix.go new file mode 100644 index 0000000..484df0d --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/prefix.go @@ -0,0 +1,30 @@ +package brotli + +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Functions for encoding of integers into prefix codes the amount of extra + bits, and the actual values of the extra bits. */ + +/* Here distance_code is an intermediate code, i.e. one of the special codes or + the actual distance increased by BROTLI_NUM_DISTANCE_SHORT_CODES - 1. */ +func prefixEncodeCopyDistance(distance_code uint, num_direct_codes uint, postfix_bits uint, code *uint16, extra_bits *uint32) { + if distance_code < numDistanceShortCodes+num_direct_codes { + *code = uint16(distance_code) + *extra_bits = 0 + return + } else { + var dist uint = (uint(1) << (postfix_bits + 2)) + (distance_code - numDistanceShortCodes - num_direct_codes) + var bucket uint = uint(log2FloorNonZero(dist) - 1) + var postfix_mask uint = (1 << postfix_bits) - 1 + var postfix uint = dist & postfix_mask + var prefix uint = (dist >> bucket) & 1 + var offset uint = (2 + prefix) << bucket + var nbits uint = bucket - postfix_bits + *code = uint16(nbits<<10 | (numDistanceShortCodes + num_direct_codes + ((2*(nbits-1) + prefix) << postfix_bits) + postfix)) + *extra_bits = uint32((dist - offset) >> postfix_bits) + } +} diff --git a/vendor/github.com/andybalholm/brotli/prefix_dec.go b/vendor/github.com/andybalholm/brotli/prefix_dec.go new file mode 100644 index 0000000..183f0d5 --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/prefix_dec.go @@ -0,0 +1,723 @@ +package brotli + +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +type cmdLutElement struct { + insert_len_extra_bits byte + copy_len_extra_bits byte + distance_code int8 + context byte + insert_len_offset uint16 + copy_len_offset uint16 +} + +var kCmdLut = [numCommandSymbols]cmdLutElement{ + cmdLutElement{0x00, 0x00, 0, 0x00, 0x0000, 0x0002}, + cmdLutElement{0x00, 0x00, 0, 0x01, 0x0000, 0x0003}, + cmdLutElement{0x00, 0x00, 0, 0x02, 0x0000, 0x0004}, + cmdLutElement{0x00, 0x00, 0, 0x03, 0x0000, 0x0005}, + cmdLutElement{0x00, 0x00, 0, 0x03, 0x0000, 0x0006}, + cmdLutElement{0x00, 0x00, 0, 0x03, 0x0000, 0x0007}, + cmdLutElement{0x00, 0x00, 0, 0x03, 0x0000, 0x0008}, + cmdLutElement{0x00, 0x00, 0, 0x03, 0x0000, 0x0009}, + cmdLutElement{0x00, 0x00, 0, 0x00, 0x0001, 0x0002}, + cmdLutElement{0x00, 0x00, 0, 0x01, 0x0001, 0x0003}, + cmdLutElement{0x00, 0x00, 0, 0x02, 0x0001, 0x0004}, + cmdLutElement{0x00, 0x00, 0, 0x03, 0x0001, 0x0005}, + cmdLutElement{0x00, 0x00, 0, 0x03, 0x0001, 0x0006}, + cmdLutElement{0x00, 0x00, 0, 0x03, 0x0001, 0x0007}, + cmdLutElement{0x00, 0x00, 0, 0x03, 0x0001, 0x0008}, + cmdLutElement{0x00, 0x00, 0, 0x03, 0x0001, 0x0009}, + cmdLutElement{0x00, 0x00, 0, 0x00, 0x0002, 0x0002}, + cmdLutElement{0x00, 0x00, 0, 0x01, 0x0002, 0x0003}, + cmdLutElement{0x00, 0x00, 0, 0x02, 0x0002, 0x0004}, + cmdLutElement{0x00, 0x00, 0, 0x03, 0x0002, 0x0005}, + cmdLutElement{0x00, 0x00, 0, 0x03, 0x0002, 0x0006}, + cmdLutElement{0x00, 0x00, 0, 0x03, 0x0002, 0x0007}, + cmdLutElement{0x00, 0x00, 0, 0x03, 0x0002, 0x0008}, + cmdLutElement{0x00, 0x00, 0, 0x03, 0x0002, 0x0009}, + cmdLutElement{0x00, 0x00, 0, 0x00, 0x0003, 0x0002}, + cmdLutElement{0x00, 0x00, 0, 0x01, 0x0003, 0x0003}, + cmdLutElement{0x00, 0x00, 0, 0x02, 0x0003, 0x0004}, + cmdLutElement{0x00, 0x00, 0, 0x03, 0x0003, 0x0005}, + cmdLutElement{0x00, 0x00, 0, 0x03, 0x0003, 0x0006}, + cmdLutElement{0x00, 0x00, 0, 0x03, 0x0003, 0x0007}, + cmdLutElement{0x00, 0x00, 0, 0x03, 0x0003, 0x0008}, + cmdLutElement{0x00, 0x00, 0, 0x03, 0x0003, 0x0009}, + cmdLutElement{0x00, 0x00, 0, 0x00, 0x0004, 0x0002}, + cmdLutElement{0x00, 0x00, 0, 0x01, 0x0004, 0x0003}, + cmdLutElement{0x00, 0x00, 0, 0x02, 0x0004, 0x0004}, + cmdLutElement{0x00, 0x00, 0, 0x03, 0x0004, 0x0005}, + cmdLutElement{0x00, 0x00, 0, 0x03, 0x0004, 0x0006}, + cmdLutElement{0x00, 0x00, 0, 0x03, 0x0004, 0x0007}, + cmdLutElement{0x00, 0x00, 0, 0x03, 0x0004, 0x0008}, + cmdLutElement{0x00, 0x00, 0, 0x03, 0x0004, 0x0009}, + cmdLutElement{0x00, 0x00, 0, 0x00, 0x0005, 0x0002}, + cmdLutElement{0x00, 0x00, 0, 0x01, 0x0005, 0x0003}, + cmdLutElement{0x00, 0x00, 0, 0x02, 0x0005, 0x0004}, + cmdLutElement{0x00, 0x00, 0, 0x03, 0x0005, 0x0005}, + cmdLutElement{0x00, 0x00, 0, 0x03, 0x0005, 0x0006}, + cmdLutElement{0x00, 0x00, 0, 0x03, 0x0005, 0x0007}, + cmdLutElement{0x00, 0x00, 0, 0x03, 0x0005, 0x0008}, + cmdLutElement{0x00, 0x00, 0, 0x03, 0x0005, 0x0009}, + cmdLutElement{0x01, 0x00, 0, 0x00, 0x0006, 0x0002}, + cmdLutElement{0x01, 0x00, 0, 0x01, 0x0006, 0x0003}, + cmdLutElement{0x01, 0x00, 0, 0x02, 0x0006, 0x0004}, + cmdLutElement{0x01, 0x00, 0, 0x03, 0x0006, 0x0005}, + cmdLutElement{0x01, 0x00, 0, 0x03, 0x0006, 0x0006}, + cmdLutElement{0x01, 0x00, 0, 0x03, 0x0006, 0x0007}, + cmdLutElement{0x01, 0x00, 0, 0x03, 0x0006, 0x0008}, + cmdLutElement{0x01, 0x00, 0, 0x03, 0x0006, 0x0009}, + cmdLutElement{0x01, 0x00, 0, 0x00, 0x0008, 0x0002}, + cmdLutElement{0x01, 0x00, 0, 0x01, 0x0008, 0x0003}, + cmdLutElement{0x01, 0x00, 0, 0x02, 0x0008, 0x0004}, + cmdLutElement{0x01, 0x00, 0, 0x03, 0x0008, 0x0005}, + cmdLutElement{0x01, 0x00, 0, 0x03, 0x0008, 0x0006}, + cmdLutElement{0x01, 0x00, 0, 0x03, 0x0008, 0x0007}, + cmdLutElement{0x01, 0x00, 0, 0x03, 0x0008, 0x0008}, + cmdLutElement{0x01, 0x00, 0, 0x03, 0x0008, 0x0009}, + cmdLutElement{0x00, 0x01, 0, 0x03, 0x0000, 0x000a}, + cmdLutElement{0x00, 0x01, 0, 0x03, 0x0000, 0x000c}, + cmdLutElement{0x00, 0x02, 0, 0x03, 0x0000, 0x000e}, + cmdLutElement{0x00, 0x02, 0, 0x03, 0x0000, 0x0012}, + cmdLutElement{0x00, 0x03, 0, 0x03, 0x0000, 0x0016}, + cmdLutElement{0x00, 0x03, 0, 0x03, 0x0000, 0x001e}, + cmdLutElement{0x00, 0x04, 0, 0x03, 0x0000, 0x0026}, + cmdLutElement{0x00, 0x04, 0, 0x03, 0x0000, 0x0036}, + cmdLutElement{0x00, 0x01, 0, 0x03, 0x0001, 0x000a}, + cmdLutElement{0x00, 0x01, 0, 0x03, 0x0001, 0x000c}, + cmdLutElement{0x00, 0x02, 0, 0x03, 0x0001, 0x000e}, + cmdLutElement{0x00, 0x02, 0, 0x03, 0x0001, 0x0012}, + cmdLutElement{0x00, 0x03, 0, 0x03, 0x0001, 0x0016}, + cmdLutElement{0x00, 0x03, 0, 0x03, 0x0001, 0x001e}, + cmdLutElement{0x00, 0x04, 0, 0x03, 0x0001, 0x0026}, + cmdLutElement{0x00, 0x04, 0, 0x03, 0x0001, 0x0036}, + cmdLutElement{0x00, 0x01, 0, 0x03, 0x0002, 0x000a}, + cmdLutElement{0x00, 0x01, 0, 0x03, 0x0002, 0x000c}, + cmdLutElement{0x00, 0x02, 0, 0x03, 0x0002, 0x000e}, + cmdLutElement{0x00, 0x02, 0, 0x03, 0x0002, 0x0012}, + cmdLutElement{0x00, 0x03, 0, 0x03, 0x0002, 0x0016}, + cmdLutElement{0x00, 0x03, 0, 0x03, 0x0002, 0x001e}, + cmdLutElement{0x00, 0x04, 0, 0x03, 0x0002, 0x0026}, + cmdLutElement{0x00, 0x04, 0, 0x03, 0x0002, 0x0036}, + cmdLutElement{0x00, 0x01, 0, 0x03, 0x0003, 0x000a}, + cmdLutElement{0x00, 0x01, 0, 0x03, 0x0003, 0x000c}, + cmdLutElement{0x00, 0x02, 0, 0x03, 0x0003, 0x000e}, + cmdLutElement{0x00, 0x02, 0, 0x03, 0x0003, 0x0012}, + cmdLutElement{0x00, 0x03, 0, 0x03, 0x0003, 0x0016}, + cmdLutElement{0x00, 0x03, 0, 0x03, 0x0003, 0x001e}, + cmdLutElement{0x00, 0x04, 0, 0x03, 0x0003, 0x0026}, + cmdLutElement{0x00, 0x04, 0, 0x03, 0x0003, 0x0036}, + cmdLutElement{0x00, 0x01, 0, 0x03, 0x0004, 0x000a}, + cmdLutElement{0x00, 0x01, 0, 0x03, 0x0004, 0x000c}, + cmdLutElement{0x00, 0x02, 0, 0x03, 0x0004, 0x000e}, + cmdLutElement{0x00, 0x02, 0, 0x03, 0x0004, 0x0012}, + cmdLutElement{0x00, 0x03, 0, 0x03, 0x0004, 0x0016}, + cmdLutElement{0x00, 0x03, 0, 0x03, 0x0004, 0x001e}, + cmdLutElement{0x00, 0x04, 0, 0x03, 0x0004, 0x0026}, + cmdLutElement{0x00, 0x04, 0, 0x03, 0x0004, 0x0036}, + cmdLutElement{0x00, 0x01, 0, 0x03, 0x0005, 0x000a}, + cmdLutElement{0x00, 0x01, 0, 0x03, 0x0005, 0x000c}, + cmdLutElement{0x00, 0x02, 0, 0x03, 0x0005, 0x000e}, + cmdLutElement{0x00, 0x02, 0, 0x03, 0x0005, 0x0012}, + cmdLutElement{0x00, 0x03, 0, 0x03, 0x0005, 0x0016}, + cmdLutElement{0x00, 0x03, 0, 0x03, 0x0005, 0x001e}, + cmdLutElement{0x00, 0x04, 0, 0x03, 0x0005, 0x0026}, + cmdLutElement{0x00, 0x04, 0, 0x03, 0x0005, 0x0036}, + cmdLutElement{0x01, 0x01, 0, 0x03, 0x0006, 0x000a}, + cmdLutElement{0x01, 0x01, 0, 0x03, 0x0006, 0x000c}, + cmdLutElement{0x01, 0x02, 0, 0x03, 0x0006, 0x000e}, + cmdLutElement{0x01, 0x02, 0, 0x03, 0x0006, 0x0012}, + cmdLutElement{0x01, 0x03, 0, 0x03, 0x0006, 0x0016}, + cmdLutElement{0x01, 0x03, 0, 0x03, 0x0006, 0x001e}, + cmdLutElement{0x01, 0x04, 0, 0x03, 0x0006, 0x0026}, + cmdLutElement{0x01, 0x04, 0, 0x03, 0x0006, 0x0036}, + cmdLutElement{0x01, 0x01, 0, 0x03, 0x0008, 0x000a}, + cmdLutElement{0x01, 0x01, 0, 0x03, 0x0008, 0x000c}, + cmdLutElement{0x01, 0x02, 0, 0x03, 0x0008, 0x000e}, + cmdLutElement{0x01, 0x02, 0, 0x03, 0x0008, 0x0012}, + cmdLutElement{0x01, 0x03, 0, 0x03, 0x0008, 0x0016}, + cmdLutElement{0x01, 0x03, 0, 0x03, 0x0008, 0x001e}, + cmdLutElement{0x01, 0x04, 0, 0x03, 0x0008, 0x0026}, + cmdLutElement{0x01, 0x04, 0, 0x03, 0x0008, 0x0036}, + cmdLutElement{0x00, 0x00, -1, 0x00, 0x0000, 0x0002}, + cmdLutElement{0x00, 0x00, -1, 0x01, 0x0000, 0x0003}, + cmdLutElement{0x00, 0x00, -1, 0x02, 0x0000, 0x0004}, + cmdLutElement{0x00, 0x00, -1, 0x03, 0x0000, 0x0005}, + cmdLutElement{0x00, 0x00, -1, 0x03, 0x0000, 0x0006}, + cmdLutElement{0x00, 0x00, -1, 0x03, 0x0000, 0x0007}, + cmdLutElement{0x00, 0x00, -1, 0x03, 0x0000, 0x0008}, + cmdLutElement{0x00, 0x00, -1, 0x03, 0x0000, 0x0009}, + cmdLutElement{0x00, 0x00, -1, 0x00, 0x0001, 0x0002}, + cmdLutElement{0x00, 0x00, -1, 0x01, 0x0001, 0x0003}, + cmdLutElement{0x00, 0x00, -1, 0x02, 0x0001, 0x0004}, + cmdLutElement{0x00, 0x00, -1, 0x03, 0x0001, 0x0005}, + cmdLutElement{0x00, 0x00, -1, 0x03, 0x0001, 0x0006}, + cmdLutElement{0x00, 0x00, -1, 0x03, 0x0001, 0x0007}, + cmdLutElement{0x00, 0x00, -1, 0x03, 0x0001, 0x0008}, + cmdLutElement{0x00, 0x00, -1, 0x03, 0x0001, 0x0009}, + cmdLutElement{0x00, 0x00, -1, 0x00, 0x0002, 0x0002}, + cmdLutElement{0x00, 0x00, -1, 0x01, 0x0002, 0x0003}, + cmdLutElement{0x00, 0x00, -1, 0x02, 0x0002, 0x0004}, + cmdLutElement{0x00, 0x00, -1, 0x03, 0x0002, 0x0005}, + cmdLutElement{0x00, 0x00, -1, 0x03, 0x0002, 0x0006}, + cmdLutElement{0x00, 0x00, -1, 0x03, 0x0002, 0x0007}, + cmdLutElement{0x00, 0x00, -1, 0x03, 0x0002, 0x0008}, + cmdLutElement{0x00, 0x00, -1, 0x03, 0x0002, 0x0009}, + cmdLutElement{0x00, 0x00, -1, 0x00, 0x0003, 0x0002}, + cmdLutElement{0x00, 0x00, -1, 0x01, 0x0003, 0x0003}, + cmdLutElement{0x00, 0x00, -1, 0x02, 0x0003, 0x0004}, + cmdLutElement{0x00, 0x00, -1, 0x03, 0x0003, 0x0005}, + cmdLutElement{0x00, 0x00, -1, 0x03, 0x0003, 0x0006}, + cmdLutElement{0x00, 0x00, -1, 0x03, 0x0003, 0x0007}, + cmdLutElement{0x00, 0x00, -1, 0x03, 0x0003, 0x0008}, + cmdLutElement{0x00, 0x00, -1, 0x03, 0x0003, 0x0009}, + cmdLutElement{0x00, 0x00, -1, 0x00, 0x0004, 0x0002}, + cmdLutElement{0x00, 0x00, -1, 0x01, 0x0004, 0x0003}, + cmdLutElement{0x00, 0x00, -1, 0x02, 0x0004, 0x0004}, + cmdLutElement{0x00, 0x00, -1, 0x03, 0x0004, 0x0005}, + cmdLutElement{0x00, 0x00, -1, 0x03, 0x0004, 0x0006}, + cmdLutElement{0x00, 0x00, -1, 0x03, 0x0004, 0x0007}, + cmdLutElement{0x00, 0x00, -1, 0x03, 0x0004, 0x0008}, + cmdLutElement{0x00, 0x00, -1, 0x03, 0x0004, 0x0009}, + cmdLutElement{0x00, 0x00, -1, 0x00, 0x0005, 0x0002}, + cmdLutElement{0x00, 0x00, -1, 0x01, 0x0005, 0x0003}, + cmdLutElement{0x00, 0x00, -1, 0x02, 0x0005, 0x0004}, + cmdLutElement{0x00, 0x00, -1, 0x03, 0x0005, 0x0005}, + cmdLutElement{0x00, 0x00, -1, 0x03, 0x0005, 0x0006}, + cmdLutElement{0x00, 0x00, -1, 0x03, 0x0005, 0x0007}, + cmdLutElement{0x00, 0x00, -1, 0x03, 0x0005, 0x0008}, + cmdLutElement{0x00, 0x00, -1, 0x03, 0x0005, 0x0009}, + cmdLutElement{0x01, 0x00, -1, 0x00, 0x0006, 0x0002}, + cmdLutElement{0x01, 0x00, -1, 0x01, 0x0006, 0x0003}, + cmdLutElement{0x01, 0x00, -1, 0x02, 0x0006, 0x0004}, + cmdLutElement{0x01, 0x00, -1, 0x03, 0x0006, 0x0005}, + cmdLutElement{0x01, 0x00, -1, 0x03, 0x0006, 0x0006}, + cmdLutElement{0x01, 0x00, -1, 0x03, 0x0006, 0x0007}, + cmdLutElement{0x01, 0x00, -1, 0x03, 0x0006, 0x0008}, + cmdLutElement{0x01, 0x00, -1, 0x03, 0x0006, 0x0009}, + cmdLutElement{0x01, 0x00, -1, 0x00, 0x0008, 0x0002}, + cmdLutElement{0x01, 0x00, -1, 0x01, 0x0008, 0x0003}, + cmdLutElement{0x01, 0x00, -1, 0x02, 0x0008, 0x0004}, + cmdLutElement{0x01, 0x00, -1, 0x03, 0x0008, 0x0005}, + cmdLutElement{0x01, 0x00, -1, 0x03, 0x0008, 0x0006}, + cmdLutElement{0x01, 0x00, -1, 0x03, 0x0008, 0x0007}, + cmdLutElement{0x01, 0x00, -1, 0x03, 0x0008, 0x0008}, + cmdLutElement{0x01, 0x00, -1, 0x03, 0x0008, 0x0009}, + cmdLutElement{0x00, 0x01, -1, 0x03, 0x0000, 0x000a}, + cmdLutElement{0x00, 0x01, -1, 0x03, 0x0000, 0x000c}, + cmdLutElement{0x00, 0x02, -1, 0x03, 0x0000, 0x000e}, + cmdLutElement{0x00, 0x02, -1, 0x03, 0x0000, 0x0012}, + cmdLutElement{0x00, 0x03, -1, 0x03, 0x0000, 0x0016}, + cmdLutElement{0x00, 0x03, -1, 0x03, 0x0000, 0x001e}, + cmdLutElement{0x00, 0x04, -1, 0x03, 0x0000, 0x0026}, + cmdLutElement{0x00, 0x04, -1, 0x03, 0x0000, 0x0036}, + cmdLutElement{0x00, 0x01, -1, 0x03, 0x0001, 0x000a}, + cmdLutElement{0x00, 0x01, -1, 0x03, 0x0001, 0x000c}, + cmdLutElement{0x00, 0x02, -1, 0x03, 0x0001, 0x000e}, + cmdLutElement{0x00, 0x02, -1, 0x03, 0x0001, 0x0012}, + cmdLutElement{0x00, 0x03, -1, 0x03, 0x0001, 0x0016}, + cmdLutElement{0x00, 0x03, -1, 0x03, 0x0001, 0x001e}, + cmdLutElement{0x00, 0x04, -1, 0x03, 0x0001, 0x0026}, + cmdLutElement{0x00, 0x04, -1, 0x03, 0x0001, 0x0036}, + cmdLutElement{0x00, 0x01, -1, 0x03, 0x0002, 0x000a}, + cmdLutElement{0x00, 0x01, -1, 0x03, 0x0002, 0x000c}, + cmdLutElement{0x00, 0x02, -1, 0x03, 0x0002, 0x000e}, + cmdLutElement{0x00, 0x02, -1, 0x03, 0x0002, 0x0012}, + cmdLutElement{0x00, 0x03, -1, 0x03, 0x0002, 0x0016}, + cmdLutElement{0x00, 0x03, -1, 0x03, 0x0002, 0x001e}, + cmdLutElement{0x00, 0x04, -1, 0x03, 0x0002, 0x0026}, + cmdLutElement{0x00, 0x04, -1, 0x03, 0x0002, 0x0036}, + cmdLutElement{0x00, 0x01, -1, 0x03, 0x0003, 0x000a}, + cmdLutElement{0x00, 0x01, -1, 0x03, 0x0003, 0x000c}, + cmdLutElement{0x00, 0x02, -1, 0x03, 0x0003, 0x000e}, + cmdLutElement{0x00, 0x02, -1, 0x03, 0x0003, 0x0012}, + cmdLutElement{0x00, 0x03, -1, 0x03, 0x0003, 0x0016}, + cmdLutElement{0x00, 0x03, -1, 0x03, 0x0003, 0x001e}, + cmdLutElement{0x00, 0x04, -1, 0x03, 0x0003, 0x0026}, + cmdLutElement{0x00, 0x04, -1, 0x03, 0x0003, 0x0036}, + cmdLutElement{0x00, 0x01, -1, 0x03, 0x0004, 0x000a}, + cmdLutElement{0x00, 0x01, -1, 0x03, 0x0004, 0x000c}, + cmdLutElement{0x00, 0x02, -1, 0x03, 0x0004, 0x000e}, + cmdLutElement{0x00, 0x02, -1, 0x03, 0x0004, 0x0012}, + cmdLutElement{0x00, 0x03, -1, 0x03, 0x0004, 0x0016}, + cmdLutElement{0x00, 0x03, -1, 0x03, 0x0004, 0x001e}, + cmdLutElement{0x00, 0x04, -1, 0x03, 0x0004, 0x0026}, + cmdLutElement{0x00, 0x04, -1, 0x03, 0x0004, 0x0036}, + cmdLutElement{0x00, 0x01, -1, 0x03, 0x0005, 0x000a}, + cmdLutElement{0x00, 0x01, -1, 0x03, 0x0005, 0x000c}, + cmdLutElement{0x00, 0x02, -1, 0x03, 0x0005, 0x000e}, + cmdLutElement{0x00, 0x02, -1, 0x03, 0x0005, 0x0012}, + cmdLutElement{0x00, 0x03, -1, 0x03, 0x0005, 0x0016}, + cmdLutElement{0x00, 0x03, -1, 0x03, 0x0005, 0x001e}, + cmdLutElement{0x00, 0x04, -1, 0x03, 0x0005, 0x0026}, + cmdLutElement{0x00, 0x04, -1, 0x03, 0x0005, 0x0036}, + cmdLutElement{0x01, 0x01, -1, 0x03, 0x0006, 0x000a}, + cmdLutElement{0x01, 0x01, -1, 0x03, 0x0006, 0x000c}, + cmdLutElement{0x01, 0x02, -1, 0x03, 0x0006, 0x000e}, + cmdLutElement{0x01, 0x02, -1, 0x03, 0x0006, 0x0012}, + cmdLutElement{0x01, 0x03, -1, 0x03, 0x0006, 0x0016}, + cmdLutElement{0x01, 0x03, -1, 0x03, 0x0006, 0x001e}, + cmdLutElement{0x01, 0x04, -1, 0x03, 0x0006, 0x0026}, + cmdLutElement{0x01, 0x04, -1, 0x03, 0x0006, 0x0036}, + cmdLutElement{0x01, 0x01, -1, 0x03, 0x0008, 0x000a}, + cmdLutElement{0x01, 0x01, -1, 0x03, 0x0008, 0x000c}, + cmdLutElement{0x01, 0x02, -1, 0x03, 0x0008, 0x000e}, + cmdLutElement{0x01, 0x02, -1, 0x03, 0x0008, 0x0012}, + cmdLutElement{0x01, 0x03, -1, 0x03, 0x0008, 0x0016}, + cmdLutElement{0x01, 0x03, -1, 0x03, 0x0008, 0x001e}, + cmdLutElement{0x01, 0x04, -1, 0x03, 0x0008, 0x0026}, + cmdLutElement{0x01, 0x04, -1, 0x03, 0x0008, 0x0036}, + cmdLutElement{0x02, 0x00, -1, 0x00, 0x000a, 0x0002}, + cmdLutElement{0x02, 0x00, -1, 0x01, 0x000a, 0x0003}, + cmdLutElement{0x02, 0x00, -1, 0x02, 0x000a, 0x0004}, + cmdLutElement{0x02, 0x00, -1, 0x03, 0x000a, 0x0005}, + cmdLutElement{0x02, 0x00, -1, 0x03, 0x000a, 0x0006}, + cmdLutElement{0x02, 0x00, -1, 0x03, 0x000a, 0x0007}, + cmdLutElement{0x02, 0x00, -1, 0x03, 0x000a, 0x0008}, + cmdLutElement{0x02, 0x00, -1, 0x03, 0x000a, 0x0009}, + cmdLutElement{0x02, 0x00, -1, 0x00, 0x000e, 0x0002}, + cmdLutElement{0x02, 0x00, -1, 0x01, 0x000e, 0x0003}, + cmdLutElement{0x02, 0x00, -1, 0x02, 0x000e, 0x0004}, + cmdLutElement{0x02, 0x00, -1, 0x03, 0x000e, 0x0005}, + cmdLutElement{0x02, 0x00, -1, 0x03, 0x000e, 0x0006}, + cmdLutElement{0x02, 0x00, -1, 0x03, 0x000e, 0x0007}, + cmdLutElement{0x02, 0x00, -1, 0x03, 0x000e, 0x0008}, + cmdLutElement{0x02, 0x00, -1, 0x03, 0x000e, 0x0009}, + cmdLutElement{0x03, 0x00, -1, 0x00, 0x0012, 0x0002}, + cmdLutElement{0x03, 0x00, -1, 0x01, 0x0012, 0x0003}, + cmdLutElement{0x03, 0x00, -1, 0x02, 0x0012, 0x0004}, + cmdLutElement{0x03, 0x00, -1, 0x03, 0x0012, 0x0005}, + cmdLutElement{0x03, 0x00, -1, 0x03, 0x0012, 0x0006}, + cmdLutElement{0x03, 0x00, -1, 0x03, 0x0012, 0x0007}, + cmdLutElement{0x03, 0x00, -1, 0x03, 0x0012, 0x0008}, + cmdLutElement{0x03, 0x00, -1, 0x03, 0x0012, 0x0009}, + cmdLutElement{0x03, 0x00, -1, 0x00, 0x001a, 0x0002}, + cmdLutElement{0x03, 0x00, -1, 0x01, 0x001a, 0x0003}, + cmdLutElement{0x03, 0x00, -1, 0x02, 0x001a, 0x0004}, + cmdLutElement{0x03, 0x00, -1, 0x03, 0x001a, 0x0005}, + cmdLutElement{0x03, 0x00, -1, 0x03, 0x001a, 0x0006}, + cmdLutElement{0x03, 0x00, -1, 0x03, 0x001a, 0x0007}, + cmdLutElement{0x03, 0x00, -1, 0x03, 0x001a, 0x0008}, + cmdLutElement{0x03, 0x00, -1, 0x03, 0x001a, 0x0009}, + cmdLutElement{0x04, 0x00, -1, 0x00, 0x0022, 0x0002}, + cmdLutElement{0x04, 0x00, -1, 0x01, 0x0022, 0x0003}, + cmdLutElement{0x04, 0x00, -1, 0x02, 0x0022, 0x0004}, + cmdLutElement{0x04, 0x00, -1, 0x03, 0x0022, 0x0005}, + cmdLutElement{0x04, 0x00, -1, 0x03, 0x0022, 0x0006}, + cmdLutElement{0x04, 0x00, -1, 0x03, 0x0022, 0x0007}, + cmdLutElement{0x04, 0x00, -1, 0x03, 0x0022, 0x0008}, + cmdLutElement{0x04, 0x00, -1, 0x03, 0x0022, 0x0009}, + cmdLutElement{0x04, 0x00, -1, 0x00, 0x0032, 0x0002}, + cmdLutElement{0x04, 0x00, -1, 0x01, 0x0032, 0x0003}, + cmdLutElement{0x04, 0x00, -1, 0x02, 0x0032, 0x0004}, + cmdLutElement{0x04, 0x00, -1, 0x03, 0x0032, 0x0005}, + cmdLutElement{0x04, 0x00, -1, 0x03, 0x0032, 0x0006}, + cmdLutElement{0x04, 0x00, -1, 0x03, 0x0032, 0x0007}, + cmdLutElement{0x04, 0x00, -1, 0x03, 0x0032, 0x0008}, + cmdLutElement{0x04, 0x00, -1, 0x03, 0x0032, 0x0009}, + cmdLutElement{0x05, 0x00, -1, 0x00, 0x0042, 0x0002}, + cmdLutElement{0x05, 0x00, -1, 0x01, 0x0042, 0x0003}, + cmdLutElement{0x05, 0x00, -1, 0x02, 0x0042, 0x0004}, + cmdLutElement{0x05, 0x00, -1, 0x03, 0x0042, 0x0005}, + cmdLutElement{0x05, 0x00, -1, 0x03, 0x0042, 0x0006}, + cmdLutElement{0x05, 0x00, -1, 0x03, 0x0042, 0x0007}, + cmdLutElement{0x05, 0x00, -1, 0x03, 0x0042, 0x0008}, + cmdLutElement{0x05, 0x00, -1, 0x03, 0x0042, 0x0009}, + cmdLutElement{0x05, 0x00, -1, 0x00, 0x0062, 0x0002}, + cmdLutElement{0x05, 0x00, -1, 0x01, 0x0062, 0x0003}, + cmdLutElement{0x05, 0x00, -1, 0x02, 0x0062, 0x0004}, + cmdLutElement{0x05, 0x00, -1, 0x03, 0x0062, 0x0005}, + cmdLutElement{0x05, 0x00, -1, 0x03, 0x0062, 0x0006}, + cmdLutElement{0x05, 0x00, -1, 0x03, 0x0062, 0x0007}, + cmdLutElement{0x05, 0x00, -1, 0x03, 0x0062, 0x0008}, + cmdLutElement{0x05, 0x00, -1, 0x03, 0x0062, 0x0009}, + cmdLutElement{0x02, 0x01, -1, 0x03, 0x000a, 0x000a}, + cmdLutElement{0x02, 0x01, -1, 0x03, 0x000a, 0x000c}, + cmdLutElement{0x02, 0x02, -1, 0x03, 0x000a, 0x000e}, + cmdLutElement{0x02, 0x02, -1, 0x03, 0x000a, 0x0012}, + cmdLutElement{0x02, 0x03, -1, 0x03, 0x000a, 0x0016}, + cmdLutElement{0x02, 0x03, -1, 0x03, 0x000a, 0x001e}, + cmdLutElement{0x02, 0x04, -1, 0x03, 0x000a, 0x0026}, + cmdLutElement{0x02, 0x04, -1, 0x03, 0x000a, 0x0036}, + cmdLutElement{0x02, 0x01, -1, 0x03, 0x000e, 0x000a}, + cmdLutElement{0x02, 0x01, -1, 0x03, 0x000e, 0x000c}, + cmdLutElement{0x02, 0x02, -1, 0x03, 0x000e, 0x000e}, + cmdLutElement{0x02, 0x02, -1, 0x03, 0x000e, 0x0012}, + cmdLutElement{0x02, 0x03, -1, 0x03, 0x000e, 0x0016}, + cmdLutElement{0x02, 0x03, -1, 0x03, 0x000e, 0x001e}, + cmdLutElement{0x02, 0x04, -1, 0x03, 0x000e, 0x0026}, + cmdLutElement{0x02, 0x04, -1, 0x03, 0x000e, 0x0036}, + cmdLutElement{0x03, 0x01, -1, 0x03, 0x0012, 0x000a}, + cmdLutElement{0x03, 0x01, -1, 0x03, 0x0012, 0x000c}, + cmdLutElement{0x03, 0x02, -1, 0x03, 0x0012, 0x000e}, + cmdLutElement{0x03, 0x02, -1, 0x03, 0x0012, 0x0012}, + cmdLutElement{0x03, 0x03, -1, 0x03, 0x0012, 0x0016}, + cmdLutElement{0x03, 0x03, -1, 0x03, 0x0012, 0x001e}, + cmdLutElement{0x03, 0x04, -1, 0x03, 0x0012, 0x0026}, + cmdLutElement{0x03, 0x04, -1, 0x03, 0x0012, 0x0036}, + cmdLutElement{0x03, 0x01, -1, 0x03, 0x001a, 0x000a}, + cmdLutElement{0x03, 0x01, -1, 0x03, 0x001a, 0x000c}, + cmdLutElement{0x03, 0x02, -1, 0x03, 0x001a, 0x000e}, + cmdLutElement{0x03, 0x02, -1, 0x03, 0x001a, 0x0012}, + cmdLutElement{0x03, 0x03, -1, 0x03, 0x001a, 0x0016}, + cmdLutElement{0x03, 0x03, -1, 0x03, 0x001a, 0x001e}, + cmdLutElement{0x03, 0x04, -1, 0x03, 0x001a, 0x0026}, + cmdLutElement{0x03, 0x04, -1, 0x03, 0x001a, 0x0036}, + cmdLutElement{0x04, 0x01, -1, 0x03, 0x0022, 0x000a}, + cmdLutElement{0x04, 0x01, -1, 0x03, 0x0022, 0x000c}, + cmdLutElement{0x04, 0x02, -1, 0x03, 0x0022, 0x000e}, + cmdLutElement{0x04, 0x02, -1, 0x03, 0x0022, 0x0012}, + cmdLutElement{0x04, 0x03, -1, 0x03, 0x0022, 0x0016}, + cmdLutElement{0x04, 0x03, -1, 0x03, 0x0022, 0x001e}, + cmdLutElement{0x04, 0x04, -1, 0x03, 0x0022, 0x0026}, + cmdLutElement{0x04, 0x04, -1, 0x03, 0x0022, 0x0036}, + cmdLutElement{0x04, 0x01, -1, 0x03, 0x0032, 0x000a}, + cmdLutElement{0x04, 0x01, -1, 0x03, 0x0032, 0x000c}, + cmdLutElement{0x04, 0x02, -1, 0x03, 0x0032, 0x000e}, + cmdLutElement{0x04, 0x02, -1, 0x03, 0x0032, 0x0012}, + cmdLutElement{0x04, 0x03, -1, 0x03, 0x0032, 0x0016}, + cmdLutElement{0x04, 0x03, -1, 0x03, 0x0032, 0x001e}, + cmdLutElement{0x04, 0x04, -1, 0x03, 0x0032, 0x0026}, + cmdLutElement{0x04, 0x04, -1, 0x03, 0x0032, 0x0036}, + cmdLutElement{0x05, 0x01, -1, 0x03, 0x0042, 0x000a}, + cmdLutElement{0x05, 0x01, -1, 0x03, 0x0042, 0x000c}, + cmdLutElement{0x05, 0x02, -1, 0x03, 0x0042, 0x000e}, + cmdLutElement{0x05, 0x02, -1, 0x03, 0x0042, 0x0012}, + cmdLutElement{0x05, 0x03, -1, 0x03, 0x0042, 0x0016}, + cmdLutElement{0x05, 0x03, -1, 0x03, 0x0042, 0x001e}, + cmdLutElement{0x05, 0x04, -1, 0x03, 0x0042, 0x0026}, + cmdLutElement{0x05, 0x04, -1, 0x03, 0x0042, 0x0036}, + cmdLutElement{0x05, 0x01, -1, 0x03, 0x0062, 0x000a}, + cmdLutElement{0x05, 0x01, -1, 0x03, 0x0062, 0x000c}, + cmdLutElement{0x05, 0x02, -1, 0x03, 0x0062, 0x000e}, + cmdLutElement{0x05, 0x02, -1, 0x03, 0x0062, 0x0012}, + cmdLutElement{0x05, 0x03, -1, 0x03, 0x0062, 0x0016}, + cmdLutElement{0x05, 0x03, -1, 0x03, 0x0062, 0x001e}, + cmdLutElement{0x05, 0x04, -1, 0x03, 0x0062, 0x0026}, + cmdLutElement{0x05, 0x04, -1, 0x03, 0x0062, 0x0036}, + cmdLutElement{0x00, 0x05, -1, 0x03, 0x0000, 0x0046}, + cmdLutElement{0x00, 0x05, -1, 0x03, 0x0000, 0x0066}, + cmdLutElement{0x00, 0x06, -1, 0x03, 0x0000, 0x0086}, + cmdLutElement{0x00, 0x07, -1, 0x03, 0x0000, 0x00c6}, + cmdLutElement{0x00, 0x08, -1, 0x03, 0x0000, 0x0146}, + cmdLutElement{0x00, 0x09, -1, 0x03, 0x0000, 0x0246}, + cmdLutElement{0x00, 0x0a, -1, 0x03, 0x0000, 0x0446}, + cmdLutElement{0x00, 0x18, -1, 0x03, 0x0000, 0x0846}, + cmdLutElement{0x00, 0x05, -1, 0x03, 0x0001, 0x0046}, + cmdLutElement{0x00, 0x05, -1, 0x03, 0x0001, 0x0066}, + cmdLutElement{0x00, 0x06, -1, 0x03, 0x0001, 0x0086}, + cmdLutElement{0x00, 0x07, -1, 0x03, 0x0001, 0x00c6}, + cmdLutElement{0x00, 0x08, -1, 0x03, 0x0001, 0x0146}, + cmdLutElement{0x00, 0x09, -1, 0x03, 0x0001, 0x0246}, + cmdLutElement{0x00, 0x0a, -1, 0x03, 0x0001, 0x0446}, + cmdLutElement{0x00, 0x18, -1, 0x03, 0x0001, 0x0846}, + cmdLutElement{0x00, 0x05, -1, 0x03, 0x0002, 0x0046}, + cmdLutElement{0x00, 0x05, -1, 0x03, 0x0002, 0x0066}, + cmdLutElement{0x00, 0x06, -1, 0x03, 0x0002, 0x0086}, + cmdLutElement{0x00, 0x07, -1, 0x03, 0x0002, 0x00c6}, + cmdLutElement{0x00, 0x08, -1, 0x03, 0x0002, 0x0146}, + cmdLutElement{0x00, 0x09, -1, 0x03, 0x0002, 0x0246}, + cmdLutElement{0x00, 0x0a, -1, 0x03, 0x0002, 0x0446}, + cmdLutElement{0x00, 0x18, -1, 0x03, 0x0002, 0x0846}, + cmdLutElement{0x00, 0x05, -1, 0x03, 0x0003, 0x0046}, + cmdLutElement{0x00, 0x05, -1, 0x03, 0x0003, 0x0066}, + cmdLutElement{0x00, 0x06, -1, 0x03, 0x0003, 0x0086}, + cmdLutElement{0x00, 0x07, -1, 0x03, 0x0003, 0x00c6}, + cmdLutElement{0x00, 0x08, -1, 0x03, 0x0003, 0x0146}, + cmdLutElement{0x00, 0x09, -1, 0x03, 0x0003, 0x0246}, + cmdLutElement{0x00, 0x0a, -1, 0x03, 0x0003, 0x0446}, + cmdLutElement{0x00, 0x18, -1, 0x03, 0x0003, 0x0846}, + cmdLutElement{0x00, 0x05, -1, 0x03, 0x0004, 0x0046}, + cmdLutElement{0x00, 0x05, -1, 0x03, 0x0004, 0x0066}, + cmdLutElement{0x00, 0x06, -1, 0x03, 0x0004, 0x0086}, + cmdLutElement{0x00, 0x07, -1, 0x03, 0x0004, 0x00c6}, + cmdLutElement{0x00, 0x08, -1, 0x03, 0x0004, 0x0146}, + cmdLutElement{0x00, 0x09, -1, 0x03, 0x0004, 0x0246}, + cmdLutElement{0x00, 0x0a, -1, 0x03, 0x0004, 0x0446}, + cmdLutElement{0x00, 0x18, -1, 0x03, 0x0004, 0x0846}, + cmdLutElement{0x00, 0x05, -1, 0x03, 0x0005, 0x0046}, + cmdLutElement{0x00, 0x05, -1, 0x03, 0x0005, 0x0066}, + cmdLutElement{0x00, 0x06, -1, 0x03, 0x0005, 0x0086}, + cmdLutElement{0x00, 0x07, -1, 0x03, 0x0005, 0x00c6}, + cmdLutElement{0x00, 0x08, -1, 0x03, 0x0005, 0x0146}, + cmdLutElement{0x00, 0x09, -1, 0x03, 0x0005, 0x0246}, + cmdLutElement{0x00, 0x0a, -1, 0x03, 0x0005, 0x0446}, + cmdLutElement{0x00, 0x18, -1, 0x03, 0x0005, 0x0846}, + cmdLutElement{0x01, 0x05, -1, 0x03, 0x0006, 0x0046}, + cmdLutElement{0x01, 0x05, -1, 0x03, 0x0006, 0x0066}, + cmdLutElement{0x01, 0x06, -1, 0x03, 0x0006, 0x0086}, + cmdLutElement{0x01, 0x07, -1, 0x03, 0x0006, 0x00c6}, + cmdLutElement{0x01, 0x08, -1, 0x03, 0x0006, 0x0146}, + cmdLutElement{0x01, 0x09, -1, 0x03, 0x0006, 0x0246}, + cmdLutElement{0x01, 0x0a, -1, 0x03, 0x0006, 0x0446}, + cmdLutElement{0x01, 0x18, -1, 0x03, 0x0006, 0x0846}, + cmdLutElement{0x01, 0x05, -1, 0x03, 0x0008, 0x0046}, + cmdLutElement{0x01, 0x05, -1, 0x03, 0x0008, 0x0066}, + cmdLutElement{0x01, 0x06, -1, 0x03, 0x0008, 0x0086}, + cmdLutElement{0x01, 0x07, -1, 0x03, 0x0008, 0x00c6}, + cmdLutElement{0x01, 0x08, -1, 0x03, 0x0008, 0x0146}, + cmdLutElement{0x01, 0x09, -1, 0x03, 0x0008, 0x0246}, + cmdLutElement{0x01, 0x0a, -1, 0x03, 0x0008, 0x0446}, + cmdLutElement{0x01, 0x18, -1, 0x03, 0x0008, 0x0846}, + cmdLutElement{0x06, 0x00, -1, 0x00, 0x0082, 0x0002}, + cmdLutElement{0x06, 0x00, -1, 0x01, 0x0082, 0x0003}, + cmdLutElement{0x06, 0x00, -1, 0x02, 0x0082, 0x0004}, + cmdLutElement{0x06, 0x00, -1, 0x03, 0x0082, 0x0005}, + cmdLutElement{0x06, 0x00, -1, 0x03, 0x0082, 0x0006}, + cmdLutElement{0x06, 0x00, -1, 0x03, 0x0082, 0x0007}, + cmdLutElement{0x06, 0x00, -1, 0x03, 0x0082, 0x0008}, + cmdLutElement{0x06, 0x00, -1, 0x03, 0x0082, 0x0009}, + cmdLutElement{0x07, 0x00, -1, 0x00, 0x00c2, 0x0002}, + cmdLutElement{0x07, 0x00, -1, 0x01, 0x00c2, 0x0003}, + cmdLutElement{0x07, 0x00, -1, 0x02, 0x00c2, 0x0004}, + cmdLutElement{0x07, 0x00, -1, 0x03, 0x00c2, 0x0005}, + cmdLutElement{0x07, 0x00, -1, 0x03, 0x00c2, 0x0006}, + cmdLutElement{0x07, 0x00, -1, 0x03, 0x00c2, 0x0007}, + cmdLutElement{0x07, 0x00, -1, 0x03, 0x00c2, 0x0008}, + cmdLutElement{0x07, 0x00, -1, 0x03, 0x00c2, 0x0009}, + cmdLutElement{0x08, 0x00, -1, 0x00, 0x0142, 0x0002}, + cmdLutElement{0x08, 0x00, -1, 0x01, 0x0142, 0x0003}, + cmdLutElement{0x08, 0x00, -1, 0x02, 0x0142, 0x0004}, + cmdLutElement{0x08, 0x00, -1, 0x03, 0x0142, 0x0005}, + cmdLutElement{0x08, 0x00, -1, 0x03, 0x0142, 0x0006}, + cmdLutElement{0x08, 0x00, -1, 0x03, 0x0142, 0x0007}, + cmdLutElement{0x08, 0x00, -1, 0x03, 0x0142, 0x0008}, + cmdLutElement{0x08, 0x00, -1, 0x03, 0x0142, 0x0009}, + cmdLutElement{0x09, 0x00, -1, 0x00, 0x0242, 0x0002}, + cmdLutElement{0x09, 0x00, -1, 0x01, 0x0242, 0x0003}, + cmdLutElement{0x09, 0x00, -1, 0x02, 0x0242, 0x0004}, + cmdLutElement{0x09, 0x00, -1, 0x03, 0x0242, 0x0005}, + cmdLutElement{0x09, 0x00, -1, 0x03, 0x0242, 0x0006}, + cmdLutElement{0x09, 0x00, -1, 0x03, 0x0242, 0x0007}, + cmdLutElement{0x09, 0x00, -1, 0x03, 0x0242, 0x0008}, + cmdLutElement{0x09, 0x00, -1, 0x03, 0x0242, 0x0009}, + cmdLutElement{0x0a, 0x00, -1, 0x00, 0x0442, 0x0002}, + cmdLutElement{0x0a, 0x00, -1, 0x01, 0x0442, 0x0003}, + cmdLutElement{0x0a, 0x00, -1, 0x02, 0x0442, 0x0004}, + cmdLutElement{0x0a, 0x00, -1, 0x03, 0x0442, 0x0005}, + cmdLutElement{0x0a, 0x00, -1, 0x03, 0x0442, 0x0006}, + cmdLutElement{0x0a, 0x00, -1, 0x03, 0x0442, 0x0007}, + cmdLutElement{0x0a, 0x00, -1, 0x03, 0x0442, 0x0008}, + cmdLutElement{0x0a, 0x00, -1, 0x03, 0x0442, 0x0009}, + cmdLutElement{0x0c, 0x00, -1, 0x00, 0x0842, 0x0002}, + cmdLutElement{0x0c, 0x00, -1, 0x01, 0x0842, 0x0003}, + cmdLutElement{0x0c, 0x00, -1, 0x02, 0x0842, 0x0004}, + cmdLutElement{0x0c, 0x00, -1, 0x03, 0x0842, 0x0005}, + cmdLutElement{0x0c, 0x00, -1, 0x03, 0x0842, 0x0006}, + cmdLutElement{0x0c, 0x00, -1, 0x03, 0x0842, 0x0007}, + cmdLutElement{0x0c, 0x00, -1, 0x03, 0x0842, 0x0008}, + cmdLutElement{0x0c, 0x00, -1, 0x03, 0x0842, 0x0009}, + cmdLutElement{0x0e, 0x00, -1, 0x00, 0x1842, 0x0002}, + cmdLutElement{0x0e, 0x00, -1, 0x01, 0x1842, 0x0003}, + cmdLutElement{0x0e, 0x00, -1, 0x02, 0x1842, 0x0004}, + cmdLutElement{0x0e, 0x00, -1, 0x03, 0x1842, 0x0005}, + cmdLutElement{0x0e, 0x00, -1, 0x03, 0x1842, 0x0006}, + cmdLutElement{0x0e, 0x00, -1, 0x03, 0x1842, 0x0007}, + cmdLutElement{0x0e, 0x00, -1, 0x03, 0x1842, 0x0008}, + cmdLutElement{0x0e, 0x00, -1, 0x03, 0x1842, 0x0009}, + cmdLutElement{0x18, 0x00, -1, 0x00, 0x5842, 0x0002}, + cmdLutElement{0x18, 0x00, -1, 0x01, 0x5842, 0x0003}, + cmdLutElement{0x18, 0x00, -1, 0x02, 0x5842, 0x0004}, + cmdLutElement{0x18, 0x00, -1, 0x03, 0x5842, 0x0005}, + cmdLutElement{0x18, 0x00, -1, 0x03, 0x5842, 0x0006}, + cmdLutElement{0x18, 0x00, -1, 0x03, 0x5842, 0x0007}, + cmdLutElement{0x18, 0x00, -1, 0x03, 0x5842, 0x0008}, + cmdLutElement{0x18, 0x00, -1, 0x03, 0x5842, 0x0009}, + cmdLutElement{0x02, 0x05, -1, 0x03, 0x000a, 0x0046}, + cmdLutElement{0x02, 0x05, -1, 0x03, 0x000a, 0x0066}, + cmdLutElement{0x02, 0x06, -1, 0x03, 0x000a, 0x0086}, + cmdLutElement{0x02, 0x07, -1, 0x03, 0x000a, 0x00c6}, + cmdLutElement{0x02, 0x08, -1, 0x03, 0x000a, 0x0146}, + cmdLutElement{0x02, 0x09, -1, 0x03, 0x000a, 0x0246}, + cmdLutElement{0x02, 0x0a, -1, 0x03, 0x000a, 0x0446}, + cmdLutElement{0x02, 0x18, -1, 0x03, 0x000a, 0x0846}, + cmdLutElement{0x02, 0x05, -1, 0x03, 0x000e, 0x0046}, + cmdLutElement{0x02, 0x05, -1, 0x03, 0x000e, 0x0066}, + cmdLutElement{0x02, 0x06, -1, 0x03, 0x000e, 0x0086}, + cmdLutElement{0x02, 0x07, -1, 0x03, 0x000e, 0x00c6}, + cmdLutElement{0x02, 0x08, -1, 0x03, 0x000e, 0x0146}, + cmdLutElement{0x02, 0x09, -1, 0x03, 0x000e, 0x0246}, + cmdLutElement{0x02, 0x0a, -1, 0x03, 0x000e, 0x0446}, + cmdLutElement{0x02, 0x18, -1, 0x03, 0x000e, 0x0846}, + cmdLutElement{0x03, 0x05, -1, 0x03, 0x0012, 0x0046}, + cmdLutElement{0x03, 0x05, -1, 0x03, 0x0012, 0x0066}, + cmdLutElement{0x03, 0x06, -1, 0x03, 0x0012, 0x0086}, + cmdLutElement{0x03, 0x07, -1, 0x03, 0x0012, 0x00c6}, + cmdLutElement{0x03, 0x08, -1, 0x03, 0x0012, 0x0146}, + cmdLutElement{0x03, 0x09, -1, 0x03, 0x0012, 0x0246}, + cmdLutElement{0x03, 0x0a, -1, 0x03, 0x0012, 0x0446}, + cmdLutElement{0x03, 0x18, -1, 0x03, 0x0012, 0x0846}, + cmdLutElement{0x03, 0x05, -1, 0x03, 0x001a, 0x0046}, + cmdLutElement{0x03, 0x05, -1, 0x03, 0x001a, 0x0066}, + cmdLutElement{0x03, 0x06, -1, 0x03, 0x001a, 0x0086}, + cmdLutElement{0x03, 0x07, -1, 0x03, 0x001a, 0x00c6}, + cmdLutElement{0x03, 0x08, -1, 0x03, 0x001a, 0x0146}, + cmdLutElement{0x03, 0x09, -1, 0x03, 0x001a, 0x0246}, + cmdLutElement{0x03, 0x0a, -1, 0x03, 0x001a, 0x0446}, + cmdLutElement{0x03, 0x18, -1, 0x03, 0x001a, 0x0846}, + cmdLutElement{0x04, 0x05, -1, 0x03, 0x0022, 0x0046}, + cmdLutElement{0x04, 0x05, -1, 0x03, 0x0022, 0x0066}, + cmdLutElement{0x04, 0x06, -1, 0x03, 0x0022, 0x0086}, + cmdLutElement{0x04, 0x07, -1, 0x03, 0x0022, 0x00c6}, + cmdLutElement{0x04, 0x08, -1, 0x03, 0x0022, 0x0146}, + cmdLutElement{0x04, 0x09, -1, 0x03, 0x0022, 0x0246}, + cmdLutElement{0x04, 0x0a, -1, 0x03, 0x0022, 0x0446}, + cmdLutElement{0x04, 0x18, -1, 0x03, 0x0022, 0x0846}, + cmdLutElement{0x04, 0x05, -1, 0x03, 0x0032, 0x0046}, + cmdLutElement{0x04, 0x05, -1, 0x03, 0x0032, 0x0066}, + cmdLutElement{0x04, 0x06, -1, 0x03, 0x0032, 0x0086}, + cmdLutElement{0x04, 0x07, -1, 0x03, 0x0032, 0x00c6}, + cmdLutElement{0x04, 0x08, -1, 0x03, 0x0032, 0x0146}, + cmdLutElement{0x04, 0x09, -1, 0x03, 0x0032, 0x0246}, + cmdLutElement{0x04, 0x0a, -1, 0x03, 0x0032, 0x0446}, + cmdLutElement{0x04, 0x18, -1, 0x03, 0x0032, 0x0846}, + cmdLutElement{0x05, 0x05, -1, 0x03, 0x0042, 0x0046}, + cmdLutElement{0x05, 0x05, -1, 0x03, 0x0042, 0x0066}, + cmdLutElement{0x05, 0x06, -1, 0x03, 0x0042, 0x0086}, + cmdLutElement{0x05, 0x07, -1, 0x03, 0x0042, 0x00c6}, + cmdLutElement{0x05, 0x08, -1, 0x03, 0x0042, 0x0146}, + cmdLutElement{0x05, 0x09, -1, 0x03, 0x0042, 0x0246}, + cmdLutElement{0x05, 0x0a, -1, 0x03, 0x0042, 0x0446}, + cmdLutElement{0x05, 0x18, -1, 0x03, 0x0042, 0x0846}, + cmdLutElement{0x05, 0x05, -1, 0x03, 0x0062, 0x0046}, + cmdLutElement{0x05, 0x05, -1, 0x03, 0x0062, 0x0066}, + cmdLutElement{0x05, 0x06, -1, 0x03, 0x0062, 0x0086}, + cmdLutElement{0x05, 0x07, -1, 0x03, 0x0062, 0x00c6}, + cmdLutElement{0x05, 0x08, -1, 0x03, 0x0062, 0x0146}, + cmdLutElement{0x05, 0x09, -1, 0x03, 0x0062, 0x0246}, + cmdLutElement{0x05, 0x0a, -1, 0x03, 0x0062, 0x0446}, + cmdLutElement{0x05, 0x18, -1, 0x03, 0x0062, 0x0846}, + cmdLutElement{0x06, 0x01, -1, 0x03, 0x0082, 0x000a}, + cmdLutElement{0x06, 0x01, -1, 0x03, 0x0082, 0x000c}, + cmdLutElement{0x06, 0x02, -1, 0x03, 0x0082, 0x000e}, + cmdLutElement{0x06, 0x02, -1, 0x03, 0x0082, 0x0012}, + cmdLutElement{0x06, 0x03, -1, 0x03, 0x0082, 0x0016}, + cmdLutElement{0x06, 0x03, -1, 0x03, 0x0082, 0x001e}, + cmdLutElement{0x06, 0x04, -1, 0x03, 0x0082, 0x0026}, + cmdLutElement{0x06, 0x04, -1, 0x03, 0x0082, 0x0036}, + cmdLutElement{0x07, 0x01, -1, 0x03, 0x00c2, 0x000a}, + cmdLutElement{0x07, 0x01, -1, 0x03, 0x00c2, 0x000c}, + cmdLutElement{0x07, 0x02, -1, 0x03, 0x00c2, 0x000e}, + cmdLutElement{0x07, 0x02, -1, 0x03, 0x00c2, 0x0012}, + cmdLutElement{0x07, 0x03, -1, 0x03, 0x00c2, 0x0016}, + cmdLutElement{0x07, 0x03, -1, 0x03, 0x00c2, 0x001e}, + cmdLutElement{0x07, 0x04, -1, 0x03, 0x00c2, 0x0026}, + cmdLutElement{0x07, 0x04, -1, 0x03, 0x00c2, 0x0036}, + cmdLutElement{0x08, 0x01, -1, 0x03, 0x0142, 0x000a}, + cmdLutElement{0x08, 0x01, -1, 0x03, 0x0142, 0x000c}, + cmdLutElement{0x08, 0x02, -1, 0x03, 0x0142, 0x000e}, + cmdLutElement{0x08, 0x02, -1, 0x03, 0x0142, 0x0012}, + cmdLutElement{0x08, 0x03, -1, 0x03, 0x0142, 0x0016}, + cmdLutElement{0x08, 0x03, -1, 0x03, 0x0142, 0x001e}, + cmdLutElement{0x08, 0x04, -1, 0x03, 0x0142, 0x0026}, + cmdLutElement{0x08, 0x04, -1, 0x03, 0x0142, 0x0036}, + cmdLutElement{0x09, 0x01, -1, 0x03, 0x0242, 0x000a}, + cmdLutElement{0x09, 0x01, -1, 0x03, 0x0242, 0x000c}, + cmdLutElement{0x09, 0x02, -1, 0x03, 0x0242, 0x000e}, + cmdLutElement{0x09, 0x02, -1, 0x03, 0x0242, 0x0012}, + cmdLutElement{0x09, 0x03, -1, 0x03, 0x0242, 0x0016}, + cmdLutElement{0x09, 0x03, -1, 0x03, 0x0242, 0x001e}, + cmdLutElement{0x09, 0x04, -1, 0x03, 0x0242, 0x0026}, + cmdLutElement{0x09, 0x04, -1, 0x03, 0x0242, 0x0036}, + cmdLutElement{0x0a, 0x01, -1, 0x03, 0x0442, 0x000a}, + cmdLutElement{0x0a, 0x01, -1, 0x03, 0x0442, 0x000c}, + cmdLutElement{0x0a, 0x02, -1, 0x03, 0x0442, 0x000e}, + cmdLutElement{0x0a, 0x02, -1, 0x03, 0x0442, 0x0012}, + cmdLutElement{0x0a, 0x03, -1, 0x03, 0x0442, 0x0016}, + cmdLutElement{0x0a, 0x03, -1, 0x03, 0x0442, 0x001e}, + cmdLutElement{0x0a, 0x04, -1, 0x03, 0x0442, 0x0026}, + cmdLutElement{0x0a, 0x04, -1, 0x03, 0x0442, 0x0036}, + cmdLutElement{0x0c, 0x01, -1, 0x03, 0x0842, 0x000a}, + cmdLutElement{0x0c, 0x01, -1, 0x03, 0x0842, 0x000c}, + cmdLutElement{0x0c, 0x02, -1, 0x03, 0x0842, 0x000e}, + cmdLutElement{0x0c, 0x02, -1, 0x03, 0x0842, 0x0012}, + cmdLutElement{0x0c, 0x03, -1, 0x03, 0x0842, 0x0016}, + cmdLutElement{0x0c, 0x03, -1, 0x03, 0x0842, 0x001e}, + cmdLutElement{0x0c, 0x04, -1, 0x03, 0x0842, 0x0026}, + cmdLutElement{0x0c, 0x04, -1, 0x03, 0x0842, 0x0036}, + cmdLutElement{0x0e, 0x01, -1, 0x03, 0x1842, 0x000a}, + cmdLutElement{0x0e, 0x01, -1, 0x03, 0x1842, 0x000c}, + cmdLutElement{0x0e, 0x02, -1, 0x03, 0x1842, 0x000e}, + cmdLutElement{0x0e, 0x02, -1, 0x03, 0x1842, 0x0012}, + cmdLutElement{0x0e, 0x03, -1, 0x03, 0x1842, 0x0016}, + cmdLutElement{0x0e, 0x03, -1, 0x03, 0x1842, 0x001e}, + cmdLutElement{0x0e, 0x04, -1, 0x03, 0x1842, 0x0026}, + cmdLutElement{0x0e, 0x04, -1, 0x03, 0x1842, 0x0036}, + cmdLutElement{0x18, 0x01, -1, 0x03, 0x5842, 0x000a}, + cmdLutElement{0x18, 0x01, -1, 0x03, 0x5842, 0x000c}, + cmdLutElement{0x18, 0x02, -1, 0x03, 0x5842, 0x000e}, + cmdLutElement{0x18, 0x02, -1, 0x03, 0x5842, 0x0012}, + cmdLutElement{0x18, 0x03, -1, 0x03, 0x5842, 0x0016}, + cmdLutElement{0x18, 0x03, -1, 0x03, 0x5842, 0x001e}, + cmdLutElement{0x18, 0x04, -1, 0x03, 0x5842, 0x0026}, + cmdLutElement{0x18, 0x04, -1, 0x03, 0x5842, 0x0036}, + cmdLutElement{0x06, 0x05, -1, 0x03, 0x0082, 0x0046}, + cmdLutElement{0x06, 0x05, -1, 0x03, 0x0082, 0x0066}, + cmdLutElement{0x06, 0x06, -1, 0x03, 0x0082, 0x0086}, + cmdLutElement{0x06, 0x07, -1, 0x03, 0x0082, 0x00c6}, + cmdLutElement{0x06, 0x08, -1, 0x03, 0x0082, 0x0146}, + cmdLutElement{0x06, 0x09, -1, 0x03, 0x0082, 0x0246}, + cmdLutElement{0x06, 0x0a, -1, 0x03, 0x0082, 0x0446}, + cmdLutElement{0x06, 0x18, -1, 0x03, 0x0082, 0x0846}, + cmdLutElement{0x07, 0x05, -1, 0x03, 0x00c2, 0x0046}, + cmdLutElement{0x07, 0x05, -1, 0x03, 0x00c2, 0x0066}, + cmdLutElement{0x07, 0x06, -1, 0x03, 0x00c2, 0x0086}, + cmdLutElement{0x07, 0x07, -1, 0x03, 0x00c2, 0x00c6}, + cmdLutElement{0x07, 0x08, -1, 0x03, 0x00c2, 0x0146}, + cmdLutElement{0x07, 0x09, -1, 0x03, 0x00c2, 0x0246}, + cmdLutElement{0x07, 0x0a, -1, 0x03, 0x00c2, 0x0446}, + cmdLutElement{0x07, 0x18, -1, 0x03, 0x00c2, 0x0846}, + cmdLutElement{0x08, 0x05, -1, 0x03, 0x0142, 0x0046}, + cmdLutElement{0x08, 0x05, -1, 0x03, 0x0142, 0x0066}, + cmdLutElement{0x08, 0x06, -1, 0x03, 0x0142, 0x0086}, + cmdLutElement{0x08, 0x07, -1, 0x03, 0x0142, 0x00c6}, + cmdLutElement{0x08, 0x08, -1, 0x03, 0x0142, 0x0146}, + cmdLutElement{0x08, 0x09, -1, 0x03, 0x0142, 0x0246}, + cmdLutElement{0x08, 0x0a, -1, 0x03, 0x0142, 0x0446}, + cmdLutElement{0x08, 0x18, -1, 0x03, 0x0142, 0x0846}, + cmdLutElement{0x09, 0x05, -1, 0x03, 0x0242, 0x0046}, + cmdLutElement{0x09, 0x05, -1, 0x03, 0x0242, 0x0066}, + cmdLutElement{0x09, 0x06, -1, 0x03, 0x0242, 0x0086}, + cmdLutElement{0x09, 0x07, -1, 0x03, 0x0242, 0x00c6}, + cmdLutElement{0x09, 0x08, -1, 0x03, 0x0242, 0x0146}, + cmdLutElement{0x09, 0x09, -1, 0x03, 0x0242, 0x0246}, + cmdLutElement{0x09, 0x0a, -1, 0x03, 0x0242, 0x0446}, + cmdLutElement{0x09, 0x18, -1, 0x03, 0x0242, 0x0846}, + cmdLutElement{0x0a, 0x05, -1, 0x03, 0x0442, 0x0046}, + cmdLutElement{0x0a, 0x05, -1, 0x03, 0x0442, 0x0066}, + cmdLutElement{0x0a, 0x06, -1, 0x03, 0x0442, 0x0086}, + cmdLutElement{0x0a, 0x07, -1, 0x03, 0x0442, 0x00c6}, + cmdLutElement{0x0a, 0x08, -1, 0x03, 0x0442, 0x0146}, + cmdLutElement{0x0a, 0x09, -1, 0x03, 0x0442, 0x0246}, + cmdLutElement{0x0a, 0x0a, -1, 0x03, 0x0442, 0x0446}, + cmdLutElement{0x0a, 0x18, -1, 0x03, 0x0442, 0x0846}, + cmdLutElement{0x0c, 0x05, -1, 0x03, 0x0842, 0x0046}, + cmdLutElement{0x0c, 0x05, -1, 0x03, 0x0842, 0x0066}, + cmdLutElement{0x0c, 0x06, -1, 0x03, 0x0842, 0x0086}, + cmdLutElement{0x0c, 0x07, -1, 0x03, 0x0842, 0x00c6}, + cmdLutElement{0x0c, 0x08, -1, 0x03, 0x0842, 0x0146}, + cmdLutElement{0x0c, 0x09, -1, 0x03, 0x0842, 0x0246}, + cmdLutElement{0x0c, 0x0a, -1, 0x03, 0x0842, 0x0446}, + cmdLutElement{0x0c, 0x18, -1, 0x03, 0x0842, 0x0846}, + cmdLutElement{0x0e, 0x05, -1, 0x03, 0x1842, 0x0046}, + cmdLutElement{0x0e, 0x05, -1, 0x03, 0x1842, 0x0066}, + cmdLutElement{0x0e, 0x06, -1, 0x03, 0x1842, 0x0086}, + cmdLutElement{0x0e, 0x07, -1, 0x03, 0x1842, 0x00c6}, + cmdLutElement{0x0e, 0x08, -1, 0x03, 0x1842, 0x0146}, + cmdLutElement{0x0e, 0x09, -1, 0x03, 0x1842, 0x0246}, + cmdLutElement{0x0e, 0x0a, -1, 0x03, 0x1842, 0x0446}, + cmdLutElement{0x0e, 0x18, -1, 0x03, 0x1842, 0x0846}, + cmdLutElement{0x18, 0x05, -1, 0x03, 0x5842, 0x0046}, + cmdLutElement{0x18, 0x05, -1, 0x03, 0x5842, 0x0066}, + cmdLutElement{0x18, 0x06, -1, 0x03, 0x5842, 0x0086}, + cmdLutElement{0x18, 0x07, -1, 0x03, 0x5842, 0x00c6}, + cmdLutElement{0x18, 0x08, -1, 0x03, 0x5842, 0x0146}, + cmdLutElement{0x18, 0x09, -1, 0x03, 0x5842, 0x0246}, + cmdLutElement{0x18, 0x0a, -1, 0x03, 0x5842, 0x0446}, + cmdLutElement{0x18, 0x18, -1, 0x03, 0x5842, 0x0846}, +} diff --git a/vendor/github.com/andybalholm/brotli/quality.go b/vendor/github.com/andybalholm/brotli/quality.go new file mode 100644 index 0000000..49709a3 --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/quality.go @@ -0,0 +1,196 @@ +package brotli + +const fastOnePassCompressionQuality = 0 + +const fastTwoPassCompressionQuality = 1 + +const zopflificationQuality = 10 + +const hqZopflificationQuality = 11 + +const maxQualityForStaticEntropyCodes = 2 + +const minQualityForBlockSplit = 4 + +const minQualityForNonzeroDistanceParams = 4 + +const minQualityForOptimizeHistograms = 4 + +const minQualityForExtensiveReferenceSearch = 5 + +const minQualityForContextModeling = 5 + +const minQualityForHqContextModeling = 7 + +const minQualityForHqBlockSplitting = 10 + +/* For quality below MIN_QUALITY_FOR_BLOCK_SPLIT there is no block splitting, + so we buffer at most this much literals and commands. */ +const maxNumDelayedSymbols = 0x2FFF + +/* Returns hash-table size for quality levels 0 and 1. */ +func maxHashTableSize(quality int) uint { + if quality == fastOnePassCompressionQuality { + return 1 << 15 + } else { + return 1 << 17 + } +} + +/* The maximum length for which the zopflification uses distinct distances. */ +const maxZopfliLenQuality10 = 150 + +const maxZopfliLenQuality11 = 325 + +/* Do not thoroughly search when a long copy is found. */ +const longCopyQuickStep = 16384 + +func maxZopfliLen(params *encoderParams) uint { + if params.quality <= 10 { + return maxZopfliLenQuality10 + } else { + return maxZopfliLenQuality11 + } +} + +/* Number of best candidates to evaluate to expand Zopfli chain. */ +func maxZopfliCandidates(params *encoderParams) uint { + if params.quality <= 10 { + return 1 + } else { + return 5 + } +} + +func sanitizeParams(params *encoderParams) { + params.quality = brotli_min_int(maxQuality, brotli_max_int(minQuality, params.quality)) + if params.quality <= maxQualityForStaticEntropyCodes { + params.large_window = false + } + + if params.lgwin < minWindowBits { + params.lgwin = minWindowBits + } else { + var max_lgwin int + if params.large_window { + max_lgwin = largeMaxWindowBits + } else { + max_lgwin = maxWindowBits + } + if params.lgwin > uint(max_lgwin) { + params.lgwin = uint(max_lgwin) + } + } +} + +/* Returns optimized lg_block value. */ +func computeLgBlock(params *encoderParams) int { + var lgblock int = params.lgblock + if params.quality == fastOnePassCompressionQuality || params.quality == fastTwoPassCompressionQuality { + lgblock = int(params.lgwin) + } else if params.quality < minQualityForBlockSplit { + lgblock = 14 + } else if lgblock == 0 { + lgblock = 16 + if params.quality >= 9 && params.lgwin > uint(lgblock) { + lgblock = brotli_min_int(18, int(params.lgwin)) + } + } else { + lgblock = brotli_min_int(maxInputBlockBits, brotli_max_int(minInputBlockBits, lgblock)) + } + + return lgblock +} + +/* Returns log2 of the size of main ring buffer area. + Allocate at least lgwin + 1 bits for the ring buffer so that the newly + added block fits there completely and we still get lgwin bits and at least + read_block_size_bits + 1 bits because the copy tail length needs to be + smaller than ring-buffer size. */ +func computeRbBits(params *encoderParams) int { + return 1 + brotli_max_int(int(params.lgwin), params.lgblock) +} + +func maxMetablockSize(params *encoderParams) uint { + var bits int = brotli_min_int(computeRbBits(params), maxInputBlockBits) + return uint(1) << uint(bits) +} + +/* When searching for backward references and have not seen matches for a long + time, we can skip some match lookups. Unsuccessful match lookups are very + expensive and this kind of a heuristic speeds up compression quite a lot. + At first 8 byte strides are taken and every second byte is put to hasher. + After 4x more literals stride by 16 bytes, every put 4-th byte to hasher. + Applied only to qualities 2 to 9. */ +func literalSpreeLengthForSparseSearch(params *encoderParams) uint { + if params.quality < 9 { + return 64 + } else { + return 512 + } +} + +func chooseHasher(params *encoderParams, hparams *hasherParams) { + if params.quality > 9 { + hparams.type_ = 10 + } else if params.quality == 4 && params.size_hint >= 1<<20 { + hparams.type_ = 54 + } else if params.quality < 5 { + hparams.type_ = params.quality + } else if params.lgwin <= 16 { + if params.quality < 7 { + hparams.type_ = 40 + } else if params.quality < 9 { + hparams.type_ = 41 + } else { + hparams.type_ = 42 + } + } else if params.size_hint >= 1<<20 && params.lgwin >= 19 { + hparams.type_ = 6 + hparams.block_bits = params.quality - 1 + hparams.bucket_bits = 15 + hparams.hash_len = 5 + if params.quality < 7 { + hparams.num_last_distances_to_check = 4 + } else if params.quality < 9 { + hparams.num_last_distances_to_check = 10 + } else { + hparams.num_last_distances_to_check = 16 + } + } else { + hparams.type_ = 5 + hparams.block_bits = params.quality - 1 + if params.quality < 7 { + hparams.bucket_bits = 14 + } else { + hparams.bucket_bits = 15 + } + if params.quality < 7 { + hparams.num_last_distances_to_check = 4 + } else if params.quality < 9 { + hparams.num_last_distances_to_check = 10 + } else { + hparams.num_last_distances_to_check = 16 + } + } + + if params.lgwin > 24 { + /* Different hashers for large window brotli: not for qualities <= 2, + these are too fast for large window. Not for qualities >= 10: their + hasher already works well with large window. So the changes are: + H3 --> H35: for quality 3. + H54 --> H55: for quality 4 with size hint > 1MB + H6 --> H65: for qualities 5, 6, 7, 8, 9. */ + if hparams.type_ == 3 { + hparams.type_ = 35 + } + + if hparams.type_ == 54 { + hparams.type_ = 55 + } + + if hparams.type_ == 6 { + hparams.type_ = 65 + } + } +} diff --git a/vendor/github.com/andybalholm/brotli/reader.go b/vendor/github.com/andybalholm/brotli/reader.go new file mode 100644 index 0000000..9419c79 --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/reader.go @@ -0,0 +1,108 @@ +package brotli + +import ( + "errors" + "io" +) + +type decodeError int + +func (err decodeError) Error() string { + return "brotli: " + string(decoderErrorString(int(err))) +} + +var errExcessiveInput = errors.New("brotli: excessive input") +var errInvalidState = errors.New("brotli: invalid state") + +// readBufSize is a "good" buffer size that avoids excessive round-trips +// between C and Go but doesn't waste too much memory on buffering. +// It is arbitrarily chosen to be equal to the constant used in io.Copy. +const readBufSize = 32 * 1024 + +// NewReader creates a new Reader reading the given reader. +func NewReader(src io.Reader) *Reader { + r := new(Reader) + r.Reset(src) + return r +} + +// Reset discards the Reader's state and makes it equivalent to the result of +// its original state from NewReader, but reading from src instead. +// This permits reusing a Reader rather than allocating a new one. +// Error is always nil +func (r *Reader) Reset(src io.Reader) error { + if r.error_code < 0 { + // There was an unrecoverable error, leaving the Reader's state + // undefined. Clear out everything but the buffer. + *r = Reader{buf: r.buf} + } + + decoderStateInit(r) + r.src = src + if r.buf == nil { + r.buf = make([]byte, readBufSize) + } + return nil +} + +func (r *Reader) Read(p []byte) (n int, err error) { + if !decoderHasMoreOutput(r) && len(r.in) == 0 { + m, readErr := r.src.Read(r.buf) + if m == 0 { + // If readErr is `nil`, we just proxy underlying stream behavior. + return 0, readErr + } + r.in = r.buf[:m] + } + + if len(p) == 0 { + return 0, nil + } + + for { + var written uint + in_len := uint(len(r.in)) + out_len := uint(len(p)) + in_remaining := in_len + out_remaining := out_len + result := decoderDecompressStream(r, &in_remaining, &r.in, &out_remaining, &p) + written = out_len - out_remaining + n = int(written) + + switch result { + case decoderResultSuccess: + if len(r.in) > 0 { + return n, errExcessiveInput + } + return n, nil + case decoderResultError: + return n, decodeError(decoderGetErrorCode(r)) + case decoderResultNeedsMoreOutput: + if n == 0 { + return 0, io.ErrShortBuffer + } + return n, nil + case decoderNeedsMoreInput: + } + + if len(r.in) != 0 { + return 0, errInvalidState + } + + // Calling r.src.Read may block. Don't block if we have data to return. + if n > 0 { + return n, nil + } + + // Top off the buffer. + encN, err := r.src.Read(r.buf) + if encN == 0 { + // Not enough data to complete decoding. + if err == io.EOF { + return 0, io.ErrUnexpectedEOF + } + return 0, err + } + r.in = r.buf[:encN] + } +} diff --git a/vendor/github.com/andybalholm/brotli/ringbuffer.go b/vendor/github.com/andybalholm/brotli/ringbuffer.go new file mode 100644 index 0000000..1c8f86f --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/ringbuffer.go @@ -0,0 +1,134 @@ +package brotli + +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* A ringBuffer(window_bits, tail_bits) contains `1 << window_bits' bytes of + data in a circular manner: writing a byte writes it to: + `position() % (1 << window_bits)'. + For convenience, the ringBuffer array contains another copy of the + first `1 << tail_bits' bytes: + buffer_[i] == buffer_[i + (1 << window_bits)], if i < (1 << tail_bits), + and another copy of the last two bytes: + buffer_[-1] == buffer_[(1 << window_bits) - 1] and + buffer_[-2] == buffer_[(1 << window_bits) - 2]. */ +type ringBuffer struct { + size_ uint32 + mask_ uint32 + tail_size_ uint32 + total_size_ uint32 + cur_size_ uint32 + pos_ uint32 + data_ []byte + buffer_ []byte +} + +func ringBufferInit(rb *ringBuffer) { + rb.pos_ = 0 +} + +func ringBufferSetup(params *encoderParams, rb *ringBuffer) { + var window_bits int = computeRbBits(params) + var tail_bits int = params.lgblock + *(*uint32)(&rb.size_) = 1 << uint(window_bits) + *(*uint32)(&rb.mask_) = (1 << uint(window_bits)) - 1 + *(*uint32)(&rb.tail_size_) = 1 << uint(tail_bits) + *(*uint32)(&rb.total_size_) = rb.size_ + rb.tail_size_ +} + +const kSlackForEightByteHashingEverywhere uint = 7 + +/* Allocates or re-allocates data_ to the given length + plus some slack + region before and after. Fills the slack regions with zeros. */ +func ringBufferInitBuffer(buflen uint32, rb *ringBuffer) { + var new_data []byte + var i uint + size := 2 + int(buflen) + int(kSlackForEightByteHashingEverywhere) + if cap(rb.data_) < size { + new_data = make([]byte, size) + } else { + new_data = rb.data_[:size] + } + if rb.data_ != nil { + copy(new_data, rb.data_[:2+rb.cur_size_+uint32(kSlackForEightByteHashingEverywhere)]) + } + + rb.data_ = new_data + rb.cur_size_ = buflen + rb.buffer_ = rb.data_[2:] + rb.data_[1] = 0 + rb.data_[0] = rb.data_[1] + for i = 0; i < kSlackForEightByteHashingEverywhere; i++ { + rb.buffer_[rb.cur_size_+uint32(i)] = 0 + } +} + +func ringBufferWriteTail(bytes []byte, n uint, rb *ringBuffer) { + var masked_pos uint = uint(rb.pos_ & rb.mask_) + if uint32(masked_pos) < rb.tail_size_ { + /* Just fill the tail buffer with the beginning data. */ + var p uint = uint(rb.size_ + uint32(masked_pos)) + copy(rb.buffer_[p:], bytes[:brotli_min_size_t(n, uint(rb.tail_size_-uint32(masked_pos)))]) + } +} + +/* Push bytes into the ring buffer. */ +func ringBufferWrite(bytes []byte, n uint, rb *ringBuffer) { + if rb.pos_ == 0 && uint32(n) < rb.tail_size_ { + /* Special case for the first write: to process the first block, we don't + need to allocate the whole ring-buffer and we don't need the tail + either. However, we do this memory usage optimization only if the + first write is less than the tail size, which is also the input block + size, otherwise it is likely that other blocks will follow and we + will need to reallocate to the full size anyway. */ + rb.pos_ = uint32(n) + + ringBufferInitBuffer(rb.pos_, rb) + copy(rb.buffer_, bytes[:n]) + return + } + + if rb.cur_size_ < rb.total_size_ { + /* Lazily allocate the full buffer. */ + ringBufferInitBuffer(rb.total_size_, rb) + + /* Initialize the last two bytes to zero, so that we don't have to worry + later when we copy the last two bytes to the first two positions. */ + rb.buffer_[rb.size_-2] = 0 + + rb.buffer_[rb.size_-1] = 0 + } + { + var masked_pos uint = uint(rb.pos_ & rb.mask_) + + /* The length of the writes is limited so that we do not need to worry + about a write */ + ringBufferWriteTail(bytes, n, rb) + + if uint32(masked_pos+n) <= rb.size_ { + /* A single write fits. */ + copy(rb.buffer_[masked_pos:], bytes[:n]) + } else { + /* Split into two writes. + Copy into the end of the buffer, including the tail buffer. */ + copy(rb.buffer_[masked_pos:], bytes[:brotli_min_size_t(n, uint(rb.total_size_-uint32(masked_pos)))]) + + /* Copy into the beginning of the buffer */ + copy(rb.buffer_, bytes[rb.size_-uint32(masked_pos):][:uint32(n)-(rb.size_-uint32(masked_pos))]) + } + } + { + var not_first_lap bool = rb.pos_&(1<<31) != 0 + var rb_pos_mask uint32 = (1 << 31) - 1 + rb.data_[0] = rb.buffer_[rb.size_-2] + rb.data_[1] = rb.buffer_[rb.size_-1] + rb.pos_ = (rb.pos_ & rb_pos_mask) + uint32(uint32(n)&rb_pos_mask) + if not_first_lap { + /* Wrap, but preserve not-a-first-lap feature. */ + rb.pos_ |= 1 << 31 + } + } +} diff --git a/vendor/github.com/andybalholm/brotli/state.go b/vendor/github.com/andybalholm/brotli/state.go new file mode 100644 index 0000000..38d753e --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/state.go @@ -0,0 +1,294 @@ +package brotli + +import "io" + +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Brotli state for partial streaming decoding. */ +const ( + stateUninited = iota + stateLargeWindowBits + stateInitialize + stateMetablockBegin + stateMetablockHeader + stateMetablockHeader2 + stateContextModes + stateCommandBegin + stateCommandInner + stateCommandPostDecodeLiterals + stateCommandPostWrapCopy + stateUncompressed + stateMetadata + stateCommandInnerWrite + stateMetablockDone + stateCommandPostWrite1 + stateCommandPostWrite2 + stateHuffmanCode0 + stateHuffmanCode1 + stateHuffmanCode2 + stateHuffmanCode3 + stateContextMap1 + stateContextMap2 + stateTreeGroup + stateDone +) + +const ( + stateMetablockHeaderNone = iota + stateMetablockHeaderEmpty + stateMetablockHeaderNibbles + stateMetablockHeaderSize + stateMetablockHeaderUncompressed + stateMetablockHeaderReserved + stateMetablockHeaderBytes + stateMetablockHeaderMetadata +) + +const ( + stateUncompressedNone = iota + stateUncompressedWrite +) + +const ( + stateTreeGroupNone = iota + stateTreeGroupLoop +) + +const ( + stateContextMapNone = iota + stateContextMapReadPrefix + stateContextMapHuffman + stateContextMapDecode + stateContextMapTransform +) + +const ( + stateHuffmanNone = iota + stateHuffmanSimpleSize + stateHuffmanSimpleRead + stateHuffmanSimpleBuild + stateHuffmanComplex + stateHuffmanLengthSymbols +) + +const ( + stateDecodeUint8None = iota + stateDecodeUint8Short + stateDecodeUint8Long +) + +const ( + stateReadBlockLengthNone = iota + stateReadBlockLengthSuffix +) + +type Reader struct { + src io.Reader + buf []byte // scratch space for reading from src + in []byte // current chunk to decode; usually aliases buf + + state int + loop_counter int + br bitReader + buffer struct { + u64 uint64 + u8 [8]byte + } + buffer_length uint32 + pos int + max_backward_distance int + max_distance int + ringbuffer_size int + ringbuffer_mask int + dist_rb_idx int + dist_rb [4]int + error_code int + sub_loop_counter uint32 + ringbuffer []byte + ringbuffer_end []byte + htree_command []huffmanCode + context_lookup []byte + context_map_slice []byte + dist_context_map_slice []byte + literal_hgroup huffmanTreeGroup + insert_copy_hgroup huffmanTreeGroup + distance_hgroup huffmanTreeGroup + block_type_trees []huffmanCode + block_len_trees []huffmanCode + trivial_literal_context int + distance_context int + meta_block_remaining_len int + block_length_index uint32 + block_length [3]uint32 + num_block_types [3]uint32 + block_type_rb [6]uint32 + distance_postfix_bits uint32 + num_direct_distance_codes uint32 + distance_postfix_mask int + num_dist_htrees uint32 + dist_context_map []byte + literal_htree []huffmanCode + dist_htree_index byte + repeat_code_len uint32 + prev_code_len uint32 + copy_length int + distance_code int + rb_roundtrips uint + partial_pos_out uint + symbol uint32 + repeat uint32 + space uint32 + table [32]huffmanCode + symbol_lists symbolList + symbols_lists_array [huffmanMaxCodeLength + 1 + numCommandSymbols]uint16 + next_symbol [32]int + code_length_code_lengths [codeLengthCodes]byte + code_length_histo [16]uint16 + htree_index int + next []huffmanCode + context_index uint32 + max_run_length_prefix uint32 + code uint32 + context_map_table [huffmanMaxSize272]huffmanCode + substate_metablock_header int + substate_tree_group int + substate_context_map int + substate_uncompressed int + substate_huffman int + substate_decode_uint8 int + substate_read_block_length int + is_last_metablock uint + is_uncompressed uint + is_metadata uint + should_wrap_ringbuffer uint + canny_ringbuffer_allocation uint + large_window bool + size_nibbles uint + window_bits uint32 + new_ringbuffer_size int + num_literal_htrees uint32 + context_map []byte + context_modes []byte + dictionary *dictionary + transforms *transforms + trivial_literal_contexts [8]uint32 +} + +func decoderStateInit(s *Reader) bool { + s.error_code = 0 /* BROTLI_DECODER_NO_ERROR */ + + initBitReader(&s.br) + s.state = stateUninited + s.large_window = false + s.substate_metablock_header = stateMetablockHeaderNone + s.substate_tree_group = stateTreeGroupNone + s.substate_context_map = stateContextMapNone + s.substate_uncompressed = stateUncompressedNone + s.substate_huffman = stateHuffmanNone + s.substate_decode_uint8 = stateDecodeUint8None + s.substate_read_block_length = stateReadBlockLengthNone + + s.buffer_length = 0 + s.loop_counter = 0 + s.pos = 0 + s.rb_roundtrips = 0 + s.partial_pos_out = 0 + + s.block_type_trees = nil + s.block_len_trees = nil + s.ringbuffer_size = 0 + s.new_ringbuffer_size = 0 + s.ringbuffer_mask = 0 + + s.context_map = nil + s.context_modes = nil + s.dist_context_map = nil + s.context_map_slice = nil + s.dist_context_map_slice = nil + + s.sub_loop_counter = 0 + + s.literal_hgroup.codes = nil + s.literal_hgroup.htrees = nil + s.insert_copy_hgroup.codes = nil + s.insert_copy_hgroup.htrees = nil + s.distance_hgroup.codes = nil + s.distance_hgroup.htrees = nil + + s.is_last_metablock = 0 + s.is_uncompressed = 0 + s.is_metadata = 0 + s.should_wrap_ringbuffer = 0 + s.canny_ringbuffer_allocation = 1 + + s.window_bits = 0 + s.max_distance = 0 + s.dist_rb[0] = 16 + s.dist_rb[1] = 15 + s.dist_rb[2] = 11 + s.dist_rb[3] = 4 + s.dist_rb_idx = 0 + s.block_type_trees = nil + s.block_len_trees = nil + + s.symbol_lists.storage = s.symbols_lists_array[:] + s.symbol_lists.offset = huffmanMaxCodeLength + 1 + + s.dictionary = getDictionary() + s.transforms = getTransforms() + + return true +} + +func decoderStateMetablockBegin(s *Reader) { + s.meta_block_remaining_len = 0 + s.block_length[0] = 1 << 24 + s.block_length[1] = 1 << 24 + s.block_length[2] = 1 << 24 + s.num_block_types[0] = 1 + s.num_block_types[1] = 1 + s.num_block_types[2] = 1 + s.block_type_rb[0] = 1 + s.block_type_rb[1] = 0 + s.block_type_rb[2] = 1 + s.block_type_rb[3] = 0 + s.block_type_rb[4] = 1 + s.block_type_rb[5] = 0 + s.context_map = nil + s.context_modes = nil + s.dist_context_map = nil + s.context_map_slice = nil + s.literal_htree = nil + s.dist_context_map_slice = nil + s.dist_htree_index = 0 + s.context_lookup = nil + s.literal_hgroup.codes = nil + s.literal_hgroup.htrees = nil + s.insert_copy_hgroup.codes = nil + s.insert_copy_hgroup.htrees = nil + s.distance_hgroup.codes = nil + s.distance_hgroup.htrees = nil +} + +func decoderStateCleanupAfterMetablock(s *Reader) { + s.context_modes = nil + s.context_map = nil + s.dist_context_map = nil + s.literal_hgroup.htrees = nil + s.insert_copy_hgroup.htrees = nil + s.distance_hgroup.htrees = nil +} + +func decoderHuffmanTreeGroupInit(s *Reader, group *huffmanTreeGroup, alphabet_size uint32, max_symbol uint32, ntrees uint32) bool { + var max_table_size uint = uint(kMaxHuffmanTableSize[(alphabet_size+31)>>5]) + group.alphabet_size = uint16(alphabet_size) + group.max_symbol = uint16(max_symbol) + group.num_htrees = uint16(ntrees) + group.htrees = make([][]huffmanCode, ntrees) + group.codes = make([]huffmanCode, (uint(ntrees) * max_table_size)) + return !(group.codes == nil) +} diff --git a/vendor/github.com/andybalholm/brotli/static_dict.go b/vendor/github.com/andybalholm/brotli/static_dict.go new file mode 100644 index 0000000..bc05566 --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/static_dict.go @@ -0,0 +1,662 @@ +package brotli + +import "encoding/binary" + +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Class to model the static dictionary. */ + +const maxStaticDictionaryMatchLen = 37 + +const kInvalidMatch uint32 = 0xFFFFFFF + +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ +func hash(data []byte) uint32 { + var h uint32 = binary.LittleEndian.Uint32(data) * kDictHashMul32 + + /* The higher bits contain more mixture from the multiplication, + so we take our results from there. */ + return h >> uint(32-kDictNumBits) +} + +func addMatch(distance uint, len uint, len_code uint, matches []uint32) { + var match uint32 = uint32((distance << 5) + len_code) + matches[len] = brotli_min_uint32_t(matches[len], match) +} + +func dictMatchLength(dict *dictionary, data []byte, id uint, len uint, maxlen uint) uint { + var offset uint = uint(dict.offsets_by_length[len]) + len*id + return findMatchLengthWithLimit(dict.data[offset:], data, brotli_min_size_t(uint(len), maxlen)) +} + +func isMatch(d *dictionary, w dictWord, data []byte, max_length uint) bool { + if uint(w.len) > max_length { + return false + } else { + var offset uint = uint(d.offsets_by_length[w.len]) + uint(w.len)*uint(w.idx) + var dict []byte = d.data[offset:] + if w.transform == 0 { + /* Match against base dictionary word. */ + return findMatchLengthWithLimit(dict, data, uint(w.len)) == uint(w.len) + } else if w.transform == 10 { + /* Match against uppercase first transform. + Note that there are only ASCII uppercase words in the lookup table. */ + return dict[0] >= 'a' && dict[0] <= 'z' && (dict[0]^32) == data[0] && findMatchLengthWithLimit(dict[1:], data[1:], uint(w.len)-1) == uint(w.len-1) + } else { + /* Match against uppercase all transform. + Note that there are only ASCII uppercase words in the lookup table. */ + var i uint + for i = 0; i < uint(w.len); i++ { + if dict[i] >= 'a' && dict[i] <= 'z' { + if (dict[i] ^ 32) != data[i] { + return false + } + } else { + if dict[i] != data[i] { + return false + } + } + } + + return true + } + } +} + +func findAllStaticDictionaryMatches(dict *encoderDictionary, data []byte, min_length uint, max_length uint, matches []uint32) bool { + var has_found_match bool = false + { + var offset uint = uint(dict.buckets[hash(data)]) + var end bool = offset == 0 + for !end { + w := dict.dict_words[offset] + offset++ + var l uint = uint(w.len) & 0x1F + var n uint = uint(1) << dict.words.size_bits_by_length[l] + var id uint = uint(w.idx) + end = !(w.len&0x80 == 0) + w.len = byte(l) + if w.transform == 0 { + var matchlen uint = dictMatchLength(dict.words, data, id, l, max_length) + var s []byte + var minlen uint + var maxlen uint + var len uint + + /* Transform "" + BROTLI_TRANSFORM_IDENTITY + "" */ + if matchlen == l { + addMatch(id, l, l, matches) + has_found_match = true + } + + /* Transforms "" + BROTLI_TRANSFORM_OMIT_LAST_1 + "" and + "" + BROTLI_TRANSFORM_OMIT_LAST_1 + "ing " */ + if matchlen >= l-1 { + addMatch(id+12*n, l-1, l, matches) + if l+2 < max_length && data[l-1] == 'i' && data[l] == 'n' && data[l+1] == 'g' && data[l+2] == ' ' { + addMatch(id+49*n, l+3, l, matches) + } + + has_found_match = true + } + + /* Transform "" + BROTLI_TRANSFORM_OMIT_LAST_# + "" (# = 2 .. 9) */ + minlen = min_length + + if l > 9 { + minlen = brotli_max_size_t(minlen, l-9) + } + maxlen = brotli_min_size_t(matchlen, l-2) + for len = minlen; len <= maxlen; len++ { + var cut uint = l - len + var transform_id uint = (cut << 2) + uint((dict.cutoffTransforms>>(cut*6))&0x3F) + addMatch(id+transform_id*n, uint(len), l, matches) + has_found_match = true + } + + if matchlen < l || l+6 >= max_length { + continue + } + + s = data[l:] + + /* Transforms "" + BROTLI_TRANSFORM_IDENTITY + */ + if s[0] == ' ' { + addMatch(id+n, l+1, l, matches) + if s[1] == 'a' { + if s[2] == ' ' { + addMatch(id+28*n, l+3, l, matches) + } else if s[2] == 's' { + if s[3] == ' ' { + addMatch(id+46*n, l+4, l, matches) + } + } else if s[2] == 't' { + if s[3] == ' ' { + addMatch(id+60*n, l+4, l, matches) + } + } else if s[2] == 'n' { + if s[3] == 'd' && s[4] == ' ' { + addMatch(id+10*n, l+5, l, matches) + } + } + } else if s[1] == 'b' { + if s[2] == 'y' && s[3] == ' ' { + addMatch(id+38*n, l+4, l, matches) + } + } else if s[1] == 'i' { + if s[2] == 'n' { + if s[3] == ' ' { + addMatch(id+16*n, l+4, l, matches) + } + } else if s[2] == 's' { + if s[3] == ' ' { + addMatch(id+47*n, l+4, l, matches) + } + } + } else if s[1] == 'f' { + if s[2] == 'o' { + if s[3] == 'r' && s[4] == ' ' { + addMatch(id+25*n, l+5, l, matches) + } + } else if s[2] == 'r' { + if s[3] == 'o' && s[4] == 'm' && s[5] == ' ' { + addMatch(id+37*n, l+6, l, matches) + } + } + } else if s[1] == 'o' { + if s[2] == 'f' { + if s[3] == ' ' { + addMatch(id+8*n, l+4, l, matches) + } + } else if s[2] == 'n' { + if s[3] == ' ' { + addMatch(id+45*n, l+4, l, matches) + } + } + } else if s[1] == 'n' { + if s[2] == 'o' && s[3] == 't' && s[4] == ' ' { + addMatch(id+80*n, l+5, l, matches) + } + } else if s[1] == 't' { + if s[2] == 'h' { + if s[3] == 'e' { + if s[4] == ' ' { + addMatch(id+5*n, l+5, l, matches) + } + } else if s[3] == 'a' { + if s[4] == 't' && s[5] == ' ' { + addMatch(id+29*n, l+6, l, matches) + } + } + } else if s[2] == 'o' { + if s[3] == ' ' { + addMatch(id+17*n, l+4, l, matches) + } + } + } else if s[1] == 'w' { + if s[2] == 'i' && s[3] == 't' && s[4] == 'h' && s[5] == ' ' { + addMatch(id+35*n, l+6, l, matches) + } + } + } else if s[0] == '"' { + addMatch(id+19*n, l+1, l, matches) + if s[1] == '>' { + addMatch(id+21*n, l+2, l, matches) + } + } else if s[0] == '.' { + addMatch(id+20*n, l+1, l, matches) + if s[1] == ' ' { + addMatch(id+31*n, l+2, l, matches) + if s[2] == 'T' && s[3] == 'h' { + if s[4] == 'e' { + if s[5] == ' ' { + addMatch(id+43*n, l+6, l, matches) + } + } else if s[4] == 'i' { + if s[5] == 's' && s[6] == ' ' { + addMatch(id+75*n, l+7, l, matches) + } + } + } + } + } else if s[0] == ',' { + addMatch(id+76*n, l+1, l, matches) + if s[1] == ' ' { + addMatch(id+14*n, l+2, l, matches) + } + } else if s[0] == '\n' { + addMatch(id+22*n, l+1, l, matches) + if s[1] == '\t' { + addMatch(id+50*n, l+2, l, matches) + } + } else if s[0] == ']' { + addMatch(id+24*n, l+1, l, matches) + } else if s[0] == '\'' { + addMatch(id+36*n, l+1, l, matches) + } else if s[0] == ':' { + addMatch(id+51*n, l+1, l, matches) + } else if s[0] == '(' { + addMatch(id+57*n, l+1, l, matches) + } else if s[0] == '=' { + if s[1] == '"' { + addMatch(id+70*n, l+2, l, matches) + } else if s[1] == '\'' { + addMatch(id+86*n, l+2, l, matches) + } + } else if s[0] == 'a' { + if s[1] == 'l' && s[2] == ' ' { + addMatch(id+84*n, l+3, l, matches) + } + } else if s[0] == 'e' { + if s[1] == 'd' { + if s[2] == ' ' { + addMatch(id+53*n, l+3, l, matches) + } + } else if s[1] == 'r' { + if s[2] == ' ' { + addMatch(id+82*n, l+3, l, matches) + } + } else if s[1] == 's' { + if s[2] == 't' && s[3] == ' ' { + addMatch(id+95*n, l+4, l, matches) + } + } + } else if s[0] == 'f' { + if s[1] == 'u' && s[2] == 'l' && s[3] == ' ' { + addMatch(id+90*n, l+4, l, matches) + } + } else if s[0] == 'i' { + if s[1] == 'v' { + if s[2] == 'e' && s[3] == ' ' { + addMatch(id+92*n, l+4, l, matches) + } + } else if s[1] == 'z' { + if s[2] == 'e' && s[3] == ' ' { + addMatch(id+100*n, l+4, l, matches) + } + } + } else if s[0] == 'l' { + if s[1] == 'e' { + if s[2] == 's' && s[3] == 's' && s[4] == ' ' { + addMatch(id+93*n, l+5, l, matches) + } + } else if s[1] == 'y' { + if s[2] == ' ' { + addMatch(id+61*n, l+3, l, matches) + } + } + } else if s[0] == 'o' { + if s[1] == 'u' && s[2] == 's' && s[3] == ' ' { + addMatch(id+106*n, l+4, l, matches) + } + } + } else { + var is_all_caps bool = (w.transform != transformUppercaseFirst) + /* Set is_all_caps=0 for BROTLI_TRANSFORM_UPPERCASE_FIRST and + is_all_caps=1 otherwise (BROTLI_TRANSFORM_UPPERCASE_ALL) + transform. */ + + var s []byte + if !isMatch(dict.words, w, data, max_length) { + continue + } + + /* Transform "" + kUppercase{First,All} + "" */ + var tmp int + if is_all_caps { + tmp = 44 + } else { + tmp = 9 + } + addMatch(id+uint(tmp)*n, l, l, matches) + + has_found_match = true + if l+1 >= max_length { + continue + } + + /* Transforms "" + kUppercase{First,All} + */ + s = data[l:] + + if s[0] == ' ' { + var tmp int + if is_all_caps { + tmp = 68 + } else { + tmp = 4 + } + addMatch(id+uint(tmp)*n, l+1, l, matches) + } else if s[0] == '"' { + var tmp int + if is_all_caps { + tmp = 87 + } else { + tmp = 66 + } + addMatch(id+uint(tmp)*n, l+1, l, matches) + if s[1] == '>' { + var tmp int + if is_all_caps { + tmp = 97 + } else { + tmp = 69 + } + addMatch(id+uint(tmp)*n, l+2, l, matches) + } + } else if s[0] == '.' { + var tmp int + if is_all_caps { + tmp = 101 + } else { + tmp = 79 + } + addMatch(id+uint(tmp)*n, l+1, l, matches) + if s[1] == ' ' { + var tmp int + if is_all_caps { + tmp = 114 + } else { + tmp = 88 + } + addMatch(id+uint(tmp)*n, l+2, l, matches) + } + } else if s[0] == ',' { + var tmp int + if is_all_caps { + tmp = 112 + } else { + tmp = 99 + } + addMatch(id+uint(tmp)*n, l+1, l, matches) + if s[1] == ' ' { + var tmp int + if is_all_caps { + tmp = 107 + } else { + tmp = 58 + } + addMatch(id+uint(tmp)*n, l+2, l, matches) + } + } else if s[0] == '\'' { + var tmp int + if is_all_caps { + tmp = 94 + } else { + tmp = 74 + } + addMatch(id+uint(tmp)*n, l+1, l, matches) + } else if s[0] == '(' { + var tmp int + if is_all_caps { + tmp = 113 + } else { + tmp = 78 + } + addMatch(id+uint(tmp)*n, l+1, l, matches) + } else if s[0] == '=' { + if s[1] == '"' { + var tmp int + if is_all_caps { + tmp = 105 + } else { + tmp = 104 + } + addMatch(id+uint(tmp)*n, l+2, l, matches) + } else if s[1] == '\'' { + var tmp int + if is_all_caps { + tmp = 116 + } else { + tmp = 108 + } + addMatch(id+uint(tmp)*n, l+2, l, matches) + } + } + } + } + } + + /* Transforms with prefixes " " and "." */ + if max_length >= 5 && (data[0] == ' ' || data[0] == '.') { + var is_space bool = (data[0] == ' ') + var offset uint = uint(dict.buckets[hash(data[1:])]) + var end bool = offset == 0 + for !end { + w := dict.dict_words[offset] + offset++ + var l uint = uint(w.len) & 0x1F + var n uint = uint(1) << dict.words.size_bits_by_length[l] + var id uint = uint(w.idx) + end = !(w.len&0x80 == 0) + w.len = byte(l) + if w.transform == 0 { + var s []byte + if !isMatch(dict.words, w, data[1:], max_length-1) { + continue + } + + /* Transforms " " + BROTLI_TRANSFORM_IDENTITY + "" and + "." + BROTLI_TRANSFORM_IDENTITY + "" */ + var tmp int + if is_space { + tmp = 6 + } else { + tmp = 32 + } + addMatch(id+uint(tmp)*n, l+1, l, matches) + + has_found_match = true + if l+2 >= max_length { + continue + } + + /* Transforms " " + BROTLI_TRANSFORM_IDENTITY + and + "." + BROTLI_TRANSFORM_IDENTITY + + */ + s = data[l+1:] + + if s[0] == ' ' { + var tmp int + if is_space { + tmp = 2 + } else { + tmp = 77 + } + addMatch(id+uint(tmp)*n, l+2, l, matches) + } else if s[0] == '(' { + var tmp int + if is_space { + tmp = 89 + } else { + tmp = 67 + } + addMatch(id+uint(tmp)*n, l+2, l, matches) + } else if is_space { + if s[0] == ',' { + addMatch(id+103*n, l+2, l, matches) + if s[1] == ' ' { + addMatch(id+33*n, l+3, l, matches) + } + } else if s[0] == '.' { + addMatch(id+71*n, l+2, l, matches) + if s[1] == ' ' { + addMatch(id+52*n, l+3, l, matches) + } + } else if s[0] == '=' { + if s[1] == '"' { + addMatch(id+81*n, l+3, l, matches) + } else if s[1] == '\'' { + addMatch(id+98*n, l+3, l, matches) + } + } + } + } else if is_space { + var is_all_caps bool = (w.transform != transformUppercaseFirst) + /* Set is_all_caps=0 for BROTLI_TRANSFORM_UPPERCASE_FIRST and + is_all_caps=1 otherwise (BROTLI_TRANSFORM_UPPERCASE_ALL) + transform. */ + + var s []byte + if !isMatch(dict.words, w, data[1:], max_length-1) { + continue + } + + /* Transforms " " + kUppercase{First,All} + "" */ + var tmp int + if is_all_caps { + tmp = 85 + } else { + tmp = 30 + } + addMatch(id+uint(tmp)*n, l+1, l, matches) + + has_found_match = true + if l+2 >= max_length { + continue + } + + /* Transforms " " + kUppercase{First,All} + */ + s = data[l+1:] + + if s[0] == ' ' { + var tmp int + if is_all_caps { + tmp = 83 + } else { + tmp = 15 + } + addMatch(id+uint(tmp)*n, l+2, l, matches) + } else if s[0] == ',' { + if !is_all_caps { + addMatch(id+109*n, l+2, l, matches) + } + + if s[1] == ' ' { + var tmp int + if is_all_caps { + tmp = 111 + } else { + tmp = 65 + } + addMatch(id+uint(tmp)*n, l+3, l, matches) + } + } else if s[0] == '.' { + var tmp int + if is_all_caps { + tmp = 115 + } else { + tmp = 96 + } + addMatch(id+uint(tmp)*n, l+2, l, matches) + if s[1] == ' ' { + var tmp int + if is_all_caps { + tmp = 117 + } else { + tmp = 91 + } + addMatch(id+uint(tmp)*n, l+3, l, matches) + } + } else if s[0] == '=' { + if s[1] == '"' { + var tmp int + if is_all_caps { + tmp = 110 + } else { + tmp = 118 + } + addMatch(id+uint(tmp)*n, l+3, l, matches) + } else if s[1] == '\'' { + var tmp int + if is_all_caps { + tmp = 119 + } else { + tmp = 120 + } + addMatch(id+uint(tmp)*n, l+3, l, matches) + } + } + } + } + } + + if max_length >= 6 { + /* Transforms with prefixes "e ", "s ", ", " and "\xC2\xA0" */ + if (data[1] == ' ' && (data[0] == 'e' || data[0] == 's' || data[0] == ',')) || (data[0] == 0xC2 && data[1] == 0xA0) { + var offset uint = uint(dict.buckets[hash(data[2:])]) + var end bool = offset == 0 + for !end { + w := dict.dict_words[offset] + offset++ + var l uint = uint(w.len) & 0x1F + var n uint = uint(1) << dict.words.size_bits_by_length[l] + var id uint = uint(w.idx) + end = !(w.len&0x80 == 0) + w.len = byte(l) + if w.transform == 0 && isMatch(dict.words, w, data[2:], max_length-2) { + if data[0] == 0xC2 { + addMatch(id+102*n, l+2, l, matches) + has_found_match = true + } else if l+2 < max_length && data[l+2] == ' ' { + var t uint = 13 + if data[0] == 'e' { + t = 18 + } else if data[0] == 's' { + t = 7 + } + addMatch(id+t*n, l+3, l, matches) + has_found_match = true + } + } + } + } + } + + if max_length >= 9 { + /* Transforms with prefixes " the " and ".com/" */ + if (data[0] == ' ' && data[1] == 't' && data[2] == 'h' && data[3] == 'e' && data[4] == ' ') || (data[0] == '.' && data[1] == 'c' && data[2] == 'o' && data[3] == 'm' && data[4] == '/') { + var offset uint = uint(dict.buckets[hash(data[5:])]) + var end bool = offset == 0 + for !end { + w := dict.dict_words[offset] + offset++ + var l uint = uint(w.len) & 0x1F + var n uint = uint(1) << dict.words.size_bits_by_length[l] + var id uint = uint(w.idx) + end = !(w.len&0x80 == 0) + w.len = byte(l) + if w.transform == 0 && isMatch(dict.words, w, data[5:], max_length-5) { + var tmp int + if data[0] == ' ' { + tmp = 41 + } else { + tmp = 72 + } + addMatch(id+uint(tmp)*n, l+5, l, matches) + has_found_match = true + if l+5 < max_length { + var s []byte = data[l+5:] + if data[0] == ' ' { + if l+8 < max_length && s[0] == ' ' && s[1] == 'o' && s[2] == 'f' && s[3] == ' ' { + addMatch(id+62*n, l+9, l, matches) + if l+12 < max_length && s[4] == 't' && s[5] == 'h' && s[6] == 'e' && s[7] == ' ' { + addMatch(id+73*n, l+13, l, matches) + } + } + } + } + } + } + } + } + + return has_found_match +} diff --git a/vendor/github.com/andybalholm/brotli/static_dict_lut.go b/vendor/github.com/andybalholm/brotli/static_dict_lut.go new file mode 100644 index 0000000..b33963e --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/static_dict_lut.go @@ -0,0 +1,75094 @@ +package brotli + +/* Copyright 2017 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Lookup table for static dictionary and transforms. */ + +type dictWord struct { + len byte + transform byte + idx uint16 +} + +const kDictNumBits int = 15 + +const kDictHashMul32 uint32 = 0x1E35A7BD + +var kStaticDictionaryBuckets = [32768]uint16{ + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3, + 6, + 0, + 0, + 0, + 0, + 0, + 20, + 0, + 0, + 0, + 21, + 0, + 22, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 23, + 0, + 0, + 25, + 0, + 29, + 0, + 53, + 0, + 0, + 0, + 0, + 0, + 0, + 55, + 0, + 0, + 0, + 0, + 0, + 0, + 61, + 76, + 0, + 0, + 0, + 94, + 0, + 0, + 0, + 0, + 0, + 0, + 96, + 0, + 97, + 0, + 98, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 99, + 101, + 106, + 108, + 0, + 0, + 0, + 0, + 0, + 110, + 0, + 111, + 112, + 0, + 113, + 118, + 124, + 0, + 0, + 0, + 0, + 0, + 125, + 128, + 0, + 0, + 0, + 0, + 129, + 0, + 0, + 131, + 0, + 0, + 0, + 0, + 0, + 0, + 132, + 0, + 0, + 135, + 0, + 0, + 0, + 137, + 0, + 0, + 0, + 0, + 0, + 138, + 139, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 142, + 143, + 144, + 0, + 0, + 0, + 0, + 0, + 145, + 0, + 0, + 0, + 146, + 149, + 151, + 152, + 0, + 0, + 153, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 154, + 0, + 0, + 0, + 0, + 0, + 0, + 155, + 0, + 0, + 0, + 0, + 160, + 182, + 0, + 0, + 0, + 0, + 0, + 0, + 183, + 0, + 0, + 0, + 188, + 189, + 0, + 0, + 192, + 0, + 0, + 0, + 0, + 0, + 0, + 194, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 197, + 202, + 209, + 0, + 0, + 210, + 0, + 224, + 0, + 0, + 0, + 225, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 231, + 0, + 0, + 0, + 232, + 0, + 240, + 0, + 0, + 242, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 244, + 0, + 0, + 0, + 246, + 0, + 0, + 249, + 251, + 253, + 0, + 0, + 0, + 0, + 0, + 258, + 0, + 0, + 261, + 263, + 0, + 0, + 0, + 267, + 0, + 0, + 268, + 0, + 269, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 271, + 0, + 0, + 0, + 0, + 0, + 0, + 272, + 0, + 273, + 0, + 277, + 0, + 278, + 286, + 0, + 0, + 0, + 0, + 287, + 0, + 289, + 290, + 291, + 0, + 0, + 0, + 295, + 0, + 0, + 296, + 297, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 298, + 0, + 0, + 0, + 299, + 0, + 0, + 305, + 0, + 324, + 0, + 0, + 0, + 0, + 0, + 327, + 0, + 328, + 329, + 0, + 0, + 0, + 0, + 336, + 0, + 0, + 340, + 0, + 341, + 342, + 343, + 0, + 0, + 346, + 0, + 348, + 0, + 0, + 0, + 0, + 0, + 0, + 349, + 351, + 0, + 0, + 355, + 0, + 363, + 0, + 364, + 0, + 368, + 369, + 0, + 370, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 372, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 373, + 0, + 375, + 0, + 0, + 0, + 0, + 376, + 377, + 0, + 0, + 394, + 395, + 396, + 0, + 0, + 398, + 0, + 0, + 0, + 0, + 400, + 0, + 0, + 408, + 0, + 0, + 0, + 0, + 420, + 0, + 0, + 0, + 0, + 0, + 0, + 421, + 0, + 0, + 422, + 423, + 0, + 0, + 429, + 435, + 436, + 442, + 0, + 0, + 443, + 0, + 444, + 445, + 453, + 456, + 0, + 457, + 0, + 0, + 0, + 0, + 0, + 458, + 0, + 0, + 0, + 459, + 0, + 0, + 0, + 460, + 0, + 462, + 463, + 465, + 0, + 0, + 0, + 0, + 0, + 0, + 466, + 469, + 0, + 0, + 0, + 0, + 0, + 0, + 470, + 0, + 0, + 0, + 474, + 0, + 476, + 0, + 0, + 0, + 0, + 483, + 0, + 485, + 0, + 0, + 0, + 486, + 0, + 0, + 488, + 491, + 492, + 0, + 0, + 497, + 499, + 500, + 0, + 501, + 0, + 0, + 0, + 505, + 0, + 0, + 506, + 0, + 0, + 0, + 507, + 0, + 0, + 0, + 509, + 0, + 0, + 0, + 0, + 511, + 512, + 519, + 0, + 0, + 0, + 0, + 0, + 0, + 529, + 530, + 0, + 0, + 0, + 534, + 0, + 0, + 0, + 0, + 543, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 553, + 0, + 0, + 0, + 0, + 557, + 560, + 0, + 0, + 0, + 0, + 0, + 0, + 561, + 0, + 564, + 0, + 0, + 0, + 0, + 0, + 0, + 565, + 566, + 0, + 575, + 0, + 619, + 0, + 620, + 0, + 0, + 623, + 624, + 0, + 0, + 0, + 625, + 0, + 0, + 626, + 627, + 0, + 0, + 628, + 0, + 0, + 0, + 0, + 630, + 0, + 631, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 641, + 0, + 0, + 0, + 0, + 643, + 656, + 668, + 0, + 0, + 0, + 673, + 0, + 0, + 0, + 674, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 682, + 0, + 687, + 0, + 690, + 0, + 693, + 699, + 700, + 0, + 0, + 0, + 0, + 0, + 0, + 704, + 705, + 0, + 0, + 0, + 0, + 707, + 710, + 0, + 711, + 0, + 0, + 0, + 0, + 726, + 0, + 0, + 729, + 0, + 0, + 0, + 730, + 731, + 0, + 0, + 0, + 0, + 0, + 752, + 0, + 0, + 0, + 762, + 0, + 763, + 0, + 0, + 767, + 0, + 0, + 0, + 770, + 774, + 0, + 0, + 775, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 776, + 0, + 0, + 0, + 777, + 783, + 0, + 0, + 0, + 785, + 788, + 0, + 0, + 0, + 0, + 790, + 0, + 0, + 0, + 793, + 0, + 0, + 0, + 0, + 794, + 0, + 0, + 804, + 819, + 821, + 0, + 827, + 0, + 0, + 0, + 834, + 0, + 0, + 835, + 0, + 0, + 0, + 841, + 0, + 844, + 0, + 850, + 851, + 859, + 0, + 860, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 874, + 0, + 876, + 0, + 877, + 890, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 893, + 894, + 898, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 899, + 0, + 0, + 0, + 900, + 904, + 906, + 0, + 0, + 0, + 907, + 0, + 908, + 909, + 0, + 910, + 0, + 0, + 0, + 0, + 911, + 0, + 0, + 0, + 0, + 0, + 916, + 0, + 0, + 0, + 922, + 925, + 0, + 930, + 0, + 934, + 0, + 0, + 0, + 0, + 0, + 943, + 0, + 0, + 944, + 0, + 953, + 954, + 0, + 0, + 0, + 0, + 0, + 0, + 955, + 0, + 962, + 963, + 0, + 0, + 976, + 0, + 0, + 977, + 978, + 979, + 980, + 0, + 981, + 0, + 0, + 0, + 0, + 984, + 0, + 0, + 985, + 0, + 0, + 987, + 989, + 991, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 992, + 0, + 0, + 0, + 993, + 0, + 0, + 0, + 0, + 0, + 0, + 996, + 0, + 0, + 0, + 1000, + 0, + 0, + 0, + 0, + 0, + 1002, + 0, + 0, + 0, + 0, + 1005, + 1007, + 0, + 0, + 0, + 1009, + 0, + 0, + 0, + 1010, + 0, + 0, + 0, + 0, + 0, + 0, + 1011, + 0, + 1012, + 0, + 0, + 0, + 0, + 1014, + 1016, + 0, + 0, + 0, + 1020, + 0, + 1021, + 0, + 0, + 0, + 0, + 1022, + 0, + 0, + 0, + 1024, + 0, + 0, + 0, + 0, + 0, + 0, + 1025, + 0, + 0, + 1026, + 1027, + 0, + 0, + 0, + 0, + 0, + 1031, + 0, + 1033, + 0, + 0, + 0, + 0, + 1034, + 0, + 0, + 0, + 1037, + 1040, + 0, + 0, + 0, + 1042, + 1043, + 0, + 0, + 1053, + 0, + 1054, + 0, + 0, + 1057, + 0, + 0, + 0, + 1058, + 0, + 0, + 1060, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1061, + 0, + 0, + 1062, + 0, + 0, + 0, + 0, + 1063, + 0, + 0, + 0, + 0, + 1064, + 0, + 0, + 0, + 0, + 0, + 1065, + 0, + 0, + 0, + 0, + 1066, + 1067, + 0, + 0, + 0, + 1069, + 1070, + 1072, + 0, + 0, + 0, + 0, + 0, + 0, + 1073, + 0, + 1075, + 0, + 0, + 0, + 0, + 0, + 0, + 1080, + 1084, + 0, + 0, + 0, + 0, + 1088, + 0, + 0, + 0, + 0, + 0, + 0, + 1094, + 0, + 1095, + 0, + 1107, + 0, + 0, + 0, + 1112, + 1114, + 0, + 1119, + 0, + 1122, + 0, + 0, + 1126, + 0, + 1129, + 0, + 1130, + 0, + 0, + 0, + 0, + 0, + 1132, + 0, + 0, + 0, + 0, + 0, + 0, + 1144, + 0, + 0, + 1145, + 1146, + 0, + 1148, + 1149, + 0, + 0, + 1150, + 1151, + 0, + 0, + 0, + 0, + 1152, + 0, + 1153, + 0, + 0, + 0, + 0, + 0, + 1154, + 0, + 1163, + 0, + 0, + 0, + 1164, + 0, + 0, + 0, + 0, + 0, + 1165, + 0, + 1167, + 0, + 1170, + 0, + 0, + 0, + 0, + 0, + 1171, + 1172, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1173, + 1175, + 1177, + 0, + 1186, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1195, + 0, + 0, + 1221, + 0, + 0, + 1224, + 0, + 0, + 1227, + 0, + 0, + 0, + 0, + 0, + 1228, + 1229, + 0, + 0, + 1230, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1231, + 0, + 0, + 0, + 1233, + 0, + 0, + 1243, + 1244, + 1246, + 1248, + 0, + 0, + 0, + 0, + 1254, + 1255, + 1258, + 1259, + 0, + 0, + 0, + 1260, + 0, + 0, + 1261, + 0, + 0, + 0, + 1262, + 1264, + 0, + 0, + 1265, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1266, + 0, + 1267, + 0, + 0, + 0, + 0, + 1273, + 1274, + 1276, + 1289, + 0, + 0, + 1291, + 1292, + 1293, + 0, + 0, + 1294, + 1295, + 1296, + 0, + 0, + 0, + 0, + 1302, + 0, + 1304, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1311, + 1312, + 0, + 1314, + 0, + 1316, + 1320, + 1321, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1322, + 1323, + 1324, + 0, + 1335, + 0, + 1336, + 0, + 0, + 0, + 0, + 1341, + 1342, + 0, + 1346, + 0, + 1357, + 0, + 0, + 0, + 1358, + 1360, + 0, + 0, + 0, + 0, + 0, + 0, + 1361, + 0, + 0, + 0, + 1362, + 1365, + 0, + 1366, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1379, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1386, + 0, + 1388, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1395, + 0, + 0, + 0, + 0, + 1403, + 0, + 1405, + 0, + 0, + 1407, + 0, + 0, + 0, + 0, + 0, + 1408, + 1409, + 0, + 1410, + 0, + 0, + 0, + 1412, + 1413, + 1416, + 0, + 0, + 1429, + 1451, + 0, + 0, + 1454, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1455, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1456, + 0, + 0, + 0, + 0, + 1459, + 1460, + 1461, + 1475, + 0, + 0, + 0, + 0, + 0, + 0, + 1477, + 0, + 1480, + 0, + 1481, + 0, + 0, + 1486, + 0, + 0, + 1495, + 0, + 0, + 0, + 1496, + 0, + 0, + 1498, + 1499, + 1501, + 1520, + 1521, + 0, + 0, + 0, + 1526, + 0, + 0, + 0, + 0, + 1528, + 1529, + 0, + 1533, + 1536, + 0, + 0, + 0, + 1537, + 1538, + 1549, + 0, + 1550, + 1558, + 1559, + 1572, + 0, + 1573, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1575, + 0, + 0, + 0, + 0, + 0, + 1579, + 0, + 1599, + 0, + 1603, + 0, + 1604, + 0, + 1605, + 0, + 0, + 0, + 0, + 0, + 1608, + 1610, + 0, + 0, + 0, + 0, + 1611, + 0, + 1615, + 0, + 1616, + 1618, + 0, + 1619, + 0, + 0, + 1622, + 0, + 0, + 0, + 0, + 1634, + 0, + 0, + 0, + 1635, + 0, + 0, + 0, + 1641, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1643, + 0, + 0, + 0, + 1650, + 0, + 0, + 1652, + 0, + 0, + 0, + 0, + 0, + 1653, + 0, + 0, + 0, + 1654, + 0, + 0, + 0, + 0, + 1655, + 0, + 1662, + 0, + 0, + 1663, + 1664, + 0, + 0, + 1668, + 0, + 0, + 1669, + 1670, + 0, + 1672, + 1673, + 0, + 0, + 0, + 0, + 0, + 1674, + 0, + 0, + 0, + 1675, + 1676, + 1680, + 0, + 1682, + 0, + 0, + 1687, + 0, + 0, + 0, + 0, + 0, + 1704, + 0, + 0, + 1705, + 0, + 0, + 1721, + 0, + 0, + 0, + 0, + 1734, + 1735, + 0, + 0, + 0, + 0, + 1737, + 0, + 0, + 0, + 0, + 1739, + 0, + 0, + 1740, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1741, + 1743, + 0, + 0, + 0, + 0, + 1745, + 0, + 0, + 0, + 1749, + 0, + 0, + 0, + 1751, + 0, + 0, + 0, + 0, + 0, + 0, + 1760, + 0, + 0, + 0, + 0, + 1765, + 0, + 0, + 0, + 0, + 0, + 1784, + 0, + 1785, + 1787, + 0, + 0, + 0, + 0, + 1788, + 1789, + 0, + 0, + 0, + 0, + 1790, + 1791, + 1793, + 0, + 1798, + 1799, + 0, + 0, + 0, + 0, + 1801, + 0, + 1803, + 1805, + 0, + 0, + 0, + 1806, + 1811, + 0, + 1812, + 1814, + 0, + 1821, + 0, + 0, + 0, + 0, + 0, + 1822, + 1833, + 0, + 0, + 0, + 0, + 0, + 0, + 1848, + 0, + 0, + 0, + 0, + 0, + 0, + 1857, + 0, + 0, + 0, + 1859, + 0, + 0, + 0, + 0, + 1861, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1866, + 0, + 1921, + 1925, + 0, + 0, + 0, + 1929, + 1930, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1931, + 0, + 0, + 0, + 0, + 1932, + 0, + 0, + 0, + 1934, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1946, + 0, + 0, + 1948, + 0, + 0, + 0, + 0, + 1950, + 0, + 1957, + 0, + 1958, + 0, + 0, + 0, + 0, + 0, + 1965, + 1967, + 0, + 0, + 0, + 0, + 1968, + 0, + 1969, + 0, + 1971, + 1972, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1973, + 0, + 0, + 0, + 0, + 1975, + 0, + 0, + 0, + 0, + 1976, + 1979, + 0, + 1982, + 0, + 0, + 0, + 0, + 1984, + 1988, + 0, + 0, + 0, + 0, + 1990, + 2004, + 2008, + 0, + 0, + 0, + 2012, + 2013, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2015, + 0, + 2016, + 2017, + 0, + 0, + 0, + 0, + 2021, + 0, + 0, + 2025, + 0, + 0, + 0, + 0, + 0, + 2029, + 2036, + 2040, + 0, + 2042, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2043, + 0, + 0, + 0, + 0, + 0, + 2045, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2046, + 2047, + 0, + 2048, + 2049, + 0, + 2059, + 0, + 0, + 2063, + 0, + 2064, + 2065, + 0, + 0, + 2066, + 0, + 0, + 0, + 0, + 0, + 0, + 2069, + 0, + 0, + 0, + 0, + 2070, + 0, + 2071, + 0, + 2072, + 0, + 0, + 0, + 0, + 2080, + 2082, + 2083, + 0, + 0, + 0, + 0, + 0, + 2085, + 0, + 2086, + 2088, + 2089, + 2105, + 0, + 0, + 0, + 0, + 2107, + 0, + 0, + 2116, + 2117, + 0, + 2120, + 0, + 0, + 2122, + 0, + 0, + 0, + 0, + 0, + 2123, + 0, + 0, + 2125, + 2127, + 2128, + 0, + 0, + 0, + 2130, + 0, + 0, + 0, + 2137, + 2139, + 2140, + 2141, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2144, + 2145, + 0, + 0, + 2146, + 2149, + 0, + 0, + 0, + 0, + 2150, + 0, + 0, + 2151, + 2158, + 0, + 2159, + 0, + 2160, + 0, + 0, + 0, + 0, + 0, + 0, + 2161, + 2162, + 0, + 0, + 2194, + 2202, + 0, + 0, + 0, + 0, + 0, + 0, + 2205, + 2217, + 0, + 2220, + 0, + 2221, + 0, + 2222, + 2224, + 0, + 0, + 0, + 0, + 2237, + 0, + 0, + 0, + 0, + 0, + 2238, + 0, + 2239, + 2241, + 0, + 0, + 2242, + 0, + 0, + 0, + 0, + 0, + 2243, + 0, + 0, + 0, + 0, + 0, + 0, + 2252, + 0, + 0, + 2253, + 0, + 0, + 0, + 2257, + 2258, + 0, + 0, + 0, + 2260, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2262, + 0, + 2264, + 0, + 0, + 0, + 0, + 0, + 2269, + 2270, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2271, + 0, + 2273, + 0, + 0, + 0, + 0, + 2277, + 0, + 0, + 0, + 0, + 2278, + 0, + 0, + 0, + 0, + 2279, + 0, + 2280, + 0, + 2283, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2287, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2289, + 2290, + 0, + 0, + 0, + 0, + 2291, + 0, + 2292, + 0, + 0, + 0, + 2293, + 2295, + 2296, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2298, + 0, + 0, + 0, + 0, + 0, + 2303, + 0, + 2305, + 0, + 0, + 2306, + 0, + 2307, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2313, + 2314, + 2315, + 2316, + 0, + 0, + 2318, + 0, + 2319, + 0, + 2322, + 0, + 0, + 2323, + 0, + 2324, + 0, + 2326, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2335, + 0, + 2336, + 2338, + 2339, + 0, + 2340, + 0, + 0, + 0, + 2355, + 0, + 2375, + 0, + 2382, + 2386, + 0, + 2387, + 0, + 0, + 2394, + 0, + 0, + 0, + 0, + 2395, + 0, + 2397, + 0, + 0, + 0, + 0, + 0, + 2398, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2399, + 2402, + 2404, + 2408, + 2411, + 0, + 0, + 0, + 2413, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2415, + 0, + 0, + 2416, + 2417, + 2419, + 0, + 2420, + 0, + 0, + 0, + 0, + 0, + 2425, + 0, + 0, + 0, + 2426, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2427, + 2428, + 0, + 2429, + 0, + 0, + 2430, + 2434, + 0, + 2436, + 0, + 0, + 0, + 0, + 0, + 0, + 2441, + 2442, + 0, + 2445, + 0, + 0, + 2446, + 2457, + 0, + 2459, + 0, + 0, + 2462, + 0, + 2464, + 0, + 2477, + 0, + 2478, + 2486, + 0, + 0, + 0, + 2491, + 0, + 0, + 2493, + 0, + 0, + 2494, + 0, + 2495, + 0, + 2513, + 2523, + 0, + 0, + 0, + 0, + 2524, + 0, + 0, + 0, + 0, + 0, + 0, + 2528, + 2529, + 2530, + 0, + 0, + 2531, + 0, + 2533, + 0, + 0, + 2534, + 2535, + 0, + 2536, + 2537, + 0, + 2538, + 0, + 2539, + 2540, + 0, + 0, + 0, + 2545, + 2546, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2548, + 0, + 0, + 2549, + 0, + 2550, + 2555, + 0, + 0, + 0, + 0, + 0, + 2557, + 0, + 2560, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2561, + 0, + 2576, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2577, + 2578, + 0, + 0, + 0, + 2579, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2580, + 0, + 0, + 0, + 0, + 2581, + 0, + 0, + 0, + 0, + 2583, + 0, + 2584, + 0, + 2588, + 2590, + 0, + 0, + 0, + 2591, + 0, + 0, + 0, + 0, + 2593, + 2594, + 0, + 2595, + 0, + 2601, + 2602, + 0, + 0, + 2603, + 0, + 2605, + 0, + 0, + 0, + 2606, + 2607, + 2611, + 0, + 2615, + 0, + 0, + 0, + 2617, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2619, + 0, + 0, + 2620, + 0, + 0, + 0, + 2621, + 0, + 2623, + 0, + 2625, + 0, + 0, + 2628, + 2629, + 0, + 0, + 2635, + 2636, + 2637, + 0, + 0, + 2639, + 0, + 0, + 0, + 2642, + 0, + 0, + 0, + 0, + 2643, + 0, + 2644, + 0, + 2649, + 0, + 0, + 0, + 0, + 0, + 0, + 2655, + 2656, + 0, + 0, + 2657, + 0, + 0, + 0, + 0, + 0, + 2658, + 0, + 0, + 0, + 0, + 0, + 2659, + 0, + 0, + 0, + 0, + 2664, + 2685, + 0, + 2687, + 0, + 2688, + 0, + 0, + 2689, + 0, + 0, + 2694, + 0, + 2695, + 0, + 0, + 2698, + 0, + 2701, + 2706, + 0, + 0, + 0, + 2707, + 0, + 2709, + 2710, + 2711, + 0, + 0, + 0, + 2720, + 2730, + 2735, + 0, + 0, + 0, + 0, + 2738, + 2740, + 0, + 0, + 0, + 0, + 2747, + 0, + 0, + 0, + 0, + 0, + 0, + 2748, + 0, + 0, + 2749, + 0, + 0, + 0, + 0, + 0, + 2750, + 0, + 0, + 2752, + 2754, + 0, + 0, + 0, + 0, + 0, + 2758, + 0, + 0, + 0, + 0, + 2762, + 0, + 0, + 0, + 0, + 2763, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2764, + 2767, + 0, + 0, + 0, + 0, + 2768, + 0, + 0, + 2770, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2771, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2772, + 0, + 0, + 0, + 0, + 0, + 2773, + 2776, + 0, + 0, + 2783, + 0, + 0, + 2784, + 0, + 2789, + 0, + 2790, + 0, + 0, + 0, + 2792, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2793, + 2795, + 0, + 0, + 0, + 0, + 0, + 0, + 2796, + 0, + 0, + 0, + 0, + 0, + 0, + 2797, + 2799, + 0, + 0, + 0, + 0, + 2803, + 0, + 0, + 0, + 0, + 2806, + 0, + 2807, + 2808, + 2817, + 2819, + 0, + 0, + 0, + 0, + 0, + 2821, + 0, + 0, + 0, + 0, + 2822, + 2823, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2824, + 0, + 0, + 2828, + 0, + 2834, + 0, + 0, + 0, + 0, + 0, + 0, + 2836, + 0, + 2838, + 0, + 0, + 2839, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2841, + 0, + 0, + 0, + 2842, + 0, + 0, + 0, + 0, + 0, + 2843, + 2844, + 0, + 0, + 0, + 0, + 2846, + 0, + 0, + 2847, + 0, + 2849, + 0, + 2853, + 0, + 0, + 0, + 0, + 0, + 2857, + 0, + 0, + 0, + 0, + 2858, + 0, + 2859, + 0, + 0, + 2860, + 0, + 2862, + 2868, + 0, + 0, + 0, + 0, + 2875, + 0, + 2876, + 0, + 0, + 2877, + 2878, + 2884, + 2889, + 2890, + 0, + 0, + 2891, + 0, + 0, + 2892, + 0, + 0, + 0, + 2906, + 2912, + 0, + 2913, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2916, + 0, + 2934, + 0, + 0, + 0, + 0, + 0, + 2935, + 0, + 0, + 0, + 0, + 2939, + 0, + 2940, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2941, + 0, + 0, + 0, + 2946, + 0, + 2949, + 0, + 0, + 2950, + 2954, + 2955, + 0, + 0, + 0, + 2959, + 2961, + 0, + 0, + 2962, + 0, + 2963, + 0, + 0, + 0, + 0, + 0, + 0, + 2964, + 2965, + 2966, + 2967, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2969, + 0, + 0, + 0, + 0, + 0, + 2970, + 2975, + 0, + 2982, + 2983, + 2984, + 0, + 0, + 0, + 0, + 0, + 2989, + 0, + 0, + 2990, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2991, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2998, + 0, + 3000, + 3001, + 0, + 0, + 3002, + 0, + 0, + 0, + 3003, + 0, + 0, + 3012, + 0, + 0, + 3022, + 0, + 0, + 3024, + 0, + 0, + 3025, + 3027, + 0, + 0, + 0, + 3030, + 0, + 0, + 0, + 0, + 3034, + 3035, + 0, + 0, + 3036, + 0, + 3039, + 0, + 3049, + 0, + 0, + 3050, + 0, + 0, + 0, + 0, + 0, + 0, + 3051, + 0, + 3053, + 0, + 0, + 0, + 0, + 3057, + 0, + 3058, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3063, + 0, + 0, + 3073, + 3074, + 3078, + 3079, + 0, + 3080, + 3086, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3087, + 0, + 3092, + 0, + 3095, + 0, + 3099, + 0, + 0, + 0, + 3100, + 0, + 3101, + 3102, + 0, + 3122, + 0, + 0, + 0, + 3124, + 0, + 3125, + 0, + 0, + 0, + 0, + 0, + 0, + 3132, + 3134, + 0, + 0, + 3136, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3147, + 0, + 0, + 3149, + 0, + 0, + 0, + 0, + 0, + 3150, + 3151, + 3152, + 0, + 0, + 0, + 0, + 3158, + 0, + 0, + 3160, + 0, + 0, + 3161, + 0, + 0, + 3162, + 0, + 3163, + 3166, + 3168, + 0, + 0, + 3169, + 3170, + 0, + 0, + 3171, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3182, + 0, + 3184, + 0, + 0, + 3188, + 0, + 0, + 3194, + 0, + 0, + 0, + 0, + 0, + 0, + 3204, + 0, + 0, + 0, + 0, + 3209, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3216, + 3217, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3219, + 0, + 0, + 3220, + 3222, + 0, + 3223, + 0, + 0, + 0, + 0, + 3224, + 0, + 3225, + 3226, + 0, + 3228, + 3233, + 0, + 3239, + 3241, + 3242, + 0, + 0, + 3251, + 3252, + 3253, + 3255, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3260, + 0, + 0, + 3261, + 0, + 0, + 0, + 3267, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3271, + 0, + 0, + 0, + 3278, + 0, + 3282, + 0, + 0, + 0, + 3284, + 0, + 0, + 0, + 3285, + 3286, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3287, + 3292, + 0, + 0, + 0, + 0, + 3294, + 3296, + 0, + 0, + 3299, + 3300, + 3301, + 0, + 3302, + 0, + 0, + 0, + 0, + 0, + 3304, + 3306, + 0, + 0, + 0, + 0, + 0, + 0, + 3308, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3311, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3312, + 3314, + 3315, + 0, + 3318, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3319, + 0, + 0, + 0, + 0, + 0, + 3321, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3322, + 0, + 0, + 3324, + 3325, + 0, + 0, + 3326, + 0, + 0, + 3328, + 3329, + 3331, + 0, + 0, + 3335, + 0, + 0, + 3337, + 0, + 3338, + 0, + 0, + 0, + 0, + 3343, + 3347, + 0, + 0, + 0, + 3348, + 0, + 0, + 3351, + 0, + 0, + 0, + 0, + 0, + 0, + 3354, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3355, + 0, + 0, + 3365, + 3366, + 3367, + 0, + 0, + 0, + 0, + 0, + 0, + 3368, + 3369, + 0, + 3370, + 0, + 0, + 3373, + 0, + 0, + 3376, + 0, + 0, + 3377, + 0, + 3379, + 3387, + 0, + 0, + 0, + 0, + 0, + 3390, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3402, + 0, + 3403, + 3436, + 3437, + 3439, + 0, + 0, + 3441, + 0, + 0, + 0, + 3442, + 0, + 0, + 3449, + 0, + 0, + 0, + 3450, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3451, + 0, + 0, + 3452, + 0, + 3453, + 3456, + 0, + 3457, + 0, + 0, + 3458, + 0, + 3459, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3460, + 0, + 0, + 3469, + 3470, + 0, + 0, + 3475, + 0, + 0, + 0, + 3480, + 3487, + 3489, + 0, + 3490, + 0, + 0, + 3491, + 3499, + 0, + 3500, + 0, + 0, + 3501, + 0, + 0, + 0, + 3502, + 0, + 3514, + 0, + 0, + 0, + 3516, + 3517, + 0, + 0, + 0, + 3518, + 0, + 0, + 0, + 0, + 3520, + 3521, + 3522, + 0, + 0, + 3526, + 3530, + 0, + 0, + 0, + 0, + 3531, + 0, + 0, + 0, + 0, + 3536, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3539, + 3541, + 0, + 0, + 3542, + 3544, + 0, + 3547, + 3548, + 0, + 0, + 3550, + 0, + 3553, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3554, + 0, + 3555, + 0, + 3558, + 0, + 3559, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3563, + 0, + 3581, + 0, + 0, + 0, + 3599, + 0, + 0, + 0, + 3600, + 0, + 3601, + 0, + 3602, + 3603, + 0, + 0, + 3606, + 3608, + 0, + 3610, + 3611, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3612, + 3616, + 3619, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3624, + 3628, + 0, + 3629, + 3634, + 3635, + 0, + 0, + 0, + 0, + 0, + 0, + 3636, + 0, + 3637, + 0, + 0, + 3638, + 3651, + 0, + 0, + 0, + 0, + 0, + 0, + 3652, + 3653, + 0, + 0, + 0, + 0, + 3656, + 3657, + 0, + 0, + 0, + 0, + 0, + 3658, + 0, + 0, + 0, + 0, + 3659, + 0, + 3661, + 3663, + 3664, + 0, + 3665, + 0, + 3692, + 0, + 0, + 0, + 3694, + 3696, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3698, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3700, + 0, + 0, + 3701, + 0, + 0, + 0, + 3708, + 3709, + 0, + 0, + 0, + 3711, + 3712, + 0, + 0, + 0, + 0, + 0, + 3723, + 0, + 3724, + 3725, + 0, + 0, + 3726, + 0, + 0, + 0, + 0, + 0, + 0, + 3728, + 3729, + 0, + 3734, + 3735, + 3737, + 0, + 0, + 0, + 3743, + 0, + 3745, + 0, + 0, + 3746, + 0, + 0, + 3747, + 3748, + 0, + 3757, + 0, + 3759, + 3766, + 3767, + 0, + 3768, + 0, + 0, + 0, + 0, + 3769, + 0, + 0, + 3771, + 0, + 3774, + 0, + 0, + 0, + 0, + 0, + 0, + 3775, + 0, + 0, + 0, + 0, + 0, + 0, + 3776, + 0, + 3777, + 3786, + 0, + 3788, + 3789, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3791, + 0, + 3811, + 0, + 0, + 0, + 0, + 0, + 3814, + 3815, + 3816, + 3820, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3821, + 0, + 0, + 3825, + 0, + 0, + 0, + 0, + 3835, + 0, + 0, + 3848, + 3849, + 0, + 0, + 0, + 0, + 3850, + 3851, + 3853, + 0, + 0, + 0, + 0, + 3859, + 0, + 3860, + 3862, + 0, + 0, + 0, + 0, + 0, + 3863, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3873, + 0, + 3874, + 0, + 3875, + 3886, + 0, + 3887, + 0, + 0, + 0, + 0, + 3892, + 3913, + 0, + 3914, + 0, + 0, + 0, + 3925, + 3931, + 0, + 0, + 0, + 0, + 3934, + 3941, + 3942, + 0, + 0, + 0, + 0, + 3943, + 0, + 0, + 0, + 3944, + 0, + 0, + 0, + 0, + 0, + 3945, + 0, + 3947, + 0, + 0, + 0, + 3956, + 3957, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3958, + 0, + 3959, + 3965, + 0, + 0, + 0, + 0, + 3966, + 0, + 0, + 0, + 3967, + 0, + 0, + 0, + 3968, + 3974, + 0, + 0, + 0, + 0, + 0, + 3975, + 3977, + 3978, + 0, + 0, + 0, + 0, + 3980, + 0, + 3985, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3986, + 4011, + 0, + 0, + 4017, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 4018, + 0, + 0, + 0, + 0, + 4019, + 0, + 4023, + 0, + 0, + 0, + 4027, + 4028, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 4031, + 4034, + 0, + 0, + 4035, + 4037, + 4039, + 4040, + 0, + 0, + 0, + 0, + 0, + 4059, + 0, + 4060, + 4061, + 0, + 4062, + 4063, + 4066, + 0, + 0, + 4072, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 4088, + 0, + 0, + 0, + 0, + 0, + 4091, + 0, + 0, + 0, + 0, + 4094, + 4095, + 0, + 0, + 4096, + 0, + 0, + 0, + 0, + 0, + 4098, + 4099, + 0, + 0, + 0, + 4101, + 0, + 4104, + 0, + 0, + 0, + 4105, + 4108, + 0, + 4113, + 0, + 0, + 4115, + 4116, + 0, + 4126, + 0, + 0, + 4127, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 4128, + 4132, + 4133, + 0, + 4134, + 0, + 0, + 0, + 4137, + 0, + 0, + 4141, + 0, + 0, + 0, + 0, + 4144, + 4146, + 4147, + 0, + 0, + 0, + 0, + 4148, + 0, + 0, + 4311, + 0, + 0, + 0, + 4314, + 4329, + 0, + 4331, + 4332, + 0, + 4333, + 0, + 4334, + 0, + 0, + 0, + 4335, + 0, + 4336, + 0, + 0, + 0, + 4337, + 0, + 0, + 0, + 4342, + 4345, + 4346, + 4350, + 0, + 4351, + 4352, + 0, + 4354, + 4355, + 0, + 0, + 4364, + 0, + 0, + 0, + 0, + 4369, + 0, + 0, + 0, + 4373, + 0, + 4374, + 0, + 0, + 0, + 0, + 4377, + 0, + 0, + 0, + 0, + 4378, + 0, + 0, + 0, + 4380, + 0, + 0, + 0, + 4381, + 4382, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 4384, + 0, + 0, + 0, + 0, + 4385, + 0, + 0, + 0, + 4386, + 0, + 0, + 0, + 4391, + 4398, + 0, + 0, + 0, + 0, + 4407, + 4409, + 0, + 0, + 0, + 0, + 4410, + 0, + 0, + 4411, + 0, + 4414, + 4415, + 4418, + 0, + 4427, + 4428, + 4430, + 0, + 4431, + 0, + 4448, + 0, + 0, + 0, + 0, + 0, + 4449, + 0, + 0, + 0, + 4451, + 4452, + 0, + 4453, + 4454, + 0, + 4456, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 4459, + 0, + 4463, + 0, + 0, + 0, + 0, + 0, + 4466, + 0, + 4467, + 0, + 4469, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 4470, + 4471, + 0, + 4473, + 0, + 0, + 4475, + 0, + 0, + 0, + 0, + 4477, + 4478, + 0, + 0, + 0, + 4479, + 4481, + 0, + 4482, + 0, + 4484, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 4486, + 0, + 0, + 4488, + 0, + 0, + 4497, + 0, + 4508, + 0, + 0, + 4510, + 4511, + 0, + 4520, + 4523, + 0, + 4524, + 0, + 4525, + 0, + 4527, + 0, + 0, + 4528, + 0, + 0, + 0, + 0, + 4530, + 0, + 4531, + 0, + 0, + 4532, + 0, + 0, + 0, + 4533, + 0, + 0, + 0, + 0, + 0, + 4535, + 0, + 0, + 0, + 4536, + 0, + 0, + 0, + 0, + 0, + 4541, + 4543, + 4544, + 4545, + 4547, + 0, + 4548, + 0, + 0, + 0, + 0, + 4550, + 4551, + 0, + 4553, + 0, + 0, + 0, + 0, + 4562, + 0, + 0, + 4571, + 0, + 0, + 0, + 4574, + 0, + 0, + 0, + 4575, + 0, + 4576, + 0, + 4577, + 0, + 0, + 0, + 4581, + 0, + 0, + 0, + 0, + 0, + 4582, + 0, + 0, + 4586, + 0, + 0, + 0, + 4588, + 0, + 0, + 4597, + 0, + 4598, + 0, + 0, + 0, + 0, + 4616, + 4617, + 0, + 4618, + 0, + 0, + 0, + 0, + 4619, + 0, + 4620, + 0, + 0, + 4621, + 0, + 4624, + 0, + 0, + 0, + 0, + 0, + 4625, + 0, + 0, + 0, + 0, + 4657, + 0, + 4659, + 0, + 4667, + 0, + 0, + 0, + 4668, + 4670, + 0, + 4672, + 0, + 0, + 0, + 0, + 0, + 4673, + 4676, + 0, + 0, + 0, + 0, + 4687, + 0, + 0, + 0, + 0, + 4697, + 0, + 0, + 0, + 0, + 4699, + 0, + 4701, + 0, + 0, + 0, + 0, + 4702, + 0, + 0, + 4706, + 0, + 0, + 4713, + 0, + 0, + 0, + 4714, + 4715, + 4716, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 4717, + 0, + 0, + 4720, + 0, + 4721, + 4729, + 4735, + 0, + 0, + 0, + 4737, + 0, + 0, + 0, + 4739, + 0, + 0, + 0, + 4740, + 0, + 0, + 0, + 4741, + 0, + 0, + 0, + 0, + 0, + 4742, + 0, + 4745, + 4746, + 4747, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 4748, + 0, + 0, + 0, + 4749, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 4751, + 4786, + 0, + 4787, + 0, + 4788, + 4796, + 0, + 0, + 4797, + 4798, + 0, + 4799, + 4806, + 4807, + 0, + 0, + 0, + 0, + 4809, + 4810, + 0, + 0, + 0, + 0, + 0, + 0, + 4811, + 0, + 0, + 0, + 0, + 0, + 4812, + 0, + 4813, + 0, + 0, + 4815, + 0, + 4821, + 4822, + 0, + 0, + 0, + 0, + 4823, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 4824, + 0, + 0, + 0, + 0, + 4826, + 0, + 0, + 0, + 4828, + 0, + 4829, + 0, + 0, + 0, + 4843, + 0, + 0, + 4847, + 0, + 4853, + 4855, + 4858, + 0, + 0, + 0, + 0, + 0, + 4859, + 0, + 4864, + 0, + 0, + 4879, + 0, + 0, + 0, + 0, + 4880, + 0, + 0, + 0, + 0, + 4881, + 0, + 4882, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 4883, + 0, + 0, + 0, + 0, + 4884, + 0, + 0, + 0, + 0, + 0, + 4886, + 4887, + 4888, + 4894, + 4896, + 0, + 4902, + 0, + 0, + 4905, + 0, + 0, + 4915, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 4916, + 4917, + 4919, + 4921, + 0, + 0, + 0, + 0, + 0, + 4926, + 0, + 0, + 0, + 0, + 4927, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 4929, + 0, + 4930, + 4931, + 0, + 4938, + 0, + 4952, + 0, + 4953, + 4957, + 4960, + 4964, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5019, + 5020, + 5022, + 0, + 0, + 0, + 0, + 0, + 5023, + 0, + 0, + 0, + 5024, + 0, + 0, + 0, + 5025, + 0, + 0, + 0, + 0, + 5028, + 0, + 0, + 0, + 0, + 5029, + 5030, + 5031, + 0, + 5033, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5034, + 5035, + 0, + 5036, + 0, + 0, + 5037, + 0, + 0, + 0, + 0, + 5038, + 0, + 0, + 5039, + 0, + 0, + 0, + 5041, + 5042, + 0, + 0, + 0, + 0, + 5044, + 5049, + 5054, + 0, + 5055, + 0, + 5057, + 0, + 0, + 0, + 5060, + 0, + 0, + 0, + 0, + 0, + 5063, + 0, + 5064, + 5065, + 0, + 5067, + 0, + 0, + 0, + 5068, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5076, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5077, + 0, + 0, + 5078, + 5080, + 0, + 0, + 5083, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5085, + 0, + 0, + 0, + 0, + 0, + 0, + 5098, + 5099, + 5101, + 5105, + 5107, + 0, + 5108, + 0, + 5109, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5110, + 0, + 0, + 0, + 0, + 0, + 5117, + 5118, + 0, + 5121, + 0, + 5122, + 0, + 0, + 5130, + 0, + 0, + 0, + 5137, + 0, + 0, + 0, + 5148, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5151, + 5154, + 0, + 0, + 0, + 5155, + 0, + 0, + 5156, + 5159, + 5161, + 0, + 0, + 0, + 0, + 5162, + 0, + 0, + 0, + 0, + 5163, + 5164, + 0, + 5166, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5167, + 0, + 0, + 0, + 5172, + 0, + 0, + 0, + 0, + 0, + 0, + 5178, + 5179, + 0, + 0, + 5190, + 0, + 0, + 5191, + 5192, + 5194, + 0, + 0, + 5198, + 5201, + 0, + 0, + 0, + 0, + 0, + 5203, + 0, + 5206, + 5209, + 0, + 0, + 0, + 0, + 0, + 0, + 5213, + 0, + 5214, + 5216, + 0, + 0, + 0, + 0, + 0, + 5217, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5218, + 5219, + 0, + 5231, + 0, + 0, + 5244, + 5249, + 0, + 5254, + 0, + 5255, + 0, + 0, + 5257, + 0, + 0, + 0, + 0, + 0, + 5258, + 0, + 5260, + 5270, + 0, + 5277, + 0, + 0, + 0, + 0, + 0, + 0, + 5280, + 5281, + 5282, + 5283, + 0, + 0, + 0, + 0, + 0, + 5284, + 0, + 5285, + 0, + 0, + 0, + 0, + 0, + 5287, + 5288, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5289, + 5291, + 0, + 0, + 5294, + 0, + 0, + 5295, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5304, + 0, + 0, + 5306, + 5307, + 5308, + 0, + 5309, + 0, + 0, + 5310, + 0, + 0, + 0, + 0, + 5311, + 5312, + 0, + 5313, + 0, + 0, + 0, + 0, + 0, + 5316, + 0, + 0, + 0, + 5317, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5325, + 0, + 0, + 0, + 0, + 0, + 0, + 5326, + 0, + 5327, + 5329, + 0, + 5332, + 0, + 0, + 0, + 0, + 5338, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5340, + 0, + 0, + 5341, + 0, + 0, + 0, + 5342, + 0, + 5343, + 5344, + 0, + 0, + 5345, + 0, + 0, + 0, + 0, + 0, + 0, + 5347, + 5348, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5349, + 0, + 5350, + 0, + 5354, + 0, + 0, + 0, + 0, + 5358, + 0, + 0, + 5359, + 0, + 0, + 5361, + 0, + 0, + 5365, + 0, + 5367, + 0, + 5373, + 0, + 0, + 0, + 5379, + 0, + 0, + 0, + 5380, + 0, + 0, + 0, + 5382, + 0, + 5384, + 0, + 0, + 0, + 0, + 0, + 0, + 5385, + 0, + 0, + 0, + 0, + 5387, + 0, + 0, + 0, + 0, + 0, + 0, + 5388, + 5390, + 5393, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5396, + 0, + 0, + 0, + 0, + 5397, + 5402, + 0, + 0, + 0, + 0, + 0, + 5403, + 0, + 0, + 0, + 5404, + 5405, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5406, + 0, + 0, + 0, + 0, + 5410, + 0, + 0, + 5411, + 0, + 5415, + 0, + 0, + 0, + 0, + 5416, + 5434, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5438, + 0, + 5440, + 0, + 0, + 0, + 0, + 0, + 0, + 5441, + 5442, + 0, + 0, + 0, + 5443, + 5444, + 5447, + 0, + 0, + 5448, + 5449, + 5451, + 0, + 0, + 0, + 5456, + 5457, + 0, + 0, + 0, + 5459, + 0, + 0, + 0, + 5461, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5464, + 0, + 5466, + 0, + 0, + 5467, + 0, + 5470, + 0, + 0, + 5473, + 0, + 0, + 5474, + 0, + 0, + 5476, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5477, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5484, + 0, + 0, + 5485, + 5486, + 0, + 0, + 0, + 0, + 0, + 5488, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5489, + 0, + 0, + 0, + 0, + 0, + 5507, + 0, + 0, + 0, + 5510, + 0, + 5511, + 0, + 0, + 5512, + 0, + 0, + 0, + 5513, + 0, + 5515, + 0, + 0, + 5516, + 5517, + 0, + 5518, + 0, + 0, + 5522, + 0, + 0, + 0, + 0, + 0, + 5534, + 5535, + 0, + 0, + 5536, + 0, + 5538, + 0, + 0, + 5543, + 0, + 5544, + 0, + 0, + 5545, + 0, + 5547, + 0, + 5557, + 0, + 0, + 5558, + 0, + 5560, + 5567, + 0, + 0, + 0, + 0, + 5568, + 0, + 0, + 0, + 5571, + 5573, + 0, + 5574, + 0, + 5575, + 0, + 0, + 0, + 0, + 5577, + 0, + 0, + 5598, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5600, + 5609, + 0, + 0, + 0, + 0, + 5610, + 0, + 0, + 5612, + 0, + 5624, + 0, + 5625, + 0, + 0, + 0, + 5629, + 0, + 5641, + 0, + 5642, + 5643, + 0, + 0, + 0, + 0, + 0, + 0, + 5651, + 0, + 0, + 0, + 5652, + 5653, + 0, + 5661, + 5662, + 5678, + 0, + 5679, + 0, + 0, + 0, + 0, + 5685, + 5686, + 0, + 0, + 0, + 0, + 0, + 5690, + 5692, + 0, + 5703, + 0, + 0, + 0, + 0, + 0, + 5706, + 0, + 0, + 0, + 0, + 5707, + 0, + 0, + 0, + 0, + 0, + 0, + 5708, + 0, + 0, + 5709, + 0, + 5710, + 0, + 0, + 0, + 5712, + 0, + 5733, + 0, + 5734, + 5735, + 0, + 0, + 5744, + 5751, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5752, + 0, + 5754, + 0, + 0, + 0, + 0, + 0, + 0, + 5757, + 5758, + 0, + 5760, + 5761, + 0, + 0, + 0, + 0, + 5763, + 5764, + 5765, + 0, + 5766, + 0, + 5767, + 5768, + 0, + 5770, + 0, + 0, + 0, + 0, + 5776, + 5780, + 0, + 0, + 0, + 0, + 5782, + 0, + 0, + 0, + 0, + 5784, + 0, + 0, + 5788, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5797, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5799, + 0, + 0, + 5801, + 0, + 0, + 0, + 5811, + 0, + 0, + 0, + 0, + 0, + 0, + 5816, + 0, + 0, + 5827, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5830, + 5831, + 0, + 0, + 5832, + 0, + 0, + 5833, + 0, + 5835, + 5844, + 5845, + 0, + 5846, + 0, + 0, + 0, + 0, + 0, + 5850, + 0, + 0, + 0, + 0, + 0, + 5852, + 0, + 5855, + 5857, + 0, + 0, + 5859, + 0, + 5861, + 0, + 0, + 5863, + 0, + 5865, + 0, + 0, + 0, + 5873, + 5875, + 0, + 0, + 0, + 5877, + 0, + 5879, + 0, + 0, + 0, + 5888, + 0, + 0, + 5889, + 5891, + 0, + 5894, + 0, + 0, + 0, + 0, + 0, + 0, + 5895, + 0, + 5897, + 0, + 0, + 0, + 0, + 0, + 0, + 5907, + 0, + 5911, + 0, + 0, + 5912, + 0, + 5913, + 5922, + 5924, + 0, + 5927, + 5928, + 0, + 0, + 0, + 0, + 5929, + 5930, + 0, + 5933, + 0, + 0, + 0, + 0, + 5949, + 0, + 0, + 5951, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5953, + 0, + 0, + 5954, + 0, + 5959, + 5960, + 5961, + 0, + 5964, + 0, + 0, + 0, + 5976, + 5978, + 5987, + 5990, + 0, + 0, + 0, + 0, + 0, + 5991, + 0, + 5992, + 0, + 0, + 0, + 5994, + 5995, + 0, + 0, + 5996, + 0, + 0, + 6001, + 6003, + 0, + 0, + 0, + 0, + 6007, + 0, + 0, + 0, + 0, + 0, + 6008, + 0, + 0, + 6009, + 0, + 6010, + 0, + 0, + 0, + 6011, + 6015, + 0, + 6017, + 0, + 6019, + 0, + 6023, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6025, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6026, + 0, + 6030, + 0, + 0, + 6032, + 0, + 0, + 0, + 6033, + 6038, + 6040, + 0, + 0, + 0, + 6041, + 6045, + 0, + 0, + 6046, + 0, + 0, + 6053, + 0, + 0, + 6054, + 0, + 6055, + 0, + 0, + 0, + 0, + 0, + 0, + 6057, + 0, + 6063, + 0, + 0, + 0, + 6064, + 0, + 6066, + 6071, + 6072, + 0, + 0, + 0, + 0, + 0, + 0, + 6075, + 6076, + 0, + 0, + 6077, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6078, + 6079, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6080, + 0, + 6083, + 0, + 0, + 0, + 0, + 0, + 6084, + 0, + 0, + 6088, + 0, + 6089, + 0, + 0, + 6093, + 6105, + 0, + 0, + 6107, + 0, + 6110, + 0, + 0, + 0, + 6111, + 6125, + 6126, + 0, + 0, + 0, + 6129, + 0, + 0, + 0, + 0, + 6130, + 0, + 0, + 0, + 6131, + 6134, + 0, + 0, + 0, + 0, + 0, + 0, + 6142, + 0, + 0, + 0, + 0, + 0, + 6144, + 0, + 0, + 6146, + 6151, + 6153, + 0, + 6156, + 0, + 6163, + 0, + 6180, + 6181, + 0, + 0, + 0, + 0, + 0, + 6182, + 0, + 0, + 0, + 0, + 6184, + 6195, + 0, + 0, + 6206, + 0, + 6208, + 0, + 0, + 6212, + 6213, + 6214, + 0, + 6215, + 0, + 0, + 0, + 6228, + 0, + 0, + 0, + 6234, + 0, + 0, + 0, + 0, + 0, + 0, + 6235, + 6240, + 0, + 6242, + 6243, + 6244, + 0, + 6250, + 6255, + 0, + 0, + 0, + 0, + 0, + 6257, + 0, + 0, + 0, + 6258, + 6278, + 0, + 6284, + 0, + 0, + 0, + 6285, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6286, + 0, + 0, + 0, + 6320, + 0, + 0, + 6322, + 6332, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6334, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6335, + 0, + 0, + 6337, + 0, + 6338, + 0, + 6339, + 6340, + 0, + 0, + 6356, + 6357, + 6369, + 0, + 0, + 0, + 6370, + 6371, + 6372, + 0, + 6373, + 0, + 0, + 0, + 0, + 0, + 6376, + 0, + 0, + 0, + 0, + 0, + 6382, + 6383, + 6384, + 0, + 0, + 0, + 0, + 6386, + 0, + 6389, + 6397, + 6400, + 6411, + 0, + 6414, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6415, + 6416, + 0, + 0, + 0, + 0, + 0, + 0, + 6417, + 0, + 0, + 0, + 0, + 6418, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6420, + 0, + 6421, + 6423, + 6425, + 0, + 6429, + 6430, + 0, + 6433, + 6438, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6439, + 6440, + 0, + 0, + 6441, + 0, + 0, + 6444, + 0, + 0, + 0, + 0, + 6446, + 0, + 0, + 0, + 0, + 6447, + 6448, + 0, + 0, + 6450, + 0, + 0, + 0, + 6454, + 0, + 0, + 6455, + 0, + 6461, + 0, + 0, + 0, + 0, + 0, + 0, + 6462, + 0, + 0, + 6463, + 0, + 6464, + 0, + 6465, + 6467, + 0, + 0, + 0, + 6468, + 0, + 6479, + 6480, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6481, + 0, + 0, + 6485, + 6487, + 0, + 0, + 0, + 0, + 0, + 0, + 6493, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6494, + 6495, + 6496, + 0, + 0, + 0, + 0, + 0, + 6498, + 0, + 0, + 0, + 6507, + 6508, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6511, + 6512, + 0, + 0, + 0, + 0, + 6513, + 0, + 0, + 0, + 6514, + 0, + 0, + 0, + 0, + 0, + 6516, + 0, + 0, + 6517, + 6518, + 0, + 0, + 0, + 6519, + 6520, + 6521, + 0, + 6523, + 0, + 0, + 0, + 0, + 6524, + 6528, + 0, + 6530, + 0, + 0, + 6532, + 0, + 6578, + 0, + 0, + 0, + 6583, + 0, + 6584, + 0, + 0, + 0, + 6587, + 0, + 0, + 0, + 6590, + 0, + 6591, + 0, + 0, + 0, + 0, + 0, + 6592, + 0, + 0, + 0, + 0, + 6593, + 6594, + 0, + 0, + 0, + 0, + 0, + 6599, + 6600, + 0, + 0, + 6601, + 6602, + 6604, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6608, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6610, + 6611, + 0, + 6615, + 0, + 6616, + 6618, + 6620, + 0, + 6637, + 0, + 0, + 0, + 0, + 6639, + 0, + 0, + 0, + 0, + 6641, + 0, + 6642, + 0, + 0, + 0, + 6647, + 0, + 6660, + 6663, + 0, + 6664, + 0, + 6666, + 6669, + 0, + 6675, + 6676, + 6677, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6678, + 0, + 0, + 0, + 6679, + 0, + 6680, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6693, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6704, + 6705, + 6706, + 0, + 0, + 6711, + 6713, + 0, + 0, + 0, + 0, + 0, + 6716, + 0, + 0, + 0, + 6717, + 0, + 6719, + 6724, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6725, + 6726, + 0, + 0, + 0, + 0, + 0, + 6728, + 6729, + 6735, + 0, + 6737, + 6742, + 0, + 0, + 6743, + 6750, + 0, + 6751, + 0, + 0, + 6752, + 6753, + 0, + 0, + 0, + 0, + 0, + 0, + 6754, + 0, + 0, + 0, + 0, + 0, + 6756, + 0, + 0, + 0, + 0, + 0, + 0, + 6763, + 0, + 0, + 6764, + 6765, + 0, + 0, + 0, + 6770, + 0, + 0, + 0, + 6776, + 6780, + 0, + 6781, + 0, + 0, + 0, + 6783, + 0, + 6784, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6785, + 0, + 0, + 0, + 6792, + 0, + 0, + 0, + 6793, + 0, + 0, + 6802, + 0, + 0, + 0, + 0, + 0, + 6803, + 0, + 0, + 0, + 6804, + 0, + 0, + 0, + 6812, + 0, + 0, + 6823, + 0, + 6824, + 6839, + 0, + 0, + 0, + 0, + 6852, + 0, + 0, + 6854, + 0, + 6856, + 6857, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6867, + 0, + 6868, + 6870, + 6872, + 0, + 0, + 0, + 6873, + 6874, + 0, + 0, + 0, + 0, + 0, + 6875, + 0, + 0, + 6877, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6878, + 0, + 0, + 0, + 6879, + 0, + 6880, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6887, + 0, + 6888, + 6891, + 6893, + 0, + 6895, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6899, + 0, + 0, + 0, + 0, + 6901, + 0, + 0, + 0, + 0, + 6910, + 0, + 6911, + 0, + 0, + 6912, + 0, + 0, + 6913, + 6914, + 0, + 0, + 0, + 6915, + 0, + 0, + 0, + 6916, + 6919, + 0, + 0, + 0, + 0, + 0, + 0, + 6924, + 0, + 6925, + 0, + 0, + 0, + 6926, + 6927, + 6928, + 0, + 6929, + 0, + 6930, + 0, + 0, + 6931, + 6935, + 0, + 6936, + 0, + 0, + 0, + 0, + 6939, + 6940, + 6941, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6942, + 6948, + 6949, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6952, + 6954, + 6963, + 6965, + 6966, + 0, + 0, + 6967, + 6968, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6969, + 0, + 0, + 6970, + 6979, + 0, + 0, + 6980, + 0, + 0, + 6983, + 0, + 0, + 0, + 0, + 0, + 6984, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6988, + 6990, + 6992, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6995, + 0, + 0, + 0, + 7012, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7019, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7021, + 0, + 0, + 7022, + 7023, + 7028, + 0, + 7030, + 7033, + 0, + 0, + 0, + 0, + 0, + 0, + 7038, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7039, + 0, + 0, + 0, + 0, + 0, + 7046, + 0, + 7047, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7048, + 7052, + 0, + 0, + 0, + 0, + 0, + 7054, + 0, + 7060, + 0, + 0, + 0, + 0, + 7061, + 0, + 7065, + 0, + 0, + 0, + 0, + 7067, + 7069, + 0, + 7070, + 7071, + 7072, + 0, + 0, + 7078, + 0, + 7080, + 7081, + 0, + 7083, + 0, + 0, + 0, + 7084, + 7087, + 7088, + 0, + 0, + 7090, + 0, + 7093, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7107, + 0, + 0, + 7108, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7110, + 0, + 7114, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7115, + 0, + 7116, + 0, + 0, + 0, + 0, + 0, + 7117, + 0, + 0, + 7118, + 0, + 0, + 7124, + 0, + 7125, + 0, + 0, + 7126, + 0, + 0, + 0, + 0, + 7128, + 0, + 0, + 0, + 0, + 0, + 7129, + 0, + 7130, + 0, + 7132, + 7133, + 0, + 0, + 7134, + 0, + 0, + 7139, + 0, + 7148, + 7150, + 0, + 0, + 0, + 0, + 7152, + 0, + 0, + 0, + 7153, + 7156, + 7157, + 0, + 0, + 0, + 0, + 0, + 7158, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7163, + 7165, + 7169, + 0, + 7171, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7172, + 0, + 7173, + 7181, + 0, + 0, + 0, + 0, + 0, + 7182, + 7185, + 0, + 0, + 0, + 0, + 7187, + 0, + 7201, + 7204, + 0, + 0, + 0, + 0, + 0, + 7206, + 7207, + 0, + 0, + 0, + 0, + 7211, + 7216, + 0, + 7218, + 0, + 0, + 0, + 0, + 7226, + 7228, + 7230, + 7232, + 7233, + 7235, + 7237, + 0, + 0, + 0, + 0, + 7238, + 7241, + 0, + 7242, + 0, + 0, + 7247, + 0, + 0, + 0, + 7266, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7289, + 0, + 0, + 7290, + 7291, + 0, + 0, + 7292, + 0, + 7297, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7300, + 0, + 7301, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7302, + 0, + 0, + 0, + 0, + 7305, + 0, + 0, + 0, + 0, + 7307, + 0, + 7308, + 0, + 7310, + 0, + 7335, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7337, + 0, + 7343, + 7347, + 0, + 0, + 0, + 0, + 0, + 7348, + 0, + 7349, + 7350, + 7352, + 7354, + 0, + 0, + 0, + 0, + 7357, + 0, + 7358, + 7366, + 0, + 7367, + 7368, + 0, + 0, + 7373, + 0, + 0, + 0, + 7374, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7376, + 0, + 0, + 0, + 7377, + 0, + 0, + 0, + 0, + 0, + 7378, + 0, + 7379, + 7380, + 0, + 0, + 0, + 0, + 0, + 7383, + 0, + 0, + 7386, + 0, + 0, + 0, + 0, + 7398, + 0, + 0, + 0, + 7399, + 7400, + 0, + 7401, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7402, + 0, + 0, + 0, + 0, + 0, + 7405, + 0, + 0, + 0, + 0, + 0, + 7406, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7421, + 7427, + 7429, + 0, + 0, + 0, + 7435, + 0, + 0, + 7436, + 0, + 0, + 0, + 7437, + 0, + 0, + 0, + 0, + 0, + 0, + 7438, + 7443, + 0, + 7446, + 0, + 7448, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7456, + 0, + 0, + 0, + 0, + 0, + 7457, + 0, + 0, + 7461, + 0, + 0, + 0, + 0, + 0, + 7462, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7463, + 7466, + 7472, + 0, + 7476, + 0, + 0, + 7490, + 0, + 7491, + 0, + 0, + 7493, + 0, + 0, + 0, + 7498, + 7499, + 0, + 0, + 7508, + 0, + 0, + 0, + 0, + 0, + 7512, + 0, + 0, + 0, + 7513, + 7514, + 7516, + 0, + 0, + 0, + 0, + 7518, + 0, + 0, + 7519, + 7521, + 7522, + 0, + 0, + 0, + 7526, + 0, + 0, + 7529, + 0, + 0, + 7531, + 0, + 7536, + 0, + 7538, + 0, + 7539, + 0, + 0, + 7541, + 7542, + 7546, + 0, + 0, + 0, + 0, + 0, + 7547, + 0, + 7548, + 0, + 0, + 0, + 0, + 0, + 7550, + 0, + 0, + 7552, + 7553, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7554, + 7563, + 0, + 7573, + 0, + 0, + 0, + 0, + 0, + 0, + 7574, + 7576, + 0, + 7578, + 7581, + 7583, + 0, + 0, + 0, + 7584, + 0, + 7587, + 0, + 0, + 0, + 0, + 0, + 7589, + 0, + 0, + 0, + 7594, + 0, + 0, + 7595, + 0, + 0, + 7600, + 7602, + 7610, + 0, + 0, + 0, + 0, + 0, + 7612, + 0, + 7613, + 7614, + 0, + 0, + 7615, + 0, + 0, + 7616, + 0, + 7620, + 0, + 7621, + 7622, + 0, + 7623, + 0, + 0, + 0, + 0, + 7626, + 0, + 0, + 0, + 0, + 7627, + 7629, + 7631, + 0, + 0, + 7633, + 0, + 0, + 0, + 0, + 0, + 7639, + 0, + 7640, + 7642, + 0, + 0, + 7643, + 0, + 0, + 0, + 0, + 7644, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7645, + 0, + 0, + 0, + 0, + 0, + 7661, + 7662, + 7663, + 7665, + 0, + 7666, + 0, + 7667, + 0, + 7684, + 7688, + 7690, + 0, + 7691, + 0, + 0, + 0, + 0, + 0, + 0, + 7692, + 0, + 0, + 7700, + 0, + 7707, + 0, + 7708, + 0, + 7709, + 0, + 7721, + 0, + 0, + 0, + 7722, + 0, + 7724, + 0, + 0, + 0, + 0, + 0, + 0, + 7729, + 7731, + 0, + 7732, + 0, + 7733, + 7735, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7739, + 0, + 0, + 7741, + 7745, + 0, + 7748, + 0, + 0, + 0, + 7751, + 0, + 0, + 0, + 7752, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7753, + 0, + 0, + 7756, + 0, + 7757, + 0, + 7759, + 0, + 7760, + 0, + 0, + 0, + 0, + 7761, + 7768, + 0, + 0, + 7769, + 0, + 0, + 7770, + 0, + 0, + 7771, + 0, + 0, + 7772, + 0, + 0, + 7773, + 0, + 0, + 0, + 0, + 0, + 7778, + 7783, + 0, + 0, + 0, + 0, + 0, + 7784, + 7785, + 0, + 7790, + 0, + 0, + 0, + 0, + 7792, + 0, + 7798, + 0, + 0, + 0, + 0, + 0, + 7799, + 0, + 7810, + 0, + 0, + 7813, + 0, + 7814, + 0, + 7816, + 0, + 7818, + 7824, + 7825, + 7826, + 0, + 7828, + 7830, + 0, + 0, + 0, + 7840, + 0, + 7842, + 0, + 7843, + 0, + 0, + 0, + 0, + 7844, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7846, + 0, + 0, + 0, + 0, + 0, + 7856, + 7857, + 7858, + 7862, + 0, + 7865, + 0, + 0, + 7866, + 0, + 0, + 7913, + 0, + 0, + 0, + 0, + 7914, + 0, + 0, + 7915, + 7917, + 7918, + 7919, + 0, + 7920, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7921, + 7922, + 0, + 7924, + 0, + 0, + 7925, + 0, + 0, + 7927, + 0, + 7930, + 7935, + 0, + 0, + 7937, + 0, + 0, + 0, + 0, + 0, + 0, + 7939, + 0, + 7940, + 0, + 0, + 0, + 0, + 0, + 7941, + 0, + 0, + 0, + 0, + 7945, + 0, + 0, + 0, + 0, + 7949, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7950, + 0, + 7953, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7968, + 0, + 0, + 0, + 0, + 7969, + 7972, + 7992, + 0, + 7993, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7994, + 0, + 0, + 0, + 0, + 8007, + 8008, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8010, + 0, + 0, + 0, + 8012, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8018, + 0, + 8028, + 8029, + 0, + 0, + 8030, + 0, + 0, + 8032, + 8033, + 0, + 0, + 8034, + 8036, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8037, + 0, + 0, + 0, + 8043, + 8052, + 8059, + 8060, + 0, + 0, + 8061, + 0, + 0, + 0, + 8062, + 0, + 8063, + 0, + 8064, + 0, + 8066, + 8068, + 0, + 0, + 0, + 8080, + 8081, + 0, + 8089, + 0, + 0, + 0, + 0, + 0, + 8092, + 0, + 0, + 0, + 0, + 0, + 0, + 8093, + 8110, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8111, + 0, + 0, + 0, + 0, + 0, + 8112, + 8115, + 0, + 8117, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8120, + 8121, + 8122, + 8128, + 8129, + 8130, + 8131, + 0, + 0, + 8139, + 0, + 0, + 8144, + 0, + 0, + 0, + 0, + 8145, + 8146, + 8153, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8154, + 0, + 8157, + 8160, + 8162, + 0, + 8164, + 8165, + 0, + 0, + 0, + 0, + 8166, + 8167, + 0, + 0, + 8179, + 0, + 0, + 0, + 8185, + 0, + 0, + 0, + 8186, + 0, + 0, + 8187, + 0, + 0, + 0, + 8188, + 0, + 0, + 0, + 0, + 0, + 8204, + 0, + 0, + 0, + 0, + 8210, + 0, + 0, + 0, + 0, + 0, + 8213, + 0, + 8214, + 0, + 0, + 8215, + 0, + 0, + 0, + 0, + 0, + 0, + 8218, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8219, + 0, + 8221, + 0, + 0, + 8222, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8225, + 0, + 0, + 0, + 8233, + 0, + 0, + 8242, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8247, + 0, + 8248, + 8252, + 0, + 8256, + 8257, + 0, + 0, + 8261, + 0, + 8264, + 8265, + 0, + 0, + 0, + 0, + 8267, + 0, + 0, + 0, + 8269, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8270, + 0, + 0, + 0, + 8278, + 0, + 8279, + 8283, + 0, + 0, + 8285, + 8286, + 8289, + 8292, + 0, + 0, + 0, + 0, + 8293, + 8295, + 8299, + 8300, + 8301, + 0, + 0, + 0, + 0, + 0, + 0, + 8304, + 8307, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8321, + 0, + 0, + 0, + 8322, + 8323, + 8325, + 8326, + 8327, + 0, + 0, + 8332, + 8338, + 0, + 0, + 8340, + 0, + 0, + 0, + 0, + 0, + 8350, + 0, + 0, + 8351, + 0, + 8354, + 8355, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8360, + 8372, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8377, + 0, + 0, + 0, + 0, + 8380, + 0, + 0, + 0, + 8383, + 0, + 8384, + 0, + 0, + 0, + 0, + 8386, + 8392, + 0, + 0, + 8394, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8396, + 8397, + 0, + 8398, + 0, + 8399, + 0, + 0, + 0, + 0, + 0, + 8400, + 0, + 8401, + 8410, + 8411, + 0, + 8412, + 8413, + 8422, + 0, + 0, + 0, + 0, + 8423, + 0, + 0, + 0, + 0, + 8424, + 0, + 0, + 8425, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8441, + 8442, + 0, + 0, + 0, + 0, + 0, + 0, + 8443, + 0, + 0, + 8444, + 0, + 8447, + 0, + 0, + 0, + 0, + 8451, + 0, + 8458, + 0, + 8462, + 0, + 0, + 8468, + 0, + 8469, + 0, + 0, + 0, + 8470, + 0, + 8473, + 8479, + 8480, + 0, + 0, + 0, + 0, + 8481, + 8483, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8484, + 0, + 0, + 8490, + 0, + 0, + 0, + 0, + 0, + 0, + 8491, + 8493, + 8494, + 0, + 8528, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8530, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8534, + 8538, + 8540, + 0, + 0, + 8541, + 0, + 0, + 8545, + 0, + 8557, + 0, + 0, + 8569, + 8570, + 0, + 0, + 8571, + 8574, + 8575, + 8579, + 0, + 8583, + 0, + 0, + 0, + 0, + 8591, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8606, + 0, + 8607, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8608, + 0, + 0, + 8609, + 0, + 0, + 0, + 8610, + 0, + 0, + 0, + 8611, + 0, + 0, + 8613, + 8617, + 8621, + 0, + 0, + 8622, + 0, + 8623, + 0, + 8624, + 8625, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8637, + 8638, + 8639, + 8650, + 0, + 0, + 0, + 0, + 8652, + 8654, + 8655, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8656, + 0, + 0, + 0, + 0, + 0, + 8657, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8658, + 0, + 0, + 8659, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8660, + 0, + 0, + 0, + 0, + 0, + 0, + 8661, + 8663, + 8664, + 0, + 0, + 0, + 0, + 8665, + 0, + 8669, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8671, + 8674, + 0, + 8684, + 0, + 8686, + 0, + 0, + 0, + 8689, + 0, + 0, + 0, + 8690, + 0, + 8706, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8710, + 0, + 8711, + 8713, + 8714, + 8724, + 8727, + 8728, + 8733, + 8736, + 0, + 8737, + 8739, + 0, + 0, + 0, + 0, + 8742, + 8743, + 8745, + 8754, + 0, + 0, + 0, + 0, + 8756, + 0, + 0, + 0, + 0, + 0, + 0, + 8757, + 8760, + 0, + 0, + 0, + 0, + 0, + 8762, + 8763, + 8764, + 0, + 8766, + 8769, + 8770, + 8773, + 0, + 8774, + 0, + 8779, + 0, + 0, + 0, + 0, + 8780, + 0, + 0, + 8781, + 0, + 0, + 8783, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8784, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8785, + 0, + 0, + 0, + 0, + 8786, + 0, + 0, + 0, + 0, + 8788, + 8790, + 0, + 0, + 0, + 8803, + 0, + 8813, + 8814, + 0, + 0, + 0, + 0, + 0, + 8815, + 8816, + 0, + 0, + 0, + 0, + 8818, + 0, + 0, + 0, + 0, + 8822, + 8828, + 8829, + 0, + 8831, + 0, + 0, + 0, + 0, + 8833, + 0, + 0, + 0, + 8834, + 0, + 0, + 0, + 8835, + 0, + 8836, + 0, + 0, + 0, + 8837, + 0, + 0, + 0, + 0, + 0, + 0, + 8838, + 8839, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8840, + 0, + 0, + 0, + 8841, + 0, + 8842, + 0, + 0, + 0, + 8846, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8847, + 0, + 8848, + 0, + 0, + 8864, + 0, + 0, + 8866, + 0, + 0, + 8870, + 8872, + 0, + 0, + 8873, + 8874, + 0, + 0, + 0, + 0, + 0, + 0, + 8875, + 0, + 8876, + 0, + 0, + 0, + 0, + 8896, + 8900, + 0, + 0, + 0, + 0, + 8901, + 0, + 0, + 0, + 0, + 0, + 8904, + 0, + 8907, + 0, + 0, + 0, + 0, + 8911, + 8912, + 8913, + 0, + 0, + 0, + 8914, + 0, + 8915, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8916, + 0, + 0, + 0, + 8929, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8930, + 0, + 8932, + 0, + 8943, + 0, + 0, + 0, + 8945, + 8947, + 0, + 0, + 0, + 0, + 8949, + 0, + 8950, + 0, + 8954, + 8957, + 0, + 0, + 8970, + 0, + 0, + 0, + 0, + 8971, + 0, + 8996, + 0, + 0, + 0, + 0, + 8997, + 9000, + 0, + 0, + 0, + 0, + 9001, + 9002, + 0, + 9004, + 9009, + 9024, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 9027, + 9082, + 0, + 0, + 9083, + 9089, + 0, + 0, + 0, + 0, + 0, + 0, + 9090, + 0, + 0, + 0, + 9092, + 0, + 0, + 9093, + 0, + 9095, + 0, + 0, + 9096, + 9097, + 9101, + 9102, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 9112, + 0, + 0, + 0, + 0, + 0, + 0, + 9114, + 0, + 0, + 9120, + 0, + 9121, + 9122, + 0, + 0, + 0, + 9123, + 9124, + 0, + 0, + 9125, + 0, + 0, + 9126, + 0, + 9127, + 0, + 0, + 9129, + 9131, + 0, + 0, + 0, + 9132, + 0, + 0, + 9136, + 0, + 9144, + 0, + 0, + 9148, + 0, + 0, + 0, + 0, + 0, + 0, + 9149, + 0, + 9152, + 9163, + 0, + 0, + 9165, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 9166, + 0, + 9169, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 9170, + 0, + 0, + 0, + 0, + 9172, + 0, + 9174, + 9175, + 9176, + 0, + 9177, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 9186, + 0, + 9187, + 0, + 0, + 0, + 9188, + 9189, + 0, + 0, + 9190, + 0, + 0, + 0, + 0, + 9191, + 0, + 0, + 0, + 9193, + 0, + 0, + 0, + 0, + 9197, + 9198, + 0, + 0, + 0, + 9208, + 9211, + 0, + 0, + 0, + 0, + 9216, + 9217, + 0, + 9220, + 0, + 0, + 0, + 0, + 9221, + 9222, + 9223, + 0, + 9224, + 9225, + 0, + 0, + 9227, + 0, + 9228, + 9229, + 0, + 0, + 9230, + 0, + 9232, + 0, + 9233, + 0, + 0, + 0, + 0, + 0, + 9234, + 9235, + 0, + 0, + 9237, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 9238, + 9240, + 0, + 0, + 9241, + 0, + 0, + 0, + 0, + 9244, + 0, + 0, + 0, + 0, + 9247, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 9248, + 0, + 0, + 0, + 9249, + 0, + 0, + 0, + 0, + 0, + 9250, + 0, + 0, + 0, + 0, + 9251, + 0, + 0, + 9252, + 9255, + 0, + 0, + 0, + 9256, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 9257, + 0, + 0, + 9258, + 0, + 0, + 0, + 0, + 0, + 0, + 9259, + 0, + 0, + 0, + 0, + 0, + 9262, + 9263, + 0, + 0, + 9265, + 9266, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 9268, + 9271, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 9273, + 0, + 0, + 0, + 9276, + 9277, + 9279, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 9280, + 0, + 0, + 9293, + 0, + 0, + 0, + 0, + 0, + 9297, + 9301, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 9308, + 9309, + 9313, + 9321, + 9322, + 0, + 9326, + 9327, + 0, + 0, + 9477, + 0, + 9479, + 0, + 0, + 0, + 0, + 9482, + 0, + 0, + 0, + 9483, + 0, + 9484, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 9485, + 0, + 0, + 9486, + 0, + 0, + 0, + 9489, + 0, + 0, + 0, + 0, + 9490, + 9491, + 0, + 0, + 0, + 0, + 9493, + 0, + 9495, + 9496, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 9500, + 0, + 9502, + 0, + 0, + 0, + 0, + 0, + 9504, + 9507, + 0, + 9509, + 0, + 9511, + 0, + 0, + 9513, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 9515, + 0, + 0, + 0, + 0, + 0, + 0, + 9516, + 9517, + 0, + 0, + 0, + 0, + 9532, + 0, + 0, + 9533, + 0, + 0, + 9538, + 0, + 9539, + 9540, + 0, + 0, + 0, + 0, + 9541, + 0, + 0, + 0, + 9542, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 9544, + 9545, + 0, + 9546, + 0, + 0, + 0, + 0, + 0, + 0, + 9547, + 9548, + 0, + 0, + 0, + 9550, + 0, + 9557, + 0, + 9558, + 0, + 9561, + 0, + 9563, + 9570, + 0, + 9572, + 9574, + 9575, + 0, + 0, + 0, + 9577, + 9592, + 0, + 0, + 9596, + 0, + 0, + 0, + 9598, + 0, + 9600, + 0, + 9601, + 0, + 0, + 0, + 0, + 0, + 0, + 9608, + 0, + 9638, + 9639, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 9641, + 0, + 0, + 9643, + 9644, + 9645, + 9646, + 0, + 0, + 0, + 9648, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 9650, + 9654, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 9655, + 0, + 0, + 0, + 0, + 0, + 9656, + 0, + 9657, + 0, + 0, + 0, + 0, + 9658, + 0, + 0, + 9659, + 0, + 0, + 9664, + 0, + 0, + 9665, + 0, + 9667, + 9669, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 9671, + 0, + 9673, + 9681, + 0, + 0, + 0, + 0, + 9682, + 9683, + 9684, + 0, + 0, + 0, + 0, + 9686, + 9698, + 0, + 0, + 9700, + 9701, + 9702, + 0, + 9703, + 9717, + 0, + 0, + 0, + 0, + 9718, + 0, + 9726, + 0, + 0, + 0, + 0, + 9727, + 0, + 0, + 0, + 9728, + 0, + 9742, + 0, + 9744, + 0, + 0, + 0, + 9750, + 0, + 9754, + 9755, + 0, + 0, + 0, + 0, + 0, + 9756, + 0, + 9757, + 9768, + 0, + 9769, + 0, + 0, + 0, + 9770, + 9771, + 0, + 9773, + 0, + 9774, + 0, + 9775, + 0, + 0, + 0, + 9776, + 9777, + 9784, + 0, + 0, + 0, + 9786, + 0, + 9789, + 0, + 0, + 0, + 0, + 9793, + 9794, + 0, + 0, + 0, + 9808, + 0, + 0, + 0, + 0, + 0, + 9811, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 9812, + 0, + 9820, + 0, + 9823, + 0, + 9828, + 0, + 0, + 0, + 0, + 9830, + 0, + 0, + 9833, + 9836, + 0, + 0, + 0, + 9840, + 0, + 0, + 0, + 9841, + 0, + 0, + 9842, + 0, + 9845, + 0, + 0, + 0, + 9847, + 9848, + 0, + 0, + 9855, + 0, + 0, + 0, + 0, + 0, + 0, + 9856, + 9863, + 9865, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 9866, + 9867, + 9868, + 9873, + 9875, + 0, + 0, + 0, + 0, + 0, + 0, + 9880, + 0, + 9886, + 0, + 0, + 0, + 9887, + 0, + 0, + 9891, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 9906, + 9907, + 9908, + 0, + 0, + 0, + 9909, + 0, + 0, + 0, + 0, + 0, + 0, + 9910, + 0, + 0, + 0, + 0, + 9913, + 0, + 0, + 0, + 0, + 9914, + 0, + 0, + 0, + 0, + 0, + 9922, + 0, + 0, + 0, + 0, + 9923, + 9925, + 0, + 0, + 0, + 0, + 0, + 0, + 9930, + 0, + 0, + 0, + 9931, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 9932, + 0, + 9939, + 0, + 0, + 9940, + 9962, + 9966, + 0, + 9969, + 9970, + 0, + 0, + 9974, + 0, + 9979, + 9981, + 9982, + 0, + 0, + 0, + 9985, + 0, + 0, + 0, + 0, + 0, + 0, + 9987, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 9988, + 9993, + 0, + 0, + 9994, + 0, + 0, + 0, + 9997, + 0, + 10004, + 0, + 0, + 0, + 0, + 0, + 10007, + 10019, + 10020, + 10022, + 0, + 0, + 0, + 10031, + 0, + 0, + 0, + 0, + 0, + 10032, + 0, + 0, + 10034, + 0, + 10036, + 0, + 0, + 0, + 0, + 10038, + 0, + 10039, + 10040, + 10041, + 10042, + 0, + 0, + 0, + 0, + 0, + 10043, + 0, + 0, + 0, + 0, + 0, + 10045, + 10054, + 0, + 0, + 0, + 0, + 10055, + 0, + 0, + 10057, + 10058, + 0, + 0, + 0, + 0, + 0, + 0, + 10059, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10060, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10063, + 0, + 10066, + 0, + 0, + 0, + 10070, + 0, + 10072, + 0, + 0, + 10076, + 10077, + 0, + 0, + 10084, + 0, + 10087, + 10090, + 10091, + 0, + 0, + 0, + 10094, + 10097, + 0, + 0, + 0, + 0, + 0, + 0, + 10098, + 0, + 0, + 0, + 0, + 0, + 0, + 10103, + 0, + 10104, + 0, + 10108, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10120, + 0, + 0, + 0, + 10122, + 0, + 0, + 10125, + 0, + 0, + 0, + 0, + 10127, + 10128, + 0, + 0, + 10134, + 0, + 10135, + 10136, + 0, + 10137, + 0, + 0, + 10147, + 0, + 10149, + 10150, + 0, + 0, + 10156, + 0, + 10158, + 10159, + 10160, + 10168, + 0, + 0, + 10171, + 0, + 10173, + 0, + 0, + 0, + 10176, + 0, + 0, + 0, + 0, + 10177, + 0, + 0, + 0, + 0, + 10178, + 0, + 0, + 0, + 0, + 10194, + 0, + 10202, + 0, + 0, + 10203, + 10204, + 0, + 10205, + 10206, + 0, + 10207, + 0, + 0, + 0, + 0, + 10209, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10213, + 0, + 0, + 0, + 0, + 0, + 0, + 10217, + 0, + 10229, + 0, + 10230, + 10231, + 0, + 0, + 10232, + 0, + 0, + 10237, + 10238, + 10244, + 0, + 0, + 0, + 0, + 0, + 10250, + 0, + 10252, + 0, + 0, + 0, + 0, + 0, + 0, + 10255, + 0, + 0, + 10257, + 0, + 0, + 0, + 0, + 0, + 0, + 10258, + 0, + 10259, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10260, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10284, + 10288, + 10289, + 0, + 0, + 0, + 10290, + 0, + 10296, + 0, + 0, + 0, + 0, + 0, + 10297, + 0, + 0, + 0, + 0, + 0, + 0, + 10298, + 0, + 0, + 0, + 0, + 10299, + 10303, + 0, + 0, + 0, + 0, + 0, + 10306, + 0, + 0, + 0, + 10307, + 0, + 10308, + 0, + 0, + 0, + 0, + 10311, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10315, + 10317, + 0, + 0, + 0, + 10318, + 10319, + 0, + 10321, + 0, + 10326, + 0, + 10328, + 0, + 0, + 0, + 0, + 10329, + 0, + 0, + 10331, + 0, + 10332, + 0, + 0, + 0, + 0, + 0, + 0, + 10334, + 0, + 0, + 10335, + 10338, + 0, + 0, + 0, + 0, + 0, + 10339, + 10349, + 0, + 0, + 0, + 0, + 0, + 0, + 10351, + 0, + 10353, + 0, + 0, + 0, + 0, + 0, + 0, + 10362, + 0, + 10368, + 0, + 10369, + 0, + 0, + 0, + 10372, + 10373, + 0, + 0, + 0, + 0, + 0, + 10374, + 0, + 0, + 0, + 10375, + 0, + 10376, + 0, + 0, + 10386, + 10388, + 10390, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10391, + 0, + 0, + 10392, + 10394, + 0, + 0, + 10396, + 0, + 10397, + 0, + 10403, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10404, + 0, + 10405, + 10410, + 0, + 0, + 10411, + 0, + 10412, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10421, + 10422, + 10423, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10425, + 0, + 0, + 10427, + 0, + 0, + 10430, + 0, + 0, + 0, + 0, + 0, + 10432, + 0, + 10433, + 10434, + 0, + 0, + 0, + 0, + 10436, + 10437, + 0, + 10438, + 0, + 10439, + 0, + 10444, + 10446, + 0, + 0, + 0, + 0, + 0, + 10448, + 0, + 0, + 0, + 0, + 0, + 10449, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10451, + 0, + 10453, + 0, + 0, + 0, + 10454, + 10457, + 0, + 0, + 10459, + 0, + 10469, + 0, + 0, + 0, + 0, + 0, + 10472, + 10481, + 0, + 0, + 0, + 0, + 0, + 10482, + 10483, + 0, + 10492, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10499, + 0, + 0, + 0, + 10502, + 0, + 0, + 10510, + 0, + 10521, + 10524, + 0, + 0, + 10525, + 10526, + 10528, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10530, + 0, + 0, + 0, + 0, + 10533, + 0, + 10534, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10535, + 10536, + 0, + 0, + 10544, + 0, + 10553, + 10556, + 0, + 10557, + 10559, + 0, + 0, + 0, + 0, + 0, + 10562, + 10563, + 10564, + 0, + 10565, + 0, + 0, + 0, + 10566, + 0, + 10567, + 0, + 0, + 0, + 0, + 10575, + 0, + 0, + 10576, + 0, + 10578, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10585, + 10586, + 10587, + 10589, + 0, + 10590, + 0, + 0, + 10594, + 0, + 0, + 0, + 0, + 0, + 10598, + 0, + 0, + 10601, + 0, + 0, + 0, + 10602, + 0, + 10603, + 0, + 10604, + 0, + 10605, + 0, + 0, + 10607, + 0, + 10626, + 0, + 10627, + 0, + 0, + 0, + 0, + 0, + 10629, + 10630, + 10631, + 0, + 0, + 0, + 10646, + 0, + 0, + 0, + 10647, + 0, + 10650, + 0, + 10651, + 0, + 0, + 0, + 10652, + 10653, + 10655, + 0, + 10658, + 0, + 0, + 10659, + 0, + 10667, + 0, + 0, + 0, + 0, + 10669, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10670, + 0, + 0, + 0, + 10671, + 0, + 0, + 0, + 0, + 10672, + 10673, + 0, + 10674, + 0, + 0, + 0, + 10676, + 0, + 0, + 0, + 0, + 0, + 0, + 10678, + 0, + 10682, + 0, + 0, + 10692, + 0, + 10697, + 0, + 0, + 0, + 0, + 10698, + 0, + 0, + 0, + 10700, + 0, + 0, + 0, + 0, + 0, + 10703, + 0, + 10704, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10705, + 0, + 10715, + 10718, + 10720, + 0, + 0, + 10722, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10723, + 0, + 0, + 0, + 0, + 10726, + 0, + 0, + 0, + 0, + 0, + 10727, + 10730, + 10743, + 0, + 0, + 0, + 0, + 0, + 0, + 10744, + 0, + 0, + 10745, + 0, + 0, + 0, + 0, + 0, + 0, + 10748, + 0, + 0, + 0, + 0, + 10750, + 0, + 0, + 10752, + 10753, + 0, + 0, + 0, + 10756, + 0, + 0, + 0, + 0, + 0, + 0, + 10758, + 0, + 0, + 0, + 10759, + 0, + 10769, + 0, + 0, + 10772, + 0, + 0, + 0, + 0, + 0, + 0, + 10773, + 0, + 0, + 0, + 10777, + 0, + 0, + 10779, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10780, + 10784, + 0, + 0, + 0, + 10789, + 0, + 0, + 0, + 10791, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10795, + 0, + 0, + 10796, + 0, + 10808, + 0, + 10809, + 0, + 0, + 0, + 10810, + 0, + 0, + 0, + 10812, + 0, + 0, + 10814, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10815, + 0, + 0, + 0, + 0, + 10816, + 10817, + 0, + 0, + 0, + 0, + 10819, + 0, + 10820, + 0, + 0, + 0, + 0, + 10821, + 10822, + 10823, + 0, + 10826, + 10849, + 0, + 0, + 0, + 0, + 10850, + 0, + 0, + 10852, + 0, + 10853, + 0, + 0, + 10856, + 0, + 0, + 10857, + 10858, + 10859, + 10860, + 0, + 0, + 0, + 0, + 0, + 0, + 10863, + 0, + 10866, + 10867, + 10872, + 10890, + 0, + 0, + 10891, + 10892, + 0, + 0, + 0, + 0, + 0, + 10893, + 0, + 0, + 0, + 10896, + 10899, + 0, + 0, + 10900, + 10902, + 0, + 0, + 0, + 0, + 0, + 10903, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10905, + 0, + 10906, + 0, + 0, + 0, + 0, + 10908, + 10911, + 0, + 10912, + 0, + 0, + 10916, + 0, + 0, + 0, + 0, + 0, + 10917, + 0, + 10918, + 0, + 0, + 0, + 10923, + 0, + 0, + 0, + 0, + 0, + 10924, + 0, + 0, + 10928, + 10929, + 0, + 0, + 10930, + 0, + 0, + 0, + 10932, + 0, + 0, + 0, + 0, + 10939, + 0, + 0, + 10945, + 0, + 0, + 0, + 10947, + 0, + 0, + 10948, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10958, + 0, + 10960, + 10962, + 0, + 0, + 10964, + 0, + 0, + 0, + 10966, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10967, + 0, + 0, + 0, + 10968, + 0, + 0, + 0, + 10973, + 0, + 0, + 0, + 0, + 0, + 10975, + 0, + 0, + 0, + 10976, + 10978, + 0, + 0, + 10982, + 10984, + 10987, + 0, + 0, + 10988, + 0, + 10989, + 0, + 0, + 10991, + 0, + 0, + 0, + 0, + 10992, + 0, + 0, + 0, + 10993, + 0, + 10995, + 0, + 0, + 0, + 10996, + 10997, + 0, + 0, + 0, + 10998, + 0, + 10999, + 0, + 11001, + 0, + 0, + 0, + 0, + 0, + 0, + 11010, + 11012, + 0, + 11013, + 11016, + 11017, + 0, + 0, + 11019, + 11020, + 11021, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 11022, + 0, + 0, + 11023, + 11029, + 0, + 0, + 0, + 0, + 11031, + 0, + 0, + 0, + 11034, + 0, + 0, + 0, + 0, + 11055, + 0, + 0, + 0, + 0, + 0, + 11056, + 11060, + 0, + 0, + 0, + 0, + 0, + 0, + 11061, + 0, + 0, + 11064, + 11065, + 0, + 11066, + 0, + 11069, + 0, + 11085, + 0, + 0, + 0, + 0, + 0, + 11086, + 0, + 0, + 0, + 11088, + 0, + 0, + 0, + 11094, + 0, + 0, + 0, + 11095, + 11096, + 0, + 0, + 0, + 0, + 0, + 0, + 11097, + 11098, + 0, + 0, + 0, + 0, + 0, + 0, + 11099, + 0, + 0, + 11102, + 11108, + 0, + 0, + 0, + 11109, + 0, + 11114, + 11119, + 0, + 11131, + 0, + 0, + 0, + 11142, + 0, + 0, + 11143, + 0, + 11146, + 0, + 11147, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 11148, + 0, + 11149, + 11152, + 11153, + 11154, + 0, + 11156, + 0, + 11157, + 0, + 0, + 0, + 11158, + 0, + 0, + 11159, + 11160, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 11163, + 0, + 0, + 11164, + 11166, + 0, + 0, + 0, + 11172, + 11174, + 0, + 0, + 0, + 11176, + 0, + 0, + 0, + 0, + 0, + 11182, + 11183, + 0, + 0, + 0, + 11184, + 11187, + 0, + 0, + 11188, + 11189, + 0, + 0, + 0, + 0, + 0, + 0, + 11194, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 11200, + 11202, + 0, + 0, + 0, + 0, + 0, + 0, + 11203, + 0, + 11204, + 0, + 0, + 0, + 0, + 0, + 11205, + 0, + 0, + 0, + 11206, + 0, + 11207, + 0, + 0, + 11209, + 0, + 11211, + 0, + 11214, + 0, + 0, + 11231, + 0, + 0, + 0, + 11293, + 11295, + 0, + 0, + 11296, + 11297, + 11302, + 0, + 0, + 0, + 11307, + 0, + 0, + 0, + 0, + 11309, + 11310, + 0, + 11311, + 0, + 0, + 0, + 11313, + 0, + 11314, + 0, + 0, + 0, + 0, + 11334, + 0, + 11338, + 0, + 0, + 0, + 11339, + 0, + 0, + 0, + 0, + 0, + 11340, + 0, + 11341, + 11342, + 0, + 11344, + 0, + 11345, + 0, + 0, + 0, + 11348, + 11349, + 0, + 0, + 11350, + 0, + 0, + 0, + 11355, + 0, + 0, + 0, + 0, + 0, + 0, + 11356, + 0, + 11357, + 11370, + 0, + 0, + 11371, + 0, + 11374, + 11376, + 0, + 0, + 0, + 11377, + 0, + 0, + 11378, + 11383, + 0, + 11386, + 11399, + 0, + 11400, + 11406, + 0, + 0, + 0, + 11408, + 0, + 0, + 11409, + 11412, + 0, + 0, + 0, + 0, + 11417, + 0, + 0, + 0, + 11418, + 0, + 11421, + 0, + 11426, + 11429, + 0, + 0, + 0, + 0, + 0, + 11430, + 0, + 11437, + 0, + 11438, + 0, + 0, + 0, + 0, + 0, + 11440, + 11453, + 0, + 0, + 0, + 0, + 0, + 0, + 11454, + 0, + 0, + 0, + 0, + 11455, + 0, + 0, + 11456, + 11460, + 11461, + 11463, + 0, + 11469, + 0, + 11473, + 0, + 0, + 0, + 0, + 11474, + 0, + 0, + 0, + 11475, + 0, + 11476, + 11477, + 11480, + 0, + 0, + 0, + 0, + 11481, + 0, + 0, + 11484, + 0, + 0, + 11487, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 11497, + 0, + 0, + 11502, + 0, + 11509, + 0, + 0, + 11510, + 11511, + 11513, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 11515, + 0, + 0, + 0, + 0, + 11516, + 0, + 11520, + 11521, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 11529, + 11530, + 11531, + 11534, + 0, + 0, + 11543, + 0, + 0, + 0, + 0, + 0, + 11547, + 0, + 11548, + 0, + 0, + 0, + 0, + 0, + 11552, + 11556, + 0, + 11557, + 0, + 0, + 11559, + 0, + 11560, + 0, + 0, + 0, + 0, + 0, + 0, + 11561, + 0, + 0, + 11563, + 11564, + 0, + 11565, + 0, + 0, + 0, + 0, + 11567, + 0, + 0, + 0, + 11569, + 0, + 11574, + 0, + 11575, + 0, + 0, + 0, + 11577, + 0, + 11578, + 0, + 0, + 0, + 11580, + 11581, + 0, + 0, + 0, + 11582, + 11584, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 11587, + 0, + 11588, + 11591, + 0, + 11595, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 11596, + 0, + 11597, + 0, + 0, + 0, + 0, + 11598, + 11601, + 0, + 0, + 0, + 11602, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 11603, + 11604, + 0, + 11606, + 0, + 0, + 11608, + 0, + 0, + 0, + 0, + 11610, + 0, + 0, + 11611, + 0, + 0, + 0, + 0, + 11613, + 0, + 11622, + 0, + 0, + 0, + 11623, + 0, + 0, + 0, + 0, + 11625, + 0, + 0, + 11626, + 11627, + 11628, + 11630, + 0, + 0, + 0, + 0, + 0, + 0, + 11639, + 0, + 0, + 11646, + 0, + 11648, + 11649, + 0, + 11650, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 11651, + 0, + 0, + 11652, + 11653, + 11656, + 0, + 0, + 11677, + 11679, + 0, + 0, + 0, + 0, + 11680, + 0, + 0, + 11681, + 0, + 11685, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 11688, + 0, + 0, + 0, + 11716, + 0, + 11719, + 0, + 0, + 0, + 0, + 0, + 11721, + 0, + 0, + 11724, + 11743, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 11745, + 11748, + 11750, + 0, + 0, + 0, + 0, + 0, + 11751, + 0, + 0, + 0, + 11752, + 11754, + 0, + 11755, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 11759, + 0, + 0, + 0, + 0, + 0, + 0, + 11760, + 0, + 0, + 0, + 11761, + 0, + 0, + 0, + 0, + 0, + 0, + 11766, + 11767, + 0, + 11772, + 11773, + 0, + 11774, + 0, + 0, + 11775, + 0, + 11777, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 11778, + 11780, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 11783, + 0, + 11784, + 0, + 0, + 0, + 11785, + 0, + 0, + 0, + 11786, + 0, + 0, + 0, + 0, + 11788, + 0, + 0, + 11789, + 11791, + 11792, + 0, + 0, + 0, + 0, + 11795, + 11834, + 11835, + 11836, + 0, + 0, + 11837, + 0, + 0, + 0, + 11838, + 0, + 0, + 11846, + 11851, + 0, + 11852, + 0, + 11869, + 0, + 0, + 0, + 11871, + 0, + 0, + 0, + 11872, + 11874, + 0, + 0, + 0, + 0, + 0, + 0, + 11875, + 0, + 11876, + 11877, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 11883, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 11884, + 0, + 11885, + 0, + 11886, + 0, + 0, + 11887, + 0, + 11894, + 11895, + 11897, + 11909, + 11910, + 0, + 11912, + 11918, + 0, + 0, + 11920, + 0, + 11922, + 11924, + 11927, + 11928, + 0, + 0, + 0, + 0, + 11929, + 0, + 11934, + 0, + 0, + 0, + 0, + 0, + 11941, + 11943, + 11944, + 0, + 11945, + 0, + 0, + 0, + 0, + 11948, + 11949, + 0, + 0, + 0, + 0, + 11953, + 0, + 11954, + 0, + 11955, + 0, + 11956, + 0, + 0, + 0, + 0, + 0, + 11957, + 0, + 0, + 11959, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 11961, + 0, + 0, + 0, + 0, + 0, + 11978, + 0, + 0, + 0, + 11979, + 11980, + 11986, + 11987, + 0, + 11992, + 0, + 0, + 0, + 0, + 0, + 11993, + 0, + 0, + 0, + 11994, + 0, + 11999, + 12004, + 12005, + 12006, + 0, + 0, + 0, + 0, + 0, + 12011, + 0, + 0, + 12012, + 12014, + 0, + 0, + 12015, + 0, + 0, + 12019, + 12028, + 0, + 0, + 12029, + 0, + 0, + 12032, + 12033, + 0, + 0, + 0, + 0, + 12034, + 0, + 12041, + 12043, + 0, + 0, + 12044, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12046, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12054, + 12055, + 0, + 12056, + 0, + 0, + 0, + 12060, + 12064, + 0, + 0, + 0, + 0, + 0, + 12065, + 12067, + 12068, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12074, + 0, + 0, + 0, + 12075, + 12076, + 0, + 0, + 0, + 12079, + 0, + 12081, + 12086, + 12087, + 0, + 0, + 12088, + 0, + 0, + 0, + 0, + 12089, + 0, + 12092, + 0, + 0, + 0, + 0, + 12097, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12098, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12102, + 12103, + 12104, + 12111, + 0, + 0, + 12114, + 12116, + 0, + 0, + 0, + 12118, + 0, + 0, + 0, + 12119, + 12120, + 12128, + 0, + 0, + 0, + 0, + 12130, + 0, + 0, + 0, + 0, + 0, + 0, + 12131, + 0, + 0, + 0, + 12132, + 12134, + 0, + 0, + 0, + 0, + 12137, + 0, + 12139, + 0, + 12141, + 0, + 0, + 12142, + 0, + 0, + 0, + 12144, + 0, + 0, + 0, + 0, + 0, + 12145, + 0, + 12148, + 0, + 12153, + 0, + 0, + 0, + 0, + 12154, + 12171, + 12173, + 0, + 0, + 0, + 12175, + 0, + 0, + 0, + 0, + 12178, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12183, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12184, + 0, + 0, + 0, + 12186, + 0, + 0, + 0, + 0, + 0, + 12187, + 12188, + 0, + 0, + 12189, + 0, + 12196, + 0, + 12197, + 0, + 0, + 12198, + 0, + 12201, + 0, + 0, + 0, + 0, + 12203, + 0, + 12209, + 0, + 0, + 0, + 0, + 12210, + 12211, + 12212, + 12213, + 0, + 12217, + 12218, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12222, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12223, + 0, + 0, + 12229, + 0, + 0, + 0, + 0, + 12233, + 0, + 0, + 0, + 0, + 12234, + 0, + 0, + 12236, + 12242, + 0, + 0, + 0, + 12243, + 0, + 0, + 0, + 12244, + 12253, + 0, + 12254, + 12256, + 0, + 12257, + 0, + 0, + 12275, + 0, + 0, + 0, + 0, + 0, + 12277, + 0, + 0, + 0, + 0, + 0, + 12278, + 0, + 12289, + 0, + 0, + 12290, + 0, + 12292, + 12293, + 0, + 0, + 12294, + 0, + 12295, + 0, + 0, + 12296, + 0, + 12297, + 0, + 12298, + 0, + 0, + 0, + 0, + 12301, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12309, + 0, + 12338, + 12340, + 0, + 0, + 0, + 0, + 12341, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12342, + 12343, + 0, + 12344, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12345, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12346, + 0, + 0, + 0, + 0, + 12348, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12350, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12351, + 0, + 12355, + 12356, + 12357, + 0, + 0, + 12367, + 12370, + 12371, + 0, + 0, + 0, + 0, + 0, + 12372, + 12376, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12379, + 0, + 12382, + 0, + 12383, + 0, + 0, + 12384, + 0, + 0, + 0, + 0, + 12393, + 0, + 0, + 12394, + 0, + 0, + 0, + 0, + 12398, + 12403, + 0, + 0, + 12404, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12410, + 0, + 0, + 0, + 12411, + 0, + 0, + 0, + 12412, + 0, + 0, + 0, + 0, + 12420, + 0, + 12421, + 0, + 0, + 0, + 0, + 0, + 12423, + 0, + 12425, + 12429, + 0, + 0, + 0, + 12431, + 12432, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12434, + 0, + 0, + 0, + 0, + 0, + 12435, + 12436, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12437, + 0, + 0, + 0, + 0, + 0, + 12438, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12445, + 0, + 0, + 0, + 12450, + 12451, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12452, + 12475, + 0, + 0, + 12493, + 12494, + 0, + 0, + 0, + 12495, + 0, + 0, + 0, + 0, + 12496, + 12502, + 12509, + 0, + 0, + 0, + 0, + 12510, + 0, + 12512, + 12513, + 0, + 0, + 0, + 0, + 12514, + 0, + 0, + 0, + 12515, + 0, + 12520, + 0, + 0, + 0, + 12524, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12527, + 0, + 0, + 0, + 12528, + 0, + 0, + 0, + 12529, + 0, + 0, + 0, + 0, + 0, + 12530, + 0, + 12535, + 0, + 0, + 12536, + 0, + 12538, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12540, + 0, + 12548, + 0, + 0, + 0, + 0, + 0, + 12550, + 0, + 0, + 0, + 12551, + 12552, + 0, + 0, + 0, + 12554, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12555, + 0, + 0, + 12562, + 0, + 12565, + 0, + 12566, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12569, + 0, + 0, + 0, + 12571, + 12574, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12577, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12578, + 12579, + 12603, + 0, + 12608, + 0, + 0, + 12611, + 0, + 12612, + 0, + 12615, + 0, + 12625, + 0, + 0, + 0, + 0, + 12627, + 12646, + 0, + 12648, + 0, + 0, + 12657, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12670, + 0, + 0, + 12671, + 0, + 12673, + 12677, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12679, + 0, + 12681, + 0, + 12682, + 12693, + 0, + 12694, + 0, + 12697, + 0, + 12701, + 0, + 0, + 0, + 12703, + 12704, + 0, + 0, + 0, + 0, + 12707, + 12737, + 0, + 0, + 12739, + 0, + 0, + 12740, + 0, + 0, + 12742, + 12743, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12745, + 0, + 12746, + 12747, + 0, + 12748, + 0, + 0, + 12759, + 12767, + 0, + 0, + 0, + 0, + 12773, + 0, + 12774, + 12778, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12779, + 0, + 0, + 0, + 0, + 0, + 12780, + 12793, + 0, + 12824, + 0, + 12825, + 0, + 12836, + 0, + 0, + 0, + 0, + 12839, + 0, + 12842, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12843, + 12845, + 0, + 12846, + 0, + 0, + 0, + 0, + 12847, + 0, + 0, + 12850, + 12852, + 12853, + 0, + 0, + 0, + 12854, + 0, + 0, + 0, + 12855, + 0, + 12856, + 0, + 12858, + 0, + 0, + 12859, + 0, + 12862, + 0, + 12863, + 0, + 0, + 12866, + 0, + 12869, + 12872, + 12873, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12875, + 0, + 12877, + 0, + 0, + 12878, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12884, + 12885, + 12888, + 0, + 12889, + 0, + 0, + 0, + 0, + 12893, + 0, + 0, + 0, + 12895, + 12896, + 12898, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12902, + 0, + 12909, + 12910, + 0, + 12926, + 0, + 12928, + 0, + 0, + 0, + 12929, + 0, + 12930, + 0, + 0, + 0, + 0, + 12931, + 0, + 12932, + 12933, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12934, + 0, + 12942, + 0, + 0, + 0, + 0, + 12944, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12946, + 0, + 0, + 12948, + 0, + 0, + 12949, + 0, + 0, + 0, + 0, + 12950, + 0, + 0, + 0, + 0, + 12951, + 0, + 12952, + 0, + 12953, + 0, + 0, + 0, + 12954, + 12958, + 12959, + 0, + 0, + 0, + 0, + 0, + 12960, + 12964, + 0, + 0, + 0, + 0, + 0, + 12966, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12970, + 0, + 12971, + 0, + 0, + 0, + 0, + 0, + 0, + 12972, + 0, + 0, + 12982, + 0, + 0, + 0, + 12984, + 12985, + 0, + 12986, + 12996, + 12997, + 13001, + 13002, + 0, + 0, + 0, + 0, + 13004, + 0, + 0, + 13005, + 0, + 0, + 13007, + 13009, + 0, + 13017, + 0, + 0, + 0, + 13020, + 0, + 13021, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 13022, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 13024, + 13027, + 0, + 0, + 0, + 0, + 0, + 13028, + 0, + 0, + 13029, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 13032, + 0, + 13037, + 0, + 0, + 0, + 0, + 0, + 0, + 13040, + 0, + 0, + 13041, + 0, + 0, + 0, + 13043, + 13044, + 13046, + 0, + 0, + 0, + 0, + 13047, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 13049, + 13054, + 0, + 13056, + 0, + 0, + 13060, + 13061, + 0, + 0, + 0, + 0, + 0, + 13067, + 0, + 0, + 13068, + 0, + 13071, + 0, + 0, + 0, + 0, + 0, + 13077, + 13078, + 0, + 0, + 0, + 0, + 0, + 13079, + 13080, + 13081, + 0, + 13082, + 0, + 0, + 0, + 13085, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 13086, + 0, + 13087, + 13088, + 0, + 0, + 0, + 0, + 0, + 13094, + 0, + 13099, + 0, + 13100, + 0, + 0, + 0, + 13101, + 0, + 13125, + 13126, + 13128, + 13129, + 0, + 0, + 13130, + 0, + 13131, + 0, + 0, + 0, + 0, + 0, + 0, + 13134, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 13150, + 0, + 13168, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 13169, + 0, + 0, + 13170, + 0, + 0, + 0, + 0, + 13174, + 0, + 0, + 0, + 13176, + 0, + 0, + 0, + 0, + 0, + 13177, + 0, + 13178, + 13183, + 13187, + 0, + 0, + 0, + 13189, + 0, + 0, + 13190, + 0, + 0, + 13191, + 0, + 0, + 13206, + 0, + 0, + 0, + 13207, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 13212, + 0, + 0, + 13219, + 13232, + 0, + 0, + 0, + 13241, + 0, + 13249, + 13253, + 0, + 0, + 0, + 0, + 0, + 13255, + 13259, + 0, + 13260, + 13261, + 0, + 13262, + 0, + 13272, + 0, + 0, + 0, + 0, + 13276, + 0, + 0, + 0, + 0, + 13277, + 13299, + 0, + 0, + 13301, + 13302, + 0, + 0, + 13303, + 0, + 0, + 13305, + 0, + 13310, + 0, + 0, + 0, + 13311, + 0, + 0, + 0, + 0, + 13325, + 0, + 13328, + 0, + 0, + 0, + 13329, + 0, + 0, + 0, + 0, + 0, + 0, + 13330, + 0, + 0, + 13331, + 0, + 13335, + 0, + 0, + 13342, + 0, + 0, + 0, + 0, + 0, + 13343, + 0, + 13354, + 0, + 13362, + 0, + 13366, + 13367, + 13369, + 0, + 0, + 13371, + 13372, + 0, + 13373, + 13374, + 0, + 13376, + 0, + 13380, + 13381, + 13386, + 0, + 13387, + 13388, + 0, + 13389, + 13391, + 13395, + 0, + 0, + 0, + 0, + 0, + 13401, + 13409, + 0, + 13410, + 0, + 0, + 0, + 0, + 13420, + 0, + 0, + 0, + 0, + 0, + 13422, + 0, + 0, + 0, + 0, + 13423, + 0, + 0, + 0, + 0, + 13425, + 0, + 0, + 0, + 0, + 0, + 13427, + 0, + 0, + 0, + 13428, + 0, + 0, + 13430, + 13438, + 0, + 13439, + 0, + 13445, + 0, + 13448, + 13449, + 0, + 0, + 0, + 0, + 0, + 0, + 13451, + 0, + 13457, + 0, + 0, + 0, + 0, + 13458, + 13459, + 0, + 13460, + 0, + 0, + 0, + 0, + 13464, + 13465, + 13466, + 13470, + 0, + 13471, + 13472, + 13474, + 13475, + 0, + 13476, + 0, + 0, + 13478, + 13479, + 0, + 13481, + 0, + 0, + 0, + 0, + 13487, + 0, + 13490, + 0, + 13493, + 0, + 0, + 13494, + 0, + 0, + 13495, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 13496, + 13497, + 0, + 13500, + 0, + 0, + 13516, + 13522, + 0, + 0, + 13525, + 13528, + 0, + 0, + 0, + 13530, + 13535, + 0, + 13537, + 13539, + 0, + 13540, + 0, + 13543, + 0, + 13544, + 0, + 0, + 0, + 0, + 0, + 0, + 13545, + 0, + 0, + 0, + 0, + 0, + 0, + 13547, + 0, + 0, + 0, + 13549, + 13555, + 0, + 0, + 0, + 13556, + 13557, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 13558, + 0, + 13563, + 0, + 0, + 0, + 0, + 13564, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 13566, + 0, + 0, + 0, + 0, + 0, + 0, + 13569, + 0, + 0, + 13571, + 0, + 0, + 0, + 0, + 13573, + 0, + 0, + 0, + 0, + 0, + 0, + 13578, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 13581, + 0, + 13586, + 0, + 13595, + 0, + 13600, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 13601, + 13603, + 0, + 13604, + 13605, + 13606, + 13607, + 0, + 0, + 13617, + 13618, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 13623, + 0, + 13625, + 13627, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 13629, + 0, + 0, + 0, + 13634, + 0, + 0, + 0, + 13638, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 13654, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 13656, + 0, + 13659, + 0, + 0, + 13660, + 0, + 0, + 13662, + 0, + 0, + 0, + 13663, + 0, + 13664, + 0, + 0, + 0, + 0, + 0, + 13668, + 0, + 13669, + 13671, + 0, + 0, + 13672, + 0, + 0, + 0, + 0, + 0, + 0, + 13675, + 13685, + 0, + 13686, + 0, + 0, + 0, + 13687, + 0, + 0, + 0, + 13692, + 13694, + 13697, + 0, + 0, + 0, + 13702, + 0, + 0, + 0, + 0, + 0, + 13705, + 0, + 0, + 0, + 0, + 13707, + 0, + 0, + 0, + 13714, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 13715, + 0, + 13716, + 13717, + 0, + 0, + 13719, + 13724, + 13730, + 13731, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 13732, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 13734, + 0, + 13736, + 0, + 0, + 13737, + 13738, + 13747, + 0, + 13751, + 0, + 0, + 13752, + 0, + 0, + 0, + 13753, + 0, + 13757, + 0, + 0, + 13762, + 13763, + 0, + 13764, + 13765, + 0, + 13766, + 0, + 0, + 13767, + 0, + 0, + 0, + 13768, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 13769, + 0, + 0, + 13772, + 0, + 13775, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 13776, + 13778, + 13787, + 0, + 0, + 0, + 13797, + 0, + 13798, + 0, + 13801, + 0, + 13804, + 13806, + 0, + 0, + 0, + 0, + 13816, + 13817, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 13834, + 0, + 13836, + 0, + 0, + 13838, + 0, + 0, + 13839, + 0, + 13840, + 0, + 0, + 0, + 0, + 13842, + 0, + 0, + 0, + 0, + 0, + 0, + 13843, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 13845, + 0, + 0, + 0, + 0, + 0, + 13858, + 0, + 0, + 13860, + 0, + 0, + 13861, + 0, + 0, + 13862, + 13863, + 0, + 13868, + 0, + 13869, + 13870, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 13872, + 0, + 0, + 0, + 0, + 13873, + 13878, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 13886, + 0, + 13888, + 13889, + 13890, + 0, + 0, + 13891, + 13894, + 0, + 13897, + 13899, + 13900, + 13904, + 0, + 0, + 13906, + 0, + 0, + 0, + 13909, + 0, + 0, + 0, + 13910, + 0, + 0, + 0, + 13911, + 0, + 0, + 0, + 0, + 0, + 13912, + 13917, + 0, + 0, + 0, + 0, + 13918, + 0, + 13919, + 0, + 0, + 13920, + 0, + 0, + 0, + 13921, + 0, + 0, + 13922, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 13924, + 0, + 13927, + 0, + 0, + 0, + 0, + 0, + 13932, + 0, + 13933, + 0, + 13934, + 0, + 0, + 13935, + 0, + 13944, + 0, + 0, + 0, + 13954, + 0, + 0, + 13955, + 0, + 0, + 0, + 0, + 13956, + 0, + 13957, + 0, + 13967, + 13969, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 13970, + 13990, + 0, + 13991, + 13994, + 0, + 13995, + 0, + 0, + 0, + 0, + 13996, + 0, + 0, + 13999, + 0, + 0, + 0, + 14018, + 0, + 14019, + 0, + 14021, + 0, + 0, + 0, + 0, + 0, + 0, + 14041, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 14043, + 0, + 0, + 0, + 0, + 14046, + 0, + 0, + 0, + 14048, + 14049, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 14051, + 0, + 0, + 14052, + 14056, + 0, + 14063, + 0, + 14064, + 14066, + 0, + 0, + 14067, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 14068, + 0, + 0, + 0, + 14072, + 0, + 14074, + 14075, + 0, + 14076, + 14079, + 14085, + 14086, + 14087, + 14093, + 0, + 0, + 0, + 0, + 14095, + 0, + 0, + 0, + 0, + 0, + 0, + 14096, + 14097, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 14098, + 0, + 14102, + 0, + 0, + 0, + 0, + 0, + 14103, + 0, + 0, + 0, + 14104, + 0, + 0, + 14105, + 0, + 0, + 0, + 14107, + 14108, + 0, + 0, + 14109, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 14117, + 0, + 0, + 0, + 0, + 14118, + 0, + 0, + 0, + 0, + 14119, + 0, + 0, + 14120, + 0, + 0, + 14121, + 0, + 14122, + 14127, + 0, + 14128, + 14136, + 0, + 0, + 14138, + 0, + 14140, + 0, + 0, + 0, + 14141, + 14142, + 0, + 0, + 0, + 0, + 14146, + 0, + 0, + 14149, + 0, + 14151, + 0, + 0, + 0, + 14152, + 0, + 0, + 14153, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 14154, + 0, + 14156, + 14157, + 0, + 0, + 14159, + 0, + 14161, + 0, + 0, + 0, + 0, + 14162, + 0, + 0, + 0, + 0, + 0, + 0, + 14163, + 0, + 0, + 14173, + 0, + 0, + 0, + 0, + 0, + 0, + 14174, + 0, + 0, + 14176, + 0, + 0, + 14178, + 0, + 0, + 14179, + 14181, + 0, + 0, + 14182, + 14185, + 14187, + 0, + 14190, + 0, + 0, + 14197, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 14198, + 0, + 0, + 0, + 0, + 0, + 0, + 14199, + 14200, + 0, + 0, + 0, + 14204, + 0, + 0, + 14208, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 14231, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 14234, + 0, + 0, + 14235, + 0, + 0, + 0, + 14240, + 14241, + 0, + 0, + 0, + 14246, + 0, + 0, + 0, + 14247, + 0, + 14250, + 0, + 0, + 14251, + 0, + 0, + 14254, + 0, + 0, + 14256, + 0, + 0, + 0, + 14260, + 0, + 14261, + 0, + 0, + 0, + 0, + 14262, + 14267, + 14269, + 0, + 0, + 14277, + 0, + 0, + 14278, + 0, + 14279, + 14282, + 0, + 0, + 0, + 14283, + 0, + 0, + 0, + 14284, + 14285, + 0, + 0, + 0, + 0, + 14286, + 0, + 0, + 0, + 14288, + 0, + 0, + 0, + 14289, + 0, + 14290, + 0, + 14293, + 14301, + 14302, + 14304, + 14305, + 0, + 14307, + 0, + 14308, + 14309, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 14311, + 14312, + 0, + 0, + 14317, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 14318, + 0, + 0, + 0, + 0, + 14320, + 0, + 0, + 0, + 0, + 14321, + 14322, + 0, + 0, + 0, + 0, + 0, + 14326, + 14329, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 14330, + 14331, + 0, + 0, + 0, + 0, + 14332, + 0, + 0, + 0, + 14333, + 0, + 0, + 14337, + 14340, + 0, + 14341, + 0, + 0, + 14342, + 0, + 14345, + 14346, + 0, + 0, + 14347, + 0, + 14362, + 0, + 0, + 0, + 0, + 0, + 14364, + 14365, + 14371, + 0, + 14373, + 0, + 0, + 14374, + 0, + 14379, + 0, + 14400, + 0, + 0, + 0, + 0, + 0, + 14401, + 0, + 0, + 14405, + 0, + 14406, + 0, + 14408, + 14409, + 0, + 0, + 0, + 14417, + 0, + 0, + 14424, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 14430, + 0, + 0, + 0, + 14431, + 0, + 0, + 14435, + 0, + 14440, + 0, + 0, + 0, + 0, + 0, + 0, + 14442, + 0, + 0, + 14443, + 0, + 0, + 0, + 0, + 0, + 14446, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 14454, + 0, + 14457, + 0, + 14460, + 0, + 0, + 14466, + 0, + 0, + 0, + 0, + 0, + 14467, + 0, + 0, + 0, + 0, + 0, + 0, + 14469, + 0, + 14477, + 0, + 0, + 0, + 0, + 0, + 0, + 14478, + 14482, + 0, + 0, + 0, + 14483, + 0, + 0, + 0, + 14485, + 14486, + 0, + 0, + 0, + 14487, + 14488, + 14489, + 14492, + 14493, + 14494, + 14495, + 14496, + 14497, + 0, + 14499, + 0, + 14501, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 14502, + 0, + 14507, + 14512, + 14513, + 14514, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 14515, + 14526, + 14530, + 0, + 14537, + 0, + 14544, + 0, + 14547, + 0, + 0, + 14548, + 14550, + 14551, + 0, + 0, + 14552, + 0, + 0, + 0, + 14553, + 0, + 14554, + 0, + 0, + 0, + 0, + 14556, + 14564, + 0, + 0, + 14565, + 14566, + 0, + 0, + 0, + 0, + 0, + 0, + 14568, + 0, + 0, + 14569, + 0, + 0, + 0, + 14571, + 14576, + 0, + 0, + 14577, + 14578, + 14579, + 0, + 0, + 14580, + 0, + 0, + 0, + 0, + 14582, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 14583, + 0, + 0, + 0, + 0, + 0, + 14587, + 0, + 14588, + 0, + 0, + 14600, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 14601, + 0, + 0, + 14604, + 14605, + 14611, + 0, + 14613, + 0, + 0, + 0, + 0, + 14615, + 0, + 0, + 0, + 0, + 0, + 0, + 14627, + 0, + 14628, + 0, + 0, + 0, + 0, + 14631, + 0, + 14633, + 14634, + 0, + 0, + 0, + 0, + 14635, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 14636, + 0, + 0, + 14639, + 14642, + 0, + 0, + 0, + 0, + 14644, + 0, + 0, + 0, + 0, + 14645, + 14646, + 0, + 14653, + 0, + 0, + 14654, + 0, + 14658, + 0, + 14661, + 0, + 0, + 0, + 14665, + 0, + 0, + 0, + 14668, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 14669, + 0, + 0, + 14670, + 0, + 0, + 0, + 14680, + 0, + 0, + 14681, + 0, + 0, + 0, + 0, + 0, + 14682, + 14683, + 0, + 0, + 0, + 0, + 14686, + 0, + 0, + 0, + 0, + 14687, + 14697, + 0, + 0, + 0, + 0, + 14699, + 14705, + 14711, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 14712, + 0, + 0, + 0, + 14713, + 0, + 0, + 0, + 0, + 14719, + 0, + 14720, + 14721, + 14726, + 0, + 0, + 0, + 14728, + 14729, + 0, + 0, + 0, + 0, + 14731, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 14733, + 14736, + 14737, + 0, + 0, + 14740, + 14742, + 0, + 0, + 0, + 14744, + 14753, + 0, + 0, + 0, + 0, + 14755, + 14758, + 14760, + 0, + 0, + 0, + 0, + 0, + 14761, + 14762, + 14765, + 14771, + 0, + 14772, + 0, + 14773, + 14774, + 0, + 0, + 14775, + 0, + 0, + 14776, + 0, + 0, + 0, + 0, + 14777, + 0, + 14779, + 0, + 0, + 14782, + 0, + 0, + 14785, + 14786, + 14788, + 0, + 0, + 0, + 0, + 0, + 14795, + 0, + 0, + 0, + 0, + 0, + 0, + 14798, + 0, + 14803, + 14804, + 14806, + 0, + 0, + 0, + 14809, + 0, + 0, + 0, + 0, + 0, + 0, + 14810, + 0, + 0, + 0, + 0, + 14811, + 0, + 14812, + 0, + 0, + 0, + 0, + 0, + 14815, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 14816, + 0, + 14818, + 0, + 0, + 0, + 0, + 0, + 0, + 14819, + 0, + 14820, + 0, + 14823, + 0, + 0, + 0, + 14824, + 0, + 0, + 14826, + 14827, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 14830, + 0, + 0, + 0, + 0, + 0, + 14833, + 0, + 14845, + 0, + 0, + 0, + 0, + 0, + 14846, + 0, + 0, + 14847, + 14871, + 0, + 14873, + 0, + 14876, + 0, + 14877, + 14878, + 14880, + 0, + 0, + 0, + 0, + 0, + 14881, + 0, + 14882, + 14894, + 0, + 0, + 0, + 0, + 14895, + 0, + 14907, + 0, + 14908, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 14911, + 0, + 0, + 0, + 0, + 14920, + 0, + 0, + 14931, + 0, + 14932, + 14934, + 14935, + 0, + 0, + 14936, + 0, + 14945, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 14947, + 0, + 0, + 14948, + 14949, + 14951, + 0, + 0, + 14952, + 0, + 0, + 0, + 14964, + 14973, + 0, + 0, + 14990, + 0, + 0, + 0, + 0, + 14995, + 0, + 0, + 14998, + 15001, + 0, + 0, + 15002, + 15020, + 0, + 0, + 0, + 0, + 0, + 0, + 15021, + 0, + 15022, + 0, + 0, + 0, + 0, + 15023, + 0, + 0, + 15025, + 15029, + 15033, + 0, + 0, + 0, + 15034, + 0, + 0, + 0, + 15035, + 0, + 0, + 0, + 0, + 0, + 15043, + 15044, + 0, + 0, + 0, + 15045, + 15046, + 15048, + 15050, + 0, + 15065, + 0, + 0, + 0, + 0, + 15066, + 0, + 0, + 15075, + 15082, + 15084, + 0, + 0, + 15085, + 15086, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15088, + 0, + 0, + 0, + 15089, + 0, + 0, + 0, + 0, + 15094, + 0, + 15096, + 0, + 15097, + 0, + 15100, + 0, + 0, + 15102, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15105, + 0, + 0, + 15106, + 0, + 15109, + 15113, + 0, + 0, + 0, + 15115, + 0, + 15118, + 0, + 0, + 0, + 0, + 0, + 0, + 15119, + 0, + 0, + 15120, + 0, + 0, + 0, + 0, + 0, + 15123, + 15129, + 0, + 0, + 0, + 15130, + 0, + 15131, + 0, + 0, + 15134, + 0, + 15135, + 0, + 0, + 0, + 15137, + 15138, + 0, + 0, + 0, + 0, + 0, + 0, + 15139, + 0, + 0, + 0, + 0, + 0, + 15140, + 0, + 0, + 15154, + 15162, + 0, + 15169, + 15170, + 0, + 15175, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15177, + 0, + 15178, + 15179, + 0, + 0, + 0, + 0, + 0, + 15183, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15185, + 15187, + 0, + 15194, + 15195, + 15196, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15204, + 0, + 0, + 0, + 0, + 15206, + 0, + 0, + 0, + 0, + 0, + 15207, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15213, + 0, + 15214, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15232, + 0, + 0, + 0, + 0, + 15234, + 0, + 15238, + 15240, + 0, + 15248, + 0, + 0, + 0, + 0, + 15250, + 15251, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15252, + 0, + 0, + 0, + 15255, + 15262, + 15266, + 0, + 0, + 0, + 15267, + 0, + 0, + 0, + 15277, + 15279, + 0, + 0, + 0, + 15280, + 15281, + 15282, + 0, + 0, + 0, + 0, + 0, + 15285, + 0, + 0, + 0, + 0, + 15289, + 0, + 0, + 15291, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15296, + 15297, + 0, + 0, + 15304, + 0, + 0, + 0, + 0, + 15306, + 0, + 0, + 0, + 0, + 0, + 0, + 15307, + 15308, + 0, + 15309, + 0, + 0, + 15311, + 0, + 0, + 15312, + 15313, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15314, + 15317, + 0, + 0, + 0, + 15318, + 15319, + 0, + 0, + 0, + 0, + 15320, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15321, + 0, + 0, + 0, + 0, + 0, + 15324, + 0, + 15325, + 15326, + 0, + 15330, + 0, + 0, + 0, + 0, + 15334, + 0, + 15335, + 0, + 15341, + 0, + 0, + 15342, + 0, + 0, + 15343, + 15344, + 0, + 0, + 0, + 0, + 15345, + 0, + 0, + 0, + 0, + 15347, + 0, + 0, + 15348, + 15349, + 15350, + 0, + 15356, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15357, + 0, + 15358, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15359, + 15360, + 15364, + 0, + 15380, + 0, + 0, + 0, + 0, + 0, + 15392, + 0, + 0, + 15393, + 0, + 15395, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15396, + 0, + 0, + 15397, + 15398, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15399, + 0, + 15400, + 0, + 0, + 0, + 15402, + 0, + 15405, + 15410, + 0, + 0, + 0, + 0, + 15411, + 0, + 0, + 0, + 15412, + 0, + 15416, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15428, + 0, + 15435, + 0, + 0, + 15438, + 0, + 0, + 0, + 0, + 15439, + 0, + 0, + 0, + 15440, + 0, + 0, + 0, + 15441, + 15449, + 15451, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15452, + 0, + 0, + 15455, + 0, + 0, + 0, + 15456, + 0, + 0, + 15458, + 0, + 15460, + 15461, + 0, + 0, + 0, + 0, + 0, + 15462, + 15464, + 0, + 15465, + 0, + 0, + 15466, + 0, + 0, + 15467, + 0, + 0, + 0, + 0, + 0, + 15468, + 0, + 0, + 0, + 0, + 15481, + 0, + 0, + 15484, + 0, + 15485, + 15486, + 0, + 0, + 0, + 15487, + 0, + 0, + 0, + 0, + 0, + 15488, + 0, + 15492, + 15498, + 0, + 0, + 0, + 15499, + 0, + 0, + 0, + 15500, + 0, + 15501, + 0, + 0, + 15512, + 0, + 15522, + 0, + 0, + 0, + 15524, + 0, + 15525, + 15526, + 0, + 0, + 15527, + 0, + 0, + 15545, + 15546, + 0, + 15548, + 15552, + 0, + 15553, + 0, + 0, + 0, + 15554, + 0, + 15555, + 0, + 15557, + 15565, + 15573, + 15577, + 15578, + 0, + 15582, + 0, + 15583, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15586, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15588, + 0, + 0, + 0, + 0, + 0, + 15589, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15593, + 15594, + 0, + 0, + 0, + 0, + 15595, + 0, + 0, + 0, + 0, + 0, + 0, + 15596, + 0, + 0, + 0, + 15597, + 0, + 0, + 0, + 0, + 15600, + 0, + 0, + 15601, + 0, + 0, + 0, + 0, + 15602, + 15603, + 0, + 0, + 0, + 0, + 0, + 0, + 15604, + 0, + 15609, + 0, + 0, + 15612, + 0, + 0, + 15613, + 0, + 0, + 15615, + 15617, + 15618, + 0, + 0, + 15620, + 0, + 15636, + 15637, + 0, + 0, + 15649, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15650, + 0, + 0, + 15651, + 0, + 0, + 0, + 15656, + 0, + 15658, + 0, + 0, + 0, + 15664, + 0, + 0, + 15665, + 0, + 0, + 15668, + 0, + 0, + 0, + 0, + 0, + 15669, + 0, + 0, + 15674, + 0, + 0, + 15675, + 0, + 0, + 0, + 0, + 15676, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15677, + 0, + 0, + 0, + 0, + 15678, + 0, + 0, + 0, + 0, + 0, + 15679, + 0, + 0, + 15681, + 0, + 15686, + 0, + 0, + 0, + 0, + 15687, + 0, + 15688, + 0, + 0, + 15690, + 0, + 0, + 0, + 15697, + 0, + 15699, + 15700, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15701, + 0, + 15702, + 15703, + 0, + 15704, + 0, + 15705, + 0, + 15707, + 0, + 15709, + 0, + 15712, + 15716, + 0, + 15717, + 0, + 15718, + 15720, + 0, + 0, + 0, + 0, + 0, + 15724, + 0, + 0, + 0, + 15725, + 0, + 15726, + 0, + 0, + 0, + 15740, + 0, + 15745, + 15746, + 0, + 0, + 15747, + 0, + 15748, + 0, + 0, + 0, + 0, + 0, + 15749, + 0, + 0, + 0, + 15752, + 0, + 15753, + 0, + 0, + 0, + 0, + 0, + 0, + 15759, + 0, + 0, + 0, + 15765, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15767, + 0, + 0, + 0, + 15771, + 0, + 0, + 15784, + 0, + 0, + 0, + 0, + 15785, + 15790, + 15791, + 0, + 0, + 15792, + 0, + 0, + 0, + 15807, + 0, + 15811, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15818, + 0, + 0, + 0, + 15819, + 0, + 0, + 0, + 0, + 15821, + 0, + 0, + 0, + 0, + 0, + 15822, + 15824, + 0, + 0, + 15827, + 0, + 0, + 15829, + 15831, + 0, + 15832, + 0, + 0, + 15833, + 0, + 15835, + 15838, + 15839, + 15843, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15844, + 0, + 0, + 0, + 0, + 15845, + 15851, + 15856, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15858, + 15860, + 0, + 15861, + 0, + 0, + 0, + 15864, + 0, + 0, + 0, + 0, + 15865, + 0, + 0, + 0, + 0, + 0, + 0, + 15866, + 0, + 15872, + 0, + 0, + 15876, + 0, + 0, + 0, + 0, + 15877, + 15878, + 15883, + 15885, + 0, + 0, + 15888, + 0, + 0, + 0, + 0, + 0, + 15889, + 15890, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15892, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15893, + 0, + 0, + 15894, + 0, + 0, + 0, + 15895, + 0, + 15896, + 15897, + 0, + 15898, + 15901, + 15902, + 0, + 15911, + 15915, + 0, + 15916, + 0, + 15924, + 15935, + 0, + 15937, + 0, + 0, + 0, + 0, + 0, + 15950, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15958, + 0, + 0, + 0, + 15961, + 0, + 0, + 15966, + 0, + 15967, + 0, + 0, + 15977, + 0, + 0, + 15978, + 0, + 0, + 15981, + 15982, + 15983, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15986, + 0, + 0, + 0, + 15990, + 0, + 15991, + 15995, + 15998, + 0, + 15999, + 0, + 16000, + 0, + 0, + 0, + 0, + 16008, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16009, + 16011, + 0, + 16013, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16014, + 0, + 0, + 16015, + 16023, + 16024, + 16025, + 0, + 0, + 16026, + 0, + 16030, + 0, + 16032, + 0, + 16033, + 0, + 0, + 0, + 0, + 0, + 0, + 16035, + 16036, + 16037, + 0, + 0, + 0, + 0, + 0, + 16039, + 0, + 0, + 0, + 0, + 16041, + 0, + 0, + 0, + 0, + 0, + 16043, + 16044, + 0, + 0, + 16047, + 0, + 0, + 0, + 16048, + 0, + 0, + 16049, + 16050, + 16052, + 0, + 0, + 0, + 0, + 0, + 16055, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16056, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16058, + 16060, + 16061, + 0, + 0, + 16063, + 0, + 0, + 16064, + 0, + 0, + 0, + 16067, + 16068, + 0, + 0, + 16069, + 16078, + 0, + 0, + 0, + 16079, + 0, + 0, + 0, + 16080, + 0, + 16081, + 0, + 0, + 0, + 16088, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16089, + 16093, + 0, + 16097, + 0, + 16103, + 0, + 16104, + 16105, + 0, + 0, + 16256, + 0, + 0, + 16259, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16260, + 16261, + 0, + 0, + 16262, + 0, + 0, + 16263, + 0, + 16268, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16269, + 0, + 0, + 16270, + 16273, + 0, + 16274, + 0, + 0, + 0, + 0, + 16275, + 16276, + 16277, + 16280, + 0, + 0, + 0, + 16281, + 16284, + 0, + 0, + 0, + 16286, + 0, + 16289, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16290, + 0, + 0, + 0, + 0, + 16291, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16292, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16293, + 16295, + 16297, + 0, + 16302, + 0, + 16304, + 0, + 16305, + 0, + 16306, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16307, + 16308, + 16312, + 0, + 0, + 0, + 0, + 0, + 0, + 16313, + 16315, + 0, + 16318, + 0, + 0, + 0, + 16321, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16326, + 16333, + 16336, + 0, + 0, + 0, + 0, + 16337, + 16340, + 0, + 0, + 0, + 0, + 0, + 16345, + 0, + 0, + 16346, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16347, + 0, + 0, + 16348, + 0, + 0, + 0, + 0, + 16349, + 0, + 0, + 0, + 16350, + 0, + 16357, + 0, + 0, + 0, + 0, + 16359, + 16360, + 0, + 0, + 0, + 0, + 16362, + 16363, + 16364, + 16365, + 0, + 0, + 16366, + 0, + 0, + 0, + 0, + 16367, + 16368, + 0, + 16369, + 16374, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16376, + 0, + 0, + 0, + 0, + 16378, + 16379, + 0, + 16380, + 0, + 0, + 0, + 16381, + 16383, + 0, + 0, + 0, + 0, + 0, + 16390, + 0, + 0, + 0, + 16399, + 0, + 16402, + 16404, + 16406, + 16407, + 0, + 0, + 0, + 16409, + 16411, + 0, + 0, + 0, + 0, + 16412, + 0, + 16413, + 16415, + 16423, + 0, + 0, + 0, + 0, + 0, + 16424, + 0, + 0, + 0, + 16428, + 16434, + 16435, + 16449, + 0, + 16450, + 16451, + 0, + 0, + 0, + 16453, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16454, + 0, + 0, + 16456, + 16458, + 0, + 0, + 16459, + 0, + 0, + 16460, + 0, + 0, + 0, + 0, + 16462, + 0, + 16463, + 0, + 0, + 16466, + 0, + 0, + 0, + 0, + 0, + 16479, + 0, + 0, + 16480, + 0, + 16481, + 16484, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16485, + 0, + 0, + 0, + 0, + 0, + 0, + 16489, + 0, + 0, + 0, + 0, + 0, + 16491, + 0, + 0, + 16498, + 0, + 0, + 16503, + 0, + 16505, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16506, + 0, + 0, + 0, + 16508, + 16509, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16511, + 16513, + 0, + 0, + 0, + 16516, + 0, + 16517, + 0, + 16519, + 0, + 16529, + 0, + 0, + 16531, + 0, + 0, + 0, + 0, + 0, + 0, + 16534, + 0, + 0, + 16541, + 16542, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16543, + 16547, + 16548, + 0, + 0, + 0, + 16551, + 0, + 16552, + 0, + 0, + 0, + 16553, + 0, + 0, + 16558, + 0, + 0, + 16562, + 16565, + 0, + 0, + 0, + 16570, + 0, + 0, + 0, + 16573, + 16585, + 0, + 0, + 0, + 16586, + 16587, + 16595, + 0, + 16596, + 0, + 16598, + 0, + 0, + 0, + 16600, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16601, + 0, + 0, + 0, + 0, + 16603, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16604, + 16612, + 0, + 0, + 0, + 0, + 16613, + 0, + 16618, + 0, + 0, + 0, + 16640, + 0, + 0, + 16641, + 0, + 0, + 0, + 0, + 0, + 0, + 16645, + 0, + 0, + 0, + 0, + 16646, + 0, + 0, + 0, + 0, + 0, + 0, + 16651, + 0, + 0, + 0, + 0, + 16653, + 16654, + 0, + 0, + 0, + 16655, + 0, + 0, + 16656, + 16667, + 0, + 0, + 0, + 0, + 16671, + 0, + 16672, + 0, + 0, + 0, + 16673, + 0, + 0, + 0, + 0, + 0, + 16676, + 0, + 16686, + 0, + 0, + 0, + 0, + 16689, + 0, + 16690, + 0, + 16692, + 0, + 16693, + 0, + 16694, + 0, + 16696, + 0, + 0, + 0, + 16705, + 0, + 0, + 0, + 0, + 0, + 0, + 16707, + 0, + 0, + 0, + 16709, + 0, + 0, + 0, + 0, + 16711, + 0, + 16712, + 16713, + 0, + 0, + 0, + 16715, + 0, + 0, + 0, + 0, + 16716, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16718, + 16724, + 0, + 0, + 16726, + 16727, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16728, + 0, + 16729, + 0, + 0, + 16730, + 0, + 0, + 0, + 0, + 0, + 16731, + 0, + 0, + 0, + 16732, + 0, + 0, + 0, + 0, + 16734, + 16738, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16743, + 0, + 0, + 16745, + 0, + 0, + 0, + 0, + 0, + 16749, + 0, + 16752, + 0, + 0, + 0, + 0, + 16756, + 0, + 0, + 16758, + 0, + 16759, + 0, + 0, + 0, + 0, + 0, + 16760, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16762, + 0, + 16769, + 0, + 16770, + 0, + 16772, + 0, + 0, + 0, + 16777, + 16780, + 0, + 0, + 0, + 0, + 0, + 0, + 16781, + 0, + 0, + 16782, + 0, + 16784, + 0, + 0, + 16785, + 16787, + 16792, + 0, + 0, + 16794, + 0, + 0, + 0, + 16798, + 0, + 0, + 16809, + 0, + 0, + 16814, + 16816, + 16817, + 0, + 16819, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16820, + 0, + 0, + 16836, + 16839, + 0, + 0, + 16841, + 16851, + 16857, + 0, + 0, + 16858, + 16859, + 0, + 0, + 16860, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16862, + 0, + 16863, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16864, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16876, + 0, + 16881, + 16882, + 0, + 16885, + 16886, + 0, + 16887, + 0, + 0, + 0, + 16889, + 16891, + 0, + 0, + 0, + 0, + 0, + 16894, + 16895, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16897, + 0, + 16898, + 0, + 0, + 0, + 0, + 0, + 16913, + 0, + 0, + 16924, + 16925, + 16926, + 0, + 0, + 16927, + 0, + 0, + 0, + 16937, + 16938, + 0, + 0, + 0, + 16940, + 16941, + 0, + 0, + 0, + 16942, + 16945, + 0, + 16946, + 16949, + 16950, + 0, + 0, + 0, + 16952, + 16955, + 0, + 0, + 0, + 16965, + 0, + 16969, + 0, + 0, + 16975, + 0, + 0, + 16976, + 0, + 0, + 0, + 0, + 16978, + 0, + 0, + 16981, + 0, + 16983, + 16989, + 0, + 0, + 0, + 0, + 16990, + 0, + 0, + 16991, + 0, + 0, + 0, + 16993, + 0, + 16994, + 16996, + 17000, + 0, + 0, + 0, + 0, + 0, + 17002, + 17004, + 0, + 17006, + 0, + 0, + 17007, + 0, + 0, + 0, + 0, + 17008, + 17013, + 17014, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 17021, + 0, + 17031, + 0, + 0, + 0, + 0, + 0, + 17033, + 17036, + 0, + 17038, + 0, + 0, + 17039, + 0, + 17045, + 0, + 0, + 17046, + 17047, + 0, + 0, + 0, + 0, + 17048, + 0, + 17049, + 17050, + 0, + 17051, + 17053, + 0, + 17054, + 0, + 17055, + 0, + 0, + 0, + 0, + 0, + 17063, + 0, + 0, + 17064, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 17065, + 0, + 0, + 17068, + 0, + 0, + 0, + 0, + 0, + 17072, + 0, + 0, + 0, + 0, + 0, + 0, + 17073, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 17074, + 0, + 17080, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 17081, + 17083, + 17084, + 0, + 0, + 0, + 17085, + 0, + 0, + 0, + 0, + 17092, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 17093, + 0, + 17095, + 17102, + 0, + 0, + 0, + 0, + 0, + 0, + 17103, + 0, + 0, + 17105, + 0, + 17107, + 0, + 0, + 0, + 0, + 17114, + 0, + 0, + 0, + 0, + 0, + 17115, + 17125, + 17127, + 0, + 0, + 17128, + 0, + 0, + 0, + 17129, + 17130, + 0, + 17131, + 0, + 0, + 0, + 0, + 0, + 17132, + 17135, + 17145, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 17146, + 0, + 17147, + 0, + 17148, + 0, + 0, + 0, + 0, + 0, + 0, + 17149, + 17150, + 0, + 17151, + 17153, + 0, + 17155, + 0, + 0, + 0, + 0, + 17163, + 17171, + 0, + 17174, + 0, + 0, + 0, + 0, + 17179, + 0, + 0, + 17182, + 17185, + 0, + 0, + 0, + 0, + 0, + 17186, + 0, + 0, + 17188, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 17189, + 17191, + 0, + 17194, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 17195, + 17196, + 17203, + 17204, + 0, + 0, + 17205, + 17217, + 0, + 0, + 0, + 0, + 0, + 17218, + 0, + 0, + 0, + 0, + 17219, + 0, + 17220, + 0, + 17221, + 0, + 0, + 17230, + 0, + 0, + 0, + 0, + 0, + 17236, + 0, + 17238, + 17239, + 0, + 0, + 0, + 17241, + 17244, + 0, + 0, + 17245, + 0, + 17248, + 0, + 0, + 17251, + 0, + 17252, + 0, + 0, + 17264, + 0, + 17266, + 0, + 0, + 0, + 17268, + 0, + 0, + 0, + 0, + 17271, + 17272, + 0, + 17273, + 0, + 17295, + 0, + 17302, + 0, + 17305, + 0, + 0, + 0, + 17306, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 17308, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 17309, + 0, + 17310, + 17313, + 0, + 0, + 0, + 0, + 17314, + 17315, + 0, + 17317, + 0, + 0, + 0, + 0, + 17318, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 17320, + 0, + 0, + 0, + 0, + 0, + 0, + 17334, + 0, + 17344, + 17348, + 0, + 0, + 0, + 17350, + 17351, + 0, + 0, + 17353, + 0, + 0, + 17354, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 17355, + 0, + 0, + 0, + 0, + 0, + 0, + 17356, + 17357, + 0, + 0, + 17359, + 0, + 0, + 0, + 17371, + 0, + 17372, + 0, + 0, + 0, + 17393, + 0, + 0, + 0, + 0, + 17394, + 0, + 0, + 0, + 0, + 0, + 17395, + 0, + 0, + 17399, + 0, + 0, + 0, + 17401, + 17417, + 0, + 17418, + 0, + 17419, + 0, + 0, + 0, + 0, + 0, + 17422, + 17423, + 0, + 0, + 0, + 0, + 0, + 17424, + 0, + 0, + 0, + 0, + 0, + 17428, + 17429, + 17433, + 0, + 0, + 0, + 17437, + 0, + 0, + 17441, + 0, + 0, + 17442, + 0, + 0, + 17453, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 17454, + 17456, + 17462, + 0, + 0, + 17466, + 0, + 0, + 17468, + 0, + 0, + 17469, + 0, + 0, + 0, + 0, + 17470, + 0, + 17475, + 0, + 0, + 0, + 0, + 0, + 17479, + 0, + 0, + 0, + 17483, + 17484, + 0, + 17485, + 0, + 17486, + 0, + 17491, + 17492, + 0, + 0, + 17493, + 0, + 17494, + 17495, + 0, + 0, + 0, + 17496, + 0, + 0, + 0, + 17497, + 0, + 0, + 0, + 17502, + 0, + 0, + 0, + 0, + 0, + 17503, + 0, + 17505, + 0, + 17507, + 0, + 0, + 0, + 17512, + 17513, + 17514, + 0, + 0, + 17515, + 0, + 0, + 0, + 17519, + 0, + 0, + 0, + 17522, + 0, + 0, + 17523, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 17527, + 0, + 0, + 0, + 17528, + 0, + 0, + 0, + 17534, + 0, + 0, + 0, + 0, + 17536, + 0, + 0, + 0, + 17539, + 0, + 17540, + 17543, + 17549, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 17556, + 0, + 0, + 17558, + 0, + 17559, + 0, + 0, + 17560, + 0, + 0, + 0, + 17563, + 0, + 0, + 0, + 0, + 0, + 0, + 17564, + 0, + 0, + 17565, + 17566, + 0, + 17567, + 0, + 0, + 0, + 0, + 0, + 0, + 17569, + 17570, + 0, + 17575, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 17581, + 0, + 0, + 0, + 17582, + 17583, + 0, + 17586, + 0, + 0, + 17587, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 17588, + 0, + 0, + 0, + 0, + 17596, + 17597, + 0, + 0, + 17598, + 17600, + 0, + 0, + 0, + 0, + 0, + 0, + 17601, + 0, + 0, + 0, + 17604, + 0, + 0, + 17605, + 0, + 0, + 17607, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 17612, + 0, + 0, + 17618, + 0, + 17621, + 17622, + 0, + 0, + 0, + 0, + 17623, + 0, + 0, + 17624, + 0, + 0, + 17630, + 0, + 0, + 17631, + 17633, + 17634, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 17635, + 0, + 0, + 17636, + 0, + 0, + 17637, + 0, + 17638, + 0, + 17640, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 17641, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 17643, + 0, + 0, + 0, + 0, + 17645, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 17646, + 17662, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 17663, + 17664, + 0, + 17665, + 17666, + 0, + 0, + 0, + 17669, + 17671, + 17673, + 0, + 17679, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 17684, + 0, + 0, + 0, + 17686, + 0, + 17714, + 0, + 0, + 17720, + 17722, + 17726, + 0, + 0, + 17728, + 0, + 0, + 17729, + 0, + 0, + 0, + 17732, + 0, + 17733, + 0, + 17734, + 0, + 0, + 0, + 17735, + 0, + 0, + 0, + 0, + 17737, + 0, + 0, + 0, + 0, + 17739, + 0, + 0, + 0, + 17741, + 17742, + 0, + 0, + 0, + 0, + 17743, + 17744, + 17745, + 0, + 0, + 0, + 17749, + 0, + 17750, + 17751, + 17752, + 17754, + 17761, + 17762, + 0, + 17763, + 0, + 17766, + 0, + 17772, + 0, + 0, + 0, + 0, + 0, + 17775, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 17776, + 0, + 0, + 17777, + 0, + 0, + 17778, + 17779, + 0, + 17782, + 17783, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 17784, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 17821, + 0, + 0, + 0, + 17822, + 0, + 0, + 0, + 17823, + 17825, + 0, + 0, + 0, + 0, + 0, + 17826, + 17831, + 17832, + 17833, + 0, + 0, + 17845, + 0, + 0, + 0, + 17846, + 0, + 0, + 0, + 17848, + 17850, + 17854, + 0, + 17855, + 0, + 0, + 17859, + 0, + 0, + 0, + 0, + 0, + 0, + 17860, + 17861, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 17870, + 17871, + 0, + 0, + 0, + 0, + 0, + 0, + 17872, + 0, + 0, + 0, + 17879, + 0, + 0, + 0, + 17881, + 17883, + 0, + 17884, + 0, + 17885, + 0, + 0, + 17886, + 0, + 0, + 17887, + 17891, + 17953, + 0, + 0, + 0, + 0, + 17954, + 0, + 0, + 17955, + 0, + 17968, + 0, + 0, + 17972, + 0, + 0, + 0, + 0, + 0, + 17974, + 0, + 0, + 0, + 0, + 17976, + 17978, + 0, + 0, + 17983, + 0, + 0, + 0, + 0, + 18003, + 0, + 0, + 0, + 0, + 0, + 18007, + 0, + 0, + 0, + 0, + 0, + 18009, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 18010, + 0, + 0, + 0, + 0, + 0, + 0, + 18012, + 0, + 0, + 18014, + 0, + 0, + 0, + 18015, + 0, + 0, + 0, + 18016, + 0, + 18017, + 0, + 0, + 0, + 18030, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 18031, + 0, + 0, + 18036, + 18037, + 18038, + 0, + 0, + 18049, + 18056, + 0, + 18057, + 18058, + 0, + 18059, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 18062, + 0, + 0, + 0, + 0, + 18064, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 18067, + 0, + 0, + 0, + 18068, + 0, + 0, + 18075, + 0, + 0, + 18078, + 18093, + 18094, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 18097, + 0, + 0, + 0, + 0, + 0, + 18098, + 18100, + 0, + 0, + 0, + 18108, + 0, + 18111, + 0, + 0, + 18112, + 0, + 18113, + 0, + 0, + 18115, + 18116, + 0, + 18118, + 0, + 0, + 0, + 0, + 18121, + 0, + 0, + 0, + 0, + 18123, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 18124, + 0, + 0, + 0, + 0, + 18125, + 18126, + 0, + 18127, + 0, + 0, + 18128, + 18135, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 18150, + 0, + 0, + 0, + 0, + 0, + 18151, + 18152, + 0, + 0, + 18156, + 18164, + 0, + 18166, + 18171, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 18172, + 18183, + 0, + 18184, + 0, + 0, + 0, + 0, + 18185, + 0, + 18187, + 0, + 0, + 0, + 0, + 0, + 18188, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 18189, + 0, + 0, + 18190, + 0, + 0, + 18191, + 18192, + 0, + 0, + 18194, + 18195, + 18196, + 0, + 0, + 0, + 18197, + 0, + 18203, + 0, + 18204, + 0, + 0, + 0, + 0, + 18205, + 0, + 0, + 0, + 18207, + 18208, + 0, + 0, + 18214, + 0, + 0, + 0, + 18215, + 18216, + 0, + 0, + 0, + 18220, + 0, + 0, + 18222, + 0, + 0, + 0, + 0, + 0, + 18223, + 0, + 18225, + 18231, + 0, + 18234, + 0, + 18235, + 0, + 0, + 0, + 0, + 18240, + 0, + 0, + 18241, + 18242, + 0, + 0, + 0, + 0, + 0, + 18243, + 18251, + 0, + 18253, + 0, + 18254, + 0, + 0, + 0, + 18266, + 0, + 0, + 0, + 0, + 0, + 0, + 18269, + 18270, + 18271, + 18273, + 18281, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 18282, + 0, + 18283, + 0, + 18284, + 0, + 0, + 0, + 0, + 0, + 0, + 18285, + 0, + 18287, + 18289, + 0, + 0, + 18290, + 0, + 0, + 0, + 0, + 18308, + 0, + 0, + 0, + 18310, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 18311, + 0, + 18312, + 18313, + 0, + 18315, + 0, + 0, + 18316, + 18320, + 0, + 18331, + 0, + 18332, + 0, + 18336, + 0, + 0, + 0, + 0, + 18337, + 0, + 18340, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 18341, + 0, + 18344, + 18345, + 0, + 18346, + 0, + 0, + 0, + 0, + 0, + 18348, + 0, + 18351, + 0, + 0, + 18356, + 0, + 0, + 0, + 0, + 0, + 0, + 18357, + 0, + 0, + 0, + 0, + 0, + 18367, + 0, + 0, + 0, + 18368, + 0, + 18369, + 0, + 18370, + 18371, + 0, + 0, + 0, + 18437, + 18444, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 18445, + 18450, + 0, + 0, + 0, + 0, + 18451, + 0, + 18452, + 0, + 0, + 0, + 18453, + 0, + 0, + 0, + 0, + 0, + 18455, + 0, + 0, + 0, + 18456, + 0, + 18457, + 0, + 18460, + 0, + 0, + 18461, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 18466, + 0, + 0, + 18467, + 0, + 0, + 0, + 0, + 18473, + 0, + 0, + 0, + 18476, + 0, + 18477, + 0, + 0, + 0, + 18478, + 18479, + 18480, + 0, + 0, + 0, + 18485, + 0, + 0, + 0, + 18486, + 0, + 0, + 0, + 0, + 0, + 0, + 18488, + 18490, + 0, + 0, + 0, + 0, + 0, + 0, + 18491, + 0, + 0, + 0, + 0, + 0, + 18495, + 0, + 0, + 18496, + 0, + 0, + 0, + 0, + 0, + 0, + 18505, + 0, + 18521, + 0, + 18522, + 18523, + 0, + 0, + 0, + 18525, + 18526, + 0, + 0, + 0, + 0, + 0, + 18527, + 0, + 0, + 0, + 0, + 18532, + 18533, + 0, + 18534, + 0, + 0, + 0, + 0, + 0, + 0, + 18535, + 18537, + 0, + 18538, + 0, + 0, + 0, + 0, + 0, + 0, + 18540, + 18541, + 18542, + 18543, + 0, + 18546, + 0, + 0, + 0, + 0, + 18553, + 18556, + 0, + 0, + 18558, + 0, + 0, + 18569, + 18571, + 0, + 0, + 0, + 18572, + 0, + 18574, + 0, + 0, + 0, + 0, + 18586, + 0, + 0, + 0, + 0, + 0, + 18588, + 0, + 0, + 18589, + 0, + 0, + 0, + 0, + 0, + 0, + 18590, + 0, + 18592, + 0, + 0, + 0, + 0, + 18594, + 0, + 0, + 0, + 18596, + 0, + 0, + 18597, + 18598, + 0, + 0, + 18601, + 0, + 0, + 0, + 0, + 18602, + 0, + 0, + 0, + 18603, + 18604, + 0, + 18605, + 0, + 0, + 0, + 0, + 18608, + 0, + 0, + 18611, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 18612, + 0, + 18616, + 0, + 0, + 18617, + 18619, + 0, + 0, + 0, + 18628, + 0, + 0, + 0, + 18629, + 0, + 0, + 18630, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 18631, + 0, + 18632, + 0, + 0, + 18635, + 18637, + 0, + 0, + 0, + 0, + 0, + 0, + 18641, + 18643, + 18648, + 0, + 18652, + 0, + 0, + 18653, + 0, + 18655, + 18656, + 0, + 0, + 0, + 18657, + 0, + 0, + 18666, + 18674, + 0, + 0, + 0, + 0, + 18677, + 18684, + 18685, + 0, + 0, + 18686, + 0, + 0, + 18690, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 18695, + 18696, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 18697, + 0, + 0, + 18700, + 0, + 0, + 0, + 0, + 0, + 0, + 18702, + 0, + 18708, + 0, + 0, + 18709, + 0, + 18710, + 0, + 0, + 18711, + 0, + 18714, + 0, + 0, + 18718, + 0, + 0, + 0, + 0, + 0, + 0, + 18719, + 0, + 0, + 18722, + 0, + 18726, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 18731, + 0, + 0, + 0, + 0, + 0, + 18739, + 18741, + 0, + 0, + 18742, + 0, + 18743, + 18744, + 18746, + 18748, + 0, + 18752, + 18753, + 0, + 0, + 18754, + 18763, + 0, + 18765, + 0, + 0, + 0, + 18766, + 0, + 0, + 0, + 18769, + 0, + 0, + 0, + 0, + 0, + 18773, + 18778, + 18779, + 18781, + 0, + 0, + 18784, + 18787, + 0, + 18788, + 0, + 18793, + 0, + 0, + 0, + 0, + 0, + 0, + 18795, + 0, + 0, + 18800, + 0, + 0, + 0, + 0, + 0, + 18801, + 18804, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 18806, + 0, + 0, + 0, + 18811, + 18815, + 18816, + 0, + 0, + 0, + 0, + 18825, + 0, + 0, + 18827, + 18829, + 0, + 0, + 18830, + 0, + 0, + 0, + 0, + 18831, + 0, + 0, + 18832, + 0, + 0, + 0, + 0, + 18833, + 0, + 18840, + 0, + 18841, + 0, + 18842, + 0, + 0, + 0, + 0, + 18843, + 0, + 18844, + 0, + 0, + 0, + 0, + 0, + 0, + 18845, + 18846, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 18848, + 0, + 0, + 0, + 18853, + 18860, + 0, + 0, + 18862, + 18866, + 0, + 0, + 18867, + 18869, + 0, + 0, + 18874, + 18881, + 18891, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 18892, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 18895, + 0, + 18896, + 0, + 0, + 0, + 18900, + 0, + 0, + 0, + 18901, + 0, + 18902, + 18915, + 18916, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 18919, + 0, + 0, + 0, + 0, + 0, + 18920, + 0, + 0, + 0, + 18921, + 18929, + 0, + 0, + 0, + 0, + 18930, + 0, + 0, + 0, + 0, + 0, + 0, + 18932, + 0, + 0, + 0, + 0, + 18934, + 18942, + 0, + 0, + 0, + 18951, + 18957, + 0, + 0, + 0, + 0, + 18958, + 0, + 0, + 0, + 0, + 18959, + 18960, + 0, + 0, + 18961, + 0, + 0, + 18962, + 0, + 0, + 0, + 0, + 18963, + 18964, + 0, + 0, + 0, + 18965, + 0, + 18967, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 18968, + 0, + 18969, + 0, + 18970, + 18973, + 18976, + 0, + 0, + 0, + 0, + 0, + 0, + 18977, + 0, + 0, + 0, + 18981, + 0, + 0, + 0, + 18990, + 0, + 18998, + 0, + 0, + 0, + 0, + 0, + 18999, + 19003, + 0, + 0, + 19005, + 0, + 0, + 0, + 19006, + 0, + 0, + 0, + 0, + 0, + 0, + 19008, + 19011, + 0, + 0, + 19018, + 0, + 0, + 19019, + 0, + 19024, + 0, + 19031, + 19032, + 0, + 19039, + 0, + 19041, + 19050, + 0, + 0, + 0, + 19051, + 19055, + 19056, + 0, + 19059, + 19063, + 19064, + 0, + 0, + 19088, + 0, + 0, + 0, + 19093, + 19094, + 0, + 0, + 0, + 0, + 19095, + 0, + 19096, + 0, + 0, + 0, + 19097, + 0, + 0, + 19098, + 0, + 19099, + 19100, + 0, + 0, + 19103, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19111, + 0, + 0, + 0, + 0, + 0, + 0, + 19112, + 0, + 0, + 0, + 19116, + 19117, + 0, + 19121, + 19122, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19123, + 19124, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19125, + 19126, + 0, + 19128, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19129, + 19130, + 19131, + 19132, + 0, + 0, + 19146, + 0, + 0, + 19147, + 19156, + 19158, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19182, + 19185, + 0, + 0, + 19187, + 0, + 0, + 0, + 19193, + 0, + 0, + 0, + 0, + 0, + 19194, + 0, + 19197, + 0, + 0, + 0, + 0, + 19198, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19202, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19203, + 0, + 19205, + 19210, + 0, + 0, + 0, + 19213, + 0, + 19218, + 0, + 0, + 0, + 19223, + 19229, + 0, + 0, + 19230, + 0, + 0, + 19231, + 19232, + 19233, + 19239, + 0, + 0, + 0, + 0, + 0, + 19240, + 0, + 19248, + 19249, + 0, + 0, + 0, + 0, + 19254, + 0, + 19256, + 19258, + 19259, + 0, + 0, + 19261, + 0, + 19266, + 0, + 0, + 0, + 19272, + 0, + 19278, + 19281, + 19282, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19283, + 0, + 0, + 19284, + 0, + 0, + 19285, + 19287, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19288, + 19291, + 0, + 19292, + 0, + 0, + 0, + 0, + 19297, + 0, + 19298, + 0, + 0, + 0, + 0, + 19302, + 19303, + 0, + 0, + 0, + 0, + 19304, + 19305, + 0, + 0, + 0, + 0, + 19314, + 0, + 0, + 19315, + 0, + 0, + 19321, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19322, + 0, + 19333, + 0, + 19334, + 19335, + 0, + 19336, + 19337, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19346, + 0, + 0, + 19353, + 0, + 19354, + 19362, + 0, + 19366, + 19367, + 0, + 0, + 19369, + 0, + 19375, + 0, + 19377, + 19380, + 19388, + 0, + 0, + 0, + 0, + 0, + 19389, + 19390, + 0, + 0, + 0, + 0, + 19392, + 0, + 0, + 0, + 0, + 0, + 19402, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19412, + 0, + 0, + 19413, + 19422, + 0, + 19424, + 0, + 0, + 0, + 19425, + 0, + 0, + 0, + 19428, + 0, + 0, + 0, + 0, + 19431, + 0, + 0, + 0, + 0, + 0, + 19432, + 0, + 0, + 0, + 0, + 0, + 19448, + 19459, + 0, + 0, + 19461, + 0, + 19462, + 19463, + 0, + 19467, + 19474, + 19482, + 0, + 0, + 0, + 0, + 19494, + 0, + 0, + 0, + 0, + 19501, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19502, + 19504, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19505, + 0, + 0, + 0, + 0, + 19506, + 19507, + 0, + 0, + 0, + 19508, + 0, + 0, + 19511, + 0, + 0, + 19514, + 0, + 19515, + 0, + 19516, + 0, + 19518, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19530, + 0, + 19537, + 19538, + 0, + 19543, + 19546, + 0, + 19547, + 19551, + 0, + 0, + 0, + 0, + 0, + 0, + 19552, + 19553, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19555, + 0, + 0, + 19556, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19560, + 19561, + 0, + 0, + 19562, + 0, + 0, + 0, + 0, + 0, + 0, + 19565, + 19567, + 0, + 19568, + 0, + 0, + 0, + 19569, + 19570, + 0, + 19578, + 0, + 0, + 0, + 0, + 19580, + 0, + 0, + 0, + 0, + 19581, + 19584, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19585, + 19586, + 0, + 0, + 0, + 19587, + 19588, + 0, + 19589, + 0, + 0, + 0, + 0, + 0, + 0, + 19592, + 19593, + 19599, + 0, + 19600, + 0, + 0, + 19604, + 0, + 0, + 19605, + 0, + 19606, + 19608, + 19610, + 0, + 19613, + 19614, + 0, + 0, + 0, + 0, + 0, + 0, + 19616, + 19617, + 0, + 0, + 19618, + 0, + 0, + 19619, + 0, + 0, + 0, + 19620, + 19621, + 19631, + 0, + 0, + 19632, + 19634, + 19636, + 0, + 19643, + 0, + 0, + 19644, + 19658, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19659, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19675, + 19677, + 0, + 0, + 0, + 0, + 19679, + 0, + 19683, + 0, + 19684, + 0, + 0, + 0, + 0, + 0, + 0, + 19687, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19688, + 19689, + 19692, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19695, + 19697, + 0, + 0, + 0, + 0, + 0, + 19698, + 19699, + 0, + 0, + 19700, + 0, + 19702, + 0, + 0, + 19703, + 0, + 0, + 0, + 0, + 0, + 0, + 19704, + 19708, + 0, + 19710, + 0, + 19713, + 0, + 0, + 0, + 19715, + 0, + 0, + 0, + 0, + 19718, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19720, + 0, + 19722, + 0, + 0, + 19725, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19730, + 0, + 0, + 0, + 0, + 0, + 19731, + 0, + 19734, + 19735, + 19739, + 0, + 0, + 19740, + 0, + 19741, + 0, + 0, + 0, + 19746, + 0, + 0, + 19747, + 0, + 19771, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19772, + 19775, + 0, + 0, + 0, + 0, + 0, + 0, + 19778, + 0, + 0, + 0, + 0, + 0, + 19779, + 0, + 0, + 19780, + 19790, + 0, + 19791, + 0, + 0, + 19792, + 0, + 0, + 0, + 19793, + 0, + 0, + 19796, + 19797, + 0, + 0, + 0, + 19799, + 0, + 0, + 0, + 19801, + 0, + 0, + 0, + 0, + 19803, + 0, + 19804, + 0, + 19805, + 0, + 0, + 19807, + 0, + 0, + 0, + 19808, + 0, + 0, + 0, + 0, + 0, + 0, + 19809, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19816, + 0, + 19821, + 0, + 19822, + 19830, + 19831, + 0, + 0, + 0, + 19833, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19838, + 0, + 0, + 0, + 0, + 19839, + 0, + 0, + 19843, + 0, + 0, + 0, + 0, + 19845, + 0, + 0, + 0, + 0, + 19847, + 0, + 0, + 19848, + 0, + 19849, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19851, + 0, + 0, + 0, + 19854, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19864, + 0, + 19865, + 0, + 19866, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19868, + 0, + 0, + 19870, + 0, + 0, + 19871, + 0, + 0, + 19872, + 19873, + 19875, + 0, + 19880, + 19882, + 19884, + 0, + 0, + 19885, + 19886, + 19888, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19890, + 19892, + 19893, + 0, + 0, + 19894, + 0, + 0, + 0, + 19895, + 0, + 19896, + 19902, + 0, + 0, + 19903, + 0, + 0, + 19905, + 0, + 0, + 0, + 19906, + 0, + 19908, + 0, + 19909, + 19911, + 0, + 0, + 0, + 19913, + 19920, + 0, + 19938, + 19939, + 19940, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19942, + 0, + 19943, + 0, + 19945, + 0, + 0, + 0, + 19951, + 19952, + 19954, + 19960, + 0, + 19965, + 0, + 19971, + 0, + 0, + 0, + 0, + 0, + 19975, + 0, + 19976, + 0, + 19990, + 0, + 0, + 19991, + 0, + 19993, + 0, + 19995, + 0, + 0, + 0, + 19998, + 19999, + 20001, + 0, + 20003, + 20005, + 0, + 20011, + 20012, + 0, + 0, + 0, + 0, + 0, + 0, + 20014, + 0, + 20020, + 0, + 0, + 0, + 0, + 20021, + 0, + 0, + 0, + 0, + 0, + 20023, + 20024, + 0, + 0, + 0, + 0, + 0, + 20025, + 0, + 0, + 20027, + 0, + 0, + 20029, + 0, + 0, + 20032, + 0, + 0, + 0, + 0, + 20044, + 20045, + 0, + 20048, + 20049, + 0, + 0, + 20050, + 0, + 20052, + 0, + 0, + 20054, + 20057, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 20059, + 0, + 0, + 20061, + 0, + 20062, + 0, + 20064, + 0, + 0, + 20066, + 0, + 0, + 20067, + 0, + 0, + 0, + 0, + 20069, + 0, + 0, + 0, + 0, + 0, + 0, + 20070, + 20071, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 20072, + 0, + 0, + 20073, + 20074, + 0, + 0, + 0, + 0, + 0, + 20075, + 0, + 20078, + 0, + 0, + 0, + 0, + 20080, + 0, + 20081, + 0, + 0, + 0, + 0, + 0, + 0, + 20095, + 0, + 20098, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 20107, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 20112, + 0, + 0, + 0, + 20113, + 20114, + 0, + 0, + 0, + 20115, + 20123, + 20124, + 0, + 0, + 0, + 20131, + 20133, + 20134, + 0, + 0, + 0, + 0, + 20136, + 0, + 0, + 20137, + 20138, + 20150, + 0, + 20152, + 0, + 0, + 0, + 20153, + 0, + 0, + 20154, + 0, + 0, + 0, + 20158, + 0, + 20163, + 0, + 0, + 20164, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 20166, + 0, + 20168, + 0, + 20170, + 0, + 20175, + 0, + 0, + 20178, + 0, + 0, + 0, + 0, + 20223, + 0, + 0, + 0, + 0, + 20224, + 0, + 20226, + 0, + 0, + 20230, + 0, + 20231, + 0, + 0, + 0, + 0, + 20232, + 0, + 0, + 20233, + 20234, + 0, + 20244, + 0, + 20247, + 0, + 0, + 0, + 0, + 0, + 0, + 20249, + 0, + 0, + 0, + 20250, + 0, + 0, + 0, + 0, + 20251, + 0, + 20253, + 0, + 20254, + 0, + 0, + 0, + 0, + 20256, + 0, + 0, + 20264, + 0, + 0, + 0, + 0, + 20266, + 0, + 0, + 0, + 20278, + 0, + 0, + 20279, + 20282, + 0, + 0, + 0, + 0, + 0, + 20283, + 0, + 20284, + 0, + 20285, + 0, + 20287, + 20290, + 0, + 0, + 0, + 0, + 20292, + 0, + 0, + 0, + 0, + 20293, + 20297, + 0, + 0, + 0, + 0, + 0, + 0, + 20299, + 0, + 20300, + 20303, + 0, + 0, + 0, + 0, + 0, + 0, + 20307, + 0, + 0, + 20308, + 0, + 20309, + 0, + 20310, + 0, + 0, + 0, + 0, + 0, + 0, + 20312, + 0, + 0, + 0, + 20314, + 0, + 0, + 0, + 0, + 20315, + 20316, + 0, + 20322, + 0, + 0, + 0, + 0, + 0, + 0, + 20339, + 0, + 0, + 0, + 20342, + 0, + 0, + 0, + 0, + 20352, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 20362, + 0, + 0, + 20365, + 0, + 20375, + 20377, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 20378, + 20379, + 0, + 20380, + 0, + 0, + 20381, + 0, + 20382, + 0, + 20383, + 0, + 20388, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 20390, + 20392, + 20393, + 0, + 0, + 20395, + 0, + 0, + 0, + 0, + 0, + 20396, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 20398, + 20415, + 0, + 0, + 0, + 20417, + 0, + 0, + 20420, + 0, + 0, + 20426, + 20428, + 0, + 20431, + 0, + 0, + 20432, + 0, + 20433, + 20434, + 20435, + 0, + 0, + 0, + 0, + 20440, + 0, + 0, + 0, + 0, + 0, + 20442, + 0, + 20443, + 0, + 20446, + 0, + 0, + 0, + 0, + 20448, + 0, + 20451, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 20452, + 20453, + 0, + 0, + 20454, + 0, + 0, + 0, + 0, + 0, + 0, + 20457, + 0, + 20458, + 0, + 0, + 0, + 20465, + 0, + 0, + 0, + 0, + 0, + 20469, + 0, + 0, + 0, + 20473, + 0, + 20476, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 20477, + 0, + 0, + 20485, + 0, + 0, + 20486, + 0, + 0, + 20487, + 0, + 20496, + 0, + 20497, + 0, + 0, + 20498, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 20499, + 20500, + 0, + 20501, + 0, + 0, + 0, + 0, + 0, + 20520, + 20527, + 0, + 20529, + 0, + 0, + 0, + 0, + 20539, + 0, + 0, + 20540, + 0, + 0, + 0, + 20543, + 0, + 0, + 0, + 20546, + 0, + 0, + 0, + 0, + 0, + 20548, + 0, + 0, + 20563, + 0, + 0, + 20564, + 0, + 20566, + 0, + 0, + 0, + 0, + 0, + 20589, + 0, + 0, + 0, + 0, + 20590, + 0, + 0, + 20593, + 20594, + 0, + 0, + 0, + 0, + 20595, + 0, + 20597, + 20598, + 0, + 0, + 0, + 20618, + 20620, + 0, + 0, + 0, + 0, + 20621, + 0, + 0, + 0, + 0, + 20627, + 0, + 0, + 0, + 0, + 0, + 20628, + 0, + 0, + 0, + 20629, + 0, + 20630, + 0, + 0, + 20639, + 0, + 0, + 0, + 0, + 0, + 20707, + 0, + 0, + 20709, + 0, + 0, + 0, + 20713, + 20714, + 0, + 0, + 0, + 0, + 0, + 20724, + 20725, + 0, + 0, + 0, + 0, + 20726, + 20728, + 20729, + 0, + 20733, + 0, + 20734, + 0, + 20735, + 20736, + 0, + 20737, + 0, + 0, + 20744, + 0, + 20745, + 0, + 20748, + 0, + 0, + 20749, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 20750, + 0, + 0, + 0, + 0, + 20754, + 0, + 0, + 0, + 20761, + 0, + 0, + 20763, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 20766, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 20767, + 0, + 0, + 0, + 0, + 20768, + 0, + 20769, + 20777, + 0, + 0, + 0, + 0, + 0, + 0, + 20785, + 0, + 0, + 0, + 20786, + 20795, + 20801, + 0, + 20802, + 0, + 20807, + 0, + 0, + 20808, + 0, + 0, + 20810, + 0, + 0, + 20811, + 0, + 20812, + 0, + 0, + 0, + 0, + 0, + 20813, + 0, + 0, + 20818, + 20820, + 20821, + 0, + 0, + 0, + 20822, + 0, + 20823, + 0, + 0, + 0, + 20826, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 20829, + 20830, + 20831, + 0, + 20832, + 20836, + 0, + 0, + 20839, + 0, + 0, + 20840, + 20842, + 0, + 20843, + 0, + 20844, + 0, + 20854, + 0, + 0, + 0, + 20855, + 0, + 0, + 0, + 0, + 20856, + 0, + 0, + 0, + 20869, + 0, + 0, + 20871, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 20873, + 0, + 0, + 0, + 0, + 0, + 20876, + 0, + 0, + 0, + 0, + 0, + 20880, + 0, + 0, + 20882, + 0, + 0, + 0, + 0, + 20883, + 20884, + 0, + 0, + 20890, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 20891, + 0, + 0, + 0, + 0, + 0, + 20905, + 0, + 20906, + 20910, + 0, + 0, + 20912, + 20915, + 0, + 0, + 0, + 0, + 0, + 20916, + 0, + 20917, + 0, + 20919, + 20920, + 20922, + 0, + 20927, + 0, + 20928, + 20929, + 20930, + 0, + 0, + 20935, + 0, + 0, + 20939, + 0, + 0, + 20941, + 0, + 0, + 0, + 20943, + 0, + 0, + 0, + 20946, + 20947, + 0, + 0, + 0, + 0, + 0, + 20950, + 0, + 20954, + 0, + 0, + 20955, + 20964, + 0, + 0, + 20967, + 0, + 0, + 0, + 0, + 0, + 20973, + 20975, + 0, + 0, + 0, + 20984, + 0, + 20987, + 20988, + 0, + 0, + 0, + 0, + 0, + 20989, + 0, + 0, + 0, + 20995, + 0, + 20998, + 0, + 20999, + 0, + 0, + 0, + 0, + 21000, + 21001, + 0, + 0, + 0, + 0, + 21008, + 0, + 21010, + 0, + 21016, + 0, + 0, + 0, + 21017, + 21018, + 0, + 0, + 0, + 0, + 0, + 21021, + 21026, + 21027, + 21028, + 0, + 0, + 21029, + 0, + 0, + 0, + 0, + 0, + 21030, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21031, + 21032, + 0, + 0, + 0, + 0, + 0, + 21037, + 0, + 0, + 21038, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21039, + 0, + 21041, + 0, + 21046, + 21047, + 0, + 0, + 0, + 21049, + 21053, + 0, + 0, + 21057, + 21064, + 21065, + 0, + 0, + 21066, + 21067, + 0, + 0, + 0, + 21069, + 0, + 0, + 0, + 21071, + 21072, + 0, + 0, + 21073, + 0, + 21074, + 0, + 0, + 21078, + 0, + 0, + 0, + 0, + 21079, + 0, + 0, + 21080, + 21081, + 0, + 0, + 21086, + 21087, + 0, + 21089, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21091, + 0, + 21093, + 0, + 21094, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21095, + 0, + 0, + 0, + 0, + 0, + 21096, + 0, + 21098, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21099, + 0, + 0, + 21100, + 21101, + 21102, + 0, + 0, + 0, + 0, + 0, + 21103, + 0, + 21104, + 0, + 0, + 0, + 0, + 0, + 21105, + 21108, + 21109, + 0, + 0, + 21112, + 21113, + 0, + 0, + 0, + 0, + 0, + 0, + 21115, + 21122, + 21123, + 0, + 0, + 0, + 0, + 0, + 21125, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21129, + 21131, + 0, + 0, + 21134, + 0, + 0, + 0, + 21137, + 21142, + 0, + 21143, + 0, + 0, + 21144, + 0, + 21145, + 21146, + 0, + 21152, + 21154, + 21155, + 21156, + 0, + 0, + 0, + 21160, + 0, + 0, + 0, + 0, + 0, + 0, + 21161, + 0, + 21164, + 0, + 21166, + 0, + 0, + 0, + 0, + 21170, + 0, + 0, + 0, + 0, + 21171, + 0, + 0, + 21172, + 0, + 21174, + 0, + 21175, + 0, + 0, + 0, + 0, + 0, + 21176, + 21179, + 21188, + 0, + 0, + 0, + 21189, + 0, + 0, + 21190, + 0, + 0, + 0, + 21192, + 0, + 0, + 21193, + 0, + 0, + 0, + 21198, + 0, + 21212, + 0, + 0, + 21213, + 0, + 0, + 0, + 0, + 0, + 0, + 21215, + 21216, + 0, + 0, + 21223, + 21225, + 0, + 21226, + 0, + 0, + 0, + 0, + 21227, + 21228, + 0, + 0, + 21229, + 0, + 0, + 0, + 0, + 21230, + 21236, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21237, + 0, + 0, + 21238, + 21239, + 0, + 0, + 0, + 0, + 21256, + 0, + 0, + 0, + 0, + 0, + 21257, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21259, + 0, + 0, + 0, + 21263, + 0, + 21272, + 0, + 21274, + 0, + 21282, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21283, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21294, + 0, + 0, + 21297, + 0, + 0, + 0, + 0, + 21298, + 0, + 0, + 0, + 21299, + 0, + 21300, + 21302, + 0, + 21316, + 0, + 21318, + 21322, + 21323, + 0, + 21324, + 0, + 21326, + 0, + 0, + 0, + 21327, + 21328, + 0, + 0, + 0, + 21352, + 0, + 0, + 21354, + 21361, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21362, + 0, + 0, + 0, + 21363, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21366, + 0, + 0, + 21367, + 21372, + 21374, + 0, + 0, + 0, + 21375, + 21377, + 0, + 21378, + 0, + 0, + 0, + 21380, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21381, + 0, + 0, + 0, + 0, + 0, + 0, + 21382, + 0, + 21383, + 0, + 0, + 21384, + 0, + 0, + 21385, + 0, + 0, + 0, + 0, + 21389, + 21390, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21397, + 21398, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21399, + 0, + 21400, + 0, + 0, + 0, + 0, + 21402, + 0, + 0, + 0, + 21403, + 21404, + 0, + 21405, + 21406, + 0, + 0, + 0, + 21407, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21408, + 0, + 0, + 0, + 0, + 21409, + 0, + 21421, + 0, + 21422, + 0, + 0, + 0, + 21425, + 21428, + 0, + 0, + 0, + 0, + 21429, + 0, + 0, + 0, + 0, + 0, + 21433, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21434, + 0, + 21443, + 0, + 21444, + 21449, + 0, + 21452, + 0, + 21453, + 21454, + 0, + 0, + 0, + 21457, + 0, + 0, + 21458, + 0, + 0, + 0, + 21460, + 21461, + 0, + 0, + 21464, + 0, + 0, + 0, + 21473, + 21478, + 0, + 0, + 21479, + 0, + 0, + 21481, + 21483, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21484, + 0, + 0, + 21485, + 21486, + 0, + 0, + 21488, + 0, + 0, + 0, + 0, + 0, + 0, + 21523, + 0, + 0, + 21525, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21526, + 0, + 0, + 0, + 0, + 0, + 0, + 21529, + 21530, + 0, + 0, + 21531, + 0, + 0, + 21533, + 0, + 0, + 21539, + 21564, + 0, + 21567, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21575, + 0, + 0, + 0, + 0, + 21577, + 0, + 0, + 0, + 0, + 0, + 21591, + 0, + 0, + 21604, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21605, + 0, + 21606, + 0, + 0, + 21617, + 21618, + 21619, + 21620, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21623, + 0, + 0, + 0, + 0, + 21631, + 0, + 21635, + 0, + 0, + 0, + 0, + 21639, + 21646, + 21653, + 21662, + 0, + 0, + 21663, + 21664, + 0, + 21666, + 0, + 0, + 21667, + 0, + 21670, + 21672, + 21673, + 0, + 21674, + 21683, + 0, + 0, + 0, + 0, + 0, + 21684, + 0, + 21694, + 0, + 0, + 0, + 0, + 21695, + 21700, + 0, + 21703, + 0, + 21704, + 0, + 0, + 21709, + 0, + 0, + 0, + 21710, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21711, + 0, + 0, + 0, + 21712, + 0, + 21717, + 0, + 21730, + 0, + 0, + 0, + 21731, + 21733, + 0, + 0, + 0, + 0, + 21737, + 21741, + 21742, + 0, + 21747, + 0, + 0, + 0, + 21749, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21750, + 0, + 0, + 0, + 0, + 0, + 21752, + 0, + 0, + 0, + 0, + 21753, + 0, + 0, + 0, + 0, + 0, + 0, + 21755, + 21756, + 0, + 21757, + 0, + 0, + 0, + 0, + 0, + 0, + 21760, + 0, + 0, + 21763, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21764, + 0, + 0, + 21766, + 0, + 0, + 21767, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21773, + 0, + 21774, + 0, + 0, + 21775, + 0, + 0, + 0, + 0, + 21776, + 0, + 0, + 21777, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21780, + 21787, + 21788, + 21791, + 0, + 0, + 0, + 21797, + 0, + 0, + 0, + 0, + 0, + 21805, + 0, + 0, + 0, + 0, + 21806, + 0, + 21807, + 21809, + 0, + 21810, + 21811, + 0, + 21817, + 21819, + 21820, + 0, + 21823, + 0, + 21824, + 0, + 0, + 21825, + 0, + 0, + 21826, + 21832, + 0, + 0, + 0, + 0, + 0, + 21833, + 21848, + 21849, + 0, + 0, + 21867, + 21870, + 21871, + 21873, + 0, + 0, + 0, + 21874, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21875, + 0, + 21878, + 0, + 0, + 0, + 21879, + 0, + 21881, + 21886, + 0, + 0, + 0, + 0, + 21887, + 0, + 0, + 21888, + 21894, + 21895, + 21897, + 0, + 21901, + 0, + 21904, + 0, + 0, + 21906, + 0, + 0, + 0, + 21909, + 21910, + 21911, + 0, + 0, + 21912, + 0, + 0, + 21913, + 21914, + 21915, + 0, + 21919, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21921, + 0, + 0, + 21922, + 21933, + 21939, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21944, + 0, + 0, + 0, + 0, + 0, + 21945, + 0, + 21947, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21949, + 0, + 0, + 0, + 21950, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21951, + 0, + 21952, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21954, + 21957, + 0, + 0, + 0, + 0, + 21958, + 0, + 21959, + 0, + 0, + 0, + 0, + 0, + 0, + 21962, + 21963, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21964, + 21965, + 0, + 0, + 21969, + 21970, + 0, + 0, + 0, + 21974, + 0, + 0, + 21980, + 21981, + 0, + 21982, + 0, + 0, + 0, + 0, + 0, + 21985, + 0, + 21988, + 0, + 21992, + 0, + 21999, + 0, + 0, + 0, + 0, + 0, + 0, + 22001, + 0, + 22002, + 0, + 0, + 0, + 0, + 0, + 0, + 22003, + 0, + 0, + 0, + 0, + 0, + 22004, + 0, + 0, + 0, + 22008, + 0, + 22009, + 22015, + 0, + 0, + 22016, + 0, + 0, + 0, + 22017, + 22019, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22020, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22021, + 22037, + 0, + 22039, + 0, + 0, + 0, + 22040, + 0, + 0, + 0, + 22048, + 22049, + 0, + 0, + 22053, + 22055, + 22056, + 22059, + 0, + 0, + 22060, + 22061, + 0, + 0, + 22064, + 0, + 0, + 0, + 0, + 22066, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22073, + 0, + 0, + 0, + 22074, + 22075, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22076, + 0, + 0, + 0, + 0, + 22077, + 22084, + 22099, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22104, + 0, + 0, + 22107, + 0, + 22108, + 0, + 22109, + 0, + 22110, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22111, + 22119, + 0, + 22120, + 22122, + 0, + 0, + 0, + 0, + 22125, + 0, + 0, + 0, + 22128, + 22129, + 0, + 0, + 0, + 0, + 0, + 0, + 22141, + 0, + 0, + 0, + 22142, + 0, + 0, + 22144, + 22146, + 0, + 22148, + 22149, + 22151, + 22154, + 0, + 0, + 0, + 22162, + 0, + 0, + 0, + 0, + 22164, + 22177, + 0, + 0, + 0, + 0, + 22179, + 0, + 22182, + 22183, + 0, + 0, + 22184, + 22188, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22190, + 0, + 22194, + 22201, + 0, + 0, + 22208, + 0, + 22209, + 0, + 22212, + 0, + 0, + 22215, + 0, + 22223, + 22231, + 0, + 0, + 22232, + 0, + 22234, + 0, + 0, + 22235, + 22236, + 0, + 22237, + 0, + 22240, + 0, + 0, + 0, + 0, + 0, + 22241, + 0, + 0, + 0, + 22242, + 22246, + 22247, + 0, + 0, + 0, + 22259, + 22268, + 0, + 22269, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22270, + 0, + 0, + 0, + 0, + 22271, + 0, + 22272, + 0, + 22277, + 0, + 0, + 0, + 0, + 0, + 22278, + 22280, + 22283, + 22286, + 0, + 0, + 22287, + 22289, + 0, + 0, + 22290, + 0, + 22293, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22295, + 0, + 22301, + 22302, + 0, + 0, + 0, + 22305, + 0, + 22308, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22315, + 0, + 0, + 0, + 22317, + 0, + 22334, + 0, + 0, + 0, + 22335, + 0, + 0, + 0, + 0, + 0, + 22336, + 0, + 22338, + 22344, + 0, + 22347, + 22349, + 0, + 22350, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22357, + 0, + 0, + 0, + 0, + 0, + 22358, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22359, + 22360, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22361, + 22366, + 0, + 0, + 22369, + 0, + 22370, + 22373, + 0, + 0, + 0, + 0, + 0, + 22375, + 0, + 22377, + 0, + 0, + 0, + 0, + 0, + 22378, + 0, + 0, + 0, + 0, + 22381, + 0, + 0, + 0, + 0, + 22382, + 0, + 22383, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22391, + 0, + 0, + 22392, + 22395, + 22396, + 22402, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22405, + 0, + 0, + 22406, + 0, + 0, + 22408, + 0, + 0, + 22409, + 22410, + 0, + 0, + 0, + 0, + 0, + 0, + 22424, + 0, + 0, + 0, + 0, + 22426, + 0, + 0, + 0, + 22427, + 0, + 22428, + 0, + 22432, + 0, + 22435, + 22442, + 22443, + 0, + 0, + 0, + 0, + 22444, + 0, + 0, + 0, + 0, + 0, + 22446, + 0, + 22454, + 0, + 22455, + 0, + 0, + 0, + 22465, + 0, + 22470, + 0, + 22471, + 0, + 0, + 0, + 0, + 22472, + 22473, + 0, + 22487, + 0, + 0, + 0, + 22488, + 0, + 0, + 0, + 0, + 22489, + 0, + 0, + 22499, + 0, + 0, + 0, + 0, + 0, + 0, + 22514, + 0, + 0, + 22515, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22516, + 0, + 0, + 0, + 22517, + 22520, + 0, + 0, + 0, + 22534, + 0, + 0, + 22535, + 0, + 0, + 22536, + 0, + 22540, + 22553, + 0, + 22555, + 0, + 0, + 0, + 0, + 22561, + 0, + 0, + 22562, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22566, + 0, + 0, + 0, + 0, + 22567, + 22568, + 0, + 0, + 22575, + 0, + 22579, + 0, + 22582, + 22583, + 22585, + 0, + 0, + 0, + 0, + 0, + 22586, + 0, + 0, + 22587, + 0, + 0, + 22590, + 0, + 0, + 0, + 0, + 0, + 22591, + 0, + 22592, + 0, + 0, + 0, + 0, + 0, + 22593, + 0, + 22602, + 0, + 0, + 22604, + 0, + 0, + 22609, + 0, + 0, + 22618, + 0, + 0, + 0, + 0, + 0, + 0, + 22619, + 0, + 22624, + 22625, + 0, + 0, + 22638, + 0, + 0, + 0, + 0, + 0, + 22639, + 0, + 0, + 22640, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22644, + 0, + 22645, + 22647, + 0, + 0, + 0, + 0, + 22652, + 22653, + 0, + 0, + 0, + 22654, + 0, + 22655, + 0, + 0, + 0, + 22656, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22673, + 22675, + 22676, + 0, + 0, + 22678, + 22679, + 0, + 22691, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22693, + 0, + 0, + 22696, + 0, + 22699, + 22707, + 22708, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22718, + 0, + 22719, + 0, + 0, + 0, + 0, + 22723, + 0, + 0, + 0, + 22724, + 22725, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22726, + 22728, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22729, + 0, + 0, + 22731, + 0, + 0, + 0, + 0, + 22732, + 22735, + 22736, + 0, + 0, + 0, + 0, + 22739, + 0, + 22749, + 0, + 0, + 22751, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22758, + 0, + 0, + 0, + 0, + 0, + 22760, + 0, + 0, + 0, + 0, + 0, + 22764, + 22765, + 22766, + 0, + 22768, + 0, + 0, + 0, + 0, + 0, + 22769, + 22770, + 0, + 0, + 0, + 0, + 0, + 0, + 22771, + 0, + 0, + 22772, + 22775, + 0, + 22776, + 22777, + 22780, + 0, + 0, + 22782, + 22784, + 0, + 22787, + 0, + 22789, + 22796, + 0, + 0, + 0, + 0, + 0, + 22798, + 0, + 0, + 0, + 0, + 0, + 0, + 22802, + 0, + 22803, + 22804, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22805, + 0, + 0, + 22810, + 22811, + 22814, + 22816, + 0, + 22825, + 22826, + 0, + 22831, + 22833, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22834, + 0, + 22836, + 22838, + 0, + 22839, + 0, + 0, + 0, + 0, + 0, + 22840, + 0, + 22847, + 0, + 0, + 0, + 0, + 0, + 22856, + 22857, + 0, + 22858, + 22859, + 0, + 0, + 22862, + 0, + 0, + 22864, + 0, + 0, + 0, + 0, + 22865, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22866, + 0, + 22867, + 22868, + 0, + 0, + 0, + 0, + 22869, + 0, + 22871, + 0, + 22872, + 0, + 22873, + 22881, + 22882, + 22884, + 22885, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22886, + 22887, + 0, + 22894, + 0, + 22895, + 0, + 0, + 0, + 22900, + 0, + 22901, + 0, + 0, + 0, + 0, + 22904, + 0, + 0, + 0, + 0, + 22905, + 22907, + 0, + 0, + 0, + 22915, + 22917, + 0, + 0, + 22918, + 0, + 0, + 0, + 22920, + 0, + 0, + 0, + 22929, + 22930, + 0, + 0, + 0, + 22941, + 22942, + 0, + 0, + 0, + 22943, + 0, + 0, + 0, + 22944, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22946, + 0, + 22947, + 0, + 0, + 22954, + 0, + 22956, + 0, + 0, + 22962, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22963, + 0, + 0, + 22964, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22965, + 0, + 22968, + 0, + 0, + 0, + 22969, + 0, + 0, + 0, + 0, + 0, + 22970, + 0, + 22971, + 0, + 0, + 0, + 0, + 0, + 22978, + 0, + 0, + 22979, + 0, + 22987, + 0, + 0, + 22989, + 0, + 0, + 0, + 0, + 0, + 0, + 22990, + 0, + 23005, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 23006, + 23007, + 23008, + 0, + 0, + 23023, + 23024, + 23029, + 0, + 0, + 0, + 0, + 23030, + 0, + 0, + 0, + 0, + 0, + 23032, + 0, + 0, + 0, + 0, + 0, + 23035, + 0, + 0, + 0, + 0, + 23038, + 0, + 0, + 0, + 23048, + 0, + 23049, + 23052, + 23053, + 23060, + 23061, + 0, + 23063, + 0, + 0, + 0, + 0, + 23067, + 23068, + 0, + 0, + 0, + 23069, + 23073, + 0, + 0, + 0, + 23127, + 0, + 23128, + 0, + 0, + 0, + 0, + 0, + 23129, + 0, + 23138, + 23141, + 0, + 23149, + 0, + 0, + 23150, + 0, + 0, + 0, + 23152, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 23154, + 0, + 0, + 0, + 0, + 23157, + 23159, + 23160, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 23180, + 0, + 0, + 0, + 0, + 23181, + 0, + 0, + 23188, + 0, + 23189, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 23195, + 0, + 0, + 23196, + 23199, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 23202, + 0, + 23204, + 0, + 23207, + 0, + 23209, + 23210, + 0, + 0, + 0, + 0, + 0, + 0, + 23227, + 23229, + 0, + 0, + 23230, + 23234, + 23238, + 0, + 0, + 0, + 23245, + 23246, + 23248, + 0, + 0, + 0, + 0, + 23249, + 23254, + 0, + 0, + 0, + 23265, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 23268, + 0, + 23276, + 0, + 0, + 0, + 0, + 23277, + 0, + 23297, + 0, + 23298, + 0, + 0, + 0, + 0, + 23299, + 0, + 23302, + 0, + 0, + 23303, + 23312, + 0, + 0, + 23314, + 0, + 23320, + 0, + 0, + 0, + 0, + 23324, + 0, + 23325, + 0, + 23328, + 0, + 23334, + 0, + 0, + 0, + 23337, + 0, + 0, + 0, + 0, + 23343, + 23344, + 23346, + 0, + 23348, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 23353, + 0, + 0, + 0, + 0, + 23355, + 0, + 23356, + 23358, + 0, + 0, + 0, + 23359, + 23360, + 0, + 23361, + 0, + 23367, + 0, + 23369, + 0, + 0, + 23373, + 0, + 23378, + 23379, + 0, + 23382, + 23383, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 23387, + 0, + 0, + 0, + 0, + 0, + 0, + 23388, + 23390, + 0, + 0, + 23393, + 23398, + 0, + 0, + 0, + 23399, + 0, + 0, + 0, + 23400, + 0, + 0, + 0, + 0, + 23401, + 0, + 0, + 0, + 23415, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 23416, + 0, + 23422, + 0, + 23443, + 23444, + 0, + 0, + 0, + 0, + 23448, + 0, + 23454, + 0, + 0, + 0, + 0, + 0, + 0, + 23456, + 0, + 0, + 23458, + 23464, + 0, + 0, + 0, + 0, + 0, + 0, + 23465, + 0, + 0, + 0, + 23470, + 23471, + 0, + 0, + 23472, + 0, + 0, + 0, + 23473, + 23496, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 23497, + 0, + 23499, + 0, + 0, + 23502, + 0, + 0, + 23503, + 0, + 0, + 23513, + 0, + 0, + 23515, + 0, + 0, + 0, + 23517, + 0, + 0, + 0, + 0, + 23518, + 23519, + 23521, + 23524, + 0, + 23525, + 23528, + 23539, + 0, + 0, + 0, + 0, + 0, + 23541, + 0, + 0, + 23544, + 0, + 0, + 23556, + 0, + 0, + 23557, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 23559, + 0, + 23560, + 0, + 0, + 23561, + 0, + 0, + 23566, + 0, + 0, + 0, + 0, + 0, + 23568, + 23569, + 23570, + 0, + 0, + 0, + 0, + 23571, + 0, + 23574, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 23575, + 0, + 23579, + 0, + 0, + 23581, + 0, + 0, + 0, + 0, + 0, + 0, + 23587, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 23596, + 23598, + 0, + 0, + 0, + 0, + 23602, + 23606, + 0, + 0, + 23607, + 0, + 23608, + 0, + 0, + 0, + 23614, + 23616, + 0, + 0, + 0, + 0, + 0, + 23618, + 0, + 0, + 23619, + 0, + 0, + 0, + 0, + 23621, + 23626, + 0, + 23627, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 23629, + 0, + 23630, + 0, + 0, + 0, + 0, + 23634, + 0, + 23636, + 0, + 0, + 0, + 0, + 0, + 0, + 23638, + 0, + 0, + 0, + 0, + 23640, + 23667, + 0, + 23669, + 0, + 0, + 0, + 23681, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 23682, + 0, + 23683, + 0, + 0, + 0, + 0, + 0, + 23684, + 0, + 0, + 0, + 23685, + 23689, + 0, + 23693, + 23694, + 23700, + 0, + 23702, + 0, + 23709, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 23712, + 0, + 0, + 0, + 0, + 0, + 23714, + 0, + 0, + 23715, + 0, + 0, + 0, + 0, + 23718, + 0, + 0, + 23720, + 0, + 0, + 0, + 0, + 23722, + 0, + 0, + 0, + 23726, + 23729, + 0, + 23741, + 23746, + 0, + 23748, + 0, + 0, + 0, + 0, + 23749, + 0, + 0, + 0, + 0, + 0, + 23750, + 0, + 0, + 0, + 0, + 23751, + 0, + 23753, + 0, + 0, + 0, + 0, + 23757, + 23765, + 0, + 0, + 0, + 23770, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 23771, + 0, + 23772, + 23781, + 0, + 0, + 23796, + 0, + 0, + 0, + 0, + 23798, + 0, + 23799, + 0, + 0, + 0, + 23802, + 0, + 0, + 23806, + 0, + 23807, + 0, + 0, + 23808, + 0, + 23809, + 0, + 23819, + 0, + 0, + 0, + 23821, + 0, + 23827, + 0, + 0, + 0, + 23829, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 23830, + 0, + 0, + 0, + 0, + 0, + 0, + 23832, + 23833, + 23834, + 23835, + 0, + 0, + 0, + 0, + 23837, + 23838, + 0, + 0, + 0, + 0, + 0, + 23846, + 0, + 0, + 0, + 0, + 0, + 0, + 23847, + 0, + 0, + 0, + 0, + 0, + 23879, + 23881, + 0, + 0, + 23882, + 23883, + 23895, + 0, + 23899, + 0, + 0, + 0, + 0, + 23901, + 0, + 0, + 0, + 0, + 0, + 0, + 23902, + 0, + 0, + 0, + 0, + 0, + 23903, + 23905, + 0, + 23906, + 0, + 23907, + 23918, + 23919, + 23920, + 0, + 23922, + 0, + 23924, + 0, + 23927, + 0, + 23934, + 0, + 23937, + 23941, + 0, + 23942, + 23946, + 0, + 0, + 0, + 0, + 0, + 23955, + 23956, + 23958, + 0, + 0, + 0, + 0, + 0, + 0, + 23959, + 0, + 23962, + 23965, + 0, + 23966, + 0, + 0, + 0, + 0, + 23967, + 23968, + 0, + 0, + 23973, + 0, + 0, + 23974, + 0, + 0, + 0, + 0, + 23975, + 0, + 23976, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 23977, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 23980, + 0, + 0, + 23984, + 0, + 23985, + 0, + 0, + 23987, + 0, + 0, + 23988, + 23990, + 23991, + 0, + 0, + 0, + 0, + 0, + 0, + 23992, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 23994, + 0, + 0, + 0, + 23998, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 23999, + 0, + 0, + 24003, + 0, + 24004, + 0, + 24006, + 0, + 0, + 0, + 24007, + 0, + 0, + 24008, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 24009, + 0, + 0, + 24010, + 0, + 0, + 24011, + 0, + 0, + 24013, + 24014, + 0, + 0, + 24015, + 24016, + 24027, + 0, + 24028, + 24029, + 0, + 24030, + 0, + 0, + 0, + 0, + 0, + 24033, + 24034, + 0, + 24035, + 0, + 0, + 24036, + 0, + 0, + 24044, + 0, + 24048, + 24049, + 24063, + 24067, + 0, + 24068, + 24070, + 0, + 0, + 24071, + 24078, + 24087, + 0, + 24090, + 0, + 0, + 0, + 24095, + 0, + 24098, + 24101, + 24104, + 24106, + 0, + 24107, + 0, + 0, + 0, + 24108, + 0, + 0, + 0, + 0, + 24110, + 24111, + 0, + 24113, + 0, + 0, + 24115, + 24120, + 0, + 0, + 0, + 0, + 0, + 0, + 24124, + 0, + 24125, + 0, + 24126, + 0, + 24127, + 0, + 0, + 0, + 0, + 0, + 24135, + 0, + 0, + 24136, + 0, + 24137, + 24142, + 0, + 0, + 0, + 24146, + 0, + 0, + 24147, + 24149, + 24154, + 0, + 24163, + 0, + 0, + 0, + 24165, + 24166, + 24167, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 24169, + 24170, + 24175, + 0, + 0, + 0, + 24178, + 0, + 0, + 24179, + 0, + 0, + 24181, + 0, + 24184, + 24197, + 0, + 24201, + 24204, + 0, + 0, + 0, + 0, + 0, + 0, + 24206, + 24212, + 24220, + 0, + 0, + 0, + 24224, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 24226, + 0, + 24234, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 24235, + 0, + 24236, + 0, + 0, + 0, + 0, + 0, + 24239, + 24240, + 24241, + 0, + 0, + 24248, + 0, + 0, + 24249, + 0, + 24251, + 0, + 0, + 0, + 0, + 0, + 0, + 24253, + 0, + 24268, + 0, + 0, + 0, + 24269, + 0, + 24271, + 24272, + 0, + 0, + 0, + 0, + 24273, + 0, + 0, + 24274, + 0, + 0, + 24279, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 24280, + 0, + 24293, + 24294, + 0, + 0, + 0, + 0, + 0, + 0, + 24296, + 0, + 0, + 24323, + 0, + 0, + 0, + 24329, + 24330, + 24331, + 24339, + 0, + 24351, + 0, + 0, + 24369, + 24370, + 0, + 0, + 0, + 24371, + 0, + 0, + 0, + 0, + 24372, + 24373, + 24374, + 0, + 0, + 0, + 0, + 0, + 24378, + 0, + 0, + 0, + 0, + 24379, + 0, + 24381, + 0, + 24383, + 24389, + 0, + 24390, + 0, + 0, + 24394, + 24395, + 24400, + 0, + 0, + 0, + 24401, + 24402, + 0, + 24406, + 0, + 0, + 0, + 24411, + 0, + 0, + 0, + 24415, + 0, + 24416, + 0, + 0, + 0, + 0, + 0, + 24417, + 0, + 24419, + 0, + 24422, + 0, + 24423, + 24428, + 0, + 24435, + 0, + 0, + 0, + 24439, + 0, + 0, + 0, + 24440, + 24442, + 24446, + 0, + 0, + 0, + 24447, + 24448, + 24449, + 24452, + 0, + 0, + 0, + 0, + 24453, + 24457, + 0, + 0, + 24458, + 24459, + 24460, + 0, + 24465, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 24470, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 24471, + 0, + 24473, + 24474, + 24475, + 24476, + 0, + 24478, + 0, + 0, + 0, + 0, + 24480, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 24481, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 24482, + 24485, + 0, + 0, + 0, + 0, + 24486, + 0, + 0, + 0, + 24488, + 0, + 0, + 0, + 24494, + 0, + 0, + 0, + 0, + 24497, + 0, + 0, + 24498, + 0, + 0, + 0, + 24499, + 24506, + 0, + 0, + 0, + 24507, + 0, + 0, + 24511, + 0, + 0, + 24513, + 24514, + 0, + 0, + 0, + 0, + 0, + 24517, + 0, + 24518, + 0, + 24520, + 0, + 24521, + 24524, + 24525, + 0, + 0, + 0, + 0, + 0, + 24527, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 24528, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 24537, + 24539, + 0, + 24540, + 0, + 0, + 0, + 24548, + 0, + 0, + 0, + 0, + 0, + 24549, + 24550, + 0, + 0, + 0, + 24553, + 24554, + 0, + 24555, + 0, + 24556, + 0, + 24558, + 0, + 0, + 0, + 0, + 0, + 24560, + 0, + 0, + 0, + 24561, + 0, + 0, + 0, + 0, + 0, + 24562, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 24567, + 0, + 0, + 0, + 0, + 0, + 24569, + 0, + 0, + 0, + 24574, + 0, + 24575, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 24577, + 24581, + 0, + 24584, + 0, + 0, + 0, + 0, + 0, + 24585, + 0, + 0, + 0, + 0, + 0, + 24586, + 0, + 0, + 24587, + 0, + 24588, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 24590, + 24591, + 0, + 0, + 0, + 0, + 24592, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 24594, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 24596, + 24597, + 0, + 0, + 0, + 0, + 24602, + 24603, + 0, + 0, + 0, + 0, + 24604, + 0, + 0, + 24605, + 0, + 24610, + 0, + 0, + 24611, + 0, + 0, + 0, + 0, + 24612, + 24615, + 24616, + 24624, + 0, + 0, + 0, + 24627, + 0, + 24638, + 24639, + 0, + 0, + 0, + 0, + 24640, + 0, + 0, + 0, + 24655, + 24656, + 24657, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 24662, + 0, + 24663, + 24664, + 0, + 0, + 0, + 0, + 0, + 24665, + 0, + 0, + 0, + 0, + 24667, + 0, + 0, + 0, + 0, + 0, + 0, + 24668, + 24669, + 0, + 24670, + 24674, + 0, + 0, + 0, + 24675, + 0, + 24678, + 0, + 0, + 24679, + 0, + 0, + 0, + 24681, + 0, + 24683, + 0, + 0, + 0, + 0, + 24684, + 0, + 24685, + 0, + 0, + 24686, + 0, + 0, + 24688, + 24689, + 0, + 0, + 0, + 0, + 24690, + 24691, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 24697, + 0, + 24698, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 24709, + 0, + 0, + 0, + 0, + 0, + 24710, + 0, + 24712, + 0, + 0, + 0, + 0, + 0, + 0, + 24713, + 24714, + 0, + 24715, + 0, + 24716, + 24718, + 0, + 24719, + 0, + 0, + 0, + 0, + 24720, + 0, + 0, + 24725, + 0, + 0, + 24738, + 0, + 24749, + 24750, + 0, + 0, + 0, + 24752, + 0, + 0, + 0, + 24753, + 0, + 0, + 0, + 24758, + 0, + 0, + 0, + 0, + 0, + 24762, + 0, + 24763, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 24764, + 0, + 0, + 0, + 0, + 0, + 24765, + 24767, + 24768, + 0, + 24772, + 0, + 0, + 0, + 0, + 24773, + 0, + 0, + 0, + 0, + 24777, + 0, + 0, + 0, + 0, + 0, + 24785, + 0, + 24786, + 24788, + 0, + 0, + 0, + 24789, + 0, + 0, + 0, + 0, + 24794, + 24798, + 0, + 24799, + 24800, + 0, + 0, + 0, + 24803, + 0, + 24804, + 24806, + 0, + 24807, + 0, + 0, + 0, + 24810, + 0, + 0, + 0, + 0, + 0, + 0, + 24827, + 24828, + 0, + 24835, + 0, + 0, + 0, + 0, + 0, + 0, + 24836, + 0, + 0, + 0, + 0, + 0, + 24839, + 0, + 24843, + 24844, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 24847, + 0, + 0, + 24848, + 0, + 0, + 0, + 0, + 0, + 0, + 24849, + 0, + 24850, + 24851, + 0, + 0, + 0, + 24852, + 0, + 24853, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 24854, + 0, + 24855, + 0, + 0, + 24868, + 0, + 0, + 0, + 24883, + 0, + 0, + 0, + 24884, + 0, + 24895, + 24897, + 0, + 0, + 0, + 0, + 0, + 24899, + 0, + 0, + 0, + 0, + 0, + 24900, + 0, + 24913, + 0, + 0, + 0, + 0, + 0, + 0, + 24914, + 0, + 0, + 24917, + 24930, + 24931, + 0, + 0, + 0, + 24932, + 0, + 0, + 24939, + 0, + 0, + 24942, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 24945, + 24950, + 0, + 24951, + 0, + 0, + 24953, + 0, + 0, + 0, + 24954, + 0, + 24959, + 0, + 0, + 0, + 24961, + 0, + 0, + 24962, + 0, + 24964, + 24968, + 24970, + 24972, + 0, + 0, + 0, + 0, + 0, + 24976, + 0, + 0, + 0, + 24977, + 0, + 24982, + 0, + 0, + 24983, + 0, + 0, + 24984, + 0, + 0, + 0, + 24993, + 0, + 0, + 0, + 24994, + 0, + 0, + 25001, + 0, + 0, + 0, + 25003, + 0, + 0, + 25018, + 0, + 0, + 25023, + 0, + 0, + 0, + 25034, + 0, + 0, + 25035, + 25036, + 0, + 25037, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 25039, + 0, + 0, + 0, + 0, + 0, + 25040, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 25042, + 0, + 0, + 25043, + 25045, + 0, + 0, + 0, + 0, + 0, + 0, + 25049, + 0, + 0, + 25051, + 0, + 25052, + 25053, + 0, + 0, + 25054, + 0, + 0, + 0, + 25055, + 0, + 0, + 0, + 0, + 25057, + 25059, + 0, + 0, + 25060, + 25064, + 0, + 25065, + 25069, + 25070, + 0, + 0, + 0, + 0, + 25072, + 0, + 25073, + 0, + 25090, + 0, + 0, + 25092, + 25093, + 25101, + 0, + 0, + 0, + 0, + 0, + 0, + 25105, + 25108, + 0, + 0, + 25113, + 0, + 0, + 25115, + 25116, + 0, + 0, + 0, + 0, + 0, + 0, + 25117, + 0, + 0, + 0, + 25120, + 25121, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 25125, + 0, + 0, + 0, + 25126, + 0, + 25130, + 25134, + 0, + 25139, + 0, + 25143, + 0, + 0, + 0, + 25151, + 0, + 25161, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 25163, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 25174, + 0, + 25175, + 0, + 25207, + 0, + 0, + 0, + 25209, + 0, + 0, + 0, + 0, + 25213, + 0, + 25219, + 0, + 25223, + 0, + 25225, + 0, + 0, + 0, + 25227, + 0, + 0, + 0, + 25228, + 0, + 0, + 0, + 25229, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 25231, + 25233, + 0, + 0, + 0, + 0, + 25237, + 25239, + 0, + 0, + 0, + 25243, + 0, + 0, + 0, + 25252, + 0, + 25257, + 25258, + 0, + 0, + 0, + 0, + 25260, + 25265, + 0, + 25268, + 0, + 0, + 25273, + 25324, + 0, + 25325, + 0, + 25326, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 25327, + 0, + 0, + 0, + 0, + 0, + 25328, + 0, + 0, + 0, + 0, + 0, + 0, + 25332, + 0, + 0, + 0, + 25333, + 0, + 0, + 0, + 25336, + 25337, + 25338, + 0, + 0, + 25343, + 0, + 25350, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 25352, + 0, + 25354, + 0, + 25375, + 0, + 25379, + 0, + 0, + 0, + 0, + 25384, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 25386, + 0, + 25388, + 0, + 25390, + 0, + 0, + 25399, + 0, + 0, + 25401, + 0, + 0, + 0, + 25402, + 0, + 0, + 0, + 25407, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 25413, + 25415, + 0, + 0, + 25417, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 25419, + 0, + 0, + 0, + 25421, + 0, + 0, + 0, + 25424, + 0, + 0, + 0, + 0, + 25433, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 25435, + 0, + 0, + 0, + 0, + 0, + 0, + 25436, + 0, + 0, + 0, + 25437, + 0, + 0, + 25440, + 0, + 0, + 0, + 0, + 0, + 0, + 25442, + 0, + 0, + 25443, + 0, + 25446, + 0, + 0, + 25449, + 0, + 0, + 0, + 25450, + 0, + 0, + 0, + 0, + 25452, + 0, + 25453, + 25454, + 25455, + 0, + 0, + 0, + 25456, + 0, + 25457, + 0, + 0, + 0, + 25459, + 0, + 25461, + 0, + 25468, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 25469, + 0, + 0, + 0, + 0, + 0, + 25471, + 0, + 0, + 0, + 0, + 0, + 25474, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 25475, + 0, + 0, + 0, + 0, + 25477, + 0, + 0, + 0, + 0, + 25483, + 0, + 0, + 0, + 0, + 0, + 25484, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 25485, + 0, + 25497, + 0, + 0, + 25498, + 0, + 25504, + 0, + 25510, + 0, + 25512, + 0, + 0, + 25513, + 25514, + 0, + 0, + 0, + 0, + 0, + 0, + 25517, + 25518, + 25519, + 0, + 25520, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 25521, + 0, + 25522, + 25527, + 25534, + 0, + 25536, + 0, + 25537, + 0, + 0, + 25548, + 25550, + 0, + 0, + 25551, + 0, + 25552, + 0, + 0, + 0, + 0, + 0, + 25554, + 0, + 25555, + 0, + 25556, + 25557, + 25568, + 0, + 0, + 0, + 25570, + 25571, + 0, + 0, + 0, + 0, + 0, + 0, + 25574, + 0, + 0, + 0, + 0, + 25579, + 0, + 0, + 0, + 25581, + 0, + 0, + 0, + 25582, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 25588, + 0, + 0, + 0, + 0, + 25589, + 0, + 0, + 0, + 0, + 25590, + 0, + 25591, + 25592, + 25593, + 0, + 25594, + 0, + 0, + 0, + 25596, + 0, + 25597, + 25615, + 0, + 0, + 0, + 0, + 0, + 25618, + 0, + 0, + 0, + 0, + 25619, + 25623, + 0, + 0, + 25629, + 0, + 0, + 25631, + 0, + 0, + 0, + 25635, + 25636, + 0, + 0, + 25649, + 0, + 0, + 0, + 0, + 25654, + 0, + 0, + 0, + 25661, + 25663, + 0, + 0, + 25671, + 0, + 0, + 25678, + 25698, + 0, + 25699, + 25702, + 25703, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 25704, + 0, + 0, + 0, + 0, + 0, + 25706, + 0, + 0, + 25710, + 0, + 25711, + 0, + 25712, + 0, + 25715, + 25716, + 25717, + 0, + 0, + 25718, + 25728, + 25732, + 0, + 0, + 0, + 25734, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 25737, + 0, + 0, + 25739, + 0, + 0, + 0, + 25740, + 0, + 25741, + 25745, + 0, + 25746, + 0, + 25748, + 25772, + 25778, + 0, + 0, + 0, + 0, + 0, + 25780, + 0, + 0, + 0, + 0, + 25781, + 0, + 25782, + 25784, + 25785, + 0, + 0, + 0, + 25789, + 0, + 0, + 0, + 0, + 0, + 0, + 25797, + 25801, + 0, + 0, + 0, + 25808, + 25809, + 0, + 0, + 25811, + 25814, + 25815, + 0, + 0, + 25817, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 25820, + 0, + 0, + 0, + 0, + 25832, + 25833, + 0, + 0, + 0, + 25846, + 0, + 0, + 0, + 25847, + 25848, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 25849, + 25850, + 0, + 0, + 25851, + 0, + 0, + 25852, + 0, + 25862, + 0, + 0, + 0, + 25863, + 25865, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 25867, + 25868, + 0, + 25869, + 25874, + 0, + 25875, + 0, + 25876, + 25877, + 0, + 0, + 0, + 0, + 25878, + 25902, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 25903, + 25904, + 25905, + 0, + 0, + 0, + 25908, + 25909, + 0, + 0, + 0, + 0, + 25910, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 25912, + 0, + 25913, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 25914, + 0, + 0, + 25916, + 0, + 0, + 0, + 0, + 0, + 25917, + 25927, + 0, + 0, + 0, + 0, + 25928, + 0, + 0, + 25930, + 0, + 0, + 0, + 25933, + 0, + 0, + 25938, + 25942, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 25945, + 0, + 25950, + 0, + 25956, + 0, + 0, + 25961, + 25962, + 0, + 0, + 25963, + 0, + 25964, + 25965, + 25966, + 0, + 0, + 0, + 0, + 0, + 25967, + 0, + 0, + 0, + 0, + 25968, + 0, + 0, + 0, + 25969, + 25971, + 0, + 0, + 0, + 0, + 0, + 25973, + 25975, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 25978, + 0, + 25981, + 0, + 0, + 0, + 25982, + 0, + 0, + 0, + 25984, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 25993, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 26002, + 0, + 0, + 0, + 26005, + 0, + 0, + 0, + 26006, + 26007, + 0, + 0, + 26014, + 26015, + 26016, + 0, + 0, + 0, + 0, + 0, + 0, + 26017, + 26018, + 26020, + 0, + 26022, + 26023, + 0, + 0, + 0, + 26024, + 26028, + 0, + 26029, + 26033, + 26034, + 26044, + 0, + 0, + 0, + 0, + 0, + 26046, + 0, + 0, + 26047, + 0, + 0, + 26049, + 0, + 26050, + 0, + 26051, + 0, + 0, + 0, + 0, + 0, + 26053, + 0, + 0, + 0, + 0, + 26054, + 26059, + 0, + 0, + 0, + 0, + 0, + 0, + 26060, + 0, + 26066, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 26067, + 0, + 26069, + 0, + 0, + 26071, + 0, + 0, + 0, + 26073, + 0, + 26074, + 26077, + 0, + 0, + 0, + 0, + 26078, + 0, + 0, + 0, + 26079, + 0, + 26090, + 0, + 0, + 26094, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 26095, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 26096, + 26101, + 0, + 26107, + 26122, + 0, + 26124, + 0, + 0, + 26125, + 0, + 0, + 0, + 0, + 0, + 0, + 26136, + 26141, + 26155, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 26164, + 26166, + 0, + 0, + 0, + 26167, + 0, + 26170, + 26171, + 0, + 0, + 26172, + 0, + 0, + 26174, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 26175, + 0, + 0, + 0, + 26176, + 26177, + 0, + 26321, + 26322, + 0, + 26323, + 0, + 0, + 26324, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 26325, + 0, + 26331, + 0, + 0, + 0, + 0, + 0, + 0, + 26335, + 0, + 0, + 0, + 26350, + 0, + 0, + 0, + 26379, + 0, + 0, + 26382, + 26383, + 26385, + 0, + 0, + 26392, + 26406, + 0, + 0, + 0, + 0, + 26411, + 0, + 0, + 0, + 0, + 0, + 26412, + 0, + 0, + 26420, + 0, + 0, + 26423, + 0, + 26424, + 26426, + 26432, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 26435, + 0, + 26436, + 0, + 0, + 0, + 0, + 0, + 26441, + 0, + 26444, + 0, + 0, + 0, + 26446, + 0, + 0, + 0, + 0, + 26447, + 0, + 0, + 0, + 0, + 26449, + 0, + 26450, + 26452, + 0, + 26453, + 26454, + 0, + 0, + 0, + 26455, + 0, + 0, + 0, + 26456, + 0, + 0, + 26458, + 0, + 0, + 26460, + 0, + 26463, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 26464, + 26470, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 26473, + 0, + 0, + 26474, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 26475, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 26477, + 0, + 26485, + 0, + 0, + 26486, + 0, + 26487, + 0, + 0, + 26488, + 26493, + 26494, + 0, + 0, + 26495, + 0, + 26497, + 26504, + 26506, + 0, + 0, + 0, + 0, + 0, + 26507, + 0, + 0, + 0, + 0, + 0, + 26509, + 0, + 0, + 26510, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 26512, + 0, + 26513, + 26515, + 0, + 0, + 0, + 26518, + 0, + 0, + 0, + 26519, + 0, + 26524, + 26526, + 0, + 0, + 0, + 26527, + 0, + 26532, + 0, + 26533, + 26537, + 26558, + 0, + 0, + 0, + 26559, + 0, + 0, + 0, + 26571, + 0, + 0, + 26573, + 0, + 26588, + 0, + 26593, + 0, + 0, + 0, + 0, + 0, + 0, + 26603, + 0, + 26604, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 26606, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 26607, + 26609, + 26611, + 26614, + 0, + 0, + 0, + 26616, + 26620, + 0, + 26621, + 0, + 0, + 0, + 0, + 0, + 26627, + 0, + 26629, + 0, + 0, + 26630, + 0, + 0, + 26632, + 26643, + 0, + 0, + 0, + 26644, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 26646, + 26647, + 0, + 0, + 0, + 26650, + 0, + 0, + 26656, + 0, + 0, + 0, + 0, + 26663, + 26670, + 26671, + 0, + 0, + 0, + 26685, + 26686, + 26687, + 0, + 26689, + 0, + 0, + 0, + 0, + 26744, + 0, + 26745, + 0, + 26747, + 26748, + 0, + 26749, + 26750, + 26751, + 0, + 0, + 0, + 0, + 26752, + 26755, + 0, + 0, + 0, + 26756, + 26769, + 0, + 0, + 0, + 26774, + 0, + 0, + 0, + 0, + 0, + 26775, + 0, + 26777, + 26778, + 0, + 26786, + 0, + 0, + 0, + 26787, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 26788, + 0, + 0, + 26789, + 0, + 0, + 0, + 0, + 0, + 26791, + 0, + 26792, + 26793, + 0, + 0, + 0, + 26794, + 0, + 26797, + 26798, + 0, + 0, + 0, + 26800, + 0, + 0, + 26803, + 0, + 26804, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 26805, + 0, + 0, + 26808, + 0, + 0, + 26809, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 26812, + 0, + 26825, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 26826, + 0, + 0, + 26827, + 26829, + 26834, + 0, + 0, + 0, + 0, + 26835, + 0, + 0, + 26849, + 0, + 26851, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 26852, + 0, + 26853, + 26857, + 0, + 26858, + 0, + 26859, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 26876, + 0, + 26878, + 26882, + 26883, + 0, + 0, + 0, + 0, + 26890, + 26894, + 0, + 0, + 0, + 0, + 26895, + 26896, + 0, + 0, + 0, + 0, + 0, + 26900, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 26911, + 26913, + 26914, + 26915, + 26916, + 26919, + 0, + 0, + 0, + 26921, + 26922, + 0, + 0, + 26925, + 0, + 0, + 0, + 26928, + 0, + 0, + 26929, + 26930, + 0, + 0, + 0, + 26931, + 0, + 26932, + 0, + 0, + 0, + 0, + 0, + 26933, + 0, + 0, + 0, + 0, + 0, + 0, + 26937, + 0, + 0, + 26943, + 0, + 0, + 26944, + 0, + 0, + 0, + 26946, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 26956, + 0, + 26958, + 0, + 0, + 26963, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 26965, + 0, + 26969, + 26970, + 26972, + 0, + 0, + 0, + 0, + 0, + 26973, + 0, + 26974, + 0, + 26978, + 0, + 26980, + 0, + 0, + 0, + 0, + 0, + 0, + 26982, + 0, + 26986, + 26987, + 0, + 26990, + 0, + 0, + 0, + 0, + 27003, + 27006, + 0, + 0, + 27007, + 27010, + 27012, + 27013, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 27014, + 27015, + 27018, + 0, + 27019, + 0, + 0, + 0, + 0, + 0, + 27025, + 0, + 0, + 0, + 27026, + 0, + 0, + 0, + 0, + 27029, + 27030, + 27031, + 27034, + 0, + 0, + 27036, + 27037, + 0, + 0, + 0, + 27038, + 27042, + 0, + 0, + 0, + 27044, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 27045, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 27046, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 27047, + 27049, + 0, + 27050, + 0, + 0, + 0, + 27051, + 27052, + 0, + 27055, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 27056, + 27058, + 27059, + 0, + 27061, + 0, + 27064, + 0, + 0, + 0, + 0, + 0, + 27069, + 0, + 0, + 27070, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 27072, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 27076, + 0, + 0, + 0, + 0, + 0, + 27078, + 0, + 27079, + 0, + 0, + 0, + 27081, + 0, + 0, + 0, + 0, + 0, + 0, + 27082, + 0, + 27083, + 27086, + 0, + 0, + 0, + 0, + 27087, + 0, + 0, + 0, + 0, + 0, + 27088, + 27090, + 0, + 27094, + 0, + 0, + 27095, + 0, + 27099, + 27102, + 0, + 0, + 0, + 27103, + 0, + 0, + 0, + 0, + 27105, + 0, + 0, + 0, + 27106, + 0, + 0, + 0, + 0, + 0, + 0, + 27107, + 0, + 0, + 0, + 0, + 27108, + 27117, + 0, + 0, + 0, + 0, + 27118, + 0, + 0, + 27124, + 0, + 27126, + 0, + 0, + 27130, + 27131, + 0, + 0, + 0, + 0, + 0, + 0, + 27147, + 0, + 0, + 0, + 0, + 27148, + 27149, + 0, + 0, + 0, + 0, + 27150, + 27151, + 0, + 27152, + 0, + 27159, + 0, + 0, + 0, + 27164, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 27175, + 0, + 27189, + 0, + 0, + 27191, + 0, + 27193, + 0, + 27195, + 0, + 27198, + 0, + 0, + 0, + 0, + 0, + 27200, + 0, + 0, + 0, + 0, + 27202, + 0, + 0, + 0, + 0, + 27203, + 0, + 0, + 27204, + 0, + 0, + 27206, + 0, + 27207, + 0, + 0, + 0, + 0, + 27209, + 0, + 0, + 0, + 27213, + 0, + 0, + 27216, + 27219, + 27220, + 27222, + 27223, + 0, + 27224, + 0, + 27225, + 27226, + 0, + 0, + 27233, + 0, + 0, + 0, + 0, + 27235, + 0, + 27237, + 0, + 27238, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 27239, + 0, + 27242, + 27243, + 0, + 27250, + 0, + 0, + 0, + 27251, + 0, + 27253, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 27254, + 27255, + 27258, + 0, + 0, + 0, + 27259, + 0, + 0, + 0, + 0, + 0, + 0, + 27267, + 0, + 27276, + 27278, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 27296, + 27297, + 27301, + 0, + 0, + 0, + 0, + 0, + 0, + 27302, + 0, + 0, + 0, + 0, + 0, + 0, + 27312, + 27313, + 0, + 0, + 0, + 0, + 0, + 27318, + 0, + 27320, + 0, + 27329, + 0, + 27330, + 27331, + 0, + 27332, + 0, + 0, + 0, + 0, + 27340, + 0, + 0, + 0, + 27348, + 0, + 0, + 0, + 0, + 0, + 0, + 27350, + 0, + 27351, + 0, + 0, + 0, + 0, + 27355, + 0, + 0, + 27358, + 27359, + 27361, + 0, + 0, + 0, + 27365, + 0, + 27367, + 0, + 27376, + 27378, + 0, + 0, + 27379, + 0, + 0, + 0, + 0, + 0, + 0, + 27396, + 0, + 27397, + 27404, + 0, + 0, + 0, + 0, + 0, + 27408, + 0, + 0, + 0, + 0, + 27453, + 0, + 0, + 0, + 27456, + 0, + 0, + 0, + 27458, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 27459, + 0, + 0, + 0, + 27460, + 0, + 0, + 27461, + 0, + 27465, + 27467, + 0, + 0, + 27469, + 0, + 27470, + 0, + 27471, + 0, + 27477, + 27482, + 0, + 0, + 0, + 0, + 0, + 0, + 27484, + 0, + 0, + 0, + 0, + 0, + 0, + 27485, + 0, + 0, + 0, + 0, + 0, + 27493, + 0, + 27494, + 27502, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 27511, + 27532, + 0, + 0, + 0, + 27533, + 27545, + 0, + 0, + 0, + 27546, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 27547, + 0, + 0, + 27549, + 27550, + 0, + 27551, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 27555, + 0, + 0, + 27571, + 0, + 27573, + 27574, + 27575, + 27577, + 0, + 27578, + 0, + 0, + 27579, + 27585, + 0, + 0, + 0, + 0, + 0, + 27586, + 0, + 0, + 27588, + 27589, + 0, + 0, + 0, + 0, + 27596, + 0, + 0, + 27600, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 27608, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 27610, + 0, + 0, + 0, + 27618, + 0, + 0, + 27620, + 0, + 0, + 0, + 27631, + 0, + 0, + 27632, + 27634, + 0, + 27636, + 27638, + 0, + 0, + 0, + 27643, + 0, + 27644, + 27649, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 27651, + 27660, + 0, + 27661, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 27662, + 0, + 0, + 27664, + 0, + 27665, + 0, + 0, + 0, + 27669, + 0, + 27671, + 0, + 0, + 0, + 27673, + 27674, + 0, + 0, + 0, + 27682, + 0, + 0, + 0, + 27711, + 0, + 27712, + 27713, + 27719, + 27720, + 0, + 0, + 27728, + 0, + 27729, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 27731, + 0, + 0, + 27732, + 0, + 27733, + 0, + 27738, + 0, + 0, + 0, + 27742, + 0, + 0, + 0, + 27743, + 27744, + 0, + 0, + 0, + 0, + 0, + 0, + 27745, + 27746, + 0, + 0, + 0, + 27747, + 27748, + 27751, + 27752, + 0, + 0, + 0, + 27768, + 27770, + 0, + 0, + 0, + 27774, + 27775, + 0, + 27776, + 27777, + 0, + 0, + 27781, + 0, + 27784, + 0, + 27786, + 0, + 0, + 27791, + 0, + 27792, + 27793, + 27804, + 0, + 27812, + 27813, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 27814, + 0, + 27825, + 0, + 27827, + 0, + 0, + 0, + 0, + 27828, + 27861, + 27862, + 0, + 0, + 0, + 27864, + 0, + 0, + 0, + 27865, + 27884, + 0, + 27889, + 0, + 0, + 0, + 0, + 0, + 27890, + 0, + 27891, + 0, + 0, + 0, + 27892, + 0, + 0, + 0, + 0, + 0, + 27897, + 27898, + 0, + 0, + 27899, + 0, + 0, + 0, + 27901, + 27905, + 0, + 0, + 27920, + 0, + 0, + 27921, + 0, + 27922, + 0, + 0, + 0, + 27931, + 27934, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 27941, + 0, + 27942, + 0, + 27945, + 0, + 27947, + 27954, + 0, + 0, + 0, + 0, + 27960, + 27963, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 27964, + 27965, + 0, + 0, + 0, + 27967, + 0, + 27969, + 27975, + 0, + 27976, + 27977, + 0, + 27981, + 0, + 27983, + 28051, + 28052, + 0, + 0, + 0, + 0, + 0, + 28056, + 0, + 0, + 0, + 0, + 0, + 0, + 28058, + 28059, + 0, + 0, + 28061, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 28063, + 0, + 0, + 0, + 0, + 0, + 0, + 28066, + 0, + 0, + 0, + 0, + 0, + 0, + 28069, + 28070, + 28072, + 0, + 28073, + 0, + 0, + 28074, + 0, + 0, + 0, + 0, + 28075, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 28078, + 0, + 0, + 0, + 0, + 28085, + 0, + 0, + 0, + 0, + 28086, + 0, + 0, + 0, + 0, + 0, + 0, + 28088, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 28090, + 0, + 28097, + 28114, + 28115, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 28116, + 0, + 0, + 0, + 0, + 0, + 28118, + 0, + 28129, + 0, + 28131, + 0, + 0, + 28135, + 0, + 0, + 0, + 28140, + 28141, + 0, + 0, + 0, + 28146, + 0, + 0, + 0, + 0, + 28152, + 0, + 0, + 0, + 0, + 28155, + 28157, + 28161, + 0, + 0, + 0, + 0, + 28166, + 0, + 28167, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 28172, + 0, + 0, + 0, + 0, + 0, + 0, + 28173, + 0, + 0, + 28175, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 28178, + 28188, + 0, + 28190, + 0, + 0, + 0, + 0, + 0, + 28191, + 0, + 28193, + 28206, + 0, + 0, + 28207, + 28209, + 0, + 28211, + 0, + 28213, + 0, + 0, + 0, + 28215, + 28216, + 28217, + 0, + 28222, + 0, + 28223, + 28225, + 0, + 0, + 0, + 28226, + 0, + 28227, + 28229, + 28232, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 28235, + 0, + 28241, + 0, + 0, + 28242, + 0, + 0, + 0, + 0, + 28243, + 0, + 0, + 0, + 28245, + 0, + 0, + 0, + 28248, + 28250, + 0, + 28251, + 28252, + 0, + 0, + 0, + 0, + 0, + 0, + 28253, + 0, + 0, + 28254, + 28255, + 0, + 0, + 28256, + 0, + 0, + 28258, + 0, + 0, + 0, + 0, + 0, + 28259, + 0, + 0, + 28260, + 0, + 0, + 28261, + 0, + 0, + 0, + 0, + 28262, + 28263, + 0, + 0, + 28264, + 0, + 0, + 0, + 28266, + 0, + 28268, + 28269, + 0, + 28270, + 28272, + 28274, + 0, + 28277, + 28278, + 0, + 0, + 0, + 28279, + 0, + 28280, + 28281, + 28283, + 0, + 28292, + 0, + 28294, + 0, + 28297, + 0, + 0, + 0, + 0, + 28299, + 0, + 0, + 0, + 0, + 0, + 28300, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 28301, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 28302, + 28303, + 0, + 0, + 0, + 0, + 28304, + 0, + 0, + 28305, + 0, + 28312, + 0, + 28313, + 28314, + 0, + 0, + 0, + 0, + 0, + 0, + 28315, + 0, + 0, + 0, + 28320, + 28321, + 0, + 0, + 28328, + 0, + 0, + 0, + 28329, + 28338, + 0, + 28339, + 0, + 0, + 28344, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 28347, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 28348, + 0, + 0, + 0, + 0, + 0, + 28411, + 0, + 28412, + 28413, + 0, + 28416, + 0, + 0, + 0, + 28420, + 0, + 0, + 0, + 0, + 0, + 28421, + 0, + 0, + 0, + 0, + 28423, + 0, + 0, + 0, + 28424, + 0, + 0, + 28428, + 0, + 0, + 0, + 0, + 0, + 28429, + 0, + 0, + 0, + 28431, + 28434, + 0, + 28458, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 28464, + 0, + 0, + 0, + 0, + 28465, + 0, + 28467, + 0, + 0, + 0, + 0, + 0, + 0, + 28471, + 0, + 0, + 0, + 0, + 28474, + 0, + 28480, + 0, + 28481, + 0, + 0, + 28485, + 0, + 0, + 0, + 0, + 28486, + 28488, + 0, + 0, + 28489, + 0, + 0, + 0, + 0, + 28492, + 0, + 0, + 0, + 28495, + 0, + 28497, + 0, + 28499, + 0, + 0, + 0, + 0, + 28500, + 0, + 0, + 28502, + 28503, + 0, + 0, + 0, + 28508, + 0, + 0, + 0, + 28510, + 0, + 0, + 28512, + 28513, + 28514, + 28521, + 0, + 28526, + 0, + 28527, + 28528, + 0, + 0, + 0, + 0, + 28529, + 0, + 0, + 28532, + 0, + 0, + 28537, + 28538, + 0, + 0, + 0, + 28539, + 0, + 28548, + 0, + 28553, + 28554, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 28560, + 28563, + 0, + 0, + 28564, + 0, + 0, + 0, + 0, + 28565, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 28566, + 28568, + 0, + 0, + 0, + 0, + 0, + 0, + 28569, + 0, + 0, + 0, + 28570, + 0, + 28572, + 28573, + 0, + 0, + 0, + 0, + 28575, + 0, + 0, + 0, + 0, + 28576, + 28581, + 28588, + 0, + 0, + 28589, + 0, + 0, + 0, + 28590, + 28595, + 0, + 28598, + 0, + 0, + 28601, + 0, + 0, + 28605, + 0, + 0, + 0, + 0, + 28614, + 28615, + 28619, + 0, + 0, + 0, + 0, + 0, + 0, + 28620, + 0, + 28626, + 0, + 0, + 28628, + 0, + 28631, + 0, + 28632, + 0, + 0, + 0, + 0, + 0, + 0, + 28635, + 0, + 0, + 0, + 28637, + 28638, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 28639, + 0, + 28643, + 0, + 0, + 28652, + 0, + 0, + 0, + 28662, + 0, + 28670, + 28671, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 28672, + 28673, + 28675, + 28676, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 28691, + 0, + 0, + 0, + 28695, + 0, + 0, + 0, + 28696, + 0, + 28697, + 28698, + 0, + 28705, + 0, + 28707, + 28708, + 28710, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 28711, + 28728, + 0, + 0, + 0, + 28736, + 0, + 0, + 0, + 28737, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 28738, + 0, + 28739, + 0, + 28741, + 0, + 0, + 28742, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 28745, + 0, + 0, + 0, + 0, + 0, + 0, + 28749, + 28750, + 28752, + 28754, + 28756, + 0, + 28757, + 0, + 0, + 0, + 0, + 28759, + 28760, + 0, + 0, + 0, + 0, + 0, + 0, + 28762, + 0, + 0, + 0, + 28764, + 0, + 0, + 0, + 0, + 0, + 0, + 28766, + 0, + 28767, + 28768, + 0, + 0, + 0, + 0, + 28769, + 28770, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 28771, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 28772, + 0, + 28773, + 0, + 28782, + 0, + 0, + 0, + 0, + 0, + 0, + 28784, + 0, + 28785, + 0, + 28786, + 0, + 0, + 0, + 28787, + 0, + 0, + 0, + 28797, + 0, + 0, + 0, + 0, + 0, + 0, + 28799, + 0, + 0, + 28801, + 0, + 0, + 0, + 0, + 28802, + 0, + 28805, + 0, + 0, + 28806, + 0, + 0, + 28807, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 28808, + 0, + 0, + 0, + 0, + 0, + 28810, + 28812, + 0, + 0, + 28816, + 28819, + 0, + 0, + 28821, + 0, + 28826, + 0, + 0, + 0, + 28842, + 28852, + 0, + 0, + 28853, + 0, + 28854, + 28855, + 0, + 0, + 0, + 28857, + 0, + 0, + 0, + 28858, + 0, + 28867, + 28868, + 28869, + 0, + 0, + 0, + 28874, + 28880, + 28882, + 28890, + 28892, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 28895, + 0, + 0, + 0, + 28898, + 28899, + 0, + 0, + 0, + 28900, + 0, + 0, + 28904, + 0, + 28906, + 0, + 0, + 0, + 0, + 28907, + 0, + 0, + 0, + 0, + 0, + 0, + 28908, + 0, + 0, + 0, + 28910, + 0, + 28914, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 28915, + 28916, + 28919, + 0, + 0, + 28920, + 0, + 28921, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 28924, + 0, + 0, + 0, + 0, + 28926, + 28929, + 0, + 0, + 0, + 28930, + 0, + 28936, + 0, + 28939, + 0, + 0, + 0, + 0, + 28942, + 0, + 0, + 0, + 0, + 0, + 0, + 28956, + 0, + 0, + 0, + 28966, + 0, + 0, + 0, + 0, + 28967, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 28968, + 0, + 28971, + 0, + 28975, + 28976, + 0, + 28982, + 28983, + 0, + 0, + 28984, + 28989, + 28996, + 28997, + 28998, + 0, + 0, + 0, + 0, + 0, + 0, + 28999, + 0, + 0, + 0, + 0, + 0, + 29000, + 0, + 29001, + 0, + 0, + 0, + 29009, + 0, + 0, + 29011, + 0, + 0, + 29021, + 0, + 0, + 0, + 0, + 29024, + 0, + 29025, + 0, + 0, + 0, + 0, + 0, + 29026, + 0, + 0, + 0, + 29036, + 0, + 0, + 0, + 29037, + 0, + 0, + 0, + 0, + 29038, + 0, + 29045, + 0, + 29047, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 29051, + 0, + 0, + 0, + 29054, + 29056, + 29062, + 0, + 29070, + 29082, + 0, + 0, + 0, + 29083, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 29084, + 0, + 0, + 0, + 0, + 29085, + 29088, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 29090, + 29097, + 0, + 0, + 0, + 29103, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 29105, + 0, + 0, + 0, + 0, + 0, + 29107, + 0, + 29109, + 0, + 0, + 0, + 29115, + 0, + 0, + 29120, + 0, + 0, + 29138, + 29140, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 29152, + 0, + 29160, + 29174, + 0, + 29176, + 0, + 0, + 29180, + 0, + 29181, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 29228, + 0, + 0, + 29229, + 0, + 0, + 29230, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 29234, + 0, + 0, + 0, + 29241, + 0, + 29245, + 0, + 29248, + 0, + 29250, + 29256, + 29280, + 0, + 29282, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 29285, + 0, + 0, + 29286, + 29291, + 29292, + 0, + 0, + 0, + 0, + 29294, + 0, + 29295, + 0, + 0, + 0, + 0, + 0, + 29296, + 29297, + 29298, + 29300, + 0, + 29302, + 0, + 0, + 29304, + 29307, + 0, + 29312, + 0, + 0, + 0, + 29322, + 0, + 0, + 29323, + 0, + 0, + 29324, + 29326, + 29328, + 0, + 29335, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 29338, + 29339, + 0, + 0, + 0, + 0, + 0, + 29341, + 29343, + 0, + 0, + 0, + 0, + 29344, + 0, + 0, + 0, + 0, + 0, + 29345, + 0, + 0, + 0, + 0, + 29346, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 29347, + 29348, + 29349, + 0, + 0, + 29354, + 0, + 0, + 29355, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 29357, + 0, + 0, + 0, + 0, + 29364, + 0, + 29365, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 29366, + 0, + 0, + 29368, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 29378, + 0, + 29381, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 29386, + 0, + 0, + 0, + 0, + 0, + 0, + 29389, + 0, + 0, + 0, + 29390, + 0, + 0, + 29391, + 29397, + 0, + 29398, + 29412, + 29414, + 29418, + 29419, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 29420, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 29423, + 0, + 0, + 0, + 29435, + 0, + 0, + 0, + 29437, + 0, + 0, + 29439, + 0, + 29441, + 0, + 0, + 0, + 0, + 29443, + 0, + 29446, + 29450, + 29452, + 0, + 0, + 0, + 0, + 0, + 29456, + 0, + 0, + 0, + 0, + 0, + 29461, + 0, + 0, + 0, + 29464, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 29468, + 0, + 29473, + 0, + 0, + 0, + 29486, + 0, + 0, + 0, + 29490, + 0, + 0, + 0, + 29491, + 29492, + 0, + 0, + 29497, + 0, + 0, + 0, + 29498, + 0, + 29499, + 0, + 29502, + 29505, + 0, + 29509, + 0, + 0, + 0, + 29510, + 0, + 0, + 0, + 29512, + 0, + 0, + 0, + 29516, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 29518, + 0, + 29519, + 0, + 0, + 0, + 0, + 0, + 29520, + 29521, + 29529, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 29530, + 0, + 0, + 29531, + 29538, + 0, + 29540, + 0, + 0, + 0, + 29542, + 0, + 29543, + 29544, + 29547, + 0, + 0, + 29548, + 0, + 0, + 0, + 29549, + 0, + 0, + 0, + 29550, + 0, + 0, + 29552, + 0, + 0, + 0, + 0, + 29558, + 29561, + 0, + 29562, + 29564, + 0, + 0, + 29565, + 0, + 0, + 29566, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 29578, + 29584, + 29586, + 29591, + 0, + 0, + 0, + 0, + 29593, + 29594, + 0, + 0, + 29597, + 0, + 0, + 29613, + 0, + 29614, + 0, + 29615, + 0, + 0, + 0, + 0, + 29616, + 29617, + 0, + 0, + 29625, + 0, + 0, + 0, + 29632, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 29633, + 0, + 0, + 0, + 0, + 0, + 29634, + 29635, + 29637, + 0, + 29638, + 0, + 29641, + 29643, + 0, + 0, + 0, + 0, + 0, + 0, + 29644, + 0, + 29645, + 0, + 29649, + 0, + 0, + 0, + 29650, + 0, + 29653, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 29656, + 29659, + 0, + 0, + 29660, + 0, + 0, + 0, + 29661, + 0, + 0, + 0, + 0, + 0, + 29664, + 0, + 0, + 0, + 29671, + 29673, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 29675, + 0, + 29677, + 29679, + 0, + 0, + 29684, + 0, + 0, + 0, + 0, + 0, + 29685, + 0, + 0, + 0, + 29687, + 0, + 0, + 0, + 29688, + 0, + 29689, + 29690, + 29700, + 0, + 29701, + 0, + 0, + 0, + 29702, + 0, + 29706, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 29720, + 0, + 29721, + 0, + 29727, + 0, + 29733, + 29734, + 0, + 29750, + 29761, + 0, + 29763, + 0, + 0, + 0, + 0, + 0, + 29764, + 0, + 0, + 29765, + 0, + 0, + 0, + 29771, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 29772, + 0, + 0, + 0, + 29773, + 29774, + 29775, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 29822, + 0, + 0, + 0, + 29824, + 0, + 29825, + 0, + 0, + 0, + 0, + 0, + 29827, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 29829, + 0, + 29832, + 29834, + 0, + 0, + 29835, + 0, + 0, + 29837, + 29838, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 29843, + 0, + 0, + 0, + 0, + 29844, + 29845, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 29849, + 0, + 0, + 29869, + 29872, + 29890, + 29905, + 0, + 0, + 0, + 0, + 0, + 29907, + 29921, + 0, + 29922, + 0, + 0, + 29923, + 29926, + 29944, + 29946, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 29947, + 29948, + 0, + 0, + 0, + 29951, + 0, + 0, + 0, + 0, + 0, + 29953, + 0, + 0, + 29956, + 0, + 29957, + 0, + 0, + 29962, + 0, + 0, + 0, + 0, + 29971, + 0, + 0, + 0, + 29972, + 0, + 0, + 0, + 0, + 0, + 29978, + 0, + 29979, + 29992, + 30007, + 30008, + 30010, + 0, + 0, + 0, + 30013, + 0, + 0, + 0, + 0, + 30014, + 30016, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 30017, + 0, + 0, + 0, + 0, + 0, + 30023, + 30031, + 0, + 0, + 30033, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 30034, + 0, + 30038, + 0, + 30039, + 0, + 30040, + 0, + 0, + 0, + 0, + 0, + 0, + 30067, + 30068, + 0, + 0, + 0, + 30069, + 0, + 30072, + 0, + 0, + 0, + 30073, + 0, + 0, + 0, + 0, + 30075, + 0, + 0, + 0, + 0, + 0, + 0, + 30079, + 0, + 0, + 30080, + 0, + 0, + 0, + 0, + 0, + 30082, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 30084, + 30090, + 0, + 0, + 30091, + 0, + 0, + 0, + 0, + 30098, + 30118, + 0, + 30119, + 0, + 30121, + 30130, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 30131, + 30132, + 30133, + 0, + 0, + 0, + 0, + 0, + 0, + 30135, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 30136, + 0, + 0, + 30137, + 30138, + 0, + 0, + 0, + 30139, + 30146, + 0, + 0, + 0, + 0, + 0, + 30147, + 0, + 0, + 30148, + 30151, + 0, + 0, + 0, + 30168, + 0, + 30172, + 30173, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 30180, + 30181, + 0, + 30192, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 30194, + 30196, + 0, + 0, + 30199, + 0, + 0, + 30202, + 0, + 0, + 0, + 0, + 30203, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 30213, + 0, + 0, + 0, + 30216, + 0, + 0, + 30217, + 0, + 0, + 0, + 30218, + 0, + 0, + 0, + 0, + 30219, + 0, + 30220, + 0, + 30222, + 30227, + 0, + 0, + 0, + 0, + 0, + 30231, + 0, + 0, + 30233, + 30235, + 0, + 0, + 0, + 0, + 30238, + 0, + 30240, + 30243, + 30245, + 0, + 30250, + 30252, + 0, + 0, + 0, + 30269, + 0, + 0, + 30271, + 30272, + 0, + 0, + 0, + 30278, + 30280, + 0, + 0, + 30282, + 0, + 30284, + 0, + 30294, + 0, + 0, + 0, + 0, + 30295, + 30296, + 0, + 0, + 0, + 0, + 0, + 30298, + 30299, + 30302, + 30304, + 30306, + 0, + 0, + 0, + 0, + 0, + 0, + 30316, + 30317, + 0, + 0, + 0, + 30318, + 0, + 0, + 0, + 30319, + 0, + 30320, + 30322, + 30326, + 0, + 0, + 0, + 0, + 0, + 30327, + 0, + 30332, + 30348, + 30349, + 0, + 0, + 30356, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 30357, + 0, + 30358, + 0, + 30359, + 30360, + 0, + 0, + 30365, + 30366, + 30378, + 0, + 0, + 0, + 0, + 30379, + 0, + 0, + 30381, + 0, + 30385, + 0, + 30388, + 30397, + 0, + 0, + 0, + 30401, + 0, + 0, + 0, + 0, + 30403, + 0, + 0, + 0, + 0, + 0, + 30404, + 0, + 0, + 30405, + 0, + 30406, + 30408, + 0, + 30409, + 0, + 30410, + 0, + 0, + 0, + 30417, + 0, + 0, + 30418, + 30419, + 0, + 30420, + 0, + 30424, + 0, + 0, + 0, + 30427, + 30430, + 30432, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 30433, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 30436, + 0, + 30437, + 30438, + 0, + 30441, + 30442, + 0, + 0, + 0, + 30445, + 0, + 0, + 0, + 0, + 30452, + 30456, + 30457, + 0, + 0, + 0, + 30458, + 0, + 30464, + 0, + 0, + 0, + 0, + 0, + 0, + 30467, + 0, + 30469, + 0, + 0, + 0, + 0, + 0, + 30477, + 0, + 0, + 30484, + 0, + 0, + 0, + 0, + 0, + 30485, + 0, + 0, + 0, + 0, + 0, + 30486, + 30487, + 30497, + 30498, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 30505, + 0, + 30508, + 0, + 0, + 0, + 30509, + 30510, + 0, + 30514, + 30516, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 30523, + 0, + 30524, + 0, + 30525, + 0, + 0, + 0, + 0, + 30537, + 0, + 0, + 30538, + 0, + 0, + 0, + 0, + 0, + 30553, + 0, + 0, + 30555, + 30556, + 30558, + 30559, + 30560, + 0, + 0, + 30561, + 0, + 30562, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 30563, + 30570, + 30571, + 0, + 30586, + 30587, + 0, + 0, + 30590, + 0, + 0, + 30594, + 0, + 0, + 0, + 0, + 30611, + 30612, + 30623, + 30634, + 0, + 0, + 30636, + 30640, + 30655, + 30656, + 0, + 30657, + 0, + 0, + 30658, + 30669, + 0, + 30670, + 0, + 30676, + 30678, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 30679, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 30695, + 0, + 0, + 30698, + 0, + 0, + 0, + 0, + 30700, + 0, + 0, + 0, + 0, + 30701, + 0, + 30702, + 30703, + 0, + 0, + 0, + 0, + 30707, + 0, + 0, + 0, + 30709, + 0, + 0, + 30710, + 30719, + 30729, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 30731, + 0, + 0, + 30733, + 0, + 0, + 0, + 30734, + 0, + 0, + 0, + 0, + 0, + 30736, + 30737, + 0, + 0, + 0, + 30740, + 0, + 0, + 0, + 30743, + 0, + 30746, + 0, + 30747, + 30748, + 0, + 0, + 30751, + 30752, + 30753, + 0, + 0, + 0, + 30754, + 0, + 0, + 30760, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 30763, + 0, + 30764, + 0, + 0, + 30766, + 0, + 30769, + 30770, + 30771, + 30774, + 30777, + 0, + 0, + 30779, + 30780, + 30781, + 0, + 0, + 0, + 0, + 30790, + 0, + 0, + 0, + 30792, + 0, + 0, + 0, + 0, + 30810, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 30812, + 30819, + 0, + 0, + 30823, + 30824, + 0, + 30825, + 0, + 30827, + 0, + 0, + 0, + 0, + 0, + 0, + 30828, + 0, + 0, + 30830, + 0, + 0, + 0, + 30834, + 0, + 30835, + 0, + 30837, + 30838, + 0, + 30845, + 0, + 0, + 0, + 0, + 0, + 30846, + 30847, + 0, + 0, + 30849, + 0, + 30851, + 0, + 0, + 0, + 0, + 0, + 30852, + 30858, + 0, + 0, + 30859, + 0, + 30865, + 0, + 0, + 30866, + 0, + 0, + 30868, + 0, + 0, + 30869, + 0, + 0, + 0, + 30881, + 30883, + 0, + 0, + 0, + 0, + 0, + 30889, + 0, + 30891, + 0, + 0, + 0, + 0, + 30894, + 0, + 30895, + 0, + 30897, + 0, + 30898, + 0, + 0, + 0, + 30904, + 30906, + 0, + 30909, + 0, + 0, + 0, + 0, + 0, + 0, + 30910, + 0, + 0, + 0, + 30915, + 30933, + 30942, + 0, + 0, + 0, + 0, + 30943, + 0, + 0, + 30945, + 0, + 0, + 0, + 0, + 0, + 0, + 30946, + 0, + 0, + 30947, + 0, + 0, + 30955, + 30956, + 0, + 0, + 30960, + 0, + 0, + 30961, + 30962, + 30966, + 0, + 0, + 30969, + 30974, + 0, + 0, + 0, + 30976, + 0, + 0, + 30977, + 0, + 30978, + 30982, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 30994, + 30995, + 30998, + 0, + 31000, + 0, + 0, + 31001, + 0, + 0, + 31003, + 31005, + 0, + 0, + 31006, + 31011, + 0, + 0, + 31014, + 0, + 31016, + 0, + 0, + 0, + 0, + 31018, + 0, + 0, + 31020, + 31023, + 31024, + 31025, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 31027, + 31028, + 31029, + 0, + 0, + 0, + 0, + 0, + 0, + 31032, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 31036, + 31037, + 31038, + 0, + 0, + 0, + 31041, + 31043, + 31045, + 0, + 31047, + 0, + 0, + 0, + 31048, + 0, + 31049, + 0, + 0, + 0, + 31053, + 31054, + 31055, + 0, + 0, + 31063, + 0, + 0, + 0, + 0, + 0, + 31066, + 0, + 31068, + 31071, + 0, + 0, + 0, + 31072, + 31073, + 0, + 0, + 0, + 0, + 31075, + 0, + 0, + 31076, + 0, + 0, + 0, + 31077, + 31079, + 0, + 31080, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 31087, + 0, + 31142, + 0, + 31144, + 0, + 0, + 31145, + 31146, + 31147, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 31149, + 0, + 31151, + 31152, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 31162, + 31171, + 31174, + 31175, + 0, + 0, + 0, + 31176, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 31179, + 0, + 0, + 0, + 31186, + 0, + 0, + 0, + 31192, + 31195, + 0, + 0, + 31196, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 31198, + 0, + 0, + 0, + 0, + 0, + 31199, + 0, + 0, + 0, + 31205, + 0, + 0, + 0, + 0, + 31211, + 31215, + 0, + 0, + 0, + 0, + 31231, + 0, + 31232, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 31233, + 31236, + 31253, + 0, + 31254, + 0, + 0, + 0, + 0, + 0, + 0, + 31255, + 0, + 0, + 31257, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 31258, + 31259, + 0, + 0, + 31260, + 0, + 31261, + 0, + 0, + 0, + 0, + 0, + 31262, + 31263, + 0, + 0, + 31264, + 0, + 31266, + 0, + 31267, + 0, + 0, + 0, + 0, + 0, + 31281, + 0, + 31282, + 0, + 31284, + 0, + 0, + 31285, + 31287, + 31288, + 0, + 0, + 31290, + 0, + 0, + 0, + 31292, + 31295, + 0, + 31299, + 0, + 31300, + 0, + 0, + 0, + 0, + 0, + 31302, + 0, + 0, + 0, + 0, + 31303, + 0, + 0, + 0, + 0, + 0, + 0, + 31304, + 0, + 0, + 0, + 0, + 0, + 31305, + 31308, + 31309, + 31315, + 0, + 31317, + 0, + 0, + 0, + 0, + 0, + 31323, + 0, + 31324, + 0, + 0, + 0, + 0, + 0, + 31325, + 31327, + 0, + 0, + 31331, + 0, + 0, + 0, + 0, + 0, + 31333, + 0, + 0, + 0, + 0, + 0, + 31336, + 0, + 0, + 31337, + 0, + 0, + 0, + 0, + 0, + 0, + 31338, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 31339, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 31342, + 0, + 0, + 0, + 0, + 31345, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 31347, + 0, + 0, + 0, + 0, + 0, + 0, + 31348, + 0, + 0, + 31350, + 31351, + 0, + 31352, + 0, + 0, + 31354, + 0, + 0, + 0, + 0, + 31355, + 0, + 0, + 31356, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 31363, + 0, + 31372, + 0, + 0, + 31373, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 31376, + 0, + 31388, + 0, + 31389, + 0, + 31392, + 0, + 31401, + 0, + 31405, + 31407, + 31408, + 0, + 31409, + 0, + 0, + 0, + 0, + 0, + 0, + 31413, + 31415, + 0, + 0, + 0, + 31416, + 31418, + 0, + 0, + 0, + 0, + 0, + 0, + 31422, + 31423, + 0, + 0, + 31424, + 0, + 31425, + 31432, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 31433, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 31434, + 0, + 0, + 0, + 0, + 0, + 0, + 31435, + 0, + 0, + 0, + 0, + 31438, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 31442, + 0, + 31444, + 0, + 31448, + 0, + 0, + 31451, + 0, + 0, + 0, + 0, + 31452, + 0, + 31461, + 31465, + 0, + 0, + 31466, + 0, + 0, + 31467, + 0, + 0, + 31468, + 0, + 0, + 0, + 31469, + 31473, + 0, + 31476, + 0, + 0, + 0, + 0, + 31489, + 31490, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 31492, + 31493, + 31494, + 0, + 0, + 0, + 0, + 31501, + 31504, + 31505, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 31509, + 0, + 0, + 0, + 0, + 31510, + 0, + 0, + 31511, + 0, + 0, + 31513, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 31514, + 0, + 31522, + 31536, + 31539, + 31540, + 0, + 31541, + 0, + 0, + 0, + 0, + 0, + 0, + 31546, + 31553, + 31559, + 0, + 0, + 0, + 31560, + 31561, + 31562, + 0, + 0, + 31564, + 31567, + 0, + 31569, + 0, + 0, + 0, + 31570, + 0, + 0, + 0, + 0, + 31571, + 0, + 0, + 0, + 0, + 0, + 0, + 31572, + 31574, + 31580, + 31581, + 0, + 0, + 31582, + 31584, + 31585, + 31586, + 31595, + 0, + 31596, + 0, + 0, + 0, + 0, + 31597, + 0, + 31599, + 0, + 31600, + 31601, + 0, + 0, + 31603, + 31604, + 0, + 0, + 31608, + 31610, + 0, + 0, + 0, + 31611, + 0, + 31615, + 0, + 0, + 0, + 0, + 31616, + 0, + 0, + 0, + 0, + 0, + 0, + 31617, + 0, + 0, + 0, + 0, + 0, + 31618, + 0, + 0, + 0, + 0, + 0, + 0, + 31621, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 31622, + 31625, + 0, + 0, + 0, + 0, + 31627, + 0, + 31641, + 0, + 0, + 31642, + 0, + 0, + 31643, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 31644, + 0, + 31646, + 0, + 0, + 0, + 0, + 31648, + 0, + 0, + 0, + 31652, + 0, + 0, + 0, + 31657, + 0, + 0, + 31676, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 31689, + 31691, + 31692, + 0, + 31694, + 0, + 0, + 0, + 31696, + 0, + 31702, + 0, + 31703, + 0, +} + +var kStaticDictionaryWords = [31705]dictWord{ + dictWord{0, 0, 0}, + dictWord{8, 0, 1002}, + dictWord{136, 0, 1015}, + dictWord{4, 0, 683}, + dictWord{4, 10, 325}, + dictWord{138, 10, 125}, + dictWord{7, 11, 572}, + dictWord{ + 9, + 11, + 592, + }, + dictWord{11, 11, 680}, + dictWord{11, 11, 842}, + dictWord{11, 11, 924}, + dictWord{12, 11, 356}, + dictWord{12, 11, 550}, + dictWord{13, 11, 317}, + dictWord{13, 11, 370}, + dictWord{13, 11, 469}, + dictWord{13, 11, 471}, + dictWord{14, 11, 397}, + dictWord{18, 11, 69}, + dictWord{146, 11, 145}, + dictWord{ + 134, + 0, + 1265, + }, + dictWord{136, 11, 534}, + dictWord{134, 0, 1431}, + dictWord{11, 0, 138}, + dictWord{140, 0, 40}, + dictWord{4, 0, 155}, + dictWord{7, 0, 1689}, + dictWord{ + 4, + 10, + 718, + }, + dictWord{135, 10, 1216}, + dictWord{4, 0, 245}, + dictWord{5, 0, 151}, + dictWord{5, 0, 741}, + dictWord{6, 0, 1147}, + dictWord{7, 0, 498}, + dictWord{7, 0, 870}, + dictWord{7, 0, 1542}, + dictWord{12, 0, 213}, + dictWord{14, 0, 36}, + dictWord{14, 0, 391}, + dictWord{17, 0, 111}, + dictWord{18, 0, 6}, + dictWord{18, 0, 46}, + dictWord{ + 18, + 0, + 151, + }, + dictWord{19, 0, 36}, + dictWord{20, 0, 32}, + dictWord{20, 0, 56}, + dictWord{20, 0, 69}, + dictWord{20, 0, 102}, + dictWord{21, 0, 4}, + dictWord{22, 0, 8}, + dictWord{ + 22, + 0, + 10, + }, + dictWord{22, 0, 14}, + dictWord{150, 0, 31}, + dictWord{4, 0, 624}, + dictWord{135, 0, 1752}, + dictWord{5, 10, 124}, + dictWord{5, 10, 144}, + dictWord{6, 10, 548}, + dictWord{7, 10, 15}, + dictWord{7, 10, 153}, + dictWord{137, 10, 629}, + dictWord{6, 0, 503}, + dictWord{9, 0, 586}, + dictWord{13, 0, 468}, + dictWord{14, 0, 66}, + dictWord{ + 16, + 0, + 58, + }, + dictWord{7, 10, 1531}, + dictWord{8, 10, 416}, + dictWord{9, 10, 275}, + dictWord{10, 10, 100}, + dictWord{11, 10, 658}, + dictWord{11, 10, 979}, + dictWord{ + 12, + 10, + 86, + }, + dictWord{14, 10, 207}, + dictWord{15, 10, 20}, + dictWord{143, 10, 25}, + dictWord{5, 0, 603}, + dictWord{7, 0, 1212}, + dictWord{9, 0, 565}, + dictWord{ + 14, + 0, + 301, + }, + dictWord{5, 10, 915}, + dictWord{6, 10, 1783}, + dictWord{7, 10, 211}, + dictWord{7, 10, 1353}, + dictWord{9, 10, 83}, + dictWord{10, 10, 376}, + dictWord{ + 10, + 10, + 431, + }, + dictWord{11, 10, 543}, + dictWord{12, 10, 664}, + dictWord{13, 10, 280}, + dictWord{13, 10, 428}, + dictWord{14, 10, 128}, + dictWord{17, 10, 52}, + dictWord{ + 145, + 10, + 81, + }, + dictWord{4, 0, 492}, + dictWord{133, 0, 451}, + dictWord{135, 0, 835}, + dictWord{141, 0, 70}, + dictWord{132, 0, 539}, + dictWord{7, 11, 748}, + dictWord{ + 139, + 11, + 700, + }, + dictWord{7, 11, 1517}, + dictWord{11, 11, 597}, + dictWord{14, 11, 76}, + dictWord{14, 11, 335}, + dictWord{148, 11, 33}, + dictWord{6, 0, 113}, + dictWord{135, 0, 436}, + dictWord{4, 10, 338}, + dictWord{133, 10, 400}, + dictWord{136, 0, 718}, + dictWord{133, 11, 127}, + dictWord{133, 11, 418}, + dictWord{ + 6, + 0, + 1505, + }, + dictWord{7, 0, 520}, + dictWord{6, 11, 198}, + dictWord{11, 10, 892}, + dictWord{140, 11, 83}, + dictWord{4, 10, 221}, + dictWord{5, 10, 659}, + dictWord{ + 5, + 10, + 989, + }, + dictWord{7, 10, 697}, + dictWord{7, 10, 1211}, + dictWord{138, 10, 284}, + dictWord{135, 0, 1070}, + dictWord{5, 11, 276}, + dictWord{6, 11, 55}, + dictWord{ + 135, + 11, + 1369, + }, + dictWord{134, 0, 1515}, + dictWord{6, 11, 1752}, + dictWord{136, 11, 726}, + dictWord{138, 10, 507}, + dictWord{15, 0, 78}, + dictWord{4, 10, 188}, + dictWord{135, 10, 805}, + dictWord{5, 10, 884}, + dictWord{139, 10, 991}, + dictWord{133, 11, 764}, + dictWord{134, 10, 1653}, + dictWord{6, 11, 309}, + dictWord{ + 7, + 11, + 331, + }, + dictWord{138, 11, 550}, + dictWord{135, 11, 1861}, + dictWord{132, 11, 348}, + dictWord{135, 11, 986}, + dictWord{135, 11, 1573}, + dictWord{ + 12, + 0, + 610, + }, + dictWord{13, 0, 431}, + dictWord{144, 0, 59}, + dictWord{9, 11, 799}, + dictWord{140, 10, 166}, + dictWord{134, 0, 1530}, + dictWord{132, 0, 750}, + dictWord{132, 0, 307}, + dictWord{133, 0, 964}, + dictWord{6, 11, 194}, + dictWord{7, 11, 133}, + dictWord{10, 11, 493}, + dictWord{10, 11, 570}, + dictWord{139, 11, 664}, + dictWord{5, 11, 24}, + dictWord{5, 11, 569}, + dictWord{6, 11, 3}, + dictWord{6, 11, 119}, + dictWord{6, 11, 143}, + dictWord{6, 11, 440}, + dictWord{7, 11, 295}, + dictWord{ + 7, + 11, + 599, + }, + dictWord{7, 11, 1686}, + dictWord{7, 11, 1854}, + dictWord{8, 11, 424}, + dictWord{9, 11, 43}, + dictWord{9, 11, 584}, + dictWord{9, 11, 760}, + dictWord{ + 10, + 11, + 148, + }, + dictWord{10, 11, 328}, + dictWord{11, 11, 159}, + dictWord{11, 11, 253}, + dictWord{11, 11, 506}, + dictWord{12, 11, 487}, + dictWord{12, 11, 531}, + dictWord{144, 11, 33}, + dictWord{136, 10, 760}, + dictWord{5, 11, 14}, + dictWord{5, 11, 892}, + dictWord{6, 11, 283}, + dictWord{7, 11, 234}, + dictWord{136, 11, 537}, + dictWord{135, 11, 1251}, + dictWord{4, 11, 126}, + dictWord{8, 11, 635}, + dictWord{147, 11, 34}, + dictWord{4, 11, 316}, + dictWord{135, 11, 1561}, + dictWord{ + 6, + 0, + 999, + }, + dictWord{6, 0, 1310}, + dictWord{137, 11, 861}, + dictWord{4, 11, 64}, + dictWord{5, 11, 352}, + dictWord{5, 11, 720}, + dictWord{6, 11, 368}, + dictWord{ + 139, + 11, + 359, + }, + dictWord{4, 0, 75}, + dictWord{5, 0, 180}, + dictWord{6, 0, 500}, + dictWord{7, 0, 58}, + dictWord{7, 0, 710}, + dictWord{10, 0, 645}, + dictWord{136, 10, 770}, + dictWord{133, 0, 649}, + dictWord{6, 0, 276}, + dictWord{7, 0, 282}, + dictWord{7, 0, 879}, + dictWord{7, 0, 924}, + dictWord{8, 0, 459}, + dictWord{9, 0, 599}, + dictWord{9, 0, 754}, + dictWord{11, 0, 574}, + dictWord{12, 0, 128}, + dictWord{12, 0, 494}, + dictWord{13, 0, 52}, + dictWord{13, 0, 301}, + dictWord{15, 0, 30}, + dictWord{143, 0, 132}, + dictWord{132, 0, 200}, + dictWord{4, 10, 89}, + dictWord{5, 10, 489}, + dictWord{6, 10, 315}, + dictWord{7, 10, 553}, + dictWord{7, 10, 1745}, + dictWord{138, 10, 243}, + dictWord{135, 11, 1050}, + dictWord{7, 0, 1621}, + dictWord{6, 10, 1658}, + dictWord{9, 10, 3}, + dictWord{10, 10, 154}, + dictWord{11, 10, 641}, + dictWord{13, 10, 85}, + dictWord{13, 10, 201}, + dictWord{141, 10, 346}, + dictWord{6, 11, 175}, + dictWord{137, 11, 289}, + dictWord{5, 11, 432}, + dictWord{133, 11, 913}, + dictWord{ + 6, + 0, + 225, + }, + dictWord{137, 0, 211}, + dictWord{7, 0, 718}, + dictWord{8, 0, 687}, + dictWord{139, 0, 374}, + dictWord{4, 10, 166}, + dictWord{133, 10, 505}, + dictWord{ + 9, + 0, + 110, + }, + dictWord{134, 10, 1670}, + dictWord{8, 0, 58}, + dictWord{9, 0, 724}, + dictWord{11, 0, 809}, + dictWord{13, 0, 113}, + dictWord{145, 0, 72}, + dictWord{6, 0, 345}, + dictWord{7, 0, 1247}, + dictWord{144, 11, 82}, + dictWord{5, 11, 931}, + dictWord{134, 11, 1698}, + dictWord{8, 0, 767}, + dictWord{8, 0, 803}, + dictWord{9, 0, 301}, + dictWord{137, 0, 903}, + dictWord{139, 0, 203}, + dictWord{134, 0, 1154}, + dictWord{7, 0, 1949}, + dictWord{136, 0, 674}, + dictWord{134, 0, 259}, + dictWord{ + 135, + 0, + 1275, + }, + dictWord{5, 11, 774}, + dictWord{6, 11, 1637}, + dictWord{6, 11, 1686}, + dictWord{134, 11, 1751}, + dictWord{134, 0, 1231}, + dictWord{7, 10, 445}, + dictWord{8, 10, 307}, + dictWord{8, 10, 704}, + dictWord{10, 10, 41}, + dictWord{10, 10, 439}, + dictWord{11, 10, 237}, + dictWord{11, 10, 622}, + dictWord{140, 10, 201}, + dictWord{136, 0, 254}, + dictWord{6, 11, 260}, + dictWord{135, 11, 1484}, + dictWord{139, 0, 277}, + dictWord{135, 10, 1977}, + dictWord{4, 10, 189}, + dictWord{ + 5, + 10, + 713, + }, + dictWord{6, 11, 573}, + dictWord{136, 10, 57}, + dictWord{138, 10, 371}, + dictWord{132, 10, 552}, + dictWord{134, 11, 344}, + dictWord{133, 0, 248}, + dictWord{9, 0, 800}, + dictWord{10, 0, 693}, + dictWord{11, 0, 482}, + dictWord{11, 0, 734}, + dictWord{11, 0, 789}, + dictWord{134, 11, 240}, + dictWord{4, 0, 116}, + dictWord{ + 5, + 0, + 95, + }, + dictWord{5, 0, 445}, + dictWord{7, 0, 1688}, + dictWord{8, 0, 29}, + dictWord{9, 0, 272}, + dictWord{11, 0, 509}, + dictWord{11, 0, 915}, + dictWord{4, 11, 292}, + dictWord{4, 11, 736}, + dictWord{5, 11, 871}, + dictWord{6, 11, 171}, + dictWord{6, 11, 1689}, + dictWord{7, 11, 1324}, + dictWord{7, 11, 1944}, + dictWord{9, 11, 415}, + dictWord{9, 11, 580}, + dictWord{14, 11, 230}, + dictWord{146, 11, 68}, + dictWord{7, 0, 490}, + dictWord{13, 0, 100}, + dictWord{143, 0, 75}, + dictWord{135, 0, 1641}, + dictWord{133, 0, 543}, + dictWord{7, 11, 209}, + dictWord{8, 11, 661}, + dictWord{10, 11, 42}, + dictWord{11, 11, 58}, + dictWord{12, 11, 58}, + dictWord{12, 11, 118}, + dictWord{141, 11, 32}, + dictWord{5, 0, 181}, + dictWord{8, 0, 41}, + dictWord{6, 11, 63}, + dictWord{135, 11, 920}, + dictWord{133, 0, 657}, + dictWord{133, 11, 793}, + dictWord{138, 0, 709}, + dictWord{7, 0, 25}, + dictWord{8, 0, 202}, + dictWord{138, 0, 536}, + dictWord{5, 11, 665}, + dictWord{135, 10, 1788}, + dictWord{145, 10, 49}, + dictWord{9, 0, 423}, + dictWord{140, 0, 89}, + dictWord{5, 11, 67}, + dictWord{6, 11, 62}, + dictWord{6, 11, 374}, + dictWord{135, 11, 1391}, + dictWord{8, 0, 113}, + dictWord{ + 9, + 0, + 877, + }, + dictWord{10, 0, 554}, + dictWord{11, 0, 83}, + dictWord{12, 0, 136}, + dictWord{19, 0, 109}, + dictWord{9, 11, 790}, + dictWord{140, 11, 47}, + dictWord{ + 138, + 10, + 661, + }, + dictWord{4, 0, 963}, + dictWord{10, 0, 927}, + dictWord{14, 0, 442}, + dictWord{135, 10, 1945}, + dictWord{133, 0, 976}, + dictWord{132, 0, 206}, + dictWord{ + 4, + 11, + 391, + }, + dictWord{135, 11, 1169}, + dictWord{134, 0, 2002}, + dictWord{6, 0, 696}, + dictWord{134, 0, 1008}, + dictWord{134, 0, 1170}, + dictWord{132, 11, 271}, + dictWord{7, 0, 13}, + dictWord{8, 0, 226}, + dictWord{10, 0, 537}, + dictWord{11, 0, 570}, + dictWord{11, 0, 605}, + dictWord{11, 0, 799}, + dictWord{11, 0, 804}, + dictWord{ + 12, + 0, + 85, + }, + dictWord{12, 0, 516}, + dictWord{12, 0, 623}, + dictWord{13, 0, 112}, + dictWord{13, 0, 361}, + dictWord{14, 0, 77}, + dictWord{14, 0, 78}, + dictWord{17, 0, 28}, + dictWord{19, 0, 110}, + dictWord{140, 11, 314}, + dictWord{132, 0, 769}, + dictWord{134, 0, 1544}, + dictWord{4, 0, 551}, + dictWord{137, 0, 678}, + dictWord{5, 10, 84}, + dictWord{134, 10, 163}, + dictWord{9, 0, 57}, + dictWord{9, 0, 459}, + dictWord{10, 0, 425}, + dictWord{11, 0, 119}, + dictWord{12, 0, 184}, + dictWord{12, 0, 371}, + dictWord{ + 13, + 0, + 358, + }, + dictWord{145, 0, 51}, + dictWord{5, 0, 188}, + dictWord{5, 0, 814}, + dictWord{8, 0, 10}, + dictWord{9, 0, 421}, + dictWord{9, 0, 729}, + dictWord{10, 0, 609}, + dictWord{11, 0, 689}, + dictWord{4, 11, 253}, + dictWord{5, 10, 410}, + dictWord{5, 11, 544}, + dictWord{7, 11, 300}, + dictWord{137, 11, 340}, + dictWord{134, 0, 624}, + dictWord{138, 11, 321}, + dictWord{135, 0, 1941}, + dictWord{18, 0, 130}, + dictWord{5, 10, 322}, + dictWord{8, 10, 186}, + dictWord{9, 10, 262}, + dictWord{10, 10, 187}, + dictWord{142, 10, 208}, + dictWord{5, 11, 53}, + dictWord{5, 11, 541}, + dictWord{6, 11, 94}, + dictWord{6, 11, 499}, + dictWord{7, 11, 230}, + dictWord{139, 11, 321}, + dictWord{133, 10, 227}, + dictWord{4, 0, 378}, + dictWord{4, 11, 920}, + dictWord{5, 11, 25}, + dictWord{5, 11, 790}, + dictWord{6, 11, 457}, + dictWord{135, 11, 853}, + dictWord{137, 0, 269}, + dictWord{132, 0, 528}, + dictWord{134, 0, 1146}, + dictWord{7, 10, 1395}, + dictWord{8, 10, 486}, + dictWord{9, 10, 236}, + dictWord{9, 10, 878}, + dictWord{10, 10, 218}, + dictWord{11, 10, 95}, + dictWord{19, 10, 17}, + dictWord{147, 10, 31}, + dictWord{7, 10, 2043}, + dictWord{8, 10, 672}, + dictWord{ + 141, + 10, + 448, + }, + dictWord{134, 0, 1105}, + dictWord{134, 0, 1616}, + dictWord{134, 11, 1765}, + dictWord{140, 11, 163}, + dictWord{5, 10, 412}, + dictWord{133, 11, 822}, + dictWord{132, 11, 634}, + dictWord{6, 0, 656}, + dictWord{134, 11, 1730}, + dictWord{134, 0, 1940}, + dictWord{5, 0, 104}, + dictWord{6, 0, 173}, + dictWord{ + 135, + 0, + 1631, + }, + dictWord{136, 10, 562}, + dictWord{6, 11, 36}, + dictWord{7, 11, 658}, + dictWord{8, 11, 454}, + dictWord{147, 11, 86}, + dictWord{5, 0, 457}, + dictWord{ + 134, + 10, + 1771, + }, + dictWord{7, 0, 810}, + dictWord{8, 0, 138}, + dictWord{8, 0, 342}, + dictWord{9, 0, 84}, + dictWord{10, 0, 193}, + dictWord{11, 0, 883}, + dictWord{140, 0, 359}, + dictWord{9, 0, 620}, + dictWord{135, 10, 1190}, + dictWord{137, 10, 132}, + dictWord{7, 11, 975}, + dictWord{137, 11, 789}, + dictWord{6, 0, 95}, + dictWord{6, 0, 1934}, + dictWord{136, 0, 967}, + dictWord{141, 11, 335}, + dictWord{6, 0, 406}, + dictWord{10, 0, 409}, + dictWord{10, 0, 447}, + dictWord{11, 0, 44}, + dictWord{140, 0, 100}, + dictWord{4, 10, 317}, + dictWord{135, 10, 1279}, + dictWord{132, 0, 477}, + dictWord{134, 0, 1268}, + dictWord{6, 0, 1941}, + dictWord{8, 0, 944}, + dictWord{5, 10, 63}, + dictWord{133, 10, 509}, + dictWord{132, 0, 629}, + dictWord{132, 11, 104}, + dictWord{4, 0, 246}, + dictWord{133, 0, 375}, + dictWord{6, 0, 1636}, + dictWord{ + 132, + 10, + 288, + }, + dictWord{135, 11, 1614}, + dictWord{9, 0, 49}, + dictWord{10, 0, 774}, + dictWord{8, 10, 89}, + dictWord{8, 10, 620}, + dictWord{11, 10, 628}, + dictWord{ + 12, + 10, + 322, + }, + dictWord{143, 10, 124}, + dictWord{4, 0, 282}, + dictWord{7, 0, 1034}, + dictWord{11, 0, 398}, + dictWord{11, 0, 634}, + dictWord{12, 0, 1}, + dictWord{12, 0, 79}, + dictWord{12, 0, 544}, + dictWord{14, 0, 237}, + dictWord{17, 0, 10}, + dictWord{146, 0, 20}, + dictWord{132, 0, 824}, + dictWord{7, 11, 45}, + dictWord{9, 11, 542}, + dictWord{ + 9, + 11, + 566, + }, + dictWord{138, 11, 728}, + dictWord{5, 0, 118}, + dictWord{5, 0, 499}, + dictWord{6, 0, 476}, + dictWord{6, 0, 665}, + dictWord{6, 0, 1176}, + dictWord{ + 6, + 0, + 1196, + }, + dictWord{7, 0, 600}, + dictWord{7, 0, 888}, + dictWord{135, 0, 1096}, + dictWord{7, 0, 296}, + dictWord{7, 0, 596}, + dictWord{8, 0, 560}, + dictWord{8, 0, 586}, + dictWord{9, 0, 612}, + dictWord{11, 0, 304}, + dictWord{12, 0, 46}, + dictWord{13, 0, 89}, + dictWord{14, 0, 112}, + dictWord{145, 0, 122}, + dictWord{5, 0, 894}, + dictWord{ + 6, + 0, + 1772, + }, + dictWord{9, 0, 1009}, + dictWord{138, 10, 120}, + dictWord{5, 11, 533}, + dictWord{7, 11, 755}, + dictWord{138, 11, 780}, + dictWord{151, 10, 1}, + dictWord{ + 6, + 0, + 1474, + }, + dictWord{7, 11, 87}, + dictWord{142, 11, 288}, + dictWord{139, 0, 366}, + dictWord{137, 10, 461}, + dictWord{7, 11, 988}, + dictWord{7, 11, 1939}, + dictWord{ + 9, + 11, + 64, + }, + dictWord{9, 11, 502}, + dictWord{12, 11, 7}, + dictWord{12, 11, 34}, + dictWord{13, 11, 12}, + dictWord{13, 11, 234}, + dictWord{147, 11, 77}, + dictWord{ + 7, + 0, + 1599, + }, + dictWord{7, 0, 1723}, + dictWord{8, 0, 79}, + dictWord{8, 0, 106}, + dictWord{8, 0, 190}, + dictWord{8, 0, 302}, + dictWord{8, 0, 383}, + dictWord{8, 0, 713}, + dictWord{ + 9, + 0, + 119, + }, + dictWord{9, 0, 233}, + dictWord{9, 0, 419}, + dictWord{9, 0, 471}, + dictWord{10, 0, 181}, + dictWord{10, 0, 406}, + dictWord{11, 0, 57}, + dictWord{11, 0, 85}, + dictWord{11, 0, 120}, + dictWord{11, 0, 177}, + dictWord{11, 0, 296}, + dictWord{11, 0, 382}, + dictWord{11, 0, 454}, + dictWord{11, 0, 758}, + dictWord{11, 0, 999}, + dictWord{ + 12, + 0, + 27, + }, + dictWord{12, 0, 98}, + dictWord{12, 0, 131}, + dictWord{12, 0, 245}, + dictWord{12, 0, 312}, + dictWord{12, 0, 446}, + dictWord{12, 0, 454}, + dictWord{13, 0, 25}, + dictWord{13, 0, 98}, + dictWord{13, 0, 426}, + dictWord{13, 0, 508}, + dictWord{14, 0, 70}, + dictWord{14, 0, 163}, + dictWord{14, 0, 272}, + dictWord{14, 0, 277}, + dictWord{ + 14, + 0, + 370, + }, + dictWord{15, 0, 95}, + dictWord{15, 0, 138}, + dictWord{15, 0, 167}, + dictWord{17, 0, 38}, + dictWord{148, 0, 96}, + dictWord{135, 10, 1346}, + dictWord{ + 10, + 0, + 200, + }, + dictWord{19, 0, 2}, + dictWord{151, 0, 22}, + dictWord{135, 11, 141}, + dictWord{134, 10, 85}, + dictWord{134, 0, 1759}, + dictWord{138, 0, 372}, + dictWord{ + 145, + 0, + 16, + }, + dictWord{8, 0, 943}, + dictWord{132, 11, 619}, + dictWord{139, 11, 88}, + dictWord{5, 11, 246}, + dictWord{8, 11, 189}, + dictWord{9, 11, 355}, + dictWord{ + 9, + 11, + 512, + }, + dictWord{10, 11, 124}, + dictWord{10, 11, 453}, + dictWord{11, 11, 143}, + dictWord{11, 11, 416}, + dictWord{11, 11, 859}, + dictWord{141, 11, 341}, + dictWord{ + 5, + 0, + 258, + }, + dictWord{134, 0, 719}, + dictWord{6, 0, 1798}, + dictWord{6, 0, 1839}, + dictWord{8, 0, 900}, + dictWord{10, 0, 874}, + dictWord{10, 0, 886}, + dictWord{ + 12, + 0, + 698, + }, + dictWord{12, 0, 732}, + dictWord{12, 0, 770}, + dictWord{16, 0, 106}, + dictWord{18, 0, 163}, + dictWord{18, 0, 170}, + dictWord{18, 0, 171}, + dictWord{152, 0, 20}, + dictWord{9, 0, 707}, + dictWord{11, 0, 326}, + dictWord{11, 0, 339}, + dictWord{12, 0, 423}, + dictWord{12, 0, 502}, + dictWord{20, 0, 62}, + dictWord{9, 11, 707}, + dictWord{ + 11, + 11, + 326, + }, + dictWord{11, 11, 339}, + dictWord{12, 11, 423}, + dictWord{12, 11, 502}, + dictWord{148, 11, 62}, + dictWord{5, 0, 30}, + dictWord{7, 0, 495}, + dictWord{ + 8, + 0, + 134, + }, + dictWord{9, 0, 788}, + dictWord{140, 0, 438}, + dictWord{133, 11, 678}, + dictWord{5, 10, 279}, + dictWord{6, 10, 235}, + dictWord{7, 10, 468}, + dictWord{ + 8, + 10, + 446, + }, + dictWord{9, 10, 637}, + dictWord{10, 10, 717}, + dictWord{11, 10, 738}, + dictWord{140, 10, 514}, + dictWord{5, 11, 35}, + dictWord{6, 11, 287}, + dictWord{ + 7, + 11, + 862, + }, + dictWord{7, 11, 1886}, + dictWord{138, 11, 179}, + dictWord{7, 0, 1948}, + dictWord{7, 0, 2004}, + dictWord{132, 11, 517}, + dictWord{5, 10, 17}, + dictWord{ + 6, + 10, + 371, + }, + dictWord{137, 10, 528}, + dictWord{4, 0, 115}, + dictWord{5, 0, 669}, + dictWord{6, 0, 407}, + dictWord{8, 0, 311}, + dictWord{11, 0, 10}, + dictWord{141, 0, 5}, + dictWord{137, 0, 381}, + dictWord{5, 0, 50}, + dictWord{6, 0, 439}, + dictWord{7, 0, 780}, + dictWord{135, 0, 1040}, + dictWord{136, 11, 667}, + dictWord{11, 11, 403}, + dictWord{146, 11, 83}, + dictWord{5, 0, 1}, + dictWord{6, 0, 81}, + dictWord{138, 0, 520}, + dictWord{134, 0, 738}, + dictWord{5, 0, 482}, + dictWord{8, 0, 98}, + dictWord{9, 0, 172}, + dictWord{10, 0, 360}, + dictWord{10, 0, 700}, + dictWord{10, 0, 822}, + dictWord{11, 0, 302}, + dictWord{11, 0, 778}, + dictWord{12, 0, 50}, + dictWord{12, 0, 127}, + dictWord{ + 12, + 0, + 396, + }, + dictWord{13, 0, 62}, + dictWord{13, 0, 328}, + dictWord{14, 0, 122}, + dictWord{147, 0, 72}, + dictWord{9, 11, 157}, + dictWord{10, 11, 131}, + dictWord{ + 140, + 11, + 72, + }, + dictWord{135, 11, 714}, + dictWord{135, 11, 539}, + dictWord{5, 0, 2}, + dictWord{6, 0, 512}, + dictWord{7, 0, 797}, + dictWord{7, 0, 1494}, + dictWord{8, 0, 253}, + dictWord{8, 0, 589}, + dictWord{9, 0, 77}, + dictWord{10, 0, 1}, + dictWord{10, 0, 129}, + dictWord{10, 0, 225}, + dictWord{11, 0, 118}, + dictWord{11, 0, 226}, + dictWord{ + 11, + 0, + 251, + }, + dictWord{11, 0, 430}, + dictWord{11, 0, 701}, + dictWord{11, 0, 974}, + dictWord{11, 0, 982}, + dictWord{12, 0, 64}, + dictWord{12, 0, 260}, + dictWord{12, 0, 488}, + dictWord{140, 0, 690}, + dictWord{5, 11, 394}, + dictWord{7, 11, 367}, + dictWord{7, 11, 487}, + dictWord{7, 11, 857}, + dictWord{7, 11, 1713}, + dictWord{8, 11, 246}, + dictWord{9, 11, 537}, + dictWord{10, 11, 165}, + dictWord{12, 11, 219}, + dictWord{140, 11, 561}, + dictWord{136, 0, 557}, + dictWord{5, 10, 779}, + dictWord{5, 10, 807}, + dictWord{6, 10, 1655}, + dictWord{134, 10, 1676}, + dictWord{4, 10, 196}, + dictWord{5, 10, 558}, + dictWord{133, 10, 949}, + dictWord{11, 11, 827}, + dictWord{ + 12, + 11, + 56, + }, + dictWord{14, 11, 34}, + dictWord{143, 11, 148}, + dictWord{137, 0, 347}, + dictWord{133, 0, 572}, + dictWord{134, 0, 832}, + dictWord{4, 0, 12}, + dictWord{ + 7, + 0, + 504, + }, + dictWord{7, 0, 522}, + dictWord{7, 0, 809}, + dictWord{8, 0, 797}, + dictWord{141, 0, 88}, + dictWord{4, 10, 752}, + dictWord{133, 11, 449}, + dictWord{7, 11, 86}, + dictWord{8, 11, 103}, + dictWord{145, 11, 69}, + dictWord{7, 11, 2028}, + dictWord{138, 11, 641}, + dictWord{5, 0, 528}, + dictWord{6, 11, 1}, + dictWord{142, 11, 2}, + dictWord{134, 0, 861}, + dictWord{10, 0, 294}, + dictWord{4, 10, 227}, + dictWord{5, 10, 159}, + dictWord{5, 10, 409}, + dictWord{7, 10, 80}, + dictWord{10, 10, 479}, + dictWord{ + 12, + 10, + 418, + }, + dictWord{14, 10, 50}, + dictWord{14, 10, 249}, + dictWord{142, 10, 295}, + dictWord{7, 10, 1470}, + dictWord{8, 10, 66}, + dictWord{8, 10, 137}, + dictWord{ + 8, + 10, + 761, + }, + dictWord{9, 10, 638}, + dictWord{11, 10, 80}, + dictWord{11, 10, 212}, + dictWord{11, 10, 368}, + dictWord{11, 10, 418}, + dictWord{12, 10, 8}, + dictWord{ + 13, + 10, + 15, + }, + dictWord{16, 10, 61}, + dictWord{17, 10, 59}, + dictWord{19, 10, 28}, + dictWord{148, 10, 84}, + dictWord{20, 0, 109}, + dictWord{135, 11, 1148}, + dictWord{ + 6, + 11, + 277, + }, + dictWord{7, 11, 1274}, + dictWord{7, 11, 1386}, + dictWord{7, 11, 1392}, + dictWord{12, 11, 129}, + dictWord{146, 11, 87}, + dictWord{6, 11, 187}, + dictWord{7, 11, 39}, + dictWord{7, 11, 1203}, + dictWord{8, 11, 380}, + dictWord{8, 11, 542}, + dictWord{14, 11, 117}, + dictWord{149, 11, 28}, + dictWord{134, 0, 1187}, + dictWord{5, 0, 266}, + dictWord{9, 0, 290}, + dictWord{9, 0, 364}, + dictWord{10, 0, 293}, + dictWord{11, 0, 606}, + dictWord{142, 0, 45}, + dictWord{6, 11, 297}, + dictWord{ + 7, + 11, + 793, + }, + dictWord{139, 11, 938}, + dictWord{4, 0, 50}, + dictWord{6, 0, 594}, + dictWord{9, 0, 121}, + dictWord{10, 0, 49}, + dictWord{10, 0, 412}, + dictWord{139, 0, 834}, + dictWord{136, 0, 748}, + dictWord{7, 11, 464}, + dictWord{8, 11, 438}, + dictWord{11, 11, 105}, + dictWord{11, 11, 363}, + dictWord{12, 11, 231}, + dictWord{ + 14, + 11, + 386, + }, + dictWord{15, 11, 102}, + dictWord{148, 11, 75}, + dictWord{132, 0, 466}, + dictWord{13, 0, 399}, + dictWord{14, 0, 337}, + dictWord{6, 10, 38}, + dictWord{ + 7, + 10, + 1220, + }, + dictWord{8, 10, 185}, + dictWord{8, 10, 256}, + dictWord{9, 10, 22}, + dictWord{9, 10, 331}, + dictWord{10, 10, 738}, + dictWord{11, 10, 205}, + dictWord{ + 11, + 10, + 540, + }, + dictWord{11, 10, 746}, + dictWord{13, 10, 465}, + dictWord{142, 10, 194}, + dictWord{9, 0, 378}, + dictWord{141, 0, 162}, + dictWord{137, 0, 519}, + dictWord{ + 4, + 10, + 159, + }, + dictWord{6, 10, 115}, + dictWord{7, 10, 252}, + dictWord{7, 10, 257}, + dictWord{7, 10, 1928}, + dictWord{8, 10, 69}, + dictWord{9, 10, 384}, + dictWord{ + 10, + 10, + 91, + }, + dictWord{10, 10, 615}, + dictWord{12, 10, 375}, + dictWord{14, 10, 235}, + dictWord{18, 10, 117}, + dictWord{147, 10, 123}, + dictWord{5, 11, 604}, + dictWord{ + 5, + 10, + 911, + }, + dictWord{136, 10, 278}, + dictWord{132, 0, 667}, + dictWord{8, 0, 351}, + dictWord{9, 0, 322}, + dictWord{4, 10, 151}, + dictWord{135, 10, 1567}, + dictWord{134, 0, 902}, + dictWord{133, 10, 990}, + dictWord{12, 0, 180}, + dictWord{5, 10, 194}, + dictWord{7, 10, 1662}, + dictWord{137, 10, 90}, + dictWord{4, 0, 869}, + dictWord{134, 0, 1996}, + dictWord{134, 0, 813}, + dictWord{133, 10, 425}, + dictWord{137, 11, 761}, + dictWord{132, 0, 260}, + dictWord{133, 10, 971}, + dictWord{ + 5, + 11, + 20, + }, + dictWord{6, 11, 298}, + dictWord{7, 11, 659}, + dictWord{7, 11, 1366}, + dictWord{137, 11, 219}, + dictWord{4, 0, 39}, + dictWord{5, 0, 36}, + dictWord{ + 7, + 0, + 1843, + }, + dictWord{8, 0, 407}, + dictWord{11, 0, 144}, + dictWord{140, 0, 523}, + dictWord{4, 0, 510}, + dictWord{10, 0, 587}, + dictWord{139, 10, 752}, + dictWord{7, 0, 29}, + dictWord{7, 0, 66}, + dictWord{7, 0, 1980}, + dictWord{10, 0, 487}, + dictWord{138, 0, 809}, + dictWord{13, 0, 260}, + dictWord{14, 0, 82}, + dictWord{18, 0, 63}, + dictWord{ + 137, + 10, + 662, + }, + dictWord{5, 10, 72}, + dictWord{6, 10, 264}, + dictWord{7, 10, 21}, + dictWord{7, 10, 46}, + dictWord{7, 10, 2013}, + dictWord{8, 10, 215}, + dictWord{ + 8, + 10, + 513, + }, + dictWord{10, 10, 266}, + dictWord{139, 10, 22}, + dictWord{134, 0, 570}, + dictWord{6, 0, 565}, + dictWord{7, 0, 1667}, + dictWord{4, 11, 439}, + dictWord{ + 10, + 10, + 95, + }, + dictWord{11, 10, 603}, + dictWord{12, 11, 242}, + dictWord{13, 10, 443}, + dictWord{14, 10, 160}, + dictWord{143, 10, 4}, + dictWord{134, 0, 1464}, + dictWord{ + 134, + 10, + 431, + }, + dictWord{9, 0, 372}, + dictWord{15, 0, 2}, + dictWord{19, 0, 10}, + dictWord{19, 0, 18}, + dictWord{5, 10, 874}, + dictWord{6, 10, 1677}, + dictWord{143, 10, 0}, + dictWord{132, 0, 787}, + dictWord{6, 0, 380}, + dictWord{12, 0, 399}, + dictWord{21, 0, 19}, + dictWord{7, 10, 939}, + dictWord{7, 10, 1172}, + dictWord{7, 10, 1671}, + dictWord{9, 10, 540}, + dictWord{10, 10, 696}, + dictWord{11, 10, 265}, + dictWord{11, 10, 732}, + dictWord{11, 10, 928}, + dictWord{11, 10, 937}, + dictWord{ + 141, + 10, + 438, + }, + dictWord{137, 0, 200}, + dictWord{132, 11, 233}, + dictWord{132, 0, 516}, + dictWord{134, 11, 577}, + dictWord{132, 0, 844}, + dictWord{11, 0, 887}, + dictWord{14, 0, 365}, + dictWord{142, 0, 375}, + dictWord{132, 11, 482}, + dictWord{8, 0, 821}, + dictWord{140, 0, 44}, + dictWord{7, 0, 1655}, + dictWord{136, 0, 305}, + dictWord{5, 10, 682}, + dictWord{135, 10, 1887}, + dictWord{135, 11, 346}, + dictWord{132, 10, 696}, + dictWord{4, 0, 10}, + dictWord{7, 0, 917}, + dictWord{139, 0, 786}, + dictWord{5, 11, 795}, + dictWord{6, 11, 1741}, + dictWord{8, 11, 417}, + dictWord{137, 11, 782}, + dictWord{4, 0, 1016}, + dictWord{134, 0, 2031}, + dictWord{5, 0, 684}, + dictWord{4, 10, 726}, + dictWord{133, 10, 630}, + dictWord{6, 0, 1021}, + dictWord{134, 0, 1480}, + dictWord{8, 10, 802}, + dictWord{136, 10, 838}, + dictWord{ + 134, + 0, + 27, + }, + dictWord{134, 0, 395}, + dictWord{135, 11, 622}, + dictWord{7, 11, 625}, + dictWord{135, 11, 1750}, + dictWord{4, 11, 203}, + dictWord{135, 11, 1936}, + dictWord{6, 10, 118}, + dictWord{7, 10, 215}, + dictWord{7, 10, 1521}, + dictWord{140, 10, 11}, + dictWord{132, 0, 813}, + dictWord{136, 0, 511}, + dictWord{7, 10, 615}, + dictWord{138, 10, 251}, + dictWord{135, 10, 1044}, + dictWord{145, 0, 56}, + dictWord{133, 10, 225}, + dictWord{6, 0, 342}, + dictWord{6, 0, 496}, + dictWord{8, 0, 275}, + dictWord{137, 0, 206}, + dictWord{4, 0, 909}, + dictWord{133, 0, 940}, + dictWord{132, 0, 891}, + dictWord{7, 11, 311}, + dictWord{9, 11, 308}, + dictWord{ + 140, + 11, + 255, + }, + dictWord{4, 10, 370}, + dictWord{5, 10, 756}, + dictWord{135, 10, 1326}, + dictWord{4, 0, 687}, + dictWord{134, 0, 1596}, + dictWord{134, 0, 1342}, + dictWord{ + 6, + 10, + 1662, + }, + dictWord{7, 10, 48}, + dictWord{8, 10, 771}, + dictWord{10, 10, 116}, + dictWord{13, 10, 104}, + dictWord{14, 10, 105}, + dictWord{14, 10, 184}, + dictWord{15, 10, 168}, + dictWord{19, 10, 92}, + dictWord{148, 10, 68}, + dictWord{138, 10, 209}, + dictWord{4, 11, 400}, + dictWord{5, 11, 267}, + dictWord{135, 11, 232}, + dictWord{151, 11, 12}, + dictWord{6, 0, 41}, + dictWord{141, 0, 160}, + dictWord{141, 11, 314}, + dictWord{134, 0, 1718}, + dictWord{136, 0, 778}, + dictWord{ + 142, + 11, + 261, + }, + dictWord{134, 0, 1610}, + dictWord{133, 0, 115}, + dictWord{132, 0, 294}, + dictWord{14, 0, 314}, + dictWord{132, 10, 120}, + dictWord{132, 0, 983}, + dictWord{5, 0, 193}, + dictWord{140, 0, 178}, + dictWord{138, 10, 429}, + dictWord{5, 10, 820}, + dictWord{135, 10, 931}, + dictWord{6, 0, 994}, + dictWord{6, 0, 1051}, + dictWord{6, 0, 1439}, + dictWord{7, 0, 174}, + dictWord{133, 11, 732}, + dictWord{4, 11, 100}, + dictWord{7, 11, 679}, + dictWord{8, 11, 313}, + dictWord{138, 10, 199}, + dictWord{6, 10, 151}, + dictWord{6, 10, 1675}, + dictWord{7, 10, 383}, + dictWord{151, 10, 10}, + dictWord{6, 0, 1796}, + dictWord{8, 0, 848}, + dictWord{8, 0, 867}, + dictWord{ + 8, + 0, + 907, + }, + dictWord{10, 0, 855}, + dictWord{140, 0, 703}, + dictWord{140, 0, 221}, + dictWord{4, 0, 122}, + dictWord{5, 0, 796}, + dictWord{5, 0, 952}, + dictWord{6, 0, 1660}, + dictWord{6, 0, 1671}, + dictWord{8, 0, 567}, + dictWord{9, 0, 687}, + dictWord{9, 0, 742}, + dictWord{10, 0, 686}, + dictWord{11, 0, 682}, + dictWord{11, 0, 909}, + dictWord{ + 140, + 0, + 281, + }, + dictWord{5, 11, 362}, + dictWord{5, 11, 443}, + dictWord{6, 11, 318}, + dictWord{7, 11, 1019}, + dictWord{139, 11, 623}, + dictWord{5, 11, 463}, + dictWord{136, 11, 296}, + dictWord{11, 0, 583}, + dictWord{13, 0, 262}, + dictWord{6, 10, 1624}, + dictWord{12, 10, 422}, + dictWord{142, 10, 360}, + dictWord{5, 0, 179}, + dictWord{7, 0, 1095}, + dictWord{135, 0, 1213}, + dictWord{4, 10, 43}, + dictWord{4, 11, 454}, + dictWord{5, 10, 344}, + dictWord{133, 10, 357}, + dictWord{4, 0, 66}, + dictWord{7, 0, 722}, + dictWord{135, 0, 904}, + dictWord{134, 0, 773}, + dictWord{7, 0, 352}, + dictWord{133, 10, 888}, + dictWord{5, 11, 48}, + dictWord{5, 11, 404}, + dictWord{ + 6, + 11, + 557, + }, + dictWord{7, 11, 458}, + dictWord{8, 11, 597}, + dictWord{10, 11, 455}, + dictWord{10, 11, 606}, + dictWord{11, 11, 49}, + dictWord{11, 11, 548}, + dictWord{ + 12, + 11, + 476, + }, + dictWord{13, 11, 18}, + dictWord{141, 11, 450}, + dictWord{134, 11, 418}, + dictWord{132, 10, 711}, + dictWord{5, 11, 442}, + dictWord{ + 135, + 11, + 1984, + }, + dictWord{141, 0, 35}, + dictWord{137, 0, 152}, + dictWord{134, 0, 1197}, + dictWord{135, 11, 1093}, + dictWord{137, 11, 203}, + dictWord{137, 10, 440}, + dictWord{10, 0, 592}, + dictWord{10, 0, 753}, + dictWord{12, 0, 317}, + dictWord{12, 0, 355}, + dictWord{12, 0, 465}, + dictWord{12, 0, 469}, + dictWord{12, 0, 560}, + dictWord{12, 0, 578}, + dictWord{141, 0, 243}, + dictWord{133, 0, 564}, + dictWord{134, 0, 797}, + dictWord{5, 10, 958}, + dictWord{133, 10, 987}, + dictWord{5, 11, 55}, + dictWord{7, 11, 376}, + dictWord{140, 11, 161}, + dictWord{133, 11, 450}, + dictWord{134, 0, 556}, + dictWord{134, 0, 819}, + dictWord{11, 10, 276}, + dictWord{ + 142, + 10, + 293, + }, + dictWord{7, 0, 544}, + dictWord{138, 0, 61}, + dictWord{8, 0, 719}, + dictWord{4, 10, 65}, + dictWord{5, 10, 479}, + dictWord{5, 10, 1004}, + dictWord{7, 10, 1913}, + dictWord{8, 10, 317}, + dictWord{9, 10, 302}, + dictWord{10, 10, 612}, + dictWord{141, 10, 22}, + dictWord{4, 0, 5}, + dictWord{5, 0, 498}, + dictWord{8, 0, 637}, + dictWord{ + 9, + 0, + 521, + }, + dictWord{4, 11, 213}, + dictWord{4, 10, 261}, + dictWord{7, 11, 223}, + dictWord{7, 10, 510}, + dictWord{136, 11, 80}, + dictWord{5, 0, 927}, + dictWord{7, 0, 101}, + dictWord{4, 10, 291}, + dictWord{7, 11, 381}, + dictWord{7, 11, 806}, + dictWord{7, 11, 820}, + dictWord{8, 11, 354}, + dictWord{8, 11, 437}, + dictWord{8, 11, 787}, + dictWord{9, 10, 515}, + dictWord{9, 11, 657}, + dictWord{10, 11, 58}, + dictWord{10, 11, 339}, + dictWord{10, 11, 749}, + dictWord{11, 11, 914}, + dictWord{12, 10, 152}, + dictWord{12, 11, 162}, + dictWord{12, 10, 443}, + dictWord{13, 11, 75}, + dictWord{13, 10, 392}, + dictWord{14, 11, 106}, + dictWord{14, 11, 198}, + dictWord{ + 14, + 11, + 320, + }, + dictWord{14, 10, 357}, + dictWord{14, 11, 413}, + dictWord{146, 11, 43}, + dictWord{6, 0, 1153}, + dictWord{7, 0, 1441}, + dictWord{136, 11, 747}, + dictWord{ + 4, + 0, + 893, + }, + dictWord{5, 0, 780}, + dictWord{133, 0, 893}, + dictWord{138, 11, 654}, + dictWord{133, 11, 692}, + dictWord{133, 0, 238}, + dictWord{134, 11, 191}, + dictWord{4, 10, 130}, + dictWord{135, 10, 843}, + dictWord{6, 0, 1296}, + dictWord{5, 10, 42}, + dictWord{5, 10, 879}, + dictWord{7, 10, 245}, + dictWord{7, 10, 324}, + dictWord{ + 7, + 10, + 1532, + }, + dictWord{11, 10, 463}, + dictWord{11, 10, 472}, + dictWord{13, 10, 363}, + dictWord{144, 10, 52}, + dictWord{134, 0, 1729}, + dictWord{6, 0, 1999}, + dictWord{136, 0, 969}, + dictWord{4, 10, 134}, + dictWord{133, 10, 372}, + dictWord{4, 0, 60}, + dictWord{7, 0, 941}, + dictWord{7, 0, 1800}, + dictWord{8, 0, 314}, + dictWord{ + 9, + 0, + 700, + }, + dictWord{139, 0, 487}, + dictWord{134, 0, 1144}, + dictWord{6, 11, 162}, + dictWord{7, 11, 1960}, + dictWord{136, 11, 831}, + dictWord{132, 11, 706}, + dictWord{135, 0, 1147}, + dictWord{138, 11, 426}, + dictWord{138, 11, 89}, + dictWord{7, 0, 1853}, + dictWord{138, 0, 437}, + dictWord{136, 0, 419}, + dictWord{ + 135, + 10, + 1634, + }, + dictWord{133, 0, 828}, + dictWord{5, 0, 806}, + dictWord{7, 0, 176}, + dictWord{7, 0, 178}, + dictWord{7, 0, 1240}, + dictWord{7, 0, 1976}, + dictWord{ + 132, + 10, + 644, + }, + dictWord{135, 11, 1877}, + dictWord{5, 11, 420}, + dictWord{135, 11, 1449}, + dictWord{4, 0, 51}, + dictWord{5, 0, 39}, + dictWord{6, 0, 4}, + dictWord{7, 0, 591}, + dictWord{7, 0, 849}, + dictWord{7, 0, 951}, + dictWord{7, 0, 1613}, + dictWord{7, 0, 1760}, + dictWord{7, 0, 1988}, + dictWord{9, 0, 434}, + dictWord{10, 0, 754}, + dictWord{ + 11, + 0, + 25, + }, + dictWord{139, 0, 37}, + dictWord{10, 11, 57}, + dictWord{138, 11, 277}, + dictWord{135, 10, 540}, + dictWord{132, 11, 204}, + dictWord{135, 0, 159}, + dictWord{139, 11, 231}, + dictWord{133, 0, 902}, + dictWord{7, 0, 928}, + dictWord{7, 11, 366}, + dictWord{9, 11, 287}, + dictWord{12, 11, 199}, + dictWord{12, 11, 556}, + dictWord{140, 11, 577}, + dictWord{6, 10, 623}, + dictWord{136, 10, 789}, + dictWord{4, 10, 908}, + dictWord{5, 10, 359}, + dictWord{5, 10, 508}, + dictWord{6, 10, 1723}, + dictWord{7, 10, 343}, + dictWord{7, 10, 1996}, + dictWord{135, 10, 2026}, + dictWord{134, 0, 270}, + dictWord{4, 10, 341}, + dictWord{135, 10, 480}, + dictWord{ + 5, + 11, + 356, + }, + dictWord{135, 11, 224}, + dictWord{11, 11, 588}, + dictWord{11, 11, 864}, + dictWord{11, 11, 968}, + dictWord{143, 11, 160}, + dictWord{132, 0, 556}, + dictWord{137, 0, 801}, + dictWord{132, 0, 416}, + dictWord{142, 0, 372}, + dictWord{5, 0, 152}, + dictWord{5, 0, 197}, + dictWord{7, 0, 340}, + dictWord{7, 0, 867}, + dictWord{ + 10, + 0, + 548, + }, + dictWord{10, 0, 581}, + dictWord{11, 0, 6}, + dictWord{12, 0, 3}, + dictWord{12, 0, 19}, + dictWord{14, 0, 110}, + dictWord{142, 0, 289}, + dictWord{139, 0, 369}, + dictWord{7, 11, 630}, + dictWord{9, 11, 567}, + dictWord{11, 11, 150}, + dictWord{11, 11, 444}, + dictWord{141, 11, 119}, + dictWord{134, 11, 539}, + dictWord{ + 7, + 10, + 1995, + }, + dictWord{8, 10, 299}, + dictWord{11, 10, 890}, + dictWord{140, 10, 674}, + dictWord{7, 0, 34}, + dictWord{7, 0, 190}, + dictWord{8, 0, 28}, + dictWord{8, 0, 141}, + dictWord{8, 0, 444}, + dictWord{8, 0, 811}, + dictWord{9, 0, 468}, + dictWord{11, 0, 334}, + dictWord{12, 0, 24}, + dictWord{12, 0, 386}, + dictWord{140, 0, 576}, + dictWord{ + 133, + 0, + 757, + }, + dictWord{7, 0, 1553}, + dictWord{136, 0, 898}, + dictWord{133, 0, 721}, + dictWord{136, 0, 1012}, + dictWord{4, 0, 789}, + dictWord{5, 0, 647}, + dictWord{ + 135, + 0, + 1102, + }, + dictWord{132, 0, 898}, + dictWord{10, 0, 183}, + dictWord{4, 10, 238}, + dictWord{5, 10, 503}, + dictWord{6, 10, 179}, + dictWord{7, 10, 2003}, + dictWord{ + 8, + 10, + 381, + }, + dictWord{8, 10, 473}, + dictWord{9, 10, 149}, + dictWord{10, 10, 788}, + dictWord{15, 10, 45}, + dictWord{15, 10, 86}, + dictWord{20, 10, 110}, + dictWord{ + 150, + 10, + 57, + }, + dictWord{9, 0, 136}, + dictWord{19, 0, 107}, + dictWord{4, 10, 121}, + dictWord{5, 10, 156}, + dictWord{5, 10, 349}, + dictWord{10, 10, 605}, + dictWord{ + 142, + 10, + 342, + }, + dictWord{4, 11, 235}, + dictWord{135, 11, 255}, + dictWord{4, 11, 194}, + dictWord{5, 11, 584}, + dictWord{6, 11, 384}, + dictWord{7, 11, 583}, + dictWord{ + 10, + 11, + 761, + }, + dictWord{11, 11, 760}, + dictWord{139, 11, 851}, + dictWord{6, 10, 80}, + dictWord{6, 10, 1694}, + dictWord{7, 10, 173}, + dictWord{7, 10, 1974}, + dictWord{ + 9, + 10, + 547, + }, + dictWord{10, 10, 730}, + dictWord{14, 10, 18}, + dictWord{150, 10, 39}, + dictWord{4, 10, 923}, + dictWord{134, 10, 1711}, + dictWord{5, 0, 277}, + dictWord{141, 0, 247}, + dictWord{132, 0, 435}, + dictWord{133, 11, 562}, + dictWord{134, 0, 1311}, + dictWord{5, 11, 191}, + dictWord{137, 11, 271}, + dictWord{ + 132, + 10, + 595, + }, + dictWord{7, 11, 1537}, + dictWord{14, 11, 96}, + dictWord{143, 11, 73}, + dictWord{5, 0, 437}, + dictWord{7, 0, 502}, + dictWord{7, 0, 519}, + dictWord{7, 0, 1122}, + dictWord{7, 0, 1751}, + dictWord{14, 0, 211}, + dictWord{6, 10, 459}, + dictWord{7, 10, 1753}, + dictWord{7, 10, 1805}, + dictWord{8, 10, 658}, + dictWord{9, 10, 1}, + dictWord{11, 10, 959}, + dictWord{141, 10, 446}, + dictWord{6, 0, 814}, + dictWord{4, 11, 470}, + dictWord{5, 11, 473}, + dictWord{6, 11, 153}, + dictWord{7, 11, 1503}, + dictWord{7, 11, 1923}, + dictWord{10, 11, 701}, + dictWord{11, 11, 132}, + dictWord{11, 11, 168}, + dictWord{11, 11, 227}, + dictWord{11, 11, 320}, + dictWord{ + 11, + 11, + 436, + }, + dictWord{11, 11, 525}, + dictWord{11, 11, 855}, + dictWord{12, 11, 41}, + dictWord{12, 11, 286}, + dictWord{13, 11, 103}, + dictWord{13, 11, 284}, + dictWord{ + 14, + 11, + 255, + }, + dictWord{14, 11, 262}, + dictWord{15, 11, 117}, + dictWord{143, 11, 127}, + dictWord{5, 0, 265}, + dictWord{6, 0, 212}, + dictWord{135, 0, 28}, + dictWord{ + 138, + 0, + 750, + }, + dictWord{133, 11, 327}, + dictWord{6, 11, 552}, + dictWord{7, 11, 1754}, + dictWord{137, 11, 604}, + dictWord{134, 0, 2012}, + dictWord{132, 0, 702}, + dictWord{5, 11, 80}, + dictWord{6, 11, 405}, + dictWord{7, 11, 403}, + dictWord{7, 11, 1502}, + dictWord{7, 11, 1626}, + dictWord{8, 11, 456}, + dictWord{9, 11, 487}, + dictWord{9, 11, 853}, + dictWord{9, 11, 889}, + dictWord{10, 11, 309}, + dictWord{11, 11, 721}, + dictWord{11, 11, 994}, + dictWord{12, 11, 430}, + dictWord{ + 141, + 11, + 165, + }, + dictWord{5, 0, 808}, + dictWord{135, 0, 2045}, + dictWord{5, 0, 166}, + dictWord{8, 0, 739}, + dictWord{140, 0, 511}, + dictWord{134, 10, 490}, + dictWord{ + 4, + 11, + 453, + }, + dictWord{5, 11, 887}, + dictWord{6, 11, 535}, + dictWord{8, 11, 6}, + dictWord{136, 11, 543}, + dictWord{4, 0, 119}, + dictWord{5, 0, 170}, + dictWord{5, 0, 447}, + dictWord{7, 0, 1708}, + dictWord{7, 0, 1889}, + dictWord{9, 0, 357}, + dictWord{9, 0, 719}, + dictWord{12, 0, 486}, + dictWord{140, 0, 596}, + dictWord{137, 0, 500}, + dictWord{ + 7, + 10, + 250, + }, + dictWord{136, 10, 507}, + dictWord{132, 10, 158}, + dictWord{6, 0, 809}, + dictWord{134, 0, 1500}, + dictWord{9, 0, 327}, + dictWord{11, 0, 350}, + dictWord{11, 0, 831}, + dictWord{13, 0, 352}, + dictWord{4, 10, 140}, + dictWord{7, 10, 362}, + dictWord{8, 10, 209}, + dictWord{9, 10, 10}, + dictWord{9, 10, 503}, + dictWord{ + 9, + 10, + 614, + }, + dictWord{10, 10, 689}, + dictWord{11, 10, 327}, + dictWord{11, 10, 725}, + dictWord{12, 10, 252}, + dictWord{12, 10, 583}, + dictWord{13, 10, 192}, + dictWord{14, 10, 269}, + dictWord{14, 10, 356}, + dictWord{148, 10, 50}, + dictWord{135, 11, 741}, + dictWord{4, 0, 450}, + dictWord{7, 0, 1158}, + dictWord{19, 10, 1}, + dictWord{19, 10, 26}, + dictWord{150, 10, 9}, + dictWord{6, 0, 597}, + dictWord{135, 0, 1318}, + dictWord{134, 0, 1602}, + dictWord{6, 10, 228}, + dictWord{7, 10, 1341}, + dictWord{9, 10, 408}, + dictWord{138, 10, 343}, + dictWord{7, 0, 1375}, + dictWord{7, 0, 1466}, + dictWord{138, 0, 331}, + dictWord{132, 0, 754}, + dictWord{ + 132, + 10, + 557, + }, + dictWord{5, 11, 101}, + dictWord{6, 11, 88}, + dictWord{6, 11, 543}, + dictWord{7, 11, 1677}, + dictWord{9, 11, 100}, + dictWord{10, 11, 677}, + dictWord{ + 14, + 11, + 169, + }, + dictWord{14, 11, 302}, + dictWord{14, 11, 313}, + dictWord{15, 11, 48}, + dictWord{143, 11, 84}, + dictWord{134, 0, 1368}, + dictWord{4, 11, 310}, + dictWord{ + 9, + 11, + 795, + }, + dictWord{10, 11, 733}, + dictWord{11, 11, 451}, + dictWord{12, 11, 249}, + dictWord{14, 11, 115}, + dictWord{14, 11, 286}, + dictWord{143, 11, 100}, + dictWord{132, 10, 548}, + dictWord{10, 0, 557}, + dictWord{7, 10, 197}, + dictWord{8, 10, 142}, + dictWord{8, 10, 325}, + dictWord{9, 10, 150}, + dictWord{9, 10, 596}, + dictWord{10, 10, 353}, + dictWord{11, 10, 74}, + dictWord{11, 10, 315}, + dictWord{12, 10, 662}, + dictWord{12, 10, 681}, + dictWord{14, 10, 423}, + dictWord{ + 143, + 10, + 141, + }, + dictWord{133, 11, 587}, + dictWord{5, 0, 850}, + dictWord{136, 0, 799}, + dictWord{10, 0, 908}, + dictWord{12, 0, 701}, + dictWord{12, 0, 757}, + dictWord{ + 142, + 0, + 466, + }, + dictWord{4, 0, 62}, + dictWord{5, 0, 275}, + dictWord{18, 0, 19}, + dictWord{6, 10, 399}, + dictWord{6, 10, 579}, + dictWord{7, 10, 692}, + dictWord{7, 10, 846}, + dictWord{ + 7, + 10, + 1015, + }, + dictWord{7, 10, 1799}, + dictWord{8, 10, 403}, + dictWord{9, 10, 394}, + dictWord{10, 10, 133}, + dictWord{12, 10, 4}, + dictWord{12, 10, 297}, + dictWord{12, 10, 452}, + dictWord{16, 10, 81}, + dictWord{18, 10, 25}, + dictWord{21, 10, 14}, + dictWord{22, 10, 12}, + dictWord{151, 10, 18}, + dictWord{12, 0, 459}, + dictWord{ + 7, + 10, + 1546, + }, + dictWord{11, 10, 299}, + dictWord{142, 10, 407}, + dictWord{132, 10, 177}, + dictWord{132, 11, 498}, + dictWord{7, 11, 217}, + dictWord{ + 8, + 11, + 140, + }, + dictWord{138, 11, 610}, + dictWord{5, 10, 411}, + dictWord{135, 10, 653}, + dictWord{134, 0, 1802}, + dictWord{7, 10, 439}, + dictWord{10, 10, 727}, + dictWord{11, 10, 260}, + dictWord{139, 10, 684}, + dictWord{133, 11, 905}, + dictWord{11, 11, 580}, + dictWord{142, 11, 201}, + dictWord{134, 0, 1397}, + dictWord{ + 5, + 10, + 208, + }, + dictWord{7, 10, 753}, + dictWord{135, 10, 1528}, + dictWord{7, 0, 238}, + dictWord{7, 0, 2033}, + dictWord{8, 0, 120}, + dictWord{8, 0, 188}, + dictWord{8, 0, 659}, + dictWord{9, 0, 598}, + dictWord{10, 0, 466}, + dictWord{12, 0, 342}, + dictWord{12, 0, 588}, + dictWord{13, 0, 503}, + dictWord{14, 0, 246}, + dictWord{143, 0, 92}, + dictWord{135, 11, 1041}, + dictWord{4, 11, 456}, + dictWord{7, 11, 105}, + dictWord{7, 11, 358}, + dictWord{7, 11, 1637}, + dictWord{8, 11, 643}, + dictWord{139, 11, 483}, + dictWord{6, 0, 1318}, + dictWord{134, 0, 1324}, + dictWord{4, 0, 201}, + dictWord{7, 0, 1744}, + dictWord{8, 0, 602}, + dictWord{11, 0, 247}, + dictWord{11, 0, 826}, + dictWord{17, 0, 65}, + dictWord{133, 10, 242}, + dictWord{8, 0, 164}, + dictWord{146, 0, 62}, + dictWord{133, 10, 953}, + dictWord{139, 10, 802}, + dictWord{133, 0, 615}, + dictWord{7, 11, 1566}, + dictWord{8, 11, 269}, + dictWord{9, 11, 212}, + dictWord{9, 11, 718}, + dictWord{14, 11, 15}, + dictWord{14, 11, 132}, + dictWord{142, 11, 227}, + dictWord{133, 10, 290}, + dictWord{132, 10, 380}, + dictWord{5, 10, 52}, + dictWord{7, 10, 277}, + dictWord{9, 10, 368}, + dictWord{139, 10, 791}, + dictWord{ + 135, + 0, + 1243, + }, + dictWord{133, 11, 539}, + dictWord{11, 11, 919}, + dictWord{141, 11, 409}, + dictWord{136, 0, 968}, + dictWord{133, 11, 470}, + dictWord{134, 0, 882}, + dictWord{132, 0, 907}, + dictWord{5, 0, 100}, + dictWord{10, 0, 329}, + dictWord{12, 0, 416}, + dictWord{149, 0, 29}, + dictWord{10, 10, 138}, + dictWord{139, 10, 476}, + dictWord{5, 10, 725}, + dictWord{5, 10, 727}, + dictWord{6, 11, 91}, + dictWord{7, 11, 435}, + dictWord{135, 10, 1811}, + dictWord{4, 11, 16}, + dictWord{5, 11, 316}, + dictWord{5, 11, 842}, + dictWord{6, 11, 370}, + dictWord{6, 11, 1778}, + dictWord{8, 11, 166}, + dictWord{11, 11, 812}, + dictWord{12, 11, 206}, + dictWord{12, 11, 351}, + dictWord{14, 11, 418}, + dictWord{16, 11, 15}, + dictWord{16, 11, 34}, + dictWord{18, 11, 3}, + dictWord{19, 11, 3}, + dictWord{19, 11, 7}, + dictWord{20, 11, 4}, + dictWord{ + 149, + 11, + 21, + }, + dictWord{132, 0, 176}, + dictWord{5, 0, 636}, + dictWord{5, 0, 998}, + dictWord{7, 0, 9}, + dictWord{7, 0, 1508}, + dictWord{8, 0, 26}, + dictWord{9, 0, 317}, + dictWord{ + 9, + 0, + 358, + }, + dictWord{10, 0, 210}, + dictWord{10, 0, 292}, + dictWord{10, 0, 533}, + dictWord{11, 0, 555}, + dictWord{12, 0, 526}, + dictWord{12, 0, 607}, + dictWord{ + 13, + 0, + 263, + }, + dictWord{13, 0, 459}, + dictWord{142, 0, 271}, + dictWord{6, 0, 256}, + dictWord{8, 0, 265}, + dictWord{4, 10, 38}, + dictWord{7, 10, 307}, + dictWord{7, 10, 999}, + dictWord{7, 10, 1481}, + dictWord{7, 10, 1732}, + dictWord{7, 10, 1738}, + dictWord{9, 10, 414}, + dictWord{11, 10, 316}, + dictWord{12, 10, 52}, + dictWord{13, 10, 420}, + dictWord{147, 10, 100}, + dictWord{135, 10, 1296}, + dictWord{4, 11, 611}, + dictWord{133, 11, 606}, + dictWord{4, 0, 643}, + dictWord{142, 11, 21}, + dictWord{ + 133, + 11, + 715, + }, + dictWord{133, 10, 723}, + dictWord{6, 0, 610}, + dictWord{135, 11, 597}, + dictWord{10, 0, 127}, + dictWord{141, 0, 27}, + dictWord{6, 0, 1995}, + dictWord{ + 6, + 0, + 2001, + }, + dictWord{8, 0, 119}, + dictWord{136, 0, 973}, + dictWord{4, 11, 149}, + dictWord{138, 11, 368}, + dictWord{12, 0, 522}, + dictWord{4, 11, 154}, + dictWord{ + 5, + 10, + 109, + }, + dictWord{6, 10, 1784}, + dictWord{7, 11, 1134}, + dictWord{7, 10, 1895}, + dictWord{8, 11, 105}, + dictWord{12, 10, 296}, + dictWord{140, 10, 302}, + dictWord{4, 11, 31}, + dictWord{6, 11, 429}, + dictWord{7, 11, 962}, + dictWord{9, 11, 458}, + dictWord{139, 11, 691}, + dictWord{10, 0, 553}, + dictWord{11, 0, 876}, + dictWord{13, 0, 193}, + dictWord{13, 0, 423}, + dictWord{14, 0, 166}, + dictWord{19, 0, 84}, + dictWord{4, 11, 312}, + dictWord{5, 10, 216}, + dictWord{7, 10, 1879}, + dictWord{ + 9, + 10, + 141, + }, + dictWord{9, 10, 270}, + dictWord{9, 10, 679}, + dictWord{10, 10, 159}, + dictWord{11, 10, 197}, + dictWord{12, 10, 538}, + dictWord{12, 10, 559}, + dictWord{14, 10, 144}, + dictWord{14, 10, 167}, + dictWord{143, 10, 67}, + dictWord{134, 0, 1582}, + dictWord{7, 0, 1578}, + dictWord{135, 11, 1578}, + dictWord{ + 137, + 10, + 81, + }, + dictWord{132, 11, 236}, + dictWord{134, 10, 391}, + dictWord{134, 0, 795}, + dictWord{7, 10, 322}, + dictWord{136, 10, 249}, + dictWord{5, 11, 836}, + dictWord{ + 5, + 11, + 857, + }, + dictWord{6, 11, 1680}, + dictWord{7, 11, 59}, + dictWord{147, 11, 53}, + dictWord{135, 0, 432}, + dictWord{10, 11, 68}, + dictWord{139, 11, 494}, + dictWord{4, 11, 81}, + dictWord{139, 11, 867}, + dictWord{7, 0, 126}, + dictWord{136, 0, 84}, + dictWord{142, 11, 280}, + dictWord{5, 11, 282}, + dictWord{8, 11, 650}, + dictWord{ + 9, + 11, + 295, + }, + dictWord{9, 11, 907}, + dictWord{138, 11, 443}, + dictWord{136, 0, 790}, + dictWord{5, 10, 632}, + dictWord{138, 10, 526}, + dictWord{6, 0, 64}, + dictWord{12, 0, 377}, + dictWord{13, 0, 309}, + dictWord{14, 0, 141}, + dictWord{14, 0, 429}, + dictWord{14, 11, 141}, + dictWord{142, 11, 429}, + dictWord{134, 0, 1529}, + dictWord{6, 0, 321}, + dictWord{7, 0, 1857}, + dictWord{9, 0, 530}, + dictWord{19, 0, 99}, + dictWord{7, 10, 948}, + dictWord{7, 10, 1042}, + dictWord{8, 10, 235}, + dictWord{ + 8, + 10, + 461, + }, + dictWord{9, 10, 453}, + dictWord{10, 10, 354}, + dictWord{145, 10, 77}, + dictWord{7, 0, 1104}, + dictWord{11, 0, 269}, + dictWord{11, 0, 539}, + dictWord{ + 11, + 0, + 627, + }, + dictWord{11, 0, 706}, + dictWord{11, 0, 975}, + dictWord{12, 0, 248}, + dictWord{12, 0, 434}, + dictWord{12, 0, 600}, + dictWord{12, 0, 622}, + dictWord{ + 13, + 0, + 297, + }, + dictWord{13, 0, 485}, + dictWord{14, 0, 69}, + dictWord{14, 0, 409}, + dictWord{143, 0, 108}, + dictWord{4, 10, 362}, + dictWord{7, 10, 52}, + dictWord{7, 10, 303}, + dictWord{10, 11, 70}, + dictWord{12, 11, 26}, + dictWord{14, 11, 17}, + dictWord{14, 11, 178}, + dictWord{15, 11, 34}, + dictWord{149, 11, 12}, + dictWord{11, 0, 977}, + dictWord{141, 0, 507}, + dictWord{9, 0, 34}, + dictWord{139, 0, 484}, + dictWord{5, 10, 196}, + dictWord{6, 10, 486}, + dictWord{7, 10, 212}, + dictWord{8, 10, 309}, + dictWord{136, 10, 346}, + dictWord{6, 0, 1700}, + dictWord{7, 0, 26}, + dictWord{7, 0, 293}, + dictWord{7, 0, 382}, + dictWord{7, 0, 1026}, + dictWord{7, 0, 1087}, + dictWord{ + 7, + 0, + 2027, + }, + dictWord{8, 0, 24}, + dictWord{8, 0, 114}, + dictWord{8, 0, 252}, + dictWord{8, 0, 727}, + dictWord{8, 0, 729}, + dictWord{9, 0, 30}, + dictWord{9, 0, 199}, + dictWord{ + 9, + 0, + 231, + }, + dictWord{9, 0, 251}, + dictWord{9, 0, 334}, + dictWord{9, 0, 361}, + dictWord{9, 0, 712}, + dictWord{10, 0, 55}, + dictWord{10, 0, 60}, + dictWord{10, 0, 232}, + dictWord{ + 10, + 0, + 332, + }, + dictWord{10, 0, 384}, + dictWord{10, 0, 396}, + dictWord{10, 0, 504}, + dictWord{10, 0, 542}, + dictWord{10, 0, 652}, + dictWord{11, 0, 20}, + dictWord{11, 0, 48}, + dictWord{11, 0, 207}, + dictWord{11, 0, 291}, + dictWord{11, 0, 298}, + dictWord{11, 0, 342}, + dictWord{11, 0, 365}, + dictWord{11, 0, 394}, + dictWord{11, 0, 620}, + dictWord{11, 0, 705}, + dictWord{11, 0, 1017}, + dictWord{12, 0, 123}, + dictWord{12, 0, 340}, + dictWord{12, 0, 406}, + dictWord{12, 0, 643}, + dictWord{13, 0, 61}, + dictWord{ + 13, + 0, + 269, + }, + dictWord{13, 0, 311}, + dictWord{13, 0, 319}, + dictWord{13, 0, 486}, + dictWord{14, 0, 234}, + dictWord{15, 0, 62}, + dictWord{15, 0, 85}, + dictWord{16, 0, 71}, + dictWord{18, 0, 119}, + dictWord{20, 0, 105}, + dictWord{135, 10, 1912}, + dictWord{4, 11, 71}, + dictWord{5, 11, 376}, + dictWord{7, 11, 119}, + dictWord{138, 11, 665}, + dictWord{10, 0, 918}, + dictWord{10, 0, 926}, + dictWord{4, 10, 686}, + dictWord{136, 11, 55}, + dictWord{138, 10, 625}, + dictWord{136, 10, 706}, + dictWord{ + 132, + 11, + 479, + }, + dictWord{4, 10, 30}, + dictWord{133, 10, 43}, + dictWord{6, 0, 379}, + dictWord{7, 0, 270}, + dictWord{8, 0, 176}, + dictWord{8, 0, 183}, + dictWord{9, 0, 432}, + dictWord{ + 9, + 0, + 661, + }, + dictWord{12, 0, 247}, + dictWord{12, 0, 617}, + dictWord{18, 0, 125}, + dictWord{7, 11, 607}, + dictWord{8, 11, 99}, + dictWord{152, 11, 4}, + dictWord{ + 5, + 0, + 792, + }, + dictWord{133, 0, 900}, + dictWord{4, 11, 612}, + dictWord{133, 11, 561}, + dictWord{4, 11, 41}, + dictWord{4, 10, 220}, + dictWord{5, 11, 74}, + dictWord{ + 7, + 10, + 1535, + }, + dictWord{7, 11, 1627}, + dictWord{11, 11, 871}, + dictWord{140, 11, 619}, + dictWord{135, 0, 1920}, + dictWord{7, 11, 94}, + dictWord{11, 11, 329}, + dictWord{11, 11, 965}, + dictWord{12, 11, 241}, + dictWord{14, 11, 354}, + dictWord{15, 11, 22}, + dictWord{148, 11, 63}, + dictWord{9, 11, 209}, + dictWord{137, 11, 300}, + dictWord{134, 0, 771}, + dictWord{135, 0, 1979}, + dictWord{4, 0, 901}, + dictWord{133, 0, 776}, + dictWord{142, 0, 254}, + dictWord{133, 11, 98}, + dictWord{ + 9, + 11, + 16, + }, + dictWord{141, 11, 386}, + dictWord{133, 11, 984}, + dictWord{4, 11, 182}, + dictWord{6, 11, 205}, + dictWord{135, 11, 220}, + dictWord{7, 10, 1725}, + dictWord{ + 7, + 10, + 1774, + }, + dictWord{138, 10, 393}, + dictWord{5, 10, 263}, + dictWord{134, 10, 414}, + dictWord{4, 11, 42}, + dictWord{9, 11, 205}, + dictWord{9, 11, 786}, + dictWord{138, 11, 659}, + dictWord{14, 0, 140}, + dictWord{148, 0, 41}, + dictWord{8, 0, 440}, + dictWord{10, 0, 359}, + dictWord{6, 10, 178}, + dictWord{6, 11, 289}, + dictWord{ + 6, + 10, + 1750, + }, + dictWord{7, 11, 1670}, + dictWord{9, 10, 690}, + dictWord{10, 10, 155}, + dictWord{10, 10, 373}, + dictWord{11, 10, 698}, + dictWord{12, 11, 57}, + dictWord{13, 10, 155}, + dictWord{20, 10, 93}, + dictWord{151, 11, 4}, + dictWord{4, 0, 37}, + dictWord{5, 0, 334}, + dictWord{7, 0, 1253}, + dictWord{151, 11, 25}, + dictWord{ + 4, + 0, + 508, + }, + dictWord{4, 11, 635}, + dictWord{5, 10, 97}, + dictWord{137, 10, 393}, + dictWord{139, 11, 533}, + dictWord{4, 0, 640}, + dictWord{133, 0, 513}, + dictWord{ + 134, + 10, + 1639, + }, + dictWord{132, 11, 371}, + dictWord{4, 11, 272}, + dictWord{7, 11, 836}, + dictWord{7, 11, 1651}, + dictWord{145, 11, 89}, + dictWord{5, 11, 825}, + dictWord{6, 11, 444}, + dictWord{6, 11, 1640}, + dictWord{136, 11, 308}, + dictWord{4, 10, 191}, + dictWord{7, 10, 934}, + dictWord{8, 10, 647}, + dictWord{145, 10, 97}, + dictWord{12, 0, 246}, + dictWord{15, 0, 162}, + dictWord{19, 0, 64}, + dictWord{20, 0, 8}, + dictWord{20, 0, 95}, + dictWord{22, 0, 24}, + dictWord{152, 0, 17}, + dictWord{4, 0, 533}, + dictWord{5, 10, 165}, + dictWord{9, 10, 346}, + dictWord{138, 10, 655}, + dictWord{5, 11, 737}, + dictWord{139, 10, 885}, + dictWord{133, 10, 877}, + dictWord{ + 8, + 10, + 128, + }, + dictWord{139, 10, 179}, + dictWord{137, 11, 307}, + dictWord{140, 0, 752}, + dictWord{133, 0, 920}, + dictWord{135, 0, 1048}, + dictWord{5, 0, 153}, + dictWord{ + 6, + 0, + 580, + }, + dictWord{6, 10, 1663}, + dictWord{7, 10, 132}, + dictWord{7, 10, 1154}, + dictWord{7, 10, 1415}, + dictWord{7, 10, 1507}, + dictWord{12, 10, 493}, + dictWord{15, 10, 105}, + dictWord{151, 10, 15}, + dictWord{5, 10, 459}, + dictWord{7, 10, 1073}, + dictWord{8, 10, 241}, + dictWord{136, 10, 334}, + dictWord{138, 0, 391}, + dictWord{135, 0, 1952}, + dictWord{133, 11, 525}, + dictWord{8, 11, 641}, + dictWord{11, 11, 388}, + dictWord{140, 11, 580}, + dictWord{142, 0, 126}, + dictWord{ + 134, + 0, + 640, + }, + dictWord{132, 0, 483}, + dictWord{7, 0, 1616}, + dictWord{9, 0, 69}, + dictWord{6, 10, 324}, + dictWord{6, 10, 520}, + dictWord{7, 10, 338}, + dictWord{ + 7, + 10, + 1729, + }, + dictWord{8, 10, 228}, + dictWord{139, 10, 750}, + dictWord{5, 11, 493}, + dictWord{134, 11, 528}, + dictWord{135, 0, 734}, + dictWord{4, 11, 174}, + dictWord{135, 11, 911}, + dictWord{138, 0, 480}, + dictWord{9, 0, 495}, + dictWord{146, 0, 104}, + dictWord{135, 10, 705}, + dictWord{9, 0, 472}, + dictWord{4, 10, 73}, + dictWord{6, 10, 612}, + dictWord{7, 10, 927}, + dictWord{7, 10, 1330}, + dictWord{7, 10, 1822}, + dictWord{8, 10, 217}, + dictWord{9, 10, 765}, + dictWord{9, 10, 766}, + dictWord{10, 10, 408}, + dictWord{11, 10, 51}, + dictWord{11, 10, 793}, + dictWord{12, 10, 266}, + dictWord{15, 10, 158}, + dictWord{20, 10, 89}, + dictWord{150, 10, 32}, + dictWord{7, 11, 548}, + dictWord{137, 11, 58}, + dictWord{4, 11, 32}, + dictWord{5, 11, 215}, + dictWord{6, 11, 269}, + dictWord{7, 11, 1782}, + dictWord{7, 11, 1892}, + dictWord{10, 11, 16}, + dictWord{11, 11, 822}, + dictWord{11, 11, 954}, + dictWord{141, 11, 481}, + dictWord{132, 0, 874}, + dictWord{9, 0, 229}, + dictWord{5, 10, 389}, + dictWord{136, 10, 636}, + dictWord{7, 11, 1749}, + dictWord{136, 11, 477}, + dictWord{134, 0, 948}, + dictWord{5, 11, 308}, + dictWord{135, 11, 1088}, + dictWord{ + 4, + 0, + 748, + }, + dictWord{139, 0, 1009}, + dictWord{136, 10, 21}, + dictWord{6, 0, 555}, + dictWord{135, 0, 485}, + dictWord{5, 11, 126}, + dictWord{8, 11, 297}, + dictWord{ + 9, + 11, + 366, + }, + dictWord{9, 11, 445}, + dictWord{12, 11, 53}, + dictWord{12, 11, 374}, + dictWord{141, 11, 492}, + dictWord{7, 11, 1551}, + dictWord{139, 11, 361}, + dictWord{136, 0, 193}, + dictWord{136, 0, 472}, + dictWord{8, 0, 653}, + dictWord{13, 0, 93}, + dictWord{147, 0, 14}, + dictWord{132, 0, 984}, + dictWord{132, 11, 175}, + dictWord{5, 0, 172}, + dictWord{6, 0, 1971}, + dictWord{132, 11, 685}, + dictWord{149, 11, 8}, + dictWord{133, 11, 797}, + dictWord{13, 0, 83}, + dictWord{5, 10, 189}, + dictWord{ + 7, + 10, + 442, + }, + dictWord{7, 10, 443}, + dictWord{8, 10, 281}, + dictWord{12, 10, 174}, + dictWord{141, 10, 261}, + dictWord{134, 0, 1568}, + dictWord{133, 11, 565}, + dictWord{139, 0, 384}, + dictWord{133, 0, 260}, + dictWord{7, 0, 758}, + dictWord{7, 0, 880}, + dictWord{7, 0, 1359}, + dictWord{9, 0, 164}, + dictWord{9, 0, 167}, + dictWord{ + 10, + 0, + 156, + }, + dictWord{10, 0, 588}, + dictWord{12, 0, 101}, + dictWord{14, 0, 48}, + dictWord{15, 0, 70}, + dictWord{6, 10, 2}, + dictWord{7, 10, 1262}, + dictWord{ + 7, + 10, + 1737, + }, + dictWord{8, 10, 22}, + dictWord{8, 10, 270}, + dictWord{8, 10, 612}, + dictWord{9, 10, 312}, + dictWord{9, 10, 436}, + dictWord{10, 10, 311}, + dictWord{ + 10, + 10, + 623, + }, + dictWord{11, 10, 72}, + dictWord{11, 10, 330}, + dictWord{11, 10, 455}, + dictWord{12, 10, 321}, + dictWord{12, 10, 504}, + dictWord{12, 10, 530}, + dictWord{ + 12, + 10, + 543, + }, + dictWord{13, 10, 17}, + dictWord{13, 10, 156}, + dictWord{13, 10, 334}, + dictWord{17, 10, 60}, + dictWord{148, 10, 64}, + dictWord{4, 11, 252}, + dictWord{ + 7, + 11, + 1068, + }, + dictWord{10, 11, 434}, + dictWord{11, 11, 228}, + dictWord{11, 11, 426}, + dictWord{13, 11, 231}, + dictWord{18, 11, 106}, + dictWord{148, 11, 87}, + dictWord{7, 10, 354}, + dictWord{10, 10, 410}, + dictWord{139, 10, 815}, + dictWord{6, 0, 367}, + dictWord{7, 10, 670}, + dictWord{7, 10, 1327}, + dictWord{8, 10, 411}, + dictWord{8, 10, 435}, + dictWord{9, 10, 653}, + dictWord{9, 10, 740}, + dictWord{10, 10, 385}, + dictWord{11, 10, 222}, + dictWord{11, 10, 324}, + dictWord{11, 10, 829}, + dictWord{140, 10, 611}, + dictWord{7, 0, 1174}, + dictWord{6, 10, 166}, + dictWord{135, 10, 374}, + dictWord{146, 0, 121}, + dictWord{132, 0, 828}, + dictWord{ + 5, + 11, + 231, + }, + dictWord{138, 11, 509}, + dictWord{7, 11, 601}, + dictWord{9, 11, 277}, + dictWord{9, 11, 674}, + dictWord{10, 11, 178}, + dictWord{10, 11, 257}, + dictWord{ + 10, + 11, + 418, + }, + dictWord{11, 11, 531}, + dictWord{11, 11, 544}, + dictWord{11, 11, 585}, + dictWord{12, 11, 113}, + dictWord{12, 11, 475}, + dictWord{13, 11, 99}, + dictWord{142, 11, 428}, + dictWord{134, 0, 1541}, + dictWord{135, 11, 1779}, + dictWord{5, 0, 343}, + dictWord{134, 10, 398}, + dictWord{135, 10, 50}, + dictWord{ + 135, + 11, + 1683, + }, + dictWord{4, 0, 440}, + dictWord{7, 0, 57}, + dictWord{8, 0, 167}, + dictWord{8, 0, 375}, + dictWord{9, 0, 82}, + dictWord{9, 0, 561}, + dictWord{9, 0, 744}, + dictWord{ + 10, + 0, + 620, + }, + dictWord{137, 11, 744}, + dictWord{134, 0, 926}, + dictWord{6, 10, 517}, + dictWord{7, 10, 1159}, + dictWord{10, 10, 621}, + dictWord{139, 10, 192}, + dictWord{137, 0, 827}, + dictWord{8, 0, 194}, + dictWord{136, 0, 756}, + dictWord{10, 10, 223}, + dictWord{139, 10, 645}, + dictWord{7, 10, 64}, + dictWord{ + 136, + 10, + 245, + }, + dictWord{4, 11, 399}, + dictWord{5, 11, 119}, + dictWord{5, 11, 494}, + dictWord{7, 11, 751}, + dictWord{137, 11, 556}, + dictWord{132, 0, 808}, + dictWord{ + 135, + 0, + 22, + }, + dictWord{7, 10, 1763}, + dictWord{140, 10, 310}, + dictWord{5, 0, 639}, + dictWord{7, 0, 1249}, + dictWord{11, 0, 896}, + dictWord{134, 11, 584}, + dictWord{ + 134, + 0, + 1614, + }, + dictWord{135, 0, 860}, + dictWord{135, 11, 1121}, + dictWord{5, 10, 129}, + dictWord{6, 10, 61}, + dictWord{135, 10, 947}, + dictWord{4, 0, 102}, + dictWord{ + 7, + 0, + 815, + }, + dictWord{7, 0, 1699}, + dictWord{139, 0, 964}, + dictWord{13, 10, 505}, + dictWord{141, 10, 506}, + dictWord{139, 10, 1000}, + dictWord{ + 132, + 11, + 679, + }, + dictWord{132, 0, 899}, + dictWord{132, 0, 569}, + dictWord{5, 11, 694}, + dictWord{137, 11, 714}, + dictWord{136, 0, 795}, + dictWord{6, 0, 2045}, + dictWord{ + 139, + 11, + 7, + }, + dictWord{6, 0, 52}, + dictWord{9, 0, 104}, + dictWord{9, 0, 559}, + dictWord{12, 0, 308}, + dictWord{147, 0, 87}, + dictWord{4, 0, 301}, + dictWord{132, 0, 604}, + dictWord{133, 10, 637}, + dictWord{136, 0, 779}, + dictWord{5, 11, 143}, + dictWord{5, 11, 769}, + dictWord{6, 11, 1760}, + dictWord{7, 11, 682}, + dictWord{7, 11, 1992}, + dictWord{136, 11, 736}, + dictWord{137, 10, 590}, + dictWord{147, 0, 32}, + dictWord{137, 11, 527}, + dictWord{5, 10, 280}, + dictWord{135, 10, 1226}, + dictWord{134, 0, 494}, + dictWord{6, 0, 677}, + dictWord{6, 0, 682}, + dictWord{134, 0, 1044}, + dictWord{133, 10, 281}, + dictWord{135, 10, 1064}, + dictWord{7, 0, 508}, + dictWord{133, 11, 860}, + dictWord{6, 11, 422}, + dictWord{7, 11, 0}, + dictWord{7, 11, 1544}, + dictWord{9, 11, 577}, + dictWord{11, 11, 990}, + dictWord{12, 11, 141}, + dictWord{12, 11, 453}, + dictWord{13, 11, 47}, + dictWord{141, 11, 266}, + dictWord{134, 0, 1014}, + dictWord{5, 11, 515}, + dictWord{137, 11, 131}, + dictWord{ + 134, + 0, + 957, + }, + dictWord{132, 11, 646}, + dictWord{6, 0, 310}, + dictWord{7, 0, 1849}, + dictWord{8, 0, 72}, + dictWord{8, 0, 272}, + dictWord{8, 0, 431}, + dictWord{9, 0, 12}, + dictWord{ + 9, + 0, + 376, + }, + dictWord{10, 0, 563}, + dictWord{10, 0, 630}, + dictWord{10, 0, 796}, + dictWord{10, 0, 810}, + dictWord{11, 0, 367}, + dictWord{11, 0, 599}, + dictWord{ + 11, + 0, + 686, + }, + dictWord{140, 0, 672}, + dictWord{7, 0, 570}, + dictWord{4, 11, 396}, + dictWord{7, 10, 120}, + dictWord{7, 11, 728}, + dictWord{8, 10, 489}, + dictWord{9, 11, 117}, + dictWord{9, 10, 319}, + dictWord{10, 10, 820}, + dictWord{11, 10, 1004}, + dictWord{12, 10, 379}, + dictWord{12, 10, 679}, + dictWord{13, 10, 117}, + dictWord{ + 13, + 11, + 202, + }, + dictWord{13, 10, 412}, + dictWord{14, 10, 25}, + dictWord{15, 10, 52}, + dictWord{15, 10, 161}, + dictWord{16, 10, 47}, + dictWord{20, 11, 51}, + dictWord{ + 149, + 10, + 2, + }, + dictWord{6, 11, 121}, + dictWord{6, 11, 124}, + dictWord{6, 11, 357}, + dictWord{7, 11, 1138}, + dictWord{7, 11, 1295}, + dictWord{8, 11, 162}, + dictWord{ + 139, + 11, + 655, + }, + dictWord{8, 0, 449}, + dictWord{4, 10, 937}, + dictWord{5, 10, 801}, + dictWord{136, 11, 449}, + dictWord{139, 11, 958}, + dictWord{6, 0, 181}, + dictWord{ + 7, + 0, + 537, + }, + dictWord{8, 0, 64}, + dictWord{9, 0, 127}, + dictWord{10, 0, 496}, + dictWord{12, 0, 510}, + dictWord{141, 0, 384}, + dictWord{138, 11, 253}, + dictWord{4, 0, 244}, + dictWord{135, 0, 233}, + dictWord{133, 11, 237}, + dictWord{132, 10, 365}, + dictWord{6, 0, 1650}, + dictWord{10, 0, 702}, + dictWord{139, 0, 245}, + dictWord{ + 5, + 10, + 7, + }, + dictWord{139, 10, 774}, + dictWord{13, 0, 463}, + dictWord{20, 0, 49}, + dictWord{13, 11, 463}, + dictWord{148, 11, 49}, + dictWord{4, 10, 734}, + dictWord{ + 5, + 10, + 662, + }, + dictWord{134, 10, 430}, + dictWord{4, 10, 746}, + dictWord{135, 10, 1090}, + dictWord{5, 10, 360}, + dictWord{136, 10, 237}, + dictWord{137, 0, 338}, + dictWord{143, 11, 10}, + dictWord{7, 11, 571}, + dictWord{138, 11, 366}, + dictWord{134, 0, 1279}, + dictWord{9, 11, 513}, + dictWord{10, 11, 22}, + dictWord{10, 11, 39}, + dictWord{12, 11, 122}, + dictWord{140, 11, 187}, + dictWord{133, 0, 896}, + dictWord{146, 0, 178}, + dictWord{134, 0, 695}, + dictWord{137, 0, 808}, + dictWord{ + 134, + 11, + 587, + }, + dictWord{7, 11, 107}, + dictWord{7, 11, 838}, + dictWord{8, 11, 550}, + dictWord{138, 11, 401}, + dictWord{7, 0, 1117}, + dictWord{136, 0, 539}, + dictWord{ + 4, + 10, + 277, + }, + dictWord{5, 10, 608}, + dictWord{6, 10, 493}, + dictWord{7, 10, 457}, + dictWord{140, 10, 384}, + dictWord{133, 11, 768}, + dictWord{12, 0, 257}, + dictWord{ + 7, + 10, + 27, + }, + dictWord{135, 10, 316}, + dictWord{140, 0, 1003}, + dictWord{4, 0, 207}, + dictWord{5, 0, 586}, + dictWord{5, 0, 676}, + dictWord{6, 0, 448}, + dictWord{ + 8, + 0, + 244, + }, + dictWord{11, 0, 1}, + dictWord{13, 0, 3}, + dictWord{16, 0, 54}, + dictWord{17, 0, 4}, + dictWord{18, 0, 13}, + dictWord{133, 10, 552}, + dictWord{4, 10, 401}, + dictWord{ + 137, + 10, + 264, + }, + dictWord{5, 0, 516}, + dictWord{7, 0, 1883}, + dictWord{135, 11, 1883}, + dictWord{12, 0, 960}, + dictWord{132, 11, 894}, + dictWord{5, 0, 4}, + dictWord{ + 5, + 0, + 810, + }, + dictWord{6, 0, 13}, + dictWord{6, 0, 538}, + dictWord{6, 0, 1690}, + dictWord{6, 0, 1726}, + dictWord{7, 0, 499}, + dictWord{7, 0, 1819}, + dictWord{8, 0, 148}, + dictWord{ + 8, + 0, + 696, + }, + dictWord{8, 0, 791}, + dictWord{12, 0, 125}, + dictWord{143, 0, 9}, + dictWord{135, 0, 1268}, + dictWord{11, 0, 30}, + dictWord{14, 0, 315}, + dictWord{ + 9, + 10, + 543, + }, + dictWord{10, 10, 524}, + dictWord{12, 10, 524}, + dictWord{16, 10, 18}, + dictWord{20, 10, 26}, + dictWord{148, 10, 65}, + dictWord{6, 0, 748}, + dictWord{ + 4, + 10, + 205, + }, + dictWord{5, 10, 623}, + dictWord{7, 10, 104}, + dictWord{136, 10, 519}, + dictWord{11, 0, 542}, + dictWord{139, 0, 852}, + dictWord{140, 0, 6}, + dictWord{ + 132, + 0, + 848, + }, + dictWord{7, 0, 1385}, + dictWord{11, 0, 582}, + dictWord{11, 0, 650}, + dictWord{11, 0, 901}, + dictWord{11, 0, 949}, + dictWord{12, 0, 232}, + dictWord{12, 0, 236}, + dictWord{13, 0, 413}, + dictWord{13, 0, 501}, + dictWord{18, 0, 116}, + dictWord{7, 10, 579}, + dictWord{9, 10, 41}, + dictWord{9, 10, 244}, + dictWord{9, 10, 669}, + dictWord{10, 10, 5}, + dictWord{11, 10, 861}, + dictWord{11, 10, 951}, + dictWord{139, 10, 980}, + dictWord{4, 0, 945}, + dictWord{6, 0, 1811}, + dictWord{6, 0, 1845}, + dictWord{ + 6, + 0, + 1853, + }, + dictWord{6, 0, 1858}, + dictWord{8, 0, 862}, + dictWord{12, 0, 782}, + dictWord{12, 0, 788}, + dictWord{18, 0, 160}, + dictWord{148, 0, 117}, + dictWord{ + 132, + 10, + 717, + }, + dictWord{4, 0, 925}, + dictWord{5, 0, 803}, + dictWord{8, 0, 698}, + dictWord{138, 0, 828}, + dictWord{134, 0, 1416}, + dictWord{132, 0, 610}, + dictWord{ + 139, + 0, + 992, + }, + dictWord{6, 0, 878}, + dictWord{134, 0, 1477}, + dictWord{135, 0, 1847}, + dictWord{138, 11, 531}, + dictWord{137, 11, 539}, + dictWord{134, 11, 272}, + dictWord{133, 0, 383}, + dictWord{134, 0, 1404}, + dictWord{132, 10, 489}, + dictWord{4, 11, 9}, + dictWord{5, 11, 128}, + dictWord{7, 11, 368}, + dictWord{ + 11, + 11, + 480, + }, + dictWord{148, 11, 3}, + dictWord{136, 0, 986}, + dictWord{9, 0, 660}, + dictWord{138, 0, 347}, + dictWord{135, 10, 892}, + dictWord{136, 11, 682}, + dictWord{ + 7, + 0, + 572, + }, + dictWord{9, 0, 592}, + dictWord{11, 0, 680}, + dictWord{12, 0, 356}, + dictWord{140, 0, 550}, + dictWord{7, 0, 1411}, + dictWord{138, 11, 527}, + dictWord{ + 4, + 11, + 2, + }, + dictWord{7, 11, 545}, + dictWord{135, 11, 894}, + dictWord{137, 10, 473}, + dictWord{11, 0, 64}, + dictWord{7, 11, 481}, + dictWord{7, 10, 819}, + dictWord{9, 10, 26}, + dictWord{9, 10, 392}, + dictWord{9, 11, 792}, + dictWord{10, 10, 152}, + dictWord{10, 10, 226}, + dictWord{12, 10, 276}, + dictWord{12, 10, 426}, + dictWord{ + 12, + 10, + 589, + }, + dictWord{13, 10, 460}, + dictWord{15, 10, 97}, + dictWord{19, 10, 48}, + dictWord{148, 10, 104}, + dictWord{135, 10, 51}, + dictWord{136, 11, 445}, + dictWord{136, 11, 646}, + dictWord{135, 0, 606}, + dictWord{132, 10, 674}, + dictWord{6, 0, 1829}, + dictWord{134, 0, 1830}, + dictWord{132, 10, 770}, + dictWord{ + 5, + 10, + 79, + }, + dictWord{7, 10, 1027}, + dictWord{7, 10, 1477}, + dictWord{139, 10, 52}, + dictWord{5, 11, 530}, + dictWord{142, 11, 113}, + dictWord{134, 10, 1666}, + dictWord{ + 7, + 0, + 748, + }, + dictWord{139, 0, 700}, + dictWord{134, 10, 195}, + dictWord{133, 10, 789}, + dictWord{9, 0, 87}, + dictWord{10, 0, 365}, + dictWord{4, 10, 251}, + dictWord{ + 4, + 10, + 688, + }, + dictWord{7, 10, 513}, + dictWord{135, 10, 1284}, + dictWord{136, 11, 111}, + dictWord{133, 0, 127}, + dictWord{6, 0, 198}, + dictWord{140, 0, 83}, + dictWord{133, 11, 556}, + dictWord{133, 10, 889}, + dictWord{4, 10, 160}, + dictWord{5, 10, 330}, + dictWord{7, 10, 1434}, + dictWord{136, 10, 174}, + dictWord{5, 0, 276}, + dictWord{6, 0, 55}, + dictWord{7, 0, 1369}, + dictWord{138, 0, 864}, + dictWord{8, 11, 16}, + dictWord{140, 11, 568}, + dictWord{6, 0, 1752}, + dictWord{136, 0, 726}, + dictWord{135, 0, 1066}, + dictWord{133, 0, 764}, + dictWord{6, 11, 186}, + dictWord{137, 11, 426}, + dictWord{11, 0, 683}, + dictWord{139, 11, 683}, + dictWord{ + 6, + 0, + 309, + }, + dictWord{7, 0, 331}, + dictWord{138, 0, 550}, + dictWord{133, 10, 374}, + dictWord{6, 0, 1212}, + dictWord{6, 0, 1852}, + dictWord{7, 0, 1062}, + dictWord{ + 8, + 0, + 874, + }, + dictWord{8, 0, 882}, + dictWord{138, 0, 936}, + dictWord{132, 11, 585}, + dictWord{134, 0, 1364}, + dictWord{7, 0, 986}, + dictWord{133, 10, 731}, + dictWord{ + 6, + 0, + 723, + }, + dictWord{6, 0, 1408}, + dictWord{138, 0, 381}, + dictWord{135, 0, 1573}, + dictWord{134, 0, 1025}, + dictWord{4, 10, 626}, + dictWord{5, 10, 642}, + dictWord{ + 6, + 10, + 425, + }, + dictWord{10, 10, 202}, + dictWord{139, 10, 141}, + dictWord{4, 11, 93}, + dictWord{5, 11, 252}, + dictWord{6, 11, 229}, + dictWord{7, 11, 291}, + dictWord{ + 9, + 11, + 550, + }, + dictWord{139, 11, 644}, + dictWord{137, 11, 749}, + dictWord{137, 11, 162}, + dictWord{132, 11, 381}, + dictWord{135, 0, 1559}, + dictWord{ + 6, + 0, + 194, + }, + dictWord{7, 0, 133}, + dictWord{10, 0, 493}, + dictWord{10, 0, 570}, + dictWord{139, 0, 664}, + dictWord{5, 0, 24}, + dictWord{5, 0, 569}, + dictWord{6, 0, 3}, + dictWord{ + 6, + 0, + 119, + }, + dictWord{6, 0, 143}, + dictWord{6, 0, 440}, + dictWord{7, 0, 295}, + dictWord{7, 0, 599}, + dictWord{7, 0, 1686}, + dictWord{7, 0, 1854}, + dictWord{8, 0, 424}, + dictWord{ + 9, + 0, + 43, + }, + dictWord{9, 0, 584}, + dictWord{9, 0, 760}, + dictWord{10, 0, 148}, + dictWord{10, 0, 328}, + dictWord{11, 0, 159}, + dictWord{11, 0, 253}, + dictWord{11, 0, 506}, + dictWord{12, 0, 487}, + dictWord{140, 0, 531}, + dictWord{6, 0, 661}, + dictWord{134, 0, 1517}, + dictWord{136, 10, 835}, + dictWord{151, 10, 17}, + dictWord{5, 0, 14}, + dictWord{5, 0, 892}, + dictWord{6, 0, 283}, + dictWord{7, 0, 234}, + dictWord{136, 0, 537}, + dictWord{139, 0, 541}, + dictWord{4, 0, 126}, + dictWord{8, 0, 635}, + dictWord{ + 147, + 0, + 34, + }, + dictWord{4, 0, 316}, + dictWord{4, 0, 495}, + dictWord{135, 0, 1561}, + dictWord{4, 11, 187}, + dictWord{5, 11, 184}, + dictWord{5, 11, 690}, + dictWord{ + 7, + 11, + 1869, + }, + dictWord{138, 11, 756}, + dictWord{139, 11, 783}, + dictWord{4, 0, 998}, + dictWord{137, 0, 861}, + dictWord{136, 0, 1009}, + dictWord{139, 11, 292}, + dictWord{5, 11, 21}, + dictWord{6, 11, 77}, + dictWord{6, 11, 157}, + dictWord{7, 11, 974}, + dictWord{7, 11, 1301}, + dictWord{7, 11, 1339}, + dictWord{7, 11, 1490}, + dictWord{ + 7, + 11, + 1873, + }, + dictWord{137, 11, 628}, + dictWord{7, 11, 1283}, + dictWord{9, 11, 227}, + dictWord{9, 11, 499}, + dictWord{10, 11, 341}, + dictWord{11, 11, 325}, + dictWord{11, 11, 408}, + dictWord{14, 11, 180}, + dictWord{15, 11, 144}, + dictWord{18, 11, 47}, + dictWord{147, 11, 49}, + dictWord{4, 0, 64}, + dictWord{5, 0, 352}, + dictWord{5, 0, 720}, + dictWord{6, 0, 368}, + dictWord{139, 0, 359}, + dictWord{5, 10, 384}, + dictWord{8, 10, 455}, + dictWord{140, 10, 48}, + dictWord{5, 10, 264}, + dictWord{ + 134, + 10, + 184, + }, + dictWord{7, 0, 1577}, + dictWord{10, 0, 304}, + dictWord{10, 0, 549}, + dictWord{12, 0, 365}, + dictWord{13, 0, 220}, + dictWord{13, 0, 240}, + dictWord{ + 142, + 0, + 33, + }, + dictWord{134, 0, 1107}, + dictWord{134, 0, 929}, + dictWord{135, 0, 1142}, + dictWord{6, 0, 175}, + dictWord{137, 0, 289}, + dictWord{5, 0, 432}, + dictWord{ + 133, + 0, + 913, + }, + dictWord{6, 0, 279}, + dictWord{7, 0, 219}, + dictWord{5, 10, 633}, + dictWord{135, 10, 1323}, + dictWord{7, 0, 785}, + dictWord{7, 10, 359}, + dictWord{ + 8, + 10, + 243, + }, + dictWord{140, 10, 175}, + dictWord{139, 0, 595}, + dictWord{132, 10, 105}, + dictWord{8, 11, 398}, + dictWord{9, 11, 681}, + dictWord{139, 11, 632}, + dictWord{140, 0, 80}, + dictWord{5, 0, 931}, + dictWord{134, 0, 1698}, + dictWord{142, 11, 241}, + dictWord{134, 11, 20}, + dictWord{134, 0, 1323}, + dictWord{11, 0, 526}, + dictWord{11, 0, 939}, + dictWord{141, 0, 290}, + dictWord{5, 0, 774}, + dictWord{6, 0, 780}, + dictWord{6, 0, 1637}, + dictWord{6, 0, 1686}, + dictWord{6, 0, 1751}, + dictWord{ + 8, + 0, + 559, + }, + dictWord{141, 0, 109}, + dictWord{141, 0, 127}, + dictWord{7, 0, 1167}, + dictWord{11, 0, 934}, + dictWord{13, 0, 391}, + dictWord{17, 0, 76}, + dictWord{ + 135, + 11, + 709, + }, + dictWord{135, 0, 963}, + dictWord{6, 0, 260}, + dictWord{135, 0, 1484}, + dictWord{134, 0, 573}, + dictWord{4, 10, 758}, + dictWord{139, 11, 941}, + dictWord{135, 10, 1649}, + dictWord{145, 11, 36}, + dictWord{4, 0, 292}, + dictWord{137, 0, 580}, + dictWord{4, 0, 736}, + dictWord{5, 0, 871}, + dictWord{6, 0, 1689}, + dictWord{135, 0, 1944}, + dictWord{7, 11, 945}, + dictWord{11, 11, 713}, + dictWord{139, 11, 744}, + dictWord{134, 0, 1164}, + dictWord{135, 11, 937}, + dictWord{ + 6, + 0, + 1922, + }, + dictWord{9, 0, 982}, + dictWord{15, 0, 173}, + dictWord{15, 0, 178}, + dictWord{15, 0, 200}, + dictWord{18, 0, 189}, + dictWord{18, 0, 207}, + dictWord{21, 0, 47}, + dictWord{135, 11, 1652}, + dictWord{7, 0, 1695}, + dictWord{139, 10, 128}, + dictWord{6, 0, 63}, + dictWord{135, 0, 920}, + dictWord{133, 0, 793}, + dictWord{ + 143, + 11, + 134, + }, + dictWord{133, 10, 918}, + dictWord{5, 0, 67}, + dictWord{6, 0, 62}, + dictWord{6, 0, 374}, + dictWord{135, 0, 1391}, + dictWord{9, 0, 790}, + dictWord{12, 0, 47}, + dictWord{4, 11, 579}, + dictWord{5, 11, 226}, + dictWord{5, 11, 323}, + dictWord{135, 11, 960}, + dictWord{10, 11, 784}, + dictWord{141, 11, 191}, + dictWord{4, 0, 391}, + dictWord{135, 0, 1169}, + dictWord{137, 0, 443}, + dictWord{13, 11, 232}, + dictWord{146, 11, 35}, + dictWord{132, 10, 340}, + dictWord{132, 0, 271}, + dictWord{ + 137, + 11, + 313, + }, + dictWord{5, 11, 973}, + dictWord{137, 11, 659}, + dictWord{134, 0, 1140}, + dictWord{6, 11, 135}, + dictWord{135, 11, 1176}, + dictWord{4, 0, 253}, + dictWord{5, 0, 544}, + dictWord{7, 0, 300}, + dictWord{137, 0, 340}, + dictWord{7, 0, 897}, + dictWord{5, 10, 985}, + dictWord{7, 10, 509}, + dictWord{145, 10, 96}, + dictWord{ + 138, + 11, + 735, + }, + dictWord{135, 10, 1919}, + dictWord{138, 0, 890}, + dictWord{5, 0, 818}, + dictWord{134, 0, 1122}, + dictWord{5, 0, 53}, + dictWord{5, 0, 541}, + dictWord{ + 6, + 0, + 94, + }, + dictWord{6, 0, 499}, + dictWord{7, 0, 230}, + dictWord{139, 0, 321}, + dictWord{4, 0, 920}, + dictWord{5, 0, 25}, + dictWord{5, 0, 790}, + dictWord{6, 0, 457}, + dictWord{ + 7, + 0, + 853, + }, + dictWord{8, 0, 788}, + dictWord{142, 11, 31}, + dictWord{132, 10, 247}, + dictWord{135, 11, 314}, + dictWord{132, 0, 468}, + dictWord{7, 0, 243}, + dictWord{ + 6, + 10, + 337, + }, + dictWord{7, 10, 494}, + dictWord{8, 10, 27}, + dictWord{8, 10, 599}, + dictWord{138, 10, 153}, + dictWord{4, 10, 184}, + dictWord{5, 10, 390}, + dictWord{ + 7, + 10, + 618, + }, + dictWord{7, 10, 1456}, + dictWord{139, 10, 710}, + dictWord{134, 0, 870}, + dictWord{134, 0, 1238}, + dictWord{134, 0, 1765}, + dictWord{10, 0, 853}, + dictWord{10, 0, 943}, + dictWord{14, 0, 437}, + dictWord{14, 0, 439}, + dictWord{14, 0, 443}, + dictWord{14, 0, 446}, + dictWord{14, 0, 452}, + dictWord{14, 0, 469}, + dictWord{ + 14, + 0, + 471, + }, + dictWord{14, 0, 473}, + dictWord{16, 0, 93}, + dictWord{16, 0, 102}, + dictWord{16, 0, 110}, + dictWord{148, 0, 121}, + dictWord{4, 0, 605}, + dictWord{ + 7, + 0, + 518, + }, + dictWord{7, 0, 1282}, + dictWord{7, 0, 1918}, + dictWord{10, 0, 180}, + dictWord{139, 0, 218}, + dictWord{133, 0, 822}, + dictWord{4, 0, 634}, + dictWord{ + 11, + 0, + 916, + }, + dictWord{142, 0, 419}, + dictWord{6, 11, 281}, + dictWord{7, 11, 6}, + dictWord{8, 11, 282}, + dictWord{8, 11, 480}, + dictWord{8, 11, 499}, + dictWord{9, 11, 198}, + dictWord{10, 11, 143}, + dictWord{10, 11, 169}, + dictWord{10, 11, 211}, + dictWord{10, 11, 417}, + dictWord{10, 11, 574}, + dictWord{11, 11, 147}, + dictWord{ + 11, + 11, + 395, + }, + dictWord{12, 11, 75}, + dictWord{12, 11, 407}, + dictWord{12, 11, 608}, + dictWord{13, 11, 500}, + dictWord{142, 11, 251}, + dictWord{134, 0, 898}, + dictWord{ + 6, + 0, + 36, + }, + dictWord{7, 0, 658}, + dictWord{8, 0, 454}, + dictWord{150, 11, 48}, + dictWord{133, 11, 674}, + dictWord{135, 11, 1776}, + dictWord{4, 11, 419}, + dictWord{ + 10, + 10, + 227, + }, + dictWord{11, 10, 497}, + dictWord{11, 10, 709}, + dictWord{140, 10, 415}, + dictWord{6, 10, 360}, + dictWord{7, 10, 1664}, + dictWord{136, 10, 478}, + dictWord{137, 0, 806}, + dictWord{12, 11, 508}, + dictWord{14, 11, 102}, + dictWord{14, 11, 226}, + dictWord{144, 11, 57}, + dictWord{135, 11, 1123}, + dictWord{ + 4, + 11, + 138, + }, + dictWord{7, 11, 1012}, + dictWord{7, 11, 1280}, + dictWord{137, 11, 76}, + dictWord{5, 11, 29}, + dictWord{140, 11, 638}, + dictWord{136, 10, 699}, + dictWord{134, 0, 1326}, + dictWord{132, 0, 104}, + dictWord{135, 11, 735}, + dictWord{132, 10, 739}, + dictWord{134, 0, 1331}, + dictWord{7, 0, 260}, + dictWord{ + 135, + 11, + 260, + }, + dictWord{135, 11, 1063}, + dictWord{7, 0, 45}, + dictWord{9, 0, 542}, + dictWord{9, 0, 566}, + dictWord{10, 0, 728}, + dictWord{137, 10, 869}, + dictWord{ + 4, + 10, + 67, + }, + dictWord{5, 10, 422}, + dictWord{7, 10, 1037}, + dictWord{7, 10, 1289}, + dictWord{7, 10, 1555}, + dictWord{9, 10, 741}, + dictWord{145, 10, 108}, + dictWord{ + 139, + 0, + 263, + }, + dictWord{134, 0, 1516}, + dictWord{14, 0, 146}, + dictWord{15, 0, 42}, + dictWord{16, 0, 23}, + dictWord{17, 0, 86}, + dictWord{146, 0, 17}, + dictWord{ + 138, + 0, + 468, + }, + dictWord{136, 0, 1005}, + dictWord{4, 11, 17}, + dictWord{5, 11, 23}, + dictWord{7, 11, 995}, + dictWord{11, 11, 383}, + dictWord{11, 11, 437}, + dictWord{ + 12, + 11, + 460, + }, + dictWord{140, 11, 532}, + dictWord{7, 0, 87}, + dictWord{142, 0, 288}, + dictWord{138, 10, 96}, + dictWord{135, 11, 626}, + dictWord{144, 10, 26}, + dictWord{ + 7, + 0, + 988, + }, + dictWord{7, 0, 1939}, + dictWord{9, 0, 64}, + dictWord{9, 0, 502}, + dictWord{12, 0, 22}, + dictWord{12, 0, 34}, + dictWord{13, 0, 12}, + dictWord{13, 0, 234}, + dictWord{147, 0, 77}, + dictWord{13, 0, 133}, + dictWord{8, 10, 203}, + dictWord{11, 10, 823}, + dictWord{11, 10, 846}, + dictWord{12, 10, 482}, + dictWord{13, 10, 277}, + dictWord{13, 10, 302}, + dictWord{13, 10, 464}, + dictWord{14, 10, 205}, + dictWord{142, 10, 221}, + dictWord{4, 10, 449}, + dictWord{133, 10, 718}, + dictWord{ + 135, + 0, + 141, + }, + dictWord{6, 0, 1842}, + dictWord{136, 0, 872}, + dictWord{8, 11, 70}, + dictWord{12, 11, 171}, + dictWord{141, 11, 272}, + dictWord{4, 10, 355}, + dictWord{ + 6, + 10, + 311, + }, + dictWord{9, 10, 256}, + dictWord{138, 10, 404}, + dictWord{132, 0, 619}, + dictWord{137, 0, 261}, + dictWord{10, 11, 233}, + dictWord{10, 10, 758}, + dictWord{139, 11, 76}, + dictWord{5, 0, 246}, + dictWord{8, 0, 189}, + dictWord{9, 0, 355}, + dictWord{9, 0, 512}, + dictWord{10, 0, 124}, + dictWord{10, 0, 453}, + dictWord{ + 11, + 0, + 143, + }, + dictWord{11, 0, 416}, + dictWord{11, 0, 859}, + dictWord{141, 0, 341}, + dictWord{134, 11, 442}, + dictWord{133, 10, 827}, + dictWord{5, 10, 64}, + dictWord{ + 140, + 10, + 581, + }, + dictWord{4, 10, 442}, + dictWord{7, 10, 1047}, + dictWord{7, 10, 1352}, + dictWord{135, 10, 1643}, + dictWord{134, 11, 1709}, + dictWord{5, 0, 678}, + dictWord{6, 0, 305}, + dictWord{7, 0, 775}, + dictWord{7, 0, 1065}, + dictWord{133, 10, 977}, + dictWord{11, 11, 69}, + dictWord{12, 11, 105}, + dictWord{12, 11, 117}, + dictWord{13, 11, 213}, + dictWord{14, 11, 13}, + dictWord{14, 11, 62}, + dictWord{14, 11, 177}, + dictWord{14, 11, 421}, + dictWord{15, 11, 19}, + dictWord{146, 11, 141}, + dictWord{137, 11, 309}, + dictWord{5, 0, 35}, + dictWord{7, 0, 862}, + dictWord{7, 0, 1886}, + dictWord{138, 0, 179}, + dictWord{136, 0, 285}, + dictWord{132, 0, 517}, + dictWord{7, 11, 976}, + dictWord{9, 11, 146}, + dictWord{10, 11, 206}, + dictWord{10, 11, 596}, + dictWord{13, 11, 218}, + dictWord{142, 11, 153}, + dictWord{ + 132, + 10, + 254, + }, + dictWord{6, 0, 214}, + dictWord{12, 0, 540}, + dictWord{4, 10, 275}, + dictWord{7, 10, 1219}, + dictWord{140, 10, 376}, + dictWord{8, 0, 667}, + dictWord{ + 11, + 0, + 403, + }, + dictWord{146, 0, 83}, + dictWord{12, 0, 74}, + dictWord{10, 11, 648}, + dictWord{11, 11, 671}, + dictWord{143, 11, 46}, + dictWord{135, 0, 125}, + dictWord{ + 134, + 10, + 1753, + }, + dictWord{133, 0, 761}, + dictWord{6, 0, 912}, + dictWord{4, 11, 518}, + dictWord{6, 10, 369}, + dictWord{6, 10, 502}, + dictWord{7, 10, 1036}, + dictWord{ + 7, + 11, + 1136, + }, + dictWord{8, 10, 348}, + dictWord{9, 10, 452}, + dictWord{10, 10, 26}, + dictWord{11, 10, 224}, + dictWord{11, 10, 387}, + dictWord{11, 10, 772}, + dictWord{12, 10, 95}, + dictWord{12, 10, 629}, + dictWord{13, 10, 195}, + dictWord{13, 10, 207}, + dictWord{13, 10, 241}, + dictWord{14, 10, 260}, + dictWord{14, 10, 270}, + dictWord{143, 10, 140}, + dictWord{10, 0, 131}, + dictWord{140, 0, 72}, + dictWord{132, 10, 269}, + dictWord{5, 10, 480}, + dictWord{7, 10, 532}, + dictWord{ + 7, + 10, + 1197, + }, + dictWord{7, 10, 1358}, + dictWord{8, 10, 291}, + dictWord{11, 10, 349}, + dictWord{142, 10, 396}, + dictWord{8, 11, 689}, + dictWord{137, 11, 863}, + dictWord{ + 8, + 0, + 333, + }, + dictWord{138, 0, 182}, + dictWord{4, 11, 18}, + dictWord{7, 11, 145}, + dictWord{7, 11, 444}, + dictWord{7, 11, 1278}, + dictWord{8, 11, 49}, + dictWord{ + 8, + 11, + 400, + }, + dictWord{9, 11, 71}, + dictWord{9, 11, 250}, + dictWord{10, 11, 459}, + dictWord{12, 11, 160}, + dictWord{144, 11, 24}, + dictWord{14, 11, 35}, + dictWord{ + 142, + 11, + 191, + }, + dictWord{135, 11, 1864}, + dictWord{135, 0, 1338}, + dictWord{148, 10, 15}, + dictWord{14, 0, 94}, + dictWord{15, 0, 65}, + dictWord{16, 0, 4}, + dictWord{ + 16, + 0, + 77, + }, + dictWord{16, 0, 80}, + dictWord{145, 0, 5}, + dictWord{12, 11, 82}, + dictWord{143, 11, 36}, + dictWord{133, 11, 1010}, + dictWord{133, 0, 449}, + dictWord{ + 133, + 0, + 646, + }, + dictWord{7, 0, 86}, + dictWord{8, 0, 103}, + dictWord{135, 10, 657}, + dictWord{7, 0, 2028}, + dictWord{138, 0, 641}, + dictWord{136, 10, 533}, + dictWord{ + 134, + 0, + 1, + }, + dictWord{139, 11, 970}, + dictWord{5, 11, 87}, + dictWord{7, 11, 313}, + dictWord{7, 11, 1103}, + dictWord{10, 11, 112}, + dictWord{10, 11, 582}, + dictWord{ + 11, + 11, + 389, + }, + dictWord{11, 11, 813}, + dictWord{12, 11, 385}, + dictWord{13, 11, 286}, + dictWord{14, 11, 124}, + dictWord{146, 11, 108}, + dictWord{6, 0, 869}, + dictWord{ + 132, + 11, + 267, + }, + dictWord{6, 0, 277}, + dictWord{7, 0, 1274}, + dictWord{7, 0, 1386}, + dictWord{146, 0, 87}, + dictWord{6, 0, 187}, + dictWord{7, 0, 39}, + dictWord{7, 0, 1203}, + dictWord{8, 0, 380}, + dictWord{14, 0, 117}, + dictWord{149, 0, 28}, + dictWord{4, 10, 211}, + dictWord{4, 10, 332}, + dictWord{5, 10, 335}, + dictWord{6, 10, 238}, + dictWord{ + 7, + 10, + 269, + }, + dictWord{7, 10, 811}, + dictWord{7, 10, 1797}, + dictWord{8, 10, 836}, + dictWord{9, 10, 507}, + dictWord{141, 10, 242}, + dictWord{4, 0, 785}, + dictWord{ + 5, + 0, + 368, + }, + dictWord{6, 0, 297}, + dictWord{7, 0, 793}, + dictWord{139, 0, 938}, + dictWord{7, 0, 464}, + dictWord{8, 0, 558}, + dictWord{11, 0, 105}, + dictWord{12, 0, 231}, + dictWord{14, 0, 386}, + dictWord{15, 0, 102}, + dictWord{148, 0, 75}, + dictWord{133, 10, 1009}, + dictWord{8, 0, 877}, + dictWord{140, 0, 731}, + dictWord{ + 139, + 11, + 289, + }, + dictWord{10, 11, 249}, + dictWord{139, 11, 209}, + dictWord{132, 11, 561}, + dictWord{134, 0, 1608}, + dictWord{132, 11, 760}, + dictWord{134, 0, 1429}, + dictWord{9, 11, 154}, + dictWord{140, 11, 485}, + dictWord{5, 10, 228}, + dictWord{6, 10, 203}, + dictWord{7, 10, 156}, + dictWord{8, 10, 347}, + dictWord{ + 137, + 10, + 265, + }, + dictWord{7, 0, 1010}, + dictWord{11, 0, 733}, + dictWord{11, 0, 759}, + dictWord{13, 0, 34}, + dictWord{14, 0, 427}, + dictWord{146, 0, 45}, + dictWord{7, 10, 1131}, + dictWord{135, 10, 1468}, + dictWord{136, 11, 255}, + dictWord{7, 0, 1656}, + dictWord{9, 0, 369}, + dictWord{10, 0, 338}, + dictWord{10, 0, 490}, + dictWord{ + 11, + 0, + 154, + }, + dictWord{11, 0, 545}, + dictWord{11, 0, 775}, + dictWord{13, 0, 77}, + dictWord{141, 0, 274}, + dictWord{133, 11, 621}, + dictWord{134, 0, 1038}, + dictWord{ + 4, + 11, + 368, + }, + dictWord{135, 11, 641}, + dictWord{6, 0, 2010}, + dictWord{8, 0, 979}, + dictWord{8, 0, 985}, + dictWord{10, 0, 951}, + dictWord{138, 0, 1011}, + dictWord{ + 134, + 0, + 1005, + }, + dictWord{19, 0, 121}, + dictWord{5, 10, 291}, + dictWord{5, 10, 318}, + dictWord{7, 10, 765}, + dictWord{9, 10, 389}, + dictWord{140, 10, 548}, + dictWord{ + 5, + 0, + 20, + }, + dictWord{6, 0, 298}, + dictWord{7, 0, 659}, + dictWord{137, 0, 219}, + dictWord{7, 0, 1440}, + dictWord{11, 0, 854}, + dictWord{11, 0, 872}, + dictWord{11, 0, 921}, + dictWord{12, 0, 551}, + dictWord{13, 0, 472}, + dictWord{142, 0, 367}, + dictWord{5, 0, 490}, + dictWord{6, 0, 615}, + dictWord{6, 0, 620}, + dictWord{135, 0, 683}, + dictWord{ + 6, + 0, + 1070, + }, + dictWord{134, 0, 1597}, + dictWord{139, 0, 522}, + dictWord{132, 0, 439}, + dictWord{136, 0, 669}, + dictWord{6, 0, 766}, + dictWord{6, 0, 1143}, + dictWord{ + 6, + 0, + 1245, + }, + dictWord{10, 10, 525}, + dictWord{139, 10, 82}, + dictWord{9, 11, 92}, + dictWord{147, 11, 91}, + dictWord{6, 0, 668}, + dictWord{134, 0, 1218}, + dictWord{ + 6, + 11, + 525, + }, + dictWord{9, 11, 876}, + dictWord{140, 11, 284}, + dictWord{132, 0, 233}, + dictWord{136, 0, 547}, + dictWord{132, 10, 422}, + dictWord{5, 10, 355}, + dictWord{145, 10, 0}, + dictWord{6, 11, 300}, + dictWord{135, 11, 1515}, + dictWord{4, 0, 482}, + dictWord{137, 10, 905}, + dictWord{4, 0, 886}, + dictWord{7, 0, 346}, + dictWord{133, 11, 594}, + dictWord{133, 10, 865}, + dictWord{5, 10, 914}, + dictWord{134, 10, 1625}, + dictWord{135, 0, 334}, + dictWord{5, 0, 795}, + dictWord{ + 6, + 0, + 1741, + }, + dictWord{133, 10, 234}, + dictWord{135, 10, 1383}, + dictWord{6, 11, 1641}, + dictWord{136, 11, 820}, + dictWord{135, 0, 371}, + dictWord{7, 11, 1313}, + dictWord{138, 11, 660}, + dictWord{135, 10, 1312}, + dictWord{135, 0, 622}, + dictWord{7, 0, 625}, + dictWord{135, 0, 1750}, + dictWord{135, 0, 339}, + dictWord{ + 4, + 0, + 203, + }, + dictWord{135, 0, 1936}, + dictWord{15, 0, 29}, + dictWord{16, 0, 38}, + dictWord{15, 11, 29}, + dictWord{144, 11, 38}, + dictWord{5, 0, 338}, + dictWord{ + 135, + 0, + 1256, + }, + dictWord{135, 10, 1493}, + dictWord{10, 0, 130}, + dictWord{6, 10, 421}, + dictWord{7, 10, 61}, + dictWord{7, 10, 1540}, + dictWord{138, 10, 501}, + dictWord{ + 6, + 11, + 389, + }, + dictWord{7, 11, 149}, + dictWord{9, 11, 142}, + dictWord{138, 11, 94}, + dictWord{137, 10, 341}, + dictWord{11, 0, 678}, + dictWord{12, 0, 307}, + dictWord{142, 10, 98}, + dictWord{6, 11, 8}, + dictWord{7, 11, 1881}, + dictWord{136, 11, 91}, + dictWord{135, 0, 2044}, + dictWord{6, 0, 770}, + dictWord{6, 0, 802}, + dictWord{ + 6, + 0, + 812, + }, + dictWord{7, 0, 311}, + dictWord{9, 0, 308}, + dictWord{12, 0, 255}, + dictWord{6, 10, 102}, + dictWord{7, 10, 72}, + dictWord{15, 10, 142}, + dictWord{ + 147, + 10, + 67, + }, + dictWord{151, 10, 30}, + dictWord{135, 10, 823}, + dictWord{135, 0, 1266}, + dictWord{135, 11, 1746}, + dictWord{135, 10, 1870}, + dictWord{4, 0, 400}, + dictWord{5, 0, 267}, + dictWord{135, 0, 232}, + dictWord{7, 11, 24}, + dictWord{11, 11, 542}, + dictWord{139, 11, 852}, + dictWord{135, 11, 1739}, + dictWord{4, 11, 503}, + dictWord{135, 11, 1661}, + dictWord{5, 11, 130}, + dictWord{7, 11, 1314}, + dictWord{9, 11, 610}, + dictWord{10, 11, 718}, + dictWord{11, 11, 601}, + dictWord{ + 11, + 11, + 819, + }, + dictWord{11, 11, 946}, + dictWord{140, 11, 536}, + dictWord{10, 11, 149}, + dictWord{11, 11, 280}, + dictWord{142, 11, 336}, + dictWord{7, 0, 739}, + dictWord{11, 0, 690}, + dictWord{7, 11, 1946}, + dictWord{8, 10, 48}, + dictWord{8, 10, 88}, + dictWord{8, 10, 582}, + dictWord{8, 10, 681}, + dictWord{9, 10, 373}, + dictWord{ + 9, + 10, + 864, + }, + dictWord{11, 10, 157}, + dictWord{11, 10, 843}, + dictWord{148, 10, 27}, + dictWord{134, 0, 990}, + dictWord{4, 10, 88}, + dictWord{5, 10, 137}, + dictWord{ + 5, + 10, + 174, + }, + dictWord{5, 10, 777}, + dictWord{6, 10, 1664}, + dictWord{6, 10, 1725}, + dictWord{7, 10, 77}, + dictWord{7, 10, 426}, + dictWord{7, 10, 1317}, + dictWord{ + 7, + 10, + 1355, + }, + dictWord{8, 10, 126}, + dictWord{8, 10, 563}, + dictWord{9, 10, 523}, + dictWord{9, 10, 750}, + dictWord{10, 10, 310}, + dictWord{10, 10, 836}, + dictWord{ + 11, + 10, + 42, + }, + dictWord{11, 10, 318}, + dictWord{11, 10, 731}, + dictWord{12, 10, 68}, + dictWord{12, 10, 92}, + dictWord{12, 10, 507}, + dictWord{12, 10, 692}, + dictWord{ + 13, + 10, + 81, + }, + dictWord{13, 10, 238}, + dictWord{13, 10, 374}, + dictWord{14, 10, 436}, + dictWord{18, 10, 138}, + dictWord{19, 10, 78}, + dictWord{19, 10, 111}, + dictWord{20, 10, 55}, + dictWord{20, 10, 77}, + dictWord{148, 10, 92}, + dictWord{141, 10, 418}, + dictWord{7, 0, 1831}, + dictWord{132, 10, 938}, + dictWord{6, 0, 776}, + dictWord{134, 0, 915}, + dictWord{138, 10, 351}, + dictWord{5, 11, 348}, + dictWord{6, 11, 522}, + dictWord{6, 10, 1668}, + dictWord{7, 10, 1499}, + dictWord{8, 10, 117}, + dictWord{9, 10, 314}, + dictWord{138, 10, 174}, + dictWord{135, 10, 707}, + dictWord{132, 0, 613}, + dictWord{133, 10, 403}, + dictWord{132, 11, 392}, + dictWord{ + 5, + 11, + 433, + }, + dictWord{9, 11, 633}, + dictWord{139, 11, 629}, + dictWord{133, 0, 763}, + dictWord{132, 0, 878}, + dictWord{132, 0, 977}, + dictWord{132, 0, 100}, + dictWord{6, 0, 463}, + dictWord{4, 10, 44}, + dictWord{5, 10, 311}, + dictWord{7, 10, 639}, + dictWord{7, 10, 762}, + dictWord{7, 10, 1827}, + dictWord{9, 10, 8}, + dictWord{ + 9, + 10, + 462, + }, + dictWord{148, 10, 83}, + dictWord{134, 11, 234}, + dictWord{4, 10, 346}, + dictWord{7, 10, 115}, + dictWord{9, 10, 180}, + dictWord{9, 10, 456}, + dictWord{ + 138, + 10, + 363, + }, + dictWord{5, 0, 362}, + dictWord{5, 0, 443}, + dictWord{6, 0, 318}, + dictWord{7, 0, 1019}, + dictWord{139, 0, 623}, + dictWord{5, 0, 463}, + dictWord{8, 0, 296}, + dictWord{7, 11, 140}, + dictWord{7, 11, 1950}, + dictWord{8, 11, 680}, + dictWord{11, 11, 817}, + dictWord{147, 11, 88}, + dictWord{7, 11, 1222}, + dictWord{ + 138, + 11, + 386, + }, + dictWord{142, 0, 137}, + dictWord{132, 0, 454}, + dictWord{7, 0, 1914}, + dictWord{6, 11, 5}, + dictWord{7, 10, 1051}, + dictWord{9, 10, 545}, + dictWord{ + 11, + 11, + 249, + }, + dictWord{12, 11, 313}, + dictWord{16, 11, 66}, + dictWord{145, 11, 26}, + dictWord{135, 0, 1527}, + dictWord{145, 0, 58}, + dictWord{148, 11, 59}, + dictWord{ + 5, + 0, + 48, + }, + dictWord{5, 0, 404}, + dictWord{6, 0, 557}, + dictWord{7, 0, 458}, + dictWord{8, 0, 597}, + dictWord{10, 0, 455}, + dictWord{10, 0, 606}, + dictWord{11, 0, 49}, + dictWord{ + 11, + 0, + 548, + }, + dictWord{12, 0, 476}, + dictWord{13, 0, 18}, + dictWord{141, 0, 450}, + dictWord{5, 11, 963}, + dictWord{134, 11, 1773}, + dictWord{133, 0, 729}, + dictWord{138, 11, 586}, + dictWord{5, 0, 442}, + dictWord{135, 0, 1984}, + dictWord{134, 0, 449}, + dictWord{144, 0, 40}, + dictWord{4, 0, 853}, + dictWord{7, 11, 180}, + dictWord{8, 11, 509}, + dictWord{136, 11, 792}, + dictWord{6, 10, 185}, + dictWord{7, 10, 1899}, + dictWord{9, 10, 875}, + dictWord{139, 10, 673}, + dictWord{ + 134, + 11, + 524, + }, + dictWord{12, 0, 227}, + dictWord{4, 10, 327}, + dictWord{5, 10, 478}, + dictWord{7, 10, 1332}, + dictWord{136, 10, 753}, + dictWord{6, 0, 1491}, + dictWord{ + 5, + 10, + 1020, + }, + dictWord{133, 10, 1022}, + dictWord{4, 10, 103}, + dictWord{133, 10, 401}, + dictWord{132, 11, 931}, + dictWord{4, 10, 499}, + dictWord{135, 10, 1421}, + dictWord{5, 0, 55}, + dictWord{7, 0, 376}, + dictWord{140, 0, 161}, + dictWord{133, 0, 450}, + dictWord{6, 0, 1174}, + dictWord{134, 0, 1562}, + dictWord{10, 0, 62}, + dictWord{13, 0, 400}, + dictWord{135, 11, 1837}, + dictWord{140, 0, 207}, + dictWord{135, 0, 869}, + dictWord{4, 11, 773}, + dictWord{5, 11, 618}, + dictWord{ + 137, + 11, + 756, + }, + dictWord{132, 10, 96}, + dictWord{4, 0, 213}, + dictWord{7, 0, 223}, + dictWord{8, 0, 80}, + dictWord{135, 10, 968}, + dictWord{4, 11, 90}, + dictWord{5, 11, 337}, + dictWord{5, 11, 545}, + dictWord{7, 11, 754}, + dictWord{9, 11, 186}, + dictWord{10, 11, 72}, + dictWord{10, 11, 782}, + dictWord{11, 11, 513}, + dictWord{11, 11, 577}, + dictWord{11, 11, 610}, + dictWord{11, 11, 889}, + dictWord{11, 11, 961}, + dictWord{12, 11, 354}, + dictWord{12, 11, 362}, + dictWord{12, 11, 461}, + dictWord{ + 12, + 11, + 595, + }, + dictWord{13, 11, 79}, + dictWord{143, 11, 121}, + dictWord{7, 0, 381}, + dictWord{7, 0, 806}, + dictWord{7, 0, 820}, + dictWord{8, 0, 354}, + dictWord{8, 0, 437}, + dictWord{8, 0, 787}, + dictWord{9, 0, 657}, + dictWord{10, 0, 58}, + dictWord{10, 0, 339}, + dictWord{10, 0, 749}, + dictWord{11, 0, 914}, + dictWord{12, 0, 162}, + dictWord{ + 13, + 0, + 75, + }, + dictWord{14, 0, 106}, + dictWord{14, 0, 198}, + dictWord{14, 0, 320}, + dictWord{14, 0, 413}, + dictWord{146, 0, 43}, + dictWord{136, 0, 747}, + dictWord{ + 136, + 0, + 954, + }, + dictWord{134, 0, 1073}, + dictWord{135, 0, 556}, + dictWord{7, 11, 151}, + dictWord{9, 11, 329}, + dictWord{139, 11, 254}, + dictWord{5, 0, 692}, + dictWord{ + 134, + 0, + 1395, + }, + dictWord{6, 10, 563}, + dictWord{137, 10, 224}, + dictWord{134, 0, 191}, + dictWord{132, 0, 804}, + dictWord{9, 11, 187}, + dictWord{10, 11, 36}, + dictWord{17, 11, 44}, + dictWord{146, 11, 64}, + dictWord{7, 11, 165}, + dictWord{7, 11, 919}, + dictWord{136, 11, 517}, + dictWord{4, 11, 506}, + dictWord{5, 11, 295}, + dictWord{7, 11, 1680}, + dictWord{15, 11, 14}, + dictWord{144, 11, 5}, + dictWord{4, 0, 706}, + dictWord{6, 0, 162}, + dictWord{7, 0, 1960}, + dictWord{136, 0, 831}, + dictWord{ + 135, + 11, + 1376, + }, + dictWord{7, 11, 987}, + dictWord{9, 11, 688}, + dictWord{10, 11, 522}, + dictWord{11, 11, 788}, + dictWord{140, 11, 566}, + dictWord{150, 0, 35}, + dictWord{138, 0, 426}, + dictWord{135, 0, 1235}, + dictWord{135, 11, 1741}, + dictWord{7, 11, 389}, + dictWord{7, 11, 700}, + dictWord{7, 11, 940}, + dictWord{ + 8, + 11, + 514, + }, + dictWord{9, 11, 116}, + dictWord{9, 11, 535}, + dictWord{10, 11, 118}, + dictWord{11, 11, 107}, + dictWord{11, 11, 148}, + dictWord{11, 11, 922}, + dictWord{ + 12, + 11, + 254, + }, + dictWord{12, 11, 421}, + dictWord{142, 11, 238}, + dictWord{134, 0, 1234}, + dictWord{132, 11, 743}, + dictWord{4, 10, 910}, + dictWord{5, 10, 832}, + dictWord{135, 11, 1335}, + dictWord{141, 0, 96}, + dictWord{135, 11, 185}, + dictWord{146, 0, 149}, + dictWord{4, 0, 204}, + dictWord{137, 0, 902}, + dictWord{ + 4, + 11, + 784, + }, + dictWord{133, 11, 745}, + dictWord{136, 0, 833}, + dictWord{136, 0, 949}, + dictWord{7, 0, 366}, + dictWord{9, 0, 287}, + dictWord{12, 0, 199}, + dictWord{ + 12, + 0, + 556, + }, + dictWord{12, 0, 577}, + dictWord{5, 11, 81}, + dictWord{7, 11, 146}, + dictWord{7, 11, 1342}, + dictWord{7, 11, 1446}, + dictWord{8, 11, 53}, + dictWord{8, 11, 561}, + dictWord{8, 11, 694}, + dictWord{8, 11, 754}, + dictWord{9, 11, 97}, + dictWord{9, 11, 115}, + dictWord{9, 11, 894}, + dictWord{10, 11, 462}, + dictWord{10, 11, 813}, + dictWord{11, 11, 230}, + dictWord{11, 11, 657}, + dictWord{11, 11, 699}, + dictWord{11, 11, 748}, + dictWord{12, 11, 119}, + dictWord{12, 11, 200}, + dictWord{ + 12, + 11, + 283, + }, + dictWord{14, 11, 273}, + dictWord{145, 11, 15}, + dictWord{5, 11, 408}, + dictWord{137, 11, 747}, + dictWord{9, 11, 498}, + dictWord{140, 11, 181}, + dictWord{ + 6, + 0, + 2020, + }, + dictWord{136, 0, 992}, + dictWord{5, 0, 356}, + dictWord{135, 0, 224}, + dictWord{134, 0, 784}, + dictWord{7, 0, 630}, + dictWord{9, 0, 567}, + dictWord{ + 11, + 0, + 150, + }, + dictWord{11, 0, 444}, + dictWord{13, 0, 119}, + dictWord{8, 10, 528}, + dictWord{137, 10, 348}, + dictWord{134, 0, 539}, + dictWord{4, 10, 20}, + dictWord{ + 133, + 10, + 616, + }, + dictWord{142, 0, 27}, + dictWord{7, 11, 30}, + dictWord{8, 11, 86}, + dictWord{8, 11, 315}, + dictWord{8, 11, 700}, + dictWord{9, 11, 576}, + dictWord{9, 11, 858}, + dictWord{11, 11, 310}, + dictWord{11, 11, 888}, + dictWord{11, 11, 904}, + dictWord{12, 11, 361}, + dictWord{141, 11, 248}, + dictWord{138, 11, 839}, + dictWord{ + 134, + 0, + 755, + }, + dictWord{134, 0, 1063}, + dictWord{7, 10, 1091}, + dictWord{135, 10, 1765}, + dictWord{134, 11, 428}, + dictWord{7, 11, 524}, + dictWord{8, 11, 169}, + dictWord{8, 11, 234}, + dictWord{9, 11, 480}, + dictWord{138, 11, 646}, + dictWord{139, 0, 814}, + dictWord{7, 11, 1462}, + dictWord{139, 11, 659}, + dictWord{ + 4, + 10, + 26, + }, + dictWord{5, 10, 429}, + dictWord{6, 10, 245}, + dictWord{7, 10, 704}, + dictWord{7, 10, 1379}, + dictWord{135, 10, 1474}, + dictWord{7, 11, 1205}, + dictWord{ + 138, + 11, + 637, + }, + dictWord{139, 11, 803}, + dictWord{132, 10, 621}, + dictWord{136, 0, 987}, + dictWord{4, 11, 266}, + dictWord{8, 11, 4}, + dictWord{9, 11, 39}, + dictWord{ + 10, + 11, + 166, + }, + dictWord{11, 11, 918}, + dictWord{12, 11, 635}, + dictWord{20, 11, 10}, + dictWord{22, 11, 27}, + dictWord{150, 11, 43}, + dictWord{4, 0, 235}, + dictWord{ + 135, + 0, + 255, + }, + dictWord{4, 0, 194}, + dictWord{5, 0, 584}, + dictWord{6, 0, 384}, + dictWord{7, 0, 583}, + dictWord{10, 0, 761}, + dictWord{11, 0, 760}, + dictWord{139, 0, 851}, + dictWord{133, 10, 542}, + dictWord{134, 0, 1086}, + dictWord{133, 10, 868}, + dictWord{8, 0, 1016}, + dictWord{136, 0, 1018}, + dictWord{7, 0, 1396}, + dictWord{ + 7, + 11, + 1396, + }, + dictWord{136, 10, 433}, + dictWord{135, 10, 1495}, + dictWord{138, 10, 215}, + dictWord{141, 10, 124}, + dictWord{7, 11, 157}, + dictWord{ + 8, + 11, + 279, + }, + dictWord{9, 11, 759}, + dictWord{16, 11, 31}, + dictWord{16, 11, 39}, + dictWord{16, 11, 75}, + dictWord{18, 11, 24}, + dictWord{20, 11, 42}, + dictWord{152, 11, 1}, + dictWord{5, 0, 562}, + dictWord{134, 11, 604}, + dictWord{134, 0, 913}, + dictWord{5, 0, 191}, + dictWord{137, 0, 271}, + dictWord{4, 0, 470}, + dictWord{6, 0, 153}, + dictWord{7, 0, 1503}, + dictWord{7, 0, 1923}, + dictWord{10, 0, 701}, + dictWord{11, 0, 132}, + dictWord{11, 0, 227}, + dictWord{11, 0, 320}, + dictWord{11, 0, 436}, + dictWord{ + 11, + 0, + 525, + }, + dictWord{11, 0, 855}, + dictWord{11, 0, 873}, + dictWord{12, 0, 41}, + dictWord{12, 0, 286}, + dictWord{13, 0, 103}, + dictWord{13, 0, 284}, + dictWord{ + 14, + 0, + 255, + }, + dictWord{14, 0, 262}, + dictWord{15, 0, 117}, + dictWord{143, 0, 127}, + dictWord{7, 0, 475}, + dictWord{12, 0, 45}, + dictWord{147, 10, 112}, + dictWord{ + 132, + 11, + 567, + }, + dictWord{137, 11, 859}, + dictWord{6, 0, 713}, + dictWord{6, 0, 969}, + dictWord{6, 0, 1290}, + dictWord{134, 0, 1551}, + dictWord{133, 0, 327}, + dictWord{ + 6, + 0, + 552, + }, + dictWord{6, 0, 1292}, + dictWord{7, 0, 1754}, + dictWord{137, 0, 604}, + dictWord{4, 0, 223}, + dictWord{6, 0, 359}, + dictWord{11, 0, 3}, + dictWord{13, 0, 108}, + dictWord{14, 0, 89}, + dictWord{16, 0, 22}, + dictWord{5, 11, 762}, + dictWord{7, 11, 1880}, + dictWord{9, 11, 680}, + dictWord{139, 11, 798}, + dictWord{5, 0, 80}, + dictWord{ + 6, + 0, + 405, + }, + dictWord{7, 0, 403}, + dictWord{7, 0, 1502}, + dictWord{8, 0, 456}, + dictWord{9, 0, 487}, + dictWord{9, 0, 853}, + dictWord{9, 0, 889}, + dictWord{10, 0, 309}, + dictWord{ + 11, + 0, + 721, + }, + dictWord{11, 0, 994}, + dictWord{12, 0, 430}, + dictWord{141, 0, 165}, + dictWord{133, 11, 298}, + dictWord{132, 10, 647}, + dictWord{134, 0, 2016}, + dictWord{18, 10, 10}, + dictWord{146, 11, 10}, + dictWord{4, 0, 453}, + dictWord{5, 0, 887}, + dictWord{6, 0, 535}, + dictWord{8, 0, 6}, + dictWord{8, 0, 543}, + dictWord{ + 136, + 0, + 826, + }, + dictWord{136, 0, 975}, + dictWord{10, 0, 961}, + dictWord{138, 0, 962}, + dictWord{138, 10, 220}, + dictWord{6, 0, 1891}, + dictWord{6, 0, 1893}, + dictWord{ + 9, + 0, + 916, + }, + dictWord{9, 0, 965}, + dictWord{9, 0, 972}, + dictWord{12, 0, 801}, + dictWord{12, 0, 859}, + dictWord{12, 0, 883}, + dictWord{15, 0, 226}, + dictWord{149, 0, 51}, + dictWord{132, 10, 109}, + dictWord{135, 11, 267}, + dictWord{7, 11, 92}, + dictWord{7, 11, 182}, + dictWord{8, 11, 453}, + dictWord{9, 11, 204}, + dictWord{11, 11, 950}, + dictWord{12, 11, 94}, + dictWord{12, 11, 644}, + dictWord{16, 11, 20}, + dictWord{16, 11, 70}, + dictWord{16, 11, 90}, + dictWord{147, 11, 55}, + dictWord{ + 134, + 10, + 1746, + }, + dictWord{6, 11, 71}, + dictWord{7, 11, 845}, + dictWord{7, 11, 1308}, + dictWord{8, 11, 160}, + dictWord{137, 11, 318}, + dictWord{5, 0, 101}, + dictWord{6, 0, 88}, + dictWord{7, 0, 263}, + dictWord{7, 0, 628}, + dictWord{7, 0, 1677}, + dictWord{8, 0, 349}, + dictWord{9, 0, 100}, + dictWord{10, 0, 677}, + dictWord{14, 0, 169}, + dictWord{ + 14, + 0, + 302, + }, + dictWord{14, 0, 313}, + dictWord{15, 0, 48}, + dictWord{15, 0, 84}, + dictWord{7, 11, 237}, + dictWord{8, 11, 664}, + dictWord{9, 11, 42}, + dictWord{9, 11, 266}, + dictWord{9, 11, 380}, + dictWord{9, 11, 645}, + dictWord{10, 11, 177}, + dictWord{138, 11, 276}, + dictWord{138, 11, 69}, + dictWord{4, 0, 310}, + dictWord{7, 0, 708}, + dictWord{7, 0, 996}, + dictWord{9, 0, 795}, + dictWord{10, 0, 390}, + dictWord{10, 0, 733}, + dictWord{11, 0, 451}, + dictWord{12, 0, 249}, + dictWord{14, 0, 115}, + dictWord{ + 14, + 0, + 286, + }, + dictWord{143, 0, 100}, + dictWord{5, 0, 587}, + dictWord{4, 10, 40}, + dictWord{10, 10, 67}, + dictWord{11, 10, 117}, + dictWord{11, 10, 768}, + dictWord{ + 139, + 10, + 935, + }, + dictWord{6, 0, 1942}, + dictWord{7, 0, 512}, + dictWord{136, 0, 983}, + dictWord{7, 10, 992}, + dictWord{8, 10, 301}, + dictWord{9, 10, 722}, + dictWord{12, 10, 63}, + dictWord{13, 10, 29}, + dictWord{14, 10, 161}, + dictWord{143, 10, 18}, + dictWord{136, 11, 76}, + dictWord{139, 10, 923}, + dictWord{134, 0, 645}, + dictWord{ + 134, + 0, + 851, + }, + dictWord{4, 0, 498}, + dictWord{132, 11, 293}, + dictWord{7, 0, 217}, + dictWord{8, 0, 140}, + dictWord{10, 0, 610}, + dictWord{14, 11, 352}, + dictWord{ + 17, + 11, + 53, + }, + dictWord{18, 11, 146}, + dictWord{18, 11, 152}, + dictWord{19, 11, 11}, + dictWord{150, 11, 54}, + dictWord{134, 0, 1448}, + dictWord{138, 11, 841}, + dictWord{133, 0, 905}, + dictWord{4, 11, 605}, + dictWord{7, 11, 518}, + dictWord{7, 11, 1282}, + dictWord{7, 11, 1918}, + dictWord{10, 11, 180}, + dictWord{139, 11, 218}, + dictWord{139, 11, 917}, + dictWord{135, 10, 825}, + dictWord{140, 10, 328}, + dictWord{4, 0, 456}, + dictWord{7, 0, 105}, + dictWord{7, 0, 358}, + dictWord{7, 0, 1637}, + dictWord{8, 0, 643}, + dictWord{139, 0, 483}, + dictWord{134, 0, 792}, + dictWord{6, 11, 96}, + dictWord{135, 11, 1426}, + dictWord{137, 11, 691}, + dictWord{ + 4, + 11, + 651, + }, + dictWord{133, 11, 289}, + dictWord{7, 11, 688}, + dictWord{8, 11, 35}, + dictWord{9, 11, 511}, + dictWord{10, 11, 767}, + dictWord{147, 11, 118}, + dictWord{ + 150, + 0, + 56, + }, + dictWord{5, 0, 243}, + dictWord{5, 0, 535}, + dictWord{6, 10, 204}, + dictWord{10, 10, 320}, + dictWord{10, 10, 583}, + dictWord{13, 10, 502}, + dictWord{ + 14, + 10, + 72, + }, + dictWord{14, 10, 274}, + dictWord{14, 10, 312}, + dictWord{14, 10, 344}, + dictWord{15, 10, 159}, + dictWord{16, 10, 62}, + dictWord{16, 10, 69}, + dictWord{ + 17, + 10, + 30, + }, + dictWord{18, 10, 42}, + dictWord{18, 10, 53}, + dictWord{18, 10, 84}, + dictWord{18, 10, 140}, + dictWord{19, 10, 68}, + dictWord{19, 10, 85}, + dictWord{20, 10, 5}, + dictWord{20, 10, 45}, + dictWord{20, 10, 101}, + dictWord{22, 10, 7}, + dictWord{150, 10, 20}, + dictWord{4, 10, 558}, + dictWord{6, 10, 390}, + dictWord{7, 10, 162}, + dictWord{7, 10, 689}, + dictWord{9, 10, 360}, + dictWord{138, 10, 653}, + dictWord{146, 11, 23}, + dictWord{135, 0, 1748}, + dictWord{5, 10, 856}, + dictWord{ + 6, + 10, + 1672, + }, + dictWord{6, 10, 1757}, + dictWord{134, 10, 1781}, + dictWord{5, 0, 539}, + dictWord{5, 0, 754}, + dictWord{6, 0, 876}, + dictWord{132, 11, 704}, + dictWord{ + 135, + 11, + 1078, + }, + dictWord{5, 10, 92}, + dictWord{10, 10, 736}, + dictWord{140, 10, 102}, + dictWord{17, 0, 91}, + dictWord{5, 10, 590}, + dictWord{137, 10, 213}, + dictWord{134, 0, 1565}, + dictWord{6, 0, 91}, + dictWord{135, 0, 435}, + dictWord{4, 0, 939}, + dictWord{140, 0, 792}, + dictWord{134, 0, 1399}, + dictWord{4, 0, 16}, + dictWord{ + 5, + 0, + 316, + }, + dictWord{5, 0, 842}, + dictWord{6, 0, 370}, + dictWord{6, 0, 1778}, + dictWord{8, 0, 166}, + dictWord{11, 0, 812}, + dictWord{12, 0, 206}, + dictWord{12, 0, 351}, + dictWord{14, 0, 418}, + dictWord{16, 0, 15}, + dictWord{16, 0, 34}, + dictWord{18, 0, 3}, + dictWord{19, 0, 3}, + dictWord{19, 0, 7}, + dictWord{20, 0, 4}, + dictWord{21, 0, 21}, + dictWord{ + 4, + 11, + 720, + }, + dictWord{133, 11, 306}, + dictWord{144, 0, 95}, + dictWord{133, 11, 431}, + dictWord{132, 11, 234}, + dictWord{135, 0, 551}, + dictWord{4, 0, 999}, + dictWord{6, 0, 1966}, + dictWord{134, 0, 2042}, + dictWord{7, 0, 619}, + dictWord{10, 0, 547}, + dictWord{11, 0, 122}, + dictWord{12, 0, 601}, + dictWord{15, 0, 7}, + dictWord{148, 0, 20}, + dictWord{5, 11, 464}, + dictWord{6, 11, 236}, + dictWord{7, 11, 276}, + dictWord{7, 11, 696}, + dictWord{7, 11, 914}, + dictWord{7, 11, 1108}, + dictWord{ + 7, + 11, + 1448, + }, + dictWord{9, 11, 15}, + dictWord{9, 11, 564}, + dictWord{10, 11, 14}, + dictWord{12, 11, 565}, + dictWord{13, 11, 449}, + dictWord{14, 11, 53}, + dictWord{ + 15, + 11, + 13, + }, + dictWord{16, 11, 64}, + dictWord{145, 11, 41}, + dictWord{6, 0, 884}, + dictWord{6, 0, 1019}, + dictWord{134, 0, 1150}, + dictWord{6, 11, 1767}, + dictWord{ + 12, + 11, + 194, + }, + dictWord{145, 11, 107}, + dictWord{136, 10, 503}, + dictWord{133, 11, 840}, + dictWord{7, 0, 671}, + dictWord{134, 10, 466}, + dictWord{132, 0, 888}, + dictWord{4, 0, 149}, + dictWord{138, 0, 368}, + dictWord{4, 0, 154}, + dictWord{7, 0, 1134}, + dictWord{136, 0, 105}, + dictWord{135, 0, 983}, + dictWord{9, 11, 642}, + dictWord{11, 11, 236}, + dictWord{142, 11, 193}, + dictWord{4, 0, 31}, + dictWord{6, 0, 429}, + dictWord{7, 0, 962}, + dictWord{9, 0, 458}, + dictWord{139, 0, 691}, + dictWord{ + 6, + 0, + 643, + }, + dictWord{134, 0, 1102}, + dictWord{132, 0, 312}, + dictWord{4, 11, 68}, + dictWord{5, 11, 634}, + dictWord{6, 11, 386}, + dictWord{7, 11, 794}, + dictWord{ + 8, + 11, + 273, + }, + dictWord{9, 11, 563}, + dictWord{10, 11, 105}, + dictWord{10, 11, 171}, + dictWord{11, 11, 94}, + dictWord{139, 11, 354}, + dictWord{133, 0, 740}, + dictWord{ + 135, + 0, + 1642, + }, + dictWord{4, 11, 95}, + dictWord{7, 11, 416}, + dictWord{8, 11, 211}, + dictWord{139, 11, 830}, + dictWord{132, 0, 236}, + dictWord{138, 10, 241}, + dictWord{7, 11, 731}, + dictWord{13, 11, 20}, + dictWord{143, 11, 11}, + dictWord{5, 0, 836}, + dictWord{5, 0, 857}, + dictWord{6, 0, 1680}, + dictWord{135, 0, 59}, + dictWord{ + 10, + 0, + 68, + }, + dictWord{11, 0, 494}, + dictWord{152, 11, 6}, + dictWord{4, 0, 81}, + dictWord{139, 0, 867}, + dictWord{135, 0, 795}, + dictWord{133, 11, 689}, + dictWord{ + 4, + 0, + 1001, + }, + dictWord{5, 0, 282}, + dictWord{6, 0, 1932}, + dictWord{6, 0, 1977}, + dictWord{6, 0, 1987}, + dictWord{6, 0, 1992}, + dictWord{8, 0, 650}, + dictWord{8, 0, 919}, + dictWord{8, 0, 920}, + dictWord{8, 0, 923}, + dictWord{8, 0, 926}, + dictWord{8, 0, 927}, + dictWord{8, 0, 931}, + dictWord{8, 0, 939}, + dictWord{8, 0, 947}, + dictWord{8, 0, 956}, + dictWord{8, 0, 997}, + dictWord{9, 0, 907}, + dictWord{10, 0, 950}, + dictWord{10, 0, 953}, + dictWord{10, 0, 954}, + dictWord{10, 0, 956}, + dictWord{10, 0, 958}, + dictWord{ + 10, + 0, + 959, + }, + dictWord{10, 0, 964}, + dictWord{10, 0, 970}, + dictWord{10, 0, 972}, + dictWord{10, 0, 973}, + dictWord{10, 0, 975}, + dictWord{10, 0, 976}, + dictWord{ + 10, + 0, + 980, + }, + dictWord{10, 0, 981}, + dictWord{10, 0, 984}, + dictWord{10, 0, 988}, + dictWord{10, 0, 990}, + dictWord{10, 0, 995}, + dictWord{10, 0, 999}, + dictWord{ + 10, + 0, + 1002, + }, + dictWord{10, 0, 1003}, + dictWord{10, 0, 1005}, + dictWord{10, 0, 1006}, + dictWord{10, 0, 1008}, + dictWord{10, 0, 1009}, + dictWord{10, 0, 1012}, + dictWord{10, 0, 1014}, + dictWord{10, 0, 1015}, + dictWord{10, 0, 1019}, + dictWord{10, 0, 1020}, + dictWord{10, 0, 1022}, + dictWord{12, 0, 959}, + dictWord{12, 0, 961}, + dictWord{12, 0, 962}, + dictWord{12, 0, 963}, + dictWord{12, 0, 964}, + dictWord{12, 0, 965}, + dictWord{12, 0, 967}, + dictWord{12, 0, 968}, + dictWord{12, 0, 969}, + dictWord{12, 0, 970}, + dictWord{12, 0, 971}, + dictWord{12, 0, 972}, + dictWord{12, 0, 973}, + dictWord{12, 0, 974}, + dictWord{12, 0, 975}, + dictWord{12, 0, 976}, + dictWord{ + 12, + 0, + 977, + }, + dictWord{12, 0, 979}, + dictWord{12, 0, 981}, + dictWord{12, 0, 982}, + dictWord{12, 0, 983}, + dictWord{12, 0, 984}, + dictWord{12, 0, 985}, + dictWord{ + 12, + 0, + 986, + }, + dictWord{12, 0, 987}, + dictWord{12, 0, 989}, + dictWord{12, 0, 990}, + dictWord{12, 0, 992}, + dictWord{12, 0, 993}, + dictWord{12, 0, 995}, + dictWord{12, 0, 998}, + dictWord{12, 0, 999}, + dictWord{12, 0, 1000}, + dictWord{12, 0, 1001}, + dictWord{12, 0, 1002}, + dictWord{12, 0, 1004}, + dictWord{12, 0, 1005}, + dictWord{ + 12, + 0, + 1006, + }, + dictWord{12, 0, 1007}, + dictWord{12, 0, 1008}, + dictWord{12, 0, 1009}, + dictWord{12, 0, 1010}, + dictWord{12, 0, 1011}, + dictWord{12, 0, 1012}, + dictWord{12, 0, 1014}, + dictWord{12, 0, 1015}, + dictWord{12, 0, 1016}, + dictWord{12, 0, 1017}, + dictWord{12, 0, 1018}, + dictWord{12, 0, 1019}, + dictWord{ + 12, + 0, + 1022, + }, + dictWord{12, 0, 1023}, + dictWord{14, 0, 475}, + dictWord{14, 0, 477}, + dictWord{14, 0, 478}, + dictWord{14, 0, 479}, + dictWord{14, 0, 480}, + dictWord{ + 14, + 0, + 482, + }, + dictWord{14, 0, 483}, + dictWord{14, 0, 484}, + dictWord{14, 0, 485}, + dictWord{14, 0, 486}, + dictWord{14, 0, 487}, + dictWord{14, 0, 488}, + dictWord{14, 0, 489}, + dictWord{14, 0, 490}, + dictWord{14, 0, 491}, + dictWord{14, 0, 492}, + dictWord{14, 0, 493}, + dictWord{14, 0, 494}, + dictWord{14, 0, 495}, + dictWord{14, 0, 496}, + dictWord{14, 0, 497}, + dictWord{14, 0, 498}, + dictWord{14, 0, 499}, + dictWord{14, 0, 500}, + dictWord{14, 0, 501}, + dictWord{14, 0, 502}, + dictWord{14, 0, 503}, + dictWord{ + 14, + 0, + 504, + }, + dictWord{14, 0, 506}, + dictWord{14, 0, 507}, + dictWord{14, 0, 508}, + dictWord{14, 0, 509}, + dictWord{14, 0, 510}, + dictWord{14, 0, 511}, + dictWord{ + 16, + 0, + 113, + }, + dictWord{16, 0, 114}, + dictWord{16, 0, 115}, + dictWord{16, 0, 117}, + dictWord{16, 0, 118}, + dictWord{16, 0, 119}, + dictWord{16, 0, 121}, + dictWord{16, 0, 122}, + dictWord{16, 0, 123}, + dictWord{16, 0, 124}, + dictWord{16, 0, 125}, + dictWord{16, 0, 126}, + dictWord{16, 0, 127}, + dictWord{18, 0, 242}, + dictWord{18, 0, 243}, + dictWord{18, 0, 244}, + dictWord{18, 0, 245}, + dictWord{18, 0, 248}, + dictWord{18, 0, 249}, + dictWord{18, 0, 250}, + dictWord{18, 0, 251}, + dictWord{18, 0, 252}, + dictWord{ + 18, + 0, + 253, + }, + dictWord{18, 0, 254}, + dictWord{18, 0, 255}, + dictWord{20, 0, 125}, + dictWord{20, 0, 126}, + dictWord{148, 0, 127}, + dictWord{7, 11, 1717}, + dictWord{ + 7, + 11, + 1769, + }, + dictWord{138, 11, 546}, + dictWord{7, 11, 1127}, + dictWord{7, 11, 1572}, + dictWord{10, 11, 297}, + dictWord{10, 11, 422}, + dictWord{11, 11, 764}, + dictWord{11, 11, 810}, + dictWord{12, 11, 264}, + dictWord{13, 11, 102}, + dictWord{13, 11, 300}, + dictWord{13, 11, 484}, + dictWord{14, 11, 147}, + dictWord{ + 14, + 11, + 229, + }, + dictWord{17, 11, 71}, + dictWord{18, 11, 118}, + dictWord{147, 11, 120}, + dictWord{6, 0, 1148}, + dictWord{134, 0, 1586}, + dictWord{132, 0, 775}, + dictWord{135, 10, 954}, + dictWord{133, 11, 864}, + dictWord{133, 11, 928}, + dictWord{138, 11, 189}, + dictWord{135, 10, 1958}, + dictWord{6, 10, 549}, + dictWord{ + 8, + 10, + 34, + }, + dictWord{8, 10, 283}, + dictWord{9, 10, 165}, + dictWord{138, 10, 475}, + dictWord{5, 10, 652}, + dictWord{5, 10, 701}, + dictWord{135, 10, 449}, + dictWord{135, 11, 695}, + dictWord{4, 10, 655}, + dictWord{7, 10, 850}, + dictWord{17, 10, 75}, + dictWord{146, 10, 137}, + dictWord{140, 11, 682}, + dictWord{ + 133, + 11, + 523, + }, + dictWord{8, 0, 970}, + dictWord{136, 10, 670}, + dictWord{136, 11, 555}, + dictWord{7, 11, 76}, + dictWord{8, 11, 44}, + dictWord{9, 11, 884}, + dictWord{ + 10, + 11, + 580, + }, + dictWord{11, 11, 399}, + dictWord{11, 11, 894}, + dictWord{15, 11, 122}, + dictWord{18, 11, 144}, + dictWord{147, 11, 61}, + dictWord{6, 10, 159}, + dictWord{ + 6, + 10, + 364, + }, + dictWord{7, 10, 516}, + dictWord{7, 10, 1439}, + dictWord{137, 10, 518}, + dictWord{4, 0, 71}, + dictWord{5, 0, 376}, + dictWord{7, 0, 119}, + dictWord{ + 138, + 0, + 665, + }, + dictWord{141, 10, 151}, + dictWord{11, 0, 827}, + dictWord{14, 0, 34}, + dictWord{143, 0, 148}, + dictWord{133, 11, 518}, + dictWord{4, 0, 479}, + dictWord{ + 135, + 11, + 1787, + }, + dictWord{135, 11, 1852}, + dictWord{135, 10, 993}, + dictWord{7, 0, 607}, + dictWord{136, 0, 99}, + dictWord{134, 0, 1960}, + dictWord{132, 0, 793}, + dictWord{4, 0, 41}, + dictWord{5, 0, 74}, + dictWord{7, 0, 1627}, + dictWord{11, 0, 871}, + dictWord{140, 0, 619}, + dictWord{7, 0, 94}, + dictWord{11, 0, 329}, + dictWord{ + 11, + 0, + 965, + }, + dictWord{12, 0, 241}, + dictWord{14, 0, 354}, + dictWord{15, 0, 22}, + dictWord{148, 0, 63}, + dictWord{7, 10, 501}, + dictWord{9, 10, 111}, + dictWord{10, 10, 141}, + dictWord{11, 10, 332}, + dictWord{13, 10, 43}, + dictWord{13, 10, 429}, + dictWord{14, 10, 130}, + dictWord{14, 10, 415}, + dictWord{145, 10, 102}, + dictWord{ + 9, + 0, + 209, + }, + dictWord{137, 0, 300}, + dictWord{134, 0, 1497}, + dictWord{138, 11, 255}, + dictWord{4, 11, 934}, + dictWord{5, 11, 138}, + dictWord{136, 11, 610}, + dictWord{133, 0, 98}, + dictWord{6, 0, 1316}, + dictWord{10, 11, 804}, + dictWord{138, 11, 832}, + dictWord{8, 11, 96}, + dictWord{9, 11, 36}, + dictWord{10, 11, 607}, + dictWord{11, 11, 423}, + dictWord{11, 11, 442}, + dictWord{12, 11, 309}, + dictWord{14, 11, 199}, + dictWord{15, 11, 90}, + dictWord{145, 11, 110}, + dictWord{ + 132, + 0, + 463, + }, + dictWord{5, 10, 149}, + dictWord{136, 10, 233}, + dictWord{133, 10, 935}, + dictWord{4, 11, 652}, + dictWord{8, 11, 320}, + dictWord{9, 11, 13}, + dictWord{ + 9, + 11, + 398, + }, + dictWord{9, 11, 727}, + dictWord{10, 11, 75}, + dictWord{10, 11, 184}, + dictWord{10, 11, 230}, + dictWord{10, 11, 564}, + dictWord{10, 11, 569}, + dictWord{ + 11, + 11, + 973, + }, + dictWord{12, 11, 70}, + dictWord{12, 11, 189}, + dictWord{13, 11, 57}, + dictWord{13, 11, 257}, + dictWord{22, 11, 6}, + dictWord{150, 11, 16}, + dictWord{ + 142, + 0, + 291, + }, + dictWord{12, 10, 582}, + dictWord{146, 10, 131}, + dictWord{136, 10, 801}, + dictWord{133, 0, 984}, + dictWord{145, 11, 116}, + dictWord{4, 11, 692}, + dictWord{133, 11, 321}, + dictWord{4, 0, 182}, + dictWord{6, 0, 205}, + dictWord{135, 0, 220}, + dictWord{4, 0, 42}, + dictWord{9, 0, 205}, + dictWord{9, 0, 786}, + dictWord{ + 138, + 0, + 659, + }, + dictWord{6, 0, 801}, + dictWord{11, 11, 130}, + dictWord{140, 11, 609}, + dictWord{132, 0, 635}, + dictWord{5, 11, 345}, + dictWord{135, 11, 1016}, + dictWord{139, 0, 533}, + dictWord{132, 0, 371}, + dictWord{4, 0, 272}, + dictWord{135, 0, 836}, + dictWord{6, 0, 1282}, + dictWord{135, 11, 1100}, + dictWord{5, 0, 825}, + dictWord{134, 0, 1640}, + dictWord{135, 11, 1325}, + dictWord{133, 11, 673}, + dictWord{4, 11, 287}, + dictWord{133, 11, 1018}, + dictWord{135, 0, 357}, + dictWord{ + 6, + 0, + 467, + }, + dictWord{137, 0, 879}, + dictWord{7, 0, 317}, + dictWord{135, 0, 569}, + dictWord{6, 0, 924}, + dictWord{134, 0, 1588}, + dictWord{5, 11, 34}, + dictWord{ + 5, + 10, + 406, + }, + dictWord{10, 11, 724}, + dictWord{12, 11, 444}, + dictWord{13, 11, 354}, + dictWord{18, 11, 32}, + dictWord{23, 11, 24}, + dictWord{23, 11, 31}, + dictWord{ + 152, + 11, + 5, + }, + dictWord{6, 0, 1795}, + dictWord{6, 0, 1835}, + dictWord{6, 0, 1836}, + dictWord{6, 0, 1856}, + dictWord{8, 0, 844}, + dictWord{8, 0, 849}, + dictWord{8, 0, 854}, + dictWord{8, 0, 870}, + dictWord{8, 0, 887}, + dictWord{10, 0, 852}, + dictWord{138, 0, 942}, + dictWord{6, 10, 69}, + dictWord{135, 10, 117}, + dictWord{137, 0, 307}, + dictWord{ + 4, + 0, + 944, + }, + dictWord{6, 0, 1799}, + dictWord{6, 0, 1825}, + dictWord{10, 0, 848}, + dictWord{10, 0, 875}, + dictWord{10, 0, 895}, + dictWord{10, 0, 899}, + dictWord{ + 10, + 0, + 902, + }, + dictWord{140, 0, 773}, + dictWord{11, 0, 43}, + dictWord{13, 0, 72}, + dictWord{141, 0, 142}, + dictWord{135, 10, 1830}, + dictWord{134, 11, 382}, + dictWord{ + 4, + 10, + 432, + }, + dictWord{135, 10, 824}, + dictWord{132, 11, 329}, + dictWord{7, 0, 1820}, + dictWord{139, 11, 124}, + dictWord{133, 10, 826}, + dictWord{ + 133, + 0, + 525, + }, + dictWord{132, 11, 906}, + dictWord{7, 11, 1940}, + dictWord{136, 11, 366}, + dictWord{138, 11, 10}, + dictWord{4, 11, 123}, + dictWord{4, 11, 649}, + dictWord{ + 5, + 11, + 605, + }, + dictWord{7, 11, 1509}, + dictWord{136, 11, 36}, + dictWord{6, 0, 110}, + dictWord{135, 0, 1681}, + dictWord{133, 0, 493}, + dictWord{133, 11, 767}, + dictWord{4, 0, 174}, + dictWord{135, 0, 911}, + dictWord{138, 11, 786}, + dictWord{8, 0, 417}, + dictWord{137, 0, 782}, + dictWord{133, 10, 1000}, + dictWord{7, 0, 733}, + dictWord{137, 0, 583}, + dictWord{4, 10, 297}, + dictWord{6, 10, 529}, + dictWord{7, 10, 152}, + dictWord{7, 10, 713}, + dictWord{7, 10, 1845}, + dictWord{8, 10, 710}, + dictWord{8, 10, 717}, + dictWord{12, 10, 639}, + dictWord{140, 10, 685}, + dictWord{4, 0, 32}, + dictWord{5, 0, 215}, + dictWord{6, 0, 269}, + dictWord{7, 0, 1782}, + dictWord{ + 7, + 0, + 1892, + }, + dictWord{10, 0, 16}, + dictWord{11, 0, 822}, + dictWord{11, 0, 954}, + dictWord{141, 0, 481}, + dictWord{4, 11, 273}, + dictWord{5, 11, 658}, + dictWord{ + 133, + 11, + 995, + }, + dictWord{136, 0, 477}, + dictWord{134, 11, 72}, + dictWord{135, 11, 1345}, + dictWord{5, 0, 308}, + dictWord{7, 0, 1088}, + dictWord{4, 10, 520}, + dictWord{ + 135, + 10, + 575, + }, + dictWord{133, 11, 589}, + dictWord{5, 0, 126}, + dictWord{8, 0, 297}, + dictWord{9, 0, 366}, + dictWord{140, 0, 374}, + dictWord{7, 0, 1551}, + dictWord{ + 139, + 0, + 361, + }, + dictWord{5, 11, 117}, + dictWord{6, 11, 514}, + dictWord{6, 11, 541}, + dictWord{7, 11, 1164}, + dictWord{7, 11, 1436}, + dictWord{8, 11, 220}, + dictWord{ + 8, + 11, + 648, + }, + dictWord{10, 11, 688}, + dictWord{139, 11, 560}, + dictWord{133, 11, 686}, + dictWord{4, 0, 946}, + dictWord{6, 0, 1807}, + dictWord{8, 0, 871}, + dictWord{ + 10, + 0, + 854, + }, + dictWord{10, 0, 870}, + dictWord{10, 0, 888}, + dictWord{10, 0, 897}, + dictWord{10, 0, 920}, + dictWord{12, 0, 722}, + dictWord{12, 0, 761}, + dictWord{ + 12, + 0, + 763, + }, + dictWord{12, 0, 764}, + dictWord{14, 0, 454}, + dictWord{14, 0, 465}, + dictWord{16, 0, 107}, + dictWord{18, 0, 167}, + dictWord{18, 0, 168}, + dictWord{ + 146, + 0, + 172, + }, + dictWord{132, 0, 175}, + dictWord{135, 0, 1307}, + dictWord{132, 0, 685}, + dictWord{135, 11, 1834}, + dictWord{133, 0, 797}, + dictWord{6, 0, 745}, + dictWord{ + 6, + 0, + 858, + }, + dictWord{134, 0, 963}, + dictWord{133, 0, 565}, + dictWord{5, 10, 397}, + dictWord{6, 10, 154}, + dictWord{7, 11, 196}, + dictWord{7, 10, 676}, + dictWord{ + 8, + 10, + 443, + }, + dictWord{8, 10, 609}, + dictWord{9, 10, 24}, + dictWord{9, 10, 325}, + dictWord{10, 10, 35}, + dictWord{10, 11, 765}, + dictWord{11, 11, 347}, + dictWord{ + 11, + 10, + 535, + }, + dictWord{11, 11, 552}, + dictWord{11, 11, 576}, + dictWord{11, 10, 672}, + dictWord{11, 11, 790}, + dictWord{11, 10, 1018}, + dictWord{12, 11, 263}, + dictWord{12, 10, 637}, + dictWord{13, 11, 246}, + dictWord{13, 11, 270}, + dictWord{13, 11, 395}, + dictWord{14, 11, 74}, + dictWord{14, 11, 176}, + dictWord{ + 14, + 11, + 190, + }, + dictWord{14, 11, 398}, + dictWord{14, 11, 412}, + dictWord{15, 11, 32}, + dictWord{15, 11, 63}, + dictWord{16, 10, 30}, + dictWord{16, 11, 88}, + dictWord{ + 147, + 11, + 105, + }, + dictWord{13, 11, 84}, + dictWord{141, 11, 122}, + dictWord{4, 0, 252}, + dictWord{7, 0, 1068}, + dictWord{10, 0, 434}, + dictWord{11, 0, 228}, + dictWord{ + 11, + 0, + 426, + }, + dictWord{13, 0, 231}, + dictWord{18, 0, 106}, + dictWord{148, 0, 87}, + dictWord{137, 0, 826}, + dictWord{4, 11, 589}, + dictWord{139, 11, 282}, + dictWord{ + 5, + 11, + 381, + }, + dictWord{135, 11, 1792}, + dictWord{132, 0, 791}, + dictWord{5, 0, 231}, + dictWord{10, 0, 509}, + dictWord{133, 10, 981}, + dictWord{7, 0, 601}, + dictWord{ + 9, + 0, + 277, + }, + dictWord{9, 0, 674}, + dictWord{10, 0, 178}, + dictWord{10, 0, 418}, + dictWord{10, 0, 571}, + dictWord{11, 0, 531}, + dictWord{12, 0, 113}, + dictWord{12, 0, 475}, + dictWord{13, 0, 99}, + dictWord{142, 0, 428}, + dictWord{4, 10, 56}, + dictWord{7, 11, 616}, + dictWord{7, 10, 1791}, + dictWord{8, 10, 607}, + dictWord{8, 10, 651}, + dictWord{10, 11, 413}, + dictWord{11, 10, 465}, + dictWord{11, 10, 835}, + dictWord{12, 10, 337}, + dictWord{141, 10, 480}, + dictWord{7, 0, 1591}, + dictWord{144, 0, 43}, + dictWord{9, 10, 158}, + dictWord{138, 10, 411}, + dictWord{135, 0, 1683}, + dictWord{8, 0, 289}, + dictWord{11, 0, 45}, + dictWord{12, 0, 278}, + dictWord{140, 0, 537}, + dictWord{6, 11, 120}, + dictWord{7, 11, 1188}, + dictWord{7, 11, 1710}, + dictWord{8, 11, 286}, + dictWord{9, 11, 667}, + dictWord{11, 11, 592}, + dictWord{ + 139, + 11, + 730, + }, + dictWord{136, 10, 617}, + dictWord{135, 0, 1120}, + dictWord{135, 11, 1146}, + dictWord{139, 10, 563}, + dictWord{4, 11, 352}, + dictWord{4, 10, 369}, + dictWord{135, 11, 687}, + dictWord{143, 11, 38}, + dictWord{4, 0, 399}, + dictWord{5, 0, 119}, + dictWord{5, 0, 494}, + dictWord{7, 0, 751}, + dictWord{9, 0, 556}, + dictWord{ + 14, + 11, + 179, + }, + dictWord{15, 11, 151}, + dictWord{150, 11, 11}, + dictWord{4, 11, 192}, + dictWord{5, 11, 49}, + dictWord{6, 11, 200}, + dictWord{6, 11, 293}, + dictWord{ + 6, + 11, + 1696, + }, + dictWord{135, 11, 488}, + dictWord{4, 0, 398}, + dictWord{133, 0, 660}, + dictWord{7, 0, 1030}, + dictWord{134, 10, 622}, + dictWord{135, 11, 595}, + dictWord{141, 0, 168}, + dictWord{132, 11, 147}, + dictWord{7, 0, 973}, + dictWord{10, 10, 624}, + dictWord{142, 10, 279}, + dictWord{132, 10, 363}, + dictWord{ + 132, + 0, + 642, + }, + dictWord{133, 11, 934}, + dictWord{134, 0, 1615}, + dictWord{7, 11, 505}, + dictWord{135, 11, 523}, + dictWord{7, 0, 594}, + dictWord{7, 0, 851}, + dictWord{ + 7, + 0, + 1858, + }, + dictWord{9, 0, 411}, + dictWord{9, 0, 574}, + dictWord{9, 0, 666}, + dictWord{9, 0, 737}, + dictWord{10, 0, 346}, + dictWord{10, 0, 712}, + dictWord{11, 0, 246}, + dictWord{11, 0, 432}, + dictWord{11, 0, 517}, + dictWord{11, 0, 647}, + dictWord{11, 0, 679}, + dictWord{11, 0, 727}, + dictWord{12, 0, 304}, + dictWord{12, 0, 305}, + dictWord{ + 12, + 0, + 323, + }, + dictWord{12, 0, 483}, + dictWord{12, 0, 572}, + dictWord{12, 0, 593}, + dictWord{12, 0, 602}, + dictWord{13, 0, 95}, + dictWord{13, 0, 101}, + dictWord{ + 13, + 0, + 171, + }, + dictWord{13, 0, 315}, + dictWord{13, 0, 378}, + dictWord{13, 0, 425}, + dictWord{13, 0, 475}, + dictWord{14, 0, 63}, + dictWord{14, 0, 380}, + dictWord{14, 0, 384}, + dictWord{15, 0, 133}, + dictWord{18, 0, 112}, + dictWord{148, 0, 72}, + dictWord{135, 0, 1093}, + dictWord{132, 0, 679}, + dictWord{8, 0, 913}, + dictWord{10, 0, 903}, + dictWord{10, 0, 915}, + dictWord{12, 0, 648}, + dictWord{12, 0, 649}, + dictWord{14, 0, 455}, + dictWord{16, 0, 112}, + dictWord{138, 11, 438}, + dictWord{137, 0, 203}, + dictWord{134, 10, 292}, + dictWord{134, 0, 1492}, + dictWord{7, 0, 1374}, + dictWord{8, 0, 540}, + dictWord{5, 10, 177}, + dictWord{6, 10, 616}, + dictWord{7, 10, 827}, + dictWord{9, 10, 525}, + dictWord{138, 10, 656}, + dictWord{135, 0, 1486}, + dictWord{9, 0, 714}, + dictWord{138, 10, 31}, + dictWord{136, 0, 825}, + dictWord{ + 134, + 0, + 1511, + }, + dictWord{132, 11, 637}, + dictWord{134, 0, 952}, + dictWord{4, 10, 161}, + dictWord{133, 10, 631}, + dictWord{5, 0, 143}, + dictWord{5, 0, 769}, + dictWord{ + 6, + 0, + 1760, + }, + dictWord{7, 0, 682}, + dictWord{7, 0, 1992}, + dictWord{136, 0, 736}, + dictWord{132, 0, 700}, + dictWord{134, 0, 1540}, + dictWord{132, 11, 777}, + dictWord{ + 9, + 11, + 867, + }, + dictWord{138, 11, 837}, + dictWord{7, 0, 1557}, + dictWord{135, 10, 1684}, + dictWord{133, 0, 860}, + dictWord{6, 0, 422}, + dictWord{7, 0, 0}, + dictWord{ + 7, + 0, + 1544, + }, + dictWord{9, 0, 605}, + dictWord{11, 0, 990}, + dictWord{12, 0, 235}, + dictWord{12, 0, 453}, + dictWord{13, 0, 47}, + dictWord{13, 0, 266}, + dictWord{9, 10, 469}, + dictWord{9, 10, 709}, + dictWord{12, 10, 512}, + dictWord{14, 10, 65}, + dictWord{145, 10, 12}, + dictWord{11, 0, 807}, + dictWord{10, 10, 229}, + dictWord{11, 10, 73}, + dictWord{139, 10, 376}, + dictWord{6, 11, 170}, + dictWord{7, 11, 1080}, + dictWord{8, 11, 395}, + dictWord{8, 11, 487}, + dictWord{11, 11, 125}, + dictWord{ + 141, + 11, + 147, + }, + dictWord{5, 0, 515}, + dictWord{137, 0, 131}, + dictWord{7, 0, 1605}, + dictWord{11, 0, 962}, + dictWord{146, 0, 139}, + dictWord{132, 0, 646}, + dictWord{ + 4, + 0, + 396, + }, + dictWord{7, 0, 728}, + dictWord{9, 0, 117}, + dictWord{13, 0, 202}, + dictWord{148, 0, 51}, + dictWord{6, 0, 121}, + dictWord{6, 0, 124}, + dictWord{6, 0, 357}, + dictWord{ + 7, + 0, + 1138, + }, + dictWord{7, 0, 1295}, + dictWord{8, 0, 162}, + dictWord{8, 0, 508}, + dictWord{11, 0, 655}, + dictWord{4, 11, 535}, + dictWord{6, 10, 558}, + dictWord{ + 7, + 10, + 651, + }, + dictWord{8, 11, 618}, + dictWord{9, 10, 0}, + dictWord{10, 10, 34}, + dictWord{139, 10, 1008}, + dictWord{135, 11, 1245}, + dictWord{138, 0, 357}, + dictWord{ + 150, + 11, + 23, + }, + dictWord{133, 0, 237}, + dictWord{135, 0, 1784}, + dictWord{7, 10, 1832}, + dictWord{138, 10, 374}, + dictWord{132, 0, 713}, + dictWord{132, 11, 46}, + dictWord{6, 0, 1536}, + dictWord{10, 0, 348}, + dictWord{5, 11, 811}, + dictWord{6, 11, 1679}, + dictWord{6, 11, 1714}, + dictWord{135, 11, 2032}, + dictWord{ + 11, + 11, + 182, + }, + dictWord{142, 11, 195}, + dictWord{6, 0, 523}, + dictWord{7, 0, 738}, + dictWord{7, 10, 771}, + dictWord{7, 10, 1731}, + dictWord{9, 10, 405}, + dictWord{ + 138, + 10, + 421, + }, + dictWord{7, 11, 1458}, + dictWord{9, 11, 407}, + dictWord{139, 11, 15}, + dictWord{6, 11, 34}, + dictWord{7, 11, 69}, + dictWord{7, 11, 640}, + dictWord{ + 7, + 11, + 1089, + }, + dictWord{8, 11, 708}, + dictWord{8, 11, 721}, + dictWord{9, 11, 363}, + dictWord{9, 11, 643}, + dictWord{10, 11, 628}, + dictWord{148, 11, 98}, + dictWord{ + 133, + 0, + 434, + }, + dictWord{135, 0, 1877}, + dictWord{7, 0, 571}, + dictWord{138, 0, 366}, + dictWord{5, 10, 881}, + dictWord{133, 10, 885}, + dictWord{9, 0, 513}, + dictWord{ + 10, + 0, + 25, + }, + dictWord{10, 0, 39}, + dictWord{12, 0, 122}, + dictWord{140, 0, 187}, + dictWord{132, 0, 580}, + dictWord{5, 10, 142}, + dictWord{134, 10, 546}, + dictWord{ + 132, + 11, + 462, + }, + dictWord{137, 0, 873}, + dictWord{5, 10, 466}, + dictWord{11, 10, 571}, + dictWord{12, 10, 198}, + dictWord{13, 10, 283}, + dictWord{14, 10, 186}, + dictWord{15, 10, 21}, + dictWord{143, 10, 103}, + dictWord{7, 0, 171}, + dictWord{4, 10, 185}, + dictWord{5, 10, 257}, + dictWord{5, 10, 839}, + dictWord{5, 10, 936}, + dictWord{ + 9, + 10, + 399, + }, + dictWord{10, 10, 258}, + dictWord{10, 10, 395}, + dictWord{10, 10, 734}, + dictWord{11, 10, 1014}, + dictWord{12, 10, 23}, + dictWord{13, 10, 350}, + dictWord{14, 10, 150}, + dictWord{147, 10, 6}, + dictWord{134, 0, 625}, + dictWord{7, 0, 107}, + dictWord{7, 0, 838}, + dictWord{8, 0, 550}, + dictWord{138, 0, 401}, + dictWord{ + 5, + 11, + 73, + }, + dictWord{6, 11, 23}, + dictWord{134, 11, 338}, + dictWord{4, 0, 943}, + dictWord{6, 0, 1850}, + dictWord{12, 0, 713}, + dictWord{142, 0, 434}, + dictWord{ + 11, + 0, + 588, + }, + dictWord{11, 0, 864}, + dictWord{11, 0, 936}, + dictWord{11, 0, 968}, + dictWord{12, 0, 73}, + dictWord{12, 0, 343}, + dictWord{12, 0, 394}, + dictWord{13, 0, 275}, + dictWord{14, 0, 257}, + dictWord{15, 0, 160}, + dictWord{7, 10, 404}, + dictWord{7, 10, 1377}, + dictWord{7, 10, 1430}, + dictWord{7, 10, 2017}, + dictWord{8, 10, 149}, + dictWord{8, 10, 239}, + dictWord{8, 10, 512}, + dictWord{8, 10, 793}, + dictWord{8, 10, 818}, + dictWord{9, 10, 474}, + dictWord{9, 10, 595}, + dictWord{10, 10, 122}, + dictWord{10, 10, 565}, + dictWord{10, 10, 649}, + dictWord{10, 10, 783}, + dictWord{11, 10, 239}, + dictWord{11, 10, 295}, + dictWord{11, 10, 447}, + dictWord{ + 11, + 10, + 528, + }, + dictWord{11, 10, 639}, + dictWord{11, 10, 800}, + dictWord{12, 10, 25}, + dictWord{12, 10, 157}, + dictWord{12, 10, 316}, + dictWord{12, 10, 390}, + dictWord{ + 12, + 10, + 391, + }, + dictWord{12, 10, 395}, + dictWord{12, 10, 478}, + dictWord{12, 10, 503}, + dictWord{12, 10, 592}, + dictWord{12, 10, 680}, + dictWord{13, 10, 50}, + dictWord{13, 10, 53}, + dictWord{13, 10, 132}, + dictWord{13, 10, 198}, + dictWord{13, 10, 322}, + dictWord{13, 10, 415}, + dictWord{13, 10, 511}, + dictWord{14, 10, 71}, + dictWord{14, 10, 395}, + dictWord{15, 10, 71}, + dictWord{15, 10, 136}, + dictWord{17, 10, 123}, + dictWord{18, 10, 93}, + dictWord{147, 10, 58}, + dictWord{ + 133, + 0, + 768, + }, + dictWord{11, 0, 103}, + dictWord{142, 0, 0}, + dictWord{136, 10, 712}, + dictWord{132, 0, 799}, + dictWord{132, 0, 894}, + dictWord{7, 11, 725}, + dictWord{ + 8, + 11, + 498, + }, + dictWord{139, 11, 268}, + dictWord{135, 11, 1798}, + dictWord{135, 11, 773}, + dictWord{141, 11, 360}, + dictWord{4, 10, 377}, + dictWord{152, 10, 13}, + dictWord{135, 0, 1673}, + dictWord{132, 11, 583}, + dictWord{134, 0, 1052}, + dictWord{133, 11, 220}, + dictWord{140, 11, 69}, + dictWord{132, 11, 544}, + dictWord{ + 4, + 10, + 180, + }, + dictWord{135, 10, 1906}, + dictWord{134, 0, 272}, + dictWord{4, 0, 441}, + dictWord{134, 0, 1421}, + dictWord{4, 0, 9}, + dictWord{5, 0, 128}, + dictWord{ + 7, + 0, + 368, + }, + dictWord{11, 0, 480}, + dictWord{148, 0, 3}, + dictWord{5, 11, 176}, + dictWord{6, 11, 437}, + dictWord{6, 11, 564}, + dictWord{11, 11, 181}, + dictWord{ + 141, + 11, + 183, + }, + dictWord{132, 10, 491}, + dictWord{7, 0, 1182}, + dictWord{141, 11, 67}, + dictWord{6, 0, 1346}, + dictWord{4, 10, 171}, + dictWord{138, 10, 234}, + dictWord{ + 4, + 10, + 586, + }, + dictWord{7, 10, 1186}, + dictWord{138, 10, 631}, + dictWord{136, 0, 682}, + dictWord{134, 0, 1004}, + dictWord{15, 0, 24}, + dictWord{143, 11, 24}, + dictWord{134, 0, 968}, + dictWord{4, 0, 2}, + dictWord{6, 0, 742}, + dictWord{6, 0, 793}, + dictWord{7, 0, 545}, + dictWord{7, 0, 894}, + dictWord{9, 10, 931}, + dictWord{ + 10, + 10, + 334, + }, + dictWord{148, 10, 71}, + dictWord{136, 11, 600}, + dictWord{133, 10, 765}, + dictWord{9, 0, 769}, + dictWord{140, 0, 185}, + dictWord{4, 11, 790}, + dictWord{ + 5, + 11, + 273, + }, + dictWord{134, 11, 394}, + dictWord{7, 0, 474}, + dictWord{137, 0, 578}, + dictWord{4, 11, 135}, + dictWord{6, 11, 127}, + dictWord{7, 11, 1185}, + dictWord{ + 7, + 11, + 1511, + }, + dictWord{8, 11, 613}, + dictWord{11, 11, 5}, + dictWord{12, 11, 133}, + dictWord{12, 11, 495}, + dictWord{12, 11, 586}, + dictWord{14, 11, 385}, + dictWord{15, 11, 118}, + dictWord{17, 11, 20}, + dictWord{146, 11, 98}, + dictWord{133, 10, 424}, + dictWord{5, 0, 530}, + dictWord{142, 0, 113}, + dictWord{6, 11, 230}, + dictWord{7, 11, 961}, + dictWord{7, 11, 1085}, + dictWord{136, 11, 462}, + dictWord{7, 11, 1954}, + dictWord{137, 11, 636}, + dictWord{136, 10, 714}, + dictWord{ + 149, + 11, + 6, + }, + dictWord{135, 10, 685}, + dictWord{9, 10, 420}, + dictWord{10, 10, 269}, + dictWord{10, 10, 285}, + dictWord{10, 10, 576}, + dictWord{11, 10, 397}, + dictWord{13, 10, 175}, + dictWord{145, 10, 90}, + dictWord{132, 10, 429}, + dictWord{5, 0, 556}, + dictWord{5, 11, 162}, + dictWord{136, 11, 68}, + dictWord{132, 11, 654}, + dictWord{4, 11, 156}, + dictWord{7, 11, 998}, + dictWord{7, 11, 1045}, + dictWord{7, 11, 1860}, + dictWord{9, 11, 48}, + dictWord{9, 11, 692}, + dictWord{11, 11, 419}, + dictWord{139, 11, 602}, + dictWord{6, 0, 1317}, + dictWord{8, 0, 16}, + dictWord{9, 0, 825}, + dictWord{12, 0, 568}, + dictWord{7, 11, 1276}, + dictWord{8, 11, 474}, + dictWord{137, 11, 652}, + dictWord{18, 0, 97}, + dictWord{7, 10, 18}, + dictWord{7, 10, 699}, + dictWord{7, 10, 1966}, + dictWord{8, 10, 752}, + dictWord{9, 10, 273}, + dictWord{ + 9, + 10, + 412, + }, + dictWord{9, 10, 703}, + dictWord{10, 10, 71}, + dictWord{10, 10, 427}, + dictWord{138, 10, 508}, + dictWord{10, 0, 703}, + dictWord{7, 11, 1454}, + dictWord{138, 11, 703}, + dictWord{4, 10, 53}, + dictWord{5, 10, 186}, + dictWord{135, 10, 752}, + dictWord{134, 0, 892}, + dictWord{134, 0, 1571}, + dictWord{8, 10, 575}, + dictWord{10, 10, 289}, + dictWord{139, 10, 319}, + dictWord{6, 0, 186}, + dictWord{137, 0, 426}, + dictWord{134, 0, 1101}, + dictWord{132, 10, 675}, + dictWord{ + 132, + 0, + 585, + }, + dictWord{6, 0, 1870}, + dictWord{137, 0, 937}, + dictWord{152, 11, 10}, + dictWord{9, 11, 197}, + dictWord{10, 11, 300}, + dictWord{12, 11, 473}, + dictWord{ + 13, + 11, + 90, + }, + dictWord{141, 11, 405}, + dictWord{4, 0, 93}, + dictWord{5, 0, 252}, + dictWord{6, 0, 229}, + dictWord{7, 0, 291}, + dictWord{9, 0, 550}, + dictWord{139, 0, 644}, + dictWord{137, 0, 749}, + dictWord{9, 0, 162}, + dictWord{6, 10, 209}, + dictWord{8, 10, 468}, + dictWord{9, 10, 210}, + dictWord{11, 10, 36}, + dictWord{12, 10, 28}, + dictWord{12, 10, 630}, + dictWord{13, 10, 21}, + dictWord{13, 10, 349}, + dictWord{14, 10, 7}, + dictWord{145, 10, 13}, + dictWord{132, 0, 381}, + dictWord{132, 11, 606}, + dictWord{4, 10, 342}, + dictWord{135, 10, 1179}, + dictWord{7, 11, 1587}, + dictWord{7, 11, 1707}, + dictWord{10, 11, 528}, + dictWord{139, 11, 504}, + dictWord{ + 12, + 11, + 39, + }, + dictWord{13, 11, 265}, + dictWord{141, 11, 439}, + dictWord{4, 10, 928}, + dictWord{133, 10, 910}, + dictWord{7, 10, 1838}, + dictWord{7, 11, 1978}, + dictWord{136, 11, 676}, + dictWord{6, 0, 762}, + dictWord{6, 0, 796}, + dictWord{134, 0, 956}, + dictWord{4, 10, 318}, + dictWord{4, 10, 496}, + dictWord{7, 10, 856}, + dictWord{139, 10, 654}, + dictWord{137, 11, 242}, + dictWord{4, 11, 361}, + dictWord{133, 11, 315}, + dictWord{132, 11, 461}, + dictWord{132, 11, 472}, + dictWord{ + 132, + 0, + 857, + }, + dictWord{5, 0, 21}, + dictWord{6, 0, 77}, + dictWord{6, 0, 157}, + dictWord{7, 0, 974}, + dictWord{7, 0, 1301}, + dictWord{7, 0, 1339}, + dictWord{7, 0, 1490}, + dictWord{ + 7, + 0, + 1873, + }, + dictWord{9, 0, 628}, + dictWord{7, 10, 915}, + dictWord{8, 10, 247}, + dictWord{147, 10, 0}, + dictWord{4, 10, 202}, + dictWord{5, 10, 382}, + dictWord{ + 6, + 10, + 454, + }, + dictWord{7, 10, 936}, + dictWord{7, 10, 1803}, + dictWord{8, 10, 758}, + dictWord{9, 10, 375}, + dictWord{9, 10, 895}, + dictWord{10, 10, 743}, + dictWord{ + 10, + 10, + 792, + }, + dictWord{11, 10, 978}, + dictWord{11, 10, 1012}, + dictWord{142, 10, 109}, + dictWord{7, 11, 617}, + dictWord{10, 11, 498}, + dictWord{11, 11, 501}, + dictWord{12, 11, 16}, + dictWord{140, 11, 150}, + dictWord{7, 10, 1150}, + dictWord{7, 10, 1425}, + dictWord{7, 10, 1453}, + dictWord{10, 11, 747}, + dictWord{ + 140, + 10, + 513, + }, + dictWord{133, 11, 155}, + dictWord{11, 0, 919}, + dictWord{141, 0, 409}, + dictWord{138, 10, 791}, + dictWord{10, 0, 633}, + dictWord{139, 11, 729}, + dictWord{ + 7, + 11, + 163, + }, + dictWord{8, 11, 319}, + dictWord{9, 11, 402}, + dictWord{10, 11, 24}, + dictWord{10, 11, 681}, + dictWord{11, 11, 200}, + dictWord{11, 11, 567}, + dictWord{12, 11, 253}, + dictWord{12, 11, 410}, + dictWord{142, 11, 219}, + dictWord{5, 11, 475}, + dictWord{7, 11, 1780}, + dictWord{9, 11, 230}, + dictWord{11, 11, 297}, + dictWord{11, 11, 558}, + dictWord{14, 11, 322}, + dictWord{147, 11, 76}, + dictWord{7, 0, 332}, + dictWord{6, 10, 445}, + dictWord{137, 10, 909}, + dictWord{ + 135, + 11, + 1956, + }, + dictWord{136, 11, 274}, + dictWord{134, 10, 578}, + dictWord{135, 0, 1489}, + dictWord{135, 11, 1848}, + dictWord{5, 11, 944}, + dictWord{ + 134, + 11, + 1769, + }, + dictWord{132, 11, 144}, + dictWord{136, 10, 766}, + dictWord{4, 0, 832}, + dictWord{135, 10, 541}, + dictWord{8, 0, 398}, + dictWord{9, 0, 681}, + dictWord{ + 139, + 0, + 632, + }, + dictWord{136, 0, 645}, + dictWord{9, 0, 791}, + dictWord{10, 0, 93}, + dictWord{16, 0, 13}, + dictWord{17, 0, 23}, + dictWord{18, 0, 135}, + dictWord{19, 0, 12}, + dictWord{20, 0, 1}, + dictWord{20, 0, 12}, + dictWord{148, 0, 14}, + dictWord{6, 11, 247}, + dictWord{137, 11, 555}, + dictWord{134, 0, 20}, + dictWord{132, 0, 800}, + dictWord{135, 0, 1841}, + dictWord{139, 10, 983}, + dictWord{137, 10, 768}, + dictWord{132, 10, 584}, + dictWord{141, 11, 51}, + dictWord{6, 0, 1993}, + dictWord{ + 4, + 11, + 620, + }, + dictWord{138, 11, 280}, + dictWord{136, 0, 769}, + dictWord{11, 0, 290}, + dictWord{11, 0, 665}, + dictWord{7, 11, 1810}, + dictWord{11, 11, 866}, + dictWord{ + 12, + 11, + 103, + }, + dictWord{13, 11, 495}, + dictWord{17, 11, 67}, + dictWord{147, 11, 74}, + dictWord{134, 0, 1426}, + dictWord{139, 0, 60}, + dictWord{4, 10, 326}, + dictWord{135, 10, 1770}, + dictWord{7, 0, 1874}, + dictWord{9, 0, 641}, + dictWord{132, 10, 226}, + dictWord{6, 0, 644}, + dictWord{5, 10, 426}, + dictWord{8, 10, 30}, + dictWord{ + 9, + 10, + 2, + }, + dictWord{11, 10, 549}, + dictWord{147, 10, 122}, + dictWord{5, 11, 428}, + dictWord{138, 11, 442}, + dictWord{135, 11, 1871}, + dictWord{ + 135, + 0, + 1757, + }, + dictWord{147, 10, 117}, + dictWord{135, 0, 937}, + dictWord{135, 0, 1652}, + dictWord{6, 0, 654}, + dictWord{134, 0, 1476}, + dictWord{133, 11, 99}, + dictWord{135, 0, 527}, + dictWord{132, 10, 345}, + dictWord{4, 10, 385}, + dictWord{4, 11, 397}, + dictWord{7, 10, 265}, + dictWord{135, 10, 587}, + dictWord{4, 0, 579}, + dictWord{5, 0, 226}, + dictWord{5, 0, 323}, + dictWord{135, 0, 960}, + dictWord{134, 0, 1486}, + dictWord{8, 11, 502}, + dictWord{144, 11, 9}, + dictWord{4, 10, 347}, + dictWord{ + 5, + 10, + 423, + }, + dictWord{5, 10, 996}, + dictWord{135, 10, 1329}, + dictWord{7, 11, 727}, + dictWord{146, 11, 73}, + dictWord{4, 11, 485}, + dictWord{7, 11, 353}, + dictWord{7, 10, 1259}, + dictWord{7, 11, 1523}, + dictWord{9, 10, 125}, + dictWord{139, 10, 65}, + dictWord{6, 0, 325}, + dictWord{5, 10, 136}, + dictWord{6, 11, 366}, + dictWord{ + 7, + 11, + 1384, + }, + dictWord{7, 11, 1601}, + dictWord{136, 10, 644}, + dictWord{138, 11, 160}, + dictWord{6, 0, 1345}, + dictWord{137, 11, 282}, + dictWord{18, 0, 91}, + dictWord{147, 0, 70}, + dictWord{136, 0, 404}, + dictWord{4, 11, 157}, + dictWord{133, 11, 471}, + dictWord{133, 0, 973}, + dictWord{6, 0, 135}, + dictWord{ + 135, + 0, + 1176, + }, + dictWord{8, 11, 116}, + dictWord{11, 11, 551}, + dictWord{142, 11, 159}, + dictWord{4, 0, 549}, + dictWord{4, 10, 433}, + dictWord{133, 10, 719}, + dictWord{ + 136, + 0, + 976, + }, + dictWord{5, 11, 160}, + dictWord{7, 11, 363}, + dictWord{7, 11, 589}, + dictWord{10, 11, 170}, + dictWord{141, 11, 55}, + dictWord{144, 0, 21}, + dictWord{ + 144, + 0, + 51, + }, + dictWord{135, 0, 314}, + dictWord{135, 10, 1363}, + dictWord{4, 11, 108}, + dictWord{7, 11, 405}, + dictWord{10, 11, 491}, + dictWord{139, 11, 498}, + dictWord{146, 0, 4}, + dictWord{4, 10, 555}, + dictWord{8, 10, 536}, + dictWord{10, 10, 288}, + dictWord{139, 10, 1005}, + dictWord{135, 11, 1005}, + dictWord{6, 0, 281}, + dictWord{7, 0, 6}, + dictWord{8, 0, 282}, + dictWord{8, 0, 480}, + dictWord{8, 0, 499}, + dictWord{9, 0, 198}, + dictWord{10, 0, 143}, + dictWord{10, 0, 169}, + dictWord{ + 10, + 0, + 211, + }, + dictWord{10, 0, 417}, + dictWord{10, 0, 574}, + dictWord{11, 0, 147}, + dictWord{11, 0, 395}, + dictWord{12, 0, 75}, + dictWord{12, 0, 407}, + dictWord{12, 0, 608}, + dictWord{13, 0, 500}, + dictWord{142, 0, 251}, + dictWord{6, 0, 1093}, + dictWord{6, 0, 1405}, + dictWord{9, 10, 370}, + dictWord{138, 10, 90}, + dictWord{4, 11, 926}, + dictWord{133, 11, 983}, + dictWord{135, 0, 1776}, + dictWord{134, 0, 1528}, + dictWord{132, 0, 419}, + dictWord{132, 11, 538}, + dictWord{6, 11, 294}, + dictWord{ + 7, + 11, + 1267, + }, + dictWord{136, 11, 624}, + dictWord{135, 11, 1772}, + dictWord{138, 11, 301}, + dictWord{4, 10, 257}, + dictWord{135, 10, 2031}, + dictWord{4, 0, 138}, + dictWord{7, 0, 1012}, + dictWord{7, 0, 1280}, + dictWord{9, 0, 76}, + dictWord{135, 10, 1768}, + dictWord{132, 11, 757}, + dictWord{5, 0, 29}, + dictWord{140, 0, 638}, + dictWord{7, 11, 655}, + dictWord{135, 11, 1844}, + dictWord{7, 0, 1418}, + dictWord{6, 11, 257}, + dictWord{135, 11, 1522}, + dictWord{8, 11, 469}, + dictWord{ + 138, + 11, + 47, + }, + dictWord{142, 11, 278}, + dictWord{6, 10, 83}, + dictWord{6, 10, 1733}, + dictWord{135, 10, 1389}, + dictWord{11, 11, 204}, + dictWord{11, 11, 243}, + dictWord{140, 11, 293}, + dictWord{135, 11, 1875}, + dictWord{6, 0, 1710}, + dictWord{135, 0, 2038}, + dictWord{137, 11, 299}, + dictWord{4, 0, 17}, + dictWord{5, 0, 23}, + dictWord{7, 0, 995}, + dictWord{11, 0, 383}, + dictWord{11, 0, 437}, + dictWord{12, 0, 460}, + dictWord{140, 0, 532}, + dictWord{133, 0, 862}, + dictWord{137, 10, 696}, + dictWord{6, 0, 592}, + dictWord{138, 0, 946}, + dictWord{138, 11, 599}, + dictWord{7, 10, 1718}, + dictWord{9, 10, 95}, + dictWord{9, 10, 274}, + dictWord{10, 10, 279}, + dictWord{10, 10, 317}, + dictWord{10, 10, 420}, + dictWord{11, 10, 303}, + dictWord{11, 10, 808}, + dictWord{12, 10, 134}, + dictWord{12, 10, 367}, + dictWord{ + 13, + 10, + 149, + }, + dictWord{13, 10, 347}, + dictWord{14, 10, 349}, + dictWord{14, 10, 406}, + dictWord{18, 10, 22}, + dictWord{18, 10, 89}, + dictWord{18, 10, 122}, + dictWord{ + 147, + 10, + 47, + }, + dictWord{8, 0, 70}, + dictWord{12, 0, 171}, + dictWord{141, 0, 272}, + dictWord{133, 10, 26}, + dictWord{132, 10, 550}, + dictWord{137, 0, 812}, + dictWord{ + 10, + 0, + 233, + }, + dictWord{139, 0, 76}, + dictWord{134, 0, 988}, + dictWord{134, 0, 442}, + dictWord{136, 10, 822}, + dictWord{7, 0, 896}, + dictWord{4, 10, 902}, + dictWord{ + 5, + 10, + 809, + }, + dictWord{134, 10, 122}, + dictWord{5, 11, 150}, + dictWord{7, 11, 106}, + dictWord{8, 11, 603}, + dictWord{9, 11, 593}, + dictWord{9, 11, 634}, + dictWord{ + 10, + 11, + 44, + }, + dictWord{10, 11, 173}, + dictWord{11, 11, 462}, + dictWord{11, 11, 515}, + dictWord{13, 11, 216}, + dictWord{13, 11, 288}, + dictWord{142, 11, 400}, + dictWord{136, 0, 483}, + dictWord{135, 10, 262}, + dictWord{6, 0, 1709}, + dictWord{133, 10, 620}, + dictWord{4, 10, 34}, + dictWord{5, 10, 574}, + dictWord{7, 10, 279}, + dictWord{7, 10, 1624}, + dictWord{136, 10, 601}, + dictWord{137, 10, 170}, + dictWord{147, 0, 119}, + dictWord{12, 11, 108}, + dictWord{141, 11, 291}, + dictWord{ + 11, + 0, + 69, + }, + dictWord{12, 0, 105}, + dictWord{12, 0, 117}, + dictWord{13, 0, 213}, + dictWord{14, 0, 13}, + dictWord{14, 0, 62}, + dictWord{14, 0, 177}, + dictWord{14, 0, 421}, + dictWord{15, 0, 19}, + dictWord{146, 0, 141}, + dictWord{137, 0, 309}, + dictWord{11, 11, 278}, + dictWord{142, 11, 73}, + dictWord{7, 0, 608}, + dictWord{7, 0, 976}, + dictWord{9, 0, 146}, + dictWord{10, 0, 206}, + dictWord{10, 0, 596}, + dictWord{13, 0, 218}, + dictWord{142, 0, 153}, + dictWord{133, 10, 332}, + dictWord{6, 10, 261}, + dictWord{ + 8, + 10, + 182, + }, + dictWord{139, 10, 943}, + dictWord{4, 11, 493}, + dictWord{144, 11, 55}, + dictWord{134, 10, 1721}, + dictWord{132, 0, 768}, + dictWord{4, 10, 933}, + dictWord{133, 10, 880}, + dictWord{7, 11, 555}, + dictWord{7, 11, 1316}, + dictWord{7, 11, 1412}, + dictWord{7, 11, 1839}, + dictWord{9, 11, 192}, + dictWord{ + 9, + 11, + 589, + }, + dictWord{11, 11, 241}, + dictWord{11, 11, 676}, + dictWord{11, 11, 811}, + dictWord{11, 11, 891}, + dictWord{12, 11, 140}, + dictWord{12, 11, 346}, + dictWord{ + 12, + 11, + 479, + }, + dictWord{13, 11, 30}, + dictWord{13, 11, 49}, + dictWord{13, 11, 381}, + dictWord{14, 11, 188}, + dictWord{15, 11, 150}, + dictWord{16, 11, 76}, + dictWord{18, 11, 30}, + dictWord{148, 11, 52}, + dictWord{4, 0, 518}, + dictWord{135, 0, 1136}, + dictWord{6, 11, 568}, + dictWord{7, 11, 112}, + dictWord{7, 11, 1804}, + dictWord{8, 11, 362}, + dictWord{8, 11, 410}, + dictWord{8, 11, 830}, + dictWord{9, 11, 514}, + dictWord{11, 11, 649}, + dictWord{142, 11, 157}, + dictWord{135, 11, 673}, + dictWord{8, 0, 689}, + dictWord{137, 0, 863}, + dictWord{4, 0, 18}, + dictWord{7, 0, 145}, + dictWord{7, 0, 444}, + dictWord{7, 0, 1278}, + dictWord{8, 0, 49}, + dictWord{8, 0, 400}, + dictWord{9, 0, 71}, + dictWord{9, 0, 250}, + dictWord{10, 0, 459}, + dictWord{12, 0, 160}, + dictWord{16, 0, 24}, + dictWord{132, 11, 625}, + dictWord{140, 0, 1020}, + dictWord{4, 0, 997}, + dictWord{6, 0, 1946}, + dictWord{6, 0, 1984}, + dictWord{134, 0, 1998}, + dictWord{6, 11, 16}, + dictWord{6, 11, 158}, + dictWord{7, 11, 43}, + dictWord{ + 7, + 11, + 129, + }, + dictWord{7, 11, 181}, + dictWord{8, 11, 276}, + dictWord{8, 11, 377}, + dictWord{10, 11, 523}, + dictWord{11, 11, 816}, + dictWord{12, 11, 455}, + dictWord{ + 13, + 11, + 303, + }, + dictWord{142, 11, 135}, + dictWord{133, 10, 812}, + dictWord{134, 0, 658}, + dictWord{4, 11, 1}, + dictWord{7, 11, 1143}, + dictWord{7, 11, 1463}, + dictWord{8, 11, 61}, + dictWord{9, 11, 207}, + dictWord{9, 11, 390}, + dictWord{9, 11, 467}, + dictWord{139, 11, 836}, + dictWord{150, 11, 26}, + dictWord{140, 0, 106}, + dictWord{6, 0, 1827}, + dictWord{10, 0, 931}, + dictWord{18, 0, 166}, + dictWord{20, 0, 114}, + dictWord{4, 10, 137}, + dictWord{7, 10, 1178}, + dictWord{7, 11, 1319}, + dictWord{135, 10, 1520}, + dictWord{133, 0, 1010}, + dictWord{4, 11, 723}, + dictWord{5, 11, 895}, + dictWord{7, 11, 1031}, + dictWord{8, 11, 199}, + dictWord{8, 11, 340}, + dictWord{9, 11, 153}, + dictWord{9, 11, 215}, + dictWord{10, 11, 21}, + dictWord{10, 11, 59}, + dictWord{10, 11, 80}, + dictWord{10, 11, 224}, + dictWord{11, 11, 229}, + dictWord{11, 11, 652}, + dictWord{12, 11, 192}, + dictWord{13, 11, 146}, + dictWord{142, 11, 91}, + dictWord{132, 11, 295}, + dictWord{6, 11, 619}, + dictWord{ + 7, + 11, + 898, + }, + dictWord{7, 11, 1092}, + dictWord{8, 11, 485}, + dictWord{18, 11, 28}, + dictWord{147, 11, 116}, + dictWord{137, 11, 51}, + dictWord{6, 10, 1661}, + dictWord{ + 7, + 10, + 1975, + }, + dictWord{7, 10, 2009}, + dictWord{135, 10, 2011}, + dictWord{5, 11, 309}, + dictWord{140, 11, 211}, + dictWord{5, 0, 87}, + dictWord{7, 0, 313}, + dictWord{ + 7, + 0, + 1103, + }, + dictWord{10, 0, 208}, + dictWord{10, 0, 582}, + dictWord{11, 0, 389}, + dictWord{11, 0, 813}, + dictWord{12, 0, 385}, + dictWord{13, 0, 286}, + dictWord{ + 14, + 0, + 124, + }, + dictWord{146, 0, 108}, + dictWord{5, 11, 125}, + dictWord{8, 11, 77}, + dictWord{138, 11, 15}, + dictWord{132, 0, 267}, + dictWord{133, 0, 703}, + dictWord{ + 137, + 11, + 155, + }, + dictWord{133, 11, 439}, + dictWord{11, 11, 164}, + dictWord{140, 11, 76}, + dictWord{9, 0, 496}, + dictWord{5, 10, 89}, + dictWord{7, 10, 1915}, + dictWord{ + 9, + 10, + 185, + }, + dictWord{9, 10, 235}, + dictWord{10, 10, 64}, + dictWord{10, 10, 270}, + dictWord{10, 10, 403}, + dictWord{10, 10, 469}, + dictWord{10, 10, 529}, + dictWord{10, 10, 590}, + dictWord{11, 10, 140}, + dictWord{11, 10, 860}, + dictWord{13, 10, 1}, + dictWord{13, 10, 422}, + dictWord{14, 10, 341}, + dictWord{14, 10, 364}, + dictWord{17, 10, 93}, + dictWord{18, 10, 113}, + dictWord{19, 10, 97}, + dictWord{147, 10, 113}, + dictWord{133, 10, 695}, + dictWord{135, 0, 1121}, + dictWord{ + 5, + 10, + 6, + }, + dictWord{6, 10, 183}, + dictWord{7, 10, 680}, + dictWord{7, 10, 978}, + dictWord{7, 10, 1013}, + dictWord{7, 10, 1055}, + dictWord{12, 10, 230}, + dictWord{ + 13, + 10, + 172, + }, + dictWord{146, 10, 29}, + dictWord{4, 11, 8}, + dictWord{7, 11, 1152}, + dictWord{7, 11, 1153}, + dictWord{7, 11, 1715}, + dictWord{9, 11, 374}, + dictWord{ + 10, + 11, + 478, + }, + dictWord{139, 11, 648}, + dictWord{135, 11, 1099}, + dictWord{6, 10, 29}, + dictWord{139, 10, 63}, + dictWord{4, 0, 561}, + dictWord{10, 0, 249}, + dictWord{ + 139, + 0, + 209, + }, + dictWord{132, 0, 760}, + dictWord{7, 11, 799}, + dictWord{138, 11, 511}, + dictWord{136, 11, 87}, + dictWord{9, 0, 154}, + dictWord{140, 0, 485}, + dictWord{136, 0, 255}, + dictWord{132, 0, 323}, + dictWord{140, 0, 419}, + dictWord{132, 10, 311}, + dictWord{134, 10, 1740}, + dictWord{4, 0, 368}, + dictWord{ + 135, + 0, + 641, + }, + dictWord{7, 10, 170}, + dictWord{8, 10, 90}, + dictWord{8, 10, 177}, + dictWord{8, 10, 415}, + dictWord{11, 10, 714}, + dictWord{142, 10, 281}, + dictWord{ + 4, + 11, + 69, + }, + dictWord{5, 11, 122}, + dictWord{9, 11, 656}, + dictWord{138, 11, 464}, + dictWord{5, 11, 849}, + dictWord{134, 11, 1633}, + dictWord{8, 0, 522}, + dictWord{ + 142, + 0, + 328, + }, + dictWord{11, 10, 91}, + dictWord{13, 10, 129}, + dictWord{15, 10, 101}, + dictWord{145, 10, 125}, + dictWord{7, 0, 562}, + dictWord{8, 0, 551}, + dictWord{ + 4, + 10, + 494, + }, + dictWord{6, 10, 74}, + dictWord{7, 10, 44}, + dictWord{11, 11, 499}, + dictWord{12, 10, 17}, + dictWord{15, 10, 5}, + dictWord{148, 10, 11}, + dictWord{4, 10, 276}, + dictWord{133, 10, 296}, + dictWord{9, 0, 92}, + dictWord{147, 0, 91}, + dictWord{4, 10, 7}, + dictWord{5, 10, 90}, + dictWord{5, 10, 158}, + dictWord{6, 10, 542}, + dictWord{ + 7, + 10, + 221, + }, + dictWord{7, 10, 1574}, + dictWord{9, 10, 490}, + dictWord{10, 10, 540}, + dictWord{11, 10, 443}, + dictWord{139, 10, 757}, + dictWord{6, 0, 525}, + dictWord{ + 6, + 0, + 1976, + }, + dictWord{8, 0, 806}, + dictWord{9, 0, 876}, + dictWord{140, 0, 284}, + dictWord{5, 11, 859}, + dictWord{7, 10, 588}, + dictWord{7, 11, 1160}, + dictWord{ + 8, + 11, + 107, + }, + dictWord{9, 10, 175}, + dictWord{9, 11, 291}, + dictWord{9, 11, 439}, + dictWord{10, 10, 530}, + dictWord{10, 11, 663}, + dictWord{11, 11, 609}, + dictWord{ + 140, + 11, + 197, + }, + dictWord{7, 11, 168}, + dictWord{13, 11, 196}, + dictWord{141, 11, 237}, + dictWord{139, 0, 958}, + dictWord{133, 0, 594}, + dictWord{135, 10, 580}, + dictWord{7, 10, 88}, + dictWord{136, 10, 627}, + dictWord{6, 0, 479}, + dictWord{6, 0, 562}, + dictWord{7, 0, 1060}, + dictWord{13, 0, 6}, + dictWord{5, 10, 872}, + dictWord{ + 6, + 10, + 57, + }, + dictWord{7, 10, 471}, + dictWord{9, 10, 447}, + dictWord{137, 10, 454}, + dictWord{136, 11, 413}, + dictWord{145, 11, 19}, + dictWord{4, 11, 117}, + dictWord{ + 6, + 11, + 372, + }, + dictWord{7, 11, 1905}, + dictWord{142, 11, 323}, + dictWord{4, 11, 722}, + dictWord{139, 11, 471}, + dictWord{17, 0, 61}, + dictWord{5, 10, 31}, + dictWord{134, 10, 614}, + dictWord{8, 10, 330}, + dictWord{140, 10, 477}, + dictWord{7, 10, 1200}, + dictWord{138, 10, 460}, + dictWord{6, 10, 424}, + dictWord{ + 135, + 10, + 1866, + }, + dictWord{6, 0, 1641}, + dictWord{136, 0, 820}, + dictWord{6, 0, 1556}, + dictWord{134, 0, 1618}, + dictWord{9, 11, 5}, + dictWord{12, 11, 216}, + dictWord{ + 12, + 11, + 294, + }, + dictWord{12, 11, 298}, + dictWord{12, 11, 400}, + dictWord{12, 11, 518}, + dictWord{13, 11, 229}, + dictWord{143, 11, 139}, + dictWord{15, 11, 155}, + dictWord{144, 11, 79}, + dictWord{4, 0, 302}, + dictWord{135, 0, 1766}, + dictWord{5, 10, 13}, + dictWord{134, 10, 142}, + dictWord{6, 0, 148}, + dictWord{7, 0, 1313}, + dictWord{ + 7, + 10, + 116, + }, + dictWord{8, 10, 322}, + dictWord{8, 10, 755}, + dictWord{9, 10, 548}, + dictWord{10, 10, 714}, + dictWord{11, 10, 884}, + dictWord{141, 10, 324}, + dictWord{137, 0, 676}, + dictWord{9, 11, 88}, + dictWord{139, 11, 270}, + dictWord{5, 11, 12}, + dictWord{7, 11, 375}, + dictWord{137, 11, 438}, + dictWord{134, 0, 1674}, + dictWord{7, 10, 1472}, + dictWord{135, 10, 1554}, + dictWord{11, 0, 178}, + dictWord{7, 10, 1071}, + dictWord{7, 10, 1541}, + dictWord{7, 10, 1767}, + dictWord{ + 7, + 10, + 1806, + }, + dictWord{11, 10, 162}, + dictWord{11, 10, 242}, + dictWord{12, 10, 605}, + dictWord{15, 10, 26}, + dictWord{144, 10, 44}, + dictWord{6, 0, 389}, + dictWord{ + 7, + 0, + 149, + }, + dictWord{9, 0, 142}, + dictWord{138, 0, 94}, + dictWord{140, 11, 71}, + dictWord{145, 10, 115}, + dictWord{6, 0, 8}, + dictWord{7, 0, 1881}, + dictWord{8, 0, 91}, + dictWord{11, 11, 966}, + dictWord{12, 11, 287}, + dictWord{13, 11, 342}, + dictWord{13, 11, 402}, + dictWord{15, 11, 110}, + dictWord{143, 11, 163}, + dictWord{ + 4, + 11, + 258, + }, + dictWord{136, 11, 639}, + dictWord{6, 11, 22}, + dictWord{7, 11, 903}, + dictWord{138, 11, 577}, + dictWord{133, 11, 681}, + dictWord{135, 10, 1111}, + dictWord{135, 11, 1286}, + dictWord{9, 0, 112}, + dictWord{8, 10, 1}, + dictWord{138, 10, 326}, + dictWord{5, 10, 488}, + dictWord{6, 10, 527}, + dictWord{7, 10, 489}, + dictWord{ + 7, + 10, + 1636, + }, + dictWord{8, 10, 121}, + dictWord{8, 10, 144}, + dictWord{8, 10, 359}, + dictWord{9, 10, 193}, + dictWord{9, 10, 241}, + dictWord{9, 10, 336}, + dictWord{ + 9, + 10, + 882, + }, + dictWord{11, 10, 266}, + dictWord{11, 10, 372}, + dictWord{11, 10, 944}, + dictWord{12, 10, 401}, + dictWord{140, 10, 641}, + dictWord{4, 11, 664}, + dictWord{133, 11, 804}, + dictWord{6, 0, 747}, + dictWord{134, 0, 1015}, + dictWord{135, 0, 1746}, + dictWord{9, 10, 31}, + dictWord{10, 10, 244}, + dictWord{ + 10, + 10, + 699, + }, + dictWord{12, 10, 149}, + dictWord{141, 10, 497}, + dictWord{133, 10, 377}, + dictWord{135, 0, 24}, + dictWord{6, 0, 1352}, + dictWord{5, 11, 32}, + dictWord{ + 145, + 10, + 101, + }, + dictWord{7, 0, 1530}, + dictWord{10, 0, 158}, + dictWord{13, 0, 13}, + dictWord{13, 0, 137}, + dictWord{13, 0, 258}, + dictWord{14, 0, 111}, + dictWord{ + 14, + 0, + 225, + }, + dictWord{14, 0, 253}, + dictWord{14, 0, 304}, + dictWord{14, 0, 339}, + dictWord{14, 0, 417}, + dictWord{146, 0, 33}, + dictWord{4, 0, 503}, + dictWord{ + 135, + 0, + 1661, + }, + dictWord{5, 0, 130}, + dictWord{6, 0, 845}, + dictWord{7, 0, 1314}, + dictWord{9, 0, 610}, + dictWord{10, 0, 718}, + dictWord{11, 0, 601}, + dictWord{11, 0, 819}, + dictWord{11, 0, 946}, + dictWord{140, 0, 536}, + dictWord{10, 0, 149}, + dictWord{11, 0, 280}, + dictWord{142, 0, 336}, + dictWord{134, 0, 1401}, + dictWord{ + 135, + 0, + 1946, + }, + dictWord{8, 0, 663}, + dictWord{144, 0, 8}, + dictWord{134, 0, 1607}, + dictWord{135, 10, 2023}, + dictWord{4, 11, 289}, + dictWord{7, 11, 629}, + dictWord{ + 7, + 11, + 1698, + }, + dictWord{7, 11, 1711}, + dictWord{140, 11, 215}, + dictWord{6, 11, 450}, + dictWord{136, 11, 109}, + dictWord{10, 0, 882}, + dictWord{10, 0, 883}, + dictWord{10, 0, 914}, + dictWord{138, 0, 928}, + dictWord{133, 10, 843}, + dictWord{136, 11, 705}, + dictWord{132, 10, 554}, + dictWord{133, 10, 536}, + dictWord{ + 5, + 0, + 417, + }, + dictWord{9, 10, 79}, + dictWord{11, 10, 625}, + dictWord{145, 10, 7}, + dictWord{7, 11, 1238}, + dictWord{142, 11, 37}, + dictWord{4, 0, 392}, + dictWord{ + 135, + 0, + 1597, + }, + dictWord{5, 0, 433}, + dictWord{9, 0, 633}, + dictWord{11, 0, 629}, + dictWord{132, 10, 424}, + dictWord{7, 10, 336}, + dictWord{136, 10, 785}, + dictWord{ + 134, + 11, + 355, + }, + dictWord{6, 0, 234}, + dictWord{7, 0, 769}, + dictWord{9, 0, 18}, + dictWord{138, 0, 358}, + dictWord{4, 10, 896}, + dictWord{134, 10, 1777}, + dictWord{ + 138, + 11, + 323, + }, + dictWord{7, 0, 140}, + dictWord{7, 0, 1950}, + dictWord{8, 0, 680}, + dictWord{11, 0, 817}, + dictWord{147, 0, 88}, + dictWord{7, 0, 1222}, + dictWord{ + 138, + 0, + 386, + }, + dictWord{139, 11, 908}, + dictWord{11, 0, 249}, + dictWord{12, 0, 313}, + dictWord{16, 0, 66}, + dictWord{145, 0, 26}, + dictWord{134, 0, 5}, + dictWord{7, 10, 750}, + dictWord{9, 10, 223}, + dictWord{11, 10, 27}, + dictWord{11, 10, 466}, + dictWord{12, 10, 624}, + dictWord{14, 10, 265}, + dictWord{146, 10, 61}, + dictWord{ + 134, + 11, + 26, + }, + dictWord{134, 0, 1216}, + dictWord{5, 0, 963}, + dictWord{134, 0, 1773}, + dictWord{4, 11, 414}, + dictWord{5, 11, 467}, + dictWord{9, 11, 654}, + dictWord{ + 10, + 11, + 451, + }, + dictWord{12, 11, 59}, + dictWord{141, 11, 375}, + dictWord{135, 11, 17}, + dictWord{4, 10, 603}, + dictWord{133, 10, 661}, + dictWord{4, 10, 11}, + dictWord{ + 6, + 10, + 128, + }, + dictWord{7, 10, 231}, + dictWord{7, 10, 1533}, + dictWord{138, 10, 725}, + dictWord{135, 11, 955}, + dictWord{7, 0, 180}, + dictWord{8, 0, 509}, + dictWord{ + 136, + 0, + 792, + }, + dictWord{132, 10, 476}, + dictWord{132, 0, 1002}, + dictWord{133, 11, 538}, + dictWord{135, 10, 1807}, + dictWord{132, 0, 931}, + dictWord{7, 0, 943}, + dictWord{11, 0, 614}, + dictWord{140, 0, 747}, + dictWord{135, 0, 1837}, + dictWord{9, 10, 20}, + dictWord{10, 10, 324}, + dictWord{10, 10, 807}, + dictWord{ + 139, + 10, + 488, + }, + dictWord{134, 0, 641}, + dictWord{6, 11, 280}, + dictWord{10, 11, 502}, + dictWord{11, 11, 344}, + dictWord{140, 11, 38}, + dictWord{5, 11, 45}, + dictWord{ + 7, + 11, + 1161, + }, + dictWord{11, 11, 448}, + dictWord{11, 11, 880}, + dictWord{13, 11, 139}, + dictWord{13, 11, 407}, + dictWord{15, 11, 16}, + dictWord{17, 11, 95}, + dictWord{ + 18, + 11, + 66, + }, + dictWord{18, 11, 88}, + dictWord{18, 11, 123}, + dictWord{149, 11, 7}, + dictWord{9, 0, 280}, + dictWord{138, 0, 134}, + dictWord{22, 0, 22}, + dictWord{23, 0, 5}, + dictWord{151, 0, 29}, + dictWord{136, 11, 777}, + dictWord{4, 0, 90}, + dictWord{5, 0, 545}, + dictWord{7, 0, 754}, + dictWord{9, 0, 186}, + dictWord{10, 0, 72}, + dictWord{ + 10, + 0, + 782, + }, + dictWord{11, 0, 577}, + dictWord{11, 0, 610}, + dictWord{11, 0, 960}, + dictWord{12, 0, 354}, + dictWord{12, 0, 362}, + dictWord{12, 0, 595}, + dictWord{ + 4, + 11, + 410, + }, + dictWord{135, 11, 521}, + dictWord{135, 11, 1778}, + dictWord{5, 10, 112}, + dictWord{6, 10, 103}, + dictWord{134, 10, 150}, + dictWord{138, 10, 356}, + dictWord{132, 0, 742}, + dictWord{7, 0, 151}, + dictWord{9, 0, 329}, + dictWord{139, 0, 254}, + dictWord{8, 0, 853}, + dictWord{8, 0, 881}, + dictWord{8, 0, 911}, + dictWord{ + 8, + 0, + 912, + }, + dictWord{10, 0, 872}, + dictWord{12, 0, 741}, + dictWord{12, 0, 742}, + dictWord{152, 0, 18}, + dictWord{4, 11, 573}, + dictWord{136, 11, 655}, + dictWord{ + 6, + 0, + 921, + }, + dictWord{134, 0, 934}, + dictWord{9, 0, 187}, + dictWord{10, 0, 36}, + dictWord{11, 0, 1016}, + dictWord{17, 0, 44}, + dictWord{146, 0, 64}, + dictWord{7, 0, 833}, + dictWord{136, 0, 517}, + dictWord{4, 0, 506}, + dictWord{5, 0, 295}, + dictWord{135, 0, 1680}, + dictWord{4, 10, 708}, + dictWord{8, 10, 15}, + dictWord{9, 10, 50}, + dictWord{ + 9, + 10, + 386, + }, + dictWord{11, 10, 18}, + dictWord{11, 10, 529}, + dictWord{140, 10, 228}, + dictWord{7, 0, 251}, + dictWord{7, 0, 1701}, + dictWord{8, 0, 436}, + dictWord{ + 4, + 10, + 563, + }, + dictWord{7, 10, 592}, + dictWord{7, 10, 637}, + dictWord{7, 10, 770}, + dictWord{8, 10, 463}, + dictWord{9, 10, 60}, + dictWord{9, 10, 335}, + dictWord{9, 10, 904}, + dictWord{10, 10, 73}, + dictWord{11, 10, 434}, + dictWord{12, 10, 585}, + dictWord{13, 10, 331}, + dictWord{18, 10, 110}, + dictWord{148, 10, 60}, + dictWord{ + 132, + 10, + 502, + }, + dictWord{136, 0, 584}, + dictWord{6, 10, 347}, + dictWord{138, 10, 161}, + dictWord{7, 0, 987}, + dictWord{9, 0, 688}, + dictWord{10, 0, 522}, + dictWord{ + 11, + 0, + 788, + }, + dictWord{12, 0, 137}, + dictWord{12, 0, 566}, + dictWord{14, 0, 9}, + dictWord{14, 0, 24}, + dictWord{14, 0, 64}, + dictWord{7, 11, 899}, + dictWord{142, 11, 325}, + dictWord{4, 0, 214}, + dictWord{5, 0, 500}, + dictWord{5, 10, 102}, + dictWord{6, 10, 284}, + dictWord{7, 10, 1079}, + dictWord{7, 10, 1423}, + dictWord{7, 10, 1702}, + dictWord{ + 8, + 10, + 470, + }, + dictWord{9, 10, 554}, + dictWord{9, 10, 723}, + dictWord{139, 10, 333}, + dictWord{7, 10, 246}, + dictWord{135, 10, 840}, + dictWord{6, 10, 10}, + dictWord{ + 8, + 10, + 571, + }, + dictWord{9, 10, 739}, + dictWord{143, 10, 91}, + dictWord{133, 10, 626}, + dictWord{146, 0, 195}, + dictWord{134, 0, 1775}, + dictWord{7, 0, 389}, + dictWord{7, 0, 700}, + dictWord{7, 0, 940}, + dictWord{8, 0, 514}, + dictWord{9, 0, 116}, + dictWord{9, 0, 535}, + dictWord{10, 0, 118}, + dictWord{11, 0, 107}, + dictWord{ + 11, + 0, + 148, + }, + dictWord{11, 0, 922}, + dictWord{12, 0, 254}, + dictWord{12, 0, 421}, + dictWord{142, 0, 238}, + dictWord{5, 10, 18}, + dictWord{6, 10, 526}, + dictWord{13, 10, 24}, + dictWord{13, 10, 110}, + dictWord{19, 10, 5}, + dictWord{147, 10, 44}, + dictWord{132, 0, 743}, + dictWord{11, 0, 292}, + dictWord{4, 10, 309}, + dictWord{5, 10, 462}, + dictWord{7, 10, 970}, + dictWord{135, 10, 1097}, + dictWord{22, 10, 30}, + dictWord{150, 10, 33}, + dictWord{139, 11, 338}, + dictWord{135, 11, 1598}, + dictWord{ + 7, + 0, + 1283, + }, + dictWord{9, 0, 227}, + dictWord{11, 0, 325}, + dictWord{11, 0, 408}, + dictWord{14, 0, 180}, + dictWord{146, 0, 47}, + dictWord{4, 0, 953}, + dictWord{6, 0, 1805}, + dictWord{6, 0, 1814}, + dictWord{6, 0, 1862}, + dictWord{140, 0, 774}, + dictWord{6, 11, 611}, + dictWord{135, 11, 1733}, + dictWord{135, 11, 1464}, + dictWord{ + 5, + 0, + 81, + }, + dictWord{7, 0, 146}, + dictWord{7, 0, 1342}, + dictWord{8, 0, 53}, + dictWord{8, 0, 561}, + dictWord{8, 0, 694}, + dictWord{8, 0, 754}, + dictWord{9, 0, 115}, + dictWord{ + 9, + 0, + 179, + }, + dictWord{9, 0, 894}, + dictWord{10, 0, 462}, + dictWord{10, 0, 813}, + dictWord{11, 0, 230}, + dictWord{11, 0, 657}, + dictWord{11, 0, 699}, + dictWord{11, 0, 748}, + dictWord{12, 0, 119}, + dictWord{12, 0, 200}, + dictWord{12, 0, 283}, + dictWord{142, 0, 273}, + dictWord{5, 0, 408}, + dictWord{6, 0, 789}, + dictWord{6, 0, 877}, + dictWord{ + 6, + 0, + 1253, + }, + dictWord{6, 0, 1413}, + dictWord{137, 0, 747}, + dictWord{134, 10, 1704}, + dictWord{135, 11, 663}, + dictWord{6, 0, 1910}, + dictWord{6, 0, 1915}, + dictWord{6, 0, 1923}, + dictWord{9, 0, 913}, + dictWord{9, 0, 928}, + dictWord{9, 0, 950}, + dictWord{9, 0, 954}, + dictWord{9, 0, 978}, + dictWord{9, 0, 993}, + dictWord{12, 0, 812}, + dictWord{12, 0, 819}, + dictWord{12, 0, 831}, + dictWord{12, 0, 833}, + dictWord{12, 0, 838}, + dictWord{12, 0, 909}, + dictWord{12, 0, 928}, + dictWord{12, 0, 931}, + dictWord{12, 0, 950}, + dictWord{15, 0, 186}, + dictWord{15, 0, 187}, + dictWord{15, 0, 195}, + dictWord{15, 0, 196}, + dictWord{15, 0, 209}, + dictWord{15, 0, 215}, + dictWord{ + 15, + 0, + 236, + }, + dictWord{15, 0, 241}, + dictWord{15, 0, 249}, + dictWord{15, 0, 253}, + dictWord{18, 0, 180}, + dictWord{18, 0, 221}, + dictWord{18, 0, 224}, + dictWord{ + 18, + 0, + 227, + }, + dictWord{18, 0, 229}, + dictWord{149, 0, 60}, + dictWord{7, 0, 1826}, + dictWord{135, 0, 1938}, + dictWord{11, 0, 490}, + dictWord{18, 0, 143}, + dictWord{ + 5, + 10, + 86, + }, + dictWord{7, 10, 743}, + dictWord{9, 10, 85}, + dictWord{10, 10, 281}, + dictWord{10, 10, 432}, + dictWord{12, 10, 251}, + dictWord{13, 10, 118}, + dictWord{ + 142, + 10, + 378, + }, + dictWord{5, 10, 524}, + dictWord{133, 10, 744}, + dictWord{141, 11, 442}, + dictWord{10, 10, 107}, + dictWord{140, 10, 436}, + dictWord{135, 11, 503}, + dictWord{134, 0, 1162}, + dictWord{132, 10, 927}, + dictWord{7, 0, 30}, + dictWord{8, 0, 86}, + dictWord{8, 0, 315}, + dictWord{8, 0, 700}, + dictWord{9, 0, 576}, + dictWord{ + 9, + 0, + 858, + }, + dictWord{10, 0, 414}, + dictWord{11, 0, 310}, + dictWord{11, 0, 888}, + dictWord{11, 0, 904}, + dictWord{12, 0, 361}, + dictWord{13, 0, 248}, + dictWord{13, 0, 371}, + dictWord{14, 0, 142}, + dictWord{12, 10, 670}, + dictWord{146, 10, 94}, + dictWord{134, 0, 721}, + dictWord{4, 11, 113}, + dictWord{5, 11, 163}, + dictWord{5, 11, 735}, + dictWord{7, 11, 1009}, + dictWord{7, 10, 1149}, + dictWord{9, 11, 9}, + dictWord{9, 10, 156}, + dictWord{9, 11, 771}, + dictWord{12, 11, 90}, + dictWord{13, 11, 138}, + dictWord{13, 11, 410}, + dictWord{143, 11, 128}, + dictWord{138, 0, 839}, + dictWord{133, 10, 778}, + dictWord{137, 0, 617}, + dictWord{133, 10, 502}, + dictWord{ + 8, + 10, + 196, + }, + dictWord{10, 10, 283}, + dictWord{139, 10, 406}, + dictWord{6, 0, 428}, + dictWord{7, 0, 524}, + dictWord{8, 0, 169}, + dictWord{8, 0, 234}, + dictWord{9, 0, 480}, + dictWord{138, 0, 646}, + dictWord{133, 10, 855}, + dictWord{134, 0, 1648}, + dictWord{7, 0, 1205}, + dictWord{138, 0, 637}, + dictWord{7, 0, 1596}, + dictWord{ + 4, + 11, + 935, + }, + dictWord{133, 11, 823}, + dictWord{5, 11, 269}, + dictWord{7, 11, 434}, + dictWord{7, 11, 891}, + dictWord{8, 11, 339}, + dictWord{9, 11, 702}, + dictWord{ + 11, + 11, + 594, + }, + dictWord{11, 11, 718}, + dictWord{145, 11, 100}, + dictWord{7, 11, 878}, + dictWord{9, 11, 485}, + dictWord{141, 11, 264}, + dictWord{4, 0, 266}, + dictWord{ + 8, + 0, + 4, + }, + dictWord{9, 0, 39}, + dictWord{10, 0, 166}, + dictWord{11, 0, 918}, + dictWord{12, 0, 635}, + dictWord{20, 0, 10}, + dictWord{22, 0, 27}, + dictWord{22, 0, 43}, + dictWord{ + 22, + 0, + 52, + }, + dictWord{134, 11, 1713}, + dictWord{7, 10, 1400}, + dictWord{9, 10, 446}, + dictWord{138, 10, 45}, + dictWord{135, 11, 900}, + dictWord{132, 0, 862}, + dictWord{134, 0, 1554}, + dictWord{135, 11, 1033}, + dictWord{19, 0, 16}, + dictWord{147, 11, 16}, + dictWord{135, 11, 1208}, + dictWord{7, 0, 157}, + dictWord{ + 136, + 0, + 279, + }, + dictWord{6, 0, 604}, + dictWord{136, 0, 391}, + dictWord{13, 10, 455}, + dictWord{15, 10, 99}, + dictWord{15, 10, 129}, + dictWord{144, 10, 68}, + dictWord{ + 135, + 10, + 172, + }, + dictWord{7, 0, 945}, + dictWord{11, 0, 713}, + dictWord{139, 0, 744}, + dictWord{4, 0, 973}, + dictWord{10, 0, 877}, + dictWord{10, 0, 937}, + dictWord{ + 10, + 0, + 938, + }, + dictWord{140, 0, 711}, + dictWord{139, 0, 1022}, + dictWord{132, 10, 568}, + dictWord{142, 11, 143}, + dictWord{4, 0, 567}, + dictWord{9, 0, 859}, + dictWord{ + 132, + 10, + 732, + }, + dictWord{7, 0, 1846}, + dictWord{136, 0, 628}, + dictWord{136, 10, 733}, + dictWord{133, 0, 762}, + dictWord{4, 10, 428}, + dictWord{135, 10, 1789}, + dictWord{10, 0, 784}, + dictWord{13, 0, 191}, + dictWord{7, 10, 2015}, + dictWord{140, 10, 665}, + dictWord{133, 0, 298}, + dictWord{7, 0, 633}, + dictWord{7, 0, 905}, + dictWord{7, 0, 909}, + dictWord{7, 0, 1538}, + dictWord{9, 0, 767}, + dictWord{140, 0, 636}, + dictWord{138, 10, 806}, + dictWord{132, 0, 795}, + dictWord{139, 0, 301}, + dictWord{135, 0, 1970}, + dictWord{5, 11, 625}, + dictWord{135, 11, 1617}, + dictWord{135, 11, 275}, + dictWord{7, 11, 37}, + dictWord{8, 11, 425}, + dictWord{ + 8, + 11, + 693, + }, + dictWord{9, 11, 720}, + dictWord{10, 11, 380}, + dictWord{10, 11, 638}, + dictWord{11, 11, 273}, + dictWord{11, 11, 307}, + dictWord{11, 11, 473}, + dictWord{ + 12, + 11, + 61, + }, + dictWord{143, 11, 43}, + dictWord{135, 11, 198}, + dictWord{134, 0, 1236}, + dictWord{7, 0, 369}, + dictWord{12, 0, 644}, + dictWord{12, 0, 645}, + dictWord{144, 0, 90}, + dictWord{19, 0, 15}, + dictWord{149, 0, 27}, + dictWord{6, 0, 71}, + dictWord{7, 0, 845}, + dictWord{8, 0, 160}, + dictWord{9, 0, 318}, + dictWord{6, 10, 1623}, + dictWord{134, 10, 1681}, + dictWord{134, 0, 1447}, + dictWord{134, 0, 1255}, + dictWord{138, 0, 735}, + dictWord{8, 0, 76}, + dictWord{132, 11, 168}, + dictWord{ + 6, + 10, + 1748, + }, + dictWord{8, 10, 715}, + dictWord{9, 10, 802}, + dictWord{10, 10, 46}, + dictWord{10, 10, 819}, + dictWord{13, 10, 308}, + dictWord{14, 10, 351}, + dictWord{14, 10, 363}, + dictWord{146, 10, 67}, + dictWord{135, 11, 91}, + dictWord{6, 0, 474}, + dictWord{4, 10, 63}, + dictWord{133, 10, 347}, + dictWord{133, 10, 749}, + dictWord{138, 0, 841}, + dictWord{133, 10, 366}, + dictWord{6, 0, 836}, + dictWord{132, 11, 225}, + dictWord{135, 0, 1622}, + dictWord{135, 10, 89}, + dictWord{ + 140, + 0, + 735, + }, + dictWord{134, 0, 1601}, + dictWord{138, 11, 145}, + dictWord{6, 0, 1390}, + dictWord{137, 0, 804}, + dictWord{142, 0, 394}, + dictWord{6, 11, 15}, + dictWord{ + 7, + 11, + 70, + }, + dictWord{10, 11, 240}, + dictWord{147, 11, 93}, + dictWord{6, 0, 96}, + dictWord{135, 0, 1426}, + dictWord{4, 0, 651}, + dictWord{133, 0, 289}, + dictWord{ + 7, + 11, + 956, + }, + dictWord{7, 10, 977}, + dictWord{7, 11, 1157}, + dictWord{7, 11, 1506}, + dictWord{7, 11, 1606}, + dictWord{7, 11, 1615}, + dictWord{7, 11, 1619}, + dictWord{ + 7, + 11, + 1736, + }, + dictWord{7, 11, 1775}, + dictWord{8, 11, 590}, + dictWord{9, 11, 324}, + dictWord{9, 11, 736}, + dictWord{9, 11, 774}, + dictWord{9, 11, 776}, + dictWord{ + 9, + 11, + 784, + }, + dictWord{10, 11, 567}, + dictWord{10, 11, 708}, + dictWord{11, 11, 518}, + dictWord{11, 11, 613}, + dictWord{11, 11, 695}, + dictWord{11, 11, 716}, + dictWord{11, 11, 739}, + dictWord{11, 11, 770}, + dictWord{11, 11, 771}, + dictWord{11, 11, 848}, + dictWord{11, 11, 857}, + dictWord{11, 11, 931}, + dictWord{ + 11, + 11, + 947, + }, + dictWord{12, 11, 326}, + dictWord{12, 11, 387}, + dictWord{12, 11, 484}, + dictWord{12, 11, 528}, + dictWord{12, 11, 552}, + dictWord{12, 11, 613}, + dictWord{ + 13, + 11, + 189, + }, + dictWord{13, 11, 256}, + dictWord{13, 11, 340}, + dictWord{13, 11, 432}, + dictWord{13, 11, 436}, + dictWord{13, 11, 440}, + dictWord{13, 11, 454}, + dictWord{14, 11, 174}, + dictWord{14, 11, 220}, + dictWord{14, 11, 284}, + dictWord{14, 11, 390}, + dictWord{145, 11, 121}, + dictWord{7, 0, 688}, + dictWord{8, 0, 35}, + dictWord{9, 0, 511}, + dictWord{10, 0, 767}, + dictWord{147, 0, 118}, + dictWord{134, 0, 667}, + dictWord{4, 0, 513}, + dictWord{5, 10, 824}, + dictWord{133, 10, 941}, + dictWord{7, 10, 440}, + dictWord{8, 10, 230}, + dictWord{139, 10, 106}, + dictWord{134, 0, 2034}, + dictWord{135, 11, 1399}, + dictWord{143, 11, 66}, + dictWord{ + 135, + 11, + 1529, + }, + dictWord{4, 11, 145}, + dictWord{6, 11, 176}, + dictWord{7, 11, 395}, + dictWord{9, 11, 562}, + dictWord{144, 11, 28}, + dictWord{132, 11, 501}, + dictWord{132, 0, 704}, + dictWord{134, 0, 1524}, + dictWord{7, 0, 1078}, + dictWord{134, 11, 464}, + dictWord{6, 11, 509}, + dictWord{10, 11, 82}, + dictWord{20, 11, 91}, + dictWord{151, 11, 13}, + dictWord{4, 0, 720}, + dictWord{133, 0, 306}, + dictWord{133, 0, 431}, + dictWord{7, 0, 1196}, + dictWord{4, 10, 914}, + dictWord{5, 10, 800}, + dictWord{133, 10, 852}, + dictWord{135, 11, 1189}, + dictWord{10, 0, 54}, + dictWord{141, 10, 115}, + dictWord{7, 10, 564}, + dictWord{142, 10, 168}, + dictWord{ + 5, + 0, + 464, + }, + dictWord{6, 0, 236}, + dictWord{7, 0, 696}, + dictWord{7, 0, 914}, + dictWord{7, 0, 1108}, + dictWord{7, 0, 1448}, + dictWord{9, 0, 15}, + dictWord{9, 0, 564}, + dictWord{ + 10, + 0, + 14, + }, + dictWord{12, 0, 565}, + dictWord{13, 0, 449}, + dictWord{14, 0, 53}, + dictWord{15, 0, 13}, + dictWord{16, 0, 64}, + dictWord{17, 0, 41}, + dictWord{4, 10, 918}, + dictWord{133, 10, 876}, + dictWord{6, 0, 1418}, + dictWord{134, 10, 1764}, + dictWord{4, 10, 92}, + dictWord{133, 10, 274}, + dictWord{134, 0, 907}, + dictWord{ + 4, + 11, + 114, + }, + dictWord{8, 10, 501}, + dictWord{9, 11, 492}, + dictWord{13, 11, 462}, + dictWord{142, 11, 215}, + dictWord{4, 11, 77}, + dictWord{5, 11, 361}, + dictWord{ + 6, + 11, + 139, + }, + dictWord{6, 11, 401}, + dictWord{6, 11, 404}, + dictWord{7, 11, 413}, + dictWord{7, 11, 715}, + dictWord{7, 11, 1716}, + dictWord{11, 11, 279}, + dictWord{ + 12, + 11, + 179, + }, + dictWord{12, 11, 258}, + dictWord{13, 11, 244}, + dictWord{142, 11, 358}, + dictWord{6, 0, 1767}, + dictWord{12, 0, 194}, + dictWord{145, 0, 107}, + dictWord{ + 134, + 11, + 1717, + }, + dictWord{5, 10, 743}, + dictWord{142, 11, 329}, + dictWord{4, 10, 49}, + dictWord{7, 10, 280}, + dictWord{135, 10, 1633}, + dictWord{5, 0, 840}, + dictWord{7, 11, 1061}, + dictWord{8, 11, 82}, + dictWord{11, 11, 250}, + dictWord{12, 11, 420}, + dictWord{141, 11, 184}, + dictWord{135, 11, 724}, + dictWord{ + 134, + 0, + 900, + }, + dictWord{136, 10, 47}, + dictWord{134, 0, 1436}, + dictWord{144, 11, 0}, + dictWord{6, 0, 675}, + dictWord{7, 0, 1008}, + dictWord{7, 0, 1560}, + dictWord{ + 9, + 0, + 642, + }, + dictWord{11, 0, 236}, + dictWord{14, 0, 193}, + dictWord{5, 10, 272}, + dictWord{5, 10, 908}, + dictWord{5, 10, 942}, + dictWord{8, 10, 197}, + dictWord{9, 10, 47}, + dictWord{11, 10, 538}, + dictWord{139, 10, 742}, + dictWord{4, 0, 68}, + dictWord{5, 0, 628}, + dictWord{5, 0, 634}, + dictWord{6, 0, 386}, + dictWord{7, 0, 794}, + dictWord{ + 8, + 0, + 273, + }, + dictWord{9, 0, 563}, + dictWord{10, 0, 105}, + dictWord{10, 0, 171}, + dictWord{11, 0, 94}, + dictWord{139, 0, 354}, + dictWord{135, 10, 1911}, + dictWord{ + 137, + 10, + 891, + }, + dictWord{4, 0, 95}, + dictWord{6, 0, 1297}, + dictWord{6, 0, 1604}, + dictWord{7, 0, 416}, + dictWord{139, 0, 830}, + dictWord{6, 11, 513}, + dictWord{ + 135, + 11, + 1052, + }, + dictWord{7, 0, 731}, + dictWord{13, 0, 20}, + dictWord{143, 0, 11}, + dictWord{137, 11, 899}, + dictWord{10, 0, 850}, + dictWord{140, 0, 697}, + dictWord{ + 4, + 0, + 662, + }, + dictWord{7, 11, 1417}, + dictWord{12, 11, 382}, + dictWord{17, 11, 48}, + dictWord{152, 11, 12}, + dictWord{133, 0, 736}, + dictWord{132, 0, 861}, + dictWord{ + 4, + 10, + 407, + }, + dictWord{132, 10, 560}, + dictWord{141, 10, 490}, + dictWord{6, 11, 545}, + dictWord{7, 11, 565}, + dictWord{7, 11, 1669}, + dictWord{10, 11, 114}, + dictWord{11, 11, 642}, + dictWord{140, 11, 618}, + dictWord{6, 0, 871}, + dictWord{134, 0, 1000}, + dictWord{5, 0, 864}, + dictWord{10, 0, 648}, + dictWord{11, 0, 671}, + dictWord{15, 0, 46}, + dictWord{133, 11, 5}, + dictWord{133, 0, 928}, + dictWord{11, 0, 90}, + dictWord{13, 0, 7}, + dictWord{4, 10, 475}, + dictWord{11, 10, 35}, + dictWord{ + 13, + 10, + 71, + }, + dictWord{13, 10, 177}, + dictWord{142, 10, 422}, + dictWord{136, 0, 332}, + dictWord{135, 11, 192}, + dictWord{134, 0, 1055}, + dictWord{136, 11, 763}, + dictWord{11, 0, 986}, + dictWord{140, 0, 682}, + dictWord{7, 0, 76}, + dictWord{8, 0, 44}, + dictWord{9, 0, 884}, + dictWord{10, 0, 580}, + dictWord{11, 0, 399}, + dictWord{ + 11, + 0, + 894, + }, + dictWord{143, 0, 122}, + dictWord{135, 11, 1237}, + dictWord{135, 10, 636}, + dictWord{11, 0, 300}, + dictWord{6, 10, 222}, + dictWord{7, 10, 1620}, + dictWord{ + 8, + 10, + 409, + }, + dictWord{137, 10, 693}, + dictWord{4, 11, 87}, + dictWord{5, 11, 250}, + dictWord{10, 11, 601}, + dictWord{13, 11, 298}, + dictWord{13, 11, 353}, + dictWord{141, 11, 376}, + dictWord{5, 0, 518}, + dictWord{10, 0, 340}, + dictWord{11, 0, 175}, + dictWord{149, 0, 16}, + dictWord{140, 0, 771}, + dictWord{6, 0, 1108}, + dictWord{137, 0, 831}, + dictWord{132, 0, 836}, + dictWord{135, 0, 1852}, + dictWord{4, 0, 957}, + dictWord{6, 0, 1804}, + dictWord{8, 0, 842}, + dictWord{8, 0, 843}, + dictWord{ + 8, + 0, + 851, + }, + dictWord{8, 0, 855}, + dictWord{140, 0, 767}, + dictWord{135, 11, 814}, + dictWord{4, 11, 57}, + dictWord{7, 11, 1195}, + dictWord{7, 11, 1438}, + dictWord{ + 7, + 11, + 1548, + }, + dictWord{7, 11, 1835}, + dictWord{7, 11, 1904}, + dictWord{9, 11, 757}, + dictWord{10, 11, 604}, + dictWord{139, 11, 519}, + dictWord{133, 10, 882}, + dictWord{138, 0, 246}, + dictWord{4, 0, 934}, + dictWord{5, 0, 202}, + dictWord{8, 0, 610}, + dictWord{7, 11, 1897}, + dictWord{12, 11, 290}, + dictWord{13, 11, 80}, + dictWord{13, 11, 437}, + dictWord{145, 11, 74}, + dictWord{8, 0, 96}, + dictWord{9, 0, 36}, + dictWord{10, 0, 607}, + dictWord{10, 0, 804}, + dictWord{10, 0, 832}, + dictWord{ + 11, + 0, + 423, + }, + dictWord{11, 0, 442}, + dictWord{12, 0, 309}, + dictWord{14, 0, 199}, + dictWord{15, 0, 90}, + dictWord{145, 0, 110}, + dictWord{132, 10, 426}, + dictWord{ + 7, + 0, + 654, + }, + dictWord{8, 0, 240}, + dictWord{6, 10, 58}, + dictWord{7, 10, 745}, + dictWord{7, 10, 1969}, + dictWord{8, 10, 675}, + dictWord{9, 10, 479}, + dictWord{9, 10, 731}, + dictWord{10, 10, 330}, + dictWord{10, 10, 593}, + dictWord{10, 10, 817}, + dictWord{11, 10, 32}, + dictWord{11, 10, 133}, + dictWord{11, 10, 221}, + dictWord{ + 145, + 10, + 68, + }, + dictWord{9, 0, 13}, + dictWord{9, 0, 398}, + dictWord{9, 0, 727}, + dictWord{10, 0, 75}, + dictWord{10, 0, 184}, + dictWord{10, 0, 230}, + dictWord{10, 0, 564}, + dictWord{ + 10, + 0, + 569, + }, + dictWord{11, 0, 973}, + dictWord{12, 0, 70}, + dictWord{12, 0, 189}, + dictWord{13, 0, 57}, + dictWord{141, 0, 257}, + dictWord{4, 11, 209}, + dictWord{ + 135, + 11, + 902, + }, + dictWord{7, 0, 391}, + dictWord{137, 10, 538}, + dictWord{134, 0, 403}, + dictWord{6, 11, 303}, + dictWord{7, 11, 335}, + dictWord{7, 11, 1437}, + dictWord{ + 7, + 11, + 1668, + }, + dictWord{8, 11, 553}, + dictWord{8, 11, 652}, + dictWord{8, 11, 656}, + dictWord{9, 11, 558}, + dictWord{11, 11, 743}, + dictWord{149, 11, 18}, + dictWord{ + 132, + 11, + 559, + }, + dictWord{11, 0, 75}, + dictWord{142, 0, 267}, + dictWord{6, 0, 815}, + dictWord{141, 11, 2}, + dictWord{141, 0, 366}, + dictWord{137, 0, 631}, + dictWord{ + 133, + 11, + 1017, + }, + dictWord{5, 0, 345}, + dictWord{135, 0, 1016}, + dictWord{133, 11, 709}, + dictWord{134, 11, 1745}, + dictWord{133, 10, 566}, + dictWord{7, 0, 952}, + dictWord{6, 10, 48}, + dictWord{9, 10, 139}, + dictWord{10, 10, 399}, + dictWord{11, 10, 469}, + dictWord{12, 10, 634}, + dictWord{141, 10, 223}, + dictWord{ + 133, + 0, + 673, + }, + dictWord{9, 0, 850}, + dictWord{7, 11, 8}, + dictWord{136, 11, 206}, + dictWord{6, 0, 662}, + dictWord{149, 0, 35}, + dictWord{4, 0, 287}, + dictWord{133, 0, 1018}, + dictWord{6, 10, 114}, + dictWord{7, 10, 1224}, + dictWord{7, 10, 1556}, + dictWord{136, 10, 3}, + dictWord{8, 10, 576}, + dictWord{137, 10, 267}, + dictWord{4, 0, 884}, + dictWord{5, 0, 34}, + dictWord{10, 0, 724}, + dictWord{12, 0, 444}, + dictWord{13, 0, 354}, + dictWord{18, 0, 32}, + dictWord{23, 0, 24}, + dictWord{23, 0, 31}, + dictWord{ + 152, + 0, + 5, + }, + dictWord{133, 10, 933}, + dictWord{132, 11, 776}, + dictWord{138, 0, 151}, + dictWord{136, 0, 427}, + dictWord{134, 0, 382}, + dictWord{132, 0, 329}, + dictWord{ + 9, + 0, + 846, + }, + dictWord{10, 0, 827}, + dictWord{138, 11, 33}, + dictWord{9, 0, 279}, + dictWord{10, 0, 407}, + dictWord{14, 0, 84}, + dictWord{22, 0, 18}, + dictWord{ + 135, + 11, + 1297, + }, + dictWord{136, 11, 406}, + dictWord{132, 0, 906}, + dictWord{136, 0, 366}, + dictWord{134, 0, 843}, + dictWord{134, 0, 1443}, + dictWord{135, 0, 1372}, + dictWord{138, 0, 992}, + dictWord{4, 0, 123}, + dictWord{5, 0, 605}, + dictWord{7, 0, 1509}, + dictWord{136, 0, 36}, + dictWord{132, 0, 649}, + dictWord{8, 11, 175}, + dictWord{10, 11, 168}, + dictWord{138, 11, 573}, + dictWord{133, 0, 767}, + dictWord{134, 0, 1018}, + dictWord{135, 11, 1305}, + dictWord{12, 10, 30}, + dictWord{ + 13, + 10, + 148, + }, + dictWord{14, 10, 87}, + dictWord{14, 10, 182}, + dictWord{16, 10, 42}, + dictWord{148, 10, 70}, + dictWord{134, 11, 607}, + dictWord{4, 0, 273}, + dictWord{ + 5, + 0, + 658, + }, + dictWord{133, 0, 995}, + dictWord{6, 0, 72}, + dictWord{139, 11, 174}, + dictWord{10, 0, 483}, + dictWord{12, 0, 368}, + dictWord{7, 10, 56}, + dictWord{ + 7, + 10, + 1989, + }, + dictWord{8, 10, 337}, + dictWord{8, 10, 738}, + dictWord{9, 10, 600}, + dictWord{13, 10, 447}, + dictWord{142, 10, 92}, + dictWord{5, 11, 784}, + dictWord{ + 138, + 10, + 666, + }, + dictWord{135, 0, 1345}, + dictWord{139, 11, 882}, + dictWord{134, 0, 1293}, + dictWord{133, 0, 589}, + dictWord{134, 0, 1988}, + dictWord{5, 0, 117}, + dictWord{6, 0, 514}, + dictWord{6, 0, 541}, + dictWord{7, 0, 1164}, + dictWord{7, 0, 1436}, + dictWord{8, 0, 220}, + dictWord{8, 0, 648}, + dictWord{10, 0, 688}, + dictWord{ + 139, + 0, + 560, + }, + dictWord{136, 0, 379}, + dictWord{5, 0, 686}, + dictWord{7, 10, 866}, + dictWord{135, 10, 1163}, + dictWord{132, 10, 328}, + dictWord{9, 11, 14}, + dictWord{ + 9, + 11, + 441, + }, + dictWord{10, 11, 306}, + dictWord{139, 11, 9}, + dictWord{4, 10, 101}, + dictWord{135, 10, 1171}, + dictWord{5, 10, 833}, + dictWord{136, 10, 744}, + dictWord{5, 11, 161}, + dictWord{7, 11, 839}, + dictWord{135, 11, 887}, + dictWord{7, 0, 196}, + dictWord{10, 0, 765}, + dictWord{11, 0, 347}, + dictWord{11, 0, 552}, + dictWord{11, 0, 790}, + dictWord{12, 0, 263}, + dictWord{13, 0, 246}, + dictWord{13, 0, 270}, + dictWord{13, 0, 395}, + dictWord{14, 0, 176}, + dictWord{14, 0, 190}, + dictWord{ + 14, + 0, + 398, + }, + dictWord{14, 0, 412}, + dictWord{15, 0, 32}, + dictWord{15, 0, 63}, + dictWord{16, 0, 88}, + dictWord{147, 0, 105}, + dictWord{6, 10, 9}, + dictWord{6, 10, 397}, + dictWord{7, 10, 53}, + dictWord{7, 10, 1742}, + dictWord{10, 10, 632}, + dictWord{11, 10, 828}, + dictWord{140, 10, 146}, + dictWord{5, 0, 381}, + dictWord{135, 0, 1792}, + dictWord{134, 0, 1452}, + dictWord{135, 11, 429}, + dictWord{8, 0, 367}, + dictWord{10, 0, 760}, + dictWord{14, 0, 79}, + dictWord{20, 0, 17}, + dictWord{152, 0, 0}, + dictWord{7, 0, 616}, + dictWord{138, 0, 413}, + dictWord{11, 10, 417}, + dictWord{12, 10, 223}, + dictWord{140, 10, 265}, + dictWord{7, 11, 1611}, + dictWord{13, 11, 14}, + dictWord{15, 11, 44}, + dictWord{19, 11, 13}, + dictWord{148, 11, 76}, + dictWord{135, 0, 1229}, + dictWord{6, 0, 120}, + dictWord{7, 0, 1188}, + dictWord{7, 0, 1710}, + dictWord{8, 0, 286}, + dictWord{9, 0, 667}, + dictWord{11, 0, 592}, + dictWord{139, 0, 730}, + dictWord{135, 11, 1814}, + dictWord{135, 0, 1146}, + dictWord{4, 10, 186}, + dictWord{5, 10, 157}, + dictWord{8, 10, 168}, + dictWord{138, 10, 6}, + dictWord{4, 0, 352}, + dictWord{135, 0, 687}, + dictWord{4, 0, 192}, + dictWord{5, 0, 49}, + dictWord{ + 6, + 0, + 200, + }, + dictWord{6, 0, 293}, + dictWord{6, 0, 1696}, + dictWord{135, 0, 1151}, + dictWord{133, 10, 875}, + dictWord{5, 10, 773}, + dictWord{5, 10, 991}, + dictWord{ + 6, + 10, + 1635, + }, + dictWord{134, 10, 1788}, + dictWord{7, 10, 111}, + dictWord{136, 10, 581}, + dictWord{6, 0, 935}, + dictWord{134, 0, 1151}, + dictWord{134, 0, 1050}, + dictWord{132, 0, 650}, + dictWord{132, 0, 147}, + dictWord{11, 0, 194}, + dictWord{12, 0, 62}, + dictWord{12, 0, 88}, + dictWord{11, 11, 194}, + dictWord{12, 11, 62}, + dictWord{140, 11, 88}, + dictWord{6, 0, 339}, + dictWord{135, 0, 923}, + dictWord{134, 10, 1747}, + dictWord{7, 11, 643}, + dictWord{136, 11, 236}, + dictWord{ + 133, + 0, + 934, + }, + dictWord{7, 10, 1364}, + dictWord{7, 10, 1907}, + dictWord{141, 10, 158}, + dictWord{132, 10, 659}, + dictWord{4, 10, 404}, + dictWord{135, 10, 675}, + dictWord{7, 11, 581}, + dictWord{9, 11, 644}, + dictWord{137, 11, 699}, + dictWord{13, 0, 211}, + dictWord{14, 0, 133}, + dictWord{14, 0, 204}, + dictWord{15, 0, 64}, + dictWord{ + 15, + 0, + 69, + }, + dictWord{15, 0, 114}, + dictWord{16, 0, 10}, + dictWord{19, 0, 23}, + dictWord{19, 0, 35}, + dictWord{19, 0, 39}, + dictWord{19, 0, 51}, + dictWord{19, 0, 71}, + dictWord{19, 0, 75}, + dictWord{152, 0, 15}, + dictWord{133, 10, 391}, + dictWord{5, 11, 54}, + dictWord{135, 11, 1513}, + dictWord{7, 0, 222}, + dictWord{8, 0, 341}, + dictWord{ + 5, + 10, + 540, + }, + dictWord{134, 10, 1697}, + dictWord{134, 10, 78}, + dictWord{132, 11, 744}, + dictWord{136, 0, 293}, + dictWord{137, 11, 701}, + dictWord{ + 7, + 11, + 930, + }, + dictWord{10, 11, 402}, + dictWord{10, 11, 476}, + dictWord{13, 11, 452}, + dictWord{18, 11, 55}, + dictWord{147, 11, 104}, + dictWord{132, 0, 637}, + dictWord{133, 10, 460}, + dictWord{8, 11, 50}, + dictWord{137, 11, 624}, + dictWord{132, 11, 572}, + dictWord{134, 0, 1159}, + dictWord{4, 10, 199}, + dictWord{ + 139, + 10, + 34, + }, + dictWord{134, 0, 847}, + dictWord{134, 10, 388}, + dictWord{6, 11, 43}, + dictWord{7, 11, 38}, + dictWord{8, 11, 248}, + dictWord{9, 11, 504}, + dictWord{ + 138, + 11, + 513, + }, + dictWord{9, 0, 683}, + dictWord{4, 10, 511}, + dictWord{6, 10, 608}, + dictWord{9, 10, 333}, + dictWord{10, 10, 602}, + dictWord{11, 10, 441}, + dictWord{ + 11, + 10, + 723, + }, + dictWord{11, 10, 976}, + dictWord{140, 10, 357}, + dictWord{9, 0, 867}, + dictWord{138, 0, 837}, + dictWord{6, 0, 944}, + dictWord{135, 11, 326}, + dictWord{ + 135, + 0, + 1809, + }, + dictWord{5, 10, 938}, + dictWord{7, 11, 783}, + dictWord{136, 10, 707}, + dictWord{133, 11, 766}, + dictWord{133, 11, 363}, + dictWord{6, 0, 170}, + dictWord{7, 0, 1080}, + dictWord{8, 0, 395}, + dictWord{8, 0, 487}, + dictWord{141, 0, 147}, + dictWord{6, 11, 258}, + dictWord{140, 11, 409}, + dictWord{4, 0, 535}, + dictWord{ + 8, + 0, + 618, + }, + dictWord{5, 11, 249}, + dictWord{148, 11, 82}, + dictWord{6, 0, 1379}, + dictWord{149, 11, 15}, + dictWord{135, 0, 1625}, + dictWord{150, 0, 23}, + dictWord{ + 5, + 11, + 393, + }, + dictWord{6, 11, 378}, + dictWord{7, 11, 1981}, + dictWord{9, 11, 32}, + dictWord{9, 11, 591}, + dictWord{10, 11, 685}, + dictWord{10, 11, 741}, + dictWord{ + 142, + 11, + 382, + }, + dictWord{133, 11, 788}, + dictWord{7, 11, 1968}, + dictWord{10, 11, 19}, + dictWord{139, 11, 911}, + dictWord{7, 11, 1401}, + dictWord{ + 135, + 11, + 1476, + }, + dictWord{4, 11, 61}, + dictWord{5, 11, 58}, + dictWord{5, 11, 171}, + dictWord{5, 11, 635}, + dictWord{5, 11, 683}, + dictWord{5, 11, 700}, + dictWord{6, 11, 291}, + dictWord{6, 11, 566}, + dictWord{7, 11, 1650}, + dictWord{11, 11, 523}, + dictWord{12, 11, 273}, + dictWord{12, 11, 303}, + dictWord{15, 11, 39}, + dictWord{ + 143, + 11, + 111, + }, + dictWord{6, 10, 469}, + dictWord{7, 10, 1709}, + dictWord{138, 10, 515}, + dictWord{4, 0, 778}, + dictWord{134, 11, 589}, + dictWord{132, 0, 46}, + dictWord{ + 5, + 0, + 811, + }, + dictWord{6, 0, 1679}, + dictWord{6, 0, 1714}, + dictWord{135, 0, 2032}, + dictWord{7, 0, 1458}, + dictWord{9, 0, 407}, + dictWord{11, 0, 15}, + dictWord{12, 0, 651}, + dictWord{149, 0, 37}, + dictWord{7, 0, 938}, + dictWord{132, 10, 500}, + dictWord{6, 0, 34}, + dictWord{7, 0, 69}, + dictWord{7, 0, 1089}, + dictWord{7, 0, 1281}, + dictWord{ + 8, + 0, + 708, + }, + dictWord{8, 0, 721}, + dictWord{9, 0, 363}, + dictWord{148, 0, 98}, + dictWord{10, 11, 231}, + dictWord{147, 11, 124}, + dictWord{7, 11, 726}, + dictWord{ + 152, + 11, + 9, + }, + dictWord{5, 10, 68}, + dictWord{134, 10, 383}, + dictWord{136, 11, 583}, + dictWord{4, 11, 917}, + dictWord{133, 11, 1005}, + dictWord{11, 10, 216}, + dictWord{139, 10, 340}, + dictWord{135, 11, 1675}, + dictWord{8, 0, 441}, + dictWord{10, 0, 314}, + dictWord{143, 0, 3}, + dictWord{132, 11, 919}, + dictWord{4, 10, 337}, + dictWord{6, 10, 353}, + dictWord{7, 10, 1934}, + dictWord{8, 10, 488}, + dictWord{137, 10, 429}, + dictWord{7, 0, 889}, + dictWord{7, 10, 1795}, + dictWord{8, 10, 259}, + dictWord{9, 10, 135}, + dictWord{9, 10, 177}, + dictWord{9, 10, 860}, + dictWord{10, 10, 825}, + dictWord{11, 10, 115}, + dictWord{11, 10, 370}, + dictWord{11, 10, 405}, + dictWord{11, 10, 604}, + dictWord{12, 10, 10}, + dictWord{12, 10, 667}, + dictWord{12, 10, 669}, + dictWord{13, 10, 76}, + dictWord{14, 10, 310}, + dictWord{ + 15, + 10, + 76, + }, + dictWord{15, 10, 147}, + dictWord{148, 10, 23}, + dictWord{4, 10, 15}, + dictWord{4, 11, 255}, + dictWord{5, 10, 22}, + dictWord{5, 11, 302}, + dictWord{6, 11, 132}, + dictWord{6, 10, 244}, + dictWord{7, 10, 40}, + dictWord{7, 11, 128}, + dictWord{7, 10, 200}, + dictWord{7, 11, 283}, + dictWord{7, 10, 906}, + dictWord{7, 10, 1199}, + dictWord{ + 7, + 11, + 1299, + }, + dictWord{9, 10, 616}, + dictWord{10, 11, 52}, + dictWord{10, 11, 514}, + dictWord{10, 10, 716}, + dictWord{11, 10, 635}, + dictWord{11, 10, 801}, + dictWord{11, 11, 925}, + dictWord{12, 10, 458}, + dictWord{13, 11, 92}, + dictWord{142, 11, 309}, + dictWord{132, 0, 462}, + dictWord{137, 11, 173}, + dictWord{ + 135, + 10, + 1735, + }, + dictWord{8, 0, 525}, + dictWord{5, 10, 598}, + dictWord{7, 10, 791}, + dictWord{8, 10, 108}, + dictWord{137, 10, 123}, + dictWord{5, 0, 73}, + dictWord{6, 0, 23}, + dictWord{134, 0, 338}, + dictWord{132, 0, 676}, + dictWord{132, 10, 683}, + dictWord{7, 0, 725}, + dictWord{8, 0, 498}, + dictWord{139, 0, 268}, + dictWord{12, 0, 21}, + dictWord{151, 0, 7}, + dictWord{135, 0, 773}, + dictWord{4, 10, 155}, + dictWord{135, 10, 1689}, + dictWord{4, 0, 164}, + dictWord{5, 0, 730}, + dictWord{5, 10, 151}, + dictWord{ + 5, + 10, + 741, + }, + dictWord{6, 11, 210}, + dictWord{7, 10, 498}, + dictWord{7, 10, 870}, + dictWord{7, 10, 1542}, + dictWord{12, 10, 213}, + dictWord{14, 10, 36}, + dictWord{ + 14, + 10, + 391, + }, + dictWord{17, 10, 111}, + dictWord{18, 10, 6}, + dictWord{18, 10, 46}, + dictWord{18, 10, 151}, + dictWord{19, 10, 36}, + dictWord{20, 10, 32}, + dictWord{ + 20, + 10, + 56, + }, + dictWord{20, 10, 69}, + dictWord{20, 10, 102}, + dictWord{21, 10, 4}, + dictWord{22, 10, 8}, + dictWord{22, 10, 10}, + dictWord{22, 10, 14}, + dictWord{ + 150, + 10, + 31, + }, + dictWord{4, 10, 624}, + dictWord{135, 10, 1752}, + dictWord{4, 0, 583}, + dictWord{9, 0, 936}, + dictWord{15, 0, 214}, + dictWord{18, 0, 199}, + dictWord{24, 0, 26}, + dictWord{134, 11, 588}, + dictWord{7, 0, 1462}, + dictWord{11, 0, 659}, + dictWord{4, 11, 284}, + dictWord{134, 11, 223}, + dictWord{133, 0, 220}, + dictWord{ + 139, + 0, + 803, + }, + dictWord{132, 0, 544}, + dictWord{4, 10, 492}, + dictWord{133, 10, 451}, + dictWord{16, 0, 98}, + dictWord{148, 0, 119}, + dictWord{4, 11, 218}, + dictWord{ + 7, + 11, + 526, + }, + dictWord{143, 11, 137}, + dictWord{135, 10, 835}, + dictWord{4, 11, 270}, + dictWord{5, 11, 192}, + dictWord{6, 11, 332}, + dictWord{7, 11, 1322}, + dictWord{ + 13, + 11, + 9, + }, + dictWord{13, 10, 70}, + dictWord{14, 11, 104}, + dictWord{142, 11, 311}, + dictWord{132, 10, 539}, + dictWord{140, 11, 661}, + dictWord{5, 0, 176}, + dictWord{ + 6, + 0, + 437, + }, + dictWord{6, 0, 564}, + dictWord{11, 0, 181}, + dictWord{141, 0, 183}, + dictWord{135, 0, 1192}, + dictWord{6, 10, 113}, + dictWord{135, 10, 436}, + dictWord{136, 10, 718}, + dictWord{135, 10, 520}, + dictWord{135, 0, 1878}, + dictWord{140, 11, 196}, + dictWord{7, 11, 379}, + dictWord{8, 11, 481}, + dictWord{ + 137, + 11, + 377, + }, + dictWord{5, 11, 1003}, + dictWord{6, 11, 149}, + dictWord{137, 11, 746}, + dictWord{8, 11, 262}, + dictWord{9, 11, 627}, + dictWord{10, 11, 18}, + dictWord{ + 11, + 11, + 214, + }, + dictWord{11, 11, 404}, + dictWord{11, 11, 457}, + dictWord{11, 11, 780}, + dictWord{11, 11, 849}, + dictWord{11, 11, 913}, + dictWord{13, 11, 330}, + dictWord{13, 11, 401}, + dictWord{142, 11, 200}, + dictWord{149, 0, 26}, + dictWord{136, 11, 304}, + dictWord{132, 11, 142}, + dictWord{135, 0, 944}, + dictWord{ + 4, + 0, + 790, + }, + dictWord{5, 0, 273}, + dictWord{134, 0, 394}, + dictWord{134, 0, 855}, + dictWord{4, 0, 135}, + dictWord{6, 0, 127}, + dictWord{7, 0, 1185}, + dictWord{7, 0, 1511}, + dictWord{8, 0, 613}, + dictWord{11, 0, 5}, + dictWord{12, 0, 336}, + dictWord{12, 0, 495}, + dictWord{12, 0, 586}, + dictWord{12, 0, 660}, + dictWord{12, 0, 668}, + dictWord{ + 14, + 0, + 385, + }, + dictWord{15, 0, 118}, + dictWord{17, 0, 20}, + dictWord{146, 0, 98}, + dictWord{6, 0, 230}, + dictWord{9, 0, 752}, + dictWord{18, 0, 109}, + dictWord{12, 10, 610}, + dictWord{13, 10, 431}, + dictWord{144, 10, 59}, + dictWord{7, 0, 1954}, + dictWord{135, 11, 925}, + dictWord{4, 11, 471}, + dictWord{5, 11, 51}, + dictWord{6, 11, 602}, + dictWord{8, 11, 484}, + dictWord{10, 11, 195}, + dictWord{140, 11, 159}, + dictWord{132, 10, 307}, + dictWord{136, 11, 688}, + dictWord{132, 11, 697}, + dictWord{ + 7, + 11, + 812, + }, + dictWord{7, 11, 1261}, + dictWord{7, 11, 1360}, + dictWord{9, 11, 632}, + dictWord{140, 11, 352}, + dictWord{5, 0, 162}, + dictWord{8, 0, 68}, + dictWord{ + 133, + 10, + 964, + }, + dictWord{4, 0, 654}, + dictWord{136, 11, 212}, + dictWord{4, 0, 156}, + dictWord{7, 0, 998}, + dictWord{7, 0, 1045}, + dictWord{7, 0, 1860}, + dictWord{9, 0, 48}, + dictWord{9, 0, 692}, + dictWord{11, 0, 419}, + dictWord{139, 0, 602}, + dictWord{133, 11, 221}, + dictWord{4, 11, 373}, + dictWord{5, 11, 283}, + dictWord{6, 11, 480}, + dictWord{135, 11, 609}, + dictWord{142, 11, 216}, + dictWord{132, 0, 240}, + dictWord{6, 11, 192}, + dictWord{9, 11, 793}, + dictWord{145, 11, 55}, + dictWord{ + 4, + 10, + 75, + }, + dictWord{5, 10, 180}, + dictWord{6, 10, 500}, + dictWord{7, 10, 58}, + dictWord{7, 10, 710}, + dictWord{138, 10, 645}, + dictWord{4, 11, 132}, + dictWord{5, 11, 69}, + dictWord{5, 10, 649}, + dictWord{135, 11, 1242}, + dictWord{6, 10, 276}, + dictWord{7, 10, 282}, + dictWord{7, 10, 879}, + dictWord{7, 10, 924}, + dictWord{8, 10, 459}, + dictWord{9, 10, 599}, + dictWord{9, 10, 754}, + dictWord{11, 10, 574}, + dictWord{12, 10, 128}, + dictWord{12, 10, 494}, + dictWord{13, 10, 52}, + dictWord{13, 10, 301}, + dictWord{15, 10, 30}, + dictWord{143, 10, 132}, + dictWord{132, 10, 200}, + dictWord{4, 11, 111}, + dictWord{135, 11, 302}, + dictWord{9, 0, 197}, + dictWord{ + 10, + 0, + 300, + }, + dictWord{12, 0, 473}, + dictWord{13, 0, 90}, + dictWord{141, 0, 405}, + dictWord{132, 11, 767}, + dictWord{6, 11, 42}, + dictWord{7, 11, 1416}, + dictWord{ + 7, + 11, + 1590, + }, + dictWord{7, 11, 2005}, + dictWord{8, 11, 131}, + dictWord{8, 11, 466}, + dictWord{9, 11, 672}, + dictWord{13, 11, 252}, + dictWord{148, 11, 103}, + dictWord{ + 8, + 0, + 958, + }, + dictWord{8, 0, 999}, + dictWord{10, 0, 963}, + dictWord{138, 0, 1001}, + dictWord{135, 10, 1621}, + dictWord{135, 0, 858}, + dictWord{4, 0, 606}, + dictWord{ + 137, + 11, + 444, + }, + dictWord{6, 11, 44}, + dictWord{136, 11, 368}, + dictWord{139, 11, 172}, + dictWord{4, 11, 570}, + dictWord{133, 11, 120}, + dictWord{139, 11, 624}, + dictWord{7, 0, 1978}, + dictWord{8, 0, 676}, + dictWord{6, 10, 225}, + dictWord{137, 10, 211}, + dictWord{7, 0, 972}, + dictWord{11, 0, 102}, + dictWord{136, 10, 687}, + dictWord{6, 11, 227}, + dictWord{135, 11, 1589}, + dictWord{8, 10, 58}, + dictWord{9, 10, 724}, + dictWord{11, 10, 809}, + dictWord{13, 10, 113}, + dictWord{ + 145, + 10, + 72, + }, + dictWord{4, 0, 361}, + dictWord{133, 0, 315}, + dictWord{132, 0, 461}, + dictWord{6, 10, 345}, + dictWord{135, 10, 1247}, + dictWord{132, 0, 472}, + dictWord{ + 8, + 10, + 767, + }, + dictWord{8, 10, 803}, + dictWord{9, 10, 301}, + dictWord{137, 10, 903}, + dictWord{135, 11, 1333}, + dictWord{135, 11, 477}, + dictWord{7, 10, 1949}, + dictWord{136, 10, 674}, + dictWord{6, 0, 905}, + dictWord{138, 0, 747}, + dictWord{133, 0, 155}, + dictWord{134, 10, 259}, + dictWord{7, 0, 163}, + dictWord{8, 0, 319}, + dictWord{9, 0, 402}, + dictWord{10, 0, 24}, + dictWord{10, 0, 681}, + dictWord{11, 0, 200}, + dictWord{12, 0, 253}, + dictWord{12, 0, 410}, + dictWord{142, 0, 219}, + dictWord{ + 5, + 0, + 475, + }, + dictWord{7, 0, 1780}, + dictWord{9, 0, 230}, + dictWord{11, 0, 297}, + dictWord{11, 0, 558}, + dictWord{14, 0, 322}, + dictWord{19, 0, 76}, + dictWord{6, 11, 1667}, + dictWord{7, 11, 2036}, + dictWord{138, 11, 600}, + dictWord{136, 10, 254}, + dictWord{6, 0, 848}, + dictWord{135, 0, 1956}, + dictWord{6, 11, 511}, + dictWord{ + 140, + 11, + 132, + }, + dictWord{5, 11, 568}, + dictWord{6, 11, 138}, + dictWord{135, 11, 1293}, + dictWord{6, 0, 631}, + dictWord{137, 0, 838}, + dictWord{149, 0, 36}, + dictWord{ + 4, + 11, + 565, + }, + dictWord{8, 11, 23}, + dictWord{136, 11, 827}, + dictWord{5, 0, 944}, + dictWord{134, 0, 1769}, + dictWord{4, 0, 144}, + dictWord{6, 0, 842}, + dictWord{ + 6, + 0, + 1400, + }, + dictWord{4, 11, 922}, + dictWord{133, 11, 1023}, + dictWord{133, 10, 248}, + dictWord{9, 10, 800}, + dictWord{10, 10, 693}, + dictWord{11, 10, 482}, + dictWord{11, 10, 734}, + dictWord{139, 10, 789}, + dictWord{7, 11, 1002}, + dictWord{139, 11, 145}, + dictWord{4, 10, 116}, + dictWord{5, 10, 95}, + dictWord{5, 10, 445}, + dictWord{7, 10, 1688}, + dictWord{8, 10, 29}, + dictWord{9, 10, 272}, + dictWord{11, 10, 509}, + dictWord{139, 10, 915}, + dictWord{14, 0, 369}, + dictWord{146, 0, 72}, + dictWord{135, 10, 1641}, + dictWord{132, 11, 740}, + dictWord{133, 10, 543}, + dictWord{140, 11, 116}, + dictWord{6, 0, 247}, + dictWord{9, 0, 555}, + dictWord{ + 5, + 10, + 181, + }, + dictWord{136, 10, 41}, + dictWord{133, 10, 657}, + dictWord{136, 0, 996}, + dictWord{138, 10, 709}, + dictWord{7, 0, 189}, + dictWord{8, 10, 202}, + dictWord{ + 138, + 10, + 536, + }, + dictWord{136, 11, 402}, + dictWord{4, 11, 716}, + dictWord{141, 11, 31}, + dictWord{10, 0, 280}, + dictWord{138, 0, 797}, + dictWord{9, 10, 423}, + dictWord{140, 10, 89}, + dictWord{8, 10, 113}, + dictWord{9, 10, 877}, + dictWord{10, 10, 554}, + dictWord{11, 10, 83}, + dictWord{12, 10, 136}, + dictWord{147, 10, 109}, + dictWord{133, 10, 976}, + dictWord{7, 0, 746}, + dictWord{132, 10, 206}, + dictWord{136, 0, 526}, + dictWord{139, 0, 345}, + dictWord{136, 0, 1017}, + dictWord{ + 8, + 11, + 152, + }, + dictWord{9, 11, 53}, + dictWord{9, 11, 268}, + dictWord{9, 11, 901}, + dictWord{10, 11, 518}, + dictWord{10, 11, 829}, + dictWord{11, 11, 188}, + dictWord{ + 13, + 11, + 74, + }, + dictWord{14, 11, 46}, + dictWord{15, 11, 17}, + dictWord{15, 11, 33}, + dictWord{17, 11, 40}, + dictWord{18, 11, 36}, + dictWord{19, 11, 20}, + dictWord{22, 11, 1}, + dictWord{152, 11, 2}, + dictWord{133, 11, 736}, + dictWord{136, 11, 532}, + dictWord{5, 0, 428}, + dictWord{138, 0, 651}, + dictWord{135, 11, 681}, + dictWord{ + 135, + 0, + 1162, + }, + dictWord{7, 0, 327}, + dictWord{13, 0, 230}, + dictWord{17, 0, 113}, + dictWord{8, 10, 226}, + dictWord{10, 10, 537}, + dictWord{11, 10, 570}, + dictWord{ + 11, + 10, + 605, + }, + dictWord{11, 10, 799}, + dictWord{11, 10, 804}, + dictWord{12, 10, 85}, + dictWord{12, 10, 516}, + dictWord{12, 10, 623}, + dictWord{12, 11, 677}, + dictWord{ + 13, + 10, + 361, + }, + dictWord{14, 10, 77}, + dictWord{14, 10, 78}, + dictWord{147, 10, 110}, + dictWord{4, 0, 792}, + dictWord{7, 0, 1717}, + dictWord{10, 0, 546}, + dictWord{ + 132, + 10, + 769, + }, + dictWord{4, 11, 684}, + dictWord{136, 11, 384}, + dictWord{132, 10, 551}, + dictWord{134, 0, 1203}, + dictWord{9, 10, 57}, + dictWord{9, 10, 459}, + dictWord{10, 10, 425}, + dictWord{11, 10, 119}, + dictWord{12, 10, 184}, + dictWord{12, 10, 371}, + dictWord{13, 10, 358}, + dictWord{145, 10, 51}, + dictWord{5, 0, 672}, + dictWord{5, 10, 814}, + dictWord{8, 10, 10}, + dictWord{9, 10, 421}, + dictWord{9, 10, 729}, + dictWord{10, 10, 609}, + dictWord{139, 10, 689}, + dictWord{138, 0, 189}, + dictWord{134, 10, 624}, + dictWord{7, 11, 110}, + dictWord{7, 11, 188}, + dictWord{8, 11, 290}, + dictWord{8, 11, 591}, + dictWord{9, 11, 382}, + dictWord{9, 11, 649}, + dictWord{11, 11, 71}, + dictWord{11, 11, 155}, + dictWord{11, 11, 313}, + dictWord{12, 11, 5}, + dictWord{13, 11, 325}, + dictWord{142, 11, 287}, + dictWord{133, 0, 99}, + dictWord{6, 0, 1053}, + dictWord{135, 0, 298}, + dictWord{7, 11, 360}, + dictWord{7, 11, 425}, + dictWord{9, 11, 66}, + dictWord{9, 11, 278}, + dictWord{138, 11, 644}, + dictWord{4, 0, 397}, + dictWord{136, 0, 555}, + dictWord{137, 10, 269}, + dictWord{132, 10, 528}, + dictWord{4, 11, 900}, + dictWord{133, 11, 861}, + dictWord{ + 6, + 0, + 1157, + }, + dictWord{5, 11, 254}, + dictWord{7, 11, 985}, + dictWord{136, 11, 73}, + dictWord{7, 11, 1959}, + dictWord{136, 11, 683}, + dictWord{12, 0, 398}, + dictWord{ + 20, + 0, + 39, + }, + dictWord{21, 0, 11}, + dictWord{150, 0, 41}, + dictWord{4, 0, 485}, + dictWord{7, 0, 353}, + dictWord{135, 0, 1523}, + dictWord{6, 0, 366}, + dictWord{7, 0, 1384}, + dictWord{135, 0, 1601}, + dictWord{138, 0, 787}, + dictWord{137, 0, 282}, + dictWord{5, 10, 104}, + dictWord{6, 10, 173}, + dictWord{135, 10, 1631}, + dictWord{ + 139, + 11, + 146, + }, + dictWord{4, 0, 157}, + dictWord{133, 0, 471}, + dictWord{134, 0, 941}, + dictWord{132, 11, 725}, + dictWord{7, 0, 1336}, + dictWord{8, 10, 138}, + dictWord{ + 8, + 10, + 342, + }, + dictWord{9, 10, 84}, + dictWord{10, 10, 193}, + dictWord{11, 10, 883}, + dictWord{140, 10, 359}, + dictWord{134, 11, 196}, + dictWord{136, 0, 116}, + dictWord{133, 11, 831}, + dictWord{134, 0, 787}, + dictWord{134, 10, 95}, + dictWord{6, 10, 406}, + dictWord{10, 10, 409}, + dictWord{10, 10, 447}, + dictWord{ + 11, + 10, + 44, + }, + dictWord{140, 10, 100}, + dictWord{5, 0, 160}, + dictWord{7, 0, 363}, + dictWord{7, 0, 589}, + dictWord{10, 0, 170}, + dictWord{141, 0, 55}, + dictWord{134, 0, 1815}, + dictWord{132, 0, 866}, + dictWord{6, 0, 889}, + dictWord{6, 0, 1067}, + dictWord{6, 0, 1183}, + dictWord{4, 11, 321}, + dictWord{134, 11, 569}, + dictWord{5, 11, 848}, + dictWord{134, 11, 66}, + dictWord{4, 11, 36}, + dictWord{6, 10, 1636}, + dictWord{7, 11, 1387}, + dictWord{10, 11, 205}, + dictWord{11, 11, 755}, + dictWord{ + 141, + 11, + 271, + }, + dictWord{132, 0, 689}, + dictWord{9, 0, 820}, + dictWord{4, 10, 282}, + dictWord{7, 10, 1034}, + dictWord{11, 10, 398}, + dictWord{11, 10, 634}, + dictWord{ + 12, + 10, + 1, + }, + dictWord{12, 10, 79}, + dictWord{12, 10, 544}, + dictWord{14, 10, 237}, + dictWord{17, 10, 10}, + dictWord{146, 10, 20}, + dictWord{4, 0, 108}, + dictWord{7, 0, 804}, + dictWord{139, 0, 498}, + dictWord{132, 11, 887}, + dictWord{6, 0, 1119}, + dictWord{135, 11, 620}, + dictWord{6, 11, 165}, + dictWord{138, 11, 388}, + dictWord{ + 5, + 0, + 244, + }, + dictWord{5, 10, 499}, + dictWord{6, 10, 476}, + dictWord{7, 10, 600}, + dictWord{7, 10, 888}, + dictWord{135, 10, 1096}, + dictWord{140, 0, 609}, + dictWord{ + 135, + 0, + 1005, + }, + dictWord{4, 0, 412}, + dictWord{133, 0, 581}, + dictWord{4, 11, 719}, + dictWord{135, 11, 155}, + dictWord{7, 10, 296}, + dictWord{7, 10, 596}, + dictWord{ + 8, + 10, + 560, + }, + dictWord{8, 10, 586}, + dictWord{9, 10, 612}, + dictWord{11, 10, 304}, + dictWord{12, 10, 46}, + dictWord{13, 10, 89}, + dictWord{14, 10, 112}, + dictWord{ + 145, + 10, + 122, + }, + dictWord{4, 0, 895}, + dictWord{133, 0, 772}, + dictWord{142, 11, 307}, + dictWord{135, 0, 1898}, + dictWord{4, 0, 926}, + dictWord{133, 0, 983}, + dictWord{4, 11, 353}, + dictWord{6, 11, 146}, + dictWord{6, 11, 1789}, + dictWord{7, 11, 288}, + dictWord{7, 11, 990}, + dictWord{7, 11, 1348}, + dictWord{9, 11, 665}, + dictWord{ + 9, + 11, + 898, + }, + dictWord{11, 11, 893}, + dictWord{142, 11, 212}, + dictWord{132, 0, 538}, + dictWord{133, 11, 532}, + dictWord{6, 0, 294}, + dictWord{7, 0, 1267}, + dictWord{8, 0, 624}, + dictWord{141, 0, 496}, + dictWord{7, 0, 1325}, + dictWord{4, 11, 45}, + dictWord{135, 11, 1257}, + dictWord{138, 0, 301}, + dictWord{9, 0, 298}, + dictWord{12, 0, 291}, + dictWord{13, 0, 276}, + dictWord{14, 0, 6}, + dictWord{17, 0, 18}, + dictWord{21, 0, 32}, + dictWord{7, 10, 1599}, + dictWord{7, 10, 1723}, + dictWord{ + 8, + 10, + 79, + }, + dictWord{8, 10, 106}, + dictWord{8, 10, 190}, + dictWord{8, 10, 302}, + dictWord{8, 10, 383}, + dictWord{8, 10, 713}, + dictWord{9, 10, 119}, + dictWord{9, 10, 233}, + dictWord{9, 10, 419}, + dictWord{9, 10, 471}, + dictWord{10, 10, 181}, + dictWord{10, 10, 406}, + dictWord{11, 10, 57}, + dictWord{11, 10, 85}, + dictWord{11, 10, 120}, + dictWord{11, 10, 177}, + dictWord{11, 10, 296}, + dictWord{11, 10, 382}, + dictWord{11, 10, 454}, + dictWord{11, 10, 758}, + dictWord{11, 10, 999}, + dictWord{ + 12, + 10, + 27, + }, + dictWord{12, 10, 131}, + dictWord{12, 10, 245}, + dictWord{12, 10, 312}, + dictWord{12, 10, 446}, + dictWord{12, 10, 454}, + dictWord{13, 10, 98}, + dictWord{ + 13, + 10, + 426, + }, + dictWord{13, 10, 508}, + dictWord{14, 10, 163}, + dictWord{14, 10, 272}, + dictWord{14, 10, 277}, + dictWord{14, 10, 370}, + dictWord{15, 10, 95}, + dictWord{15, 10, 138}, + dictWord{15, 10, 167}, + dictWord{17, 10, 38}, + dictWord{148, 10, 96}, + dictWord{132, 0, 757}, + dictWord{134, 0, 1263}, + dictWord{4, 0, 820}, + dictWord{134, 10, 1759}, + dictWord{133, 0, 722}, + dictWord{136, 11, 816}, + dictWord{138, 10, 372}, + dictWord{145, 10, 16}, + dictWord{134, 0, 1039}, + dictWord{ + 4, + 0, + 991, + }, + dictWord{134, 0, 2028}, + dictWord{133, 10, 258}, + dictWord{7, 0, 1875}, + dictWord{139, 0, 124}, + dictWord{6, 11, 559}, + dictWord{6, 11, 1691}, + dictWord{135, 11, 586}, + dictWord{5, 0, 324}, + dictWord{7, 0, 881}, + dictWord{8, 10, 134}, + dictWord{9, 10, 788}, + dictWord{140, 10, 438}, + dictWord{7, 11, 1823}, + dictWord{139, 11, 693}, + dictWord{6, 0, 1348}, + dictWord{134, 0, 1545}, + dictWord{134, 0, 911}, + dictWord{132, 0, 954}, + dictWord{8, 0, 329}, + dictWord{8, 0, 414}, + dictWord{7, 10, 1948}, + dictWord{135, 10, 2004}, + dictWord{5, 0, 517}, + dictWord{6, 10, 439}, + dictWord{7, 10, 780}, + dictWord{135, 10, 1040}, + dictWord{ + 132, + 0, + 816, + }, + dictWord{5, 10, 1}, + dictWord{6, 10, 81}, + dictWord{138, 10, 520}, + dictWord{9, 0, 713}, + dictWord{10, 0, 222}, + dictWord{5, 10, 482}, + dictWord{8, 10, 98}, + dictWord{10, 10, 700}, + dictWord{10, 10, 822}, + dictWord{11, 10, 302}, + dictWord{11, 10, 778}, + dictWord{12, 10, 50}, + dictWord{12, 10, 127}, + dictWord{12, 10, 396}, + dictWord{13, 10, 62}, + dictWord{13, 10, 328}, + dictWord{14, 10, 122}, + dictWord{147, 10, 72}, + dictWord{137, 0, 33}, + dictWord{5, 10, 2}, + dictWord{7, 10, 1494}, + dictWord{136, 10, 589}, + dictWord{6, 10, 512}, + dictWord{7, 10, 797}, + dictWord{8, 10, 253}, + dictWord{9, 10, 77}, + dictWord{10, 10, 1}, + dictWord{10, 11, 108}, + dictWord{10, 10, 129}, + dictWord{10, 10, 225}, + dictWord{11, 11, 116}, + dictWord{11, 10, 118}, + dictWord{11, 10, 226}, + dictWord{11, 10, 251}, + dictWord{ + 11, + 10, + 430, + }, + dictWord{11, 10, 701}, + dictWord{11, 10, 974}, + dictWord{11, 10, 982}, + dictWord{12, 10, 64}, + dictWord{12, 10, 260}, + dictWord{12, 10, 488}, + dictWord{ + 140, + 10, + 690, + }, + dictWord{134, 11, 456}, + dictWord{133, 11, 925}, + dictWord{5, 0, 150}, + dictWord{7, 0, 106}, + dictWord{7, 0, 774}, + dictWord{8, 0, 603}, + dictWord{ + 9, + 0, + 593, + }, + dictWord{9, 0, 634}, + dictWord{10, 0, 44}, + dictWord{10, 0, 173}, + dictWord{11, 0, 462}, + dictWord{11, 0, 515}, + dictWord{13, 0, 216}, + dictWord{13, 0, 288}, + dictWord{142, 0, 400}, + dictWord{137, 10, 347}, + dictWord{5, 0, 748}, + dictWord{134, 0, 553}, + dictWord{12, 0, 108}, + dictWord{141, 0, 291}, + dictWord{7, 0, 420}, + dictWord{4, 10, 12}, + dictWord{7, 10, 522}, + dictWord{7, 10, 809}, + dictWord{8, 10, 797}, + dictWord{141, 10, 88}, + dictWord{6, 11, 193}, + dictWord{7, 11, 240}, + dictWord{ + 7, + 11, + 1682, + }, + dictWord{10, 11, 51}, + dictWord{10, 11, 640}, + dictWord{11, 11, 410}, + dictWord{13, 11, 82}, + dictWord{14, 11, 247}, + dictWord{14, 11, 331}, + dictWord{142, 11, 377}, + dictWord{133, 10, 528}, + dictWord{135, 0, 1777}, + dictWord{4, 0, 493}, + dictWord{144, 0, 55}, + dictWord{136, 11, 633}, + dictWord{ + 139, + 0, + 81, + }, + dictWord{6, 0, 980}, + dictWord{136, 0, 321}, + dictWord{148, 10, 109}, + dictWord{5, 10, 266}, + dictWord{9, 10, 290}, + dictWord{9, 10, 364}, + dictWord{ + 10, + 10, + 293, + }, + dictWord{11, 10, 606}, + dictWord{142, 10, 45}, + dictWord{6, 0, 568}, + dictWord{7, 0, 112}, + dictWord{7, 0, 1804}, + dictWord{8, 0, 362}, + dictWord{8, 0, 410}, + dictWord{8, 0, 830}, + dictWord{9, 0, 514}, + dictWord{11, 0, 649}, + dictWord{142, 0, 157}, + dictWord{4, 0, 74}, + dictWord{6, 0, 510}, + dictWord{6, 10, 594}, + dictWord{ + 9, + 10, + 121, + }, + dictWord{10, 10, 49}, + dictWord{10, 10, 412}, + dictWord{139, 10, 834}, + dictWord{134, 0, 838}, + dictWord{136, 10, 748}, + dictWord{132, 10, 466}, + dictWord{132, 0, 625}, + dictWord{135, 11, 1443}, + dictWord{4, 11, 237}, + dictWord{135, 11, 514}, + dictWord{9, 10, 378}, + dictWord{141, 10, 162}, + dictWord{6, 0, 16}, + dictWord{6, 0, 158}, + dictWord{7, 0, 43}, + dictWord{7, 0, 129}, + dictWord{7, 0, 181}, + dictWord{8, 0, 276}, + dictWord{8, 0, 377}, + dictWord{10, 0, 523}, + dictWord{ + 11, + 0, + 816, + }, + dictWord{12, 0, 455}, + dictWord{13, 0, 303}, + dictWord{142, 0, 135}, + dictWord{135, 0, 281}, + dictWord{4, 0, 1}, + dictWord{7, 0, 1143}, + dictWord{7, 0, 1463}, + dictWord{8, 0, 61}, + dictWord{9, 0, 207}, + dictWord{9, 0, 390}, + dictWord{9, 0, 467}, + dictWord{139, 0, 836}, + dictWord{6, 11, 392}, + dictWord{7, 11, 65}, + dictWord{ + 135, + 11, + 2019, + }, + dictWord{132, 10, 667}, + dictWord{4, 0, 723}, + dictWord{5, 0, 895}, + dictWord{7, 0, 1031}, + dictWord{8, 0, 199}, + dictWord{8, 0, 340}, + dictWord{9, 0, 153}, + dictWord{9, 0, 215}, + dictWord{10, 0, 21}, + dictWord{10, 0, 59}, + dictWord{10, 0, 80}, + dictWord{10, 0, 224}, + dictWord{10, 0, 838}, + dictWord{11, 0, 229}, + dictWord{ + 11, + 0, + 652, + }, + dictWord{12, 0, 192}, + dictWord{13, 0, 146}, + dictWord{142, 0, 91}, + dictWord{132, 0, 295}, + dictWord{137, 0, 51}, + dictWord{9, 11, 222}, + dictWord{ + 10, + 11, + 43, + }, + dictWord{139, 11, 900}, + dictWord{5, 0, 309}, + dictWord{140, 0, 211}, + dictWord{5, 0, 125}, + dictWord{8, 0, 77}, + dictWord{138, 0, 15}, + dictWord{136, 11, 604}, + dictWord{138, 0, 789}, + dictWord{5, 0, 173}, + dictWord{4, 10, 39}, + dictWord{7, 10, 1843}, + dictWord{8, 10, 407}, + dictWord{11, 10, 144}, + dictWord{140, 10, 523}, + dictWord{138, 11, 265}, + dictWord{133, 0, 439}, + dictWord{132, 10, 510}, + dictWord{7, 0, 648}, + dictWord{7, 0, 874}, + dictWord{11, 0, 164}, + dictWord{12, 0, 76}, + dictWord{18, 0, 9}, + dictWord{7, 10, 1980}, + dictWord{10, 10, 487}, + dictWord{138, 10, 809}, + dictWord{12, 0, 111}, + dictWord{14, 0, 294}, + dictWord{19, 0, 45}, + dictWord{13, 10, 260}, + dictWord{146, 10, 63}, + dictWord{133, 11, 549}, + dictWord{134, 10, 570}, + dictWord{4, 0, 8}, + dictWord{7, 0, 1152}, + dictWord{7, 0, 1153}, + dictWord{7, 0, 1715}, + dictWord{9, 0, 374}, + dictWord{10, 0, 478}, + dictWord{139, 0, 648}, + dictWord{135, 0, 1099}, + dictWord{5, 0, 575}, + dictWord{6, 0, 354}, + dictWord{ + 135, + 0, + 701, + }, + dictWord{7, 11, 36}, + dictWord{8, 11, 201}, + dictWord{136, 11, 605}, + dictWord{4, 10, 787}, + dictWord{136, 11, 156}, + dictWord{6, 0, 518}, + dictWord{ + 149, + 11, + 13, + }, + dictWord{140, 11, 224}, + dictWord{134, 0, 702}, + dictWord{132, 10, 516}, + dictWord{5, 11, 724}, + dictWord{10, 11, 305}, + dictWord{11, 11, 151}, + dictWord{12, 11, 33}, + dictWord{12, 11, 121}, + dictWord{12, 11, 381}, + dictWord{17, 11, 3}, + dictWord{17, 11, 27}, + dictWord{17, 11, 78}, + dictWord{18, 11, 18}, + dictWord{19, 11, 54}, + dictWord{149, 11, 5}, + dictWord{8, 0, 87}, + dictWord{4, 11, 523}, + dictWord{5, 11, 638}, + dictWord{11, 10, 887}, + dictWord{14, 10, 365}, + dictWord{ + 142, + 10, + 375, + }, + dictWord{138, 0, 438}, + dictWord{136, 10, 821}, + dictWord{135, 11, 1908}, + dictWord{6, 11, 242}, + dictWord{7, 11, 227}, + dictWord{7, 11, 1581}, + dictWord{8, 11, 104}, + dictWord{9, 11, 113}, + dictWord{9, 11, 220}, + dictWord{9, 11, 427}, + dictWord{10, 11, 74}, + dictWord{10, 11, 239}, + dictWord{11, 11, 579}, + dictWord{11, 11, 1023}, + dictWord{13, 11, 4}, + dictWord{13, 11, 204}, + dictWord{13, 11, 316}, + dictWord{18, 11, 95}, + dictWord{148, 11, 86}, + dictWord{4, 0, 69}, + dictWord{5, 0, 122}, + dictWord{5, 0, 849}, + dictWord{6, 0, 1633}, + dictWord{9, 0, 656}, + dictWord{138, 0, 464}, + dictWord{7, 0, 1802}, + dictWord{4, 10, 10}, + dictWord{ + 139, + 10, + 786, + }, + dictWord{135, 11, 861}, + dictWord{139, 0, 499}, + dictWord{7, 0, 476}, + dictWord{7, 0, 1592}, + dictWord{138, 0, 87}, + dictWord{133, 10, 684}, + dictWord{ + 4, + 0, + 840, + }, + dictWord{134, 10, 27}, + dictWord{142, 0, 283}, + dictWord{6, 0, 1620}, + dictWord{7, 11, 1328}, + dictWord{136, 11, 494}, + dictWord{5, 0, 859}, + dictWord{ + 7, + 0, + 1160, + }, + dictWord{8, 0, 107}, + dictWord{9, 0, 291}, + dictWord{9, 0, 439}, + dictWord{10, 0, 663}, + dictWord{11, 0, 609}, + dictWord{140, 0, 197}, + dictWord{ + 7, + 11, + 1306, + }, + dictWord{8, 11, 505}, + dictWord{9, 11, 482}, + dictWord{10, 11, 126}, + dictWord{11, 11, 225}, + dictWord{12, 11, 347}, + dictWord{12, 11, 449}, + dictWord{ + 13, + 11, + 19, + }, + dictWord{142, 11, 218}, + dictWord{5, 11, 268}, + dictWord{10, 11, 764}, + dictWord{12, 11, 120}, + dictWord{13, 11, 39}, + dictWord{145, 11, 127}, + dictWord{145, 10, 56}, + dictWord{7, 11, 1672}, + dictWord{10, 11, 472}, + dictWord{11, 11, 189}, + dictWord{143, 11, 51}, + dictWord{6, 10, 342}, + dictWord{6, 10, 496}, + dictWord{8, 10, 275}, + dictWord{137, 10, 206}, + dictWord{133, 0, 600}, + dictWord{4, 0, 117}, + dictWord{6, 0, 372}, + dictWord{7, 0, 1905}, + dictWord{142, 0, 323}, + dictWord{4, 10, 909}, + dictWord{5, 10, 940}, + dictWord{135, 11, 1471}, + dictWord{132, 10, 891}, + dictWord{4, 0, 722}, + dictWord{139, 0, 471}, + dictWord{4, 11, 384}, + dictWord{135, 11, 1022}, + dictWord{132, 10, 687}, + dictWord{9, 0, 5}, + dictWord{12, 0, 216}, + dictWord{12, 0, 294}, + dictWord{12, 0, 298}, + dictWord{12, 0, 400}, + dictWord{12, 0, 518}, + dictWord{13, 0, 229}, + dictWord{143, 0, 139}, + dictWord{135, 11, 1703}, + dictWord{7, 11, 1602}, + dictWord{10, 11, 698}, + dictWord{ + 12, + 11, + 212, + }, + dictWord{141, 11, 307}, + dictWord{6, 10, 41}, + dictWord{141, 10, 160}, + dictWord{135, 11, 1077}, + dictWord{9, 11, 159}, + dictWord{11, 11, 28}, + dictWord{140, 11, 603}, + dictWord{4, 0, 514}, + dictWord{7, 0, 1304}, + dictWord{138, 0, 477}, + dictWord{134, 0, 1774}, + dictWord{9, 0, 88}, + dictWord{139, 0, 270}, + dictWord{5, 0, 12}, + dictWord{7, 0, 375}, + dictWord{9, 0, 438}, + dictWord{134, 10, 1718}, + dictWord{132, 11, 515}, + dictWord{136, 10, 778}, + dictWord{8, 11, 632}, + dictWord{8, 11, 697}, + dictWord{137, 11, 854}, + dictWord{6, 0, 362}, + dictWord{6, 0, 997}, + dictWord{146, 0, 51}, + dictWord{7, 0, 816}, + dictWord{7, 0, 1241}, + dictWord{ + 9, + 0, + 283, + }, + dictWord{9, 0, 520}, + dictWord{10, 0, 213}, + dictWord{10, 0, 307}, + dictWord{10, 0, 463}, + dictWord{10, 0, 671}, + dictWord{10, 0, 746}, + dictWord{11, 0, 401}, + dictWord{11, 0, 794}, + dictWord{12, 0, 517}, + dictWord{18, 0, 107}, + dictWord{147, 0, 115}, + dictWord{133, 10, 115}, + dictWord{150, 11, 28}, + dictWord{4, 11, 136}, + dictWord{133, 11, 551}, + dictWord{142, 10, 314}, + dictWord{132, 0, 258}, + dictWord{6, 0, 22}, + dictWord{7, 0, 903}, + dictWord{7, 0, 1963}, + dictWord{8, 0, 639}, + dictWord{138, 0, 577}, + dictWord{5, 0, 681}, + dictWord{8, 0, 782}, + dictWord{13, 0, 130}, + dictWord{17, 0, 84}, + dictWord{5, 10, 193}, + dictWord{140, 10, 178}, + dictWord{ + 9, + 11, + 17, + }, + dictWord{138, 11, 291}, + dictWord{7, 11, 1287}, + dictWord{9, 11, 44}, + dictWord{10, 11, 552}, + dictWord{10, 11, 642}, + dictWord{11, 11, 839}, + dictWord{12, 11, 274}, + dictWord{12, 11, 275}, + dictWord{12, 11, 372}, + dictWord{13, 11, 91}, + dictWord{142, 11, 125}, + dictWord{135, 10, 174}, + dictWord{4, 0, 664}, + dictWord{5, 0, 804}, + dictWord{139, 0, 1013}, + dictWord{134, 0, 942}, + dictWord{6, 0, 1349}, + dictWord{6, 0, 1353}, + dictWord{6, 0, 1450}, + dictWord{7, 11, 1518}, + dictWord{139, 11, 694}, + dictWord{11, 0, 356}, + dictWord{4, 10, 122}, + dictWord{5, 10, 796}, + dictWord{5, 10, 952}, + dictWord{6, 10, 1660}, + dictWord{ + 6, + 10, + 1671, + }, + dictWord{8, 10, 567}, + dictWord{9, 10, 687}, + dictWord{9, 10, 742}, + dictWord{10, 10, 686}, + dictWord{11, 10, 682}, + dictWord{140, 10, 281}, + dictWord{ + 5, + 0, + 32, + }, + dictWord{6, 11, 147}, + dictWord{7, 11, 886}, + dictWord{9, 11, 753}, + dictWord{138, 11, 268}, + dictWord{5, 10, 179}, + dictWord{7, 10, 1095}, + dictWord{ + 135, + 10, + 1213, + }, + dictWord{4, 10, 66}, + dictWord{7, 10, 722}, + dictWord{135, 10, 904}, + dictWord{135, 10, 352}, + dictWord{9, 11, 245}, + dictWord{138, 11, 137}, + dictWord{4, 0, 289}, + dictWord{7, 0, 629}, + dictWord{7, 0, 1698}, + dictWord{7, 0, 1711}, + dictWord{12, 0, 215}, + dictWord{133, 11, 414}, + dictWord{6, 0, 1975}, + dictWord{135, 11, 1762}, + dictWord{6, 0, 450}, + dictWord{136, 0, 109}, + dictWord{141, 10, 35}, + dictWord{134, 11, 599}, + dictWord{136, 0, 705}, + dictWord{ + 133, + 0, + 664, + }, + dictWord{134, 11, 1749}, + dictWord{11, 11, 402}, + dictWord{12, 11, 109}, + dictWord{12, 11, 431}, + dictWord{13, 11, 179}, + dictWord{13, 11, 206}, + dictWord{14, 11, 175}, + dictWord{14, 11, 217}, + dictWord{16, 11, 3}, + dictWord{148, 11, 53}, + dictWord{135, 0, 1238}, + dictWord{134, 11, 1627}, + dictWord{ + 132, + 11, + 488, + }, + dictWord{13, 0, 318}, + dictWord{10, 10, 592}, + dictWord{10, 10, 753}, + dictWord{12, 10, 317}, + dictWord{12, 10, 355}, + dictWord{12, 10, 465}, + dictWord{ + 12, + 10, + 469, + }, + dictWord{12, 10, 560}, + dictWord{140, 10, 578}, + dictWord{133, 10, 564}, + dictWord{132, 11, 83}, + dictWord{140, 11, 676}, + dictWord{6, 0, 1872}, + dictWord{6, 0, 1906}, + dictWord{6, 0, 1907}, + dictWord{9, 0, 934}, + dictWord{9, 0, 956}, + dictWord{9, 0, 960}, + dictWord{9, 0, 996}, + dictWord{12, 0, 794}, + dictWord{ + 12, + 0, + 876, + }, + dictWord{12, 0, 880}, + dictWord{12, 0, 918}, + dictWord{15, 0, 230}, + dictWord{18, 0, 234}, + dictWord{18, 0, 238}, + dictWord{21, 0, 38}, + dictWord{149, 0, 62}, + dictWord{134, 10, 556}, + dictWord{134, 11, 278}, + dictWord{137, 0, 103}, + dictWord{7, 10, 544}, + dictWord{8, 10, 719}, + dictWord{138, 10, 61}, + dictWord{ + 4, + 10, + 5, + }, + dictWord{5, 10, 498}, + dictWord{8, 10, 637}, + dictWord{137, 10, 521}, + dictWord{7, 0, 777}, + dictWord{12, 0, 229}, + dictWord{12, 0, 239}, + dictWord{15, 0, 12}, + dictWord{12, 11, 229}, + dictWord{12, 11, 239}, + dictWord{143, 11, 12}, + dictWord{6, 0, 26}, + dictWord{7, 11, 388}, + dictWord{7, 11, 644}, + dictWord{139, 11, 781}, + dictWord{7, 11, 229}, + dictWord{8, 11, 59}, + dictWord{9, 11, 190}, + dictWord{9, 11, 257}, + dictWord{10, 11, 378}, + dictWord{140, 11, 191}, + dictWord{133, 10, 927}, + dictWord{135, 10, 1441}, + dictWord{4, 10, 893}, + dictWord{5, 10, 780}, + dictWord{133, 10, 893}, + dictWord{4, 0, 414}, + dictWord{5, 0, 467}, + dictWord{9, 0, 654}, + dictWord{10, 0, 451}, + dictWord{12, 0, 59}, + dictWord{141, 0, 375}, + dictWord{142, 0, 173}, + dictWord{135, 0, 17}, + dictWord{7, 0, 1350}, + dictWord{133, 10, 238}, + dictWord{135, 0, 955}, + dictWord{4, 0, 960}, + dictWord{10, 0, 887}, + dictWord{12, 0, 753}, + dictWord{18, 0, 161}, + dictWord{18, 0, 162}, + dictWord{152, 0, 19}, + dictWord{136, 11, 344}, + dictWord{6, 10, 1729}, + dictWord{137, 11, 288}, + dictWord{132, 11, 660}, + dictWord{4, 0, 217}, + dictWord{5, 0, 710}, + dictWord{7, 0, 760}, + dictWord{7, 0, 1926}, + dictWord{9, 0, 428}, + dictWord{9, 0, 708}, + dictWord{10, 0, 254}, + dictWord{10, 0, 296}, + dictWord{10, 0, 720}, + dictWord{11, 0, 109}, + dictWord{ + 11, + 0, + 255, + }, + dictWord{12, 0, 165}, + dictWord{12, 0, 315}, + dictWord{13, 0, 107}, + dictWord{13, 0, 203}, + dictWord{14, 0, 54}, + dictWord{14, 0, 99}, + dictWord{14, 0, 114}, + dictWord{14, 0, 388}, + dictWord{16, 0, 85}, + dictWord{17, 0, 9}, + dictWord{17, 0, 33}, + dictWord{20, 0, 25}, + dictWord{20, 0, 28}, + dictWord{20, 0, 29}, + dictWord{21, 0, 9}, + dictWord{21, 0, 10}, + dictWord{21, 0, 34}, + dictWord{22, 0, 17}, + dictWord{4, 10, 60}, + dictWord{7, 10, 1800}, + dictWord{8, 10, 314}, + dictWord{9, 10, 700}, + dictWord{ + 139, + 10, + 487, + }, + dictWord{7, 11, 1035}, + dictWord{138, 11, 737}, + dictWord{7, 11, 690}, + dictWord{9, 11, 217}, + dictWord{9, 11, 587}, + dictWord{140, 11, 521}, + dictWord{6, 0, 919}, + dictWord{7, 11, 706}, + dictWord{7, 11, 1058}, + dictWord{138, 11, 538}, + dictWord{7, 10, 1853}, + dictWord{138, 10, 437}, + dictWord{ + 136, + 10, + 419, + }, + dictWord{6, 0, 280}, + dictWord{10, 0, 502}, + dictWord{11, 0, 344}, + dictWord{140, 0, 38}, + dictWord{5, 0, 45}, + dictWord{7, 0, 1161}, + dictWord{11, 0, 448}, + dictWord{11, 0, 880}, + dictWord{13, 0, 139}, + dictWord{13, 0, 407}, + dictWord{15, 0, 16}, + dictWord{17, 0, 95}, + dictWord{18, 0, 66}, + dictWord{18, 0, 88}, + dictWord{ + 18, + 0, + 123, + }, + dictWord{149, 0, 7}, + dictWord{11, 11, 92}, + dictWord{11, 11, 196}, + dictWord{11, 11, 409}, + dictWord{11, 11, 450}, + dictWord{11, 11, 666}, + dictWord{ + 11, + 11, + 777, + }, + dictWord{12, 11, 262}, + dictWord{13, 11, 385}, + dictWord{13, 11, 393}, + dictWord{15, 11, 115}, + dictWord{16, 11, 45}, + dictWord{145, 11, 82}, + dictWord{136, 0, 777}, + dictWord{134, 11, 1744}, + dictWord{4, 0, 410}, + dictWord{7, 0, 521}, + dictWord{133, 10, 828}, + dictWord{134, 0, 673}, + dictWord{7, 0, 1110}, + dictWord{7, 0, 1778}, + dictWord{7, 10, 176}, + dictWord{135, 10, 178}, + dictWord{5, 10, 806}, + dictWord{7, 11, 268}, + dictWord{7, 10, 1976}, + dictWord{ + 136, + 11, + 569, + }, + dictWord{4, 11, 733}, + dictWord{9, 11, 194}, + dictWord{10, 11, 92}, + dictWord{11, 11, 198}, + dictWord{12, 11, 84}, + dictWord{12, 11, 87}, + dictWord{ + 13, + 11, + 128, + }, + dictWord{144, 11, 74}, + dictWord{5, 0, 341}, + dictWord{7, 0, 1129}, + dictWord{11, 0, 414}, + dictWord{4, 10, 51}, + dictWord{6, 10, 4}, + dictWord{7, 10, 591}, + dictWord{7, 10, 849}, + dictWord{7, 10, 951}, + dictWord{7, 10, 1613}, + dictWord{7, 10, 1760}, + dictWord{7, 10, 1988}, + dictWord{9, 10, 434}, + dictWord{10, 10, 754}, + dictWord{11, 10, 25}, + dictWord{139, 10, 37}, + dictWord{133, 10, 902}, + dictWord{135, 10, 928}, + dictWord{135, 0, 787}, + dictWord{132, 0, 436}, + dictWord{ + 134, + 10, + 270, + }, + dictWord{7, 0, 1587}, + dictWord{135, 0, 1707}, + dictWord{6, 0, 377}, + dictWord{7, 0, 1025}, + dictWord{9, 0, 613}, + dictWord{145, 0, 104}, + dictWord{ + 7, + 11, + 982, + }, + dictWord{7, 11, 1361}, + dictWord{10, 11, 32}, + dictWord{143, 11, 56}, + dictWord{139, 0, 96}, + dictWord{132, 0, 451}, + dictWord{132, 10, 416}, + dictWord{ + 142, + 10, + 372, + }, + dictWord{5, 10, 152}, + dictWord{5, 10, 197}, + dictWord{7, 11, 306}, + dictWord{7, 10, 340}, + dictWord{7, 10, 867}, + dictWord{10, 10, 548}, + dictWord{ + 10, + 10, + 581, + }, + dictWord{11, 10, 6}, + dictWord{12, 10, 3}, + dictWord{12, 10, 19}, + dictWord{14, 10, 110}, + dictWord{142, 10, 289}, + dictWord{134, 0, 680}, + dictWord{ + 134, + 11, + 609, + }, + dictWord{7, 0, 483}, + dictWord{7, 10, 190}, + dictWord{8, 10, 28}, + dictWord{8, 10, 141}, + dictWord{8, 10, 444}, + dictWord{8, 10, 811}, + dictWord{ + 9, + 10, + 468, + }, + dictWord{11, 10, 334}, + dictWord{12, 10, 24}, + dictWord{12, 10, 386}, + dictWord{140, 10, 576}, + dictWord{10, 0, 916}, + dictWord{133, 10, 757}, + dictWord{ + 5, + 10, + 721, + }, + dictWord{135, 10, 1553}, + dictWord{133, 11, 178}, + dictWord{134, 0, 937}, + dictWord{132, 10, 898}, + dictWord{133, 0, 739}, + dictWord{ + 147, + 0, + 82, + }, + dictWord{135, 0, 663}, + dictWord{146, 0, 128}, + dictWord{5, 10, 277}, + dictWord{141, 10, 247}, + dictWord{134, 0, 1087}, + dictWord{132, 10, 435}, + dictWord{ + 6, + 11, + 381, + }, + dictWord{7, 11, 645}, + dictWord{7, 11, 694}, + dictWord{136, 11, 546}, + dictWord{7, 0, 503}, + dictWord{135, 0, 1885}, + dictWord{6, 0, 1965}, + dictWord{ + 8, + 0, + 925, + }, + dictWord{138, 0, 955}, + dictWord{4, 0, 113}, + dictWord{5, 0, 163}, + dictWord{5, 0, 735}, + dictWord{7, 0, 1009}, + dictWord{9, 0, 9}, + dictWord{9, 0, 771}, + dictWord{12, 0, 90}, + dictWord{13, 0, 138}, + dictWord{13, 0, 410}, + dictWord{143, 0, 128}, + dictWord{4, 0, 324}, + dictWord{138, 0, 104}, + dictWord{7, 0, 460}, + dictWord{ + 5, + 10, + 265, + }, + dictWord{134, 10, 212}, + dictWord{133, 11, 105}, + dictWord{7, 11, 261}, + dictWord{7, 11, 1107}, + dictWord{7, 11, 1115}, + dictWord{7, 11, 1354}, + dictWord{7, 11, 1588}, + dictWord{7, 11, 1705}, + dictWord{7, 11, 1902}, + dictWord{9, 11, 465}, + dictWord{10, 11, 248}, + dictWord{10, 11, 349}, + dictWord{10, 11, 647}, + dictWord{11, 11, 527}, + dictWord{11, 11, 660}, + dictWord{11, 11, 669}, + dictWord{12, 11, 529}, + dictWord{141, 11, 305}, + dictWord{5, 11, 438}, + dictWord{ + 9, + 11, + 694, + }, + dictWord{12, 11, 627}, + dictWord{141, 11, 210}, + dictWord{152, 11, 11}, + dictWord{4, 0, 935}, + dictWord{133, 0, 823}, + dictWord{132, 10, 702}, + dictWord{ + 5, + 0, + 269, + }, + dictWord{7, 0, 434}, + dictWord{7, 0, 891}, + dictWord{8, 0, 339}, + dictWord{9, 0, 702}, + dictWord{11, 0, 594}, + dictWord{11, 0, 718}, + dictWord{17, 0, 100}, + dictWord{5, 10, 808}, + dictWord{135, 10, 2045}, + dictWord{7, 0, 1014}, + dictWord{9, 0, 485}, + dictWord{141, 0, 264}, + dictWord{134, 0, 1713}, + dictWord{7, 0, 1810}, + dictWord{11, 0, 866}, + dictWord{12, 0, 103}, + dictWord{13, 0, 495}, + dictWord{140, 11, 233}, + dictWord{4, 0, 423}, + dictWord{10, 0, 949}, + dictWord{138, 0, 1013}, + dictWord{135, 0, 900}, + dictWord{8, 11, 25}, + dictWord{138, 11, 826}, + dictWord{5, 10, 166}, + dictWord{8, 10, 739}, + dictWord{140, 10, 511}, + dictWord{ + 134, + 0, + 2018, + }, + dictWord{7, 11, 1270}, + dictWord{139, 11, 612}, + dictWord{4, 10, 119}, + dictWord{5, 10, 170}, + dictWord{5, 10, 447}, + dictWord{7, 10, 1708}, + dictWord{ + 7, + 10, + 1889, + }, + dictWord{9, 10, 357}, + dictWord{9, 10, 719}, + dictWord{12, 10, 486}, + dictWord{140, 10, 596}, + dictWord{12, 0, 574}, + dictWord{140, 11, 574}, + dictWord{132, 11, 308}, + dictWord{6, 0, 964}, + dictWord{6, 0, 1206}, + dictWord{134, 0, 1302}, + dictWord{4, 10, 450}, + dictWord{135, 10, 1158}, + dictWord{ + 135, + 11, + 150, + }, + dictWord{136, 11, 649}, + dictWord{14, 0, 213}, + dictWord{148, 0, 38}, + dictWord{9, 11, 45}, + dictWord{9, 11, 311}, + dictWord{141, 11, 42}, + dictWord{ + 134, + 11, + 521, + }, + dictWord{7, 10, 1375}, + dictWord{7, 10, 1466}, + dictWord{138, 10, 331}, + dictWord{132, 10, 754}, + dictWord{5, 11, 339}, + dictWord{7, 11, 1442}, + dictWord{14, 11, 3}, + dictWord{15, 11, 41}, + dictWord{147, 11, 66}, + dictWord{136, 11, 378}, + dictWord{134, 0, 1022}, + dictWord{5, 10, 850}, + dictWord{136, 10, 799}, + dictWord{142, 0, 143}, + dictWord{135, 0, 2029}, + dictWord{134, 11, 1628}, + dictWord{8, 0, 523}, + dictWord{150, 0, 34}, + dictWord{5, 0, 625}, + dictWord{ + 135, + 0, + 1617, + }, + dictWord{7, 0, 275}, + dictWord{7, 10, 238}, + dictWord{7, 10, 2033}, + dictWord{8, 10, 120}, + dictWord{8, 10, 188}, + dictWord{8, 10, 659}, + dictWord{ + 9, + 10, + 598, + }, + dictWord{10, 10, 466}, + dictWord{12, 10, 342}, + dictWord{12, 10, 588}, + dictWord{13, 10, 503}, + dictWord{14, 10, 246}, + dictWord{143, 10, 92}, + dictWord{ + 7, + 0, + 37, + }, + dictWord{8, 0, 425}, + dictWord{8, 0, 693}, + dictWord{9, 0, 720}, + dictWord{10, 0, 380}, + dictWord{10, 0, 638}, + dictWord{11, 0, 273}, + dictWord{11, 0, 473}, + dictWord{12, 0, 61}, + dictWord{143, 0, 43}, + dictWord{135, 11, 829}, + dictWord{135, 0, 1943}, + dictWord{132, 0, 765}, + dictWord{5, 11, 486}, + dictWord{ + 135, + 11, + 1349, + }, + dictWord{7, 11, 1635}, + dictWord{8, 11, 17}, + dictWord{10, 11, 217}, + dictWord{138, 11, 295}, + dictWord{4, 10, 201}, + dictWord{7, 10, 1744}, + dictWord{ + 8, + 10, + 602, + }, + dictWord{11, 10, 247}, + dictWord{11, 10, 826}, + dictWord{145, 10, 65}, + dictWord{138, 11, 558}, + dictWord{11, 0, 551}, + dictWord{142, 0, 159}, + dictWord{8, 10, 164}, + dictWord{146, 10, 62}, + dictWord{139, 11, 176}, + dictWord{132, 0, 168}, + dictWord{136, 0, 1010}, + dictWord{134, 0, 1994}, + dictWord{ + 135, + 0, + 91, + }, + dictWord{138, 0, 532}, + dictWord{135, 10, 1243}, + dictWord{135, 0, 1884}, + dictWord{132, 10, 907}, + dictWord{5, 10, 100}, + dictWord{10, 10, 329}, + dictWord{12, 10, 416}, + dictWord{149, 10, 29}, + dictWord{134, 11, 447}, + dictWord{132, 10, 176}, + dictWord{5, 10, 636}, + dictWord{5, 10, 998}, + dictWord{7, 10, 9}, + dictWord{7, 10, 1508}, + dictWord{8, 10, 26}, + dictWord{9, 10, 317}, + dictWord{9, 10, 358}, + dictWord{10, 10, 210}, + dictWord{10, 10, 292}, + dictWord{10, 10, 533}, + dictWord{11, 10, 555}, + dictWord{12, 10, 526}, + dictWord{12, 10, 607}, + dictWord{13, 10, 263}, + dictWord{13, 10, 459}, + dictWord{142, 10, 271}, + dictWord{ + 4, + 11, + 609, + }, + dictWord{135, 11, 756}, + dictWord{6, 0, 15}, + dictWord{7, 0, 70}, + dictWord{10, 0, 240}, + dictWord{147, 0, 93}, + dictWord{4, 11, 930}, + dictWord{133, 11, 947}, + dictWord{134, 0, 1227}, + dictWord{134, 0, 1534}, + dictWord{133, 11, 939}, + dictWord{133, 11, 962}, + dictWord{5, 11, 651}, + dictWord{8, 11, 170}, + dictWord{ + 9, + 11, + 61, + }, + dictWord{9, 11, 63}, + dictWord{10, 11, 23}, + dictWord{10, 11, 37}, + dictWord{10, 11, 834}, + dictWord{11, 11, 4}, + dictWord{11, 11, 187}, + dictWord{ + 11, + 11, + 281, + }, + dictWord{11, 11, 503}, + dictWord{11, 11, 677}, + dictWord{12, 11, 96}, + dictWord{12, 11, 130}, + dictWord{12, 11, 244}, + dictWord{14, 11, 5}, + dictWord{ + 14, + 11, + 40, + }, + dictWord{14, 11, 162}, + dictWord{14, 11, 202}, + dictWord{146, 11, 133}, + dictWord{4, 11, 406}, + dictWord{5, 11, 579}, + dictWord{12, 11, 492}, + dictWord{ + 150, + 11, + 15, + }, + dictWord{139, 0, 392}, + dictWord{6, 10, 610}, + dictWord{10, 10, 127}, + dictWord{141, 10, 27}, + dictWord{7, 0, 655}, + dictWord{7, 0, 1844}, + dictWord{ + 136, + 10, + 119, + }, + dictWord{4, 0, 145}, + dictWord{6, 0, 176}, + dictWord{7, 0, 395}, + dictWord{137, 0, 562}, + dictWord{132, 0, 501}, + dictWord{140, 11, 145}, + dictWord{ + 136, + 0, + 1019, + }, + dictWord{134, 0, 509}, + dictWord{139, 0, 267}, + dictWord{6, 11, 17}, + dictWord{7, 11, 16}, + dictWord{7, 11, 1001}, + dictWord{7, 11, 1982}, + dictWord{ + 9, + 11, + 886, + }, + dictWord{10, 11, 489}, + dictWord{10, 11, 800}, + dictWord{11, 11, 782}, + dictWord{12, 11, 320}, + dictWord{13, 11, 467}, + dictWord{14, 11, 145}, + dictWord{14, 11, 387}, + dictWord{143, 11, 119}, + dictWord{145, 11, 17}, + dictWord{6, 0, 1099}, + dictWord{133, 11, 458}, + dictWord{7, 11, 1983}, + dictWord{8, 11, 0}, + dictWord{8, 11, 171}, + dictWord{9, 11, 120}, + dictWord{9, 11, 732}, + dictWord{10, 11, 473}, + dictWord{11, 11, 656}, + dictWord{11, 11, 998}, + dictWord{18, 11, 0}, + dictWord{18, 11, 2}, + dictWord{147, 11, 21}, + dictWord{12, 11, 427}, + dictWord{146, 11, 38}, + dictWord{10, 0, 948}, + dictWord{138, 0, 968}, + dictWord{7, 10, 126}, + dictWord{136, 10, 84}, + dictWord{136, 10, 790}, + dictWord{4, 0, 114}, + dictWord{9, 0, 492}, + dictWord{13, 0, 462}, + dictWord{142, 0, 215}, + dictWord{6, 10, 64}, + dictWord{12, 10, 377}, + dictWord{141, 10, 309}, + dictWord{4, 0, 77}, + dictWord{5, 0, 361}, + dictWord{6, 0, 139}, + dictWord{6, 0, 401}, + dictWord{6, 0, 404}, + dictWord{ + 7, + 0, + 413, + }, + dictWord{7, 0, 715}, + dictWord{7, 0, 1716}, + dictWord{11, 0, 279}, + dictWord{12, 0, 179}, + dictWord{12, 0, 258}, + dictWord{13, 0, 244}, + dictWord{142, 0, 358}, + dictWord{134, 0, 1717}, + dictWord{7, 0, 772}, + dictWord{7, 0, 1061}, + dictWord{7, 0, 1647}, + dictWord{8, 0, 82}, + dictWord{11, 0, 250}, + dictWord{11, 0, 607}, + dictWord{12, 0, 311}, + dictWord{12, 0, 420}, + dictWord{13, 0, 184}, + dictWord{13, 0, 367}, + dictWord{7, 10, 1104}, + dictWord{11, 10, 269}, + dictWord{11, 10, 539}, + dictWord{11, 10, 627}, + dictWord{11, 10, 706}, + dictWord{11, 10, 975}, + dictWord{12, 10, 248}, + dictWord{12, 10, 434}, + dictWord{12, 10, 600}, + dictWord{ + 12, + 10, + 622, + }, + dictWord{13, 10, 297}, + dictWord{13, 10, 485}, + dictWord{14, 10, 69}, + dictWord{14, 10, 409}, + dictWord{143, 10, 108}, + dictWord{135, 0, 724}, + dictWord{ + 4, + 11, + 512, + }, + dictWord{4, 11, 519}, + dictWord{133, 11, 342}, + dictWord{134, 0, 1133}, + dictWord{145, 11, 29}, + dictWord{11, 10, 977}, + dictWord{141, 10, 507}, + dictWord{6, 0, 841}, + dictWord{6, 0, 1042}, + dictWord{6, 0, 1194}, + dictWord{10, 0, 993}, + dictWord{140, 0, 1021}, + dictWord{6, 11, 31}, + dictWord{7, 11, 491}, + dictWord{7, 11, 530}, + dictWord{8, 11, 592}, + dictWord{9, 10, 34}, + dictWord{11, 11, 53}, + dictWord{11, 10, 484}, + dictWord{11, 11, 779}, + dictWord{12, 11, 167}, + dictWord{12, 11, 411}, + dictWord{14, 11, 14}, + dictWord{14, 11, 136}, + dictWord{15, 11, 72}, + dictWord{16, 11, 17}, + dictWord{144, 11, 72}, + dictWord{4, 0, 1021}, + dictWord{6, 0, 2037}, + dictWord{133, 11, 907}, + dictWord{7, 0, 373}, + dictWord{8, 0, 335}, + dictWord{8, 0, 596}, + dictWord{9, 0, 488}, + dictWord{6, 10, 1700}, + dictWord{ + 7, + 10, + 293, + }, + dictWord{7, 10, 382}, + dictWord{7, 10, 1026}, + dictWord{7, 10, 1087}, + dictWord{7, 10, 2027}, + dictWord{8, 10, 252}, + dictWord{8, 10, 727}, + dictWord{ + 8, + 10, + 729, + }, + dictWord{9, 10, 30}, + dictWord{9, 10, 199}, + dictWord{9, 10, 231}, + dictWord{9, 10, 251}, + dictWord{9, 10, 334}, + dictWord{9, 10, 361}, + dictWord{9, 10, 712}, + dictWord{10, 10, 55}, + dictWord{10, 10, 60}, + dictWord{10, 10, 232}, + dictWord{10, 10, 332}, + dictWord{10, 10, 384}, + dictWord{10, 10, 396}, + dictWord{ + 10, + 10, + 504, + }, + dictWord{10, 10, 542}, + dictWord{10, 10, 652}, + dictWord{11, 10, 20}, + dictWord{11, 10, 48}, + dictWord{11, 10, 207}, + dictWord{11, 10, 291}, + dictWord{ + 11, + 10, + 298, + }, + dictWord{11, 10, 342}, + dictWord{11, 10, 365}, + dictWord{11, 10, 394}, + dictWord{11, 10, 620}, + dictWord{11, 10, 705}, + dictWord{11, 10, 1017}, + dictWord{12, 10, 123}, + dictWord{12, 10, 340}, + dictWord{12, 10, 406}, + dictWord{12, 10, 643}, + dictWord{13, 10, 61}, + dictWord{13, 10, 269}, + dictWord{ + 13, + 10, + 311, + }, + dictWord{13, 10, 319}, + dictWord{13, 10, 486}, + dictWord{14, 10, 234}, + dictWord{15, 10, 62}, + dictWord{15, 10, 85}, + dictWord{16, 10, 71}, + dictWord{ + 18, + 10, + 119, + }, + dictWord{148, 10, 105}, + dictWord{150, 0, 37}, + dictWord{4, 11, 208}, + dictWord{5, 11, 106}, + dictWord{6, 11, 531}, + dictWord{8, 11, 408}, + dictWord{ + 9, + 11, + 188, + }, + dictWord{138, 11, 572}, + dictWord{132, 0, 564}, + dictWord{6, 0, 513}, + dictWord{135, 0, 1052}, + dictWord{132, 0, 825}, + dictWord{9, 0, 899}, + dictWord{ + 140, + 11, + 441, + }, + dictWord{134, 0, 778}, + dictWord{133, 11, 379}, + dictWord{7, 0, 1417}, + dictWord{12, 0, 382}, + dictWord{17, 0, 48}, + dictWord{152, 0, 12}, + dictWord{ + 132, + 11, + 241, + }, + dictWord{7, 0, 1116}, + dictWord{6, 10, 379}, + dictWord{7, 10, 270}, + dictWord{8, 10, 176}, + dictWord{8, 10, 183}, + dictWord{9, 10, 432}, + dictWord{ + 9, + 10, + 661, + }, + dictWord{12, 10, 247}, + dictWord{12, 10, 617}, + dictWord{146, 10, 125}, + dictWord{5, 10, 792}, + dictWord{133, 10, 900}, + dictWord{6, 0, 545}, + dictWord{ + 7, + 0, + 565, + }, + dictWord{7, 0, 1669}, + dictWord{10, 0, 114}, + dictWord{11, 0, 642}, + dictWord{140, 0, 618}, + dictWord{133, 0, 5}, + dictWord{138, 11, 7}, + dictWord{ + 132, + 11, + 259, + }, + dictWord{135, 0, 192}, + dictWord{134, 0, 701}, + dictWord{136, 0, 763}, + dictWord{135, 10, 1979}, + dictWord{4, 10, 901}, + dictWord{133, 10, 776}, + dictWord{10, 0, 755}, + dictWord{147, 0, 29}, + dictWord{133, 0, 759}, + dictWord{4, 11, 173}, + dictWord{5, 11, 312}, + dictWord{5, 11, 512}, + dictWord{135, 11, 1285}, + dictWord{7, 11, 1603}, + dictWord{7, 11, 1691}, + dictWord{9, 11, 464}, + dictWord{11, 11, 195}, + dictWord{12, 11, 279}, + dictWord{12, 11, 448}, + dictWord{ + 14, + 11, + 11, + }, + dictWord{147, 11, 102}, + dictWord{7, 0, 370}, + dictWord{7, 0, 1007}, + dictWord{7, 0, 1177}, + dictWord{135, 0, 1565}, + dictWord{135, 0, 1237}, + dictWord{ + 4, + 0, + 87, + }, + dictWord{5, 0, 250}, + dictWord{141, 0, 298}, + dictWord{4, 11, 452}, + dictWord{5, 11, 583}, + dictWord{5, 11, 817}, + dictWord{6, 11, 433}, + dictWord{7, 11, 593}, + dictWord{7, 11, 720}, + dictWord{7, 11, 1378}, + dictWord{8, 11, 161}, + dictWord{9, 11, 284}, + dictWord{10, 11, 313}, + dictWord{139, 11, 886}, + dictWord{4, 11, 547}, + dictWord{135, 11, 1409}, + dictWord{136, 11, 722}, + dictWord{4, 10, 37}, + dictWord{5, 10, 334}, + dictWord{135, 10, 1253}, + dictWord{132, 10, 508}, + dictWord{ + 12, + 0, + 107, + }, + dictWord{146, 0, 31}, + dictWord{8, 11, 420}, + dictWord{139, 11, 193}, + dictWord{135, 0, 814}, + dictWord{135, 11, 409}, + dictWord{140, 0, 991}, + dictWord{4, 0, 57}, + dictWord{7, 0, 1195}, + dictWord{7, 0, 1438}, + dictWord{7, 0, 1548}, + dictWord{7, 0, 1835}, + dictWord{7, 0, 1904}, + dictWord{9, 0, 757}, + dictWord{ + 10, + 0, + 604, + }, + dictWord{139, 0, 519}, + dictWord{132, 0, 540}, + dictWord{138, 11, 308}, + dictWord{132, 10, 533}, + dictWord{136, 0, 608}, + dictWord{144, 11, 65}, + dictWord{4, 0, 1014}, + dictWord{134, 0, 2029}, + dictWord{4, 0, 209}, + dictWord{7, 0, 902}, + dictWord{5, 11, 1002}, + dictWord{136, 11, 745}, + dictWord{134, 0, 2030}, + dictWord{6, 0, 303}, + dictWord{7, 0, 335}, + dictWord{7, 0, 1437}, + dictWord{7, 0, 1668}, + dictWord{8, 0, 553}, + dictWord{8, 0, 652}, + dictWord{8, 0, 656}, + dictWord{ + 9, + 0, + 558, + }, + dictWord{11, 0, 743}, + dictWord{149, 0, 18}, + dictWord{5, 11, 575}, + dictWord{6, 11, 354}, + dictWord{135, 11, 701}, + dictWord{4, 11, 239}, + dictWord{ + 6, + 11, + 477, + }, + dictWord{7, 11, 1607}, + dictWord{11, 11, 68}, + dictWord{139, 11, 617}, + dictWord{132, 0, 559}, + dictWord{8, 0, 527}, + dictWord{18, 0, 60}, + dictWord{ + 147, + 0, + 24, + }, + dictWord{133, 10, 920}, + dictWord{138, 0, 511}, + dictWord{133, 0, 1017}, + dictWord{133, 0, 675}, + dictWord{138, 10, 391}, + dictWord{11, 0, 156}, + dictWord{135, 10, 1952}, + dictWord{138, 11, 369}, + dictWord{132, 11, 367}, + dictWord{133, 0, 709}, + dictWord{6, 0, 698}, + dictWord{134, 0, 887}, + dictWord{ + 142, + 10, + 126, + }, + dictWord{134, 0, 1745}, + dictWord{132, 10, 483}, + dictWord{13, 11, 299}, + dictWord{142, 11, 75}, + dictWord{133, 0, 714}, + dictWord{7, 0, 8}, + dictWord{ + 136, + 0, + 206, + }, + dictWord{138, 10, 480}, + dictWord{4, 11, 694}, + dictWord{9, 10, 495}, + dictWord{146, 10, 104}, + dictWord{7, 11, 1248}, + dictWord{11, 11, 621}, + dictWord{139, 11, 702}, + dictWord{140, 11, 687}, + dictWord{132, 0, 776}, + dictWord{139, 10, 1009}, + dictWord{135, 0, 1272}, + dictWord{134, 0, 1059}, + dictWord{ + 8, + 10, + 653, + }, + dictWord{13, 10, 93}, + dictWord{147, 10, 14}, + dictWord{135, 11, 213}, + dictWord{136, 0, 406}, + dictWord{133, 10, 172}, + dictWord{132, 0, 947}, + dictWord{8, 0, 175}, + dictWord{10, 0, 168}, + dictWord{138, 0, 573}, + dictWord{132, 0, 870}, + dictWord{6, 0, 1567}, + dictWord{151, 11, 28}, + dictWord{ + 134, + 11, + 472, + }, + dictWord{5, 10, 260}, + dictWord{136, 11, 132}, + dictWord{4, 11, 751}, + dictWord{11, 11, 390}, + dictWord{140, 11, 32}, + dictWord{4, 11, 409}, + dictWord{ + 133, + 11, + 78, + }, + dictWord{12, 0, 554}, + dictWord{6, 11, 473}, + dictWord{145, 11, 105}, + dictWord{133, 0, 784}, + dictWord{8, 0, 908}, + dictWord{136, 11, 306}, + dictWord{139, 0, 882}, + dictWord{6, 0, 358}, + dictWord{7, 0, 1393}, + dictWord{8, 0, 396}, + dictWord{10, 0, 263}, + dictWord{14, 0, 154}, + dictWord{16, 0, 48}, + dictWord{ + 17, + 0, + 8, + }, + dictWord{7, 11, 1759}, + dictWord{8, 11, 396}, + dictWord{10, 11, 263}, + dictWord{14, 11, 154}, + dictWord{16, 11, 48}, + dictWord{145, 11, 8}, + dictWord{ + 13, + 11, + 163, + }, + dictWord{13, 11, 180}, + dictWord{18, 11, 78}, + dictWord{148, 11, 35}, + dictWord{14, 0, 32}, + dictWord{18, 0, 85}, + dictWord{20, 0, 2}, + dictWord{152, 0, 16}, + dictWord{7, 0, 228}, + dictWord{10, 0, 770}, + dictWord{8, 10, 167}, + dictWord{8, 10, 375}, + dictWord{9, 10, 82}, + dictWord{9, 10, 561}, + dictWord{138, 10, 620}, + dictWord{132, 0, 845}, + dictWord{9, 0, 14}, + dictWord{9, 0, 441}, + dictWord{10, 0, 306}, + dictWord{139, 0, 9}, + dictWord{11, 0, 966}, + dictWord{12, 0, 287}, + dictWord{ + 13, + 0, + 342, + }, + dictWord{13, 0, 402}, + dictWord{15, 0, 110}, + dictWord{15, 0, 163}, + dictWord{8, 10, 194}, + dictWord{136, 10, 756}, + dictWord{134, 0, 1578}, + dictWord{ + 4, + 0, + 967, + }, + dictWord{6, 0, 1820}, + dictWord{6, 0, 1847}, + dictWord{140, 0, 716}, + dictWord{136, 0, 594}, + dictWord{7, 0, 1428}, + dictWord{7, 0, 1640}, + dictWord{ + 7, + 0, + 1867, + }, + dictWord{9, 0, 169}, + dictWord{9, 0, 182}, + dictWord{9, 0, 367}, + dictWord{9, 0, 478}, + dictWord{9, 0, 506}, + dictWord{9, 0, 551}, + dictWord{9, 0, 557}, + dictWord{ + 9, + 0, + 648, + }, + dictWord{9, 0, 697}, + dictWord{9, 0, 705}, + dictWord{9, 0, 725}, + dictWord{9, 0, 787}, + dictWord{9, 0, 794}, + dictWord{10, 0, 198}, + dictWord{10, 0, 214}, + dictWord{10, 0, 267}, + dictWord{10, 0, 275}, + dictWord{10, 0, 456}, + dictWord{10, 0, 551}, + dictWord{10, 0, 561}, + dictWord{10, 0, 613}, + dictWord{10, 0, 627}, + dictWord{ + 10, + 0, + 668, + }, + dictWord{10, 0, 675}, + dictWord{10, 0, 691}, + dictWord{10, 0, 695}, + dictWord{10, 0, 707}, + dictWord{10, 0, 715}, + dictWord{11, 0, 183}, + dictWord{ + 11, + 0, + 201, + }, + dictWord{11, 0, 244}, + dictWord{11, 0, 262}, + dictWord{11, 0, 352}, + dictWord{11, 0, 439}, + dictWord{11, 0, 493}, + dictWord{11, 0, 572}, + dictWord{11, 0, 591}, + dictWord{11, 0, 608}, + dictWord{11, 0, 611}, + dictWord{11, 0, 646}, + dictWord{11, 0, 674}, + dictWord{11, 0, 711}, + dictWord{11, 0, 751}, + dictWord{11, 0, 761}, + dictWord{11, 0, 776}, + dictWord{11, 0, 785}, + dictWord{11, 0, 850}, + dictWord{11, 0, 853}, + dictWord{11, 0, 862}, + dictWord{11, 0, 865}, + dictWord{11, 0, 868}, + dictWord{ + 11, + 0, + 875, + }, + dictWord{11, 0, 898}, + dictWord{11, 0, 902}, + dictWord{11, 0, 903}, + dictWord{11, 0, 910}, + dictWord{11, 0, 932}, + dictWord{11, 0, 942}, + dictWord{ + 11, + 0, + 957, + }, + dictWord{11, 0, 967}, + dictWord{11, 0, 972}, + dictWord{12, 0, 148}, + dictWord{12, 0, 195}, + dictWord{12, 0, 220}, + dictWord{12, 0, 237}, + dictWord{12, 0, 318}, + dictWord{12, 0, 339}, + dictWord{12, 0, 393}, + dictWord{12, 0, 445}, + dictWord{12, 0, 450}, + dictWord{12, 0, 474}, + dictWord{12, 0, 505}, + dictWord{12, 0, 509}, + dictWord{12, 0, 533}, + dictWord{12, 0, 591}, + dictWord{12, 0, 594}, + dictWord{12, 0, 597}, + dictWord{12, 0, 621}, + dictWord{12, 0, 633}, + dictWord{12, 0, 642}, + dictWord{ + 13, + 0, + 59, + }, + dictWord{13, 0, 60}, + dictWord{13, 0, 145}, + dictWord{13, 0, 239}, + dictWord{13, 0, 250}, + dictWord{13, 0, 329}, + dictWord{13, 0, 344}, + dictWord{13, 0, 365}, + dictWord{13, 0, 372}, + dictWord{13, 0, 387}, + dictWord{13, 0, 403}, + dictWord{13, 0, 414}, + dictWord{13, 0, 456}, + dictWord{13, 0, 470}, + dictWord{13, 0, 478}, + dictWord{13, 0, 483}, + dictWord{13, 0, 489}, + dictWord{14, 0, 55}, + dictWord{14, 0, 57}, + dictWord{14, 0, 81}, + dictWord{14, 0, 90}, + dictWord{14, 0, 148}, + dictWord{ + 14, + 0, + 239, + }, + dictWord{14, 0, 266}, + dictWord{14, 0, 321}, + dictWord{14, 0, 326}, + dictWord{14, 0, 327}, + dictWord{14, 0, 330}, + dictWord{14, 0, 347}, + dictWord{14, 0, 355}, + dictWord{14, 0, 401}, + dictWord{14, 0, 404}, + dictWord{14, 0, 411}, + dictWord{14, 0, 414}, + dictWord{14, 0, 416}, + dictWord{14, 0, 420}, + dictWord{15, 0, 61}, + dictWord{15, 0, 74}, + dictWord{15, 0, 87}, + dictWord{15, 0, 88}, + dictWord{15, 0, 94}, + dictWord{15, 0, 96}, + dictWord{15, 0, 116}, + dictWord{15, 0, 149}, + dictWord{15, 0, 154}, + dictWord{16, 0, 50}, + dictWord{16, 0, 63}, + dictWord{16, 0, 73}, + dictWord{17, 0, 2}, + dictWord{17, 0, 66}, + dictWord{17, 0, 92}, + dictWord{17, 0, 103}, + dictWord{ + 17, + 0, + 112, + }, + dictWord{17, 0, 120}, + dictWord{18, 0, 50}, + dictWord{18, 0, 54}, + dictWord{18, 0, 82}, + dictWord{18, 0, 86}, + dictWord{18, 0, 90}, + dictWord{18, 0, 111}, + dictWord{ + 18, + 0, + 115, + }, + dictWord{18, 0, 156}, + dictWord{19, 0, 40}, + dictWord{19, 0, 79}, + dictWord{20, 0, 78}, + dictWord{21, 0, 22}, + dictWord{135, 11, 883}, + dictWord{5, 0, 161}, + dictWord{135, 0, 839}, + dictWord{4, 0, 782}, + dictWord{13, 11, 293}, + dictWord{142, 11, 56}, + dictWord{133, 11, 617}, + dictWord{139, 11, 50}, + dictWord{ + 135, + 10, + 22, + }, + dictWord{145, 0, 64}, + dictWord{5, 10, 639}, + dictWord{7, 10, 1249}, + dictWord{139, 10, 896}, + dictWord{138, 0, 998}, + dictWord{135, 11, 2042}, + dictWord{ + 4, + 11, + 546, + }, + dictWord{142, 11, 233}, + dictWord{6, 0, 1043}, + dictWord{134, 0, 1574}, + dictWord{134, 0, 1496}, + dictWord{4, 10, 102}, + dictWord{7, 10, 815}, + dictWord{7, 10, 1699}, + dictWord{139, 10, 964}, + dictWord{12, 0, 781}, + dictWord{142, 0, 461}, + dictWord{4, 11, 313}, + dictWord{133, 11, 577}, + dictWord{ + 6, + 0, + 639, + }, + dictWord{6, 0, 1114}, + dictWord{137, 0, 817}, + dictWord{8, 11, 184}, + dictWord{141, 11, 433}, + dictWord{7, 0, 1814}, + dictWord{135, 11, 935}, + dictWord{ + 10, + 0, + 997, + }, + dictWord{140, 0, 958}, + dictWord{4, 0, 812}, + dictWord{137, 11, 625}, + dictWord{132, 10, 899}, + dictWord{136, 10, 795}, + dictWord{5, 11, 886}, + dictWord{6, 11, 46}, + dictWord{6, 11, 1790}, + dictWord{7, 11, 14}, + dictWord{7, 11, 732}, + dictWord{7, 11, 1654}, + dictWord{8, 11, 95}, + dictWord{8, 11, 327}, + dictWord{ + 8, + 11, + 616, + }, + dictWord{10, 11, 598}, + dictWord{10, 11, 769}, + dictWord{11, 11, 134}, + dictWord{11, 11, 747}, + dictWord{12, 11, 378}, + dictWord{142, 11, 97}, + dictWord{136, 0, 139}, + dictWord{6, 10, 52}, + dictWord{9, 10, 104}, + dictWord{9, 10, 559}, + dictWord{12, 10, 308}, + dictWord{147, 10, 87}, + dictWord{133, 11, 1021}, + dictWord{132, 10, 604}, + dictWord{132, 10, 301}, + dictWord{136, 10, 779}, + dictWord{7, 0, 643}, + dictWord{136, 0, 236}, + dictWord{132, 11, 153}, + dictWord{ + 134, + 0, + 1172, + }, + dictWord{147, 10, 32}, + dictWord{133, 11, 798}, + dictWord{6, 0, 1338}, + dictWord{132, 11, 587}, + dictWord{6, 11, 598}, + dictWord{7, 11, 42}, + dictWord{ + 8, + 11, + 695, + }, + dictWord{10, 11, 212}, + dictWord{11, 11, 158}, + dictWord{14, 11, 196}, + dictWord{145, 11, 85}, + dictWord{135, 10, 508}, + dictWord{5, 11, 957}, + dictWord{5, 11, 1008}, + dictWord{135, 11, 249}, + dictWord{4, 11, 129}, + dictWord{135, 11, 465}, + dictWord{5, 0, 54}, + dictWord{7, 11, 470}, + dictWord{7, 11, 1057}, + dictWord{7, 11, 1201}, + dictWord{9, 11, 755}, + dictWord{11, 11, 906}, + dictWord{140, 11, 527}, + dictWord{7, 11, 908}, + dictWord{146, 11, 7}, + dictWord{ + 5, + 11, + 148, + }, + dictWord{136, 11, 450}, + dictWord{144, 11, 1}, + dictWord{4, 0, 256}, + dictWord{135, 0, 1488}, + dictWord{9, 0, 351}, + dictWord{6, 10, 310}, + dictWord{ + 7, + 10, + 1849, + }, + dictWord{8, 10, 72}, + dictWord{8, 10, 272}, + dictWord{8, 10, 431}, + dictWord{9, 10, 12}, + dictWord{10, 10, 563}, + dictWord{10, 10, 630}, + dictWord{ + 10, + 10, + 796, + }, + dictWord{10, 10, 810}, + dictWord{11, 10, 367}, + dictWord{11, 10, 599}, + dictWord{11, 10, 686}, + dictWord{140, 10, 672}, + dictWord{6, 0, 1885}, + dictWord{ + 6, + 0, + 1898, + }, + dictWord{6, 0, 1899}, + dictWord{140, 0, 955}, + dictWord{4, 0, 714}, + dictWord{133, 0, 469}, + dictWord{6, 0, 1270}, + dictWord{134, 0, 1456}, + dictWord{132, 0, 744}, + dictWord{6, 0, 313}, + dictWord{7, 10, 537}, + dictWord{8, 10, 64}, + dictWord{9, 10, 127}, + dictWord{10, 10, 496}, + dictWord{12, 10, 510}, + dictWord{141, 10, 384}, + dictWord{4, 11, 217}, + dictWord{4, 10, 244}, + dictWord{5, 11, 710}, + dictWord{7, 10, 233}, + dictWord{7, 11, 1926}, + dictWord{9, 11, 428}, + dictWord{9, 11, 708}, + dictWord{10, 11, 254}, + dictWord{10, 11, 296}, + dictWord{10, 11, 720}, + dictWord{11, 11, 109}, + dictWord{11, 11, 255}, + dictWord{12, 11, 165}, + dictWord{12, 11, 315}, + dictWord{13, 11, 107}, + dictWord{13, 11, 203}, + dictWord{14, 11, 54}, + dictWord{14, 11, 99}, + dictWord{14, 11, 114}, + dictWord{ + 14, + 11, + 388, + }, + dictWord{16, 11, 85}, + dictWord{17, 11, 9}, + dictWord{17, 11, 33}, + dictWord{20, 11, 25}, + dictWord{20, 11, 28}, + dictWord{20, 11, 29}, + dictWord{21, 11, 9}, + dictWord{21, 11, 10}, + dictWord{21, 11, 34}, + dictWord{150, 11, 17}, + dictWord{138, 0, 402}, + dictWord{7, 0, 969}, + dictWord{146, 0, 55}, + dictWord{8, 0, 50}, + dictWord{ + 137, + 0, + 624, + }, + dictWord{134, 0, 1355}, + dictWord{132, 0, 572}, + dictWord{134, 10, 1650}, + dictWord{10, 10, 702}, + dictWord{139, 10, 245}, + dictWord{ + 10, + 0, + 847, + }, + dictWord{142, 0, 445}, + dictWord{6, 0, 43}, + dictWord{7, 0, 38}, + dictWord{8, 0, 248}, + dictWord{138, 0, 513}, + dictWord{133, 0, 369}, + dictWord{137, 10, 338}, + dictWord{133, 0, 766}, + dictWord{133, 0, 363}, + dictWord{133, 10, 896}, + dictWord{8, 11, 392}, + dictWord{11, 11, 54}, + dictWord{13, 11, 173}, + dictWord{ + 13, + 11, + 294, + }, + dictWord{148, 11, 7}, + dictWord{134, 0, 678}, + dictWord{7, 11, 1230}, + dictWord{136, 11, 531}, + dictWord{6, 0, 258}, + dictWord{140, 0, 409}, + dictWord{ + 5, + 0, + 249, + }, + dictWord{148, 0, 82}, + dictWord{7, 10, 1117}, + dictWord{136, 10, 539}, + dictWord{5, 0, 393}, + dictWord{6, 0, 378}, + dictWord{7, 0, 1981}, + dictWord{9, 0, 32}, + dictWord{9, 0, 591}, + dictWord{10, 0, 685}, + dictWord{10, 0, 741}, + dictWord{142, 0, 382}, + dictWord{133, 0, 788}, + dictWord{134, 0, 1281}, + dictWord{ + 134, + 0, + 1295, + }, + dictWord{7, 0, 1968}, + dictWord{141, 0, 509}, + dictWord{4, 0, 61}, + dictWord{5, 0, 58}, + dictWord{5, 0, 171}, + dictWord{5, 0, 683}, + dictWord{6, 0, 291}, + dictWord{ + 6, + 0, + 566, + }, + dictWord{7, 0, 1650}, + dictWord{11, 0, 523}, + dictWord{12, 0, 273}, + dictWord{12, 0, 303}, + dictWord{15, 0, 39}, + dictWord{143, 0, 111}, + dictWord{ + 6, + 0, + 706, + }, + dictWord{134, 0, 1283}, + dictWord{134, 0, 589}, + dictWord{135, 11, 1433}, + dictWord{133, 11, 435}, + dictWord{7, 0, 1059}, + dictWord{13, 0, 54}, + dictWord{ + 5, + 10, + 4, + }, + dictWord{5, 10, 810}, + dictWord{6, 10, 13}, + dictWord{6, 10, 538}, + dictWord{6, 10, 1690}, + dictWord{6, 10, 1726}, + dictWord{7, 10, 1819}, + dictWord{ + 8, + 10, + 148, + }, + dictWord{8, 10, 696}, + dictWord{8, 10, 791}, + dictWord{12, 10, 125}, + dictWord{143, 10, 9}, + dictWord{135, 10, 1268}, + dictWord{5, 11, 85}, + dictWord{ + 6, + 11, + 419, + }, + dictWord{7, 11, 134}, + dictWord{7, 11, 305}, + dictWord{7, 11, 361}, + dictWord{7, 11, 1337}, + dictWord{8, 11, 71}, + dictWord{140, 11, 519}, + dictWord{ + 137, + 0, + 824, + }, + dictWord{140, 11, 688}, + dictWord{5, 11, 691}, + dictWord{7, 11, 345}, + dictWord{7, 10, 1385}, + dictWord{9, 11, 94}, + dictWord{11, 10, 582}, + dictWord{ + 11, + 10, + 650, + }, + dictWord{11, 10, 901}, + dictWord{11, 10, 949}, + dictWord{12, 11, 169}, + dictWord{12, 10, 232}, + dictWord{12, 10, 236}, + dictWord{13, 10, 413}, + dictWord{13, 10, 501}, + dictWord{146, 10, 116}, + dictWord{4, 0, 917}, + dictWord{133, 0, 1005}, + dictWord{7, 0, 1598}, + dictWord{5, 11, 183}, + dictWord{6, 11, 582}, + dictWord{9, 11, 344}, + dictWord{10, 11, 679}, + dictWord{140, 11, 435}, + dictWord{4, 10, 925}, + dictWord{5, 10, 803}, + dictWord{8, 10, 698}, + dictWord{ + 138, + 10, + 828, + }, + dictWord{132, 0, 919}, + dictWord{135, 11, 511}, + dictWord{139, 10, 992}, + dictWord{4, 0, 255}, + dictWord{5, 0, 302}, + dictWord{6, 0, 132}, + dictWord{ + 7, + 0, + 128, + }, + dictWord{7, 0, 283}, + dictWord{7, 0, 1299}, + dictWord{10, 0, 52}, + dictWord{10, 0, 514}, + dictWord{11, 0, 925}, + dictWord{13, 0, 92}, + dictWord{142, 0, 309}, + dictWord{134, 0, 1369}, + dictWord{135, 10, 1847}, + dictWord{134, 0, 328}, + dictWord{7, 11, 1993}, + dictWord{136, 11, 684}, + dictWord{133, 10, 383}, + dictWord{137, 0, 173}, + dictWord{134, 11, 583}, + dictWord{134, 0, 1411}, + dictWord{19, 0, 65}, + dictWord{5, 11, 704}, + dictWord{8, 11, 357}, + dictWord{10, 11, 745}, + dictWord{14, 11, 426}, + dictWord{17, 11, 94}, + dictWord{147, 11, 57}, + dictWord{9, 10, 660}, + dictWord{138, 10, 347}, + dictWord{4, 11, 179}, + dictWord{5, 11, 198}, + dictWord{133, 11, 697}, + dictWord{7, 11, 347}, + dictWord{7, 11, 971}, + dictWord{8, 11, 181}, + dictWord{138, 11, 711}, + dictWord{141, 0, 442}, + dictWord{ + 11, + 0, + 842, + }, + dictWord{11, 0, 924}, + dictWord{13, 0, 317}, + dictWord{13, 0, 370}, + dictWord{13, 0, 469}, + dictWord{13, 0, 471}, + dictWord{14, 0, 397}, + dictWord{18, 0, 69}, + dictWord{18, 0, 145}, + dictWord{7, 10, 572}, + dictWord{9, 10, 592}, + dictWord{11, 10, 680}, + dictWord{12, 10, 356}, + dictWord{140, 10, 550}, + dictWord{14, 11, 19}, + dictWord{14, 11, 28}, + dictWord{144, 11, 29}, + dictWord{136, 0, 534}, + dictWord{4, 11, 243}, + dictWord{5, 11, 203}, + dictWord{7, 11, 19}, + dictWord{7, 11, 71}, + dictWord{7, 11, 113}, + dictWord{10, 11, 405}, + dictWord{11, 11, 357}, + dictWord{142, 11, 240}, + dictWord{6, 0, 210}, + dictWord{10, 0, 845}, + dictWord{138, 0, 862}, + dictWord{7, 11, 1351}, + dictWord{9, 11, 581}, + dictWord{10, 11, 639}, + dictWord{11, 11, 453}, + dictWord{140, 11, 584}, + dictWord{7, 11, 1450}, + dictWord{ + 139, + 11, + 99, + }, + dictWord{10, 0, 892}, + dictWord{12, 0, 719}, + dictWord{144, 0, 105}, + dictWord{4, 0, 284}, + dictWord{6, 0, 223}, + dictWord{134, 11, 492}, + dictWord{5, 11, 134}, + dictWord{6, 11, 408}, + dictWord{6, 11, 495}, + dictWord{135, 11, 1593}, + dictWord{136, 0, 529}, + dictWord{137, 0, 807}, + dictWord{4, 0, 218}, + dictWord{7, 0, 526}, + dictWord{143, 0, 137}, + dictWord{6, 0, 1444}, + dictWord{142, 11, 4}, + dictWord{132, 11, 665}, + dictWord{4, 0, 270}, + dictWord{5, 0, 192}, + dictWord{6, 0, 332}, + dictWord{7, 0, 1322}, + dictWord{4, 11, 248}, + dictWord{7, 11, 137}, + dictWord{137, 11, 349}, + dictWord{140, 0, 661}, + dictWord{7, 0, 1517}, + dictWord{11, 0, 597}, + dictWord{14, 0, 76}, + dictWord{14, 0, 335}, + dictWord{20, 0, 33}, + dictWord{7, 10, 748}, + dictWord{139, 10, 700}, + dictWord{5, 11, 371}, + dictWord{135, 11, 563}, + dictWord{146, 11, 57}, + dictWord{133, 10, 127}, + dictWord{133, 0, 418}, + dictWord{4, 11, 374}, + dictWord{7, 11, 547}, + dictWord{7, 11, 1700}, + dictWord{7, 11, 1833}, + dictWord{139, 11, 858}, + dictWord{6, 10, 198}, + dictWord{140, 10, 83}, + dictWord{7, 11, 1812}, + dictWord{13, 11, 259}, + dictWord{13, 11, 356}, + dictWord{ + 14, + 11, + 242, + }, + dictWord{147, 11, 114}, + dictWord{7, 0, 379}, + dictWord{8, 0, 481}, + dictWord{9, 0, 377}, + dictWord{5, 10, 276}, + dictWord{6, 10, 55}, + dictWord{ + 135, + 10, + 1369, + }, + dictWord{138, 11, 286}, + dictWord{5, 0, 1003}, + dictWord{6, 0, 149}, + dictWord{6, 10, 1752}, + dictWord{136, 10, 726}, + dictWord{8, 0, 262}, + dictWord{ + 9, + 0, + 627, + }, + dictWord{10, 0, 18}, + dictWord{11, 0, 214}, + dictWord{11, 0, 404}, + dictWord{11, 0, 457}, + dictWord{11, 0, 780}, + dictWord{11, 0, 913}, + dictWord{13, 0, 401}, + dictWord{14, 0, 200}, + dictWord{6, 11, 1647}, + dictWord{7, 11, 1552}, + dictWord{7, 11, 2010}, + dictWord{9, 11, 494}, + dictWord{137, 11, 509}, + dictWord{ + 135, + 0, + 742, + }, + dictWord{136, 0, 304}, + dictWord{132, 0, 142}, + dictWord{133, 10, 764}, + dictWord{6, 10, 309}, + dictWord{7, 10, 331}, + dictWord{138, 10, 550}, + dictWord{135, 10, 1062}, + dictWord{6, 11, 123}, + dictWord{7, 11, 214}, + dictWord{7, 10, 986}, + dictWord{9, 11, 728}, + dictWord{10, 11, 157}, + dictWord{11, 11, 346}, + dictWord{11, 11, 662}, + dictWord{143, 11, 106}, + dictWord{135, 10, 1573}, + dictWord{7, 0, 925}, + dictWord{137, 0, 799}, + dictWord{4, 0, 471}, + dictWord{5, 0, 51}, + dictWord{6, 0, 602}, + dictWord{8, 0, 484}, + dictWord{138, 0, 195}, + dictWord{136, 0, 688}, + dictWord{132, 0, 697}, + dictWord{6, 0, 1169}, + dictWord{6, 0, 1241}, + dictWord{6, 10, 194}, + dictWord{7, 10, 133}, + dictWord{10, 10, 493}, + dictWord{10, 10, 570}, + dictWord{139, 10, 664}, + dictWord{140, 0, 751}, + dictWord{7, 0, 929}, + dictWord{10, 0, 452}, + dictWord{11, 0, 878}, + dictWord{16, 0, 33}, + dictWord{5, 10, 24}, + dictWord{5, 10, 569}, + dictWord{6, 10, 3}, + dictWord{6, 10, 119}, + dictWord{ + 6, + 10, + 143, + }, + dictWord{6, 10, 440}, + dictWord{7, 10, 599}, + dictWord{7, 10, 1686}, + dictWord{7, 10, 1854}, + dictWord{8, 10, 424}, + dictWord{9, 10, 43}, + dictWord{ + 9, + 10, + 584, + }, + dictWord{9, 10, 760}, + dictWord{10, 10, 328}, + dictWord{11, 10, 159}, + dictWord{11, 10, 253}, + dictWord{12, 10, 487}, + dictWord{140, 10, 531}, + dictWord{ + 4, + 11, + 707, + }, + dictWord{13, 11, 106}, + dictWord{18, 11, 49}, + dictWord{147, 11, 41}, + dictWord{5, 0, 221}, + dictWord{5, 11, 588}, + dictWord{134, 11, 393}, + dictWord{134, 0, 1437}, + dictWord{6, 11, 211}, + dictWord{7, 11, 1690}, + dictWord{11, 11, 486}, + dictWord{140, 11, 369}, + dictWord{5, 10, 14}, + dictWord{5, 10, 892}, + dictWord{6, 10, 283}, + dictWord{7, 10, 234}, + dictWord{136, 10, 537}, + dictWord{4, 0, 988}, + dictWord{136, 0, 955}, + dictWord{135, 0, 1251}, + dictWord{4, 10, 126}, + dictWord{8, 10, 635}, + dictWord{147, 10, 34}, + dictWord{4, 10, 316}, + dictWord{135, 10, 1561}, + dictWord{137, 10, 861}, + dictWord{4, 10, 64}, + dictWord{ + 5, + 10, + 352, + }, + dictWord{5, 10, 720}, + dictWord{6, 10, 368}, + dictWord{139, 10, 359}, + dictWord{134, 0, 192}, + dictWord{4, 0, 132}, + dictWord{5, 0, 69}, + dictWord{ + 135, + 0, + 1242, + }, + dictWord{7, 10, 1577}, + dictWord{10, 10, 304}, + dictWord{10, 10, 549}, + dictWord{12, 10, 365}, + dictWord{13, 10, 220}, + dictWord{13, 10, 240}, + dictWord{142, 10, 33}, + dictWord{4, 0, 111}, + dictWord{7, 0, 865}, + dictWord{134, 11, 219}, + dictWord{5, 11, 582}, + dictWord{6, 11, 1646}, + dictWord{7, 11, 99}, + dictWord{ + 7, + 11, + 1962, + }, + dictWord{7, 11, 1986}, + dictWord{8, 11, 515}, + dictWord{8, 11, 773}, + dictWord{9, 11, 23}, + dictWord{9, 11, 491}, + dictWord{12, 11, 620}, + dictWord{ + 14, + 11, + 52, + }, + dictWord{145, 11, 50}, + dictWord{132, 0, 767}, + dictWord{7, 11, 568}, + dictWord{148, 11, 21}, + dictWord{6, 0, 42}, + dictWord{7, 0, 1416}, + dictWord{ + 7, + 0, + 2005, + }, + dictWord{8, 0, 131}, + dictWord{8, 0, 466}, + dictWord{9, 0, 672}, + dictWord{13, 0, 252}, + dictWord{20, 0, 103}, + dictWord{133, 11, 851}, + dictWord{ + 135, + 0, + 1050, + }, + dictWord{6, 10, 175}, + dictWord{137, 10, 289}, + dictWord{5, 10, 432}, + dictWord{133, 10, 913}, + dictWord{6, 0, 44}, + dictWord{136, 0, 368}, + dictWord{ + 135, + 11, + 784, + }, + dictWord{132, 0, 570}, + dictWord{133, 0, 120}, + dictWord{139, 10, 595}, + dictWord{140, 0, 29}, + dictWord{6, 0, 227}, + dictWord{135, 0, 1589}, + dictWord{4, 11, 98}, + dictWord{7, 11, 1365}, + dictWord{9, 11, 422}, + dictWord{9, 11, 670}, + dictWord{10, 11, 775}, + dictWord{11, 11, 210}, + dictWord{13, 11, 26}, + dictWord{13, 11, 457}, + dictWord{141, 11, 476}, + dictWord{140, 10, 80}, + dictWord{5, 10, 931}, + dictWord{134, 10, 1698}, + dictWord{133, 0, 522}, + dictWord{ + 134, + 0, + 1120, + }, + dictWord{135, 0, 1529}, + dictWord{12, 0, 739}, + dictWord{14, 0, 448}, + dictWord{142, 0, 467}, + dictWord{11, 10, 526}, + dictWord{11, 10, 939}, + dictWord{141, 10, 290}, + dictWord{5, 10, 774}, + dictWord{6, 10, 1637}, + dictWord{6, 10, 1686}, + dictWord{134, 10, 1751}, + dictWord{6, 0, 1667}, + dictWord{ + 135, + 0, + 2036, + }, + dictWord{7, 10, 1167}, + dictWord{11, 10, 934}, + dictWord{13, 10, 391}, + dictWord{145, 10, 76}, + dictWord{137, 11, 147}, + dictWord{6, 10, 260}, + dictWord{ + 7, + 10, + 1484, + }, + dictWord{11, 11, 821}, + dictWord{12, 11, 110}, + dictWord{12, 11, 153}, + dictWord{18, 11, 41}, + dictWord{150, 11, 19}, + dictWord{6, 0, 511}, + dictWord{12, 0, 132}, + dictWord{134, 10, 573}, + dictWord{5, 0, 568}, + dictWord{6, 0, 138}, + dictWord{135, 0, 1293}, + dictWord{132, 0, 1020}, + dictWord{8, 0, 258}, + dictWord{9, 0, 208}, + dictWord{137, 0, 359}, + dictWord{4, 0, 565}, + dictWord{8, 0, 23}, + dictWord{136, 0, 827}, + dictWord{134, 0, 344}, + dictWord{4, 0, 922}, + dictWord{ + 5, + 0, + 1023, + }, + dictWord{13, 11, 477}, + dictWord{14, 11, 120}, + dictWord{148, 11, 61}, + dictWord{134, 0, 240}, + dictWord{5, 11, 209}, + dictWord{6, 11, 30}, + dictWord{ + 11, + 11, + 56, + }, + dictWord{139, 11, 305}, + dictWord{6, 0, 171}, + dictWord{7, 0, 1002}, + dictWord{7, 0, 1324}, + dictWord{9, 0, 415}, + dictWord{14, 0, 230}, + dictWord{ + 18, + 0, + 68, + }, + dictWord{4, 10, 292}, + dictWord{4, 10, 736}, + dictWord{5, 10, 871}, + dictWord{6, 10, 1689}, + dictWord{7, 10, 1944}, + dictWord{137, 10, 580}, + dictWord{ + 9, + 11, + 635, + }, + dictWord{139, 11, 559}, + dictWord{4, 11, 150}, + dictWord{5, 11, 303}, + dictWord{134, 11, 327}, + dictWord{6, 10, 63}, + dictWord{135, 10, 920}, + dictWord{ + 133, + 10, + 793, + }, + dictWord{8, 11, 192}, + dictWord{10, 11, 78}, + dictWord{10, 11, 555}, + dictWord{11, 11, 308}, + dictWord{13, 11, 359}, + dictWord{147, 11, 95}, + dictWord{135, 11, 786}, + dictWord{135, 11, 1712}, + dictWord{136, 0, 402}, + dictWord{6, 0, 754}, + dictWord{6, 11, 1638}, + dictWord{7, 11, 79}, + dictWord{7, 11, 496}, + dictWord{9, 11, 138}, + dictWord{10, 11, 336}, + dictWord{11, 11, 12}, + dictWord{12, 11, 412}, + dictWord{12, 11, 440}, + dictWord{142, 11, 305}, + dictWord{4, 0, 716}, + dictWord{141, 0, 31}, + dictWord{133, 0, 982}, + dictWord{8, 0, 691}, + dictWord{8, 0, 731}, + dictWord{5, 10, 67}, + dictWord{6, 10, 62}, + dictWord{6, 10, 374}, + dictWord{ + 135, + 10, + 1391, + }, + dictWord{9, 10, 790}, + dictWord{140, 10, 47}, + dictWord{139, 11, 556}, + dictWord{151, 11, 1}, + dictWord{7, 11, 204}, + dictWord{7, 11, 415}, + dictWord{8, 11, 42}, + dictWord{10, 11, 85}, + dictWord{11, 11, 33}, + dictWord{11, 11, 564}, + dictWord{12, 11, 571}, + dictWord{149, 11, 1}, + dictWord{8, 0, 888}, + dictWord{ + 7, + 11, + 610, + }, + dictWord{135, 11, 1501}, + dictWord{4, 10, 391}, + dictWord{135, 10, 1169}, + dictWord{5, 0, 847}, + dictWord{9, 0, 840}, + dictWord{138, 0, 803}, + dictWord{137, 0, 823}, + dictWord{134, 0, 785}, + dictWord{8, 0, 152}, + dictWord{9, 0, 53}, + dictWord{9, 0, 268}, + dictWord{9, 0, 901}, + dictWord{10, 0, 518}, + dictWord{ + 10, + 0, + 829, + }, + dictWord{11, 0, 188}, + dictWord{13, 0, 74}, + dictWord{14, 0, 46}, + dictWord{15, 0, 17}, + dictWord{15, 0, 33}, + dictWord{17, 0, 40}, + dictWord{18, 0, 36}, + dictWord{ + 19, + 0, + 20, + }, + dictWord{22, 0, 1}, + dictWord{152, 0, 2}, + dictWord{4, 11, 3}, + dictWord{5, 11, 247}, + dictWord{5, 11, 644}, + dictWord{7, 11, 744}, + dictWord{7, 11, 1207}, + dictWord{7, 11, 1225}, + dictWord{7, 11, 1909}, + dictWord{146, 11, 147}, + dictWord{136, 0, 532}, + dictWord{135, 0, 681}, + dictWord{132, 10, 271}, + dictWord{ + 140, + 0, + 314, + }, + dictWord{140, 0, 677}, + dictWord{4, 0, 684}, + dictWord{136, 0, 384}, + dictWord{5, 11, 285}, + dictWord{9, 11, 67}, + dictWord{13, 11, 473}, + dictWord{ + 143, + 11, + 82, + }, + dictWord{4, 10, 253}, + dictWord{5, 10, 544}, + dictWord{7, 10, 300}, + dictWord{137, 10, 340}, + dictWord{7, 0, 110}, + dictWord{7, 0, 447}, + dictWord{8, 0, 290}, + dictWord{8, 0, 591}, + dictWord{9, 0, 382}, + dictWord{9, 0, 649}, + dictWord{11, 0, 71}, + dictWord{11, 0, 155}, + dictWord{11, 0, 313}, + dictWord{12, 0, 5}, + dictWord{13, 0, 325}, + dictWord{142, 0, 287}, + dictWord{134, 0, 1818}, + dictWord{136, 0, 1007}, + dictWord{138, 0, 321}, + dictWord{7, 0, 360}, + dictWord{7, 0, 425}, + dictWord{9, 0, 66}, + dictWord{9, 0, 278}, + dictWord{138, 0, 644}, + dictWord{133, 10, 818}, + dictWord{5, 0, 385}, + dictWord{5, 10, 541}, + dictWord{6, 10, 94}, + dictWord{6, 10, 499}, + dictWord{ + 7, + 10, + 230, + }, + dictWord{139, 10, 321}, + dictWord{4, 10, 920}, + dictWord{5, 10, 25}, + dictWord{5, 10, 790}, + dictWord{6, 10, 457}, + dictWord{7, 10, 853}, + dictWord{ + 136, + 10, + 788, + }, + dictWord{4, 0, 900}, + dictWord{133, 0, 861}, + dictWord{5, 0, 254}, + dictWord{7, 0, 985}, + dictWord{136, 0, 73}, + dictWord{7, 0, 1959}, + dictWord{ + 136, + 0, + 683, + }, + dictWord{134, 10, 1765}, + dictWord{133, 10, 822}, + dictWord{132, 10, 634}, + dictWord{4, 11, 29}, + dictWord{6, 11, 532}, + dictWord{7, 11, 1628}, + dictWord{ + 7, + 11, + 1648, + }, + dictWord{9, 11, 303}, + dictWord{9, 11, 350}, + dictWord{10, 11, 433}, + dictWord{11, 11, 97}, + dictWord{11, 11, 557}, + dictWord{11, 11, 745}, + dictWord{12, 11, 289}, + dictWord{12, 11, 335}, + dictWord{12, 11, 348}, + dictWord{12, 11, 606}, + dictWord{13, 11, 116}, + dictWord{13, 11, 233}, + dictWord{ + 13, + 11, + 466, + }, + dictWord{14, 11, 181}, + dictWord{14, 11, 209}, + dictWord{14, 11, 232}, + dictWord{14, 11, 236}, + dictWord{14, 11, 300}, + dictWord{16, 11, 41}, + dictWord{ + 148, + 11, + 97, + }, + dictWord{19, 0, 86}, + dictWord{6, 10, 36}, + dictWord{7, 10, 658}, + dictWord{136, 10, 454}, + dictWord{135, 11, 1692}, + dictWord{132, 0, 725}, + dictWord{ + 5, + 11, + 501, + }, + dictWord{7, 11, 1704}, + dictWord{9, 11, 553}, + dictWord{11, 11, 520}, + dictWord{12, 11, 557}, + dictWord{141, 11, 249}, + dictWord{134, 0, 196}, + dictWord{133, 0, 831}, + dictWord{136, 0, 723}, + dictWord{7, 0, 1897}, + dictWord{13, 0, 80}, + dictWord{13, 0, 437}, + dictWord{145, 0, 74}, + dictWord{4, 0, 992}, + dictWord{ + 6, + 0, + 627, + }, + dictWord{136, 0, 994}, + dictWord{135, 11, 1294}, + dictWord{132, 10, 104}, + dictWord{5, 0, 848}, + dictWord{6, 0, 66}, + dictWord{136, 0, 764}, + dictWord{ + 4, + 0, + 36, + }, + dictWord{7, 0, 1387}, + dictWord{10, 0, 205}, + dictWord{139, 0, 755}, + dictWord{6, 0, 1046}, + dictWord{134, 0, 1485}, + dictWord{134, 0, 950}, + dictWord{132, 0, 887}, + dictWord{14, 0, 450}, + dictWord{148, 0, 111}, + dictWord{7, 0, 620}, + dictWord{7, 0, 831}, + dictWord{9, 10, 542}, + dictWord{9, 10, 566}, + dictWord{ + 138, + 10, + 728, + }, + dictWord{6, 0, 165}, + dictWord{138, 0, 388}, + dictWord{139, 10, 263}, + dictWord{4, 0, 719}, + dictWord{135, 0, 155}, + dictWord{138, 10, 468}, + dictWord{6, 11, 453}, + dictWord{144, 11, 36}, + dictWord{134, 11, 129}, + dictWord{5, 0, 533}, + dictWord{7, 0, 755}, + dictWord{138, 0, 780}, + dictWord{134, 0, 1465}, + dictWord{4, 0, 353}, + dictWord{6, 0, 146}, + dictWord{6, 0, 1789}, + dictWord{7, 0, 427}, + dictWord{7, 0, 990}, + dictWord{7, 0, 1348}, + dictWord{9, 0, 665}, + dictWord{9, 0, 898}, + dictWord{11, 0, 893}, + dictWord{142, 0, 212}, + dictWord{7, 10, 87}, + dictWord{142, 10, 288}, + dictWord{4, 0, 45}, + dictWord{135, 0, 1257}, + dictWord{12, 0, 7}, + dictWord{7, 10, 988}, + dictWord{7, 10, 1939}, + dictWord{9, 10, 64}, + dictWord{9, 10, 502}, + dictWord{12, 10, 34}, + dictWord{13, 10, 12}, + dictWord{13, 10, 234}, + dictWord{147, 10, 77}, + dictWord{4, 0, 607}, + dictWord{5, 11, 60}, + dictWord{6, 11, 504}, + dictWord{7, 11, 614}, + dictWord{7, 11, 1155}, + dictWord{140, 11, 0}, + dictWord{ + 135, + 10, + 141, + }, + dictWord{8, 11, 198}, + dictWord{11, 11, 29}, + dictWord{140, 11, 534}, + dictWord{140, 0, 65}, + dictWord{136, 0, 816}, + dictWord{132, 10, 619}, + dictWord{139, 0, 88}, + dictWord{5, 10, 246}, + dictWord{8, 10, 189}, + dictWord{9, 10, 355}, + dictWord{9, 10, 512}, + dictWord{10, 10, 124}, + dictWord{10, 10, 453}, + dictWord{11, 10, 143}, + dictWord{11, 10, 416}, + dictWord{11, 10, 859}, + dictWord{141, 10, 341}, + dictWord{4, 11, 379}, + dictWord{135, 11, 1397}, + dictWord{ + 4, + 0, + 600, + }, + dictWord{137, 0, 621}, + dictWord{133, 0, 367}, + dictWord{134, 0, 561}, + dictWord{6, 0, 559}, + dictWord{134, 0, 1691}, + dictWord{6, 0, 585}, + dictWord{ + 134, + 11, + 585, + }, + dictWord{135, 11, 1228}, + dictWord{4, 11, 118}, + dictWord{5, 10, 678}, + dictWord{6, 11, 274}, + dictWord{6, 11, 361}, + dictWord{7, 11, 75}, + dictWord{ + 141, + 11, + 441, + }, + dictWord{135, 11, 1818}, + dictWord{137, 11, 841}, + dictWord{5, 0, 573}, + dictWord{6, 0, 287}, + dictWord{7, 10, 862}, + dictWord{7, 10, 1886}, + dictWord{138, 10, 179}, + dictWord{132, 10, 517}, + dictWord{140, 11, 693}, + dictWord{5, 11, 314}, + dictWord{6, 11, 221}, + dictWord{7, 11, 419}, + dictWord{ + 10, + 11, + 650, + }, + dictWord{11, 11, 396}, + dictWord{12, 11, 156}, + dictWord{13, 11, 369}, + dictWord{14, 11, 333}, + dictWord{145, 11, 47}, + dictWord{140, 10, 540}, + dictWord{136, 10, 667}, + dictWord{11, 10, 403}, + dictWord{146, 10, 83}, + dictWord{6, 0, 672}, + dictWord{133, 10, 761}, + dictWord{9, 0, 157}, + dictWord{10, 10, 131}, + dictWord{140, 10, 72}, + dictWord{7, 0, 714}, + dictWord{134, 11, 460}, + dictWord{134, 0, 456}, + dictWord{133, 0, 925}, + dictWord{5, 11, 682}, + dictWord{ + 135, + 11, + 1887, + }, + dictWord{136, 11, 510}, + dictWord{136, 11, 475}, + dictWord{133, 11, 1016}, + dictWord{9, 0, 19}, + dictWord{7, 11, 602}, + dictWord{8, 11, 179}, + dictWord{ + 10, + 11, + 781, + }, + dictWord{140, 11, 126}, + dictWord{6, 11, 329}, + dictWord{138, 11, 111}, + dictWord{6, 0, 822}, + dictWord{134, 0, 1473}, + dictWord{144, 11, 86}, + dictWord{11, 0, 113}, + dictWord{139, 11, 113}, + dictWord{5, 11, 821}, + dictWord{134, 11, 1687}, + dictWord{133, 10, 449}, + dictWord{7, 0, 463}, + dictWord{ + 17, + 0, + 69, + }, + dictWord{136, 10, 103}, + dictWord{7, 10, 2028}, + dictWord{138, 10, 641}, + dictWord{6, 0, 193}, + dictWord{7, 0, 240}, + dictWord{7, 0, 1682}, + dictWord{ + 10, + 0, + 51, + }, + dictWord{10, 0, 640}, + dictWord{11, 0, 410}, + dictWord{13, 0, 82}, + dictWord{14, 0, 247}, + dictWord{14, 0, 331}, + dictWord{142, 0, 377}, + dictWord{6, 0, 471}, + dictWord{11, 0, 411}, + dictWord{142, 0, 2}, + dictWord{5, 11, 71}, + dictWord{7, 11, 1407}, + dictWord{9, 11, 388}, + dictWord{9, 11, 704}, + dictWord{10, 11, 261}, + dictWord{ + 10, + 11, + 619, + }, + dictWord{11, 11, 547}, + dictWord{11, 11, 619}, + dictWord{143, 11, 157}, + dictWord{136, 0, 633}, + dictWord{135, 0, 1148}, + dictWord{6, 0, 554}, + dictWord{7, 0, 1392}, + dictWord{12, 0, 129}, + dictWord{7, 10, 1274}, + dictWord{7, 10, 1386}, + dictWord{7, 11, 2008}, + dictWord{9, 11, 337}, + dictWord{10, 11, 517}, + dictWord{146, 10, 87}, + dictWord{7, 0, 803}, + dictWord{8, 0, 542}, + dictWord{6, 10, 187}, + dictWord{7, 10, 1203}, + dictWord{8, 10, 380}, + dictWord{14, 10, 117}, + dictWord{149, 10, 28}, + dictWord{6, 10, 297}, + dictWord{7, 10, 793}, + dictWord{139, 10, 938}, + dictWord{8, 0, 438}, + dictWord{11, 0, 363}, + dictWord{7, 10, 464}, + dictWord{11, 10, 105}, + dictWord{12, 10, 231}, + dictWord{14, 10, 386}, + dictWord{15, 10, 102}, + dictWord{148, 10, 75}, + dictWord{5, 11, 16}, + dictWord{6, 11, 86}, + dictWord{6, 11, 603}, + dictWord{7, 11, 292}, + dictWord{7, 11, 561}, + dictWord{8, 11, 257}, + dictWord{8, 11, 382}, + dictWord{9, 11, 721}, + dictWord{9, 11, 778}, + dictWord{ + 11, + 11, + 581, + }, + dictWord{140, 11, 466}, + dictWord{6, 0, 717}, + dictWord{4, 11, 486}, + dictWord{133, 11, 491}, + dictWord{132, 0, 875}, + dictWord{132, 11, 72}, + dictWord{6, 11, 265}, + dictWord{135, 11, 847}, + dictWord{4, 0, 237}, + dictWord{135, 0, 514}, + dictWord{6, 0, 392}, + dictWord{7, 0, 65}, + dictWord{135, 0, 2019}, + dictWord{140, 11, 261}, + dictWord{135, 11, 922}, + dictWord{137, 11, 404}, + dictWord{12, 0, 563}, + dictWord{14, 0, 101}, + dictWord{18, 0, 129}, + dictWord{ + 7, + 10, + 1010, + }, + dictWord{11, 10, 733}, + dictWord{11, 10, 759}, + dictWord{13, 10, 34}, + dictWord{146, 10, 45}, + dictWord{7, 10, 1656}, + dictWord{9, 10, 369}, + dictWord{ + 10, + 10, + 338, + }, + dictWord{10, 10, 490}, + dictWord{11, 10, 154}, + dictWord{11, 10, 545}, + dictWord{11, 10, 775}, + dictWord{13, 10, 77}, + dictWord{141, 10, 274}, + dictWord{4, 0, 444}, + dictWord{10, 0, 146}, + dictWord{140, 0, 9}, + dictWord{139, 11, 163}, + dictWord{7, 0, 1260}, + dictWord{135, 0, 1790}, + dictWord{9, 0, 222}, + dictWord{10, 0, 43}, + dictWord{139, 0, 900}, + dictWord{137, 11, 234}, + dictWord{138, 0, 971}, + dictWord{137, 0, 761}, + dictWord{134, 0, 699}, + dictWord{ + 136, + 11, + 434, + }, + dictWord{6, 0, 1116}, + dictWord{7, 0, 1366}, + dictWord{5, 10, 20}, + dictWord{6, 11, 197}, + dictWord{6, 10, 298}, + dictWord{7, 10, 659}, + dictWord{8, 11, 205}, + dictWord{137, 10, 219}, + dictWord{132, 11, 490}, + dictWord{11, 11, 820}, + dictWord{150, 11, 51}, + dictWord{7, 10, 1440}, + dictWord{11, 10, 854}, + dictWord{ + 11, + 10, + 872, + }, + dictWord{11, 10, 921}, + dictWord{12, 10, 551}, + dictWord{13, 10, 472}, + dictWord{142, 10, 367}, + dictWord{140, 11, 13}, + dictWord{132, 0, 829}, + dictWord{12, 0, 242}, + dictWord{132, 10, 439}, + dictWord{136, 10, 669}, + dictWord{6, 0, 593}, + dictWord{6, 11, 452}, + dictWord{7, 11, 312}, + dictWord{ + 138, + 11, + 219, + }, + dictWord{4, 11, 333}, + dictWord{9, 11, 176}, + dictWord{12, 11, 353}, + dictWord{141, 11, 187}, + dictWord{7, 0, 36}, + dictWord{8, 0, 201}, + dictWord{ + 136, + 0, + 605, + }, + dictWord{140, 0, 224}, + dictWord{132, 10, 233}, + dictWord{134, 0, 1430}, + dictWord{134, 0, 1806}, + dictWord{4, 0, 523}, + dictWord{133, 0, 638}, + dictWord{ + 6, + 0, + 1889, + }, + dictWord{9, 0, 958}, + dictWord{9, 0, 971}, + dictWord{9, 0, 976}, + dictWord{12, 0, 796}, + dictWord{12, 0, 799}, + dictWord{12, 0, 808}, + dictWord{ + 12, + 0, + 835, + }, + dictWord{12, 0, 836}, + dictWord{12, 0, 914}, + dictWord{12, 0, 946}, + dictWord{15, 0, 216}, + dictWord{15, 0, 232}, + dictWord{18, 0, 183}, + dictWord{18, 0, 187}, + dictWord{18, 0, 194}, + dictWord{18, 0, 212}, + dictWord{18, 0, 232}, + dictWord{149, 0, 49}, + dictWord{132, 10, 482}, + dictWord{6, 0, 827}, + dictWord{134, 0, 1434}, + dictWord{135, 10, 346}, + dictWord{134, 0, 2043}, + dictWord{6, 0, 242}, + dictWord{7, 0, 227}, + dictWord{7, 0, 1581}, + dictWord{8, 0, 104}, + dictWord{9, 0, 113}, + dictWord{9, 0, 220}, + dictWord{9, 0, 427}, + dictWord{10, 0, 136}, + dictWord{10, 0, 239}, + dictWord{11, 0, 579}, + dictWord{11, 0, 1023}, + dictWord{13, 0, 4}, + dictWord{ + 13, + 0, + 204, + }, + dictWord{13, 0, 316}, + dictWord{148, 0, 86}, + dictWord{134, 11, 1685}, + dictWord{7, 0, 148}, + dictWord{8, 0, 284}, + dictWord{141, 0, 63}, + dictWord{ + 142, + 0, + 10, + }, + dictWord{135, 11, 584}, + dictWord{134, 0, 1249}, + dictWord{7, 0, 861}, + dictWord{135, 10, 334}, + dictWord{5, 10, 795}, + dictWord{6, 10, 1741}, + dictWord{ + 137, + 11, + 70, + }, + dictWord{132, 0, 807}, + dictWord{7, 11, 135}, + dictWord{8, 11, 7}, + dictWord{8, 11, 62}, + dictWord{9, 11, 243}, + dictWord{10, 11, 658}, + dictWord{ + 10, + 11, + 697, + }, + dictWord{11, 11, 456}, + dictWord{139, 11, 756}, + dictWord{9, 11, 395}, + dictWord{138, 11, 79}, + dictWord{137, 11, 108}, + dictWord{147, 0, 94}, + dictWord{136, 0, 494}, + dictWord{135, 11, 631}, + dictWord{135, 10, 622}, + dictWord{7, 0, 1510}, + dictWord{135, 10, 1750}, + dictWord{4, 10, 203}, + dictWord{ + 135, + 10, + 1936, + }, + dictWord{7, 11, 406}, + dictWord{7, 11, 459}, + dictWord{8, 11, 606}, + dictWord{139, 11, 726}, + dictWord{7, 0, 1306}, + dictWord{8, 0, 505}, + dictWord{ + 9, + 0, + 482, + }, + dictWord{10, 0, 126}, + dictWord{11, 0, 225}, + dictWord{12, 0, 347}, + dictWord{12, 0, 449}, + dictWord{13, 0, 19}, + dictWord{14, 0, 218}, + dictWord{142, 0, 435}, + dictWord{5, 0, 268}, + dictWord{10, 0, 764}, + dictWord{12, 0, 120}, + dictWord{13, 0, 39}, + dictWord{145, 0, 127}, + dictWord{142, 11, 68}, + dictWord{11, 10, 678}, + dictWord{140, 10, 307}, + dictWord{12, 11, 268}, + dictWord{12, 11, 640}, + dictWord{142, 11, 119}, + dictWord{135, 10, 2044}, + dictWord{133, 11, 612}, + dictWord{ + 4, + 11, + 372, + }, + dictWord{7, 11, 482}, + dictWord{8, 11, 158}, + dictWord{9, 11, 602}, + dictWord{9, 11, 615}, + dictWord{10, 11, 245}, + dictWord{10, 11, 678}, + dictWord{ + 10, + 11, + 744, + }, + dictWord{11, 11, 248}, + dictWord{139, 11, 806}, + dictWord{7, 10, 311}, + dictWord{9, 10, 308}, + dictWord{140, 10, 255}, + dictWord{4, 0, 384}, + dictWord{135, 0, 1022}, + dictWord{5, 11, 854}, + dictWord{135, 11, 1991}, + dictWord{135, 10, 1266}, + dictWord{4, 10, 400}, + dictWord{5, 10, 267}, + dictWord{ + 135, + 10, + 232, + }, + dictWord{135, 0, 1703}, + dictWord{9, 0, 159}, + dictWord{11, 0, 661}, + dictWord{140, 0, 603}, + dictWord{4, 0, 964}, + dictWord{14, 0, 438}, + dictWord{ + 14, + 0, + 444, + }, + dictWord{14, 0, 456}, + dictWord{22, 0, 60}, + dictWord{22, 0, 63}, + dictWord{9, 11, 106}, + dictWord{9, 11, 163}, + dictWord{9, 11, 296}, + dictWord{10, 11, 167}, + dictWord{10, 11, 172}, + dictWord{10, 11, 777}, + dictWord{139, 11, 16}, + dictWord{136, 0, 583}, + dictWord{132, 0, 515}, + dictWord{8, 0, 632}, + dictWord{8, 0, 697}, + dictWord{137, 0, 854}, + dictWord{5, 11, 195}, + dictWord{135, 11, 1685}, + dictWord{6, 0, 1123}, + dictWord{134, 0, 1365}, + dictWord{134, 11, 328}, + dictWord{ + 7, + 11, + 1997, + }, + dictWord{8, 11, 730}, + dictWord{139, 11, 1006}, + dictWord{4, 0, 136}, + dictWord{133, 0, 551}, + dictWord{134, 0, 1782}, + dictWord{7, 0, 1287}, + dictWord{ + 9, + 0, + 44, + }, + dictWord{10, 0, 552}, + dictWord{10, 0, 642}, + dictWord{11, 0, 839}, + dictWord{12, 0, 274}, + dictWord{12, 0, 275}, + dictWord{12, 0, 372}, + dictWord{ + 13, + 0, + 91, + }, + dictWord{142, 0, 125}, + dictWord{5, 11, 751}, + dictWord{11, 11, 797}, + dictWord{140, 11, 203}, + dictWord{133, 0, 732}, + dictWord{7, 0, 679}, + dictWord{ + 8, + 0, + 313, + }, + dictWord{4, 10, 100}, + dictWord{135, 11, 821}, + dictWord{10, 0, 361}, + dictWord{142, 0, 316}, + dictWord{134, 0, 595}, + dictWord{6, 0, 147}, + dictWord{ + 7, + 0, + 886, + }, + dictWord{9, 0, 753}, + dictWord{138, 0, 268}, + dictWord{5, 10, 362}, + dictWord{5, 10, 443}, + dictWord{6, 10, 318}, + dictWord{7, 10, 1019}, + dictWord{ + 139, + 10, + 623, + }, + dictWord{5, 10, 463}, + dictWord{136, 10, 296}, + dictWord{4, 10, 454}, + dictWord{5, 11, 950}, + dictWord{5, 11, 994}, + dictWord{134, 11, 351}, + dictWord{ + 138, + 0, + 137, + }, + dictWord{5, 10, 48}, + dictWord{5, 10, 404}, + dictWord{6, 10, 557}, + dictWord{7, 10, 458}, + dictWord{8, 10, 597}, + dictWord{10, 10, 455}, + dictWord{ + 10, + 10, + 606, + }, + dictWord{11, 10, 49}, + dictWord{11, 10, 548}, + dictWord{12, 10, 476}, + dictWord{13, 10, 18}, + dictWord{141, 10, 450}, + dictWord{133, 0, 414}, + dictWord{ + 135, + 0, + 1762, + }, + dictWord{5, 11, 421}, + dictWord{135, 11, 47}, + dictWord{5, 10, 442}, + dictWord{135, 10, 1984}, + dictWord{134, 0, 599}, + dictWord{134, 0, 1749}, + dictWord{134, 0, 1627}, + dictWord{4, 0, 488}, + dictWord{132, 11, 350}, + dictWord{137, 11, 751}, + dictWord{132, 0, 83}, + dictWord{140, 0, 676}, + dictWord{ + 133, + 11, + 967, + }, + dictWord{7, 0, 1639}, + dictWord{5, 10, 55}, + dictWord{140, 10, 161}, + dictWord{4, 11, 473}, + dictWord{7, 11, 623}, + dictWord{8, 11, 808}, + dictWord{ + 9, + 11, + 871, + }, + dictWord{9, 11, 893}, + dictWord{11, 11, 38}, + dictWord{11, 11, 431}, + dictWord{12, 11, 112}, + dictWord{12, 11, 217}, + dictWord{12, 11, 243}, + dictWord{ + 12, + 11, + 562, + }, + dictWord{12, 11, 683}, + dictWord{13, 11, 141}, + dictWord{13, 11, 197}, + dictWord{13, 11, 227}, + dictWord{13, 11, 406}, + dictWord{13, 11, 487}, + dictWord{14, 11, 156}, + dictWord{14, 11, 203}, + dictWord{14, 11, 224}, + dictWord{14, 11, 256}, + dictWord{18, 11, 58}, + dictWord{150, 11, 0}, + dictWord{ + 133, + 10, + 450, + }, + dictWord{7, 11, 736}, + dictWord{139, 11, 264}, + dictWord{134, 0, 278}, + dictWord{4, 11, 222}, + dictWord{7, 11, 286}, + dictWord{136, 11, 629}, + dictWord{ + 135, + 10, + 869, + }, + dictWord{140, 0, 97}, + dictWord{144, 0, 14}, + dictWord{134, 0, 1085}, + dictWord{4, 10, 213}, + dictWord{7, 10, 223}, + dictWord{136, 10, 80}, + dictWord{ + 7, + 0, + 388, + }, + dictWord{7, 0, 644}, + dictWord{139, 0, 781}, + dictWord{132, 0, 849}, + dictWord{7, 0, 229}, + dictWord{8, 0, 59}, + dictWord{9, 0, 190}, + dictWord{10, 0, 378}, + dictWord{140, 0, 191}, + dictWord{7, 10, 381}, + dictWord{7, 10, 806}, + dictWord{7, 10, 820}, + dictWord{8, 10, 354}, + dictWord{8, 10, 437}, + dictWord{8, 10, 787}, + dictWord{9, 10, 657}, + dictWord{10, 10, 58}, + dictWord{10, 10, 339}, + dictWord{10, 10, 749}, + dictWord{11, 10, 914}, + dictWord{12, 10, 162}, + dictWord{13, 10, 75}, + dictWord{14, 10, 106}, + dictWord{14, 10, 198}, + dictWord{14, 10, 320}, + dictWord{14, 10, 413}, + dictWord{146, 10, 43}, + dictWord{141, 11, 306}, + dictWord{ + 136, + 10, + 747, + }, + dictWord{134, 0, 1115}, + dictWord{16, 0, 94}, + dictWord{16, 0, 108}, + dictWord{136, 11, 146}, + dictWord{6, 0, 700}, + dictWord{6, 0, 817}, + dictWord{ + 134, + 0, + 1002, + }, + dictWord{133, 10, 692}, + dictWord{4, 11, 465}, + dictWord{135, 11, 1663}, + dictWord{134, 10, 191}, + dictWord{6, 0, 1414}, + dictWord{ + 135, + 11, + 913, + }, + dictWord{132, 0, 660}, + dictWord{7, 0, 1035}, + dictWord{138, 0, 737}, + dictWord{6, 10, 162}, + dictWord{7, 10, 1960}, + dictWord{136, 10, 831}, + dictWord{ + 132, + 10, + 706, + }, + dictWord{7, 0, 690}, + dictWord{9, 0, 217}, + dictWord{9, 0, 587}, + dictWord{140, 0, 521}, + dictWord{138, 10, 426}, + dictWord{135, 10, 1235}, + dictWord{ + 6, + 11, + 82, + }, + dictWord{7, 11, 138}, + dictWord{7, 11, 517}, + dictWord{9, 11, 673}, + dictWord{139, 11, 238}, + dictWord{138, 0, 272}, + dictWord{5, 11, 495}, + dictWord{ + 7, + 11, + 834, + }, + dictWord{9, 11, 733}, + dictWord{139, 11, 378}, + dictWord{134, 0, 1744}, + dictWord{132, 0, 1011}, + dictWord{7, 11, 828}, + dictWord{142, 11, 116}, + dictWord{4, 0, 733}, + dictWord{9, 0, 194}, + dictWord{10, 0, 92}, + dictWord{11, 0, 198}, + dictWord{12, 0, 84}, + dictWord{13, 0, 128}, + dictWord{133, 11, 559}, + dictWord{ + 10, + 0, + 57, + }, + dictWord{10, 0, 277}, + dictWord{6, 11, 21}, + dictWord{6, 11, 1737}, + dictWord{7, 11, 1444}, + dictWord{136, 11, 224}, + dictWord{4, 10, 204}, + dictWord{ + 137, + 10, + 902, + }, + dictWord{136, 10, 833}, + dictWord{11, 0, 348}, + dictWord{12, 0, 99}, + dictWord{18, 0, 1}, + dictWord{18, 0, 11}, + dictWord{19, 0, 4}, + dictWord{7, 10, 366}, + dictWord{9, 10, 287}, + dictWord{12, 10, 199}, + dictWord{12, 10, 556}, + dictWord{140, 10, 577}, + dictWord{6, 0, 1981}, + dictWord{136, 0, 936}, + dictWord{ + 21, + 0, + 33, + }, + dictWord{150, 0, 40}, + dictWord{5, 11, 519}, + dictWord{138, 11, 204}, + dictWord{5, 10, 356}, + dictWord{135, 10, 224}, + dictWord{134, 0, 775}, + dictWord{ + 135, + 0, + 306, + }, + dictWord{7, 10, 630}, + dictWord{9, 10, 567}, + dictWord{11, 10, 150}, + dictWord{11, 10, 444}, + dictWord{141, 10, 119}, + dictWord{5, 0, 979}, + dictWord{ + 134, + 10, + 539, + }, + dictWord{133, 0, 611}, + dictWord{4, 11, 402}, + dictWord{135, 11, 1679}, + dictWord{5, 0, 178}, + dictWord{7, 11, 2}, + dictWord{8, 11, 323}, + dictWord{ + 136, + 11, + 479, + }, + dictWord{5, 11, 59}, + dictWord{135, 11, 672}, + dictWord{4, 0, 1010}, + dictWord{6, 0, 1969}, + dictWord{138, 11, 237}, + dictWord{133, 11, 412}, + dictWord{146, 11, 34}, + dictWord{7, 11, 1740}, + dictWord{146, 11, 48}, + dictWord{134, 0, 664}, + dictWord{139, 10, 814}, + dictWord{4, 11, 85}, + dictWord{ + 135, + 11, + 549, + }, + dictWord{133, 11, 94}, + dictWord{133, 11, 457}, + dictWord{132, 0, 390}, + dictWord{134, 0, 1510}, + dictWord{4, 10, 235}, + dictWord{135, 10, 255}, + dictWord{4, 10, 194}, + dictWord{5, 10, 584}, + dictWord{6, 11, 11}, + dictWord{6, 10, 384}, + dictWord{7, 11, 187}, + dictWord{7, 10, 583}, + dictWord{10, 10, 761}, + dictWord{ + 11, + 10, + 760, + }, + dictWord{139, 10, 851}, + dictWord{4, 11, 522}, + dictWord{139, 11, 802}, + dictWord{135, 0, 493}, + dictWord{10, 11, 776}, + dictWord{13, 11, 345}, + dictWord{142, 11, 425}, + dictWord{146, 0, 37}, + dictWord{4, 11, 52}, + dictWord{135, 11, 661}, + dictWord{134, 0, 724}, + dictWord{134, 0, 829}, + dictWord{ + 133, + 11, + 520, + }, + dictWord{133, 10, 562}, + dictWord{4, 11, 281}, + dictWord{5, 11, 38}, + dictWord{7, 11, 194}, + dictWord{7, 11, 668}, + dictWord{7, 11, 1893}, + dictWord{ + 137, + 11, + 397, + }, + dictWord{5, 10, 191}, + dictWord{137, 10, 271}, + dictWord{7, 0, 1537}, + dictWord{14, 0, 96}, + dictWord{143, 0, 73}, + dictWord{5, 0, 473}, + dictWord{ + 11, + 0, + 168, + }, + dictWord{4, 10, 470}, + dictWord{6, 10, 153}, + dictWord{7, 10, 1503}, + dictWord{7, 10, 1923}, + dictWord{10, 10, 701}, + dictWord{11, 10, 132}, + dictWord{ + 11, + 10, + 227, + }, + dictWord{11, 10, 320}, + dictWord{11, 10, 436}, + dictWord{11, 10, 525}, + dictWord{11, 10, 855}, + dictWord{12, 10, 41}, + dictWord{12, 10, 286}, + dictWord{13, 10, 103}, + dictWord{13, 10, 284}, + dictWord{14, 10, 255}, + dictWord{14, 10, 262}, + dictWord{15, 10, 117}, + dictWord{143, 10, 127}, + dictWord{ + 133, + 0, + 105, + }, + dictWord{5, 0, 438}, + dictWord{9, 0, 694}, + dictWord{12, 0, 627}, + dictWord{141, 0, 210}, + dictWord{133, 10, 327}, + dictWord{6, 10, 552}, + dictWord{ + 7, + 10, + 1754, + }, + dictWord{137, 10, 604}, + dictWord{134, 0, 1256}, + dictWord{152, 0, 11}, + dictWord{5, 11, 448}, + dictWord{11, 11, 98}, + dictWord{139, 11, 524}, + dictWord{ + 7, + 0, + 1626, + }, + dictWord{5, 10, 80}, + dictWord{6, 10, 405}, + dictWord{7, 10, 403}, + dictWord{7, 10, 1502}, + dictWord{8, 10, 456}, + dictWord{9, 10, 487}, + dictWord{ + 9, + 10, + 853, + }, + dictWord{9, 10, 889}, + dictWord{10, 10, 309}, + dictWord{11, 10, 721}, + dictWord{11, 10, 994}, + dictWord{12, 10, 430}, + dictWord{13, 10, 165}, + dictWord{ + 14, + 11, + 16, + }, + dictWord{146, 11, 44}, + dictWord{132, 0, 779}, + dictWord{8, 0, 25}, + dictWord{138, 0, 826}, + dictWord{4, 10, 453}, + dictWord{5, 10, 887}, + dictWord{ + 6, + 10, + 535, + }, + dictWord{8, 10, 6}, + dictWord{8, 10, 543}, + dictWord{136, 10, 826}, + dictWord{137, 11, 461}, + dictWord{140, 11, 632}, + dictWord{132, 0, 308}, + dictWord{135, 0, 741}, + dictWord{132, 0, 671}, + dictWord{7, 0, 150}, + dictWord{8, 0, 649}, + dictWord{136, 0, 1020}, + dictWord{9, 0, 99}, + dictWord{6, 11, 336}, + dictWord{ + 8, + 11, + 552, + }, + dictWord{9, 11, 285}, + dictWord{10, 11, 99}, + dictWord{139, 11, 568}, + dictWord{134, 0, 521}, + dictWord{5, 0, 339}, + dictWord{14, 0, 3}, + dictWord{ + 15, + 0, + 41, + }, + dictWord{15, 0, 166}, + dictWord{147, 0, 66}, + dictWord{6, 11, 423}, + dictWord{7, 11, 665}, + dictWord{7, 11, 1210}, + dictWord{9, 11, 218}, + dictWord{ + 141, + 11, + 222, + }, + dictWord{6, 0, 543}, + dictWord{5, 10, 101}, + dictWord{5, 11, 256}, + dictWord{6, 10, 88}, + dictWord{7, 10, 1677}, + dictWord{9, 10, 100}, + dictWord{10, 10, 677}, + dictWord{14, 10, 169}, + dictWord{14, 10, 302}, + dictWord{14, 10, 313}, + dictWord{15, 10, 48}, + dictWord{143, 10, 84}, + dictWord{4, 10, 310}, + dictWord{ + 7, + 10, + 708, + }, + dictWord{7, 10, 996}, + dictWord{9, 10, 795}, + dictWord{10, 10, 390}, + dictWord{10, 10, 733}, + dictWord{11, 10, 451}, + dictWord{12, 10, 249}, + dictWord{ + 14, + 10, + 115, + }, + dictWord{14, 10, 286}, + dictWord{143, 10, 100}, + dictWord{133, 10, 587}, + dictWord{13, 11, 417}, + dictWord{14, 11, 129}, + dictWord{143, 11, 15}, + dictWord{134, 0, 1358}, + dictWord{136, 11, 554}, + dictWord{132, 10, 498}, + dictWord{7, 10, 217}, + dictWord{8, 10, 140}, + dictWord{138, 10, 610}, + dictWord{ + 135, + 11, + 989, + }, + dictWord{135, 11, 634}, + dictWord{6, 0, 155}, + dictWord{140, 0, 234}, + dictWord{135, 11, 462}, + dictWord{132, 11, 618}, + dictWord{ + 134, + 0, + 1628, + }, + dictWord{132, 0, 766}, + dictWord{4, 11, 339}, + dictWord{5, 10, 905}, + dictWord{135, 11, 259}, + dictWord{135, 0, 829}, + dictWord{4, 11, 759}, + dictWord{ + 141, + 11, + 169, + }, + dictWord{7, 0, 1445}, + dictWord{4, 10, 456}, + dictWord{7, 10, 358}, + dictWord{7, 10, 1637}, + dictWord{8, 10, 643}, + dictWord{139, 10, 483}, + dictWord{ + 5, + 0, + 486, + }, + dictWord{135, 0, 1349}, + dictWord{5, 11, 688}, + dictWord{135, 11, 712}, + dictWord{7, 0, 1635}, + dictWord{8, 0, 17}, + dictWord{10, 0, 217}, + dictWord{ + 10, + 0, + 295, + }, + dictWord{12, 0, 2}, + dictWord{140, 11, 2}, + dictWord{138, 0, 558}, + dictWord{150, 10, 56}, + dictWord{4, 11, 278}, + dictWord{5, 11, 465}, + dictWord{ + 135, + 11, + 1367, + }, + dictWord{136, 11, 482}, + dictWord{133, 10, 535}, + dictWord{6, 0, 1362}, + dictWord{6, 0, 1461}, + dictWord{10, 11, 274}, + dictWord{10, 11, 625}, + dictWord{139, 11, 530}, + dictWord{5, 0, 599}, + dictWord{5, 11, 336}, + dictWord{6, 11, 341}, + dictWord{6, 11, 478}, + dictWord{6, 11, 1763}, + dictWord{136, 11, 386}, + dictWord{7, 10, 1748}, + dictWord{137, 11, 151}, + dictWord{134, 0, 1376}, + dictWord{133, 10, 539}, + dictWord{135, 11, 73}, + dictWord{135, 11, 1971}, + dictWord{139, 11, 283}, + dictWord{9, 0, 93}, + dictWord{139, 0, 474}, + dictWord{6, 10, 91}, + dictWord{135, 10, 435}, + dictWord{6, 0, 447}, + dictWord{5, 11, 396}, + dictWord{134, 11, 501}, + dictWord{4, 10, 16}, + dictWord{5, 10, 316}, + dictWord{5, 10, 842}, + dictWord{6, 10, 370}, + dictWord{6, 10, 1778}, + dictWord{8, 10, 166}, + dictWord{11, 10, 812}, + dictWord{12, 10, 206}, + dictWord{12, 10, 351}, + dictWord{14, 10, 418}, + dictWord{16, 10, 15}, + dictWord{16, 10, 34}, + dictWord{18, 10, 3}, + dictWord{19, 10, 3}, + dictWord{19, 10, 7}, + dictWord{20, 10, 4}, + dictWord{149, 10, 21}, + dictWord{7, 0, 577}, + dictWord{7, 0, 1432}, + dictWord{9, 0, 475}, + dictWord{9, 0, 505}, + dictWord{9, 0, 526}, + dictWord{9, 0, 609}, + dictWord{9, 0, 689}, + dictWord{9, 0, 726}, + dictWord{9, 0, 735}, + dictWord{9, 0, 738}, + dictWord{10, 0, 556}, + dictWord{ + 10, + 0, + 674, + }, + dictWord{10, 0, 684}, + dictWord{11, 0, 89}, + dictWord{11, 0, 202}, + dictWord{11, 0, 272}, + dictWord{11, 0, 380}, + dictWord{11, 0, 415}, + dictWord{11, 0, 505}, + dictWord{11, 0, 537}, + dictWord{11, 0, 550}, + dictWord{11, 0, 562}, + dictWord{11, 0, 640}, + dictWord{11, 0, 667}, + dictWord{11, 0, 688}, + dictWord{11, 0, 847}, + dictWord{11, 0, 927}, + dictWord{11, 0, 930}, + dictWord{11, 0, 940}, + dictWord{12, 0, 144}, + dictWord{12, 0, 325}, + dictWord{12, 0, 329}, + dictWord{12, 0, 389}, + dictWord{ + 12, + 0, + 403, + }, + dictWord{12, 0, 451}, + dictWord{12, 0, 515}, + dictWord{12, 0, 604}, + dictWord{12, 0, 616}, + dictWord{12, 0, 626}, + dictWord{13, 0, 66}, + dictWord{ + 13, + 0, + 131, + }, + dictWord{13, 0, 167}, + dictWord{13, 0, 236}, + dictWord{13, 0, 368}, + dictWord{13, 0, 411}, + dictWord{13, 0, 434}, + dictWord{13, 0, 453}, + dictWord{13, 0, 461}, + dictWord{13, 0, 474}, + dictWord{14, 0, 59}, + dictWord{14, 0, 60}, + dictWord{14, 0, 139}, + dictWord{14, 0, 152}, + dictWord{14, 0, 276}, + dictWord{14, 0, 353}, + dictWord{ + 14, + 0, + 402, + }, + dictWord{15, 0, 28}, + dictWord{15, 0, 81}, + dictWord{15, 0, 123}, + dictWord{15, 0, 152}, + dictWord{18, 0, 136}, + dictWord{148, 0, 88}, + dictWord{ + 4, + 11, + 929, + }, + dictWord{133, 11, 799}, + dictWord{136, 11, 46}, + dictWord{142, 0, 307}, + dictWord{4, 0, 609}, + dictWord{7, 0, 756}, + dictWord{9, 0, 544}, + dictWord{ + 11, + 0, + 413, + }, + dictWord{144, 0, 25}, + dictWord{10, 0, 687}, + dictWord{7, 10, 619}, + dictWord{10, 10, 547}, + dictWord{11, 10, 122}, + dictWord{140, 10, 601}, + dictWord{ + 4, + 0, + 930, + }, + dictWord{133, 0, 947}, + dictWord{133, 0, 939}, + dictWord{142, 0, 21}, + dictWord{4, 11, 892}, + dictWord{133, 11, 770}, + dictWord{133, 0, 962}, + dictWord{ + 5, + 0, + 651, + }, + dictWord{8, 0, 170}, + dictWord{9, 0, 61}, + dictWord{9, 0, 63}, + dictWord{10, 0, 23}, + dictWord{10, 0, 37}, + dictWord{10, 0, 834}, + dictWord{11, 0, 4}, + dictWord{ + 11, + 0, + 187, + }, + dictWord{11, 0, 281}, + dictWord{11, 0, 503}, + dictWord{11, 0, 677}, + dictWord{12, 0, 96}, + dictWord{12, 0, 130}, + dictWord{12, 0, 244}, + dictWord{14, 0, 5}, + dictWord{14, 0, 40}, + dictWord{14, 0, 162}, + dictWord{14, 0, 202}, + dictWord{146, 0, 133}, + dictWord{4, 0, 406}, + dictWord{5, 0, 579}, + dictWord{12, 0, 492}, + dictWord{ + 150, + 0, + 15, + }, + dictWord{135, 11, 158}, + dictWord{135, 0, 597}, + dictWord{132, 0, 981}, + dictWord{132, 10, 888}, + dictWord{4, 10, 149}, + dictWord{138, 10, 368}, + dictWord{132, 0, 545}, + dictWord{4, 10, 154}, + dictWord{7, 10, 1134}, + dictWord{136, 10, 105}, + dictWord{135, 11, 2001}, + dictWord{134, 0, 1558}, + dictWord{ + 4, + 10, + 31, + }, + dictWord{6, 10, 429}, + dictWord{7, 10, 962}, + dictWord{9, 10, 458}, + dictWord{139, 10, 691}, + dictWord{132, 10, 312}, + dictWord{135, 10, 1642}, + dictWord{ + 6, + 0, + 17, + }, + dictWord{6, 0, 1304}, + dictWord{7, 0, 16}, + dictWord{7, 0, 1001}, + dictWord{9, 0, 886}, + dictWord{10, 0, 489}, + dictWord{10, 0, 800}, + dictWord{11, 0, 782}, + dictWord{12, 0, 320}, + dictWord{13, 0, 467}, + dictWord{14, 0, 145}, + dictWord{14, 0, 387}, + dictWord{143, 0, 119}, + dictWord{135, 0, 1982}, + dictWord{17, 0, 17}, + dictWord{7, 11, 1461}, + dictWord{140, 11, 91}, + dictWord{4, 10, 236}, + dictWord{132, 11, 602}, + dictWord{138, 0, 907}, + dictWord{136, 0, 110}, + dictWord{7, 0, 272}, + dictWord{19, 0, 53}, + dictWord{5, 10, 836}, + dictWord{5, 10, 857}, + dictWord{134, 10, 1680}, + dictWord{5, 0, 458}, + dictWord{7, 11, 1218}, + dictWord{136, 11, 303}, + dictWord{7, 0, 1983}, + dictWord{8, 0, 0}, + dictWord{8, 0, 171}, + dictWord{9, 0, 120}, + dictWord{9, 0, 732}, + dictWord{10, 0, 473}, + dictWord{11, 0, 656}, + dictWord{ + 11, + 0, + 998, + }, + dictWord{18, 0, 0}, + dictWord{18, 0, 2}, + dictWord{19, 0, 21}, + dictWord{10, 10, 68}, + dictWord{139, 10, 494}, + dictWord{137, 11, 662}, + dictWord{4, 11, 13}, + dictWord{5, 11, 567}, + dictWord{7, 11, 1498}, + dictWord{9, 11, 124}, + dictWord{11, 11, 521}, + dictWord{140, 11, 405}, + dictWord{4, 10, 81}, + dictWord{139, 10, 867}, + dictWord{135, 11, 1006}, + dictWord{7, 11, 800}, + dictWord{7, 11, 1783}, + dictWord{138, 11, 12}, + dictWord{9, 0, 295}, + dictWord{10, 0, 443}, + dictWord{ + 5, + 10, + 282, + }, + dictWord{8, 10, 650}, + dictWord{137, 10, 907}, + dictWord{132, 11, 735}, + dictWord{4, 11, 170}, + dictWord{4, 10, 775}, + dictWord{135, 11, 323}, + dictWord{ + 6, + 0, + 1844, + }, + dictWord{10, 0, 924}, + dictWord{11, 11, 844}, + dictWord{12, 11, 104}, + dictWord{140, 11, 625}, + dictWord{5, 11, 304}, + dictWord{7, 11, 1403}, + dictWord{140, 11, 498}, + dictWord{134, 0, 1232}, + dictWord{4, 0, 519}, + dictWord{10, 0, 70}, + dictWord{12, 0, 26}, + dictWord{14, 0, 17}, + dictWord{14, 0, 178}, + dictWord{ + 15, + 0, + 34, + }, + dictWord{149, 0, 12}, + dictWord{132, 0, 993}, + dictWord{4, 11, 148}, + dictWord{133, 11, 742}, + dictWord{6, 0, 31}, + dictWord{7, 0, 491}, + dictWord{7, 0, 530}, + dictWord{8, 0, 592}, + dictWord{11, 0, 53}, + dictWord{11, 0, 779}, + dictWord{12, 0, 167}, + dictWord{12, 0, 411}, + dictWord{14, 0, 14}, + dictWord{14, 0, 136}, + dictWord{ + 15, + 0, + 72, + }, + dictWord{16, 0, 17}, + dictWord{144, 0, 72}, + dictWord{133, 0, 907}, + dictWord{134, 0, 733}, + dictWord{133, 11, 111}, + dictWord{4, 10, 71}, + dictWord{ + 5, + 10, + 376, + }, + dictWord{7, 10, 119}, + dictWord{138, 10, 665}, + dictWord{136, 0, 55}, + dictWord{8, 0, 430}, + dictWord{136, 11, 430}, + dictWord{4, 0, 208}, + dictWord{ + 5, + 0, + 106, + }, + dictWord{6, 0, 531}, + dictWord{8, 0, 408}, + dictWord{9, 0, 188}, + dictWord{138, 0, 572}, + dictWord{12, 0, 56}, + dictWord{11, 10, 827}, + dictWord{14, 10, 34}, + dictWord{143, 10, 148}, + dictWord{134, 0, 1693}, + dictWord{133, 11, 444}, + dictWord{132, 10, 479}, + dictWord{140, 0, 441}, + dictWord{9, 0, 449}, + dictWord{ + 10, + 0, + 192, + }, + dictWord{138, 0, 740}, + dictWord{134, 0, 928}, + dictWord{4, 0, 241}, + dictWord{7, 10, 607}, + dictWord{136, 10, 99}, + dictWord{8, 11, 123}, + dictWord{ + 15, + 11, + 6, + }, + dictWord{144, 11, 7}, + dictWord{6, 11, 285}, + dictWord{8, 11, 654}, + dictWord{11, 11, 749}, + dictWord{12, 11, 190}, + dictWord{12, 11, 327}, + dictWord{ + 13, + 11, + 120, + }, + dictWord{13, 11, 121}, + dictWord{13, 11, 327}, + dictWord{15, 11, 47}, + dictWord{146, 11, 40}, + dictWord{4, 10, 41}, + dictWord{5, 10, 74}, + dictWord{ + 7, + 10, + 1627, + }, + dictWord{11, 10, 871}, + dictWord{140, 10, 619}, + dictWord{7, 0, 1525}, + dictWord{11, 10, 329}, + dictWord{11, 10, 965}, + dictWord{12, 10, 241}, + dictWord{14, 10, 354}, + dictWord{15, 10, 22}, + dictWord{148, 10, 63}, + dictWord{132, 0, 259}, + dictWord{135, 11, 183}, + dictWord{9, 10, 209}, + dictWord{ + 137, + 10, + 300, + }, + dictWord{5, 11, 937}, + dictWord{135, 11, 100}, + dictWord{133, 10, 98}, + dictWord{4, 0, 173}, + dictWord{5, 0, 312}, + dictWord{5, 0, 512}, + dictWord{ + 135, + 0, + 1285, + }, + dictWord{141, 0, 185}, + dictWord{7, 0, 1603}, + dictWord{7, 0, 1691}, + dictWord{9, 0, 464}, + dictWord{11, 0, 195}, + dictWord{12, 0, 279}, + dictWord{ + 12, + 0, + 448, + }, + dictWord{14, 0, 11}, + dictWord{147, 0, 102}, + dictWord{135, 0, 1113}, + dictWord{133, 10, 984}, + dictWord{4, 0, 452}, + dictWord{5, 0, 583}, + dictWord{ + 135, + 0, + 720, + }, + dictWord{4, 0, 547}, + dictWord{5, 0, 817}, + dictWord{6, 0, 433}, + dictWord{7, 0, 593}, + dictWord{7, 0, 1378}, + dictWord{8, 0, 161}, + dictWord{9, 0, 284}, + dictWord{ + 10, + 0, + 313, + }, + dictWord{139, 0, 886}, + dictWord{8, 0, 722}, + dictWord{4, 10, 182}, + dictWord{6, 10, 205}, + dictWord{135, 10, 220}, + dictWord{150, 0, 13}, + dictWord{ + 4, + 10, + 42, + }, + dictWord{9, 10, 205}, + dictWord{9, 10, 786}, + dictWord{138, 10, 659}, + dictWord{6, 0, 289}, + dictWord{7, 0, 1670}, + dictWord{12, 0, 57}, + dictWord{151, 0, 4}, + dictWord{132, 10, 635}, + dictWord{14, 0, 43}, + dictWord{146, 0, 21}, + dictWord{139, 10, 533}, + dictWord{135, 0, 1694}, + dictWord{8, 0, 420}, + dictWord{ + 139, + 0, + 193, + }, + dictWord{135, 0, 409}, + dictWord{132, 10, 371}, + dictWord{4, 10, 272}, + dictWord{135, 10, 836}, + dictWord{5, 10, 825}, + dictWord{134, 10, 1640}, + dictWord{5, 11, 251}, + dictWord{5, 11, 956}, + dictWord{8, 11, 268}, + dictWord{9, 11, 214}, + dictWord{146, 11, 142}, + dictWord{138, 0, 308}, + dictWord{6, 0, 1863}, + dictWord{141, 11, 37}, + dictWord{137, 10, 879}, + dictWord{7, 10, 317}, + dictWord{135, 10, 569}, + dictWord{132, 11, 294}, + dictWord{134, 0, 790}, + dictWord{ + 5, + 0, + 1002, + }, + dictWord{136, 0, 745}, + dictWord{5, 11, 346}, + dictWord{5, 11, 711}, + dictWord{136, 11, 390}, + dictWord{135, 0, 289}, + dictWord{5, 0, 504}, + dictWord{ + 11, + 0, + 68, + }, + dictWord{137, 10, 307}, + dictWord{4, 0, 239}, + dictWord{6, 0, 477}, + dictWord{7, 0, 1607}, + dictWord{139, 0, 617}, + dictWord{149, 0, 13}, + dictWord{ + 133, + 0, + 609, + }, + dictWord{133, 11, 624}, + dictWord{5, 11, 783}, + dictWord{7, 11, 1998}, + dictWord{135, 11, 2047}, + dictWord{133, 10, 525}, + dictWord{132, 0, 367}, + dictWord{132, 11, 594}, + dictWord{6, 0, 528}, + dictWord{133, 10, 493}, + dictWord{4, 10, 174}, + dictWord{135, 10, 911}, + dictWord{8, 10, 417}, + dictWord{ + 137, + 10, + 782, + }, + dictWord{132, 0, 694}, + dictWord{7, 0, 548}, + dictWord{137, 0, 58}, + dictWord{4, 10, 32}, + dictWord{5, 10, 215}, + dictWord{6, 10, 269}, + dictWord{7, 10, 1782}, + dictWord{7, 10, 1892}, + dictWord{10, 10, 16}, + dictWord{11, 10, 822}, + dictWord{11, 10, 954}, + dictWord{141, 10, 481}, + dictWord{140, 0, 687}, + dictWord{ + 7, + 0, + 1749, + }, + dictWord{136, 10, 477}, + dictWord{132, 11, 569}, + dictWord{133, 10, 308}, + dictWord{135, 10, 1088}, + dictWord{4, 0, 661}, + dictWord{138, 0, 1004}, + dictWord{5, 11, 37}, + dictWord{6, 11, 39}, + dictWord{6, 11, 451}, + dictWord{7, 11, 218}, + dictWord{7, 11, 667}, + dictWord{7, 11, 1166}, + dictWord{7, 11, 1687}, + dictWord{8, 11, 662}, + dictWord{144, 11, 2}, + dictWord{9, 0, 445}, + dictWord{12, 0, 53}, + dictWord{13, 0, 492}, + dictWord{5, 10, 126}, + dictWord{8, 10, 297}, + dictWord{ + 9, + 10, + 366, + }, + dictWord{140, 10, 374}, + dictWord{7, 10, 1551}, + dictWord{139, 10, 361}, + dictWord{148, 0, 74}, + dictWord{134, 11, 508}, + dictWord{135, 0, 213}, + dictWord{132, 10, 175}, + dictWord{132, 10, 685}, + dictWord{6, 0, 760}, + dictWord{6, 0, 834}, + dictWord{134, 0, 1248}, + dictWord{7, 11, 453}, + dictWord{7, 11, 635}, + dictWord{7, 11, 796}, + dictWord{8, 11, 331}, + dictWord{9, 11, 328}, + dictWord{9, 11, 330}, + dictWord{9, 11, 865}, + dictWord{10, 11, 119}, + dictWord{10, 11, 235}, + dictWord{11, 11, 111}, + dictWord{11, 11, 129}, + dictWord{11, 11, 240}, + dictWord{12, 11, 31}, + dictWord{12, 11, 66}, + dictWord{12, 11, 222}, + dictWord{12, 11, 269}, + dictWord{12, 11, 599}, + dictWord{12, 11, 689}, + dictWord{13, 11, 186}, + dictWord{13, 11, 364}, + dictWord{142, 11, 345}, + dictWord{7, 0, 1672}, + dictWord{ + 139, + 0, + 189, + }, + dictWord{133, 10, 797}, + dictWord{133, 10, 565}, + dictWord{6, 0, 1548}, + dictWord{6, 11, 98}, + dictWord{7, 11, 585}, + dictWord{135, 11, 702}, + dictWord{ + 9, + 0, + 968, + }, + dictWord{15, 0, 192}, + dictWord{149, 0, 56}, + dictWord{4, 10, 252}, + dictWord{6, 11, 37}, + dictWord{7, 11, 299}, + dictWord{7, 10, 1068}, + dictWord{ + 7, + 11, + 1666, + }, + dictWord{8, 11, 195}, + dictWord{8, 11, 316}, + dictWord{9, 11, 178}, + dictWord{9, 11, 276}, + dictWord{9, 11, 339}, + dictWord{9, 11, 536}, + dictWord{ + 10, + 11, + 102, + }, + dictWord{10, 11, 362}, + dictWord{10, 10, 434}, + dictWord{10, 11, 785}, + dictWord{11, 11, 55}, + dictWord{11, 11, 149}, + dictWord{11, 10, 228}, + dictWord{ + 11, + 10, + 426, + }, + dictWord{11, 11, 773}, + dictWord{13, 10, 231}, + dictWord{13, 11, 416}, + dictWord{13, 11, 419}, + dictWord{14, 11, 38}, + dictWord{14, 11, 41}, + dictWord{14, 11, 210}, + dictWord{18, 10, 106}, + dictWord{148, 10, 87}, + dictWord{4, 0, 751}, + dictWord{11, 0, 390}, + dictWord{140, 0, 32}, + dictWord{4, 0, 409}, + dictWord{133, 0, 78}, + dictWord{11, 11, 458}, + dictWord{12, 11, 15}, + dictWord{140, 11, 432}, + dictWord{7, 0, 1602}, + dictWord{10, 0, 257}, + dictWord{10, 0, 698}, + dictWord{11, 0, 544}, + dictWord{11, 0, 585}, + dictWord{12, 0, 212}, + dictWord{13, 0, 307}, + dictWord{5, 10, 231}, + dictWord{7, 10, 601}, + dictWord{9, 10, 277}, + dictWord{ + 9, + 10, + 674, + }, + dictWord{10, 10, 178}, + dictWord{10, 10, 418}, + dictWord{10, 10, 509}, + dictWord{11, 10, 531}, + dictWord{12, 10, 113}, + dictWord{12, 10, 475}, + dictWord{13, 10, 99}, + dictWord{142, 10, 428}, + dictWord{6, 0, 473}, + dictWord{145, 0, 105}, + dictWord{6, 0, 1949}, + dictWord{15, 0, 156}, + dictWord{133, 11, 645}, + dictWord{7, 10, 1591}, + dictWord{144, 10, 43}, + dictWord{135, 0, 1779}, + dictWord{135, 10, 1683}, + dictWord{4, 11, 290}, + dictWord{135, 11, 1356}, + dictWord{134, 0, 763}, + dictWord{6, 11, 70}, + dictWord{7, 11, 1292}, + dictWord{10, 11, 762}, + dictWord{139, 11, 288}, + dictWord{142, 0, 29}, + dictWord{140, 11, 428}, + dictWord{7, 0, 883}, + dictWord{7, 11, 131}, + dictWord{7, 11, 422}, + dictWord{8, 11, 210}, + dictWord{140, 11, 573}, + dictWord{134, 0, 488}, + dictWord{4, 10, 399}, + dictWord{5, 10, 119}, + dictWord{5, 10, 494}, + dictWord{7, 10, 751}, + dictWord{137, 10, 556}, + dictWord{133, 0, 617}, + dictWord{132, 11, 936}, + dictWord{ + 139, + 0, + 50, + }, + dictWord{7, 0, 1518}, + dictWord{139, 0, 694}, + dictWord{137, 0, 785}, + dictWord{4, 0, 546}, + dictWord{135, 0, 2042}, + dictWord{7, 11, 716}, + dictWord{ + 13, + 11, + 97, + }, + dictWord{141, 11, 251}, + dictWord{132, 11, 653}, + dictWord{145, 0, 22}, + dictWord{134, 0, 1016}, + dictWord{4, 0, 313}, + dictWord{133, 0, 577}, + dictWord{ + 136, + 11, + 657, + }, + dictWord{8, 0, 184}, + dictWord{141, 0, 433}, + dictWord{135, 0, 935}, + dictWord{6, 0, 720}, + dictWord{9, 0, 114}, + dictWord{146, 11, 80}, + dictWord{ + 12, + 0, + 186, + }, + dictWord{12, 0, 292}, + dictWord{14, 0, 100}, + dictWord{18, 0, 70}, + dictWord{7, 10, 594}, + dictWord{7, 10, 851}, + dictWord{7, 10, 1858}, + dictWord{ + 9, + 10, + 411, + }, + dictWord{9, 10, 574}, + dictWord{9, 10, 666}, + dictWord{9, 10, 737}, + dictWord{10, 10, 346}, + dictWord{10, 10, 712}, + dictWord{11, 10, 246}, + dictWord{ + 11, + 10, + 432, + }, + dictWord{11, 10, 517}, + dictWord{11, 10, 647}, + dictWord{11, 10, 679}, + dictWord{11, 10, 727}, + dictWord{12, 10, 304}, + dictWord{12, 10, 305}, + dictWord{12, 10, 323}, + dictWord{12, 10, 483}, + dictWord{12, 10, 572}, + dictWord{12, 10, 593}, + dictWord{12, 10, 602}, + dictWord{13, 10, 95}, + dictWord{13, 10, 101}, + dictWord{13, 10, 171}, + dictWord{13, 10, 315}, + dictWord{13, 10, 378}, + dictWord{13, 10, 425}, + dictWord{13, 10, 475}, + dictWord{14, 10, 63}, + dictWord{ + 14, + 10, + 380, + }, + dictWord{14, 10, 384}, + dictWord{15, 10, 133}, + dictWord{18, 10, 112}, + dictWord{148, 10, 72}, + dictWord{135, 10, 1093}, + dictWord{135, 11, 1836}, + dictWord{132, 10, 679}, + dictWord{137, 10, 203}, + dictWord{11, 0, 402}, + dictWord{12, 0, 109}, + dictWord{12, 0, 431}, + dictWord{13, 0, 179}, + dictWord{13, 0, 206}, + dictWord{14, 0, 217}, + dictWord{16, 0, 3}, + dictWord{148, 0, 53}, + dictWord{7, 11, 1368}, + dictWord{8, 11, 232}, + dictWord{8, 11, 361}, + dictWord{10, 11, 682}, + dictWord{138, 11, 742}, + dictWord{137, 10, 714}, + dictWord{5, 0, 886}, + dictWord{6, 0, 46}, + dictWord{6, 0, 1790}, + dictWord{7, 0, 14}, + dictWord{7, 0, 732}, + dictWord{ + 7, + 0, + 1654, + }, + dictWord{8, 0, 95}, + dictWord{8, 0, 327}, + dictWord{8, 0, 616}, + dictWord{9, 0, 892}, + dictWord{10, 0, 598}, + dictWord{10, 0, 769}, + dictWord{11, 0, 134}, + dictWord{11, 0, 747}, + dictWord{12, 0, 378}, + dictWord{14, 0, 97}, + dictWord{137, 11, 534}, + dictWord{4, 0, 969}, + dictWord{136, 10, 825}, + dictWord{137, 11, 27}, + dictWord{6, 0, 727}, + dictWord{142, 11, 12}, + dictWord{133, 0, 1021}, + dictWord{134, 0, 1190}, + dictWord{134, 11, 1657}, + dictWord{5, 10, 143}, + dictWord{ + 5, + 10, + 769, + }, + dictWord{6, 10, 1760}, + dictWord{7, 10, 682}, + dictWord{7, 10, 1992}, + dictWord{136, 10, 736}, + dictWord{132, 0, 153}, + dictWord{135, 11, 127}, + dictWord{133, 0, 798}, + dictWord{132, 0, 587}, + dictWord{6, 0, 598}, + dictWord{7, 0, 42}, + dictWord{8, 0, 695}, + dictWord{10, 0, 212}, + dictWord{11, 0, 158}, + dictWord{ + 14, + 0, + 196, + }, + dictWord{145, 0, 85}, + dictWord{133, 10, 860}, + dictWord{6, 0, 1929}, + dictWord{134, 0, 1933}, + dictWord{5, 0, 957}, + dictWord{5, 0, 1008}, + dictWord{ + 9, + 0, + 577, + }, + dictWord{12, 0, 141}, + dictWord{6, 10, 422}, + dictWord{7, 10, 0}, + dictWord{7, 10, 1544}, + dictWord{8, 11, 364}, + dictWord{11, 10, 990}, + dictWord{ + 12, + 10, + 453, + }, + dictWord{13, 10, 47}, + dictWord{141, 10, 266}, + dictWord{134, 0, 1319}, + dictWord{4, 0, 129}, + dictWord{135, 0, 465}, + dictWord{7, 0, 470}, + dictWord{ + 7, + 0, + 1057, + }, + dictWord{7, 0, 1201}, + dictWord{9, 0, 755}, + dictWord{11, 0, 906}, + dictWord{140, 0, 527}, + dictWord{7, 0, 908}, + dictWord{146, 0, 7}, + dictWord{5, 0, 148}, + dictWord{136, 0, 450}, + dictWord{5, 10, 515}, + dictWord{137, 10, 131}, + dictWord{7, 10, 1605}, + dictWord{11, 10, 962}, + dictWord{146, 10, 139}, + dictWord{ + 132, + 10, + 646, + }, + dictWord{134, 0, 1166}, + dictWord{4, 10, 396}, + dictWord{7, 10, 728}, + dictWord{9, 10, 117}, + dictWord{13, 10, 202}, + dictWord{148, 10, 51}, + dictWord{ + 6, + 10, + 121, + }, + dictWord{6, 10, 124}, + dictWord{6, 10, 357}, + dictWord{7, 10, 1138}, + dictWord{7, 10, 1295}, + dictWord{8, 10, 162}, + dictWord{139, 10, 655}, + dictWord{14, 0, 374}, + dictWord{142, 11, 374}, + dictWord{138, 0, 253}, + dictWord{139, 0, 1003}, + dictWord{5, 11, 909}, + dictWord{9, 11, 849}, + dictWord{ + 138, + 11, + 805, + }, + dictWord{133, 10, 237}, + dictWord{7, 11, 525}, + dictWord{7, 11, 1579}, + dictWord{8, 11, 497}, + dictWord{136, 11, 573}, + dictWord{137, 0, 46}, + dictWord{ + 132, + 0, + 879, + }, + dictWord{134, 0, 806}, + dictWord{135, 0, 1868}, + dictWord{6, 0, 1837}, + dictWord{134, 0, 1846}, + dictWord{6, 0, 730}, + dictWord{134, 0, 881}, + dictWord{7, 0, 965}, + dictWord{7, 0, 1460}, + dictWord{7, 0, 1604}, + dictWord{7, 11, 193}, + dictWord{7, 11, 397}, + dictWord{7, 11, 1105}, + dictWord{8, 11, 124}, + dictWord{ + 8, + 11, + 619, + }, + dictWord{9, 11, 305}, + dictWord{10, 11, 264}, + dictWord{11, 11, 40}, + dictWord{12, 11, 349}, + dictWord{13, 11, 134}, + dictWord{13, 11, 295}, + dictWord{14, 11, 155}, + dictWord{15, 11, 120}, + dictWord{146, 11, 105}, + dictWord{136, 0, 506}, + dictWord{143, 0, 10}, + dictWord{4, 11, 262}, + dictWord{7, 11, 342}, + dictWord{7, 10, 571}, + dictWord{7, 10, 1877}, + dictWord{10, 10, 366}, + dictWord{141, 11, 23}, + dictWord{133, 11, 641}, + dictWord{10, 0, 22}, + dictWord{9, 10, 513}, + dictWord{10, 10, 39}, + dictWord{12, 10, 122}, + dictWord{140, 10, 187}, + dictWord{135, 11, 1431}, + dictWord{150, 11, 49}, + dictWord{4, 11, 99}, + dictWord{ + 6, + 11, + 250, + }, + dictWord{6, 11, 346}, + dictWord{8, 11, 127}, + dictWord{138, 11, 81}, + dictWord{6, 0, 2014}, + dictWord{8, 0, 928}, + dictWord{10, 0, 960}, + dictWord{10, 0, 979}, + dictWord{140, 0, 996}, + dictWord{134, 0, 296}, + dictWord{132, 11, 915}, + dictWord{5, 11, 75}, + dictWord{9, 11, 517}, + dictWord{10, 11, 470}, + dictWord{ + 12, + 11, + 155, + }, + dictWord{141, 11, 224}, + dictWord{137, 10, 873}, + dictWord{4, 0, 854}, + dictWord{140, 11, 18}, + dictWord{134, 0, 587}, + dictWord{7, 10, 107}, + dictWord{ + 7, + 10, + 838, + }, + dictWord{8, 10, 550}, + dictWord{138, 10, 401}, + dictWord{11, 0, 636}, + dictWord{15, 0, 145}, + dictWord{17, 0, 34}, + dictWord{19, 0, 50}, + dictWord{ + 23, + 0, + 20, + }, + dictWord{11, 10, 588}, + dictWord{11, 10, 864}, + dictWord{11, 10, 968}, + dictWord{143, 10, 160}, + dictWord{135, 11, 216}, + dictWord{7, 0, 982}, + dictWord{ + 10, + 0, + 32, + }, + dictWord{143, 0, 56}, + dictWord{133, 10, 768}, + dictWord{133, 11, 954}, + dictWord{6, 11, 304}, + dictWord{7, 11, 1114}, + dictWord{8, 11, 418}, + dictWord{ + 10, + 11, + 345, + }, + dictWord{11, 11, 341}, + dictWord{11, 11, 675}, + dictWord{141, 11, 40}, + dictWord{9, 11, 410}, + dictWord{139, 11, 425}, + dictWord{136, 0, 941}, + dictWord{5, 0, 435}, + dictWord{132, 10, 894}, + dictWord{5, 0, 85}, + dictWord{6, 0, 419}, + dictWord{7, 0, 134}, + dictWord{7, 0, 305}, + dictWord{7, 0, 361}, + dictWord{ + 7, + 0, + 1337, + }, + dictWord{8, 0, 71}, + dictWord{140, 0, 519}, + dictWord{140, 0, 688}, + dictWord{135, 0, 740}, + dictWord{5, 0, 691}, + dictWord{7, 0, 345}, + dictWord{9, 0, 94}, + dictWord{140, 0, 169}, + dictWord{5, 0, 183}, + dictWord{6, 0, 582}, + dictWord{10, 0, 679}, + dictWord{140, 0, 435}, + dictWord{134, 11, 14}, + dictWord{6, 0, 945}, + dictWord{135, 0, 511}, + dictWord{134, 11, 1708}, + dictWord{5, 11, 113}, + dictWord{6, 11, 243}, + dictWord{7, 11, 1865}, + dictWord{11, 11, 161}, + dictWord{16, 11, 37}, + dictWord{145, 11, 99}, + dictWord{132, 11, 274}, + dictWord{137, 0, 539}, + dictWord{7, 0, 1993}, + dictWord{8, 0, 684}, + dictWord{134, 10, 272}, + dictWord{ + 6, + 0, + 659, + }, + dictWord{134, 0, 982}, + dictWord{4, 10, 9}, + dictWord{5, 10, 128}, + dictWord{7, 10, 368}, + dictWord{11, 10, 480}, + dictWord{148, 10, 3}, + dictWord{ + 134, + 0, + 583, + }, + dictWord{132, 0, 803}, + dictWord{133, 0, 704}, + dictWord{4, 0, 179}, + dictWord{5, 0, 198}, + dictWord{133, 0, 697}, + dictWord{7, 0, 347}, + dictWord{7, 0, 971}, + dictWord{8, 0, 181}, + dictWord{10, 0, 711}, + dictWord{135, 11, 166}, + dictWord{136, 10, 682}, + dictWord{4, 10, 2}, + dictWord{7, 10, 545}, + dictWord{7, 10, 894}, + dictWord{136, 11, 521}, + dictWord{135, 0, 481}, + dictWord{132, 0, 243}, + dictWord{5, 0, 203}, + dictWord{7, 0, 19}, + dictWord{7, 0, 71}, + dictWord{7, 0, 113}, + dictWord{ + 10, + 0, + 405, + }, + dictWord{11, 0, 357}, + dictWord{142, 0, 240}, + dictWord{5, 11, 725}, + dictWord{5, 11, 727}, + dictWord{135, 11, 1811}, + dictWord{6, 0, 826}, + dictWord{ + 137, + 11, + 304, + }, + dictWord{7, 0, 1450}, + dictWord{139, 0, 99}, + dictWord{133, 11, 654}, + dictWord{134, 0, 492}, + dictWord{5, 0, 134}, + dictWord{6, 0, 408}, + dictWord{ + 6, + 0, + 495, + }, + dictWord{7, 0, 1593}, + dictWord{6, 11, 273}, + dictWord{10, 11, 188}, + dictWord{13, 11, 377}, + dictWord{146, 11, 77}, + dictWord{9, 10, 769}, + dictWord{ + 140, + 10, + 185, + }, + dictWord{135, 11, 410}, + dictWord{142, 0, 4}, + dictWord{4, 0, 665}, + dictWord{134, 11, 1785}, + dictWord{4, 0, 248}, + dictWord{7, 0, 137}, + dictWord{ + 137, + 0, + 349, + }, + dictWord{5, 10, 530}, + dictWord{142, 10, 113}, + dictWord{7, 0, 1270}, + dictWord{139, 0, 612}, + dictWord{132, 11, 780}, + dictWord{5, 0, 371}, + dictWord{135, 0, 563}, + dictWord{135, 0, 826}, + dictWord{6, 0, 1535}, + dictWord{23, 0, 21}, + dictWord{151, 0, 23}, + dictWord{4, 0, 374}, + dictWord{7, 0, 547}, + dictWord{ + 7, + 0, + 1700, + }, + dictWord{7, 0, 1833}, + dictWord{139, 0, 858}, + dictWord{133, 10, 556}, + dictWord{7, 11, 612}, + dictWord{8, 11, 545}, + dictWord{8, 11, 568}, + dictWord{ + 8, + 11, + 642, + }, + dictWord{9, 11, 717}, + dictWord{10, 11, 541}, + dictWord{10, 11, 763}, + dictWord{11, 11, 449}, + dictWord{12, 11, 489}, + dictWord{13, 11, 153}, + dictWord{ + 13, + 11, + 296, + }, + dictWord{14, 11, 138}, + dictWord{14, 11, 392}, + dictWord{15, 11, 50}, + dictWord{16, 11, 6}, + dictWord{16, 11, 12}, + dictWord{148, 11, 9}, + dictWord{ + 9, + 0, + 311, + }, + dictWord{141, 0, 42}, + dictWord{8, 10, 16}, + dictWord{140, 10, 568}, + dictWord{6, 0, 1968}, + dictWord{6, 0, 2027}, + dictWord{138, 0, 991}, + dictWord{ + 6, + 0, + 1647, + }, + dictWord{7, 0, 1552}, + dictWord{7, 0, 2010}, + dictWord{9, 0, 494}, + dictWord{137, 0, 509}, + dictWord{133, 11, 948}, + dictWord{6, 10, 186}, + dictWord{ + 137, + 10, + 426, + }, + dictWord{134, 0, 769}, + dictWord{134, 0, 642}, + dictWord{132, 10, 585}, + dictWord{6, 0, 123}, + dictWord{7, 0, 214}, + dictWord{9, 0, 728}, + dictWord{ + 10, + 0, + 157, + }, + dictWord{11, 0, 346}, + dictWord{11, 0, 662}, + dictWord{143, 0, 106}, + dictWord{142, 11, 381}, + dictWord{135, 0, 1435}, + dictWord{4, 11, 532}, + dictWord{ + 5, + 11, + 706, + }, + dictWord{135, 11, 662}, + dictWord{5, 11, 837}, + dictWord{134, 11, 1651}, + dictWord{4, 10, 93}, + dictWord{5, 10, 252}, + dictWord{6, 10, 229}, + dictWord{ + 7, + 10, + 291, + }, + dictWord{9, 10, 550}, + dictWord{139, 10, 644}, + dictWord{148, 0, 79}, + dictWord{137, 10, 749}, + dictWord{134, 0, 1425}, + dictWord{ + 137, + 10, + 162, + }, + dictWord{4, 11, 362}, + dictWord{7, 11, 52}, + dictWord{7, 11, 303}, + dictWord{140, 11, 166}, + dictWord{132, 10, 381}, + dictWord{4, 11, 330}, + dictWord{ + 7, + 11, + 933, + }, + dictWord{7, 11, 2012}, + dictWord{136, 11, 292}, + dictWord{135, 11, 767}, + dictWord{4, 0, 707}, + dictWord{5, 0, 588}, + dictWord{6, 0, 393}, + dictWord{ + 13, + 0, + 106, + }, + dictWord{18, 0, 49}, + dictWord{147, 0, 41}, + dictWord{6, 0, 211}, + dictWord{7, 0, 1690}, + dictWord{11, 0, 486}, + dictWord{140, 0, 369}, + dictWord{ + 137, + 11, + 883, + }, + dictWord{4, 11, 703}, + dictWord{135, 11, 207}, + dictWord{4, 0, 187}, + dictWord{5, 0, 184}, + dictWord{5, 0, 690}, + dictWord{7, 0, 1869}, + dictWord{10, 0, 756}, + dictWord{139, 0, 783}, + dictWord{132, 11, 571}, + dictWord{134, 0, 1382}, + dictWord{5, 0, 175}, + dictWord{6, 10, 77}, + dictWord{6, 10, 157}, + dictWord{7, 10, 974}, + dictWord{7, 10, 1301}, + dictWord{7, 10, 1339}, + dictWord{7, 10, 1490}, + dictWord{7, 10, 1873}, + dictWord{137, 10, 628}, + dictWord{134, 0, 1493}, + dictWord{ + 5, + 11, + 873, + }, + dictWord{133, 11, 960}, + dictWord{134, 0, 1007}, + dictWord{12, 11, 93}, + dictWord{12, 11, 501}, + dictWord{13, 11, 362}, + dictWord{14, 11, 151}, + dictWord{15, 11, 40}, + dictWord{15, 11, 59}, + dictWord{16, 11, 46}, + dictWord{17, 11, 25}, + dictWord{18, 11, 14}, + dictWord{18, 11, 134}, + dictWord{19, 11, 25}, + dictWord{ + 19, + 11, + 69, + }, + dictWord{20, 11, 16}, + dictWord{20, 11, 19}, + dictWord{20, 11, 66}, + dictWord{21, 11, 23}, + dictWord{21, 11, 25}, + dictWord{150, 11, 42}, + dictWord{ + 11, + 10, + 919, + }, + dictWord{141, 10, 409}, + dictWord{134, 0, 219}, + dictWord{5, 0, 582}, + dictWord{6, 0, 1646}, + dictWord{7, 0, 99}, + dictWord{7, 0, 1962}, + dictWord{ + 7, + 0, + 1986, + }, + dictWord{8, 0, 515}, + dictWord{8, 0, 773}, + dictWord{9, 0, 23}, + dictWord{9, 0, 491}, + dictWord{12, 0, 620}, + dictWord{142, 0, 93}, + dictWord{133, 0, 851}, + dictWord{5, 11, 33}, + dictWord{134, 11, 470}, + dictWord{135, 11, 1291}, + dictWord{134, 0, 1278}, + dictWord{135, 11, 1882}, + dictWord{135, 10, 1489}, + dictWord{132, 0, 1000}, + dictWord{138, 0, 982}, + dictWord{8, 0, 762}, + dictWord{8, 0, 812}, + dictWord{137, 0, 910}, + dictWord{6, 11, 47}, + dictWord{7, 11, 90}, + dictWord{ + 7, + 11, + 664, + }, + dictWord{7, 11, 830}, + dictWord{7, 11, 1380}, + dictWord{7, 11, 2025}, + dictWord{8, 11, 448}, + dictWord{136, 11, 828}, + dictWord{4, 0, 98}, + dictWord{ + 4, + 0, + 940, + }, + dictWord{6, 0, 1819}, + dictWord{6, 0, 1834}, + dictWord{6, 0, 1841}, + dictWord{7, 0, 1365}, + dictWord{8, 0, 859}, + dictWord{8, 0, 897}, + dictWord{8, 0, 918}, + dictWord{9, 0, 422}, + dictWord{9, 0, 670}, + dictWord{10, 0, 775}, + dictWord{10, 0, 894}, + dictWord{10, 0, 909}, + dictWord{10, 0, 910}, + dictWord{10, 0, 935}, + dictWord{ + 11, + 0, + 210, + }, + dictWord{12, 0, 750}, + dictWord{12, 0, 755}, + dictWord{13, 0, 26}, + dictWord{13, 0, 457}, + dictWord{13, 0, 476}, + dictWord{16, 0, 100}, + dictWord{16, 0, 109}, + dictWord{18, 0, 173}, + dictWord{18, 0, 175}, + dictWord{8, 10, 398}, + dictWord{9, 10, 681}, + dictWord{139, 10, 632}, + dictWord{9, 11, 417}, + dictWord{ + 137, + 11, + 493, + }, + dictWord{136, 10, 645}, + dictWord{138, 0, 906}, + dictWord{134, 0, 1730}, + dictWord{134, 10, 20}, + dictWord{133, 11, 1019}, + dictWord{134, 0, 1185}, + dictWord{10, 0, 40}, + dictWord{136, 10, 769}, + dictWord{9, 0, 147}, + dictWord{134, 11, 208}, + dictWord{140, 0, 650}, + dictWord{5, 0, 209}, + dictWord{6, 0, 30}, + dictWord{11, 0, 56}, + dictWord{139, 0, 305}, + dictWord{132, 0, 553}, + dictWord{138, 11, 344}, + dictWord{6, 11, 68}, + dictWord{7, 11, 398}, + dictWord{7, 11, 448}, + dictWord{ + 7, + 11, + 1629, + }, + dictWord{7, 11, 1813}, + dictWord{8, 11, 387}, + dictWord{8, 11, 442}, + dictWord{9, 11, 710}, + dictWord{10, 11, 282}, + dictWord{138, 11, 722}, + dictWord{5, 0, 597}, + dictWord{14, 0, 20}, + dictWord{142, 11, 20}, + dictWord{135, 0, 1614}, + dictWord{135, 10, 1757}, + dictWord{4, 0, 150}, + dictWord{5, 0, 303}, + dictWord{6, 0, 327}, + dictWord{135, 10, 937}, + dictWord{16, 0, 49}, + dictWord{7, 10, 1652}, + dictWord{144, 11, 49}, + dictWord{8, 0, 192}, + dictWord{10, 0, 78}, + dictWord{ + 141, + 0, + 359, + }, + dictWord{135, 0, 786}, + dictWord{143, 0, 134}, + dictWord{6, 0, 1638}, + dictWord{7, 0, 79}, + dictWord{7, 0, 496}, + dictWord{9, 0, 138}, + dictWord{ + 10, + 0, + 336, + }, + dictWord{11, 0, 12}, + dictWord{12, 0, 412}, + dictWord{12, 0, 440}, + dictWord{142, 0, 305}, + dictWord{136, 11, 491}, + dictWord{4, 10, 579}, + dictWord{ + 5, + 10, + 226, + }, + dictWord{5, 10, 323}, + dictWord{135, 10, 960}, + dictWord{7, 0, 204}, + dictWord{7, 0, 415}, + dictWord{8, 0, 42}, + dictWord{10, 0, 85}, + dictWord{139, 0, 564}, + dictWord{132, 0, 614}, + dictWord{4, 11, 403}, + dictWord{5, 11, 441}, + dictWord{7, 11, 450}, + dictWord{11, 11, 101}, + dictWord{12, 11, 193}, + dictWord{141, 11, 430}, + dictWord{135, 11, 1927}, + dictWord{135, 11, 1330}, + dictWord{4, 0, 3}, + dictWord{5, 0, 247}, + dictWord{5, 0, 644}, + dictWord{7, 0, 744}, + dictWord{7, 0, 1207}, + dictWord{7, 0, 1225}, + dictWord{7, 0, 1909}, + dictWord{146, 0, 147}, + dictWord{136, 0, 942}, + dictWord{4, 0, 1019}, + dictWord{134, 0, 2023}, + dictWord{5, 11, 679}, + dictWord{133, 10, 973}, + dictWord{5, 0, 285}, + dictWord{9, 0, 67}, + dictWord{13, 0, 473}, + dictWord{143, 0, 82}, + dictWord{7, 11, 328}, + dictWord{137, 11, 326}, + dictWord{151, 0, 8}, + dictWord{6, 10, 135}, + dictWord{135, 10, 1176}, + dictWord{135, 11, 1128}, + dictWord{134, 0, 1309}, + dictWord{135, 11, 1796}, + dictWord{ + 135, + 10, + 314, + }, + dictWord{4, 11, 574}, + dictWord{7, 11, 350}, + dictWord{7, 11, 1024}, + dictWord{8, 11, 338}, + dictWord{9, 11, 677}, + dictWord{10, 11, 808}, + dictWord{ + 139, + 11, + 508, + }, + dictWord{7, 11, 818}, + dictWord{17, 11, 14}, + dictWord{17, 11, 45}, + dictWord{18, 11, 75}, + dictWord{148, 11, 18}, + dictWord{146, 10, 4}, + dictWord{ + 135, + 11, + 1081, + }, + dictWord{4, 0, 29}, + dictWord{6, 0, 532}, + dictWord{7, 0, 1628}, + dictWord{7, 0, 1648}, + dictWord{9, 0, 350}, + dictWord{10, 0, 433}, + dictWord{11, 0, 97}, + dictWord{11, 0, 557}, + dictWord{11, 0, 745}, + dictWord{12, 0, 289}, + dictWord{12, 0, 335}, + dictWord{12, 0, 348}, + dictWord{12, 0, 606}, + dictWord{13, 0, 116}, + dictWord{13, 0, 233}, + dictWord{13, 0, 466}, + dictWord{14, 0, 181}, + dictWord{14, 0, 209}, + dictWord{14, 0, 232}, + dictWord{14, 0, 236}, + dictWord{14, 0, 300}, + dictWord{ + 16, + 0, + 41, + }, + dictWord{148, 0, 97}, + dictWord{7, 0, 318}, + dictWord{6, 10, 281}, + dictWord{8, 10, 282}, + dictWord{8, 10, 480}, + dictWord{8, 10, 499}, + dictWord{9, 10, 198}, + dictWord{10, 10, 143}, + dictWord{10, 10, 169}, + dictWord{10, 10, 211}, + dictWord{10, 10, 417}, + dictWord{10, 10, 574}, + dictWord{11, 10, 147}, + dictWord{ + 11, + 10, + 395, + }, + dictWord{12, 10, 75}, + dictWord{12, 10, 407}, + dictWord{12, 10, 608}, + dictWord{13, 10, 500}, + dictWord{142, 10, 251}, + dictWord{135, 11, 1676}, + dictWord{135, 11, 2037}, + dictWord{135, 0, 1692}, + dictWord{5, 0, 501}, + dictWord{7, 0, 1704}, + dictWord{9, 0, 553}, + dictWord{11, 0, 520}, + dictWord{12, 0, 557}, + dictWord{141, 0, 249}, + dictWord{6, 0, 1527}, + dictWord{14, 0, 324}, + dictWord{15, 0, 55}, + dictWord{15, 0, 80}, + dictWord{14, 11, 324}, + dictWord{15, 11, 55}, + dictWord{143, 11, 80}, + dictWord{135, 10, 1776}, + dictWord{8, 0, 988}, + dictWord{137, 11, 297}, + dictWord{132, 10, 419}, + dictWord{142, 0, 223}, + dictWord{ + 139, + 11, + 234, + }, + dictWord{7, 0, 1123}, + dictWord{12, 0, 508}, + dictWord{14, 0, 102}, + dictWord{14, 0, 226}, + dictWord{144, 0, 57}, + dictWord{4, 10, 138}, + dictWord{ + 7, + 10, + 1012, + }, + dictWord{7, 10, 1280}, + dictWord{137, 10, 76}, + dictWord{7, 0, 1764}, + dictWord{5, 10, 29}, + dictWord{140, 10, 638}, + dictWord{134, 0, 2015}, + dictWord{134, 0, 1599}, + dictWord{138, 11, 56}, + dictWord{6, 11, 306}, + dictWord{7, 11, 1140}, + dictWord{7, 11, 1340}, + dictWord{8, 11, 133}, + dictWord{ + 138, + 11, + 449, + }, + dictWord{139, 11, 1011}, + dictWord{6, 10, 1710}, + dictWord{135, 10, 2038}, + dictWord{7, 11, 1763}, + dictWord{140, 11, 310}, + dictWord{6, 0, 129}, + dictWord{4, 10, 17}, + dictWord{5, 10, 23}, + dictWord{7, 10, 995}, + dictWord{11, 10, 383}, + dictWord{11, 10, 437}, + dictWord{12, 10, 460}, + dictWord{140, 10, 532}, + dictWord{5, 11, 329}, + dictWord{136, 11, 260}, + dictWord{133, 10, 862}, + dictWord{132, 0, 534}, + dictWord{6, 0, 811}, + dictWord{135, 0, 626}, + dictWord{ + 132, + 11, + 657, + }, + dictWord{4, 0, 25}, + dictWord{5, 0, 60}, + dictWord{6, 0, 504}, + dictWord{7, 0, 614}, + dictWord{7, 0, 1155}, + dictWord{12, 0, 0}, + dictWord{152, 11, 7}, + dictWord{ + 7, + 0, + 1248, + }, + dictWord{11, 0, 621}, + dictWord{139, 0, 702}, + dictWord{137, 0, 321}, + dictWord{8, 10, 70}, + dictWord{12, 10, 171}, + dictWord{141, 10, 272}, + dictWord{ + 10, + 10, + 233, + }, + dictWord{139, 10, 76}, + dictWord{4, 0, 379}, + dictWord{7, 0, 1397}, + dictWord{134, 10, 442}, + dictWord{5, 11, 66}, + dictWord{7, 11, 1896}, + dictWord{ + 136, + 11, + 288, + }, + dictWord{134, 11, 1643}, + dictWord{134, 10, 1709}, + dictWord{4, 11, 21}, + dictWord{5, 11, 91}, + dictWord{5, 11, 570}, + dictWord{5, 11, 648}, + dictWord{5, 11, 750}, + dictWord{5, 11, 781}, + dictWord{6, 11, 54}, + dictWord{6, 11, 112}, + dictWord{6, 11, 402}, + dictWord{6, 11, 1732}, + dictWord{7, 11, 315}, + dictWord{ + 7, + 11, + 749, + }, + dictWord{7, 11, 1347}, + dictWord{7, 11, 1900}, + dictWord{9, 11, 78}, + dictWord{9, 11, 508}, + dictWord{10, 11, 611}, + dictWord{11, 11, 510}, + dictWord{ + 11, + 11, + 728, + }, + dictWord{13, 11, 36}, + dictWord{14, 11, 39}, + dictWord{16, 11, 83}, + dictWord{17, 11, 124}, + dictWord{148, 11, 30}, + dictWord{4, 0, 118}, + dictWord{ + 6, + 0, + 274, + }, + dictWord{6, 0, 361}, + dictWord{7, 0, 75}, + dictWord{141, 0, 441}, + dictWord{10, 11, 322}, + dictWord{10, 11, 719}, + dictWord{139, 11, 407}, + dictWord{ + 147, + 10, + 119, + }, + dictWord{12, 11, 549}, + dictWord{14, 11, 67}, + dictWord{147, 11, 60}, + dictWord{11, 10, 69}, + dictWord{12, 10, 105}, + dictWord{12, 10, 117}, + dictWord{13, 10, 213}, + dictWord{14, 10, 13}, + dictWord{14, 10, 62}, + dictWord{14, 10, 177}, + dictWord{14, 10, 421}, + dictWord{15, 10, 19}, + dictWord{146, 10, 141}, + dictWord{9, 0, 841}, + dictWord{137, 10, 309}, + dictWord{7, 10, 608}, + dictWord{7, 10, 976}, + dictWord{8, 11, 125}, + dictWord{8, 11, 369}, + dictWord{8, 11, 524}, + dictWord{9, 10, 146}, + dictWord{10, 10, 206}, + dictWord{10, 11, 486}, + dictWord{10, 10, 596}, + dictWord{11, 11, 13}, + dictWord{11, 11, 381}, + dictWord{11, 11, 736}, + dictWord{11, 11, 766}, + dictWord{11, 11, 845}, + dictWord{13, 11, 114}, + dictWord{13, 10, 218}, + dictWord{13, 11, 292}, + dictWord{14, 11, 47}, + dictWord{ + 142, + 10, + 153, + }, + dictWord{12, 0, 693}, + dictWord{135, 11, 759}, + dictWord{5, 0, 314}, + dictWord{6, 0, 221}, + dictWord{7, 0, 419}, + dictWord{10, 0, 650}, + dictWord{11, 0, 396}, + dictWord{12, 0, 156}, + dictWord{13, 0, 369}, + dictWord{14, 0, 333}, + dictWord{145, 0, 47}, + dictWord{6, 11, 1684}, + dictWord{6, 11, 1731}, + dictWord{7, 11, 356}, + dictWord{7, 11, 1932}, + dictWord{8, 11, 54}, + dictWord{8, 11, 221}, + dictWord{9, 11, 225}, + dictWord{9, 11, 356}, + dictWord{10, 11, 77}, + dictWord{10, 11, 446}, + dictWord{10, 11, 731}, + dictWord{12, 11, 404}, + dictWord{141, 11, 491}, + dictWord{132, 11, 375}, + dictWord{4, 10, 518}, + dictWord{135, 10, 1136}, + dictWord{ + 4, + 0, + 913, + }, + dictWord{4, 11, 411}, + dictWord{11, 11, 643}, + dictWord{140, 11, 115}, + dictWord{4, 11, 80}, + dictWord{133, 11, 44}, + dictWord{8, 10, 689}, + dictWord{ + 137, + 10, + 863, + }, + dictWord{138, 0, 880}, + dictWord{4, 10, 18}, + dictWord{7, 10, 145}, + dictWord{7, 10, 444}, + dictWord{7, 10, 1278}, + dictWord{8, 10, 49}, + dictWord{ + 8, + 10, + 400, + }, + dictWord{9, 10, 71}, + dictWord{9, 10, 250}, + dictWord{10, 10, 459}, + dictWord{12, 10, 160}, + dictWord{144, 10, 24}, + dictWord{136, 0, 475}, + dictWord{ + 5, + 0, + 1016, + }, + dictWord{5, 11, 299}, + dictWord{135, 11, 1083}, + dictWord{7, 0, 602}, + dictWord{8, 0, 179}, + dictWord{10, 0, 781}, + dictWord{140, 0, 126}, + dictWord{ + 6, + 0, + 329, + }, + dictWord{138, 0, 111}, + dictWord{135, 0, 1864}, + dictWord{4, 11, 219}, + dictWord{7, 11, 1761}, + dictWord{137, 11, 86}, + dictWord{6, 0, 1888}, + dictWord{ + 6, + 0, + 1892, + }, + dictWord{6, 0, 1901}, + dictWord{6, 0, 1904}, + dictWord{9, 0, 953}, + dictWord{9, 0, 985}, + dictWord{9, 0, 991}, + dictWord{9, 0, 1001}, + dictWord{12, 0, 818}, + dictWord{12, 0, 846}, + dictWord{12, 0, 847}, + dictWord{12, 0, 861}, + dictWord{12, 0, 862}, + dictWord{12, 0, 873}, + dictWord{12, 0, 875}, + dictWord{12, 0, 877}, + dictWord{12, 0, 879}, + dictWord{12, 0, 881}, + dictWord{12, 0, 884}, + dictWord{12, 0, 903}, + dictWord{12, 0, 915}, + dictWord{12, 0, 926}, + dictWord{12, 0, 939}, + dictWord{ + 15, + 0, + 182, + }, + dictWord{15, 0, 219}, + dictWord{15, 0, 255}, + dictWord{18, 0, 191}, + dictWord{18, 0, 209}, + dictWord{18, 0, 211}, + dictWord{149, 0, 41}, + dictWord{ + 5, + 11, + 328, + }, + dictWord{135, 11, 918}, + dictWord{137, 0, 780}, + dictWord{12, 0, 82}, + dictWord{143, 0, 36}, + dictWord{133, 10, 1010}, + dictWord{5, 0, 821}, + dictWord{ + 134, + 0, + 1687, + }, + dictWord{133, 11, 514}, + dictWord{132, 0, 956}, + dictWord{134, 0, 1180}, + dictWord{10, 0, 112}, + dictWord{5, 10, 87}, + dictWord{7, 10, 313}, + dictWord{ + 7, + 10, + 1103, + }, + dictWord{10, 10, 582}, + dictWord{11, 10, 389}, + dictWord{11, 10, 813}, + dictWord{12, 10, 385}, + dictWord{13, 10, 286}, + dictWord{14, 10, 124}, + dictWord{146, 10, 108}, + dictWord{5, 0, 71}, + dictWord{7, 0, 1407}, + dictWord{9, 0, 704}, + dictWord{10, 0, 261}, + dictWord{10, 0, 619}, + dictWord{11, 0, 547}, + dictWord{11, 0, 619}, + dictWord{143, 0, 157}, + dictWord{4, 0, 531}, + dictWord{5, 0, 455}, + dictWord{5, 11, 301}, + dictWord{6, 11, 571}, + dictWord{14, 11, 49}, + dictWord{ + 146, + 11, + 102, + }, + dictWord{132, 10, 267}, + dictWord{6, 0, 385}, + dictWord{7, 0, 2008}, + dictWord{9, 0, 337}, + dictWord{138, 0, 517}, + dictWord{133, 11, 726}, + dictWord{133, 11, 364}, + dictWord{4, 11, 76}, + dictWord{7, 11, 1550}, + dictWord{9, 11, 306}, + dictWord{9, 11, 430}, + dictWord{9, 11, 663}, + dictWord{10, 11, 683}, + dictWord{11, 11, 427}, + dictWord{11, 11, 753}, + dictWord{12, 11, 334}, + dictWord{12, 11, 442}, + dictWord{14, 11, 258}, + dictWord{14, 11, 366}, + dictWord{ + 143, + 11, + 131, + }, + dictWord{6, 0, 1865}, + dictWord{6, 0, 1879}, + dictWord{6, 0, 1881}, + dictWord{6, 0, 1894}, + dictWord{6, 0, 1908}, + dictWord{9, 0, 915}, + dictWord{9, 0, 926}, + dictWord{9, 0, 940}, + dictWord{9, 0, 943}, + dictWord{9, 0, 966}, + dictWord{9, 0, 980}, + dictWord{9, 0, 989}, + dictWord{9, 0, 1005}, + dictWord{9, 0, 1010}, + dictWord{ + 12, + 0, + 813, + }, + dictWord{12, 0, 817}, + dictWord{12, 0, 840}, + dictWord{12, 0, 843}, + dictWord{12, 0, 855}, + dictWord{12, 0, 864}, + dictWord{12, 0, 871}, + dictWord{12, 0, 872}, + dictWord{12, 0, 899}, + dictWord{12, 0, 905}, + dictWord{12, 0, 924}, + dictWord{15, 0, 171}, + dictWord{15, 0, 181}, + dictWord{15, 0, 224}, + dictWord{15, 0, 235}, + dictWord{15, 0, 251}, + dictWord{146, 0, 184}, + dictWord{137, 11, 52}, + dictWord{5, 0, 16}, + dictWord{6, 0, 86}, + dictWord{6, 0, 603}, + dictWord{7, 0, 292}, + dictWord{7, 0, 561}, + dictWord{8, 0, 257}, + dictWord{8, 0, 382}, + dictWord{9, 0, 721}, + dictWord{9, 0, 778}, + dictWord{11, 0, 581}, + dictWord{140, 0, 466}, + dictWord{4, 0, 486}, + dictWord{ + 5, + 0, + 491, + }, + dictWord{135, 10, 1121}, + dictWord{4, 0, 72}, + dictWord{6, 0, 265}, + dictWord{135, 0, 1300}, + dictWord{135, 11, 1183}, + dictWord{10, 10, 249}, + dictWord{139, 10, 209}, + dictWord{132, 10, 561}, + dictWord{137, 11, 519}, + dictWord{4, 11, 656}, + dictWord{4, 10, 760}, + dictWord{135, 11, 779}, + dictWord{ + 9, + 10, + 154, + }, + dictWord{140, 10, 485}, + dictWord{135, 11, 1793}, + dictWord{135, 11, 144}, + dictWord{136, 10, 255}, + dictWord{133, 0, 621}, + dictWord{4, 10, 368}, + dictWord{135, 10, 641}, + dictWord{135, 11, 1373}, + dictWord{7, 11, 554}, + dictWord{7, 11, 605}, + dictWord{141, 11, 10}, + dictWord{137, 0, 234}, + dictWord{ + 5, + 0, + 815, + }, + dictWord{6, 0, 1688}, + dictWord{134, 0, 1755}, + dictWord{5, 11, 838}, + dictWord{5, 11, 841}, + dictWord{134, 11, 1649}, + dictWord{7, 0, 1987}, + dictWord{ + 7, + 0, + 2040, + }, + dictWord{136, 0, 743}, + dictWord{133, 11, 1012}, + dictWord{6, 0, 197}, + dictWord{136, 0, 205}, + dictWord{6, 0, 314}, + dictWord{134, 11, 314}, + dictWord{144, 11, 53}, + dictWord{6, 11, 251}, + dictWord{7, 11, 365}, + dictWord{7, 11, 1357}, + dictWord{7, 11, 1497}, + dictWord{8, 11, 154}, + dictWord{141, 11, 281}, + dictWord{133, 11, 340}, + dictWord{6, 0, 452}, + dictWord{7, 0, 312}, + dictWord{138, 0, 219}, + dictWord{138, 0, 589}, + dictWord{4, 0, 333}, + dictWord{9, 0, 176}, + dictWord{12, 0, 353}, + dictWord{141, 0, 187}, + dictWord{9, 10, 92}, + dictWord{147, 10, 91}, + dictWord{134, 0, 1110}, + dictWord{11, 0, 47}, + dictWord{139, 11, 495}, + dictWord{6, 10, 525}, + dictWord{8, 10, 806}, + dictWord{9, 10, 876}, + dictWord{140, 10, 284}, + dictWord{8, 11, 261}, + dictWord{9, 11, 144}, + dictWord{9, 11, 466}, + dictWord{10, 11, 370}, + dictWord{12, 11, 470}, + dictWord{13, 11, 144}, + dictWord{142, 11, 348}, + dictWord{137, 11, 897}, + dictWord{8, 0, 863}, + dictWord{8, 0, 864}, + dictWord{8, 0, 868}, + dictWord{8, 0, 884}, + dictWord{10, 0, 866}, + dictWord{10, 0, 868}, + dictWord{10, 0, 873}, + dictWord{10, 0, 911}, + dictWord{10, 0, 912}, + dictWord{ + 10, + 0, + 944, + }, + dictWord{12, 0, 727}, + dictWord{6, 11, 248}, + dictWord{9, 11, 546}, + dictWord{10, 11, 535}, + dictWord{11, 11, 681}, + dictWord{141, 11, 135}, + dictWord{ + 6, + 0, + 300, + }, + dictWord{135, 0, 1515}, + dictWord{134, 0, 1237}, + dictWord{139, 10, 958}, + dictWord{133, 10, 594}, + dictWord{140, 11, 250}, + dictWord{ + 134, + 0, + 1685, + }, + dictWord{134, 11, 567}, + dictWord{7, 0, 135}, + dictWord{8, 0, 7}, + dictWord{8, 0, 62}, + dictWord{9, 0, 243}, + dictWord{10, 0, 658}, + dictWord{10, 0, 697}, + dictWord{11, 0, 456}, + dictWord{139, 0, 756}, + dictWord{9, 0, 395}, + dictWord{138, 0, 79}, + dictWord{6, 10, 1641}, + dictWord{136, 10, 820}, + dictWord{4, 10, 302}, + dictWord{135, 10, 1766}, + dictWord{134, 11, 174}, + dictWord{135, 10, 1313}, + dictWord{135, 0, 631}, + dictWord{134, 10, 1674}, + dictWord{134, 11, 395}, + dictWord{138, 0, 835}, + dictWord{7, 0, 406}, + dictWord{7, 0, 459}, + dictWord{8, 0, 606}, + dictWord{139, 0, 726}, + dictWord{134, 11, 617}, + dictWord{134, 0, 979}, + dictWord{ + 6, + 10, + 389, + }, + dictWord{7, 10, 149}, + dictWord{9, 10, 142}, + dictWord{138, 10, 94}, + dictWord{5, 11, 878}, + dictWord{133, 11, 972}, + dictWord{6, 10, 8}, + dictWord{ + 7, + 10, + 1881, + }, + dictWord{8, 10, 91}, + dictWord{136, 11, 511}, + dictWord{133, 0, 612}, + dictWord{132, 11, 351}, + dictWord{4, 0, 372}, + dictWord{7, 0, 482}, + dictWord{ + 8, + 0, + 158, + }, + dictWord{9, 0, 602}, + dictWord{9, 0, 615}, + dictWord{10, 0, 245}, + dictWord{10, 0, 678}, + dictWord{10, 0, 744}, + dictWord{11, 0, 248}, + dictWord{ + 139, + 0, + 806, + }, + dictWord{5, 0, 854}, + dictWord{135, 0, 1991}, + dictWord{132, 11, 286}, + dictWord{135, 11, 344}, + dictWord{7, 11, 438}, + dictWord{7, 11, 627}, + dictWord{ + 7, + 11, + 1516, + }, + dictWord{8, 11, 40}, + dictWord{9, 11, 56}, + dictWord{9, 11, 294}, + dictWord{10, 11, 30}, + dictWord{10, 11, 259}, + dictWord{11, 11, 969}, + dictWord{ + 146, + 11, + 148, + }, + dictWord{135, 0, 1492}, + dictWord{5, 11, 259}, + dictWord{7, 11, 414}, + dictWord{7, 11, 854}, + dictWord{142, 11, 107}, + dictWord{135, 10, 1746}, + dictWord{6, 0, 833}, + dictWord{134, 0, 998}, + dictWord{135, 10, 24}, + dictWord{6, 0, 750}, + dictWord{135, 0, 1739}, + dictWord{4, 10, 503}, + dictWord{ + 135, + 10, + 1661, + }, + dictWord{5, 10, 130}, + dictWord{7, 10, 1314}, + dictWord{9, 10, 610}, + dictWord{10, 10, 718}, + dictWord{11, 10, 601}, + dictWord{11, 10, 819}, + dictWord{ + 11, + 10, + 946, + }, + dictWord{140, 10, 536}, + dictWord{10, 10, 149}, + dictWord{11, 10, 280}, + dictWord{142, 10, 336}, + dictWord{132, 11, 738}, + dictWord{ + 135, + 10, + 1946, + }, + dictWord{5, 0, 195}, + dictWord{135, 0, 1685}, + dictWord{7, 0, 1997}, + dictWord{8, 0, 730}, + dictWord{139, 0, 1006}, + dictWord{151, 11, 17}, + dictWord{ + 133, + 11, + 866, + }, + dictWord{14, 0, 463}, + dictWord{14, 0, 470}, + dictWord{150, 0, 61}, + dictWord{5, 0, 751}, + dictWord{8, 0, 266}, + dictWord{11, 0, 578}, + dictWord{ + 4, + 10, + 392, + }, + dictWord{135, 10, 1597}, + dictWord{5, 10, 433}, + dictWord{9, 10, 633}, + dictWord{139, 10, 629}, + dictWord{135, 0, 821}, + dictWord{6, 0, 715}, + dictWord{ + 134, + 0, + 1325, + }, + dictWord{133, 11, 116}, + dictWord{6, 0, 868}, + dictWord{132, 11, 457}, + dictWord{134, 0, 959}, + dictWord{6, 10, 234}, + dictWord{138, 11, 199}, + dictWord{7, 0, 1053}, + dictWord{7, 10, 1950}, + dictWord{8, 10, 680}, + dictWord{11, 10, 817}, + dictWord{147, 10, 88}, + dictWord{7, 10, 1222}, + dictWord{ + 138, + 10, + 386, + }, + dictWord{5, 0, 950}, + dictWord{5, 0, 994}, + dictWord{6, 0, 351}, + dictWord{134, 0, 1124}, + dictWord{134, 0, 1081}, + dictWord{7, 0, 1595}, + dictWord{6, 10, 5}, + dictWord{11, 10, 249}, + dictWord{12, 10, 313}, + dictWord{16, 10, 66}, + dictWord{145, 10, 26}, + dictWord{148, 0, 59}, + dictWord{5, 11, 527}, + dictWord{6, 11, 189}, + dictWord{135, 11, 859}, + dictWord{5, 10, 963}, + dictWord{6, 10, 1773}, + dictWord{11, 11, 104}, + dictWord{11, 11, 554}, + dictWord{15, 11, 60}, + dictWord{ + 143, + 11, + 125, + }, + dictWord{135, 0, 47}, + dictWord{137, 0, 684}, + dictWord{134, 11, 116}, + dictWord{134, 0, 1606}, + dictWord{134, 0, 777}, + dictWord{7, 0, 1020}, + dictWord{ + 8, + 10, + 509, + }, + dictWord{136, 10, 792}, + dictWord{135, 0, 1094}, + dictWord{132, 0, 350}, + dictWord{133, 11, 487}, + dictWord{4, 11, 86}, + dictWord{5, 11, 667}, + dictWord{5, 11, 753}, + dictWord{6, 11, 316}, + dictWord{6, 11, 455}, + dictWord{135, 11, 946}, + dictWord{7, 0, 1812}, + dictWord{13, 0, 259}, + dictWord{13, 0, 356}, + dictWord{14, 0, 242}, + dictWord{147, 0, 114}, + dictWord{132, 10, 931}, + dictWord{133, 0, 967}, + dictWord{4, 0, 473}, + dictWord{7, 0, 623}, + dictWord{8, 0, 808}, + dictWord{ + 9, + 0, + 871, + }, + dictWord{9, 0, 893}, + dictWord{11, 0, 38}, + dictWord{11, 0, 431}, + dictWord{12, 0, 112}, + dictWord{12, 0, 217}, + dictWord{12, 0, 243}, + dictWord{12, 0, 562}, + dictWord{12, 0, 663}, + dictWord{12, 0, 683}, + dictWord{13, 0, 141}, + dictWord{13, 0, 197}, + dictWord{13, 0, 227}, + dictWord{13, 0, 406}, + dictWord{13, 0, 487}, + dictWord{14, 0, 156}, + dictWord{14, 0, 203}, + dictWord{14, 0, 224}, + dictWord{14, 0, 256}, + dictWord{18, 0, 58}, + dictWord{150, 0, 0}, + dictWord{138, 0, 286}, + dictWord{ + 7, + 10, + 943, + }, + dictWord{139, 10, 614}, + dictWord{135, 10, 1837}, + dictWord{150, 11, 45}, + dictWord{132, 0, 798}, + dictWord{4, 0, 222}, + dictWord{7, 0, 286}, + dictWord{136, 0, 629}, + dictWord{4, 11, 79}, + dictWord{7, 11, 1773}, + dictWord{10, 11, 450}, + dictWord{11, 11, 589}, + dictWord{13, 11, 332}, + dictWord{13, 11, 493}, + dictWord{14, 11, 183}, + dictWord{14, 11, 334}, + dictWord{14, 11, 362}, + dictWord{14, 11, 368}, + dictWord{14, 11, 376}, + dictWord{14, 11, 379}, + dictWord{ + 19, + 11, + 90, + }, + dictWord{19, 11, 103}, + dictWord{19, 11, 127}, + dictWord{148, 11, 90}, + dictWord{5, 0, 337}, + dictWord{11, 0, 513}, + dictWord{11, 0, 889}, + dictWord{ + 11, + 0, + 961, + }, + dictWord{12, 0, 461}, + dictWord{13, 0, 79}, + dictWord{15, 0, 121}, + dictWord{4, 10, 90}, + dictWord{5, 10, 545}, + dictWord{7, 10, 754}, + dictWord{9, 10, 186}, + dictWord{10, 10, 72}, + dictWord{10, 10, 782}, + dictWord{11, 10, 577}, + dictWord{11, 10, 610}, + dictWord{12, 10, 354}, + dictWord{12, 10, 362}, + dictWord{ + 140, + 10, + 595, + }, + dictWord{141, 0, 306}, + dictWord{136, 0, 146}, + dictWord{7, 0, 1646}, + dictWord{9, 10, 329}, + dictWord{11, 10, 254}, + dictWord{141, 11, 124}, + dictWord{ + 4, + 0, + 465, + }, + dictWord{135, 0, 1663}, + dictWord{132, 0, 525}, + dictWord{133, 11, 663}, + dictWord{10, 0, 299}, + dictWord{18, 0, 74}, + dictWord{9, 10, 187}, + dictWord{ + 11, + 10, + 1016, + }, + dictWord{145, 10, 44}, + dictWord{7, 0, 165}, + dictWord{7, 0, 919}, + dictWord{4, 10, 506}, + dictWord{136, 10, 517}, + dictWord{5, 10, 295}, + dictWord{ + 135, + 10, + 1680, + }, + dictWord{133, 11, 846}, + dictWord{134, 0, 1064}, + dictWord{5, 11, 378}, + dictWord{7, 11, 1402}, + dictWord{7, 11, 1414}, + dictWord{8, 11, 465}, + dictWord{9, 11, 286}, + dictWord{10, 11, 185}, + dictWord{10, 11, 562}, + dictWord{10, 11, 635}, + dictWord{11, 11, 31}, + dictWord{11, 11, 393}, + dictWord{ + 12, + 11, + 456, + }, + dictWord{13, 11, 312}, + dictWord{18, 11, 65}, + dictWord{18, 11, 96}, + dictWord{147, 11, 89}, + dictWord{132, 0, 596}, + dictWord{7, 10, 987}, + dictWord{ + 9, + 10, + 688, + }, + dictWord{10, 10, 522}, + dictWord{11, 10, 788}, + dictWord{140, 10, 566}, + dictWord{6, 0, 82}, + dictWord{7, 0, 138}, + dictWord{7, 0, 517}, + dictWord{7, 0, 1741}, + dictWord{11, 0, 238}, + dictWord{4, 11, 648}, + dictWord{134, 10, 1775}, + dictWord{7, 0, 1233}, + dictWord{7, 10, 700}, + dictWord{7, 10, 940}, + dictWord{8, 10, 514}, + dictWord{9, 10, 116}, + dictWord{9, 10, 535}, + dictWord{10, 10, 118}, + dictWord{11, 10, 107}, + dictWord{11, 10, 148}, + dictWord{11, 10, 922}, + dictWord{ + 12, + 10, + 254, + }, + dictWord{12, 10, 421}, + dictWord{142, 10, 238}, + dictWord{4, 0, 962}, + dictWord{6, 0, 1824}, + dictWord{8, 0, 894}, + dictWord{12, 0, 708}, + dictWord{ + 12, + 0, + 725, + }, + dictWord{14, 0, 451}, + dictWord{20, 0, 94}, + dictWord{22, 0, 59}, + dictWord{150, 0, 62}, + dictWord{5, 11, 945}, + dictWord{6, 11, 1656}, + dictWord{6, 11, 1787}, + dictWord{7, 11, 167}, + dictWord{8, 11, 824}, + dictWord{9, 11, 391}, + dictWord{10, 11, 375}, + dictWord{139, 11, 185}, + dictWord{5, 0, 495}, + dictWord{7, 0, 834}, + dictWord{9, 0, 733}, + dictWord{139, 0, 378}, + dictWord{4, 10, 743}, + dictWord{135, 11, 1273}, + dictWord{6, 0, 1204}, + dictWord{7, 11, 1645}, + dictWord{8, 11, 352}, + dictWord{137, 11, 249}, + dictWord{139, 10, 292}, + dictWord{133, 0, 559}, + dictWord{132, 11, 152}, + dictWord{9, 0, 499}, + dictWord{10, 0, 341}, + dictWord{ + 15, + 0, + 144, + }, + dictWord{19, 0, 49}, + dictWord{7, 10, 1283}, + dictWord{9, 10, 227}, + dictWord{11, 10, 325}, + dictWord{11, 10, 408}, + dictWord{14, 10, 180}, + dictWord{ + 146, + 10, + 47, + }, + dictWord{6, 0, 21}, + dictWord{6, 0, 1737}, + dictWord{7, 0, 1444}, + dictWord{136, 0, 224}, + dictWord{133, 11, 1006}, + dictWord{7, 0, 1446}, + dictWord{ + 9, + 0, + 97, + }, + dictWord{17, 0, 15}, + dictWord{5, 10, 81}, + dictWord{7, 10, 146}, + dictWord{7, 10, 1342}, + dictWord{8, 10, 53}, + dictWord{8, 10, 561}, + dictWord{8, 10, 694}, + dictWord{8, 10, 754}, + dictWord{9, 10, 115}, + dictWord{9, 10, 894}, + dictWord{10, 10, 462}, + dictWord{10, 10, 813}, + dictWord{11, 10, 230}, + dictWord{11, 10, 657}, + dictWord{11, 10, 699}, + dictWord{11, 10, 748}, + dictWord{12, 10, 119}, + dictWord{12, 10, 200}, + dictWord{12, 10, 283}, + dictWord{142, 10, 273}, + dictWord{ + 5, + 10, + 408, + }, + dictWord{137, 10, 747}, + dictWord{135, 11, 431}, + dictWord{135, 11, 832}, + dictWord{6, 0, 729}, + dictWord{134, 0, 953}, + dictWord{4, 0, 727}, + dictWord{ + 8, + 0, + 565, + }, + dictWord{5, 11, 351}, + dictWord{7, 11, 264}, + dictWord{136, 11, 565}, + dictWord{134, 0, 1948}, + dictWord{5, 0, 519}, + dictWord{5, 11, 40}, + dictWord{ + 7, + 11, + 598, + }, + dictWord{7, 11, 1638}, + dictWord{8, 11, 78}, + dictWord{9, 11, 166}, + dictWord{9, 11, 640}, + dictWord{9, 11, 685}, + dictWord{9, 11, 773}, + dictWord{ + 11, + 11, + 215, + }, + dictWord{13, 11, 65}, + dictWord{14, 11, 172}, + dictWord{14, 11, 317}, + dictWord{145, 11, 6}, + dictWord{8, 11, 60}, + dictWord{9, 11, 343}, + dictWord{ + 139, + 11, + 769, + }, + dictWord{137, 11, 455}, + dictWord{134, 0, 1193}, + dictWord{140, 0, 790}, + dictWord{7, 11, 1951}, + dictWord{8, 11, 765}, + dictWord{8, 11, 772}, + dictWord{140, 11, 671}, + dictWord{7, 11, 108}, + dictWord{8, 11, 219}, + dictWord{8, 11, 388}, + dictWord{9, 11, 639}, + dictWord{9, 11, 775}, + dictWord{11, 11, 275}, + dictWord{140, 11, 464}, + dictWord{132, 11, 468}, + dictWord{7, 10, 30}, + dictWord{8, 10, 86}, + dictWord{8, 10, 315}, + dictWord{8, 10, 700}, + dictWord{9, 10, 576}, + dictWord{ + 9, + 10, + 858, + }, + dictWord{11, 10, 310}, + dictWord{11, 10, 888}, + dictWord{11, 10, 904}, + dictWord{12, 10, 361}, + dictWord{141, 10, 248}, + dictWord{5, 11, 15}, + dictWord{6, 11, 56}, + dictWord{7, 11, 1758}, + dictWord{8, 11, 500}, + dictWord{9, 11, 730}, + dictWord{11, 11, 331}, + dictWord{13, 11, 150}, + dictWord{142, 11, 282}, + dictWord{4, 0, 402}, + dictWord{7, 0, 2}, + dictWord{8, 0, 323}, + dictWord{136, 0, 479}, + dictWord{138, 10, 839}, + dictWord{11, 0, 580}, + dictWord{142, 0, 201}, + dictWord{ + 5, + 0, + 59, + }, + dictWord{135, 0, 672}, + dictWord{137, 10, 617}, + dictWord{146, 0, 34}, + dictWord{134, 11, 1886}, + dictWord{4, 0, 961}, + dictWord{136, 0, 896}, + dictWord{ + 6, + 0, + 1285, + }, + dictWord{5, 11, 205}, + dictWord{6, 11, 438}, + dictWord{137, 11, 711}, + dictWord{134, 10, 428}, + dictWord{7, 10, 524}, + dictWord{8, 10, 169}, + dictWord{8, 10, 234}, + dictWord{9, 10, 480}, + dictWord{138, 10, 646}, + dictWord{148, 0, 46}, + dictWord{141, 0, 479}, + dictWord{133, 11, 534}, + dictWord{6, 0, 2019}, + dictWord{134, 10, 1648}, + dictWord{4, 0, 85}, + dictWord{7, 0, 549}, + dictWord{7, 10, 1205}, + dictWord{138, 10, 637}, + dictWord{4, 0, 663}, + dictWord{5, 0, 94}, + dictWord{ + 7, + 11, + 235, + }, + dictWord{7, 11, 1475}, + dictWord{15, 11, 68}, + dictWord{146, 11, 120}, + dictWord{6, 11, 443}, + dictWord{9, 11, 237}, + dictWord{9, 11, 571}, + dictWord{ + 9, + 11, + 695, + }, + dictWord{10, 11, 139}, + dictWord{11, 11, 715}, + dictWord{12, 11, 417}, + dictWord{141, 11, 421}, + dictWord{132, 0, 783}, + dictWord{4, 0, 682}, + dictWord{8, 0, 65}, + dictWord{9, 10, 39}, + dictWord{10, 10, 166}, + dictWord{11, 10, 918}, + dictWord{12, 10, 635}, + dictWord{20, 10, 10}, + dictWord{22, 10, 27}, + dictWord{ + 22, + 10, + 43, + }, + dictWord{150, 10, 52}, + dictWord{6, 0, 11}, + dictWord{135, 0, 187}, + dictWord{132, 0, 522}, + dictWord{4, 0, 52}, + dictWord{135, 0, 661}, + dictWord{ + 4, + 0, + 383, + }, + dictWord{133, 0, 520}, + dictWord{135, 11, 546}, + dictWord{11, 0, 343}, + dictWord{142, 0, 127}, + dictWord{4, 11, 578}, + dictWord{7, 10, 157}, + dictWord{ + 7, + 11, + 624, + }, + dictWord{7, 11, 916}, + dictWord{8, 10, 279}, + dictWord{10, 11, 256}, + dictWord{11, 11, 87}, + dictWord{139, 11, 703}, + dictWord{134, 10, 604}, + dictWord{ + 4, + 0, + 281, + }, + dictWord{5, 0, 38}, + dictWord{7, 0, 194}, + dictWord{7, 0, 668}, + dictWord{7, 0, 1893}, + dictWord{137, 0, 397}, + dictWord{7, 10, 945}, + dictWord{11, 10, 713}, + dictWord{139, 10, 744}, + dictWord{139, 10, 1022}, + dictWord{9, 0, 635}, + dictWord{139, 0, 559}, + dictWord{5, 11, 923}, + dictWord{7, 11, 490}, + dictWord{ + 12, + 11, + 553, + }, + dictWord{13, 11, 100}, + dictWord{14, 11, 118}, + dictWord{143, 11, 75}, + dictWord{132, 0, 975}, + dictWord{132, 10, 567}, + dictWord{137, 10, 859}, + dictWord{7, 10, 1846}, + dictWord{7, 11, 1846}, + dictWord{8, 10, 628}, + dictWord{136, 11, 628}, + dictWord{148, 0, 116}, + dictWord{138, 11, 750}, + dictWord{14, 0, 51}, + dictWord{14, 11, 51}, + dictWord{15, 11, 7}, + dictWord{148, 11, 20}, + dictWord{132, 0, 858}, + dictWord{134, 0, 1075}, + dictWord{4, 11, 924}, + dictWord{ + 133, + 10, + 762, + }, + dictWord{136, 0, 535}, + dictWord{133, 0, 448}, + dictWord{10, 10, 784}, + dictWord{141, 10, 191}, + dictWord{133, 10, 298}, + dictWord{7, 0, 610}, + dictWord{135, 0, 1501}, + dictWord{7, 10, 633}, + dictWord{7, 10, 905}, + dictWord{7, 10, 909}, + dictWord{7, 10, 1538}, + dictWord{9, 10, 767}, + dictWord{140, 10, 636}, + dictWord{4, 11, 265}, + dictWord{7, 11, 807}, + dictWord{135, 11, 950}, + dictWord{5, 11, 93}, + dictWord{12, 11, 267}, + dictWord{144, 11, 26}, + dictWord{136, 0, 191}, + dictWord{139, 10, 301}, + dictWord{135, 10, 1970}, + dictWord{135, 0, 267}, + dictWord{4, 0, 319}, + dictWord{5, 0, 699}, + dictWord{138, 0, 673}, + dictWord{ + 6, + 0, + 336, + }, + dictWord{7, 0, 92}, + dictWord{7, 0, 182}, + dictWord{8, 0, 453}, + dictWord{8, 0, 552}, + dictWord{9, 0, 204}, + dictWord{9, 0, 285}, + dictWord{10, 0, 99}, + dictWord{ + 11, + 0, + 568, + }, + dictWord{11, 0, 950}, + dictWord{12, 0, 94}, + dictWord{16, 0, 20}, + dictWord{16, 0, 70}, + dictWord{19, 0, 55}, + dictWord{12, 10, 644}, + dictWord{144, 10, 90}, + dictWord{6, 0, 551}, + dictWord{7, 0, 1308}, + dictWord{7, 10, 845}, + dictWord{7, 11, 994}, + dictWord{8, 10, 160}, + dictWord{137, 10, 318}, + dictWord{19, 11, 1}, + dictWord{ + 19, + 11, + 26, + }, + dictWord{150, 11, 9}, + dictWord{7, 0, 1406}, + dictWord{9, 0, 218}, + dictWord{141, 0, 222}, + dictWord{5, 0, 256}, + dictWord{138, 0, 69}, + dictWord{ + 5, + 11, + 233, + }, + dictWord{5, 11, 320}, + dictWord{6, 11, 140}, + dictWord{7, 11, 330}, + dictWord{136, 11, 295}, + dictWord{6, 0, 1980}, + dictWord{136, 0, 952}, + dictWord{ + 4, + 0, + 833, + }, + dictWord{137, 11, 678}, + dictWord{133, 11, 978}, + dictWord{4, 11, 905}, + dictWord{6, 11, 1701}, + dictWord{137, 11, 843}, + dictWord{138, 10, 735}, + dictWord{136, 10, 76}, + dictWord{17, 0, 39}, + dictWord{148, 0, 36}, + dictWord{18, 0, 81}, + dictWord{146, 11, 81}, + dictWord{14, 0, 352}, + dictWord{17, 0, 53}, + dictWord{ + 18, + 0, + 146, + }, + dictWord{18, 0, 152}, + dictWord{19, 0, 11}, + dictWord{150, 0, 54}, + dictWord{135, 0, 634}, + dictWord{138, 10, 841}, + dictWord{132, 0, 618}, + dictWord{ + 4, + 0, + 339, + }, + dictWord{7, 0, 259}, + dictWord{17, 0, 73}, + dictWord{4, 11, 275}, + dictWord{140, 11, 376}, + dictWord{132, 11, 509}, + dictWord{7, 11, 273}, + dictWord{ + 139, + 11, + 377, + }, + dictWord{4, 0, 759}, + dictWord{13, 0, 169}, + dictWord{137, 10, 804}, + dictWord{6, 10, 96}, + dictWord{135, 10, 1426}, + dictWord{4, 10, 651}, + dictWord{133, 10, 289}, + dictWord{7, 0, 1075}, + dictWord{8, 10, 35}, + dictWord{9, 10, 511}, + dictWord{10, 10, 767}, + dictWord{147, 10, 118}, + dictWord{6, 0, 649}, + dictWord{6, 0, 670}, + dictWord{136, 0, 482}, + dictWord{5, 0, 336}, + dictWord{6, 0, 341}, + dictWord{6, 0, 478}, + dictWord{6, 0, 1763}, + dictWord{136, 0, 386}, + dictWord{ + 5, + 11, + 802, + }, + dictWord{7, 11, 2021}, + dictWord{8, 11, 805}, + dictWord{14, 11, 94}, + dictWord{15, 11, 65}, + dictWord{16, 11, 4}, + dictWord{16, 11, 77}, + dictWord{16, 11, 80}, + dictWord{145, 11, 5}, + dictWord{6, 0, 1035}, + dictWord{5, 11, 167}, + dictWord{5, 11, 899}, + dictWord{6, 11, 410}, + dictWord{137, 11, 777}, + dictWord{ + 134, + 11, + 1705, + }, + dictWord{5, 0, 924}, + dictWord{133, 0, 969}, + dictWord{132, 10, 704}, + dictWord{135, 0, 73}, + dictWord{135, 11, 10}, + dictWord{135, 10, 1078}, + dictWord{ + 5, + 11, + 11, + }, + dictWord{6, 11, 117}, + dictWord{6, 11, 485}, + dictWord{7, 11, 1133}, + dictWord{9, 11, 582}, + dictWord{9, 11, 594}, + dictWord{11, 11, 21}, + dictWord{ + 11, + 11, + 818, + }, + dictWord{12, 11, 535}, + dictWord{141, 11, 86}, + dictWord{135, 0, 1971}, + dictWord{4, 11, 264}, + dictWord{7, 11, 1067}, + dictWord{8, 11, 204}, + dictWord{8, 11, 385}, + dictWord{139, 11, 953}, + dictWord{6, 0, 1458}, + dictWord{135, 0, 1344}, + dictWord{5, 0, 396}, + dictWord{134, 0, 501}, + dictWord{4, 10, 720}, + dictWord{133, 10, 306}, + dictWord{4, 0, 929}, + dictWord{5, 0, 799}, + dictWord{8, 0, 46}, + dictWord{8, 0, 740}, + dictWord{133, 10, 431}, + dictWord{7, 11, 646}, + dictWord{ + 7, + 11, + 1730, + }, + dictWord{11, 11, 446}, + dictWord{141, 11, 178}, + dictWord{7, 0, 276}, + dictWord{5, 10, 464}, + dictWord{6, 10, 236}, + dictWord{7, 10, 696}, + dictWord{ + 7, + 10, + 914, + }, + dictWord{7, 10, 1108}, + dictWord{7, 10, 1448}, + dictWord{9, 10, 15}, + dictWord{9, 10, 564}, + dictWord{10, 10, 14}, + dictWord{12, 10, 565}, + dictWord{ + 13, + 10, + 449, + }, + dictWord{14, 10, 53}, + dictWord{15, 10, 13}, + dictWord{16, 10, 64}, + dictWord{145, 10, 41}, + dictWord{4, 0, 892}, + dictWord{133, 0, 770}, + dictWord{ + 6, + 10, + 1767, + }, + dictWord{12, 10, 194}, + dictWord{145, 10, 107}, + dictWord{135, 0, 158}, + dictWord{5, 10, 840}, + dictWord{138, 11, 608}, + dictWord{134, 0, 1432}, + dictWord{138, 11, 250}, + dictWord{8, 11, 794}, + dictWord{9, 11, 400}, + dictWord{10, 11, 298}, + dictWord{142, 11, 228}, + dictWord{151, 0, 25}, + dictWord{ + 7, + 11, + 1131, + }, + dictWord{135, 11, 1468}, + dictWord{135, 0, 2001}, + dictWord{9, 10, 642}, + dictWord{11, 10, 236}, + dictWord{142, 10, 193}, + dictWord{4, 10, 68}, + dictWord{5, 10, 634}, + dictWord{6, 10, 386}, + dictWord{7, 10, 794}, + dictWord{8, 10, 273}, + dictWord{9, 10, 563}, + dictWord{10, 10, 105}, + dictWord{10, 10, 171}, + dictWord{11, 10, 94}, + dictWord{139, 10, 354}, + dictWord{136, 11, 724}, + dictWord{132, 0, 478}, + dictWord{11, 11, 512}, + dictWord{13, 11, 205}, + dictWord{ + 19, + 11, + 30, + }, + dictWord{22, 11, 36}, + dictWord{151, 11, 19}, + dictWord{7, 0, 1461}, + dictWord{140, 0, 91}, + dictWord{6, 11, 190}, + dictWord{7, 11, 768}, + dictWord{ + 135, + 11, + 1170, + }, + dictWord{4, 0, 602}, + dictWord{8, 0, 211}, + dictWord{4, 10, 95}, + dictWord{7, 10, 416}, + dictWord{139, 10, 830}, + dictWord{7, 10, 731}, + dictWord{13, 10, 20}, + dictWord{143, 10, 11}, + dictWord{6, 0, 1068}, + dictWord{135, 0, 1872}, + dictWord{4, 0, 13}, + dictWord{5, 0, 567}, + dictWord{7, 0, 1498}, + dictWord{9, 0, 124}, + dictWord{11, 0, 521}, + dictWord{12, 0, 405}, + dictWord{135, 11, 1023}, + dictWord{135, 0, 1006}, + dictWord{132, 0, 735}, + dictWord{138, 0, 812}, + dictWord{4, 0, 170}, + dictWord{135, 0, 323}, + dictWord{6, 11, 137}, + dictWord{9, 11, 75}, + dictWord{9, 11, 253}, + dictWord{10, 11, 194}, + dictWord{138, 11, 444}, + dictWord{5, 0, 304}, + dictWord{7, 0, 1403}, + dictWord{5, 10, 864}, + dictWord{10, 10, 648}, + dictWord{11, 10, 671}, + dictWord{143, 10, 46}, + dictWord{135, 11, 1180}, + dictWord{ + 133, + 10, + 928, + }, + dictWord{4, 0, 148}, + dictWord{133, 0, 742}, + dictWord{11, 10, 986}, + dictWord{140, 10, 682}, + dictWord{133, 0, 523}, + dictWord{135, 11, 1743}, + dictWord{7, 0, 730}, + dictWord{18, 0, 144}, + dictWord{19, 0, 61}, + dictWord{8, 10, 44}, + dictWord{9, 10, 884}, + dictWord{10, 10, 580}, + dictWord{11, 10, 399}, + dictWord{ + 11, + 10, + 894, + }, + dictWord{143, 10, 122}, + dictWord{5, 11, 760}, + dictWord{7, 11, 542}, + dictWord{8, 11, 135}, + dictWord{136, 11, 496}, + dictWord{136, 0, 981}, + dictWord{133, 0, 111}, + dictWord{10, 0, 132}, + dictWord{11, 0, 191}, + dictWord{11, 0, 358}, + dictWord{139, 0, 460}, + dictWord{7, 11, 319}, + dictWord{7, 11, 355}, + dictWord{ + 7, + 11, + 763, + }, + dictWord{10, 11, 389}, + dictWord{145, 11, 43}, + dictWord{134, 0, 890}, + dictWord{134, 0, 1420}, + dictWord{136, 11, 557}, + dictWord{ + 133, + 10, + 518, + }, + dictWord{133, 0, 444}, + dictWord{135, 0, 1787}, + dictWord{135, 10, 1852}, + dictWord{8, 0, 123}, + dictWord{15, 0, 6}, + dictWord{144, 0, 7}, + dictWord{ + 6, + 0, + 2041, + }, + dictWord{10, 11, 38}, + dictWord{139, 11, 784}, + dictWord{136, 0, 932}, + dictWord{5, 0, 937}, + dictWord{135, 0, 100}, + dictWord{6, 0, 995}, + dictWord{ + 4, + 11, + 58, + }, + dictWord{5, 11, 286}, + dictWord{6, 11, 319}, + dictWord{7, 11, 402}, + dictWord{7, 11, 1254}, + dictWord{7, 11, 1903}, + dictWord{8, 11, 356}, + dictWord{ + 140, + 11, + 408, + }, + dictWord{4, 11, 389}, + dictWord{9, 11, 181}, + dictWord{9, 11, 255}, + dictWord{10, 11, 8}, + dictWord{10, 11, 29}, + dictWord{10, 11, 816}, + dictWord{ + 11, + 11, + 311, + }, + dictWord{11, 11, 561}, + dictWord{12, 11, 67}, + dictWord{141, 11, 181}, + dictWord{138, 0, 255}, + dictWord{5, 0, 138}, + dictWord{4, 10, 934}, + dictWord{ + 136, + 10, + 610, + }, + dictWord{4, 0, 965}, + dictWord{10, 0, 863}, + dictWord{138, 0, 898}, + dictWord{10, 10, 804}, + dictWord{138, 10, 832}, + dictWord{12, 0, 631}, + dictWord{ + 8, + 10, + 96, + }, + dictWord{9, 10, 36}, + dictWord{10, 10, 607}, + dictWord{11, 10, 423}, + dictWord{11, 10, 442}, + dictWord{12, 10, 309}, + dictWord{14, 10, 199}, + dictWord{ + 15, + 10, + 90, + }, + dictWord{145, 10, 110}, + dictWord{134, 0, 1394}, + dictWord{4, 0, 652}, + dictWord{8, 0, 320}, + dictWord{22, 0, 6}, + dictWord{22, 0, 16}, + dictWord{ + 9, + 10, + 13, + }, + dictWord{9, 10, 398}, + dictWord{9, 10, 727}, + dictWord{10, 10, 75}, + dictWord{10, 10, 184}, + dictWord{10, 10, 230}, + dictWord{10, 10, 564}, + dictWord{ + 10, + 10, + 569, + }, + dictWord{11, 10, 973}, + dictWord{12, 10, 70}, + dictWord{12, 10, 189}, + dictWord{13, 10, 57}, + dictWord{141, 10, 257}, + dictWord{6, 0, 897}, + dictWord{ + 134, + 0, + 1333, + }, + dictWord{4, 0, 692}, + dictWord{133, 0, 321}, + dictWord{133, 11, 373}, + dictWord{135, 0, 922}, + dictWord{5, 0, 619}, + dictWord{133, 0, 698}, + dictWord{ + 137, + 10, + 631, + }, + dictWord{5, 10, 345}, + dictWord{135, 10, 1016}, + dictWord{9, 0, 957}, + dictWord{9, 0, 1018}, + dictWord{12, 0, 828}, + dictWord{12, 0, 844}, + dictWord{ + 12, + 0, + 897, + }, + dictWord{12, 0, 901}, + dictWord{12, 0, 943}, + dictWord{15, 0, 180}, + dictWord{18, 0, 197}, + dictWord{18, 0, 200}, + dictWord{18, 0, 213}, + dictWord{ + 18, + 0, + 214, + }, + dictWord{146, 0, 226}, + dictWord{5, 0, 917}, + dictWord{134, 0, 1659}, + dictWord{135, 0, 1100}, + dictWord{134, 0, 1173}, + dictWord{134, 0, 1930}, + dictWord{5, 0, 251}, + dictWord{5, 0, 956}, + dictWord{8, 0, 268}, + dictWord{9, 0, 214}, + dictWord{146, 0, 142}, + dictWord{133, 10, 673}, + dictWord{137, 10, 850}, + dictWord{ + 4, + 10, + 287, + }, + dictWord{133, 10, 1018}, + dictWord{132, 11, 672}, + dictWord{5, 0, 346}, + dictWord{5, 0, 711}, + dictWord{8, 0, 390}, + dictWord{11, 11, 752}, + dictWord{139, 11, 885}, + dictWord{5, 10, 34}, + dictWord{10, 10, 724}, + dictWord{12, 10, 444}, + dictWord{13, 10, 354}, + dictWord{18, 10, 32}, + dictWord{23, 10, 24}, + dictWord{23, 10, 31}, + dictWord{152, 10, 5}, + dictWord{4, 11, 710}, + dictWord{134, 11, 606}, + dictWord{134, 0, 744}, + dictWord{134, 10, 382}, + dictWord{ + 133, + 11, + 145, + }, + dictWord{4, 10, 329}, + dictWord{7, 11, 884}, + dictWord{140, 11, 124}, + dictWord{4, 11, 467}, + dictWord{5, 11, 405}, + dictWord{134, 11, 544}, + dictWord{ + 9, + 10, + 846, + }, + dictWord{138, 10, 827}, + dictWord{133, 0, 624}, + dictWord{9, 11, 372}, + dictWord{15, 11, 2}, + dictWord{19, 11, 10}, + dictWord{147, 11, 18}, + dictWord{ + 4, + 11, + 387, + }, + dictWord{135, 11, 1288}, + dictWord{5, 0, 783}, + dictWord{7, 0, 1998}, + dictWord{135, 0, 2047}, + dictWord{132, 10, 906}, + dictWord{136, 10, 366}, + dictWord{135, 11, 550}, + dictWord{4, 10, 123}, + dictWord{4, 10, 649}, + dictWord{5, 10, 605}, + dictWord{7, 10, 1509}, + dictWord{136, 10, 36}, + dictWord{ + 134, + 0, + 1125, + }, + dictWord{132, 0, 594}, + dictWord{133, 10, 767}, + dictWord{135, 11, 1227}, + dictWord{136, 11, 467}, + dictWord{4, 11, 576}, + dictWord{ + 135, + 11, + 1263, + }, + dictWord{4, 0, 268}, + dictWord{7, 0, 1534}, + dictWord{135, 11, 1534}, + dictWord{4, 10, 273}, + dictWord{5, 10, 658}, + dictWord{5, 11, 919}, + dictWord{ + 5, + 10, + 995, + }, + dictWord{134, 11, 1673}, + dictWord{133, 0, 563}, + dictWord{134, 10, 72}, + dictWord{135, 10, 1345}, + dictWord{4, 11, 82}, + dictWord{5, 11, 333}, + dictWord{ + 5, + 11, + 904, + }, + dictWord{6, 11, 207}, + dictWord{7, 11, 325}, + dictWord{7, 11, 1726}, + dictWord{8, 11, 101}, + dictWord{10, 11, 778}, + dictWord{139, 11, 220}, + dictWord{5, 0, 37}, + dictWord{6, 0, 39}, + dictWord{6, 0, 451}, + dictWord{7, 0, 218}, + dictWord{7, 0, 667}, + dictWord{7, 0, 1166}, + dictWord{7, 0, 1687}, + dictWord{8, 0, 662}, + dictWord{16, 0, 2}, + dictWord{133, 10, 589}, + dictWord{134, 0, 1332}, + dictWord{133, 11, 903}, + dictWord{134, 0, 508}, + dictWord{5, 10, 117}, + dictWord{6, 10, 514}, + dictWord{6, 10, 541}, + dictWord{7, 10, 1164}, + dictWord{7, 10, 1436}, + dictWord{8, 10, 220}, + dictWord{8, 10, 648}, + dictWord{10, 10, 688}, + dictWord{11, 10, 560}, + dictWord{140, 11, 147}, + dictWord{6, 11, 555}, + dictWord{135, 11, 485}, + dictWord{133, 10, 686}, + dictWord{7, 0, 453}, + dictWord{7, 0, 635}, + dictWord{7, 0, 796}, + dictWord{8, 0, 331}, + dictWord{9, 0, 330}, + dictWord{9, 0, 865}, + dictWord{10, 0, 119}, + dictWord{10, 0, 235}, + dictWord{11, 0, 111}, + dictWord{11, 0, 129}, + dictWord{ + 11, + 0, + 240, + }, + dictWord{12, 0, 31}, + dictWord{12, 0, 66}, + dictWord{12, 0, 222}, + dictWord{12, 0, 269}, + dictWord{12, 0, 599}, + dictWord{12, 0, 684}, + dictWord{12, 0, 689}, + dictWord{12, 0, 691}, + dictWord{142, 0, 345}, + dictWord{135, 0, 1834}, + dictWord{4, 11, 705}, + dictWord{7, 11, 615}, + dictWord{138, 11, 251}, + dictWord{ + 136, + 11, + 345, + }, + dictWord{137, 0, 527}, + dictWord{6, 0, 98}, + dictWord{7, 0, 702}, + dictWord{135, 0, 991}, + dictWord{11, 0, 576}, + dictWord{14, 0, 74}, + dictWord{7, 10, 196}, + dictWord{10, 10, 765}, + dictWord{11, 10, 347}, + dictWord{11, 10, 552}, + dictWord{11, 10, 790}, + dictWord{12, 10, 263}, + dictWord{13, 10, 246}, + dictWord{ + 13, + 10, + 270, + }, + dictWord{13, 10, 395}, + dictWord{14, 10, 176}, + dictWord{14, 10, 190}, + dictWord{14, 10, 398}, + dictWord{14, 10, 412}, + dictWord{15, 10, 32}, + dictWord{ + 15, + 10, + 63, + }, + dictWord{16, 10, 88}, + dictWord{147, 10, 105}, + dictWord{134, 11, 90}, + dictWord{13, 0, 84}, + dictWord{141, 0, 122}, + dictWord{6, 0, 37}, + dictWord{ + 7, + 0, + 299, + }, + dictWord{7, 0, 1666}, + dictWord{8, 0, 195}, + dictWord{8, 0, 316}, + dictWord{9, 0, 178}, + dictWord{9, 0, 276}, + dictWord{9, 0, 339}, + dictWord{9, 0, 536}, + dictWord{ + 10, + 0, + 102, + }, + dictWord{10, 0, 362}, + dictWord{10, 0, 785}, + dictWord{11, 0, 55}, + dictWord{11, 0, 149}, + dictWord{11, 0, 773}, + dictWord{13, 0, 416}, + dictWord{ + 13, + 0, + 419, + }, + dictWord{14, 0, 38}, + dictWord{14, 0, 41}, + dictWord{142, 0, 210}, + dictWord{5, 10, 381}, + dictWord{135, 10, 1792}, + dictWord{7, 11, 813}, + dictWord{ + 12, + 11, + 497, + }, + dictWord{141, 11, 56}, + dictWord{7, 10, 616}, + dictWord{138, 10, 413}, + dictWord{133, 0, 645}, + dictWord{6, 11, 125}, + dictWord{135, 11, 1277}, + dictWord{132, 0, 290}, + dictWord{6, 0, 70}, + dictWord{7, 0, 1292}, + dictWord{10, 0, 762}, + dictWord{139, 0, 288}, + dictWord{6, 10, 120}, + dictWord{7, 10, 1188}, + dictWord{ + 7, + 10, + 1710, + }, + dictWord{8, 10, 286}, + dictWord{9, 10, 667}, + dictWord{11, 10, 592}, + dictWord{139, 10, 730}, + dictWord{135, 11, 1784}, + dictWord{7, 0, 1315}, + dictWord{135, 11, 1315}, + dictWord{134, 0, 1955}, + dictWord{135, 10, 1146}, + dictWord{7, 0, 131}, + dictWord{7, 0, 422}, + dictWord{8, 0, 210}, + dictWord{ + 140, + 0, + 573, + }, + dictWord{4, 10, 352}, + dictWord{135, 10, 687}, + dictWord{139, 0, 797}, + dictWord{143, 0, 38}, + dictWord{14, 0, 179}, + dictWord{15, 0, 151}, + dictWord{ + 150, + 0, + 11, + }, + dictWord{7, 0, 488}, + dictWord{4, 10, 192}, + dictWord{5, 10, 49}, + dictWord{6, 10, 200}, + dictWord{6, 10, 293}, + dictWord{134, 10, 1696}, + dictWord{ + 132, + 0, + 936, + }, + dictWord{135, 11, 703}, + dictWord{6, 11, 160}, + dictWord{7, 11, 1106}, + dictWord{9, 11, 770}, + dictWord{10, 11, 618}, + dictWord{11, 11, 112}, + dictWord{ + 140, + 11, + 413, + }, + dictWord{5, 0, 453}, + dictWord{134, 0, 441}, + dictWord{135, 0, 595}, + dictWord{132, 10, 650}, + dictWord{132, 10, 147}, + dictWord{6, 0, 991}, + dictWord{6, 0, 1182}, + dictWord{12, 11, 271}, + dictWord{145, 11, 109}, + dictWord{133, 10, 934}, + dictWord{140, 11, 221}, + dictWord{132, 0, 653}, + dictWord{ + 7, + 0, + 505, + }, + dictWord{135, 0, 523}, + dictWord{134, 0, 903}, + dictWord{135, 11, 479}, + dictWord{7, 11, 304}, + dictWord{9, 11, 646}, + dictWord{9, 11, 862}, + dictWord{ + 10, + 11, + 262, + }, + dictWord{11, 11, 696}, + dictWord{12, 11, 208}, + dictWord{15, 11, 79}, + dictWord{147, 11, 108}, + dictWord{146, 0, 80}, + dictWord{135, 11, 981}, + dictWord{142, 0, 432}, + dictWord{132, 0, 314}, + dictWord{137, 11, 152}, + dictWord{7, 0, 1368}, + dictWord{8, 0, 232}, + dictWord{8, 0, 361}, + dictWord{10, 0, 682}, + dictWord{138, 0, 742}, + dictWord{135, 11, 1586}, + dictWord{9, 0, 534}, + dictWord{4, 11, 434}, + dictWord{11, 11, 663}, + dictWord{12, 11, 210}, + dictWord{13, 11, 166}, + dictWord{13, 11, 310}, + dictWord{14, 11, 373}, + dictWord{147, 11, 43}, + dictWord{7, 11, 1091}, + dictWord{135, 11, 1765}, + dictWord{6, 11, 550}, + dictWord{ + 135, + 11, + 652, + }, + dictWord{137, 0, 27}, + dictWord{142, 0, 12}, + dictWord{4, 10, 637}, + dictWord{5, 11, 553}, + dictWord{7, 11, 766}, + dictWord{138, 11, 824}, + dictWord{ + 7, + 11, + 737, + }, + dictWord{8, 11, 298}, + dictWord{136, 11, 452}, + dictWord{7, 0, 736}, + dictWord{139, 0, 264}, + dictWord{134, 0, 1657}, + dictWord{133, 11, 292}, + dictWord{138, 11, 135}, + dictWord{6, 0, 844}, + dictWord{134, 0, 1117}, + dictWord{135, 0, 127}, + dictWord{9, 10, 867}, + dictWord{138, 10, 837}, + dictWord{ + 6, + 0, + 1184, + }, + dictWord{134, 0, 1208}, + dictWord{134, 0, 1294}, + dictWord{136, 0, 364}, + dictWord{6, 0, 1415}, + dictWord{7, 0, 1334}, + dictWord{11, 0, 125}, + dictWord{ + 6, + 10, + 170, + }, + dictWord{7, 11, 393}, + dictWord{8, 10, 395}, + dictWord{8, 10, 487}, + dictWord{10, 11, 603}, + dictWord{11, 11, 206}, + dictWord{141, 10, 147}, + dictWord{137, 11, 748}, + dictWord{4, 11, 912}, + dictWord{137, 11, 232}, + dictWord{4, 10, 535}, + dictWord{136, 10, 618}, + dictWord{137, 0, 792}, + dictWord{ + 7, + 11, + 1973, + }, + dictWord{136, 11, 716}, + dictWord{135, 11, 98}, + dictWord{5, 0, 909}, + dictWord{9, 0, 849}, + dictWord{138, 0, 805}, + dictWord{4, 0, 630}, + dictWord{ + 132, + 0, + 699, + }, + dictWord{5, 11, 733}, + dictWord{14, 11, 103}, + dictWord{150, 10, 23}, + dictWord{12, 11, 158}, + dictWord{18, 11, 8}, + dictWord{19, 11, 62}, + dictWord{ + 20, + 11, + 6, + }, + dictWord{22, 11, 4}, + dictWord{23, 11, 2}, + dictWord{151, 11, 9}, + dictWord{132, 0, 968}, + dictWord{132, 10, 778}, + dictWord{132, 10, 46}, + dictWord{5, 10, 811}, + dictWord{6, 10, 1679}, + dictWord{6, 10, 1714}, + dictWord{135, 10, 2032}, + dictWord{6, 0, 1446}, + dictWord{7, 10, 1458}, + dictWord{9, 10, 407}, + dictWord{ + 139, + 10, + 15, + }, + dictWord{7, 0, 206}, + dictWord{7, 0, 397}, + dictWord{7, 0, 621}, + dictWord{7, 0, 640}, + dictWord{8, 0, 124}, + dictWord{8, 0, 619}, + dictWord{9, 0, 305}, + dictWord{ + 9, + 0, + 643, + }, + dictWord{10, 0, 264}, + dictWord{10, 0, 628}, + dictWord{11, 0, 40}, + dictWord{12, 0, 349}, + dictWord{13, 0, 134}, + dictWord{13, 0, 295}, + dictWord{ + 14, + 0, + 155, + }, + dictWord{15, 0, 120}, + dictWord{18, 0, 105}, + dictWord{6, 10, 34}, + dictWord{7, 10, 1089}, + dictWord{8, 10, 708}, + dictWord{8, 10, 721}, + dictWord{9, 10, 363}, + dictWord{148, 10, 98}, + dictWord{4, 0, 262}, + dictWord{5, 0, 641}, + dictWord{135, 0, 342}, + dictWord{137, 11, 72}, + dictWord{4, 0, 99}, + dictWord{6, 0, 250}, + dictWord{ + 6, + 0, + 346, + }, + dictWord{8, 0, 127}, + dictWord{138, 0, 81}, + dictWord{132, 0, 915}, + dictWord{5, 0, 75}, + dictWord{9, 0, 517}, + dictWord{10, 0, 470}, + dictWord{12, 0, 155}, + dictWord{141, 0, 224}, + dictWord{132, 10, 462}, + dictWord{11, 11, 600}, + dictWord{11, 11, 670}, + dictWord{141, 11, 245}, + dictWord{142, 0, 83}, + dictWord{ + 5, + 10, + 73, + }, + dictWord{6, 10, 23}, + dictWord{134, 10, 338}, + dictWord{6, 0, 1031}, + dictWord{139, 11, 923}, + dictWord{7, 11, 164}, + dictWord{7, 11, 1571}, + dictWord{ + 9, + 11, + 107, + }, + dictWord{140, 11, 225}, + dictWord{134, 0, 1470}, + dictWord{133, 0, 954}, + dictWord{6, 0, 304}, + dictWord{8, 0, 418}, + dictWord{10, 0, 345}, + dictWord{ + 11, + 0, + 341, + }, + dictWord{139, 0, 675}, + dictWord{9, 0, 410}, + dictWord{139, 0, 425}, + dictWord{4, 11, 27}, + dictWord{5, 11, 484}, + dictWord{5, 11, 510}, + dictWord{6, 11, 434}, + dictWord{7, 11, 1000}, + dictWord{7, 11, 1098}, + dictWord{8, 11, 2}, + dictWord{136, 11, 200}, + dictWord{134, 0, 734}, + dictWord{140, 11, 257}, + dictWord{ + 7, + 10, + 725, + }, + dictWord{8, 10, 498}, + dictWord{139, 10, 268}, + dictWord{134, 0, 1822}, + dictWord{135, 0, 1798}, + dictWord{135, 10, 773}, + dictWord{132, 11, 460}, + dictWord{4, 11, 932}, + dictWord{133, 11, 891}, + dictWord{134, 0, 14}, + dictWord{132, 10, 583}, + dictWord{7, 10, 1462}, + dictWord{8, 11, 625}, + dictWord{ + 139, + 10, + 659, + }, + dictWord{5, 0, 113}, + dictWord{6, 0, 243}, + dictWord{6, 0, 1708}, + dictWord{7, 0, 1865}, + dictWord{11, 0, 161}, + dictWord{16, 0, 37}, + dictWord{17, 0, 99}, + dictWord{133, 10, 220}, + dictWord{134, 11, 76}, + dictWord{5, 11, 461}, + dictWord{135, 11, 1925}, + dictWord{140, 0, 69}, + dictWord{8, 11, 92}, + dictWord{ + 137, + 11, + 221, + }, + dictWord{139, 10, 803}, + dictWord{132, 10, 544}, + dictWord{4, 0, 274}, + dictWord{134, 0, 922}, + dictWord{132, 0, 541}, + dictWord{5, 0, 627}, + dictWord{ + 6, + 10, + 437, + }, + dictWord{6, 10, 564}, + dictWord{11, 10, 181}, + dictWord{141, 10, 183}, + dictWord{135, 10, 1192}, + dictWord{7, 0, 166}, + dictWord{132, 11, 763}, + dictWord{133, 11, 253}, + dictWord{134, 0, 849}, + dictWord{9, 11, 73}, + dictWord{10, 11, 110}, + dictWord{14, 11, 185}, + dictWord{145, 11, 119}, + dictWord{5, 11, 212}, + dictWord{12, 11, 35}, + dictWord{141, 11, 382}, + dictWord{133, 0, 717}, + dictWord{137, 0, 304}, + dictWord{136, 0, 600}, + dictWord{133, 0, 654}, + dictWord{ + 6, + 0, + 273, + }, + dictWord{10, 0, 188}, + dictWord{13, 0, 377}, + dictWord{146, 0, 77}, + dictWord{4, 10, 790}, + dictWord{5, 10, 273}, + dictWord{134, 10, 394}, + dictWord{ + 132, + 0, + 543, + }, + dictWord{135, 0, 410}, + dictWord{11, 0, 98}, + dictWord{11, 0, 524}, + dictWord{141, 0, 87}, + dictWord{132, 0, 941}, + dictWord{135, 11, 1175}, + dictWord{ + 4, + 0, + 250, + }, + dictWord{7, 0, 1612}, + dictWord{11, 0, 186}, + dictWord{12, 0, 133}, + dictWord{6, 10, 127}, + dictWord{7, 10, 1511}, + dictWord{8, 10, 613}, + dictWord{ + 12, + 10, + 495, + }, + dictWord{12, 10, 586}, + dictWord{12, 10, 660}, + dictWord{12, 10, 668}, + dictWord{14, 10, 385}, + dictWord{15, 10, 118}, + dictWord{17, 10, 20}, + dictWord{ + 146, + 10, + 98, + }, + dictWord{6, 0, 1785}, + dictWord{133, 11, 816}, + dictWord{134, 0, 1339}, + dictWord{7, 0, 961}, + dictWord{7, 0, 1085}, + dictWord{7, 0, 1727}, + dictWord{ + 8, + 0, + 462, + }, + dictWord{6, 10, 230}, + dictWord{135, 11, 1727}, + dictWord{9, 0, 636}, + dictWord{135, 10, 1954}, + dictWord{132, 0, 780}, + dictWord{5, 11, 869}, + dictWord{5, 11, 968}, + dictWord{6, 11, 1626}, + dictWord{8, 11, 734}, + dictWord{136, 11, 784}, + dictWord{4, 11, 542}, + dictWord{6, 11, 1716}, + dictWord{6, 11, 1727}, + dictWord{7, 11, 1082}, + dictWord{7, 11, 1545}, + dictWord{8, 11, 56}, + dictWord{8, 11, 118}, + dictWord{8, 11, 412}, + dictWord{8, 11, 564}, + dictWord{9, 11, 888}, + dictWord{9, 11, 908}, + dictWord{10, 11, 50}, + dictWord{10, 11, 423}, + dictWord{11, 11, 685}, + dictWord{11, 11, 697}, + dictWord{11, 11, 933}, + dictWord{12, 11, 299}, + dictWord{13, 11, 126}, + dictWord{13, 11, 136}, + dictWord{13, 11, 170}, + dictWord{141, 11, 190}, + dictWord{134, 11, 226}, + dictWord{4, 11, 232}, + dictWord{ + 9, + 11, + 202, + }, + dictWord{10, 11, 474}, + dictWord{140, 11, 433}, + dictWord{137, 11, 500}, + dictWord{5, 0, 529}, + dictWord{136, 10, 68}, + dictWord{132, 10, 654}, + dictWord{ + 4, + 10, + 156, + }, + dictWord{7, 10, 998}, + dictWord{7, 10, 1045}, + dictWord{7, 10, 1860}, + dictWord{9, 10, 48}, + dictWord{9, 10, 692}, + dictWord{11, 10, 419}, + dictWord{139, 10, 602}, + dictWord{7, 0, 1276}, + dictWord{8, 0, 474}, + dictWord{9, 0, 652}, + dictWord{6, 11, 108}, + dictWord{7, 11, 1003}, + dictWord{7, 11, 1181}, + dictWord{136, 11, 343}, + dictWord{7, 11, 1264}, + dictWord{7, 11, 1678}, + dictWord{11, 11, 945}, + dictWord{12, 11, 341}, + dictWord{12, 11, 471}, + dictWord{ + 140, + 11, + 569, + }, + dictWord{134, 11, 1712}, + dictWord{5, 0, 948}, + dictWord{12, 0, 468}, + dictWord{19, 0, 96}, + dictWord{148, 0, 24}, + dictWord{4, 11, 133}, + dictWord{ + 7, + 11, + 711, + }, + dictWord{7, 11, 1298}, + dictWord{7, 11, 1585}, + dictWord{135, 11, 1929}, + dictWord{6, 0, 753}, + dictWord{140, 0, 657}, + dictWord{139, 0, 941}, + dictWord{ + 6, + 11, + 99, + }, + dictWord{7, 11, 1808}, + dictWord{145, 11, 57}, + dictWord{6, 11, 574}, + dictWord{7, 11, 428}, + dictWord{7, 11, 1250}, + dictWord{10, 11, 669}, + dictWord{ + 11, + 11, + 485, + }, + dictWord{11, 11, 840}, + dictWord{12, 11, 300}, + dictWord{142, 11, 250}, + dictWord{4, 0, 532}, + dictWord{5, 0, 706}, + dictWord{135, 0, 662}, + dictWord{ + 5, + 0, + 837, + }, + dictWord{6, 0, 1651}, + dictWord{139, 0, 985}, + dictWord{7, 0, 1861}, + dictWord{9, 10, 197}, + dictWord{10, 10, 300}, + dictWord{12, 10, 473}, + dictWord{ + 13, + 10, + 90, + }, + dictWord{141, 10, 405}, + dictWord{137, 11, 252}, + dictWord{6, 11, 323}, + dictWord{135, 11, 1564}, + dictWord{4, 0, 330}, + dictWord{4, 0, 863}, + dictWord{7, 0, 933}, + dictWord{7, 0, 2012}, + dictWord{8, 0, 292}, + dictWord{7, 11, 461}, + dictWord{8, 11, 775}, + dictWord{138, 11, 435}, + dictWord{132, 10, 606}, + dictWord{ + 4, + 11, + 655, + }, + dictWord{7, 11, 850}, + dictWord{17, 11, 75}, + dictWord{146, 11, 137}, + dictWord{135, 0, 767}, + dictWord{7, 10, 1978}, + dictWord{136, 10, 676}, + dictWord{132, 0, 641}, + dictWord{135, 11, 1559}, + dictWord{134, 0, 1233}, + dictWord{137, 0, 242}, + dictWord{17, 0, 114}, + dictWord{4, 10, 361}, + dictWord{ + 133, + 10, + 315, + }, + dictWord{137, 0, 883}, + dictWord{132, 10, 461}, + dictWord{138, 0, 274}, + dictWord{134, 0, 2008}, + dictWord{134, 0, 1794}, + dictWord{4, 0, 703}, + dictWord{135, 0, 207}, + dictWord{12, 0, 285}, + dictWord{132, 10, 472}, + dictWord{132, 0, 571}, + dictWord{5, 0, 873}, + dictWord{5, 0, 960}, + dictWord{8, 0, 823}, + dictWord{9, 0, 881}, + dictWord{136, 11, 577}, + dictWord{7, 0, 617}, + dictWord{10, 0, 498}, + dictWord{11, 0, 501}, + dictWord{12, 0, 16}, + dictWord{140, 0, 150}, + dictWord{ + 138, + 10, + 747, + }, + dictWord{132, 0, 431}, + dictWord{133, 10, 155}, + dictWord{11, 0, 283}, + dictWord{11, 0, 567}, + dictWord{7, 10, 163}, + dictWord{8, 10, 319}, + dictWord{ + 9, + 10, + 402, + }, + dictWord{10, 10, 24}, + dictWord{10, 10, 681}, + dictWord{11, 10, 200}, + dictWord{12, 10, 253}, + dictWord{12, 10, 410}, + dictWord{142, 10, 219}, + dictWord{4, 11, 413}, + dictWord{5, 11, 677}, + dictWord{8, 11, 432}, + dictWord{140, 11, 280}, + dictWord{9, 0, 401}, + dictWord{5, 10, 475}, + dictWord{7, 10, 1780}, + dictWord{11, 10, 297}, + dictWord{11, 10, 558}, + dictWord{14, 10, 322}, + dictWord{147, 10, 76}, + dictWord{6, 0, 781}, + dictWord{9, 0, 134}, + dictWord{10, 0, 2}, + dictWord{ + 10, + 0, + 27, + }, + dictWord{10, 0, 333}, + dictWord{11, 0, 722}, + dictWord{143, 0, 1}, + dictWord{5, 0, 33}, + dictWord{6, 0, 470}, + dictWord{139, 0, 424}, + dictWord{ + 135, + 0, + 2006, + }, + dictWord{12, 0, 783}, + dictWord{135, 10, 1956}, + dictWord{136, 0, 274}, + dictWord{135, 0, 1882}, + dictWord{132, 0, 794}, + dictWord{135, 0, 1848}, + dictWord{5, 10, 944}, + dictWord{134, 10, 1769}, + dictWord{6, 0, 47}, + dictWord{7, 0, 90}, + dictWord{7, 0, 664}, + dictWord{7, 0, 830}, + dictWord{7, 0, 1380}, + dictWord{ + 7, + 0, + 2025, + }, + dictWord{8, 0, 448}, + dictWord{136, 0, 828}, + dictWord{132, 10, 144}, + dictWord{134, 0, 1199}, + dictWord{4, 11, 395}, + dictWord{139, 11, 762}, + dictWord{135, 11, 1504}, + dictWord{9, 0, 417}, + dictWord{137, 0, 493}, + dictWord{9, 11, 174}, + dictWord{10, 11, 164}, + dictWord{11, 11, 440}, + dictWord{11, 11, 841}, + dictWord{143, 11, 98}, + dictWord{134, 11, 426}, + dictWord{139, 11, 1002}, + dictWord{134, 0, 295}, + dictWord{134, 0, 816}, + dictWord{6, 10, 247}, + dictWord{ + 137, + 10, + 555, + }, + dictWord{133, 0, 1019}, + dictWord{4, 0, 620}, + dictWord{5, 11, 476}, + dictWord{10, 10, 280}, + dictWord{138, 10, 797}, + dictWord{139, 0, 464}, + dictWord{5, 11, 76}, + dictWord{6, 11, 458}, + dictWord{6, 11, 497}, + dictWord{7, 11, 764}, + dictWord{7, 11, 868}, + dictWord{9, 11, 658}, + dictWord{10, 11, 594}, + dictWord{ + 11, + 11, + 173, + }, + dictWord{11, 11, 566}, + dictWord{12, 11, 20}, + dictWord{12, 11, 338}, + dictWord{141, 11, 200}, + dictWord{134, 0, 208}, + dictWord{4, 11, 526}, + dictWord{7, 11, 1029}, + dictWord{135, 11, 1054}, + dictWord{132, 11, 636}, + dictWord{6, 11, 233}, + dictWord{7, 11, 660}, + dictWord{7, 11, 1124}, + dictWord{ + 17, + 11, + 31, + }, + dictWord{19, 11, 22}, + dictWord{151, 11, 14}, + dictWord{10, 0, 442}, + dictWord{133, 10, 428}, + dictWord{10, 0, 930}, + dictWord{140, 0, 778}, + dictWord{ + 6, + 0, + 68, + }, + dictWord{7, 0, 448}, + dictWord{7, 0, 1629}, + dictWord{7, 0, 1769}, + dictWord{7, 0, 1813}, + dictWord{8, 0, 442}, + dictWord{8, 0, 516}, + dictWord{9, 0, 710}, + dictWord{ + 10, + 0, + 282, + }, + dictWord{10, 0, 722}, + dictWord{7, 10, 1717}, + dictWord{138, 10, 546}, + dictWord{134, 0, 1128}, + dictWord{11, 0, 844}, + dictWord{12, 0, 104}, + dictWord{140, 0, 625}, + dictWord{4, 11, 432}, + dictWord{135, 11, 824}, + dictWord{138, 10, 189}, + dictWord{133, 0, 787}, + dictWord{133, 10, 99}, + dictWord{ + 4, + 11, + 279, + }, + dictWord{7, 11, 301}, + dictWord{137, 11, 362}, + dictWord{8, 0, 491}, + dictWord{4, 10, 397}, + dictWord{136, 10, 555}, + dictWord{4, 11, 178}, + dictWord{ + 133, + 11, + 399, + }, + dictWord{134, 0, 711}, + dictWord{144, 0, 9}, + dictWord{4, 0, 403}, + dictWord{5, 0, 441}, + dictWord{7, 0, 450}, + dictWord{10, 0, 840}, + dictWord{11, 0, 101}, + dictWord{12, 0, 193}, + dictWord{141, 0, 430}, + dictWord{135, 11, 1246}, + dictWord{12, 10, 398}, + dictWord{20, 10, 39}, + dictWord{21, 10, 11}, + dictWord{ + 150, + 10, + 41, + }, + dictWord{4, 10, 485}, + dictWord{7, 10, 353}, + dictWord{135, 10, 1523}, + dictWord{6, 10, 366}, + dictWord{7, 10, 1384}, + dictWord{7, 10, 1601}, + dictWord{ + 135, + 11, + 1912, + }, + dictWord{7, 0, 396}, + dictWord{10, 0, 160}, + dictWord{135, 11, 396}, + dictWord{137, 10, 282}, + dictWord{134, 11, 1692}, + dictWord{4, 10, 157}, + dictWord{5, 10, 471}, + dictWord{6, 11, 202}, + dictWord{10, 11, 448}, + dictWord{11, 11, 208}, + dictWord{12, 11, 360}, + dictWord{17, 11, 117}, + dictWord{ + 17, + 11, + 118, + }, + dictWord{18, 11, 27}, + dictWord{148, 11, 67}, + dictWord{133, 0, 679}, + dictWord{137, 0, 326}, + dictWord{136, 10, 116}, + dictWord{7, 11, 872}, + dictWord{ + 10, + 11, + 516, + }, + dictWord{139, 11, 167}, + dictWord{132, 11, 224}, + dictWord{5, 11, 546}, + dictWord{7, 11, 35}, + dictWord{8, 11, 11}, + dictWord{8, 11, 12}, + dictWord{ + 9, + 11, + 315, + }, + dictWord{9, 11, 533}, + dictWord{10, 11, 802}, + dictWord{11, 11, 166}, + dictWord{12, 11, 525}, + dictWord{142, 11, 243}, + dictWord{7, 0, 1128}, + dictWord{135, 11, 1920}, + dictWord{5, 11, 241}, + dictWord{8, 11, 242}, + dictWord{9, 11, 451}, + dictWord{10, 11, 667}, + dictWord{11, 11, 598}, + dictWord{ + 140, + 11, + 429, + }, + dictWord{6, 0, 737}, + dictWord{5, 10, 160}, + dictWord{7, 10, 363}, + dictWord{7, 10, 589}, + dictWord{10, 10, 170}, + dictWord{141, 10, 55}, + dictWord{ + 135, + 0, + 1796, + }, + dictWord{142, 11, 254}, + dictWord{4, 0, 574}, + dictWord{7, 0, 350}, + dictWord{7, 0, 1024}, + dictWord{8, 0, 338}, + dictWord{9, 0, 677}, + dictWord{138, 0, 808}, + dictWord{134, 0, 1096}, + dictWord{137, 11, 516}, + dictWord{7, 0, 405}, + dictWord{10, 0, 491}, + dictWord{4, 10, 108}, + dictWord{4, 11, 366}, + dictWord{ + 139, + 10, + 498, + }, + dictWord{11, 11, 337}, + dictWord{142, 11, 303}, + dictWord{134, 11, 1736}, + dictWord{7, 0, 1081}, + dictWord{140, 11, 364}, + dictWord{7, 10, 1005}, + dictWord{140, 10, 609}, + dictWord{7, 0, 1676}, + dictWord{4, 10, 895}, + dictWord{133, 10, 772}, + dictWord{135, 0, 2037}, + dictWord{6, 0, 1207}, + dictWord{ + 11, + 11, + 916, + }, + dictWord{142, 11, 419}, + dictWord{14, 11, 140}, + dictWord{148, 11, 41}, + dictWord{6, 11, 331}, + dictWord{136, 11, 623}, + dictWord{9, 0, 944}, + dictWord{ + 9, + 0, + 969, + }, + dictWord{9, 0, 1022}, + dictWord{12, 0, 913}, + dictWord{12, 0, 936}, + dictWord{15, 0, 177}, + dictWord{15, 0, 193}, + dictWord{4, 10, 926}, + dictWord{ + 133, + 10, + 983, + }, + dictWord{5, 0, 354}, + dictWord{135, 11, 506}, + dictWord{8, 0, 598}, + dictWord{9, 0, 664}, + dictWord{138, 0, 441}, + dictWord{4, 11, 640}, + dictWord{ + 133, + 11, + 513, + }, + dictWord{137, 0, 297}, + dictWord{132, 10, 538}, + dictWord{6, 10, 294}, + dictWord{7, 10, 1267}, + dictWord{136, 10, 624}, + dictWord{7, 0, 1772}, + dictWord{ + 7, + 11, + 1888, + }, + dictWord{8, 11, 289}, + dictWord{11, 11, 45}, + dictWord{12, 11, 278}, + dictWord{140, 11, 537}, + dictWord{135, 10, 1325}, + dictWord{138, 0, 751}, + dictWord{141, 0, 37}, + dictWord{134, 0, 1828}, + dictWord{132, 10, 757}, + dictWord{132, 11, 394}, + dictWord{6, 0, 257}, + dictWord{135, 0, 1522}, + dictWord{ + 4, + 0, + 582, + }, + dictWord{9, 0, 191}, + dictWord{135, 11, 1931}, + dictWord{7, 11, 574}, + dictWord{7, 11, 1719}, + dictWord{137, 11, 145}, + dictWord{132, 11, 658}, + dictWord{10, 0, 790}, + dictWord{132, 11, 369}, + dictWord{9, 11, 781}, + dictWord{10, 11, 144}, + dictWord{11, 11, 385}, + dictWord{13, 11, 161}, + dictWord{13, 11, 228}, + dictWord{13, 11, 268}, + dictWord{148, 11, 107}, + dictWord{8, 0, 469}, + dictWord{10, 0, 47}, + dictWord{136, 11, 374}, + dictWord{6, 0, 306}, + dictWord{7, 0, 1140}, + dictWord{7, 0, 1340}, + dictWord{8, 0, 133}, + dictWord{138, 0, 449}, + dictWord{139, 0, 1011}, + dictWord{7, 10, 1875}, + dictWord{139, 10, 124}, + dictWord{ + 4, + 11, + 344, + }, + dictWord{6, 11, 498}, + dictWord{139, 11, 323}, + dictWord{137, 0, 299}, + dictWord{132, 0, 837}, + dictWord{133, 11, 906}, + dictWord{5, 0, 329}, + dictWord{ + 8, + 0, + 260, + }, + dictWord{138, 0, 10}, + dictWord{134, 0, 1320}, + dictWord{4, 0, 657}, + dictWord{146, 0, 158}, + dictWord{135, 0, 1191}, + dictWord{152, 0, 7}, + dictWord{ + 6, + 0, + 1939, + }, + dictWord{8, 0, 974}, + dictWord{138, 0, 996}, + dictWord{135, 0, 1665}, + dictWord{11, 11, 126}, + dictWord{139, 11, 287}, + dictWord{143, 0, 8}, + dictWord{ + 14, + 11, + 149, + }, + dictWord{14, 11, 399}, + dictWord{143, 11, 57}, + dictWord{5, 0, 66}, + dictWord{7, 0, 1896}, + dictWord{136, 0, 288}, + dictWord{7, 0, 175}, + dictWord{ + 10, + 0, + 494, + }, + dictWord{5, 10, 150}, + dictWord{8, 10, 603}, + dictWord{9, 10, 593}, + dictWord{9, 10, 634}, + dictWord{10, 10, 173}, + dictWord{11, 10, 462}, + dictWord{ + 11, + 10, + 515, + }, + dictWord{13, 10, 216}, + dictWord{13, 10, 288}, + dictWord{142, 10, 400}, + dictWord{134, 0, 1643}, + dictWord{136, 11, 21}, + dictWord{4, 0, 21}, + dictWord{ + 5, + 0, + 91, + }, + dictWord{5, 0, 648}, + dictWord{5, 0, 750}, + dictWord{5, 0, 781}, + dictWord{6, 0, 54}, + dictWord{6, 0, 112}, + dictWord{6, 0, 402}, + dictWord{6, 0, 1732}, + dictWord{ + 7, + 0, + 315, + }, + dictWord{7, 0, 749}, + dictWord{7, 0, 1427}, + dictWord{7, 0, 1900}, + dictWord{9, 0, 78}, + dictWord{9, 0, 508}, + dictWord{10, 0, 611}, + dictWord{10, 0, 811}, + dictWord{11, 0, 510}, + dictWord{11, 0, 728}, + dictWord{13, 0, 36}, + dictWord{14, 0, 39}, + dictWord{16, 0, 83}, + dictWord{17, 0, 124}, + dictWord{148, 0, 30}, + dictWord{ + 4, + 0, + 668, + }, + dictWord{136, 0, 570}, + dictWord{10, 0, 322}, + dictWord{10, 0, 719}, + dictWord{139, 0, 407}, + dictWord{135, 11, 1381}, + dictWord{136, 11, 193}, + dictWord{12, 10, 108}, + dictWord{141, 10, 291}, + dictWord{132, 11, 616}, + dictWord{136, 11, 692}, + dictWord{8, 0, 125}, + dictWord{8, 0, 369}, + dictWord{8, 0, 524}, + dictWord{10, 0, 486}, + dictWord{11, 0, 13}, + dictWord{11, 0, 381}, + dictWord{11, 0, 736}, + dictWord{11, 0, 766}, + dictWord{11, 0, 845}, + dictWord{13, 0, 114}, + dictWord{ + 13, + 0, + 292, + }, + dictWord{142, 0, 47}, + dictWord{134, 0, 1247}, + dictWord{6, 0, 1684}, + dictWord{6, 0, 1731}, + dictWord{7, 0, 356}, + dictWord{8, 0, 54}, + dictWord{8, 0, 221}, + dictWord{9, 0, 225}, + dictWord{9, 0, 356}, + dictWord{10, 0, 77}, + dictWord{10, 0, 446}, + dictWord{10, 0, 731}, + dictWord{12, 0, 404}, + dictWord{141, 0, 491}, + dictWord{135, 10, 1777}, + dictWord{4, 11, 305}, + dictWord{4, 10, 493}, + dictWord{144, 10, 55}, + dictWord{4, 0, 951}, + dictWord{6, 0, 1809}, + dictWord{6, 0, 1849}, + dictWord{8, 0, 846}, + dictWord{8, 0, 866}, + dictWord{8, 0, 899}, + dictWord{10, 0, 896}, + dictWord{12, 0, 694}, + dictWord{142, 0, 468}, + dictWord{5, 11, 214}, + dictWord{ + 7, + 11, + 603, + }, + dictWord{8, 11, 611}, + dictWord{9, 11, 686}, + dictWord{10, 11, 88}, + dictWord{11, 11, 459}, + dictWord{11, 11, 496}, + dictWord{12, 11, 463}, + dictWord{ + 12, + 11, + 590, + }, + dictWord{13, 11, 0}, + dictWord{142, 11, 214}, + dictWord{132, 0, 411}, + dictWord{4, 0, 80}, + dictWord{133, 0, 44}, + dictWord{140, 11, 74}, + dictWord{ + 143, + 0, + 31, + }, + dictWord{7, 0, 669}, + dictWord{6, 10, 568}, + dictWord{7, 10, 1804}, + dictWord{8, 10, 362}, + dictWord{8, 10, 410}, + dictWord{8, 10, 830}, + dictWord{9, 10, 514}, + dictWord{11, 10, 649}, + dictWord{142, 10, 157}, + dictWord{7, 0, 673}, + dictWord{134, 11, 1703}, + dictWord{132, 10, 625}, + dictWord{134, 0, 1303}, + dictWord{ + 5, + 0, + 299, + }, + dictWord{135, 0, 1083}, + dictWord{138, 0, 704}, + dictWord{6, 0, 275}, + dictWord{7, 0, 408}, + dictWord{6, 10, 158}, + dictWord{7, 10, 129}, + dictWord{ + 7, + 10, + 181, + }, + dictWord{8, 10, 276}, + dictWord{8, 10, 377}, + dictWord{10, 10, 523}, + dictWord{11, 10, 816}, + dictWord{12, 10, 455}, + dictWord{13, 10, 303}, + dictWord{ + 142, + 10, + 135, + }, + dictWord{4, 0, 219}, + dictWord{7, 0, 367}, + dictWord{7, 0, 1713}, + dictWord{7, 0, 1761}, + dictWord{9, 0, 86}, + dictWord{9, 0, 537}, + dictWord{10, 0, 165}, + dictWord{12, 0, 219}, + dictWord{140, 0, 561}, + dictWord{8, 0, 216}, + dictWord{4, 10, 1}, + dictWord{4, 11, 737}, + dictWord{6, 11, 317}, + dictWord{7, 10, 1143}, + dictWord{ + 7, + 10, + 1463, + }, + dictWord{9, 10, 207}, + dictWord{9, 10, 390}, + dictWord{9, 10, 467}, + dictWord{10, 11, 98}, + dictWord{11, 11, 294}, + dictWord{11, 10, 836}, + dictWord{ + 12, + 11, + 60, + }, + dictWord{12, 11, 437}, + dictWord{13, 11, 64}, + dictWord{13, 11, 380}, + dictWord{142, 11, 430}, + dictWord{6, 11, 1758}, + dictWord{8, 11, 520}, + dictWord{9, 11, 345}, + dictWord{9, 11, 403}, + dictWord{142, 11, 350}, + dictWord{5, 11, 47}, + dictWord{10, 11, 242}, + dictWord{138, 11, 579}, + dictWord{5, 11, 139}, + dictWord{7, 11, 1168}, + dictWord{138, 11, 539}, + dictWord{135, 0, 1319}, + dictWord{4, 10, 295}, + dictWord{4, 10, 723}, + dictWord{5, 10, 895}, + dictWord{ + 7, + 10, + 1031, + }, + dictWord{8, 10, 199}, + dictWord{8, 10, 340}, + dictWord{9, 10, 153}, + dictWord{9, 10, 215}, + dictWord{10, 10, 21}, + dictWord{10, 10, 59}, + dictWord{ + 10, + 10, + 80, + }, + dictWord{10, 10, 224}, + dictWord{10, 10, 838}, + dictWord{11, 10, 229}, + dictWord{11, 10, 652}, + dictWord{12, 10, 192}, + dictWord{13, 10, 146}, + dictWord{ + 142, + 10, + 91, + }, + dictWord{140, 0, 428}, + dictWord{137, 10, 51}, + dictWord{133, 0, 514}, + dictWord{5, 10, 309}, + dictWord{140, 10, 211}, + dictWord{6, 0, 1010}, + dictWord{5, 10, 125}, + dictWord{8, 10, 77}, + dictWord{138, 10, 15}, + dictWord{4, 0, 55}, + dictWord{5, 0, 301}, + dictWord{6, 0, 571}, + dictWord{142, 0, 49}, + dictWord{ + 146, + 0, + 102, + }, + dictWord{136, 11, 370}, + dictWord{4, 11, 107}, + dictWord{7, 11, 613}, + dictWord{8, 11, 358}, + dictWord{8, 11, 439}, + dictWord{8, 11, 504}, + dictWord{ + 9, + 11, + 501, + }, + dictWord{10, 11, 383}, + dictWord{139, 11, 477}, + dictWord{132, 11, 229}, + dictWord{133, 0, 364}, + dictWord{133, 10, 439}, + dictWord{4, 11, 903}, + dictWord{135, 11, 1816}, + dictWord{11, 0, 379}, + dictWord{140, 10, 76}, + dictWord{4, 0, 76}, + dictWord{4, 0, 971}, + dictWord{7, 0, 1550}, + dictWord{9, 0, 306}, + dictWord{ + 9, + 0, + 430, + }, + dictWord{9, 0, 663}, + dictWord{10, 0, 683}, + dictWord{10, 0, 921}, + dictWord{11, 0, 427}, + dictWord{11, 0, 753}, + dictWord{12, 0, 334}, + dictWord{12, 0, 442}, + dictWord{14, 0, 258}, + dictWord{14, 0, 366}, + dictWord{143, 0, 131}, + dictWord{137, 0, 52}, + dictWord{4, 11, 47}, + dictWord{6, 11, 373}, + dictWord{7, 11, 452}, + dictWord{7, 11, 543}, + dictWord{7, 11, 1714}, + dictWord{7, 11, 1856}, + dictWord{9, 11, 6}, + dictWord{11, 11, 257}, + dictWord{139, 11, 391}, + dictWord{4, 10, 8}, + dictWord{ + 7, + 10, + 1152, + }, + dictWord{7, 10, 1153}, + dictWord{7, 10, 1715}, + dictWord{9, 10, 374}, + dictWord{10, 10, 478}, + dictWord{139, 10, 648}, + dictWord{4, 11, 785}, + dictWord{133, 11, 368}, + dictWord{135, 10, 1099}, + dictWord{135, 11, 860}, + dictWord{5, 11, 980}, + dictWord{134, 11, 1754}, + dictWord{134, 0, 1258}, + dictWord{ + 6, + 0, + 1058, + }, + dictWord{6, 0, 1359}, + dictWord{7, 11, 536}, + dictWord{7, 11, 1331}, + dictWord{136, 11, 143}, + dictWord{4, 0, 656}, + dictWord{135, 0, 779}, + dictWord{136, 10, 87}, + dictWord{5, 11, 19}, + dictWord{6, 11, 533}, + dictWord{146, 11, 126}, + dictWord{7, 0, 144}, + dictWord{138, 10, 438}, + dictWord{5, 11, 395}, + dictWord{5, 11, 951}, + dictWord{134, 11, 1776}, + dictWord{135, 0, 1373}, + dictWord{7, 0, 554}, + dictWord{7, 0, 605}, + dictWord{141, 0, 10}, + dictWord{4, 10, 69}, + dictWord{ + 5, + 10, + 122, + }, + dictWord{9, 10, 656}, + dictWord{138, 10, 464}, + dictWord{5, 10, 849}, + dictWord{134, 10, 1633}, + dictWord{5, 0, 838}, + dictWord{5, 0, 841}, + dictWord{134, 0, 1649}, + dictWord{133, 0, 1012}, + dictWord{139, 10, 499}, + dictWord{7, 10, 476}, + dictWord{7, 10, 1592}, + dictWord{138, 10, 87}, + dictWord{ + 6, + 0, + 251, + }, + dictWord{7, 0, 365}, + dictWord{7, 0, 1357}, + dictWord{7, 0, 1497}, + dictWord{8, 0, 154}, + dictWord{141, 0, 281}, + dictWord{132, 11, 441}, + dictWord{ + 132, + 11, + 695, + }, + dictWord{7, 11, 497}, + dictWord{9, 11, 387}, + dictWord{147, 11, 81}, + dictWord{133, 0, 340}, + dictWord{14, 10, 283}, + dictWord{142, 11, 283}, + dictWord{ + 134, + 0, + 810, + }, + dictWord{135, 11, 1894}, + dictWord{139, 0, 495}, + dictWord{5, 11, 284}, + dictWord{6, 11, 49}, + dictWord{6, 11, 350}, + dictWord{7, 11, 1}, + dictWord{ + 7, + 11, + 377, + }, + dictWord{7, 11, 1693}, + dictWord{8, 11, 18}, + dictWord{8, 11, 678}, + dictWord{9, 11, 161}, + dictWord{9, 11, 585}, + dictWord{9, 11, 671}, + dictWord{ + 9, + 11, + 839, + }, + dictWord{11, 11, 912}, + dictWord{141, 11, 427}, + dictWord{5, 10, 859}, + dictWord{7, 10, 1160}, + dictWord{8, 10, 107}, + dictWord{9, 10, 291}, + dictWord{ + 9, + 10, + 439, + }, + dictWord{10, 10, 663}, + dictWord{11, 10, 609}, + dictWord{140, 10, 197}, + dictWord{8, 0, 261}, + dictWord{9, 0, 144}, + dictWord{9, 0, 466}, + dictWord{ + 10, + 0, + 370, + }, + dictWord{12, 0, 470}, + dictWord{13, 0, 144}, + dictWord{142, 0, 348}, + dictWord{137, 0, 897}, + dictWord{6, 0, 248}, + dictWord{9, 0, 546}, + dictWord{10, 0, 535}, + dictWord{11, 0, 681}, + dictWord{141, 0, 135}, + dictWord{4, 0, 358}, + dictWord{135, 0, 1496}, + dictWord{134, 0, 567}, + dictWord{136, 0, 445}, + dictWord{ + 4, + 10, + 117, + }, + dictWord{6, 10, 372}, + dictWord{7, 10, 1905}, + dictWord{142, 10, 323}, + dictWord{4, 10, 722}, + dictWord{139, 10, 471}, + dictWord{6, 0, 697}, + dictWord{ + 134, + 0, + 996, + }, + dictWord{7, 11, 2007}, + dictWord{9, 11, 101}, + dictWord{9, 11, 450}, + dictWord{10, 11, 66}, + dictWord{10, 11, 842}, + dictWord{11, 11, 536}, + dictWord{ + 140, + 11, + 587, + }, + dictWord{132, 0, 577}, + dictWord{134, 0, 1336}, + dictWord{9, 10, 5}, + dictWord{12, 10, 216}, + dictWord{12, 10, 294}, + dictWord{12, 10, 298}, + dictWord{12, 10, 400}, + dictWord{12, 10, 518}, + dictWord{13, 10, 229}, + dictWord{143, 10, 139}, + dictWord{6, 0, 174}, + dictWord{138, 0, 917}, + dictWord{ + 134, + 10, + 1774, + }, + dictWord{5, 10, 12}, + dictWord{7, 10, 375}, + dictWord{9, 10, 88}, + dictWord{9, 10, 438}, + dictWord{11, 11, 62}, + dictWord{139, 10, 270}, + dictWord{ + 134, + 11, + 1766, + }, + dictWord{6, 11, 0}, + dictWord{7, 11, 84}, + dictWord{7, 10, 816}, + dictWord{7, 10, 1241}, + dictWord{9, 10, 283}, + dictWord{9, 10, 520}, + dictWord{10, 10, 213}, + dictWord{10, 10, 307}, + dictWord{10, 10, 463}, + dictWord{10, 10, 671}, + dictWord{10, 10, 746}, + dictWord{11, 10, 401}, + dictWord{11, 10, 794}, + dictWord{ + 11, + 11, + 895, + }, + dictWord{12, 10, 517}, + dictWord{17, 11, 11}, + dictWord{18, 10, 107}, + dictWord{147, 10, 115}, + dictWord{5, 0, 878}, + dictWord{133, 0, 972}, + dictWord{ + 6, + 11, + 1665, + }, + dictWord{7, 11, 256}, + dictWord{7, 11, 1388}, + dictWord{138, 11, 499}, + dictWord{4, 10, 258}, + dictWord{136, 10, 639}, + dictWord{4, 11, 22}, + dictWord{5, 11, 10}, + dictWord{6, 10, 22}, + dictWord{7, 11, 848}, + dictWord{7, 10, 903}, + dictWord{7, 10, 1963}, + dictWord{8, 11, 97}, + dictWord{138, 10, 577}, + dictWord{ + 5, + 10, + 681, + }, + dictWord{136, 10, 782}, + dictWord{133, 11, 481}, + dictWord{132, 0, 351}, + dictWord{4, 10, 664}, + dictWord{5, 10, 804}, + dictWord{139, 10, 1013}, + dictWord{6, 11, 134}, + dictWord{7, 11, 437}, + dictWord{7, 11, 959}, + dictWord{9, 11, 37}, + dictWord{14, 11, 285}, + dictWord{14, 11, 371}, + dictWord{144, 11, 60}, + dictWord{7, 11, 486}, + dictWord{8, 11, 155}, + dictWord{11, 11, 93}, + dictWord{140, 11, 164}, + dictWord{132, 0, 286}, + dictWord{7, 0, 438}, + dictWord{7, 0, 627}, + dictWord{7, 0, 1516}, + dictWord{8, 0, 40}, + dictWord{9, 0, 56}, + dictWord{9, 0, 294}, + dictWord{10, 0, 30}, + dictWord{11, 0, 969}, + dictWord{11, 0, 995}, + dictWord{146, 0, 148}, + dictWord{5, 11, 591}, + dictWord{135, 11, 337}, + dictWord{134, 0, 1950}, + dictWord{133, 10, 32}, + dictWord{138, 11, 500}, + dictWord{5, 11, 380}, + dictWord{ + 5, + 11, + 650, + }, + dictWord{136, 11, 310}, + dictWord{4, 11, 364}, + dictWord{7, 11, 1156}, + dictWord{7, 11, 1187}, + dictWord{137, 11, 409}, + dictWord{4, 0, 738}, + dictWord{134, 11, 482}, + dictWord{4, 11, 781}, + dictWord{6, 11, 487}, + dictWord{7, 11, 926}, + dictWord{8, 11, 263}, + dictWord{139, 11, 500}, + dictWord{135, 11, 418}, + dictWord{6, 0, 2047}, + dictWord{10, 0, 969}, + dictWord{4, 10, 289}, + dictWord{7, 10, 629}, + dictWord{7, 10, 1698}, + dictWord{7, 10, 1711}, + dictWord{ + 140, + 10, + 215, + }, + dictWord{6, 10, 450}, + dictWord{136, 10, 109}, + dictWord{134, 0, 818}, + dictWord{136, 10, 705}, + dictWord{133, 0, 866}, + dictWord{4, 11, 94}, + dictWord{ + 135, + 11, + 1265, + }, + dictWord{132, 11, 417}, + dictWord{134, 0, 1467}, + dictWord{135, 10, 1238}, + dictWord{4, 0, 972}, + dictWord{6, 0, 1851}, + dictWord{ + 134, + 0, + 1857, + }, + dictWord{134, 0, 355}, + dictWord{133, 0, 116}, + dictWord{132, 0, 457}, + dictWord{135, 11, 1411}, + dictWord{4, 11, 408}, + dictWord{4, 11, 741}, + dictWord{135, 11, 500}, + dictWord{134, 10, 26}, + dictWord{142, 11, 137}, + dictWord{5, 0, 527}, + dictWord{6, 0, 189}, + dictWord{7, 0, 859}, + dictWord{136, 0, 267}, + dictWord{11, 0, 104}, + dictWord{11, 0, 554}, + dictWord{15, 0, 60}, + dictWord{143, 0, 125}, + dictWord{134, 0, 1613}, + dictWord{4, 10, 414}, + dictWord{5, 10, 467}, + dictWord{ + 9, + 10, + 654, + }, + dictWord{10, 10, 451}, + dictWord{12, 10, 59}, + dictWord{141, 10, 375}, + dictWord{135, 10, 17}, + dictWord{134, 0, 116}, + dictWord{135, 11, 541}, + dictWord{135, 10, 955}, + dictWord{6, 11, 73}, + dictWord{135, 11, 177}, + dictWord{133, 11, 576}, + dictWord{134, 0, 886}, + dictWord{133, 0, 487}, + dictWord{ + 4, + 0, + 86, + }, + dictWord{5, 0, 667}, + dictWord{5, 0, 753}, + dictWord{6, 0, 316}, + dictWord{6, 0, 455}, + dictWord{135, 0, 946}, + dictWord{142, 11, 231}, + dictWord{150, 0, 45}, + dictWord{134, 0, 863}, + dictWord{134, 0, 1953}, + dictWord{6, 10, 280}, + dictWord{10, 10, 502}, + dictWord{11, 10, 344}, + dictWord{140, 10, 38}, + dictWord{4, 0, 79}, + dictWord{7, 0, 1773}, + dictWord{10, 0, 450}, + dictWord{11, 0, 589}, + dictWord{13, 0, 332}, + dictWord{13, 0, 493}, + dictWord{14, 0, 183}, + dictWord{14, 0, 334}, + dictWord{14, 0, 362}, + dictWord{14, 0, 368}, + dictWord{14, 0, 376}, + dictWord{14, 0, 379}, + dictWord{19, 0, 90}, + dictWord{19, 0, 103}, + dictWord{19, 0, 127}, + dictWord{ + 148, + 0, + 90, + }, + dictWord{5, 10, 45}, + dictWord{7, 10, 1161}, + dictWord{11, 10, 448}, + dictWord{11, 10, 880}, + dictWord{13, 10, 139}, + dictWord{13, 10, 407}, + dictWord{ + 15, + 10, + 16, + }, + dictWord{17, 10, 95}, + dictWord{18, 10, 66}, + dictWord{18, 10, 88}, + dictWord{18, 10, 123}, + dictWord{149, 10, 7}, + dictWord{136, 10, 777}, + dictWord{ + 4, + 10, + 410, + }, + dictWord{135, 10, 521}, + dictWord{135, 10, 1778}, + dictWord{135, 11, 538}, + dictWord{142, 0, 381}, + dictWord{133, 11, 413}, + dictWord{ + 134, + 0, + 1142, + }, + dictWord{6, 0, 1189}, + dictWord{136, 11, 495}, + dictWord{5, 0, 663}, + dictWord{6, 0, 1962}, + dictWord{134, 0, 2003}, + dictWord{7, 11, 54}, + dictWord{ + 8, + 11, + 312, + }, + dictWord{10, 11, 191}, + dictWord{10, 11, 614}, + dictWord{140, 11, 567}, + dictWord{132, 10, 436}, + dictWord{133, 0, 846}, + dictWord{10, 0, 528}, + dictWord{11, 0, 504}, + dictWord{7, 10, 1587}, + dictWord{135, 10, 1707}, + dictWord{5, 0, 378}, + dictWord{8, 0, 465}, + dictWord{9, 0, 286}, + dictWord{10, 0, 185}, + dictWord{ + 10, + 0, + 562, + }, + dictWord{10, 0, 635}, + dictWord{11, 0, 31}, + dictWord{11, 0, 393}, + dictWord{13, 0, 312}, + dictWord{18, 0, 65}, + dictWord{18, 0, 96}, + dictWord{147, 0, 89}, + dictWord{7, 0, 899}, + dictWord{14, 0, 325}, + dictWord{6, 11, 468}, + dictWord{7, 11, 567}, + dictWord{7, 11, 1478}, + dictWord{8, 11, 530}, + dictWord{142, 11, 290}, + dictWord{7, 0, 1880}, + dictWord{9, 0, 680}, + dictWord{139, 0, 798}, + dictWord{134, 0, 1770}, + dictWord{132, 0, 648}, + dictWord{150, 11, 35}, + dictWord{5, 0, 945}, + dictWord{6, 0, 1656}, + dictWord{6, 0, 1787}, + dictWord{7, 0, 167}, + dictWord{8, 0, 824}, + dictWord{9, 0, 391}, + dictWord{10, 0, 375}, + dictWord{139, 0, 185}, + dictWord{ + 6, + 11, + 484, + }, + dictWord{135, 11, 822}, + dictWord{134, 0, 2046}, + dictWord{7, 0, 1645}, + dictWord{8, 0, 352}, + dictWord{137, 0, 249}, + dictWord{132, 0, 152}, + dictWord{6, 0, 611}, + dictWord{135, 0, 1733}, + dictWord{6, 11, 1724}, + dictWord{135, 11, 2022}, + dictWord{133, 0, 1006}, + dictWord{141, 11, 96}, + dictWord{ + 5, + 0, + 420, + }, + dictWord{135, 0, 1449}, + dictWord{146, 11, 149}, + dictWord{135, 0, 832}, + dictWord{135, 10, 663}, + dictWord{133, 0, 351}, + dictWord{5, 0, 40}, + dictWord{ + 7, + 0, + 598, + }, + dictWord{7, 0, 1638}, + dictWord{8, 0, 78}, + dictWord{9, 0, 166}, + dictWord{9, 0, 640}, + dictWord{9, 0, 685}, + dictWord{9, 0, 773}, + dictWord{11, 0, 215}, + dictWord{13, 0, 65}, + dictWord{14, 0, 172}, + dictWord{14, 0, 317}, + dictWord{145, 0, 6}, + dictWord{8, 0, 60}, + dictWord{9, 0, 343}, + dictWord{139, 0, 769}, + dictWord{ + 134, + 0, + 1354, + }, + dictWord{132, 0, 724}, + dictWord{137, 0, 745}, + dictWord{132, 11, 474}, + dictWord{7, 0, 1951}, + dictWord{8, 0, 765}, + dictWord{8, 0, 772}, + dictWord{ + 140, + 0, + 671, + }, + dictWord{7, 0, 108}, + dictWord{8, 0, 219}, + dictWord{8, 0, 388}, + dictWord{9, 0, 775}, + dictWord{11, 0, 275}, + dictWord{140, 0, 464}, + dictWord{137, 0, 639}, + dictWord{135, 10, 503}, + dictWord{133, 11, 366}, + dictWord{5, 0, 15}, + dictWord{6, 0, 56}, + dictWord{7, 0, 1758}, + dictWord{8, 0, 500}, + dictWord{9, 0, 730}, + dictWord{ + 11, + 0, + 331, + }, + dictWord{13, 0, 150}, + dictWord{14, 0, 282}, + dictWord{5, 11, 305}, + dictWord{9, 11, 560}, + dictWord{141, 11, 208}, + dictWord{4, 10, 113}, + dictWord{ + 5, + 10, + 163, + }, + dictWord{5, 10, 735}, + dictWord{7, 10, 1009}, + dictWord{9, 10, 9}, + dictWord{9, 10, 771}, + dictWord{12, 10, 90}, + dictWord{13, 10, 138}, + dictWord{ + 13, + 10, + 410, + }, + dictWord{143, 10, 128}, + dictWord{4, 10, 324}, + dictWord{138, 10, 104}, + dictWord{135, 11, 466}, + dictWord{142, 11, 27}, + dictWord{134, 0, 1886}, + dictWord{5, 0, 205}, + dictWord{6, 0, 438}, + dictWord{9, 0, 711}, + dictWord{4, 11, 480}, + dictWord{6, 11, 167}, + dictWord{6, 11, 302}, + dictWord{6, 11, 1642}, + dictWord{ + 7, + 11, + 130, + }, + dictWord{7, 11, 656}, + dictWord{7, 11, 837}, + dictWord{7, 11, 1547}, + dictWord{7, 11, 1657}, + dictWord{8, 11, 429}, + dictWord{9, 11, 228}, + dictWord{ + 10, + 11, + 643, + }, + dictWord{13, 11, 289}, + dictWord{13, 11, 343}, + dictWord{147, 11, 101}, + dictWord{134, 0, 865}, + dictWord{6, 0, 2025}, + dictWord{136, 0, 965}, + dictWord{ + 7, + 11, + 278, + }, + dictWord{10, 11, 739}, + dictWord{11, 11, 708}, + dictWord{141, 11, 348}, + dictWord{133, 0, 534}, + dictWord{135, 11, 1922}, + dictWord{ + 137, + 0, + 691, + }, + dictWord{4, 10, 935}, + dictWord{133, 10, 823}, + dictWord{6, 0, 443}, + dictWord{9, 0, 237}, + dictWord{9, 0, 571}, + dictWord{9, 0, 695}, + dictWord{10, 0, 139}, + dictWord{11, 0, 715}, + dictWord{12, 0, 417}, + dictWord{141, 0, 421}, + dictWord{5, 10, 269}, + dictWord{7, 10, 434}, + dictWord{7, 10, 891}, + dictWord{8, 10, 339}, + dictWord{ + 9, + 10, + 702, + }, + dictWord{11, 10, 594}, + dictWord{11, 10, 718}, + dictWord{145, 10, 100}, + dictWord{6, 0, 1555}, + dictWord{7, 0, 878}, + dictWord{9, 10, 485}, + dictWord{141, 10, 264}, + dictWord{134, 10, 1713}, + dictWord{7, 10, 1810}, + dictWord{11, 10, 866}, + dictWord{12, 10, 103}, + dictWord{141, 10, 495}, + dictWord{ + 135, + 10, + 900, + }, + dictWord{6, 0, 1410}, + dictWord{9, 11, 316}, + dictWord{139, 11, 256}, + dictWord{4, 0, 995}, + dictWord{135, 0, 1033}, + dictWord{132, 0, 578}, + dictWord{10, 0, 881}, + dictWord{12, 0, 740}, + dictWord{12, 0, 743}, + dictWord{140, 0, 759}, + dictWord{132, 0, 822}, + dictWord{133, 0, 923}, + dictWord{142, 10, 143}, + dictWord{135, 11, 1696}, + dictWord{6, 11, 363}, + dictWord{7, 11, 1955}, + dictWord{136, 11, 725}, + dictWord{132, 0, 924}, + dictWord{133, 0, 665}, + dictWord{ + 135, + 10, + 2029, + }, + dictWord{135, 0, 1901}, + dictWord{4, 0, 265}, + dictWord{6, 0, 1092}, + dictWord{6, 0, 1417}, + dictWord{7, 0, 807}, + dictWord{135, 0, 950}, + dictWord{ + 5, + 0, + 93, + }, + dictWord{12, 0, 267}, + dictWord{141, 0, 498}, + dictWord{135, 0, 1451}, + dictWord{5, 11, 813}, + dictWord{135, 11, 2046}, + dictWord{5, 10, 625}, + dictWord{135, 10, 1617}, + dictWord{135, 0, 747}, + dictWord{6, 0, 788}, + dictWord{137, 0, 828}, + dictWord{7, 0, 184}, + dictWord{11, 0, 307}, + dictWord{11, 0, 400}, + dictWord{15, 0, 130}, + dictWord{5, 11, 712}, + dictWord{7, 11, 1855}, + dictWord{8, 10, 425}, + dictWord{8, 10, 693}, + dictWord{9, 10, 720}, + dictWord{10, 10, 380}, + dictWord{10, 10, 638}, + dictWord{11, 11, 17}, + dictWord{11, 10, 473}, + dictWord{12, 10, 61}, + dictWord{13, 11, 321}, + dictWord{144, 11, 67}, + dictWord{135, 0, 198}, + dictWord{6, 11, 320}, + dictWord{7, 11, 781}, + dictWord{7, 11, 1921}, + dictWord{9, 11, 55}, + dictWord{10, 11, 186}, + dictWord{10, 11, 273}, + dictWord{10, 11, 664}, + dictWord{10, 11, 801}, + dictWord{11, 11, 996}, + dictWord{11, 11, 997}, + dictWord{13, 11, 157}, + dictWord{142, 11, 170}, + dictWord{136, 11, 271}, + dictWord{ + 135, + 0, + 994, + }, + dictWord{7, 11, 103}, + dictWord{7, 11, 863}, + dictWord{11, 11, 184}, + dictWord{14, 11, 299}, + dictWord{145, 11, 62}, + dictWord{11, 10, 551}, + dictWord{142, 10, 159}, + dictWord{5, 0, 233}, + dictWord{5, 0, 320}, + dictWord{6, 0, 140}, + dictWord{8, 0, 295}, + dictWord{8, 0, 615}, + dictWord{136, 11, 615}, + dictWord{ + 133, + 0, + 978, + }, + dictWord{4, 0, 905}, + dictWord{6, 0, 1701}, + dictWord{137, 0, 843}, + dictWord{132, 10, 168}, + dictWord{4, 0, 974}, + dictWord{8, 0, 850}, + dictWord{ + 12, + 0, + 709, + }, + dictWord{12, 0, 768}, + dictWord{140, 0, 786}, + dictWord{135, 10, 91}, + dictWord{152, 0, 6}, + dictWord{138, 10, 532}, + dictWord{135, 10, 1884}, + dictWord{132, 0, 509}, + dictWord{6, 0, 1307}, + dictWord{135, 0, 273}, + dictWord{5, 11, 77}, + dictWord{7, 11, 1455}, + dictWord{10, 11, 843}, + dictWord{19, 11, 73}, + dictWord{150, 11, 5}, + dictWord{132, 11, 458}, + dictWord{135, 11, 1420}, + dictWord{6, 11, 109}, + dictWord{138, 11, 382}, + dictWord{6, 0, 201}, + dictWord{6, 11, 330}, + dictWord{7, 10, 70}, + dictWord{7, 11, 1084}, + dictWord{10, 10, 240}, + dictWord{11, 11, 142}, + dictWord{147, 10, 93}, + dictWord{7, 0, 1041}, + dictWord{ + 140, + 11, + 328, + }, + dictWord{133, 11, 354}, + dictWord{134, 0, 1040}, + dictWord{133, 0, 693}, + dictWord{134, 0, 774}, + dictWord{139, 0, 234}, + dictWord{132, 0, 336}, + dictWord{7, 0, 1399}, + dictWord{139, 10, 392}, + dictWord{20, 0, 22}, + dictWord{148, 11, 22}, + dictWord{5, 0, 802}, + dictWord{7, 0, 2021}, + dictWord{136, 0, 805}, + dictWord{ + 5, + 0, + 167, + }, + dictWord{5, 0, 899}, + dictWord{6, 0, 410}, + dictWord{137, 0, 777}, + dictWord{137, 0, 789}, + dictWord{134, 0, 1705}, + dictWord{7, 10, 655}, + dictWord{ + 135, + 10, + 1844, + }, + dictWord{4, 10, 145}, + dictWord{6, 10, 176}, + dictWord{7, 10, 395}, + dictWord{137, 10, 562}, + dictWord{132, 10, 501}, + dictWord{135, 0, 10}, + dictWord{5, 0, 11}, + dictWord{6, 0, 117}, + dictWord{6, 0, 485}, + dictWord{7, 0, 1133}, + dictWord{9, 0, 582}, + dictWord{9, 0, 594}, + dictWord{10, 0, 82}, + dictWord{11, 0, 21}, + dictWord{11, 0, 818}, + dictWord{12, 0, 535}, + dictWord{13, 0, 86}, + dictWord{20, 0, 91}, + dictWord{23, 0, 13}, + dictWord{134, 10, 509}, + dictWord{4, 0, 264}, + dictWord{ + 7, + 0, + 1067, + }, + dictWord{8, 0, 204}, + dictWord{8, 0, 385}, + dictWord{139, 0, 953}, + dictWord{139, 11, 737}, + dictWord{138, 0, 56}, + dictWord{134, 0, 1917}, + dictWord{ + 133, + 0, + 470, + }, + dictWord{10, 11, 657}, + dictWord{14, 11, 297}, + dictWord{142, 11, 361}, + dictWord{135, 11, 412}, + dictWord{7, 0, 1198}, + dictWord{7, 11, 1198}, + dictWord{8, 11, 556}, + dictWord{14, 11, 123}, + dictWord{14, 11, 192}, + dictWord{143, 11, 27}, + dictWord{7, 11, 1985}, + dictWord{14, 11, 146}, + dictWord{15, 11, 42}, + dictWord{16, 11, 23}, + dictWord{17, 11, 86}, + dictWord{146, 11, 17}, + dictWord{11, 0, 1015}, + dictWord{136, 11, 122}, + dictWord{4, 10, 114}, + dictWord{ + 9, + 10, + 492, + }, + dictWord{13, 10, 462}, + dictWord{142, 10, 215}, + dictWord{4, 10, 77}, + dictWord{5, 10, 361}, + dictWord{6, 10, 139}, + dictWord{6, 10, 401}, + dictWord{ + 6, + 10, + 404, + }, + dictWord{7, 10, 413}, + dictWord{7, 10, 715}, + dictWord{7, 10, 1716}, + dictWord{11, 10, 279}, + dictWord{12, 10, 179}, + dictWord{12, 10, 258}, + dictWord{ + 13, + 10, + 244, + }, + dictWord{142, 10, 358}, + dictWord{134, 10, 1717}, + dictWord{7, 10, 1061}, + dictWord{8, 10, 82}, + dictWord{11, 10, 250}, + dictWord{12, 10, 420}, + dictWord{141, 10, 184}, + dictWord{133, 0, 715}, + dictWord{135, 10, 724}, + dictWord{9, 0, 919}, + dictWord{9, 0, 922}, + dictWord{9, 0, 927}, + dictWord{9, 0, 933}, + dictWord{9, 0, 962}, + dictWord{9, 0, 1000}, + dictWord{9, 0, 1002}, + dictWord{9, 0, 1021}, + dictWord{12, 0, 890}, + dictWord{12, 0, 907}, + dictWord{12, 0, 930}, + dictWord{ + 15, + 0, + 207, + }, + dictWord{15, 0, 228}, + dictWord{15, 0, 238}, + dictWord{149, 0, 61}, + dictWord{8, 0, 794}, + dictWord{9, 0, 400}, + dictWord{10, 0, 298}, + dictWord{142, 0, 228}, + dictWord{5, 11, 430}, + dictWord{5, 11, 932}, + dictWord{6, 11, 131}, + dictWord{7, 11, 417}, + dictWord{9, 11, 522}, + dictWord{11, 11, 314}, + dictWord{141, 11, 390}, + dictWord{132, 0, 867}, + dictWord{8, 0, 724}, + dictWord{132, 11, 507}, + dictWord{137, 11, 261}, + dictWord{4, 11, 343}, + dictWord{133, 11, 511}, + dictWord{ + 6, + 0, + 190, + }, + dictWord{7, 0, 768}, + dictWord{135, 0, 1170}, + dictWord{6, 10, 513}, + dictWord{135, 10, 1052}, + dictWord{7, 11, 455}, + dictWord{138, 11, 591}, + dictWord{134, 0, 1066}, + dictWord{137, 10, 899}, + dictWord{14, 0, 67}, + dictWord{147, 0, 60}, + dictWord{4, 0, 948}, + dictWord{18, 0, 174}, + dictWord{146, 0, 176}, + dictWord{135, 0, 1023}, + dictWord{7, 10, 1417}, + dictWord{12, 10, 382}, + dictWord{17, 10, 48}, + dictWord{152, 10, 12}, + dictWord{134, 11, 575}, + dictWord{ + 132, + 0, + 764, + }, + dictWord{6, 10, 545}, + dictWord{7, 10, 565}, + dictWord{7, 10, 1669}, + dictWord{10, 10, 114}, + dictWord{11, 10, 642}, + dictWord{140, 10, 618}, + dictWord{ + 6, + 0, + 137, + }, + dictWord{9, 0, 75}, + dictWord{9, 0, 253}, + dictWord{10, 0, 194}, + dictWord{138, 0, 444}, + dictWord{4, 0, 756}, + dictWord{133, 10, 5}, + dictWord{8, 0, 1008}, + dictWord{135, 10, 192}, + dictWord{132, 0, 842}, + dictWord{11, 0, 643}, + dictWord{12, 0, 115}, + dictWord{136, 10, 763}, + dictWord{139, 0, 67}, + dictWord{ + 133, + 10, + 759, + }, + dictWord{4, 0, 821}, + dictWord{5, 0, 760}, + dictWord{7, 0, 542}, + dictWord{8, 0, 135}, + dictWord{8, 0, 496}, + dictWord{135, 11, 580}, + dictWord{7, 10, 370}, + dictWord{7, 10, 1007}, + dictWord{7, 10, 1177}, + dictWord{135, 10, 1565}, + dictWord{135, 10, 1237}, + dictWord{140, 0, 736}, + dictWord{7, 0, 319}, + dictWord{ + 7, + 0, + 355, + }, + dictWord{7, 0, 763}, + dictWord{10, 0, 389}, + dictWord{145, 0, 43}, + dictWord{8, 11, 333}, + dictWord{138, 11, 182}, + dictWord{4, 10, 87}, + dictWord{5, 10, 250}, + dictWord{141, 10, 298}, + dictWord{138, 0, 786}, + dictWord{134, 0, 2044}, + dictWord{8, 11, 330}, + dictWord{140, 11, 477}, + dictWord{135, 11, 1338}, + dictWord{132, 11, 125}, + dictWord{134, 0, 1030}, + dictWord{134, 0, 1083}, + dictWord{132, 11, 721}, + dictWord{135, 10, 814}, + dictWord{7, 11, 776}, + dictWord{ + 8, + 11, + 145, + }, + dictWord{147, 11, 56}, + dictWord{134, 0, 1226}, + dictWord{4, 10, 57}, + dictWord{7, 10, 1195}, + dictWord{7, 10, 1438}, + dictWord{7, 10, 1548}, + dictWord{ + 7, + 10, + 1835, + }, + dictWord{7, 10, 1904}, + dictWord{9, 10, 757}, + dictWord{10, 10, 604}, + dictWord{139, 10, 519}, + dictWord{7, 11, 792}, + dictWord{8, 11, 147}, + dictWord{10, 11, 821}, + dictWord{139, 11, 1021}, + dictWord{137, 11, 797}, + dictWord{4, 0, 58}, + dictWord{5, 0, 286}, + dictWord{6, 0, 319}, + dictWord{7, 0, 402}, + dictWord{ + 7, + 0, + 1254, + }, + dictWord{7, 0, 1903}, + dictWord{8, 0, 356}, + dictWord{140, 0, 408}, + dictWord{4, 0, 389}, + dictWord{4, 0, 815}, + dictWord{9, 0, 181}, + dictWord{9, 0, 255}, + dictWord{10, 0, 8}, + dictWord{10, 0, 29}, + dictWord{10, 0, 816}, + dictWord{11, 0, 311}, + dictWord{11, 0, 561}, + dictWord{12, 0, 67}, + dictWord{141, 0, 181}, + dictWord{ + 7, + 11, + 1472, + }, + dictWord{135, 11, 1554}, + dictWord{7, 11, 1071}, + dictWord{7, 11, 1541}, + dictWord{7, 11, 1767}, + dictWord{7, 11, 1806}, + dictWord{7, 11, 1999}, + dictWord{9, 11, 248}, + dictWord{10, 11, 400}, + dictWord{11, 11, 162}, + dictWord{11, 11, 178}, + dictWord{11, 11, 242}, + dictWord{12, 11, 605}, + dictWord{ + 15, + 11, + 26, + }, + dictWord{144, 11, 44}, + dictWord{5, 11, 168}, + dictWord{5, 11, 930}, + dictWord{8, 11, 74}, + dictWord{9, 11, 623}, + dictWord{12, 11, 500}, + dictWord{ + 12, + 11, + 579, + }, + dictWord{13, 11, 41}, + dictWord{143, 11, 93}, + dictWord{6, 11, 220}, + dictWord{7, 11, 1101}, + dictWord{141, 11, 105}, + dictWord{5, 0, 474}, + dictWord{ + 7, + 0, + 507, + }, + dictWord{4, 10, 209}, + dictWord{7, 11, 507}, + dictWord{135, 10, 902}, + dictWord{132, 0, 427}, + dictWord{6, 0, 413}, + dictWord{7, 10, 335}, + dictWord{ + 7, + 10, + 1437, + }, + dictWord{7, 10, 1668}, + dictWord{8, 10, 553}, + dictWord{8, 10, 652}, + dictWord{8, 10, 656}, + dictWord{9, 10, 558}, + dictWord{11, 10, 743}, + dictWord{ + 149, + 10, + 18, + }, + dictWord{132, 0, 730}, + dictWord{6, 11, 19}, + dictWord{7, 11, 1413}, + dictWord{139, 11, 428}, + dictWord{133, 0, 373}, + dictWord{132, 10, 559}, + dictWord{7, 11, 96}, + dictWord{8, 11, 401}, + dictWord{137, 11, 896}, + dictWord{7, 0, 799}, + dictWord{7, 0, 1972}, + dictWord{5, 10, 1017}, + dictWord{138, 10, 511}, + dictWord{135, 0, 1793}, + dictWord{7, 11, 1961}, + dictWord{7, 11, 1965}, + dictWord{8, 11, 702}, + dictWord{136, 11, 750}, + dictWord{8, 11, 150}, + dictWord{8, 11, 737}, + dictWord{140, 11, 366}, + dictWord{132, 0, 322}, + dictWord{133, 10, 709}, + dictWord{8, 11, 800}, + dictWord{9, 11, 148}, + dictWord{9, 11, 872}, + dictWord{ + 9, + 11, + 890, + }, + dictWord{11, 11, 309}, + dictWord{11, 11, 1001}, + dictWord{13, 11, 267}, + dictWord{141, 11, 323}, + dictWord{134, 10, 1745}, + dictWord{7, 0, 290}, + dictWord{136, 10, 206}, + dictWord{7, 0, 1651}, + dictWord{145, 0, 89}, + dictWord{139, 0, 2}, + dictWord{132, 0, 672}, + dictWord{6, 0, 1860}, + dictWord{8, 0, 905}, + dictWord{ + 10, + 0, + 844, + }, + dictWord{10, 0, 846}, + dictWord{10, 0, 858}, + dictWord{12, 0, 699}, + dictWord{12, 0, 746}, + dictWord{140, 0, 772}, + dictWord{135, 11, 424}, + dictWord{133, 11, 547}, + dictWord{133, 0, 737}, + dictWord{5, 11, 490}, + dictWord{6, 11, 615}, + dictWord{6, 11, 620}, + dictWord{135, 11, 683}, + dictWord{6, 0, 746}, + dictWord{134, 0, 1612}, + dictWord{132, 10, 776}, + dictWord{9, 11, 385}, + dictWord{149, 11, 17}, + dictWord{133, 0, 145}, + dictWord{135, 10, 1272}, + dictWord{ + 7, + 0, + 884, + }, + dictWord{140, 0, 124}, + dictWord{4, 0, 387}, + dictWord{135, 0, 1288}, + dictWord{5, 11, 133}, + dictWord{136, 10, 406}, + dictWord{136, 11, 187}, + dictWord{ + 6, + 0, + 679, + }, + dictWord{8, 11, 8}, + dictWord{138, 11, 0}, + dictWord{135, 0, 550}, + dictWord{135, 11, 798}, + dictWord{136, 11, 685}, + dictWord{7, 11, 1086}, + dictWord{145, 11, 46}, + dictWord{8, 10, 175}, + dictWord{10, 10, 168}, + dictWord{138, 10, 573}, + dictWord{135, 0, 1305}, + dictWord{4, 0, 576}, + dictWord{ + 135, + 0, + 1263, + }, + dictWord{6, 0, 686}, + dictWord{134, 0, 1563}, + dictWord{134, 0, 607}, + dictWord{5, 0, 919}, + dictWord{134, 0, 1673}, + dictWord{148, 0, 37}, + dictWord{ + 8, + 11, + 774, + }, + dictWord{10, 11, 670}, + dictWord{140, 11, 51}, + dictWord{133, 10, 784}, + dictWord{139, 10, 882}, + dictWord{4, 0, 82}, + dictWord{5, 0, 333}, + dictWord{ + 5, + 0, + 904, + }, + dictWord{6, 0, 207}, + dictWord{7, 0, 325}, + dictWord{7, 0, 1726}, + dictWord{8, 0, 101}, + dictWord{10, 0, 778}, + dictWord{139, 0, 220}, + dictWord{135, 11, 371}, + dictWord{132, 0, 958}, + dictWord{133, 0, 903}, + dictWord{4, 11, 127}, + dictWord{5, 11, 350}, + dictWord{6, 11, 356}, + dictWord{8, 11, 426}, + dictWord{9, 11, 572}, + dictWord{10, 11, 247}, + dictWord{139, 11, 312}, + dictWord{140, 0, 147}, + dictWord{6, 11, 59}, + dictWord{7, 11, 885}, + dictWord{9, 11, 603}, + dictWord{ + 141, + 11, + 397, + }, + dictWord{10, 0, 367}, + dictWord{9, 10, 14}, + dictWord{9, 10, 441}, + dictWord{139, 10, 9}, + dictWord{11, 10, 966}, + dictWord{12, 10, 287}, + dictWord{ + 13, + 10, + 342, + }, + dictWord{13, 10, 402}, + dictWord{15, 10, 110}, + dictWord{143, 10, 163}, + dictWord{134, 0, 690}, + dictWord{132, 0, 705}, + dictWord{9, 0, 651}, + dictWord{ + 11, + 0, + 971, + }, + dictWord{13, 0, 273}, + dictWord{7, 10, 1428}, + dictWord{7, 10, 1640}, + dictWord{7, 10, 1867}, + dictWord{9, 10, 169}, + dictWord{9, 10, 182}, + dictWord{ + 9, + 10, + 367, + }, + dictWord{9, 10, 478}, + dictWord{9, 10, 506}, + dictWord{9, 10, 551}, + dictWord{9, 10, 557}, + dictWord{9, 10, 648}, + dictWord{9, 10, 697}, + dictWord{ + 9, + 10, + 705, + }, + dictWord{9, 10, 725}, + dictWord{9, 10, 787}, + dictWord{9, 10, 794}, + dictWord{10, 10, 198}, + dictWord{10, 10, 214}, + dictWord{10, 10, 267}, + dictWord{ + 10, + 10, + 275, + }, + dictWord{10, 10, 456}, + dictWord{10, 10, 551}, + dictWord{10, 10, 561}, + dictWord{10, 10, 613}, + dictWord{10, 10, 627}, + dictWord{10, 10, 668}, + dictWord{10, 10, 675}, + dictWord{10, 10, 691}, + dictWord{10, 10, 695}, + dictWord{10, 10, 707}, + dictWord{10, 10, 715}, + dictWord{11, 10, 183}, + dictWord{ + 11, + 10, + 201, + }, + dictWord{11, 10, 262}, + dictWord{11, 10, 352}, + dictWord{11, 10, 439}, + dictWord{11, 10, 493}, + dictWord{11, 10, 572}, + dictWord{11, 10, 591}, + dictWord{ + 11, + 10, + 608, + }, + dictWord{11, 10, 611}, + dictWord{11, 10, 646}, + dictWord{11, 10, 674}, + dictWord{11, 10, 711}, + dictWord{11, 10, 751}, + dictWord{11, 10, 761}, + dictWord{11, 10, 776}, + dictWord{11, 10, 785}, + dictWord{11, 10, 850}, + dictWord{11, 10, 853}, + dictWord{11, 10, 862}, + dictWord{11, 10, 865}, + dictWord{ + 11, + 10, + 868, + }, + dictWord{11, 10, 875}, + dictWord{11, 10, 898}, + dictWord{11, 10, 902}, + dictWord{11, 10, 903}, + dictWord{11, 10, 910}, + dictWord{11, 10, 932}, + dictWord{ + 11, + 10, + 942, + }, + dictWord{11, 10, 957}, + dictWord{11, 10, 967}, + dictWord{11, 10, 972}, + dictWord{12, 10, 148}, + dictWord{12, 10, 195}, + dictWord{12, 10, 220}, + dictWord{12, 10, 237}, + dictWord{12, 10, 318}, + dictWord{12, 10, 339}, + dictWord{12, 10, 393}, + dictWord{12, 10, 445}, + dictWord{12, 10, 450}, + dictWord{ + 12, + 10, + 474, + }, + dictWord{12, 10, 505}, + dictWord{12, 10, 509}, + dictWord{12, 10, 533}, + dictWord{12, 10, 591}, + dictWord{12, 10, 594}, + dictWord{12, 10, 597}, + dictWord{ + 12, + 10, + 621, + }, + dictWord{12, 10, 633}, + dictWord{12, 10, 642}, + dictWord{13, 10, 59}, + dictWord{13, 10, 60}, + dictWord{13, 10, 145}, + dictWord{13, 10, 239}, + dictWord{13, 10, 250}, + dictWord{13, 10, 329}, + dictWord{13, 10, 344}, + dictWord{13, 10, 365}, + dictWord{13, 10, 372}, + dictWord{13, 10, 387}, + dictWord{ + 13, + 10, + 403, + }, + dictWord{13, 10, 414}, + dictWord{13, 10, 456}, + dictWord{13, 10, 470}, + dictWord{13, 10, 478}, + dictWord{13, 10, 483}, + dictWord{13, 10, 489}, + dictWord{ + 14, + 10, + 55, + }, + dictWord{14, 10, 57}, + dictWord{14, 10, 81}, + dictWord{14, 10, 90}, + dictWord{14, 10, 148}, + dictWord{14, 10, 239}, + dictWord{14, 10, 266}, + dictWord{ + 14, + 10, + 321, + }, + dictWord{14, 10, 326}, + dictWord{14, 10, 327}, + dictWord{14, 10, 330}, + dictWord{14, 10, 347}, + dictWord{14, 10, 355}, + dictWord{14, 10, 401}, + dictWord{14, 10, 404}, + dictWord{14, 10, 411}, + dictWord{14, 10, 414}, + dictWord{14, 10, 416}, + dictWord{14, 10, 420}, + dictWord{15, 10, 61}, + dictWord{ + 15, + 10, + 74, + }, + dictWord{15, 10, 87}, + dictWord{15, 10, 88}, + dictWord{15, 10, 94}, + dictWord{15, 10, 96}, + dictWord{15, 10, 116}, + dictWord{15, 10, 149}, + dictWord{ + 15, + 10, + 154, + }, + dictWord{16, 10, 50}, + dictWord{16, 10, 63}, + dictWord{16, 10, 73}, + dictWord{17, 10, 2}, + dictWord{17, 10, 66}, + dictWord{17, 10, 92}, + dictWord{17, 10, 103}, + dictWord{17, 10, 112}, + dictWord{17, 10, 120}, + dictWord{18, 10, 50}, + dictWord{18, 10, 54}, + dictWord{18, 10, 82}, + dictWord{18, 10, 86}, + dictWord{18, 10, 90}, + dictWord{18, 10, 111}, + dictWord{18, 10, 115}, + dictWord{18, 10, 156}, + dictWord{19, 10, 40}, + dictWord{19, 10, 79}, + dictWord{20, 10, 78}, + dictWord{149, 10, 22}, + dictWord{7, 0, 887}, + dictWord{5, 10, 161}, + dictWord{135, 10, 839}, + dictWord{142, 11, 98}, + dictWord{134, 0, 90}, + dictWord{138, 11, 356}, + dictWord{ + 135, + 11, + 441, + }, + dictWord{6, 11, 111}, + dictWord{7, 11, 4}, + dictWord{8, 11, 163}, + dictWord{8, 11, 776}, + dictWord{138, 11, 566}, + dictWord{134, 0, 908}, + dictWord{ + 134, + 0, + 1261, + }, + dictWord{7, 0, 813}, + dictWord{12, 0, 497}, + dictWord{141, 0, 56}, + dictWord{134, 0, 1235}, + dictWord{135, 0, 429}, + dictWord{135, 11, 1994}, + dictWord{138, 0, 904}, + dictWord{6, 0, 125}, + dictWord{7, 0, 1277}, + dictWord{137, 0, 772}, + dictWord{151, 0, 12}, + dictWord{4, 0, 841}, + dictWord{5, 0, 386}, + dictWord{ + 133, + 11, + 386, + }, + dictWord{5, 11, 297}, + dictWord{135, 11, 1038}, + dictWord{6, 0, 860}, + dictWord{6, 0, 1069}, + dictWord{135, 11, 309}, + dictWord{136, 0, 946}, + dictWord{135, 10, 1814}, + dictWord{141, 11, 418}, + dictWord{136, 11, 363}, + dictWord{10, 0, 768}, + dictWord{139, 0, 787}, + dictWord{22, 11, 30}, + dictWord{ + 150, + 11, + 33, + }, + dictWord{6, 0, 160}, + dictWord{7, 0, 1106}, + dictWord{9, 0, 770}, + dictWord{11, 0, 112}, + dictWord{140, 0, 413}, + dictWord{11, 11, 216}, + dictWord{ + 139, + 11, + 340, + }, + dictWord{136, 10, 139}, + dictWord{135, 11, 1390}, + dictWord{135, 11, 808}, + dictWord{132, 11, 280}, + dictWord{12, 0, 271}, + dictWord{17, 0, 109}, + dictWord{7, 10, 643}, + dictWord{136, 10, 236}, + dictWord{140, 11, 54}, + dictWord{4, 11, 421}, + dictWord{133, 11, 548}, + dictWord{11, 0, 719}, + dictWord{12, 0, 36}, + dictWord{141, 0, 337}, + dictWord{7, 0, 581}, + dictWord{9, 0, 644}, + dictWord{137, 0, 699}, + dictWord{11, 11, 511}, + dictWord{13, 11, 394}, + dictWord{14, 11, 298}, + dictWord{14, 11, 318}, + dictWord{146, 11, 103}, + dictWord{7, 0, 304}, + dictWord{9, 0, 646}, + dictWord{9, 0, 862}, + dictWord{11, 0, 696}, + dictWord{12, 0, 208}, + dictWord{15, 0, 79}, + dictWord{147, 0, 108}, + dictWord{4, 0, 631}, + dictWord{7, 0, 1126}, + dictWord{135, 0, 1536}, + dictWord{135, 11, 1527}, + dictWord{8, 0, 880}, + dictWord{10, 0, 869}, + dictWord{138, 0, 913}, + dictWord{7, 0, 1513}, + dictWord{5, 10, 54}, + dictWord{6, 11, 254}, + dictWord{9, 11, 109}, + dictWord{138, 11, 103}, + dictWord{135, 0, 981}, + dictWord{133, 11, 729}, + dictWord{132, 10, 744}, + dictWord{132, 0, 434}, + dictWord{134, 0, 550}, + dictWord{7, 0, 930}, + dictWord{10, 0, 476}, + dictWord{13, 0, 452}, + dictWord{19, 0, 104}, + dictWord{6, 11, 1630}, + dictWord{10, 10, 402}, + dictWord{146, 10, 55}, + dictWord{5, 0, 553}, + dictWord{138, 0, 824}, + dictWord{136, 0, 452}, + dictWord{8, 0, 151}, + dictWord{137, 10, 624}, + dictWord{132, 10, 572}, + dictWord{132, 0, 772}, + dictWord{133, 11, 671}, + dictWord{ + 133, + 0, + 292, + }, + dictWord{138, 0, 135}, + dictWord{132, 11, 889}, + dictWord{140, 11, 207}, + dictWord{9, 0, 504}, + dictWord{6, 10, 43}, + dictWord{7, 10, 38}, + dictWord{ + 8, + 10, + 248, + }, + dictWord{138, 10, 513}, + dictWord{6, 0, 1089}, + dictWord{135, 11, 1910}, + dictWord{4, 11, 627}, + dictWord{133, 11, 775}, + dictWord{135, 0, 783}, + dictWord{133, 10, 766}, + dictWord{133, 10, 363}, + dictWord{7, 0, 387}, + dictWord{135, 11, 387}, + dictWord{7, 0, 393}, + dictWord{10, 0, 603}, + dictWord{11, 0, 206}, + dictWord{7, 11, 202}, + dictWord{11, 11, 362}, + dictWord{11, 11, 948}, + dictWord{140, 11, 388}, + dictWord{6, 11, 507}, + dictWord{7, 11, 451}, + dictWord{8, 11, 389}, + dictWord{12, 11, 490}, + dictWord{13, 11, 16}, + dictWord{13, 11, 215}, + dictWord{13, 11, 351}, + dictWord{18, 11, 132}, + dictWord{147, 11, 125}, + dictWord{ + 4, + 0, + 912, + }, + dictWord{9, 0, 232}, + dictWord{135, 11, 841}, + dictWord{6, 10, 258}, + dictWord{140, 10, 409}, + dictWord{5, 10, 249}, + dictWord{148, 10, 82}, + dictWord{ + 136, + 11, + 566, + }, + dictWord{6, 0, 977}, + dictWord{135, 11, 1214}, + dictWord{7, 0, 1973}, + dictWord{136, 0, 716}, + dictWord{135, 0, 98}, + dictWord{133, 0, 733}, + dictWord{ + 5, + 11, + 912, + }, + dictWord{134, 11, 1695}, + dictWord{5, 10, 393}, + dictWord{6, 10, 378}, + dictWord{7, 10, 1981}, + dictWord{9, 10, 32}, + dictWord{9, 10, 591}, + dictWord{10, 10, 685}, + dictWord{10, 10, 741}, + dictWord{142, 10, 382}, + dictWord{133, 10, 788}, + dictWord{10, 0, 19}, + dictWord{11, 0, 911}, + dictWord{7, 10, 1968}, + dictWord{141, 10, 509}, + dictWord{5, 0, 668}, + dictWord{5, 11, 236}, + dictWord{6, 11, 572}, + dictWord{8, 11, 492}, + dictWord{11, 11, 618}, + dictWord{144, 11, 56}, + dictWord{135, 11, 1789}, + dictWord{4, 0, 360}, + dictWord{5, 0, 635}, + dictWord{5, 0, 700}, + dictWord{5, 10, 58}, + dictWord{5, 10, 171}, + dictWord{5, 10, 683}, + dictWord{ + 6, + 10, + 291, + }, + dictWord{6, 10, 566}, + dictWord{7, 10, 1650}, + dictWord{11, 10, 523}, + dictWord{12, 10, 273}, + dictWord{12, 10, 303}, + dictWord{15, 10, 39}, + dictWord{143, 10, 111}, + dictWord{133, 0, 901}, + dictWord{134, 10, 589}, + dictWord{5, 11, 190}, + dictWord{136, 11, 318}, + dictWord{140, 0, 656}, + dictWord{ + 7, + 0, + 726, + }, + dictWord{152, 0, 9}, + dictWord{4, 10, 917}, + dictWord{133, 10, 1005}, + dictWord{135, 10, 1598}, + dictWord{134, 11, 491}, + dictWord{4, 10, 919}, + dictWord{133, 11, 434}, + dictWord{137, 0, 72}, + dictWord{6, 0, 1269}, + dictWord{6, 0, 1566}, + dictWord{134, 0, 1621}, + dictWord{9, 0, 463}, + dictWord{10, 0, 595}, + dictWord{4, 10, 255}, + dictWord{5, 10, 302}, + dictWord{6, 10, 132}, + dictWord{7, 10, 128}, + dictWord{7, 10, 283}, + dictWord{7, 10, 1299}, + dictWord{10, 10, 52}, + dictWord{ + 10, + 10, + 514, + }, + dictWord{11, 10, 925}, + dictWord{13, 10, 92}, + dictWord{142, 10, 309}, + dictWord{135, 0, 1454}, + dictWord{134, 0, 1287}, + dictWord{11, 0, 600}, + dictWord{13, 0, 245}, + dictWord{137, 10, 173}, + dictWord{136, 0, 989}, + dictWord{7, 0, 164}, + dictWord{7, 0, 1571}, + dictWord{9, 0, 107}, + dictWord{140, 0, 225}, + dictWord{6, 0, 1061}, + dictWord{141, 10, 442}, + dictWord{4, 0, 27}, + dictWord{5, 0, 484}, + dictWord{5, 0, 510}, + dictWord{6, 0, 434}, + dictWord{7, 0, 1000}, + dictWord{ + 7, + 0, + 1098, + }, + dictWord{136, 0, 2}, + dictWord{7, 11, 85}, + dictWord{7, 11, 247}, + dictWord{8, 11, 585}, + dictWord{10, 11, 163}, + dictWord{138, 11, 316}, + dictWord{ + 11, + 11, + 103, + }, + dictWord{142, 11, 0}, + dictWord{134, 0, 1127}, + dictWord{4, 0, 460}, + dictWord{134, 0, 852}, + dictWord{134, 10, 210}, + dictWord{4, 0, 932}, + dictWord{ + 133, + 0, + 891, + }, + dictWord{6, 0, 588}, + dictWord{147, 11, 83}, + dictWord{8, 0, 625}, + dictWord{4, 10, 284}, + dictWord{134, 10, 223}, + dictWord{134, 0, 76}, + dictWord{8, 0, 92}, + dictWord{137, 0, 221}, + dictWord{4, 11, 124}, + dictWord{10, 11, 457}, + dictWord{11, 11, 121}, + dictWord{11, 11, 169}, + dictWord{11, 11, 422}, + dictWord{ + 11, + 11, + 870, + }, + dictWord{12, 11, 214}, + dictWord{13, 11, 389}, + dictWord{14, 11, 187}, + dictWord{143, 11, 77}, + dictWord{9, 11, 618}, + dictWord{138, 11, 482}, + dictWord{ + 4, + 10, + 218, + }, + dictWord{7, 10, 526}, + dictWord{143, 10, 137}, + dictWord{13, 0, 9}, + dictWord{14, 0, 104}, + dictWord{14, 0, 311}, + dictWord{4, 10, 270}, + dictWord{ + 5, + 10, + 192, + }, + dictWord{6, 10, 332}, + dictWord{135, 10, 1322}, + dictWord{140, 10, 661}, + dictWord{135, 11, 1193}, + dictWord{6, 11, 107}, + dictWord{7, 11, 638}, + dictWord{7, 11, 1632}, + dictWord{137, 11, 396}, + dictWord{132, 0, 763}, + dictWord{4, 0, 622}, + dictWord{5, 11, 370}, + dictWord{134, 11, 1756}, + dictWord{ + 133, + 0, + 253, + }, + dictWord{135, 0, 546}, + dictWord{9, 0, 73}, + dictWord{10, 0, 110}, + dictWord{14, 0, 185}, + dictWord{17, 0, 119}, + dictWord{133, 11, 204}, + dictWord{7, 0, 624}, + dictWord{7, 0, 916}, + dictWord{10, 0, 256}, + dictWord{139, 0, 87}, + dictWord{7, 10, 379}, + dictWord{8, 10, 481}, + dictWord{137, 10, 377}, + dictWord{5, 0, 212}, + dictWord{12, 0, 35}, + dictWord{13, 0, 382}, + dictWord{5, 11, 970}, + dictWord{134, 11, 1706}, + dictWord{9, 0, 746}, + dictWord{5, 10, 1003}, + dictWord{134, 10, 149}, + dictWord{10, 0, 150}, + dictWord{11, 0, 849}, + dictWord{13, 0, 330}, + dictWord{8, 10, 262}, + dictWord{9, 10, 627}, + dictWord{11, 10, 214}, + dictWord{11, 10, 404}, + dictWord{11, 10, 457}, + dictWord{11, 10, 780}, + dictWord{11, 10, 913}, + dictWord{13, 10, 401}, + dictWord{142, 10, 200}, + dictWord{134, 0, 1466}, + dictWord{ + 135, + 11, + 3, + }, + dictWord{6, 0, 1299}, + dictWord{4, 11, 35}, + dictWord{5, 11, 121}, + dictWord{5, 11, 483}, + dictWord{5, 11, 685}, + dictWord{6, 11, 489}, + dictWord{7, 11, 1204}, + dictWord{136, 11, 394}, + dictWord{135, 10, 742}, + dictWord{4, 10, 142}, + dictWord{136, 10, 304}, + dictWord{4, 11, 921}, + dictWord{133, 11, 1007}, + dictWord{ + 134, + 0, + 1518, + }, + dictWord{6, 0, 1229}, + dictWord{135, 0, 1175}, + dictWord{133, 0, 816}, + dictWord{12, 0, 159}, + dictWord{4, 10, 471}, + dictWord{4, 11, 712}, + dictWord{ + 5, + 10, + 51, + }, + dictWord{6, 10, 602}, + dictWord{7, 10, 925}, + dictWord{8, 10, 484}, + dictWord{138, 10, 195}, + dictWord{134, 11, 1629}, + dictWord{5, 0, 869}, + dictWord{ + 5, + 0, + 968, + }, + dictWord{6, 0, 1626}, + dictWord{8, 0, 734}, + dictWord{136, 0, 784}, + dictWord{4, 0, 542}, + dictWord{6, 0, 1716}, + dictWord{6, 0, 1727}, + dictWord{ + 7, + 0, + 1082, + }, + dictWord{7, 0, 1545}, + dictWord{8, 0, 56}, + dictWord{8, 0, 118}, + dictWord{8, 0, 412}, + dictWord{8, 0, 564}, + dictWord{9, 0, 888}, + dictWord{9, 0, 908}, + dictWord{ + 10, + 0, + 50, + }, + dictWord{10, 0, 423}, + dictWord{11, 0, 685}, + dictWord{11, 0, 697}, + dictWord{11, 0, 933}, + dictWord{12, 0, 299}, + dictWord{13, 0, 126}, + dictWord{ + 13, + 0, + 136, + }, + dictWord{13, 0, 170}, + dictWord{13, 0, 190}, + dictWord{136, 10, 688}, + dictWord{132, 10, 697}, + dictWord{4, 0, 232}, + dictWord{9, 0, 202}, + dictWord{ + 10, + 0, + 474, + }, + dictWord{140, 0, 433}, + dictWord{136, 0, 212}, + dictWord{6, 0, 108}, + dictWord{7, 0, 1003}, + dictWord{7, 0, 1181}, + dictWord{8, 0, 111}, + dictWord{ + 136, + 0, + 343, + }, + dictWord{5, 10, 221}, + dictWord{135, 11, 1255}, + dictWord{133, 11, 485}, + dictWord{134, 0, 1712}, + dictWord{142, 0, 216}, + dictWord{5, 0, 643}, + dictWord{ + 6, + 0, + 516, + }, + dictWord{4, 11, 285}, + dictWord{5, 11, 317}, + dictWord{6, 11, 301}, + dictWord{7, 11, 7}, + dictWord{8, 11, 153}, + dictWord{10, 11, 766}, + dictWord{ + 11, + 11, + 468, + }, + dictWord{12, 11, 467}, + dictWord{141, 11, 143}, + dictWord{4, 0, 133}, + dictWord{7, 0, 711}, + dictWord{7, 0, 1298}, + dictWord{135, 0, 1585}, + dictWord{ + 134, + 0, + 650, + }, + dictWord{135, 11, 512}, + dictWord{6, 0, 99}, + dictWord{7, 0, 1808}, + dictWord{145, 0, 57}, + dictWord{6, 0, 246}, + dictWord{6, 0, 574}, + dictWord{7, 0, 428}, + dictWord{9, 0, 793}, + dictWord{10, 0, 669}, + dictWord{11, 0, 485}, + dictWord{11, 0, 840}, + dictWord{12, 0, 300}, + dictWord{14, 0, 250}, + dictWord{145, 0, 55}, + dictWord{ + 4, + 10, + 132, + }, + dictWord{5, 10, 69}, + dictWord{135, 10, 1242}, + dictWord{136, 0, 1023}, + dictWord{7, 0, 302}, + dictWord{132, 10, 111}, + dictWord{135, 0, 1871}, + dictWord{132, 0, 728}, + dictWord{9, 0, 252}, + dictWord{132, 10, 767}, + dictWord{6, 0, 461}, + dictWord{7, 0, 1590}, + dictWord{7, 10, 1416}, + dictWord{7, 10, 2005}, + dictWord{8, 10, 131}, + dictWord{8, 10, 466}, + dictWord{9, 10, 672}, + dictWord{13, 10, 252}, + dictWord{148, 10, 103}, + dictWord{6, 0, 323}, + dictWord{135, 0, 1564}, + dictWord{7, 0, 461}, + dictWord{136, 0, 775}, + dictWord{6, 10, 44}, + dictWord{136, 10, 368}, + dictWord{139, 0, 172}, + dictWord{132, 0, 464}, + dictWord{4, 10, 570}, + dictWord{133, 10, 120}, + dictWord{137, 11, 269}, + dictWord{6, 10, 227}, + dictWord{135, 10, 1589}, + dictWord{6, 11, 1719}, + dictWord{6, 11, 1735}, + dictWord{ + 7, + 11, + 2016, + }, + dictWord{7, 11, 2020}, + dictWord{8, 11, 837}, + dictWord{137, 11, 852}, + dictWord{7, 0, 727}, + dictWord{146, 0, 73}, + dictWord{132, 0, 1023}, + dictWord{135, 11, 852}, + dictWord{135, 10, 1529}, + dictWord{136, 0, 577}, + dictWord{138, 11, 568}, + dictWord{134, 0, 1037}, + dictWord{8, 11, 67}, + dictWord{ + 138, + 11, + 419, + }, + dictWord{4, 0, 413}, + dictWord{5, 0, 677}, + dictWord{8, 0, 432}, + dictWord{140, 0, 280}, + dictWord{10, 0, 600}, + dictWord{6, 10, 1667}, + dictWord{ + 7, + 11, + 967, + }, + dictWord{7, 10, 2036}, + dictWord{141, 11, 11}, + dictWord{6, 10, 511}, + dictWord{140, 10, 132}, + dictWord{6, 0, 799}, + dictWord{5, 10, 568}, + dictWord{ + 6, + 10, + 138, + }, + dictWord{135, 10, 1293}, + dictWord{8, 0, 159}, + dictWord{4, 10, 565}, + dictWord{136, 10, 827}, + dictWord{7, 0, 646}, + dictWord{7, 0, 1730}, + dictWord{ + 11, + 0, + 446, + }, + dictWord{141, 0, 178}, + dictWord{4, 10, 922}, + dictWord{133, 10, 1023}, + dictWord{135, 11, 11}, + dictWord{132, 0, 395}, + dictWord{11, 0, 145}, + dictWord{135, 10, 1002}, + dictWord{9, 0, 174}, + dictWord{10, 0, 164}, + dictWord{11, 0, 440}, + dictWord{11, 0, 514}, + dictWord{11, 0, 841}, + dictWord{15, 0, 98}, + dictWord{149, 0, 20}, + dictWord{134, 0, 426}, + dictWord{10, 0, 608}, + dictWord{139, 0, 1002}, + dictWord{7, 11, 320}, + dictWord{8, 11, 51}, + dictWord{12, 11, 481}, + dictWord{12, 11, 570}, + dictWord{148, 11, 106}, + dictWord{9, 0, 977}, + dictWord{9, 0, 983}, + dictWord{132, 11, 445}, + dictWord{138, 0, 250}, + dictWord{139, 0, 100}, + dictWord{6, 0, 1982}, + dictWord{136, 10, 402}, + dictWord{133, 11, 239}, + dictWord{4, 10, 716}, + dictWord{141, 10, 31}, + dictWord{5, 0, 476}, + dictWord{7, 11, 83}, + dictWord{7, 11, 1990}, + dictWord{8, 11, 130}, + dictWord{139, 11, 720}, + dictWord{8, 10, 691}, + dictWord{136, 10, 731}, + dictWord{5, 11, 123}, + dictWord{ + 6, + 11, + 530, + }, + dictWord{7, 11, 348}, + dictWord{135, 11, 1419}, + dictWord{5, 0, 76}, + dictWord{6, 0, 458}, + dictWord{6, 0, 497}, + dictWord{7, 0, 868}, + dictWord{9, 0, 658}, + dictWord{10, 0, 594}, + dictWord{11, 0, 173}, + dictWord{11, 0, 566}, + dictWord{12, 0, 20}, + dictWord{12, 0, 338}, + dictWord{141, 0, 200}, + dictWord{9, 11, 139}, + dictWord{ + 10, + 11, + 399, + }, + dictWord{11, 11, 469}, + dictWord{12, 11, 634}, + dictWord{141, 11, 223}, + dictWord{9, 10, 840}, + dictWord{138, 10, 803}, + dictWord{133, 10, 847}, + dictWord{11, 11, 223}, + dictWord{140, 11, 168}, + dictWord{132, 11, 210}, + dictWord{8, 0, 447}, + dictWord{9, 10, 53}, + dictWord{9, 10, 268}, + dictWord{9, 10, 901}, + dictWord{10, 10, 518}, + dictWord{10, 10, 829}, + dictWord{11, 10, 188}, + dictWord{13, 10, 74}, + dictWord{14, 10, 46}, + dictWord{15, 10, 17}, + dictWord{15, 10, 33}, + dictWord{17, 10, 40}, + dictWord{18, 10, 36}, + dictWord{19, 10, 20}, + dictWord{22, 10, 1}, + dictWord{152, 10, 2}, + dictWord{4, 0, 526}, + dictWord{7, 0, 1029}, + dictWord{135, 0, 1054}, + dictWord{19, 11, 59}, + dictWord{150, 11, 2}, + dictWord{4, 0, 636}, + dictWord{6, 0, 1875}, + dictWord{6, 0, 1920}, + dictWord{9, 0, 999}, + dictWord{ + 12, + 0, + 807, + }, + dictWord{12, 0, 825}, + dictWord{15, 0, 179}, + dictWord{15, 0, 190}, + dictWord{18, 0, 182}, + dictWord{136, 10, 532}, + dictWord{6, 0, 1699}, + dictWord{ + 7, + 0, + 660, + }, + dictWord{7, 0, 1124}, + dictWord{17, 0, 31}, + dictWord{19, 0, 22}, + dictWord{151, 0, 14}, + dictWord{135, 10, 681}, + dictWord{132, 11, 430}, + dictWord{ + 140, + 10, + 677, + }, + dictWord{4, 10, 684}, + dictWord{136, 10, 384}, + dictWord{132, 11, 756}, + dictWord{133, 11, 213}, + dictWord{7, 0, 188}, + dictWord{7, 10, 110}, + dictWord{ + 8, + 10, + 290, + }, + dictWord{8, 10, 591}, + dictWord{9, 10, 382}, + dictWord{9, 10, 649}, + dictWord{11, 10, 71}, + dictWord{11, 10, 155}, + dictWord{11, 10, 313}, + dictWord{ + 12, + 10, + 5, + }, + dictWord{13, 10, 325}, + dictWord{142, 10, 287}, + dictWord{7, 10, 360}, + dictWord{7, 10, 425}, + dictWord{9, 10, 66}, + dictWord{9, 10, 278}, + dictWord{ + 138, + 10, + 644, + }, + dictWord{142, 11, 164}, + dictWord{4, 0, 279}, + dictWord{7, 0, 301}, + dictWord{137, 0, 362}, + dictWord{134, 11, 586}, + dictWord{135, 0, 1743}, + dictWord{4, 0, 178}, + dictWord{133, 0, 399}, + dictWord{4, 10, 900}, + dictWord{133, 10, 861}, + dictWord{5, 10, 254}, + dictWord{7, 10, 985}, + dictWord{136, 10, 73}, + dictWord{133, 11, 108}, + dictWord{7, 10, 1959}, + dictWord{136, 10, 683}, + dictWord{133, 11, 219}, + dictWord{4, 11, 193}, + dictWord{5, 11, 916}, + dictWord{ + 7, + 11, + 364, + }, + dictWord{10, 11, 398}, + dictWord{10, 11, 726}, + dictWord{11, 11, 317}, + dictWord{11, 11, 626}, + dictWord{12, 11, 142}, + dictWord{12, 11, 288}, + dictWord{ + 12, + 11, + 678, + }, + dictWord{13, 11, 313}, + dictWord{15, 11, 113}, + dictWord{18, 11, 114}, + dictWord{21, 11, 30}, + dictWord{150, 11, 53}, + dictWord{6, 11, 241}, + dictWord{7, 11, 907}, + dictWord{8, 11, 832}, + dictWord{9, 11, 342}, + dictWord{10, 11, 729}, + dictWord{11, 11, 284}, + dictWord{11, 11, 445}, + dictWord{11, 11, 651}, + dictWord{11, 11, 863}, + dictWord{13, 11, 398}, + dictWord{146, 11, 99}, + dictWord{132, 0, 872}, + dictWord{134, 0, 831}, + dictWord{134, 0, 1692}, + dictWord{ + 6, + 0, + 202, + }, + dictWord{6, 0, 1006}, + dictWord{9, 0, 832}, + dictWord{10, 0, 636}, + dictWord{11, 0, 208}, + dictWord{12, 0, 360}, + dictWord{17, 0, 118}, + dictWord{18, 0, 27}, + dictWord{20, 0, 67}, + dictWord{137, 11, 734}, + dictWord{132, 10, 725}, + dictWord{7, 11, 993}, + dictWord{138, 11, 666}, + dictWord{134, 0, 1954}, + dictWord{ + 134, + 10, + 196, + }, + dictWord{7, 0, 872}, + dictWord{10, 0, 516}, + dictWord{139, 0, 167}, + dictWord{133, 10, 831}, + dictWord{4, 11, 562}, + dictWord{9, 11, 254}, + dictWord{ + 139, + 11, + 879, + }, + dictWord{137, 0, 313}, + dictWord{4, 0, 224}, + dictWord{132, 11, 786}, + dictWord{11, 0, 24}, + dictWord{12, 0, 170}, + dictWord{136, 10, 723}, + dictWord{ + 5, + 0, + 546, + }, + dictWord{7, 0, 35}, + dictWord{8, 0, 11}, + dictWord{8, 0, 12}, + dictWord{9, 0, 315}, + dictWord{9, 0, 533}, + dictWord{10, 0, 802}, + dictWord{11, 0, 166}, + dictWord{ + 12, + 0, + 525, + }, + dictWord{142, 0, 243}, + dictWord{7, 0, 1937}, + dictWord{13, 10, 80}, + dictWord{13, 10, 437}, + dictWord{145, 10, 74}, + dictWord{5, 0, 241}, + dictWord{ + 8, + 0, + 242, + }, + dictWord{9, 0, 451}, + dictWord{10, 0, 667}, + dictWord{11, 0, 598}, + dictWord{140, 0, 429}, + dictWord{150, 0, 46}, + dictWord{6, 0, 1273}, + dictWord{ + 137, + 0, + 830, + }, + dictWord{5, 10, 848}, + dictWord{6, 10, 66}, + dictWord{136, 10, 764}, + dictWord{6, 0, 825}, + dictWord{134, 0, 993}, + dictWord{4, 0, 1006}, + dictWord{ + 10, + 0, + 327, + }, + dictWord{13, 0, 271}, + dictWord{4, 10, 36}, + dictWord{7, 10, 1387}, + dictWord{139, 10, 755}, + dictWord{134, 0, 1023}, + dictWord{135, 0, 1580}, + dictWord{ + 4, + 0, + 366, + }, + dictWord{137, 0, 516}, + dictWord{132, 10, 887}, + dictWord{6, 0, 1736}, + dictWord{135, 0, 1891}, + dictWord{6, 11, 216}, + dictWord{7, 11, 901}, + dictWord{ + 7, + 11, + 1343, + }, + dictWord{136, 11, 493}, + dictWord{6, 10, 165}, + dictWord{138, 10, 388}, + dictWord{7, 11, 341}, + dictWord{139, 11, 219}, + dictWord{4, 10, 719}, + dictWord{135, 10, 155}, + dictWord{134, 0, 1935}, + dictWord{132, 0, 826}, + dictWord{6, 0, 331}, + dictWord{6, 0, 1605}, + dictWord{8, 0, 623}, + dictWord{11, 0, 139}, + dictWord{139, 0, 171}, + dictWord{135, 11, 1734}, + dictWord{10, 11, 115}, + dictWord{11, 11, 420}, + dictWord{12, 11, 154}, + dictWord{13, 11, 404}, + dictWord{ + 14, + 11, + 346, + }, + dictWord{15, 11, 54}, + dictWord{143, 11, 112}, + dictWord{7, 0, 288}, + dictWord{4, 10, 353}, + dictWord{6, 10, 146}, + dictWord{6, 10, 1789}, + dictWord{ + 7, + 10, + 990, + }, + dictWord{7, 10, 1348}, + dictWord{9, 10, 665}, + dictWord{9, 10, 898}, + dictWord{11, 10, 893}, + dictWord{142, 10, 212}, + dictWord{6, 0, 916}, + dictWord{134, 0, 1592}, + dictWord{7, 0, 1888}, + dictWord{4, 10, 45}, + dictWord{135, 10, 1257}, + dictWord{5, 11, 1011}, + dictWord{136, 11, 701}, + dictWord{ + 139, + 11, + 596, + }, + dictWord{4, 11, 54}, + dictWord{5, 11, 666}, + dictWord{7, 11, 1039}, + dictWord{7, 11, 1130}, + dictWord{9, 11, 195}, + dictWord{138, 11, 302}, + dictWord{ + 134, + 0, + 1471, + }, + dictWord{134, 0, 1570}, + dictWord{132, 0, 394}, + dictWord{140, 10, 65}, + dictWord{136, 10, 816}, + dictWord{135, 0, 1931}, + dictWord{7, 0, 574}, + dictWord{135, 0, 1719}, + dictWord{134, 11, 467}, + dictWord{132, 0, 658}, + dictWord{9, 0, 781}, + dictWord{10, 0, 144}, + dictWord{11, 0, 385}, + dictWord{13, 0, 161}, + dictWord{13, 0, 228}, + dictWord{13, 0, 268}, + dictWord{20, 0, 107}, + dictWord{134, 11, 1669}, + dictWord{136, 0, 374}, + dictWord{135, 0, 735}, + dictWord{4, 0, 344}, + dictWord{6, 0, 498}, + dictWord{139, 0, 323}, + dictWord{7, 0, 586}, + dictWord{7, 0, 1063}, + dictWord{6, 10, 559}, + dictWord{134, 10, 1691}, + dictWord{137, 0, 155}, + dictWord{133, 0, 906}, + dictWord{7, 11, 122}, + dictWord{9, 11, 259}, + dictWord{10, 11, 84}, + dictWord{11, 11, 470}, + dictWord{12, 11, 541}, + dictWord{ + 141, + 11, + 379, + }, + dictWord{134, 0, 1139}, + dictWord{10, 0, 108}, + dictWord{139, 0, 116}, + dictWord{134, 10, 456}, + dictWord{133, 10, 925}, + dictWord{5, 11, 82}, + dictWord{ + 5, + 11, + 131, + }, + dictWord{7, 11, 1755}, + dictWord{8, 11, 31}, + dictWord{9, 11, 168}, + dictWord{9, 11, 764}, + dictWord{139, 11, 869}, + dictWord{134, 11, 605}, + dictWord{ + 5, + 11, + 278, + }, + dictWord{137, 11, 68}, + dictWord{4, 11, 163}, + dictWord{5, 11, 201}, + dictWord{5, 11, 307}, + dictWord{5, 11, 310}, + dictWord{6, 11, 335}, + dictWord{ + 7, + 11, + 284, + }, + dictWord{136, 11, 165}, + dictWord{135, 11, 1660}, + dictWord{6, 11, 33}, + dictWord{135, 11, 1244}, + dictWord{4, 0, 616}, + dictWord{136, 11, 483}, + dictWord{8, 0, 857}, + dictWord{8, 0, 902}, + dictWord{8, 0, 910}, + dictWord{10, 0, 879}, + dictWord{12, 0, 726}, + dictWord{4, 11, 199}, + dictWord{139, 11, 34}, + dictWord{136, 0, 692}, + dictWord{6, 10, 193}, + dictWord{7, 10, 240}, + dictWord{7, 10, 1682}, + dictWord{10, 10, 51}, + dictWord{10, 10, 640}, + dictWord{11, 10, 410}, + dictWord{13, 10, 82}, + dictWord{14, 10, 247}, + dictWord{14, 10, 331}, + dictWord{142, 10, 377}, + dictWord{6, 0, 823}, + dictWord{134, 0, 983}, + dictWord{ + 139, + 10, + 411, + }, + dictWord{132, 0, 305}, + dictWord{136, 10, 633}, + dictWord{138, 11, 203}, + dictWord{134, 0, 681}, + dictWord{6, 11, 326}, + dictWord{7, 11, 677}, + dictWord{137, 11, 425}, + dictWord{5, 0, 214}, + dictWord{7, 0, 603}, + dictWord{8, 0, 611}, + dictWord{9, 0, 686}, + dictWord{10, 0, 88}, + dictWord{11, 0, 459}, + dictWord{ + 11, + 0, + 496, + }, + dictWord{12, 0, 463}, + dictWord{12, 0, 590}, + dictWord{141, 0, 0}, + dictWord{136, 0, 1004}, + dictWord{142, 0, 23}, + dictWord{134, 0, 1703}, + dictWord{ + 147, + 11, + 8, + }, + dictWord{145, 11, 56}, + dictWord{135, 0, 1443}, + dictWord{4, 10, 237}, + dictWord{135, 10, 514}, + dictWord{6, 0, 714}, + dictWord{145, 0, 19}, + dictWord{ + 5, + 11, + 358, + }, + dictWord{7, 11, 473}, + dictWord{7, 11, 1184}, + dictWord{10, 11, 662}, + dictWord{13, 11, 212}, + dictWord{13, 11, 304}, + dictWord{13, 11, 333}, + dictWord{145, 11, 98}, + dictWord{4, 0, 737}, + dictWord{10, 0, 98}, + dictWord{11, 0, 294}, + dictWord{12, 0, 60}, + dictWord{12, 0, 437}, + dictWord{13, 0, 64}, + dictWord{ + 13, + 0, + 380, + }, + dictWord{142, 0, 430}, + dictWord{6, 10, 392}, + dictWord{7, 10, 65}, + dictWord{135, 10, 2019}, + dictWord{6, 0, 1758}, + dictWord{8, 0, 520}, + dictWord{ + 9, + 0, + 345, + }, + dictWord{9, 0, 403}, + dictWord{142, 0, 350}, + dictWord{5, 0, 47}, + dictWord{10, 0, 242}, + dictWord{138, 0, 579}, + dictWord{5, 0, 139}, + dictWord{7, 0, 1168}, + dictWord{138, 0, 539}, + dictWord{134, 0, 1459}, + dictWord{13, 0, 388}, + dictWord{141, 11, 388}, + dictWord{134, 0, 253}, + dictWord{7, 10, 1260}, + dictWord{ + 135, + 10, + 1790, + }, + dictWord{10, 0, 252}, + dictWord{9, 10, 222}, + dictWord{139, 10, 900}, + dictWord{140, 0, 745}, + dictWord{133, 11, 946}, + dictWord{4, 0, 107}, + dictWord{ + 7, + 0, + 613, + }, + dictWord{8, 0, 439}, + dictWord{8, 0, 504}, + dictWord{9, 0, 501}, + dictWord{10, 0, 383}, + dictWord{139, 0, 477}, + dictWord{135, 11, 1485}, + dictWord{ + 132, + 0, + 871, + }, + dictWord{7, 11, 411}, + dictWord{7, 11, 590}, + dictWord{8, 11, 631}, + dictWord{9, 11, 323}, + dictWord{10, 11, 355}, + dictWord{11, 11, 491}, + dictWord{ + 12, + 11, + 143, + }, + dictWord{12, 11, 402}, + dictWord{13, 11, 73}, + dictWord{14, 11, 408}, + dictWord{15, 11, 107}, + dictWord{146, 11, 71}, + dictWord{132, 0, 229}, + dictWord{132, 0, 903}, + dictWord{140, 0, 71}, + dictWord{133, 0, 549}, + dictWord{4, 0, 47}, + dictWord{6, 0, 373}, + dictWord{7, 0, 452}, + dictWord{7, 0, 543}, + dictWord{ + 7, + 0, + 1828, + }, + dictWord{7, 0, 1856}, + dictWord{9, 0, 6}, + dictWord{11, 0, 257}, + dictWord{139, 0, 391}, + dictWord{7, 11, 1467}, + dictWord{8, 11, 328}, + dictWord{ + 10, + 11, + 544, + }, + dictWord{11, 11, 955}, + dictWord{13, 11, 320}, + dictWord{145, 11, 83}, + dictWord{5, 0, 980}, + dictWord{134, 0, 1754}, + dictWord{136, 0, 865}, + dictWord{ + 5, + 0, + 705, + }, + dictWord{137, 0, 606}, + dictWord{7, 0, 161}, + dictWord{8, 10, 201}, + dictWord{136, 10, 605}, + dictWord{143, 11, 35}, + dictWord{5, 11, 835}, + dictWord{ + 6, + 11, + 483, + }, + dictWord{140, 10, 224}, + dictWord{7, 0, 536}, + dictWord{7, 0, 1331}, + dictWord{136, 0, 143}, + dictWord{134, 0, 1388}, + dictWord{5, 0, 724}, + dictWord{ + 10, + 0, + 305, + }, + dictWord{11, 0, 151}, + dictWord{12, 0, 33}, + dictWord{12, 0, 121}, + dictWord{12, 0, 381}, + dictWord{17, 0, 3}, + dictWord{17, 0, 27}, + dictWord{17, 0, 78}, + dictWord{18, 0, 18}, + dictWord{19, 0, 54}, + dictWord{149, 0, 5}, + dictWord{4, 10, 523}, + dictWord{133, 10, 638}, + dictWord{5, 0, 19}, + dictWord{134, 0, 533}, + dictWord{ + 5, + 0, + 395, + }, + dictWord{5, 0, 951}, + dictWord{134, 0, 1776}, + dictWord{135, 0, 1908}, + dictWord{132, 0, 846}, + dictWord{10, 0, 74}, + dictWord{11, 0, 663}, + dictWord{ + 12, + 0, + 210, + }, + dictWord{13, 0, 166}, + dictWord{13, 0, 310}, + dictWord{14, 0, 373}, + dictWord{18, 0, 95}, + dictWord{19, 0, 43}, + dictWord{6, 10, 242}, + dictWord{7, 10, 227}, + dictWord{7, 10, 1581}, + dictWord{8, 10, 104}, + dictWord{9, 10, 113}, + dictWord{9, 10, 220}, + dictWord{9, 10, 427}, + dictWord{10, 10, 239}, + dictWord{11, 10, 579}, + dictWord{11, 10, 1023}, + dictWord{13, 10, 4}, + dictWord{13, 10, 204}, + dictWord{13, 10, 316}, + dictWord{148, 10, 86}, + dictWord{9, 11, 716}, + dictWord{11, 11, 108}, + dictWord{13, 11, 123}, + dictWord{14, 11, 252}, + dictWord{19, 11, 38}, + dictWord{21, 11, 3}, + dictWord{151, 11, 11}, + dictWord{8, 0, 372}, + dictWord{9, 0, 122}, + dictWord{138, 0, 175}, + dictWord{132, 11, 677}, + dictWord{7, 11, 1374}, + dictWord{136, 11, 540}, + dictWord{135, 10, 861}, + dictWord{132, 0, 695}, + dictWord{ + 7, + 0, + 497, + }, + dictWord{9, 0, 387}, + dictWord{147, 0, 81}, + dictWord{136, 0, 937}, + dictWord{134, 0, 718}, + dictWord{7, 0, 1328}, + dictWord{136, 10, 494}, + dictWord{ + 132, + 11, + 331, + }, + dictWord{6, 0, 1581}, + dictWord{133, 11, 747}, + dictWord{5, 0, 284}, + dictWord{6, 0, 49}, + dictWord{6, 0, 350}, + dictWord{7, 0, 1}, + dictWord{7, 0, 377}, + dictWord{7, 0, 1693}, + dictWord{8, 0, 18}, + dictWord{8, 0, 678}, + dictWord{9, 0, 161}, + dictWord{9, 0, 585}, + dictWord{9, 0, 671}, + dictWord{9, 0, 839}, + dictWord{11, 0, 912}, + dictWord{141, 0, 427}, + dictWord{7, 10, 1306}, + dictWord{8, 10, 505}, + dictWord{9, 10, 482}, + dictWord{10, 10, 126}, + dictWord{11, 10, 225}, + dictWord{12, 10, 347}, + dictWord{12, 10, 449}, + dictWord{13, 10, 19}, + dictWord{14, 10, 218}, + dictWord{142, 10, 435}, + dictWord{10, 10, 764}, + dictWord{12, 10, 120}, + dictWord{ + 13, + 10, + 39, + }, + dictWord{145, 10, 127}, + dictWord{4, 0, 597}, + dictWord{133, 10, 268}, + dictWord{134, 0, 1094}, + dictWord{4, 0, 1008}, + dictWord{134, 0, 1973}, + dictWord{132, 0, 811}, + dictWord{139, 0, 908}, + dictWord{135, 0, 1471}, + dictWord{133, 11, 326}, + dictWord{4, 10, 384}, + dictWord{135, 10, 1022}, + dictWord{ + 7, + 0, + 1935, + }, + dictWord{8, 0, 324}, + dictWord{12, 0, 42}, + dictWord{4, 11, 691}, + dictWord{7, 11, 1935}, + dictWord{8, 11, 324}, + dictWord{9, 11, 35}, + dictWord{10, 11, 680}, + dictWord{11, 11, 364}, + dictWord{12, 11, 42}, + dictWord{13, 11, 357}, + dictWord{146, 11, 16}, + dictWord{135, 0, 2014}, + dictWord{7, 0, 2007}, + dictWord{ + 9, + 0, + 101, + }, + dictWord{9, 0, 450}, + dictWord{10, 0, 66}, + dictWord{10, 0, 842}, + dictWord{11, 0, 536}, + dictWord{12, 0, 587}, + dictWord{6, 11, 32}, + dictWord{7, 11, 385}, + dictWord{7, 11, 757}, + dictWord{7, 11, 1916}, + dictWord{8, 11, 37}, + dictWord{8, 11, 94}, + dictWord{8, 11, 711}, + dictWord{9, 11, 541}, + dictWord{10, 11, 162}, + dictWord{ + 10, + 11, + 795, + }, + dictWord{11, 11, 989}, + dictWord{11, 11, 1010}, + dictWord{12, 11, 14}, + dictWord{142, 11, 308}, + dictWord{139, 0, 586}, + dictWord{ + 135, + 10, + 1703, + }, + dictWord{7, 0, 1077}, + dictWord{11, 0, 28}, + dictWord{9, 10, 159}, + dictWord{140, 10, 603}, + dictWord{6, 0, 1221}, + dictWord{136, 10, 583}, + dictWord{ + 6, + 11, + 152, + }, + dictWord{6, 11, 349}, + dictWord{6, 11, 1682}, + dictWord{7, 11, 1252}, + dictWord{8, 11, 112}, + dictWord{9, 11, 435}, + dictWord{9, 11, 668}, + dictWord{ + 10, + 11, + 290, + }, + dictWord{10, 11, 319}, + dictWord{10, 11, 815}, + dictWord{11, 11, 180}, + dictWord{11, 11, 837}, + dictWord{12, 11, 240}, + dictWord{13, 11, 152}, + dictWord{13, 11, 219}, + dictWord{142, 11, 158}, + dictWord{139, 0, 62}, + dictWord{132, 10, 515}, + dictWord{8, 10, 632}, + dictWord{8, 10, 697}, + dictWord{ + 137, + 10, + 854, + }, + dictWord{134, 0, 1766}, + dictWord{132, 11, 581}, + dictWord{6, 11, 126}, + dictWord{7, 11, 573}, + dictWord{8, 11, 397}, + dictWord{142, 11, 44}, + dictWord{ + 150, + 0, + 28, + }, + dictWord{11, 0, 670}, + dictWord{22, 0, 25}, + dictWord{4, 10, 136}, + dictWord{133, 10, 551}, + dictWord{6, 0, 1665}, + dictWord{7, 0, 256}, + dictWord{ + 7, + 0, + 1388, + }, + dictWord{138, 0, 499}, + dictWord{4, 0, 22}, + dictWord{5, 0, 10}, + dictWord{7, 0, 1576}, + dictWord{136, 0, 97}, + dictWord{134, 10, 1782}, + dictWord{5, 0, 481}, + dictWord{7, 10, 1287}, + dictWord{9, 10, 44}, + dictWord{10, 10, 552}, + dictWord{10, 10, 642}, + dictWord{11, 10, 839}, + dictWord{12, 10, 274}, + dictWord{ + 12, + 10, + 275, + }, + dictWord{12, 10, 372}, + dictWord{13, 10, 91}, + dictWord{142, 10, 125}, + dictWord{133, 11, 926}, + dictWord{7, 11, 1232}, + dictWord{137, 11, 531}, + dictWord{6, 0, 134}, + dictWord{7, 0, 437}, + dictWord{7, 0, 1824}, + dictWord{9, 0, 37}, + dictWord{14, 0, 285}, + dictWord{142, 0, 371}, + dictWord{7, 0, 486}, + dictWord{8, 0, 155}, + dictWord{11, 0, 93}, + dictWord{140, 0, 164}, + dictWord{6, 0, 1391}, + dictWord{134, 0, 1442}, + dictWord{133, 11, 670}, + dictWord{133, 0, 591}, + dictWord{ + 6, + 10, + 147, + }, + dictWord{7, 10, 886}, + dictWord{7, 11, 1957}, + dictWord{9, 10, 753}, + dictWord{138, 10, 268}, + dictWord{5, 0, 380}, + dictWord{5, 0, 650}, + dictWord{ + 7, + 0, + 1173, + }, + dictWord{136, 0, 310}, + dictWord{4, 0, 364}, + dictWord{7, 0, 1156}, + dictWord{7, 0, 1187}, + dictWord{137, 0, 409}, + dictWord{135, 11, 1621}, + dictWord{ + 134, + 0, + 482, + }, + dictWord{133, 11, 506}, + dictWord{4, 0, 781}, + dictWord{6, 0, 487}, + dictWord{7, 0, 926}, + dictWord{8, 0, 263}, + dictWord{139, 0, 500}, + dictWord{ + 138, + 10, + 137, + }, + dictWord{135, 11, 242}, + dictWord{139, 11, 96}, + dictWord{133, 10, 414}, + dictWord{135, 10, 1762}, + dictWord{134, 0, 804}, + dictWord{5, 11, 834}, + dictWord{7, 11, 1202}, + dictWord{8, 11, 14}, + dictWord{9, 11, 481}, + dictWord{137, 11, 880}, + dictWord{134, 10, 599}, + dictWord{4, 0, 94}, + dictWord{135, 0, 1265}, + dictWord{4, 0, 415}, + dictWord{132, 0, 417}, + dictWord{5, 0, 348}, + dictWord{6, 0, 522}, + dictWord{6, 10, 1749}, + dictWord{7, 11, 1526}, + dictWord{138, 11, 465}, + dictWord{134, 10, 1627}, + dictWord{132, 0, 1012}, + dictWord{132, 10, 488}, + dictWord{4, 11, 357}, + dictWord{6, 11, 172}, + dictWord{7, 11, 143}, + dictWord{ + 137, + 11, + 413, + }, + dictWord{4, 10, 83}, + dictWord{4, 11, 590}, + dictWord{146, 11, 76}, + dictWord{140, 10, 676}, + dictWord{7, 11, 287}, + dictWord{8, 11, 355}, + dictWord{ + 9, + 11, + 293, + }, + dictWord{137, 11, 743}, + dictWord{134, 10, 278}, + dictWord{6, 0, 1803}, + dictWord{18, 0, 165}, + dictWord{24, 0, 21}, + dictWord{5, 11, 169}, + dictWord{ + 7, + 11, + 333, + }, + dictWord{136, 11, 45}, + dictWord{12, 10, 97}, + dictWord{140, 11, 97}, + dictWord{4, 0, 408}, + dictWord{4, 0, 741}, + dictWord{135, 0, 500}, + dictWord{ + 132, + 11, + 198, + }, + dictWord{7, 10, 388}, + dictWord{7, 10, 644}, + dictWord{139, 10, 781}, + dictWord{4, 11, 24}, + dictWord{5, 11, 140}, + dictWord{5, 11, 185}, + dictWord{ + 7, + 11, + 1500, + }, + dictWord{11, 11, 565}, + dictWord{139, 11, 838}, + dictWord{6, 0, 1321}, + dictWord{9, 0, 257}, + dictWord{7, 10, 229}, + dictWord{8, 10, 59}, + dictWord{ + 9, + 10, + 190, + }, + dictWord{10, 10, 378}, + dictWord{140, 10, 191}, + dictWord{4, 11, 334}, + dictWord{133, 11, 593}, + dictWord{135, 11, 1885}, + dictWord{134, 0, 1138}, + dictWord{4, 0, 249}, + dictWord{6, 0, 73}, + dictWord{135, 0, 177}, + dictWord{133, 0, 576}, + dictWord{142, 0, 231}, + dictWord{137, 0, 288}, + dictWord{132, 10, 660}, + dictWord{7, 10, 1035}, + dictWord{138, 10, 737}, + dictWord{135, 0, 1487}, + dictWord{6, 0, 989}, + dictWord{9, 0, 433}, + dictWord{7, 10, 690}, + dictWord{9, 10, 587}, + dictWord{140, 10, 521}, + dictWord{7, 0, 1264}, + dictWord{7, 0, 1678}, + dictWord{11, 0, 945}, + dictWord{12, 0, 341}, + dictWord{12, 0, 471}, + dictWord{140, 0, 569}, + dictWord{132, 11, 709}, + dictWord{133, 11, 897}, + dictWord{5, 11, 224}, + dictWord{13, 11, 174}, + dictWord{146, 11, 52}, + dictWord{135, 11, 1840}, + dictWord{ + 134, + 10, + 1744, + }, + dictWord{12, 0, 87}, + dictWord{16, 0, 74}, + dictWord{4, 10, 733}, + dictWord{9, 10, 194}, + dictWord{10, 10, 92}, + dictWord{11, 10, 198}, + dictWord{ + 12, + 10, + 84, + }, + dictWord{141, 10, 128}, + dictWord{140, 0, 779}, + dictWord{135, 0, 538}, + dictWord{4, 11, 608}, + dictWord{133, 11, 497}, + dictWord{133, 0, 413}, + dictWord{7, 11, 1375}, + dictWord{7, 11, 1466}, + dictWord{138, 11, 331}, + dictWord{136, 0, 495}, + dictWord{6, 11, 540}, + dictWord{136, 11, 136}, + dictWord{7, 0, 54}, + dictWord{8, 0, 312}, + dictWord{10, 0, 191}, + dictWord{10, 0, 614}, + dictWord{140, 0, 567}, + dictWord{6, 0, 468}, + dictWord{7, 0, 567}, + dictWord{7, 0, 1478}, + dictWord{ + 8, + 0, + 530, + }, + dictWord{14, 0, 290}, + dictWord{133, 11, 999}, + dictWord{4, 11, 299}, + dictWord{7, 10, 306}, + dictWord{135, 11, 1004}, + dictWord{142, 11, 296}, + dictWord{134, 0, 1484}, + dictWord{133, 10, 979}, + dictWord{6, 0, 609}, + dictWord{9, 0, 815}, + dictWord{12, 11, 137}, + dictWord{14, 11, 9}, + dictWord{14, 11, 24}, + dictWord{142, 11, 64}, + dictWord{133, 11, 456}, + dictWord{6, 0, 484}, + dictWord{135, 0, 822}, + dictWord{133, 10, 178}, + dictWord{136, 11, 180}, + dictWord{ + 132, + 11, + 755, + }, + dictWord{137, 0, 900}, + dictWord{135, 0, 1335}, + dictWord{6, 0, 1724}, + dictWord{135, 0, 2022}, + dictWord{135, 11, 1139}, + dictWord{5, 0, 640}, + dictWord{132, 10, 390}, + dictWord{6, 0, 1831}, + dictWord{138, 11, 633}, + dictWord{135, 11, 566}, + dictWord{4, 11, 890}, + dictWord{5, 11, 805}, + dictWord{5, 11, 819}, + dictWord{5, 11, 961}, + dictWord{6, 11, 396}, + dictWord{6, 11, 1631}, + dictWord{6, 11, 1678}, + dictWord{7, 11, 1967}, + dictWord{7, 11, 2041}, + dictWord{ + 9, + 11, + 630, + }, + dictWord{11, 11, 8}, + dictWord{11, 11, 1019}, + dictWord{12, 11, 176}, + dictWord{13, 11, 225}, + dictWord{14, 11, 292}, + dictWord{149, 11, 24}, + dictWord{ + 132, + 0, + 474, + }, + dictWord{134, 0, 1103}, + dictWord{135, 0, 1504}, + dictWord{134, 0, 1576}, + dictWord{6, 0, 961}, + dictWord{6, 0, 1034}, + dictWord{140, 0, 655}, + dictWord{11, 11, 514}, + dictWord{149, 11, 20}, + dictWord{5, 0, 305}, + dictWord{135, 11, 1815}, + dictWord{7, 11, 1505}, + dictWord{10, 11, 190}, + dictWord{ + 10, + 11, + 634, + }, + dictWord{11, 11, 792}, + dictWord{12, 11, 358}, + dictWord{140, 11, 447}, + dictWord{5, 11, 0}, + dictWord{6, 11, 536}, + dictWord{7, 11, 604}, + dictWord{ + 13, + 11, + 445, + }, + dictWord{145, 11, 126}, + dictWord{7, 0, 1236}, + dictWord{133, 10, 105}, + dictWord{4, 0, 480}, + dictWord{6, 0, 217}, + dictWord{6, 0, 302}, + dictWord{ + 6, + 0, + 1642, + }, + dictWord{7, 0, 130}, + dictWord{7, 0, 837}, + dictWord{7, 0, 1321}, + dictWord{7, 0, 1547}, + dictWord{7, 0, 1657}, + dictWord{8, 0, 429}, + dictWord{9, 0, 228}, + dictWord{13, 0, 289}, + dictWord{13, 0, 343}, + dictWord{19, 0, 101}, + dictWord{6, 11, 232}, + dictWord{6, 11, 412}, + dictWord{7, 11, 1074}, + dictWord{8, 11, 9}, + dictWord{ + 8, + 11, + 157, + }, + dictWord{8, 11, 786}, + dictWord{9, 11, 196}, + dictWord{9, 11, 352}, + dictWord{9, 11, 457}, + dictWord{10, 11, 337}, + dictWord{11, 11, 232}, + dictWord{ + 11, + 11, + 877, + }, + dictWord{12, 11, 480}, + dictWord{140, 11, 546}, + dictWord{5, 10, 438}, + dictWord{7, 11, 958}, + dictWord{9, 10, 694}, + dictWord{12, 10, 627}, + dictWord{ + 13, + 11, + 38, + }, + dictWord{141, 10, 210}, + dictWord{4, 11, 382}, + dictWord{136, 11, 579}, + dictWord{7, 0, 278}, + dictWord{10, 0, 739}, + dictWord{11, 0, 708}, + dictWord{ + 141, + 0, + 348, + }, + dictWord{4, 11, 212}, + dictWord{135, 11, 1206}, + dictWord{135, 11, 1898}, + dictWord{6, 0, 708}, + dictWord{6, 0, 1344}, + dictWord{152, 10, 11}, + dictWord{137, 11, 768}, + dictWord{134, 0, 1840}, + dictWord{140, 0, 233}, + dictWord{8, 10, 25}, + dictWord{138, 10, 826}, + dictWord{6, 0, 2017}, + dictWord{ + 133, + 11, + 655, + }, + dictWord{6, 0, 1488}, + dictWord{139, 11, 290}, + dictWord{132, 10, 308}, + dictWord{134, 0, 1590}, + dictWord{134, 0, 1800}, + dictWord{134, 0, 1259}, + dictWord{16, 0, 28}, + dictWord{6, 11, 231}, + dictWord{7, 11, 95}, + dictWord{136, 11, 423}, + dictWord{133, 11, 300}, + dictWord{135, 10, 150}, + dictWord{ + 136, + 10, + 649, + }, + dictWord{7, 11, 1874}, + dictWord{137, 11, 641}, + dictWord{6, 11, 237}, + dictWord{7, 11, 611}, + dictWord{8, 11, 100}, + dictWord{9, 11, 416}, + dictWord{ + 11, + 11, + 335, + }, + dictWord{12, 11, 173}, + dictWord{146, 11, 101}, + dictWord{137, 0, 45}, + dictWord{134, 10, 521}, + dictWord{17, 0, 36}, + dictWord{14, 11, 26}, + dictWord{ + 146, + 11, + 150, + }, + dictWord{7, 0, 1442}, + dictWord{14, 0, 22}, + dictWord{5, 10, 339}, + dictWord{15, 10, 41}, + dictWord{15, 10, 166}, + dictWord{147, 10, 66}, + dictWord{ + 8, + 0, + 378, + }, + dictWord{6, 11, 581}, + dictWord{135, 11, 1119}, + dictWord{134, 0, 1507}, + dictWord{147, 11, 117}, + dictWord{139, 0, 39}, + dictWord{134, 0, 1054}, + dictWord{6, 0, 363}, + dictWord{7, 0, 1955}, + dictWord{136, 0, 725}, + dictWord{134, 0, 2036}, + dictWord{133, 11, 199}, + dictWord{6, 0, 1871}, + dictWord{9, 0, 935}, + dictWord{9, 0, 961}, + dictWord{9, 0, 1004}, + dictWord{9, 0, 1016}, + dictWord{12, 0, 805}, + dictWord{12, 0, 852}, + dictWord{12, 0, 853}, + dictWord{12, 0, 869}, + dictWord{ + 12, + 0, + 882, + }, + dictWord{12, 0, 896}, + dictWord{12, 0, 906}, + dictWord{12, 0, 917}, + dictWord{12, 0, 940}, + dictWord{15, 0, 170}, + dictWord{15, 0, 176}, + dictWord{ + 15, + 0, + 188, + }, + dictWord{15, 0, 201}, + dictWord{15, 0, 205}, + dictWord{15, 0, 212}, + dictWord{15, 0, 234}, + dictWord{15, 0, 244}, + dictWord{18, 0, 181}, + dictWord{18, 0, 193}, + dictWord{18, 0, 196}, + dictWord{18, 0, 201}, + dictWord{18, 0, 202}, + dictWord{18, 0, 210}, + dictWord{18, 0, 217}, + dictWord{18, 0, 235}, + dictWord{18, 0, 236}, + dictWord{18, 0, 237}, + dictWord{21, 0, 54}, + dictWord{21, 0, 55}, + dictWord{21, 0, 58}, + dictWord{21, 0, 59}, + dictWord{152, 0, 22}, + dictWord{134, 10, 1628}, + dictWord{ + 137, + 0, + 805, + }, + dictWord{5, 0, 813}, + dictWord{135, 0, 2046}, + dictWord{142, 11, 42}, + dictWord{5, 0, 712}, + dictWord{6, 0, 1240}, + dictWord{11, 0, 17}, + dictWord{ + 13, + 0, + 321, + }, + dictWord{144, 0, 67}, + dictWord{132, 0, 617}, + dictWord{135, 10, 829}, + dictWord{6, 0, 320}, + dictWord{7, 0, 781}, + dictWord{7, 0, 1921}, + dictWord{9, 0, 55}, + dictWord{10, 0, 186}, + dictWord{10, 0, 273}, + dictWord{10, 0, 664}, + dictWord{10, 0, 801}, + dictWord{11, 0, 996}, + dictWord{11, 0, 997}, + dictWord{13, 0, 157}, + dictWord{142, 0, 170}, + dictWord{136, 0, 271}, + dictWord{5, 10, 486}, + dictWord{135, 10, 1349}, + dictWord{18, 11, 91}, + dictWord{147, 11, 70}, + dictWord{10, 0, 445}, + dictWord{7, 10, 1635}, + dictWord{8, 10, 17}, + dictWord{138, 10, 295}, + dictWord{136, 11, 404}, + dictWord{7, 0, 103}, + dictWord{7, 0, 863}, + dictWord{11, 0, 184}, + dictWord{145, 0, 62}, + dictWord{138, 10, 558}, + dictWord{137, 0, 659}, + dictWord{6, 11, 312}, + dictWord{6, 11, 1715}, + dictWord{10, 11, 584}, + dictWord{ + 11, + 11, + 546, + }, + dictWord{11, 11, 692}, + dictWord{12, 11, 259}, + dictWord{12, 11, 295}, + dictWord{13, 11, 46}, + dictWord{141, 11, 154}, + dictWord{134, 0, 676}, + dictWord{132, 11, 588}, + dictWord{4, 11, 231}, + dictWord{5, 11, 61}, + dictWord{6, 11, 104}, + dictWord{7, 11, 729}, + dictWord{7, 11, 964}, + dictWord{7, 11, 1658}, + dictWord{140, 11, 414}, + dictWord{6, 11, 263}, + dictWord{138, 11, 757}, + dictWord{11, 0, 337}, + dictWord{142, 0, 303}, + dictWord{135, 11, 1363}, + dictWord{ + 132, + 11, + 320, + }, + dictWord{140, 0, 506}, + dictWord{134, 10, 447}, + dictWord{5, 0, 77}, + dictWord{7, 0, 1455}, + dictWord{10, 0, 843}, + dictWord{147, 0, 73}, + dictWord{ + 7, + 10, + 577, + }, + dictWord{7, 10, 1432}, + dictWord{9, 10, 475}, + dictWord{9, 10, 505}, + dictWord{9, 10, 526}, + dictWord{9, 10, 609}, + dictWord{9, 10, 689}, + dictWord{ + 9, + 10, + 726, + }, + dictWord{9, 10, 735}, + dictWord{9, 10, 738}, + dictWord{10, 10, 556}, + dictWord{10, 10, 674}, + dictWord{10, 10, 684}, + dictWord{11, 10, 89}, + dictWord{ + 11, + 10, + 202, + }, + dictWord{11, 10, 272}, + dictWord{11, 10, 380}, + dictWord{11, 10, 415}, + dictWord{11, 10, 505}, + dictWord{11, 10, 537}, + dictWord{11, 10, 550}, + dictWord{11, 10, 562}, + dictWord{11, 10, 640}, + dictWord{11, 10, 667}, + dictWord{11, 10, 688}, + dictWord{11, 10, 847}, + dictWord{11, 10, 927}, + dictWord{ + 11, + 10, + 930, + }, + dictWord{11, 10, 940}, + dictWord{12, 10, 144}, + dictWord{12, 10, 325}, + dictWord{12, 10, 329}, + dictWord{12, 10, 389}, + dictWord{12, 10, 403}, + dictWord{ + 12, + 10, + 451, + }, + dictWord{12, 10, 515}, + dictWord{12, 10, 604}, + dictWord{12, 10, 616}, + dictWord{12, 10, 626}, + dictWord{13, 10, 66}, + dictWord{13, 10, 131}, + dictWord{13, 10, 167}, + dictWord{13, 10, 236}, + dictWord{13, 10, 368}, + dictWord{13, 10, 411}, + dictWord{13, 10, 434}, + dictWord{13, 10, 453}, + dictWord{ + 13, + 10, + 461, + }, + dictWord{13, 10, 474}, + dictWord{14, 10, 59}, + dictWord{14, 10, 60}, + dictWord{14, 10, 139}, + dictWord{14, 10, 152}, + dictWord{14, 10, 276}, + dictWord{ + 14, + 10, + 353, + }, + dictWord{14, 10, 402}, + dictWord{15, 10, 28}, + dictWord{15, 10, 81}, + dictWord{15, 10, 123}, + dictWord{15, 10, 152}, + dictWord{18, 10, 136}, + dictWord{148, 10, 88}, + dictWord{132, 0, 458}, + dictWord{135, 0, 1420}, + dictWord{6, 0, 109}, + dictWord{10, 0, 382}, + dictWord{4, 11, 405}, + dictWord{4, 10, 609}, + dictWord{7, 10, 756}, + dictWord{7, 11, 817}, + dictWord{9, 10, 544}, + dictWord{11, 10, 413}, + dictWord{14, 11, 58}, + dictWord{14, 10, 307}, + dictWord{16, 10, 25}, + dictWord{17, 11, 37}, + dictWord{146, 11, 124}, + dictWord{6, 0, 330}, + dictWord{7, 0, 1084}, + dictWord{11, 0, 142}, + dictWord{133, 11, 974}, + dictWord{4, 10, 930}, + dictWord{133, 10, 947}, + dictWord{5, 10, 939}, + dictWord{142, 11, 394}, + dictWord{16, 0, 91}, + dictWord{145, 0, 87}, + dictWord{5, 11, 235}, + dictWord{5, 10, 962}, + dictWord{7, 11, 1239}, + dictWord{11, 11, 131}, + dictWord{140, 11, 370}, + dictWord{11, 0, 492}, + dictWord{5, 10, 651}, + dictWord{8, 10, 170}, + dictWord{9, 10, 61}, + dictWord{9, 10, 63}, + dictWord{10, 10, 23}, + dictWord{10, 10, 37}, + dictWord{10, 10, 834}, + dictWord{11, 10, 4}, + dictWord{11, 10, 281}, + dictWord{11, 10, 503}, + dictWord{ + 11, + 10, + 677, + }, + dictWord{12, 10, 96}, + dictWord{12, 10, 130}, + dictWord{12, 10, 244}, + dictWord{14, 10, 5}, + dictWord{14, 10, 40}, + dictWord{14, 10, 162}, + dictWord{ + 14, + 10, + 202, + }, + dictWord{146, 10, 133}, + dictWord{4, 10, 406}, + dictWord{5, 10, 579}, + dictWord{12, 10, 492}, + dictWord{150, 10, 15}, + dictWord{9, 11, 137}, + dictWord{138, 11, 221}, + dictWord{134, 0, 1239}, + dictWord{11, 0, 211}, + dictWord{140, 0, 145}, + dictWord{7, 11, 390}, + dictWord{138, 11, 140}, + dictWord{ + 135, + 11, + 1418, + }, + dictWord{135, 11, 1144}, + dictWord{134, 0, 1049}, + dictWord{7, 0, 321}, + dictWord{6, 10, 17}, + dictWord{7, 10, 1001}, + dictWord{7, 10, 1982}, + dictWord{ + 9, + 10, + 886, + }, + dictWord{10, 10, 489}, + dictWord{10, 10, 800}, + dictWord{11, 10, 782}, + dictWord{12, 10, 320}, + dictWord{13, 10, 467}, + dictWord{14, 10, 145}, + dictWord{14, 10, 387}, + dictWord{143, 10, 119}, + dictWord{145, 10, 17}, + dictWord{5, 11, 407}, + dictWord{11, 11, 489}, + dictWord{19, 11, 37}, + dictWord{20, 11, 73}, + dictWord{150, 11, 38}, + dictWord{133, 10, 458}, + dictWord{135, 0, 1985}, + dictWord{7, 10, 1983}, + dictWord{8, 10, 0}, + dictWord{8, 10, 171}, + dictWord{ + 9, + 10, + 120, + }, + dictWord{9, 10, 732}, + dictWord{10, 10, 473}, + dictWord{11, 10, 656}, + dictWord{11, 10, 998}, + dictWord{18, 10, 0}, + dictWord{18, 10, 2}, + dictWord{ + 147, + 10, + 21, + }, + dictWord{5, 11, 325}, + dictWord{7, 11, 1483}, + dictWord{8, 11, 5}, + dictWord{8, 11, 227}, + dictWord{9, 11, 105}, + dictWord{10, 11, 585}, + dictWord{ + 140, + 11, + 614, + }, + dictWord{136, 0, 122}, + dictWord{132, 0, 234}, + dictWord{135, 11, 1196}, + dictWord{6, 0, 976}, + dictWord{6, 0, 1098}, + dictWord{134, 0, 1441}, + dictWord{ + 7, + 0, + 253, + }, + dictWord{136, 0, 549}, + dictWord{6, 11, 621}, + dictWord{13, 11, 504}, + dictWord{144, 11, 19}, + dictWord{132, 10, 519}, + dictWord{5, 0, 430}, + dictWord{ + 5, + 0, + 932, + }, + dictWord{6, 0, 131}, + dictWord{7, 0, 417}, + dictWord{9, 0, 522}, + dictWord{11, 0, 314}, + dictWord{141, 0, 390}, + dictWord{14, 0, 149}, + dictWord{14, 0, 399}, + dictWord{143, 0, 57}, + dictWord{5, 10, 907}, + dictWord{6, 10, 31}, + dictWord{6, 11, 218}, + dictWord{7, 10, 491}, + dictWord{7, 10, 530}, + dictWord{8, 10, 592}, + dictWord{11, 10, 53}, + dictWord{11, 10, 779}, + dictWord{12, 10, 167}, + dictWord{12, 10, 411}, + dictWord{14, 10, 14}, + dictWord{14, 10, 136}, + dictWord{15, 10, 72}, + dictWord{16, 10, 17}, + dictWord{144, 10, 72}, + dictWord{140, 11, 330}, + dictWord{7, 11, 454}, + dictWord{7, 11, 782}, + dictWord{136, 11, 768}, + dictWord{ + 132, + 0, + 507, + }, + dictWord{10, 11, 676}, + dictWord{140, 11, 462}, + dictWord{6, 0, 630}, + dictWord{9, 0, 811}, + dictWord{4, 10, 208}, + dictWord{5, 10, 106}, + dictWord{ + 6, + 10, + 531, + }, + dictWord{8, 10, 408}, + dictWord{9, 10, 188}, + dictWord{138, 10, 572}, + dictWord{4, 0, 343}, + dictWord{5, 0, 511}, + dictWord{134, 10, 1693}, + dictWord{ + 134, + 11, + 164, + }, + dictWord{132, 0, 448}, + dictWord{7, 0, 455}, + dictWord{138, 0, 591}, + dictWord{135, 0, 1381}, + dictWord{12, 10, 441}, + dictWord{150, 11, 50}, + dictWord{9, 10, 449}, + dictWord{10, 10, 192}, + dictWord{138, 10, 740}, + dictWord{6, 0, 575}, + dictWord{132, 10, 241}, + dictWord{134, 0, 1175}, + dictWord{ + 134, + 0, + 653, + }, + dictWord{134, 0, 1761}, + dictWord{134, 0, 1198}, + dictWord{132, 10, 259}, + dictWord{6, 11, 343}, + dictWord{7, 11, 195}, + dictWord{9, 11, 226}, + dictWord{ + 10, + 11, + 197, + }, + dictWord{10, 11, 575}, + dictWord{11, 11, 502}, + dictWord{139, 11, 899}, + dictWord{7, 0, 1127}, + dictWord{7, 0, 1572}, + dictWord{10, 0, 297}, + dictWord{10, 0, 422}, + dictWord{11, 0, 764}, + dictWord{11, 0, 810}, + dictWord{12, 0, 264}, + dictWord{13, 0, 102}, + dictWord{13, 0, 300}, + dictWord{13, 0, 484}, + dictWord{ + 14, + 0, + 147, + }, + dictWord{14, 0, 229}, + dictWord{17, 0, 71}, + dictWord{18, 0, 118}, + dictWord{147, 0, 120}, + dictWord{135, 11, 666}, + dictWord{132, 0, 678}, + dictWord{ + 4, + 10, + 173, + }, + dictWord{5, 10, 312}, + dictWord{5, 10, 512}, + dictWord{135, 10, 1285}, + dictWord{7, 10, 1603}, + dictWord{7, 10, 1691}, + dictWord{9, 10, 464}, + dictWord{11, 10, 195}, + dictWord{12, 10, 279}, + dictWord{12, 10, 448}, + dictWord{14, 10, 11}, + dictWord{147, 10, 102}, + dictWord{16, 0, 99}, + dictWord{146, 0, 164}, + dictWord{7, 11, 1125}, + dictWord{9, 11, 143}, + dictWord{11, 11, 61}, + dictWord{14, 11, 405}, + dictWord{150, 11, 21}, + dictWord{137, 11, 260}, + dictWord{ + 4, + 10, + 452, + }, + dictWord{5, 10, 583}, + dictWord{5, 10, 817}, + dictWord{6, 10, 433}, + dictWord{7, 10, 593}, + dictWord{7, 10, 720}, + dictWord{7, 10, 1378}, + dictWord{ + 8, + 10, + 161, + }, + dictWord{9, 10, 284}, + dictWord{10, 10, 313}, + dictWord{139, 10, 886}, + dictWord{132, 10, 547}, + dictWord{136, 10, 722}, + dictWord{14, 0, 35}, + dictWord{142, 0, 191}, + dictWord{141, 0, 45}, + dictWord{138, 0, 121}, + dictWord{132, 0, 125}, + dictWord{134, 0, 1622}, + dictWord{133, 11, 959}, + dictWord{ + 8, + 10, + 420, + }, + dictWord{139, 10, 193}, + dictWord{132, 0, 721}, + dictWord{135, 10, 409}, + dictWord{136, 0, 145}, + dictWord{7, 0, 792}, + dictWord{8, 0, 147}, + dictWord{ + 10, + 0, + 821, + }, + dictWord{11, 0, 970}, + dictWord{11, 0, 1021}, + dictWord{136, 11, 173}, + dictWord{134, 11, 266}, + dictWord{132, 0, 715}, + dictWord{7, 0, 1999}, + dictWord{138, 10, 308}, + dictWord{133, 0, 531}, + dictWord{5, 0, 168}, + dictWord{5, 0, 930}, + dictWord{8, 0, 74}, + dictWord{9, 0, 623}, + dictWord{12, 0, 500}, + dictWord{ + 140, + 0, + 579, + }, + dictWord{144, 0, 65}, + dictWord{138, 11, 246}, + dictWord{6, 0, 220}, + dictWord{7, 0, 1101}, + dictWord{13, 0, 105}, + dictWord{142, 11, 314}, + dictWord{ + 5, + 10, + 1002, + }, + dictWord{136, 10, 745}, + dictWord{134, 0, 960}, + dictWord{20, 0, 0}, + dictWord{148, 11, 0}, + dictWord{4, 0, 1005}, + dictWord{4, 10, 239}, + dictWord{ + 6, + 10, + 477, + }, + dictWord{7, 10, 1607}, + dictWord{11, 10, 68}, + dictWord{139, 10, 617}, + dictWord{6, 0, 19}, + dictWord{7, 0, 1413}, + dictWord{139, 0, 428}, + dictWord{ + 149, + 10, + 13, + }, + dictWord{7, 0, 96}, + dictWord{8, 0, 401}, + dictWord{8, 0, 703}, + dictWord{9, 0, 896}, + dictWord{136, 11, 300}, + dictWord{134, 0, 1595}, + dictWord{145, 0, 116}, + dictWord{136, 0, 1021}, + dictWord{7, 0, 1961}, + dictWord{7, 0, 1965}, + dictWord{7, 0, 2030}, + dictWord{8, 0, 150}, + dictWord{8, 0, 702}, + dictWord{8, 0, 737}, + dictWord{ + 8, + 0, + 750, + }, + dictWord{140, 0, 366}, + dictWord{11, 11, 75}, + dictWord{142, 11, 267}, + dictWord{132, 10, 367}, + dictWord{8, 0, 800}, + dictWord{9, 0, 148}, + dictWord{ + 9, + 0, + 872, + }, + dictWord{9, 0, 890}, + dictWord{11, 0, 309}, + dictWord{11, 0, 1001}, + dictWord{13, 0, 267}, + dictWord{13, 0, 323}, + dictWord{5, 11, 427}, + dictWord{ + 5, + 11, + 734, + }, + dictWord{7, 11, 478}, + dictWord{136, 11, 52}, + dictWord{7, 11, 239}, + dictWord{11, 11, 217}, + dictWord{142, 11, 165}, + dictWord{132, 11, 323}, + dictWord{140, 11, 419}, + dictWord{13, 0, 299}, + dictWord{142, 0, 75}, + dictWord{6, 11, 87}, + dictWord{6, 11, 1734}, + dictWord{7, 11, 20}, + dictWord{7, 11, 1056}, + dictWord{ + 8, + 11, + 732, + }, + dictWord{9, 11, 406}, + dictWord{9, 11, 911}, + dictWord{138, 11, 694}, + dictWord{134, 0, 1383}, + dictWord{132, 10, 694}, + dictWord{ + 133, + 11, + 613, + }, + dictWord{137, 0, 779}, + dictWord{4, 0, 598}, + dictWord{140, 10, 687}, + dictWord{6, 0, 970}, + dictWord{135, 0, 424}, + dictWord{133, 0, 547}, + dictWord{ + 7, + 11, + 32, + }, + dictWord{7, 11, 984}, + dictWord{8, 11, 85}, + dictWord{8, 11, 709}, + dictWord{9, 11, 579}, + dictWord{9, 11, 847}, + dictWord{9, 11, 856}, + dictWord{10, 11, 799}, + dictWord{11, 11, 258}, + dictWord{11, 11, 1007}, + dictWord{12, 11, 331}, + dictWord{12, 11, 615}, + dictWord{13, 11, 188}, + dictWord{13, 11, 435}, + dictWord{ + 14, + 11, + 8, + }, + dictWord{15, 11, 165}, + dictWord{16, 11, 27}, + dictWord{148, 11, 40}, + dictWord{6, 0, 1222}, + dictWord{134, 0, 1385}, + dictWord{132, 0, 876}, + dictWord{ + 138, + 11, + 151, + }, + dictWord{135, 10, 213}, + dictWord{4, 11, 167}, + dictWord{135, 11, 82}, + dictWord{133, 0, 133}, + dictWord{6, 11, 24}, + dictWord{7, 11, 74}, + dictWord{ + 7, + 11, + 678, + }, + dictWord{137, 11, 258}, + dictWord{5, 11, 62}, + dictWord{6, 11, 534}, + dictWord{7, 11, 684}, + dictWord{7, 11, 1043}, + dictWord{7, 11, 1072}, + dictWord{ + 8, + 11, + 280, + }, + dictWord{8, 11, 541}, + dictWord{8, 11, 686}, + dictWord{10, 11, 519}, + dictWord{11, 11, 252}, + dictWord{140, 11, 282}, + dictWord{136, 0, 187}, + dictWord{8, 0, 8}, + dictWord{10, 0, 0}, + dictWord{10, 0, 818}, + dictWord{139, 0, 988}, + dictWord{132, 11, 359}, + dictWord{11, 0, 429}, + dictWord{15, 0, 51}, + dictWord{ + 135, + 10, + 1672, + }, + dictWord{136, 0, 685}, + dictWord{5, 11, 211}, + dictWord{7, 11, 88}, + dictWord{136, 11, 627}, + dictWord{134, 0, 472}, + dictWord{136, 0, 132}, + dictWord{ + 6, + 11, + 145, + }, + dictWord{141, 11, 336}, + dictWord{4, 10, 751}, + dictWord{11, 10, 390}, + dictWord{140, 10, 32}, + dictWord{6, 0, 938}, + dictWord{6, 0, 1060}, + dictWord{ + 4, + 11, + 263, + }, + dictWord{4, 10, 409}, + dictWord{133, 10, 78}, + dictWord{137, 0, 874}, + dictWord{8, 0, 774}, + dictWord{10, 0, 670}, + dictWord{12, 0, 51}, + dictWord{ + 4, + 11, + 916, + }, + dictWord{6, 10, 473}, + dictWord{7, 10, 1602}, + dictWord{10, 10, 698}, + dictWord{12, 10, 212}, + dictWord{13, 10, 307}, + dictWord{145, 10, 105}, + dictWord{146, 0, 92}, + dictWord{143, 10, 156}, + dictWord{132, 0, 830}, + dictWord{137, 0, 701}, + dictWord{4, 11, 599}, + dictWord{6, 11, 1634}, + dictWord{7, 11, 5}, + dictWord{7, 11, 55}, + dictWord{7, 11, 67}, + dictWord{7, 11, 97}, + dictWord{7, 11, 691}, + dictWord{7, 11, 979}, + dictWord{7, 11, 1697}, + dictWord{8, 11, 207}, + dictWord{ + 8, + 11, + 214, + }, + dictWord{8, 11, 231}, + dictWord{8, 11, 294}, + dictWord{8, 11, 336}, + dictWord{8, 11, 428}, + dictWord{8, 11, 451}, + dictWord{8, 11, 460}, + dictWord{8, 11, 471}, + dictWord{8, 11, 622}, + dictWord{8, 11, 626}, + dictWord{8, 11, 679}, + dictWord{8, 11, 759}, + dictWord{8, 11, 829}, + dictWord{9, 11, 11}, + dictWord{9, 11, 246}, + dictWord{ + 9, + 11, + 484, + }, + dictWord{9, 11, 573}, + dictWord{9, 11, 706}, + dictWord{9, 11, 762}, + dictWord{9, 11, 798}, + dictWord{9, 11, 855}, + dictWord{9, 11, 870}, + dictWord{ + 9, + 11, + 912, + }, + dictWord{10, 11, 303}, + dictWord{10, 11, 335}, + dictWord{10, 11, 424}, + dictWord{10, 11, 461}, + dictWord{10, 11, 543}, + dictWord{10, 11, 759}, + dictWord{10, 11, 814}, + dictWord{11, 11, 59}, + dictWord{11, 11, 199}, + dictWord{11, 11, 235}, + dictWord{11, 11, 475}, + dictWord{11, 11, 590}, + dictWord{11, 11, 929}, + dictWord{11, 11, 963}, + dictWord{12, 11, 114}, + dictWord{12, 11, 182}, + dictWord{12, 11, 226}, + dictWord{12, 11, 332}, + dictWord{12, 11, 439}, + dictWord{ + 12, + 11, + 575, + }, + dictWord{12, 11, 598}, + dictWord{13, 11, 8}, + dictWord{13, 11, 125}, + dictWord{13, 11, 194}, + dictWord{13, 11, 287}, + dictWord{14, 11, 197}, + dictWord{ + 14, + 11, + 383, + }, + dictWord{15, 11, 53}, + dictWord{17, 11, 63}, + dictWord{19, 11, 46}, + dictWord{19, 11, 98}, + dictWord{19, 11, 106}, + dictWord{148, 11, 85}, + dictWord{ + 4, + 0, + 127, + }, + dictWord{5, 0, 350}, + dictWord{6, 0, 356}, + dictWord{8, 0, 426}, + dictWord{9, 0, 572}, + dictWord{10, 0, 247}, + dictWord{139, 0, 312}, + dictWord{134, 0, 1215}, + dictWord{6, 0, 59}, + dictWord{9, 0, 603}, + dictWord{13, 0, 397}, + dictWord{7, 11, 1853}, + dictWord{138, 11, 437}, + dictWord{134, 0, 1762}, + dictWord{ + 147, + 11, + 126, + }, + dictWord{135, 10, 883}, + dictWord{13, 0, 293}, + dictWord{142, 0, 56}, + dictWord{133, 10, 617}, + dictWord{139, 10, 50}, + dictWord{5, 11, 187}, + dictWord{ + 7, + 10, + 1518, + }, + dictWord{139, 10, 694}, + dictWord{135, 0, 441}, + dictWord{6, 0, 111}, + dictWord{7, 0, 4}, + dictWord{8, 0, 163}, + dictWord{8, 0, 776}, + dictWord{ + 138, + 0, + 566, + }, + dictWord{132, 0, 806}, + dictWord{4, 11, 215}, + dictWord{9, 11, 38}, + dictWord{10, 11, 3}, + dictWord{11, 11, 23}, + dictWord{11, 11, 127}, + dictWord{ + 139, + 11, + 796, + }, + dictWord{14, 0, 233}, + dictWord{4, 10, 546}, + dictWord{135, 10, 2042}, + dictWord{135, 0, 1994}, + dictWord{134, 0, 1739}, + dictWord{135, 11, 1530}, + dictWord{136, 0, 393}, + dictWord{5, 0, 297}, + dictWord{7, 0, 1038}, + dictWord{14, 0, 359}, + dictWord{19, 0, 52}, + dictWord{148, 0, 47}, + dictWord{135, 0, 309}, + dictWord{ + 4, + 10, + 313, + }, + dictWord{133, 10, 577}, + dictWord{8, 10, 184}, + dictWord{141, 10, 433}, + dictWord{135, 10, 935}, + dictWord{12, 10, 186}, + dictWord{ + 12, + 10, + 292, + }, + dictWord{14, 10, 100}, + dictWord{146, 10, 70}, + dictWord{136, 0, 363}, + dictWord{14, 0, 175}, + dictWord{11, 10, 402}, + dictWord{12, 10, 109}, + dictWord{ + 12, + 10, + 431, + }, + dictWord{13, 10, 179}, + dictWord{13, 10, 206}, + dictWord{14, 10, 217}, + dictWord{16, 10, 3}, + dictWord{148, 10, 53}, + dictWord{5, 10, 886}, + dictWord{ + 6, + 10, + 46, + }, + dictWord{6, 10, 1790}, + dictWord{7, 10, 14}, + dictWord{7, 10, 732}, + dictWord{7, 10, 1654}, + dictWord{8, 10, 95}, + dictWord{8, 10, 327}, + dictWord{ + 8, + 10, + 616, + }, + dictWord{9, 10, 892}, + dictWord{10, 10, 598}, + dictWord{10, 10, 769}, + dictWord{11, 10, 134}, + dictWord{11, 10, 747}, + dictWord{12, 10, 378}, + dictWord{ + 142, + 10, + 97, + }, + dictWord{136, 0, 666}, + dictWord{135, 0, 1675}, + dictWord{6, 0, 655}, + dictWord{134, 0, 1600}, + dictWord{135, 0, 808}, + dictWord{133, 10, 1021}, + dictWord{4, 11, 28}, + dictWord{5, 11, 440}, + dictWord{7, 11, 248}, + dictWord{11, 11, 833}, + dictWord{140, 11, 344}, + dictWord{134, 11, 1654}, + dictWord{ + 132, + 0, + 280, + }, + dictWord{140, 0, 54}, + dictWord{4, 0, 421}, + dictWord{133, 0, 548}, + dictWord{132, 10, 153}, + dictWord{6, 11, 339}, + dictWord{135, 11, 923}, + dictWord{ + 133, + 11, + 853, + }, + dictWord{133, 10, 798}, + dictWord{132, 10, 587}, + dictWord{6, 11, 249}, + dictWord{7, 11, 1234}, + dictWord{139, 11, 573}, + dictWord{6, 10, 598}, + dictWord{7, 10, 42}, + dictWord{8, 10, 695}, + dictWord{10, 10, 212}, + dictWord{11, 10, 158}, + dictWord{14, 10, 196}, + dictWord{145, 10, 85}, + dictWord{7, 0, 249}, + dictWord{5, 10, 957}, + dictWord{133, 10, 1008}, + dictWord{4, 10, 129}, + dictWord{135, 10, 465}, + dictWord{6, 0, 254}, + dictWord{7, 0, 842}, + dictWord{7, 0, 1659}, + dictWord{9, 0, 109}, + dictWord{10, 0, 103}, + dictWord{7, 10, 908}, + dictWord{7, 10, 1201}, + dictWord{9, 10, 755}, + dictWord{11, 10, 906}, + dictWord{12, 10, 527}, + dictWord{146, 10, 7}, + dictWord{5, 0, 262}, + dictWord{136, 10, 450}, + dictWord{144, 0, 1}, + dictWord{10, 11, 201}, + dictWord{142, 11, 319}, + dictWord{7, 11, 49}, + dictWord{ + 7, + 11, + 392, + }, + dictWord{8, 11, 20}, + dictWord{8, 11, 172}, + dictWord{8, 11, 690}, + dictWord{9, 11, 383}, + dictWord{9, 11, 845}, + dictWord{10, 11, 48}, + dictWord{ + 11, + 11, + 293, + }, + dictWord{11, 11, 832}, + dictWord{11, 11, 920}, + dictWord{141, 11, 221}, + dictWord{5, 11, 858}, + dictWord{133, 11, 992}, + dictWord{134, 0, 805}, + dictWord{139, 10, 1003}, + dictWord{6, 0, 1630}, + dictWord{134, 11, 307}, + dictWord{7, 11, 1512}, + dictWord{135, 11, 1794}, + dictWord{6, 11, 268}, + dictWord{ + 137, + 11, + 62, + }, + dictWord{135, 10, 1868}, + dictWord{133, 0, 671}, + dictWord{4, 0, 989}, + dictWord{8, 0, 972}, + dictWord{136, 0, 998}, + dictWord{132, 11, 423}, + dictWord{132, 0, 889}, + dictWord{135, 0, 1382}, + dictWord{135, 0, 1910}, + dictWord{7, 10, 965}, + dictWord{7, 10, 1460}, + dictWord{135, 10, 1604}, + dictWord{ + 4, + 0, + 627, + }, + dictWord{5, 0, 775}, + dictWord{138, 11, 106}, + dictWord{134, 11, 348}, + dictWord{7, 0, 202}, + dictWord{11, 0, 362}, + dictWord{11, 0, 948}, + dictWord{ + 140, + 0, + 388, + }, + dictWord{138, 11, 771}, + dictWord{6, 11, 613}, + dictWord{136, 11, 223}, + dictWord{6, 0, 560}, + dictWord{7, 0, 451}, + dictWord{8, 0, 389}, + dictWord{ + 12, + 0, + 490, + }, + dictWord{13, 0, 16}, + dictWord{13, 0, 215}, + dictWord{13, 0, 351}, + dictWord{18, 0, 132}, + dictWord{147, 0, 125}, + dictWord{135, 0, 841}, + dictWord{ + 136, + 0, + 566, + }, + dictWord{136, 0, 938}, + dictWord{132, 11, 670}, + dictWord{5, 0, 912}, + dictWord{6, 0, 1695}, + dictWord{140, 11, 55}, + dictWord{9, 11, 40}, + dictWord{ + 139, + 11, + 136, + }, + dictWord{7, 0, 1361}, + dictWord{7, 10, 982}, + dictWord{10, 10, 32}, + dictWord{143, 10, 56}, + dictWord{11, 11, 259}, + dictWord{140, 11, 270}, + dictWord{ + 5, + 0, + 236, + }, + dictWord{6, 0, 572}, + dictWord{8, 0, 492}, + dictWord{11, 0, 618}, + dictWord{144, 0, 56}, + dictWord{8, 11, 572}, + dictWord{9, 11, 310}, + dictWord{9, 11, 682}, + dictWord{137, 11, 698}, + dictWord{134, 0, 1854}, + dictWord{5, 0, 190}, + dictWord{136, 0, 318}, + dictWord{133, 10, 435}, + dictWord{135, 0, 1376}, + dictWord{ + 4, + 11, + 296, + }, + dictWord{6, 11, 352}, + dictWord{7, 11, 401}, + dictWord{7, 11, 1410}, + dictWord{7, 11, 1594}, + dictWord{7, 11, 1674}, + dictWord{8, 11, 63}, + dictWord{ + 8, + 11, + 660, + }, + dictWord{137, 11, 74}, + dictWord{7, 0, 349}, + dictWord{5, 10, 85}, + dictWord{6, 10, 419}, + dictWord{7, 10, 305}, + dictWord{7, 10, 361}, + dictWord{7, 10, 1337}, + dictWord{8, 10, 71}, + dictWord{140, 10, 519}, + dictWord{4, 11, 139}, + dictWord{4, 11, 388}, + dictWord{140, 11, 188}, + dictWord{6, 0, 1972}, + dictWord{6, 0, 2013}, + dictWord{8, 0, 951}, + dictWord{10, 0, 947}, + dictWord{10, 0, 974}, + dictWord{10, 0, 1018}, + dictWord{142, 0, 476}, + dictWord{140, 10, 688}, + dictWord{ + 135, + 10, + 740, + }, + dictWord{5, 10, 691}, + dictWord{7, 10, 345}, + dictWord{9, 10, 94}, + dictWord{140, 10, 169}, + dictWord{9, 0, 344}, + dictWord{5, 10, 183}, + dictWord{6, 10, 582}, + dictWord{10, 10, 679}, + dictWord{140, 10, 435}, + dictWord{135, 10, 511}, + dictWord{132, 0, 850}, + dictWord{8, 11, 441}, + dictWord{10, 11, 314}, + dictWord{ + 143, + 11, + 3, + }, + dictWord{7, 10, 1993}, + dictWord{136, 10, 684}, + dictWord{4, 11, 747}, + dictWord{6, 11, 290}, + dictWord{6, 10, 583}, + dictWord{7, 11, 649}, + dictWord{ + 7, + 11, + 1479, + }, + dictWord{135, 11, 1583}, + dictWord{133, 11, 232}, + dictWord{133, 10, 704}, + dictWord{134, 0, 910}, + dictWord{4, 10, 179}, + dictWord{5, 10, 198}, + dictWord{133, 10, 697}, + dictWord{7, 10, 347}, + dictWord{7, 10, 971}, + dictWord{8, 10, 181}, + dictWord{138, 10, 711}, + dictWord{136, 11, 525}, + dictWord{ + 14, + 0, + 19, + }, + dictWord{14, 0, 28}, + dictWord{144, 0, 29}, + dictWord{7, 0, 85}, + dictWord{7, 0, 247}, + dictWord{8, 0, 585}, + dictWord{138, 0, 163}, + dictWord{4, 0, 487}, + dictWord{ + 7, + 11, + 472, + }, + dictWord{7, 11, 1801}, + dictWord{10, 11, 748}, + dictWord{141, 11, 458}, + dictWord{4, 10, 243}, + dictWord{5, 10, 203}, + dictWord{7, 10, 19}, + dictWord{ + 7, + 10, + 71, + }, + dictWord{7, 10, 113}, + dictWord{10, 10, 405}, + dictWord{11, 10, 357}, + dictWord{142, 10, 240}, + dictWord{7, 10, 1450}, + dictWord{139, 10, 99}, + dictWord{132, 11, 425}, + dictWord{138, 0, 145}, + dictWord{147, 0, 83}, + dictWord{6, 10, 492}, + dictWord{137, 11, 247}, + dictWord{4, 0, 1013}, + dictWord{ + 134, + 0, + 2033, + }, + dictWord{5, 10, 134}, + dictWord{6, 10, 408}, + dictWord{6, 10, 495}, + dictWord{135, 10, 1593}, + dictWord{135, 0, 1922}, + dictWord{134, 11, 1768}, + dictWord{4, 0, 124}, + dictWord{10, 0, 457}, + dictWord{11, 0, 121}, + dictWord{11, 0, 169}, + dictWord{11, 0, 870}, + dictWord{11, 0, 874}, + dictWord{12, 0, 214}, + dictWord{ + 14, + 0, + 187, + }, + dictWord{143, 0, 77}, + dictWord{5, 0, 557}, + dictWord{135, 0, 1457}, + dictWord{139, 0, 66}, + dictWord{5, 11, 943}, + dictWord{6, 11, 1779}, + dictWord{ + 142, + 10, + 4, + }, + dictWord{4, 10, 248}, + dictWord{4, 10, 665}, + dictWord{7, 10, 137}, + dictWord{137, 10, 349}, + dictWord{7, 0, 1193}, + dictWord{5, 11, 245}, + dictWord{ + 6, + 11, + 576, + }, + dictWord{7, 11, 582}, + dictWord{136, 11, 225}, + dictWord{144, 0, 82}, + dictWord{7, 10, 1270}, + dictWord{139, 10, 612}, + dictWord{5, 0, 454}, + dictWord{ + 10, + 0, + 352, + }, + dictWord{138, 11, 352}, + dictWord{18, 0, 57}, + dictWord{5, 10, 371}, + dictWord{135, 10, 563}, + dictWord{135, 0, 1333}, + dictWord{6, 0, 107}, + dictWord{ + 7, + 0, + 638, + }, + dictWord{7, 0, 1632}, + dictWord{9, 0, 396}, + dictWord{134, 11, 610}, + dictWord{5, 0, 370}, + dictWord{134, 0, 1756}, + dictWord{4, 10, 374}, + dictWord{ + 7, + 10, + 547, + }, + dictWord{7, 10, 1700}, + dictWord{7, 10, 1833}, + dictWord{139, 10, 858}, + dictWord{133, 0, 204}, + dictWord{6, 0, 1305}, + dictWord{9, 10, 311}, + dictWord{ + 141, + 10, + 42, + }, + dictWord{5, 0, 970}, + dictWord{134, 0, 1706}, + dictWord{6, 10, 1647}, + dictWord{7, 10, 1552}, + dictWord{7, 10, 2010}, + dictWord{9, 10, 494}, + dictWord{137, 10, 509}, + dictWord{13, 11, 455}, + dictWord{15, 11, 99}, + dictWord{15, 11, 129}, + dictWord{144, 11, 68}, + dictWord{135, 0, 3}, + dictWord{4, 0, 35}, + dictWord{ + 5, + 0, + 121, + }, + dictWord{5, 0, 483}, + dictWord{5, 0, 685}, + dictWord{6, 0, 489}, + dictWord{6, 0, 782}, + dictWord{6, 0, 1032}, + dictWord{7, 0, 1204}, + dictWord{136, 0, 394}, + dictWord{4, 0, 921}, + dictWord{133, 0, 1007}, + dictWord{8, 11, 360}, + dictWord{138, 11, 63}, + dictWord{135, 0, 1696}, + dictWord{134, 0, 1519}, + dictWord{ + 132, + 11, + 443, + }, + dictWord{135, 11, 944}, + dictWord{6, 10, 123}, + dictWord{7, 10, 214}, + dictWord{9, 10, 728}, + dictWord{10, 10, 157}, + dictWord{11, 10, 346}, + dictWord{11, 10, 662}, + dictWord{143, 10, 106}, + dictWord{137, 0, 981}, + dictWord{135, 10, 1435}, + dictWord{134, 0, 1072}, + dictWord{132, 0, 712}, + dictWord{ + 134, + 0, + 1629, + }, + dictWord{134, 0, 728}, + dictWord{4, 11, 298}, + dictWord{137, 11, 483}, + dictWord{6, 0, 1177}, + dictWord{6, 0, 1271}, + dictWord{5, 11, 164}, + dictWord{ + 7, + 11, + 121, + }, + dictWord{142, 11, 189}, + dictWord{7, 0, 1608}, + dictWord{4, 10, 707}, + dictWord{5, 10, 588}, + dictWord{6, 10, 393}, + dictWord{13, 10, 106}, + dictWord{ + 18, + 10, + 49, + }, + dictWord{147, 10, 41}, + dictWord{23, 0, 16}, + dictWord{151, 11, 16}, + dictWord{6, 10, 211}, + dictWord{7, 10, 1690}, + dictWord{11, 10, 486}, + dictWord{140, 10, 369}, + dictWord{133, 0, 485}, + dictWord{19, 11, 15}, + dictWord{149, 11, 27}, + dictWord{4, 11, 172}, + dictWord{9, 11, 611}, + dictWord{10, 11, 436}, + dictWord{12, 11, 673}, + dictWord{141, 11, 255}, + dictWord{5, 11, 844}, + dictWord{10, 11, 484}, + dictWord{11, 11, 754}, + dictWord{12, 11, 457}, + dictWord{ + 14, + 11, + 171, + }, + dictWord{14, 11, 389}, + dictWord{146, 11, 153}, + dictWord{4, 0, 285}, + dictWord{5, 0, 27}, + dictWord{5, 0, 317}, + dictWord{6, 0, 301}, + dictWord{7, 0, 7}, + dictWord{ + 8, + 0, + 153, + }, + dictWord{10, 0, 766}, + dictWord{11, 0, 468}, + dictWord{12, 0, 467}, + dictWord{141, 0, 143}, + dictWord{134, 0, 1462}, + dictWord{9, 11, 263}, + dictWord{ + 10, + 11, + 147, + }, + dictWord{138, 11, 492}, + dictWord{133, 11, 537}, + dictWord{6, 0, 1945}, + dictWord{6, 0, 1986}, + dictWord{6, 0, 1991}, + dictWord{134, 0, 2038}, + dictWord{134, 10, 219}, + dictWord{137, 11, 842}, + dictWord{14, 0, 52}, + dictWord{17, 0, 50}, + dictWord{5, 10, 582}, + dictWord{6, 10, 1646}, + dictWord{7, 10, 99}, + dictWord{7, 10, 1962}, + dictWord{7, 10, 1986}, + dictWord{8, 10, 515}, + dictWord{8, 10, 773}, + dictWord{9, 10, 23}, + dictWord{9, 10, 491}, + dictWord{12, 10, 620}, + dictWord{142, 10, 93}, + dictWord{138, 11, 97}, + dictWord{20, 0, 21}, + dictWord{20, 0, 44}, + dictWord{133, 10, 851}, + dictWord{136, 0, 819}, + dictWord{139, 0, 917}, + dictWord{5, 11, 230}, + dictWord{5, 11, 392}, + dictWord{6, 11, 420}, + dictWord{8, 10, 762}, + dictWord{8, 10, 812}, + dictWord{9, 11, 568}, + dictWord{9, 10, 910}, + dictWord{140, 11, 612}, + dictWord{135, 0, 784}, + dictWord{15, 0, 135}, + dictWord{143, 11, 135}, + dictWord{10, 0, 454}, + dictWord{140, 0, 324}, + dictWord{4, 11, 0}, + dictWord{5, 11, 41}, + dictWord{7, 11, 1459}, + dictWord{7, 11, 1469}, + dictWord{7, 11, 1618}, + dictWord{7, 11, 1859}, + dictWord{9, 11, 549}, + dictWord{139, 11, 905}, + dictWord{4, 10, 98}, + dictWord{7, 10, 1365}, + dictWord{9, 10, 422}, + dictWord{9, 10, 670}, + dictWord{10, 10, 775}, + dictWord{11, 10, 210}, + dictWord{13, 10, 26}, + dictWord{13, 10, 457}, + dictWord{141, 10, 476}, + dictWord{6, 0, 1719}, + dictWord{6, 0, 1735}, + dictWord{7, 0, 2016}, + dictWord{7, 0, 2020}, + dictWord{8, 0, 837}, + dictWord{137, 0, 852}, + dictWord{133, 11, 696}, + dictWord{135, 0, 852}, + dictWord{132, 0, 952}, + dictWord{134, 10, 1730}, + dictWord{132, 11, 771}, + dictWord{ + 138, + 0, + 568, + }, + dictWord{137, 0, 448}, + dictWord{139, 0, 146}, + dictWord{8, 0, 67}, + dictWord{138, 0, 419}, + dictWord{133, 11, 921}, + dictWord{137, 10, 147}, + dictWord{134, 0, 1826}, + dictWord{10, 0, 657}, + dictWord{14, 0, 297}, + dictWord{142, 0, 361}, + dictWord{6, 0, 666}, + dictWord{6, 0, 767}, + dictWord{134, 0, 1542}, + dictWord{139, 0, 729}, + dictWord{6, 11, 180}, + dictWord{7, 11, 1137}, + dictWord{8, 11, 751}, + dictWord{139, 11, 805}, + dictWord{4, 11, 183}, + dictWord{7, 11, 271}, + dictWord{11, 11, 824}, + dictWord{11, 11, 952}, + dictWord{13, 11, 278}, + dictWord{13, 11, 339}, + dictWord{13, 11, 482}, + dictWord{14, 11, 424}, + dictWord{ + 148, + 11, + 99, + }, + dictWord{4, 0, 669}, + dictWord{5, 11, 477}, + dictWord{5, 11, 596}, + dictWord{6, 11, 505}, + dictWord{7, 11, 1221}, + dictWord{11, 11, 907}, + dictWord{ + 12, + 11, + 209, + }, + dictWord{141, 11, 214}, + dictWord{135, 11, 1215}, + dictWord{5, 0, 402}, + dictWord{6, 10, 30}, + dictWord{11, 10, 56}, + dictWord{139, 10, 305}, + dictWord{ + 7, + 11, + 564, + }, + dictWord{142, 11, 168}, + dictWord{139, 0, 152}, + dictWord{7, 0, 912}, + dictWord{135, 10, 1614}, + dictWord{4, 10, 150}, + dictWord{5, 10, 303}, + dictWord{134, 10, 327}, + dictWord{7, 0, 320}, + dictWord{8, 0, 51}, + dictWord{9, 0, 868}, + dictWord{10, 0, 833}, + dictWord{12, 0, 481}, + dictWord{12, 0, 570}, + dictWord{ + 148, + 0, + 106, + }, + dictWord{132, 0, 445}, + dictWord{7, 11, 274}, + dictWord{11, 11, 263}, + dictWord{11, 11, 479}, + dictWord{11, 11, 507}, + dictWord{140, 11, 277}, + dictWord{10, 0, 555}, + dictWord{11, 0, 308}, + dictWord{19, 0, 95}, + dictWord{6, 11, 1645}, + dictWord{8, 10, 192}, + dictWord{10, 10, 78}, + dictWord{141, 10, 359}, + dictWord{135, 10, 786}, + dictWord{6, 11, 92}, + dictWord{6, 11, 188}, + dictWord{7, 11, 1269}, + dictWord{7, 11, 1524}, + dictWord{7, 11, 1876}, + dictWord{10, 11, 228}, + dictWord{139, 11, 1020}, + dictWord{4, 11, 459}, + dictWord{133, 11, 966}, + dictWord{11, 0, 386}, + dictWord{6, 10, 1638}, + dictWord{7, 10, 79}, + dictWord{ + 7, + 10, + 496, + }, + dictWord{9, 10, 138}, + dictWord{10, 10, 336}, + dictWord{12, 10, 412}, + dictWord{12, 10, 440}, + dictWord{142, 10, 305}, + dictWord{133, 0, 239}, + dictWord{ + 7, + 0, + 83, + }, + dictWord{7, 0, 1990}, + dictWord{8, 0, 130}, + dictWord{139, 0, 720}, + dictWord{138, 11, 709}, + dictWord{4, 0, 143}, + dictWord{5, 0, 550}, + dictWord{ + 133, + 0, + 752, + }, + dictWord{5, 0, 123}, + dictWord{6, 0, 530}, + dictWord{7, 0, 348}, + dictWord{135, 0, 1419}, + dictWord{135, 0, 2024}, + dictWord{6, 11, 18}, + dictWord{7, 11, 179}, + dictWord{7, 11, 721}, + dictWord{7, 11, 932}, + dictWord{8, 11, 548}, + dictWord{8, 11, 757}, + dictWord{9, 11, 54}, + dictWord{9, 11, 65}, + dictWord{9, 11, 532}, + dictWord{ + 9, + 11, + 844, + }, + dictWord{10, 11, 113}, + dictWord{10, 11, 117}, + dictWord{10, 11, 236}, + dictWord{10, 11, 315}, + dictWord{10, 11, 430}, + dictWord{10, 11, 798}, + dictWord{11, 11, 153}, + dictWord{11, 11, 351}, + dictWord{11, 11, 375}, + dictWord{12, 11, 78}, + dictWord{12, 11, 151}, + dictWord{12, 11, 392}, + dictWord{ + 14, + 11, + 248, + }, + dictWord{143, 11, 23}, + dictWord{7, 10, 204}, + dictWord{7, 10, 415}, + dictWord{8, 10, 42}, + dictWord{10, 10, 85}, + dictWord{139, 10, 564}, + dictWord{ + 134, + 0, + 958, + }, + dictWord{133, 11, 965}, + dictWord{132, 0, 210}, + dictWord{135, 11, 1429}, + dictWord{138, 11, 480}, + dictWord{134, 11, 182}, + dictWord{ + 139, + 11, + 345, + }, + dictWord{10, 11, 65}, + dictWord{10, 11, 488}, + dictWord{138, 11, 497}, + dictWord{4, 10, 3}, + dictWord{5, 10, 247}, + dictWord{5, 10, 644}, + dictWord{ + 7, + 10, + 744, + }, + dictWord{7, 10, 1207}, + dictWord{7, 10, 1225}, + dictWord{7, 10, 1909}, + dictWord{146, 10, 147}, + dictWord{132, 0, 430}, + dictWord{5, 10, 285}, + dictWord{ + 9, + 10, + 67, + }, + dictWord{13, 10, 473}, + dictWord{143, 10, 82}, + dictWord{144, 11, 16}, + dictWord{7, 11, 1162}, + dictWord{9, 11, 588}, + dictWord{10, 11, 260}, + dictWord{151, 10, 8}, + dictWord{133, 0, 213}, + dictWord{138, 0, 7}, + dictWord{135, 0, 801}, + dictWord{134, 11, 1786}, + dictWord{135, 11, 308}, + dictWord{6, 0, 936}, + dictWord{134, 0, 1289}, + dictWord{133, 0, 108}, + dictWord{132, 0, 885}, + dictWord{133, 0, 219}, + dictWord{139, 0, 587}, + dictWord{4, 0, 193}, + dictWord{5, 0, 916}, + dictWord{6, 0, 1041}, + dictWord{7, 0, 364}, + dictWord{10, 0, 398}, + dictWord{10, 0, 726}, + dictWord{11, 0, 317}, + dictWord{11, 0, 626}, + dictWord{12, 0, 142}, + dictWord{12, 0, 288}, + dictWord{12, 0, 678}, + dictWord{13, 0, 313}, + dictWord{15, 0, 113}, + dictWord{146, 0, 114}, + dictWord{135, 0, 1165}, + dictWord{6, 0, 241}, + dictWord{ + 9, + 0, + 342, + }, + dictWord{10, 0, 729}, + dictWord{11, 0, 284}, + dictWord{11, 0, 445}, + dictWord{11, 0, 651}, + dictWord{11, 0, 863}, + dictWord{13, 0, 398}, + dictWord{ + 146, + 0, + 99, + }, + dictWord{7, 0, 907}, + dictWord{136, 0, 832}, + dictWord{9, 0, 303}, + dictWord{4, 10, 29}, + dictWord{6, 10, 532}, + dictWord{7, 10, 1628}, + dictWord{7, 10, 1648}, + dictWord{9, 10, 350}, + dictWord{10, 10, 433}, + dictWord{11, 10, 97}, + dictWord{11, 10, 557}, + dictWord{11, 10, 745}, + dictWord{12, 10, 289}, + dictWord{ + 12, + 10, + 335, + }, + dictWord{12, 10, 348}, + dictWord{12, 10, 606}, + dictWord{13, 10, 116}, + dictWord{13, 10, 233}, + dictWord{13, 10, 466}, + dictWord{14, 10, 181}, + dictWord{ + 14, + 10, + 209, + }, + dictWord{14, 10, 232}, + dictWord{14, 10, 236}, + dictWord{14, 10, 300}, + dictWord{16, 10, 41}, + dictWord{148, 10, 97}, + dictWord{7, 11, 423}, + dictWord{7, 10, 1692}, + dictWord{136, 11, 588}, + dictWord{6, 0, 931}, + dictWord{134, 0, 1454}, + dictWord{5, 10, 501}, + dictWord{7, 10, 1704}, + dictWord{9, 10, 553}, + dictWord{11, 10, 520}, + dictWord{12, 10, 557}, + dictWord{141, 10, 249}, + dictWord{136, 11, 287}, + dictWord{4, 0, 562}, + dictWord{9, 0, 254}, + dictWord{ + 139, + 0, + 879, + }, + dictWord{132, 0, 786}, + dictWord{14, 11, 32}, + dictWord{18, 11, 85}, + dictWord{20, 11, 2}, + dictWord{152, 11, 16}, + dictWord{135, 0, 1294}, + dictWord{ + 7, + 11, + 723, + }, + dictWord{135, 11, 1135}, + dictWord{6, 0, 216}, + dictWord{7, 0, 901}, + dictWord{7, 0, 1343}, + dictWord{8, 0, 493}, + dictWord{134, 11, 403}, + dictWord{ + 7, + 11, + 719, + }, + dictWord{8, 11, 809}, + dictWord{136, 11, 834}, + dictWord{5, 11, 210}, + dictWord{6, 11, 213}, + dictWord{7, 11, 60}, + dictWord{10, 11, 364}, + dictWord{ + 139, + 11, + 135, + }, + dictWord{7, 0, 341}, + dictWord{11, 0, 219}, + dictWord{5, 11, 607}, + dictWord{8, 11, 326}, + dictWord{136, 11, 490}, + dictWord{4, 11, 701}, + dictWord{ + 5, + 11, + 472, + }, + dictWord{5, 11, 639}, + dictWord{7, 11, 1249}, + dictWord{9, 11, 758}, + dictWord{139, 11, 896}, + dictWord{135, 11, 380}, + dictWord{135, 11, 1947}, + dictWord{139, 0, 130}, + dictWord{135, 0, 1734}, + dictWord{10, 0, 115}, + dictWord{11, 0, 420}, + dictWord{12, 0, 154}, + dictWord{13, 0, 404}, + dictWord{14, 0, 346}, + dictWord{143, 0, 54}, + dictWord{134, 10, 129}, + dictWord{4, 11, 386}, + dictWord{7, 11, 41}, + dictWord{8, 11, 405}, + dictWord{9, 11, 497}, + dictWord{11, 11, 110}, + dictWord{11, 11, 360}, + dictWord{15, 11, 37}, + dictWord{144, 11, 84}, + dictWord{141, 11, 282}, + dictWord{5, 11, 46}, + dictWord{7, 11, 1452}, + dictWord{7, 11, 1480}, + dictWord{8, 11, 634}, + dictWord{140, 11, 472}, + dictWord{4, 11, 524}, + dictWord{136, 11, 810}, + dictWord{10, 11, 238}, + dictWord{141, 11, 33}, + dictWord{ + 133, + 0, + 604, + }, + dictWord{5, 0, 1011}, + dictWord{136, 0, 701}, + dictWord{8, 0, 856}, + dictWord{8, 0, 858}, + dictWord{8, 0, 879}, + dictWord{12, 0, 702}, + dictWord{142, 0, 447}, + dictWord{4, 0, 54}, + dictWord{5, 0, 666}, + dictWord{7, 0, 1039}, + dictWord{7, 0, 1130}, + dictWord{9, 0, 195}, + dictWord{138, 0, 302}, + dictWord{4, 10, 25}, + dictWord{ + 5, + 10, + 60, + }, + dictWord{6, 10, 504}, + dictWord{7, 10, 614}, + dictWord{7, 10, 1155}, + dictWord{140, 10, 0}, + dictWord{7, 10, 1248}, + dictWord{11, 10, 621}, + dictWord{ + 139, + 10, + 702, + }, + dictWord{133, 11, 997}, + dictWord{137, 10, 321}, + dictWord{134, 0, 1669}, + dictWord{134, 0, 1791}, + dictWord{4, 10, 379}, + dictWord{ + 135, + 10, + 1397, + }, + dictWord{138, 11, 372}, + dictWord{5, 11, 782}, + dictWord{5, 11, 829}, + dictWord{134, 11, 1738}, + dictWord{135, 0, 1228}, + dictWord{4, 10, 118}, + dictWord{6, 10, 274}, + dictWord{6, 10, 361}, + dictWord{7, 10, 75}, + dictWord{141, 10, 441}, + dictWord{132, 0, 623}, + dictWord{9, 11, 279}, + dictWord{10, 11, 407}, + dictWord{14, 11, 84}, + dictWord{150, 11, 18}, + dictWord{137, 10, 841}, + dictWord{135, 0, 798}, + dictWord{140, 10, 693}, + dictWord{5, 10, 314}, + dictWord{6, 10, 221}, + dictWord{7, 10, 419}, + dictWord{10, 10, 650}, + dictWord{11, 10, 396}, + dictWord{12, 10, 156}, + dictWord{13, 10, 369}, + dictWord{14, 10, 333}, + dictWord{ + 145, + 10, + 47, + }, + dictWord{135, 11, 1372}, + dictWord{7, 0, 122}, + dictWord{9, 0, 259}, + dictWord{10, 0, 84}, + dictWord{11, 0, 470}, + dictWord{12, 0, 541}, + dictWord{ + 141, + 0, + 379, + }, + dictWord{134, 0, 837}, + dictWord{8, 0, 1013}, + dictWord{4, 11, 78}, + dictWord{5, 11, 96}, + dictWord{5, 11, 182}, + dictWord{7, 11, 1724}, + dictWord{ + 7, + 11, + 1825, + }, + dictWord{10, 11, 394}, + dictWord{10, 11, 471}, + dictWord{11, 11, 532}, + dictWord{14, 11, 340}, + dictWord{145, 11, 88}, + dictWord{134, 0, 577}, + dictWord{135, 11, 1964}, + dictWord{132, 10, 913}, + dictWord{134, 0, 460}, + dictWord{8, 0, 891}, + dictWord{10, 0, 901}, + dictWord{10, 0, 919}, + dictWord{10, 0, 932}, + dictWord{12, 0, 715}, + dictWord{12, 0, 728}, + dictWord{12, 0, 777}, + dictWord{14, 0, 457}, + dictWord{144, 0, 103}, + dictWord{5, 0, 82}, + dictWord{5, 0, 131}, + dictWord{ + 7, + 0, + 1755, + }, + dictWord{8, 0, 31}, + dictWord{9, 0, 168}, + dictWord{9, 0, 764}, + dictWord{139, 0, 869}, + dictWord{136, 10, 475}, + dictWord{6, 0, 605}, + dictWord{ + 5, + 10, + 1016, + }, + dictWord{9, 11, 601}, + dictWord{9, 11, 619}, + dictWord{10, 11, 505}, + dictWord{10, 11, 732}, + dictWord{11, 11, 355}, + dictWord{140, 11, 139}, + dictWord{ + 7, + 10, + 602, + }, + dictWord{8, 10, 179}, + dictWord{10, 10, 781}, + dictWord{140, 10, 126}, + dictWord{134, 0, 1246}, + dictWord{6, 10, 329}, + dictWord{138, 10, 111}, + dictWord{6, 11, 215}, + dictWord{7, 11, 1028}, + dictWord{7, 11, 1473}, + dictWord{7, 11, 1721}, + dictWord{9, 11, 424}, + dictWord{138, 11, 779}, + dictWord{5, 0, 278}, + dictWord{137, 0, 68}, + dictWord{6, 0, 932}, + dictWord{6, 0, 1084}, + dictWord{144, 0, 86}, + dictWord{4, 0, 163}, + dictWord{5, 0, 201}, + dictWord{5, 0, 307}, + dictWord{ + 5, + 0, + 310, + }, + dictWord{6, 0, 335}, + dictWord{7, 0, 284}, + dictWord{7, 0, 1660}, + dictWord{136, 0, 165}, + dictWord{136, 0, 781}, + dictWord{134, 0, 707}, + dictWord{6, 0, 33}, + dictWord{135, 0, 1244}, + dictWord{5, 10, 821}, + dictWord{6, 11, 67}, + dictWord{6, 10, 1687}, + dictWord{7, 11, 258}, + dictWord{7, 11, 1630}, + dictWord{9, 11, 354}, + dictWord{9, 11, 675}, + dictWord{10, 11, 830}, + dictWord{14, 11, 80}, + dictWord{145, 11, 80}, + dictWord{6, 11, 141}, + dictWord{7, 11, 225}, + dictWord{9, 11, 59}, + dictWord{9, 11, 607}, + dictWord{10, 11, 312}, + dictWord{11, 11, 687}, + dictWord{12, 11, 555}, + dictWord{13, 11, 373}, + dictWord{13, 11, 494}, + dictWord{148, 11, 58}, + dictWord{134, 0, 1113}, + dictWord{9, 0, 388}, + dictWord{5, 10, 71}, + dictWord{7, 10, 1407}, + dictWord{9, 10, 704}, + dictWord{10, 10, 261}, + dictWord{10, 10, 619}, + dictWord{11, 10, 547}, + dictWord{11, 10, 619}, + dictWord{143, 10, 157}, + dictWord{7, 0, 1953}, + dictWord{136, 0, 720}, + dictWord{138, 0, 203}, + dictWord{ + 7, + 10, + 2008, + }, + dictWord{9, 10, 337}, + dictWord{138, 10, 517}, + dictWord{6, 0, 326}, + dictWord{7, 0, 677}, + dictWord{137, 0, 425}, + dictWord{139, 11, 81}, + dictWord{ + 7, + 0, + 1316, + }, + dictWord{7, 0, 1412}, + dictWord{7, 0, 1839}, + dictWord{9, 0, 589}, + dictWord{11, 0, 241}, + dictWord{11, 0, 676}, + dictWord{11, 0, 811}, + dictWord{11, 0, 891}, + dictWord{12, 0, 140}, + dictWord{12, 0, 346}, + dictWord{12, 0, 479}, + dictWord{13, 0, 140}, + dictWord{13, 0, 381}, + dictWord{14, 0, 188}, + dictWord{18, 0, 30}, + dictWord{148, 0, 108}, + dictWord{5, 0, 416}, + dictWord{6, 10, 86}, + dictWord{6, 10, 603}, + dictWord{7, 10, 292}, + dictWord{7, 10, 561}, + dictWord{8, 10, 257}, + dictWord{ + 8, + 10, + 382, + }, + dictWord{9, 10, 721}, + dictWord{9, 10, 778}, + dictWord{11, 10, 581}, + dictWord{140, 10, 466}, + dictWord{4, 10, 486}, + dictWord{133, 10, 491}, + dictWord{134, 0, 1300}, + dictWord{132, 10, 72}, + dictWord{7, 0, 847}, + dictWord{6, 10, 265}, + dictWord{7, 11, 430}, + dictWord{139, 11, 46}, + dictWord{5, 11, 602}, + dictWord{6, 11, 106}, + dictWord{7, 11, 1786}, + dictWord{7, 11, 1821}, + dictWord{7, 11, 2018}, + dictWord{9, 11, 418}, + dictWord{137, 11, 763}, + dictWord{5, 0, 358}, + dictWord{7, 0, 535}, + dictWord{7, 0, 1184}, + dictWord{10, 0, 662}, + dictWord{13, 0, 212}, + dictWord{13, 0, 304}, + dictWord{13, 0, 333}, + dictWord{145, 0, 98}, + dictWord{ + 5, + 11, + 65, + }, + dictWord{6, 11, 416}, + dictWord{7, 11, 1720}, + dictWord{7, 11, 1924}, + dictWord{8, 11, 677}, + dictWord{10, 11, 109}, + dictWord{11, 11, 14}, + dictWord{ + 11, + 11, + 70, + }, + dictWord{11, 11, 569}, + dictWord{11, 11, 735}, + dictWord{15, 11, 153}, + dictWord{148, 11, 80}, + dictWord{6, 0, 1823}, + dictWord{8, 0, 839}, + dictWord{ + 8, + 0, + 852, + }, + dictWord{8, 0, 903}, + dictWord{10, 0, 940}, + dictWord{12, 0, 707}, + dictWord{140, 0, 775}, + dictWord{135, 11, 1229}, + dictWord{6, 0, 1522}, + dictWord{ + 140, + 0, + 654, + }, + dictWord{136, 11, 595}, + dictWord{139, 0, 163}, + dictWord{141, 0, 314}, + dictWord{132, 0, 978}, + dictWord{4, 0, 601}, + dictWord{6, 0, 2035}, + dictWord{137, 10, 234}, + dictWord{5, 10, 815}, + dictWord{6, 10, 1688}, + dictWord{134, 10, 1755}, + dictWord{133, 0, 946}, + dictWord{136, 0, 434}, + dictWord{ + 6, + 10, + 197, + }, + dictWord{136, 10, 205}, + dictWord{7, 0, 411}, + dictWord{7, 0, 590}, + dictWord{8, 0, 631}, + dictWord{9, 0, 323}, + dictWord{10, 0, 355}, + dictWord{11, 0, 491}, + dictWord{12, 0, 143}, + dictWord{12, 0, 402}, + dictWord{13, 0, 73}, + dictWord{14, 0, 408}, + dictWord{15, 0, 107}, + dictWord{146, 0, 71}, + dictWord{7, 0, 1467}, + dictWord{ + 8, + 0, + 328, + }, + dictWord{10, 0, 544}, + dictWord{11, 0, 955}, + dictWord{12, 0, 13}, + dictWord{13, 0, 320}, + dictWord{145, 0, 83}, + dictWord{142, 0, 410}, + dictWord{ + 11, + 0, + 511, + }, + dictWord{13, 0, 394}, + dictWord{14, 0, 298}, + dictWord{14, 0, 318}, + dictWord{146, 0, 103}, + dictWord{6, 10, 452}, + dictWord{7, 10, 312}, + dictWord{ + 138, + 10, + 219, + }, + dictWord{138, 10, 589}, + dictWord{4, 10, 333}, + dictWord{9, 10, 176}, + dictWord{12, 10, 353}, + dictWord{141, 10, 187}, + dictWord{135, 11, 329}, + dictWord{132, 11, 469}, + dictWord{5, 0, 835}, + dictWord{134, 0, 483}, + dictWord{134, 11, 1743}, + dictWord{5, 11, 929}, + dictWord{6, 11, 340}, + dictWord{8, 11, 376}, + dictWord{136, 11, 807}, + dictWord{134, 10, 1685}, + dictWord{132, 0, 677}, + dictWord{5, 11, 218}, + dictWord{7, 11, 1610}, + dictWord{138, 11, 83}, + dictWord{ + 5, + 11, + 571, + }, + dictWord{135, 11, 1842}, + dictWord{132, 11, 455}, + dictWord{137, 0, 70}, + dictWord{135, 0, 1405}, + dictWord{7, 10, 135}, + dictWord{8, 10, 7}, + dictWord{ + 8, + 10, + 62, + }, + dictWord{9, 10, 243}, + dictWord{10, 10, 658}, + dictWord{10, 10, 697}, + dictWord{11, 10, 456}, + dictWord{139, 10, 756}, + dictWord{9, 10, 395}, + dictWord{138, 10, 79}, + dictWord{137, 0, 108}, + dictWord{6, 11, 161}, + dictWord{7, 11, 372}, + dictWord{137, 11, 597}, + dictWord{132, 11, 349}, + dictWord{ + 132, + 0, + 777, + }, + dictWord{132, 0, 331}, + dictWord{135, 10, 631}, + dictWord{133, 0, 747}, + dictWord{6, 11, 432}, + dictWord{6, 11, 608}, + dictWord{139, 11, 322}, + dictWord{138, 10, 835}, + dictWord{5, 11, 468}, + dictWord{7, 11, 1809}, + dictWord{10, 11, 325}, + dictWord{11, 11, 856}, + dictWord{12, 11, 345}, + dictWord{ + 143, + 11, + 104, + }, + dictWord{133, 11, 223}, + dictWord{7, 10, 406}, + dictWord{7, 10, 459}, + dictWord{8, 10, 606}, + dictWord{139, 10, 726}, + dictWord{132, 11, 566}, + dictWord{142, 0, 68}, + dictWord{4, 11, 59}, + dictWord{135, 11, 1394}, + dictWord{6, 11, 436}, + dictWord{139, 11, 481}, + dictWord{4, 11, 48}, + dictWord{5, 11, 271}, + dictWord{135, 11, 953}, + dictWord{139, 11, 170}, + dictWord{5, 11, 610}, + dictWord{136, 11, 457}, + dictWord{133, 11, 755}, + dictWord{135, 11, 1217}, + dictWord{ + 133, + 10, + 612, + }, + dictWord{132, 11, 197}, + dictWord{132, 0, 505}, + dictWord{4, 10, 372}, + dictWord{7, 10, 482}, + dictWord{8, 10, 158}, + dictWord{9, 10, 602}, + dictWord{ + 9, + 10, + 615, + }, + dictWord{10, 10, 245}, + dictWord{10, 10, 678}, + dictWord{10, 10, 744}, + dictWord{11, 10, 248}, + dictWord{139, 10, 806}, + dictWord{133, 0, 326}, + dictWord{5, 10, 854}, + dictWord{135, 10, 1991}, + dictWord{4, 0, 691}, + dictWord{146, 0, 16}, + dictWord{6, 0, 628}, + dictWord{9, 0, 35}, + dictWord{10, 0, 680}, + dictWord{10, 0, 793}, + dictWord{11, 0, 364}, + dictWord{13, 0, 357}, + dictWord{143, 0, 164}, + dictWord{138, 0, 654}, + dictWord{6, 0, 32}, + dictWord{7, 0, 385}, + dictWord{ + 7, + 0, + 757, + }, + dictWord{7, 0, 1916}, + dictWord{8, 0, 37}, + dictWord{8, 0, 94}, + dictWord{8, 0, 711}, + dictWord{9, 0, 541}, + dictWord{10, 0, 162}, + dictWord{10, 0, 795}, + dictWord{ + 11, + 0, + 989, + }, + dictWord{11, 0, 1010}, + dictWord{12, 0, 14}, + dictWord{142, 0, 308}, + dictWord{133, 11, 217}, + dictWord{6, 0, 152}, + dictWord{6, 0, 349}, + dictWord{ + 6, + 0, + 1682, + }, + dictWord{7, 0, 1252}, + dictWord{8, 0, 112}, + dictWord{9, 0, 435}, + dictWord{9, 0, 668}, + dictWord{10, 0, 290}, + dictWord{10, 0, 319}, + dictWord{10, 0, 815}, + dictWord{11, 0, 180}, + dictWord{11, 0, 837}, + dictWord{12, 0, 240}, + dictWord{13, 0, 152}, + dictWord{13, 0, 219}, + dictWord{142, 0, 158}, + dictWord{4, 0, 581}, + dictWord{134, 0, 726}, + dictWord{5, 10, 195}, + dictWord{135, 10, 1685}, + dictWord{6, 0, 126}, + dictWord{7, 0, 573}, + dictWord{8, 0, 397}, + dictWord{142, 0, 44}, + dictWord{138, 0, 89}, + dictWord{7, 10, 1997}, + dictWord{8, 10, 730}, + dictWord{139, 10, 1006}, + dictWord{134, 0, 1531}, + dictWord{134, 0, 1167}, + dictWord{ + 5, + 0, + 926, + }, + dictWord{12, 0, 203}, + dictWord{133, 10, 751}, + dictWord{4, 11, 165}, + dictWord{7, 11, 1398}, + dictWord{135, 11, 1829}, + dictWord{7, 0, 1232}, + dictWord{137, 0, 531}, + dictWord{135, 10, 821}, + dictWord{134, 0, 943}, + dictWord{133, 0, 670}, + dictWord{4, 0, 880}, + dictWord{139, 0, 231}, + dictWord{ + 134, + 0, + 1617, + }, + dictWord{135, 0, 1957}, + dictWord{5, 11, 9}, + dictWord{7, 11, 297}, + dictWord{7, 11, 966}, + dictWord{140, 11, 306}, + dictWord{6, 0, 975}, + dictWord{ + 134, + 0, + 985, + }, + dictWord{5, 10, 950}, + dictWord{5, 10, 994}, + dictWord{134, 10, 351}, + dictWord{12, 11, 21}, + dictWord{151, 11, 7}, + dictWord{5, 11, 146}, + dictWord{ + 6, + 11, + 411, + }, + dictWord{138, 11, 721}, + dictWord{7, 0, 242}, + dictWord{135, 0, 1942}, + dictWord{6, 11, 177}, + dictWord{135, 11, 467}, + dictWord{5, 0, 421}, + dictWord{ + 7, + 10, + 47, + }, + dictWord{137, 10, 684}, + dictWord{5, 0, 834}, + dictWord{7, 0, 1202}, + dictWord{8, 0, 14}, + dictWord{9, 0, 481}, + dictWord{137, 0, 880}, + dictWord{138, 0, 465}, + dictWord{6, 0, 688}, + dictWord{9, 0, 834}, + dictWord{132, 10, 350}, + dictWord{132, 0, 855}, + dictWord{4, 0, 357}, + dictWord{6, 0, 172}, + dictWord{7, 0, 143}, + dictWord{137, 0, 413}, + dictWord{133, 11, 200}, + dictWord{132, 0, 590}, + dictWord{7, 10, 1812}, + dictWord{13, 10, 259}, + dictWord{13, 10, 356}, + dictWord{ + 14, + 10, + 242, + }, + dictWord{147, 10, 114}, + dictWord{133, 10, 967}, + dictWord{11, 0, 114}, + dictWord{4, 10, 473}, + dictWord{7, 10, 623}, + dictWord{8, 10, 808}, + dictWord{ + 9, + 10, + 871, + }, + dictWord{9, 10, 893}, + dictWord{11, 10, 431}, + dictWord{12, 10, 112}, + dictWord{12, 10, 217}, + dictWord{12, 10, 243}, + dictWord{12, 10, 562}, + dictWord{ + 12, + 10, + 663, + }, + dictWord{12, 10, 683}, + dictWord{13, 10, 141}, + dictWord{13, 10, 197}, + dictWord{13, 10, 227}, + dictWord{13, 10, 406}, + dictWord{13, 10, 487}, + dictWord{14, 10, 156}, + dictWord{14, 10, 203}, + dictWord{14, 10, 224}, + dictWord{14, 10, 256}, + dictWord{18, 10, 58}, + dictWord{150, 10, 0}, + dictWord{ + 138, + 10, + 286, + }, + dictWord{4, 10, 222}, + dictWord{7, 10, 286}, + dictWord{136, 10, 629}, + dictWord{5, 0, 169}, + dictWord{7, 0, 333}, + dictWord{136, 0, 45}, + dictWord{ + 134, + 11, + 481, + }, + dictWord{132, 0, 198}, + dictWord{4, 0, 24}, + dictWord{5, 0, 140}, + dictWord{5, 0, 185}, + dictWord{7, 0, 1500}, + dictWord{11, 0, 565}, + dictWord{11, 0, 838}, + dictWord{4, 11, 84}, + dictWord{7, 11, 1482}, + dictWord{10, 11, 76}, + dictWord{138, 11, 142}, + dictWord{133, 0, 585}, + dictWord{141, 10, 306}, + dictWord{ + 133, + 11, + 1015, + }, + dictWord{4, 11, 315}, + dictWord{5, 11, 507}, + dictWord{135, 11, 1370}, + dictWord{136, 10, 146}, + dictWord{6, 0, 691}, + dictWord{134, 0, 1503}, + dictWord{ + 4, + 0, + 334, + }, + dictWord{133, 0, 593}, + dictWord{4, 10, 465}, + dictWord{135, 10, 1663}, + dictWord{142, 11, 173}, + dictWord{135, 0, 913}, + dictWord{12, 0, 116}, + dictWord{134, 11, 1722}, + dictWord{134, 0, 1360}, + dictWord{132, 0, 802}, + dictWord{8, 11, 222}, + dictWord{8, 11, 476}, + dictWord{9, 11, 238}, + dictWord{ + 11, + 11, + 516, + }, + dictWord{11, 11, 575}, + dictWord{15, 11, 109}, + dictWord{146, 11, 100}, + dictWord{6, 0, 308}, + dictWord{9, 0, 673}, + dictWord{7, 10, 138}, + dictWord{ + 7, + 10, + 517, + }, + dictWord{139, 10, 238}, + dictWord{132, 0, 709}, + dictWord{6, 0, 1876}, + dictWord{6, 0, 1895}, + dictWord{9, 0, 994}, + dictWord{9, 0, 1006}, + dictWord{ + 12, + 0, + 829, + }, + dictWord{12, 0, 888}, + dictWord{12, 0, 891}, + dictWord{146, 0, 185}, + dictWord{148, 10, 94}, + dictWord{4, 0, 228}, + dictWord{133, 0, 897}, + dictWord{ + 7, + 0, + 1840, + }, + dictWord{5, 10, 495}, + dictWord{7, 10, 834}, + dictWord{9, 10, 733}, + dictWord{139, 10, 378}, + dictWord{133, 10, 559}, + dictWord{6, 10, 21}, + dictWord{ + 6, + 10, + 1737, + }, + dictWord{7, 10, 1444}, + dictWord{136, 10, 224}, + dictWord{4, 0, 608}, + dictWord{133, 0, 497}, + dictWord{6, 11, 40}, + dictWord{135, 11, 1781}, + dictWord{134, 0, 1573}, + dictWord{135, 0, 2039}, + dictWord{6, 0, 540}, + dictWord{136, 0, 136}, + dictWord{4, 0, 897}, + dictWord{5, 0, 786}, + dictWord{133, 10, 519}, + dictWord{6, 0, 1878}, + dictWord{6, 0, 1884}, + dictWord{9, 0, 938}, + dictWord{9, 0, 948}, + dictWord{9, 0, 955}, + dictWord{9, 0, 973}, + dictWord{9, 0, 1012}, + dictWord{ + 12, + 0, + 895, + }, + dictWord{12, 0, 927}, + dictWord{143, 0, 254}, + dictWord{134, 0, 1469}, + dictWord{133, 0, 999}, + dictWord{4, 0, 299}, + dictWord{135, 0, 1004}, + dictWord{ + 4, + 0, + 745, + }, + dictWord{133, 0, 578}, + dictWord{136, 11, 574}, + dictWord{133, 0, 456}, + dictWord{134, 0, 1457}, + dictWord{7, 0, 1679}, + dictWord{132, 10, 402}, + dictWord{7, 0, 693}, + dictWord{8, 0, 180}, + dictWord{12, 0, 163}, + dictWord{8, 10, 323}, + dictWord{136, 10, 479}, + dictWord{11, 10, 580}, + dictWord{142, 10, 201}, + dictWord{5, 10, 59}, + dictWord{135, 10, 672}, + dictWord{132, 11, 354}, + dictWord{146, 10, 34}, + dictWord{4, 0, 755}, + dictWord{135, 11, 1558}, + dictWord{ + 7, + 0, + 1740, + }, + dictWord{146, 0, 48}, + dictWord{4, 10, 85}, + dictWord{135, 10, 549}, + dictWord{139, 0, 338}, + dictWord{133, 10, 94}, + dictWord{134, 0, 1091}, + dictWord{135, 11, 469}, + dictWord{12, 0, 695}, + dictWord{12, 0, 704}, + dictWord{20, 0, 113}, + dictWord{5, 11, 830}, + dictWord{14, 11, 338}, + dictWord{148, 11, 81}, + dictWord{135, 0, 1464}, + dictWord{6, 10, 11}, + dictWord{135, 10, 187}, + dictWord{135, 0, 975}, + dictWord{13, 0, 335}, + dictWord{132, 10, 522}, + dictWord{ + 134, + 0, + 1979, + }, + dictWord{5, 11, 496}, + dictWord{135, 11, 203}, + dictWord{4, 10, 52}, + dictWord{135, 10, 661}, + dictWord{7, 0, 1566}, + dictWord{8, 0, 269}, + dictWord{ + 9, + 0, + 212, + }, + dictWord{9, 0, 718}, + dictWord{14, 0, 15}, + dictWord{14, 0, 132}, + dictWord{142, 0, 227}, + dictWord{4, 0, 890}, + dictWord{5, 0, 805}, + dictWord{5, 0, 819}, + dictWord{ + 5, + 0, + 961, + }, + dictWord{6, 0, 396}, + dictWord{6, 0, 1631}, + dictWord{6, 0, 1678}, + dictWord{7, 0, 1967}, + dictWord{7, 0, 2041}, + dictWord{9, 0, 630}, + dictWord{11, 0, 8}, + dictWord{11, 0, 1019}, + dictWord{12, 0, 176}, + dictWord{13, 0, 225}, + dictWord{14, 0, 292}, + dictWord{21, 0, 24}, + dictWord{4, 10, 383}, + dictWord{133, 10, 520}, + dictWord{134, 11, 547}, + dictWord{135, 11, 1748}, + dictWord{5, 11, 88}, + dictWord{137, 11, 239}, + dictWord{146, 11, 128}, + dictWord{7, 11, 650}, + dictWord{ + 135, + 11, + 1310, + }, + dictWord{4, 10, 281}, + dictWord{5, 10, 38}, + dictWord{7, 10, 194}, + dictWord{7, 10, 668}, + dictWord{7, 10, 1893}, + dictWord{137, 10, 397}, + dictWord{135, 0, 1815}, + dictWord{9, 10, 635}, + dictWord{139, 10, 559}, + dictWord{7, 0, 1505}, + dictWord{10, 0, 190}, + dictWord{10, 0, 634}, + dictWord{11, 0, 792}, + dictWord{12, 0, 358}, + dictWord{140, 0, 447}, + dictWord{5, 0, 0}, + dictWord{6, 0, 536}, + dictWord{7, 0, 604}, + dictWord{13, 0, 445}, + dictWord{145, 0, 126}, + dictWord{ + 7, + 11, + 1076, + }, + dictWord{9, 11, 80}, + dictWord{11, 11, 78}, + dictWord{11, 11, 421}, + dictWord{11, 11, 534}, + dictWord{140, 11, 545}, + dictWord{8, 0, 966}, + dictWord{ + 10, + 0, + 1023, + }, + dictWord{14, 11, 369}, + dictWord{146, 11, 72}, + dictWord{135, 11, 1641}, + dictWord{6, 0, 232}, + dictWord{6, 0, 412}, + dictWord{7, 0, 1074}, + dictWord{ + 8, + 0, + 9, + }, + dictWord{8, 0, 157}, + dictWord{8, 0, 786}, + dictWord{9, 0, 196}, + dictWord{9, 0, 352}, + dictWord{9, 0, 457}, + dictWord{10, 0, 337}, + dictWord{11, 0, 232}, + dictWord{ + 11, + 0, + 877, + }, + dictWord{12, 0, 480}, + dictWord{140, 0, 546}, + dictWord{135, 0, 958}, + dictWord{4, 0, 382}, + dictWord{136, 0, 579}, + dictWord{4, 0, 212}, + dictWord{ + 135, + 0, + 1206, + }, + dictWord{4, 11, 497}, + dictWord{5, 11, 657}, + dictWord{135, 11, 1584}, + dictWord{132, 0, 681}, + dictWord{8, 0, 971}, + dictWord{138, 0, 965}, + dictWord{ + 5, + 10, + 448, + }, + dictWord{136, 10, 535}, + dictWord{14, 0, 16}, + dictWord{146, 0, 44}, + dictWord{11, 0, 584}, + dictWord{11, 0, 616}, + dictWord{14, 0, 275}, + dictWord{ + 11, + 11, + 584, + }, + dictWord{11, 11, 616}, + dictWord{142, 11, 275}, + dictWord{136, 11, 13}, + dictWord{7, 10, 610}, + dictWord{135, 10, 1501}, + dictWord{7, 11, 642}, + dictWord{8, 11, 250}, + dictWord{11, 11, 123}, + dictWord{11, 11, 137}, + dictWord{13, 11, 48}, + dictWord{142, 11, 95}, + dictWord{133, 0, 655}, + dictWord{17, 0, 67}, + dictWord{147, 0, 74}, + dictWord{134, 0, 751}, + dictWord{134, 0, 1967}, + dictWord{6, 0, 231}, + dictWord{136, 0, 423}, + dictWord{5, 0, 300}, + dictWord{138, 0, 1016}, + dictWord{4, 10, 319}, + dictWord{5, 10, 699}, + dictWord{138, 10, 673}, + dictWord{6, 0, 237}, + dictWord{7, 0, 611}, + dictWord{8, 0, 100}, + dictWord{9, 0, 416}, + dictWord{ + 11, + 0, + 335, + }, + dictWord{12, 0, 173}, + dictWord{18, 0, 101}, + dictWord{6, 10, 336}, + dictWord{8, 10, 552}, + dictWord{9, 10, 285}, + dictWord{10, 10, 99}, + dictWord{ + 139, + 10, + 568, + }, + dictWord{134, 0, 1370}, + dictWord{7, 10, 1406}, + dictWord{9, 10, 218}, + dictWord{141, 10, 222}, + dictWord{133, 10, 256}, + dictWord{ + 135, + 0, + 1208, + }, + dictWord{14, 11, 213}, + dictWord{148, 11, 38}, + dictWord{6, 0, 1219}, + dictWord{135, 11, 1642}, + dictWord{13, 0, 417}, + dictWord{14, 0, 129}, + dictWord{143, 0, 15}, + dictWord{10, 11, 545}, + dictWord{140, 11, 301}, + dictWord{17, 10, 39}, + dictWord{148, 10, 36}, + dictWord{133, 0, 199}, + dictWord{4, 11, 904}, + dictWord{133, 11, 794}, + dictWord{12, 0, 427}, + dictWord{146, 0, 38}, + dictWord{134, 0, 949}, + dictWord{8, 0, 665}, + dictWord{135, 10, 634}, + dictWord{ + 132, + 10, + 618, + }, + dictWord{135, 10, 259}, + dictWord{132, 10, 339}, + dictWord{133, 11, 761}, + dictWord{141, 10, 169}, + dictWord{132, 10, 759}, + dictWord{5, 0, 688}, + dictWord{7, 0, 539}, + dictWord{135, 0, 712}, + dictWord{7, 11, 386}, + dictWord{138, 11, 713}, + dictWord{134, 0, 1186}, + dictWord{6, 11, 7}, + dictWord{6, 11, 35}, + dictWord{ + 7, + 11, + 147, + }, + dictWord{7, 11, 1069}, + dictWord{7, 11, 1568}, + dictWord{7, 11, 1575}, + dictWord{7, 11, 1917}, + dictWord{8, 11, 43}, + dictWord{8, 11, 208}, + dictWord{ + 9, + 11, + 128, + }, + dictWord{9, 11, 866}, + dictWord{10, 11, 20}, + dictWord{11, 11, 981}, + dictWord{147, 11, 33}, + dictWord{7, 11, 893}, + dictWord{8, 10, 482}, + dictWord{141, 11, 424}, + dictWord{6, 0, 312}, + dictWord{6, 0, 1715}, + dictWord{10, 0, 584}, + dictWord{11, 0, 546}, + dictWord{11, 0, 692}, + dictWord{12, 0, 259}, + dictWord{ + 12, + 0, + 295, + }, + dictWord{13, 0, 46}, + dictWord{141, 0, 154}, + dictWord{5, 10, 336}, + dictWord{6, 10, 341}, + dictWord{6, 10, 478}, + dictWord{6, 10, 1763}, + dictWord{ + 136, + 10, + 386, + }, + dictWord{137, 0, 151}, + dictWord{132, 0, 588}, + dictWord{152, 0, 4}, + dictWord{6, 11, 322}, + dictWord{9, 11, 552}, + dictWord{11, 11, 274}, + dictWord{ + 13, + 11, + 209, + }, + dictWord{13, 11, 499}, + dictWord{14, 11, 85}, + dictWord{15, 11, 126}, + dictWord{145, 11, 70}, + dictWord{135, 10, 73}, + dictWord{4, 0, 231}, + dictWord{ + 5, + 0, + 61, + }, + dictWord{6, 0, 104}, + dictWord{7, 0, 729}, + dictWord{7, 0, 964}, + dictWord{7, 0, 1658}, + dictWord{140, 0, 414}, + dictWord{6, 0, 263}, + dictWord{138, 0, 757}, + dictWord{135, 10, 1971}, + dictWord{4, 0, 612}, + dictWord{133, 0, 561}, + dictWord{132, 0, 320}, + dictWord{135, 10, 1344}, + dictWord{8, 11, 83}, + dictWord{ + 8, + 11, + 817, + }, + dictWord{9, 11, 28}, + dictWord{9, 11, 29}, + dictWord{9, 11, 885}, + dictWord{10, 11, 387}, + dictWord{11, 11, 633}, + dictWord{11, 11, 740}, + dictWord{ + 13, + 11, + 235, + }, + dictWord{13, 11, 254}, + dictWord{15, 11, 143}, + dictWord{143, 11, 146}, + dictWord{5, 10, 396}, + dictWord{134, 10, 501}, + dictWord{140, 11, 49}, + dictWord{132, 0, 225}, + dictWord{4, 10, 929}, + dictWord{5, 10, 799}, + dictWord{8, 10, 46}, + dictWord{136, 10, 740}, + dictWord{4, 0, 405}, + dictWord{7, 0, 817}, + dictWord{ + 14, + 0, + 58, + }, + dictWord{17, 0, 37}, + dictWord{146, 0, 124}, + dictWord{133, 0, 974}, + dictWord{4, 11, 412}, + dictWord{133, 11, 581}, + dictWord{4, 10, 892}, + dictWord{ + 133, + 10, + 770, + }, + dictWord{4, 0, 996}, + dictWord{134, 0, 2026}, + dictWord{4, 0, 527}, + dictWord{5, 0, 235}, + dictWord{7, 0, 1239}, + dictWord{11, 0, 131}, + dictWord{ + 140, + 0, + 370, + }, + dictWord{9, 0, 16}, + dictWord{13, 0, 386}, + dictWord{135, 11, 421}, + dictWord{7, 0, 956}, + dictWord{7, 0, 1157}, + dictWord{7, 0, 1506}, + dictWord{7, 0, 1606}, + dictWord{7, 0, 1615}, + dictWord{7, 0, 1619}, + dictWord{7, 0, 1736}, + dictWord{7, 0, 1775}, + dictWord{8, 0, 590}, + dictWord{9, 0, 324}, + dictWord{9, 0, 736}, + dictWord{ + 9, + 0, + 774, + }, + dictWord{9, 0, 776}, + dictWord{9, 0, 784}, + dictWord{10, 0, 567}, + dictWord{10, 0, 708}, + dictWord{11, 0, 518}, + dictWord{11, 0, 613}, + dictWord{11, 0, 695}, + dictWord{11, 0, 716}, + dictWord{11, 0, 739}, + dictWord{11, 0, 770}, + dictWord{11, 0, 771}, + dictWord{11, 0, 848}, + dictWord{11, 0, 857}, + dictWord{11, 0, 931}, + dictWord{ + 11, + 0, + 947, + }, + dictWord{12, 0, 326}, + dictWord{12, 0, 387}, + dictWord{12, 0, 484}, + dictWord{12, 0, 528}, + dictWord{12, 0, 552}, + dictWord{12, 0, 613}, + dictWord{ + 13, + 0, + 189, + }, + dictWord{13, 0, 256}, + dictWord{13, 0, 340}, + dictWord{13, 0, 432}, + dictWord{13, 0, 436}, + dictWord{13, 0, 440}, + dictWord{13, 0, 454}, + dictWord{14, 0, 174}, + dictWord{14, 0, 220}, + dictWord{14, 0, 284}, + dictWord{14, 0, 390}, + dictWord{145, 0, 121}, + dictWord{135, 10, 158}, + dictWord{9, 0, 137}, + dictWord{138, 0, 221}, + dictWord{4, 11, 110}, + dictWord{10, 11, 415}, + dictWord{10, 11, 597}, + dictWord{142, 11, 206}, + dictWord{141, 11, 496}, + dictWord{135, 11, 205}, + dictWord{ + 151, + 10, + 25, + }, + dictWord{135, 11, 778}, + dictWord{7, 11, 1656}, + dictWord{7, 10, 2001}, + dictWord{9, 11, 369}, + dictWord{10, 11, 338}, + dictWord{10, 11, 490}, + dictWord{11, 11, 154}, + dictWord{11, 11, 545}, + dictWord{11, 11, 775}, + dictWord{13, 11, 77}, + dictWord{141, 11, 274}, + dictWord{4, 11, 444}, + dictWord{ + 10, + 11, + 146, + }, + dictWord{140, 11, 9}, + dictWord{7, 0, 390}, + dictWord{138, 0, 140}, + dictWord{135, 0, 1144}, + dictWord{134, 0, 464}, + dictWord{7, 10, 1461}, + dictWord{ + 140, + 10, + 91, + }, + dictWord{132, 10, 602}, + dictWord{4, 11, 283}, + dictWord{135, 11, 1194}, + dictWord{5, 0, 407}, + dictWord{11, 0, 204}, + dictWord{11, 0, 243}, + dictWord{ + 11, + 0, + 489, + }, + dictWord{12, 0, 293}, + dictWord{19, 0, 37}, + dictWord{20, 0, 73}, + dictWord{150, 0, 38}, + dictWord{7, 0, 1218}, + dictWord{136, 0, 303}, + dictWord{ + 5, + 0, + 325, + }, + dictWord{8, 0, 5}, + dictWord{8, 0, 227}, + dictWord{9, 0, 105}, + dictWord{10, 0, 585}, + dictWord{12, 0, 614}, + dictWord{4, 10, 13}, + dictWord{5, 10, 567}, + dictWord{ + 7, + 10, + 1498, + }, + dictWord{9, 10, 124}, + dictWord{11, 10, 521}, + dictWord{140, 10, 405}, + dictWord{135, 10, 1006}, + dictWord{7, 0, 800}, + dictWord{10, 0, 12}, + dictWord{134, 11, 1720}, + dictWord{135, 0, 1783}, + dictWord{132, 10, 735}, + dictWord{138, 10, 812}, + dictWord{4, 10, 170}, + dictWord{135, 10, 323}, + dictWord{ + 6, + 0, + 621, + }, + dictWord{13, 0, 504}, + dictWord{144, 0, 89}, + dictWord{5, 10, 304}, + dictWord{135, 10, 1403}, + dictWord{137, 11, 216}, + dictWord{6, 0, 920}, + dictWord{ + 6, + 0, + 1104, + }, + dictWord{9, 11, 183}, + dictWord{139, 11, 286}, + dictWord{4, 0, 376}, + dictWord{133, 10, 742}, + dictWord{134, 0, 218}, + dictWord{8, 0, 641}, + dictWord{ + 11, + 0, + 388, + }, + dictWord{140, 0, 580}, + dictWord{7, 0, 454}, + dictWord{7, 0, 782}, + dictWord{8, 0, 768}, + dictWord{140, 0, 686}, + dictWord{137, 11, 33}, + dictWord{ + 133, + 10, + 111, + }, + dictWord{144, 0, 0}, + dictWord{10, 0, 676}, + dictWord{140, 0, 462}, + dictWord{6, 0, 164}, + dictWord{136, 11, 735}, + dictWord{133, 10, 444}, + dictWord{ + 150, + 0, + 50, + }, + dictWord{7, 11, 1862}, + dictWord{12, 11, 491}, + dictWord{12, 11, 520}, + dictWord{13, 11, 383}, + dictWord{14, 11, 244}, + dictWord{146, 11, 12}, + dictWord{ + 5, + 11, + 132, + }, + dictWord{9, 11, 486}, + dictWord{9, 11, 715}, + dictWord{10, 11, 458}, + dictWord{11, 11, 373}, + dictWord{11, 11, 668}, + dictWord{11, 11, 795}, + dictWord{11, 11, 897}, + dictWord{12, 11, 272}, + dictWord{12, 11, 424}, + dictWord{12, 11, 539}, + dictWord{12, 11, 558}, + dictWord{14, 11, 245}, + dictWord{ + 14, + 11, + 263, + }, + dictWord{14, 11, 264}, + dictWord{14, 11, 393}, + dictWord{142, 11, 403}, + dictWord{8, 10, 123}, + dictWord{15, 10, 6}, + dictWord{144, 10, 7}, + dictWord{ + 6, + 0, + 285, + }, + dictWord{8, 0, 654}, + dictWord{11, 0, 749}, + dictWord{12, 0, 190}, + dictWord{12, 0, 327}, + dictWord{13, 0, 120}, + dictWord{13, 0, 121}, + dictWord{13, 0, 327}, + dictWord{15, 0, 47}, + dictWord{146, 0, 40}, + dictWord{5, 11, 8}, + dictWord{6, 11, 89}, + dictWord{6, 11, 400}, + dictWord{7, 11, 1569}, + dictWord{7, 11, 1623}, + dictWord{ + 7, + 11, + 1850, + }, + dictWord{8, 11, 218}, + dictWord{8, 11, 422}, + dictWord{9, 11, 570}, + dictWord{138, 11, 626}, + dictWord{6, 11, 387}, + dictWord{7, 11, 882}, + dictWord{141, 11, 111}, + dictWord{6, 0, 343}, + dictWord{7, 0, 195}, + dictWord{9, 0, 226}, + dictWord{10, 0, 197}, + dictWord{10, 0, 575}, + dictWord{11, 0, 502}, + dictWord{ + 11, + 0, + 899, + }, + dictWord{6, 11, 224}, + dictWord{7, 11, 877}, + dictWord{137, 11, 647}, + dictWord{5, 10, 937}, + dictWord{135, 10, 100}, + dictWord{135, 11, 790}, + dictWord{150, 0, 29}, + dictWord{147, 0, 8}, + dictWord{134, 0, 1812}, + dictWord{149, 0, 8}, + dictWord{135, 11, 394}, + dictWord{7, 0, 1125}, + dictWord{9, 0, 143}, + dictWord{ + 11, + 0, + 61, + }, + dictWord{14, 0, 405}, + dictWord{150, 0, 21}, + dictWord{10, 11, 755}, + dictWord{147, 11, 29}, + dictWord{9, 11, 378}, + dictWord{141, 11, 162}, + dictWord{135, 10, 922}, + dictWord{5, 10, 619}, + dictWord{133, 10, 698}, + dictWord{134, 0, 1327}, + dictWord{6, 0, 1598}, + dictWord{137, 0, 575}, + dictWord{ + 9, + 11, + 569, + }, + dictWord{12, 11, 12}, + dictWord{12, 11, 81}, + dictWord{12, 11, 319}, + dictWord{13, 11, 69}, + dictWord{14, 11, 259}, + dictWord{16, 11, 87}, + dictWord{ + 17, + 11, + 1, + }, + dictWord{17, 11, 21}, + dictWord{17, 11, 24}, + dictWord{18, 11, 15}, + dictWord{18, 11, 56}, + dictWord{18, 11, 59}, + dictWord{18, 11, 127}, + dictWord{18, 11, 154}, + dictWord{19, 11, 19}, + dictWord{148, 11, 31}, + dictWord{6, 0, 895}, + dictWord{135, 11, 1231}, + dictWord{5, 0, 959}, + dictWord{7, 11, 124}, + dictWord{136, 11, 38}, + dictWord{5, 11, 261}, + dictWord{7, 11, 78}, + dictWord{7, 11, 199}, + dictWord{8, 11, 815}, + dictWord{9, 11, 126}, + dictWord{138, 11, 342}, + dictWord{5, 10, 917}, + dictWord{134, 10, 1659}, + dictWord{7, 0, 1759}, + dictWord{5, 11, 595}, + dictWord{135, 11, 1863}, + dictWord{136, 0, 173}, + dictWord{134, 0, 266}, + dictWord{ + 142, + 0, + 261, + }, + dictWord{132, 11, 628}, + dictWord{5, 10, 251}, + dictWord{5, 10, 956}, + dictWord{8, 10, 268}, + dictWord{9, 10, 214}, + dictWord{146, 10, 142}, + dictWord{ + 7, + 11, + 266, + }, + dictWord{136, 11, 804}, + dictWord{135, 11, 208}, + dictWord{6, 11, 79}, + dictWord{7, 11, 1021}, + dictWord{135, 11, 1519}, + dictWord{11, 11, 704}, + dictWord{141, 11, 396}, + dictWord{5, 10, 346}, + dictWord{5, 10, 711}, + dictWord{136, 10, 390}, + dictWord{136, 11, 741}, + dictWord{134, 11, 376}, + dictWord{ + 134, + 0, + 1427, + }, + dictWord{6, 0, 1033}, + dictWord{6, 0, 1217}, + dictWord{136, 0, 300}, + dictWord{133, 10, 624}, + dictWord{6, 11, 100}, + dictWord{7, 11, 244}, + dictWord{ + 7, + 11, + 632, + }, + dictWord{7, 11, 1609}, + dictWord{8, 11, 178}, + dictWord{8, 11, 638}, + dictWord{141, 11, 58}, + dictWord{6, 0, 584}, + dictWord{5, 10, 783}, + dictWord{ + 7, + 10, + 1998, + }, + dictWord{135, 10, 2047}, + dictWord{5, 0, 427}, + dictWord{5, 0, 734}, + dictWord{7, 0, 478}, + dictWord{136, 0, 52}, + dictWord{7, 0, 239}, + dictWord{ + 11, + 0, + 217, + }, + dictWord{142, 0, 165}, + dictWord{134, 0, 1129}, + dictWord{6, 0, 168}, + dictWord{6, 0, 1734}, + dictWord{7, 0, 20}, + dictWord{7, 0, 1056}, + dictWord{8, 0, 732}, + dictWord{9, 0, 406}, + dictWord{9, 0, 911}, + dictWord{138, 0, 694}, + dictWord{132, 10, 594}, + dictWord{133, 11, 791}, + dictWord{7, 11, 686}, + dictWord{8, 11, 33}, + dictWord{8, 11, 238}, + dictWord{10, 11, 616}, + dictWord{11, 11, 467}, + dictWord{11, 11, 881}, + dictWord{13, 11, 217}, + dictWord{13, 11, 253}, + dictWord{ + 142, + 11, + 268, + }, + dictWord{137, 11, 476}, + dictWord{134, 0, 418}, + dictWord{133, 0, 613}, + dictWord{132, 0, 632}, + dictWord{132, 11, 447}, + dictWord{7, 0, 32}, + dictWord{ + 7, + 0, + 984, + }, + dictWord{8, 0, 85}, + dictWord{8, 0, 709}, + dictWord{9, 0, 579}, + dictWord{9, 0, 847}, + dictWord{9, 0, 856}, + dictWord{10, 0, 799}, + dictWord{11, 0, 258}, + dictWord{ + 11, + 0, + 1007, + }, + dictWord{12, 0, 331}, + dictWord{12, 0, 615}, + dictWord{13, 0, 188}, + dictWord{13, 0, 435}, + dictWord{14, 0, 8}, + dictWord{15, 0, 165}, + dictWord{ + 16, + 0, + 27, + }, + dictWord{20, 0, 40}, + dictWord{144, 11, 35}, + dictWord{4, 11, 128}, + dictWord{5, 11, 415}, + dictWord{6, 11, 462}, + dictWord{7, 11, 294}, + dictWord{7, 11, 578}, + dictWord{10, 11, 710}, + dictWord{139, 11, 86}, + dictWord{5, 0, 694}, + dictWord{136, 0, 909}, + dictWord{7, 0, 1109}, + dictWord{11, 0, 7}, + dictWord{5, 10, 37}, + dictWord{ + 6, + 10, + 39, + }, + dictWord{6, 10, 451}, + dictWord{7, 10, 218}, + dictWord{7, 10, 1166}, + dictWord{7, 10, 1687}, + dictWord{8, 10, 662}, + dictWord{144, 10, 2}, + dictWord{ + 136, + 11, + 587, + }, + dictWord{6, 11, 427}, + dictWord{7, 11, 1018}, + dictWord{138, 11, 692}, + dictWord{4, 11, 195}, + dictWord{6, 10, 508}, + dictWord{135, 11, 802}, + dictWord{4, 0, 167}, + dictWord{135, 0, 82}, + dictWord{5, 0, 62}, + dictWord{6, 0, 24}, + dictWord{6, 0, 534}, + dictWord{7, 0, 74}, + dictWord{7, 0, 678}, + dictWord{7, 0, 684}, + dictWord{ + 7, + 0, + 1043, + }, + dictWord{7, 0, 1072}, + dictWord{8, 0, 280}, + dictWord{8, 0, 541}, + dictWord{8, 0, 686}, + dictWord{9, 0, 258}, + dictWord{10, 0, 519}, + dictWord{11, 0, 252}, + dictWord{140, 0, 282}, + dictWord{138, 0, 33}, + dictWord{4, 0, 359}, + dictWord{133, 11, 738}, + dictWord{7, 0, 980}, + dictWord{9, 0, 328}, + dictWord{13, 0, 186}, + dictWord{13, 0, 364}, + dictWord{7, 10, 635}, + dictWord{7, 10, 796}, + dictWord{8, 10, 331}, + dictWord{9, 10, 330}, + dictWord{9, 10, 865}, + dictWord{10, 10, 119}, + dictWord{ + 10, + 10, + 235, + }, + dictWord{11, 10, 111}, + dictWord{11, 10, 129}, + dictWord{11, 10, 240}, + dictWord{12, 10, 31}, + dictWord{12, 10, 66}, + dictWord{12, 10, 222}, + dictWord{12, 10, 269}, + dictWord{12, 10, 599}, + dictWord{12, 10, 684}, + dictWord{12, 10, 689}, + dictWord{12, 10, 691}, + dictWord{142, 10, 345}, + dictWord{ + 137, + 10, + 527, + }, + dictWord{6, 0, 596}, + dictWord{7, 0, 585}, + dictWord{135, 10, 702}, + dictWord{134, 11, 1683}, + dictWord{133, 0, 211}, + dictWord{6, 0, 145}, + dictWord{ + 141, + 0, + 336, + }, + dictWord{134, 0, 1130}, + dictWord{7, 0, 873}, + dictWord{6, 10, 37}, + dictWord{7, 10, 1666}, + dictWord{8, 10, 195}, + dictWord{8, 10, 316}, + dictWord{ + 9, + 10, + 178, + }, + dictWord{9, 10, 276}, + dictWord{9, 10, 339}, + dictWord{9, 10, 536}, + dictWord{10, 10, 102}, + dictWord{10, 10, 362}, + dictWord{10, 10, 785}, + dictWord{ + 11, + 10, + 55, + }, + dictWord{11, 10, 149}, + dictWord{11, 10, 773}, + dictWord{13, 10, 416}, + dictWord{13, 10, 419}, + dictWord{14, 10, 38}, + dictWord{14, 10, 41}, + dictWord{ + 142, + 10, + 210, + }, + dictWord{8, 0, 840}, + dictWord{136, 0, 841}, + dictWord{132, 0, 263}, + dictWord{5, 11, 3}, + dictWord{8, 11, 578}, + dictWord{9, 11, 118}, + dictWord{ + 10, + 11, + 705, + }, + dictWord{12, 11, 383}, + dictWord{141, 11, 279}, + dictWord{132, 0, 916}, + dictWord{133, 11, 229}, + dictWord{133, 10, 645}, + dictWord{15, 0, 155}, + dictWord{16, 0, 79}, + dictWord{8, 11, 102}, + dictWord{10, 11, 578}, + dictWord{10, 11, 672}, + dictWord{12, 11, 496}, + dictWord{13, 11, 408}, + dictWord{14, 11, 121}, + dictWord{145, 11, 106}, + dictWord{4, 0, 599}, + dictWord{5, 0, 592}, + dictWord{6, 0, 1634}, + dictWord{7, 0, 5}, + dictWord{7, 0, 55}, + dictWord{7, 0, 67}, + dictWord{7, 0, 97}, + dictWord{7, 0, 691}, + dictWord{7, 0, 979}, + dictWord{7, 0, 1600}, + dictWord{7, 0, 1697}, + dictWord{8, 0, 207}, + dictWord{8, 0, 214}, + dictWord{8, 0, 231}, + dictWord{8, 0, 294}, + dictWord{8, 0, 336}, + dictWord{8, 0, 428}, + dictWord{8, 0, 471}, + dictWord{8, 0, 622}, + dictWord{8, 0, 626}, + dictWord{8, 0, 679}, + dictWord{8, 0, 759}, + dictWord{8, 0, 829}, + dictWord{9, 0, 11}, + dictWord{9, 0, 246}, + dictWord{9, 0, 484}, + dictWord{9, 0, 573}, + dictWord{9, 0, 706}, + dictWord{9, 0, 762}, + dictWord{9, 0, 798}, + dictWord{9, 0, 855}, + dictWord{9, 0, 870}, + dictWord{9, 0, 912}, + dictWord{10, 0, 303}, + dictWord{10, 0, 335}, + dictWord{10, 0, 424}, + dictWord{10, 0, 461}, + dictWord{10, 0, 543}, + dictWord{ + 10, + 0, + 759, + }, + dictWord{10, 0, 814}, + dictWord{11, 0, 59}, + dictWord{11, 0, 199}, + dictWord{11, 0, 235}, + dictWord{11, 0, 590}, + dictWord{11, 0, 631}, + dictWord{11, 0, 929}, + dictWord{11, 0, 963}, + dictWord{11, 0, 987}, + dictWord{12, 0, 114}, + dictWord{12, 0, 182}, + dictWord{12, 0, 226}, + dictWord{12, 0, 332}, + dictWord{12, 0, 439}, + dictWord{12, 0, 575}, + dictWord{12, 0, 598}, + dictWord{12, 0, 675}, + dictWord{13, 0, 8}, + dictWord{13, 0, 125}, + dictWord{13, 0, 194}, + dictWord{13, 0, 287}, + dictWord{ + 14, + 0, + 197, + }, + dictWord{14, 0, 383}, + dictWord{15, 0, 53}, + dictWord{17, 0, 63}, + dictWord{19, 0, 46}, + dictWord{19, 0, 98}, + dictWord{19, 0, 106}, + dictWord{148, 0, 85}, + dictWord{ + 7, + 0, + 1356, + }, + dictWord{132, 10, 290}, + dictWord{6, 10, 70}, + dictWord{7, 10, 1292}, + dictWord{10, 10, 762}, + dictWord{139, 10, 288}, + dictWord{150, 11, 55}, + dictWord{4, 0, 593}, + dictWord{8, 11, 115}, + dictWord{8, 11, 350}, + dictWord{9, 11, 489}, + dictWord{10, 11, 128}, + dictWord{11, 11, 306}, + dictWord{12, 11, 373}, + dictWord{14, 11, 30}, + dictWord{17, 11, 79}, + dictWord{147, 11, 80}, + dictWord{135, 11, 1235}, + dictWord{134, 0, 1392}, + dictWord{4, 11, 230}, + dictWord{ + 133, + 11, + 702, + }, + dictWord{147, 0, 126}, + dictWord{7, 10, 131}, + dictWord{7, 10, 422}, + dictWord{8, 10, 210}, + dictWord{140, 10, 573}, + dictWord{134, 0, 1179}, + dictWord{ + 139, + 11, + 435, + }, + dictWord{139, 10, 797}, + dictWord{134, 11, 1728}, + dictWord{4, 0, 162}, + dictWord{18, 11, 26}, + dictWord{19, 11, 42}, + dictWord{20, 11, 43}, + dictWord{21, 11, 0}, + dictWord{23, 11, 27}, + dictWord{152, 11, 14}, + dictWord{132, 10, 936}, + dictWord{6, 0, 765}, + dictWord{5, 10, 453}, + dictWord{134, 10, 441}, + dictWord{133, 0, 187}, + dictWord{135, 0, 1286}, + dictWord{6, 0, 635}, + dictWord{6, 0, 904}, + dictWord{6, 0, 1210}, + dictWord{134, 0, 1489}, + dictWord{4, 0, 215}, + dictWord{ + 8, + 0, + 890, + }, + dictWord{9, 0, 38}, + dictWord{10, 0, 923}, + dictWord{11, 0, 23}, + dictWord{11, 0, 127}, + dictWord{139, 0, 796}, + dictWord{6, 0, 1165}, + dictWord{ + 134, + 0, + 1306, + }, + dictWord{7, 0, 716}, + dictWord{13, 0, 97}, + dictWord{141, 0, 251}, + dictWord{132, 10, 653}, + dictWord{136, 0, 657}, + dictWord{146, 10, 80}, + dictWord{ + 5, + 11, + 622, + }, + dictWord{7, 11, 1032}, + dictWord{11, 11, 26}, + dictWord{11, 11, 213}, + dictWord{11, 11, 707}, + dictWord{12, 11, 380}, + dictWord{13, 11, 226}, + dictWord{141, 11, 355}, + dictWord{6, 0, 299}, + dictWord{5, 11, 70}, + dictWord{6, 11, 334}, + dictWord{9, 11, 171}, + dictWord{11, 11, 637}, + dictWord{12, 11, 202}, + dictWord{14, 11, 222}, + dictWord{145, 11, 42}, + dictWord{142, 0, 134}, + dictWord{4, 11, 23}, + dictWord{5, 11, 313}, + dictWord{5, 11, 1014}, + dictWord{6, 11, 50}, + dictWord{ + 6, + 11, + 51, + }, + dictWord{7, 11, 142}, + dictWord{7, 11, 384}, + dictWord{9, 11, 783}, + dictWord{139, 11, 741}, + dictWord{4, 11, 141}, + dictWord{7, 11, 559}, + dictWord{ + 8, + 11, + 640, + }, + dictWord{9, 11, 460}, + dictWord{12, 11, 183}, + dictWord{141, 11, 488}, + dictWord{136, 11, 614}, + dictWord{7, 10, 1368}, + dictWord{8, 10, 232}, + dictWord{8, 10, 361}, + dictWord{10, 10, 682}, + dictWord{138, 10, 742}, + dictWord{137, 10, 534}, + dictWord{6, 0, 1082}, + dictWord{140, 0, 658}, + dictWord{ + 137, + 10, + 27, + }, + dictWord{135, 0, 2002}, + dictWord{142, 10, 12}, + dictWord{4, 0, 28}, + dictWord{5, 0, 440}, + dictWord{7, 0, 248}, + dictWord{11, 0, 833}, + dictWord{140, 0, 344}, + dictWord{7, 10, 736}, + dictWord{139, 10, 264}, + dictWord{134, 10, 1657}, + dictWord{134, 0, 1654}, + dictWord{138, 0, 531}, + dictWord{5, 11, 222}, + dictWord{ + 9, + 11, + 140, + }, + dictWord{138, 11, 534}, + dictWord{6, 0, 634}, + dictWord{6, 0, 798}, + dictWord{134, 0, 840}, + dictWord{138, 11, 503}, + dictWord{135, 10, 127}, + dictWord{133, 0, 853}, + dictWord{5, 11, 154}, + dictWord{7, 11, 1491}, + dictWord{10, 11, 379}, + dictWord{138, 11, 485}, + dictWord{6, 0, 249}, + dictWord{7, 0, 1234}, + dictWord{139, 0, 573}, + dictWord{133, 11, 716}, + dictWord{7, 11, 1570}, + dictWord{140, 11, 542}, + dictWord{136, 10, 364}, + dictWord{138, 0, 527}, + dictWord{ + 4, + 11, + 91, + }, + dictWord{5, 11, 388}, + dictWord{5, 11, 845}, + dictWord{6, 11, 206}, + dictWord{6, 11, 252}, + dictWord{6, 11, 365}, + dictWord{7, 11, 136}, + dictWord{7, 11, 531}, + dictWord{8, 11, 264}, + dictWord{136, 11, 621}, + dictWord{134, 0, 1419}, + dictWord{135, 11, 1441}, + dictWord{7, 0, 49}, + dictWord{7, 0, 392}, + dictWord{8, 0, 20}, + dictWord{8, 0, 172}, + dictWord{8, 0, 690}, + dictWord{9, 0, 383}, + dictWord{9, 0, 845}, + dictWord{10, 0, 48}, + dictWord{11, 0, 293}, + dictWord{11, 0, 832}, + dictWord{ + 11, + 0, + 920, + }, + dictWord{11, 0, 984}, + dictWord{141, 0, 221}, + dictWord{5, 0, 858}, + dictWord{133, 0, 992}, + dictWord{5, 0, 728}, + dictWord{137, 10, 792}, + dictWord{ + 5, + 10, + 909, + }, + dictWord{9, 10, 849}, + dictWord{138, 10, 805}, + dictWord{7, 0, 525}, + dictWord{7, 0, 1579}, + dictWord{8, 0, 497}, + dictWord{136, 0, 573}, + dictWord{6, 0, 268}, + dictWord{137, 0, 62}, + dictWord{135, 11, 576}, + dictWord{134, 0, 1201}, + dictWord{5, 11, 771}, + dictWord{5, 11, 863}, + dictWord{5, 11, 898}, + dictWord{ + 6, + 11, + 1632, + }, + dictWord{6, 11, 1644}, + dictWord{134, 11, 1780}, + dictWord{133, 11, 331}, + dictWord{7, 0, 193}, + dictWord{7, 0, 1105}, + dictWord{10, 0, 495}, + dictWord{ + 7, + 10, + 397, + }, + dictWord{8, 10, 124}, + dictWord{8, 10, 619}, + dictWord{9, 10, 305}, + dictWord{11, 10, 40}, + dictWord{12, 10, 349}, + dictWord{13, 10, 134}, + dictWord{ + 13, + 10, + 295, + }, + dictWord{14, 10, 155}, + dictWord{15, 10, 120}, + dictWord{146, 10, 105}, + dictWord{138, 0, 106}, + dictWord{6, 0, 859}, + dictWord{5, 11, 107}, + dictWord{ + 7, + 11, + 201, + }, + dictWord{136, 11, 518}, + dictWord{6, 11, 446}, + dictWord{135, 11, 1817}, + dictWord{13, 0, 23}, + dictWord{4, 10, 262}, + dictWord{135, 10, 342}, + dictWord{133, 10, 641}, + dictWord{137, 11, 851}, + dictWord{6, 0, 925}, + dictWord{137, 0, 813}, + dictWord{132, 11, 504}, + dictWord{6, 0, 613}, + dictWord{ + 136, + 0, + 223, + }, + dictWord{4, 10, 99}, + dictWord{6, 10, 250}, + dictWord{6, 10, 346}, + dictWord{8, 10, 127}, + dictWord{138, 10, 81}, + dictWord{136, 0, 953}, + dictWord{ + 132, + 10, + 915, + }, + dictWord{139, 11, 892}, + dictWord{5, 10, 75}, + dictWord{9, 10, 517}, + dictWord{10, 10, 470}, + dictWord{12, 10, 155}, + dictWord{141, 10, 224}, + dictWord{ + 4, + 0, + 666, + }, + dictWord{7, 0, 1017}, + dictWord{7, 11, 996}, + dictWord{138, 11, 390}, + dictWord{5, 11, 883}, + dictWord{133, 11, 975}, + dictWord{14, 10, 83}, + dictWord{ + 142, + 11, + 83, + }, + dictWord{4, 0, 670}, + dictWord{5, 11, 922}, + dictWord{134, 11, 1707}, + dictWord{135, 0, 216}, + dictWord{9, 0, 40}, + dictWord{11, 0, 136}, + dictWord{ + 135, + 11, + 787, + }, + dictWord{5, 10, 954}, + dictWord{5, 11, 993}, + dictWord{7, 11, 515}, + dictWord{137, 11, 91}, + dictWord{139, 0, 259}, + dictWord{7, 0, 1114}, + dictWord{ + 9, + 0, + 310, + }, + dictWord{9, 0, 682}, + dictWord{10, 0, 440}, + dictWord{13, 0, 40}, + dictWord{6, 10, 304}, + dictWord{8, 10, 418}, + dictWord{11, 10, 341}, + dictWord{ + 139, + 10, + 675, + }, + dictWord{14, 0, 296}, + dictWord{9, 10, 410}, + dictWord{139, 10, 425}, + dictWord{10, 11, 377}, + dictWord{12, 11, 363}, + dictWord{13, 11, 68}, + dictWord{ + 13, + 11, + 94, + }, + dictWord{14, 11, 108}, + dictWord{142, 11, 306}, + dictWord{7, 0, 1401}, + dictWord{135, 0, 1476}, + dictWord{4, 0, 296}, + dictWord{6, 0, 475}, + dictWord{ + 7, + 0, + 401, + }, + dictWord{7, 0, 1410}, + dictWord{7, 0, 1594}, + dictWord{7, 0, 1674}, + dictWord{8, 0, 63}, + dictWord{8, 0, 660}, + dictWord{137, 0, 74}, + dictWord{4, 0, 139}, + dictWord{4, 0, 388}, + dictWord{140, 0, 188}, + dictWord{132, 0, 797}, + dictWord{132, 11, 766}, + dictWord{5, 11, 103}, + dictWord{7, 11, 921}, + dictWord{8, 11, 580}, + dictWord{8, 11, 593}, + dictWord{8, 11, 630}, + dictWord{138, 11, 28}, + dictWord{4, 11, 911}, + dictWord{5, 11, 867}, + dictWord{133, 11, 1013}, + dictWord{134, 10, 14}, + dictWord{134, 0, 1572}, + dictWord{134, 10, 1708}, + dictWord{21, 0, 39}, + dictWord{5, 10, 113}, + dictWord{6, 10, 243}, + dictWord{7, 10, 1865}, + dictWord{ + 11, + 10, + 161, + }, + dictWord{16, 10, 37}, + dictWord{145, 10, 99}, + dictWord{7, 11, 1563}, + dictWord{141, 11, 182}, + dictWord{5, 11, 135}, + dictWord{6, 11, 519}, + dictWord{ + 7, + 11, + 1722, + }, + dictWord{10, 11, 271}, + dictWord{11, 11, 261}, + dictWord{145, 11, 54}, + dictWord{132, 10, 274}, + dictWord{134, 0, 1594}, + dictWord{4, 11, 300}, + dictWord{5, 11, 436}, + dictWord{135, 11, 484}, + dictWord{4, 0, 747}, + dictWord{6, 0, 290}, + dictWord{7, 0, 649}, + dictWord{7, 0, 1479}, + dictWord{135, 0, 1583}, + dictWord{133, 11, 535}, + dictWord{147, 11, 82}, + dictWord{133, 0, 232}, + dictWord{137, 0, 887}, + dictWord{135, 10, 166}, + dictWord{136, 0, 521}, + dictWord{4, 0, 14}, + dictWord{7, 0, 472}, + dictWord{7, 0, 1801}, + dictWord{10, 0, 748}, + dictWord{141, 0, 458}, + dictWord{134, 0, 741}, + dictWord{134, 0, 992}, + dictWord{16, 0, 111}, + dictWord{137, 10, 304}, + dictWord{4, 0, 425}, + dictWord{5, 11, 387}, + dictWord{7, 11, 557}, + dictWord{12, 11, 547}, + dictWord{142, 11, 86}, + dictWord{ + 135, + 11, + 1747, + }, + dictWord{5, 10, 654}, + dictWord{135, 11, 1489}, + dictWord{7, 0, 789}, + dictWord{4, 11, 6}, + dictWord{5, 11, 708}, + dictWord{136, 11, 75}, + dictWord{ + 6, + 10, + 273, + }, + dictWord{10, 10, 188}, + dictWord{13, 10, 377}, + dictWord{146, 10, 77}, + dictWord{6, 0, 1593}, + dictWord{4, 11, 303}, + dictWord{7, 11, 619}, + dictWord{ + 10, + 11, + 547, + }, + dictWord{10, 11, 687}, + dictWord{11, 11, 122}, + dictWord{140, 11, 601}, + dictWord{134, 0, 1768}, + dictWord{135, 10, 410}, + dictWord{138, 11, 772}, + dictWord{11, 0, 233}, + dictWord{139, 10, 524}, + dictWord{5, 0, 943}, + dictWord{134, 0, 1779}, + dictWord{134, 10, 1785}, + dictWord{136, 11, 529}, + dictWord{ + 132, + 0, + 955, + }, + dictWord{5, 0, 245}, + dictWord{6, 0, 576}, + dictWord{7, 0, 582}, + dictWord{136, 0, 225}, + dictWord{132, 10, 780}, + dictWord{142, 0, 241}, + dictWord{ + 134, + 0, + 1943, + }, + dictWord{4, 11, 106}, + dictWord{7, 11, 310}, + dictWord{7, 11, 1785}, + dictWord{10, 11, 690}, + dictWord{139, 11, 717}, + dictWord{134, 0, 1284}, + dictWord{5, 11, 890}, + dictWord{133, 11, 988}, + dictWord{6, 11, 626}, + dictWord{142, 11, 431}, + dictWord{10, 11, 706}, + dictWord{145, 11, 32}, + dictWord{ + 137, + 11, + 332, + }, + dictWord{132, 11, 698}, + dictWord{135, 0, 709}, + dictWord{5, 10, 948}, + dictWord{138, 11, 17}, + dictWord{136, 0, 554}, + dictWord{134, 0, 1564}, + dictWord{139, 10, 941}, + dictWord{132, 0, 443}, + dictWord{134, 0, 909}, + dictWord{134, 11, 84}, + dictWord{142, 0, 280}, + dictWord{4, 10, 532}, + dictWord{5, 10, 706}, + dictWord{135, 10, 662}, + dictWord{132, 0, 729}, + dictWord{5, 10, 837}, + dictWord{6, 10, 1651}, + dictWord{139, 10, 985}, + dictWord{135, 10, 1861}, + dictWord{ + 4, + 0, + 348, + }, + dictWord{152, 11, 3}, + dictWord{5, 11, 986}, + dictWord{6, 11, 130}, + dictWord{7, 11, 1582}, + dictWord{8, 11, 458}, + dictWord{10, 11, 101}, + dictWord{ + 10, + 11, + 318, + }, + dictWord{138, 11, 823}, + dictWord{134, 0, 758}, + dictWord{4, 0, 298}, + dictWord{137, 0, 848}, + dictWord{4, 10, 330}, + dictWord{7, 10, 933}, + dictWord{ + 7, + 10, + 2012, + }, + dictWord{136, 10, 292}, + dictWord{7, 11, 1644}, + dictWord{137, 11, 129}, + dictWord{6, 0, 1422}, + dictWord{9, 0, 829}, + dictWord{135, 10, 767}, + dictWord{5, 0, 164}, + dictWord{7, 0, 121}, + dictWord{142, 0, 189}, + dictWord{7, 0, 812}, + dictWord{7, 0, 1261}, + dictWord{7, 0, 1360}, + dictWord{9, 0, 632}, + dictWord{ + 140, + 0, + 352, + }, + dictWord{135, 11, 1788}, + dictWord{139, 0, 556}, + dictWord{135, 11, 997}, + dictWord{145, 10, 114}, + dictWord{4, 0, 172}, + dictWord{9, 0, 611}, + dictWord{10, 0, 436}, + dictWord{12, 0, 673}, + dictWord{13, 0, 255}, + dictWord{137, 10, 883}, + dictWord{11, 0, 530}, + dictWord{138, 10, 274}, + dictWord{133, 0, 844}, + dictWord{134, 0, 984}, + dictWord{13, 0, 232}, + dictWord{18, 0, 35}, + dictWord{4, 10, 703}, + dictWord{135, 10, 207}, + dictWord{132, 10, 571}, + dictWord{9, 0, 263}, + dictWord{10, 0, 147}, + dictWord{138, 0, 492}, + dictWord{7, 11, 1756}, + dictWord{137, 11, 98}, + dictWord{5, 10, 873}, + dictWord{5, 10, 960}, + dictWord{8, 10, 823}, + dictWord{137, 10, 881}, + dictWord{133, 0, 537}, + dictWord{132, 0, 859}, + dictWord{7, 11, 1046}, + dictWord{139, 11, 160}, + dictWord{137, 0, 842}, + dictWord{ + 139, + 10, + 283, + }, + dictWord{5, 10, 33}, + dictWord{6, 10, 470}, + dictWord{139, 10, 424}, + dictWord{6, 11, 45}, + dictWord{7, 11, 433}, + dictWord{8, 11, 129}, + dictWord{ + 9, + 11, + 21, + }, + dictWord{10, 11, 392}, + dictWord{11, 11, 79}, + dictWord{12, 11, 499}, + dictWord{13, 11, 199}, + dictWord{141, 11, 451}, + dictWord{135, 0, 1291}, + dictWord{135, 10, 1882}, + dictWord{7, 11, 558}, + dictWord{136, 11, 353}, + dictWord{134, 0, 1482}, + dictWord{5, 0, 230}, + dictWord{5, 0, 392}, + dictWord{6, 0, 420}, + dictWord{9, 0, 568}, + dictWord{140, 0, 612}, + dictWord{6, 0, 262}, + dictWord{7, 10, 90}, + dictWord{7, 10, 664}, + dictWord{7, 10, 830}, + dictWord{7, 10, 1380}, + dictWord{ + 7, + 10, + 2025, + }, + dictWord{8, 11, 81}, + dictWord{8, 10, 448}, + dictWord{8, 10, 828}, + dictWord{9, 11, 189}, + dictWord{9, 11, 201}, + dictWord{11, 11, 478}, + dictWord{ + 11, + 11, + 712, + }, + dictWord{141, 11, 338}, + dictWord{142, 0, 31}, + dictWord{5, 11, 353}, + dictWord{151, 11, 26}, + dictWord{132, 0, 753}, + dictWord{4, 0, 0}, + dictWord{ + 5, + 0, + 41, + }, + dictWord{7, 0, 1459}, + dictWord{7, 0, 1469}, + dictWord{7, 0, 1859}, + dictWord{9, 0, 549}, + dictWord{139, 0, 905}, + dictWord{9, 10, 417}, + dictWord{ + 137, + 10, + 493, + }, + dictWord{135, 11, 1113}, + dictWord{133, 0, 696}, + dictWord{141, 11, 448}, + dictWord{134, 10, 295}, + dictWord{132, 0, 834}, + dictWord{4, 0, 771}, + dictWord{5, 10, 1019}, + dictWord{6, 11, 25}, + dictWord{7, 11, 855}, + dictWord{7, 11, 1258}, + dictWord{144, 11, 32}, + dictWord{134, 0, 1076}, + dictWord{133, 0, 921}, + dictWord{133, 0, 674}, + dictWord{4, 11, 4}, + dictWord{7, 11, 1118}, + dictWord{7, 11, 1320}, + dictWord{7, 11, 1706}, + dictWord{8, 11, 277}, + dictWord{9, 11, 622}, + dictWord{10, 11, 9}, + dictWord{11, 11, 724}, + dictWord{12, 11, 350}, + dictWord{12, 11, 397}, + dictWord{13, 11, 28}, + dictWord{13, 11, 159}, + dictWord{15, 11, 89}, + dictWord{18, 11, 5}, + dictWord{19, 11, 9}, + dictWord{20, 11, 34}, + dictWord{150, 11, 47}, + dictWord{134, 10, 208}, + dictWord{6, 0, 444}, + dictWord{136, 0, 308}, + dictWord{ + 6, + 0, + 180, + }, + dictWord{7, 0, 1137}, + dictWord{8, 0, 751}, + dictWord{139, 0, 805}, + dictWord{4, 0, 183}, + dictWord{7, 0, 271}, + dictWord{11, 0, 824}, + dictWord{ + 11, + 0, + 952, + }, + dictWord{13, 0, 278}, + dictWord{13, 0, 339}, + dictWord{13, 0, 482}, + dictWord{14, 0, 424}, + dictWord{148, 0, 99}, + dictWord{7, 11, 317}, + dictWord{ + 135, + 11, + 569, + }, + dictWord{4, 0, 19}, + dictWord{5, 0, 477}, + dictWord{5, 0, 596}, + dictWord{6, 0, 505}, + dictWord{7, 0, 1221}, + dictWord{11, 0, 907}, + dictWord{12, 0, 209}, + dictWord{141, 0, 214}, + dictWord{135, 0, 1215}, + dictWord{6, 0, 271}, + dictWord{7, 0, 398}, + dictWord{8, 0, 387}, + dictWord{10, 0, 344}, + dictWord{7, 10, 448}, + dictWord{ + 7, + 10, + 1629, + }, + dictWord{7, 10, 1813}, + dictWord{8, 10, 442}, + dictWord{9, 10, 710}, + dictWord{10, 10, 282}, + dictWord{138, 10, 722}, + dictWord{11, 10, 844}, + dictWord{12, 10, 104}, + dictWord{140, 10, 625}, + dictWord{134, 11, 255}, + dictWord{133, 10, 787}, + dictWord{134, 0, 1645}, + dictWord{11, 11, 956}, + dictWord{ + 151, + 11, + 3, + }, + dictWord{6, 0, 92}, + dictWord{6, 0, 188}, + dictWord{7, 0, 209}, + dictWord{7, 0, 1269}, + dictWord{7, 0, 1524}, + dictWord{7, 0, 1876}, + dictWord{8, 0, 661}, + dictWord{10, 0, 42}, + dictWord{10, 0, 228}, + dictWord{11, 0, 58}, + dictWord{11, 0, 1020}, + dictWord{12, 0, 58}, + dictWord{12, 0, 118}, + dictWord{141, 0, 32}, + dictWord{ + 4, + 0, + 459, + }, + dictWord{133, 0, 966}, + dictWord{4, 11, 536}, + dictWord{7, 11, 1141}, + dictWord{10, 11, 723}, + dictWord{139, 11, 371}, + dictWord{140, 0, 330}, + dictWord{134, 0, 1557}, + dictWord{7, 11, 285}, + dictWord{135, 11, 876}, + dictWord{136, 10, 491}, + dictWord{135, 11, 560}, + dictWord{6, 0, 18}, + dictWord{7, 0, 179}, + dictWord{7, 0, 932}, + dictWord{8, 0, 548}, + dictWord{8, 0, 757}, + dictWord{9, 0, 54}, + dictWord{9, 0, 65}, + dictWord{9, 0, 532}, + dictWord{9, 0, 844}, + dictWord{10, 0, 113}, + dictWord{10, 0, 117}, + dictWord{10, 0, 315}, + dictWord{10, 0, 560}, + dictWord{10, 0, 622}, + dictWord{10, 0, 798}, + dictWord{11, 0, 153}, + dictWord{11, 0, 351}, + dictWord{ + 11, + 0, + 375, + }, + dictWord{12, 0, 78}, + dictWord{12, 0, 151}, + dictWord{12, 0, 392}, + dictWord{12, 0, 666}, + dictWord{14, 0, 248}, + dictWord{143, 0, 23}, + dictWord{ + 6, + 0, + 1742, + }, + dictWord{132, 11, 690}, + dictWord{4, 10, 403}, + dictWord{5, 10, 441}, + dictWord{7, 10, 450}, + dictWord{10, 10, 840}, + dictWord{11, 10, 101}, + dictWord{ + 12, + 10, + 193, + }, + dictWord{141, 10, 430}, + dictWord{133, 0, 965}, + dictWord{134, 0, 182}, + dictWord{10, 0, 65}, + dictWord{10, 0, 488}, + dictWord{138, 0, 497}, + dictWord{135, 11, 1346}, + dictWord{6, 0, 973}, + dictWord{6, 0, 1158}, + dictWord{10, 11, 200}, + dictWord{19, 11, 2}, + dictWord{151, 11, 22}, + dictWord{4, 11, 190}, + dictWord{133, 11, 554}, + dictWord{133, 10, 679}, + dictWord{7, 0, 328}, + dictWord{137, 10, 326}, + dictWord{133, 11, 1001}, + dictWord{9, 0, 588}, + dictWord{ + 138, + 0, + 260, + }, + dictWord{133, 11, 446}, + dictWord{135, 10, 1128}, + dictWord{135, 10, 1796}, + dictWord{147, 11, 119}, + dictWord{134, 0, 1786}, + dictWord{ + 6, + 0, + 1328, + }, + dictWord{6, 0, 1985}, + dictWord{8, 0, 962}, + dictWord{138, 0, 1017}, + dictWord{135, 0, 308}, + dictWord{11, 0, 508}, + dictWord{4, 10, 574}, + dictWord{ + 7, + 10, + 350, + }, + dictWord{7, 10, 1024}, + dictWord{8, 10, 338}, + dictWord{9, 10, 677}, + dictWord{138, 10, 808}, + dictWord{138, 11, 752}, + dictWord{135, 10, 1081}, + dictWord{137, 11, 96}, + dictWord{7, 10, 1676}, + dictWord{135, 10, 2037}, + dictWord{136, 0, 588}, + dictWord{132, 11, 304}, + dictWord{133, 0, 614}, + dictWord{ + 140, + 0, + 793, + }, + dictWord{136, 0, 287}, + dictWord{137, 10, 297}, + dictWord{141, 10, 37}, + dictWord{6, 11, 53}, + dictWord{6, 11, 199}, + dictWord{7, 11, 1408}, + dictWord{ + 8, + 11, + 32, + }, + dictWord{8, 11, 93}, + dictWord{9, 11, 437}, + dictWord{10, 11, 397}, + dictWord{10, 11, 629}, + dictWord{11, 11, 593}, + dictWord{11, 11, 763}, + dictWord{ + 13, + 11, + 326, + }, + dictWord{145, 11, 35}, + dictWord{134, 11, 105}, + dictWord{9, 11, 320}, + dictWord{10, 11, 506}, + dictWord{138, 11, 794}, + dictWord{5, 11, 114}, + dictWord{5, 11, 255}, + dictWord{141, 11, 285}, + dictWord{140, 0, 290}, + dictWord{7, 11, 2035}, + dictWord{8, 11, 19}, + dictWord{9, 11, 89}, + dictWord{138, 11, 831}, + dictWord{134, 0, 1136}, + dictWord{7, 0, 719}, + dictWord{8, 0, 796}, + dictWord{8, 0, 809}, + dictWord{8, 0, 834}, + dictWord{6, 10, 306}, + dictWord{7, 10, 1140}, + dictWord{ + 7, + 10, + 1340, + }, + dictWord{8, 10, 133}, + dictWord{138, 10, 449}, + dictWord{139, 10, 1011}, + dictWord{5, 0, 210}, + dictWord{6, 0, 213}, + dictWord{7, 0, 60}, + dictWord{ + 10, + 0, + 364, + }, + dictWord{139, 0, 135}, + dictWord{5, 0, 607}, + dictWord{8, 0, 326}, + dictWord{136, 0, 490}, + dictWord{138, 11, 176}, + dictWord{132, 0, 701}, + dictWord{ + 5, + 0, + 472, + }, + dictWord{7, 0, 380}, + dictWord{137, 0, 758}, + dictWord{135, 0, 1947}, + dictWord{6, 0, 1079}, + dictWord{138, 0, 278}, + dictWord{138, 11, 391}, + dictWord{ + 5, + 10, + 329, + }, + dictWord{8, 10, 260}, + dictWord{139, 11, 156}, + dictWord{4, 0, 386}, + dictWord{7, 0, 41}, + dictWord{8, 0, 405}, + dictWord{8, 0, 728}, + dictWord{9, 0, 497}, + dictWord{11, 0, 110}, + dictWord{11, 0, 360}, + dictWord{15, 0, 37}, + dictWord{144, 0, 84}, + dictWord{5, 0, 46}, + dictWord{7, 0, 1452}, + dictWord{7, 0, 1480}, + dictWord{ + 8, + 0, + 634, + }, + dictWord{140, 0, 472}, + dictWord{136, 0, 961}, + dictWord{4, 0, 524}, + dictWord{136, 0, 810}, + dictWord{10, 0, 238}, + dictWord{141, 0, 33}, + dictWord{ + 132, + 10, + 657, + }, + dictWord{152, 10, 7}, + dictWord{133, 0, 532}, + dictWord{5, 0, 997}, + dictWord{135, 10, 1665}, + dictWord{7, 11, 594}, + dictWord{7, 11, 851}, + dictWord{ + 7, + 11, + 1858, + }, + dictWord{9, 11, 411}, + dictWord{9, 11, 574}, + dictWord{9, 11, 666}, + dictWord{9, 11, 737}, + dictWord{10, 11, 346}, + dictWord{10, 11, 712}, + dictWord{ + 11, + 11, + 246, + }, + dictWord{11, 11, 432}, + dictWord{11, 11, 517}, + dictWord{11, 11, 647}, + dictWord{11, 11, 679}, + dictWord{11, 11, 727}, + dictWord{12, 11, 304}, + dictWord{12, 11, 305}, + dictWord{12, 11, 323}, + dictWord{12, 11, 483}, + dictWord{12, 11, 572}, + dictWord{12, 11, 593}, + dictWord{12, 11, 602}, + dictWord{ + 13, + 11, + 95, + }, + dictWord{13, 11, 101}, + dictWord{13, 11, 171}, + dictWord{13, 11, 315}, + dictWord{13, 11, 378}, + dictWord{13, 11, 425}, + dictWord{13, 11, 475}, + dictWord{ + 14, + 11, + 63, + }, + dictWord{14, 11, 380}, + dictWord{14, 11, 384}, + dictWord{15, 11, 133}, + dictWord{18, 11, 112}, + dictWord{148, 11, 72}, + dictWord{5, 11, 955}, + dictWord{136, 11, 814}, + dictWord{134, 0, 1301}, + dictWord{5, 10, 66}, + dictWord{7, 10, 1896}, + dictWord{136, 10, 288}, + dictWord{133, 11, 56}, + dictWord{ + 134, + 10, + 1643, + }, + dictWord{6, 0, 1298}, + dictWord{148, 11, 100}, + dictWord{5, 0, 782}, + dictWord{5, 0, 829}, + dictWord{6, 0, 671}, + dictWord{6, 0, 1156}, + dictWord{6, 0, 1738}, + dictWord{137, 11, 621}, + dictWord{4, 0, 306}, + dictWord{5, 0, 570}, + dictWord{7, 0, 1347}, + dictWord{5, 10, 91}, + dictWord{5, 10, 648}, + dictWord{5, 10, 750}, + dictWord{ + 5, + 10, + 781, + }, + dictWord{6, 10, 54}, + dictWord{6, 10, 112}, + dictWord{6, 10, 402}, + dictWord{6, 10, 1732}, + dictWord{7, 10, 315}, + dictWord{7, 10, 749}, + dictWord{ + 7, + 10, + 1900, + }, + dictWord{9, 10, 78}, + dictWord{9, 10, 508}, + dictWord{10, 10, 611}, + dictWord{10, 10, 811}, + dictWord{11, 10, 510}, + dictWord{11, 10, 728}, + dictWord{ + 13, + 10, + 36, + }, + dictWord{14, 10, 39}, + dictWord{16, 10, 83}, + dictWord{17, 10, 124}, + dictWord{148, 10, 30}, + dictWord{8, 10, 570}, + dictWord{9, 11, 477}, + dictWord{ + 141, + 11, + 78, + }, + dictWord{4, 11, 639}, + dictWord{10, 11, 4}, + dictWord{10, 10, 322}, + dictWord{10, 10, 719}, + dictWord{11, 10, 407}, + dictWord{11, 11, 638}, + dictWord{ + 12, + 11, + 177, + }, + dictWord{148, 11, 57}, + dictWord{7, 0, 1823}, + dictWord{139, 0, 693}, + dictWord{7, 0, 759}, + dictWord{5, 11, 758}, + dictWord{8, 10, 125}, + dictWord{ + 8, + 10, + 369, + }, + dictWord{8, 10, 524}, + dictWord{10, 10, 486}, + dictWord{11, 10, 13}, + dictWord{11, 10, 381}, + dictWord{11, 10, 736}, + dictWord{11, 10, 766}, + dictWord{ + 11, + 10, + 845, + }, + dictWord{13, 10, 114}, + dictWord{13, 10, 292}, + dictWord{142, 10, 47}, + dictWord{7, 0, 1932}, + dictWord{6, 10, 1684}, + dictWord{6, 10, 1731}, + dictWord{7, 10, 356}, + dictWord{8, 10, 54}, + dictWord{8, 10, 221}, + dictWord{9, 10, 225}, + dictWord{9, 10, 356}, + dictWord{10, 10, 77}, + dictWord{10, 10, 446}, + dictWord{ + 10, + 10, + 731, + }, + dictWord{12, 10, 404}, + dictWord{141, 10, 491}, + dictWord{135, 11, 552}, + dictWord{135, 11, 1112}, + dictWord{4, 0, 78}, + dictWord{5, 0, 96}, + dictWord{ + 5, + 0, + 182, + }, + dictWord{6, 0, 1257}, + dictWord{7, 0, 1724}, + dictWord{7, 0, 1825}, + dictWord{10, 0, 394}, + dictWord{10, 0, 471}, + dictWord{11, 0, 532}, + dictWord{ + 14, + 0, + 340, + }, + dictWord{145, 0, 88}, + dictWord{139, 11, 328}, + dictWord{135, 0, 1964}, + dictWord{132, 10, 411}, + dictWord{4, 10, 80}, + dictWord{5, 10, 44}, + dictWord{ + 137, + 11, + 133, + }, + dictWord{5, 11, 110}, + dictWord{6, 11, 169}, + dictWord{6, 11, 1702}, + dictWord{7, 11, 400}, + dictWord{8, 11, 538}, + dictWord{9, 11, 184}, + dictWord{ + 9, + 11, + 524, + }, + dictWord{140, 11, 218}, + dictWord{4, 0, 521}, + dictWord{5, 10, 299}, + dictWord{7, 10, 1083}, + dictWord{140, 11, 554}, + dictWord{6, 11, 133}, + dictWord{ + 9, + 11, + 353, + }, + dictWord{12, 11, 628}, + dictWord{146, 11, 79}, + dictWord{6, 0, 215}, + dictWord{7, 0, 584}, + dictWord{7, 0, 1028}, + dictWord{7, 0, 1473}, + dictWord{ + 7, + 0, + 1721, + }, + dictWord{9, 0, 424}, + dictWord{138, 0, 779}, + dictWord{7, 0, 857}, + dictWord{7, 0, 1209}, + dictWord{7, 10, 1713}, + dictWord{9, 10, 537}, + dictWord{ + 10, + 10, + 165, + }, + dictWord{12, 10, 219}, + dictWord{140, 10, 561}, + dictWord{4, 10, 219}, + dictWord{6, 11, 93}, + dictWord{7, 11, 1422}, + dictWord{7, 10, 1761}, + dictWord{ + 7, + 11, + 1851, + }, + dictWord{8, 11, 673}, + dictWord{9, 10, 86}, + dictWord{9, 11, 529}, + dictWord{140, 11, 43}, + dictWord{137, 11, 371}, + dictWord{136, 0, 671}, + dictWord{ + 5, + 0, + 328, + }, + dictWord{135, 0, 918}, + dictWord{132, 0, 529}, + dictWord{9, 11, 25}, + dictWord{10, 11, 467}, + dictWord{138, 11, 559}, + dictWord{4, 11, 335}, + dictWord{ + 135, + 11, + 942, + }, + dictWord{134, 0, 716}, + dictWord{134, 0, 1509}, + dictWord{6, 0, 67}, + dictWord{7, 0, 258}, + dictWord{7, 0, 1630}, + dictWord{9, 0, 354}, + dictWord{ + 9, + 0, + 675, + }, + dictWord{10, 0, 830}, + dictWord{14, 0, 80}, + dictWord{17, 0, 80}, + dictWord{140, 10, 428}, + dictWord{134, 0, 1112}, + dictWord{6, 0, 141}, + dictWord{7, 0, 225}, + dictWord{9, 0, 59}, + dictWord{9, 0, 607}, + dictWord{10, 0, 312}, + dictWord{11, 0, 687}, + dictWord{12, 0, 555}, + dictWord{13, 0, 373}, + dictWord{13, 0, 494}, + dictWord{ + 148, + 0, + 58, + }, + dictWord{133, 10, 514}, + dictWord{8, 11, 39}, + dictWord{10, 11, 773}, + dictWord{11, 11, 84}, + dictWord{12, 11, 205}, + dictWord{142, 11, 1}, + dictWord{ + 8, + 0, + 783, + }, + dictWord{5, 11, 601}, + dictWord{133, 11, 870}, + dictWord{136, 11, 594}, + dictWord{4, 10, 55}, + dictWord{5, 10, 301}, + dictWord{6, 10, 571}, + dictWord{ + 14, + 10, + 49, + }, + dictWord{146, 10, 102}, + dictWord{132, 11, 181}, + dictWord{134, 11, 1652}, + dictWord{133, 10, 364}, + dictWord{4, 11, 97}, + dictWord{5, 11, 147}, + dictWord{6, 11, 286}, + dictWord{7, 11, 1362}, + dictWord{141, 11, 176}, + dictWord{4, 10, 76}, + dictWord{7, 10, 1550}, + dictWord{9, 10, 306}, + dictWord{9, 10, 430}, + dictWord{9, 10, 663}, + dictWord{10, 10, 683}, + dictWord{11, 10, 427}, + dictWord{11, 10, 753}, + dictWord{12, 10, 334}, + dictWord{12, 10, 442}, + dictWord{ + 14, + 10, + 258, + }, + dictWord{14, 10, 366}, + dictWord{143, 10, 131}, + dictWord{137, 10, 52}, + dictWord{6, 0, 955}, + dictWord{134, 0, 1498}, + dictWord{6, 11, 375}, + dictWord{ + 7, + 11, + 169, + }, + dictWord{7, 11, 254}, + dictWord{136, 11, 780}, + dictWord{7, 0, 430}, + dictWord{11, 0, 46}, + dictWord{14, 0, 343}, + dictWord{142, 11, 343}, + dictWord{ + 135, + 0, + 1183, + }, + dictWord{5, 0, 602}, + dictWord{7, 0, 2018}, + dictWord{9, 0, 418}, + dictWord{9, 0, 803}, + dictWord{135, 11, 1447}, + dictWord{8, 0, 677}, + dictWord{ + 135, + 11, + 1044, + }, + dictWord{139, 11, 285}, + dictWord{4, 10, 656}, + dictWord{135, 10, 779}, + dictWord{135, 10, 144}, + dictWord{5, 11, 629}, + dictWord{ + 135, + 11, + 1549, + }, + dictWord{135, 10, 1373}, + dictWord{138, 11, 209}, + dictWord{7, 10, 554}, + dictWord{7, 10, 605}, + dictWord{141, 10, 10}, + dictWord{5, 10, 838}, + dictWord{ + 5, + 10, + 841, + }, + dictWord{134, 10, 1649}, + dictWord{133, 10, 1012}, + dictWord{6, 0, 1357}, + dictWord{134, 0, 1380}, + dictWord{144, 0, 53}, + dictWord{6, 0, 590}, + dictWord{7, 10, 365}, + dictWord{7, 10, 1357}, + dictWord{7, 10, 1497}, + dictWord{8, 10, 154}, + dictWord{141, 10, 281}, + dictWord{133, 10, 340}, + dictWord{ + 132, + 11, + 420, + }, + dictWord{135, 0, 329}, + dictWord{147, 11, 32}, + dictWord{4, 0, 469}, + dictWord{10, 11, 429}, + dictWord{139, 10, 495}, + dictWord{8, 10, 261}, + dictWord{ + 9, + 10, + 144, + }, + dictWord{9, 10, 466}, + dictWord{10, 10, 370}, + dictWord{12, 10, 470}, + dictWord{13, 10, 144}, + dictWord{142, 10, 348}, + dictWord{142, 0, 460}, + dictWord{4, 11, 325}, + dictWord{9, 10, 897}, + dictWord{138, 11, 125}, + dictWord{6, 0, 1743}, + dictWord{6, 10, 248}, + dictWord{9, 10, 546}, + dictWord{10, 10, 535}, + dictWord{11, 10, 681}, + dictWord{141, 10, 135}, + dictWord{4, 0, 990}, + dictWord{5, 0, 929}, + dictWord{6, 0, 340}, + dictWord{8, 0, 376}, + dictWord{8, 0, 807}, + dictWord{ + 8, + 0, + 963, + }, + dictWord{8, 0, 980}, + dictWord{138, 0, 1007}, + dictWord{134, 0, 1603}, + dictWord{140, 0, 250}, + dictWord{4, 11, 714}, + dictWord{133, 11, 469}, + dictWord{134, 10, 567}, + dictWord{136, 10, 445}, + dictWord{5, 0, 218}, + dictWord{7, 0, 1610}, + dictWord{8, 0, 646}, + dictWord{10, 0, 83}, + dictWord{11, 11, 138}, + dictWord{140, 11, 40}, + dictWord{7, 0, 1512}, + dictWord{135, 0, 1794}, + dictWord{135, 11, 1216}, + dictWord{11, 0, 0}, + dictWord{16, 0, 78}, + dictWord{132, 11, 718}, + dictWord{133, 0, 571}, + dictWord{132, 0, 455}, + dictWord{134, 0, 1012}, + dictWord{5, 11, 124}, + dictWord{5, 11, 144}, + dictWord{6, 11, 548}, + dictWord{7, 11, 15}, + dictWord{7, 11, 153}, + dictWord{137, 11, 629}, + dictWord{142, 11, 10}, + dictWord{6, 11, 75}, + dictWord{7, 11, 1531}, + dictWord{8, 11, 416}, + dictWord{9, 11, 240}, + dictWord{9, 11, 275}, + dictWord{10, 11, 100}, + dictWord{11, 11, 658}, + dictWord{11, 11, 979}, + dictWord{12, 11, 86}, + dictWord{13, 11, 468}, + dictWord{14, 11, 66}, + dictWord{14, 11, 207}, + dictWord{15, 11, 20}, + dictWord{15, 11, 25}, + dictWord{144, 11, 58}, + dictWord{132, 10, 577}, + dictWord{5, 11, 141}, + dictWord{ + 5, + 11, + 915, + }, + dictWord{6, 11, 1783}, + dictWord{7, 11, 211}, + dictWord{7, 11, 698}, + dictWord{7, 11, 1353}, + dictWord{9, 11, 83}, + dictWord{9, 11, 281}, + dictWord{ + 10, + 11, + 376, + }, + dictWord{10, 11, 431}, + dictWord{11, 11, 543}, + dictWord{12, 11, 664}, + dictWord{13, 11, 280}, + dictWord{13, 11, 428}, + dictWord{14, 11, 61}, + dictWord{ + 14, + 11, + 128, + }, + dictWord{17, 11, 52}, + dictWord{145, 11, 81}, + dictWord{6, 0, 161}, + dictWord{7, 0, 372}, + dictWord{137, 0, 597}, + dictWord{132, 0, 349}, + dictWord{ + 10, + 11, + 702, + }, + dictWord{139, 11, 245}, + dictWord{134, 0, 524}, + dictWord{134, 10, 174}, + dictWord{6, 0, 432}, + dictWord{9, 0, 751}, + dictWord{139, 0, 322}, + dictWord{147, 11, 94}, + dictWord{4, 11, 338}, + dictWord{133, 11, 400}, + dictWord{5, 0, 468}, + dictWord{10, 0, 325}, + dictWord{11, 0, 856}, + dictWord{12, 0, 345}, + dictWord{143, 0, 104}, + dictWord{133, 0, 223}, + dictWord{132, 0, 566}, + dictWord{4, 11, 221}, + dictWord{5, 11, 659}, + dictWord{5, 11, 989}, + dictWord{7, 11, 697}, + dictWord{7, 11, 1211}, + dictWord{138, 11, 284}, + dictWord{135, 11, 1070}, + dictWord{4, 0, 59}, + dictWord{135, 0, 1394}, + dictWord{6, 0, 436}, + dictWord{11, 0, 481}, + dictWord{5, 10, 878}, + dictWord{133, 10, 972}, + dictWord{4, 0, 48}, + dictWord{5, 0, 271}, + dictWord{135, 0, 953}, + dictWord{5, 0, 610}, + dictWord{136, 0, 457}, + dictWord{ + 4, + 0, + 773, + }, + dictWord{5, 0, 618}, + dictWord{137, 0, 756}, + dictWord{133, 0, 755}, + dictWord{135, 0, 1217}, + dictWord{138, 11, 507}, + dictWord{132, 10, 351}, + dictWord{132, 0, 197}, + dictWord{143, 11, 78}, + dictWord{4, 11, 188}, + dictWord{7, 11, 805}, + dictWord{11, 11, 276}, + dictWord{142, 11, 293}, + dictWord{ + 5, + 11, + 884, + }, + dictWord{139, 11, 991}, + dictWord{132, 10, 286}, + dictWord{10, 0, 259}, + dictWord{10, 0, 428}, + dictWord{7, 10, 438}, + dictWord{7, 10, 627}, + dictWord{ + 7, + 10, + 1516, + }, + dictWord{8, 10, 40}, + dictWord{9, 10, 56}, + dictWord{9, 10, 294}, + dictWord{11, 10, 969}, + dictWord{11, 10, 995}, + dictWord{146, 10, 148}, + dictWord{ + 4, + 0, + 356, + }, + dictWord{5, 0, 217}, + dictWord{5, 0, 492}, + dictWord{5, 0, 656}, + dictWord{8, 0, 544}, + dictWord{136, 11, 544}, + dictWord{5, 0, 259}, + dictWord{6, 0, 1230}, + dictWord{7, 0, 414}, + dictWord{7, 0, 854}, + dictWord{142, 0, 107}, + dictWord{132, 0, 1007}, + dictWord{15, 0, 14}, + dictWord{144, 0, 5}, + dictWord{6, 0, 1580}, + dictWord{ + 132, + 10, + 738, + }, + dictWord{132, 11, 596}, + dictWord{132, 0, 673}, + dictWord{133, 10, 866}, + dictWord{6, 0, 1843}, + dictWord{135, 11, 1847}, + dictWord{4, 0, 165}, + dictWord{7, 0, 1398}, + dictWord{135, 0, 1829}, + dictWord{135, 11, 1634}, + dictWord{147, 11, 65}, + dictWord{6, 0, 885}, + dictWord{6, 0, 1009}, + dictWord{ + 137, + 0, + 809, + }, + dictWord{133, 10, 116}, + dictWord{132, 10, 457}, + dictWord{136, 11, 770}, + dictWord{9, 0, 498}, + dictWord{12, 0, 181}, + dictWord{10, 11, 361}, + dictWord{142, 11, 316}, + dictWord{134, 11, 595}, + dictWord{5, 0, 9}, + dictWord{7, 0, 297}, + dictWord{7, 0, 966}, + dictWord{140, 0, 306}, + dictWord{4, 11, 89}, + dictWord{ + 5, + 11, + 489, + }, + dictWord{6, 11, 315}, + dictWord{7, 11, 553}, + dictWord{7, 11, 1745}, + dictWord{138, 11, 243}, + dictWord{134, 0, 1487}, + dictWord{132, 0, 437}, + dictWord{ + 5, + 0, + 146, + }, + dictWord{6, 0, 411}, + dictWord{138, 0, 721}, + dictWord{5, 10, 527}, + dictWord{6, 10, 189}, + dictWord{135, 10, 859}, + dictWord{11, 10, 104}, + dictWord{ + 11, + 10, + 554, + }, + dictWord{15, 10, 60}, + dictWord{143, 10, 125}, + dictWord{6, 11, 1658}, + dictWord{9, 11, 3}, + dictWord{10, 11, 154}, + dictWord{11, 11, 641}, + dictWord{13, 11, 85}, + dictWord{13, 11, 201}, + dictWord{141, 11, 346}, + dictWord{6, 0, 177}, + dictWord{135, 0, 467}, + dictWord{134, 0, 1377}, + dictWord{ + 134, + 10, + 116, + }, + dictWord{136, 11, 645}, + dictWord{4, 11, 166}, + dictWord{5, 11, 505}, + dictWord{6, 11, 1670}, + dictWord{137, 11, 110}, + dictWord{133, 10, 487}, + dictWord{ + 4, + 10, + 86, + }, + dictWord{5, 10, 667}, + dictWord{5, 10, 753}, + dictWord{6, 10, 316}, + dictWord{6, 10, 455}, + dictWord{135, 10, 946}, + dictWord{133, 0, 200}, + dictWord{132, 0, 959}, + dictWord{6, 0, 1928}, + dictWord{134, 0, 1957}, + dictWord{139, 11, 203}, + dictWord{150, 10, 45}, + dictWord{4, 10, 79}, + dictWord{7, 10, 1773}, + dictWord{10, 10, 450}, + dictWord{11, 10, 589}, + dictWord{13, 10, 332}, + dictWord{13, 10, 493}, + dictWord{14, 10, 183}, + dictWord{14, 10, 334}, + dictWord{ + 14, + 10, + 362, + }, + dictWord{14, 10, 368}, + dictWord{14, 10, 376}, + dictWord{14, 10, 379}, + dictWord{19, 10, 90}, + dictWord{19, 10, 103}, + dictWord{19, 10, 127}, + dictWord{148, 10, 90}, + dictWord{6, 0, 1435}, + dictWord{135, 11, 1275}, + dictWord{134, 0, 481}, + dictWord{7, 11, 445}, + dictWord{8, 11, 307}, + dictWord{8, 11, 704}, + dictWord{10, 11, 41}, + dictWord{10, 11, 439}, + dictWord{11, 11, 237}, + dictWord{11, 11, 622}, + dictWord{140, 11, 201}, + dictWord{135, 11, 869}, + dictWord{ + 4, + 0, + 84, + }, + dictWord{7, 0, 1482}, + dictWord{10, 0, 76}, + dictWord{138, 0, 142}, + dictWord{11, 11, 277}, + dictWord{144, 11, 14}, + dictWord{135, 11, 1977}, + dictWord{ + 4, + 11, + 189, + }, + dictWord{5, 11, 713}, + dictWord{136, 11, 57}, + dictWord{133, 0, 1015}, + dictWord{138, 11, 371}, + dictWord{4, 0, 315}, + dictWord{5, 0, 507}, + dictWord{ + 135, + 0, + 1370, + }, + dictWord{4, 11, 552}, + dictWord{142, 10, 381}, + dictWord{9, 0, 759}, + dictWord{16, 0, 31}, + dictWord{16, 0, 39}, + dictWord{16, 0, 75}, + dictWord{18, 0, 24}, + dictWord{20, 0, 42}, + dictWord{152, 0, 1}, + dictWord{134, 0, 712}, + dictWord{134, 0, 1722}, + dictWord{133, 10, 663}, + dictWord{133, 10, 846}, + dictWord{ + 8, + 0, + 222, + }, + dictWord{8, 0, 476}, + dictWord{9, 0, 238}, + dictWord{11, 0, 516}, + dictWord{11, 0, 575}, + dictWord{15, 0, 109}, + dictWord{146, 0, 100}, + dictWord{7, 0, 1402}, + dictWord{7, 0, 1414}, + dictWord{12, 0, 456}, + dictWord{5, 10, 378}, + dictWord{8, 10, 465}, + dictWord{9, 10, 286}, + dictWord{10, 10, 185}, + dictWord{10, 10, 562}, + dictWord{10, 10, 635}, + dictWord{11, 10, 31}, + dictWord{11, 10, 393}, + dictWord{13, 10, 312}, + dictWord{18, 10, 65}, + dictWord{18, 10, 96}, + dictWord{147, 10, 89}, + dictWord{4, 0, 986}, + dictWord{6, 0, 1958}, + dictWord{6, 0, 2032}, + dictWord{8, 0, 934}, + dictWord{138, 0, 985}, + dictWord{7, 10, 1880}, + dictWord{9, 10, 680}, + dictWord{139, 10, 798}, + dictWord{134, 10, 1770}, + dictWord{145, 11, 49}, + dictWord{132, 11, 614}, + dictWord{132, 10, 648}, + dictWord{5, 10, 945}, + dictWord{ + 6, + 10, + 1656, + }, + dictWord{6, 10, 1787}, + dictWord{7, 10, 167}, + dictWord{8, 10, 824}, + dictWord{9, 10, 391}, + dictWord{10, 10, 375}, + dictWord{139, 10, 185}, + dictWord{138, 11, 661}, + dictWord{7, 0, 1273}, + dictWord{135, 11, 1945}, + dictWord{7, 0, 706}, + dictWord{7, 0, 1058}, + dictWord{138, 0, 538}, + dictWord{7, 10, 1645}, + dictWord{8, 10, 352}, + dictWord{137, 10, 249}, + dictWord{132, 10, 152}, + dictWord{11, 0, 92}, + dictWord{11, 0, 196}, + dictWord{11, 0, 409}, + dictWord{11, 0, 450}, + dictWord{11, 0, 666}, + dictWord{11, 0, 777}, + dictWord{12, 0, 262}, + dictWord{13, 0, 385}, + dictWord{13, 0, 393}, + dictWord{15, 0, 115}, + dictWord{16, 0, 45}, + dictWord{145, 0, 82}, + dictWord{133, 10, 1006}, + dictWord{6, 0, 40}, + dictWord{135, 0, 1781}, + dictWord{9, 11, 614}, + dictWord{139, 11, 327}, + dictWord{5, 10, 420}, + dictWord{135, 10, 1449}, + dictWord{135, 0, 431}, + dictWord{10, 0, 97}, + dictWord{135, 10, 832}, + dictWord{6, 0, 423}, + dictWord{7, 0, 665}, + dictWord{ + 135, + 0, + 1210, + }, + dictWord{7, 0, 237}, + dictWord{8, 0, 664}, + dictWord{9, 0, 42}, + dictWord{9, 0, 266}, + dictWord{9, 0, 380}, + dictWord{9, 0, 645}, + dictWord{10, 0, 177}, + dictWord{ + 138, + 0, + 276, + }, + dictWord{7, 0, 264}, + dictWord{133, 10, 351}, + dictWord{8, 0, 213}, + dictWord{5, 10, 40}, + dictWord{7, 10, 598}, + dictWord{7, 10, 1638}, + dictWord{ + 9, + 10, + 166, + }, + dictWord{9, 10, 640}, + dictWord{9, 10, 685}, + dictWord{9, 10, 773}, + dictWord{11, 10, 215}, + dictWord{13, 10, 65}, + dictWord{14, 10, 172}, + dictWord{ + 14, + 10, + 317, + }, + dictWord{145, 10, 6}, + dictWord{5, 11, 84}, + dictWord{134, 11, 163}, + dictWord{8, 10, 60}, + dictWord{9, 10, 343}, + dictWord{139, 10, 769}, + dictWord{ + 137, + 0, + 455, + }, + dictWord{133, 11, 410}, + dictWord{8, 0, 906}, + dictWord{12, 0, 700}, + dictWord{12, 0, 706}, + dictWord{140, 0, 729}, + dictWord{21, 11, 33}, + dictWord{ + 150, + 11, + 40, + }, + dictWord{7, 10, 1951}, + dictWord{8, 10, 765}, + dictWord{8, 10, 772}, + dictWord{140, 10, 671}, + dictWord{7, 10, 108}, + dictWord{8, 10, 219}, + dictWord{ + 8, + 10, + 388, + }, + dictWord{9, 10, 639}, + dictWord{9, 10, 775}, + dictWord{11, 10, 275}, + dictWord{140, 10, 464}, + dictWord{5, 11, 322}, + dictWord{7, 11, 1941}, + dictWord{ + 8, + 11, + 186, + }, + dictWord{9, 11, 262}, + dictWord{10, 11, 187}, + dictWord{14, 11, 208}, + dictWord{146, 11, 130}, + dictWord{139, 0, 624}, + dictWord{8, 0, 574}, + dictWord{ + 5, + 11, + 227, + }, + dictWord{140, 11, 29}, + dictWord{7, 11, 1546}, + dictWord{11, 11, 299}, + dictWord{142, 11, 407}, + dictWord{5, 10, 15}, + dictWord{6, 10, 56}, + dictWord{ + 7, + 10, + 1758, + }, + dictWord{8, 10, 500}, + dictWord{9, 10, 730}, + dictWord{11, 10, 331}, + dictWord{13, 10, 150}, + dictWord{142, 10, 282}, + dictWord{7, 11, 1395}, + dictWord{8, 11, 486}, + dictWord{9, 11, 236}, + dictWord{9, 11, 878}, + dictWord{10, 11, 218}, + dictWord{11, 11, 95}, + dictWord{19, 11, 17}, + dictWord{147, 11, 31}, + dictWord{135, 11, 2043}, + dictWord{4, 0, 354}, + dictWord{146, 11, 4}, + dictWord{140, 11, 80}, + dictWord{135, 0, 1558}, + dictWord{134, 10, 1886}, + dictWord{ + 5, + 10, + 205, + }, + dictWord{6, 10, 438}, + dictWord{137, 10, 711}, + dictWord{133, 11, 522}, + dictWord{133, 10, 534}, + dictWord{7, 0, 235}, + dictWord{7, 0, 1475}, + dictWord{ + 15, + 0, + 68, + }, + dictWord{146, 0, 120}, + dictWord{137, 10, 691}, + dictWord{4, 0, 942}, + dictWord{6, 0, 1813}, + dictWord{8, 0, 917}, + dictWord{10, 0, 884}, + dictWord{ + 12, + 0, + 696, + }, + dictWord{12, 0, 717}, + dictWord{12, 0, 723}, + dictWord{12, 0, 738}, + dictWord{12, 0, 749}, + dictWord{12, 0, 780}, + dictWord{16, 0, 97}, + dictWord{146, 0, 169}, + dictWord{6, 10, 443}, + dictWord{8, 11, 562}, + dictWord{9, 10, 237}, + dictWord{9, 10, 571}, + dictWord{9, 10, 695}, + dictWord{10, 10, 139}, + dictWord{11, 10, 715}, + dictWord{12, 10, 417}, + dictWord{141, 10, 421}, + dictWord{135, 0, 957}, + dictWord{133, 0, 830}, + dictWord{134, 11, 1771}, + dictWord{146, 0, 23}, + dictWord{ + 5, + 0, + 496, + }, + dictWord{6, 0, 694}, + dictWord{7, 0, 203}, + dictWord{7, 11, 1190}, + dictWord{137, 11, 620}, + dictWord{137, 11, 132}, + dictWord{6, 0, 547}, + dictWord{ + 134, + 0, + 1549, + }, + dictWord{8, 11, 258}, + dictWord{9, 11, 208}, + dictWord{137, 11, 359}, + dictWord{4, 0, 864}, + dictWord{5, 0, 88}, + dictWord{137, 0, 239}, + dictWord{ + 135, + 11, + 493, + }, + dictWord{4, 11, 317}, + dictWord{135, 11, 1279}, + dictWord{132, 11, 477}, + dictWord{4, 10, 578}, + dictWord{5, 11, 63}, + dictWord{133, 11, 509}, + dictWord{ + 7, + 0, + 650, + }, + dictWord{135, 0, 1310}, + dictWord{7, 0, 1076}, + dictWord{9, 0, 80}, + dictWord{11, 0, 78}, + dictWord{11, 0, 421}, + dictWord{11, 0, 534}, + dictWord{ + 140, + 0, + 545, + }, + dictWord{132, 11, 288}, + dictWord{12, 0, 553}, + dictWord{14, 0, 118}, + dictWord{133, 10, 923}, + dictWord{7, 0, 274}, + dictWord{11, 0, 479}, + dictWord{ + 139, + 0, + 507, + }, + dictWord{8, 11, 89}, + dictWord{8, 11, 620}, + dictWord{9, 11, 49}, + dictWord{10, 11, 774}, + dictWord{11, 11, 628}, + dictWord{12, 11, 322}, + dictWord{ + 143, + 11, + 124, + }, + dictWord{4, 0, 497}, + dictWord{135, 0, 1584}, + dictWord{7, 0, 261}, + dictWord{7, 0, 1115}, + dictWord{7, 0, 1354}, + dictWord{7, 0, 1404}, + dictWord{ + 7, + 0, + 1588, + }, + dictWord{7, 0, 1705}, + dictWord{7, 0, 1902}, + dictWord{9, 0, 465}, + dictWord{10, 0, 248}, + dictWord{10, 0, 349}, + dictWord{10, 0, 647}, + dictWord{11, 0, 527}, + dictWord{11, 0, 660}, + dictWord{11, 0, 669}, + dictWord{12, 0, 529}, + dictWord{13, 0, 305}, + dictWord{132, 10, 924}, + dictWord{133, 10, 665}, + dictWord{ + 136, + 0, + 13, + }, + dictWord{6, 0, 791}, + dictWord{138, 11, 120}, + dictWord{7, 0, 642}, + dictWord{8, 0, 250}, + dictWord{11, 0, 123}, + dictWord{11, 0, 137}, + dictWord{13, 0, 48}, + dictWord{142, 0, 95}, + dictWord{4, 10, 265}, + dictWord{7, 10, 807}, + dictWord{135, 10, 950}, + dictWord{5, 10, 93}, + dictWord{140, 10, 267}, + dictWord{135, 0, 1429}, + dictWord{4, 0, 949}, + dictWord{10, 0, 885}, + dictWord{10, 0, 891}, + dictWord{10, 0, 900}, + dictWord{10, 0, 939}, + dictWord{12, 0, 760}, + dictWord{142, 0, 449}, + dictWord{139, 11, 366}, + dictWord{132, 0, 818}, + dictWord{134, 11, 85}, + dictWord{135, 10, 994}, + dictWord{7, 0, 330}, + dictWord{5, 10, 233}, + dictWord{5, 10, 320}, + dictWord{6, 10, 140}, + dictWord{136, 10, 295}, + dictWord{4, 0, 1004}, + dictWord{8, 0, 982}, + dictWord{136, 0, 993}, + dictWord{133, 10, 978}, + dictWord{4, 10, 905}, + dictWord{6, 10, 1701}, + dictWord{137, 10, 843}, + dictWord{10, 0, 545}, + dictWord{140, 0, 301}, + dictWord{6, 0, 947}, + dictWord{134, 0, 1062}, + dictWord{ + 134, + 0, + 1188, + }, + dictWord{4, 0, 904}, + dictWord{5, 0, 794}, + dictWord{152, 10, 6}, + dictWord{134, 0, 1372}, + dictWord{135, 11, 608}, + dictWord{5, 11, 279}, + dictWord{ + 6, + 11, + 235, + }, + dictWord{7, 11, 468}, + dictWord{8, 11, 446}, + dictWord{9, 11, 637}, + dictWord{10, 11, 717}, + dictWord{11, 11, 738}, + dictWord{140, 11, 514}, + dictWord{ + 132, + 10, + 509, + }, + dictWord{5, 11, 17}, + dictWord{6, 11, 371}, + dictWord{137, 11, 528}, + dictWord{132, 0, 693}, + dictWord{4, 11, 115}, + dictWord{5, 11, 669}, + dictWord{ + 6, + 11, + 407, + }, + dictWord{8, 11, 311}, + dictWord{11, 11, 10}, + dictWord{141, 11, 5}, + dictWord{11, 0, 377}, + dictWord{7, 10, 273}, + dictWord{137, 11, 381}, + dictWord{ + 135, + 0, + 695, + }, + dictWord{7, 0, 386}, + dictWord{138, 0, 713}, + dictWord{135, 10, 1041}, + dictWord{134, 0, 1291}, + dictWord{6, 0, 7}, + dictWord{6, 0, 35}, + dictWord{ + 7, + 0, + 147, + }, + dictWord{7, 0, 1069}, + dictWord{7, 0, 1568}, + dictWord{7, 0, 1575}, + dictWord{7, 0, 1917}, + dictWord{8, 0, 43}, + dictWord{8, 0, 208}, + dictWord{9, 0, 128}, + dictWord{ + 9, + 0, + 866, + }, + dictWord{10, 0, 20}, + dictWord{11, 0, 981}, + dictWord{147, 0, 33}, + dictWord{7, 0, 893}, + dictWord{141, 0, 424}, + dictWord{139, 10, 234}, + dictWord{ + 150, + 11, + 56, + }, + dictWord{5, 11, 779}, + dictWord{5, 11, 807}, + dictWord{6, 11, 1655}, + dictWord{134, 11, 1676}, + dictWord{5, 10, 802}, + dictWord{7, 10, 2021}, + dictWord{136, 10, 805}, + dictWord{4, 11, 196}, + dictWord{5, 10, 167}, + dictWord{5, 11, 558}, + dictWord{5, 10, 899}, + dictWord{5, 11, 949}, + dictWord{6, 10, 410}, + dictWord{137, 10, 777}, + dictWord{137, 10, 789}, + dictWord{134, 10, 1705}, + dictWord{8, 0, 904}, + dictWord{140, 0, 787}, + dictWord{6, 0, 322}, + dictWord{9, 0, 552}, + dictWord{11, 0, 274}, + dictWord{13, 0, 209}, + dictWord{13, 0, 499}, + dictWord{14, 0, 85}, + dictWord{15, 0, 126}, + dictWord{145, 0, 70}, + dictWord{135, 10, 10}, + dictWord{ + 5, + 10, + 11, + }, + dictWord{6, 10, 117}, + dictWord{6, 10, 485}, + dictWord{7, 10, 1133}, + dictWord{9, 10, 582}, + dictWord{9, 10, 594}, + dictWord{11, 10, 21}, + dictWord{ + 11, + 10, + 818, + }, + dictWord{12, 10, 535}, + dictWord{141, 10, 86}, + dictWord{4, 10, 264}, + dictWord{7, 10, 1067}, + dictWord{8, 10, 204}, + dictWord{8, 10, 385}, + dictWord{139, 10, 953}, + dictWord{132, 11, 752}, + dictWord{138, 10, 56}, + dictWord{133, 10, 470}, + dictWord{6, 0, 1808}, + dictWord{8, 0, 83}, + dictWord{8, 0, 742}, + dictWord{8, 0, 817}, + dictWord{9, 0, 28}, + dictWord{9, 0, 29}, + dictWord{9, 0, 885}, + dictWord{10, 0, 387}, + dictWord{11, 0, 633}, + dictWord{11, 0, 740}, + dictWord{13, 0, 235}, + dictWord{13, 0, 254}, + dictWord{15, 0, 143}, + dictWord{143, 0, 146}, + dictWord{140, 0, 49}, + dictWord{134, 0, 1832}, + dictWord{4, 11, 227}, + dictWord{5, 11, 159}, + dictWord{5, 11, 409}, + dictWord{7, 11, 80}, + dictWord{10, 11, 294}, + dictWord{10, 11, 479}, + dictWord{12, 11, 418}, + dictWord{14, 11, 50}, + dictWord{14, 11, 249}, + dictWord{142, 11, 295}, + dictWord{7, 11, 1470}, + dictWord{8, 11, 66}, + dictWord{8, 11, 137}, + dictWord{8, 11, 761}, + dictWord{9, 11, 638}, + dictWord{11, 11, 80}, + dictWord{11, 11, 212}, + dictWord{11, 11, 368}, + dictWord{11, 11, 418}, + dictWord{12, 11, 8}, + dictWord{13, 11, 15}, + dictWord{16, 11, 61}, + dictWord{17, 11, 59}, + dictWord{19, 11, 28}, + dictWord{148, 11, 84}, + dictWord{139, 10, 1015}, + dictWord{138, 11, 468}, + dictWord{135, 0, 421}, + dictWord{6, 0, 415}, + dictWord{ + 7, + 0, + 1049, + }, + dictWord{137, 0, 442}, + dictWord{6, 11, 38}, + dictWord{7, 11, 1220}, + dictWord{8, 11, 185}, + dictWord{8, 11, 256}, + dictWord{9, 11, 22}, + dictWord{ + 9, + 11, + 331, + }, + dictWord{10, 11, 738}, + dictWord{11, 11, 205}, + dictWord{11, 11, 540}, + dictWord{11, 11, 746}, + dictWord{13, 11, 399}, + dictWord{13, 11, 465}, + dictWord{ + 14, + 11, + 88, + }, + dictWord{142, 11, 194}, + dictWord{139, 0, 289}, + dictWord{133, 10, 715}, + dictWord{4, 0, 110}, + dictWord{10, 0, 415}, + dictWord{10, 0, 597}, + dictWord{142, 0, 206}, + dictWord{4, 11, 159}, + dictWord{6, 11, 115}, + dictWord{7, 11, 252}, + dictWord{7, 11, 257}, + dictWord{7, 11, 1928}, + dictWord{8, 11, 69}, + dictWord{ + 9, + 11, + 384, + }, + dictWord{10, 11, 91}, + dictWord{10, 11, 615}, + dictWord{12, 11, 375}, + dictWord{14, 11, 235}, + dictWord{18, 11, 117}, + dictWord{147, 11, 123}, + dictWord{5, 11, 911}, + dictWord{136, 11, 278}, + dictWord{7, 0, 205}, + dictWord{7, 0, 2000}, + dictWord{8, 10, 794}, + dictWord{9, 10, 400}, + dictWord{10, 10, 298}, + dictWord{142, 10, 228}, + dictWord{135, 11, 1774}, + dictWord{4, 11, 151}, + dictWord{7, 11, 1567}, + dictWord{8, 11, 351}, + dictWord{137, 11, 322}, + dictWord{ + 136, + 10, + 724, + }, + dictWord{133, 11, 990}, + dictWord{7, 0, 1539}, + dictWord{11, 0, 512}, + dictWord{13, 0, 205}, + dictWord{19, 0, 30}, + dictWord{22, 0, 36}, + dictWord{23, 0, 19}, + dictWord{135, 11, 1539}, + dictWord{5, 11, 194}, + dictWord{7, 11, 1662}, + dictWord{9, 11, 90}, + dictWord{140, 11, 180}, + dictWord{6, 10, 190}, + dictWord{ + 7, + 10, + 768, + }, + dictWord{135, 10, 1170}, + dictWord{134, 0, 1340}, + dictWord{4, 0, 283}, + dictWord{135, 0, 1194}, + dictWord{133, 11, 425}, + dictWord{133, 11, 971}, + dictWord{12, 0, 549}, + dictWord{14, 10, 67}, + dictWord{147, 10, 60}, + dictWord{135, 10, 1023}, + dictWord{134, 0, 1720}, + dictWord{138, 11, 587}, + dictWord{ + 5, + 11, + 72, + }, + dictWord{6, 11, 264}, + dictWord{7, 11, 21}, + dictWord{7, 11, 46}, + dictWord{7, 11, 2013}, + dictWord{8, 11, 215}, + dictWord{8, 11, 513}, + dictWord{10, 11, 266}, + dictWord{139, 11, 22}, + dictWord{5, 0, 319}, + dictWord{135, 0, 534}, + dictWord{6, 10, 137}, + dictWord{9, 10, 75}, + dictWord{9, 10, 253}, + dictWord{10, 10, 194}, + dictWord{138, 10, 444}, + dictWord{7, 0, 1180}, + dictWord{20, 0, 112}, + dictWord{6, 11, 239}, + dictWord{7, 11, 118}, + dictWord{10, 11, 95}, + dictWord{11, 11, 603}, + dictWord{13, 11, 443}, + dictWord{14, 11, 160}, + dictWord{143, 11, 4}, + dictWord{134, 11, 431}, + dictWord{5, 11, 874}, + dictWord{6, 11, 1677}, + dictWord{ + 11, + 10, + 643, + }, + dictWord{12, 10, 115}, + dictWord{143, 11, 0}, + dictWord{134, 0, 967}, + dictWord{6, 11, 65}, + dictWord{7, 11, 939}, + dictWord{7, 11, 1172}, + dictWord{ + 7, + 11, + 1671, + }, + dictWord{9, 11, 540}, + dictWord{10, 11, 696}, + dictWord{11, 11, 265}, + dictWord{11, 11, 732}, + dictWord{11, 11, 928}, + dictWord{11, 11, 937}, + dictWord{ + 12, + 11, + 399, + }, + dictWord{13, 11, 438}, + dictWord{149, 11, 19}, + dictWord{137, 11, 200}, + dictWord{135, 0, 1940}, + dictWord{5, 10, 760}, + dictWord{7, 10, 542}, + dictWord{8, 10, 135}, + dictWord{136, 10, 496}, + dictWord{140, 11, 44}, + dictWord{7, 11, 1655}, + dictWord{136, 11, 305}, + dictWord{7, 10, 319}, + dictWord{ + 7, + 10, + 355, + }, + dictWord{7, 10, 763}, + dictWord{10, 10, 389}, + dictWord{145, 10, 43}, + dictWord{136, 0, 735}, + dictWord{138, 10, 786}, + dictWord{137, 11, 19}, + dictWord{132, 11, 696}, + dictWord{5, 0, 132}, + dictWord{9, 0, 486}, + dictWord{9, 0, 715}, + dictWord{10, 0, 458}, + dictWord{11, 0, 373}, + dictWord{11, 0, 668}, + dictWord{ + 11, + 0, + 795, + }, + dictWord{11, 0, 897}, + dictWord{12, 0, 272}, + dictWord{12, 0, 424}, + dictWord{12, 0, 539}, + dictWord{12, 0, 558}, + dictWord{14, 0, 245}, + dictWord{ + 14, + 0, + 263, + }, + dictWord{14, 0, 264}, + dictWord{14, 0, 393}, + dictWord{142, 0, 403}, + dictWord{10, 0, 38}, + dictWord{139, 0, 784}, + dictWord{132, 0, 838}, + dictWord{ + 4, + 11, + 302, + }, + dictWord{135, 11, 1766}, + dictWord{133, 0, 379}, + dictWord{5, 0, 8}, + dictWord{6, 0, 89}, + dictWord{6, 0, 400}, + dictWord{7, 0, 1569}, + dictWord{7, 0, 1623}, + dictWord{7, 0, 1850}, + dictWord{8, 0, 218}, + dictWord{8, 0, 422}, + dictWord{9, 0, 570}, + dictWord{10, 0, 626}, + dictWord{4, 11, 726}, + dictWord{133, 11, 630}, + dictWord{ + 4, + 0, + 1017, + }, + dictWord{138, 0, 660}, + dictWord{6, 0, 387}, + dictWord{7, 0, 882}, + dictWord{141, 0, 111}, + dictWord{6, 0, 224}, + dictWord{7, 0, 877}, + dictWord{ + 137, + 0, + 647, + }, + dictWord{4, 10, 58}, + dictWord{5, 10, 286}, + dictWord{6, 10, 319}, + dictWord{7, 10, 402}, + dictWord{7, 10, 1254}, + dictWord{7, 10, 1903}, + dictWord{ + 8, + 10, + 356, + }, + dictWord{140, 10, 408}, + dictWord{135, 0, 790}, + dictWord{9, 0, 510}, + dictWord{10, 0, 53}, + dictWord{4, 10, 389}, + dictWord{9, 10, 181}, + dictWord{ + 10, + 10, + 29, + }, + dictWord{10, 10, 816}, + dictWord{11, 10, 311}, + dictWord{11, 10, 561}, + dictWord{12, 10, 67}, + dictWord{141, 10, 181}, + dictWord{142, 0, 458}, + dictWord{ + 6, + 11, + 118, + }, + dictWord{7, 11, 215}, + dictWord{7, 11, 1521}, + dictWord{140, 11, 11}, + dictWord{134, 0, 954}, + dictWord{135, 0, 394}, + dictWord{134, 0, 1367}, + dictWord{5, 11, 225}, + dictWord{133, 10, 373}, + dictWord{132, 0, 882}, + dictWord{7, 0, 1409}, + dictWord{135, 10, 1972}, + dictWord{135, 10, 1793}, + dictWord{ + 4, + 11, + 370, + }, + dictWord{5, 11, 756}, + dictWord{135, 11, 1326}, + dictWord{150, 11, 13}, + dictWord{7, 11, 354}, + dictWord{10, 11, 410}, + dictWord{139, 11, 815}, + dictWord{6, 11, 1662}, + dictWord{7, 11, 48}, + dictWord{8, 11, 771}, + dictWord{10, 11, 116}, + dictWord{13, 11, 104}, + dictWord{14, 11, 105}, + dictWord{14, 11, 184}, + dictWord{15, 11, 168}, + dictWord{19, 11, 92}, + dictWord{148, 11, 68}, + dictWord{7, 0, 124}, + dictWord{136, 0, 38}, + dictWord{5, 0, 261}, + dictWord{7, 0, 78}, + dictWord{ + 7, + 0, + 199, + }, + dictWord{8, 0, 815}, + dictWord{9, 0, 126}, + dictWord{10, 0, 342}, + dictWord{140, 0, 647}, + dictWord{4, 0, 628}, + dictWord{140, 0, 724}, + dictWord{7, 0, 266}, + dictWord{8, 0, 804}, + dictWord{7, 10, 1651}, + dictWord{145, 10, 89}, + dictWord{135, 0, 208}, + dictWord{134, 0, 1178}, + dictWord{6, 0, 79}, + dictWord{135, 0, 1519}, + dictWord{132, 10, 672}, + dictWord{133, 10, 737}, + dictWord{136, 0, 741}, + dictWord{132, 11, 120}, + dictWord{4, 0, 710}, + dictWord{6, 0, 376}, + dictWord{ + 134, + 0, + 606, + }, + dictWord{134, 0, 1347}, + dictWord{134, 0, 1494}, + dictWord{6, 0, 850}, + dictWord{6, 0, 1553}, + dictWord{137, 0, 821}, + dictWord{5, 10, 145}, + dictWord{ + 134, + 11, + 593, + }, + dictWord{7, 0, 1311}, + dictWord{140, 0, 135}, + dictWord{4, 0, 467}, + dictWord{5, 0, 405}, + dictWord{134, 0, 544}, + dictWord{5, 11, 820}, + dictWord{ + 135, + 11, + 931, + }, + dictWord{6, 0, 100}, + dictWord{7, 0, 244}, + dictWord{7, 0, 632}, + dictWord{7, 0, 1609}, + dictWord{8, 0, 178}, + dictWord{8, 0, 638}, + dictWord{141, 0, 58}, + dictWord{4, 10, 387}, + dictWord{135, 10, 1288}, + dictWord{6, 11, 151}, + dictWord{6, 11, 1675}, + dictWord{7, 11, 383}, + dictWord{151, 11, 10}, + dictWord{ + 132, + 0, + 481, + }, + dictWord{135, 10, 550}, + dictWord{134, 0, 1378}, + dictWord{6, 11, 1624}, + dictWord{11, 11, 11}, + dictWord{12, 11, 422}, + dictWord{13, 11, 262}, + dictWord{142, 11, 360}, + dictWord{133, 0, 791}, + dictWord{4, 11, 43}, + dictWord{5, 11, 344}, + dictWord{133, 11, 357}, + dictWord{7, 0, 1227}, + dictWord{140, 0, 978}, + dictWord{7, 0, 686}, + dictWord{8, 0, 33}, + dictWord{8, 0, 238}, + dictWord{10, 0, 616}, + dictWord{11, 0, 467}, + dictWord{11, 0, 881}, + dictWord{13, 0, 217}, + dictWord{ + 13, + 0, + 253, + }, + dictWord{142, 0, 268}, + dictWord{137, 0, 857}, + dictWord{8, 0, 467}, + dictWord{8, 0, 1006}, + dictWord{7, 11, 148}, + dictWord{8, 11, 284}, + dictWord{ + 141, + 11, + 63, + }, + dictWord{4, 10, 576}, + dictWord{135, 10, 1263}, + dictWord{133, 11, 888}, + dictWord{5, 10, 919}, + dictWord{134, 10, 1673}, + dictWord{20, 10, 37}, + dictWord{148, 11, 37}, + dictWord{132, 0, 447}, + dictWord{132, 11, 711}, + dictWord{4, 0, 128}, + dictWord{5, 0, 415}, + dictWord{6, 0, 462}, + dictWord{7, 0, 294}, + dictWord{ + 7, + 0, + 578, + }, + dictWord{10, 0, 710}, + dictWord{139, 0, 86}, + dictWord{4, 10, 82}, + dictWord{5, 10, 333}, + dictWord{5, 10, 904}, + dictWord{6, 10, 207}, + dictWord{7, 10, 325}, + dictWord{7, 10, 1726}, + dictWord{8, 10, 101}, + dictWord{10, 10, 778}, + dictWord{139, 10, 220}, + dictWord{136, 0, 587}, + dictWord{137, 11, 440}, + dictWord{ + 133, + 10, + 903, + }, + dictWord{6, 0, 427}, + dictWord{7, 0, 1018}, + dictWord{138, 0, 692}, + dictWord{4, 0, 195}, + dictWord{135, 0, 802}, + dictWord{140, 10, 147}, + dictWord{ + 134, + 0, + 1546, + }, + dictWord{134, 0, 684}, + dictWord{132, 10, 705}, + dictWord{136, 0, 345}, + dictWord{11, 11, 678}, + dictWord{140, 11, 307}, + dictWord{ + 133, + 0, + 365, + }, + dictWord{134, 0, 1683}, + dictWord{4, 11, 65}, + dictWord{5, 11, 479}, + dictWord{5, 11, 1004}, + dictWord{7, 11, 1913}, + dictWord{8, 11, 317}, + dictWord{ + 9, + 11, + 302, + }, + dictWord{10, 11, 612}, + dictWord{141, 11, 22}, + dictWord{138, 0, 472}, + dictWord{4, 11, 261}, + dictWord{135, 11, 510}, + dictWord{134, 10, 90}, + dictWord{142, 0, 433}, + dictWord{151, 0, 28}, + dictWord{4, 11, 291}, + dictWord{7, 11, 101}, + dictWord{9, 11, 515}, + dictWord{12, 11, 152}, + dictWord{12, 11, 443}, + dictWord{13, 11, 392}, + dictWord{142, 11, 357}, + dictWord{140, 0, 997}, + dictWord{5, 0, 3}, + dictWord{8, 0, 578}, + dictWord{9, 0, 118}, + dictWord{10, 0, 705}, + dictWord{ + 141, + 0, + 279, + }, + dictWord{135, 11, 1266}, + dictWord{7, 10, 813}, + dictWord{12, 10, 497}, + dictWord{141, 10, 56}, + dictWord{133, 0, 229}, + dictWord{6, 10, 125}, + dictWord{135, 10, 1277}, + dictWord{8, 0, 102}, + dictWord{10, 0, 578}, + dictWord{10, 0, 672}, + dictWord{12, 0, 496}, + dictWord{13, 0, 408}, + dictWord{14, 0, 121}, + dictWord{17, 0, 106}, + dictWord{151, 10, 12}, + dictWord{6, 0, 866}, + dictWord{134, 0, 1080}, + dictWord{136, 0, 1022}, + dictWord{4, 11, 130}, + dictWord{135, 11, 843}, + dictWord{5, 11, 42}, + dictWord{5, 11, 879}, + dictWord{7, 11, 245}, + dictWord{7, 11, 324}, + dictWord{7, 11, 1532}, + dictWord{11, 11, 463}, + dictWord{11, 11, 472}, + dictWord{13, 11, 363}, + dictWord{144, 11, 52}, + dictWord{150, 0, 55}, + dictWord{8, 0, 115}, + dictWord{8, 0, 350}, + dictWord{9, 0, 489}, + dictWord{10, 0, 128}, + dictWord{ + 11, + 0, + 306, + }, + dictWord{12, 0, 373}, + dictWord{14, 0, 30}, + dictWord{17, 0, 79}, + dictWord{19, 0, 80}, + dictWord{4, 11, 134}, + dictWord{133, 11, 372}, + dictWord{ + 134, + 0, + 657, + }, + dictWord{134, 0, 933}, + dictWord{135, 11, 1147}, + dictWord{4, 0, 230}, + dictWord{133, 0, 702}, + dictWord{134, 0, 1728}, + dictWord{4, 0, 484}, + dictWord{ + 18, + 0, + 26, + }, + dictWord{19, 0, 42}, + dictWord{20, 0, 43}, + dictWord{21, 0, 0}, + dictWord{23, 0, 27}, + dictWord{152, 0, 14}, + dictWord{7, 0, 185}, + dictWord{135, 0, 703}, + dictWord{ + 6, + 0, + 417, + }, + dictWord{10, 0, 618}, + dictWord{7, 10, 1106}, + dictWord{9, 10, 770}, + dictWord{11, 10, 112}, + dictWord{140, 10, 413}, + dictWord{134, 0, 803}, + dictWord{132, 11, 644}, + dictWord{134, 0, 1262}, + dictWord{7, 11, 540}, + dictWord{12, 10, 271}, + dictWord{145, 10, 109}, + dictWord{135, 11, 123}, + dictWord{ + 132, + 0, + 633, + }, + dictWord{134, 11, 623}, + dictWord{4, 11, 908}, + dictWord{5, 11, 359}, + dictWord{5, 11, 508}, + dictWord{6, 11, 1723}, + dictWord{7, 11, 343}, + dictWord{ + 7, + 11, + 1996, + }, + dictWord{135, 11, 2026}, + dictWord{135, 0, 479}, + dictWord{10, 0, 262}, + dictWord{7, 10, 304}, + dictWord{9, 10, 646}, + dictWord{9, 10, 862}, + dictWord{ + 11, + 10, + 696, + }, + dictWord{12, 10, 208}, + dictWord{15, 10, 79}, + dictWord{147, 10, 108}, + dictWord{4, 11, 341}, + dictWord{135, 11, 480}, + dictWord{134, 0, 830}, + dictWord{5, 0, 70}, + dictWord{5, 0, 622}, + dictWord{6, 0, 334}, + dictWord{7, 0, 1032}, + dictWord{9, 0, 171}, + dictWord{11, 0, 26}, + dictWord{11, 0, 213}, + dictWord{ + 11, + 0, + 637, + }, + dictWord{11, 0, 707}, + dictWord{12, 0, 202}, + dictWord{12, 0, 380}, + dictWord{13, 0, 226}, + dictWord{13, 0, 355}, + dictWord{14, 0, 222}, + dictWord{145, 0, 42}, + dictWord{135, 10, 981}, + dictWord{143, 0, 217}, + dictWord{137, 11, 114}, + dictWord{4, 0, 23}, + dictWord{4, 0, 141}, + dictWord{5, 0, 313}, + dictWord{5, 0, 1014}, + dictWord{6, 0, 50}, + dictWord{6, 0, 51}, + dictWord{7, 0, 142}, + dictWord{7, 0, 384}, + dictWord{7, 0, 559}, + dictWord{8, 0, 640}, + dictWord{9, 0, 460}, + dictWord{9, 0, 783}, + dictWord{11, 0, 741}, + dictWord{12, 0, 183}, + dictWord{141, 0, 488}, + dictWord{141, 0, 360}, + dictWord{7, 0, 1586}, + dictWord{7, 11, 1995}, + dictWord{8, 11, 299}, + dictWord{11, 11, 890}, + dictWord{140, 11, 674}, + dictWord{132, 10, 434}, + dictWord{7, 0, 652}, + dictWord{134, 10, 550}, + dictWord{7, 0, 766}, + dictWord{5, 10, 553}, + dictWord{138, 10, 824}, + dictWord{7, 0, 737}, + dictWord{8, 0, 298}, + dictWord{136, 10, 452}, + dictWord{4, 11, 238}, + dictWord{5, 11, 503}, + dictWord{6, 11, 179}, + dictWord{7, 11, 2003}, + dictWord{8, 11, 381}, + dictWord{8, 11, 473}, + dictWord{9, 11, 149}, + dictWord{10, 11, 183}, + dictWord{15, 11, 45}, + dictWord{143, 11, 86}, + dictWord{133, 10, 292}, + dictWord{5, 0, 222}, + dictWord{9, 0, 655}, + dictWord{138, 0, 534}, + dictWord{138, 10, 135}, + dictWord{4, 11, 121}, + dictWord{5, 11, 156}, + dictWord{5, 11, 349}, + dictWord{9, 11, 136}, + dictWord{10, 11, 605}, + dictWord{14, 11, 342}, + dictWord{147, 11, 107}, + dictWord{137, 0, 906}, + dictWord{6, 0, 1013}, + dictWord{134, 0, 1250}, + dictWord{6, 0, 1956}, + dictWord{6, 0, 2009}, + dictWord{8, 0, 991}, + dictWord{144, 0, 120}, + dictWord{135, 11, 1192}, + dictWord{ + 138, + 0, + 503, + }, + dictWord{5, 0, 154}, + dictWord{7, 0, 1491}, + dictWord{10, 0, 379}, + dictWord{138, 0, 485}, + dictWord{6, 0, 1867}, + dictWord{6, 0, 1914}, + dictWord{6, 0, 1925}, + dictWord{9, 0, 917}, + dictWord{9, 0, 925}, + dictWord{9, 0, 932}, + dictWord{9, 0, 951}, + dictWord{9, 0, 1007}, + dictWord{9, 0, 1013}, + dictWord{12, 0, 806}, + dictWord{ + 12, + 0, + 810, + }, + dictWord{12, 0, 814}, + dictWord{12, 0, 816}, + dictWord{12, 0, 824}, + dictWord{12, 0, 832}, + dictWord{12, 0, 837}, + dictWord{12, 0, 863}, + dictWord{ + 12, + 0, + 868, + }, + dictWord{12, 0, 870}, + dictWord{12, 0, 889}, + dictWord{12, 0, 892}, + dictWord{12, 0, 900}, + dictWord{12, 0, 902}, + dictWord{12, 0, 908}, + dictWord{12, 0, 933}, + dictWord{12, 0, 942}, + dictWord{12, 0, 949}, + dictWord{12, 0, 954}, + dictWord{15, 0, 175}, + dictWord{15, 0, 203}, + dictWord{15, 0, 213}, + dictWord{15, 0, 218}, + dictWord{15, 0, 225}, + dictWord{15, 0, 231}, + dictWord{15, 0, 239}, + dictWord{15, 0, 248}, + dictWord{15, 0, 252}, + dictWord{18, 0, 190}, + dictWord{18, 0, 204}, + dictWord{ + 18, + 0, + 215, + }, + dictWord{18, 0, 216}, + dictWord{18, 0, 222}, + dictWord{18, 0, 225}, + dictWord{18, 0, 230}, + dictWord{18, 0, 239}, + dictWord{18, 0, 241}, + dictWord{ + 21, + 0, + 42, + }, + dictWord{21, 0, 43}, + dictWord{21, 0, 44}, + dictWord{21, 0, 45}, + dictWord{21, 0, 46}, + dictWord{21, 0, 53}, + dictWord{24, 0, 27}, + dictWord{152, 0, 31}, + dictWord{ + 133, + 0, + 716, + }, + dictWord{135, 0, 844}, + dictWord{4, 0, 91}, + dictWord{5, 0, 388}, + dictWord{5, 0, 845}, + dictWord{6, 0, 206}, + dictWord{6, 0, 252}, + dictWord{6, 0, 365}, + dictWord{ + 7, + 0, + 136, + }, + dictWord{7, 0, 531}, + dictWord{136, 0, 621}, + dictWord{7, 10, 393}, + dictWord{10, 10, 603}, + dictWord{139, 10, 206}, + dictWord{6, 11, 80}, + dictWord{ + 6, + 11, + 1694, + }, + dictWord{7, 11, 173}, + dictWord{7, 11, 1974}, + dictWord{9, 11, 547}, + dictWord{10, 11, 730}, + dictWord{14, 11, 18}, + dictWord{150, 11, 39}, + dictWord{137, 0, 748}, + dictWord{4, 11, 923}, + dictWord{134, 11, 1711}, + dictWord{4, 10, 912}, + dictWord{137, 10, 232}, + dictWord{7, 10, 98}, + dictWord{7, 10, 1973}, + dictWord{136, 10, 716}, + dictWord{14, 0, 103}, + dictWord{133, 10, 733}, + dictWord{132, 11, 595}, + dictWord{12, 0, 158}, + dictWord{18, 0, 8}, + dictWord{19, 0, 62}, + dictWord{20, 0, 6}, + dictWord{22, 0, 4}, + dictWord{23, 0, 2}, + dictWord{23, 0, 9}, + dictWord{5, 11, 240}, + dictWord{6, 11, 459}, + dictWord{7, 11, 12}, + dictWord{7, 11, 114}, + dictWord{7, 11, 502}, + dictWord{7, 11, 1751}, + dictWord{7, 11, 1753}, + dictWord{7, 11, 1805}, + dictWord{8, 11, 658}, + dictWord{9, 11, 1}, + dictWord{11, 11, 959}, + dictWord{13, 11, 446}, + dictWord{142, 11, 211}, + dictWord{135, 0, 576}, + dictWord{5, 0, 771}, + dictWord{5, 0, 863}, + dictWord{5, 0, 898}, + dictWord{6, 0, 648}, + dictWord{ + 6, + 0, + 1632, + }, + dictWord{6, 0, 1644}, + dictWord{134, 0, 1780}, + dictWord{133, 0, 331}, + dictWord{7, 11, 633}, + dictWord{7, 11, 905}, + dictWord{7, 11, 909}, + dictWord{ + 7, + 11, + 1538, + }, + dictWord{9, 11, 767}, + dictWord{140, 11, 636}, + dictWord{140, 0, 632}, + dictWord{5, 0, 107}, + dictWord{7, 0, 201}, + dictWord{136, 0, 518}, + dictWord{ + 6, + 0, + 446, + }, + dictWord{7, 0, 1817}, + dictWord{134, 11, 490}, + dictWord{9, 0, 851}, + dictWord{141, 0, 510}, + dictWord{7, 11, 250}, + dictWord{8, 11, 506}, + dictWord{ + 136, + 11, + 507, + }, + dictWord{4, 0, 504}, + dictWord{137, 10, 72}, + dictWord{132, 11, 158}, + dictWord{4, 11, 140}, + dictWord{7, 11, 362}, + dictWord{8, 11, 209}, + dictWord{ + 9, + 11, + 10, + }, + dictWord{9, 11, 160}, + dictWord{9, 11, 503}, + dictWord{10, 11, 689}, + dictWord{11, 11, 350}, + dictWord{11, 11, 553}, + dictWord{11, 11, 725}, + dictWord{ + 12, + 11, + 252, + }, + dictWord{12, 11, 583}, + dictWord{13, 11, 192}, + dictWord{13, 11, 352}, + dictWord{14, 11, 269}, + dictWord{14, 11, 356}, + dictWord{148, 11, 50}, + dictWord{6, 11, 597}, + dictWord{135, 11, 1318}, + dictWord{135, 10, 1454}, + dictWord{5, 0, 883}, + dictWord{5, 0, 975}, + dictWord{8, 0, 392}, + dictWord{148, 0, 7}, + dictWord{6, 11, 228}, + dictWord{7, 11, 1341}, + dictWord{9, 11, 408}, + dictWord{138, 11, 343}, + dictWord{11, 11, 348}, + dictWord{11, 10, 600}, + dictWord{12, 11, 99}, + dictWord{13, 10, 245}, + dictWord{18, 11, 1}, + dictWord{18, 11, 11}, + dictWord{147, 11, 4}, + dictWord{134, 11, 296}, + dictWord{5, 0, 922}, + dictWord{134, 0, 1707}, + dictWord{132, 11, 557}, + dictWord{4, 11, 548}, + dictWord{7, 10, 164}, + dictWord{7, 10, 1571}, + dictWord{9, 10, 107}, + dictWord{140, 10, 225}, + dictWord{ + 7, + 11, + 197, + }, + dictWord{8, 11, 142}, + dictWord{8, 11, 325}, + dictWord{9, 11, 150}, + dictWord{9, 11, 596}, + dictWord{10, 11, 350}, + dictWord{10, 11, 353}, + dictWord{ + 11, + 11, + 74, + }, + dictWord{11, 11, 315}, + dictWord{14, 11, 423}, + dictWord{143, 11, 141}, + dictWord{5, 0, 993}, + dictWord{7, 0, 515}, + dictWord{137, 0, 91}, + dictWord{4, 0, 131}, + dictWord{8, 0, 200}, + dictWord{5, 10, 484}, + dictWord{5, 10, 510}, + dictWord{6, 10, 434}, + dictWord{7, 10, 1000}, + dictWord{7, 10, 1098}, + dictWord{136, 10, 2}, + dictWord{152, 0, 10}, + dictWord{4, 11, 62}, + dictWord{5, 11, 83}, + dictWord{6, 11, 399}, + dictWord{6, 11, 579}, + dictWord{7, 11, 692}, + dictWord{7, 11, 846}, + dictWord{ + 7, + 11, + 1015, + }, + dictWord{7, 11, 1799}, + dictWord{8, 11, 403}, + dictWord{9, 11, 394}, + dictWord{10, 11, 133}, + dictWord{12, 11, 4}, + dictWord{12, 11, 297}, + dictWord{ + 12, + 11, + 452, + }, + dictWord{16, 11, 81}, + dictWord{18, 11, 19}, + dictWord{18, 11, 25}, + dictWord{21, 11, 14}, + dictWord{22, 11, 12}, + dictWord{151, 11, 18}, + dictWord{ + 140, + 11, + 459, + }, + dictWord{132, 11, 177}, + dictWord{7, 0, 1433}, + dictWord{9, 0, 365}, + dictWord{137, 11, 365}, + dictWord{132, 10, 460}, + dictWord{5, 0, 103}, + dictWord{ + 6, + 0, + 2004, + }, + dictWord{7, 0, 921}, + dictWord{8, 0, 580}, + dictWord{8, 0, 593}, + dictWord{8, 0, 630}, + dictWord{10, 0, 28}, + dictWord{5, 11, 411}, + dictWord{ + 135, + 11, + 653, + }, + dictWord{4, 10, 932}, + dictWord{133, 10, 891}, + dictWord{4, 0, 911}, + dictWord{5, 0, 867}, + dictWord{5, 0, 1013}, + dictWord{7, 0, 2034}, + dictWord{8, 0, 798}, + dictWord{136, 0, 813}, + dictWord{7, 11, 439}, + dictWord{10, 11, 727}, + dictWord{11, 11, 260}, + dictWord{139, 11, 684}, + dictWord{136, 10, 625}, + dictWord{ + 5, + 11, + 208, + }, + dictWord{7, 11, 753}, + dictWord{135, 11, 1528}, + dictWord{5, 0, 461}, + dictWord{7, 0, 1925}, + dictWord{12, 0, 39}, + dictWord{13, 0, 265}, + dictWord{ + 13, + 0, + 439, + }, + dictWord{134, 10, 76}, + dictWord{6, 0, 853}, + dictWord{8, 10, 92}, + dictWord{137, 10, 221}, + dictWord{5, 0, 135}, + dictWord{6, 0, 519}, + dictWord{7, 0, 1722}, + dictWord{10, 0, 271}, + dictWord{11, 0, 261}, + dictWord{145, 0, 54}, + dictWord{139, 11, 814}, + dictWord{14, 0, 338}, + dictWord{148, 0, 81}, + dictWord{4, 0, 300}, + dictWord{133, 0, 436}, + dictWord{5, 0, 419}, + dictWord{5, 0, 687}, + dictWord{7, 0, 864}, + dictWord{9, 0, 470}, + dictWord{135, 11, 864}, + dictWord{9, 0, 836}, + dictWord{ + 133, + 11, + 242, + }, + dictWord{134, 0, 1937}, + dictWord{4, 10, 763}, + dictWord{133, 11, 953}, + dictWord{132, 10, 622}, + dictWord{132, 0, 393}, + dictWord{ + 133, + 10, + 253, + }, + dictWord{8, 0, 357}, + dictWord{10, 0, 745}, + dictWord{14, 0, 426}, + dictWord{17, 0, 94}, + dictWord{19, 0, 57}, + dictWord{135, 10, 546}, + dictWord{5, 11, 615}, + dictWord{146, 11, 37}, + dictWord{9, 10, 73}, + dictWord{10, 10, 110}, + dictWord{14, 10, 185}, + dictWord{145, 10, 119}, + dictWord{11, 0, 703}, + dictWord{7, 10, 624}, + dictWord{7, 10, 916}, + dictWord{10, 10, 256}, + dictWord{139, 10, 87}, + dictWord{133, 11, 290}, + dictWord{5, 10, 212}, + dictWord{12, 10, 35}, + dictWord{ + 141, + 10, + 382, + }, + dictWord{132, 11, 380}, + dictWord{5, 11, 52}, + dictWord{7, 11, 277}, + dictWord{9, 11, 368}, + dictWord{139, 11, 791}, + dictWord{133, 0, 387}, + dictWord{ + 10, + 11, + 138, + }, + dictWord{139, 11, 476}, + dictWord{4, 0, 6}, + dictWord{5, 0, 708}, + dictWord{136, 0, 75}, + dictWord{7, 0, 1351}, + dictWord{9, 0, 581}, + dictWord{10, 0, 639}, + dictWord{11, 0, 453}, + dictWord{140, 0, 584}, + dictWord{132, 0, 303}, + dictWord{138, 0, 772}, + dictWord{135, 10, 1175}, + dictWord{4, 0, 749}, + dictWord{ + 5, + 10, + 816, + }, + dictWord{6, 11, 256}, + dictWord{7, 11, 307}, + dictWord{7, 11, 999}, + dictWord{7, 11, 1481}, + dictWord{7, 11, 1732}, + dictWord{7, 11, 1738}, + dictWord{ + 8, + 11, + 265, + }, + dictWord{9, 11, 414}, + dictWord{11, 11, 316}, + dictWord{12, 11, 52}, + dictWord{13, 11, 420}, + dictWord{147, 11, 100}, + dictWord{135, 11, 1296}, + dictWord{ + 6, + 0, + 1065, + }, + dictWord{5, 10, 869}, + dictWord{5, 10, 968}, + dictWord{6, 10, 1626}, + dictWord{8, 10, 734}, + dictWord{136, 10, 784}, + dictWord{4, 10, 542}, + dictWord{ + 6, + 10, + 1716, + }, + dictWord{6, 10, 1727}, + dictWord{7, 10, 1082}, + dictWord{7, 10, 1545}, + dictWord{8, 10, 56}, + dictWord{8, 10, 118}, + dictWord{8, 10, 412}, + dictWord{ + 8, + 10, + 564, + }, + dictWord{9, 10, 888}, + dictWord{9, 10, 908}, + dictWord{10, 10, 50}, + dictWord{10, 10, 423}, + dictWord{11, 10, 685}, + dictWord{11, 10, 697}, + dictWord{11, 10, 933}, + dictWord{12, 10, 299}, + dictWord{13, 10, 126}, + dictWord{13, 10, 136}, + dictWord{13, 10, 170}, + dictWord{141, 10, 190}, + dictWord{ + 134, + 0, + 226, + }, + dictWord{4, 0, 106}, + dictWord{7, 0, 310}, + dictWord{11, 0, 717}, + dictWord{133, 11, 723}, + dictWord{5, 0, 890}, + dictWord{5, 0, 988}, + dictWord{4, 10, 232}, + dictWord{9, 10, 202}, + dictWord{10, 10, 474}, + dictWord{140, 10, 433}, + dictWord{6, 0, 626}, + dictWord{142, 0, 431}, + dictWord{10, 0, 706}, + dictWord{150, 0, 44}, + dictWord{13, 0, 51}, + dictWord{6, 10, 108}, + dictWord{7, 10, 1003}, + dictWord{7, 10, 1181}, + dictWord{8, 10, 111}, + dictWord{136, 10, 343}, + dictWord{132, 0, 698}, + dictWord{5, 11, 109}, + dictWord{6, 11, 1784}, + dictWord{7, 11, 1895}, + dictWord{12, 11, 296}, + dictWord{140, 11, 302}, + dictWord{134, 0, 828}, + dictWord{ + 134, + 10, + 1712, + }, + dictWord{138, 0, 17}, + dictWord{7, 0, 1929}, + dictWord{4, 10, 133}, + dictWord{5, 11, 216}, + dictWord{7, 10, 711}, + dictWord{7, 10, 1298}, + dictWord{ + 7, + 10, + 1585, + }, + dictWord{7, 11, 1879}, + dictWord{9, 11, 141}, + dictWord{9, 11, 270}, + dictWord{9, 11, 679}, + dictWord{10, 11, 159}, + dictWord{10, 11, 553}, + dictWord{ + 11, + 11, + 197, + }, + dictWord{11, 11, 438}, + dictWord{12, 11, 538}, + dictWord{12, 11, 559}, + dictWord{13, 11, 193}, + dictWord{13, 11, 423}, + dictWord{14, 11, 144}, + dictWord{14, 11, 166}, + dictWord{14, 11, 167}, + dictWord{15, 11, 67}, + dictWord{147, 11, 84}, + dictWord{141, 11, 127}, + dictWord{7, 11, 1872}, + dictWord{ + 137, + 11, + 81, + }, + dictWord{6, 10, 99}, + dictWord{7, 10, 1808}, + dictWord{145, 10, 57}, + dictWord{134, 11, 391}, + dictWord{5, 0, 689}, + dictWord{6, 0, 84}, + dictWord{7, 0, 1250}, + dictWord{6, 10, 574}, + dictWord{7, 10, 428}, + dictWord{10, 10, 669}, + dictWord{11, 10, 485}, + dictWord{11, 10, 840}, + dictWord{12, 10, 300}, + dictWord{ + 142, + 10, + 250, + }, + dictWord{7, 11, 322}, + dictWord{136, 11, 249}, + dictWord{7, 11, 432}, + dictWord{135, 11, 1649}, + dictWord{135, 10, 1871}, + dictWord{137, 10, 252}, + dictWord{6, 11, 155}, + dictWord{140, 11, 234}, + dictWord{7, 0, 871}, + dictWord{19, 0, 27}, + dictWord{147, 11, 27}, + dictWord{140, 0, 498}, + dictWord{5, 0, 986}, + dictWord{6, 0, 130}, + dictWord{138, 0, 823}, + dictWord{6, 0, 1793}, + dictWord{7, 0, 1582}, + dictWord{8, 0, 458}, + dictWord{10, 0, 101}, + dictWord{10, 0, 318}, + dictWord{ + 10, + 0, + 945, + }, + dictWord{12, 0, 734}, + dictWord{16, 0, 104}, + dictWord{18, 0, 177}, + dictWord{6, 10, 323}, + dictWord{135, 10, 1564}, + dictWord{5, 11, 632}, + dictWord{ + 138, + 11, + 526, + }, + dictWord{10, 0, 435}, + dictWord{7, 10, 461}, + dictWord{136, 10, 775}, + dictWord{6, 11, 144}, + dictWord{7, 11, 948}, + dictWord{7, 11, 1042}, + dictWord{ + 7, + 11, + 1857, + }, + dictWord{8, 11, 235}, + dictWord{8, 11, 461}, + dictWord{9, 11, 453}, + dictWord{9, 11, 530}, + dictWord{10, 11, 354}, + dictWord{17, 11, 77}, + dictWord{ + 19, + 11, + 99, + }, + dictWord{148, 11, 79}, + dictWord{138, 0, 966}, + dictWord{7, 0, 1644}, + dictWord{137, 0, 129}, + dictWord{135, 0, 997}, + dictWord{136, 0, 502}, + dictWord{ + 5, + 11, + 196, + }, + dictWord{6, 11, 486}, + dictWord{7, 11, 212}, + dictWord{8, 11, 309}, + dictWord{136, 11, 346}, + dictWord{7, 10, 727}, + dictWord{146, 10, 73}, + dictWord{132, 0, 823}, + dictWord{132, 11, 686}, + dictWord{135, 0, 1927}, + dictWord{4, 0, 762}, + dictWord{7, 0, 1756}, + dictWord{137, 0, 98}, + dictWord{136, 10, 577}, + dictWord{24, 0, 8}, + dictWord{4, 11, 30}, + dictWord{5, 11, 43}, + dictWord{152, 11, 8}, + dictWord{7, 0, 1046}, + dictWord{139, 0, 160}, + dictWord{7, 0, 492}, + dictWord{ + 4, + 10, + 413, + }, + dictWord{5, 10, 677}, + dictWord{7, 11, 492}, + dictWord{8, 10, 432}, + dictWord{140, 10, 280}, + dictWord{6, 0, 45}, + dictWord{7, 0, 433}, + dictWord{8, 0, 129}, + dictWord{9, 0, 21}, + dictWord{10, 0, 392}, + dictWord{11, 0, 79}, + dictWord{12, 0, 499}, + dictWord{13, 0, 199}, + dictWord{141, 0, 451}, + dictWord{7, 0, 558}, + dictWord{ + 136, + 0, + 353, + }, + dictWord{4, 11, 220}, + dictWord{7, 11, 1535}, + dictWord{9, 11, 93}, + dictWord{139, 11, 474}, + dictWord{7, 10, 646}, + dictWord{7, 10, 1730}, + dictWord{ + 11, + 10, + 446, + }, + dictWord{141, 10, 178}, + dictWord{133, 0, 785}, + dictWord{134, 0, 1145}, + dictWord{8, 0, 81}, + dictWord{9, 0, 189}, + dictWord{9, 0, 201}, + dictWord{ + 11, + 0, + 478, + }, + dictWord{11, 0, 712}, + dictWord{141, 0, 338}, + dictWord{5, 0, 353}, + dictWord{151, 0, 26}, + dictWord{11, 0, 762}, + dictWord{132, 10, 395}, + dictWord{ + 134, + 0, + 2024, + }, + dictWord{4, 0, 611}, + dictWord{133, 0, 606}, + dictWord{9, 10, 174}, + dictWord{10, 10, 164}, + dictWord{11, 10, 440}, + dictWord{11, 10, 841}, + dictWord{ + 143, + 10, + 98, + }, + dictWord{134, 10, 426}, + dictWord{10, 10, 608}, + dictWord{139, 10, 1002}, + dictWord{138, 10, 250}, + dictWord{6, 0, 25}, + dictWord{7, 0, 855}, + dictWord{7, 0, 1258}, + dictWord{144, 0, 32}, + dictWord{7, 11, 1725}, + dictWord{138, 11, 393}, + dictWord{5, 11, 263}, + dictWord{134, 11, 414}, + dictWord{6, 0, 2011}, + dictWord{133, 10, 476}, + dictWord{4, 0, 4}, + dictWord{7, 0, 1118}, + dictWord{7, 0, 1320}, + dictWord{7, 0, 1706}, + dictWord{8, 0, 277}, + dictWord{9, 0, 622}, + dictWord{ + 10, + 0, + 9, + }, + dictWord{11, 0, 724}, + dictWord{12, 0, 350}, + dictWord{12, 0, 397}, + dictWord{13, 0, 28}, + dictWord{13, 0, 159}, + dictWord{15, 0, 89}, + dictWord{18, 0, 5}, + dictWord{ + 19, + 0, + 9, + }, + dictWord{20, 0, 34}, + dictWord{22, 0, 47}, + dictWord{6, 11, 178}, + dictWord{6, 11, 1750}, + dictWord{8, 11, 251}, + dictWord{9, 11, 690}, + dictWord{ + 10, + 11, + 155, + }, + dictWord{10, 11, 196}, + dictWord{10, 11, 373}, + dictWord{11, 11, 698}, + dictWord{13, 11, 155}, + dictWord{148, 11, 93}, + dictWord{5, 11, 97}, + dictWord{ + 137, + 11, + 393, + }, + dictWord{7, 0, 764}, + dictWord{11, 0, 461}, + dictWord{12, 0, 172}, + dictWord{5, 10, 76}, + dictWord{6, 10, 458}, + dictWord{6, 10, 497}, + dictWord{ + 7, + 10, + 868, + }, + dictWord{9, 10, 658}, + dictWord{10, 10, 594}, + dictWord{11, 10, 566}, + dictWord{12, 10, 338}, + dictWord{141, 10, 200}, + dictWord{134, 0, 1449}, + dictWord{138, 11, 40}, + dictWord{134, 11, 1639}, + dictWord{134, 0, 1445}, + dictWord{6, 0, 1168}, + dictWord{4, 10, 526}, + dictWord{7, 10, 1029}, + dictWord{ + 135, + 10, + 1054, + }, + dictWord{4, 11, 191}, + dictWord{7, 11, 934}, + dictWord{8, 11, 647}, + dictWord{145, 11, 97}, + dictWord{132, 10, 636}, + dictWord{6, 0, 233}, + dictWord{ + 7, + 10, + 660, + }, + dictWord{7, 10, 1124}, + dictWord{17, 10, 31}, + dictWord{19, 10, 22}, + dictWord{151, 10, 14}, + dictWord{6, 10, 1699}, + dictWord{136, 11, 110}, + dictWord{ + 12, + 11, + 246, + }, + dictWord{15, 11, 162}, + dictWord{19, 11, 64}, + dictWord{20, 11, 8}, + dictWord{20, 11, 95}, + dictWord{22, 11, 24}, + dictWord{152, 11, 17}, + dictWord{ + 5, + 11, + 165, + }, + dictWord{9, 11, 346}, + dictWord{138, 11, 655}, + dictWord{5, 11, 319}, + dictWord{135, 11, 534}, + dictWord{134, 0, 255}, + dictWord{9, 0, 216}, + dictWord{ + 8, + 11, + 128, + }, + dictWord{139, 11, 179}, + dictWord{9, 0, 183}, + dictWord{139, 0, 286}, + dictWord{11, 0, 956}, + dictWord{151, 0, 3}, + dictWord{4, 0, 536}, + dictWord{ + 7, + 0, + 1141, + }, + dictWord{10, 0, 723}, + dictWord{139, 0, 371}, + dictWord{4, 10, 279}, + dictWord{7, 10, 301}, + dictWord{137, 10, 362}, + dictWord{7, 0, 285}, + dictWord{ + 5, + 11, + 57, + }, + dictWord{6, 11, 101}, + dictWord{6, 11, 1663}, + dictWord{7, 11, 132}, + dictWord{7, 11, 1048}, + dictWord{7, 11, 1154}, + dictWord{7, 11, 1415}, + dictWord{ + 7, + 11, + 1507, + }, + dictWord{12, 11, 493}, + dictWord{15, 11, 105}, + dictWord{151, 11, 15}, + dictWord{5, 11, 459}, + dictWord{7, 11, 1073}, + dictWord{7, 10, 1743}, + dictWord{ + 8, + 11, + 241, + }, + dictWord{136, 11, 334}, + dictWord{4, 10, 178}, + dictWord{133, 10, 399}, + dictWord{135, 0, 560}, + dictWord{132, 0, 690}, + dictWord{135, 0, 1246}, + dictWord{18, 0, 157}, + dictWord{147, 0, 63}, + dictWord{10, 0, 599}, + dictWord{11, 0, 33}, + dictWord{12, 0, 571}, + dictWord{149, 0, 1}, + dictWord{6, 11, 324}, + dictWord{ + 6, + 11, + 520, + }, + dictWord{7, 11, 338}, + dictWord{7, 11, 1616}, + dictWord{7, 11, 1729}, + dictWord{8, 11, 228}, + dictWord{9, 11, 69}, + dictWord{139, 11, 750}, + dictWord{ + 7, + 0, + 1862, + }, + dictWord{12, 0, 491}, + dictWord{12, 0, 520}, + dictWord{13, 0, 383}, + dictWord{142, 0, 244}, + dictWord{135, 11, 734}, + dictWord{134, 10, 1692}, + dictWord{10, 0, 448}, + dictWord{11, 0, 630}, + dictWord{17, 0, 117}, + dictWord{6, 10, 202}, + dictWord{7, 11, 705}, + dictWord{12, 10, 360}, + dictWord{17, 10, 118}, + dictWord{18, 10, 27}, + dictWord{148, 10, 67}, + dictWord{4, 11, 73}, + dictWord{6, 11, 612}, + dictWord{7, 11, 927}, + dictWord{7, 11, 1822}, + dictWord{8, 11, 217}, + dictWord{ + 9, + 11, + 472, + }, + dictWord{9, 11, 765}, + dictWord{9, 11, 766}, + dictWord{10, 11, 408}, + dictWord{11, 11, 51}, + dictWord{11, 11, 793}, + dictWord{12, 11, 266}, + dictWord{ + 15, + 11, + 158, + }, + dictWord{20, 11, 89}, + dictWord{150, 11, 32}, + dictWord{4, 0, 190}, + dictWord{133, 0, 554}, + dictWord{133, 0, 1001}, + dictWord{5, 11, 389}, + dictWord{ + 8, + 11, + 636, + }, + dictWord{137, 11, 229}, + dictWord{5, 0, 446}, + dictWord{7, 10, 872}, + dictWord{10, 10, 516}, + dictWord{139, 10, 167}, + dictWord{137, 10, 313}, + dictWord{132, 10, 224}, + dictWord{134, 0, 1313}, + dictWord{5, 10, 546}, + dictWord{7, 10, 35}, + dictWord{8, 10, 11}, + dictWord{8, 10, 12}, + dictWord{9, 10, 315}, + dictWord{9, 10, 533}, + dictWord{10, 10, 802}, + dictWord{11, 10, 166}, + dictWord{12, 10, 525}, + dictWord{142, 10, 243}, + dictWord{6, 0, 636}, + dictWord{137, 0, 837}, + dictWord{5, 10, 241}, + dictWord{8, 10, 242}, + dictWord{9, 10, 451}, + dictWord{10, 10, 667}, + dictWord{11, 10, 598}, + dictWord{140, 10, 429}, + dictWord{22, 10, 46}, + dictWord{150, 11, 46}, + dictWord{136, 11, 472}, + dictWord{11, 0, 278}, + dictWord{142, 0, 73}, + dictWord{141, 11, 185}, + dictWord{132, 0, 868}, + dictWord{ + 134, + 0, + 972, + }, + dictWord{4, 10, 366}, + dictWord{137, 10, 516}, + dictWord{138, 0, 1010}, + dictWord{5, 11, 189}, + dictWord{6, 10, 1736}, + dictWord{7, 11, 442}, + dictWord{ + 7, + 11, + 443, + }, + dictWord{8, 11, 281}, + dictWord{12, 11, 174}, + dictWord{13, 11, 83}, + dictWord{141, 11, 261}, + dictWord{139, 11, 384}, + dictWord{6, 11, 2}, + dictWord{ + 7, + 11, + 191, + }, + dictWord{7, 11, 446}, + dictWord{7, 11, 758}, + dictWord{7, 11, 1262}, + dictWord{7, 11, 1737}, + dictWord{8, 11, 22}, + dictWord{8, 11, 270}, + dictWord{ + 8, + 11, + 612, + }, + dictWord{9, 11, 4}, + dictWord{9, 11, 167}, + dictWord{9, 11, 312}, + dictWord{9, 11, 436}, + dictWord{10, 11, 156}, + dictWord{10, 11, 216}, + dictWord{ + 10, + 11, + 311, + }, + dictWord{10, 11, 623}, + dictWord{11, 11, 72}, + dictWord{11, 11, 330}, + dictWord{11, 11, 455}, + dictWord{12, 11, 101}, + dictWord{12, 11, 321}, + dictWord{ + 12, + 11, + 504, + }, + dictWord{12, 11, 530}, + dictWord{12, 11, 543}, + dictWord{13, 11, 17}, + dictWord{13, 11, 156}, + dictWord{13, 11, 334}, + dictWord{14, 11, 48}, + dictWord{15, 11, 70}, + dictWord{17, 11, 60}, + dictWord{148, 11, 64}, + dictWord{6, 10, 331}, + dictWord{136, 10, 623}, + dictWord{135, 0, 1231}, + dictWord{132, 0, 304}, + dictWord{6, 11, 60}, + dictWord{7, 11, 670}, + dictWord{7, 11, 1327}, + dictWord{8, 11, 411}, + dictWord{8, 11, 435}, + dictWord{9, 11, 653}, + dictWord{9, 11, 740}, + dictWord{10, 11, 385}, + dictWord{11, 11, 222}, + dictWord{11, 11, 324}, + dictWord{11, 11, 829}, + dictWord{140, 11, 611}, + dictWord{7, 0, 506}, + dictWord{6, 11, 166}, + dictWord{7, 11, 374}, + dictWord{135, 11, 1174}, + dictWord{14, 11, 43}, + dictWord{146, 11, 21}, + dictWord{135, 11, 1694}, + dictWord{135, 10, 1888}, + dictWord{ + 5, + 11, + 206, + }, + dictWord{134, 11, 398}, + dictWord{135, 11, 50}, + dictWord{150, 0, 26}, + dictWord{6, 0, 53}, + dictWord{6, 0, 199}, + dictWord{7, 0, 1408}, + dictWord{ + 8, + 0, + 32, + }, + dictWord{8, 0, 93}, + dictWord{10, 0, 397}, + dictWord{10, 0, 629}, + dictWord{11, 0, 593}, + dictWord{11, 0, 763}, + dictWord{13, 0, 326}, + dictWord{145, 0, 35}, + dictWord{134, 0, 105}, + dictWord{132, 10, 394}, + dictWord{4, 0, 843}, + dictWord{138, 0, 794}, + dictWord{11, 0, 704}, + dictWord{141, 0, 396}, + dictWord{5, 0, 114}, + dictWord{5, 0, 255}, + dictWord{141, 0, 285}, + dictWord{6, 0, 619}, + dictWord{7, 0, 898}, + dictWord{7, 0, 1092}, + dictWord{8, 0, 485}, + dictWord{18, 0, 28}, + dictWord{ + 19, + 0, + 116, + }, + dictWord{135, 10, 1931}, + dictWord{9, 0, 145}, + dictWord{7, 10, 574}, + dictWord{135, 10, 1719}, + dictWord{7, 0, 2035}, + dictWord{8, 0, 19}, + dictWord{ + 9, + 0, + 89, + }, + dictWord{138, 0, 831}, + dictWord{132, 10, 658}, + dictWord{6, 11, 517}, + dictWord{7, 11, 1159}, + dictWord{10, 11, 621}, + dictWord{139, 11, 192}, + dictWord{ + 7, + 0, + 1933, + }, + dictWord{7, 11, 1933}, + dictWord{9, 10, 781}, + dictWord{10, 10, 144}, + dictWord{11, 10, 385}, + dictWord{13, 10, 161}, + dictWord{13, 10, 228}, + dictWord{13, 10, 268}, + dictWord{148, 10, 107}, + dictWord{136, 10, 374}, + dictWord{10, 11, 223}, + dictWord{139, 11, 645}, + dictWord{135, 0, 1728}, + dictWord{ + 7, + 11, + 64, + }, + dictWord{7, 11, 289}, + dictWord{136, 11, 245}, + dictWord{4, 10, 344}, + dictWord{6, 10, 498}, + dictWord{139, 10, 323}, + dictWord{136, 0, 746}, + dictWord{ + 135, + 10, + 1063, + }, + dictWord{137, 10, 155}, + dictWord{4, 0, 987}, + dictWord{6, 0, 1964}, + dictWord{6, 0, 1974}, + dictWord{6, 0, 1990}, + dictWord{136, 0, 995}, + dictWord{133, 11, 609}, + dictWord{133, 10, 906}, + dictWord{134, 0, 1550}, + dictWord{134, 0, 874}, + dictWord{5, 11, 129}, + dictWord{6, 11, 61}, + dictWord{ + 135, + 11, + 947, + }, + dictWord{4, 0, 1018}, + dictWord{6, 0, 1938}, + dictWord{6, 0, 2021}, + dictWord{134, 0, 2039}, + dictWord{132, 0, 814}, + dictWord{11, 0, 126}, + dictWord{ + 139, + 0, + 287, + }, + dictWord{134, 0, 1264}, + dictWord{5, 0, 955}, + dictWord{136, 0, 814}, + dictWord{141, 11, 506}, + dictWord{132, 11, 314}, + dictWord{6, 0, 981}, + dictWord{139, 11, 1000}, + dictWord{5, 0, 56}, + dictWord{8, 0, 892}, + dictWord{8, 0, 915}, + dictWord{140, 0, 776}, + dictWord{148, 0, 100}, + dictWord{10, 0, 4}, + dictWord{ + 10, + 0, + 13, + }, + dictWord{11, 0, 638}, + dictWord{148, 0, 57}, + dictWord{148, 11, 74}, + dictWord{5, 0, 738}, + dictWord{132, 10, 616}, + dictWord{133, 11, 637}, + dictWord{ + 136, + 10, + 692, + }, + dictWord{133, 0, 758}, + dictWord{132, 10, 305}, + dictWord{137, 11, 590}, + dictWord{5, 11, 280}, + dictWord{135, 11, 1226}, + dictWord{ + 134, + 11, + 494, + }, + dictWord{135, 0, 1112}, + dictWord{133, 11, 281}, + dictWord{13, 0, 44}, + dictWord{14, 0, 214}, + dictWord{5, 10, 214}, + dictWord{7, 10, 603}, + dictWord{ + 8, + 10, + 611, + }, + dictWord{9, 10, 686}, + dictWord{10, 10, 88}, + dictWord{11, 10, 459}, + dictWord{11, 10, 496}, + dictWord{12, 10, 463}, + dictWord{140, 10, 590}, + dictWord{ + 139, + 0, + 328, + }, + dictWord{135, 11, 1064}, + dictWord{137, 0, 133}, + dictWord{7, 0, 168}, + dictWord{13, 0, 196}, + dictWord{141, 0, 237}, + dictWord{134, 10, 1703}, + dictWord{134, 0, 1152}, + dictWord{135, 0, 1245}, + dictWord{5, 0, 110}, + dictWord{6, 0, 169}, + dictWord{6, 0, 1702}, + dictWord{7, 0, 400}, + dictWord{8, 0, 538}, + dictWord{ + 9, + 0, + 184, + }, + dictWord{9, 0, 524}, + dictWord{140, 0, 218}, + dictWord{6, 0, 1816}, + dictWord{10, 0, 871}, + dictWord{12, 0, 769}, + dictWord{140, 0, 785}, + dictWord{ + 132, + 11, + 630, + }, + dictWord{7, 11, 33}, + dictWord{7, 11, 120}, + dictWord{8, 11, 489}, + dictWord{9, 11, 319}, + dictWord{10, 11, 820}, + dictWord{11, 11, 1004}, + dictWord{ + 12, + 11, + 379, + }, + dictWord{13, 11, 117}, + dictWord{13, 11, 412}, + dictWord{14, 11, 25}, + dictWord{15, 11, 52}, + dictWord{15, 11, 161}, + dictWord{16, 11, 47}, + dictWord{149, 11, 2}, + dictWord{6, 0, 133}, + dictWord{8, 0, 413}, + dictWord{9, 0, 353}, + dictWord{139, 0, 993}, + dictWord{145, 10, 19}, + dictWord{4, 11, 937}, + dictWord{ + 133, + 11, + 801, + }, + dictWord{134, 0, 978}, + dictWord{6, 0, 93}, + dictWord{6, 0, 1508}, + dictWord{7, 0, 1422}, + dictWord{7, 0, 1851}, + dictWord{8, 0, 673}, + dictWord{9, 0, 529}, + dictWord{140, 0, 43}, + dictWord{6, 0, 317}, + dictWord{10, 0, 512}, + dictWord{4, 10, 737}, + dictWord{11, 10, 294}, + dictWord{12, 10, 60}, + dictWord{12, 10, 437}, + dictWord{13, 10, 64}, + dictWord{13, 10, 380}, + dictWord{142, 10, 430}, + dictWord{9, 0, 371}, + dictWord{7, 11, 1591}, + dictWord{144, 11, 43}, + dictWord{6, 10, 1758}, + dictWord{8, 10, 520}, + dictWord{9, 10, 345}, + dictWord{9, 10, 403}, + dictWord{142, 10, 350}, + dictWord{5, 0, 526}, + dictWord{10, 10, 242}, + dictWord{ + 138, + 10, + 579, + }, + dictWord{9, 0, 25}, + dictWord{10, 0, 467}, + dictWord{138, 0, 559}, + dictWord{5, 10, 139}, + dictWord{7, 10, 1168}, + dictWord{138, 10, 539}, + dictWord{ + 4, + 0, + 335, + }, + dictWord{135, 0, 942}, + dictWord{140, 0, 754}, + dictWord{132, 11, 365}, + dictWord{11, 0, 182}, + dictWord{142, 0, 195}, + dictWord{142, 11, 29}, + dictWord{ + 5, + 11, + 7, + }, + dictWord{139, 11, 774}, + dictWord{4, 11, 746}, + dictWord{135, 11, 1090}, + dictWord{8, 0, 39}, + dictWord{10, 0, 773}, + dictWord{11, 0, 84}, + dictWord{ + 12, + 0, + 205, + }, + dictWord{142, 0, 1}, + dictWord{5, 0, 601}, + dictWord{5, 0, 870}, + dictWord{5, 11, 360}, + dictWord{136, 11, 237}, + dictWord{132, 0, 181}, + dictWord{ + 136, + 0, + 370, + }, + dictWord{134, 0, 1652}, + dictWord{8, 0, 358}, + dictWord{4, 10, 107}, + dictWord{7, 10, 613}, + dictWord{8, 10, 439}, + dictWord{8, 10, 504}, + dictWord{ + 9, + 10, + 501, + }, + dictWord{10, 10, 383}, + dictWord{139, 10, 477}, + dictWord{132, 10, 229}, + dictWord{137, 11, 785}, + dictWord{4, 0, 97}, + dictWord{5, 0, 147}, + dictWord{ + 6, + 0, + 286, + }, + dictWord{7, 0, 1362}, + dictWord{141, 0, 176}, + dictWord{6, 0, 537}, + dictWord{7, 0, 788}, + dictWord{7, 0, 1816}, + dictWord{132, 10, 903}, + dictWord{ + 140, + 10, + 71, + }, + dictWord{6, 0, 743}, + dictWord{134, 0, 1223}, + dictWord{6, 0, 375}, + dictWord{7, 0, 169}, + dictWord{7, 0, 254}, + dictWord{8, 0, 780}, + dictWord{135, 11, 1493}, + dictWord{7, 0, 1714}, + dictWord{4, 10, 47}, + dictWord{6, 10, 373}, + dictWord{7, 10, 452}, + dictWord{7, 10, 543}, + dictWord{7, 10, 1856}, + dictWord{9, 10, 6}, + dictWord{ + 11, + 10, + 257, + }, + dictWord{139, 10, 391}, + dictWord{6, 0, 896}, + dictWord{136, 0, 1003}, + dictWord{135, 0, 1447}, + dictWord{137, 11, 341}, + dictWord{5, 10, 980}, + dictWord{134, 10, 1754}, + dictWord{145, 11, 22}, + dictWord{4, 11, 277}, + dictWord{5, 11, 608}, + dictWord{6, 11, 493}, + dictWord{7, 11, 457}, + dictWord{ + 140, + 11, + 384, + }, + dictWord{7, 10, 536}, + dictWord{7, 10, 1331}, + dictWord{136, 10, 143}, + dictWord{140, 0, 744}, + dictWord{7, 11, 27}, + dictWord{135, 11, 316}, + dictWord{ + 18, + 0, + 126, + }, + dictWord{5, 10, 19}, + dictWord{134, 10, 533}, + dictWord{4, 0, 788}, + dictWord{11, 0, 41}, + dictWord{5, 11, 552}, + dictWord{5, 11, 586}, + dictWord{ + 5, + 11, + 676, + }, + dictWord{6, 11, 448}, + dictWord{8, 11, 244}, + dictWord{11, 11, 1}, + dictWord{11, 11, 41}, + dictWord{13, 11, 3}, + dictWord{16, 11, 54}, + dictWord{17, 11, 4}, + dictWord{146, 11, 13}, + dictWord{4, 0, 985}, + dictWord{6, 0, 1801}, + dictWord{4, 11, 401}, + dictWord{137, 11, 264}, + dictWord{5, 10, 395}, + dictWord{5, 10, 951}, + dictWord{134, 10, 1776}, + dictWord{5, 0, 629}, + dictWord{135, 0, 1549}, + dictWord{11, 10, 663}, + dictWord{12, 10, 210}, + dictWord{13, 10, 166}, + dictWord{ + 13, + 10, + 310, + }, + dictWord{14, 10, 373}, + dictWord{147, 10, 43}, + dictWord{9, 11, 543}, + dictWord{10, 11, 524}, + dictWord{11, 11, 30}, + dictWord{12, 11, 524}, + dictWord{ + 14, + 11, + 315, + }, + dictWord{16, 11, 18}, + dictWord{20, 11, 26}, + dictWord{148, 11, 65}, + dictWord{4, 11, 205}, + dictWord{5, 11, 623}, + dictWord{7, 11, 104}, + dictWord{ + 136, + 11, + 519, + }, + dictWord{5, 0, 293}, + dictWord{134, 0, 601}, + dictWord{7, 11, 579}, + dictWord{9, 11, 41}, + dictWord{9, 11, 244}, + dictWord{9, 11, 669}, + dictWord{ + 10, + 11, + 5, + }, + dictWord{11, 11, 861}, + dictWord{11, 11, 951}, + dictWord{139, 11, 980}, + dictWord{132, 11, 717}, + dictWord{132, 10, 695}, + dictWord{7, 10, 497}, + dictWord{ + 9, + 10, + 387, + }, + dictWord{147, 10, 81}, + dictWord{132, 0, 420}, + dictWord{142, 0, 37}, + dictWord{6, 0, 1134}, + dictWord{6, 0, 1900}, + dictWord{12, 0, 830}, + dictWord{ + 12, + 0, + 878, + }, + dictWord{12, 0, 894}, + dictWord{15, 0, 221}, + dictWord{143, 0, 245}, + dictWord{132, 11, 489}, + dictWord{7, 0, 1570}, + dictWord{140, 0, 542}, + dictWord{ + 8, + 0, + 933, + }, + dictWord{136, 0, 957}, + dictWord{6, 0, 1371}, + dictWord{7, 0, 31}, + dictWord{8, 0, 373}, + dictWord{5, 10, 284}, + dictWord{6, 10, 49}, + dictWord{6, 10, 350}, + dictWord{7, 10, 377}, + dictWord{7, 10, 1693}, + dictWord{8, 10, 678}, + dictWord{9, 10, 161}, + dictWord{9, 10, 585}, + dictWord{9, 10, 671}, + dictWord{9, 10, 839}, + dictWord{11, 10, 912}, + dictWord{141, 10, 427}, + dictWord{135, 11, 892}, + dictWord{4, 0, 325}, + dictWord{138, 0, 125}, + dictWord{139, 11, 47}, + dictWord{ + 132, + 10, + 597, + }, + dictWord{138, 0, 323}, + dictWord{6, 0, 1547}, + dictWord{7, 11, 1605}, + dictWord{9, 11, 473}, + dictWord{11, 11, 962}, + dictWord{146, 11, 139}, + dictWord{ + 139, + 10, + 908, + }, + dictWord{7, 11, 819}, + dictWord{9, 11, 26}, + dictWord{9, 11, 392}, + dictWord{10, 11, 152}, + dictWord{10, 11, 226}, + dictWord{11, 11, 19}, + dictWord{ + 12, + 11, + 276, + }, + dictWord{12, 11, 426}, + dictWord{12, 11, 589}, + dictWord{13, 11, 460}, + dictWord{15, 11, 97}, + dictWord{19, 11, 48}, + dictWord{148, 11, 104}, + dictWord{135, 11, 51}, + dictWord{4, 0, 718}, + dictWord{135, 0, 1216}, + dictWord{6, 0, 1896}, + dictWord{6, 0, 1905}, + dictWord{6, 0, 1912}, + dictWord{9, 0, 947}, + dictWord{ + 9, + 0, + 974, + }, + dictWord{12, 0, 809}, + dictWord{12, 0, 850}, + dictWord{12, 0, 858}, + dictWord{12, 0, 874}, + dictWord{12, 0, 887}, + dictWord{12, 0, 904}, + dictWord{ + 12, + 0, + 929, + }, + dictWord{12, 0, 948}, + dictWord{12, 0, 952}, + dictWord{15, 0, 198}, + dictWord{15, 0, 206}, + dictWord{15, 0, 220}, + dictWord{15, 0, 227}, + dictWord{15, 0, 247}, + dictWord{18, 0, 188}, + dictWord{21, 0, 48}, + dictWord{21, 0, 50}, + dictWord{24, 0, 25}, + dictWord{24, 0, 29}, + dictWord{7, 11, 761}, + dictWord{7, 11, 1051}, + dictWord{ + 137, + 11, + 545, + }, + dictWord{5, 0, 124}, + dictWord{5, 0, 144}, + dictWord{6, 0, 548}, + dictWord{7, 0, 15}, + dictWord{7, 0, 153}, + dictWord{137, 0, 629}, + dictWord{ + 135, + 11, + 606, + }, + dictWord{135, 10, 2014}, + dictWord{7, 10, 2007}, + dictWord{9, 11, 46}, + dictWord{9, 10, 101}, + dictWord{9, 10, 450}, + dictWord{10, 10, 66}, + dictWord{ + 10, + 10, + 842, + }, + dictWord{11, 10, 536}, + dictWord{140, 10, 587}, + dictWord{6, 0, 75}, + dictWord{7, 0, 1531}, + dictWord{8, 0, 416}, + dictWord{9, 0, 240}, + dictWord{9, 0, 275}, + dictWord{10, 0, 100}, + dictWord{11, 0, 658}, + dictWord{11, 0, 979}, + dictWord{12, 0, 86}, + dictWord{14, 0, 207}, + dictWord{15, 0, 20}, + dictWord{143, 0, 25}, + dictWord{ + 5, + 0, + 141, + }, + dictWord{5, 0, 915}, + dictWord{6, 0, 1783}, + dictWord{7, 0, 211}, + dictWord{7, 0, 698}, + dictWord{7, 0, 1353}, + dictWord{9, 0, 83}, + dictWord{9, 0, 281}, + dictWord{ + 10, + 0, + 376, + }, + dictWord{10, 0, 431}, + dictWord{11, 0, 543}, + dictWord{12, 0, 664}, + dictWord{13, 0, 280}, + dictWord{13, 0, 428}, + dictWord{14, 0, 61}, + dictWord{ + 14, + 0, + 128, + }, + dictWord{17, 0, 52}, + dictWord{145, 0, 81}, + dictWord{132, 11, 674}, + dictWord{135, 0, 533}, + dictWord{149, 0, 6}, + dictWord{132, 11, 770}, + dictWord{ + 133, + 0, + 538, + }, + dictWord{5, 11, 79}, + dictWord{7, 11, 1027}, + dictWord{7, 11, 1477}, + dictWord{139, 11, 52}, + dictWord{139, 10, 62}, + dictWord{4, 0, 338}, + dictWord{ + 133, + 0, + 400, + }, + dictWord{5, 11, 789}, + dictWord{134, 11, 195}, + dictWord{4, 11, 251}, + dictWord{4, 11, 688}, + dictWord{7, 11, 513}, + dictWord{7, 11, 1284}, + dictWord{ + 9, + 11, + 87, + }, + dictWord{138, 11, 365}, + dictWord{134, 10, 1766}, + dictWord{6, 0, 0}, + dictWord{7, 0, 84}, + dictWord{11, 0, 895}, + dictWord{145, 0, 11}, + dictWord{ + 139, + 0, + 892, + }, + dictWord{4, 0, 221}, + dictWord{5, 0, 659}, + dictWord{7, 0, 697}, + dictWord{7, 0, 1211}, + dictWord{138, 0, 284}, + dictWord{133, 0, 989}, + dictWord{ + 133, + 11, + 889, + }, + dictWord{4, 11, 160}, + dictWord{5, 11, 330}, + dictWord{7, 11, 1434}, + dictWord{136, 11, 174}, + dictWord{6, 10, 1665}, + dictWord{7, 10, 256}, + dictWord{ + 7, + 10, + 1388, + }, + dictWord{10, 10, 499}, + dictWord{139, 10, 670}, + dictWord{7, 0, 848}, + dictWord{4, 10, 22}, + dictWord{5, 10, 10}, + dictWord{136, 10, 97}, + dictWord{ + 138, + 0, + 507, + }, + dictWord{133, 10, 481}, + dictWord{4, 0, 188}, + dictWord{135, 0, 805}, + dictWord{5, 0, 884}, + dictWord{6, 0, 732}, + dictWord{139, 0, 991}, + dictWord{ + 135, + 11, + 968, + }, + dictWord{11, 11, 636}, + dictWord{15, 11, 145}, + dictWord{17, 11, 34}, + dictWord{19, 11, 50}, + dictWord{151, 11, 20}, + dictWord{7, 0, 959}, + dictWord{ + 16, + 0, + 60, + }, + dictWord{6, 10, 134}, + dictWord{7, 10, 437}, + dictWord{9, 10, 37}, + dictWord{14, 10, 285}, + dictWord{142, 10, 371}, + dictWord{7, 10, 486}, + dictWord{ + 8, + 10, + 155, + }, + dictWord{11, 10, 93}, + dictWord{140, 10, 164}, + dictWord{134, 0, 1653}, + dictWord{7, 0, 337}, + dictWord{133, 10, 591}, + dictWord{6, 0, 1989}, + dictWord{ + 8, + 0, + 922, + }, + dictWord{8, 0, 978}, + dictWord{133, 11, 374}, + dictWord{132, 0, 638}, + dictWord{138, 0, 500}, + dictWord{133, 11, 731}, + dictWord{5, 10, 380}, + dictWord{ + 5, + 10, + 650, + }, + dictWord{136, 10, 310}, + dictWord{138, 11, 381}, + dictWord{4, 10, 364}, + dictWord{7, 10, 1156}, + dictWord{7, 10, 1187}, + dictWord{137, 10, 409}, + dictWord{137, 11, 224}, + dictWord{140, 0, 166}, + dictWord{134, 10, 482}, + dictWord{4, 11, 626}, + dictWord{5, 11, 642}, + dictWord{6, 11, 425}, + dictWord{ + 10, + 11, + 202, + }, + dictWord{139, 11, 141}, + dictWord{4, 10, 781}, + dictWord{6, 10, 487}, + dictWord{7, 10, 926}, + dictWord{8, 10, 263}, + dictWord{139, 10, 500}, + dictWord{ + 135, + 0, + 418, + }, + dictWord{4, 10, 94}, + dictWord{135, 10, 1265}, + dictWord{136, 0, 760}, + dictWord{132, 10, 417}, + dictWord{136, 11, 835}, + dictWord{5, 10, 348}, + dictWord{134, 10, 522}, + dictWord{6, 0, 1277}, + dictWord{134, 0, 1538}, + dictWord{139, 11, 541}, + dictWord{135, 11, 1597}, + dictWord{5, 11, 384}, + dictWord{ + 8, + 11, + 455, + }, + dictWord{140, 11, 48}, + dictWord{136, 0, 770}, + dictWord{5, 11, 264}, + dictWord{134, 11, 184}, + dictWord{4, 0, 89}, + dictWord{5, 0, 489}, + dictWord{ + 6, + 0, + 315, + }, + dictWord{7, 0, 553}, + dictWord{7, 0, 1745}, + dictWord{138, 0, 243}, + dictWord{4, 10, 408}, + dictWord{4, 10, 741}, + dictWord{135, 10, 500}, + dictWord{ + 134, + 0, + 1396, + }, + dictWord{133, 0, 560}, + dictWord{6, 0, 1658}, + dictWord{9, 0, 3}, + dictWord{10, 0, 154}, + dictWord{11, 0, 641}, + dictWord{13, 0, 85}, + dictWord{13, 0, 201}, + dictWord{141, 0, 346}, + dictWord{135, 11, 1595}, + dictWord{5, 11, 633}, + dictWord{6, 11, 28}, + dictWord{7, 11, 219}, + dictWord{135, 11, 1323}, + dictWord{ + 9, + 11, + 769, + }, + dictWord{140, 11, 185}, + dictWord{135, 11, 785}, + dictWord{7, 11, 359}, + dictWord{8, 11, 243}, + dictWord{140, 11, 175}, + dictWord{138, 0, 586}, + dictWord{ + 7, + 0, + 1271, + }, + dictWord{134, 10, 73}, + dictWord{132, 11, 105}, + dictWord{4, 0, 166}, + dictWord{5, 0, 505}, + dictWord{134, 0, 1670}, + dictWord{133, 10, 576}, + dictWord{4, 11, 324}, + dictWord{138, 11, 104}, + dictWord{142, 10, 231}, + dictWord{6, 0, 637}, + dictWord{7, 10, 1264}, + dictWord{7, 10, 1678}, + dictWord{ + 11, + 10, + 945, + }, + dictWord{12, 10, 341}, + dictWord{12, 10, 471}, + dictWord{12, 10, 569}, + dictWord{23, 11, 21}, + dictWord{151, 11, 23}, + dictWord{8, 11, 559}, + dictWord{ + 141, + 11, + 109, + }, + dictWord{134, 0, 1947}, + dictWord{7, 0, 445}, + dictWord{8, 0, 307}, + dictWord{8, 0, 704}, + dictWord{10, 0, 41}, + dictWord{10, 0, 439}, + dictWord{ + 11, + 0, + 237, + }, + dictWord{11, 0, 622}, + dictWord{140, 0, 201}, + dictWord{135, 11, 963}, + dictWord{135, 0, 1977}, + dictWord{4, 0, 189}, + dictWord{5, 0, 713}, + dictWord{ + 136, + 0, + 57, + }, + dictWord{138, 0, 371}, + dictWord{135, 10, 538}, + dictWord{132, 0, 552}, + dictWord{6, 0, 883}, + dictWord{133, 10, 413}, + dictWord{6, 0, 923}, + dictWord{ + 132, + 11, + 758, + }, + dictWord{138, 11, 215}, + dictWord{136, 10, 495}, + dictWord{7, 10, 54}, + dictWord{8, 10, 312}, + dictWord{10, 10, 191}, + dictWord{10, 10, 614}, + dictWord{140, 10, 567}, + dictWord{7, 11, 351}, + dictWord{139, 11, 128}, + dictWord{7, 0, 875}, + dictWord{6, 10, 468}, + dictWord{7, 10, 1478}, + dictWord{8, 10, 530}, + dictWord{142, 10, 290}, + dictWord{135, 0, 1788}, + dictWord{17, 0, 49}, + dictWord{133, 11, 918}, + dictWord{12, 11, 398}, + dictWord{20, 11, 39}, + dictWord{ + 21, + 11, + 11, + }, + dictWord{150, 11, 41}, + dictWord{10, 0, 661}, + dictWord{6, 10, 484}, + dictWord{135, 10, 822}, + dictWord{135, 0, 1945}, + dictWord{134, 0, 794}, + dictWord{ + 137, + 10, + 900, + }, + dictWord{135, 10, 1335}, + dictWord{6, 10, 1724}, + dictWord{135, 10, 2022}, + dictWord{132, 11, 340}, + dictWord{134, 0, 1135}, + dictWord{ + 4, + 0, + 784, + }, + dictWord{133, 0, 745}, + dictWord{5, 0, 84}, + dictWord{134, 0, 163}, + dictWord{133, 0, 410}, + dictWord{4, 0, 976}, + dictWord{5, 11, 985}, + dictWord{7, 11, 509}, + dictWord{7, 11, 529}, + dictWord{145, 11, 96}, + dictWord{132, 10, 474}, + dictWord{134, 0, 703}, + dictWord{135, 11, 1919}, + dictWord{5, 0, 322}, + dictWord{ + 8, + 0, + 186, + }, + dictWord{9, 0, 262}, + dictWord{10, 0, 187}, + dictWord{142, 0, 208}, + dictWord{135, 10, 1504}, + dictWord{133, 0, 227}, + dictWord{9, 0, 560}, + dictWord{ + 13, + 0, + 208, + }, + dictWord{133, 10, 305}, + dictWord{132, 11, 247}, + dictWord{7, 0, 1395}, + dictWord{8, 0, 486}, + dictWord{9, 0, 236}, + dictWord{9, 0, 878}, + dictWord{ + 10, + 0, + 218, + }, + dictWord{11, 0, 95}, + dictWord{19, 0, 17}, + dictWord{147, 0, 31}, + dictWord{7, 0, 2043}, + dictWord{8, 0, 672}, + dictWord{141, 0, 448}, + dictWord{4, 11, 184}, + dictWord{5, 11, 390}, + dictWord{6, 11, 337}, + dictWord{7, 11, 23}, + dictWord{7, 11, 494}, + dictWord{7, 11, 618}, + dictWord{7, 11, 1456}, + dictWord{8, 11, 27}, + dictWord{ + 8, + 11, + 599, + }, + dictWord{10, 11, 153}, + dictWord{139, 11, 710}, + dictWord{135, 0, 466}, + dictWord{135, 10, 1236}, + dictWord{6, 0, 167}, + dictWord{7, 0, 186}, + dictWord{7, 0, 656}, + dictWord{10, 0, 643}, + dictWord{4, 10, 480}, + dictWord{6, 10, 302}, + dictWord{6, 10, 1642}, + dictWord{7, 10, 837}, + dictWord{7, 10, 1547}, + dictWord{ + 7, + 10, + 1657, + }, + dictWord{8, 10, 429}, + dictWord{9, 10, 228}, + dictWord{13, 10, 289}, + dictWord{13, 10, 343}, + dictWord{147, 10, 101}, + dictWord{134, 0, 1428}, + dictWord{134, 0, 1440}, + dictWord{5, 0, 412}, + dictWord{7, 10, 278}, + dictWord{10, 10, 739}, + dictWord{11, 10, 708}, + dictWord{141, 10, 348}, + dictWord{ + 134, + 0, + 1118, + }, + dictWord{136, 0, 562}, + dictWord{148, 11, 46}, + dictWord{9, 0, 316}, + dictWord{139, 0, 256}, + dictWord{134, 0, 1771}, + dictWord{135, 0, 1190}, + dictWord{137, 0, 132}, + dictWord{10, 11, 227}, + dictWord{11, 11, 497}, + dictWord{11, 11, 709}, + dictWord{140, 11, 415}, + dictWord{143, 0, 66}, + dictWord{6, 11, 360}, + dictWord{7, 11, 1664}, + dictWord{136, 11, 478}, + dictWord{144, 10, 28}, + dictWord{4, 0, 317}, + dictWord{135, 0, 1279}, + dictWord{5, 0, 63}, + dictWord{ + 133, + 0, + 509, + }, + dictWord{136, 11, 699}, + dictWord{145, 10, 36}, + dictWord{134, 0, 1475}, + dictWord{11, 11, 343}, + dictWord{142, 11, 127}, + dictWord{132, 11, 739}, + dictWord{132, 0, 288}, + dictWord{135, 11, 1757}, + dictWord{8, 0, 89}, + dictWord{8, 0, 620}, + dictWord{9, 0, 608}, + dictWord{11, 0, 628}, + dictWord{12, 0, 322}, + dictWord{143, 0, 124}, + dictWord{134, 0, 1225}, + dictWord{7, 0, 1189}, + dictWord{4, 11, 67}, + dictWord{5, 11, 422}, + dictWord{6, 10, 363}, + dictWord{7, 11, 1037}, + dictWord{7, 11, 1289}, + dictWord{7, 11, 1555}, + dictWord{7, 10, 1955}, + dictWord{8, 10, 725}, + dictWord{9, 11, 741}, + dictWord{145, 11, 108}, + dictWord{ + 134, + 0, + 1468, + }, + dictWord{6, 0, 689}, + dictWord{134, 0, 1451}, + dictWord{138, 0, 120}, + dictWord{151, 0, 1}, + dictWord{137, 10, 805}, + dictWord{142, 0, 329}, + dictWord{ + 5, + 10, + 813, + }, + dictWord{135, 10, 2046}, + dictWord{135, 0, 226}, + dictWord{138, 11, 96}, + dictWord{7, 0, 1855}, + dictWord{5, 10, 712}, + dictWord{11, 10, 17}, + dictWord{13, 10, 321}, + dictWord{144, 10, 67}, + dictWord{9, 0, 461}, + dictWord{6, 10, 320}, + dictWord{7, 10, 781}, + dictWord{7, 10, 1921}, + dictWord{9, 10, 55}, + dictWord{ + 10, + 10, + 186, + }, + dictWord{10, 10, 273}, + dictWord{10, 10, 664}, + dictWord{10, 10, 801}, + dictWord{11, 10, 996}, + dictWord{11, 10, 997}, + dictWord{13, 10, 157}, + dictWord{142, 10, 170}, + dictWord{8, 11, 203}, + dictWord{8, 10, 271}, + dictWord{11, 11, 823}, + dictWord{11, 11, 846}, + dictWord{12, 11, 482}, + dictWord{ + 13, + 11, + 133, + }, + dictWord{13, 11, 277}, + dictWord{13, 11, 302}, + dictWord{13, 11, 464}, + dictWord{14, 11, 205}, + dictWord{142, 11, 221}, + dictWord{135, 0, 1346}, + dictWord{4, 11, 449}, + dictWord{133, 11, 718}, + dictWord{134, 0, 85}, + dictWord{14, 0, 299}, + dictWord{7, 10, 103}, + dictWord{7, 10, 863}, + dictWord{11, 10, 184}, + dictWord{145, 10, 62}, + dictWord{4, 11, 355}, + dictWord{6, 11, 311}, + dictWord{9, 11, 256}, + dictWord{138, 11, 404}, + dictWord{137, 10, 659}, + dictWord{ + 138, + 11, + 758, + }, + dictWord{133, 11, 827}, + dictWord{5, 11, 64}, + dictWord{140, 11, 581}, + dictWord{134, 0, 1171}, + dictWord{4, 11, 442}, + dictWord{7, 11, 1047}, + dictWord{ + 7, + 11, + 1352, + }, + dictWord{135, 11, 1643}, + dictWord{132, 0, 980}, + dictWord{5, 11, 977}, + dictWord{6, 11, 288}, + dictWord{7, 11, 528}, + dictWord{135, 11, 1065}, + dictWord{5, 0, 279}, + dictWord{6, 0, 235}, + dictWord{7, 0, 468}, + dictWord{8, 0, 446}, + dictWord{9, 0, 637}, + dictWord{10, 0, 717}, + dictWord{11, 0, 738}, + dictWord{ + 140, + 0, + 514, + }, + dictWord{132, 0, 293}, + dictWord{11, 10, 337}, + dictWord{142, 10, 303}, + dictWord{136, 11, 285}, + dictWord{5, 0, 17}, + dictWord{6, 0, 371}, + dictWord{ + 9, + 0, + 528, + }, + dictWord{12, 0, 364}, + dictWord{132, 11, 254}, + dictWord{5, 10, 77}, + dictWord{7, 10, 1455}, + dictWord{10, 10, 843}, + dictWord{147, 10, 73}, + dictWord{ + 150, + 0, + 5, + }, + dictWord{132, 10, 458}, + dictWord{6, 11, 12}, + dictWord{7, 11, 1219}, + dictWord{145, 11, 73}, + dictWord{135, 10, 1420}, + dictWord{6, 10, 109}, + dictWord{138, 10, 382}, + dictWord{135, 11, 125}, + dictWord{6, 10, 330}, + dictWord{7, 10, 1084}, + dictWord{139, 10, 142}, + dictWord{6, 11, 369}, + dictWord{ + 6, + 11, + 502, + }, + dictWord{7, 11, 1036}, + dictWord{8, 11, 348}, + dictWord{9, 11, 452}, + dictWord{10, 11, 26}, + dictWord{11, 11, 224}, + dictWord{11, 11, 387}, + dictWord{ + 11, + 11, + 772, + }, + dictWord{12, 11, 95}, + dictWord{12, 11, 629}, + dictWord{13, 11, 195}, + dictWord{13, 11, 207}, + dictWord{13, 11, 241}, + dictWord{14, 11, 260}, + dictWord{ + 14, + 11, + 270, + }, + dictWord{143, 11, 140}, + dictWord{132, 11, 269}, + dictWord{5, 11, 480}, + dictWord{7, 11, 532}, + dictWord{7, 11, 1197}, + dictWord{7, 11, 1358}, + dictWord{8, 11, 291}, + dictWord{11, 11, 349}, + dictWord{142, 11, 396}, + dictWord{150, 0, 48}, + dictWord{10, 0, 601}, + dictWord{13, 0, 353}, + dictWord{141, 0, 376}, + dictWord{5, 0, 779}, + dictWord{5, 0, 807}, + dictWord{6, 0, 1655}, + dictWord{134, 0, 1676}, + dictWord{142, 11, 223}, + dictWord{4, 0, 196}, + dictWord{5, 0, 558}, + dictWord{133, 0, 949}, + dictWord{148, 11, 15}, + dictWord{135, 11, 1764}, + dictWord{134, 0, 1322}, + dictWord{132, 0, 752}, + dictWord{139, 0, 737}, + dictWord{ + 135, + 11, + 657, + }, + dictWord{136, 11, 533}, + dictWord{135, 0, 412}, + dictWord{4, 0, 227}, + dictWord{5, 0, 159}, + dictWord{5, 0, 409}, + dictWord{7, 0, 80}, + dictWord{8, 0, 556}, + dictWord{10, 0, 479}, + dictWord{12, 0, 418}, + dictWord{14, 0, 50}, + dictWord{14, 0, 123}, + dictWord{14, 0, 192}, + dictWord{14, 0, 249}, + dictWord{14, 0, 295}, + dictWord{143, 0, 27}, + dictWord{7, 0, 1470}, + dictWord{8, 0, 66}, + dictWord{8, 0, 137}, + dictWord{8, 0, 761}, + dictWord{9, 0, 638}, + dictWord{11, 0, 80}, + dictWord{11, 0, 212}, + dictWord{11, 0, 368}, + dictWord{11, 0, 418}, + dictWord{12, 0, 8}, + dictWord{13, 0, 15}, + dictWord{16, 0, 61}, + dictWord{17, 0, 59}, + dictWord{19, 0, 28}, + dictWord{ + 148, + 0, + 84, + }, + dictWord{135, 10, 1985}, + dictWord{4, 11, 211}, + dictWord{4, 11, 332}, + dictWord{5, 11, 335}, + dictWord{6, 11, 238}, + dictWord{7, 11, 269}, + dictWord{ + 7, + 11, + 811, + }, + dictWord{7, 11, 1797}, + dictWord{8, 10, 122}, + dictWord{8, 11, 836}, + dictWord{9, 11, 507}, + dictWord{141, 11, 242}, + dictWord{6, 0, 683}, + dictWord{ + 134, + 0, + 1252, + }, + dictWord{4, 0, 873}, + dictWord{132, 10, 234}, + dictWord{134, 0, 835}, + dictWord{6, 0, 38}, + dictWord{7, 0, 1220}, + dictWord{8, 0, 185}, + dictWord{8, 0, 256}, + dictWord{9, 0, 22}, + dictWord{9, 0, 331}, + dictWord{10, 0, 738}, + dictWord{11, 0, 205}, + dictWord{11, 0, 540}, + dictWord{11, 0, 746}, + dictWord{13, 0, 465}, + dictWord{ + 14, + 0, + 88, + }, + dictWord{142, 0, 194}, + dictWord{138, 0, 986}, + dictWord{5, 11, 1009}, + dictWord{12, 11, 582}, + dictWord{146, 11, 131}, + dictWord{4, 0, 159}, + dictWord{ + 6, + 0, + 115, + }, + dictWord{7, 0, 252}, + dictWord{7, 0, 257}, + dictWord{7, 0, 1928}, + dictWord{8, 0, 69}, + dictWord{9, 0, 384}, + dictWord{10, 0, 91}, + dictWord{10, 0, 615}, + dictWord{ + 12, + 0, + 375, + }, + dictWord{14, 0, 235}, + dictWord{18, 0, 117}, + dictWord{147, 0, 123}, + dictWord{133, 0, 911}, + dictWord{136, 0, 278}, + dictWord{5, 10, 430}, + dictWord{ + 5, + 10, + 932, + }, + dictWord{6, 10, 131}, + dictWord{7, 10, 417}, + dictWord{9, 10, 522}, + dictWord{11, 10, 314}, + dictWord{141, 10, 390}, + dictWord{14, 10, 149}, + dictWord{14, 10, 399}, + dictWord{143, 10, 57}, + dictWord{4, 0, 151}, + dictWord{7, 0, 1567}, + dictWord{136, 0, 749}, + dictWord{5, 11, 228}, + dictWord{6, 11, 203}, + dictWord{ + 7, + 11, + 156, + }, + dictWord{8, 11, 347}, + dictWord{137, 11, 265}, + dictWord{132, 10, 507}, + dictWord{10, 0, 989}, + dictWord{140, 0, 956}, + dictWord{133, 0, 990}, + dictWord{5, 0, 194}, + dictWord{6, 0, 927}, + dictWord{7, 0, 1662}, + dictWord{9, 0, 90}, + dictWord{140, 0, 564}, + dictWord{4, 10, 343}, + dictWord{133, 10, 511}, + dictWord{133, 0, 425}, + dictWord{7, 10, 455}, + dictWord{138, 10, 591}, + dictWord{4, 0, 774}, + dictWord{7, 11, 476}, + dictWord{7, 11, 1592}, + dictWord{138, 11, 87}, + dictWord{5, 0, 971}, + dictWord{135, 10, 1381}, + dictWord{5, 11, 318}, + dictWord{147, 11, 121}, + dictWord{5, 11, 291}, + dictWord{7, 11, 765}, + dictWord{9, 11, 389}, + dictWord{140, 11, 548}, + dictWord{134, 10, 575}, + dictWord{4, 0, 827}, + dictWord{12, 0, 646}, + dictWord{12, 0, 705}, + dictWord{12, 0, 712}, + dictWord{140, 0, 714}, + dictWord{139, 0, 752}, + dictWord{137, 0, 662}, + dictWord{5, 0, 72}, + dictWord{6, 0, 264}, + dictWord{7, 0, 21}, + dictWord{7, 0, 46}, + dictWord{7, 0, 2013}, + dictWord{ + 8, + 0, + 215, + }, + dictWord{8, 0, 513}, + dictWord{10, 0, 266}, + dictWord{139, 0, 22}, + dictWord{139, 11, 522}, + dictWord{6, 0, 239}, + dictWord{7, 0, 118}, + dictWord{10, 0, 95}, + dictWord{11, 0, 603}, + dictWord{13, 0, 443}, + dictWord{14, 0, 160}, + dictWord{143, 0, 4}, + dictWord{6, 0, 431}, + dictWord{134, 0, 669}, + dictWord{7, 10, 1127}, + dictWord{ + 7, + 10, + 1572, + }, + dictWord{10, 10, 297}, + dictWord{10, 10, 422}, + dictWord{11, 10, 764}, + dictWord{11, 10, 810}, + dictWord{12, 10, 264}, + dictWord{13, 10, 102}, + dictWord{13, 10, 300}, + dictWord{13, 10, 484}, + dictWord{14, 10, 147}, + dictWord{14, 10, 229}, + dictWord{17, 10, 71}, + dictWord{18, 10, 118}, + dictWord{ + 147, + 10, + 120, + }, + dictWord{5, 0, 874}, + dictWord{6, 0, 1677}, + dictWord{15, 0, 0}, + dictWord{10, 11, 525}, + dictWord{139, 11, 82}, + dictWord{6, 0, 65}, + dictWord{7, 0, 939}, + dictWord{ + 7, + 0, + 1172, + }, + dictWord{7, 0, 1671}, + dictWord{9, 0, 540}, + dictWord{10, 0, 696}, + dictWord{11, 0, 265}, + dictWord{11, 0, 732}, + dictWord{11, 0, 928}, + dictWord{ + 11, + 0, + 937, + }, + dictWord{141, 0, 438}, + dictWord{134, 0, 1350}, + dictWord{136, 11, 547}, + dictWord{132, 11, 422}, + dictWord{5, 11, 355}, + dictWord{145, 11, 0}, + dictWord{137, 11, 905}, + dictWord{5, 0, 682}, + dictWord{135, 0, 1887}, + dictWord{132, 0, 809}, + dictWord{4, 0, 696}, + dictWord{133, 11, 865}, + dictWord{6, 0, 1074}, + dictWord{6, 0, 1472}, + dictWord{14, 10, 35}, + dictWord{142, 10, 191}, + dictWord{5, 11, 914}, + dictWord{134, 11, 1625}, + dictWord{133, 11, 234}, + dictWord{ + 135, + 11, + 1383, + }, + dictWord{137, 11, 780}, + dictWord{132, 10, 125}, + dictWord{4, 0, 726}, + dictWord{133, 0, 630}, + dictWord{8, 0, 802}, + dictWord{136, 0, 838}, + dictWord{132, 10, 721}, + dictWord{6, 0, 1337}, + dictWord{7, 0, 776}, + dictWord{19, 0, 56}, + dictWord{136, 10, 145}, + dictWord{132, 0, 970}, + dictWord{7, 10, 792}, + dictWord{8, 10, 147}, + dictWord{10, 10, 821}, + dictWord{139, 10, 1021}, + dictWord{139, 10, 970}, + dictWord{8, 0, 940}, + dictWord{137, 0, 797}, + dictWord{ + 135, + 11, + 1312, + }, + dictWord{9, 0, 248}, + dictWord{10, 0, 400}, + dictWord{7, 11, 816}, + dictWord{7, 11, 1241}, + dictWord{7, 10, 1999}, + dictWord{9, 11, 283}, + dictWord{ + 9, + 11, + 520, + }, + dictWord{10, 11, 213}, + dictWord{10, 11, 307}, + dictWord{10, 11, 463}, + dictWord{10, 11, 671}, + dictWord{10, 11, 746}, + dictWord{11, 11, 401}, + dictWord{ + 11, + 11, + 794, + }, + dictWord{12, 11, 517}, + dictWord{18, 11, 107}, + dictWord{147, 11, 115}, + dictWord{6, 0, 1951}, + dictWord{134, 0, 2040}, + dictWord{ + 135, + 11, + 339, + }, + dictWord{13, 0, 41}, + dictWord{15, 0, 93}, + dictWord{5, 10, 168}, + dictWord{5, 10, 930}, + dictWord{8, 10, 74}, + dictWord{9, 10, 623}, + dictWord{12, 10, 500}, + dictWord{140, 10, 579}, + dictWord{6, 0, 118}, + dictWord{7, 0, 215}, + dictWord{7, 0, 1521}, + dictWord{140, 0, 11}, + dictWord{6, 10, 220}, + dictWord{7, 10, 1101}, + dictWord{141, 10, 105}, + dictWord{6, 11, 421}, + dictWord{7, 11, 61}, + dictWord{7, 11, 1540}, + dictWord{10, 11, 11}, + dictWord{138, 11, 501}, + dictWord{7, 0, 615}, + dictWord{138, 0, 251}, + dictWord{140, 11, 631}, + dictWord{135, 0, 1044}, + dictWord{6, 10, 19}, + dictWord{7, 10, 1413}, + dictWord{139, 10, 428}, + dictWord{ + 133, + 0, + 225, + }, + dictWord{7, 10, 96}, + dictWord{8, 10, 401}, + dictWord{8, 10, 703}, + dictWord{137, 10, 896}, + dictWord{145, 10, 116}, + dictWord{6, 11, 102}, + dictWord{ + 7, + 11, + 72, + }, + dictWord{15, 11, 142}, + dictWord{147, 11, 67}, + dictWord{7, 10, 1961}, + dictWord{7, 10, 1965}, + dictWord{8, 10, 702}, + dictWord{136, 10, 750}, + dictWord{ + 7, + 10, + 2030, + }, + dictWord{8, 10, 150}, + dictWord{8, 10, 737}, + dictWord{12, 10, 366}, + dictWord{151, 11, 30}, + dictWord{4, 0, 370}, + dictWord{5, 0, 756}, + dictWord{ + 7, + 0, + 1326, + }, + dictWord{135, 11, 823}, + dictWord{8, 10, 800}, + dictWord{9, 10, 148}, + dictWord{9, 10, 872}, + dictWord{9, 10, 890}, + dictWord{11, 10, 309}, + dictWord{ + 11, + 10, + 1001, + }, + dictWord{13, 10, 267}, + dictWord{141, 10, 323}, + dictWord{6, 0, 1662}, + dictWord{7, 0, 48}, + dictWord{8, 0, 771}, + dictWord{10, 0, 116}, + dictWord{ + 13, + 0, + 104, + }, + dictWord{14, 0, 105}, + dictWord{14, 0, 184}, + dictWord{15, 0, 168}, + dictWord{19, 0, 92}, + dictWord{148, 0, 68}, + dictWord{10, 0, 209}, + dictWord{ + 135, + 11, + 1870, + }, + dictWord{7, 11, 68}, + dictWord{8, 11, 48}, + dictWord{8, 11, 88}, + dictWord{8, 11, 582}, + dictWord{8, 11, 681}, + dictWord{9, 11, 373}, + dictWord{9, 11, 864}, + dictWord{11, 11, 157}, + dictWord{11, 11, 336}, + dictWord{11, 11, 843}, + dictWord{148, 11, 27}, + dictWord{134, 0, 930}, + dictWord{4, 11, 88}, + dictWord{5, 11, 137}, + dictWord{5, 11, 174}, + dictWord{5, 11, 777}, + dictWord{6, 11, 1664}, + dictWord{6, 11, 1725}, + dictWord{7, 11, 77}, + dictWord{7, 11, 426}, + dictWord{7, 11, 1317}, + dictWord{7, 11, 1355}, + dictWord{8, 11, 126}, + dictWord{8, 11, 563}, + dictWord{9, 11, 523}, + dictWord{9, 11, 750}, + dictWord{10, 11, 310}, + dictWord{10, 11, 836}, + dictWord{11, 11, 42}, + dictWord{11, 11, 318}, + dictWord{11, 11, 731}, + dictWord{12, 11, 68}, + dictWord{12, 11, 92}, + dictWord{12, 11, 507}, + dictWord{12, 11, 692}, + dictWord{13, 11, 81}, + dictWord{13, 11, 238}, + dictWord{13, 11, 374}, + dictWord{18, 11, 138}, + dictWord{19, 11, 78}, + dictWord{19, 11, 111}, + dictWord{20, 11, 55}, + dictWord{20, 11, 77}, + dictWord{148, 11, 92}, + dictWord{4, 11, 938}, + dictWord{135, 11, 1831}, + dictWord{5, 10, 547}, + dictWord{7, 10, 424}, + dictWord{ + 8, + 11, + 617, + }, + dictWord{138, 11, 351}, + dictWord{6, 0, 1286}, + dictWord{6, 11, 1668}, + dictWord{7, 11, 1499}, + dictWord{8, 11, 117}, + dictWord{9, 11, 314}, + dictWord{ + 138, + 11, + 174, + }, + dictWord{6, 0, 759}, + dictWord{6, 0, 894}, + dictWord{7, 11, 707}, + dictWord{139, 11, 563}, + dictWord{4, 0, 120}, + dictWord{135, 0, 1894}, + dictWord{ + 9, + 0, + 385, + }, + dictWord{149, 0, 17}, + dictWord{138, 0, 429}, + dictWord{133, 11, 403}, + dictWord{5, 0, 820}, + dictWord{135, 0, 931}, + dictWord{10, 0, 199}, + dictWord{ + 133, + 10, + 133, + }, + dictWord{6, 0, 151}, + dictWord{6, 0, 1675}, + dictWord{7, 0, 383}, + dictWord{151, 0, 10}, + dictWord{6, 0, 761}, + dictWord{136, 10, 187}, + dictWord{ + 8, + 0, + 365, + }, + dictWord{10, 10, 0}, + dictWord{10, 10, 818}, + dictWord{139, 10, 988}, + dictWord{4, 11, 44}, + dictWord{5, 11, 311}, + dictWord{6, 11, 156}, + dictWord{ + 7, + 11, + 639, + }, + dictWord{7, 11, 762}, + dictWord{7, 11, 1827}, + dictWord{9, 11, 8}, + dictWord{9, 11, 462}, + dictWord{148, 11, 83}, + dictWord{4, 11, 346}, + dictWord{7, 11, 115}, + dictWord{9, 11, 180}, + dictWord{9, 11, 456}, + dictWord{138, 11, 363}, + dictWord{136, 10, 685}, + dictWord{7, 0, 1086}, + dictWord{145, 0, 46}, + dictWord{ + 6, + 0, + 1624, + }, + dictWord{11, 0, 11}, + dictWord{12, 0, 422}, + dictWord{13, 0, 444}, + dictWord{142, 0, 360}, + dictWord{6, 0, 1020}, + dictWord{6, 0, 1260}, + dictWord{ + 134, + 0, + 1589, + }, + dictWord{4, 0, 43}, + dictWord{5, 0, 344}, + dictWord{5, 0, 357}, + dictWord{14, 0, 472}, + dictWord{150, 0, 58}, + dictWord{6, 0, 1864}, + dictWord{6, 0, 1866}, + dictWord{6, 0, 1868}, + dictWord{6, 0, 1869}, + dictWord{6, 0, 1874}, + dictWord{6, 0, 1877}, + dictWord{6, 0, 1903}, + dictWord{6, 0, 1911}, + dictWord{9, 0, 920}, + dictWord{ + 9, + 0, + 921, + }, + dictWord{9, 0, 924}, + dictWord{9, 0, 946}, + dictWord{9, 0, 959}, + dictWord{9, 0, 963}, + dictWord{9, 0, 970}, + dictWord{9, 0, 997}, + dictWord{9, 0, 1008}, + dictWord{ + 9, + 0, + 1017, + }, + dictWord{12, 0, 795}, + dictWord{12, 0, 797}, + dictWord{12, 0, 798}, + dictWord{12, 0, 800}, + dictWord{12, 0, 803}, + dictWord{12, 0, 811}, + dictWord{ + 12, + 0, + 820, + }, + dictWord{12, 0, 821}, + dictWord{12, 0, 839}, + dictWord{12, 0, 841}, + dictWord{12, 0, 848}, + dictWord{12, 0, 911}, + dictWord{12, 0, 921}, + dictWord{12, 0, 922}, + dictWord{12, 0, 925}, + dictWord{12, 0, 937}, + dictWord{12, 0, 944}, + dictWord{12, 0, 945}, + dictWord{12, 0, 953}, + dictWord{15, 0, 184}, + dictWord{15, 0, 191}, + dictWord{15, 0, 199}, + dictWord{15, 0, 237}, + dictWord{15, 0, 240}, + dictWord{15, 0, 243}, + dictWord{15, 0, 246}, + dictWord{18, 0, 203}, + dictWord{21, 0, 40}, + dictWord{ + 21, + 0, + 52, + }, + dictWord{21, 0, 57}, + dictWord{24, 0, 23}, + dictWord{24, 0, 28}, + dictWord{152, 0, 30}, + dictWord{134, 0, 725}, + dictWord{145, 11, 58}, + dictWord{133, 0, 888}, + dictWord{137, 10, 874}, + dictWord{4, 0, 711}, + dictWord{8, 10, 774}, + dictWord{10, 10, 670}, + dictWord{140, 10, 51}, + dictWord{144, 11, 40}, + dictWord{ + 6, + 11, + 185, + }, + dictWord{7, 11, 1899}, + dictWord{139, 11, 673}, + dictWord{137, 10, 701}, + dictWord{137, 0, 440}, + dictWord{4, 11, 327}, + dictWord{5, 11, 478}, + dictWord{ + 7, + 11, + 1332, + }, + dictWord{8, 11, 753}, + dictWord{140, 11, 227}, + dictWord{4, 10, 127}, + dictWord{5, 10, 350}, + dictWord{6, 10, 356}, + dictWord{8, 10, 426}, + dictWord{ + 9, + 10, + 572, + }, + dictWord{10, 10, 247}, + dictWord{139, 10, 312}, + dictWord{5, 11, 1020}, + dictWord{133, 11, 1022}, + dictWord{4, 11, 103}, + dictWord{ + 133, + 11, + 401, + }, + dictWord{6, 0, 1913}, + dictWord{6, 0, 1926}, + dictWord{6, 0, 1959}, + dictWord{9, 0, 914}, + dictWord{9, 0, 939}, + dictWord{9, 0, 952}, + dictWord{9, 0, 979}, + dictWord{ + 9, + 0, + 990, + }, + dictWord{9, 0, 998}, + dictWord{9, 0, 1003}, + dictWord{9, 0, 1023}, + dictWord{12, 0, 827}, + dictWord{12, 0, 834}, + dictWord{12, 0, 845}, + dictWord{ + 12, + 0, + 912, + }, + dictWord{12, 0, 935}, + dictWord{12, 0, 951}, + dictWord{15, 0, 172}, + dictWord{15, 0, 174}, + dictWord{18, 0, 198}, + dictWord{149, 0, 63}, + dictWord{5, 0, 958}, + dictWord{5, 0, 987}, + dictWord{4, 11, 499}, + dictWord{135, 11, 1421}, + dictWord{7, 0, 885}, + dictWord{6, 10, 59}, + dictWord{6, 10, 1762}, + dictWord{9, 10, 603}, + dictWord{141, 10, 397}, + dictWord{10, 11, 62}, + dictWord{141, 11, 164}, + dictWord{4, 0, 847}, + dictWord{135, 0, 326}, + dictWord{11, 0, 276}, + dictWord{142, 0, 293}, + dictWord{4, 0, 65}, + dictWord{5, 0, 479}, + dictWord{5, 0, 1004}, + dictWord{7, 0, 1913}, + dictWord{8, 0, 317}, + dictWord{9, 0, 302}, + dictWord{10, 0, 612}, + dictWord{ + 13, + 0, + 22, + }, + dictWord{132, 11, 96}, + dictWord{4, 0, 261}, + dictWord{135, 0, 510}, + dictWord{135, 0, 1514}, + dictWord{6, 10, 111}, + dictWord{7, 10, 4}, + dictWord{8, 10, 163}, + dictWord{8, 10, 776}, + dictWord{138, 10, 566}, + dictWord{4, 0, 291}, + dictWord{9, 0, 515}, + dictWord{12, 0, 152}, + dictWord{12, 0, 443}, + dictWord{13, 0, 392}, + dictWord{142, 0, 357}, + dictWord{7, 11, 399}, + dictWord{135, 11, 1492}, + dictWord{4, 0, 589}, + dictWord{139, 0, 282}, + dictWord{6, 11, 563}, + dictWord{ + 135, + 10, + 1994, + }, + dictWord{5, 10, 297}, + dictWord{135, 10, 1038}, + dictWord{4, 0, 130}, + dictWord{7, 0, 843}, + dictWord{135, 0, 1562}, + dictWord{5, 0, 42}, + dictWord{ + 5, + 0, + 879, + }, + dictWord{7, 0, 245}, + dictWord{7, 0, 324}, + dictWord{7, 0, 1532}, + dictWord{11, 0, 463}, + dictWord{11, 0, 472}, + dictWord{13, 0, 363}, + dictWord{144, 0, 52}, + dictWord{4, 0, 134}, + dictWord{133, 0, 372}, + dictWord{133, 0, 680}, + dictWord{136, 10, 363}, + dictWord{6, 0, 1997}, + dictWord{8, 0, 935}, + dictWord{136, 0, 977}, + dictWord{4, 0, 810}, + dictWord{135, 0, 1634}, + dictWord{135, 10, 1675}, + dictWord{7, 0, 1390}, + dictWord{4, 11, 910}, + dictWord{133, 11, 832}, + dictWord{ + 7, + 10, + 808, + }, + dictWord{8, 11, 266}, + dictWord{139, 11, 578}, + dictWord{132, 0, 644}, + dictWord{4, 0, 982}, + dictWord{138, 0, 867}, + dictWord{132, 10, 280}, + dictWord{ + 135, + 0, + 540, + }, + dictWord{140, 10, 54}, + dictWord{135, 0, 123}, + dictWord{134, 0, 1978}, + dictWord{4, 10, 421}, + dictWord{133, 10, 548}, + dictWord{6, 0, 623}, + dictWord{136, 0, 789}, + dictWord{4, 0, 908}, + dictWord{5, 0, 359}, + dictWord{5, 0, 508}, + dictWord{6, 0, 1723}, + dictWord{7, 0, 343}, + dictWord{7, 0, 1996}, + dictWord{ + 135, + 0, + 2026, + }, + dictWord{134, 0, 1220}, + dictWord{4, 0, 341}, + dictWord{135, 0, 480}, + dictWord{6, 10, 254}, + dictWord{9, 10, 109}, + dictWord{138, 10, 103}, + dictWord{ + 134, + 0, + 888, + }, + dictWord{8, 11, 528}, + dictWord{137, 11, 348}, + dictWord{7, 0, 1995}, + dictWord{8, 0, 299}, + dictWord{11, 0, 890}, + dictWord{12, 0, 674}, + dictWord{ + 4, + 11, + 20, + }, + dictWord{133, 11, 616}, + dictWord{135, 11, 1094}, + dictWord{134, 10, 1630}, + dictWord{4, 0, 238}, + dictWord{5, 0, 503}, + dictWord{6, 0, 179}, + dictWord{ + 7, + 0, + 2003, + }, + dictWord{8, 0, 381}, + dictWord{8, 0, 473}, + dictWord{9, 0, 149}, + dictWord{10, 0, 788}, + dictWord{15, 0, 45}, + dictWord{15, 0, 86}, + dictWord{20, 0, 110}, + dictWord{150, 0, 57}, + dictWord{133, 10, 671}, + dictWord{4, 11, 26}, + dictWord{5, 11, 429}, + dictWord{6, 11, 245}, + dictWord{7, 11, 704}, + dictWord{7, 11, 1379}, + dictWord{135, 11, 1474}, + dictWord{4, 0, 121}, + dictWord{5, 0, 156}, + dictWord{5, 0, 349}, + dictWord{9, 0, 431}, + dictWord{10, 0, 605}, + dictWord{142, 0, 342}, + dictWord{ + 7, + 11, + 943, + }, + dictWord{139, 11, 614}, + dictWord{132, 10, 889}, + dictWord{132, 11, 621}, + dictWord{7, 10, 1382}, + dictWord{7, 11, 1382}, + dictWord{ + 135, + 10, + 1910, + }, + dictWord{132, 10, 627}, + dictWord{133, 10, 775}, + dictWord{133, 11, 542}, + dictWord{133, 11, 868}, + dictWord{136, 11, 433}, + dictWord{6, 0, 1373}, + dictWord{7, 0, 1011}, + dictWord{11, 10, 362}, + dictWord{11, 10, 948}, + dictWord{140, 10, 388}, + dictWord{6, 0, 80}, + dictWord{7, 0, 173}, + dictWord{9, 0, 547}, + dictWord{10, 0, 730}, + dictWord{14, 0, 18}, + dictWord{22, 0, 39}, + dictWord{135, 11, 1495}, + dictWord{6, 0, 1694}, + dictWord{135, 0, 1974}, + dictWord{140, 0, 196}, + dictWord{4, 0, 923}, + dictWord{6, 0, 507}, + dictWord{6, 0, 1711}, + dictWord{7, 10, 451}, + dictWord{8, 10, 389}, + dictWord{12, 10, 490}, + dictWord{13, 10, 16}, + dictWord{ + 13, + 10, + 215, + }, + dictWord{13, 10, 351}, + dictWord{18, 10, 132}, + dictWord{147, 10, 125}, + dictWord{6, 0, 646}, + dictWord{134, 0, 1047}, + dictWord{135, 10, 841}, + dictWord{136, 10, 566}, + dictWord{6, 0, 1611}, + dictWord{135, 0, 1214}, + dictWord{139, 0, 926}, + dictWord{132, 11, 525}, + dictWord{132, 0, 595}, + dictWord{ + 5, + 0, + 240, + }, + dictWord{6, 0, 459}, + dictWord{7, 0, 12}, + dictWord{7, 0, 114}, + dictWord{7, 0, 949}, + dictWord{7, 0, 1753}, + dictWord{7, 0, 1805}, + dictWord{8, 0, 658}, + dictWord{ + 9, + 0, + 1, + }, + dictWord{11, 0, 959}, + dictWord{141, 0, 446}, + dictWord{5, 10, 912}, + dictWord{134, 10, 1695}, + dictWord{132, 0, 446}, + dictWord{7, 11, 62}, + dictWord{ + 12, + 11, + 45, + }, + dictWord{147, 11, 112}, + dictWord{5, 10, 236}, + dictWord{6, 10, 572}, + dictWord{8, 10, 492}, + dictWord{11, 10, 618}, + dictWord{144, 10, 56}, + dictWord{ + 5, + 10, + 190, + }, + dictWord{136, 10, 318}, + dictWord{135, 10, 1376}, + dictWord{4, 11, 223}, + dictWord{6, 11, 359}, + dictWord{11, 11, 3}, + dictWord{13, 11, 108}, + dictWord{ + 14, + 11, + 89, + }, + dictWord{144, 11, 22}, + dictWord{132, 11, 647}, + dictWord{134, 0, 490}, + dictWord{134, 0, 491}, + dictWord{134, 0, 1584}, + dictWord{ + 135, + 11, + 685, + }, + dictWord{138, 11, 220}, + dictWord{7, 0, 250}, + dictWord{136, 0, 507}, + dictWord{132, 0, 158}, + dictWord{4, 0, 140}, + dictWord{7, 0, 362}, + dictWord{8, 0, 209}, + dictWord{9, 0, 10}, + dictWord{9, 0, 160}, + dictWord{9, 0, 503}, + dictWord{9, 0, 614}, + dictWord{10, 0, 689}, + dictWord{11, 0, 327}, + dictWord{11, 0, 553}, + dictWord{ + 11, + 0, + 725, + }, + dictWord{11, 0, 767}, + dictWord{12, 0, 252}, + dictWord{12, 0, 583}, + dictWord{13, 0, 192}, + dictWord{14, 0, 269}, + dictWord{14, 0, 356}, + dictWord{148, 0, 50}, + dictWord{19, 0, 1}, + dictWord{19, 0, 26}, + dictWord{150, 0, 9}, + dictWord{132, 11, 109}, + dictWord{6, 0, 228}, + dictWord{7, 0, 1341}, + dictWord{9, 0, 408}, + dictWord{ + 138, + 0, + 343, + }, + dictWord{4, 0, 373}, + dictWord{5, 0, 283}, + dictWord{6, 0, 480}, + dictWord{7, 0, 609}, + dictWord{10, 0, 860}, + dictWord{138, 0, 878}, + dictWord{6, 0, 779}, + dictWord{134, 0, 1209}, + dictWord{4, 0, 557}, + dictWord{7, 11, 263}, + dictWord{7, 11, 628}, + dictWord{136, 11, 349}, + dictWord{132, 0, 548}, + dictWord{7, 0, 197}, + dictWord{8, 0, 142}, + dictWord{8, 0, 325}, + dictWord{9, 0, 150}, + dictWord{9, 0, 596}, + dictWord{10, 0, 350}, + dictWord{10, 0, 353}, + dictWord{11, 0, 74}, + dictWord{ + 11, + 0, + 315, + }, + dictWord{12, 0, 662}, + dictWord{12, 0, 681}, + dictWord{14, 0, 423}, + dictWord{143, 0, 141}, + dictWord{4, 11, 40}, + dictWord{10, 11, 67}, + dictWord{ + 11, + 11, + 117, + }, + dictWord{11, 11, 768}, + dictWord{139, 11, 935}, + dictWord{7, 11, 992}, + dictWord{8, 11, 301}, + dictWord{9, 11, 722}, + dictWord{12, 11, 63}, + dictWord{ + 13, + 11, + 29, + }, + dictWord{14, 11, 161}, + dictWord{143, 11, 18}, + dictWord{6, 0, 1490}, + dictWord{138, 11, 532}, + dictWord{5, 0, 580}, + dictWord{7, 0, 378}, + dictWord{ + 7, + 0, + 674, + }, + dictWord{7, 0, 1424}, + dictWord{15, 0, 83}, + dictWord{16, 0, 11}, + dictWord{15, 11, 83}, + dictWord{144, 11, 11}, + dictWord{6, 0, 1057}, + dictWord{6, 0, 1335}, + dictWord{10, 0, 316}, + dictWord{7, 10, 85}, + dictWord{7, 10, 247}, + dictWord{8, 10, 585}, + dictWord{138, 10, 163}, + dictWord{4, 0, 169}, + dictWord{5, 0, 83}, + dictWord{ + 6, + 0, + 399, + }, + dictWord{6, 0, 579}, + dictWord{6, 0, 1513}, + dictWord{7, 0, 692}, + dictWord{7, 0, 846}, + dictWord{7, 0, 1015}, + dictWord{7, 0, 1799}, + dictWord{8, 0, 403}, + dictWord{9, 0, 394}, + dictWord{10, 0, 133}, + dictWord{12, 0, 4}, + dictWord{12, 0, 297}, + dictWord{12, 0, 452}, + dictWord{16, 0, 81}, + dictWord{18, 0, 25}, + dictWord{21, 0, 14}, + dictWord{22, 0, 12}, + dictWord{151, 0, 18}, + dictWord{134, 0, 1106}, + dictWord{7, 0, 1546}, + dictWord{11, 0, 299}, + dictWord{142, 0, 407}, + dictWord{134, 0, 1192}, + dictWord{132, 0, 177}, + dictWord{5, 0, 411}, + dictWord{135, 0, 653}, + dictWord{7, 0, 439}, + dictWord{10, 0, 727}, + dictWord{11, 0, 260}, + dictWord{139, 0, 684}, + dictWord{138, 10, 145}, + dictWord{147, 10, 83}, + dictWord{5, 0, 208}, + dictWord{7, 0, 753}, + dictWord{135, 0, 1528}, + dictWord{137, 11, 617}, + dictWord{ + 135, + 10, + 1922, + }, + dictWord{135, 11, 825}, + dictWord{11, 0, 422}, + dictWord{13, 0, 389}, + dictWord{4, 10, 124}, + dictWord{10, 10, 457}, + dictWord{11, 10, 121}, + dictWord{ + 11, + 10, + 169, + }, + dictWord{11, 10, 870}, + dictWord{12, 10, 214}, + dictWord{14, 10, 187}, + dictWord{143, 10, 77}, + dictWord{11, 0, 615}, + dictWord{15, 0, 58}, + dictWord{ + 11, + 11, + 615, + }, + dictWord{143, 11, 58}, + dictWord{9, 0, 618}, + dictWord{138, 0, 482}, + dictWord{6, 0, 1952}, + dictWord{6, 0, 1970}, + dictWord{142, 0, 505}, + dictWord{ + 7, + 10, + 1193, + }, + dictWord{135, 11, 1838}, + dictWord{133, 0, 242}, + dictWord{135, 10, 1333}, + dictWord{6, 10, 107}, + dictWord{7, 10, 638}, + dictWord{ + 7, + 10, + 1632, + }, + dictWord{137, 10, 396}, + dictWord{133, 0, 953}, + dictWord{5, 10, 370}, + dictWord{134, 10, 1756}, + dictWord{5, 11, 28}, + dictWord{6, 11, 204}, + dictWord{ + 10, + 11, + 320, + }, + dictWord{10, 11, 583}, + dictWord{13, 11, 502}, + dictWord{14, 11, 72}, + dictWord{14, 11, 274}, + dictWord{14, 11, 312}, + dictWord{14, 11, 344}, + dictWord{15, 11, 159}, + dictWord{16, 11, 62}, + dictWord{16, 11, 69}, + dictWord{17, 11, 30}, + dictWord{18, 11, 42}, + dictWord{18, 11, 53}, + dictWord{18, 11, 84}, + dictWord{18, 11, 140}, + dictWord{19, 11, 68}, + dictWord{19, 11, 85}, + dictWord{20, 11, 5}, + dictWord{20, 11, 45}, + dictWord{20, 11, 101}, + dictWord{22, 11, 7}, + dictWord{ + 150, + 11, + 20, + }, + dictWord{4, 11, 558}, + dictWord{6, 11, 390}, + dictWord{7, 11, 162}, + dictWord{7, 11, 689}, + dictWord{9, 11, 360}, + dictWord{138, 11, 653}, + dictWord{ + 11, + 0, + 802, + }, + dictWord{141, 0, 67}, + dictWord{133, 10, 204}, + dictWord{133, 0, 290}, + dictWord{5, 10, 970}, + dictWord{134, 10, 1706}, + dictWord{132, 0, 380}, + dictWord{5, 0, 52}, + dictWord{7, 0, 277}, + dictWord{9, 0, 368}, + dictWord{139, 0, 791}, + dictWord{5, 11, 856}, + dictWord{6, 11, 1672}, + dictWord{6, 11, 1757}, + dictWord{ + 6, + 11, + 1781, + }, + dictWord{7, 11, 1150}, + dictWord{7, 11, 1425}, + dictWord{7, 11, 1453}, + dictWord{140, 11, 513}, + dictWord{5, 11, 92}, + dictWord{7, 10, 3}, + dictWord{ + 10, + 11, + 736, + }, + dictWord{140, 11, 102}, + dictWord{4, 0, 112}, + dictWord{5, 0, 653}, + dictWord{5, 10, 483}, + dictWord{5, 10, 685}, + dictWord{6, 10, 489}, + dictWord{ + 7, + 10, + 1204, + }, + dictWord{136, 10, 394}, + dictWord{132, 10, 921}, + dictWord{6, 0, 1028}, + dictWord{133, 10, 1007}, + dictWord{5, 11, 590}, + dictWord{9, 11, 213}, + dictWord{145, 11, 91}, + dictWord{135, 10, 1696}, + dictWord{10, 0, 138}, + dictWord{139, 0, 476}, + dictWord{5, 0, 725}, + dictWord{5, 0, 727}, + dictWord{135, 0, 1811}, + dictWord{4, 0, 979}, + dictWord{6, 0, 1821}, + dictWord{6, 0, 1838}, + dictWord{8, 0, 876}, + dictWord{8, 0, 883}, + dictWord{8, 0, 889}, + dictWord{8, 0, 893}, + dictWord{ + 8, + 0, + 895, + }, + dictWord{10, 0, 934}, + dictWord{12, 0, 720}, + dictWord{14, 0, 459}, + dictWord{148, 0, 123}, + dictWord{135, 11, 551}, + dictWord{4, 0, 38}, + dictWord{6, 0, 435}, + dictWord{7, 0, 307}, + dictWord{7, 0, 999}, + dictWord{7, 0, 1481}, + dictWord{7, 0, 1732}, + dictWord{7, 0, 1738}, + dictWord{8, 0, 371}, + dictWord{9, 0, 414}, + dictWord{ + 11, + 0, + 316, + }, + dictWord{12, 0, 52}, + dictWord{13, 0, 420}, + dictWord{147, 0, 100}, + dictWord{135, 0, 1296}, + dictWord{132, 10, 712}, + dictWord{134, 10, 1629}, + dictWord{133, 0, 723}, + dictWord{134, 0, 651}, + dictWord{136, 11, 191}, + dictWord{9, 11, 791}, + dictWord{10, 11, 93}, + dictWord{11, 11, 301}, + dictWord{16, 11, 13}, + dictWord{17, 11, 23}, + dictWord{18, 11, 135}, + dictWord{19, 11, 12}, + dictWord{20, 11, 1}, + dictWord{20, 11, 12}, + dictWord{148, 11, 14}, + dictWord{136, 11, 503}, + dictWord{6, 11, 466}, + dictWord{135, 11, 671}, + dictWord{6, 0, 1200}, + dictWord{134, 0, 1330}, + dictWord{135, 0, 1255}, + dictWord{134, 0, 986}, + dictWord{ + 5, + 0, + 109, + }, + dictWord{6, 0, 1784}, + dictWord{7, 0, 1895}, + dictWord{12, 0, 296}, + dictWord{140, 0, 302}, + dictWord{135, 11, 983}, + dictWord{133, 10, 485}, + dictWord{ + 134, + 0, + 660, + }, + dictWord{134, 0, 800}, + dictWord{5, 0, 216}, + dictWord{5, 0, 294}, + dictWord{6, 0, 591}, + dictWord{7, 0, 1879}, + dictWord{9, 0, 141}, + dictWord{9, 0, 270}, + dictWord{9, 0, 679}, + dictWord{10, 0, 159}, + dictWord{11, 0, 197}, + dictWord{11, 0, 438}, + dictWord{12, 0, 538}, + dictWord{12, 0, 559}, + dictWord{14, 0, 144}, + dictWord{ + 14, + 0, + 167, + }, + dictWord{15, 0, 67}, + dictWord{4, 10, 285}, + dictWord{5, 10, 317}, + dictWord{6, 10, 301}, + dictWord{7, 10, 7}, + dictWord{8, 10, 153}, + dictWord{ + 10, + 10, + 766, + }, + dictWord{11, 10, 468}, + dictWord{12, 10, 467}, + dictWord{141, 10, 143}, + dictWord{136, 0, 945}, + dictWord{134, 0, 1090}, + dictWord{137, 0, 81}, + dictWord{12, 11, 468}, + dictWord{19, 11, 96}, + dictWord{148, 11, 24}, + dictWord{134, 0, 391}, + dictWord{138, 11, 241}, + dictWord{7, 0, 322}, + dictWord{136, 0, 249}, + dictWord{134, 0, 1412}, + dictWord{135, 11, 795}, + dictWord{5, 0, 632}, + dictWord{138, 0, 526}, + dictWord{136, 10, 819}, + dictWord{6, 0, 144}, + dictWord{7, 0, 948}, + dictWord{7, 0, 1042}, + dictWord{8, 0, 235}, + dictWord{8, 0, 461}, + dictWord{9, 0, 453}, + dictWord{9, 0, 796}, + dictWord{10, 0, 354}, + dictWord{17, 0, 77}, + dictWord{ + 135, + 11, + 954, + }, + dictWord{139, 10, 917}, + dictWord{6, 0, 940}, + dictWord{134, 0, 1228}, + dictWord{4, 0, 362}, + dictWord{7, 0, 52}, + dictWord{135, 0, 303}, + dictWord{ + 6, + 11, + 549, + }, + dictWord{8, 11, 34}, + dictWord{8, 11, 283}, + dictWord{9, 11, 165}, + dictWord{138, 11, 475}, + dictWord{7, 11, 370}, + dictWord{7, 11, 1007}, + dictWord{ + 7, + 11, + 1177, + }, + dictWord{135, 11, 1565}, + dictWord{5, 11, 652}, + dictWord{5, 11, 701}, + dictWord{135, 11, 449}, + dictWord{5, 0, 196}, + dictWord{6, 0, 486}, + dictWord{ + 7, + 0, + 212, + }, + dictWord{8, 0, 309}, + dictWord{136, 0, 346}, + dictWord{6, 10, 1719}, + dictWord{6, 10, 1735}, + dictWord{7, 10, 2016}, + dictWord{7, 10, 2020}, + dictWord{ + 8, + 10, + 837, + }, + dictWord{137, 10, 852}, + dictWord{6, 11, 159}, + dictWord{6, 11, 364}, + dictWord{7, 11, 516}, + dictWord{7, 11, 1439}, + dictWord{137, 11, 518}, + dictWord{135, 0, 1912}, + dictWord{135, 0, 1290}, + dictWord{132, 0, 686}, + dictWord{141, 11, 151}, + dictWord{138, 0, 625}, + dictWord{136, 0, 706}, + dictWord{ + 138, + 10, + 568, + }, + dictWord{139, 0, 412}, + dictWord{4, 0, 30}, + dictWord{133, 0, 43}, + dictWord{8, 10, 67}, + dictWord{138, 10, 419}, + dictWord{7, 0, 967}, + dictWord{ + 141, + 0, + 11, + }, + dictWord{12, 0, 758}, + dictWord{14, 0, 441}, + dictWord{142, 0, 462}, + dictWord{10, 10, 657}, + dictWord{14, 10, 297}, + dictWord{142, 10, 361}, + dictWord{ + 139, + 10, + 729, + }, + dictWord{4, 0, 220}, + dictWord{135, 0, 1535}, + dictWord{7, 11, 501}, + dictWord{9, 11, 111}, + dictWord{10, 11, 141}, + dictWord{11, 11, 332}, + dictWord{ + 13, + 11, + 43, + }, + dictWord{13, 11, 429}, + dictWord{14, 11, 130}, + dictWord{14, 11, 415}, + dictWord{145, 11, 102}, + dictWord{4, 0, 950}, + dictWord{6, 0, 1859}, + dictWord{ + 7, + 0, + 11, + }, + dictWord{8, 0, 873}, + dictWord{12, 0, 710}, + dictWord{12, 0, 718}, + dictWord{12, 0, 748}, + dictWord{12, 0, 765}, + dictWord{148, 0, 124}, + dictWord{ + 5, + 11, + 149, + }, + dictWord{5, 11, 935}, + dictWord{136, 11, 233}, + dictWord{142, 11, 291}, + dictWord{134, 0, 1579}, + dictWord{7, 0, 890}, + dictWord{8, 10, 51}, + dictWord{ + 9, + 10, + 868, + }, + dictWord{10, 10, 833}, + dictWord{12, 10, 481}, + dictWord{12, 10, 570}, + dictWord{148, 10, 106}, + dictWord{141, 0, 2}, + dictWord{132, 10, 445}, + dictWord{136, 11, 801}, + dictWord{135, 0, 1774}, + dictWord{7, 0, 1725}, + dictWord{138, 0, 393}, + dictWord{5, 0, 263}, + dictWord{134, 0, 414}, + dictWord{ + 132, + 11, + 322, + }, + dictWord{133, 10, 239}, + dictWord{7, 0, 456}, + dictWord{7, 10, 1990}, + dictWord{8, 10, 130}, + dictWord{139, 10, 720}, + dictWord{137, 0, 818}, + dictWord{ + 5, + 10, + 123, + }, + dictWord{6, 10, 530}, + dictWord{7, 10, 348}, + dictWord{135, 10, 1419}, + dictWord{135, 10, 2024}, + dictWord{6, 0, 178}, + dictWord{6, 0, 1750}, + dictWord{8, 0, 251}, + dictWord{9, 0, 690}, + dictWord{10, 0, 155}, + dictWord{10, 0, 196}, + dictWord{10, 0, 373}, + dictWord{11, 0, 698}, + dictWord{13, 0, 155}, + dictWord{ + 148, + 0, + 93, + }, + dictWord{5, 0, 97}, + dictWord{137, 0, 393}, + dictWord{134, 0, 674}, + dictWord{11, 0, 223}, + dictWord{140, 0, 168}, + dictWord{132, 10, 210}, + dictWord{ + 139, + 11, + 464, + }, + dictWord{6, 0, 1639}, + dictWord{146, 0, 159}, + dictWord{139, 11, 2}, + dictWord{7, 0, 934}, + dictWord{8, 0, 647}, + dictWord{17, 0, 97}, + dictWord{19, 0, 59}, + dictWord{150, 0, 2}, + dictWord{132, 0, 191}, + dictWord{5, 0, 165}, + dictWord{9, 0, 346}, + dictWord{10, 0, 655}, + dictWord{11, 0, 885}, + dictWord{4, 10, 430}, + dictWord{135, 11, 357}, + dictWord{133, 0, 877}, + dictWord{5, 10, 213}, + dictWord{133, 11, 406}, + dictWord{8, 0, 128}, + dictWord{139, 0, 179}, + dictWord{6, 11, 69}, + dictWord{135, 11, 117}, + dictWord{135, 0, 1297}, + dictWord{11, 11, 43}, + dictWord{13, 11, 72}, + dictWord{141, 11, 142}, + dictWord{135, 11, 1830}, + dictWord{ + 142, + 0, + 164, + }, + dictWord{5, 0, 57}, + dictWord{6, 0, 101}, + dictWord{6, 0, 586}, + dictWord{6, 0, 1663}, + dictWord{7, 0, 132}, + dictWord{7, 0, 1154}, + dictWord{7, 0, 1415}, + dictWord{7, 0, 1507}, + dictWord{12, 0, 493}, + dictWord{15, 0, 105}, + dictWord{151, 0, 15}, + dictWord{5, 0, 459}, + dictWord{7, 0, 1073}, + dictWord{8, 0, 241}, + dictWord{ + 136, + 0, + 334, + }, + dictWord{133, 11, 826}, + dictWord{133, 10, 108}, + dictWord{5, 10, 219}, + dictWord{10, 11, 132}, + dictWord{11, 11, 191}, + dictWord{11, 11, 358}, + dictWord{139, 11, 460}, + dictWord{6, 0, 324}, + dictWord{6, 0, 520}, + dictWord{7, 0, 338}, + dictWord{7, 0, 1729}, + dictWord{8, 0, 228}, + dictWord{139, 0, 750}, + dictWord{ + 21, + 0, + 30, + }, + dictWord{22, 0, 53}, + dictWord{4, 10, 193}, + dictWord{5, 10, 916}, + dictWord{7, 10, 364}, + dictWord{10, 10, 398}, + dictWord{10, 10, 726}, + dictWord{ + 11, + 10, + 317, + }, + dictWord{11, 10, 626}, + dictWord{12, 10, 142}, + dictWord{12, 10, 288}, + dictWord{12, 10, 678}, + dictWord{13, 10, 313}, + dictWord{15, 10, 113}, + dictWord{146, 10, 114}, + dictWord{6, 11, 110}, + dictWord{135, 11, 1681}, + dictWord{135, 0, 910}, + dictWord{6, 10, 241}, + dictWord{7, 10, 907}, + dictWord{8, 10, 832}, + dictWord{9, 10, 342}, + dictWord{10, 10, 729}, + dictWord{11, 10, 284}, + dictWord{11, 10, 445}, + dictWord{11, 10, 651}, + dictWord{11, 10, 863}, + dictWord{ + 13, + 10, + 398, + }, + dictWord{146, 10, 99}, + dictWord{7, 0, 705}, + dictWord{9, 0, 734}, + dictWord{5, 11, 1000}, + dictWord{7, 11, 733}, + dictWord{137, 11, 583}, + dictWord{4, 0, 73}, + dictWord{6, 0, 612}, + dictWord{7, 0, 927}, + dictWord{7, 0, 1822}, + dictWord{8, 0, 217}, + dictWord{9, 0, 765}, + dictWord{9, 0, 766}, + dictWord{10, 0, 408}, + dictWord{ + 11, + 0, + 51, + }, + dictWord{11, 0, 793}, + dictWord{12, 0, 266}, + dictWord{15, 0, 158}, + dictWord{20, 0, 89}, + dictWord{150, 0, 32}, + dictWord{7, 0, 1330}, + dictWord{4, 11, 297}, + dictWord{6, 11, 529}, + dictWord{7, 11, 152}, + dictWord{7, 11, 713}, + dictWord{7, 11, 1845}, + dictWord{8, 11, 710}, + dictWord{8, 11, 717}, + dictWord{140, 11, 639}, + dictWord{5, 0, 389}, + dictWord{136, 0, 636}, + dictWord{134, 0, 1409}, + dictWord{4, 10, 562}, + dictWord{9, 10, 254}, + dictWord{139, 10, 879}, + dictWord{134, 0, 893}, + dictWord{132, 10, 786}, + dictWord{4, 11, 520}, + dictWord{135, 11, 575}, + dictWord{136, 0, 21}, + dictWord{140, 0, 721}, + dictWord{136, 0, 959}, + dictWord{ + 7, + 11, + 1428, + }, + dictWord{7, 11, 1640}, + dictWord{9, 11, 169}, + dictWord{9, 11, 182}, + dictWord{9, 11, 367}, + dictWord{9, 11, 478}, + dictWord{9, 11, 506}, + dictWord{ + 9, + 11, + 551, + }, + dictWord{9, 11, 648}, + dictWord{9, 11, 651}, + dictWord{9, 11, 697}, + dictWord{9, 11, 705}, + dictWord{9, 11, 725}, + dictWord{9, 11, 787}, + dictWord{9, 11, 794}, + dictWord{10, 11, 198}, + dictWord{10, 11, 214}, + dictWord{10, 11, 267}, + dictWord{10, 11, 275}, + dictWord{10, 11, 456}, + dictWord{10, 11, 551}, + dictWord{ + 10, + 11, + 561, + }, + dictWord{10, 11, 613}, + dictWord{10, 11, 627}, + dictWord{10, 11, 668}, + dictWord{10, 11, 675}, + dictWord{10, 11, 691}, + dictWord{10, 11, 695}, + dictWord{10, 11, 707}, + dictWord{10, 11, 715}, + dictWord{11, 11, 183}, + dictWord{11, 11, 201}, + dictWord{11, 11, 244}, + dictWord{11, 11, 262}, + dictWord{ + 11, + 11, + 352, + }, + dictWord{11, 11, 439}, + dictWord{11, 11, 493}, + dictWord{11, 11, 572}, + dictWord{11, 11, 591}, + dictWord{11, 11, 608}, + dictWord{11, 11, 611}, + dictWord{ + 11, + 11, + 646, + }, + dictWord{11, 11, 674}, + dictWord{11, 11, 711}, + dictWord{11, 11, 751}, + dictWord{11, 11, 761}, + dictWord{11, 11, 776}, + dictWord{11, 11, 785}, + dictWord{11, 11, 850}, + dictWord{11, 11, 853}, + dictWord{11, 11, 862}, + dictWord{11, 11, 865}, + dictWord{11, 11, 868}, + dictWord{11, 11, 898}, + dictWord{ + 11, + 11, + 902, + }, + dictWord{11, 11, 903}, + dictWord{11, 11, 910}, + dictWord{11, 11, 932}, + dictWord{11, 11, 942}, + dictWord{11, 11, 957}, + dictWord{11, 11, 967}, + dictWord{ + 11, + 11, + 972, + }, + dictWord{12, 11, 148}, + dictWord{12, 11, 195}, + dictWord{12, 11, 220}, + dictWord{12, 11, 237}, + dictWord{12, 11, 318}, + dictWord{12, 11, 339}, + dictWord{12, 11, 393}, + dictWord{12, 11, 445}, + dictWord{12, 11, 450}, + dictWord{12, 11, 474}, + dictWord{12, 11, 509}, + dictWord{12, 11, 533}, + dictWord{ + 12, + 11, + 591, + }, + dictWord{12, 11, 594}, + dictWord{12, 11, 597}, + dictWord{12, 11, 621}, + dictWord{12, 11, 633}, + dictWord{12, 11, 642}, + dictWord{13, 11, 59}, + dictWord{ + 13, + 11, + 60, + }, + dictWord{13, 11, 145}, + dictWord{13, 11, 239}, + dictWord{13, 11, 250}, + dictWord{13, 11, 273}, + dictWord{13, 11, 329}, + dictWord{13, 11, 344}, + dictWord{13, 11, 365}, + dictWord{13, 11, 372}, + dictWord{13, 11, 387}, + dictWord{13, 11, 403}, + dictWord{13, 11, 414}, + dictWord{13, 11, 456}, + dictWord{ + 13, + 11, + 478, + }, + dictWord{13, 11, 483}, + dictWord{13, 11, 489}, + dictWord{14, 11, 55}, + dictWord{14, 11, 57}, + dictWord{14, 11, 81}, + dictWord{14, 11, 90}, + dictWord{ + 14, + 11, + 148, + }, + dictWord{14, 11, 239}, + dictWord{14, 11, 266}, + dictWord{14, 11, 321}, + dictWord{14, 11, 326}, + dictWord{14, 11, 327}, + dictWord{14, 11, 330}, + dictWord{ + 14, + 11, + 347, + }, + dictWord{14, 11, 355}, + dictWord{14, 11, 401}, + dictWord{14, 11, 411}, + dictWord{14, 11, 414}, + dictWord{14, 11, 416}, + dictWord{14, 11, 420}, + dictWord{15, 11, 61}, + dictWord{15, 11, 74}, + dictWord{15, 11, 87}, + dictWord{15, 11, 88}, + dictWord{15, 11, 94}, + dictWord{15, 11, 96}, + dictWord{15, 11, 116}, + dictWord{15, 11, 149}, + dictWord{15, 11, 154}, + dictWord{16, 11, 50}, + dictWord{16, 11, 63}, + dictWord{16, 11, 73}, + dictWord{17, 11, 2}, + dictWord{17, 11, 66}, + dictWord{ + 17, + 11, + 92, + }, + dictWord{17, 11, 103}, + dictWord{17, 11, 112}, + dictWord{18, 11, 50}, + dictWord{18, 11, 54}, + dictWord{18, 11, 82}, + dictWord{18, 11, 86}, + dictWord{ + 18, + 11, + 90, + }, + dictWord{18, 11, 111}, + dictWord{18, 11, 115}, + dictWord{18, 11, 156}, + dictWord{19, 11, 40}, + dictWord{19, 11, 79}, + dictWord{20, 11, 78}, + dictWord{ + 149, + 11, + 22, + }, + dictWord{137, 11, 170}, + dictWord{134, 0, 1433}, + dictWord{135, 11, 1307}, + dictWord{139, 11, 411}, + dictWord{5, 0, 189}, + dictWord{7, 0, 442}, + dictWord{7, 0, 443}, + dictWord{8, 0, 281}, + dictWord{12, 0, 174}, + dictWord{141, 0, 261}, + dictWord{6, 10, 216}, + dictWord{7, 10, 901}, + dictWord{7, 10, 1343}, + dictWord{136, 10, 493}, + dictWord{5, 11, 397}, + dictWord{6, 11, 154}, + dictWord{7, 10, 341}, + dictWord{7, 11, 676}, + dictWord{8, 11, 443}, + dictWord{8, 11, 609}, + dictWord{ + 9, + 11, + 24, + }, + dictWord{9, 11, 325}, + dictWord{10, 11, 35}, + dictWord{11, 10, 219}, + dictWord{11, 11, 535}, + dictWord{11, 11, 672}, + dictWord{11, 11, 1018}, + dictWord{12, 11, 637}, + dictWord{144, 11, 30}, + dictWord{6, 0, 2}, + dictWord{7, 0, 191}, + dictWord{7, 0, 446}, + dictWord{7, 0, 1262}, + dictWord{7, 0, 1737}, + dictWord{8, 0, 22}, + dictWord{8, 0, 270}, + dictWord{8, 0, 612}, + dictWord{9, 0, 4}, + dictWord{9, 0, 312}, + dictWord{9, 0, 436}, + dictWord{9, 0, 626}, + dictWord{10, 0, 216}, + dictWord{10, 0, 311}, + dictWord{10, 0, 521}, + dictWord{10, 0, 623}, + dictWord{11, 0, 72}, + dictWord{11, 0, 330}, + dictWord{11, 0, 455}, + dictWord{12, 0, 321}, + dictWord{12, 0, 504}, + dictWord{12, 0, 530}, + dictWord{12, 0, 543}, + dictWord{13, 0, 17}, + dictWord{13, 0, 156}, + dictWord{13, 0, 334}, + dictWord{14, 0, 131}, + dictWord{17, 0, 60}, + dictWord{ + 148, + 0, + 64, + }, + dictWord{7, 0, 354}, + dictWord{10, 0, 410}, + dictWord{139, 0, 815}, + dictWord{139, 10, 130}, + dictWord{7, 10, 1734}, + dictWord{137, 11, 631}, + dictWord{ + 12, + 0, + 425, + }, + dictWord{15, 0, 112}, + dictWord{10, 10, 115}, + dictWord{11, 10, 420}, + dictWord{13, 10, 404}, + dictWord{14, 10, 346}, + dictWord{143, 10, 54}, + dictWord{ + 6, + 0, + 60, + }, + dictWord{6, 0, 166}, + dictWord{7, 0, 374}, + dictWord{7, 0, 670}, + dictWord{7, 0, 1327}, + dictWord{8, 0, 411}, + dictWord{8, 0, 435}, + dictWord{9, 0, 653}, + dictWord{ + 9, + 0, + 740, + }, + dictWord{10, 0, 385}, + dictWord{11, 0, 222}, + dictWord{11, 0, 324}, + dictWord{11, 0, 829}, + dictWord{140, 0, 611}, + dictWord{7, 0, 1611}, + dictWord{ + 13, + 0, + 14, + }, + dictWord{15, 0, 44}, + dictWord{19, 0, 13}, + dictWord{148, 0, 76}, + dictWord{133, 11, 981}, + dictWord{4, 11, 56}, + dictWord{7, 11, 1791}, + dictWord{8, 11, 607}, + dictWord{8, 11, 651}, + dictWord{11, 11, 465}, + dictWord{11, 11, 835}, + dictWord{12, 11, 337}, + dictWord{141, 11, 480}, + dictWord{6, 0, 1478}, + dictWord{ + 5, + 10, + 1011, + }, + dictWord{136, 10, 701}, + dictWord{139, 0, 596}, + dictWord{5, 0, 206}, + dictWord{134, 0, 398}, + dictWord{4, 10, 54}, + dictWord{5, 10, 666}, + dictWord{ + 7, + 10, + 1039, + }, + dictWord{7, 10, 1130}, + dictWord{9, 10, 195}, + dictWord{138, 10, 302}, + dictWord{7, 0, 50}, + dictWord{9, 11, 158}, + dictWord{138, 11, 411}, + dictWord{ + 135, + 11, + 1120, + }, + dictWord{6, 0, 517}, + dictWord{7, 0, 1159}, + dictWord{10, 0, 621}, + dictWord{11, 0, 192}, + dictWord{134, 10, 1669}, + dictWord{4, 0, 592}, + dictWord{ + 6, + 0, + 600, + }, + dictWord{135, 0, 1653}, + dictWord{10, 0, 223}, + dictWord{139, 0, 645}, + dictWord{136, 11, 139}, + dictWord{7, 0, 64}, + dictWord{136, 0, 245}, + dictWord{ + 142, + 0, + 278, + }, + dictWord{6, 11, 622}, + dictWord{135, 11, 1030}, + dictWord{136, 0, 604}, + dictWord{134, 0, 1502}, + dictWord{138, 0, 265}, + dictWord{ + 141, + 11, + 168, + }, + dictWord{7, 0, 1763}, + dictWord{140, 0, 310}, + dictWord{7, 10, 798}, + dictWord{139, 11, 719}, + dictWord{7, 11, 160}, + dictWord{10, 11, 624}, + dictWord{ + 142, + 11, + 279, + }, + dictWord{132, 11, 363}, + dictWord{7, 10, 122}, + dictWord{9, 10, 259}, + dictWord{10, 10, 84}, + dictWord{11, 10, 470}, + dictWord{12, 10, 541}, + dictWord{141, 10, 379}, + dictWord{5, 0, 129}, + dictWord{6, 0, 61}, + dictWord{135, 0, 947}, + dictWord{134, 0, 1356}, + dictWord{135, 11, 1191}, + dictWord{13, 0, 505}, + dictWord{141, 0, 506}, + dictWord{11, 0, 1000}, + dictWord{5, 10, 82}, + dictWord{5, 10, 131}, + dictWord{7, 10, 1755}, + dictWord{8, 10, 31}, + dictWord{9, 10, 168}, + dictWord{9, 10, 764}, + dictWord{139, 10, 869}, + dictWord{134, 0, 966}, + dictWord{134, 10, 605}, + dictWord{134, 11, 292}, + dictWord{5, 11, 177}, + dictWord{ + 6, + 11, + 616, + }, + dictWord{7, 11, 827}, + dictWord{9, 11, 525}, + dictWord{138, 11, 656}, + dictWord{135, 11, 1486}, + dictWord{138, 11, 31}, + dictWord{5, 10, 278}, + dictWord{137, 10, 68}, + dictWord{4, 10, 163}, + dictWord{5, 10, 201}, + dictWord{5, 10, 307}, + dictWord{5, 10, 310}, + dictWord{6, 10, 335}, + dictWord{7, 10, 284}, + dictWord{136, 10, 165}, + dictWord{6, 0, 839}, + dictWord{135, 10, 1660}, + dictWord{136, 10, 781}, + dictWord{6, 10, 33}, + dictWord{135, 10, 1244}, + dictWord{ + 133, + 0, + 637, + }, + dictWord{4, 11, 161}, + dictWord{133, 11, 631}, + dictWord{137, 0, 590}, + dictWord{7, 10, 1953}, + dictWord{136, 10, 720}, + dictWord{5, 0, 280}, + dictWord{ + 7, + 0, + 1226, + }, + dictWord{138, 10, 203}, + dictWord{134, 0, 1386}, + dictWord{5, 0, 281}, + dictWord{6, 0, 1026}, + dictWord{6, 10, 326}, + dictWord{7, 10, 677}, + dictWord{ + 137, + 10, + 425, + }, + dictWord{7, 11, 1557}, + dictWord{135, 11, 1684}, + dictWord{135, 0, 1064}, + dictWord{9, 11, 469}, + dictWord{9, 11, 709}, + dictWord{12, 11, 512}, + dictWord{14, 11, 65}, + dictWord{145, 11, 12}, + dictWord{134, 0, 917}, + dictWord{10, 11, 229}, + dictWord{11, 11, 73}, + dictWord{11, 11, 376}, + dictWord{ + 139, + 11, + 433, + }, + dictWord{7, 0, 555}, + dictWord{9, 0, 192}, + dictWord{13, 0, 30}, + dictWord{13, 0, 49}, + dictWord{15, 0, 150}, + dictWord{16, 0, 76}, + dictWord{20, 0, 52}, + dictWord{ + 7, + 10, + 1316, + }, + dictWord{7, 10, 1412}, + dictWord{7, 10, 1839}, + dictWord{9, 10, 589}, + dictWord{11, 10, 241}, + dictWord{11, 10, 676}, + dictWord{11, 10, 811}, + dictWord{11, 10, 891}, + dictWord{12, 10, 140}, + dictWord{12, 10, 346}, + dictWord{12, 10, 479}, + dictWord{13, 10, 381}, + dictWord{14, 10, 188}, + dictWord{ + 146, + 10, + 30, + }, + dictWord{149, 0, 15}, + dictWord{6, 0, 1882}, + dictWord{6, 0, 1883}, + dictWord{6, 0, 1897}, + dictWord{9, 0, 945}, + dictWord{9, 0, 1014}, + dictWord{9, 0, 1020}, + dictWord{12, 0, 823}, + dictWord{12, 0, 842}, + dictWord{12, 0, 866}, + dictWord{12, 0, 934}, + dictWord{15, 0, 242}, + dictWord{146, 0, 208}, + dictWord{6, 0, 965}, + dictWord{134, 0, 1499}, + dictWord{7, 0, 33}, + dictWord{7, 0, 120}, + dictWord{8, 0, 489}, + dictWord{9, 0, 319}, + dictWord{10, 0, 820}, + dictWord{11, 0, 1004}, + dictWord{ + 12, + 0, + 379, + }, + dictWord{12, 0, 679}, + dictWord{13, 0, 117}, + dictWord{13, 0, 412}, + dictWord{14, 0, 25}, + dictWord{15, 0, 52}, + dictWord{15, 0, 161}, + dictWord{16, 0, 47}, + dictWord{149, 0, 2}, + dictWord{6, 11, 558}, + dictWord{7, 11, 651}, + dictWord{8, 11, 421}, + dictWord{9, 11, 0}, + dictWord{138, 11, 34}, + dictWord{4, 0, 937}, + dictWord{ + 5, + 0, + 801, + }, + dictWord{7, 0, 473}, + dictWord{5, 10, 358}, + dictWord{7, 10, 1184}, + dictWord{10, 10, 662}, + dictWord{13, 10, 212}, + dictWord{13, 10, 304}, + dictWord{ + 13, + 10, + 333, + }, + dictWord{145, 10, 98}, + dictWord{132, 0, 877}, + dictWord{6, 0, 693}, + dictWord{134, 0, 824}, + dictWord{132, 0, 365}, + dictWord{7, 11, 1832}, + dictWord{ + 138, + 11, + 374, + }, + dictWord{5, 0, 7}, + dictWord{139, 0, 774}, + dictWord{4, 0, 734}, + dictWord{5, 0, 662}, + dictWord{134, 0, 430}, + dictWord{4, 0, 746}, + dictWord{ + 135, + 0, + 1090, + }, + dictWord{5, 0, 360}, + dictWord{8, 0, 237}, + dictWord{10, 0, 231}, + dictWord{147, 0, 124}, + dictWord{138, 11, 348}, + dictWord{6, 11, 6}, + dictWord{7, 11, 81}, + dictWord{7, 11, 771}, + dictWord{7, 11, 1731}, + dictWord{9, 11, 405}, + dictWord{138, 11, 421}, + dictWord{6, 0, 740}, + dictWord{137, 0, 822}, + dictWord{ + 133, + 10, + 946, + }, + dictWord{7, 0, 1485}, + dictWord{136, 0, 929}, + dictWord{7, 10, 411}, + dictWord{8, 10, 631}, + dictWord{9, 10, 323}, + dictWord{10, 10, 355}, + dictWord{ + 11, + 10, + 491, + }, + dictWord{12, 10, 143}, + dictWord{12, 10, 402}, + dictWord{13, 10, 73}, + dictWord{14, 10, 408}, + dictWord{15, 10, 107}, + dictWord{146, 10, 71}, + dictWord{ + 135, + 10, + 590, + }, + dictWord{5, 11, 881}, + dictWord{133, 11, 885}, + dictWord{150, 11, 25}, + dictWord{4, 0, 852}, + dictWord{5, 11, 142}, + dictWord{134, 11, 546}, + dictWord{7, 10, 1467}, + dictWord{8, 10, 328}, + dictWord{10, 10, 544}, + dictWord{11, 10, 955}, + dictWord{13, 10, 320}, + dictWord{145, 10, 83}, + dictWord{9, 0, 17}, + dictWord{10, 0, 291}, + dictWord{11, 10, 511}, + dictWord{13, 10, 394}, + dictWord{14, 10, 298}, + dictWord{14, 10, 318}, + dictWord{146, 10, 103}, + dictWord{5, 11, 466}, + dictWord{11, 11, 571}, + dictWord{12, 11, 198}, + dictWord{13, 11, 283}, + dictWord{14, 11, 186}, + dictWord{15, 11, 21}, + dictWord{143, 11, 103}, + dictWord{ + 134, + 0, + 1001, + }, + dictWord{4, 11, 185}, + dictWord{5, 11, 257}, + dictWord{5, 11, 839}, + dictWord{5, 11, 936}, + dictWord{7, 11, 171}, + dictWord{9, 11, 399}, + dictWord{ + 10, + 11, + 258, + }, + dictWord{10, 11, 395}, + dictWord{10, 11, 734}, + dictWord{11, 11, 1014}, + dictWord{12, 11, 23}, + dictWord{13, 11, 350}, + dictWord{14, 11, 150}, + dictWord{147, 11, 6}, + dictWord{143, 0, 35}, + dictWord{132, 0, 831}, + dictWord{5, 10, 835}, + dictWord{134, 10, 483}, + dictWord{4, 0, 277}, + dictWord{5, 0, 608}, + dictWord{ + 6, + 0, + 493, + }, + dictWord{7, 0, 457}, + dictWord{12, 0, 384}, + dictWord{7, 11, 404}, + dictWord{7, 11, 1377}, + dictWord{7, 11, 1430}, + dictWord{7, 11, 2017}, + dictWord{ + 8, + 11, + 149, + }, + dictWord{8, 11, 239}, + dictWord{8, 11, 512}, + dictWord{8, 11, 793}, + dictWord{8, 11, 818}, + dictWord{9, 11, 474}, + dictWord{9, 11, 595}, + dictWord{ + 10, + 11, + 122, + }, + dictWord{10, 11, 565}, + dictWord{10, 11, 649}, + dictWord{10, 11, 783}, + dictWord{11, 11, 239}, + dictWord{11, 11, 295}, + dictWord{11, 11, 447}, + dictWord{ + 11, + 11, + 528, + }, + dictWord{11, 11, 639}, + dictWord{11, 11, 800}, + dictWord{11, 11, 936}, + dictWord{12, 11, 25}, + dictWord{12, 11, 73}, + dictWord{12, 11, 77}, + dictWord{12, 11, 157}, + dictWord{12, 11, 316}, + dictWord{12, 11, 390}, + dictWord{12, 11, 391}, + dictWord{12, 11, 394}, + dictWord{12, 11, 395}, + dictWord{ + 12, + 11, + 478, + }, + dictWord{12, 11, 503}, + dictWord{12, 11, 592}, + dictWord{12, 11, 680}, + dictWord{13, 11, 50}, + dictWord{13, 11, 53}, + dictWord{13, 11, 132}, + dictWord{ + 13, + 11, + 198, + }, + dictWord{13, 11, 275}, + dictWord{13, 11, 322}, + dictWord{13, 11, 415}, + dictWord{14, 11, 71}, + dictWord{14, 11, 257}, + dictWord{14, 11, 395}, + dictWord{15, 11, 71}, + dictWord{15, 11, 136}, + dictWord{17, 11, 123}, + dictWord{18, 11, 93}, + dictWord{147, 11, 58}, + dictWord{134, 0, 1351}, + dictWord{7, 0, 27}, + dictWord{135, 0, 316}, + dictWord{136, 11, 712}, + dictWord{136, 0, 984}, + dictWord{133, 0, 552}, + dictWord{137, 0, 264}, + dictWord{132, 0, 401}, + dictWord{6, 0, 710}, + dictWord{6, 0, 1111}, + dictWord{134, 0, 1343}, + dictWord{134, 0, 1211}, + dictWord{9, 0, 543}, + dictWord{10, 0, 524}, + dictWord{11, 0, 108}, + dictWord{11, 0, 653}, + dictWord{12, 0, 524}, + dictWord{13, 0, 123}, + dictWord{14, 0, 252}, + dictWord{16, 0, 18}, + dictWord{19, 0, 38}, + dictWord{20, 0, 26}, + dictWord{20, 0, 65}, + dictWord{ + 21, + 0, + 3, + }, + dictWord{151, 0, 11}, + dictWord{4, 0, 205}, + dictWord{5, 0, 623}, + dictWord{7, 0, 104}, + dictWord{8, 0, 519}, + dictWord{137, 0, 716}, + dictWord{132, 10, 677}, + dictWord{4, 11, 377}, + dictWord{152, 11, 13}, + dictWord{135, 11, 1673}, + dictWord{7, 0, 579}, + dictWord{9, 0, 41}, + dictWord{9, 0, 244}, + dictWord{9, 0, 669}, + dictWord{ + 10, + 0, + 5, + }, + dictWord{11, 0, 861}, + dictWord{11, 0, 951}, + dictWord{139, 0, 980}, + dictWord{132, 0, 717}, + dictWord{136, 0, 1011}, + dictWord{132, 0, 805}, + dictWord{ + 4, + 11, + 180, + }, + dictWord{135, 11, 1906}, + dictWord{132, 10, 777}, + dictWord{132, 10, 331}, + dictWord{132, 0, 489}, + dictWord{6, 0, 1024}, + dictWord{4, 11, 491}, + dictWord{133, 10, 747}, + dictWord{135, 11, 1182}, + dictWord{4, 11, 171}, + dictWord{138, 11, 234}, + dictWord{4, 11, 586}, + dictWord{7, 11, 1186}, + dictWord{ + 138, + 11, + 631, + }, + dictWord{135, 0, 892}, + dictWord{135, 11, 336}, + dictWord{9, 11, 931}, + dictWord{10, 11, 334}, + dictWord{148, 11, 71}, + dictWord{137, 0, 473}, + dictWord{6, 0, 864}, + dictWord{12, 0, 659}, + dictWord{139, 11, 926}, + dictWord{7, 0, 819}, + dictWord{9, 0, 26}, + dictWord{9, 0, 392}, + dictWord{10, 0, 152}, + dictWord{ + 10, + 0, + 226, + }, + dictWord{11, 0, 19}, + dictWord{12, 0, 276}, + dictWord{12, 0, 426}, + dictWord{12, 0, 589}, + dictWord{13, 0, 460}, + dictWord{15, 0, 97}, + dictWord{19, 0, 48}, + dictWord{148, 0, 104}, + dictWord{135, 0, 51}, + dictWord{133, 10, 326}, + dictWord{4, 10, 691}, + dictWord{146, 10, 16}, + dictWord{9, 0, 130}, + dictWord{11, 0, 765}, + dictWord{10, 10, 680}, + dictWord{10, 10, 793}, + dictWord{141, 10, 357}, + dictWord{133, 11, 765}, + dictWord{8, 0, 229}, + dictWord{6, 10, 32}, + dictWord{7, 10, 385}, + dictWord{7, 10, 757}, + dictWord{7, 10, 1916}, + dictWord{8, 10, 94}, + dictWord{8, 10, 711}, + dictWord{9, 10, 541}, + dictWord{10, 10, 162}, + dictWord{10, 10, 795}, + dictWord{11, 10, 989}, + dictWord{11, 10, 1010}, + dictWord{12, 10, 14}, + dictWord{142, 10, 308}, + dictWord{7, 11, 474}, + dictWord{137, 11, 578}, + dictWord{ + 132, + 0, + 674, + }, + dictWord{132, 0, 770}, + dictWord{5, 0, 79}, + dictWord{7, 0, 1027}, + dictWord{7, 0, 1477}, + dictWord{139, 0, 52}, + dictWord{133, 11, 424}, + dictWord{ + 134, + 0, + 1666, + }, + dictWord{6, 0, 409}, + dictWord{6, 10, 349}, + dictWord{6, 10, 1682}, + dictWord{7, 10, 1252}, + dictWord{8, 10, 112}, + dictWord{8, 11, 714}, + dictWord{ + 9, + 10, + 435, + }, + dictWord{9, 10, 668}, + dictWord{10, 10, 290}, + dictWord{10, 10, 319}, + dictWord{10, 10, 815}, + dictWord{11, 10, 180}, + dictWord{11, 10, 837}, + dictWord{ + 12, + 10, + 240, + }, + dictWord{13, 10, 152}, + dictWord{13, 10, 219}, + dictWord{142, 10, 158}, + dictWord{5, 0, 789}, + dictWord{134, 0, 195}, + dictWord{4, 0, 251}, + dictWord{ + 4, + 0, + 688, + }, + dictWord{7, 0, 513}, + dictWord{135, 0, 1284}, + dictWord{132, 10, 581}, + dictWord{9, 11, 420}, + dictWord{10, 11, 269}, + dictWord{10, 11, 285}, + dictWord{10, 11, 576}, + dictWord{11, 11, 397}, + dictWord{13, 11, 175}, + dictWord{145, 11, 90}, + dictWord{6, 10, 126}, + dictWord{7, 10, 573}, + dictWord{8, 10, 397}, + dictWord{142, 10, 44}, + dictWord{132, 11, 429}, + dictWord{133, 0, 889}, + dictWord{4, 0, 160}, + dictWord{5, 0, 330}, + dictWord{7, 0, 1434}, + dictWord{136, 0, 174}, + dictWord{7, 11, 18}, + dictWord{7, 11, 699}, + dictWord{7, 11, 1966}, + dictWord{8, 11, 752}, + dictWord{9, 11, 273}, + dictWord{9, 11, 412}, + dictWord{9, 11, 703}, + dictWord{ + 10, + 11, + 71, + }, + dictWord{10, 11, 427}, + dictWord{10, 11, 508}, + dictWord{146, 11, 97}, + dictWord{6, 0, 872}, + dictWord{134, 0, 899}, + dictWord{133, 10, 926}, + dictWord{134, 0, 1126}, + dictWord{134, 0, 918}, + dictWord{4, 11, 53}, + dictWord{5, 11, 186}, + dictWord{135, 11, 752}, + dictWord{7, 0, 268}, + dictWord{136, 0, 569}, + dictWord{134, 0, 1224}, + dictWord{6, 0, 1361}, + dictWord{7, 10, 1232}, + dictWord{137, 10, 531}, + dictWord{8, 11, 575}, + dictWord{10, 11, 289}, + dictWord{ + 139, + 11, + 319, + }, + dictWord{133, 10, 670}, + dictWord{132, 11, 675}, + dictWord{133, 0, 374}, + dictWord{135, 10, 1957}, + dictWord{133, 0, 731}, + dictWord{11, 0, 190}, + dictWord{15, 0, 49}, + dictWord{11, 11, 190}, + dictWord{143, 11, 49}, + dictWord{4, 0, 626}, + dictWord{5, 0, 506}, + dictWord{5, 0, 642}, + dictWord{6, 0, 425}, + dictWord{ + 10, + 0, + 202, + }, + dictWord{139, 0, 141}, + dictWord{137, 0, 444}, + dictWord{7, 10, 242}, + dictWord{135, 10, 1942}, + dictWord{6, 11, 209}, + dictWord{8, 11, 468}, + dictWord{ + 9, + 11, + 210, + }, + dictWord{11, 11, 36}, + dictWord{12, 11, 28}, + dictWord{12, 11, 630}, + dictWord{13, 11, 21}, + dictWord{13, 11, 349}, + dictWord{14, 11, 7}, + dictWord{ + 145, + 11, + 13, + }, + dictWord{4, 11, 342}, + dictWord{135, 11, 1179}, + dictWord{5, 10, 834}, + dictWord{7, 10, 1202}, + dictWord{8, 10, 14}, + dictWord{9, 10, 481}, + dictWord{ + 137, + 10, + 880, + }, + dictWord{4, 11, 928}, + dictWord{133, 11, 910}, + dictWord{4, 11, 318}, + dictWord{4, 11, 496}, + dictWord{7, 11, 856}, + dictWord{139, 11, 654}, + dictWord{136, 0, 835}, + dictWord{7, 0, 1526}, + dictWord{138, 10, 465}, + dictWord{151, 0, 17}, + dictWord{135, 0, 477}, + dictWord{4, 10, 357}, + dictWord{6, 10, 172}, + dictWord{7, 10, 143}, + dictWord{137, 10, 413}, + dictWord{6, 0, 1374}, + dictWord{138, 0, 994}, + dictWord{18, 0, 76}, + dictWord{132, 10, 590}, + dictWord{7, 0, 287}, + dictWord{8, 0, 355}, + dictWord{9, 0, 293}, + dictWord{137, 0, 743}, + dictWord{134, 0, 1389}, + dictWord{7, 11, 915}, + dictWord{8, 11, 247}, + dictWord{147, 11, 0}, + dictWord{ + 4, + 11, + 202, + }, + dictWord{5, 11, 382}, + dictWord{6, 11, 454}, + dictWord{7, 11, 936}, + dictWord{7, 11, 1803}, + dictWord{8, 11, 758}, + dictWord{9, 11, 375}, + dictWord{ + 9, + 11, + 895, + }, + dictWord{10, 11, 743}, + dictWord{10, 11, 792}, + dictWord{11, 11, 978}, + dictWord{11, 11, 1012}, + dictWord{142, 11, 109}, + dictWord{5, 0, 384}, + dictWord{8, 0, 455}, + dictWord{140, 0, 48}, + dictWord{132, 11, 390}, + dictWord{5, 10, 169}, + dictWord{7, 10, 333}, + dictWord{136, 10, 45}, + dictWord{5, 0, 264}, + dictWord{134, 0, 184}, + dictWord{138, 11, 791}, + dictWord{133, 11, 717}, + dictWord{132, 10, 198}, + dictWord{6, 11, 445}, + dictWord{7, 11, 332}, + dictWord{ + 137, + 11, + 909, + }, + dictWord{136, 0, 1001}, + dictWord{4, 10, 24}, + dictWord{5, 10, 140}, + dictWord{5, 10, 185}, + dictWord{7, 10, 1500}, + dictWord{11, 10, 565}, + dictWord{ + 139, + 10, + 838, + }, + dictWord{134, 11, 578}, + dictWord{5, 0, 633}, + dictWord{6, 0, 28}, + dictWord{135, 0, 1323}, + dictWord{132, 0, 851}, + dictWord{136, 11, 267}, + dictWord{ + 7, + 0, + 359, + }, + dictWord{8, 0, 243}, + dictWord{140, 0, 175}, + dictWord{4, 10, 334}, + dictWord{133, 10, 593}, + dictWord{141, 11, 87}, + dictWord{136, 11, 766}, + dictWord{10, 0, 287}, + dictWord{12, 0, 138}, + dictWord{10, 11, 287}, + dictWord{140, 11, 138}, + dictWord{4, 0, 105}, + dictWord{132, 0, 740}, + dictWord{140, 10, 116}, + dictWord{134, 0, 857}, + dictWord{135, 11, 1841}, + dictWord{6, 0, 1402}, + dictWord{137, 0, 819}, + dictWord{132, 11, 584}, + dictWord{132, 10, 709}, + dictWord{ + 133, + 10, + 897, + }, + dictWord{5, 0, 224}, + dictWord{13, 0, 174}, + dictWord{146, 0, 52}, + dictWord{135, 10, 1840}, + dictWord{4, 10, 608}, + dictWord{133, 10, 497}, + dictWord{139, 11, 60}, + dictWord{4, 0, 758}, + dictWord{135, 0, 1649}, + dictWord{4, 11, 226}, + dictWord{4, 11, 326}, + dictWord{135, 11, 1770}, + dictWord{5, 11, 426}, + dictWord{8, 11, 30}, + dictWord{9, 11, 2}, + dictWord{11, 11, 549}, + dictWord{147, 11, 122}, + dictWord{135, 10, 2039}, + dictWord{6, 10, 540}, + dictWord{ + 136, + 10, + 136, + }, + dictWord{4, 0, 573}, + dictWord{8, 0, 655}, + dictWord{4, 10, 897}, + dictWord{133, 10, 786}, + dictWord{7, 0, 351}, + dictWord{139, 0, 128}, + dictWord{ + 133, + 10, + 999, + }, + dictWord{4, 10, 299}, + dictWord{135, 10, 1004}, + dictWord{133, 0, 918}, + dictWord{132, 11, 345}, + dictWord{4, 11, 385}, + dictWord{7, 11, 265}, + dictWord{135, 11, 587}, + dictWord{133, 10, 456}, + dictWord{136, 10, 180}, + dictWord{6, 0, 687}, + dictWord{134, 0, 1537}, + dictWord{4, 11, 347}, + dictWord{ + 5, + 11, + 423, + }, + dictWord{5, 11, 996}, + dictWord{135, 11, 1329}, + dictWord{132, 10, 755}, + dictWord{7, 11, 1259}, + dictWord{9, 11, 125}, + dictWord{11, 11, 65}, + dictWord{140, 11, 285}, + dictWord{5, 11, 136}, + dictWord{6, 11, 136}, + dictWord{136, 11, 644}, + dictWord{134, 0, 1525}, + dictWord{4, 0, 1009}, + dictWord{ + 135, + 0, + 1139, + }, + dictWord{139, 10, 338}, + dictWord{132, 0, 340}, + dictWord{135, 10, 1464}, + dictWord{8, 0, 847}, + dictWord{10, 0, 861}, + dictWord{10, 0, 876}, + dictWord{ + 10, + 0, + 889, + }, + dictWord{10, 0, 922}, + dictWord{10, 0, 929}, + dictWord{10, 0, 933}, + dictWord{12, 0, 784}, + dictWord{140, 0, 791}, + dictWord{139, 0, 176}, + dictWord{ + 9, + 11, + 134, + }, + dictWord{10, 11, 2}, + dictWord{10, 11, 27}, + dictWord{10, 11, 333}, + dictWord{11, 11, 722}, + dictWord{143, 11, 1}, + dictWord{4, 11, 433}, + dictWord{ + 133, + 11, + 719, + }, + dictWord{5, 0, 985}, + dictWord{7, 0, 509}, + dictWord{7, 0, 529}, + dictWord{145, 0, 96}, + dictWord{132, 0, 615}, + dictWord{4, 10, 890}, + dictWord{ + 5, + 10, + 805, + }, + dictWord{5, 10, 819}, + dictWord{5, 10, 961}, + dictWord{6, 10, 396}, + dictWord{6, 10, 1631}, + dictWord{6, 10, 1678}, + dictWord{7, 10, 1967}, + dictWord{ + 7, + 10, + 2041, + }, + dictWord{9, 10, 630}, + dictWord{11, 10, 8}, + dictWord{11, 10, 1019}, + dictWord{12, 10, 176}, + dictWord{13, 10, 225}, + dictWord{14, 10, 292}, + dictWord{ + 149, + 10, + 24, + }, + dictWord{135, 0, 1919}, + dictWord{134, 0, 1131}, + dictWord{144, 11, 21}, + dictWord{144, 11, 51}, + dictWord{135, 10, 1815}, + dictWord{4, 0, 247}, + dictWord{7, 10, 1505}, + dictWord{10, 10, 190}, + dictWord{10, 10, 634}, + dictWord{11, 10, 792}, + dictWord{12, 10, 358}, + dictWord{140, 10, 447}, + dictWord{ + 5, + 10, + 0, + }, + dictWord{6, 10, 536}, + dictWord{7, 10, 604}, + dictWord{13, 10, 445}, + dictWord{145, 10, 126}, + dictWord{4, 0, 184}, + dictWord{5, 0, 390}, + dictWord{6, 0, 337}, + dictWord{7, 0, 23}, + dictWord{7, 0, 494}, + dictWord{7, 0, 618}, + dictWord{7, 0, 1456}, + dictWord{8, 0, 27}, + dictWord{8, 0, 599}, + dictWord{10, 0, 153}, + dictWord{ + 139, + 0, + 710, + }, + dictWord{6, 10, 232}, + dictWord{6, 10, 412}, + dictWord{7, 10, 1074}, + dictWord{8, 10, 9}, + dictWord{8, 10, 157}, + dictWord{8, 10, 786}, + dictWord{9, 10, 196}, + dictWord{9, 10, 352}, + dictWord{9, 10, 457}, + dictWord{10, 10, 337}, + dictWord{11, 10, 232}, + dictWord{11, 10, 877}, + dictWord{12, 10, 480}, + dictWord{ + 140, + 10, + 546, + }, + dictWord{13, 0, 38}, + dictWord{135, 10, 958}, + dictWord{4, 10, 382}, + dictWord{136, 10, 579}, + dictWord{4, 10, 212}, + dictWord{135, 10, 1206}, + dictWord{ + 4, + 11, + 555, + }, + dictWord{8, 11, 536}, + dictWord{138, 11, 288}, + dictWord{11, 11, 139}, + dictWord{139, 11, 171}, + dictWord{9, 11, 370}, + dictWord{138, 11, 90}, + dictWord{132, 0, 1015}, + dictWord{134, 0, 1088}, + dictWord{5, 10, 655}, + dictWord{135, 11, 977}, + dictWord{134, 0, 1585}, + dictWord{17, 10, 67}, + dictWord{ + 147, + 10, + 74, + }, + dictWord{10, 0, 227}, + dictWord{11, 0, 497}, + dictWord{11, 0, 709}, + dictWord{140, 0, 415}, + dictWord{6, 0, 360}, + dictWord{7, 0, 1664}, + dictWord{ + 136, + 0, + 478, + }, + dictWord{7, 0, 95}, + dictWord{6, 10, 231}, + dictWord{136, 10, 423}, + dictWord{140, 11, 65}, + dictWord{4, 11, 257}, + dictWord{135, 11, 2031}, + dictWord{ + 135, + 11, + 1768, + }, + dictWord{133, 10, 300}, + dictWord{139, 11, 211}, + dictWord{136, 0, 699}, + dictWord{6, 10, 237}, + dictWord{7, 10, 611}, + dictWord{8, 10, 100}, + dictWord{9, 10, 416}, + dictWord{11, 10, 335}, + dictWord{12, 10, 173}, + dictWord{146, 10, 101}, + dictWord{14, 0, 26}, + dictWord{146, 0, 150}, + dictWord{6, 0, 581}, + dictWord{135, 0, 1119}, + dictWord{135, 10, 1208}, + dictWord{132, 0, 739}, + dictWord{6, 11, 83}, + dictWord{6, 11, 1733}, + dictWord{135, 11, 1389}, + dictWord{ + 137, + 0, + 869, + }, + dictWord{4, 0, 67}, + dictWord{5, 0, 422}, + dictWord{7, 0, 1037}, + dictWord{7, 0, 1289}, + dictWord{7, 0, 1555}, + dictWord{9, 0, 741}, + dictWord{145, 0, 108}, + dictWord{133, 10, 199}, + dictWord{12, 10, 427}, + dictWord{146, 10, 38}, + dictWord{136, 0, 464}, + dictWord{142, 0, 42}, + dictWord{10, 0, 96}, + dictWord{8, 11, 501}, + dictWord{137, 11, 696}, + dictWord{134, 11, 592}, + dictWord{4, 0, 512}, + dictWord{4, 0, 966}, + dictWord{5, 0, 342}, + dictWord{6, 0, 1855}, + dictWord{8, 0, 869}, + dictWord{8, 0, 875}, + dictWord{8, 0, 901}, + dictWord{144, 0, 26}, + dictWord{8, 0, 203}, + dictWord{11, 0, 823}, + dictWord{11, 0, 846}, + dictWord{12, 0, 482}, + dictWord{ + 13, + 0, + 277, + }, + dictWord{13, 0, 302}, + dictWord{13, 0, 464}, + dictWord{14, 0, 205}, + dictWord{142, 0, 221}, + dictWord{4, 0, 449}, + dictWord{133, 0, 718}, + dictWord{ + 7, + 11, + 1718, + }, + dictWord{9, 11, 95}, + dictWord{9, 11, 274}, + dictWord{10, 11, 279}, + dictWord{10, 11, 317}, + dictWord{10, 11, 420}, + dictWord{11, 11, 303}, + dictWord{ + 11, + 11, + 808, + }, + dictWord{12, 11, 134}, + dictWord{12, 11, 367}, + dictWord{13, 11, 149}, + dictWord{13, 11, 347}, + dictWord{14, 11, 349}, + dictWord{14, 11, 406}, + dictWord{18, 11, 22}, + dictWord{18, 11, 89}, + dictWord{18, 11, 122}, + dictWord{147, 11, 47}, + dictWord{133, 11, 26}, + dictWord{4, 0, 355}, + dictWord{6, 0, 311}, + dictWord{ + 9, + 0, + 256, + }, + dictWord{138, 0, 404}, + dictWord{132, 11, 550}, + dictWord{10, 0, 758}, + dictWord{6, 10, 312}, + dictWord{6, 10, 1715}, + dictWord{10, 10, 584}, + dictWord{11, 10, 546}, + dictWord{11, 10, 692}, + dictWord{12, 10, 259}, + dictWord{12, 10, 295}, + dictWord{13, 10, 46}, + dictWord{141, 10, 154}, + dictWord{ + 136, + 11, + 822, + }, + dictWord{5, 0, 827}, + dictWord{4, 11, 902}, + dictWord{5, 11, 809}, + dictWord{6, 11, 122}, + dictWord{135, 11, 896}, + dictWord{5, 0, 64}, + dictWord{140, 0, 581}, + dictWord{4, 0, 442}, + dictWord{6, 0, 739}, + dictWord{7, 0, 1047}, + dictWord{7, 0, 1352}, + dictWord{7, 0, 1643}, + dictWord{7, 11, 1911}, + dictWord{9, 11, 449}, + dictWord{10, 11, 192}, + dictWord{138, 11, 740}, + dictWord{135, 11, 262}, + dictWord{132, 10, 588}, + dictWord{133, 11, 620}, + dictWord{5, 0, 977}, + dictWord{ + 6, + 0, + 288, + }, + dictWord{7, 0, 528}, + dictWord{4, 11, 34}, + dictWord{5, 11, 574}, + dictWord{7, 11, 279}, + dictWord{7, 11, 1624}, + dictWord{136, 11, 601}, + dictWord{ + 6, + 0, + 1375, + }, + dictWord{4, 10, 231}, + dictWord{5, 10, 61}, + dictWord{6, 10, 104}, + dictWord{7, 10, 729}, + dictWord{7, 10, 964}, + dictWord{7, 10, 1658}, + dictWord{ + 140, + 10, + 414, + }, + dictWord{6, 10, 263}, + dictWord{138, 10, 757}, + dictWord{132, 10, 320}, + dictWord{4, 0, 254}, + dictWord{7, 0, 1309}, + dictWord{5, 11, 332}, + dictWord{ + 135, + 11, + 1309, + }, + dictWord{6, 11, 261}, + dictWord{8, 11, 182}, + dictWord{139, 11, 943}, + dictWord{132, 10, 225}, + dictWord{6, 0, 12}, + dictWord{135, 0, 1219}, + dictWord{4, 0, 275}, + dictWord{12, 0, 376}, + dictWord{6, 11, 1721}, + dictWord{141, 11, 490}, + dictWord{4, 11, 933}, + dictWord{133, 11, 880}, + dictWord{6, 0, 951}, + dictWord{6, 0, 1109}, + dictWord{6, 0, 1181}, + dictWord{7, 0, 154}, + dictWord{4, 10, 405}, + dictWord{7, 10, 817}, + dictWord{14, 10, 58}, + dictWord{17, 10, 37}, + dictWord{ + 146, + 10, + 124, + }, + dictWord{6, 0, 1520}, + dictWord{133, 10, 974}, + dictWord{134, 0, 1753}, + dictWord{6, 0, 369}, + dictWord{6, 0, 502}, + dictWord{7, 0, 1036}, + dictWord{ + 8, + 0, + 348, + }, + dictWord{9, 0, 452}, + dictWord{10, 0, 26}, + dictWord{11, 0, 224}, + dictWord{11, 0, 387}, + dictWord{11, 0, 772}, + dictWord{12, 0, 95}, + dictWord{12, 0, 629}, + dictWord{13, 0, 195}, + dictWord{13, 0, 207}, + dictWord{13, 0, 241}, + dictWord{14, 0, 260}, + dictWord{14, 0, 270}, + dictWord{143, 0, 140}, + dictWord{132, 0, 269}, + dictWord{5, 0, 480}, + dictWord{7, 0, 532}, + dictWord{7, 0, 1197}, + dictWord{7, 0, 1358}, + dictWord{8, 0, 291}, + dictWord{11, 0, 349}, + dictWord{142, 0, 396}, + dictWord{ + 5, + 10, + 235, + }, + dictWord{7, 10, 1239}, + dictWord{11, 10, 131}, + dictWord{140, 10, 370}, + dictWord{7, 10, 956}, + dictWord{7, 10, 1157}, + dictWord{7, 10, 1506}, + dictWord{ + 7, + 10, + 1606, + }, + dictWord{7, 10, 1615}, + dictWord{7, 10, 1619}, + dictWord{7, 10, 1736}, + dictWord{7, 10, 1775}, + dictWord{8, 10, 590}, + dictWord{9, 10, 324}, + dictWord{9, 10, 736}, + dictWord{9, 10, 774}, + dictWord{9, 10, 776}, + dictWord{9, 10, 784}, + dictWord{10, 10, 567}, + dictWord{10, 10, 708}, + dictWord{11, 10, 518}, + dictWord{11, 10, 613}, + dictWord{11, 10, 695}, + dictWord{11, 10, 716}, + dictWord{11, 10, 739}, + dictWord{11, 10, 770}, + dictWord{11, 10, 771}, + dictWord{ + 11, + 10, + 848, + }, + dictWord{11, 10, 857}, + dictWord{11, 10, 931}, + dictWord{11, 10, 947}, + dictWord{12, 10, 326}, + dictWord{12, 10, 387}, + dictWord{12, 10, 484}, + dictWord{ + 12, + 10, + 528, + }, + dictWord{12, 10, 552}, + dictWord{12, 10, 613}, + dictWord{13, 10, 189}, + dictWord{13, 10, 256}, + dictWord{13, 10, 340}, + dictWord{13, 10, 432}, + dictWord{13, 10, 436}, + dictWord{13, 10, 440}, + dictWord{13, 10, 454}, + dictWord{14, 10, 174}, + dictWord{14, 10, 220}, + dictWord{14, 10, 284}, + dictWord{ + 14, + 10, + 390, + }, + dictWord{145, 10, 121}, + dictWord{8, 11, 598}, + dictWord{9, 11, 664}, + dictWord{138, 11, 441}, + dictWord{9, 10, 137}, + dictWord{138, 10, 221}, + dictWord{133, 11, 812}, + dictWord{148, 0, 15}, + dictWord{134, 0, 1341}, + dictWord{6, 0, 1017}, + dictWord{4, 11, 137}, + dictWord{7, 11, 1178}, + dictWord{ + 135, + 11, + 1520, + }, + dictWord{7, 10, 390}, + dictWord{138, 10, 140}, + dictWord{7, 11, 1260}, + dictWord{135, 11, 1790}, + dictWord{137, 11, 191}, + dictWord{ + 135, + 10, + 1144, + }, + dictWord{6, 0, 1810}, + dictWord{7, 0, 657}, + dictWord{8, 0, 886}, + dictWord{10, 0, 857}, + dictWord{14, 0, 440}, + dictWord{144, 0, 96}, + dictWord{8, 0, 533}, + dictWord{6, 11, 1661}, + dictWord{7, 11, 1975}, + dictWord{7, 11, 2009}, + dictWord{135, 11, 2011}, + dictWord{6, 0, 1453}, + dictWord{134, 10, 464}, + dictWord{ + 132, + 11, + 715, + }, + dictWord{5, 10, 407}, + dictWord{11, 10, 204}, + dictWord{11, 10, 243}, + dictWord{11, 10, 489}, + dictWord{12, 10, 293}, + dictWord{19, 10, 37}, + dictWord{20, 10, 73}, + dictWord{150, 10, 38}, + dictWord{133, 11, 703}, + dictWord{4, 0, 211}, + dictWord{7, 0, 1483}, + dictWord{5, 10, 325}, + dictWord{8, 10, 5}, + dictWord{ + 8, + 10, + 227, + }, + dictWord{9, 10, 105}, + dictWord{10, 10, 585}, + dictWord{140, 10, 614}, + dictWord{4, 0, 332}, + dictWord{5, 0, 335}, + dictWord{6, 0, 238}, + dictWord{ + 7, + 0, + 269, + }, + dictWord{7, 0, 811}, + dictWord{7, 0, 1797}, + dictWord{8, 0, 836}, + dictWord{9, 0, 507}, + dictWord{141, 0, 242}, + dictWord{5, 11, 89}, + dictWord{7, 11, 1915}, + dictWord{9, 11, 185}, + dictWord{9, 11, 235}, + dictWord{9, 11, 496}, + dictWord{10, 11, 64}, + dictWord{10, 11, 270}, + dictWord{10, 11, 403}, + dictWord{10, 11, 469}, + dictWord{10, 11, 529}, + dictWord{10, 11, 590}, + dictWord{11, 11, 140}, + dictWord{11, 11, 860}, + dictWord{13, 11, 1}, + dictWord{13, 11, 422}, + dictWord{14, 11, 341}, + dictWord{14, 11, 364}, + dictWord{17, 11, 93}, + dictWord{18, 11, 113}, + dictWord{19, 11, 97}, + dictWord{147, 11, 113}, + dictWord{133, 11, 695}, + dictWord{ + 16, + 0, + 19, + }, + dictWord{5, 11, 6}, + dictWord{6, 11, 183}, + dictWord{6, 10, 621}, + dictWord{7, 11, 680}, + dictWord{7, 11, 978}, + dictWord{7, 11, 1013}, + dictWord{7, 11, 1055}, + dictWord{12, 11, 230}, + dictWord{13, 11, 172}, + dictWord{13, 10, 504}, + dictWord{146, 11, 29}, + dictWord{136, 0, 156}, + dictWord{133, 0, 1009}, + dictWord{ + 6, + 11, + 29, + }, + dictWord{139, 11, 63}, + dictWord{134, 0, 820}, + dictWord{134, 10, 218}, + dictWord{7, 10, 454}, + dictWord{7, 10, 782}, + dictWord{8, 10, 768}, + dictWord{ + 140, + 10, + 686, + }, + dictWord{5, 0, 228}, + dictWord{6, 0, 203}, + dictWord{7, 0, 156}, + dictWord{8, 0, 347}, + dictWord{9, 0, 265}, + dictWord{18, 0, 39}, + dictWord{20, 0, 54}, + dictWord{21, 0, 31}, + dictWord{22, 0, 3}, + dictWord{23, 0, 0}, + dictWord{15, 11, 8}, + dictWord{18, 11, 39}, + dictWord{20, 11, 54}, + dictWord{21, 11, 31}, + dictWord{22, 11, 3}, + dictWord{151, 11, 0}, + dictWord{7, 0, 1131}, + dictWord{135, 0, 1468}, + dictWord{144, 10, 0}, + dictWord{134, 0, 1276}, + dictWord{10, 10, 676}, + dictWord{ + 140, + 10, + 462, + }, + dictWord{132, 11, 311}, + dictWord{134, 11, 1740}, + dictWord{7, 11, 170}, + dictWord{8, 11, 90}, + dictWord{8, 11, 177}, + dictWord{8, 11, 415}, + dictWord{ + 11, + 11, + 714, + }, + dictWord{142, 11, 281}, + dictWord{134, 10, 164}, + dictWord{6, 0, 1792}, + dictWord{138, 0, 849}, + dictWord{150, 10, 50}, + dictWord{5, 0, 291}, + dictWord{5, 0, 318}, + dictWord{7, 0, 765}, + dictWord{9, 0, 389}, + dictWord{12, 0, 548}, + dictWord{8, 11, 522}, + dictWord{142, 11, 328}, + dictWord{11, 11, 91}, + dictWord{ + 13, + 11, + 129, + }, + dictWord{15, 11, 101}, + dictWord{145, 11, 125}, + dictWord{4, 11, 494}, + dictWord{6, 11, 74}, + dictWord{7, 11, 44}, + dictWord{7, 11, 407}, + dictWord{ + 8, + 11, + 551, + }, + dictWord{12, 11, 17}, + dictWord{15, 11, 5}, + dictWord{148, 11, 11}, + dictWord{4, 11, 276}, + dictWord{133, 11, 296}, + dictWord{6, 10, 343}, + dictWord{ + 7, + 10, + 195, + }, + dictWord{7, 11, 1777}, + dictWord{9, 10, 226}, + dictWord{10, 10, 197}, + dictWord{10, 10, 575}, + dictWord{11, 10, 502}, + dictWord{139, 10, 899}, + dictWord{ + 10, + 0, + 525, + }, + dictWord{139, 0, 82}, + dictWord{14, 0, 453}, + dictWord{4, 11, 7}, + dictWord{5, 11, 90}, + dictWord{5, 11, 158}, + dictWord{6, 11, 542}, + dictWord{7, 11, 221}, + dictWord{7, 11, 1574}, + dictWord{9, 11, 490}, + dictWord{10, 11, 540}, + dictWord{11, 11, 443}, + dictWord{139, 11, 757}, + dictWord{135, 0, 666}, + dictWord{ + 22, + 10, + 29, + }, + dictWord{150, 11, 29}, + dictWord{4, 0, 422}, + dictWord{147, 10, 8}, + dictWord{5, 0, 355}, + dictWord{145, 0, 0}, + dictWord{6, 0, 1873}, + dictWord{9, 0, 918}, + dictWord{7, 11, 588}, + dictWord{9, 11, 175}, + dictWord{138, 11, 530}, + dictWord{143, 11, 31}, + dictWord{11, 0, 165}, + dictWord{7, 10, 1125}, + dictWord{9, 10, 143}, + dictWord{14, 10, 405}, + dictWord{150, 10, 21}, + dictWord{9, 0, 260}, + dictWord{137, 0, 905}, + dictWord{5, 11, 872}, + dictWord{6, 11, 57}, + dictWord{6, 11, 479}, + dictWord{ + 6, + 11, + 562, + }, + dictWord{7, 11, 471}, + dictWord{7, 11, 1060}, + dictWord{9, 11, 447}, + dictWord{9, 11, 454}, + dictWord{141, 11, 6}, + dictWord{138, 11, 704}, + dictWord{133, 0, 865}, + dictWord{5, 0, 914}, + dictWord{134, 0, 1625}, + dictWord{133, 0, 234}, + dictWord{7, 0, 1383}, + dictWord{5, 11, 31}, + dictWord{6, 11, 614}, + dictWord{145, 11, 61}, + dictWord{7, 11, 1200}, + dictWord{138, 11, 460}, + dictWord{6, 11, 424}, + dictWord{135, 11, 1866}, + dictWord{136, 0, 306}, + dictWord{ + 5, + 10, + 959, + }, + dictWord{12, 11, 30}, + dictWord{13, 11, 148}, + dictWord{14, 11, 87}, + dictWord{14, 11, 182}, + dictWord{16, 11, 42}, + dictWord{18, 11, 92}, + dictWord{ + 148, + 11, + 70, + }, + dictWord{6, 0, 1919}, + dictWord{6, 0, 1921}, + dictWord{9, 0, 923}, + dictWord{9, 0, 930}, + dictWord{9, 0, 941}, + dictWord{9, 0, 949}, + dictWord{9, 0, 987}, + dictWord{ + 9, + 0, + 988, + }, + dictWord{9, 0, 992}, + dictWord{12, 0, 802}, + dictWord{12, 0, 815}, + dictWord{12, 0, 856}, + dictWord{12, 0, 885}, + dictWord{12, 0, 893}, + dictWord{ + 12, + 0, + 898, + }, + dictWord{12, 0, 919}, + dictWord{12, 0, 920}, + dictWord{12, 0, 941}, + dictWord{12, 0, 947}, + dictWord{15, 0, 183}, + dictWord{15, 0, 185}, + dictWord{15, 0, 189}, + dictWord{15, 0, 197}, + dictWord{15, 0, 202}, + dictWord{15, 0, 233}, + dictWord{18, 0, 218}, + dictWord{18, 0, 219}, + dictWord{18, 0, 233}, + dictWord{143, 11, 156}, + dictWord{135, 10, 1759}, + dictWord{136, 10, 173}, + dictWord{13, 0, 163}, + dictWord{13, 0, 180}, + dictWord{18, 0, 78}, + dictWord{20, 0, 35}, + dictWord{5, 11, 13}, + dictWord{134, 11, 142}, + dictWord{134, 10, 266}, + dictWord{6, 11, 97}, + dictWord{7, 11, 116}, + dictWord{8, 11, 322}, + dictWord{8, 11, 755}, + dictWord{9, 11, 548}, + dictWord{10, 11, 714}, + dictWord{11, 11, 884}, + dictWord{141, 11, 324}, + dictWord{135, 0, 1312}, + dictWord{9, 0, 814}, + dictWord{137, 11, 676}, + dictWord{ + 133, + 0, + 707, + }, + dictWord{135, 0, 1493}, + dictWord{6, 0, 421}, + dictWord{7, 0, 61}, + dictWord{7, 0, 1540}, + dictWord{10, 0, 11}, + dictWord{138, 0, 501}, + dictWord{12, 0, 733}, + dictWord{12, 0, 766}, + dictWord{7, 11, 866}, + dictWord{135, 11, 1163}, + dictWord{137, 0, 341}, + dictWord{142, 0, 98}, + dictWord{145, 11, 115}, + dictWord{ + 135, + 11, + 1111, + }, + dictWord{136, 10, 300}, + dictWord{136, 0, 1014}, + dictWord{8, 11, 1}, + dictWord{9, 11, 112}, + dictWord{138, 11, 326}, + dictWord{132, 11, 730}, + dictWord{5, 11, 488}, + dictWord{6, 11, 527}, + dictWord{7, 11, 489}, + dictWord{7, 11, 1636}, + dictWord{8, 11, 121}, + dictWord{8, 11, 144}, + dictWord{8, 11, 359}, + dictWord{ + 9, + 11, + 193, + }, + dictWord{9, 11, 241}, + dictWord{9, 11, 336}, + dictWord{9, 11, 882}, + dictWord{11, 11, 266}, + dictWord{11, 11, 372}, + dictWord{11, 11, 944}, + dictWord{ + 12, + 11, + 401, + }, + dictWord{140, 11, 641}, + dictWord{6, 0, 971}, + dictWord{134, 0, 1121}, + dictWord{6, 0, 102}, + dictWord{7, 0, 72}, + dictWord{15, 0, 142}, + dictWord{ + 147, + 0, + 67, + }, + dictWord{151, 0, 30}, + dictWord{135, 0, 823}, + dictWord{134, 0, 1045}, + dictWord{5, 10, 427}, + dictWord{5, 10, 734}, + dictWord{7, 10, 478}, + dictWord{ + 136, + 10, + 52, + }, + dictWord{7, 0, 1930}, + dictWord{11, 10, 217}, + dictWord{142, 10, 165}, + dictWord{6, 0, 1512}, + dictWord{135, 0, 1870}, + dictWord{9, 11, 31}, + dictWord{ + 10, + 11, + 244, + }, + dictWord{10, 11, 699}, + dictWord{12, 11, 149}, + dictWord{141, 11, 497}, + dictWord{133, 11, 377}, + dictWord{145, 11, 101}, + dictWord{ + 10, + 11, + 158, + }, + dictWord{13, 11, 13}, + dictWord{13, 11, 137}, + dictWord{13, 11, 258}, + dictWord{14, 11, 111}, + dictWord{14, 11, 225}, + dictWord{14, 11, 253}, + dictWord{ + 14, + 11, + 304, + }, + dictWord{14, 11, 339}, + dictWord{14, 11, 417}, + dictWord{146, 11, 33}, + dictWord{6, 0, 87}, + dictWord{6, 10, 1734}, + dictWord{7, 10, 20}, + dictWord{ + 7, + 10, + 1056, + }, + dictWord{8, 10, 732}, + dictWord{9, 10, 406}, + dictWord{9, 10, 911}, + dictWord{138, 10, 694}, + dictWord{134, 0, 1243}, + dictWord{137, 0, 245}, + dictWord{ + 7, + 0, + 68, + }, + dictWord{8, 0, 48}, + dictWord{8, 0, 88}, + dictWord{8, 0, 582}, + dictWord{8, 0, 681}, + dictWord{9, 0, 373}, + dictWord{9, 0, 864}, + dictWord{11, 0, 157}, + dictWord{ + 11, + 0, + 336, + }, + dictWord{11, 0, 843}, + dictWord{148, 0, 27}, + dictWord{8, 11, 663}, + dictWord{144, 11, 8}, + dictWord{133, 10, 613}, + dictWord{4, 0, 88}, + dictWord{ + 5, + 0, + 137, + }, + dictWord{5, 0, 174}, + dictWord{5, 0, 777}, + dictWord{6, 0, 1664}, + dictWord{6, 0, 1725}, + dictWord{7, 0, 77}, + dictWord{7, 0, 426}, + dictWord{7, 0, 1317}, + dictWord{ + 7, + 0, + 1355, + }, + dictWord{8, 0, 126}, + dictWord{8, 0, 563}, + dictWord{9, 0, 523}, + dictWord{9, 0, 750}, + dictWord{10, 0, 310}, + dictWord{10, 0, 836}, + dictWord{11, 0, 42}, + dictWord{11, 0, 318}, + dictWord{11, 0, 731}, + dictWord{12, 0, 68}, + dictWord{12, 0, 92}, + dictWord{12, 0, 507}, + dictWord{12, 0, 692}, + dictWord{13, 0, 81}, + dictWord{ + 13, + 0, + 238, + }, + dictWord{13, 0, 374}, + dictWord{14, 0, 436}, + dictWord{18, 0, 138}, + dictWord{19, 0, 78}, + dictWord{19, 0, 111}, + dictWord{20, 0, 55}, + dictWord{20, 0, 77}, + dictWord{148, 0, 92}, + dictWord{141, 0, 418}, + dictWord{4, 0, 938}, + dictWord{137, 0, 625}, + dictWord{138, 0, 351}, + dictWord{5, 11, 843}, + dictWord{7, 10, 32}, + dictWord{ + 7, + 10, + 984, + }, + dictWord{8, 10, 85}, + dictWord{8, 10, 709}, + dictWord{9, 10, 579}, + dictWord{9, 10, 847}, + dictWord{9, 10, 856}, + dictWord{10, 10, 799}, + dictWord{ + 11, + 10, + 258, + }, + dictWord{11, 10, 1007}, + dictWord{12, 10, 331}, + dictWord{12, 10, 615}, + dictWord{13, 10, 188}, + dictWord{13, 10, 435}, + dictWord{14, 10, 8}, + dictWord{ + 15, + 10, + 165, + }, + dictWord{16, 10, 27}, + dictWord{148, 10, 40}, + dictWord{6, 0, 1668}, + dictWord{7, 0, 1499}, + dictWord{8, 0, 117}, + dictWord{9, 0, 314}, + dictWord{ + 138, + 0, + 174, + }, + dictWord{135, 0, 707}, + dictWord{132, 11, 554}, + dictWord{133, 11, 536}, + dictWord{5, 0, 403}, + dictWord{5, 11, 207}, + dictWord{9, 11, 79}, + dictWord{ + 11, + 11, + 625, + }, + dictWord{145, 11, 7}, + dictWord{132, 11, 424}, + dictWord{136, 11, 785}, + dictWord{4, 10, 167}, + dictWord{135, 10, 82}, + dictWord{9, 0, 7}, + dictWord{ + 23, + 0, + 6, + }, + dictWord{9, 11, 7}, + dictWord{151, 11, 6}, + dictWord{6, 0, 282}, + dictWord{5, 10, 62}, + dictWord{6, 10, 534}, + dictWord{7, 10, 74}, + dictWord{7, 10, 678}, + dictWord{ + 7, + 10, + 684, + }, + dictWord{7, 10, 1043}, + dictWord{7, 10, 1072}, + dictWord{8, 10, 280}, + dictWord{8, 10, 541}, + dictWord{8, 10, 686}, + dictWord{9, 10, 258}, + dictWord{ + 10, + 10, + 519, + }, + dictWord{11, 10, 252}, + dictWord{140, 10, 282}, + dictWord{138, 10, 33}, + dictWord{132, 10, 359}, + dictWord{4, 0, 44}, + dictWord{5, 0, 311}, + dictWord{ + 6, + 0, + 156, + }, + dictWord{7, 0, 639}, + dictWord{7, 0, 762}, + dictWord{7, 0, 1827}, + dictWord{9, 0, 8}, + dictWord{9, 0, 462}, + dictWord{148, 0, 83}, + dictWord{7, 11, 769}, + dictWord{ + 9, + 11, + 18, + }, + dictWord{138, 11, 358}, + dictWord{4, 0, 346}, + dictWord{7, 0, 115}, + dictWord{9, 0, 180}, + dictWord{9, 0, 456}, + dictWord{10, 0, 363}, + dictWord{ + 4, + 11, + 896, + }, + dictWord{134, 11, 1777}, + dictWord{133, 10, 211}, + dictWord{7, 0, 761}, + dictWord{7, 0, 1051}, + dictWord{137, 0, 545}, + dictWord{6, 10, 145}, + dictWord{ + 141, + 10, + 336, + }, + dictWord{7, 11, 750}, + dictWord{9, 11, 223}, + dictWord{11, 11, 27}, + dictWord{11, 11, 466}, + dictWord{12, 11, 624}, + dictWord{14, 11, 265}, + dictWord{146, 11, 61}, + dictWord{6, 0, 752}, + dictWord{6, 0, 768}, + dictWord{6, 0, 1195}, + dictWord{6, 0, 1254}, + dictWord{6, 0, 1619}, + dictWord{137, 0, 835}, + dictWord{ + 6, + 0, + 1936, + }, + dictWord{8, 0, 930}, + dictWord{136, 0, 960}, + dictWord{132, 10, 263}, + dictWord{132, 11, 249}, + dictWord{12, 0, 653}, + dictWord{132, 10, 916}, + dictWord{4, 11, 603}, + dictWord{133, 11, 661}, + dictWord{8, 0, 344}, + dictWord{4, 11, 11}, + dictWord{6, 11, 128}, + dictWord{7, 11, 231}, + dictWord{7, 11, 1533}, + dictWord{138, 11, 725}, + dictWord{134, 0, 1483}, + dictWord{134, 0, 875}, + dictWord{6, 0, 185}, + dictWord{7, 0, 1899}, + dictWord{9, 0, 875}, + dictWord{139, 0, 673}, + dictWord{15, 10, 155}, + dictWord{144, 10, 79}, + dictWord{7, 0, 93}, + dictWord{7, 0, 210}, + dictWord{7, 0, 1223}, + dictWord{8, 0, 451}, + dictWord{8, 0, 460}, + dictWord{ + 11, + 0, + 353, + }, + dictWord{11, 0, 475}, + dictWord{4, 10, 599}, + dictWord{6, 10, 1634}, + dictWord{7, 10, 67}, + dictWord{7, 10, 691}, + dictWord{7, 10, 979}, + dictWord{ + 7, + 10, + 1697, + }, + dictWord{8, 10, 207}, + dictWord{8, 10, 214}, + dictWord{8, 10, 231}, + dictWord{8, 10, 294}, + dictWord{8, 10, 336}, + dictWord{8, 10, 428}, + dictWord{ + 8, + 10, + 471, + }, + dictWord{8, 10, 622}, + dictWord{8, 10, 626}, + dictWord{8, 10, 679}, + dictWord{8, 10, 759}, + dictWord{8, 10, 829}, + dictWord{9, 10, 11}, + dictWord{9, 10, 246}, + dictWord{9, 10, 484}, + dictWord{9, 10, 573}, + dictWord{9, 10, 706}, + dictWord{9, 10, 762}, + dictWord{9, 10, 798}, + dictWord{9, 10, 855}, + dictWord{9, 10, 870}, + dictWord{ + 9, + 10, + 912, + }, + dictWord{10, 10, 303}, + dictWord{10, 10, 335}, + dictWord{10, 10, 424}, + dictWord{10, 10, 461}, + dictWord{10, 10, 543}, + dictWord{10, 10, 759}, + dictWord{10, 10, 814}, + dictWord{11, 10, 59}, + dictWord{11, 10, 235}, + dictWord{11, 10, 590}, + dictWord{11, 10, 929}, + dictWord{11, 10, 963}, + dictWord{ + 11, + 10, + 987, + }, + dictWord{12, 10, 114}, + dictWord{12, 10, 182}, + dictWord{12, 10, 226}, + dictWord{12, 10, 332}, + dictWord{12, 10, 439}, + dictWord{12, 10, 575}, + dictWord{ + 12, + 10, + 598, + }, + dictWord{12, 10, 675}, + dictWord{13, 10, 8}, + dictWord{13, 10, 125}, + dictWord{13, 10, 194}, + dictWord{13, 10, 287}, + dictWord{14, 10, 197}, + dictWord{14, 10, 383}, + dictWord{15, 10, 53}, + dictWord{17, 10, 63}, + dictWord{19, 10, 46}, + dictWord{19, 10, 98}, + dictWord{19, 10, 106}, + dictWord{148, 10, 85}, + dictWord{132, 11, 476}, + dictWord{4, 0, 327}, + dictWord{5, 0, 478}, + dictWord{7, 0, 1332}, + dictWord{136, 0, 753}, + dictWord{5, 0, 1020}, + dictWord{133, 0, 1022}, + dictWord{135, 11, 1807}, + dictWord{4, 0, 103}, + dictWord{133, 0, 401}, + dictWord{4, 0, 499}, + dictWord{135, 0, 1421}, + dictWord{10, 0, 207}, + dictWord{13, 0, 164}, + dictWord{147, 10, 126}, + dictWord{9, 11, 20}, + dictWord{10, 11, 324}, + dictWord{139, 11, 488}, + dictWord{132, 0, 96}, + dictWord{9, 11, 280}, + dictWord{ + 138, + 11, + 134, + }, + dictWord{135, 0, 968}, + dictWord{133, 10, 187}, + dictWord{135, 10, 1286}, + dictWord{5, 11, 112}, + dictWord{6, 11, 103}, + dictWord{134, 11, 150}, + dictWord{8, 0, 914}, + dictWord{10, 0, 3}, + dictWord{4, 10, 215}, + dictWord{9, 10, 38}, + dictWord{11, 10, 23}, + dictWord{11, 10, 127}, + dictWord{139, 10, 796}, + dictWord{ + 135, + 0, + 399, + }, + dictWord{6, 0, 563}, + dictWord{137, 0, 224}, + dictWord{6, 0, 704}, + dictWord{134, 0, 1214}, + dictWord{4, 11, 708}, + dictWord{8, 11, 15}, + dictWord{ + 9, + 11, + 50, + }, + dictWord{9, 11, 386}, + dictWord{11, 11, 18}, + dictWord{11, 11, 529}, + dictWord{140, 11, 228}, + dictWord{4, 11, 563}, + dictWord{7, 11, 109}, + dictWord{ + 7, + 11, + 592, + }, + dictWord{7, 11, 637}, + dictWord{7, 11, 770}, + dictWord{7, 11, 1701}, + dictWord{8, 11, 436}, + dictWord{8, 11, 463}, + dictWord{9, 11, 60}, + dictWord{9, 11, 335}, + dictWord{9, 11, 904}, + dictWord{10, 11, 73}, + dictWord{11, 11, 434}, + dictWord{12, 11, 585}, + dictWord{13, 11, 331}, + dictWord{18, 11, 110}, + dictWord{ + 148, + 11, + 60, + }, + dictWord{134, 0, 1559}, + dictWord{132, 11, 502}, + dictWord{6, 11, 347}, + dictWord{138, 11, 161}, + dictWord{4, 11, 33}, + dictWord{5, 11, 102}, + dictWord{ + 5, + 11, + 500, + }, + dictWord{6, 11, 284}, + dictWord{7, 11, 1079}, + dictWord{7, 11, 1423}, + dictWord{7, 11, 1702}, + dictWord{8, 11, 470}, + dictWord{9, 11, 554}, + dictWord{ + 9, + 11, + 723, + }, + dictWord{139, 11, 333}, + dictWord{7, 11, 246}, + dictWord{135, 11, 840}, + dictWord{6, 11, 10}, + dictWord{8, 11, 571}, + dictWord{9, 11, 739}, + dictWord{ + 143, + 11, + 91, + }, + dictWord{8, 0, 861}, + dictWord{10, 0, 905}, + dictWord{12, 0, 730}, + dictWord{12, 0, 789}, + dictWord{133, 11, 626}, + dictWord{134, 0, 946}, + dictWord{ + 5, + 0, + 746, + }, + dictWord{12, 0, 333}, + dictWord{14, 0, 332}, + dictWord{12, 11, 333}, + dictWord{142, 11, 332}, + dictWord{5, 11, 18}, + dictWord{6, 11, 526}, + dictWord{ + 13, + 11, + 24, + }, + dictWord{13, 11, 110}, + dictWord{19, 11, 5}, + dictWord{147, 11, 44}, + dictWord{4, 0, 910}, + dictWord{5, 0, 832}, + dictWord{135, 10, 2002}, + dictWord{ + 10, + 11, + 768, + }, + dictWord{139, 11, 787}, + dictWord{4, 11, 309}, + dictWord{5, 11, 462}, + dictWord{7, 11, 970}, + dictWord{135, 11, 1097}, + dictWord{4, 10, 28}, + dictWord{ + 5, + 10, + 440, + }, + dictWord{7, 10, 248}, + dictWord{11, 10, 833}, + dictWord{140, 10, 344}, + dictWord{134, 10, 1654}, + dictWord{6, 0, 632}, + dictWord{6, 0, 652}, + dictWord{ + 6, + 0, + 1272, + }, + dictWord{6, 0, 1384}, + dictWord{134, 0, 1560}, + dictWord{134, 11, 1704}, + dictWord{6, 0, 1393}, + dictWord{133, 10, 853}, + dictWord{6, 10, 249}, + dictWord{7, 10, 1234}, + dictWord{139, 10, 573}, + dictWord{5, 11, 86}, + dictWord{7, 11, 743}, + dictWord{9, 11, 85}, + dictWord{10, 11, 281}, + dictWord{10, 11, 432}, + dictWord{11, 11, 490}, + dictWord{12, 11, 251}, + dictWord{13, 11, 118}, + dictWord{14, 11, 378}, + dictWord{146, 11, 143}, + dictWord{5, 11, 524}, + dictWord{ + 133, + 11, + 744, + }, + dictWord{134, 0, 1514}, + dictWord{10, 0, 201}, + dictWord{142, 0, 319}, + dictWord{7, 0, 717}, + dictWord{10, 0, 510}, + dictWord{7, 10, 392}, + dictWord{ + 8, + 10, + 20, + }, + dictWord{8, 10, 172}, + dictWord{8, 10, 690}, + dictWord{9, 10, 383}, + dictWord{9, 10, 845}, + dictWord{11, 10, 293}, + dictWord{11, 10, 832}, + dictWord{ + 11, + 10, + 920, + }, + dictWord{11, 10, 984}, + dictWord{141, 10, 221}, + dictWord{134, 0, 1381}, + dictWord{5, 10, 858}, + dictWord{133, 10, 992}, + dictWord{8, 0, 528}, + dictWord{137, 0, 348}, + dictWord{10, 11, 107}, + dictWord{140, 11, 436}, + dictWord{4, 0, 20}, + dictWord{133, 0, 616}, + dictWord{134, 0, 1251}, + dictWord{ + 132, + 11, + 927, + }, + dictWord{10, 11, 123}, + dictWord{12, 11, 670}, + dictWord{13, 11, 371}, + dictWord{14, 11, 142}, + dictWord{146, 11, 94}, + dictWord{134, 0, 1163}, + dictWord{ + 7, + 11, + 1149, + }, + dictWord{137, 11, 156}, + dictWord{134, 0, 307}, + dictWord{133, 11, 778}, + dictWord{7, 0, 1091}, + dictWord{135, 0, 1765}, + dictWord{ + 5, + 11, + 502, + }, + dictWord{6, 10, 268}, + dictWord{137, 10, 62}, + dictWord{8, 11, 196}, + dictWord{10, 11, 283}, + dictWord{139, 11, 406}, + dictWord{4, 0, 26}, + dictWord{ + 5, + 0, + 429, + }, + dictWord{6, 0, 245}, + dictWord{7, 0, 704}, + dictWord{7, 0, 1379}, + dictWord{135, 0, 1474}, + dictWord{133, 11, 855}, + dictWord{132, 0, 881}, + dictWord{ + 4, + 0, + 621, + }, + dictWord{135, 11, 1596}, + dictWord{7, 11, 1400}, + dictWord{9, 11, 446}, + dictWord{138, 11, 45}, + dictWord{6, 0, 736}, + dictWord{138, 10, 106}, + dictWord{133, 0, 542}, + dictWord{134, 0, 348}, + dictWord{133, 0, 868}, + dictWord{136, 0, 433}, + dictWord{135, 0, 1495}, + dictWord{138, 0, 771}, + dictWord{ + 6, + 10, + 613, + }, + dictWord{136, 10, 223}, + dictWord{138, 0, 215}, + dictWord{141, 0, 124}, + dictWord{136, 11, 391}, + dictWord{135, 11, 172}, + dictWord{132, 10, 670}, + dictWord{140, 0, 55}, + dictWord{9, 10, 40}, + dictWord{139, 10, 136}, + dictWord{7, 0, 62}, + dictWord{147, 0, 112}, + dictWord{132, 0, 856}, + dictWord{132, 11, 568}, + dictWord{12, 0, 270}, + dictWord{139, 10, 259}, + dictWord{8, 0, 572}, + dictWord{137, 0, 698}, + dictWord{4, 11, 732}, + dictWord{9, 10, 310}, + dictWord{137, 10, 682}, + dictWord{142, 10, 296}, + dictWord{134, 0, 939}, + dictWord{136, 11, 733}, + dictWord{135, 11, 1435}, + dictWord{7, 10, 1401}, + dictWord{135, 10, 1476}, + dictWord{6, 0, 352}, + dictWord{4, 10, 296}, + dictWord{7, 10, 401}, + dictWord{7, 10, 1410}, + dictWord{7, 10, 1594}, + dictWord{7, 10, 1674}, + dictWord{8, 10, 63}, + dictWord{ + 8, + 10, + 660, + }, + dictWord{137, 10, 74}, + dictWord{4, 11, 428}, + dictWord{133, 11, 668}, + dictWord{4, 10, 139}, + dictWord{4, 10, 388}, + dictWord{140, 10, 188}, + dictWord{7, 11, 2015}, + dictWord{140, 11, 665}, + dictWord{132, 0, 647}, + dictWord{146, 0, 10}, + dictWord{138, 0, 220}, + dictWord{142, 0, 464}, + dictWord{ + 132, + 0, + 109, + }, + dictWord{134, 0, 1746}, + dictWord{6, 0, 515}, + dictWord{4, 10, 747}, + dictWord{6, 11, 1623}, + dictWord{6, 11, 1681}, + dictWord{7, 10, 649}, + dictWord{ + 7, + 10, + 1479, + }, + dictWord{135, 10, 1583}, + dictWord{133, 10, 232}, + dictWord{135, 0, 566}, + dictWord{137, 10, 887}, + dictWord{4, 0, 40}, + dictWord{10, 0, 67}, + dictWord{ + 11, + 0, + 117, + }, + dictWord{11, 0, 768}, + dictWord{139, 0, 935}, + dictWord{132, 0, 801}, + dictWord{7, 0, 992}, + dictWord{8, 0, 301}, + dictWord{9, 0, 722}, + dictWord{ + 12, + 0, + 63, + }, + dictWord{13, 0, 29}, + dictWord{14, 0, 161}, + dictWord{143, 0, 18}, + dictWord{139, 0, 923}, + dictWord{6, 11, 1748}, + dictWord{8, 11, 715}, + dictWord{9, 11, 802}, + dictWord{10, 11, 46}, + dictWord{10, 11, 819}, + dictWord{13, 11, 308}, + dictWord{14, 11, 351}, + dictWord{14, 11, 363}, + dictWord{146, 11, 67}, + dictWord{ + 137, + 11, + 745, + }, + dictWord{7, 0, 1145}, + dictWord{4, 10, 14}, + dictWord{7, 10, 1801}, + dictWord{10, 10, 748}, + dictWord{141, 10, 458}, + dictWord{4, 11, 63}, + dictWord{ + 5, + 11, + 347, + }, + dictWord{134, 11, 474}, + dictWord{135, 0, 568}, + dictWord{4, 10, 425}, + dictWord{7, 11, 577}, + dictWord{7, 11, 1432}, + dictWord{9, 11, 475}, + dictWord{ + 9, + 11, + 505, + }, + dictWord{9, 11, 526}, + dictWord{9, 11, 609}, + dictWord{9, 11, 689}, + dictWord{9, 11, 726}, + dictWord{9, 11, 735}, + dictWord{9, 11, 738}, + dictWord{ + 10, + 11, + 556, + }, + dictWord{10, 11, 674}, + dictWord{10, 11, 684}, + dictWord{11, 11, 89}, + dictWord{11, 11, 202}, + dictWord{11, 11, 272}, + dictWord{11, 11, 380}, + dictWord{ + 11, + 11, + 415, + }, + dictWord{11, 11, 505}, + dictWord{11, 11, 537}, + dictWord{11, 11, 550}, + dictWord{11, 11, 562}, + dictWord{11, 11, 640}, + dictWord{11, 11, 667}, + dictWord{11, 11, 688}, + dictWord{11, 11, 847}, + dictWord{11, 11, 927}, + dictWord{11, 11, 930}, + dictWord{11, 11, 940}, + dictWord{12, 11, 144}, + dictWord{ + 12, + 11, + 325, + }, + dictWord{12, 11, 329}, + dictWord{12, 11, 389}, + dictWord{12, 11, 403}, + dictWord{12, 11, 451}, + dictWord{12, 11, 515}, + dictWord{12, 11, 604}, + dictWord{ + 12, + 11, + 616, + }, + dictWord{12, 11, 626}, + dictWord{13, 11, 66}, + dictWord{13, 11, 131}, + dictWord{13, 11, 167}, + dictWord{13, 11, 236}, + dictWord{13, 11, 368}, + dictWord{13, 11, 411}, + dictWord{13, 11, 434}, + dictWord{13, 11, 453}, + dictWord{13, 11, 461}, + dictWord{13, 11, 474}, + dictWord{14, 11, 59}, + dictWord{14, 11, 60}, + dictWord{14, 11, 139}, + dictWord{14, 11, 152}, + dictWord{14, 11, 276}, + dictWord{14, 11, 353}, + dictWord{14, 11, 402}, + dictWord{15, 11, 28}, + dictWord{ + 15, + 11, + 81, + }, + dictWord{15, 11, 123}, + dictWord{15, 11, 152}, + dictWord{18, 11, 136}, + dictWord{148, 11, 88}, + dictWord{137, 0, 247}, + dictWord{135, 11, 1622}, + dictWord{ + 9, + 11, + 544, + }, + dictWord{11, 11, 413}, + dictWord{144, 11, 25}, + dictWord{4, 0, 645}, + dictWord{7, 0, 825}, + dictWord{6, 10, 1768}, + dictWord{135, 11, 89}, + dictWord{140, 0, 328}, + dictWord{5, 10, 943}, + dictWord{134, 10, 1779}, + dictWord{134, 0, 1363}, + dictWord{5, 10, 245}, + dictWord{6, 10, 576}, + dictWord{7, 10, 582}, + dictWord{136, 10, 225}, + dictWord{134, 0, 1280}, + dictWord{5, 11, 824}, + dictWord{133, 11, 941}, + dictWord{7, 11, 440}, + dictWord{8, 11, 230}, + dictWord{ + 139, + 11, + 106, + }, + dictWord{5, 0, 28}, + dictWord{6, 0, 204}, + dictWord{10, 0, 320}, + dictWord{10, 0, 583}, + dictWord{13, 0, 502}, + dictWord{14, 0, 72}, + dictWord{14, 0, 274}, + dictWord{14, 0, 312}, + dictWord{14, 0, 344}, + dictWord{15, 0, 159}, + dictWord{16, 0, 62}, + dictWord{16, 0, 69}, + dictWord{17, 0, 30}, + dictWord{18, 0, 42}, + dictWord{ + 18, + 0, + 53, + }, + dictWord{18, 0, 84}, + dictWord{18, 0, 140}, + dictWord{19, 0, 68}, + dictWord{19, 0, 85}, + dictWord{20, 0, 5}, + dictWord{20, 0, 45}, + dictWord{20, 0, 101}, + dictWord{ + 22, + 0, + 7, + }, + dictWord{150, 0, 20}, + dictWord{4, 0, 558}, + dictWord{6, 0, 390}, + dictWord{7, 0, 162}, + dictWord{7, 0, 689}, + dictWord{9, 0, 360}, + dictWord{138, 0, 653}, + dictWord{134, 0, 764}, + dictWord{6, 0, 862}, + dictWord{137, 0, 833}, + dictWord{5, 0, 856}, + dictWord{6, 0, 1672}, + dictWord{6, 0, 1757}, + dictWord{134, 0, 1781}, + dictWord{ + 5, + 0, + 92, + }, + dictWord{10, 0, 736}, + dictWord{140, 0, 102}, + dictWord{6, 0, 1927}, + dictWord{6, 0, 1944}, + dictWord{8, 0, 924}, + dictWord{8, 0, 948}, + dictWord{ + 10, + 0, + 967, + }, + dictWord{138, 0, 978}, + dictWord{134, 0, 1479}, + dictWord{5, 0, 590}, + dictWord{8, 0, 360}, + dictWord{9, 0, 213}, + dictWord{138, 0, 63}, + dictWord{ + 134, + 0, + 1521, + }, + dictWord{6, 0, 709}, + dictWord{134, 0, 891}, + dictWord{132, 10, 443}, + dictWord{13, 0, 477}, + dictWord{14, 0, 120}, + dictWord{148, 0, 61}, + dictWord{ + 4, + 11, + 914, + }, + dictWord{5, 11, 800}, + dictWord{133, 11, 852}, + dictWord{10, 11, 54}, + dictWord{141, 11, 115}, + dictWord{4, 11, 918}, + dictWord{133, 11, 876}, + dictWord{139, 11, 152}, + dictWord{4, 11, 92}, + dictWord{133, 11, 274}, + dictWord{135, 11, 1901}, + dictWord{9, 11, 800}, + dictWord{10, 11, 693}, + dictWord{ + 11, + 11, + 482, + }, + dictWord{11, 11, 734}, + dictWord{139, 11, 789}, + dictWord{9, 0, 483}, + dictWord{132, 10, 298}, + dictWord{6, 0, 1213}, + dictWord{141, 11, 498}, + dictWord{135, 11, 1451}, + dictWord{133, 11, 743}, + dictWord{4, 0, 1022}, + dictWord{10, 0, 1000}, + dictWord{12, 0, 957}, + dictWord{12, 0, 980}, + dictWord{ + 12, + 0, + 1013, + }, + dictWord{14, 0, 481}, + dictWord{144, 0, 116}, + dictWord{8, 0, 503}, + dictWord{17, 0, 29}, + dictWord{4, 11, 49}, + dictWord{7, 11, 280}, + dictWord{ + 135, + 11, + 1633, + }, + dictWord{135, 0, 1712}, + dictWord{134, 0, 466}, + dictWord{136, 11, 47}, + dictWord{5, 10, 164}, + dictWord{7, 10, 121}, + dictWord{142, 10, 189}, + dictWord{ + 7, + 10, + 812, + }, + dictWord{7, 10, 1261}, + dictWord{7, 10, 1360}, + dictWord{9, 10, 632}, + dictWord{140, 10, 352}, + dictWord{139, 10, 556}, + dictWord{132, 0, 731}, + dictWord{5, 11, 272}, + dictWord{5, 11, 908}, + dictWord{5, 11, 942}, + dictWord{7, 11, 1008}, + dictWord{7, 11, 1560}, + dictWord{8, 11, 197}, + dictWord{9, 11, 47}, + dictWord{11, 11, 538}, + dictWord{139, 11, 742}, + dictWord{4, 10, 172}, + dictWord{9, 10, 611}, + dictWord{10, 10, 436}, + dictWord{12, 10, 673}, + dictWord{ + 141, + 10, + 255, + }, + dictWord{133, 10, 844}, + dictWord{10, 0, 484}, + dictWord{11, 0, 754}, + dictWord{12, 0, 457}, + dictWord{14, 0, 171}, + dictWord{14, 0, 389}, + dictWord{ + 146, + 0, + 153, + }, + dictWord{9, 10, 263}, + dictWord{10, 10, 147}, + dictWord{138, 10, 492}, + dictWord{137, 11, 891}, + dictWord{138, 0, 241}, + dictWord{133, 10, 537}, + dictWord{6, 0, 2005}, + dictWord{136, 0, 964}, + dictWord{137, 10, 842}, + dictWord{151, 11, 8}, + dictWord{4, 11, 407}, + dictWord{132, 11, 560}, + dictWord{ + 135, + 11, + 1884, + }, + dictWord{6, 0, 1100}, + dictWord{134, 0, 1242}, + dictWord{135, 0, 954}, + dictWord{5, 10, 230}, + dictWord{5, 10, 392}, + dictWord{6, 10, 420}, + dictWord{ + 9, + 10, + 568, + }, + dictWord{140, 10, 612}, + dictWord{4, 11, 475}, + dictWord{11, 11, 35}, + dictWord{11, 11, 90}, + dictWord{13, 11, 7}, + dictWord{13, 11, 71}, + dictWord{ + 13, + 11, + 177, + }, + dictWord{142, 11, 422}, + dictWord{136, 11, 332}, + dictWord{135, 0, 1958}, + dictWord{6, 0, 549}, + dictWord{8, 0, 34}, + dictWord{8, 0, 283}, + dictWord{ + 9, + 0, + 165, + }, + dictWord{138, 0, 475}, + dictWord{10, 0, 952}, + dictWord{12, 0, 966}, + dictWord{140, 0, 994}, + dictWord{5, 0, 652}, + dictWord{5, 0, 701}, + dictWord{ + 135, + 0, + 449, + }, + dictWord{4, 0, 655}, + dictWord{7, 0, 850}, + dictWord{17, 0, 75}, + dictWord{146, 0, 137}, + dictWord{4, 0, 146}, + dictWord{7, 0, 1618}, + dictWord{8, 0, 670}, + dictWord{ + 5, + 10, + 41, + }, + dictWord{7, 10, 1459}, + dictWord{7, 10, 1469}, + dictWord{7, 10, 1859}, + dictWord{9, 10, 549}, + dictWord{139, 10, 905}, + dictWord{133, 10, 696}, + dictWord{6, 0, 159}, + dictWord{6, 0, 364}, + dictWord{7, 0, 516}, + dictWord{137, 0, 518}, + dictWord{135, 0, 1439}, + dictWord{6, 11, 222}, + dictWord{7, 11, 636}, + dictWord{ + 7, + 11, + 1620, + }, + dictWord{8, 11, 409}, + dictWord{9, 11, 693}, + dictWord{139, 11, 77}, + dictWord{13, 0, 151}, + dictWord{141, 11, 45}, + dictWord{6, 0, 1027}, + dictWord{ + 4, + 11, + 336, + }, + dictWord{132, 10, 771}, + dictWord{139, 11, 392}, + dictWord{10, 11, 121}, + dictWord{11, 11, 175}, + dictWord{149, 11, 16}, + dictWord{8, 0, 950}, + dictWord{138, 0, 983}, + dictWord{133, 10, 921}, + dictWord{135, 0, 993}, + dictWord{6, 10, 180}, + dictWord{7, 10, 1137}, + dictWord{8, 10, 751}, + dictWord{ + 139, + 10, + 805, + }, + dictWord{7, 0, 501}, + dictWord{9, 0, 111}, + dictWord{10, 0, 141}, + dictWord{11, 0, 332}, + dictWord{13, 0, 43}, + dictWord{13, 0, 429}, + dictWord{14, 0, 130}, + dictWord{14, 0, 415}, + dictWord{145, 0, 102}, + dictWord{4, 10, 183}, + dictWord{5, 11, 882}, + dictWord{7, 10, 271}, + dictWord{11, 10, 824}, + dictWord{11, 10, 952}, + dictWord{13, 10, 278}, + dictWord{13, 10, 339}, + dictWord{13, 10, 482}, + dictWord{14, 10, 424}, + dictWord{148, 10, 99}, + dictWord{4, 10, 19}, + dictWord{5, 10, 477}, + dictWord{5, 10, 596}, + dictWord{6, 10, 505}, + dictWord{7, 10, 1221}, + dictWord{11, 10, 907}, + dictWord{12, 10, 209}, + dictWord{141, 10, 214}, + dictWord{ + 135, + 10, + 1215, + }, + dictWord{133, 0, 452}, + dictWord{132, 11, 426}, + dictWord{5, 0, 149}, + dictWord{136, 0, 233}, + dictWord{133, 0, 935}, + dictWord{6, 11, 58}, + dictWord{ + 7, + 11, + 654, + }, + dictWord{7, 11, 745}, + dictWord{7, 11, 1969}, + dictWord{8, 11, 240}, + dictWord{8, 11, 675}, + dictWord{9, 11, 479}, + dictWord{9, 11, 731}, + dictWord{ + 10, + 11, + 330, + }, + dictWord{10, 11, 593}, + dictWord{10, 11, 817}, + dictWord{11, 11, 32}, + dictWord{11, 11, 133}, + dictWord{11, 11, 221}, + dictWord{145, 11, 68}, + dictWord{ + 12, + 0, + 582, + }, + dictWord{18, 0, 131}, + dictWord{7, 11, 102}, + dictWord{137, 11, 538}, + dictWord{136, 0, 801}, + dictWord{134, 10, 1645}, + dictWord{132, 0, 70}, + dictWord{6, 10, 92}, + dictWord{6, 10, 188}, + dictWord{7, 10, 1269}, + dictWord{7, 10, 1524}, + dictWord{7, 10, 1876}, + dictWord{10, 10, 228}, + dictWord{139, 10, 1020}, + dictWord{4, 10, 459}, + dictWord{133, 10, 966}, + dictWord{138, 0, 369}, + dictWord{16, 0, 36}, + dictWord{140, 10, 330}, + dictWord{141, 11, 366}, + dictWord{ + 7, + 0, + 721, + }, + dictWord{10, 0, 236}, + dictWord{12, 0, 204}, + dictWord{6, 10, 18}, + dictWord{7, 10, 932}, + dictWord{8, 10, 757}, + dictWord{9, 10, 54}, + dictWord{9, 10, 65}, + dictWord{9, 10, 844}, + dictWord{10, 10, 113}, + dictWord{10, 10, 315}, + dictWord{10, 10, 798}, + dictWord{11, 10, 153}, + dictWord{12, 10, 151}, + dictWord{12, 10, 392}, + dictWord{12, 10, 666}, + dictWord{142, 10, 248}, + dictWord{7, 0, 241}, + dictWord{10, 0, 430}, + dictWord{8, 10, 548}, + dictWord{9, 10, 532}, + dictWord{10, 10, 117}, + dictWord{11, 10, 351}, + dictWord{11, 10, 375}, + dictWord{143, 10, 23}, + dictWord{134, 10, 1742}, + dictWord{133, 10, 965}, + dictWord{133, 11, 566}, + dictWord{ + 6, + 11, + 48, + }, + dictWord{135, 11, 63}, + dictWord{134, 10, 182}, + dictWord{10, 10, 65}, + dictWord{10, 10, 488}, + dictWord{138, 10, 497}, + dictWord{6, 11, 114}, + dictWord{7, 11, 1224}, + dictWord{7, 11, 1556}, + dictWord{136, 11, 3}, + dictWord{134, 0, 1817}, + dictWord{8, 11, 576}, + dictWord{137, 11, 267}, + dictWord{ + 6, + 0, + 1078, + }, + dictWord{144, 0, 16}, + dictWord{9, 10, 588}, + dictWord{138, 10, 260}, + dictWord{138, 0, 1021}, + dictWord{5, 0, 406}, + dictWord{134, 0, 2022}, + dictWord{133, 11, 933}, + dictWord{6, 0, 69}, + dictWord{135, 0, 117}, + dictWord{7, 0, 1830}, + dictWord{136, 11, 427}, + dictWord{4, 0, 432}, + dictWord{135, 0, 824}, + dictWord{134, 10, 1786}, + dictWord{133, 0, 826}, + dictWord{139, 11, 67}, + dictWord{133, 11, 759}, + dictWord{135, 10, 308}, + dictWord{137, 0, 816}, + dictWord{ + 133, + 0, + 1000, + }, + dictWord{4, 0, 297}, + dictWord{6, 0, 529}, + dictWord{7, 0, 152}, + dictWord{7, 0, 713}, + dictWord{7, 0, 1845}, + dictWord{8, 0, 710}, + dictWord{8, 0, 717}, + dictWord{12, 0, 639}, + dictWord{140, 0, 685}, + dictWord{7, 0, 423}, + dictWord{136, 10, 588}, + dictWord{136, 10, 287}, + dictWord{136, 0, 510}, + dictWord{ + 134, + 0, + 1048, + }, + dictWord{6, 0, 618}, + dictWord{7, 11, 56}, + dictWord{7, 11, 1989}, + dictWord{8, 11, 337}, + dictWord{8, 11, 738}, + dictWord{9, 11, 600}, + dictWord{ + 10, + 11, + 483, + }, + dictWord{12, 11, 37}, + dictWord{13, 11, 447}, + dictWord{142, 11, 92}, + dictWord{4, 0, 520}, + dictWord{135, 0, 575}, + dictWord{8, 0, 990}, + dictWord{ + 138, + 0, + 977, + }, + dictWord{135, 11, 774}, + dictWord{9, 11, 347}, + dictWord{11, 11, 24}, + dictWord{140, 11, 170}, + dictWord{136, 11, 379}, + dictWord{140, 10, 290}, + dictWord{132, 11, 328}, + dictWord{4, 0, 321}, + dictWord{134, 0, 569}, + dictWord{4, 11, 101}, + dictWord{135, 11, 1171}, + dictWord{7, 0, 723}, + dictWord{7, 0, 1135}, + dictWord{5, 11, 833}, + dictWord{136, 11, 744}, + dictWord{7, 10, 719}, + dictWord{8, 10, 809}, + dictWord{136, 10, 834}, + dictWord{8, 0, 921}, + dictWord{136, 10, 796}, + dictWord{5, 10, 210}, + dictWord{6, 10, 213}, + dictWord{7, 10, 60}, + dictWord{10, 10, 364}, + dictWord{139, 10, 135}, + dictWord{5, 0, 397}, + dictWord{6, 0, 154}, + dictWord{7, 0, 676}, + dictWord{8, 0, 443}, + dictWord{8, 0, 609}, + dictWord{9, 0, 24}, + dictWord{9, 0, 325}, + dictWord{10, 0, 35}, + dictWord{11, 0, 535}, + dictWord{11, 0, 672}, + dictWord{11, 0, 1018}, + dictWord{12, 0, 637}, + dictWord{16, 0, 30}, + dictWord{5, 10, 607}, + dictWord{8, 10, 326}, + dictWord{136, 10, 490}, + dictWord{4, 10, 701}, + dictWord{5, 10, 472}, + dictWord{6, 11, 9}, + dictWord{6, 11, 397}, + dictWord{7, 11, 53}, + dictWord{7, 11, 1742}, + dictWord{9, 10, 758}, + dictWord{10, 11, 632}, + dictWord{ + 11, + 11, + 828, + }, + dictWord{140, 11, 146}, + dictWord{135, 10, 380}, + dictWord{135, 10, 1947}, + dictWord{148, 11, 109}, + dictWord{10, 10, 278}, + dictWord{ + 138, + 11, + 278, + }, + dictWord{134, 0, 856}, + dictWord{7, 0, 139}, + dictWord{4, 10, 386}, + dictWord{8, 10, 405}, + dictWord{8, 10, 728}, + dictWord{9, 10, 497}, + dictWord{ + 11, + 10, + 110, + }, + dictWord{11, 10, 360}, + dictWord{15, 10, 37}, + dictWord{144, 10, 84}, + dictWord{141, 0, 282}, + dictWord{133, 0, 981}, + dictWord{5, 0, 288}, + dictWord{ + 7, + 10, + 1452, + }, + dictWord{7, 10, 1480}, + dictWord{8, 10, 634}, + dictWord{140, 10, 472}, + dictWord{7, 0, 1890}, + dictWord{8, 11, 367}, + dictWord{10, 11, 760}, + dictWord{ + 14, + 11, + 79, + }, + dictWord{20, 11, 17}, + dictWord{152, 11, 0}, + dictWord{4, 10, 524}, + dictWord{136, 10, 810}, + dictWord{4, 0, 56}, + dictWord{7, 0, 1791}, + dictWord{ + 8, + 0, + 607, + }, + dictWord{8, 0, 651}, + dictWord{11, 0, 465}, + dictWord{11, 0, 835}, + dictWord{12, 0, 337}, + dictWord{141, 0, 480}, + dictWord{10, 10, 238}, + dictWord{ + 141, + 10, + 33, + }, + dictWord{11, 11, 417}, + dictWord{12, 11, 223}, + dictWord{140, 11, 265}, + dictWord{9, 0, 158}, + dictWord{10, 0, 411}, + dictWord{140, 0, 261}, + dictWord{ + 133, + 10, + 532, + }, + dictWord{133, 10, 997}, + dictWord{12, 11, 186}, + dictWord{12, 11, 292}, + dictWord{14, 11, 100}, + dictWord{146, 11, 70}, + dictWord{6, 0, 1403}, + dictWord{136, 0, 617}, + dictWord{134, 0, 1205}, + dictWord{139, 0, 563}, + dictWord{4, 0, 242}, + dictWord{134, 0, 333}, + dictWord{4, 11, 186}, + dictWord{5, 11, 157}, + dictWord{8, 11, 168}, + dictWord{138, 11, 6}, + dictWord{132, 0, 369}, + dictWord{133, 11, 875}, + dictWord{5, 10, 782}, + dictWord{5, 10, 829}, + dictWord{ + 134, + 10, + 1738, + }, + dictWord{134, 0, 622}, + dictWord{135, 11, 1272}, + dictWord{6, 0, 1407}, + dictWord{7, 11, 111}, + dictWord{136, 11, 581}, + dictWord{7, 10, 1823}, + dictWord{139, 10, 693}, + dictWord{7, 0, 160}, + dictWord{10, 0, 624}, + dictWord{142, 0, 279}, + dictWord{132, 0, 363}, + dictWord{10, 11, 589}, + dictWord{12, 11, 111}, + dictWord{13, 11, 260}, + dictWord{14, 11, 82}, + dictWord{18, 11, 63}, + dictWord{147, 11, 45}, + dictWord{7, 11, 1364}, + dictWord{7, 11, 1907}, + dictWord{ + 141, + 11, + 158, + }, + dictWord{4, 11, 404}, + dictWord{4, 11, 659}, + dictWord{135, 11, 675}, + dictWord{13, 11, 211}, + dictWord{14, 11, 133}, + dictWord{14, 11, 204}, + dictWord{ + 15, + 11, + 64, + }, + dictWord{15, 11, 69}, + dictWord{15, 11, 114}, + dictWord{16, 11, 10}, + dictWord{19, 11, 23}, + dictWord{19, 11, 35}, + dictWord{19, 11, 39}, + dictWord{ + 19, + 11, + 51, + }, + dictWord{19, 11, 71}, + dictWord{19, 11, 75}, + dictWord{152, 11, 15}, + dictWord{4, 10, 78}, + dictWord{5, 10, 96}, + dictWord{5, 10, 182}, + dictWord{7, 10, 1724}, + dictWord{7, 10, 1825}, + dictWord{10, 10, 394}, + dictWord{10, 10, 471}, + dictWord{11, 10, 532}, + dictWord{14, 10, 340}, + dictWord{145, 10, 88}, + dictWord{ + 135, + 10, + 1964, + }, + dictWord{133, 11, 391}, + dictWord{11, 11, 887}, + dictWord{14, 11, 365}, + dictWord{142, 11, 375}, + dictWord{5, 11, 540}, + dictWord{6, 11, 1697}, + dictWord{7, 11, 222}, + dictWord{136, 11, 341}, + dictWord{134, 11, 78}, + dictWord{9, 0, 601}, + dictWord{9, 0, 619}, + dictWord{10, 0, 505}, + dictWord{10, 0, 732}, + dictWord{11, 0, 355}, + dictWord{140, 0, 139}, + dictWord{134, 0, 292}, + dictWord{139, 0, 174}, + dictWord{5, 0, 177}, + dictWord{6, 0, 616}, + dictWord{7, 0, 827}, + dictWord{ + 9, + 0, + 525, + }, + dictWord{138, 0, 656}, + dictWord{10, 0, 31}, + dictWord{6, 10, 215}, + dictWord{7, 10, 1028}, + dictWord{7, 10, 1473}, + dictWord{7, 10, 1721}, + dictWord{ + 9, + 10, + 424, + }, + dictWord{138, 10, 779}, + dictWord{135, 10, 584}, + dictWord{136, 11, 293}, + dictWord{134, 0, 685}, + dictWord{135, 11, 1868}, + dictWord{ + 133, + 11, + 460, + }, + dictWord{7, 0, 647}, + dictWord{6, 10, 67}, + dictWord{7, 10, 1630}, + dictWord{9, 10, 354}, + dictWord{9, 10, 675}, + dictWord{10, 10, 830}, + dictWord{ + 14, + 10, + 80, + }, + dictWord{145, 10, 80}, + dictWord{4, 0, 161}, + dictWord{133, 0, 631}, + dictWord{6, 10, 141}, + dictWord{7, 10, 225}, + dictWord{9, 10, 59}, + dictWord{9, 10, 607}, + dictWord{10, 10, 312}, + dictWord{11, 10, 687}, + dictWord{12, 10, 555}, + dictWord{13, 10, 373}, + dictWord{13, 10, 494}, + dictWord{148, 10, 58}, + dictWord{ + 7, + 11, + 965, + }, + dictWord{7, 11, 1460}, + dictWord{135, 11, 1604}, + dictWord{136, 10, 783}, + dictWord{134, 11, 388}, + dictWord{6, 0, 722}, + dictWord{6, 0, 1267}, + dictWord{ + 4, + 11, + 511, + }, + dictWord{9, 11, 333}, + dictWord{9, 11, 379}, + dictWord{10, 11, 602}, + dictWord{11, 11, 441}, + dictWord{11, 11, 723}, + dictWord{11, 11, 976}, + dictWord{140, 11, 357}, + dictWord{134, 0, 1797}, + dictWord{135, 0, 1684}, + dictWord{9, 0, 469}, + dictWord{9, 0, 709}, + dictWord{12, 0, 512}, + dictWord{14, 0, 65}, + dictWord{17, 0, 12}, + dictWord{5, 11, 938}, + dictWord{136, 11, 707}, + dictWord{7, 0, 1230}, + dictWord{136, 0, 531}, + dictWord{10, 0, 229}, + dictWord{11, 0, 73}, + dictWord{ + 11, + 0, + 376, + }, + dictWord{139, 0, 433}, + dictWord{12, 0, 268}, + dictWord{12, 0, 640}, + dictWord{142, 0, 119}, + dictWord{7, 10, 430}, + dictWord{139, 10, 46}, + dictWord{ + 6, + 0, + 558, + }, + dictWord{7, 0, 651}, + dictWord{8, 0, 421}, + dictWord{9, 0, 0}, + dictWord{10, 0, 34}, + dictWord{139, 0, 1008}, + dictWord{6, 0, 106}, + dictWord{7, 0, 1786}, + dictWord{7, 0, 1821}, + dictWord{9, 0, 102}, + dictWord{9, 0, 763}, + dictWord{5, 10, 602}, + dictWord{7, 10, 2018}, + dictWord{137, 10, 418}, + dictWord{5, 0, 65}, + dictWord{ + 6, + 0, + 416, + }, + dictWord{7, 0, 1720}, + dictWord{7, 0, 1924}, + dictWord{10, 0, 109}, + dictWord{11, 0, 14}, + dictWord{11, 0, 70}, + dictWord{11, 0, 569}, + dictWord{11, 0, 735}, + dictWord{15, 0, 153}, + dictWord{20, 0, 80}, + dictWord{136, 10, 677}, + dictWord{135, 11, 1625}, + dictWord{137, 11, 772}, + dictWord{136, 0, 595}, + dictWord{ + 6, + 11, + 469, + }, + dictWord{7, 11, 1709}, + dictWord{138, 11, 515}, + dictWord{7, 0, 1832}, + dictWord{138, 0, 374}, + dictWord{9, 0, 106}, + dictWord{9, 0, 163}, + dictWord{ + 9, + 0, + 296, + }, + dictWord{10, 0, 167}, + dictWord{10, 0, 172}, + dictWord{10, 0, 777}, + dictWord{139, 0, 16}, + dictWord{6, 0, 6}, + dictWord{7, 0, 81}, + dictWord{7, 0, 771}, + dictWord{ + 7, + 0, + 1731, + }, + dictWord{9, 0, 405}, + dictWord{138, 0, 421}, + dictWord{4, 11, 500}, + dictWord{135, 11, 938}, + dictWord{5, 11, 68}, + dictWord{134, 11, 383}, + dictWord{ + 5, + 0, + 881, + }, + dictWord{133, 0, 885}, + dictWord{6, 0, 854}, + dictWord{6, 0, 1132}, + dictWord{6, 0, 1495}, + dictWord{6, 0, 1526}, + dictWord{6, 0, 1533}, + dictWord{ + 134, + 0, + 1577, + }, + dictWord{4, 11, 337}, + dictWord{6, 11, 353}, + dictWord{7, 11, 1934}, + dictWord{8, 11, 488}, + dictWord{137, 11, 429}, + dictWord{7, 11, 236}, + dictWord{ + 7, + 11, + 1795, + }, + dictWord{8, 11, 259}, + dictWord{9, 11, 135}, + dictWord{9, 11, 177}, + dictWord{10, 11, 825}, + dictWord{11, 11, 115}, + dictWord{11, 11, 370}, + dictWord{ + 11, + 11, + 405, + }, + dictWord{11, 11, 604}, + dictWord{12, 11, 10}, + dictWord{12, 11, 667}, + dictWord{12, 11, 669}, + dictWord{13, 11, 76}, + dictWord{14, 11, 310}, + dictWord{15, 11, 76}, + dictWord{15, 11, 147}, + dictWord{148, 11, 23}, + dictWord{5, 0, 142}, + dictWord{134, 0, 546}, + dictWord{4, 11, 15}, + dictWord{5, 11, 22}, + dictWord{ + 6, + 11, + 244, + }, + dictWord{7, 11, 40}, + dictWord{7, 11, 200}, + dictWord{7, 11, 906}, + dictWord{7, 11, 1199}, + dictWord{9, 11, 616}, + dictWord{10, 11, 716}, + dictWord{ + 11, + 11, + 635, + }, + dictWord{11, 11, 801}, + dictWord{140, 11, 458}, + dictWord{5, 0, 466}, + dictWord{11, 0, 571}, + dictWord{12, 0, 198}, + dictWord{13, 0, 283}, + dictWord{ + 14, + 0, + 186, + }, + dictWord{15, 0, 21}, + dictWord{15, 0, 103}, + dictWord{135, 10, 329}, + dictWord{4, 0, 185}, + dictWord{5, 0, 257}, + dictWord{5, 0, 839}, + dictWord{5, 0, 936}, + dictWord{9, 0, 399}, + dictWord{10, 0, 258}, + dictWord{10, 0, 395}, + dictWord{10, 0, 734}, + dictWord{11, 0, 1014}, + dictWord{12, 0, 23}, + dictWord{13, 0, 350}, + dictWord{ + 14, + 0, + 150, + }, + dictWord{19, 0, 6}, + dictWord{135, 11, 1735}, + dictWord{12, 11, 36}, + dictWord{141, 11, 337}, + dictWord{5, 11, 598}, + dictWord{7, 11, 791}, + dictWord{ + 8, + 11, + 108, + }, + dictWord{137, 11, 123}, + dictWord{132, 10, 469}, + dictWord{7, 0, 404}, + dictWord{7, 0, 1377}, + dictWord{7, 0, 1430}, + dictWord{7, 0, 2017}, + dictWord{ + 8, + 0, + 149, + }, + dictWord{8, 0, 239}, + dictWord{8, 0, 512}, + dictWord{8, 0, 793}, + dictWord{8, 0, 818}, + dictWord{9, 0, 474}, + dictWord{9, 0, 595}, + dictWord{10, 0, 122}, + dictWord{10, 0, 565}, + dictWord{10, 0, 649}, + dictWord{10, 0, 783}, + dictWord{11, 0, 239}, + dictWord{11, 0, 295}, + dictWord{11, 0, 447}, + dictWord{11, 0, 528}, + dictWord{ + 11, + 0, + 639, + }, + dictWord{11, 0, 800}, + dictWord{12, 0, 25}, + dictWord{12, 0, 77}, + dictWord{12, 0, 157}, + dictWord{12, 0, 256}, + dictWord{12, 0, 316}, + dictWord{12, 0, 390}, + dictWord{12, 0, 391}, + dictWord{12, 0, 395}, + dictWord{12, 0, 478}, + dictWord{12, 0, 503}, + dictWord{12, 0, 592}, + dictWord{12, 0, 680}, + dictWord{13, 0, 50}, + dictWord{13, 0, 53}, + dictWord{13, 0, 132}, + dictWord{13, 0, 198}, + dictWord{13, 0, 322}, + dictWord{13, 0, 415}, + dictWord{13, 0, 511}, + dictWord{14, 0, 71}, + dictWord{ + 14, + 0, + 395, + }, + dictWord{15, 0, 71}, + dictWord{15, 0, 136}, + dictWord{17, 0, 123}, + dictWord{18, 0, 93}, + dictWord{147, 0, 58}, + dictWord{136, 0, 712}, + dictWord{ + 134, + 10, + 1743, + }, + dictWord{5, 10, 929}, + dictWord{6, 10, 340}, + dictWord{8, 10, 376}, + dictWord{136, 10, 807}, + dictWord{6, 0, 1848}, + dictWord{8, 0, 860}, + dictWord{ + 10, + 0, + 856, + }, + dictWord{10, 0, 859}, + dictWord{10, 0, 925}, + dictWord{10, 0, 941}, + dictWord{140, 0, 762}, + dictWord{6, 0, 629}, + dictWord{6, 0, 906}, + dictWord{9, 0, 810}, + dictWord{140, 0, 652}, + dictWord{5, 10, 218}, + dictWord{7, 10, 1610}, + dictWord{138, 10, 83}, + dictWord{7, 10, 1512}, + dictWord{135, 10, 1794}, + dictWord{ + 4, + 0, + 377, + }, + dictWord{24, 0, 13}, + dictWord{4, 11, 155}, + dictWord{7, 11, 1689}, + dictWord{11, 10, 0}, + dictWord{144, 10, 78}, + dictWord{4, 11, 164}, + dictWord{5, 11, 151}, + dictWord{5, 11, 730}, + dictWord{5, 11, 741}, + dictWord{7, 11, 498}, + dictWord{7, 11, 870}, + dictWord{7, 11, 1542}, + dictWord{12, 11, 213}, + dictWord{14, 11, 36}, + dictWord{14, 11, 391}, + dictWord{17, 11, 111}, + dictWord{18, 11, 6}, + dictWord{18, 11, 46}, + dictWord{18, 11, 151}, + dictWord{19, 11, 36}, + dictWord{20, 11, 32}, + dictWord{20, 11, 56}, + dictWord{20, 11, 69}, + dictWord{20, 11, 102}, + dictWord{21, 11, 4}, + dictWord{22, 11, 8}, + dictWord{22, 11, 10}, + dictWord{22, 11, 14}, + dictWord{ + 150, + 11, + 31, + }, + dictWord{7, 0, 1842}, + dictWord{133, 10, 571}, + dictWord{4, 10, 455}, + dictWord{4, 11, 624}, + dictWord{135, 11, 1752}, + dictWord{134, 0, 1501}, + dictWord{4, 11, 492}, + dictWord{5, 11, 451}, + dictWord{6, 10, 161}, + dictWord{7, 10, 372}, + dictWord{137, 10, 597}, + dictWord{132, 10, 349}, + dictWord{4, 0, 180}, + dictWord{135, 0, 1906}, + dictWord{135, 11, 835}, + dictWord{141, 11, 70}, + dictWord{132, 0, 491}, + dictWord{137, 10, 751}, + dictWord{6, 10, 432}, + dictWord{ + 139, + 10, + 322, + }, + dictWord{4, 0, 171}, + dictWord{138, 0, 234}, + dictWord{6, 11, 113}, + dictWord{135, 11, 436}, + dictWord{4, 0, 586}, + dictWord{7, 0, 1186}, + dictWord{ + 138, + 0, + 631, + }, + dictWord{5, 10, 468}, + dictWord{10, 10, 325}, + dictWord{11, 10, 856}, + dictWord{12, 10, 345}, + dictWord{143, 10, 104}, + dictWord{5, 10, 223}, + dictWord{10, 11, 592}, + dictWord{10, 11, 753}, + dictWord{12, 11, 317}, + dictWord{12, 11, 355}, + dictWord{12, 11, 465}, + dictWord{12, 11, 469}, + dictWord{ + 12, + 11, + 560, + }, + dictWord{12, 11, 578}, + dictWord{141, 11, 243}, + dictWord{132, 10, 566}, + dictWord{135, 11, 520}, + dictWord{4, 10, 59}, + dictWord{135, 10, 1394}, + dictWord{6, 10, 436}, + dictWord{139, 10, 481}, + dictWord{9, 0, 931}, + dictWord{10, 0, 334}, + dictWord{20, 0, 71}, + dictWord{4, 10, 48}, + dictWord{5, 10, 271}, + dictWord{ + 7, + 10, + 953, + }, + dictWord{135, 11, 1878}, + dictWord{11, 0, 170}, + dictWord{5, 10, 610}, + dictWord{136, 10, 457}, + dictWord{133, 10, 755}, + dictWord{6, 0, 1587}, + dictWord{135, 10, 1217}, + dictWord{4, 10, 197}, + dictWord{149, 11, 26}, + dictWord{133, 11, 585}, + dictWord{137, 11, 521}, + dictWord{133, 0, 765}, + dictWord{ + 133, + 10, + 217, + }, + dictWord{139, 11, 586}, + dictWord{133, 0, 424}, + dictWord{9, 11, 752}, + dictWord{12, 11, 610}, + dictWord{13, 11, 431}, + dictWord{16, 11, 59}, + dictWord{146, 11, 109}, + dictWord{136, 0, 714}, + dictWord{7, 0, 685}, + dictWord{132, 11, 307}, + dictWord{9, 0, 420}, + dictWord{10, 0, 269}, + dictWord{10, 0, 285}, + dictWord{10, 0, 576}, + dictWord{11, 0, 397}, + dictWord{13, 0, 175}, + dictWord{145, 0, 90}, + dictWord{132, 0, 429}, + dictWord{133, 11, 964}, + dictWord{9, 11, 463}, + dictWord{138, 11, 595}, + dictWord{7, 0, 18}, + dictWord{7, 0, 699}, + dictWord{7, 0, 1966}, + dictWord{8, 0, 752}, + dictWord{9, 0, 273}, + dictWord{9, 0, 412}, + dictWord{ + 9, + 0, + 703, + }, + dictWord{10, 0, 71}, + dictWord{10, 0, 427}, + dictWord{138, 0, 508}, + dictWord{4, 10, 165}, + dictWord{7, 10, 1398}, + dictWord{135, 10, 1829}, + dictWord{ + 4, + 0, + 53, + }, + dictWord{5, 0, 186}, + dictWord{7, 0, 752}, + dictWord{7, 0, 828}, + dictWord{142, 0, 116}, + dictWord{8, 0, 575}, + dictWord{10, 0, 289}, + dictWord{139, 0, 319}, + dictWord{132, 0, 675}, + dictWord{134, 0, 1424}, + dictWord{4, 11, 75}, + dictWord{5, 11, 180}, + dictWord{6, 11, 500}, + dictWord{7, 11, 58}, + dictWord{7, 11, 710}, + dictWord{138, 11, 645}, + dictWord{133, 11, 649}, + dictWord{6, 11, 276}, + dictWord{7, 11, 282}, + dictWord{7, 11, 879}, + dictWord{7, 11, 924}, + dictWord{8, 11, 459}, + dictWord{9, 11, 599}, + dictWord{9, 11, 754}, + dictWord{11, 11, 574}, + dictWord{12, 11, 128}, + dictWord{12, 11, 494}, + dictWord{13, 11, 52}, + dictWord{13, 11, 301}, + dictWord{15, 11, 30}, + dictWord{143, 11, 132}, + dictWord{6, 0, 647}, + dictWord{134, 0, 1095}, + dictWord{5, 10, 9}, + dictWord{7, 10, 297}, + dictWord{7, 10, 966}, + dictWord{140, 10, 306}, + dictWord{132, 11, 200}, + dictWord{134, 0, 1334}, + dictWord{5, 10, 146}, + dictWord{6, 10, 411}, + dictWord{138, 10, 721}, + dictWord{ + 6, + 0, + 209, + }, + dictWord{6, 0, 1141}, + dictWord{6, 0, 1288}, + dictWord{8, 0, 468}, + dictWord{9, 0, 210}, + dictWord{11, 0, 36}, + dictWord{12, 0, 28}, + dictWord{12, 0, 630}, + dictWord{13, 0, 21}, + dictWord{13, 0, 349}, + dictWord{14, 0, 7}, + dictWord{145, 0, 13}, + dictWord{6, 10, 177}, + dictWord{135, 10, 467}, + dictWord{4, 0, 342}, + dictWord{ + 135, + 0, + 1179, + }, + dictWord{10, 11, 454}, + dictWord{140, 11, 324}, + dictWord{4, 0, 928}, + dictWord{133, 0, 910}, + dictWord{7, 0, 1838}, + dictWord{6, 11, 225}, + dictWord{ + 137, + 11, + 211, + }, + dictWord{16, 0, 101}, + dictWord{20, 0, 115}, + dictWord{20, 0, 118}, + dictWord{148, 0, 122}, + dictWord{4, 0, 496}, + dictWord{135, 0, 856}, + dictWord{ + 4, + 0, + 318, + }, + dictWord{11, 0, 654}, + dictWord{7, 11, 718}, + dictWord{139, 11, 102}, + dictWord{8, 11, 58}, + dictWord{9, 11, 724}, + dictWord{11, 11, 809}, + dictWord{ + 13, + 11, + 113, + }, + dictWord{145, 11, 72}, + dictWord{5, 10, 200}, + dictWord{6, 11, 345}, + dictWord{135, 11, 1247}, + dictWord{8, 11, 767}, + dictWord{8, 11, 803}, + dictWord{ + 9, + 11, + 301, + }, + dictWord{137, 11, 903}, + dictWord{7, 0, 915}, + dictWord{8, 0, 247}, + dictWord{19, 0, 0}, + dictWord{7, 11, 1949}, + dictWord{136, 11, 674}, + dictWord{ + 4, + 0, + 202, + }, + dictWord{5, 0, 382}, + dictWord{6, 0, 454}, + dictWord{7, 0, 936}, + dictWord{7, 0, 1803}, + dictWord{8, 0, 758}, + dictWord{9, 0, 375}, + dictWord{9, 0, 895}, + dictWord{ + 10, + 0, + 743, + }, + dictWord{10, 0, 792}, + dictWord{11, 0, 978}, + dictWord{11, 0, 1012}, + dictWord{142, 0, 109}, + dictWord{7, 0, 1150}, + dictWord{7, 0, 1425}, + dictWord{ + 7, + 0, + 1453, + }, + dictWord{140, 0, 513}, + dictWord{134, 11, 259}, + dictWord{138, 0, 791}, + dictWord{11, 0, 821}, + dictWord{12, 0, 110}, + dictWord{12, 0, 153}, + dictWord{ + 18, + 0, + 41, + }, + dictWord{150, 0, 19}, + dictWord{134, 10, 481}, + dictWord{132, 0, 796}, + dictWord{6, 0, 445}, + dictWord{9, 0, 909}, + dictWord{136, 11, 254}, + dictWord{ + 10, + 0, + 776, + }, + dictWord{13, 0, 345}, + dictWord{142, 0, 425}, + dictWord{4, 10, 84}, + dictWord{7, 10, 1482}, + dictWord{10, 10, 76}, + dictWord{138, 10, 142}, + dictWord{ + 135, + 11, + 742, + }, + dictWord{6, 0, 578}, + dictWord{133, 10, 1015}, + dictWord{6, 0, 1387}, + dictWord{4, 10, 315}, + dictWord{5, 10, 507}, + dictWord{135, 10, 1370}, + dictWord{4, 0, 438}, + dictWord{133, 0, 555}, + dictWord{136, 0, 766}, + dictWord{133, 11, 248}, + dictWord{134, 10, 1722}, + dictWord{4, 11, 116}, + dictWord{5, 11, 95}, + dictWord{5, 11, 445}, + dictWord{7, 11, 1688}, + dictWord{8, 11, 29}, + dictWord{9, 11, 272}, + dictWord{11, 11, 509}, + dictWord{139, 11, 915}, + dictWord{135, 0, 541}, + dictWord{133, 11, 543}, + dictWord{8, 10, 222}, + dictWord{8, 10, 476}, + dictWord{9, 10, 238}, + dictWord{11, 10, 516}, + dictWord{11, 10, 575}, + dictWord{ + 15, + 10, + 109, + }, + dictWord{146, 10, 100}, + dictWord{6, 0, 880}, + dictWord{134, 0, 1191}, + dictWord{5, 11, 181}, + dictWord{136, 11, 41}, + dictWord{134, 0, 1506}, + dictWord{132, 11, 681}, + dictWord{7, 11, 25}, + dictWord{8, 11, 202}, + dictWord{138, 11, 536}, + dictWord{139, 0, 983}, + dictWord{137, 0, 768}, + dictWord{132, 0, 584}, + dictWord{9, 11, 423}, + dictWord{140, 11, 89}, + dictWord{8, 11, 113}, + dictWord{9, 11, 877}, + dictWord{10, 11, 554}, + dictWord{11, 11, 83}, + dictWord{12, 11, 136}, + dictWord{147, 11, 109}, + dictWord{7, 10, 706}, + dictWord{7, 10, 1058}, + dictWord{138, 10, 538}, + dictWord{133, 11, 976}, + dictWord{4, 11, 206}, + dictWord{ + 135, + 11, + 746, + }, + dictWord{136, 11, 526}, + dictWord{140, 0, 737}, + dictWord{11, 10, 92}, + dictWord{11, 10, 196}, + dictWord{11, 10, 409}, + dictWord{11, 10, 450}, + dictWord{11, 10, 666}, + dictWord{11, 10, 777}, + dictWord{12, 10, 262}, + dictWord{13, 10, 385}, + dictWord{13, 10, 393}, + dictWord{15, 10, 115}, + dictWord{ + 16, + 10, + 45, + }, + dictWord{145, 10, 82}, + dictWord{4, 0, 226}, + dictWord{4, 0, 326}, + dictWord{7, 0, 1770}, + dictWord{4, 11, 319}, + dictWord{5, 11, 699}, + dictWord{138, 11, 673}, + dictWord{6, 10, 40}, + dictWord{135, 10, 1781}, + dictWord{5, 0, 426}, + dictWord{8, 0, 30}, + dictWord{9, 0, 2}, + dictWord{11, 0, 549}, + dictWord{147, 0, 122}, + dictWord{ + 6, + 0, + 1161, + }, + dictWord{134, 0, 1329}, + dictWord{138, 10, 97}, + dictWord{6, 10, 423}, + dictWord{7, 10, 665}, + dictWord{135, 10, 1210}, + dictWord{7, 11, 13}, + dictWord{ + 8, + 11, + 226, + }, + dictWord{10, 11, 537}, + dictWord{11, 11, 570}, + dictWord{11, 11, 605}, + dictWord{11, 11, 799}, + dictWord{11, 11, 804}, + dictWord{12, 11, 85}, + dictWord{12, 11, 516}, + dictWord{12, 11, 623}, + dictWord{13, 11, 112}, + dictWord{13, 11, 361}, + dictWord{14, 11, 77}, + dictWord{14, 11, 78}, + dictWord{17, 11, 28}, + dictWord{147, 11, 110}, + dictWord{132, 11, 769}, + dictWord{132, 11, 551}, + dictWord{132, 11, 728}, + dictWord{147, 0, 117}, + dictWord{9, 11, 57}, + dictWord{ + 9, + 11, + 459, + }, + dictWord{10, 11, 425}, + dictWord{11, 11, 119}, + dictWord{12, 11, 184}, + dictWord{12, 11, 371}, + dictWord{13, 11, 358}, + dictWord{145, 11, 51}, + dictWord{ + 5, + 11, + 188, + }, + dictWord{5, 11, 814}, + dictWord{8, 11, 10}, + dictWord{9, 11, 421}, + dictWord{9, 11, 729}, + dictWord{10, 11, 609}, + dictWord{139, 11, 689}, + dictWord{134, 11, 624}, + dictWord{135, 11, 298}, + dictWord{135, 0, 462}, + dictWord{4, 0, 345}, + dictWord{139, 10, 624}, + dictWord{136, 10, 574}, + dictWord{ + 4, + 0, + 385, + }, + dictWord{7, 0, 265}, + dictWord{135, 0, 587}, + dictWord{6, 0, 808}, + dictWord{132, 11, 528}, + dictWord{133, 0, 398}, + dictWord{132, 10, 354}, + dictWord{ + 4, + 0, + 347, + }, + dictWord{5, 0, 423}, + dictWord{5, 0, 996}, + dictWord{135, 0, 1329}, + dictWord{135, 10, 1558}, + dictWord{7, 0, 1259}, + dictWord{9, 0, 125}, + dictWord{ + 139, + 0, + 65, + }, + dictWord{5, 0, 136}, + dictWord{6, 0, 136}, + dictWord{136, 0, 644}, + dictWord{5, 11, 104}, + dictWord{6, 11, 173}, + dictWord{135, 11, 1631}, + dictWord{ + 135, + 0, + 469, + }, + dictWord{133, 10, 830}, + dictWord{4, 0, 278}, + dictWord{5, 0, 465}, + dictWord{135, 0, 1367}, + dictWord{7, 11, 810}, + dictWord{8, 11, 138}, + dictWord{ + 8, + 11, + 342, + }, + dictWord{9, 11, 84}, + dictWord{10, 11, 193}, + dictWord{11, 11, 883}, + dictWord{140, 11, 359}, + dictWord{5, 10, 496}, + dictWord{135, 10, 203}, + dictWord{ + 4, + 0, + 433, + }, + dictWord{133, 0, 719}, + dictWord{6, 11, 95}, + dictWord{134, 10, 547}, + dictWord{5, 10, 88}, + dictWord{137, 10, 239}, + dictWord{6, 11, 406}, + dictWord{ + 10, + 11, + 409, + }, + dictWord{10, 11, 447}, + dictWord{11, 11, 44}, + dictWord{140, 11, 100}, + dictWord{134, 0, 1423}, + dictWord{7, 10, 650}, + dictWord{135, 10, 1310}, + dictWord{134, 0, 749}, + dictWord{135, 11, 1243}, + dictWord{135, 0, 1363}, + dictWord{6, 0, 381}, + dictWord{7, 0, 645}, + dictWord{7, 0, 694}, + dictWord{8, 0, 546}, + dictWord{7, 10, 1076}, + dictWord{9, 10, 80}, + dictWord{11, 10, 78}, + dictWord{11, 10, 421}, + dictWord{11, 10, 534}, + dictWord{140, 10, 545}, + dictWord{ + 134, + 11, + 1636, + }, + dictWord{135, 11, 1344}, + dictWord{12, 0, 277}, + dictWord{7, 10, 274}, + dictWord{11, 10, 479}, + dictWord{139, 10, 507}, + dictWord{6, 0, 705}, + dictWord{ + 6, + 0, + 783, + }, + dictWord{6, 0, 1275}, + dictWord{6, 0, 1481}, + dictWord{4, 11, 282}, + dictWord{7, 11, 1034}, + dictWord{11, 11, 398}, + dictWord{11, 11, 634}, + dictWord{ + 12, + 11, + 1, + }, + dictWord{12, 11, 79}, + dictWord{12, 11, 544}, + dictWord{14, 11, 237}, + dictWord{17, 11, 10}, + dictWord{146, 11, 20}, + dictWord{134, 0, 453}, + dictWord{ + 4, + 0, + 555, + }, + dictWord{8, 0, 536}, + dictWord{10, 0, 288}, + dictWord{11, 0, 1005}, + dictWord{4, 10, 497}, + dictWord{135, 10, 1584}, + dictWord{5, 11, 118}, + dictWord{ + 5, + 11, + 499, + }, + dictWord{6, 11, 476}, + dictWord{7, 11, 600}, + dictWord{7, 11, 888}, + dictWord{135, 11, 1096}, + dictWord{138, 0, 987}, + dictWord{7, 0, 1107}, + dictWord{ + 7, + 10, + 261, + }, + dictWord{7, 10, 1115}, + dictWord{7, 10, 1354}, + dictWord{7, 10, 1588}, + dictWord{7, 10, 1705}, + dictWord{7, 10, 1902}, + dictWord{9, 10, 465}, + dictWord{10, 10, 248}, + dictWord{10, 10, 349}, + dictWord{10, 10, 647}, + dictWord{11, 10, 527}, + dictWord{11, 10, 660}, + dictWord{11, 10, 669}, + dictWord{ + 12, + 10, + 529, + }, + dictWord{141, 10, 305}, + dictWord{7, 11, 296}, + dictWord{7, 11, 596}, + dictWord{8, 11, 560}, + dictWord{8, 11, 586}, + dictWord{9, 11, 612}, + dictWord{ + 11, + 11, + 100, + }, + dictWord{11, 11, 304}, + dictWord{12, 11, 46}, + dictWord{13, 11, 89}, + dictWord{14, 11, 112}, + dictWord{145, 11, 122}, + dictWord{9, 0, 370}, + dictWord{ + 138, + 0, + 90, + }, + dictWord{136, 10, 13}, + dictWord{132, 0, 860}, + dictWord{7, 10, 642}, + dictWord{8, 10, 250}, + dictWord{11, 10, 123}, + dictWord{11, 10, 137}, + dictWord{ + 13, + 10, + 48, + }, + dictWord{142, 10, 95}, + dictWord{135, 10, 1429}, + dictWord{137, 11, 321}, + dictWord{132, 0, 257}, + dictWord{135, 0, 2031}, + dictWord{7, 0, 1768}, + dictWord{7, 11, 1599}, + dictWord{7, 11, 1723}, + dictWord{8, 11, 79}, + dictWord{8, 11, 106}, + dictWord{8, 11, 190}, + dictWord{8, 11, 302}, + dictWord{8, 11, 383}, + dictWord{9, 11, 119}, + dictWord{9, 11, 233}, + dictWord{9, 11, 298}, + dictWord{9, 11, 419}, + dictWord{9, 11, 471}, + dictWord{10, 11, 181}, + dictWord{10, 11, 406}, + dictWord{11, 11, 57}, + dictWord{11, 11, 85}, + dictWord{11, 11, 120}, + dictWord{11, 11, 177}, + dictWord{11, 11, 296}, + dictWord{11, 11, 382}, + dictWord{11, 11, 454}, + dictWord{11, 11, 758}, + dictWord{11, 11, 999}, + dictWord{12, 11, 27}, + dictWord{12, 11, 98}, + dictWord{12, 11, 131}, + dictWord{12, 11, 245}, + dictWord{ + 12, + 11, + 312, + }, + dictWord{12, 11, 446}, + dictWord{12, 11, 454}, + dictWord{13, 11, 25}, + dictWord{13, 11, 98}, + dictWord{13, 11, 426}, + dictWord{13, 11, 508}, + dictWord{ + 14, + 11, + 6, + }, + dictWord{14, 11, 163}, + dictWord{14, 11, 272}, + dictWord{14, 11, 277}, + dictWord{14, 11, 370}, + dictWord{15, 11, 95}, + dictWord{15, 11, 138}, + dictWord{ + 15, + 11, + 167, + }, + dictWord{17, 11, 18}, + dictWord{17, 11, 38}, + dictWord{20, 11, 96}, + dictWord{149, 11, 32}, + dictWord{5, 11, 722}, + dictWord{134, 11, 1759}, + dictWord{145, 11, 16}, + dictWord{6, 0, 1071}, + dictWord{134, 0, 1561}, + dictWord{10, 10, 545}, + dictWord{140, 10, 301}, + dictWord{6, 0, 83}, + dictWord{6, 0, 1733}, + dictWord{135, 0, 1389}, + dictWord{4, 0, 835}, + dictWord{135, 0, 1818}, + dictWord{133, 11, 258}, + dictWord{4, 10, 904}, + dictWord{133, 10, 794}, + dictWord{ + 134, + 0, + 2006, + }, + dictWord{5, 11, 30}, + dictWord{7, 11, 495}, + dictWord{8, 11, 134}, + dictWord{9, 11, 788}, + dictWord{140, 11, 438}, + dictWord{135, 11, 2004}, + dictWord{ + 137, + 0, + 696, + }, + dictWord{5, 11, 50}, + dictWord{6, 11, 439}, + dictWord{7, 11, 780}, + dictWord{135, 11, 1040}, + dictWord{7, 11, 772}, + dictWord{7, 11, 1104}, + dictWord{ + 7, + 11, + 1647, + }, + dictWord{11, 11, 269}, + dictWord{11, 11, 539}, + dictWord{11, 11, 607}, + dictWord{11, 11, 627}, + dictWord{11, 11, 706}, + dictWord{11, 11, 975}, + dictWord{12, 11, 248}, + dictWord{12, 11, 311}, + dictWord{12, 11, 434}, + dictWord{12, 11, 600}, + dictWord{12, 11, 622}, + dictWord{13, 11, 297}, + dictWord{ + 13, + 11, + 367, + }, + dictWord{13, 11, 485}, + dictWord{14, 11, 69}, + dictWord{14, 11, 409}, + dictWord{143, 11, 108}, + dictWord{5, 11, 1}, + dictWord{6, 11, 81}, + dictWord{ + 138, + 11, + 520, + }, + dictWord{7, 0, 1718}, + dictWord{9, 0, 95}, + dictWord{9, 0, 274}, + dictWord{10, 0, 279}, + dictWord{10, 0, 317}, + dictWord{10, 0, 420}, + dictWord{11, 0, 303}, + dictWord{11, 0, 808}, + dictWord{12, 0, 134}, + dictWord{12, 0, 367}, + dictWord{13, 0, 149}, + dictWord{13, 0, 347}, + dictWord{14, 0, 349}, + dictWord{14, 0, 406}, + dictWord{ + 18, + 0, + 22, + }, + dictWord{18, 0, 89}, + dictWord{18, 0, 122}, + dictWord{147, 0, 47}, + dictWord{5, 11, 482}, + dictWord{8, 11, 98}, + dictWord{9, 11, 172}, + dictWord{10, 11, 222}, + dictWord{10, 11, 700}, + dictWord{10, 11, 822}, + dictWord{11, 11, 302}, + dictWord{11, 11, 778}, + dictWord{12, 11, 50}, + dictWord{12, 11, 127}, + dictWord{ + 12, + 11, + 396, + }, + dictWord{13, 11, 62}, + dictWord{13, 11, 328}, + dictWord{14, 11, 122}, + dictWord{147, 11, 72}, + dictWord{7, 10, 386}, + dictWord{138, 10, 713}, + dictWord{ + 6, + 10, + 7, + }, + dictWord{6, 10, 35}, + dictWord{7, 10, 147}, + dictWord{7, 10, 1069}, + dictWord{7, 10, 1568}, + dictWord{7, 10, 1575}, + dictWord{7, 10, 1917}, + dictWord{ + 8, + 10, + 43, + }, + dictWord{8, 10, 208}, + dictWord{9, 10, 128}, + dictWord{9, 10, 866}, + dictWord{10, 10, 20}, + dictWord{11, 10, 981}, + dictWord{147, 10, 33}, + dictWord{ + 133, + 0, + 26, + }, + dictWord{132, 0, 550}, + dictWord{5, 11, 2}, + dictWord{7, 11, 1494}, + dictWord{136, 11, 589}, + dictWord{6, 11, 512}, + dictWord{7, 11, 797}, + dictWord{ + 8, + 11, + 253, + }, + dictWord{9, 11, 77}, + dictWord{10, 11, 1}, + dictWord{10, 11, 129}, + dictWord{10, 11, 225}, + dictWord{11, 11, 118}, + dictWord{11, 11, 226}, + dictWord{ + 11, + 11, + 251, + }, + dictWord{11, 11, 430}, + dictWord{11, 11, 701}, + dictWord{11, 11, 974}, + dictWord{11, 11, 982}, + dictWord{12, 11, 64}, + dictWord{12, 11, 260}, + dictWord{ + 12, + 11, + 488, + }, + dictWord{140, 11, 690}, + dictWord{7, 10, 893}, + dictWord{141, 10, 424}, + dictWord{134, 0, 901}, + dictWord{136, 0, 822}, + dictWord{4, 0, 902}, + dictWord{5, 0, 809}, + dictWord{134, 0, 122}, + dictWord{6, 0, 807}, + dictWord{134, 0, 1366}, + dictWord{7, 0, 262}, + dictWord{5, 11, 748}, + dictWord{134, 11, 553}, + dictWord{133, 0, 620}, + dictWord{4, 0, 34}, + dictWord{5, 0, 574}, + dictWord{7, 0, 279}, + dictWord{7, 0, 1624}, + dictWord{136, 0, 601}, + dictWord{9, 0, 170}, + dictWord{ + 6, + 10, + 322, + }, + dictWord{9, 10, 552}, + dictWord{11, 10, 274}, + dictWord{13, 10, 209}, + dictWord{13, 10, 499}, + dictWord{14, 10, 85}, + dictWord{15, 10, 126}, + dictWord{ + 145, + 10, + 70, + }, + dictWord{132, 0, 537}, + dictWord{4, 11, 12}, + dictWord{7, 11, 420}, + dictWord{7, 11, 522}, + dictWord{7, 11, 809}, + dictWord{8, 11, 797}, + dictWord{ + 141, + 11, + 88, + }, + dictWord{133, 0, 332}, + dictWord{8, 10, 83}, + dictWord{8, 10, 742}, + dictWord{8, 10, 817}, + dictWord{9, 10, 28}, + dictWord{9, 10, 29}, + dictWord{9, 10, 885}, + dictWord{10, 10, 387}, + dictWord{11, 10, 633}, + dictWord{11, 10, 740}, + dictWord{13, 10, 235}, + dictWord{13, 10, 254}, + dictWord{15, 10, 143}, + dictWord{ + 143, + 10, + 146, + }, + dictWord{6, 0, 1909}, + dictWord{9, 0, 964}, + dictWord{12, 0, 822}, + dictWord{12, 0, 854}, + dictWord{12, 0, 865}, + dictWord{12, 0, 910}, + dictWord{12, 0, 938}, + dictWord{15, 0, 169}, + dictWord{15, 0, 208}, + dictWord{15, 0, 211}, + dictWord{18, 0, 205}, + dictWord{18, 0, 206}, + dictWord{18, 0, 220}, + dictWord{18, 0, 223}, + dictWord{152, 0, 24}, + dictWord{140, 10, 49}, + dictWord{5, 11, 528}, + dictWord{135, 11, 1580}, + dictWord{6, 0, 261}, + dictWord{8, 0, 182}, + dictWord{139, 0, 943}, + dictWord{134, 0, 1721}, + dictWord{4, 0, 933}, + dictWord{133, 0, 880}, + dictWord{136, 11, 321}, + dictWord{5, 11, 266}, + dictWord{9, 11, 290}, + dictWord{9, 11, 364}, + dictWord{10, 11, 293}, + dictWord{11, 11, 606}, + dictWord{142, 11, 45}, + dictWord{6, 0, 1609}, + dictWord{4, 11, 50}, + dictWord{6, 11, 510}, + dictWord{6, 11, 594}, + dictWord{9, 11, 121}, + dictWord{10, 11, 49}, + dictWord{10, 11, 412}, + dictWord{139, 11, 834}, + dictWord{7, 0, 895}, + dictWord{136, 11, 748}, + dictWord{132, 11, 466}, + dictWord{4, 10, 110}, + dictWord{10, 10, 415}, + dictWord{10, 10, 597}, + dictWord{142, 10, 206}, + dictWord{133, 0, 812}, + dictWord{135, 11, 281}, + dictWord{ + 6, + 0, + 1890, + }, + dictWord{6, 0, 1902}, + dictWord{6, 0, 1916}, + dictWord{9, 0, 929}, + dictWord{9, 0, 942}, + dictWord{9, 0, 975}, + dictWord{9, 0, 984}, + dictWord{9, 0, 986}, + dictWord{ + 9, + 0, + 1011, + }, + dictWord{9, 0, 1019}, + dictWord{12, 0, 804}, + dictWord{12, 0, 851}, + dictWord{12, 0, 867}, + dictWord{12, 0, 916}, + dictWord{12, 0, 923}, + dictWord{ + 15, + 0, + 194, + }, + dictWord{15, 0, 204}, + dictWord{15, 0, 210}, + dictWord{15, 0, 222}, + dictWord{15, 0, 223}, + dictWord{15, 0, 229}, + dictWord{15, 0, 250}, + dictWord{ + 18, + 0, + 179, + }, + dictWord{18, 0, 186}, + dictWord{18, 0, 192}, + dictWord{7, 10, 205}, + dictWord{135, 10, 2000}, + dictWord{132, 11, 667}, + dictWord{135, 0, 778}, + dictWord{ + 4, + 0, + 137, + }, + dictWord{7, 0, 1178}, + dictWord{135, 0, 1520}, + dictWord{134, 0, 1314}, + dictWord{4, 11, 242}, + dictWord{134, 11, 333}, + dictWord{6, 0, 1661}, + dictWord{7, 0, 1975}, + dictWord{7, 0, 2009}, + dictWord{135, 0, 2011}, + dictWord{134, 0, 1591}, + dictWord{4, 10, 283}, + dictWord{135, 10, 1194}, + dictWord{ + 11, + 0, + 820, + }, + dictWord{150, 0, 51}, + dictWord{4, 11, 39}, + dictWord{5, 11, 36}, + dictWord{7, 11, 1843}, + dictWord{8, 11, 407}, + dictWord{11, 11, 144}, + dictWord{ + 140, + 11, + 523, + }, + dictWord{134, 10, 1720}, + dictWord{4, 11, 510}, + dictWord{7, 11, 29}, + dictWord{7, 11, 66}, + dictWord{7, 11, 1980}, + dictWord{10, 11, 487}, + dictWord{ + 10, + 11, + 809, + }, + dictWord{146, 11, 9}, + dictWord{5, 0, 89}, + dictWord{7, 0, 1915}, + dictWord{9, 0, 185}, + dictWord{9, 0, 235}, + dictWord{10, 0, 64}, + dictWord{10, 0, 270}, + dictWord{10, 0, 403}, + dictWord{10, 0, 469}, + dictWord{10, 0, 529}, + dictWord{10, 0, 590}, + dictWord{11, 0, 140}, + dictWord{11, 0, 860}, + dictWord{13, 0, 1}, + dictWord{ + 13, + 0, + 422, + }, + dictWord{14, 0, 341}, + dictWord{14, 0, 364}, + dictWord{17, 0, 93}, + dictWord{18, 0, 113}, + dictWord{19, 0, 97}, + dictWord{147, 0, 113}, + dictWord{133, 0, 695}, + dictWord{6, 0, 987}, + dictWord{134, 0, 1160}, + dictWord{5, 0, 6}, + dictWord{6, 0, 183}, + dictWord{7, 0, 680}, + dictWord{7, 0, 978}, + dictWord{7, 0, 1013}, + dictWord{ + 7, + 0, + 1055, + }, + dictWord{12, 0, 230}, + dictWord{13, 0, 172}, + dictWord{146, 0, 29}, + dictWord{134, 11, 570}, + dictWord{132, 11, 787}, + dictWord{134, 11, 518}, + dictWord{ + 6, + 0, + 29, + }, + dictWord{139, 0, 63}, + dictWord{132, 11, 516}, + dictWord{136, 11, 821}, + dictWord{132, 0, 311}, + dictWord{134, 0, 1740}, + dictWord{7, 0, 170}, + dictWord{8, 0, 90}, + dictWord{8, 0, 177}, + dictWord{8, 0, 415}, + dictWord{11, 0, 714}, + dictWord{14, 0, 281}, + dictWord{136, 10, 735}, + dictWord{134, 0, 1961}, + dictWord{ + 135, + 11, + 1405, + }, + dictWord{4, 11, 10}, + dictWord{7, 11, 917}, + dictWord{139, 11, 786}, + dictWord{5, 10, 132}, + dictWord{9, 10, 486}, + dictWord{9, 10, 715}, + dictWord{ + 10, + 10, + 458, + }, + dictWord{11, 10, 373}, + dictWord{11, 10, 668}, + dictWord{11, 10, 795}, + dictWord{11, 10, 897}, + dictWord{12, 10, 272}, + dictWord{12, 10, 424}, + dictWord{12, 10, 539}, + dictWord{12, 10, 558}, + dictWord{14, 10, 245}, + dictWord{14, 10, 263}, + dictWord{14, 10, 264}, + dictWord{14, 10, 393}, + dictWord{ + 142, + 10, + 403, + }, + dictWord{11, 0, 91}, + dictWord{13, 0, 129}, + dictWord{15, 0, 101}, + dictWord{145, 0, 125}, + dictWord{135, 0, 1132}, + dictWord{4, 0, 494}, + dictWord{6, 0, 74}, + dictWord{7, 0, 44}, + dictWord{7, 0, 407}, + dictWord{12, 0, 17}, + dictWord{15, 0, 5}, + dictWord{148, 0, 11}, + dictWord{133, 10, 379}, + dictWord{5, 0, 270}, + dictWord{ + 5, + 11, + 684, + }, + dictWord{6, 10, 89}, + dictWord{6, 10, 400}, + dictWord{7, 10, 1569}, + dictWord{7, 10, 1623}, + dictWord{7, 10, 1850}, + dictWord{8, 10, 218}, + dictWord{ + 8, + 10, + 422, + }, + dictWord{9, 10, 570}, + dictWord{138, 10, 626}, + dictWord{4, 0, 276}, + dictWord{133, 0, 296}, + dictWord{6, 0, 1523}, + dictWord{134, 11, 27}, + dictWord{ + 6, + 10, + 387, + }, + dictWord{7, 10, 882}, + dictWord{141, 10, 111}, + dictWord{6, 10, 224}, + dictWord{7, 10, 877}, + dictWord{137, 10, 647}, + dictWord{135, 10, 790}, + dictWord{ + 4, + 0, + 7, + }, + dictWord{5, 0, 90}, + dictWord{5, 0, 158}, + dictWord{6, 0, 542}, + dictWord{7, 0, 221}, + dictWord{7, 0, 1574}, + dictWord{9, 0, 490}, + dictWord{10, 0, 540}, + dictWord{ + 11, + 0, + 443, + }, + dictWord{139, 0, 757}, + dictWord{7, 0, 588}, + dictWord{9, 0, 175}, + dictWord{138, 0, 530}, + dictWord{135, 10, 394}, + dictWord{142, 11, 23}, + dictWord{ + 134, + 0, + 786, + }, + dictWord{135, 0, 580}, + dictWord{7, 0, 88}, + dictWord{136, 0, 627}, + dictWord{5, 0, 872}, + dictWord{6, 0, 57}, + dictWord{7, 0, 471}, + dictWord{9, 0, 447}, + dictWord{137, 0, 454}, + dictWord{6, 11, 342}, + dictWord{6, 11, 496}, + dictWord{8, 11, 275}, + dictWord{137, 11, 206}, + dictWord{4, 11, 909}, + dictWord{133, 11, 940}, + dictWord{6, 0, 735}, + dictWord{132, 11, 891}, + dictWord{8, 0, 845}, + dictWord{8, 0, 916}, + dictWord{135, 10, 1409}, + dictWord{5, 0, 31}, + dictWord{134, 0, 614}, + dictWord{11, 0, 458}, + dictWord{12, 0, 15}, + dictWord{140, 0, 432}, + dictWord{8, 0, 330}, + dictWord{140, 0, 477}, + dictWord{4, 0, 530}, + dictWord{5, 0, 521}, + dictWord{ + 7, + 0, + 1200, + }, + dictWord{10, 0, 460}, + dictWord{132, 11, 687}, + dictWord{6, 0, 424}, + dictWord{135, 0, 1866}, + dictWord{9, 0, 569}, + dictWord{12, 0, 12}, + dictWord{ + 12, + 0, + 81, + }, + dictWord{12, 0, 319}, + dictWord{13, 0, 69}, + dictWord{14, 0, 259}, + dictWord{16, 0, 87}, + dictWord{17, 0, 1}, + dictWord{17, 0, 21}, + dictWord{17, 0, 24}, + dictWord{ + 18, + 0, + 15, + }, + dictWord{18, 0, 56}, + dictWord{18, 0, 59}, + dictWord{18, 0, 127}, + dictWord{18, 0, 154}, + dictWord{19, 0, 19}, + dictWord{148, 0, 31}, + dictWord{7, 0, 1302}, + dictWord{136, 10, 38}, + dictWord{134, 11, 253}, + dictWord{5, 10, 261}, + dictWord{7, 10, 78}, + dictWord{7, 10, 199}, + dictWord{8, 10, 815}, + dictWord{9, 10, 126}, + dictWord{138, 10, 342}, + dictWord{5, 0, 595}, + dictWord{135, 0, 1863}, + dictWord{6, 11, 41}, + dictWord{141, 11, 160}, + dictWord{5, 0, 13}, + dictWord{134, 0, 142}, + dictWord{6, 0, 97}, + dictWord{7, 0, 116}, + dictWord{8, 0, 322}, + dictWord{8, 0, 755}, + dictWord{9, 0, 548}, + dictWord{10, 0, 714}, + dictWord{11, 0, 884}, + dictWord{13, 0, 324}, + dictWord{7, 11, 1304}, + dictWord{138, 11, 477}, + dictWord{132, 10, 628}, + dictWord{134, 11, 1718}, + dictWord{7, 10, 266}, + dictWord{136, 10, 804}, + dictWord{135, 10, 208}, + dictWord{7, 0, 1021}, + dictWord{6, 10, 79}, + dictWord{135, 10, 1519}, + dictWord{7, 0, 1472}, + dictWord{135, 0, 1554}, + dictWord{6, 11, 362}, + dictWord{146, 11, 51}, + dictWord{7, 0, 1071}, + dictWord{7, 0, 1541}, + dictWord{7, 0, 1767}, + dictWord{7, 0, 1806}, + dictWord{11, 0, 162}, + dictWord{11, 0, 242}, + dictWord{11, 0, 452}, + dictWord{12, 0, 605}, + dictWord{15, 0, 26}, + dictWord{144, 0, 44}, + dictWord{136, 10, 741}, + dictWord{133, 11, 115}, + dictWord{145, 0, 115}, + dictWord{134, 10, 376}, + dictWord{6, 0, 1406}, + dictWord{134, 0, 1543}, + dictWord{5, 11, 193}, + dictWord{12, 11, 178}, + dictWord{13, 11, 130}, + dictWord{ + 145, + 11, + 84, + }, + dictWord{135, 0, 1111}, + dictWord{8, 0, 1}, + dictWord{9, 0, 650}, + dictWord{10, 0, 326}, + dictWord{5, 11, 705}, + dictWord{137, 11, 606}, + dictWord{5, 0, 488}, + dictWord{6, 0, 527}, + dictWord{7, 0, 489}, + dictWord{7, 0, 1636}, + dictWord{8, 0, 121}, + dictWord{8, 0, 144}, + dictWord{8, 0, 359}, + dictWord{9, 0, 193}, + dictWord{9, 0, 241}, + dictWord{9, 0, 336}, + dictWord{9, 0, 882}, + dictWord{11, 0, 266}, + dictWord{11, 0, 372}, + dictWord{11, 0, 944}, + dictWord{12, 0, 401}, + dictWord{140, 0, 641}, + dictWord{135, 11, 174}, + dictWord{6, 0, 267}, + dictWord{7, 10, 244}, + dictWord{7, 10, 632}, + dictWord{7, 10, 1609}, + dictWord{8, 10, 178}, + dictWord{8, 10, 638}, + dictWord{141, 10, 58}, + dictWord{134, 0, 1983}, + dictWord{134, 0, 1155}, + dictWord{134, 0, 1575}, + dictWord{134, 0, 1438}, + dictWord{9, 0, 31}, + dictWord{ + 10, + 0, + 244, + }, + dictWord{10, 0, 699}, + dictWord{12, 0, 149}, + dictWord{141, 0, 497}, + dictWord{133, 0, 377}, + dictWord{4, 11, 122}, + dictWord{5, 11, 796}, + dictWord{ + 5, + 11, + 952, + }, + dictWord{6, 11, 1660}, + dictWord{6, 11, 1671}, + dictWord{8, 11, 567}, + dictWord{9, 11, 687}, + dictWord{9, 11, 742}, + dictWord{10, 11, 686}, + dictWord{ + 11, + 11, + 356, + }, + dictWord{11, 11, 682}, + dictWord{140, 11, 281}, + dictWord{145, 0, 101}, + dictWord{11, 11, 0}, + dictWord{144, 11, 78}, + dictWord{5, 11, 179}, + dictWord{ + 5, + 10, + 791, + }, + dictWord{7, 11, 1095}, + dictWord{135, 11, 1213}, + dictWord{8, 11, 372}, + dictWord{9, 11, 122}, + dictWord{138, 11, 175}, + dictWord{7, 10, 686}, + dictWord{8, 10, 33}, + dictWord{8, 10, 238}, + dictWord{10, 10, 616}, + dictWord{11, 10, 467}, + dictWord{11, 10, 881}, + dictWord{13, 10, 217}, + dictWord{13, 10, 253}, + dictWord{142, 10, 268}, + dictWord{9, 0, 476}, + dictWord{4, 11, 66}, + dictWord{7, 11, 722}, + dictWord{135, 11, 904}, + dictWord{7, 11, 352}, + dictWord{137, 11, 684}, + dictWord{135, 0, 2023}, + dictWord{135, 0, 1836}, + dictWord{132, 10, 447}, + dictWord{5, 0, 843}, + dictWord{144, 0, 35}, + dictWord{137, 11, 779}, + dictWord{ + 141, + 11, + 35, + }, + dictWord{4, 10, 128}, + dictWord{5, 10, 415}, + dictWord{6, 10, 462}, + dictWord{7, 10, 294}, + dictWord{7, 10, 578}, + dictWord{10, 10, 710}, + dictWord{ + 139, + 10, + 86, + }, + dictWord{132, 0, 554}, + dictWord{133, 0, 536}, + dictWord{136, 10, 587}, + dictWord{5, 0, 207}, + dictWord{9, 0, 79}, + dictWord{11, 0, 625}, + dictWord{ + 145, + 0, + 7, + }, + dictWord{7, 0, 1371}, + dictWord{6, 10, 427}, + dictWord{138, 10, 692}, + dictWord{4, 0, 424}, + dictWord{4, 10, 195}, + dictWord{135, 10, 802}, + dictWord{ + 8, + 0, + 785, + }, + dictWord{133, 11, 564}, + dictWord{135, 0, 336}, + dictWord{4, 0, 896}, + dictWord{6, 0, 1777}, + dictWord{134, 11, 556}, + dictWord{137, 11, 103}, + dictWord{134, 10, 1683}, + dictWord{7, 11, 544}, + dictWord{8, 11, 719}, + dictWord{138, 11, 61}, + dictWord{138, 10, 472}, + dictWord{4, 11, 5}, + dictWord{5, 11, 498}, + dictWord{136, 11, 637}, + dictWord{7, 0, 750}, + dictWord{9, 0, 223}, + dictWord{11, 0, 27}, + dictWord{11, 0, 466}, + dictWord{12, 0, 624}, + dictWord{14, 0, 265}, + dictWord{ + 146, + 0, + 61, + }, + dictWord{12, 0, 238}, + dictWord{18, 0, 155}, + dictWord{12, 11, 238}, + dictWord{146, 11, 155}, + dictWord{151, 10, 28}, + dictWord{133, 11, 927}, + dictWord{12, 0, 383}, + dictWord{5, 10, 3}, + dictWord{8, 10, 578}, + dictWord{9, 10, 118}, + dictWord{10, 10, 705}, + dictWord{141, 10, 279}, + dictWord{4, 11, 893}, + dictWord{ + 5, + 11, + 780, + }, + dictWord{133, 11, 893}, + dictWord{4, 0, 603}, + dictWord{133, 0, 661}, + dictWord{4, 0, 11}, + dictWord{6, 0, 128}, + dictWord{7, 0, 231}, + dictWord{ + 7, + 0, + 1533, + }, + dictWord{10, 0, 725}, + dictWord{5, 10, 229}, + dictWord{5, 11, 238}, + dictWord{135, 11, 1350}, + dictWord{8, 10, 102}, + dictWord{10, 10, 578}, + dictWord{ + 10, + 10, + 672, + }, + dictWord{12, 10, 496}, + dictWord{13, 10, 408}, + dictWord{14, 10, 121}, + dictWord{145, 10, 106}, + dictWord{132, 0, 476}, + dictWord{134, 0, 1552}, + dictWord{134, 11, 1729}, + dictWord{8, 10, 115}, + dictWord{8, 10, 350}, + dictWord{9, 10, 489}, + dictWord{10, 10, 128}, + dictWord{11, 10, 306}, + dictWord{ + 12, + 10, + 373, + }, + dictWord{14, 10, 30}, + dictWord{17, 10, 79}, + dictWord{19, 10, 80}, + dictWord{150, 10, 55}, + dictWord{135, 0, 1807}, + dictWord{4, 0, 680}, + dictWord{ + 4, + 11, + 60, + }, + dictWord{7, 11, 760}, + dictWord{7, 11, 1800}, + dictWord{8, 11, 314}, + dictWord{9, 11, 700}, + dictWord{139, 11, 487}, + dictWord{4, 10, 230}, + dictWord{ + 5, + 10, + 702, + }, + dictWord{148, 11, 94}, + dictWord{132, 11, 228}, + dictWord{139, 0, 435}, + dictWord{9, 0, 20}, + dictWord{10, 0, 324}, + dictWord{10, 0, 807}, + dictWord{ + 139, + 0, + 488, + }, + dictWord{6, 10, 1728}, + dictWord{136, 11, 419}, + dictWord{4, 10, 484}, + dictWord{18, 10, 26}, + dictWord{19, 10, 42}, + dictWord{20, 10, 43}, + dictWord{ + 21, + 10, + 0, + }, + dictWord{23, 10, 27}, + dictWord{152, 10, 14}, + dictWord{135, 0, 1431}, + dictWord{133, 11, 828}, + dictWord{5, 0, 112}, + dictWord{6, 0, 103}, + dictWord{ + 6, + 0, + 150, + }, + dictWord{7, 0, 1303}, + dictWord{9, 0, 292}, + dictWord{10, 0, 481}, + dictWord{20, 0, 13}, + dictWord{7, 11, 176}, + dictWord{7, 11, 178}, + dictWord{7, 11, 1110}, + dictWord{10, 11, 481}, + dictWord{148, 11, 13}, + dictWord{138, 0, 356}, + dictWord{4, 11, 51}, + dictWord{5, 11, 39}, + dictWord{6, 11, 4}, + dictWord{7, 11, 591}, + dictWord{ + 7, + 11, + 849, + }, + dictWord{7, 11, 951}, + dictWord{7, 11, 1129}, + dictWord{7, 11, 1613}, + dictWord{7, 11, 1760}, + dictWord{7, 11, 1988}, + dictWord{9, 11, 434}, + dictWord{10, 11, 754}, + dictWord{11, 11, 25}, + dictWord{11, 11, 37}, + dictWord{139, 11, 414}, + dictWord{6, 0, 1963}, + dictWord{134, 0, 2000}, + dictWord{ + 132, + 10, + 633, + }, + dictWord{6, 0, 1244}, + dictWord{133, 11, 902}, + dictWord{135, 11, 928}, + dictWord{140, 0, 18}, + dictWord{138, 0, 204}, + dictWord{135, 11, 1173}, + dictWord{134, 0, 867}, + dictWord{4, 0, 708}, + dictWord{8, 0, 15}, + dictWord{9, 0, 50}, + dictWord{9, 0, 386}, + dictWord{11, 0, 18}, + dictWord{11, 0, 529}, + dictWord{140, 0, 228}, + dictWord{134, 11, 270}, + dictWord{4, 0, 563}, + dictWord{7, 0, 109}, + dictWord{7, 0, 592}, + dictWord{7, 0, 637}, + dictWord{7, 0, 770}, + dictWord{8, 0, 463}, + dictWord{ + 9, + 0, + 60, + }, + dictWord{9, 0, 335}, + dictWord{9, 0, 904}, + dictWord{10, 0, 73}, + dictWord{11, 0, 434}, + dictWord{12, 0, 585}, + dictWord{13, 0, 331}, + dictWord{18, 0, 110}, + dictWord{148, 0, 60}, + dictWord{132, 0, 502}, + dictWord{14, 11, 359}, + dictWord{19, 11, 52}, + dictWord{148, 11, 47}, + dictWord{6, 11, 377}, + dictWord{7, 11, 1025}, + dictWord{9, 11, 613}, + dictWord{145, 11, 104}, + dictWord{6, 0, 347}, + dictWord{10, 0, 161}, + dictWord{5, 10, 70}, + dictWord{5, 10, 622}, + dictWord{6, 10, 334}, + dictWord{ + 7, + 10, + 1032, + }, + dictWord{9, 10, 171}, + dictWord{11, 10, 26}, + dictWord{11, 10, 213}, + dictWord{11, 10, 637}, + dictWord{11, 10, 707}, + dictWord{12, 10, 202}, + dictWord{12, 10, 380}, + dictWord{13, 10, 226}, + dictWord{13, 10, 355}, + dictWord{14, 10, 222}, + dictWord{145, 10, 42}, + dictWord{132, 11, 416}, + dictWord{4, 0, 33}, + dictWord{5, 0, 102}, + dictWord{6, 0, 284}, + dictWord{7, 0, 1079}, + dictWord{7, 0, 1423}, + dictWord{7, 0, 1702}, + dictWord{8, 0, 470}, + dictWord{9, 0, 554}, + dictWord{ + 9, + 0, + 723, + }, + dictWord{11, 0, 333}, + dictWord{142, 11, 372}, + dictWord{5, 11, 152}, + dictWord{5, 11, 197}, + dictWord{7, 11, 340}, + dictWord{7, 11, 867}, + dictWord{ + 10, + 11, + 548, + }, + dictWord{10, 11, 581}, + dictWord{11, 11, 6}, + dictWord{12, 11, 3}, + dictWord{12, 11, 19}, + dictWord{14, 11, 110}, + dictWord{142, 11, 289}, + dictWord{ + 7, + 0, + 246, + }, + dictWord{135, 0, 840}, + dictWord{6, 0, 10}, + dictWord{8, 0, 571}, + dictWord{9, 0, 739}, + dictWord{143, 0, 91}, + dictWord{6, 0, 465}, + dictWord{7, 0, 1465}, + dictWord{ + 4, + 10, + 23, + }, + dictWord{4, 10, 141}, + dictWord{5, 10, 313}, + dictWord{5, 10, 1014}, + dictWord{6, 10, 50}, + dictWord{7, 10, 142}, + dictWord{7, 10, 559}, + dictWord{ + 8, + 10, + 640, + }, + dictWord{9, 10, 460}, + dictWord{9, 10, 783}, + dictWord{11, 10, 741}, + dictWord{12, 10, 183}, + dictWord{141, 10, 488}, + dictWord{133, 0, 626}, + dictWord{ + 136, + 0, + 614, + }, + dictWord{138, 0, 237}, + dictWord{7, 11, 34}, + dictWord{7, 11, 190}, + dictWord{8, 11, 28}, + dictWord{8, 11, 141}, + dictWord{8, 11, 444}, + dictWord{ + 8, + 11, + 811, + }, + dictWord{9, 11, 468}, + dictWord{11, 11, 334}, + dictWord{12, 11, 24}, + dictWord{12, 11, 386}, + dictWord{140, 11, 576}, + dictWord{133, 11, 757}, + dictWord{ + 5, + 0, + 18, + }, + dictWord{6, 0, 526}, + dictWord{13, 0, 24}, + dictWord{13, 0, 110}, + dictWord{19, 0, 5}, + dictWord{147, 0, 44}, + dictWord{6, 0, 506}, + dictWord{134, 11, 506}, + dictWord{135, 11, 1553}, + dictWord{4, 0, 309}, + dictWord{5, 0, 462}, + dictWord{7, 0, 970}, + dictWord{7, 0, 1097}, + dictWord{22, 0, 30}, + dictWord{22, 0, 33}, + dictWord{ + 7, + 11, + 1385, + }, + dictWord{11, 11, 582}, + dictWord{11, 11, 650}, + dictWord{11, 11, 901}, + dictWord{11, 11, 949}, + dictWord{12, 11, 232}, + dictWord{12, 11, 236}, + dictWord{13, 11, 413}, + dictWord{13, 11, 501}, + dictWord{146, 11, 116}, + dictWord{9, 0, 140}, + dictWord{5, 10, 222}, + dictWord{138, 10, 534}, + dictWord{6, 0, 1056}, + dictWord{137, 10, 906}, + dictWord{134, 0, 1704}, + dictWord{138, 10, 503}, + dictWord{134, 0, 1036}, + dictWord{5, 10, 154}, + dictWord{7, 10, 1491}, + dictWord{ + 10, + 10, + 379, + }, + dictWord{138, 10, 485}, + dictWord{4, 11, 383}, + dictWord{133, 10, 716}, + dictWord{134, 0, 1315}, + dictWord{5, 0, 86}, + dictWord{7, 0, 743}, + dictWord{ + 9, + 0, + 85, + }, + dictWord{10, 0, 281}, + dictWord{10, 0, 432}, + dictWord{11, 0, 825}, + dictWord{12, 0, 251}, + dictWord{13, 0, 118}, + dictWord{142, 0, 378}, + dictWord{ + 8, + 0, + 264, + }, + dictWord{4, 10, 91}, + dictWord{5, 10, 388}, + dictWord{5, 10, 845}, + dictWord{6, 10, 206}, + dictWord{6, 10, 252}, + dictWord{6, 10, 365}, + dictWord{7, 10, 136}, + dictWord{7, 10, 531}, + dictWord{136, 10, 621}, + dictWord{5, 0, 524}, + dictWord{133, 0, 744}, + dictWord{5, 11, 277}, + dictWord{141, 11, 247}, + dictWord{ + 132, + 11, + 435, + }, + dictWord{10, 0, 107}, + dictWord{140, 0, 436}, + dictWord{132, 0, 927}, + dictWord{10, 0, 123}, + dictWord{12, 0, 670}, + dictWord{146, 0, 94}, + dictWord{ + 7, + 0, + 1149, + }, + dictWord{9, 0, 156}, + dictWord{138, 0, 957}, + dictWord{5, 11, 265}, + dictWord{6, 11, 212}, + dictWord{135, 11, 28}, + dictWord{133, 0, 778}, + dictWord{ + 133, + 0, + 502, + }, + dictWord{8, 0, 196}, + dictWord{10, 0, 283}, + dictWord{139, 0, 406}, + dictWord{135, 10, 576}, + dictWord{136, 11, 535}, + dictWord{134, 0, 1312}, + dictWord{ + 5, + 10, + 771, + }, + dictWord{5, 10, 863}, + dictWord{5, 10, 898}, + dictWord{6, 10, 1632}, + dictWord{6, 10, 1644}, + dictWord{134, 10, 1780}, + dictWord{5, 0, 855}, + dictWord{5, 10, 331}, + dictWord{135, 11, 1487}, + dictWord{132, 11, 702}, + dictWord{5, 11, 808}, + dictWord{135, 11, 2045}, + dictWord{7, 0, 1400}, + dictWord{ + 9, + 0, + 446, + }, + dictWord{138, 0, 45}, + dictWord{140, 10, 632}, + dictWord{132, 0, 1003}, + dictWord{5, 11, 166}, + dictWord{8, 11, 739}, + dictWord{140, 11, 511}, + dictWord{ + 5, + 10, + 107, + }, + dictWord{7, 10, 201}, + dictWord{136, 10, 518}, + dictWord{6, 10, 446}, + dictWord{135, 10, 1817}, + dictWord{134, 0, 1532}, + dictWord{ + 134, + 0, + 1097, + }, + dictWord{4, 11, 119}, + dictWord{5, 11, 170}, + dictWord{5, 11, 447}, + dictWord{7, 11, 1708}, + dictWord{7, 11, 1889}, + dictWord{9, 11, 357}, + dictWord{ + 9, + 11, + 719, + }, + dictWord{12, 11, 486}, + dictWord{140, 11, 596}, + dictWord{9, 10, 851}, + dictWord{141, 10, 510}, + dictWord{7, 0, 612}, + dictWord{8, 0, 545}, + dictWord{ + 8, + 0, + 568, + }, + dictWord{8, 0, 642}, + dictWord{9, 0, 717}, + dictWord{10, 0, 541}, + dictWord{10, 0, 763}, + dictWord{11, 0, 449}, + dictWord{12, 0, 489}, + dictWord{13, 0, 153}, + dictWord{13, 0, 296}, + dictWord{14, 0, 138}, + dictWord{14, 0, 392}, + dictWord{15, 0, 50}, + dictWord{16, 0, 6}, + dictWord{16, 0, 12}, + dictWord{20, 0, 9}, + dictWord{ + 132, + 10, + 504, + }, + dictWord{4, 11, 450}, + dictWord{135, 11, 1158}, + dictWord{11, 0, 54}, + dictWord{13, 0, 173}, + dictWord{13, 0, 294}, + dictWord{5, 10, 883}, + dictWord{ + 5, + 10, + 975, + }, + dictWord{8, 10, 392}, + dictWord{148, 10, 7}, + dictWord{13, 0, 455}, + dictWord{15, 0, 99}, + dictWord{15, 0, 129}, + dictWord{144, 0, 68}, + dictWord{135, 0, 172}, + dictWord{132, 11, 754}, + dictWord{5, 10, 922}, + dictWord{134, 10, 1707}, + dictWord{134, 0, 1029}, + dictWord{17, 11, 39}, + dictWord{148, 11, 36}, + dictWord{ + 4, + 0, + 568, + }, + dictWord{5, 10, 993}, + dictWord{7, 10, 515}, + dictWord{137, 10, 91}, + dictWord{132, 0, 732}, + dictWord{10, 0, 617}, + dictWord{138, 11, 617}, + dictWord{ + 134, + 0, + 974, + }, + dictWord{7, 0, 989}, + dictWord{10, 0, 377}, + dictWord{12, 0, 363}, + dictWord{13, 0, 68}, + dictWord{13, 0, 94}, + dictWord{14, 0, 108}, + dictWord{ + 142, + 0, + 306, + }, + dictWord{136, 0, 733}, + dictWord{132, 0, 428}, + dictWord{7, 0, 1789}, + dictWord{135, 11, 1062}, + dictWord{7, 0, 2015}, + dictWord{140, 0, 665}, + dictWord{135, 10, 1433}, + dictWord{5, 0, 287}, + dictWord{7, 10, 921}, + dictWord{8, 10, 580}, + dictWord{8, 10, 593}, + dictWord{8, 10, 630}, + dictWord{138, 10, 28}, + dictWord{138, 0, 806}, + dictWord{4, 10, 911}, + dictWord{5, 10, 867}, + dictWord{5, 10, 1013}, + dictWord{7, 10, 2034}, + dictWord{8, 10, 798}, + dictWord{136, 10, 813}, + dictWord{134, 0, 1539}, + dictWord{8, 11, 523}, + dictWord{150, 11, 34}, + dictWord{135, 11, 740}, + dictWord{7, 11, 238}, + dictWord{7, 11, 2033}, + dictWord{ + 8, + 11, + 120, + }, + dictWord{8, 11, 188}, + dictWord{8, 11, 659}, + dictWord{9, 11, 598}, + dictWord{10, 11, 466}, + dictWord{12, 11, 342}, + dictWord{12, 11, 588}, + dictWord{ + 13, + 11, + 503, + }, + dictWord{14, 11, 246}, + dictWord{143, 11, 92}, + dictWord{7, 0, 1563}, + dictWord{141, 0, 182}, + dictWord{5, 10, 135}, + dictWord{6, 10, 519}, + dictWord{ + 7, + 10, + 1722, + }, + dictWord{10, 10, 271}, + dictWord{11, 10, 261}, + dictWord{145, 10, 54}, + dictWord{14, 10, 338}, + dictWord{148, 10, 81}, + dictWord{7, 0, 484}, + dictWord{ + 4, + 10, + 300, + }, + dictWord{133, 10, 436}, + dictWord{145, 11, 114}, + dictWord{6, 0, 1623}, + dictWord{134, 0, 1681}, + dictWord{133, 11, 640}, + dictWord{4, 11, 201}, + dictWord{7, 11, 1744}, + dictWord{8, 11, 602}, + dictWord{11, 11, 247}, + dictWord{11, 11, 826}, + dictWord{145, 11, 65}, + dictWord{8, 11, 164}, + dictWord{ + 146, + 11, + 62, + }, + dictWord{6, 0, 1833}, + dictWord{6, 0, 1861}, + dictWord{136, 0, 878}, + dictWord{134, 0, 1569}, + dictWord{8, 10, 357}, + dictWord{10, 10, 745}, + dictWord{ + 14, + 10, + 426, + }, + dictWord{17, 10, 94}, + dictWord{147, 10, 57}, + dictWord{12, 0, 93}, + dictWord{12, 0, 501}, + dictWord{13, 0, 362}, + dictWord{14, 0, 151}, + dictWord{15, 0, 40}, + dictWord{15, 0, 59}, + dictWord{16, 0, 46}, + dictWord{17, 0, 25}, + dictWord{18, 0, 14}, + dictWord{18, 0, 134}, + dictWord{19, 0, 25}, + dictWord{19, 0, 69}, + dictWord{ + 20, + 0, + 16, + }, + dictWord{20, 0, 19}, + dictWord{20, 0, 66}, + dictWord{21, 0, 23}, + dictWord{21, 0, 25}, + dictWord{150, 0, 42}, + dictWord{6, 0, 1748}, + dictWord{8, 0, 715}, + dictWord{ + 9, + 0, + 802, + }, + dictWord{10, 0, 46}, + dictWord{10, 0, 819}, + dictWord{13, 0, 308}, + dictWord{14, 0, 351}, + dictWord{14, 0, 363}, + dictWord{146, 0, 67}, + dictWord{ + 132, + 0, + 994, + }, + dictWord{4, 0, 63}, + dictWord{133, 0, 347}, + dictWord{132, 0, 591}, + dictWord{133, 0, 749}, + dictWord{7, 11, 1577}, + dictWord{10, 11, 304}, + dictWord{ + 10, + 11, + 549, + }, + dictWord{11, 11, 424}, + dictWord{12, 11, 365}, + dictWord{13, 11, 220}, + dictWord{13, 11, 240}, + dictWord{142, 11, 33}, + dictWord{133, 0, 366}, + dictWord{ + 7, + 0, + 557, + }, + dictWord{12, 0, 547}, + dictWord{14, 0, 86}, + dictWord{133, 10, 387}, + dictWord{135, 0, 1747}, + dictWord{132, 11, 907}, + dictWord{5, 11, 100}, + dictWord{10, 11, 329}, + dictWord{12, 11, 416}, + dictWord{149, 11, 29}, + dictWord{4, 10, 6}, + dictWord{5, 10, 708}, + dictWord{136, 10, 75}, + dictWord{7, 10, 1351}, + dictWord{9, 10, 581}, + dictWord{10, 10, 639}, + dictWord{11, 10, 453}, + dictWord{140, 10, 584}, + dictWord{7, 0, 89}, + dictWord{132, 10, 303}, + dictWord{138, 10, 772}, + dictWord{132, 11, 176}, + dictWord{5, 11, 636}, + dictWord{5, 11, 998}, + dictWord{8, 11, 26}, + dictWord{137, 11, 358}, + dictWord{7, 11, 9}, + dictWord{7, 11, 1508}, + dictWord{9, 11, 317}, + dictWord{10, 11, 210}, + dictWord{10, 11, 292}, + dictWord{10, 11, 533}, + dictWord{11, 11, 555}, + dictWord{12, 11, 526}, + dictWord{ + 12, + 11, + 607, + }, + dictWord{13, 11, 263}, + dictWord{13, 11, 459}, + dictWord{142, 11, 271}, + dictWord{134, 0, 1463}, + dictWord{6, 0, 772}, + dictWord{6, 0, 1137}, + dictWord{ + 139, + 11, + 595, + }, + dictWord{7, 0, 977}, + dictWord{139, 11, 66}, + dictWord{138, 0, 893}, + dictWord{20, 0, 48}, + dictWord{148, 11, 48}, + dictWord{5, 0, 824}, + dictWord{ + 133, + 0, + 941, + }, + dictWord{134, 11, 295}, + dictWord{7, 0, 1543}, + dictWord{7, 0, 1785}, + dictWord{10, 0, 690}, + dictWord{4, 10, 106}, + dictWord{139, 10, 717}, + dictWord{ + 7, + 0, + 440, + }, + dictWord{8, 0, 230}, + dictWord{139, 0, 106}, + dictWord{5, 10, 890}, + dictWord{133, 10, 988}, + dictWord{6, 10, 626}, + dictWord{142, 10, 431}, + dictWord{ + 10, + 11, + 127, + }, + dictWord{141, 11, 27}, + dictWord{17, 0, 32}, + dictWord{10, 10, 706}, + dictWord{150, 10, 44}, + dictWord{132, 0, 216}, + dictWord{137, 0, 332}, + dictWord{4, 10, 698}, + dictWord{136, 11, 119}, + dictWord{139, 11, 267}, + dictWord{138, 10, 17}, + dictWord{11, 11, 526}, + dictWord{11, 11, 939}, + dictWord{ + 141, + 11, + 290, + }, + dictWord{7, 11, 1167}, + dictWord{11, 11, 934}, + dictWord{13, 11, 391}, + dictWord{145, 11, 76}, + dictWord{139, 11, 39}, + dictWord{134, 10, 84}, + dictWord{ + 4, + 0, + 914, + }, + dictWord{5, 0, 800}, + dictWord{133, 0, 852}, + dictWord{10, 0, 416}, + dictWord{141, 0, 115}, + dictWord{7, 0, 564}, + dictWord{142, 0, 168}, + dictWord{ + 4, + 0, + 918, + }, + dictWord{133, 0, 876}, + dictWord{134, 0, 1764}, + dictWord{152, 0, 3}, + dictWord{4, 0, 92}, + dictWord{5, 0, 274}, + dictWord{7, 11, 126}, + dictWord{136, 11, 84}, + dictWord{140, 10, 498}, + dictWord{136, 11, 790}, + dictWord{8, 0, 501}, + dictWord{5, 10, 986}, + dictWord{6, 10, 130}, + dictWord{7, 10, 1582}, + dictWord{ + 8, + 10, + 458, + }, + dictWord{10, 10, 101}, + dictWord{10, 10, 318}, + dictWord{138, 10, 823}, + dictWord{6, 11, 64}, + dictWord{12, 11, 377}, + dictWord{141, 11, 309}, + dictWord{ + 5, + 0, + 743, + }, + dictWord{138, 0, 851}, + dictWord{4, 0, 49}, + dictWord{7, 0, 280}, + dictWord{135, 0, 1633}, + dictWord{134, 0, 879}, + dictWord{136, 0, 47}, + dictWord{ + 7, + 10, + 1644, + }, + dictWord{137, 10, 129}, + dictWord{132, 0, 865}, + dictWord{134, 0, 1202}, + dictWord{9, 11, 34}, + dictWord{139, 11, 484}, + dictWord{135, 10, 997}, + dictWord{5, 0, 272}, + dictWord{5, 0, 908}, + dictWord{5, 0, 942}, + dictWord{8, 0, 197}, + dictWord{9, 0, 47}, + dictWord{11, 0, 538}, + dictWord{139, 0, 742}, + dictWord{ + 6, + 11, + 1700, + }, + dictWord{7, 11, 26}, + dictWord{7, 11, 293}, + dictWord{7, 11, 382}, + dictWord{7, 11, 1026}, + dictWord{7, 11, 1087}, + dictWord{7, 11, 2027}, + dictWord{ + 8, + 11, + 24, + }, + dictWord{8, 11, 114}, + dictWord{8, 11, 252}, + dictWord{8, 11, 727}, + dictWord{8, 11, 729}, + dictWord{9, 11, 30}, + dictWord{9, 11, 199}, + dictWord{9, 11, 231}, + dictWord{9, 11, 251}, + dictWord{9, 11, 334}, + dictWord{9, 11, 361}, + dictWord{9, 11, 488}, + dictWord{9, 11, 712}, + dictWord{10, 11, 55}, + dictWord{10, 11, 60}, + dictWord{ + 10, + 11, + 232, + }, + dictWord{10, 11, 332}, + dictWord{10, 11, 384}, + dictWord{10, 11, 396}, + dictWord{10, 11, 504}, + dictWord{10, 11, 542}, + dictWord{10, 11, 652}, + dictWord{11, 11, 20}, + dictWord{11, 11, 48}, + dictWord{11, 11, 207}, + dictWord{11, 11, 291}, + dictWord{11, 11, 298}, + dictWord{11, 11, 342}, + dictWord{ + 11, + 11, + 365, + }, + dictWord{11, 11, 394}, + dictWord{11, 11, 620}, + dictWord{11, 11, 705}, + dictWord{11, 11, 1017}, + dictWord{12, 11, 123}, + dictWord{12, 11, 340}, + dictWord{12, 11, 406}, + dictWord{12, 11, 643}, + dictWord{13, 11, 61}, + dictWord{13, 11, 269}, + dictWord{13, 11, 311}, + dictWord{13, 11, 319}, + dictWord{13, 11, 486}, + dictWord{14, 11, 234}, + dictWord{15, 11, 62}, + dictWord{15, 11, 85}, + dictWord{16, 11, 71}, + dictWord{18, 11, 119}, + dictWord{148, 11, 105}, + dictWord{ + 6, + 0, + 1455, + }, + dictWord{150, 11, 37}, + dictWord{135, 10, 1927}, + dictWord{135, 0, 1911}, + dictWord{137, 0, 891}, + dictWord{7, 10, 1756}, + dictWord{137, 10, 98}, + dictWord{7, 10, 1046}, + dictWord{139, 10, 160}, + dictWord{132, 0, 761}, + dictWord{6, 11, 379}, + dictWord{7, 11, 270}, + dictWord{7, 11, 1116}, + dictWord{ + 8, + 11, + 176, + }, + dictWord{8, 11, 183}, + dictWord{9, 11, 432}, + dictWord{9, 11, 661}, + dictWord{12, 11, 247}, + dictWord{12, 11, 617}, + dictWord{146, 11, 125}, + dictWord{ + 6, + 10, + 45, + }, + dictWord{7, 10, 433}, + dictWord{8, 10, 129}, + dictWord{9, 10, 21}, + dictWord{10, 10, 392}, + dictWord{11, 10, 79}, + dictWord{12, 10, 499}, + dictWord{ + 13, + 10, + 199, + }, + dictWord{141, 10, 451}, + dictWord{4, 0, 407}, + dictWord{5, 11, 792}, + dictWord{133, 11, 900}, + dictWord{132, 0, 560}, + dictWord{135, 0, 183}, + dictWord{ + 13, + 0, + 490, + }, + dictWord{7, 10, 558}, + dictWord{136, 10, 353}, + dictWord{4, 0, 475}, + dictWord{6, 0, 731}, + dictWord{11, 0, 35}, + dictWord{13, 0, 71}, + dictWord{13, 0, 177}, + dictWord{14, 0, 422}, + dictWord{133, 10, 785}, + dictWord{8, 10, 81}, + dictWord{9, 10, 189}, + dictWord{9, 10, 201}, + dictWord{11, 10, 478}, + dictWord{11, 10, 712}, + dictWord{141, 10, 338}, + dictWord{4, 0, 418}, + dictWord{4, 0, 819}, + dictWord{133, 10, 353}, + dictWord{151, 10, 26}, + dictWord{4, 11, 901}, + dictWord{ + 133, + 11, + 776, + }, + dictWord{132, 0, 575}, + dictWord{7, 0, 818}, + dictWord{16, 0, 92}, + dictWord{17, 0, 14}, + dictWord{17, 0, 45}, + dictWord{18, 0, 75}, + dictWord{148, 0, 18}, + dictWord{ + 6, + 0, + 222, + }, + dictWord{7, 0, 636}, + dictWord{7, 0, 1620}, + dictWord{8, 0, 409}, + dictWord{9, 0, 693}, + dictWord{139, 0, 77}, + dictWord{6, 10, 25}, + dictWord{7, 10, 855}, + dictWord{7, 10, 1258}, + dictWord{144, 10, 32}, + dictWord{6, 0, 1880}, + dictWord{6, 0, 1887}, + dictWord{6, 0, 1918}, + dictWord{6, 0, 1924}, + dictWord{9, 0, 967}, + dictWord{9, 0, 995}, + dictWord{9, 0, 1015}, + dictWord{12, 0, 826}, + dictWord{12, 0, 849}, + dictWord{12, 0, 857}, + dictWord{12, 0, 860}, + dictWord{12, 0, 886}, + dictWord{ + 12, + 0, + 932, + }, + dictWord{18, 0, 228}, + dictWord{18, 0, 231}, + dictWord{146, 0, 240}, + dictWord{134, 0, 633}, + dictWord{134, 0, 1308}, + dictWord{4, 11, 37}, + dictWord{ + 5, + 11, + 334, + }, + dictWord{135, 11, 1253}, + dictWord{10, 0, 86}, + dictWord{4, 10, 4}, + dictWord{7, 10, 1118}, + dictWord{7, 10, 1320}, + dictWord{7, 10, 1706}, + dictWord{ + 8, + 10, + 277, + }, + dictWord{9, 10, 622}, + dictWord{11, 10, 724}, + dictWord{12, 10, 350}, + dictWord{12, 10, 397}, + dictWord{13, 10, 28}, + dictWord{13, 10, 159}, + dictWord{ + 15, + 10, + 89, + }, + dictWord{18, 10, 5}, + dictWord{19, 10, 9}, + dictWord{20, 10, 34}, + dictWord{150, 10, 47}, + dictWord{132, 11, 508}, + dictWord{137, 11, 448}, + dictWord{ + 12, + 11, + 107, + }, + dictWord{146, 11, 31}, + dictWord{132, 0, 817}, + dictWord{134, 0, 663}, + dictWord{133, 0, 882}, + dictWord{134, 0, 914}, + dictWord{132, 11, 540}, + dictWord{132, 11, 533}, + dictWord{136, 11, 608}, + dictWord{8, 0, 885}, + dictWord{138, 0, 865}, + dictWord{132, 0, 426}, + dictWord{6, 0, 58}, + dictWord{7, 0, 745}, + dictWord{7, 0, 1969}, + dictWord{8, 0, 399}, + dictWord{8, 0, 675}, + dictWord{9, 0, 479}, + dictWord{9, 0, 731}, + dictWord{10, 0, 330}, + dictWord{10, 0, 593}, + dictWord{ + 10, + 0, + 817, + }, + dictWord{11, 0, 32}, + dictWord{11, 0, 133}, + dictWord{11, 0, 221}, + dictWord{145, 0, 68}, + dictWord{134, 10, 255}, + dictWord{7, 0, 102}, + dictWord{ + 137, + 0, + 538, + }, + dictWord{137, 10, 216}, + dictWord{7, 11, 253}, + dictWord{136, 11, 549}, + dictWord{135, 11, 912}, + dictWord{9, 10, 183}, + dictWord{139, 10, 286}, + dictWord{11, 10, 956}, + dictWord{151, 10, 3}, + dictWord{8, 11, 527}, + dictWord{18, 11, 60}, + dictWord{147, 11, 24}, + dictWord{4, 10, 536}, + dictWord{7, 10, 1141}, + dictWord{10, 10, 723}, + dictWord{139, 10, 371}, + dictWord{133, 11, 920}, + dictWord{7, 0, 876}, + dictWord{135, 10, 285}, + dictWord{135, 10, 560}, + dictWord{ + 132, + 10, + 690, + }, + dictWord{142, 11, 126}, + dictWord{11, 10, 33}, + dictWord{12, 10, 571}, + dictWord{149, 10, 1}, + dictWord{133, 0, 566}, + dictWord{9, 0, 139}, + dictWord{ + 10, + 0, + 399, + }, + dictWord{11, 0, 469}, + dictWord{12, 0, 634}, + dictWord{13, 0, 223}, + dictWord{132, 11, 483}, + dictWord{6, 0, 48}, + dictWord{135, 0, 63}, + dictWord{18, 0, 12}, + dictWord{7, 10, 1862}, + dictWord{12, 10, 491}, + dictWord{12, 10, 520}, + dictWord{13, 10, 383}, + dictWord{142, 10, 244}, + dictWord{135, 11, 1665}, + dictWord{132, 11, 448}, + dictWord{9, 11, 495}, + dictWord{146, 11, 104}, + dictWord{6, 0, 114}, + dictWord{7, 0, 1224}, + dictWord{7, 0, 1556}, + dictWord{136, 0, 3}, + dictWord{ + 4, + 10, + 190, + }, + dictWord{133, 10, 554}, + dictWord{8, 0, 576}, + dictWord{9, 0, 267}, + dictWord{133, 10, 1001}, + dictWord{133, 10, 446}, + dictWord{133, 0, 933}, + dictWord{139, 11, 1009}, + dictWord{8, 11, 653}, + dictWord{13, 11, 93}, + dictWord{147, 11, 14}, + dictWord{6, 0, 692}, + dictWord{6, 0, 821}, + dictWord{134, 0, 1077}, + dictWord{5, 11, 172}, + dictWord{135, 11, 801}, + dictWord{138, 0, 752}, + dictWord{4, 0, 375}, + dictWord{134, 0, 638}, + dictWord{134, 0, 1011}, + dictWord{ + 140, + 11, + 540, + }, + dictWord{9, 0, 96}, + dictWord{133, 11, 260}, + dictWord{139, 11, 587}, + dictWord{135, 10, 1231}, + dictWord{12, 0, 30}, + dictWord{13, 0, 148}, + dictWord{ + 14, + 0, + 87, + }, + dictWord{14, 0, 182}, + dictWord{16, 0, 42}, + dictWord{20, 0, 70}, + dictWord{132, 10, 304}, + dictWord{6, 0, 1398}, + dictWord{7, 0, 56}, + dictWord{7, 0, 1989}, + dictWord{8, 0, 337}, + dictWord{8, 0, 738}, + dictWord{9, 0, 600}, + dictWord{12, 0, 37}, + dictWord{13, 0, 447}, + dictWord{142, 0, 92}, + dictWord{138, 0, 666}, + dictWord{ + 5, + 0, + 394, + }, + dictWord{7, 0, 487}, + dictWord{136, 0, 246}, + dictWord{9, 0, 437}, + dictWord{6, 10, 53}, + dictWord{6, 10, 199}, + dictWord{7, 10, 1408}, + dictWord{8, 10, 32}, + dictWord{8, 10, 93}, + dictWord{10, 10, 397}, + dictWord{10, 10, 629}, + dictWord{11, 10, 593}, + dictWord{11, 10, 763}, + dictWord{13, 10, 326}, + dictWord{145, 10, 35}, + dictWord{134, 10, 105}, + dictWord{9, 0, 320}, + dictWord{10, 0, 506}, + dictWord{138, 10, 794}, + dictWord{7, 11, 57}, + dictWord{8, 11, 167}, + dictWord{8, 11, 375}, + dictWord{9, 11, 82}, + dictWord{9, 11, 561}, + dictWord{10, 11, 620}, + dictWord{10, 11, 770}, + dictWord{11, 10, 704}, + dictWord{141, 10, 396}, + dictWord{6, 0, 1003}, + dictWord{5, 10, 114}, + dictWord{5, 10, 255}, + dictWord{141, 10, 285}, + dictWord{7, 0, 866}, + dictWord{135, 0, 1163}, + dictWord{133, 11, 531}, + dictWord{ + 132, + 0, + 328, + }, + dictWord{7, 10, 2035}, + dictWord{8, 10, 19}, + dictWord{9, 10, 89}, + dictWord{138, 10, 831}, + dictWord{8, 11, 194}, + dictWord{136, 11, 756}, + dictWord{ + 136, + 0, + 1000, + }, + dictWord{5, 11, 453}, + dictWord{134, 11, 441}, + dictWord{4, 0, 101}, + dictWord{5, 0, 833}, + dictWord{7, 0, 1171}, + dictWord{136, 0, 744}, + dictWord{ + 133, + 0, + 726, + }, + dictWord{136, 10, 746}, + dictWord{138, 0, 176}, + dictWord{6, 0, 9}, + dictWord{6, 0, 397}, + dictWord{7, 0, 53}, + dictWord{7, 0, 1742}, + dictWord{10, 0, 632}, + dictWord{11, 0, 828}, + dictWord{140, 0, 146}, + dictWord{135, 11, 22}, + dictWord{145, 11, 64}, + dictWord{132, 0, 839}, + dictWord{11, 0, 417}, + dictWord{12, 0, 223}, + dictWord{140, 0, 265}, + dictWord{4, 11, 102}, + dictWord{7, 11, 815}, + dictWord{7, 11, 1699}, + dictWord{139, 11, 964}, + dictWord{5, 10, 955}, + dictWord{ + 136, + 10, + 814, + }, + dictWord{6, 0, 1931}, + dictWord{6, 0, 2007}, + dictWord{18, 0, 246}, + dictWord{146, 0, 247}, + dictWord{8, 0, 198}, + dictWord{11, 0, 29}, + dictWord{140, 0, 534}, + dictWord{135, 0, 1771}, + dictWord{6, 0, 846}, + dictWord{7, 11, 1010}, + dictWord{11, 11, 733}, + dictWord{11, 11, 759}, + dictWord{12, 11, 563}, + dictWord{ + 13, + 11, + 34, + }, + dictWord{14, 11, 101}, + dictWord{18, 11, 45}, + dictWord{146, 11, 129}, + dictWord{4, 0, 186}, + dictWord{5, 0, 157}, + dictWord{8, 0, 168}, + dictWord{138, 0, 6}, + dictWord{132, 11, 899}, + dictWord{133, 10, 56}, + dictWord{148, 10, 100}, + dictWord{133, 0, 875}, + dictWord{5, 0, 773}, + dictWord{5, 0, 991}, + dictWord{6, 0, 1635}, + dictWord{134, 0, 1788}, + dictWord{6, 0, 1274}, + dictWord{9, 0, 477}, + dictWord{141, 0, 78}, + dictWord{4, 0, 639}, + dictWord{7, 0, 111}, + dictWord{8, 0, 581}, + dictWord{ + 12, + 0, + 177, + }, + dictWord{6, 11, 52}, + dictWord{9, 11, 104}, + dictWord{9, 11, 559}, + dictWord{10, 10, 4}, + dictWord{10, 10, 13}, + dictWord{11, 10, 638}, + dictWord{ + 12, + 11, + 308, + }, + dictWord{19, 11, 87}, + dictWord{148, 10, 57}, + dictWord{132, 11, 604}, + dictWord{4, 11, 301}, + dictWord{133, 10, 738}, + dictWord{133, 10, 758}, + dictWord{134, 0, 1747}, + dictWord{7, 11, 1440}, + dictWord{11, 11, 854}, + dictWord{11, 11, 872}, + dictWord{11, 11, 921}, + dictWord{12, 11, 551}, + dictWord{ + 13, + 11, + 472, + }, + dictWord{142, 11, 367}, + dictWord{7, 0, 1364}, + dictWord{7, 0, 1907}, + dictWord{141, 0, 158}, + dictWord{134, 0, 873}, + dictWord{4, 0, 404}, + dictWord{ + 4, + 0, + 659, + }, + dictWord{7, 0, 552}, + dictWord{135, 0, 675}, + dictWord{135, 10, 1112}, + dictWord{139, 10, 328}, + dictWord{7, 11, 508}, + dictWord{137, 10, 133}, + dictWord{133, 0, 391}, + dictWord{5, 10, 110}, + dictWord{6, 10, 169}, + dictWord{6, 10, 1702}, + dictWord{7, 10, 400}, + dictWord{8, 10, 538}, + dictWord{9, 10, 184}, + dictWord{ + 9, + 10, + 524, + }, + dictWord{140, 10, 218}, + dictWord{6, 11, 310}, + dictWord{7, 11, 1849}, + dictWord{8, 11, 72}, + dictWord{8, 11, 272}, + dictWord{8, 11, 431}, + dictWord{ + 9, + 11, + 12, + }, + dictWord{9, 11, 351}, + dictWord{10, 11, 563}, + dictWord{10, 11, 630}, + dictWord{10, 11, 810}, + dictWord{11, 11, 367}, + dictWord{11, 11, 599}, + dictWord{11, 11, 686}, + dictWord{140, 11, 672}, + dictWord{5, 0, 540}, + dictWord{6, 0, 1697}, + dictWord{136, 0, 668}, + dictWord{132, 0, 883}, + dictWord{134, 0, 78}, + dictWord{12, 0, 628}, + dictWord{18, 0, 79}, + dictWord{6, 10, 133}, + dictWord{9, 10, 353}, + dictWord{139, 10, 993}, + dictWord{6, 11, 181}, + dictWord{7, 11, 537}, + dictWord{ + 8, + 11, + 64, + }, + dictWord{9, 11, 127}, + dictWord{10, 11, 496}, + dictWord{12, 11, 510}, + dictWord{141, 11, 384}, + dictWord{6, 10, 93}, + dictWord{7, 10, 1422}, + dictWord{ + 7, + 10, + 1851, + }, + dictWord{8, 10, 673}, + dictWord{9, 10, 529}, + dictWord{140, 10, 43}, + dictWord{137, 10, 371}, + dictWord{134, 0, 1460}, + dictWord{134, 0, 962}, + dictWord{4, 11, 244}, + dictWord{135, 11, 233}, + dictWord{9, 10, 25}, + dictWord{10, 10, 467}, + dictWord{138, 10, 559}, + dictWord{4, 10, 335}, + dictWord{ + 135, + 10, + 942, + }, + dictWord{133, 0, 460}, + dictWord{135, 11, 334}, + dictWord{134, 11, 1650}, + dictWord{4, 0, 199}, + dictWord{139, 0, 34}, + dictWord{5, 10, 601}, + dictWord{ + 8, + 10, + 39, + }, + dictWord{10, 10, 773}, + dictWord{11, 10, 84}, + dictWord{12, 10, 205}, + dictWord{142, 10, 1}, + dictWord{133, 10, 870}, + dictWord{134, 0, 388}, + dictWord{14, 0, 474}, + dictWord{148, 0, 120}, + dictWord{133, 11, 369}, + dictWord{139, 0, 271}, + dictWord{4, 0, 511}, + dictWord{9, 0, 333}, + dictWord{9, 0, 379}, + dictWord{ + 10, + 0, + 602, + }, + dictWord{11, 0, 441}, + dictWord{11, 0, 723}, + dictWord{11, 0, 976}, + dictWord{12, 0, 357}, + dictWord{132, 10, 181}, + dictWord{134, 0, 608}, + dictWord{134, 10, 1652}, + dictWord{22, 0, 49}, + dictWord{137, 11, 338}, + dictWord{140, 0, 988}, + dictWord{134, 0, 617}, + dictWord{5, 0, 938}, + dictWord{136, 0, 707}, + dictWord{132, 10, 97}, + dictWord{5, 10, 147}, + dictWord{6, 10, 286}, + dictWord{7, 10, 1362}, + dictWord{141, 10, 176}, + dictWord{6, 0, 756}, + dictWord{ + 134, + 0, + 1149, + }, + dictWord{133, 11, 896}, + dictWord{6, 10, 375}, + dictWord{7, 10, 169}, + dictWord{7, 10, 254}, + dictWord{136, 10, 780}, + dictWord{134, 0, 1583}, + dictWord{135, 10, 1447}, + dictWord{139, 0, 285}, + dictWord{7, 11, 1117}, + dictWord{8, 11, 393}, + dictWord{136, 11, 539}, + dictWord{135, 0, 344}, + dictWord{ + 6, + 0, + 469, + }, + dictWord{7, 0, 1709}, + dictWord{138, 0, 515}, + dictWord{5, 10, 629}, + dictWord{135, 10, 1549}, + dictWord{5, 11, 4}, + dictWord{5, 11, 810}, + dictWord{ + 6, + 11, + 13, + }, + dictWord{6, 11, 538}, + dictWord{6, 11, 1690}, + dictWord{6, 11, 1726}, + dictWord{7, 11, 499}, + dictWord{7, 11, 1819}, + dictWord{8, 11, 148}, + dictWord{ + 8, + 11, + 696, + }, + dictWord{8, 11, 791}, + dictWord{12, 11, 125}, + dictWord{13, 11, 54}, + dictWord{143, 11, 9}, + dictWord{135, 11, 1268}, + dictWord{137, 0, 404}, + dictWord{ + 132, + 0, + 500, + }, + dictWord{5, 0, 68}, + dictWord{134, 0, 383}, + dictWord{11, 0, 216}, + dictWord{139, 0, 340}, + dictWord{4, 11, 925}, + dictWord{5, 11, 803}, + dictWord{ + 8, + 11, + 698, + }, + dictWord{138, 11, 828}, + dictWord{4, 0, 337}, + dictWord{6, 0, 353}, + dictWord{7, 0, 1934}, + dictWord{8, 0, 488}, + dictWord{137, 0, 429}, + dictWord{7, 0, 236}, + dictWord{7, 0, 1795}, + dictWord{8, 0, 259}, + dictWord{9, 0, 135}, + dictWord{9, 0, 177}, + dictWord{9, 0, 860}, + dictWord{10, 0, 825}, + dictWord{11, 0, 115}, + dictWord{ + 11, + 0, + 370, + }, + dictWord{11, 0, 405}, + dictWord{11, 0, 604}, + dictWord{12, 0, 10}, + dictWord{12, 0, 667}, + dictWord{12, 0, 669}, + dictWord{13, 0, 76}, + dictWord{14, 0, 310}, + dictWord{15, 0, 76}, + dictWord{15, 0, 147}, + dictWord{148, 0, 23}, + dictWord{4, 0, 15}, + dictWord{4, 0, 490}, + dictWord{5, 0, 22}, + dictWord{6, 0, 244}, + dictWord{7, 0, 40}, + dictWord{7, 0, 200}, + dictWord{7, 0, 906}, + dictWord{7, 0, 1199}, + dictWord{9, 0, 616}, + dictWord{10, 0, 716}, + dictWord{11, 0, 635}, + dictWord{11, 0, 801}, + dictWord{ + 140, + 0, + 458, + }, + dictWord{12, 0, 756}, + dictWord{132, 10, 420}, + dictWord{134, 0, 1504}, + dictWord{6, 0, 757}, + dictWord{133, 11, 383}, + dictWord{6, 0, 1266}, + dictWord{ + 135, + 0, + 1735, + }, + dictWord{5, 0, 598}, + dictWord{7, 0, 791}, + dictWord{8, 0, 108}, + dictWord{9, 0, 123}, + dictWord{7, 10, 1570}, + dictWord{140, 10, 542}, + dictWord{ + 142, + 11, + 410, + }, + dictWord{9, 11, 660}, + dictWord{138, 11, 347}, +} diff --git a/vendor/github.com/andybalholm/brotli/symbol_list.go b/vendor/github.com/andybalholm/brotli/symbol_list.go new file mode 100644 index 0000000..c5cb49e --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/symbol_list.go @@ -0,0 +1,22 @@ +package brotli + +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Utilities for building Huffman decoding tables. */ + +type symbolList struct { + storage []uint16 + offset int +} + +func symbolListGet(sl symbolList, i int) uint16 { + return sl.storage[i+sl.offset] +} + +func symbolListPut(sl symbolList, i int, val uint16) { + sl.storage[i+sl.offset] = val +} diff --git a/vendor/github.com/andybalholm/brotli/transform.go b/vendor/github.com/andybalholm/brotli/transform.go new file mode 100644 index 0000000..d2c043a --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/transform.go @@ -0,0 +1,641 @@ +package brotli + +const ( + transformIdentity = 0 + transformOmitLast1 = 1 + transformOmitLast2 = 2 + transformOmitLast3 = 3 + transformOmitLast4 = 4 + transformOmitLast5 = 5 + transformOmitLast6 = 6 + transformOmitLast7 = 7 + transformOmitLast8 = 8 + transformOmitLast9 = 9 + transformUppercaseFirst = 10 + transformUppercaseAll = 11 + transformOmitFirst1 = 12 + transformOmitFirst2 = 13 + transformOmitFirst3 = 14 + transformOmitFirst4 = 15 + transformOmitFirst5 = 16 + transformOmitFirst6 = 17 + transformOmitFirst7 = 18 + transformOmitFirst8 = 19 + transformOmitFirst9 = 20 + transformShiftFirst = 21 + transformShiftAll = 22 + iota - 22 + numTransformTypes +) + +const transformsMaxCutOff = transformOmitLast9 + +type transforms struct { + prefix_suffix_size uint16 + prefix_suffix []byte + prefix_suffix_map []uint16 + num_transforms uint32 + transforms []byte + params []byte + cutOffTransforms [transformsMaxCutOff + 1]int16 +} + +func transformPrefixId(t *transforms, I int) byte { + return t.transforms[(I*3)+0] +} + +func transformType(t *transforms, I int) byte { + return t.transforms[(I*3)+1] +} + +func transformSuffixId(t *transforms, I int) byte { + return t.transforms[(I*3)+2] +} + +func transformPrefix(t *transforms, I int) []byte { + return t.prefix_suffix[t.prefix_suffix_map[transformPrefixId(t, I)]:] +} + +func transformSuffix(t *transforms, I int) []byte { + return t.prefix_suffix[t.prefix_suffix_map[transformSuffixId(t, I)]:] +} + +/* RFC 7932 transforms string data */ +const kPrefixSuffix string = "\001 \002, \010 of the \004 of \002s \001.\005 and \004 " + "in \001\"\004 to \002\">\001\n\002. \001]\005 for \003 a \006 " + "that \001'\006 with \006 from \004 by \001(\006. T" + "he \004 on \004 as \004 is \004ing \002\n\t\001:\003ed " + "\002=\"\004 at \003ly \001,\002='\005.com/\007. This \005" + " not \003er \003al \004ful \004ive \005less \004es" + "t \004ize \002\xc2\xa0\004ous \005 the \002e \000" + +var kPrefixSuffixMap = [50]uint16{ + 0x00, + 0x02, + 0x05, + 0x0E, + 0x13, + 0x16, + 0x18, + 0x1E, + 0x23, + 0x25, + 0x2A, + 0x2D, + 0x2F, + 0x32, + 0x34, + 0x3A, + 0x3E, + 0x45, + 0x47, + 0x4E, + 0x55, + 0x5A, + 0x5C, + 0x63, + 0x68, + 0x6D, + 0x72, + 0x77, + 0x7A, + 0x7C, + 0x80, + 0x83, + 0x88, + 0x8C, + 0x8E, + 0x91, + 0x97, + 0x9F, + 0xA5, + 0xA9, + 0xAD, + 0xB2, + 0xB7, + 0xBD, + 0xC2, + 0xC7, + 0xCA, + 0xCF, + 0xD5, + 0xD8, +} + +/* RFC 7932 transforms */ +var kTransformsData = []byte{ + 49, + transformIdentity, + 49, + 49, + transformIdentity, + 0, + 0, + transformIdentity, + 0, + 49, + transformOmitFirst1, + 49, + 49, + transformUppercaseFirst, + 0, + 49, + transformIdentity, + 47, + 0, + transformIdentity, + 49, + 4, + transformIdentity, + 0, + 49, + transformIdentity, + 3, + 49, + transformUppercaseFirst, + 49, + 49, + transformIdentity, + 6, + 49, + transformOmitFirst2, + 49, + 49, + transformOmitLast1, + 49, + 1, + transformIdentity, + 0, + 49, + transformIdentity, + 1, + 0, + transformUppercaseFirst, + 0, + 49, + transformIdentity, + 7, + 49, + transformIdentity, + 9, + 48, + transformIdentity, + 0, + 49, + transformIdentity, + 8, + 49, + transformIdentity, + 5, + 49, + transformIdentity, + 10, + 49, + transformIdentity, + 11, + 49, + transformOmitLast3, + 49, + 49, + transformIdentity, + 13, + 49, + transformIdentity, + 14, + 49, + transformOmitFirst3, + 49, + 49, + transformOmitLast2, + 49, + 49, + transformIdentity, + 15, + 49, + transformIdentity, + 16, + 0, + transformUppercaseFirst, + 49, + 49, + transformIdentity, + 12, + 5, + transformIdentity, + 49, + 0, + transformIdentity, + 1, + 49, + transformOmitFirst4, + 49, + 49, + transformIdentity, + 18, + 49, + transformIdentity, + 17, + 49, + transformIdentity, + 19, + 49, + transformIdentity, + 20, + 49, + transformOmitFirst5, + 49, + 49, + transformOmitFirst6, + 49, + 47, + transformIdentity, + 49, + 49, + transformOmitLast4, + 49, + 49, + transformIdentity, + 22, + 49, + transformUppercaseAll, + 49, + 49, + transformIdentity, + 23, + 49, + transformIdentity, + 24, + 49, + transformIdentity, + 25, + 49, + transformOmitLast7, + 49, + 49, + transformOmitLast1, + 26, + 49, + transformIdentity, + 27, + 49, + transformIdentity, + 28, + 0, + transformIdentity, + 12, + 49, + transformIdentity, + 29, + 49, + transformOmitFirst9, + 49, + 49, + transformOmitFirst7, + 49, + 49, + transformOmitLast6, + 49, + 49, + transformIdentity, + 21, + 49, + transformUppercaseFirst, + 1, + 49, + transformOmitLast8, + 49, + 49, + transformIdentity, + 31, + 49, + transformIdentity, + 32, + 47, + transformIdentity, + 3, + 49, + transformOmitLast5, + 49, + 49, + transformOmitLast9, + 49, + 0, + transformUppercaseFirst, + 1, + 49, + transformUppercaseFirst, + 8, + 5, + transformIdentity, + 21, + 49, + transformUppercaseAll, + 0, + 49, + transformUppercaseFirst, + 10, + 49, + transformIdentity, + 30, + 0, + transformIdentity, + 5, + 35, + transformIdentity, + 49, + 47, + transformIdentity, + 2, + 49, + transformUppercaseFirst, + 17, + 49, + transformIdentity, + 36, + 49, + transformIdentity, + 33, + 5, + transformIdentity, + 0, + 49, + transformUppercaseFirst, + 21, + 49, + transformUppercaseFirst, + 5, + 49, + transformIdentity, + 37, + 0, + transformIdentity, + 30, + 49, + transformIdentity, + 38, + 0, + transformUppercaseAll, + 0, + 49, + transformIdentity, + 39, + 0, + transformUppercaseAll, + 49, + 49, + transformIdentity, + 34, + 49, + transformUppercaseAll, + 8, + 49, + transformUppercaseFirst, + 12, + 0, + transformIdentity, + 21, + 49, + transformIdentity, + 40, + 0, + transformUppercaseFirst, + 12, + 49, + transformIdentity, + 41, + 49, + transformIdentity, + 42, + 49, + transformUppercaseAll, + 17, + 49, + transformIdentity, + 43, + 0, + transformUppercaseFirst, + 5, + 49, + transformUppercaseAll, + 10, + 0, + transformIdentity, + 34, + 49, + transformUppercaseFirst, + 33, + 49, + transformIdentity, + 44, + 49, + transformUppercaseAll, + 5, + 45, + transformIdentity, + 49, + 0, + transformIdentity, + 33, + 49, + transformUppercaseFirst, + 30, + 49, + transformUppercaseAll, + 30, + 49, + transformIdentity, + 46, + 49, + transformUppercaseAll, + 1, + 49, + transformUppercaseFirst, + 34, + 0, + transformUppercaseFirst, + 33, + 0, + transformUppercaseAll, + 30, + 0, + transformUppercaseAll, + 1, + 49, + transformUppercaseAll, + 33, + 49, + transformUppercaseAll, + 21, + 49, + transformUppercaseAll, + 12, + 0, + transformUppercaseAll, + 5, + 49, + transformUppercaseAll, + 34, + 0, + transformUppercaseAll, + 12, + 0, + transformUppercaseFirst, + 30, + 0, + transformUppercaseAll, + 34, + 0, + transformUppercaseFirst, + 34, +} + +var kBrotliTransforms = transforms{ + 217, + []byte(kPrefixSuffix), + kPrefixSuffixMap[:], + 121, + kTransformsData, + nil, /* no extra parameters */ + [transformsMaxCutOff + 1]int16{0, 12, 27, 23, 42, 63, 56, 48, 59, 64}, +} + +func getTransforms() *transforms { + return &kBrotliTransforms +} + +func toUpperCase(p []byte) int { + if p[0] < 0xC0 { + if p[0] >= 'a' && p[0] <= 'z' { + p[0] ^= 32 + } + + return 1 + } + + /* An overly simplified uppercasing model for UTF-8. */ + if p[0] < 0xE0 { + p[1] ^= 32 + return 2 + } + + /* An arbitrary transform for three byte characters. */ + p[2] ^= 5 + + return 3 +} + +func shiftTransform(word []byte, word_len int, parameter uint16) int { + /* Limited sign extension: scalar < (1 << 24). */ + var scalar uint32 = (uint32(parameter) & 0x7FFF) + (0x1000000 - (uint32(parameter) & 0x8000)) + if word[0] < 0x80 { + /* 1-byte rune / 0sssssss / 7 bit scalar (ASCII). */ + scalar += uint32(word[0]) + + word[0] = byte(scalar & 0x7F) + return 1 + } else if word[0] < 0xC0 { + /* Continuation / 10AAAAAA. */ + return 1 + } else if word[0] < 0xE0 { + /* 2-byte rune / 110sssss AAssssss / 11 bit scalar. */ + if word_len < 2 { + return 1 + } + scalar += uint32(word[1]&0x3F | (word[0]&0x1F)<<6) + word[0] = byte(0xC0 | (scalar>>6)&0x1F) + word[1] = byte(uint32(word[1]&0xC0) | scalar&0x3F) + return 2 + } else if word[0] < 0xF0 { + /* 3-byte rune / 1110ssss AAssssss BBssssss / 16 bit scalar. */ + if word_len < 3 { + return word_len + } + scalar += uint32(word[2])&0x3F | uint32(word[1]&0x3F)<<6 | uint32(word[0]&0x0F)<<12 + word[0] = byte(0xE0 | (scalar>>12)&0x0F) + word[1] = byte(uint32(word[1]&0xC0) | (scalar>>6)&0x3F) + word[2] = byte(uint32(word[2]&0xC0) | scalar&0x3F) + return 3 + } else if word[0] < 0xF8 { + /* 4-byte rune / 11110sss AAssssss BBssssss CCssssss / 21 bit scalar. */ + if word_len < 4 { + return word_len + } + scalar += uint32(word[3])&0x3F | uint32(word[2]&0x3F)<<6 | uint32(word[1]&0x3F)<<12 | uint32(word[0]&0x07)<<18 + word[0] = byte(0xF0 | (scalar>>18)&0x07) + word[1] = byte(uint32(word[1]&0xC0) | (scalar>>12)&0x3F) + word[2] = byte(uint32(word[2]&0xC0) | (scalar>>6)&0x3F) + word[3] = byte(uint32(word[3]&0xC0) | scalar&0x3F) + return 4 + } + + return 1 +} + +func transformDictionaryWord(dst []byte, word []byte, len int, trans *transforms, transform_idx int) int { + var idx int = 0 + var prefix []byte = transformPrefix(trans, transform_idx) + var type_ byte = transformType(trans, transform_idx) + var suffix []byte = transformSuffix(trans, transform_idx) + { + var prefix_len int = int(prefix[0]) + prefix = prefix[1:] + for { + tmp1 := prefix_len + prefix_len-- + if tmp1 == 0 { + break + } + dst[idx] = prefix[0] + idx++ + prefix = prefix[1:] + } + } + { + var t int = int(type_) + var i int = 0 + if t <= transformOmitLast9 { + len -= t + } else if t >= transformOmitFirst1 && t <= transformOmitFirst9 { + var skip int = t - (transformOmitFirst1 - 1) + word = word[skip:] + len -= skip + } + + for i < len { + dst[idx] = word[i] + idx++ + i++ + } + if t == transformUppercaseFirst { + toUpperCase(dst[idx-len:]) + } else if t == transformUppercaseAll { + var uppercase []byte = dst + uppercase = uppercase[idx-len:] + for len > 0 { + var step int = toUpperCase(uppercase) + uppercase = uppercase[step:] + len -= step + } + } else if t == transformShiftFirst { + var param uint16 = uint16(trans.params[transform_idx*2]) + uint16(trans.params[transform_idx*2+1])<<8 + shiftTransform(dst[idx-len:], int(len), param) + } else if t == transformShiftAll { + var param uint16 = uint16(trans.params[transform_idx*2]) + uint16(trans.params[transform_idx*2+1])<<8 + var shift []byte = dst + shift = shift[idx-len:] + for len > 0 { + var step int = shiftTransform(shift, int(len), param) + shift = shift[step:] + len -= step + } + } + } + { + var suffix_len int = int(suffix[0]) + suffix = suffix[1:] + for { + tmp2 := suffix_len + suffix_len-- + if tmp2 == 0 { + break + } + dst[idx] = suffix[0] + idx++ + suffix = suffix[1:] + } + return idx + } +} diff --git a/vendor/github.com/andybalholm/brotli/utf8_util.go b/vendor/github.com/andybalholm/brotli/utf8_util.go new file mode 100644 index 0000000..3244247 --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/utf8_util.go @@ -0,0 +1,70 @@ +package brotli + +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Heuristics for deciding about the UTF8-ness of strings. */ + +const kMinUTF8Ratio float64 = 0.75 + +/* Returns 1 if at least min_fraction of the bytes between pos and + pos + length in the (data, mask) ring-buffer is UTF8-encoded, otherwise + returns 0. */ +func parseAsUTF8(symbol *int, input []byte, size uint) uint { + /* ASCII */ + if input[0]&0x80 == 0 { + *symbol = int(input[0]) + if *symbol > 0 { + return 1 + } + } + + /* 2-byte UTF8 */ + if size > 1 && input[0]&0xE0 == 0xC0 && input[1]&0xC0 == 0x80 { + *symbol = (int(input[0])&0x1F)<<6 | int(input[1])&0x3F + if *symbol > 0x7F { + return 2 + } + } + + /* 3-byte UFT8 */ + if size > 2 && input[0]&0xF0 == 0xE0 && input[1]&0xC0 == 0x80 && input[2]&0xC0 == 0x80 { + *symbol = (int(input[0])&0x0F)<<12 | (int(input[1])&0x3F)<<6 | int(input[2])&0x3F + if *symbol > 0x7FF { + return 3 + } + } + + /* 4-byte UFT8 */ + if size > 3 && input[0]&0xF8 == 0xF0 && input[1]&0xC0 == 0x80 && input[2]&0xC0 == 0x80 && input[3]&0xC0 == 0x80 { + *symbol = (int(input[0])&0x07)<<18 | (int(input[1])&0x3F)<<12 | (int(input[2])&0x3F)<<6 | int(input[3])&0x3F + if *symbol > 0xFFFF && *symbol <= 0x10FFFF { + return 4 + } + } + + /* Not UTF8, emit a special symbol above the UTF8-code space */ + *symbol = 0x110000 | int(input[0]) + + return 1 +} + +/* Returns 1 if at least min_fraction of the data is UTF8-encoded.*/ +func isMostlyUTF8(data []byte, pos uint, mask uint, length uint, min_fraction float64) bool { + var size_utf8 uint = 0 + var i uint = 0 + for i < length { + var symbol int + current_data := data[(pos+i)&mask:] + var bytes_read uint = parseAsUTF8(&symbol, current_data, length-i) + i += bytes_read + if symbol < 0x110000 { + size_utf8 += bytes_read + } + } + + return float64(size_utf8) > min_fraction*float64(length) +} diff --git a/vendor/github.com/andybalholm/brotli/util.go b/vendor/github.com/andybalholm/brotli/util.go new file mode 100644 index 0000000..a84553a --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/util.go @@ -0,0 +1,7 @@ +package brotli + +func assert(cond bool) { + if !cond { + panic("assertion failure") + } +} diff --git a/vendor/github.com/andybalholm/brotli/write_bits.go b/vendor/github.com/andybalholm/brotli/write_bits.go new file mode 100644 index 0000000..8729901 --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/write_bits.go @@ -0,0 +1,52 @@ +package brotli + +import "encoding/binary" + +/* Copyright 2010 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Write bits into a byte array. */ + +/* This function writes bits into bytes in increasing addresses, and within + a byte least-significant-bit first. + + The function can write up to 56 bits in one go with WriteBits + Example: let's assume that 3 bits (Rs below) have been written already: + + BYTE-0 BYTE+1 BYTE+2 + + 0000 0RRR 0000 0000 0000 0000 + + Now, we could write 5 or less bits in MSB by just sifting by 3 + and OR'ing to BYTE-0. + + For n bits, we take the last 5 bits, OR that with high bits in BYTE-0, + and locate the rest in BYTE+1, BYTE+2, etc. */ +func writeBits(n_bits uint, bits uint64, pos *uint, array []byte) { + /* This branch of the code can write up to 56 bits at a time, + 7 bits are lost by being perhaps already in *p and at least + 1 bit is needed to initialize the bit-stream ahead (i.e. if 7 + bits are in *p and we write 57 bits, then the next write will + access a byte that was never initialized). */ + p := array[*pos>>3:] + v := uint64(p[0]) + v |= bits << (*pos & 7) + binary.LittleEndian.PutUint64(p, v) + *pos += n_bits +} + +func writeSingleBit(bit bool, pos *uint, array []byte) { + if bit { + writeBits(1, 1, pos, array) + } else { + writeBits(1, 0, pos, array) + } +} + +func writeBitsPrepareStorage(pos uint, array []byte) { + assert(pos&7 == 0) + array[pos>>3] = 0 +} diff --git a/vendor/github.com/andybalholm/brotli/writer.go b/vendor/github.com/andybalholm/brotli/writer.go new file mode 100644 index 0000000..39feaef --- /dev/null +++ b/vendor/github.com/andybalholm/brotli/writer.go @@ -0,0 +1,119 @@ +package brotli + +import ( + "errors" + "io" +) + +const ( + BestSpeed = 0 + BestCompression = 11 + DefaultCompression = 6 +) + +// WriterOptions configures Writer. +type WriterOptions struct { + // Quality controls the compression-speed vs compression-density trade-offs. + // The higher the quality, the slower the compression. Range is 0 to 11. + Quality int + // LGWin is the base 2 logarithm of the sliding window size. + // Range is 10 to 24. 0 indicates automatic configuration based on Quality. + LGWin int +} + +var ( + errEncode = errors.New("brotli: encode error") + errWriterClosed = errors.New("brotli: Writer is closed") +) + +// Writes to the returned writer are compressed and written to dst. +// It is the caller's responsibility to call Close on the Writer when done. +// Writes may be buffered and not flushed until Close. +func NewWriter(dst io.Writer) *Writer { + return NewWriterLevel(dst, DefaultCompression) +} + +// NewWriterLevel is like NewWriter but specifies the compression level instead +// of assuming DefaultCompression. +// The compression level can be DefaultCompression or any integer value between +// BestSpeed and BestCompression inclusive. +func NewWriterLevel(dst io.Writer, level int) *Writer { + return NewWriterOptions(dst, WriterOptions{ + Quality: level, + }) +} + +// NewWriterOptions is like NewWriter but specifies WriterOptions +func NewWriterOptions(dst io.Writer, options WriterOptions) *Writer { + w := new(Writer) + w.options = options + w.Reset(dst) + return w +} + +// Reset discards the Writer's state and makes it equivalent to the result of +// its original state from NewWriter or NewWriterLevel, but writing to dst +// instead. This permits reusing a Writer rather than allocating a new one. +func (w *Writer) Reset(dst io.Writer) { + encoderInitState(w) + w.params.quality = w.options.Quality + if w.options.LGWin > 0 { + w.params.lgwin = uint(w.options.LGWin) + } + w.dst = dst + w.err = nil +} + +func (w *Writer) writeChunk(p []byte, op int) (n int, err error) { + if w.dst == nil { + return 0, errWriterClosed + } + if w.err != nil { + return 0, w.err + } + + for { + availableIn := uint(len(p)) + nextIn := p + success := encoderCompressStream(w, op, &availableIn, &nextIn) + bytesConsumed := len(p) - int(availableIn) + p = p[bytesConsumed:] + n += bytesConsumed + if !success { + return n, errEncode + } + + if len(p) == 0 || w.err != nil { + return n, w.err + } + } +} + +// Flush outputs encoded data for all input provided to Write. The resulting +// output can be decoded to match all input before Flush, but the stream is +// not yet complete until after Close. +// Flush has a negative impact on compression. +func (w *Writer) Flush() error { + _, err := w.writeChunk(nil, operationFlush) + return err +} + +// Close flushes remaining data to the decorated writer. +func (w *Writer) Close() error { + // If stream is already closed, it is reported by `writeChunk`. + _, err := w.writeChunk(nil, operationFinish) + w.dst = nil + return err +} + +// Write implements io.Writer. Flush or Close must be called to ensure that the +// encoded bytes are actually flushed to the underlying Writer. +func (w *Writer) Write(p []byte) (n int, err error) { + return w.writeChunk(p, operationProcess) +} + +type nopCloser struct { + io.Writer +} + +func (nopCloser) Close() error { return nil } diff --git a/vendor/github.com/araddon/dateparse/.travis.yml b/vendor/github.com/araddon/dateparse/.travis.yml new file mode 100644 index 0000000..3b4b177 --- /dev/null +++ b/vendor/github.com/araddon/dateparse/.travis.yml @@ -0,0 +1,13 @@ +language: go + +go: + - 1.13.x + +before_install: + - go get -t -v ./... + +script: + - go test -race -coverprofile=coverage.txt -covermode=atomic + +after_success: + - bash <(curl -s https://codecov.io/bash) diff --git a/vendor/github.com/araddon/dateparse/LICENSE b/vendor/github.com/araddon/dateparse/LICENSE new file mode 100644 index 0000000..f675ed3 --- /dev/null +++ b/vendor/github.com/araddon/dateparse/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015-2017 Aaron Raddon + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/araddon/dateparse/README.md b/vendor/github.com/araddon/dateparse/README.md new file mode 100644 index 0000000..fe682dd --- /dev/null +++ b/vendor/github.com/araddon/dateparse/README.md @@ -0,0 +1,323 @@ +Go Date Parser +--------------------------- + +Parse many date strings without knowing format in advance. Uses a scanner to read bytes and use a state machine to find format. Much faster than shotgun based parse methods. See [bench_test.go](https://github.com/araddon/dateparse/blob/master/bench_test.go) for performance comparison. + + +[![Code Coverage](https://codecov.io/gh/araddon/dateparse/branch/master/graph/badge.svg)](https://codecov.io/gh/araddon/dateparse) +[![GoDoc](https://godoc.org/github.com/araddon/dateparse?status.svg)](http://godoc.org/github.com/araddon/dateparse) +[![Build Status](https://travis-ci.org/araddon/dateparse.svg?branch=master)](https://travis-ci.org/araddon/dateparse) +[![Go ReportCard](https://goreportcard.com/badge/araddon/dateparse)](https://goreportcard.com/report/araddon/dateparse) + +**MM/DD/YYYY VS DD/MM/YYYY** Right now this uses mm/dd/yyyy WHEN ambiguous if this is not desired behavior, use `ParseStrict` which will fail on ambiguous date strings. + +**Timezones** The location your server is configured affects the results! See example or https://play.golang.org/p/IDHRalIyXh and last paragraph here https://golang.org/pkg/time/#Parse. + + +```go + +// Normal parse. Equivalent Timezone rules as time.Parse() +t, err := dateparse.ParseAny("3/1/2014") + +// Parse Strict, error on ambigous mm/dd vs dd/mm dates +t, err := dateparse.ParseStrict("3/1/2014") +> returns error + +// Return a string that represents the layout to parse the given date-time. +layout, err := dateparse.ParseFormat("May 8, 2009 5:57:51 PM") +> "Jan 2, 2006 3:04:05 PM" + +``` + +cli tool for testing dateformats +---------------------------------- + +[Date Parse CLI](https://github.com/araddon/dateparse/blob/master/dateparse) + + +Extended example +------------------- + +https://github.com/araddon/dateparse/blob/master/example/main.go + +```go +package main + +import ( + "flag" + "fmt" + "time" + + "github.com/scylladb/termtables" + "github.com/araddon/dateparse" +) + +var examples = []string{ + "May 8, 2009 5:57:51 PM", + "oct 7, 1970", + "oct 7, '70", + "oct. 7, 1970", + "oct. 7, 70", + "Mon Jan 2 15:04:05 2006", + "Mon Jan 2 15:04:05 MST 2006", + "Mon Jan 02 15:04:05 -0700 2006", + "Monday, 02-Jan-06 15:04:05 MST", + "Mon, 02 Jan 2006 15:04:05 MST", + "Tue, 11 Jul 2017 16:28:13 +0200 (CEST)", + "Mon, 02 Jan 2006 15:04:05 -0700", + "Mon 30 Sep 2018 09:09:09 PM UTC", + "Mon Aug 10 15:44:11 UTC+0100 2015", + "Thu, 4 Jan 2018 17:53:36 +0000", + "Fri Jul 03 2015 18:04:07 GMT+0100 (GMT Daylight Time)", + "Sun, 3 Jan 2021 00:12:23 +0800 (GMT+08:00)", + "September 17, 2012 10:09am", + "September 17, 2012 at 10:09am PST-08", + "September 17, 2012, 10:10:09", + "October 7, 1970", + "October 7th, 1970", + "12 Feb 2006, 19:17", + "12 Feb 2006 19:17", + "14 May 2019 19:11:40.164", + "7 oct 70", + "7 oct 1970", + "03 February 2013", + "1 July 2013", + "2013-Feb-03", + // dd/Mon/yyy alpha Months + "06/Jan/2008:15:04:05 -0700", + "06/Jan/2008 15:04:05 -0700", + // mm/dd/yy + "3/31/2014", + "03/31/2014", + "08/21/71", + "8/1/71", + "4/8/2014 22:05", + "04/08/2014 22:05", + "4/8/14 22:05", + "04/2/2014 03:00:51", + "8/8/1965 12:00:00 AM", + "8/8/1965 01:00:01 PM", + "8/8/1965 01:00 PM", + "8/8/1965 1:00 PM", + "8/8/1965 12:00 AM", + "4/02/2014 03:00:51", + "03/19/2012 10:11:59", + "03/19/2012 10:11:59.3186369", + // yyyy/mm/dd + "2014/3/31", + "2014/03/31", + "2014/4/8 22:05", + "2014/04/08 22:05", + "2014/04/2 03:00:51", + "2014/4/02 03:00:51", + "2012/03/19 10:11:59", + "2012/03/19 10:11:59.3186369", + // yyyy:mm:dd + "2014:3:31", + "2014:03:31", + "2014:4:8 22:05", + "2014:04:08 22:05", + "2014:04:2 03:00:51", + "2014:4:02 03:00:51", + "2012:03:19 10:11:59", + "2012:03:19 10:11:59.3186369", + // Chinese + "2014年04月08日", + // yyyy-mm-ddThh + "2006-01-02T15:04:05+0000", + "2009-08-12T22:15:09-07:00", + "2009-08-12T22:15:09", + "2009-08-12T22:15:09.988", + "2009-08-12T22:15:09Z", + "2017-07-19T03:21:51:897+0100", + "2019-05-29T08:41-04", // no seconds, 2 digit TZ offset + // yyyy-mm-dd hh:mm:ss + "2014-04-26 17:24:37.3186369", + "2012-08-03 18:31:59.257000000", + "2014-04-26 17:24:37.123", + "2013-04-01 22:43", + "2013-04-01 22:43:22", + "2014-12-16 06:20:00 UTC", + "2014-12-16 06:20:00 GMT", + "2014-04-26 05:24:37 PM", + "2014-04-26 13:13:43 +0800", + "2014-04-26 13:13:43 +0800 +08", + "2014-04-26 13:13:44 +09:00", + "2012-08-03 18:31:59.257000000 +0000 UTC", + "2015-09-30 18:48:56.35272715 +0000 UTC", + "2015-02-18 00:12:00 +0000 GMT", + "2015-02-18 00:12:00 +0000 UTC", + "2015-02-08 03:02:00 +0300 MSK m=+0.000000001", + "2015-02-08 03:02:00.001 +0300 MSK m=+0.000000001", + "2017-07-19 03:21:51+00:00", + "2014-04-26", + "2014-04", + "2014", + "2014-05-11 08:20:13,787", + // yyyy-mm-dd-07:00 + "2020-07-20+08:00", + // mm.dd.yy + "3.31.2014", + "03.31.2014", + "08.21.71", + "2014.03", + "2014.03.30", + // yyyymmdd and similar + "20140601", + "20140722105203", + // yymmdd hh:mm:yy mysql log + // 080313 05:21:55 mysqld started + "171113 14:14:20", + // unix seconds, ms, micro, nano + "1332151919", + "1384216367189", + "1384216367111222", + "1384216367111222333", +} + +var ( + timezone = "" +) + +func main() { + flag.StringVar(&timezone, "timezone", "UTC", "Timezone aka `America/Los_Angeles` formatted time-zone") + flag.Parse() + + if timezone != "" { + // NOTE: This is very, very important to understand + // time-parsing in go + loc, err := time.LoadLocation(timezone) + if err != nil { + panic(err.Error()) + } + time.Local = loc + } + + table := termtables.CreateTable() + + table.AddHeaders("Input", "Parsed, and Output as %v") + for _, dateExample := range examples { + t, err := dateparse.ParseLocal(dateExample) + if err != nil { + panic(err.Error()) + } + table.AddRow(dateExample, fmt.Sprintf("%v", t)) + } + fmt.Println(table.Render()) +} + +/* ++-------------------------------------------------------+-----------------------------------------+ +| Input | Parsed, and Output as %v | ++-------------------------------------------------------+-----------------------------------------+ +| May 8, 2009 5:57:51 PM | 2009-05-08 17:57:51 +0000 UTC | +| oct 7, 1970 | 1970-10-07 00:00:00 +0000 UTC | +| oct 7, '70 | 1970-10-07 00:00:00 +0000 UTC | +| oct. 7, 1970 | 1970-10-07 00:00:00 +0000 UTC | +| oct. 7, 70 | 1970-10-07 00:00:00 +0000 UTC | +| Mon Jan 2 15:04:05 2006 | 2006-01-02 15:04:05 +0000 UTC | +| Mon Jan 2 15:04:05 MST 2006 | 2006-01-02 15:04:05 +0000 MST | +| Mon Jan 02 15:04:05 -0700 2006 | 2006-01-02 15:04:05 -0700 -0700 | +| Monday, 02-Jan-06 15:04:05 MST | 2006-01-02 15:04:05 +0000 MST | +| Mon, 02 Jan 2006 15:04:05 MST | 2006-01-02 15:04:05 +0000 MST | +| Tue, 11 Jul 2017 16:28:13 +0200 (CEST) | 2017-07-11 16:28:13 +0200 +0200 | +| Mon, 02 Jan 2006 15:04:05 -0700 | 2006-01-02 15:04:05 -0700 -0700 | +| Mon 30 Sep 2018 09:09:09 PM UTC | 2018-09-30 21:09:09 +0000 UTC | +| Mon Aug 10 15:44:11 UTC+0100 2015 | 2015-08-10 15:44:11 +0000 UTC | +| Thu, 4 Jan 2018 17:53:36 +0000 | 2018-01-04 17:53:36 +0000 UTC | +| Fri Jul 03 2015 18:04:07 GMT+0100 (GMT Daylight Time) | 2015-07-03 18:04:07 +0100 GMT | +| Sun, 3 Jan 2021 00:12:23 +0800 (GMT+08:00) | 2021-01-03 00:12:23 +0800 +0800 | +| September 17, 2012 10:09am | 2012-09-17 10:09:00 +0000 UTC | +| September 17, 2012 at 10:09am PST-08 | 2012-09-17 10:09:00 -0800 PST | +| September 17, 2012, 10:10:09 | 2012-09-17 10:10:09 +0000 UTC | +| October 7, 1970 | 1970-10-07 00:00:00 +0000 UTC | +| October 7th, 1970 | 1970-10-07 00:00:00 +0000 UTC | +| 12 Feb 2006, 19:17 | 2006-02-12 19:17:00 +0000 UTC | +| 12 Feb 2006 19:17 | 2006-02-12 19:17:00 +0000 UTC | +| 14 May 2019 19:11:40.164 | 2019-05-14 19:11:40.164 +0000 UTC | +| 7 oct 70 | 1970-10-07 00:00:00 +0000 UTC | +| 7 oct 1970 | 1970-10-07 00:00:00 +0000 UTC | +| 03 February 2013 | 2013-02-03 00:00:00 +0000 UTC | +| 1 July 2013 | 2013-07-01 00:00:00 +0000 UTC | +| 2013-Feb-03 | 2013-02-03 00:00:00 +0000 UTC | +| 06/Jan/2008:15:04:05 -0700 | 2008-01-06 15:04:05 -0700 -0700 | +| 06/Jan/2008 15:04:05 -0700 | 2008-01-06 15:04:05 -0700 -0700 | +| 3/31/2014 | 2014-03-31 00:00:00 +0000 UTC | +| 03/31/2014 | 2014-03-31 00:00:00 +0000 UTC | +| 08/21/71 | 1971-08-21 00:00:00 +0000 UTC | +| 8/1/71 | 1971-08-01 00:00:00 +0000 UTC | +| 4/8/2014 22:05 | 2014-04-08 22:05:00 +0000 UTC | +| 04/08/2014 22:05 | 2014-04-08 22:05:00 +0000 UTC | +| 4/8/14 22:05 | 2014-04-08 22:05:00 +0000 UTC | +| 04/2/2014 03:00:51 | 2014-04-02 03:00:51 +0000 UTC | +| 8/8/1965 12:00:00 AM | 1965-08-08 00:00:00 +0000 UTC | +| 8/8/1965 01:00:01 PM | 1965-08-08 13:00:01 +0000 UTC | +| 8/8/1965 01:00 PM | 1965-08-08 13:00:00 +0000 UTC | +| 8/8/1965 1:00 PM | 1965-08-08 13:00:00 +0000 UTC | +| 8/8/1965 12:00 AM | 1965-08-08 00:00:00 +0000 UTC | +| 4/02/2014 03:00:51 | 2014-04-02 03:00:51 +0000 UTC | +| 03/19/2012 10:11:59 | 2012-03-19 10:11:59 +0000 UTC | +| 03/19/2012 10:11:59.3186369 | 2012-03-19 10:11:59.3186369 +0000 UTC | +| 2014/3/31 | 2014-03-31 00:00:00 +0000 UTC | +| 2014/03/31 | 2014-03-31 00:00:00 +0000 UTC | +| 2014/4/8 22:05 | 2014-04-08 22:05:00 +0000 UTC | +| 2014/04/08 22:05 | 2014-04-08 22:05:00 +0000 UTC | +| 2014/04/2 03:00:51 | 2014-04-02 03:00:51 +0000 UTC | +| 2014/4/02 03:00:51 | 2014-04-02 03:00:51 +0000 UTC | +| 2012/03/19 10:11:59 | 2012-03-19 10:11:59 +0000 UTC | +| 2012/03/19 10:11:59.3186369 | 2012-03-19 10:11:59.3186369 +0000 UTC | +| 2014:3:31 | 2014-03-31 00:00:00 +0000 UTC | +| 2014:03:31 | 2014-03-31 00:00:00 +0000 UTC | +| 2014:4:8 22:05 | 2014-04-08 22:05:00 +0000 UTC | +| 2014:04:08 22:05 | 2014-04-08 22:05:00 +0000 UTC | +| 2014:04:2 03:00:51 | 2014-04-02 03:00:51 +0000 UTC | +| 2014:4:02 03:00:51 | 2014-04-02 03:00:51 +0000 UTC | +| 2012:03:19 10:11:59 | 2012-03-19 10:11:59 +0000 UTC | +| 2012:03:19 10:11:59.3186369 | 2012-03-19 10:11:59.3186369 +0000 UTC | +| 2014年04月08日 | 2014-04-08 00:00:00 +0000 UTC | +| 2006-01-02T15:04:05+0000 | 2006-01-02 15:04:05 +0000 UTC | +| 2009-08-12T22:15:09-07:00 | 2009-08-12 22:15:09 -0700 -0700 | +| 2009-08-12T22:15:09 | 2009-08-12 22:15:09 +0000 UTC | +| 2009-08-12T22:15:09.988 | 2009-08-12 22:15:09.988 +0000 UTC | +| 2009-08-12T22:15:09Z | 2009-08-12 22:15:09 +0000 UTC | +| 2017-07-19T03:21:51:897+0100 | 2017-07-19 03:21:51.897 +0100 +0100 | +| 2019-05-29T08:41-04 | 2019-05-29 08:41:00 -0400 -0400 | +| 2014-04-26 17:24:37.3186369 | 2014-04-26 17:24:37.3186369 +0000 UTC | +| 2012-08-03 18:31:59.257000000 | 2012-08-03 18:31:59.257 +0000 UTC | +| 2014-04-26 17:24:37.123 | 2014-04-26 17:24:37.123 +0000 UTC | +| 2013-04-01 22:43 | 2013-04-01 22:43:00 +0000 UTC | +| 2013-04-01 22:43:22 | 2013-04-01 22:43:22 +0000 UTC | +| 2014-12-16 06:20:00 UTC | 2014-12-16 06:20:00 +0000 UTC | +| 2014-12-16 06:20:00 GMT | 2014-12-16 06:20:00 +0000 UTC | +| 2014-04-26 05:24:37 PM | 2014-04-26 17:24:37 +0000 UTC | +| 2014-04-26 13:13:43 +0800 | 2014-04-26 13:13:43 +0800 +0800 | +| 2014-04-26 13:13:43 +0800 +08 | 2014-04-26 13:13:43 +0800 +0800 | +| 2014-04-26 13:13:44 +09:00 | 2014-04-26 13:13:44 +0900 +0900 | +| 2012-08-03 18:31:59.257000000 +0000 UTC | 2012-08-03 18:31:59.257 +0000 UTC | +| 2015-09-30 18:48:56.35272715 +0000 UTC | 2015-09-30 18:48:56.35272715 +0000 UTC | +| 2015-02-18 00:12:00 +0000 GMT | 2015-02-18 00:12:00 +0000 UTC | +| 2015-02-18 00:12:00 +0000 UTC | 2015-02-18 00:12:00 +0000 UTC | +| 2015-02-08 03:02:00 +0300 MSK m=+0.000000001 | 2015-02-08 03:02:00 +0300 +0300 | +| 2015-02-08 03:02:00.001 +0300 MSK m=+0.000000001 | 2015-02-08 03:02:00.001 +0300 +0300 | +| 2017-07-19 03:21:51+00:00 | 2017-07-19 03:21:51 +0000 UTC | +| 2014-04-26 | 2014-04-26 00:00:00 +0000 UTC | +| 2014-04 | 2014-04-01 00:00:00 +0000 UTC | +| 2014 | 2014-01-01 00:00:00 +0000 UTC | +| 2014-05-11 08:20:13,787 | 2014-05-11 08:20:13.787 +0000 UTC | +| 2020-07-20+08:00 | 2020-07-20 00:00:00 +0800 +0800 | +| 3.31.2014 | 2014-03-31 00:00:00 +0000 UTC | +| 03.31.2014 | 2014-03-31 00:00:00 +0000 UTC | +| 08.21.71 | 1971-08-21 00:00:00 +0000 UTC | +| 2014.03 | 2014-03-01 00:00:00 +0000 UTC | +| 2014.03.30 | 2014-03-30 00:00:00 +0000 UTC | +| 20140601 | 2014-06-01 00:00:00 +0000 UTC | +| 20140722105203 | 2014-07-22 10:52:03 +0000 UTC | +| 171113 14:14:20 | 2017-11-13 14:14:20 +0000 UTC | +| 1332151919 | 2012-03-19 10:11:59 +0000 UTC | +| 1384216367189 | 2013-11-12 00:32:47.189 +0000 UTC | +| 1384216367111222 | 2013-11-12 00:32:47.111222 +0000 UTC | +| 1384216367111222333 | 2013-11-12 00:32:47.111222333 +0000 UTC | ++-------------------------------------------------------+-----------------------------------------+ +*/ + +``` diff --git a/vendor/github.com/araddon/dateparse/go.mod b/vendor/github.com/araddon/dateparse/go.mod new file mode 100644 index 0000000..071cd5e --- /dev/null +++ b/vendor/github.com/araddon/dateparse/go.mod @@ -0,0 +1,9 @@ +module github.com/araddon/dateparse + +go 1.12 + +require ( + github.com/mattn/go-runewidth v0.0.10 // indirect + github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4 + github.com/stretchr/testify v1.7.0 +) diff --git a/vendor/github.com/araddon/dateparse/go.sum b/vendor/github.com/araddon/dateparse/go.sum new file mode 100644 index 0000000..40bf744 --- /dev/null +++ b/vendor/github.com/araddon/dateparse/go.sum @@ -0,0 +1,18 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/mattn/go-runewidth v0.0.10 h1:CoZ3S2P7pvtP45xOtBw+/mDL2z0RKI576gSkzRRpdGg= +github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY= +github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4 h1:8qmTC5ByIXO3GP/IzBkxcZ/99VITvnIETDhdFz/om7A= +github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg= +github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/vendor/github.com/araddon/dateparse/parseany.go b/vendor/github.com/araddon/dateparse/parseany.go new file mode 100644 index 0000000..b9668b2 --- /dev/null +++ b/vendor/github.com/araddon/dateparse/parseany.go @@ -0,0 +1,2189 @@ +// Package dateparse parses date-strings without knowing the format +// in advance, using a fast lex based approach to eliminate shotgun +// attempts. It leans towards US style dates when there is a conflict. +package dateparse + +import ( + "fmt" + "strconv" + "strings" + "time" + "unicode" + "unicode/utf8" +) + +// func init() { +// gou.SetupLogging("debug") +// gou.SetColorOutput() +// } + +var days = []string{ + "mon", + "tue", + "wed", + "thu", + "fri", + "sat", + "sun", + "monday", + "tuesday", + "wednesday", + "thursday", + "friday", + "saturday", + "sunday", +} + +var months = []string{ + "january", + "february", + "march", + "april", + "may", + "june", + "july", + "august", + "september", + "october", + "november", + "december", +} + +type dateState uint8 +type timeState uint8 + +const ( + dateStart dateState = iota // 0 + dateDigit + dateDigitSt + dateYearDash + dateYearDashAlphaDash + dateYearDashDash + dateYearDashDashWs // 5 + dateYearDashDashT + dateYearDashDashOffset + dateDigitDash + dateDigitDashAlpha + dateDigitDashAlphaDash // 10 + dateDigitDot + dateDigitDotDot + dateDigitSlash + dateDigitYearSlash + dateDigitSlashAlpha // 15 + dateDigitColon + dateDigitChineseYear + dateDigitChineseYearWs + dateDigitWs + dateDigitWsMoYear // 20 + dateDigitWsMolong + dateAlpha + dateAlphaWs + dateAlphaWsDigit + dateAlphaWsDigitMore // 25 + dateAlphaWsDigitMoreWs + dateAlphaWsDigitMoreWsYear + dateAlphaWsMonth + dateAlphaWsDigitYearmaybe + dateAlphaWsMonthMore + dateAlphaWsMonthSuffix + dateAlphaWsMore + dateAlphaWsAtTime + dateAlphaWsAlpha + dateAlphaWsAlphaYearmaybe // 35 + dateAlphaPeriodWsDigit + dateWeekdayComma + dateWeekdayAbbrevComma +) +const ( + // Time state + timeIgnore timeState = iota // 0 + timeStart + timeWs + timeWsAlpha + timeWsAlphaWs + timeWsAlphaZoneOffset // 5 + timeWsAlphaZoneOffsetWs + timeWsAlphaZoneOffsetWsYear + timeWsAlphaZoneOffsetWsExtra + timeWsAMPMMaybe + timeWsAMPM // 10 + timeWsOffset + timeWsOffsetWs // 12 + timeWsOffsetColonAlpha + timeWsOffsetColon + timeWsYear // 15 + timeOffset + timeOffsetColon + timeAlpha + timePeriod + timePeriodOffset // 20 + timePeriodOffsetColon + timePeriodOffsetColonWs + timePeriodWs + timePeriodWsAlpha + timePeriodWsOffset // 25 + timePeriodWsOffsetWs + timePeriodWsOffsetWsAlpha + timePeriodWsOffsetColon + timePeriodWsOffsetColonAlpha + timeZ + timeZDigit +) + +var ( + // ErrAmbiguousMMDD for date formats such as 04/02/2014 the mm/dd vs dd/mm are + // ambiguous, so it is an error for strict parse rules. + ErrAmbiguousMMDD = fmt.Errorf("This date has ambiguous mm/dd vs dd/mm type format") +) + +func unknownErr(datestr string) error { + return fmt.Errorf("Could not find format for %q", datestr) +} + +// ParseAny parse an unknown date format, detect the layout. +// Normal parse. Equivalent Timezone rules as time.Parse(). +// NOTE: please see readme on mmdd vs ddmm ambiguous dates. +func ParseAny(datestr string, opts ...ParserOption) (time.Time, error) { + p, err := parseTime(datestr, nil, opts...) + if err != nil { + return time.Time{}, err + } + return p.parse() +} + +// ParseIn with Location, equivalent to time.ParseInLocation() timezone/offset +// rules. Using location arg, if timezone/offset info exists in the +// datestring, it uses the given location rules for any zone interpretation. +// That is, MST means one thing when using America/Denver and something else +// in other locations. +func ParseIn(datestr string, loc *time.Location, opts ...ParserOption) (time.Time, error) { + p, err := parseTime(datestr, loc, opts...) + if err != nil { + return time.Time{}, err + } + return p.parse() +} + +// ParseLocal Given an unknown date format, detect the layout, +// using time.Local, parse. +// +// Set Location to time.Local. Same as ParseIn Location but lazily uses +// the global time.Local variable for Location argument. +// +// denverLoc, _ := time.LoadLocation("America/Denver") +// time.Local = denverLoc +// +// t, err := dateparse.ParseLocal("3/1/2014") +// +// Equivalent to: +// +// t, err := dateparse.ParseIn("3/1/2014", denverLoc) +// +func ParseLocal(datestr string, opts ...ParserOption) (time.Time, error) { + p, err := parseTime(datestr, time.Local, opts...) + if err != nil { + return time.Time{}, err + } + return p.parse() +} + +// MustParse parse a date, and panic if it can't be parsed. Used for testing. +// Not recommended for most use-cases. +func MustParse(datestr string, opts ...ParserOption) time.Time { + p, err := parseTime(datestr, nil, opts...) + if err != nil { + panic(err.Error()) + } + t, err := p.parse() + if err != nil { + panic(err.Error()) + } + return t +} + +// ParseFormat parse's an unknown date-time string and returns a layout +// string that can parse this (and exact same format) other date-time strings. +// +// layout, err := dateparse.ParseFormat("2013-02-01 00:00:00") +// // layout = "2006-01-02 15:04:05" +// +func ParseFormat(datestr string, opts ...ParserOption) (string, error) { + p, err := parseTime(datestr, nil, opts...) + if err != nil { + return "", err + } + _, err = p.parse() + if err != nil { + return "", err + } + return string(p.format), nil +} + +// ParseStrict parse an unknown date format. IF the date is ambigous +// mm/dd vs dd/mm then return an error. These return errors: 3.3.2014 , 8/8/71 etc +func ParseStrict(datestr string, opts ...ParserOption) (time.Time, error) { + p, err := parseTime(datestr, nil, opts...) + if err != nil { + return time.Time{}, err + } + if p.ambiguousMD { + return time.Time{}, ErrAmbiguousMMDD + } + return p.parse() +} + +func parseTime(datestr string, loc *time.Location, opts ...ParserOption) (p *parser, err error) { + + p = newParser(datestr, loc, opts...) + if p.retryAmbiguousDateWithSwap { + // month out of range signifies that a day/month swap is the correct solution to an ambiguous date + // this is because it means that a day is being interpreted as a month and overflowing the valid value for that + // by retrying in this case, we can fix a common situation with no assumptions + defer func() { + if p != nil && p.ambiguousMD { + // if it errors out with the following error, swap before we + // get out of this function to reduce scope it needs to be applied on + _, err := p.parse() + if err != nil && strings.Contains(err.Error(), "month out of range") { + // create the option to reverse the preference + preferMonthFirst := PreferMonthFirst(!p.preferMonthFirst) + // turn off the retry to avoid endless recursion + retryAmbiguousDateWithSwap := RetryAmbiguousDateWithSwap(false) + modifiedOpts := append(opts, preferMonthFirst, retryAmbiguousDateWithSwap) + p, err = parseTime(datestr, time.Local, modifiedOpts...) + } + } + + }() + } + + i := 0 + + // General strategy is to read rune by rune through the date looking for + // certain hints of what type of date we are dealing with. + // Hopefully we only need to read about 5 or 6 bytes before + // we figure it out and then attempt a parse +iterRunes: + for ; i < len(datestr); i++ { + //r := rune(datestr[i]) + r, bytesConsumed := utf8.DecodeRuneInString(datestr[i:]) + if bytesConsumed > 1 { + i += (bytesConsumed - 1) + } + + // gou.Debugf("i=%d r=%s state=%d %s", i, string(r), p.stateDate, datestr) + switch p.stateDate { + case dateStart: + if unicode.IsDigit(r) { + p.stateDate = dateDigit + } else if unicode.IsLetter(r) { + p.stateDate = dateAlpha + } else { + return nil, unknownErr(datestr) + } + case dateDigit: + + switch r { + case '-', '\u2212': + // 2006-01-02 + // 2013-Feb-03 + // 13-Feb-03 + // 29-Jun-2016 + if i == 4 { + p.stateDate = dateYearDash + p.yeari = 0 + p.yearlen = i + p.moi = i + 1 + p.set(0, "2006") + } else { + p.stateDate = dateDigitDash + } + case '/': + // 08/May/2005 + // 03/31/2005 + // 2014/02/24 + p.stateDate = dateDigitSlash + if i == 4 { + // 2014/02/24 - Year first / + p.yearlen = i // since it was start of datestr, i=len + p.moi = i + 1 + p.setYear() + p.stateDate = dateDigitYearSlash + } else { + // Either Ambiguous dd/mm vs mm/dd OR dd/month/yy + // 08/May/2005 + // 03/31/2005 + // 31/03/2005 + if i+2 < len(p.datestr) && unicode.IsLetter(rune(datestr[i+1])) { + // 08/May/2005 + p.stateDate = dateDigitSlashAlpha + p.moi = i + 1 + p.daylen = 2 + p.dayi = 0 + p.setDay() + continue + } + // Ambiguous dd/mm vs mm/dd the bane of date-parsing + // 03/31/2005 + // 31/03/2005 + p.ambiguousMD = true + if p.preferMonthFirst { + if p.molen == 0 { + // 03/31/2005 + p.molen = i + p.setMonth() + p.dayi = i + 1 + } + } else { + if p.daylen == 0 { + p.daylen = i + p.setDay() + p.moi = i + 1 + } + } + + } + + case ':': + // 03/31/2005 + // 2014/02/24 + p.stateDate = dateDigitColon + if i == 4 { + p.yearlen = i + p.moi = i + 1 + p.setYear() + } else { + p.ambiguousMD = true + if p.preferMonthFirst { + if p.molen == 0 { + p.molen = i + p.setMonth() + p.dayi = i + 1 + } + } + } + + case '.': + // 3.31.2014 + // 08.21.71 + // 2014.05 + p.stateDate = dateDigitDot + if i == 4 { + p.yearlen = i + p.moi = i + 1 + p.setYear() + } else { + p.ambiguousMD = true + p.moi = 0 + p.molen = i + p.setMonth() + p.dayi = i + 1 + } + + case ' ': + // 18 January 2018 + // 8 January 2018 + // 8 jan 2018 + // 02 Jan 2018 23:59 + // 02 Jan 2018 23:59:34 + // 12 Feb 2006, 19:17 + // 12 Feb 2006, 19:17:22 + if i == 6 { + p.stateDate = dateDigitSt + } else { + p.stateDate = dateDigitWs + p.dayi = 0 + p.daylen = i + } + case '年': + // Chinese Year + p.stateDate = dateDigitChineseYear + case ',': + return nil, unknownErr(datestr) + default: + continue + } + p.part1Len = i + + case dateDigitSt: + p.set(0, "060102") + i = i - 1 + p.stateTime = timeStart + break iterRunes + case dateYearDash: + // dateYearDashDashT + // 2006-01-02T15:04:05Z07:00 + // 2020-08-17T17:00:00:000+0100 + // dateYearDashDashWs + // 2013-04-01 22:43:22 + // dateYearDashAlphaDash + // 2013-Feb-03 + switch r { + case '-': + p.molen = i - p.moi + p.dayi = i + 1 + p.stateDate = dateYearDashDash + p.setMonth() + default: + if unicode.IsLetter(r) { + p.stateDate = dateYearDashAlphaDash + } + } + + case dateYearDashDash: + // dateYearDashDashT + // 2006-01-02T15:04:05Z07:00 + // dateYearDashDashWs + // 2013-04-01 22:43:22 + // dateYearDashDashOffset + // 2020-07-20+00:00 + switch r { + case '+', '-': + p.offseti = i + p.daylen = i - p.dayi + p.stateDate = dateYearDashDashOffset + p.setDay() + case ' ': + p.daylen = i - p.dayi + p.stateDate = dateYearDashDashWs + p.stateTime = timeStart + p.setDay() + break iterRunes + case 'T': + p.daylen = i - p.dayi + p.stateDate = dateYearDashDashT + p.stateTime = timeStart + p.setDay() + break iterRunes + } + + case dateYearDashDashT: + // dateYearDashDashT + // 2006-01-02T15:04:05Z07:00 + // 2020-08-17T17:00:00:000+0100 + + case dateYearDashDashOffset: + // 2020-07-20+00:00 + switch r { + case ':': + p.set(p.offseti, "-07:00") + // case ' ': + // return nil, unknownErr(datestr) + } + + case dateYearDashAlphaDash: + // 2013-Feb-03 + switch r { + case '-': + p.molen = i - p.moi + p.set(p.moi, "Jan") + p.dayi = i + 1 + } + case dateDigitDash: + // 13-Feb-03 + // 29-Jun-2016 + if unicode.IsLetter(r) { + p.stateDate = dateDigitDashAlpha + p.moi = i + } else { + return nil, unknownErr(datestr) + } + case dateDigitDashAlpha: + // 13-Feb-03 + // 28-Feb-03 + // 29-Jun-2016 + switch r { + case '-': + p.molen = i - p.moi + p.set(p.moi, "Jan") + p.yeari = i + 1 + p.stateDate = dateDigitDashAlphaDash + } + + case dateDigitDashAlphaDash: + // 13-Feb-03 ambiguous + // 28-Feb-03 ambiguous + // 29-Jun-2016 dd-month(alpha)-yyyy + switch r { + case ' ': + // we need to find if this was 4 digits, aka year + // or 2 digits which makes it ambiguous year/day + length := i - (p.moi + p.molen + 1) + if length == 4 { + p.yearlen = 4 + p.set(p.yeari, "2006") + // We now also know that part1 was the day + p.dayi = 0 + p.daylen = p.part1Len + p.setDay() + } else if length == 2 { + // We have no idea if this is + // yy-mon-dd OR dd-mon-yy + // + // We are going to ASSUME (bad, bad) that it is dd-mon-yy which is a horible assumption + p.ambiguousMD = true + p.yearlen = 2 + p.set(p.yeari, "06") + // We now also know that part1 was the day + p.dayi = 0 + p.daylen = p.part1Len + p.setDay() + } + p.stateTime = timeStart + break iterRunes + } + + case dateDigitYearSlash: + // 2014/07/10 06:55:38.156283 + // I honestly don't know if this format ever shows up as yyyy/ + + switch r { + case ' ', ':': + p.stateTime = timeStart + if p.daylen == 0 { + p.daylen = i - p.dayi + p.setDay() + } + break iterRunes + case '/': + if p.molen == 0 { + p.molen = i - p.moi + p.setMonth() + p.dayi = i + 1 + } + } + + case dateDigitSlashAlpha: + // 06/May/2008 + + switch r { + case '/': + // | + // 06/May/2008 + if p.molen == 0 { + p.set(p.moi, "Jan") + p.yeari = i + 1 + } + // We aren't breaking because we are going to re-use this case + // to find where the date starts, and possible time begins + case ' ', ':': + p.stateTime = timeStart + if p.yearlen == 0 { + p.yearlen = i - p.yeari + p.setYear() + } + break iterRunes + } + + case dateDigitSlash: + // 03/19/2012 10:11:59 + // 04/2/2014 03:00:37 + // 3/1/2012 10:11:59 + // 4/8/2014 22:05 + // 3/1/2014 + // 10/13/2014 + // 01/02/2006 + // 1/2/06 + + switch r { + case '/': + // This is the 2nd / so now we should know start pts of all of the dd, mm, yy + if p.preferMonthFirst { + if p.daylen == 0 { + p.daylen = i - p.dayi + p.setDay() + p.yeari = i + 1 + } + } else { + if p.molen == 0 { + p.molen = i - p.moi + p.setMonth() + p.yeari = i + 1 + } + } + // Note no break, we are going to pass by and re-enter this dateDigitSlash + // and look for ending (space) or not (just date) + case ' ': + p.stateTime = timeStart + if p.yearlen == 0 { + p.yearlen = i - p.yeari + p.setYear() + } + break iterRunes + } + + case dateDigitColon: + // 2014:07:10 06:55:38.156283 + // 03:19:2012 10:11:59 + // 04:2:2014 03:00:37 + // 3:1:2012 10:11:59 + // 4:8:2014 22:05 + // 3:1:2014 + // 10:13:2014 + // 01:02:2006 + // 1:2:06 + + switch r { + case ' ': + p.stateTime = timeStart + if p.yearlen == 0 { + p.yearlen = i - p.yeari + p.setYear() + } else if p.daylen == 0 { + p.daylen = i - p.dayi + p.setDay() + } + break iterRunes + case ':': + if p.yearlen > 0 { + // 2014:07:10 06:55:38.156283 + if p.molen == 0 { + p.molen = i - p.moi + p.setMonth() + p.dayi = i + 1 + } + } else if p.preferMonthFirst { + if p.daylen == 0 { + p.daylen = i - p.dayi + p.setDay() + p.yeari = i + 1 + } + } + } + + case dateDigitWs: + // 18 January 2018 + // 8 January 2018 + // 8 jan 2018 + // 1 jan 18 + // 02 Jan 2018 23:59 + // 02 Jan 2018 23:59:34 + // 12 Feb 2006, 19:17 + // 12 Feb 2006, 19:17:22 + switch r { + case ' ': + p.yeari = i + 1 + //p.yearlen = 4 + p.dayi = 0 + p.daylen = p.part1Len + p.setDay() + p.stateTime = timeStart + if i > p.daylen+len(" Sep") { // November etc + // If len greather than space + 3 it must be full month + p.stateDate = dateDigitWsMolong + } else { + // If len=3, the might be Feb or May? Ie ambigous abbreviated but + // we can parse may with either. BUT, that means the + // format may not be correct? + // mo := strings.ToLower(datestr[p.daylen+1 : i]) + p.moi = p.daylen + 1 + p.molen = i - p.moi + p.set(p.moi, "Jan") + p.stateDate = dateDigitWsMoYear + } + } + + case dateDigitWsMoYear: + // 8 jan 2018 + // 02 Jan 2018 23:59 + // 02 Jan 2018 23:59:34 + // 12 Feb 2006, 19:17 + // 12 Feb 2006, 19:17:22 + switch r { + case ',': + p.yearlen = i - p.yeari + p.setYear() + i++ + break iterRunes + case ' ': + p.yearlen = i - p.yeari + p.setYear() + break iterRunes + } + case dateDigitWsMolong: + // 18 January 2018 + // 8 January 2018 + + case dateDigitChineseYear: + // dateDigitChineseYear + // 2014年04月08日 + // weekday %Y年%m月%e日 %A %I:%M %p + // 2013年07月18日 星期四 10:27 上午 + if r == ' ' { + p.stateDate = dateDigitChineseYearWs + break + } + case dateDigitDot: + // This is the 2nd period + // 3.31.2014 + // 08.21.71 + // 2014.05 + // 2018.09.30 + if r == '.' { + if p.moi == 0 { + // 3.31.2014 + p.daylen = i - p.dayi + p.yeari = i + 1 + p.setDay() + p.stateDate = dateDigitDotDot + } else { + // 2018.09.30 + //p.molen = 2 + p.molen = i - p.moi + p.dayi = i + 1 + p.setMonth() + p.stateDate = dateDigitDotDot + } + } + case dateDigitDotDot: + // iterate all the way through + case dateAlpha: + // dateAlphaWS + // Mon Jan _2 15:04:05 2006 + // Mon Jan _2 15:04:05 MST 2006 + // Mon Jan 02 15:04:05 -0700 2006 + // Mon Aug 10 15:44:11 UTC+0100 2015 + // Fri Jul 03 2015 18:04:07 GMT+0100 (GMT Daylight Time) + // dateAlphaWSDigit + // May 8, 2009 5:57:51 PM + // oct 1, 1970 + // dateAlphaWsMonth + // April 8, 2009 + // dateAlphaWsMore + // dateAlphaWsAtTime + // January 02, 2006 at 3:04pm MST-07 + // + // dateAlphaPeriodWsDigit + // oct. 1, 1970 + // dateWeekdayComma + // Monday, 02 Jan 2006 15:04:05 MST + // Monday, 02-Jan-06 15:04:05 MST + // Monday, 02 Jan 2006 15:04:05 -0700 + // Monday, 02 Jan 2006 15:04:05 +0100 + // dateWeekdayAbbrevComma + // Mon, 02 Jan 2006 15:04:05 MST + // Mon, 02 Jan 2006 15:04:05 -0700 + // Thu, 13 Jul 2017 08:58:40 +0100 + // Tue, 11 Jul 2017 16:28:13 +0200 (CEST) + // Mon, 02-Jan-06 15:04:05 MST + switch { + case r == ' ': + // X + // April 8, 2009 + if i > 3 { + // Check to see if the alpha is name of month? or Day? + month := strings.ToLower(datestr[0:i]) + if isMonthFull(month) { + p.fullMonth = month + // len(" 31, 2018") = 9 + if len(datestr[i:]) < 10 { + // April 8, 2009 + p.stateDate = dateAlphaWsMonth + } else { + p.stateDate = dateAlphaWsMore + } + p.dayi = i + 1 + break + } + + } else { + // This is possibly ambiguous? May will parse as either though. + // So, it could return in-correct format. + // dateAlphaWs + // May 05, 2005, 05:05:05 + // May 05 2005, 05:05:05 + // Jul 05, 2005, 05:05:05 + // May 8 17:57:51 2009 + // May 8 17:57:51 2009 + // skip & return to dateStart + // Tue 05 May 2020, 05:05:05 + // Mon Jan 2 15:04:05 2006 + + maybeDay := strings.ToLower(datestr[0:i]) + if isDay(maybeDay) { + // using skip throws off indices used by other code; saner to restart + return parseTime(datestr[i+1:], loc) + } + p.stateDate = dateAlphaWs + } + + case r == ',': + // Mon, 02 Jan 2006 + + if i == 3 { + p.stateDate = dateWeekdayAbbrevComma + p.set(0, "Mon") + } else { + p.stateDate = dateWeekdayComma + p.skip = i + 2 + i++ + // TODO: lets just make this "skip" as we don't need + // the mon, monday, they are all superfelous and not needed + // just lay down the skip, no need to fill and then skip + } + case r == '.': + // sept. 28, 2017 + // jan. 28, 2017 + p.stateDate = dateAlphaPeriodWsDigit + if i == 3 { + p.molen = i + p.set(0, "Jan") + } else if i == 4 { + // gross + datestr = datestr[0:i-1] + datestr[i:] + return parseTime(datestr, loc, opts...) + } else { + return nil, unknownErr(datestr) + } + } + + case dateAlphaWs: + // dateAlphaWsAlpha + // Mon Jan _2 15:04:05 2006 + // Mon Jan _2 15:04:05 MST 2006 + // Mon Jan 02 15:04:05 -0700 2006 + // Fri Jul 03 2015 18:04:07 GMT+0100 (GMT Daylight Time) + // Mon Aug 10 15:44:11 UTC+0100 2015 + // dateAlphaWsDigit + // May 8, 2009 5:57:51 PM + // May 8 2009 5:57:51 PM + // May 8 17:57:51 2009 + // May 8 17:57:51 2009 + // May 08 17:57:51 2009 + // oct 1, 1970 + // oct 7, '70 + switch { + case unicode.IsLetter(r): + p.set(0, "Mon") + p.stateDate = dateAlphaWsAlpha + p.set(i, "Jan") + case unicode.IsDigit(r): + p.set(0, "Jan") + p.stateDate = dateAlphaWsDigit + p.dayi = i + } + + case dateAlphaWsDigit: + // May 8, 2009 5:57:51 PM + // May 8 2009 5:57:51 PM + // oct 1, 1970 + // oct 7, '70 + // oct. 7, 1970 + // May 8 17:57:51 2009 + // May 8 17:57:51 2009 + // May 08 17:57:51 2009 + if r == ',' { + p.daylen = i - p.dayi + p.setDay() + p.stateDate = dateAlphaWsDigitMore + } else if r == ' ' { + p.daylen = i - p.dayi + p.setDay() + p.yeari = i + 1 + p.stateDate = dateAlphaWsDigitYearmaybe + p.stateTime = timeStart + } else if unicode.IsLetter(r) { + p.stateDate = dateAlphaWsMonthSuffix + i-- + } + case dateAlphaWsDigitYearmaybe: + // x + // May 8 2009 5:57:51 PM + // May 8 17:57:51 2009 + // May 8 17:57:51 2009 + // May 08 17:57:51 2009 + // Jul 03 2015 18:04:07 GMT+0100 (GMT Daylight Time) + if r == ':' { + // Guessed wrong; was not a year + i = i - 3 + p.stateDate = dateAlphaWsDigit + p.yeari = 0 + break iterRunes + } else if r == ' ' { + // must be year format, not 15:04 + p.yearlen = i - p.yeari + p.setYear() + break iterRunes + } + case dateAlphaWsDigitMore: + // x + // May 8, 2009 5:57:51 PM + // May 05, 2005, 05:05:05 + // May 05 2005, 05:05:05 + // oct 1, 1970 + // oct 7, '70 + if r == ' ' { + p.yeari = i + 1 + p.stateDate = dateAlphaWsDigitMoreWs + } + case dateAlphaWsDigitMoreWs: + // x + // May 8, 2009 5:57:51 PM + // May 05, 2005, 05:05:05 + // oct 1, 1970 + // oct 7, '70 + switch r { + case '\'': + p.yeari = i + 1 + case ' ', ',': + // x + // May 8, 2009 5:57:51 PM + // x + // May 8, 2009, 5:57:51 PM + p.stateDate = dateAlphaWsDigitMoreWsYear + p.yearlen = i - p.yeari + p.setYear() + p.stateTime = timeStart + break iterRunes + } + + case dateAlphaWsMonth: + // April 8, 2009 + // April 8 2009 + switch r { + case ' ', ',': + // x + // June 8, 2009 + // x + // June 8 2009 + if p.daylen == 0 { + p.daylen = i - p.dayi + p.setDay() + } + case 's', 'S', 'r', 'R', 't', 'T', 'n', 'N': + // st, rd, nd, st + i-- + p.stateDate = dateAlphaWsMonthSuffix + default: + if p.daylen > 0 && p.yeari == 0 { + p.yeari = i + } + } + case dateAlphaWsMonthMore: + // X + // January 02, 2006, 15:04:05 + // January 02 2006, 15:04:05 + // January 02, 2006 15:04:05 + // January 02 2006 15:04:05 + switch r { + case ',': + p.yearlen = i - p.yeari + p.setYear() + p.stateTime = timeStart + i++ + break iterRunes + case ' ': + p.yearlen = i - p.yeari + p.setYear() + p.stateTime = timeStart + break iterRunes + } + case dateAlphaWsMonthSuffix: + // x + // April 8th, 2009 + // April 8th 2009 + switch r { + case 't', 'T': + if p.nextIs(i, 'h') || p.nextIs(i, 'H') { + if len(datestr) > i+2 { + return parseTime(fmt.Sprintf("%s%s", p.datestr[0:i], p.datestr[i+2:]), loc, opts...) + } + } + case 'n', 'N': + if p.nextIs(i, 'd') || p.nextIs(i, 'D') { + if len(datestr) > i+2 { + return parseTime(fmt.Sprintf("%s%s", p.datestr[0:i], p.datestr[i+2:]), loc, opts...) + } + } + case 's', 'S': + if p.nextIs(i, 't') || p.nextIs(i, 'T') { + if len(datestr) > i+2 { + return parseTime(fmt.Sprintf("%s%s", p.datestr[0:i], p.datestr[i+2:]), loc, opts...) + } + } + case 'r', 'R': + if p.nextIs(i, 'd') || p.nextIs(i, 'D') { + if len(datestr) > i+2 { + return parseTime(fmt.Sprintf("%s%s", p.datestr[0:i], p.datestr[i+2:]), loc, opts...) + } + } + } + case dateAlphaWsMore: + // January 02, 2006, 15:04:05 + // January 02 2006, 15:04:05 + // January 2nd, 2006, 15:04:05 + // January 2nd 2006, 15:04:05 + // September 17, 2012 at 5:00pm UTC-05 + switch { + case r == ',': + // x + // January 02, 2006, 15:04:05 + if p.nextIs(i, ' ') { + p.daylen = i - p.dayi + p.setDay() + p.yeari = i + 2 + p.stateDate = dateAlphaWsMonthMore + i++ + } + + case r == ' ': + // x + // January 02 2006, 15:04:05 + p.daylen = i - p.dayi + p.setDay() + p.yeari = i + 1 + p.stateDate = dateAlphaWsMonthMore + case unicode.IsDigit(r): + // XX + // January 02, 2006, 15:04:05 + continue + case unicode.IsLetter(r): + // X + // January 2nd, 2006, 15:04:05 + p.daylen = i - p.dayi + p.setDay() + p.stateDate = dateAlphaWsMonthSuffix + i-- + } + + case dateAlphaPeriodWsDigit: + // oct. 7, '70 + switch { + case r == ' ': + // continue + case unicode.IsDigit(r): + p.stateDate = dateAlphaWsDigit + p.dayi = i + default: + return p, unknownErr(datestr) + } + case dateWeekdayComma: + // Monday, 02 Jan 2006 15:04:05 MST + // Monday, 02 Jan 2006 15:04:05 -0700 + // Monday, 02 Jan 2006 15:04:05 +0100 + // Monday, 02-Jan-06 15:04:05 MST + if p.dayi == 0 { + p.dayi = i + } + switch r { + case ' ', '-': + if p.moi == 0 { + p.moi = i + 1 + p.daylen = i - p.dayi + p.setDay() + } else if p.yeari == 0 { + p.yeari = i + 1 + p.molen = i - p.moi + p.set(p.moi, "Jan") + } else { + p.stateTime = timeStart + break iterRunes + } + } + case dateWeekdayAbbrevComma: + // Mon, 02 Jan 2006 15:04:05 MST + // Mon, 02 Jan 2006 15:04:05 -0700 + // Thu, 13 Jul 2017 08:58:40 +0100 + // Thu, 4 Jan 2018 17:53:36 +0000 + // Tue, 11 Jul 2017 16:28:13 +0200 (CEST) + // Mon, 02-Jan-06 15:04:05 MST + switch r { + case ' ', '-': + if p.dayi == 0 { + p.dayi = i + 1 + } else if p.moi == 0 { + p.daylen = i - p.dayi + p.setDay() + p.moi = i + 1 + } else if p.yeari == 0 { + p.molen = i - p.moi + p.set(p.moi, "Jan") + p.yeari = i + 1 + } else { + p.yearlen = i - p.yeari + p.setYear() + p.stateTime = timeStart + break iterRunes + } + } + + default: + break iterRunes + } + } + p.coalesceDate(i) + if p.stateTime == timeStart { + // increment first one, since the i++ occurs at end of loop + if i < len(p.datestr) { + i++ + } + // ensure we skip any whitespace prefix + for ; i < len(datestr); i++ { + r := rune(datestr[i]) + if r != ' ' { + break + } + } + + iterTimeRunes: + for ; i < len(datestr); i++ { + r := rune(datestr[i]) + + // gou.Debugf("i=%d r=%s state=%d iterTimeRunes %s %s", i, string(r), p.stateTime, p.ds(), p.ts()) + + switch p.stateTime { + case timeStart: + // 22:43:22 + // 22:43 + // timeComma + // 08:20:13,787 + // timeWs + // 05:24:37 PM + // 06:20:00 UTC + // 06:20:00 UTC-05 + // 00:12:00 +0000 UTC + // 22:18:00 +0000 UTC m=+0.000000001 + // 15:04:05 -0700 + // 15:04:05 -07:00 + // 15:04:05 2008 + // timeOffset + // 03:21:51+00:00 + // 19:55:00+0100 + // timePeriod + // 17:24:37.3186369 + // 00:07:31.945167 + // 18:31:59.257000000 + // 00:00:00.000 + // timePeriodOffset + // 19:55:00.799+0100 + // timePeriodOffsetColon + // 15:04:05.999-07:00 + // timePeriodWs + // timePeriodWsOffset + // 00:07:31.945167 +0000 + // 00:00:00.000 +0000 + // timePeriodWsOffsetAlpha + // 00:07:31.945167 +0000 UTC + // 22:18:00.001 +0000 UTC m=+0.000000001 + // 00:00:00.000 +0000 UTC + // timePeriodWsAlpha + // 06:20:00.000 UTC + if p.houri == 0 { + p.houri = i + } + switch r { + case ',': + // hm, lets just swap out comma for period. for some reason go + // won't parse it. + // 2014-05-11 08:20:13,787 + ds := []byte(p.datestr) + ds[i] = '.' + return parseTime(string(ds), loc, opts...) + case '-', '+': + // 03:21:51+00:00 + p.stateTime = timeOffset + if p.seci == 0 { + // 22:18+0530 + p.minlen = i - p.mini + } else { + if p.seclen == 0 { + p.seclen = i - p.seci + } + if p.msi > 0 && p.mslen == 0 { + p.mslen = i - p.msi + } + } + p.offseti = i + case '.': + p.stateTime = timePeriod + p.seclen = i - p.seci + p.msi = i + 1 + case 'Z': + p.stateTime = timeZ + if p.seci == 0 { + p.minlen = i - p.mini + } else { + p.seclen = i - p.seci + } + // (Z)ulu time + p.loc = time.UTC + case 'a', 'A': + if p.nextIs(i, 't') || p.nextIs(i, 'T') { + // x + // September 17, 2012 at 5:00pm UTC-05 + i++ // skip t + if p.nextIs(i, ' ') { + // x + // September 17, 2012 at 5:00pm UTC-05 + i++ // skip ' + p.houri = 0 // reset hour + } + } else { + switch { + case r == 'a' && p.nextIs(i, 'm'): + p.coalesceTime(i) + p.set(i, "am") + case r == 'A' && p.nextIs(i, 'M'): + p.coalesceTime(i) + p.set(i, "PM") + } + } + + case 'p', 'P': + // Could be AM/PM + switch { + case r == 'p' && p.nextIs(i, 'm'): + p.coalesceTime(i) + p.set(i, "pm") + case r == 'P' && p.nextIs(i, 'M'): + p.coalesceTime(i) + p.set(i, "PM") + } + case ' ': + p.coalesceTime(i) + p.stateTime = timeWs + case ':': + if p.mini == 0 { + p.mini = i + 1 + p.hourlen = i - p.houri + } else if p.seci == 0 { + p.seci = i + 1 + p.minlen = i - p.mini + } else if p.seci > 0 { + // 18:31:59:257 ms uses colon, wtf + p.seclen = i - p.seci + p.set(p.seci, "05") + p.msi = i + 1 + + // gross, gross, gross. manipulating the datestr is horrible. + // https://github.com/araddon/dateparse/issues/117 + // Could not get the parsing to work using golang time.Parse() without + // replacing that colon with period. + p.set(i, ".") + datestr = datestr[0:i] + "." + datestr[i+1:] + p.datestr = datestr + } + } + case timeOffset: + // 19:55:00+0100 + // timeOffsetColon + // 15:04:05+07:00 + // 15:04:05-07:00 + if r == ':' { + p.stateTime = timeOffsetColon + } + case timeWs: + // timeWsAlpha + // 06:20:00 UTC + // 06:20:00 UTC-05 + // 15:44:11 UTC+0100 2015 + // 18:04:07 GMT+0100 (GMT Daylight Time) + // 17:57:51 MST 2009 + // timeWsAMPMMaybe + // 05:24:37 PM + // timeWsOffset + // 15:04:05 -0700 + // 00:12:00 +0000 UTC + // timeWsOffsetColon + // 15:04:05 -07:00 + // 17:57:51 -0700 2009 + // timeWsOffsetColonAlpha + // 00:12:00 +00:00 UTC + // timeWsYear + // 00:12:00 2008 + // timeZ + // 15:04:05.99Z + switch r { + case 'A', 'P': + // Could be AM/PM or could be PST or similar + p.tzi = i + p.stateTime = timeWsAMPMMaybe + case '+', '-': + p.offseti = i + p.stateTime = timeWsOffset + default: + if unicode.IsLetter(r) { + // 06:20:00 UTC + // 06:20:00 UTC-05 + // 15:44:11 UTC+0100 2015 + // 17:57:51 MST 2009 + p.tzi = i + p.stateTime = timeWsAlpha + } else if unicode.IsDigit(r) { + // 00:12:00 2008 + p.stateTime = timeWsYear + p.yeari = i + } + } + case timeWsAlpha: + // 06:20:00 UTC + // 06:20:00 UTC-05 + // timeWsAlphaWs + // 17:57:51 MST 2009 + // timeWsAlphaZoneOffset + // timeWsAlphaZoneOffsetWs + // timeWsAlphaZoneOffsetWsExtra + // 18:04:07 GMT+0100 (GMT Daylight Time) + // timeWsAlphaZoneOffsetWsYear + // 15:44:11 UTC+0100 2015 + switch r { + case '+', '-': + p.tzlen = i - p.tzi + if p.tzlen == 4 { + p.set(p.tzi, " MST") + } else if p.tzlen == 3 { + p.set(p.tzi, "MST") + } + p.stateTime = timeWsAlphaZoneOffset + p.offseti = i + case ' ': + // 17:57:51 MST 2009 + // 17:57:51 MST + p.tzlen = i - p.tzi + if p.tzlen == 4 { + p.set(p.tzi, " MST") + } else if p.tzlen == 3 { + p.set(p.tzi, "MST") + } + p.stateTime = timeWsAlphaWs + p.yeari = i + 1 + } + case timeWsAlphaWs: + // 17:57:51 MST 2009 + + case timeWsAlphaZoneOffset: + // 06:20:00 UTC-05 + // timeWsAlphaZoneOffset + // timeWsAlphaZoneOffsetWs + // timeWsAlphaZoneOffsetWsExtra + // 18:04:07 GMT+0100 (GMT Daylight Time) + // timeWsAlphaZoneOffsetWsYear + // 15:44:11 UTC+0100 2015 + switch r { + case ' ': + p.set(p.offseti, "-0700") + if p.yeari == 0 { + p.yeari = i + 1 + } + p.stateTime = timeWsAlphaZoneOffsetWs + } + case timeWsAlphaZoneOffsetWs: + // timeWsAlphaZoneOffsetWs + // timeWsAlphaZoneOffsetWsExtra + // 18:04:07 GMT+0100 (GMT Daylight Time) + // timeWsAlphaZoneOffsetWsYear + // 15:44:11 UTC+0100 2015 + if unicode.IsDigit(r) { + p.stateTime = timeWsAlphaZoneOffsetWsYear + } else { + p.extra = i - 1 + p.stateTime = timeWsAlphaZoneOffsetWsExtra + } + case timeWsAlphaZoneOffsetWsYear: + // 15:44:11 UTC+0100 2015 + if unicode.IsDigit(r) { + p.yearlen = i - p.yeari + 1 + if p.yearlen == 4 { + p.setYear() + } + } + case timeWsAMPMMaybe: + // timeWsAMPMMaybe + // timeWsAMPM + // 05:24:37 PM + // timeWsAlpha + // 00:12:00 PST + // 15:44:11 UTC+0100 2015 + if r == 'M' { + //return parse("2006-01-02 03:04:05 PM", datestr, loc) + p.stateTime = timeWsAMPM + p.set(i-1, "PM") + if p.hourlen == 2 { + p.set(p.houri, "03") + } else if p.hourlen == 1 { + p.set(p.houri, "3") + } + } else { + p.stateTime = timeWsAlpha + } + + case timeWsOffset: + // timeWsOffset + // 15:04:05 -0700 + // timeWsOffsetWsOffset + // 17:57:51 -0700 -07 + // timeWsOffsetWs + // 17:57:51 -0700 2009 + // 00:12:00 +0000 UTC + // timeWsOffsetColon + // 15:04:05 -07:00 + // timeWsOffsetColonAlpha + // 00:12:00 +00:00 UTC + switch r { + case ':': + p.stateTime = timeWsOffsetColon + case ' ': + p.set(p.offseti, "-0700") + p.yeari = i + 1 + p.stateTime = timeWsOffsetWs + } + case timeWsOffsetWs: + // 17:57:51 -0700 2009 + // 00:12:00 +0000 UTC + // 22:18:00.001 +0000 UTC m=+0.000000001 + // w Extra + // 17:57:51 -0700 -07 + switch r { + case '=': + // eff you golang + if datestr[i-1] == 'm' { + p.extra = i - 2 + p.trimExtra() + break + } + case '+', '-', '(': + // This really doesn't seem valid, but for some reason when round-tripping a go date + // their is an extra +03 printed out. seems like go bug to me, but, parsing anyway. + // 00:00:00 +0300 +03 + // 00:00:00 +0300 +0300 + p.extra = i - 1 + p.stateTime = timeWsOffset + p.trimExtra() + break + default: + switch { + case unicode.IsDigit(r): + p.yearlen = i - p.yeari + 1 + if p.yearlen == 4 { + p.setYear() + } + case unicode.IsLetter(r): + // 15:04:05 -0700 MST + if p.tzi == 0 { + p.tzi = i + } + } + } + + case timeWsOffsetColon: + // timeWsOffsetColon + // 15:04:05 -07:00 + // timeWsOffsetColonAlpha + // 2015-02-18 00:12:00 +00:00 UTC + if unicode.IsLetter(r) { + // 2015-02-18 00:12:00 +00:00 UTC + p.stateTime = timeWsOffsetColonAlpha + break iterTimeRunes + } + case timePeriod: + // 15:04:05.999999999+07:00 + // 15:04:05.999999999-07:00 + // 15:04:05.999999+07:00 + // 15:04:05.999999-07:00 + // 15:04:05.999+07:00 + // 15:04:05.999-07:00 + // timePeriod + // 17:24:37.3186369 + // 00:07:31.945167 + // 18:31:59.257000000 + // 00:00:00.000 + // timePeriodOffset + // 19:55:00.799+0100 + // timePeriodOffsetColon + // 15:04:05.999-07:00 + // timePeriodWs + // timePeriodWsOffset + // 00:07:31.945167 +0000 + // 00:00:00.000 +0000 + // With Extra + // 00:00:00.000 +0300 +03 + // timePeriodWsOffsetAlpha + // 00:07:31.945167 +0000 UTC + // 00:00:00.000 +0000 UTC + // 22:18:00.001 +0000 UTC m=+0.000000001 + // timePeriodWsAlpha + // 06:20:00.000 UTC + switch r { + case ' ': + p.mslen = i - p.msi + p.stateTime = timePeriodWs + case '+', '-': + // This really shouldn't happen + p.mslen = i - p.msi + p.offseti = i + p.stateTime = timePeriodOffset + default: + if unicode.IsLetter(r) { + // 06:20:00.000 UTC + p.mslen = i - p.msi + p.stateTime = timePeriodWsAlpha + } + } + case timePeriodOffset: + // timePeriodOffset + // 19:55:00.799+0100 + // timePeriodOffsetColon + // 15:04:05.999-07:00 + // 13:31:51.999-07:00 MST + if r == ':' { + p.stateTime = timePeriodOffsetColon + } + case timePeriodOffsetColon: + // timePeriodOffset + // timePeriodOffsetColon + // 15:04:05.999-07:00 + // 13:31:51.999 -07:00 MST + switch r { + case ' ': + p.set(p.offseti, "-07:00") + p.stateTime = timePeriodOffsetColonWs + p.tzi = i + 1 + } + case timePeriodOffsetColonWs: + // continue + case timePeriodWs: + // timePeriodWs + // timePeriodWsOffset + // 00:07:31.945167 +0000 + // 00:00:00.000 +0000 + // timePeriodWsOffsetAlpha + // 00:07:31.945167 +0000 UTC + // 00:00:00.000 +0000 UTC + // timePeriodWsOffsetColon + // 13:31:51.999 -07:00 MST + // timePeriodWsAlpha + // 06:20:00.000 UTC + if p.offseti == 0 { + p.offseti = i + } + switch r { + case '+', '-': + p.mslen = i - p.msi - 1 + p.stateTime = timePeriodWsOffset + default: + if unicode.IsLetter(r) { + // 00:07:31.945167 +0000 UTC + // 00:00:00.000 +0000 UTC + p.stateTime = timePeriodWsOffsetWsAlpha + break iterTimeRunes + } + } + + case timePeriodWsOffset: + // timePeriodWs + // timePeriodWsOffset + // 00:07:31.945167 +0000 + // 00:00:00.000 +0000 + // With Extra + // 00:00:00.000 +0300 +03 + // timePeriodWsOffsetAlpha + // 00:07:31.945167 +0000 UTC + // 00:00:00.000 +0000 UTC + // 03:02:00.001 +0300 MSK m=+0.000000001 + // timePeriodWsOffsetColon + // 13:31:51.999 -07:00 MST + // timePeriodWsAlpha + // 06:20:00.000 UTC + switch r { + case ':': + p.stateTime = timePeriodWsOffsetColon + case ' ': + p.set(p.offseti, "-0700") + case '+', '-': + // This really doesn't seem valid, but for some reason when round-tripping a go date + // their is an extra +03 printed out. seems like go bug to me, but, parsing anyway. + // 00:00:00.000 +0300 +03 + // 00:00:00.000 +0300 +0300 + p.extra = i - 1 + p.trimExtra() + break + default: + if unicode.IsLetter(r) { + // 00:07:31.945167 +0000 UTC + // 00:00:00.000 +0000 UTC + // 03:02:00.001 +0300 MSK m=+0.000000001 + p.stateTime = timePeriodWsOffsetWsAlpha + } + } + case timePeriodWsOffsetWsAlpha: + // 03:02:00.001 +0300 MSK m=+0.000000001 + // eff you golang + if r == '=' && datestr[i-1] == 'm' { + p.extra = i - 2 + p.trimExtra() + break + } + + case timePeriodWsOffsetColon: + // 13:31:51.999 -07:00 MST + switch r { + case ' ': + p.set(p.offseti, "-07:00") + default: + if unicode.IsLetter(r) { + // 13:31:51.999 -07:00 MST + p.tzi = i + p.stateTime = timePeriodWsOffsetColonAlpha + } + } + case timePeriodWsOffsetColonAlpha: + // continue + case timeZ: + // timeZ + // 15:04:05.99Z + // With a time-zone at end after Z + // 2006-01-02T15:04:05.999999999Z07:00 + // 2006-01-02T15:04:05Z07:00 + // RFC3339 = "2006-01-02T15:04:05Z07:00" + // RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00" + if unicode.IsDigit(r) { + p.stateTime = timeZDigit + } + + } + } + + switch p.stateTime { + case timeWsAlpha: + switch len(p.datestr) - p.tzi { + case 3: + // 13:31:51.999 +01:00 CET + p.set(p.tzi, "MST") + case 4: + p.set(p.tzi, "MST") + p.extra = len(p.datestr) - 1 + p.trimExtra() + } + + case timeWsAlphaWs: + p.yearlen = i - p.yeari + p.setYear() + case timeWsYear: + p.yearlen = i - p.yeari + p.setYear() + case timeWsAlphaZoneOffsetWsExtra: + p.trimExtra() + case timeWsAlphaZoneOffset: + // 06:20:00 UTC-05 + if i-p.offseti < 4 { + p.set(p.offseti, "-07") + } else { + p.set(p.offseti, "-0700") + } + + case timePeriod: + p.mslen = i - p.msi + case timeOffset: + + switch len(p.datestr) - p.offseti { + case 0, 1, 2, 4: + return p, fmt.Errorf("TZ offset not recognized %q near %q (must be 2 or 4 digits optional colon)", datestr, string(datestr[p.offseti:])) + case 3: + // 19:55:00+01 + p.set(p.offseti, "-07") + case 5: + // 19:55:00+0100 + p.set(p.offseti, "-0700") + } + + case timeWsOffset: + p.set(p.offseti, "-0700") + case timeWsOffsetWs: + // 17:57:51 -0700 2009 + // 00:12:00 +0000 UTC + if p.tzi > 0 { + switch len(p.datestr) - p.tzi { + case 3: + // 13:31:51.999 +01:00 CET + p.set(p.tzi, "MST") + case 4: + // 13:31:51.999 +01:00 CEST + p.set(p.tzi, "MST ") + } + + } + case timeWsOffsetColon: + // 17:57:51 -07:00 + p.set(p.offseti, "-07:00") + case timeOffsetColon: + // 15:04:05+07:00 + p.set(p.offseti, "-07:00") + case timePeriodOffset: + // 19:55:00.799+0100 + p.set(p.offseti, "-0700") + case timePeriodOffsetColon: + p.set(p.offseti, "-07:00") + case timePeriodWsOffsetColonAlpha: + p.tzlen = i - p.tzi + switch p.tzlen { + case 3: + p.set(p.tzi, "MST") + case 4: + p.set(p.tzi, "MST ") + } + case timePeriodWsOffset: + p.set(p.offseti, "-0700") + } + p.coalesceTime(i) + } + + switch p.stateDate { + case dateDigit: + // unixy timestamps ish + // example ct type + // 1499979655583057426 19 nanoseconds + // 1499979795437000 16 micro-seconds + // 20180722105203 14 yyyyMMddhhmmss + // 1499979795437 13 milliseconds + // 1332151919 10 seconds + // 20140601 8 yyyymmdd + // 2014 4 yyyy + t := time.Time{} + if len(datestr) == len("1499979655583057426") { // 19 + // nano-seconds + if nanoSecs, err := strconv.ParseInt(datestr, 10, 64); err == nil { + t = time.Unix(0, nanoSecs) + } + } else if len(datestr) == len("1499979795437000") { // 16 + // micro-seconds + if microSecs, err := strconv.ParseInt(datestr, 10, 64); err == nil { + t = time.Unix(0, microSecs*1000) + } + } else if len(datestr) == len("yyyyMMddhhmmss") { // 14 + // yyyyMMddhhmmss + p.format = []byte("20060102150405") + return p, nil + } else if len(datestr) == len("1332151919000") { // 13 + if miliSecs, err := strconv.ParseInt(datestr, 10, 64); err == nil { + t = time.Unix(0, miliSecs*1000*1000) + } + } else if len(datestr) == len("1332151919") { //10 + if secs, err := strconv.ParseInt(datestr, 10, 64); err == nil { + t = time.Unix(secs, 0) + } + } else if len(datestr) == len("20140601") { + p.format = []byte("20060102") + return p, nil + } else if len(datestr) == len("2014") { + p.format = []byte("2006") + return p, nil + } else if len(datestr) < 4 { + return nil, fmt.Errorf("unrecognized format, too short %v", datestr) + } + if !t.IsZero() { + if loc == nil { + p.t = &t + return p, nil + } + t = t.In(loc) + p.t = &t + return p, nil + } + case dateDigitSt: + // 171113 14:14:20 + return p, nil + + case dateYearDash: + // 2006-01 + return p, nil + + case dateYearDashDash: + // 2006-01-02 + // 2006-1-02 + // 2006-1-2 + // 2006-01-2 + return p, nil + + case dateYearDashDashOffset: + /// 2020-07-20+00:00 + switch len(p.datestr) - p.offseti { + case 5: + p.set(p.offseti, "-0700") + case 6: + p.set(p.offseti, "-07:00") + } + return p, nil + + case dateYearDashAlphaDash: + // 2013-Feb-03 + // 2013-Feb-3 + p.daylen = i - p.dayi + p.setDay() + return p, nil + + case dateYearDashDashWs: + // 2013-04-01 + return p, nil + + case dateYearDashDashT: + return p, nil + + case dateDigitDashAlphaDash: + // 13-Feb-03 ambiguous + // 28-Feb-03 ambiguous + // 29-Jun-2016 + length := len(datestr) - (p.moi + p.molen + 1) + if length == 4 { + p.yearlen = 4 + p.set(p.yeari, "2006") + // We now also know that part1 was the day + p.dayi = 0 + p.daylen = p.part1Len + p.setDay() + } else if length == 2 { + // We have no idea if this is + // yy-mon-dd OR dd-mon-yy + // + // We are going to ASSUME (bad, bad) that it is dd-mon-yy which is a horible assumption + p.ambiguousMD = true + p.yearlen = 2 + p.set(p.yeari, "06") + // We now also know that part1 was the day + p.dayi = 0 + p.daylen = p.part1Len + p.setDay() + } + + return p, nil + + case dateDigitDot: + // 2014.05 + p.molen = i - p.moi + p.setMonth() + return p, nil + + case dateDigitDotDot: + // 03.31.1981 + // 3.31.2014 + // 3.2.1981 + // 3.2.81 + // 08.21.71 + // 2018.09.30 + return p, nil + + case dateDigitWsMoYear: + // 2 Jan 2018 + // 2 Jan 18 + // 2 Jan 2018 23:59 + // 02 Jan 2018 23:59 + // 12 Feb 2006, 19:17 + return p, nil + + case dateDigitWsMolong: + // 18 January 2018 + // 8 January 2018 + if p.daylen == 2 { + p.format = []byte("02 January 2006") + return p, nil + } + p.format = []byte("2 January 2006") + return p, nil // parse("2 January 2006", datestr, loc) + + case dateAlphaWsMonth: + p.yearlen = i - p.yeari + p.setYear() + return p, nil + + case dateAlphaWsMonthMore: + return p, nil + + case dateAlphaWsDigitMoreWs: + // oct 1, 1970 + p.yearlen = i - p.yeari + p.setYear() + return p, nil + + case dateAlphaWsDigitMoreWsYear: + // May 8, 2009 5:57:51 PM + // Jun 7, 2005, 05:57:51 + return p, nil + + case dateAlphaWsAlpha: + return p, nil + + case dateAlphaWsDigit: + return p, nil + + case dateAlphaWsDigitYearmaybe: + return p, nil + + case dateDigitSlash: + // 3/1/2014 + // 10/13/2014 + // 01/02/2006 + return p, nil + + case dateDigitSlashAlpha: + // 03/Jun/2014 + return p, nil + + case dateDigitYearSlash: + // 2014/10/13 + return p, nil + + case dateDigitColon: + // 3:1:2014 + // 10:13:2014 + // 01:02:2006 + // 2014:10:13 + return p, nil + + case dateDigitChineseYear: + // dateDigitChineseYear + // 2014年04月08日 + p.format = []byte("2006年01月02日") + return p, nil + + case dateDigitChineseYearWs: + p.format = []byte("2006年01月02日 15:04:05") + return p, nil + + case dateWeekdayComma: + // Monday, 02 Jan 2006 15:04:05 -0700 + // Monday, 02 Jan 2006 15:04:05 +0100 + // Monday, 02-Jan-06 15:04:05 MST + return p, nil + + case dateWeekdayAbbrevComma: + // Mon, 02-Jan-06 15:04:05 MST + // Mon, 02 Jan 2006 15:04:05 MST + return p, nil + + } + + return nil, unknownErr(datestr) +} + +type parser struct { + loc *time.Location + preferMonthFirst bool + retryAmbiguousDateWithSwap bool + ambiguousMD bool + stateDate dateState + stateTime timeState + format []byte + datestr string + fullMonth string + skip int + extra int + part1Len int + yeari int + yearlen int + moi int + molen int + dayi int + daylen int + houri int + hourlen int + mini int + minlen int + seci int + seclen int + msi int + mslen int + offseti int + offsetlen int + tzi int + tzlen int + t *time.Time +} + +// ParserOption defines a function signature implemented by options +// Options defined like this accept the parser and operate on the data within +type ParserOption func(*parser) error + +// PreferMonthFirst is an option that allows preferMonthFirst to be changed from its default +func PreferMonthFirst(preferMonthFirst bool) ParserOption { + return func(p *parser) error { + p.preferMonthFirst = preferMonthFirst + return nil + } +} + +// RetryAmbiguousDateWithSwap is an option that allows retryAmbiguousDateWithSwap to be changed from its default +func RetryAmbiguousDateWithSwap(retryAmbiguousDateWithSwap bool) ParserOption { + return func(p *parser) error { + p.retryAmbiguousDateWithSwap = retryAmbiguousDateWithSwap + return nil + } +} + +func newParser(dateStr string, loc *time.Location, opts ...ParserOption) *parser { + p := &parser{ + stateDate: dateStart, + stateTime: timeIgnore, + datestr: dateStr, + loc: loc, + preferMonthFirst: true, + retryAmbiguousDateWithSwap: false, + } + p.format = []byte(dateStr) + + // allow the options to mutate the parser fields from their defaults + for _, option := range opts { + option(p) + } + return p +} + +func (p *parser) nextIs(i int, b byte) bool { + if len(p.datestr) > i+1 && p.datestr[i+1] == b { + return true + } + return false +} + +func (p *parser) set(start int, val string) { + if start < 0 { + return + } + if len(p.format) < start+len(val) { + return + } + for i, r := range val { + p.format[start+i] = byte(r) + } +} +func (p *parser) setMonth() { + if p.molen == 2 { + p.set(p.moi, "01") + } else if p.molen == 1 { + p.set(p.moi, "1") + } +} + +func (p *parser) setDay() { + if p.daylen == 2 { + p.set(p.dayi, "02") + } else if p.daylen == 1 { + p.set(p.dayi, "2") + } +} +func (p *parser) setYear() { + if p.yearlen == 2 { + p.set(p.yeari, "06") + } else if p.yearlen == 4 { + p.set(p.yeari, "2006") + } +} +func (p *parser) coalesceDate(end int) { + if p.yeari > 0 { + if p.yearlen == 0 { + p.yearlen = end - p.yeari + } + p.setYear() + } + if p.moi > 0 && p.molen == 0 { + p.molen = end - p.moi + p.setMonth() + } + if p.dayi > 0 && p.daylen == 0 { + p.daylen = end - p.dayi + p.setDay() + } +} +func (p *parser) ts() string { + return fmt.Sprintf("h:(%d:%d) m:(%d:%d) s:(%d:%d)", p.houri, p.hourlen, p.mini, p.minlen, p.seci, p.seclen) +} +func (p *parser) ds() string { + return fmt.Sprintf("%s d:(%d:%d) m:(%d:%d) y:(%d:%d)", p.datestr, p.dayi, p.daylen, p.moi, p.molen, p.yeari, p.yearlen) +} +func (p *parser) coalesceTime(end int) { + // 03:04:05 + // 15:04:05 + // 3:04:05 + // 3:4:5 + // 15:04:05.00 + if p.houri > 0 { + if p.hourlen == 2 { + p.set(p.houri, "15") + } else if p.hourlen == 1 { + p.set(p.houri, "3") + } + } + if p.mini > 0 { + if p.minlen == 0 { + p.minlen = end - p.mini + } + if p.minlen == 2 { + p.set(p.mini, "04") + } else { + p.set(p.mini, "4") + } + } + if p.seci > 0 { + if p.seclen == 0 { + p.seclen = end - p.seci + } + if p.seclen == 2 { + p.set(p.seci, "05") + } else { + p.set(p.seci, "5") + } + } + + if p.msi > 0 { + for i := 0; i < p.mslen; i++ { + p.format[p.msi+i] = '0' + } + } +} +func (p *parser) setFullMonth(month string) { + if p.moi == 0 { + p.format = []byte(fmt.Sprintf("%s%s", "January", p.format[len(month):])) + } +} + +func (p *parser) trimExtra() { + if p.extra > 0 && len(p.format) > p.extra { + p.format = p.format[0:p.extra] + p.datestr = p.datestr[0:p.extra] + } +} + +// func (p *parser) remove(i, length int) { +// if len(p.format) > i+length { +// //append(a[:i], a[j:]...) +// p.format = append(p.format[0:i], p.format[i+length:]...) +// } +// if len(p.datestr) > i+length { +// //append(a[:i], a[j:]...) +// p.datestr = fmt.Sprintf("%s%s", p.datestr[0:i], p.datestr[i+length:]) +// } +// } + +func (p *parser) parse() (time.Time, error) { + if p.t != nil { + return *p.t, nil + } + if len(p.fullMonth) > 0 { + p.setFullMonth(p.fullMonth) + } + if p.skip > 0 && len(p.format) > p.skip { + p.format = p.format[p.skip:] + p.datestr = p.datestr[p.skip:] + } + + if p.loc == nil { + // gou.Debugf("parse layout=%q input=%q \ntx, err := time.Parse(%q, %q)", string(p.format), p.datestr, string(p.format), p.datestr) + return time.Parse(string(p.format), p.datestr) + } + //gou.Debugf("parse layout=%q input=%q \ntx, err := time.ParseInLocation(%q, %q, %v)", string(p.format), p.datestr, string(p.format), p.datestr, p.loc) + return time.ParseInLocation(string(p.format), p.datestr, p.loc) +} +func isDay(alpha string) bool { + for _, day := range days { + if alpha == day { + return true + } + } + return false +} +func isMonthFull(alpha string) bool { + for _, month := range months { + if alpha == month { + return true + } + } + return false +} diff --git a/vendor/github.com/aws/aws-sdk-go/LICENSE.txt b/vendor/github.com/aws/aws-sdk-go/LICENSE.txt new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/aws/aws-sdk-go/NOTICE.txt b/vendor/github.com/aws/aws-sdk-go/NOTICE.txt new file mode 100644 index 0000000..899129e --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/NOTICE.txt @@ -0,0 +1,3 @@ +AWS SDK for Go +Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. +Copyright 2014-2015 Stripe, Inc. diff --git a/vendor/github.com/aws/aws-sdk-go/aws/awserr/error.go b/vendor/github.com/aws/aws-sdk-go/aws/awserr/error.go new file mode 100644 index 0000000..99849c0 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/awserr/error.go @@ -0,0 +1,164 @@ +// Package awserr represents API error interface accessors for the SDK. +package awserr + +// An Error wraps lower level errors with code, message and an original error. +// The underlying concrete error type may also satisfy other interfaces which +// can be to used to obtain more specific information about the error. +// +// Calling Error() or String() will always include the full information about +// an error based on its underlying type. +// +// Example: +// +// output, err := s3manage.Upload(svc, input, opts) +// if err != nil { +// if awsErr, ok := err.(awserr.Error); ok { +// // Get error details +// log.Println("Error:", awsErr.Code(), awsErr.Message()) +// +// // Prints out full error message, including original error if there was one. +// log.Println("Error:", awsErr.Error()) +// +// // Get original error +// if origErr := awsErr.OrigErr(); origErr != nil { +// // operate on original error. +// } +// } else { +// fmt.Println(err.Error()) +// } +// } +// +type Error interface { + // Satisfy the generic error interface. + error + + // Returns the short phrase depicting the classification of the error. + Code() string + + // Returns the error details message. + Message() string + + // Returns the original error if one was set. Nil is returned if not set. + OrigErr() error +} + +// BatchError is a batch of errors which also wraps lower level errors with +// code, message, and original errors. Calling Error() will include all errors +// that occurred in the batch. +// +// Deprecated: Replaced with BatchedErrors. Only defined for backwards +// compatibility. +type BatchError interface { + // Satisfy the generic error interface. + error + + // Returns the short phrase depicting the classification of the error. + Code() string + + // Returns the error details message. + Message() string + + // Returns the original error if one was set. Nil is returned if not set. + OrigErrs() []error +} + +// BatchedErrors is a batch of errors which also wraps lower level errors with +// code, message, and original errors. Calling Error() will include all errors +// that occurred in the batch. +// +// Replaces BatchError +type BatchedErrors interface { + // Satisfy the base Error interface. + Error + + // Returns the original error if one was set. Nil is returned if not set. + OrigErrs() []error +} + +// New returns an Error object described by the code, message, and origErr. +// +// If origErr satisfies the Error interface it will not be wrapped within a new +// Error object and will instead be returned. +func New(code, message string, origErr error) Error { + var errs []error + if origErr != nil { + errs = append(errs, origErr) + } + return newBaseError(code, message, errs) +} + +// NewBatchError returns an BatchedErrors with a collection of errors as an +// array of errors. +func NewBatchError(code, message string, errs []error) BatchedErrors { + return newBaseError(code, message, errs) +} + +// A RequestFailure is an interface to extract request failure information from +// an Error such as the request ID of the failed request returned by a service. +// RequestFailures may not always have a requestID value if the request failed +// prior to reaching the service such as a connection error. +// +// Example: +// +// output, err := s3manage.Upload(svc, input, opts) +// if err != nil { +// if reqerr, ok := err.(RequestFailure); ok { +// log.Println("Request failed", reqerr.Code(), reqerr.Message(), reqerr.RequestID()) +// } else { +// log.Println("Error:", err.Error()) +// } +// } +// +// Combined with awserr.Error: +// +// output, err := s3manage.Upload(svc, input, opts) +// if err != nil { +// if awsErr, ok := err.(awserr.Error); ok { +// // Generic AWS Error with Code, Message, and original error (if any) +// fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) +// +// if reqErr, ok := err.(awserr.RequestFailure); ok { +// // A service error occurred +// fmt.Println(reqErr.StatusCode(), reqErr.RequestID()) +// } +// } else { +// fmt.Println(err.Error()) +// } +// } +// +type RequestFailure interface { + Error + + // The status code of the HTTP response. + StatusCode() int + + // The request ID returned by the service for a request failure. This will + // be empty if no request ID is available such as the request failed due + // to a connection error. + RequestID() string +} + +// NewRequestFailure returns a wrapped error with additional information for +// request status code, and service requestID. +// +// Should be used to wrap all request which involve service requests. Even if +// the request failed without a service response, but had an HTTP status code +// that may be meaningful. +func NewRequestFailure(err Error, statusCode int, reqID string) RequestFailure { + return newRequestError(err, statusCode, reqID) +} + +// UnmarshalError provides the interface for the SDK failing to unmarshal data. +type UnmarshalError interface { + awsError + Bytes() []byte +} + +// NewUnmarshalError returns an initialized UnmarshalError error wrapper adding +// the bytes that fail to unmarshal to the error. +func NewUnmarshalError(err error, msg string, bytes []byte) UnmarshalError { + return &unmarshalError{ + awsError: New("UnmarshalError", msg, err), + bytes: bytes, + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/awserr/types.go b/vendor/github.com/aws/aws-sdk-go/aws/awserr/types.go new file mode 100644 index 0000000..9cf7eaf --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/awserr/types.go @@ -0,0 +1,221 @@ +package awserr + +import ( + "encoding/hex" + "fmt" +) + +// SprintError returns a string of the formatted error code. +// +// Both extra and origErr are optional. If they are included their lines +// will be added, but if they are not included their lines will be ignored. +func SprintError(code, message, extra string, origErr error) string { + msg := fmt.Sprintf("%s: %s", code, message) + if extra != "" { + msg = fmt.Sprintf("%s\n\t%s", msg, extra) + } + if origErr != nil { + msg = fmt.Sprintf("%s\ncaused by: %s", msg, origErr.Error()) + } + return msg +} + +// A baseError wraps the code and message which defines an error. It also +// can be used to wrap an original error object. +// +// Should be used as the root for errors satisfying the awserr.Error. Also +// for any error which does not fit into a specific error wrapper type. +type baseError struct { + // Classification of error + code string + + // Detailed information about error + message string + + // Optional original error this error is based off of. Allows building + // chained errors. + errs []error +} + +// newBaseError returns an error object for the code, message, and errors. +// +// code is a short no whitespace phrase depicting the classification of +// the error that is being created. +// +// message is the free flow string containing detailed information about the +// error. +// +// origErrs is the error objects which will be nested under the new errors to +// be returned. +func newBaseError(code, message string, origErrs []error) *baseError { + b := &baseError{ + code: code, + message: message, + errs: origErrs, + } + + return b +} + +// Error returns the string representation of the error. +// +// See ErrorWithExtra for formatting. +// +// Satisfies the error interface. +func (b baseError) Error() string { + size := len(b.errs) + if size > 0 { + return SprintError(b.code, b.message, "", errorList(b.errs)) + } + + return SprintError(b.code, b.message, "", nil) +} + +// String returns the string representation of the error. +// Alias for Error to satisfy the stringer interface. +func (b baseError) String() string { + return b.Error() +} + +// Code returns the short phrase depicting the classification of the error. +func (b baseError) Code() string { + return b.code +} + +// Message returns the error details message. +func (b baseError) Message() string { + return b.message +} + +// OrigErr returns the original error if one was set. Nil is returned if no +// error was set. This only returns the first element in the list. If the full +// list is needed, use BatchedErrors. +func (b baseError) OrigErr() error { + switch len(b.errs) { + case 0: + return nil + case 1: + return b.errs[0] + default: + if err, ok := b.errs[0].(Error); ok { + return NewBatchError(err.Code(), err.Message(), b.errs[1:]) + } + return NewBatchError("BatchedErrors", + "multiple errors occurred", b.errs) + } +} + +// OrigErrs returns the original errors if one was set. An empty slice is +// returned if no error was set. +func (b baseError) OrigErrs() []error { + return b.errs +} + +// So that the Error interface type can be included as an anonymous field +// in the requestError struct and not conflict with the error.Error() method. +type awsError Error + +// A requestError wraps a request or service error. +// +// Composed of baseError for code, message, and original error. +type requestError struct { + awsError + statusCode int + requestID string + bytes []byte +} + +// newRequestError returns a wrapped error with additional information for +// request status code, and service requestID. +// +// Should be used to wrap all request which involve service requests. Even if +// the request failed without a service response, but had an HTTP status code +// that may be meaningful. +// +// Also wraps original errors via the baseError. +func newRequestError(err Error, statusCode int, requestID string) *requestError { + return &requestError{ + awsError: err, + statusCode: statusCode, + requestID: requestID, + } +} + +// Error returns the string representation of the error. +// Satisfies the error interface. +func (r requestError) Error() string { + extra := fmt.Sprintf("status code: %d, request id: %s", + r.statusCode, r.requestID) + return SprintError(r.Code(), r.Message(), extra, r.OrigErr()) +} + +// String returns the string representation of the error. +// Alias for Error to satisfy the stringer interface. +func (r requestError) String() string { + return r.Error() +} + +// StatusCode returns the wrapped status code for the error +func (r requestError) StatusCode() int { + return r.statusCode +} + +// RequestID returns the wrapped requestID +func (r requestError) RequestID() string { + return r.requestID +} + +// OrigErrs returns the original errors if one was set. An empty slice is +// returned if no error was set. +func (r requestError) OrigErrs() []error { + if b, ok := r.awsError.(BatchedErrors); ok { + return b.OrigErrs() + } + return []error{r.OrigErr()} +} + +type unmarshalError struct { + awsError + bytes []byte +} + +// Error returns the string representation of the error. +// Satisfies the error interface. +func (e unmarshalError) Error() string { + extra := hex.Dump(e.bytes) + return SprintError(e.Code(), e.Message(), extra, e.OrigErr()) +} + +// String returns the string representation of the error. +// Alias for Error to satisfy the stringer interface. +func (e unmarshalError) String() string { + return e.Error() +} + +// Bytes returns the bytes that failed to unmarshal. +func (e unmarshalError) Bytes() []byte { + return e.bytes +} + +// An error list that satisfies the golang interface +type errorList []error + +// Error returns the string representation of the error. +// +// Satisfies the error interface. +func (e errorList) Error() string { + msg := "" + // How do we want to handle the array size being zero + if size := len(e); size > 0 { + for i := 0; i < size; i++ { + msg += e[i].Error() + // We check the next index to see if it is within the slice. + // If it is, then we append a newline. We do this, because unit tests + // could be broken with the additional '\n' + if i+1 < size { + msg += "\n" + } + } + } + return msg +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/awsutil/copy.go b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/copy.go new file mode 100644 index 0000000..1a3d106 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/copy.go @@ -0,0 +1,108 @@ +package awsutil + +import ( + "io" + "reflect" + "time" +) + +// Copy deeply copies a src structure to dst. Useful for copying request and +// response structures. +// +// Can copy between structs of different type, but will only copy fields which +// are assignable, and exist in both structs. Fields which are not assignable, +// or do not exist in both structs are ignored. +func Copy(dst, src interface{}) { + dstval := reflect.ValueOf(dst) + if !dstval.IsValid() { + panic("Copy dst cannot be nil") + } + + rcopy(dstval, reflect.ValueOf(src), true) +} + +// CopyOf returns a copy of src while also allocating the memory for dst. +// src must be a pointer type or this operation will fail. +func CopyOf(src interface{}) (dst interface{}) { + dsti := reflect.New(reflect.TypeOf(src).Elem()) + dst = dsti.Interface() + rcopy(dsti, reflect.ValueOf(src), true) + return +} + +// rcopy performs a recursive copy of values from the source to destination. +// +// root is used to skip certain aspects of the copy which are not valid +// for the root node of a object. +func rcopy(dst, src reflect.Value, root bool) { + if !src.IsValid() { + return + } + + switch src.Kind() { + case reflect.Ptr: + if _, ok := src.Interface().(io.Reader); ok { + if dst.Kind() == reflect.Ptr && dst.Elem().CanSet() { + dst.Elem().Set(src) + } else if dst.CanSet() { + dst.Set(src) + } + } else { + e := src.Type().Elem() + if dst.CanSet() && !src.IsNil() { + if _, ok := src.Interface().(*time.Time); !ok { + dst.Set(reflect.New(e)) + } else { + tempValue := reflect.New(e) + tempValue.Elem().Set(src.Elem()) + // Sets time.Time's unexported values + dst.Set(tempValue) + } + } + if src.Elem().IsValid() { + // Keep the current root state since the depth hasn't changed + rcopy(dst.Elem(), src.Elem(), root) + } + } + case reflect.Struct: + t := dst.Type() + for i := 0; i < t.NumField(); i++ { + name := t.Field(i).Name + srcVal := src.FieldByName(name) + dstVal := dst.FieldByName(name) + if srcVal.IsValid() && dstVal.CanSet() { + rcopy(dstVal, srcVal, false) + } + } + case reflect.Slice: + if src.IsNil() { + break + } + + s := reflect.MakeSlice(src.Type(), src.Len(), src.Cap()) + dst.Set(s) + for i := 0; i < src.Len(); i++ { + rcopy(dst.Index(i), src.Index(i), false) + } + case reflect.Map: + if src.IsNil() { + break + } + + s := reflect.MakeMap(src.Type()) + dst.Set(s) + for _, k := range src.MapKeys() { + v := src.MapIndex(k) + v2 := reflect.New(v.Type()).Elem() + rcopy(v2, v, false) + dst.SetMapIndex(k, v2) + } + default: + // Assign the value if possible. If its not assignable, the value would + // need to be converted and the impact of that may be unexpected, or is + // not compatible with the dst type. + if src.Type().AssignableTo(dst.Type()) { + dst.Set(src) + } + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/awsutil/equal.go b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/equal.go new file mode 100644 index 0000000..142a7a0 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/equal.go @@ -0,0 +1,27 @@ +package awsutil + +import ( + "reflect" +) + +// DeepEqual returns if the two values are deeply equal like reflect.DeepEqual. +// In addition to this, this method will also dereference the input values if +// possible so the DeepEqual performed will not fail if one parameter is a +// pointer and the other is not. +// +// DeepEqual will not perform indirection of nested values of the input parameters. +func DeepEqual(a, b interface{}) bool { + ra := reflect.Indirect(reflect.ValueOf(a)) + rb := reflect.Indirect(reflect.ValueOf(b)) + + if raValid, rbValid := ra.IsValid(), rb.IsValid(); !raValid && !rbValid { + // If the elements are both nil, and of the same type they are equal + // If they are of different types they are not equal + return reflect.TypeOf(a) == reflect.TypeOf(b) + } else if raValid != rbValid { + // Both values must be valid to be equal + return false + } + + return reflect.DeepEqual(ra.Interface(), rb.Interface()) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go new file mode 100644 index 0000000..a4eb6a7 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go @@ -0,0 +1,221 @@ +package awsutil + +import ( + "reflect" + "regexp" + "strconv" + "strings" + + "github.com/jmespath/go-jmespath" +) + +var indexRe = regexp.MustCompile(`(.+)\[(-?\d+)?\]$`) + +// rValuesAtPath returns a slice of values found in value v. The values +// in v are explored recursively so all nested values are collected. +func rValuesAtPath(v interface{}, path string, createPath, caseSensitive, nilTerm bool) []reflect.Value { + pathparts := strings.Split(path, "||") + if len(pathparts) > 1 { + for _, pathpart := range pathparts { + vals := rValuesAtPath(v, pathpart, createPath, caseSensitive, nilTerm) + if len(vals) > 0 { + return vals + } + } + return nil + } + + values := []reflect.Value{reflect.Indirect(reflect.ValueOf(v))} + components := strings.Split(path, ".") + for len(values) > 0 && len(components) > 0 { + var index *int64 + var indexStar bool + c := strings.TrimSpace(components[0]) + if c == "" { // no actual component, illegal syntax + return nil + } else if caseSensitive && c != "*" && strings.ToLower(c[0:1]) == c[0:1] { + // TODO normalize case for user + return nil // don't support unexported fields + } + + // parse this component + if m := indexRe.FindStringSubmatch(c); m != nil { + c = m[1] + if m[2] == "" { + index = nil + indexStar = true + } else { + i, _ := strconv.ParseInt(m[2], 10, 32) + index = &i + indexStar = false + } + } + + nextvals := []reflect.Value{} + for _, value := range values { + // pull component name out of struct member + if value.Kind() != reflect.Struct { + continue + } + + if c == "*" { // pull all members + for i := 0; i < value.NumField(); i++ { + if f := reflect.Indirect(value.Field(i)); f.IsValid() { + nextvals = append(nextvals, f) + } + } + continue + } + + value = value.FieldByNameFunc(func(name string) bool { + if c == name { + return true + } else if !caseSensitive && strings.EqualFold(name, c) { + return true + } + return false + }) + + if nilTerm && value.Kind() == reflect.Ptr && len(components[1:]) == 0 { + if !value.IsNil() { + value.Set(reflect.Zero(value.Type())) + } + return []reflect.Value{value} + } + + if createPath && value.Kind() == reflect.Ptr && value.IsNil() { + // TODO if the value is the terminus it should not be created + // if the value to be set to its position is nil. + value.Set(reflect.New(value.Type().Elem())) + value = value.Elem() + } else { + value = reflect.Indirect(value) + } + + if value.Kind() == reflect.Slice || value.Kind() == reflect.Map { + if !createPath && value.IsNil() { + value = reflect.ValueOf(nil) + } + } + + if value.IsValid() { + nextvals = append(nextvals, value) + } + } + values = nextvals + + if indexStar || index != nil { + nextvals = []reflect.Value{} + for _, valItem := range values { + value := reflect.Indirect(valItem) + if value.Kind() != reflect.Slice { + continue + } + + if indexStar { // grab all indices + for i := 0; i < value.Len(); i++ { + idx := reflect.Indirect(value.Index(i)) + if idx.IsValid() { + nextvals = append(nextvals, idx) + } + } + continue + } + + // pull out index + i := int(*index) + if i >= value.Len() { // check out of bounds + if createPath { + // TODO resize slice + } else { + continue + } + } else if i < 0 { // support negative indexing + i = value.Len() + i + } + value = reflect.Indirect(value.Index(i)) + + if value.Kind() == reflect.Slice || value.Kind() == reflect.Map { + if !createPath && value.IsNil() { + value = reflect.ValueOf(nil) + } + } + + if value.IsValid() { + nextvals = append(nextvals, value) + } + } + values = nextvals + } + + components = components[1:] + } + return values +} + +// ValuesAtPath returns a list of values at the case insensitive lexical +// path inside of a structure. +func ValuesAtPath(i interface{}, path string) ([]interface{}, error) { + result, err := jmespath.Search(path, i) + if err != nil { + return nil, err + } + + v := reflect.ValueOf(result) + if !v.IsValid() || (v.Kind() == reflect.Ptr && v.IsNil()) { + return nil, nil + } + if s, ok := result.([]interface{}); ok { + return s, err + } + if v.Kind() == reflect.Map && v.Len() == 0 { + return nil, nil + } + if v.Kind() == reflect.Slice { + out := make([]interface{}, v.Len()) + for i := 0; i < v.Len(); i++ { + out[i] = v.Index(i).Interface() + } + return out, nil + } + + return []interface{}{result}, nil +} + +// SetValueAtPath sets a value at the case insensitive lexical path inside +// of a structure. +func SetValueAtPath(i interface{}, path string, v interface{}) { + rvals := rValuesAtPath(i, path, true, false, v == nil) + for _, rval := range rvals { + if rval.Kind() == reflect.Ptr && rval.IsNil() { + continue + } + setValue(rval, v) + } +} + +func setValue(dstVal reflect.Value, src interface{}) { + if dstVal.Kind() == reflect.Ptr { + dstVal = reflect.Indirect(dstVal) + } + srcVal := reflect.ValueOf(src) + + if !srcVal.IsValid() { // src is literal nil + if dstVal.CanAddr() { + // Convert to pointer so that pointer's value can be nil'ed + // dstVal = dstVal.Addr() + } + dstVal.Set(reflect.Zero(dstVal.Type())) + + } else if srcVal.Kind() == reflect.Ptr { + if srcVal.IsNil() { + srcVal = reflect.Zero(dstVal.Type()) + } else { + srcVal = reflect.ValueOf(src).Elem() + } + dstVal.Set(srcVal) + } else { + dstVal.Set(srcVal) + } + +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/awsutil/prettify.go b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/prettify.go new file mode 100644 index 0000000..11d4240 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/prettify.go @@ -0,0 +1,123 @@ +package awsutil + +import ( + "bytes" + "fmt" + "io" + "reflect" + "strings" +) + +// Prettify returns the string representation of a value. +func Prettify(i interface{}) string { + var buf bytes.Buffer + prettify(reflect.ValueOf(i), 0, &buf) + return buf.String() +} + +// prettify will recursively walk value v to build a textual +// representation of the value. +func prettify(v reflect.Value, indent int, buf *bytes.Buffer) { + for v.Kind() == reflect.Ptr { + v = v.Elem() + } + + switch v.Kind() { + case reflect.Struct: + strtype := v.Type().String() + if strtype == "time.Time" { + fmt.Fprintf(buf, "%s", v.Interface()) + break + } else if strings.HasPrefix(strtype, "io.") { + buf.WriteString("") + break + } + + buf.WriteString("{\n") + + names := []string{} + for i := 0; i < v.Type().NumField(); i++ { + name := v.Type().Field(i).Name + f := v.Field(i) + if name[0:1] == strings.ToLower(name[0:1]) { + continue // ignore unexported fields + } + if (f.Kind() == reflect.Ptr || f.Kind() == reflect.Slice || f.Kind() == reflect.Map) && f.IsNil() { + continue // ignore unset fields + } + names = append(names, name) + } + + for i, n := range names { + val := v.FieldByName(n) + ft, ok := v.Type().FieldByName(n) + if !ok { + panic(fmt.Sprintf("expected to find field %v on type %v, but was not found", n, v.Type())) + } + + buf.WriteString(strings.Repeat(" ", indent+2)) + buf.WriteString(n + ": ") + + if tag := ft.Tag.Get("sensitive"); tag == "true" { + buf.WriteString("") + } else { + prettify(val, indent+2, buf) + } + + if i < len(names)-1 { + buf.WriteString(",\n") + } + } + + buf.WriteString("\n" + strings.Repeat(" ", indent) + "}") + case reflect.Slice: + strtype := v.Type().String() + if strtype == "[]uint8" { + fmt.Fprintf(buf, " len %d", v.Len()) + break + } + + nl, id, id2 := "", "", "" + if v.Len() > 3 { + nl, id, id2 = "\n", strings.Repeat(" ", indent), strings.Repeat(" ", indent+2) + } + buf.WriteString("[" + nl) + for i := 0; i < v.Len(); i++ { + buf.WriteString(id2) + prettify(v.Index(i), indent+2, buf) + + if i < v.Len()-1 { + buf.WriteString("," + nl) + } + } + + buf.WriteString(nl + id + "]") + case reflect.Map: + buf.WriteString("{\n") + + for i, k := range v.MapKeys() { + buf.WriteString(strings.Repeat(" ", indent+2)) + buf.WriteString(k.String() + ": ") + prettify(v.MapIndex(k), indent+2, buf) + + if i < v.Len()-1 { + buf.WriteString(",\n") + } + } + + buf.WriteString("\n" + strings.Repeat(" ", indent) + "}") + default: + if !v.IsValid() { + fmt.Fprint(buf, "") + return + } + format := "%v" + switch v.Interface().(type) { + case string: + format = "%q" + case io.ReadSeeker, io.Reader: + format = "buffer(%p)" + } + fmt.Fprintf(buf, format, v.Interface()) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/awsutil/string_value.go b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/string_value.go new file mode 100644 index 0000000..3f7cffd --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/string_value.go @@ -0,0 +1,90 @@ +package awsutil + +import ( + "bytes" + "fmt" + "reflect" + "strings" +) + +// StringValue returns the string representation of a value. +// +// Deprecated: Use Prettify instead. +func StringValue(i interface{}) string { + var buf bytes.Buffer + stringValue(reflect.ValueOf(i), 0, &buf) + return buf.String() +} + +func stringValue(v reflect.Value, indent int, buf *bytes.Buffer) { + for v.Kind() == reflect.Ptr { + v = v.Elem() + } + + switch v.Kind() { + case reflect.Struct: + buf.WriteString("{\n") + + for i := 0; i < v.Type().NumField(); i++ { + ft := v.Type().Field(i) + fv := v.Field(i) + + if ft.Name[0:1] == strings.ToLower(ft.Name[0:1]) { + continue // ignore unexported fields + } + if (fv.Kind() == reflect.Ptr || fv.Kind() == reflect.Slice) && fv.IsNil() { + continue // ignore unset fields + } + + buf.WriteString(strings.Repeat(" ", indent+2)) + buf.WriteString(ft.Name + ": ") + + if tag := ft.Tag.Get("sensitive"); tag == "true" { + buf.WriteString("") + } else { + stringValue(fv, indent+2, buf) + } + + buf.WriteString(",\n") + } + + buf.WriteString("\n" + strings.Repeat(" ", indent) + "}") + case reflect.Slice: + nl, id, id2 := "", "", "" + if v.Len() > 3 { + nl, id, id2 = "\n", strings.Repeat(" ", indent), strings.Repeat(" ", indent+2) + } + buf.WriteString("[" + nl) + for i := 0; i < v.Len(); i++ { + buf.WriteString(id2) + stringValue(v.Index(i), indent+2, buf) + + if i < v.Len()-1 { + buf.WriteString("," + nl) + } + } + + buf.WriteString(nl + id + "]") + case reflect.Map: + buf.WriteString("{\n") + + for i, k := range v.MapKeys() { + buf.WriteString(strings.Repeat(" ", indent+2)) + buf.WriteString(k.String() + ": ") + stringValue(v.MapIndex(k), indent+2, buf) + + if i < v.Len()-1 { + buf.WriteString(",\n") + } + } + + buf.WriteString("\n" + strings.Repeat(" ", indent) + "}") + default: + format := "%v" + switch v.Interface().(type) { + case string: + format = "%q" + } + fmt.Fprintf(buf, format, v.Interface()) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/client/client.go b/vendor/github.com/aws/aws-sdk-go/aws/client/client.go new file mode 100644 index 0000000..b147f10 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/client/client.go @@ -0,0 +1,94 @@ +package client + +import ( + "fmt" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/client/metadata" + "github.com/aws/aws-sdk-go/aws/request" +) + +// A Config provides configuration to a service client instance. +type Config struct { + Config *aws.Config + Handlers request.Handlers + PartitionID string + Endpoint string + SigningRegion string + SigningName string + ResolvedRegion string + + // States that the signing name did not come from a modeled source but + // was derived based on other data. Used by service client constructors + // to determine if the signin name can be overridden based on metadata the + // service has. + SigningNameDerived bool +} + +// ConfigProvider provides a generic way for a service client to receive +// the ClientConfig without circular dependencies. +type ConfigProvider interface { + ClientConfig(serviceName string, cfgs ...*aws.Config) Config +} + +// ConfigNoResolveEndpointProvider same as ConfigProvider except it will not +// resolve the endpoint automatically. The service client's endpoint must be +// provided via the aws.Config.Endpoint field. +type ConfigNoResolveEndpointProvider interface { + ClientConfigNoResolveEndpoint(cfgs ...*aws.Config) Config +} + +// A Client implements the base client request and response handling +// used by all service clients. +type Client struct { + request.Retryer + metadata.ClientInfo + + Config aws.Config + Handlers request.Handlers +} + +// New will return a pointer to a new initialized service client. +func New(cfg aws.Config, info metadata.ClientInfo, handlers request.Handlers, options ...func(*Client)) *Client { + svc := &Client{ + Config: cfg, + ClientInfo: info, + Handlers: handlers.Copy(), + } + + switch retryer, ok := cfg.Retryer.(request.Retryer); { + case ok: + svc.Retryer = retryer + case cfg.Retryer != nil && cfg.Logger != nil: + s := fmt.Sprintf("WARNING: %T does not implement request.Retryer; using DefaultRetryer instead", cfg.Retryer) + cfg.Logger.Log(s) + fallthrough + default: + maxRetries := aws.IntValue(cfg.MaxRetries) + if cfg.MaxRetries == nil || maxRetries == aws.UseServiceDefaultRetries { + maxRetries = DefaultRetryerMaxNumRetries + } + svc.Retryer = DefaultRetryer{NumMaxRetries: maxRetries} + } + + svc.AddDebugHandlers() + + for _, option := range options { + option(svc) + } + + return svc +} + +// NewRequest returns a new Request pointer for the service API +// operation and parameters. +func (c *Client) NewRequest(operation *request.Operation, params interface{}, data interface{}) *request.Request { + return request.New(c.Config, c.ClientInfo, c.Handlers, c.Retryer, operation, params, data) +} + +// AddDebugHandlers injects debug logging handlers into the service to log request +// debug information. +func (c *Client) AddDebugHandlers() { + c.Handlers.Send.PushFrontNamed(LogHTTPRequestHandler) + c.Handlers.Send.PushBackNamed(LogHTTPResponseHandler) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go b/vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go new file mode 100644 index 0000000..9f6af19 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go @@ -0,0 +1,177 @@ +package client + +import ( + "math" + "strconv" + "time" + + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/internal/sdkrand" +) + +// DefaultRetryer implements basic retry logic using exponential backoff for +// most services. If you want to implement custom retry logic, you can implement the +// request.Retryer interface. +// +type DefaultRetryer struct { + // Num max Retries is the number of max retries that will be performed. + // By default, this is zero. + NumMaxRetries int + + // MinRetryDelay is the minimum retry delay after which retry will be performed. + // If not set, the value is 0ns. + MinRetryDelay time.Duration + + // MinThrottleRetryDelay is the minimum retry delay when throttled. + // If not set, the value is 0ns. + MinThrottleDelay time.Duration + + // MaxRetryDelay is the maximum retry delay before which retry must be performed. + // If not set, the value is 0ns. + MaxRetryDelay time.Duration + + // MaxThrottleDelay is the maximum retry delay when throttled. + // If not set, the value is 0ns. + MaxThrottleDelay time.Duration +} + +const ( + // DefaultRetryerMaxNumRetries sets maximum number of retries + DefaultRetryerMaxNumRetries = 3 + + // DefaultRetryerMinRetryDelay sets minimum retry delay + DefaultRetryerMinRetryDelay = 30 * time.Millisecond + + // DefaultRetryerMinThrottleDelay sets minimum delay when throttled + DefaultRetryerMinThrottleDelay = 500 * time.Millisecond + + // DefaultRetryerMaxRetryDelay sets maximum retry delay + DefaultRetryerMaxRetryDelay = 300 * time.Second + + // DefaultRetryerMaxThrottleDelay sets maximum delay when throttled + DefaultRetryerMaxThrottleDelay = 300 * time.Second +) + +// MaxRetries returns the number of maximum returns the service will use to make +// an individual API request. +func (d DefaultRetryer) MaxRetries() int { + return d.NumMaxRetries +} + +// setRetryerDefaults sets the default values of the retryer if not set +func (d *DefaultRetryer) setRetryerDefaults() { + if d.MinRetryDelay == 0 { + d.MinRetryDelay = DefaultRetryerMinRetryDelay + } + if d.MaxRetryDelay == 0 { + d.MaxRetryDelay = DefaultRetryerMaxRetryDelay + } + if d.MinThrottleDelay == 0 { + d.MinThrottleDelay = DefaultRetryerMinThrottleDelay + } + if d.MaxThrottleDelay == 0 { + d.MaxThrottleDelay = DefaultRetryerMaxThrottleDelay + } +} + +// RetryRules returns the delay duration before retrying this request again +func (d DefaultRetryer) RetryRules(r *request.Request) time.Duration { + + // if number of max retries is zero, no retries will be performed. + if d.NumMaxRetries == 0 { + return 0 + } + + // Sets default value for retryer members + d.setRetryerDefaults() + + // minDelay is the minimum retryer delay + minDelay := d.MinRetryDelay + + var initialDelay time.Duration + + isThrottle := r.IsErrorThrottle() + if isThrottle { + if delay, ok := getRetryAfterDelay(r); ok { + initialDelay = delay + } + minDelay = d.MinThrottleDelay + } + + retryCount := r.RetryCount + + // maxDelay the maximum retryer delay + maxDelay := d.MaxRetryDelay + + if isThrottle { + maxDelay = d.MaxThrottleDelay + } + + var delay time.Duration + + // Logic to cap the retry count based on the minDelay provided + actualRetryCount := int(math.Log2(float64(minDelay))) + 1 + if actualRetryCount < 63-retryCount { + delay = time.Duration(1< maxDelay { + delay = getJitterDelay(maxDelay / 2) + } + } else { + delay = getJitterDelay(maxDelay / 2) + } + return delay + initialDelay +} + +// getJitterDelay returns a jittered delay for retry +func getJitterDelay(duration time.Duration) time.Duration { + return time.Duration(sdkrand.SeededRand.Int63n(int64(duration)) + int64(duration)) +} + +// ShouldRetry returns true if the request should be retried. +func (d DefaultRetryer) ShouldRetry(r *request.Request) bool { + + // ShouldRetry returns false if number of max retries is 0. + if d.NumMaxRetries == 0 { + return false + } + + // If one of the other handlers already set the retry state + // we don't want to override it based on the service's state + if r.Retryable != nil { + return *r.Retryable + } + return r.IsErrorRetryable() || r.IsErrorThrottle() +} + +// This will look in the Retry-After header, RFC 7231, for how long +// it will wait before attempting another request +func getRetryAfterDelay(r *request.Request) (time.Duration, bool) { + if !canUseRetryAfterHeader(r) { + return 0, false + } + + delayStr := r.HTTPResponse.Header.Get("Retry-After") + if len(delayStr) == 0 { + return 0, false + } + + delay, err := strconv.Atoi(delayStr) + if err != nil { + return 0, false + } + + return time.Duration(delay) * time.Second, true +} + +// Will look at the status code to see if the retry header pertains to +// the status code. +func canUseRetryAfterHeader(r *request.Request) bool { + switch r.HTTPResponse.StatusCode { + case 429: + case 503: + default: + return false + } + + return true +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/client/logger.go b/vendor/github.com/aws/aws-sdk-go/aws/client/logger.go new file mode 100644 index 0000000..5ac5c24 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/client/logger.go @@ -0,0 +1,206 @@ +package client + +import ( + "bytes" + "fmt" + "io" + "io/ioutil" + "net/http/httputil" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/request" +) + +const logReqMsg = `DEBUG: Request %s/%s Details: +---[ REQUEST POST-SIGN ]----------------------------- +%s +-----------------------------------------------------` + +const logReqErrMsg = `DEBUG ERROR: Request %s/%s: +---[ REQUEST DUMP ERROR ]----------------------------- +%s +------------------------------------------------------` + +type logWriter struct { + // Logger is what we will use to log the payload of a response. + Logger aws.Logger + // buf stores the contents of what has been read + buf *bytes.Buffer +} + +func (logger *logWriter) Write(b []byte) (int, error) { + return logger.buf.Write(b) +} + +type teeReaderCloser struct { + // io.Reader will be a tee reader that is used during logging. + // This structure will read from a body and write the contents to a logger. + io.Reader + // Source is used just to close when we are done reading. + Source io.ReadCloser +} + +func (reader *teeReaderCloser) Close() error { + return reader.Source.Close() +} + +// LogHTTPRequestHandler is a SDK request handler to log the HTTP request sent +// to a service. Will include the HTTP request body if the LogLevel of the +// request matches LogDebugWithHTTPBody. +var LogHTTPRequestHandler = request.NamedHandler{ + Name: "awssdk.client.LogRequest", + Fn: logRequest, +} + +func logRequest(r *request.Request) { + if !r.Config.LogLevel.AtLeast(aws.LogDebug) || r.Config.Logger == nil { + return + } + + logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody) + bodySeekable := aws.IsReaderSeekable(r.Body) + + b, err := httputil.DumpRequestOut(r.HTTPRequest, logBody) + if err != nil { + r.Config.Logger.Log(fmt.Sprintf(logReqErrMsg, + r.ClientInfo.ServiceName, r.Operation.Name, err)) + return + } + + if logBody { + if !bodySeekable { + r.SetReaderBody(aws.ReadSeekCloser(r.HTTPRequest.Body)) + } + // Reset the request body because dumpRequest will re-wrap the + // r.HTTPRequest's Body as a NoOpCloser and will not be reset after + // read by the HTTP client reader. + if err := r.Error; err != nil { + r.Config.Logger.Log(fmt.Sprintf(logReqErrMsg, + r.ClientInfo.ServiceName, r.Operation.Name, err)) + return + } + } + + r.Config.Logger.Log(fmt.Sprintf(logReqMsg, + r.ClientInfo.ServiceName, r.Operation.Name, string(b))) +} + +// LogHTTPRequestHeaderHandler is a SDK request handler to log the HTTP request sent +// to a service. Will only log the HTTP request's headers. The request payload +// will not be read. +var LogHTTPRequestHeaderHandler = request.NamedHandler{ + Name: "awssdk.client.LogRequestHeader", + Fn: logRequestHeader, +} + +func logRequestHeader(r *request.Request) { + if !r.Config.LogLevel.AtLeast(aws.LogDebug) || r.Config.Logger == nil { + return + } + + b, err := httputil.DumpRequestOut(r.HTTPRequest, false) + if err != nil { + r.Config.Logger.Log(fmt.Sprintf(logReqErrMsg, + r.ClientInfo.ServiceName, r.Operation.Name, err)) + return + } + + r.Config.Logger.Log(fmt.Sprintf(logReqMsg, + r.ClientInfo.ServiceName, r.Operation.Name, string(b))) +} + +const logRespMsg = `DEBUG: Response %s/%s Details: +---[ RESPONSE ]-------------------------------------- +%s +-----------------------------------------------------` + +const logRespErrMsg = `DEBUG ERROR: Response %s/%s: +---[ RESPONSE DUMP ERROR ]----------------------------- +%s +-----------------------------------------------------` + +// LogHTTPResponseHandler is a SDK request handler to log the HTTP response +// received from a service. Will include the HTTP response body if the LogLevel +// of the request matches LogDebugWithHTTPBody. +var LogHTTPResponseHandler = request.NamedHandler{ + Name: "awssdk.client.LogResponse", + Fn: logResponse, +} + +func logResponse(r *request.Request) { + if !r.Config.LogLevel.AtLeast(aws.LogDebug) || r.Config.Logger == nil { + return + } + + lw := &logWriter{r.Config.Logger, bytes.NewBuffer(nil)} + + if r.HTTPResponse == nil { + lw.Logger.Log(fmt.Sprintf(logRespErrMsg, + r.ClientInfo.ServiceName, r.Operation.Name, "request's HTTPResponse is nil")) + return + } + + logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody) + if logBody { + r.HTTPResponse.Body = &teeReaderCloser{ + Reader: io.TeeReader(r.HTTPResponse.Body, lw), + Source: r.HTTPResponse.Body, + } + } + + handlerFn := func(req *request.Request) { + b, err := httputil.DumpResponse(req.HTTPResponse, false) + if err != nil { + lw.Logger.Log(fmt.Sprintf(logRespErrMsg, + req.ClientInfo.ServiceName, req.Operation.Name, err)) + return + } + + lw.Logger.Log(fmt.Sprintf(logRespMsg, + req.ClientInfo.ServiceName, req.Operation.Name, string(b))) + + if logBody { + b, err := ioutil.ReadAll(lw.buf) + if err != nil { + lw.Logger.Log(fmt.Sprintf(logRespErrMsg, + req.ClientInfo.ServiceName, req.Operation.Name, err)) + return + } + + lw.Logger.Log(string(b)) + } + } + + const handlerName = "awsdk.client.LogResponse.ResponseBody" + + r.Handlers.Unmarshal.SetBackNamed(request.NamedHandler{ + Name: handlerName, Fn: handlerFn, + }) + r.Handlers.UnmarshalError.SetBackNamed(request.NamedHandler{ + Name: handlerName, Fn: handlerFn, + }) +} + +// LogHTTPResponseHeaderHandler is a SDK request handler to log the HTTP +// response received from a service. Will only log the HTTP response's headers. +// The response payload will not be read. +var LogHTTPResponseHeaderHandler = request.NamedHandler{ + Name: "awssdk.client.LogResponseHeader", + Fn: logResponseHeader, +} + +func logResponseHeader(r *request.Request) { + if !r.Config.LogLevel.AtLeast(aws.LogDebug) || r.Config.Logger == nil { + return + } + + b, err := httputil.DumpResponse(r.HTTPResponse, false) + if err != nil { + r.Config.Logger.Log(fmt.Sprintf(logRespErrMsg, + r.ClientInfo.ServiceName, r.Operation.Name, err)) + return + } + + r.Config.Logger.Log(fmt.Sprintf(logRespMsg, + r.ClientInfo.ServiceName, r.Operation.Name, string(b))) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/client/metadata/client_info.go b/vendor/github.com/aws/aws-sdk-go/aws/client/metadata/client_info.go new file mode 100644 index 0000000..a7530eb --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/client/metadata/client_info.go @@ -0,0 +1,15 @@ +package metadata + +// ClientInfo wraps immutable data from the client.Client structure. +type ClientInfo struct { + ServiceName string + ServiceID string + APIVersion string + PartitionID string + Endpoint string + SigningName string + SigningRegion string + JSONVersion string + TargetPrefix string + ResolvedRegion string +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/client/no_op_retryer.go b/vendor/github.com/aws/aws-sdk-go/aws/client/no_op_retryer.go new file mode 100644 index 0000000..881d575 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/client/no_op_retryer.go @@ -0,0 +1,28 @@ +package client + +import ( + "time" + + "github.com/aws/aws-sdk-go/aws/request" +) + +// NoOpRetryer provides a retryer that performs no retries. +// It should be used when we do not want retries to be performed. +type NoOpRetryer struct{} + +// MaxRetries returns the number of maximum returns the service will use to make +// an individual API; For NoOpRetryer the MaxRetries will always be zero. +func (d NoOpRetryer) MaxRetries() int { + return 0 +} + +// ShouldRetry will always return false for NoOpRetryer, as it should never retry. +func (d NoOpRetryer) ShouldRetry(_ *request.Request) bool { + return false +} + +// RetryRules returns the delay duration before retrying this request again; +// since NoOpRetryer does not retry, RetryRules always returns 0. +func (d NoOpRetryer) RetryRules(_ *request.Request) time.Duration { + return 0 +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/config.go b/vendor/github.com/aws/aws-sdk-go/aws/config.go new file mode 100644 index 0000000..79f18fb --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/config.go @@ -0,0 +1,628 @@ +package aws + +import ( + "net/http" + "time" + + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/endpoints" +) + +// UseServiceDefaultRetries instructs the config to use the service's own +// default number of retries. This will be the default action if +// Config.MaxRetries is nil also. +const UseServiceDefaultRetries = -1 + +// RequestRetryer is an alias for a type that implements the request.Retryer +// interface. +type RequestRetryer interface{} + +// A Config provides service configuration for service clients. By default, +// all clients will use the defaults.DefaultConfig structure. +// +// // Create Session with MaxRetries configuration to be shared by multiple +// // service clients. +// sess := session.Must(session.NewSession(&aws.Config{ +// MaxRetries: aws.Int(3), +// })) +// +// // Create S3 service client with a specific Region. +// svc := s3.New(sess, &aws.Config{ +// Region: aws.String("us-west-2"), +// }) +type Config struct { + // Enables verbose error printing of all credential chain errors. + // Should be used when wanting to see all errors while attempting to + // retrieve credentials. + CredentialsChainVerboseErrors *bool + + // The credentials object to use when signing requests. Defaults to a + // chain of credential providers to search for credentials in environment + // variables, shared credential file, and EC2 Instance Roles. + Credentials *credentials.Credentials + + // An optional endpoint URL (hostname only or fully qualified URI) + // that overrides the default generated endpoint for a client. Set this + // to `nil` or the value to `""` to use the default generated endpoint. + // + // Note: You must still provide a `Region` value when specifying an + // endpoint for a client. + Endpoint *string + + // The resolver to use for looking up endpoints for AWS service clients + // to use based on region. + EndpointResolver endpoints.Resolver + + // EnforceShouldRetryCheck is used in the AfterRetryHandler to always call + // ShouldRetry regardless of whether or not if request.Retryable is set. + // This will utilize ShouldRetry method of custom retryers. If EnforceShouldRetryCheck + // is not set, then ShouldRetry will only be called if request.Retryable is nil. + // Proper handling of the request.Retryable field is important when setting this field. + EnforceShouldRetryCheck *bool + + // The region to send requests to. This parameter is required and must + // be configured globally or on a per-client basis unless otherwise + // noted. A full list of regions is found in the "Regions and Endpoints" + // document. + // + // See http://docs.aws.amazon.com/general/latest/gr/rande.html for AWS + // Regions and Endpoints. + Region *string + + // Set this to `true` to disable SSL when sending requests. Defaults + // to `false`. + DisableSSL *bool + + // The HTTP client to use when sending requests. Defaults to + // `http.DefaultClient`. + HTTPClient *http.Client + + // An integer value representing the logging level. The default log level + // is zero (LogOff), which represents no logging. To enable logging set + // to a LogLevel Value. + LogLevel *LogLevelType + + // The logger writer interface to write logging messages to. Defaults to + // standard out. + Logger Logger + + // The maximum number of times that a request will be retried for failures. + // Defaults to -1, which defers the max retry setting to the service + // specific configuration. + MaxRetries *int + + // Retryer guides how HTTP requests should be retried in case of + // recoverable failures. + // + // When nil or the value does not implement the request.Retryer interface, + // the client.DefaultRetryer will be used. + // + // When both Retryer and MaxRetries are non-nil, the former is used and + // the latter ignored. + // + // To set the Retryer field in a type-safe manner and with chaining, use + // the request.WithRetryer helper function: + // + // cfg := request.WithRetryer(aws.NewConfig(), myRetryer) + // + Retryer RequestRetryer + + // Disables semantic parameter validation, which validates input for + // missing required fields and/or other semantic request input errors. + DisableParamValidation *bool + + // Disables the computation of request and response checksums, e.g., + // CRC32 checksums in Amazon DynamoDB. + DisableComputeChecksums *bool + + // Set this to `true` to force the request to use path-style addressing, + // i.e., `http://s3.amazonaws.com/BUCKET/KEY`. By default, the S3 client + // will use virtual hosted bucket addressing when possible + // (`http://BUCKET.s3.amazonaws.com/KEY`). + // + // Note: This configuration option is specific to the Amazon S3 service. + // + // See http://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html + // for Amazon S3: Virtual Hosting of Buckets + S3ForcePathStyle *bool + + // Set this to `true` to disable the SDK adding the `Expect: 100-Continue` + // header to PUT requests over 2MB of content. 100-Continue instructs the + // HTTP client not to send the body until the service responds with a + // `continue` status. This is useful to prevent sending the request body + // until after the request is authenticated, and validated. + // + // http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html + // + // 100-Continue is only enabled for Go 1.6 and above. See `http.Transport`'s + // `ExpectContinueTimeout` for information on adjusting the continue wait + // timeout. https://golang.org/pkg/net/http/#Transport + // + // You should use this flag to disable 100-Continue if you experience issues + // with proxies or third party S3 compatible services. + S3Disable100Continue *bool + + // Set this to `true` to enable S3 Accelerate feature. For all operations + // compatible with S3 Accelerate will use the accelerate endpoint for + // requests. Requests not compatible will fall back to normal S3 requests. + // + // The bucket must be enable for accelerate to be used with S3 client with + // accelerate enabled. If the bucket is not enabled for accelerate an error + // will be returned. The bucket name must be DNS compatible to also work + // with accelerate. + S3UseAccelerate *bool + + // S3DisableContentMD5Validation config option is temporarily disabled, + // For S3 GetObject API calls, #1837. + // + // Set this to `true` to disable the S3 service client from automatically + // adding the ContentMD5 to S3 Object Put and Upload API calls. This option + // will also disable the SDK from performing object ContentMD5 validation + // on GetObject API calls. + S3DisableContentMD5Validation *bool + + // Set this to `true` to have the S3 service client to use the region specified + // in the ARN, when an ARN is provided as an argument to a bucket parameter. + S3UseARNRegion *bool + + // Set this to `true` to enable the SDK to unmarshal API response header maps to + // normalized lower case map keys. + // + // For example S3's X-Amz-Meta prefixed header will be unmarshaled to lower case + // Metadata member's map keys. The value of the header in the map is unaffected. + LowerCaseHeaderMaps *bool + + // Set this to `true` to disable the EC2Metadata client from overriding the + // default http.Client's Timeout. This is helpful if you do not want the + // EC2Metadata client to create a new http.Client. This options is only + // meaningful if you're not already using a custom HTTP client with the + // SDK. Enabled by default. + // + // Must be set and provided to the session.NewSession() in order to disable + // the EC2Metadata overriding the timeout for default credentials chain. + // + // Example: + // sess := session.Must(session.NewSession(aws.NewConfig() + // .WithEC2MetadataDisableTimeoutOverride(true))) + // + // svc := s3.New(sess) + // + EC2MetadataDisableTimeoutOverride *bool + + // Instructs the endpoint to be generated for a service client to + // be the dual stack endpoint. The dual stack endpoint will support + // both IPv4 and IPv6 addressing. + // + // Setting this for a service which does not support dual stack will fail + // to make requests. It is not recommended to set this value on the session + // as it will apply to all service clients created with the session. Even + // services which don't support dual stack endpoints. + // + // If the Endpoint config value is also provided the UseDualStack flag + // will be ignored. + // + // Only supported with. + // + // sess := session.Must(session.NewSession()) + // + // svc := s3.New(sess, &aws.Config{ + // UseDualStack: aws.Bool(true), + // }) + // + // Deprecated: This option will continue to function for S3 and S3 Control for backwards compatibility. + // UseDualStackEndpoint should be used to enable usage of a service's dual-stack endpoint for all service clients + // moving forward. For S3 and S3 Control, when UseDualStackEndpoint is set to a non-zero value it takes higher + // precedence then this option. + UseDualStack *bool + + // Sets the resolver to resolve a dual-stack endpoint for the service. + UseDualStackEndpoint endpoints.DualStackEndpointState + + // UseFIPSEndpoint specifies the resolver must resolve a FIPS endpoint. + UseFIPSEndpoint endpoints.FIPSEndpointState + + // SleepDelay is an override for the func the SDK will call when sleeping + // during the lifecycle of a request. Specifically this will be used for + // request delays. This value should only be used for testing. To adjust + // the delay of a request see the aws/client.DefaultRetryer and + // aws/request.Retryer. + // + // SleepDelay will prevent any Context from being used for canceling retry + // delay of an API operation. It is recommended to not use SleepDelay at all + // and specify a Retryer instead. + SleepDelay func(time.Duration) + + // DisableRestProtocolURICleaning will not clean the URL path when making rest protocol requests. + // Will default to false. This would only be used for empty directory names in s3 requests. + // + // Example: + // sess := session.Must(session.NewSession(&aws.Config{ + // DisableRestProtocolURICleaning: aws.Bool(true), + // })) + // + // svc := s3.New(sess) + // out, err := svc.GetObject(&s3.GetObjectInput { + // Bucket: aws.String("bucketname"), + // Key: aws.String("//foo//bar//moo"), + // }) + DisableRestProtocolURICleaning *bool + + // EnableEndpointDiscovery will allow for endpoint discovery on operations that + // have the definition in its model. By default, endpoint discovery is off. + // To use EndpointDiscovery, Endpoint should be unset or set to an empty string. + // + // Example: + // sess := session.Must(session.NewSession(&aws.Config{ + // EnableEndpointDiscovery: aws.Bool(true), + // })) + // + // svc := s3.New(sess) + // out, err := svc.GetObject(&s3.GetObjectInput { + // Bucket: aws.String("bucketname"), + // Key: aws.String("/foo/bar/moo"), + // }) + EnableEndpointDiscovery *bool + + // DisableEndpointHostPrefix will disable the SDK's behavior of prefixing + // request endpoint hosts with modeled information. + // + // Disabling this feature is useful when you want to use local endpoints + // for testing that do not support the modeled host prefix pattern. + DisableEndpointHostPrefix *bool + + // STSRegionalEndpoint will enable regional or legacy endpoint resolving + STSRegionalEndpoint endpoints.STSRegionalEndpoint + + // S3UsEast1RegionalEndpoint will enable regional or legacy endpoint resolving + S3UsEast1RegionalEndpoint endpoints.S3UsEast1RegionalEndpoint +} + +// NewConfig returns a new Config pointer that can be chained with builder +// methods to set multiple configuration values inline without using pointers. +// +// // Create Session with MaxRetries configuration to be shared by multiple +// // service clients. +// sess := session.Must(session.NewSession(aws.NewConfig(). +// WithMaxRetries(3), +// )) +// +// // Create S3 service client with a specific Region. +// svc := s3.New(sess, aws.NewConfig(). +// WithRegion("us-west-2"), +// ) +func NewConfig() *Config { + return &Config{} +} + +// WithCredentialsChainVerboseErrors sets a config verbose errors boolean and returning +// a Config pointer. +func (c *Config) WithCredentialsChainVerboseErrors(verboseErrs bool) *Config { + c.CredentialsChainVerboseErrors = &verboseErrs + return c +} + +// WithCredentials sets a config Credentials value returning a Config pointer +// for chaining. +func (c *Config) WithCredentials(creds *credentials.Credentials) *Config { + c.Credentials = creds + return c +} + +// WithEndpoint sets a config Endpoint value returning a Config pointer for +// chaining. +func (c *Config) WithEndpoint(endpoint string) *Config { + c.Endpoint = &endpoint + return c +} + +// WithEndpointResolver sets a config EndpointResolver value returning a +// Config pointer for chaining. +func (c *Config) WithEndpointResolver(resolver endpoints.Resolver) *Config { + c.EndpointResolver = resolver + return c +} + +// WithRegion sets a config Region value returning a Config pointer for +// chaining. +func (c *Config) WithRegion(region string) *Config { + c.Region = ®ion + return c +} + +// WithDisableSSL sets a config DisableSSL value returning a Config pointer +// for chaining. +func (c *Config) WithDisableSSL(disable bool) *Config { + c.DisableSSL = &disable + return c +} + +// WithHTTPClient sets a config HTTPClient value returning a Config pointer +// for chaining. +func (c *Config) WithHTTPClient(client *http.Client) *Config { + c.HTTPClient = client + return c +} + +// WithMaxRetries sets a config MaxRetries value returning a Config pointer +// for chaining. +func (c *Config) WithMaxRetries(max int) *Config { + c.MaxRetries = &max + return c +} + +// WithDisableParamValidation sets a config DisableParamValidation value +// returning a Config pointer for chaining. +func (c *Config) WithDisableParamValidation(disable bool) *Config { + c.DisableParamValidation = &disable + return c +} + +// WithDisableComputeChecksums sets a config DisableComputeChecksums value +// returning a Config pointer for chaining. +func (c *Config) WithDisableComputeChecksums(disable bool) *Config { + c.DisableComputeChecksums = &disable + return c +} + +// WithLogLevel sets a config LogLevel value returning a Config pointer for +// chaining. +func (c *Config) WithLogLevel(level LogLevelType) *Config { + c.LogLevel = &level + return c +} + +// WithLogger sets a config Logger value returning a Config pointer for +// chaining. +func (c *Config) WithLogger(logger Logger) *Config { + c.Logger = logger + return c +} + +// WithS3ForcePathStyle sets a config S3ForcePathStyle value returning a Config +// pointer for chaining. +func (c *Config) WithS3ForcePathStyle(force bool) *Config { + c.S3ForcePathStyle = &force + return c +} + +// WithS3Disable100Continue sets a config S3Disable100Continue value returning +// a Config pointer for chaining. +func (c *Config) WithS3Disable100Continue(disable bool) *Config { + c.S3Disable100Continue = &disable + return c +} + +// WithS3UseAccelerate sets a config S3UseAccelerate value returning a Config +// pointer for chaining. +func (c *Config) WithS3UseAccelerate(enable bool) *Config { + c.S3UseAccelerate = &enable + return c + +} + +// WithS3DisableContentMD5Validation sets a config +// S3DisableContentMD5Validation value returning a Config pointer for chaining. +func (c *Config) WithS3DisableContentMD5Validation(enable bool) *Config { + c.S3DisableContentMD5Validation = &enable + return c + +} + +// WithS3UseARNRegion sets a config S3UseARNRegion value and +// returning a Config pointer for chaining +func (c *Config) WithS3UseARNRegion(enable bool) *Config { + c.S3UseARNRegion = &enable + return c +} + +// WithUseDualStack sets a config UseDualStack value returning a Config +// pointer for chaining. +func (c *Config) WithUseDualStack(enable bool) *Config { + c.UseDualStack = &enable + return c +} + +// WithEC2MetadataDisableTimeoutOverride sets a config EC2MetadataDisableTimeoutOverride value +// returning a Config pointer for chaining. +func (c *Config) WithEC2MetadataDisableTimeoutOverride(enable bool) *Config { + c.EC2MetadataDisableTimeoutOverride = &enable + return c +} + +// WithSleepDelay overrides the function used to sleep while waiting for the +// next retry. Defaults to time.Sleep. +func (c *Config) WithSleepDelay(fn func(time.Duration)) *Config { + c.SleepDelay = fn + return c +} + +// WithEndpointDiscovery will set whether or not to use endpoint discovery. +func (c *Config) WithEndpointDiscovery(t bool) *Config { + c.EnableEndpointDiscovery = &t + return c +} + +// WithDisableEndpointHostPrefix will set whether or not to use modeled host prefix +// when making requests. +func (c *Config) WithDisableEndpointHostPrefix(t bool) *Config { + c.DisableEndpointHostPrefix = &t + return c +} + +// WithSTSRegionalEndpoint will set whether or not to use regional endpoint flag +// when resolving the endpoint for a service +func (c *Config) WithSTSRegionalEndpoint(sre endpoints.STSRegionalEndpoint) *Config { + c.STSRegionalEndpoint = sre + return c +} + +// WithS3UsEast1RegionalEndpoint will set whether or not to use regional endpoint flag +// when resolving the endpoint for a service +func (c *Config) WithS3UsEast1RegionalEndpoint(sre endpoints.S3UsEast1RegionalEndpoint) *Config { + c.S3UsEast1RegionalEndpoint = sre + return c +} + +// WithLowerCaseHeaderMaps sets a config LowerCaseHeaderMaps value +// returning a Config pointer for chaining. +func (c *Config) WithLowerCaseHeaderMaps(t bool) *Config { + c.LowerCaseHeaderMaps = &t + return c +} + +// WithDisableRestProtocolURICleaning sets a config DisableRestProtocolURICleaning value +// returning a Config pointer for chaining. +func (c *Config) WithDisableRestProtocolURICleaning(t bool) *Config { + c.DisableRestProtocolURICleaning = &t + return c +} + +// MergeIn merges the passed in configs into the existing config object. +func (c *Config) MergeIn(cfgs ...*Config) { + for _, other := range cfgs { + mergeInConfig(c, other) + } +} + +func mergeInConfig(dst *Config, other *Config) { + if other == nil { + return + } + + if other.CredentialsChainVerboseErrors != nil { + dst.CredentialsChainVerboseErrors = other.CredentialsChainVerboseErrors + } + + if other.Credentials != nil { + dst.Credentials = other.Credentials + } + + if other.Endpoint != nil { + dst.Endpoint = other.Endpoint + } + + if other.EndpointResolver != nil { + dst.EndpointResolver = other.EndpointResolver + } + + if other.Region != nil { + dst.Region = other.Region + } + + if other.DisableSSL != nil { + dst.DisableSSL = other.DisableSSL + } + + if other.HTTPClient != nil { + dst.HTTPClient = other.HTTPClient + } + + if other.LogLevel != nil { + dst.LogLevel = other.LogLevel + } + + if other.Logger != nil { + dst.Logger = other.Logger + } + + if other.MaxRetries != nil { + dst.MaxRetries = other.MaxRetries + } + + if other.Retryer != nil { + dst.Retryer = other.Retryer + } + + if other.DisableParamValidation != nil { + dst.DisableParamValidation = other.DisableParamValidation + } + + if other.DisableComputeChecksums != nil { + dst.DisableComputeChecksums = other.DisableComputeChecksums + } + + if other.S3ForcePathStyle != nil { + dst.S3ForcePathStyle = other.S3ForcePathStyle + } + + if other.S3Disable100Continue != nil { + dst.S3Disable100Continue = other.S3Disable100Continue + } + + if other.S3UseAccelerate != nil { + dst.S3UseAccelerate = other.S3UseAccelerate + } + + if other.S3DisableContentMD5Validation != nil { + dst.S3DisableContentMD5Validation = other.S3DisableContentMD5Validation + } + + if other.S3UseARNRegion != nil { + dst.S3UseARNRegion = other.S3UseARNRegion + } + + if other.UseDualStack != nil { + dst.UseDualStack = other.UseDualStack + } + + if other.UseDualStackEndpoint != endpoints.DualStackEndpointStateUnset { + dst.UseDualStackEndpoint = other.UseDualStackEndpoint + } + + if other.EC2MetadataDisableTimeoutOverride != nil { + dst.EC2MetadataDisableTimeoutOverride = other.EC2MetadataDisableTimeoutOverride + } + + if other.SleepDelay != nil { + dst.SleepDelay = other.SleepDelay + } + + if other.DisableRestProtocolURICleaning != nil { + dst.DisableRestProtocolURICleaning = other.DisableRestProtocolURICleaning + } + + if other.EnforceShouldRetryCheck != nil { + dst.EnforceShouldRetryCheck = other.EnforceShouldRetryCheck + } + + if other.EnableEndpointDiscovery != nil { + dst.EnableEndpointDiscovery = other.EnableEndpointDiscovery + } + + if other.DisableEndpointHostPrefix != nil { + dst.DisableEndpointHostPrefix = other.DisableEndpointHostPrefix + } + + if other.STSRegionalEndpoint != endpoints.UnsetSTSEndpoint { + dst.STSRegionalEndpoint = other.STSRegionalEndpoint + } + + if other.S3UsEast1RegionalEndpoint != endpoints.UnsetS3UsEast1Endpoint { + dst.S3UsEast1RegionalEndpoint = other.S3UsEast1RegionalEndpoint + } + + if other.LowerCaseHeaderMaps != nil { + dst.LowerCaseHeaderMaps = other.LowerCaseHeaderMaps + } + + if other.UseDualStackEndpoint != endpoints.DualStackEndpointStateUnset { + dst.UseDualStackEndpoint = other.UseDualStackEndpoint + } + + if other.UseFIPSEndpoint != endpoints.FIPSEndpointStateUnset { + dst.UseFIPSEndpoint = other.UseFIPSEndpoint + } +} + +// Copy will return a shallow copy of the Config object. If any additional +// configurations are provided they will be merged into the new config returned. +func (c *Config) Copy(cfgs ...*Config) *Config { + dst := &Config{} + dst.MergeIn(c) + + for _, cfg := range cfgs { + dst.MergeIn(cfg) + } + + return dst +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/context_1_5.go b/vendor/github.com/aws/aws-sdk-go/aws/context_1_5.go new file mode 100644 index 0000000..89aad2c --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/context_1_5.go @@ -0,0 +1,38 @@ +//go:build !go1.9 +// +build !go1.9 + +package aws + +import "time" + +// Context is an copy of the Go v1.7 stdlib's context.Context interface. +// It is represented as a SDK interface to enable you to use the "WithContext" +// API methods with Go v1.6 and a Context type such as golang.org/x/net/context. +// +// See https://golang.org/pkg/context on how to use contexts. +type Context interface { + // Deadline returns the time when work done on behalf of this context + // should be canceled. Deadline returns ok==false when no deadline is + // set. Successive calls to Deadline return the same results. + Deadline() (deadline time.Time, ok bool) + + // Done returns a channel that's closed when work done on behalf of this + // context should be canceled. Done may return nil if this context can + // never be canceled. Successive calls to Done return the same value. + Done() <-chan struct{} + + // Err returns a non-nil error value after Done is closed. Err returns + // Canceled if the context was canceled or DeadlineExceeded if the + // context's deadline passed. No other values for Err are defined. + // After Done is closed, successive calls to Err return the same value. + Err() error + + // Value returns the value associated with this context for key, or nil + // if no value is associated with key. Successive calls to Value with + // the same key returns the same result. + // + // Use context values only for request-scoped data that transits + // processes and API boundaries, not for passing optional parameters to + // functions. + Value(key interface{}) interface{} +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/context_1_9.go b/vendor/github.com/aws/aws-sdk-go/aws/context_1_9.go new file mode 100644 index 0000000..6ee9ddd --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/context_1_9.go @@ -0,0 +1,12 @@ +//go:build go1.9 +// +build go1.9 + +package aws + +import "context" + +// Context is an alias of the Go stdlib's context.Context interface. +// It can be used within the SDK's API operation "WithContext" methods. +// +// See https://golang.org/pkg/context on how to use contexts. +type Context = context.Context diff --git a/vendor/github.com/aws/aws-sdk-go/aws/context_background_1_5.go b/vendor/github.com/aws/aws-sdk-go/aws/context_background_1_5.go new file mode 100644 index 0000000..3132181 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/context_background_1_5.go @@ -0,0 +1,23 @@ +//go:build !go1.7 +// +build !go1.7 + +package aws + +import ( + "github.com/aws/aws-sdk-go/internal/context" +) + +// BackgroundContext returns a context that will never be canceled, has no +// values, and no deadline. This context is used by the SDK to provide +// backwards compatibility with non-context API operations and functionality. +// +// Go 1.6 and before: +// This context function is equivalent to context.Background in the Go stdlib. +// +// Go 1.7 and later: +// The context returned will be the value returned by context.Background() +// +// See https://golang.org/pkg/context for more information on Contexts. +func BackgroundContext() Context { + return context.BackgroundCtx +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/context_background_1_7.go b/vendor/github.com/aws/aws-sdk-go/aws/context_background_1_7.go new file mode 100644 index 0000000..9975d56 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/context_background_1_7.go @@ -0,0 +1,21 @@ +//go:build go1.7 +// +build go1.7 + +package aws + +import "context" + +// BackgroundContext returns a context that will never be canceled, has no +// values, and no deadline. This context is used by the SDK to provide +// backwards compatibility with non-context API operations and functionality. +// +// Go 1.6 and before: +// This context function is equivalent to context.Background in the Go stdlib. +// +// Go 1.7 and later: +// The context returned will be the value returned by context.Background() +// +// See https://golang.org/pkg/context for more information on Contexts. +func BackgroundContext() Context { + return context.Background() +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/context_sleep.go b/vendor/github.com/aws/aws-sdk-go/aws/context_sleep.go new file mode 100644 index 0000000..304fd15 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/context_sleep.go @@ -0,0 +1,24 @@ +package aws + +import ( + "time" +) + +// SleepWithContext will wait for the timer duration to expire, or the context +// is canceled. Which ever happens first. If the context is canceled the Context's +// error will be returned. +// +// Expects Context to always return a non-nil error if the Done channel is closed. +func SleepWithContext(ctx Context, dur time.Duration) error { + t := time.NewTimer(dur) + defer t.Stop() + + select { + case <-t.C: + break + case <-ctx.Done(): + return ctx.Err() + } + + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/convert_types.go b/vendor/github.com/aws/aws-sdk-go/aws/convert_types.go new file mode 100644 index 0000000..4e076c1 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/convert_types.go @@ -0,0 +1,918 @@ +package aws + +import "time" + +// String returns a pointer to the string value passed in. +func String(v string) *string { + return &v +} + +// StringValue returns the value of the string pointer passed in or +// "" if the pointer is nil. +func StringValue(v *string) string { + if v != nil { + return *v + } + return "" +} + +// StringSlice converts a slice of string values into a slice of +// string pointers +func StringSlice(src []string) []*string { + dst := make([]*string, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// StringValueSlice converts a slice of string pointers into a slice of +// string values +func StringValueSlice(src []*string) []string { + dst := make([]string, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// StringMap converts a string map of string values into a string +// map of string pointers +func StringMap(src map[string]string) map[string]*string { + dst := make(map[string]*string) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// StringValueMap converts a string map of string pointers into a string +// map of string values +func StringValueMap(src map[string]*string) map[string]string { + dst := make(map[string]string) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Bool returns a pointer to the bool value passed in. +func Bool(v bool) *bool { + return &v +} + +// BoolValue returns the value of the bool pointer passed in or +// false if the pointer is nil. +func BoolValue(v *bool) bool { + if v != nil { + return *v + } + return false +} + +// BoolSlice converts a slice of bool values into a slice of +// bool pointers +func BoolSlice(src []bool) []*bool { + dst := make([]*bool, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// BoolValueSlice converts a slice of bool pointers into a slice of +// bool values +func BoolValueSlice(src []*bool) []bool { + dst := make([]bool, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// BoolMap converts a string map of bool values into a string +// map of bool pointers +func BoolMap(src map[string]bool) map[string]*bool { + dst := make(map[string]*bool) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// BoolValueMap converts a string map of bool pointers into a string +// map of bool values +func BoolValueMap(src map[string]*bool) map[string]bool { + dst := make(map[string]bool) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Int returns a pointer to the int value passed in. +func Int(v int) *int { + return &v +} + +// IntValue returns the value of the int pointer passed in or +// 0 if the pointer is nil. +func IntValue(v *int) int { + if v != nil { + return *v + } + return 0 +} + +// IntSlice converts a slice of int values into a slice of +// int pointers +func IntSlice(src []int) []*int { + dst := make([]*int, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// IntValueSlice converts a slice of int pointers into a slice of +// int values +func IntValueSlice(src []*int) []int { + dst := make([]int, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// IntMap converts a string map of int values into a string +// map of int pointers +func IntMap(src map[string]int) map[string]*int { + dst := make(map[string]*int) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// IntValueMap converts a string map of int pointers into a string +// map of int values +func IntValueMap(src map[string]*int) map[string]int { + dst := make(map[string]int) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Uint returns a pointer to the uint value passed in. +func Uint(v uint) *uint { + return &v +} + +// UintValue returns the value of the uint pointer passed in or +// 0 if the pointer is nil. +func UintValue(v *uint) uint { + if v != nil { + return *v + } + return 0 +} + +// UintSlice converts a slice of uint values uinto a slice of +// uint pointers +func UintSlice(src []uint) []*uint { + dst := make([]*uint, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// UintValueSlice converts a slice of uint pointers uinto a slice of +// uint values +func UintValueSlice(src []*uint) []uint { + dst := make([]uint, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// UintMap converts a string map of uint values uinto a string +// map of uint pointers +func UintMap(src map[string]uint) map[string]*uint { + dst := make(map[string]*uint) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// UintValueMap converts a string map of uint pointers uinto a string +// map of uint values +func UintValueMap(src map[string]*uint) map[string]uint { + dst := make(map[string]uint) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Int8 returns a pointer to the int8 value passed in. +func Int8(v int8) *int8 { + return &v +} + +// Int8Value returns the value of the int8 pointer passed in or +// 0 if the pointer is nil. +func Int8Value(v *int8) int8 { + if v != nil { + return *v + } + return 0 +} + +// Int8Slice converts a slice of int8 values into a slice of +// int8 pointers +func Int8Slice(src []int8) []*int8 { + dst := make([]*int8, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// Int8ValueSlice converts a slice of int8 pointers into a slice of +// int8 values +func Int8ValueSlice(src []*int8) []int8 { + dst := make([]int8, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// Int8Map converts a string map of int8 values into a string +// map of int8 pointers +func Int8Map(src map[string]int8) map[string]*int8 { + dst := make(map[string]*int8) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// Int8ValueMap converts a string map of int8 pointers into a string +// map of int8 values +func Int8ValueMap(src map[string]*int8) map[string]int8 { + dst := make(map[string]int8) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Int16 returns a pointer to the int16 value passed in. +func Int16(v int16) *int16 { + return &v +} + +// Int16Value returns the value of the int16 pointer passed in or +// 0 if the pointer is nil. +func Int16Value(v *int16) int16 { + if v != nil { + return *v + } + return 0 +} + +// Int16Slice converts a slice of int16 values into a slice of +// int16 pointers +func Int16Slice(src []int16) []*int16 { + dst := make([]*int16, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// Int16ValueSlice converts a slice of int16 pointers into a slice of +// int16 values +func Int16ValueSlice(src []*int16) []int16 { + dst := make([]int16, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// Int16Map converts a string map of int16 values into a string +// map of int16 pointers +func Int16Map(src map[string]int16) map[string]*int16 { + dst := make(map[string]*int16) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// Int16ValueMap converts a string map of int16 pointers into a string +// map of int16 values +func Int16ValueMap(src map[string]*int16) map[string]int16 { + dst := make(map[string]int16) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Int32 returns a pointer to the int32 value passed in. +func Int32(v int32) *int32 { + return &v +} + +// Int32Value returns the value of the int32 pointer passed in or +// 0 if the pointer is nil. +func Int32Value(v *int32) int32 { + if v != nil { + return *v + } + return 0 +} + +// Int32Slice converts a slice of int32 values into a slice of +// int32 pointers +func Int32Slice(src []int32) []*int32 { + dst := make([]*int32, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// Int32ValueSlice converts a slice of int32 pointers into a slice of +// int32 values +func Int32ValueSlice(src []*int32) []int32 { + dst := make([]int32, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// Int32Map converts a string map of int32 values into a string +// map of int32 pointers +func Int32Map(src map[string]int32) map[string]*int32 { + dst := make(map[string]*int32) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// Int32ValueMap converts a string map of int32 pointers into a string +// map of int32 values +func Int32ValueMap(src map[string]*int32) map[string]int32 { + dst := make(map[string]int32) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Int64 returns a pointer to the int64 value passed in. +func Int64(v int64) *int64 { + return &v +} + +// Int64Value returns the value of the int64 pointer passed in or +// 0 if the pointer is nil. +func Int64Value(v *int64) int64 { + if v != nil { + return *v + } + return 0 +} + +// Int64Slice converts a slice of int64 values into a slice of +// int64 pointers +func Int64Slice(src []int64) []*int64 { + dst := make([]*int64, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// Int64ValueSlice converts a slice of int64 pointers into a slice of +// int64 values +func Int64ValueSlice(src []*int64) []int64 { + dst := make([]int64, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// Int64Map converts a string map of int64 values into a string +// map of int64 pointers +func Int64Map(src map[string]int64) map[string]*int64 { + dst := make(map[string]*int64) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// Int64ValueMap converts a string map of int64 pointers into a string +// map of int64 values +func Int64ValueMap(src map[string]*int64) map[string]int64 { + dst := make(map[string]int64) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Uint8 returns a pointer to the uint8 value passed in. +func Uint8(v uint8) *uint8 { + return &v +} + +// Uint8Value returns the value of the uint8 pointer passed in or +// 0 if the pointer is nil. +func Uint8Value(v *uint8) uint8 { + if v != nil { + return *v + } + return 0 +} + +// Uint8Slice converts a slice of uint8 values into a slice of +// uint8 pointers +func Uint8Slice(src []uint8) []*uint8 { + dst := make([]*uint8, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// Uint8ValueSlice converts a slice of uint8 pointers into a slice of +// uint8 values +func Uint8ValueSlice(src []*uint8) []uint8 { + dst := make([]uint8, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// Uint8Map converts a string map of uint8 values into a string +// map of uint8 pointers +func Uint8Map(src map[string]uint8) map[string]*uint8 { + dst := make(map[string]*uint8) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// Uint8ValueMap converts a string map of uint8 pointers into a string +// map of uint8 values +func Uint8ValueMap(src map[string]*uint8) map[string]uint8 { + dst := make(map[string]uint8) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Uint16 returns a pointer to the uint16 value passed in. +func Uint16(v uint16) *uint16 { + return &v +} + +// Uint16Value returns the value of the uint16 pointer passed in or +// 0 if the pointer is nil. +func Uint16Value(v *uint16) uint16 { + if v != nil { + return *v + } + return 0 +} + +// Uint16Slice converts a slice of uint16 values into a slice of +// uint16 pointers +func Uint16Slice(src []uint16) []*uint16 { + dst := make([]*uint16, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// Uint16ValueSlice converts a slice of uint16 pointers into a slice of +// uint16 values +func Uint16ValueSlice(src []*uint16) []uint16 { + dst := make([]uint16, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// Uint16Map converts a string map of uint16 values into a string +// map of uint16 pointers +func Uint16Map(src map[string]uint16) map[string]*uint16 { + dst := make(map[string]*uint16) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// Uint16ValueMap converts a string map of uint16 pointers into a string +// map of uint16 values +func Uint16ValueMap(src map[string]*uint16) map[string]uint16 { + dst := make(map[string]uint16) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Uint32 returns a pointer to the uint32 value passed in. +func Uint32(v uint32) *uint32 { + return &v +} + +// Uint32Value returns the value of the uint32 pointer passed in or +// 0 if the pointer is nil. +func Uint32Value(v *uint32) uint32 { + if v != nil { + return *v + } + return 0 +} + +// Uint32Slice converts a slice of uint32 values into a slice of +// uint32 pointers +func Uint32Slice(src []uint32) []*uint32 { + dst := make([]*uint32, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// Uint32ValueSlice converts a slice of uint32 pointers into a slice of +// uint32 values +func Uint32ValueSlice(src []*uint32) []uint32 { + dst := make([]uint32, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// Uint32Map converts a string map of uint32 values into a string +// map of uint32 pointers +func Uint32Map(src map[string]uint32) map[string]*uint32 { + dst := make(map[string]*uint32) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// Uint32ValueMap converts a string map of uint32 pointers into a string +// map of uint32 values +func Uint32ValueMap(src map[string]*uint32) map[string]uint32 { + dst := make(map[string]uint32) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Uint64 returns a pointer to the uint64 value passed in. +func Uint64(v uint64) *uint64 { + return &v +} + +// Uint64Value returns the value of the uint64 pointer passed in or +// 0 if the pointer is nil. +func Uint64Value(v *uint64) uint64 { + if v != nil { + return *v + } + return 0 +} + +// Uint64Slice converts a slice of uint64 values into a slice of +// uint64 pointers +func Uint64Slice(src []uint64) []*uint64 { + dst := make([]*uint64, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// Uint64ValueSlice converts a slice of uint64 pointers into a slice of +// uint64 values +func Uint64ValueSlice(src []*uint64) []uint64 { + dst := make([]uint64, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// Uint64Map converts a string map of uint64 values into a string +// map of uint64 pointers +func Uint64Map(src map[string]uint64) map[string]*uint64 { + dst := make(map[string]*uint64) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// Uint64ValueMap converts a string map of uint64 pointers into a string +// map of uint64 values +func Uint64ValueMap(src map[string]*uint64) map[string]uint64 { + dst := make(map[string]uint64) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Float32 returns a pointer to the float32 value passed in. +func Float32(v float32) *float32 { + return &v +} + +// Float32Value returns the value of the float32 pointer passed in or +// 0 if the pointer is nil. +func Float32Value(v *float32) float32 { + if v != nil { + return *v + } + return 0 +} + +// Float32Slice converts a slice of float32 values into a slice of +// float32 pointers +func Float32Slice(src []float32) []*float32 { + dst := make([]*float32, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// Float32ValueSlice converts a slice of float32 pointers into a slice of +// float32 values +func Float32ValueSlice(src []*float32) []float32 { + dst := make([]float32, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// Float32Map converts a string map of float32 values into a string +// map of float32 pointers +func Float32Map(src map[string]float32) map[string]*float32 { + dst := make(map[string]*float32) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// Float32ValueMap converts a string map of float32 pointers into a string +// map of float32 values +func Float32ValueMap(src map[string]*float32) map[string]float32 { + dst := make(map[string]float32) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Float64 returns a pointer to the float64 value passed in. +func Float64(v float64) *float64 { + return &v +} + +// Float64Value returns the value of the float64 pointer passed in or +// 0 if the pointer is nil. +func Float64Value(v *float64) float64 { + if v != nil { + return *v + } + return 0 +} + +// Float64Slice converts a slice of float64 values into a slice of +// float64 pointers +func Float64Slice(src []float64) []*float64 { + dst := make([]*float64, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// Float64ValueSlice converts a slice of float64 pointers into a slice of +// float64 values +func Float64ValueSlice(src []*float64) []float64 { + dst := make([]float64, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// Float64Map converts a string map of float64 values into a string +// map of float64 pointers +func Float64Map(src map[string]float64) map[string]*float64 { + dst := make(map[string]*float64) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// Float64ValueMap converts a string map of float64 pointers into a string +// map of float64 values +func Float64ValueMap(src map[string]*float64) map[string]float64 { + dst := make(map[string]float64) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Time returns a pointer to the time.Time value passed in. +func Time(v time.Time) *time.Time { + return &v +} + +// TimeValue returns the value of the time.Time pointer passed in or +// time.Time{} if the pointer is nil. +func TimeValue(v *time.Time) time.Time { + if v != nil { + return *v + } + return time.Time{} +} + +// SecondsTimeValue converts an int64 pointer to a time.Time value +// representing seconds since Epoch or time.Time{} if the pointer is nil. +func SecondsTimeValue(v *int64) time.Time { + if v != nil { + return time.Unix((*v / 1000), 0) + } + return time.Time{} +} + +// MillisecondsTimeValue converts an int64 pointer to a time.Time value +// representing milliseconds sinch Epoch or time.Time{} if the pointer is nil. +func MillisecondsTimeValue(v *int64) time.Time { + if v != nil { + return time.Unix(0, (*v * 1000000)) + } + return time.Time{} +} + +// TimeUnixMilli returns a Unix timestamp in milliseconds from "January 1, 1970 UTC". +// The result is undefined if the Unix time cannot be represented by an int64. +// Which includes calling TimeUnixMilli on a zero Time is undefined. +// +// This utility is useful for service API's such as CloudWatch Logs which require +// their unix time values to be in milliseconds. +// +// See Go stdlib https://golang.org/pkg/time/#Time.UnixNano for more information. +func TimeUnixMilli(t time.Time) int64 { + return t.UnixNano() / int64(time.Millisecond/time.Nanosecond) +} + +// TimeSlice converts a slice of time.Time values into a slice of +// time.Time pointers +func TimeSlice(src []time.Time) []*time.Time { + dst := make([]*time.Time, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// TimeValueSlice converts a slice of time.Time pointers into a slice of +// time.Time values +func TimeValueSlice(src []*time.Time) []time.Time { + dst := make([]time.Time, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// TimeMap converts a string map of time.Time values into a string +// map of time.Time pointers +func TimeMap(src map[string]time.Time) map[string]*time.Time { + dst := make(map[string]*time.Time) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// TimeValueMap converts a string map of time.Time pointers into a string +// map of time.Time values +func TimeValueMap(src map[string]*time.Time) map[string]time.Time { + dst := make(map[string]time.Time) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/chain_provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/chain_provider.go new file mode 100644 index 0000000..3ad1e79 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/chain_provider.go @@ -0,0 +1,100 @@ +package credentials + +import ( + "github.com/aws/aws-sdk-go/aws/awserr" +) + +var ( + // ErrNoValidProvidersFoundInChain Is returned when there are no valid + // providers in the ChainProvider. + // + // This has been deprecated. For verbose error messaging set + // aws.Config.CredentialsChainVerboseErrors to true. + ErrNoValidProvidersFoundInChain = awserr.New("NoCredentialProviders", + `no valid providers in chain. Deprecated. + For verbose messaging see aws.Config.CredentialsChainVerboseErrors`, + nil) +) + +// A ChainProvider will search for a provider which returns credentials +// and cache that provider until Retrieve is called again. +// +// The ChainProvider provides a way of chaining multiple providers together +// which will pick the first available using priority order of the Providers +// in the list. +// +// If none of the Providers retrieve valid credentials Value, ChainProvider's +// Retrieve() will return the error ErrNoValidProvidersFoundInChain. +// +// If a Provider is found which returns valid credentials Value ChainProvider +// will cache that Provider for all calls to IsExpired(), until Retrieve is +// called again. +// +// Example of ChainProvider to be used with an EnvProvider and EC2RoleProvider. +// In this example EnvProvider will first check if any credentials are available +// via the environment variables. If there are none ChainProvider will check +// the next Provider in the list, EC2RoleProvider in this case. If EC2RoleProvider +// does not return any credentials ChainProvider will return the error +// ErrNoValidProvidersFoundInChain +// +// creds := credentials.NewChainCredentials( +// []credentials.Provider{ +// &credentials.EnvProvider{}, +// &ec2rolecreds.EC2RoleProvider{ +// Client: ec2metadata.New(sess), +// }, +// }) +// +// // Usage of ChainCredentials with aws.Config +// svc := ec2.New(session.Must(session.NewSession(&aws.Config{ +// Credentials: creds, +// }))) +// +type ChainProvider struct { + Providers []Provider + curr Provider + VerboseErrors bool +} + +// NewChainCredentials returns a pointer to a new Credentials object +// wrapping a chain of providers. +func NewChainCredentials(providers []Provider) *Credentials { + return NewCredentials(&ChainProvider{ + Providers: append([]Provider{}, providers...), + }) +} + +// Retrieve returns the credentials value or error if no provider returned +// without error. +// +// If a provider is found it will be cached and any calls to IsExpired() +// will return the expired state of the cached provider. +func (c *ChainProvider) Retrieve() (Value, error) { + var errs []error + for _, p := range c.Providers { + creds, err := p.Retrieve() + if err == nil { + c.curr = p + return creds, nil + } + errs = append(errs, err) + } + c.curr = nil + + var err error + err = ErrNoValidProvidersFoundInChain + if c.VerboseErrors { + err = awserr.NewBatchError("NoCredentialProviders", "no valid providers in chain", errs) + } + return Value{}, err +} + +// IsExpired will returned the expired state of the currently cached provider +// if there is one. If there is no current provider, true will be returned. +func (c *ChainProvider) IsExpired() bool { + if c.curr != nil { + return c.curr.IsExpired() + } + + return true +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/context_background_go1.5.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/context_background_go1.5.go new file mode 100644 index 0000000..6e3406b --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/context_background_go1.5.go @@ -0,0 +1,23 @@ +//go:build !go1.7 +// +build !go1.7 + +package credentials + +import ( + "github.com/aws/aws-sdk-go/internal/context" +) + +// backgroundContext returns a context that will never be canceled, has no +// values, and no deadline. This context is used by the SDK to provide +// backwards compatibility with non-context API operations and functionality. +// +// Go 1.6 and before: +// This context function is equivalent to context.Background in the Go stdlib. +// +// Go 1.7 and later: +// The context returned will be the value returned by context.Background() +// +// See https://golang.org/pkg/context for more information on Contexts. +func backgroundContext() Context { + return context.BackgroundCtx +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/context_background_go1.7.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/context_background_go1.7.go new file mode 100644 index 0000000..a68df0e --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/context_background_go1.7.go @@ -0,0 +1,21 @@ +//go:build go1.7 +// +build go1.7 + +package credentials + +import "context" + +// backgroundContext returns a context that will never be canceled, has no +// values, and no deadline. This context is used by the SDK to provide +// backwards compatibility with non-context API operations and functionality. +// +// Go 1.6 and before: +// This context function is equivalent to context.Background in the Go stdlib. +// +// Go 1.7 and later: +// The context returned will be the value returned by context.Background() +// +// See https://golang.org/pkg/context for more information on Contexts. +func backgroundContext() Context { + return context.Background() +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/context_go1.5.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/context_go1.5.go new file mode 100644 index 0000000..0345fab --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/context_go1.5.go @@ -0,0 +1,40 @@ +//go:build !go1.9 +// +build !go1.9 + +package credentials + +import "time" + +// Context is an copy of the Go v1.7 stdlib's context.Context interface. +// It is represented as a SDK interface to enable you to use the "WithContext" +// API methods with Go v1.6 and a Context type such as golang.org/x/net/context. +// +// This type, aws.Context, and context.Context are equivalent. +// +// See https://golang.org/pkg/context on how to use contexts. +type Context interface { + // Deadline returns the time when work done on behalf of this context + // should be canceled. Deadline returns ok==false when no deadline is + // set. Successive calls to Deadline return the same results. + Deadline() (deadline time.Time, ok bool) + + // Done returns a channel that's closed when work done on behalf of this + // context should be canceled. Done may return nil if this context can + // never be canceled. Successive calls to Done return the same value. + Done() <-chan struct{} + + // Err returns a non-nil error value after Done is closed. Err returns + // Canceled if the context was canceled or DeadlineExceeded if the + // context's deadline passed. No other values for Err are defined. + // After Done is closed, successive calls to Err return the same value. + Err() error + + // Value returns the value associated with this context for key, or nil + // if no value is associated with key. Successive calls to Value with + // the same key returns the same result. + // + // Use context values only for request-scoped data that transits + // processes and API boundaries, not for passing optional parameters to + // functions. + Value(key interface{}) interface{} +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/context_go1.9.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/context_go1.9.go new file mode 100644 index 0000000..79018ab --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/context_go1.9.go @@ -0,0 +1,14 @@ +//go:build go1.9 +// +build go1.9 + +package credentials + +import "context" + +// Context is an alias of the Go stdlib's context.Context interface. +// It can be used within the SDK's API operation "WithContext" methods. +// +// This type, aws.Context, and context.Context are equivalent. +// +// See https://golang.org/pkg/context on how to use contexts. +type Context = context.Context diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/credentials.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/credentials.go new file mode 100644 index 0000000..a880a3d --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/credentials.go @@ -0,0 +1,383 @@ +// Package credentials provides credential retrieval and management +// +// The Credentials is the primary method of getting access to and managing +// credentials Values. Using dependency injection retrieval of the credential +// values is handled by a object which satisfies the Provider interface. +// +// By default the Credentials.Get() will cache the successful result of a +// Provider's Retrieve() until Provider.IsExpired() returns true. At which +// point Credentials will call Provider's Retrieve() to get new credential Value. +// +// The Provider is responsible for determining when credentials Value have expired. +// It is also important to note that Credentials will always call Retrieve the +// first time Credentials.Get() is called. +// +// Example of using the environment variable credentials. +// +// creds := credentials.NewEnvCredentials() +// +// // Retrieve the credentials value +// credValue, err := creds.Get() +// if err != nil { +// // handle error +// } +// +// Example of forcing credentials to expire and be refreshed on the next Get(). +// This may be helpful to proactively expire credentials and refresh them sooner +// than they would naturally expire on their own. +// +// creds := credentials.NewCredentials(&ec2rolecreds.EC2RoleProvider{}) +// creds.Expire() +// credsValue, err := creds.Get() +// // New credentials will be retrieved instead of from cache. +// +// +// Custom Provider +// +// Each Provider built into this package also provides a helper method to generate +// a Credentials pointer setup with the provider. To use a custom Provider just +// create a type which satisfies the Provider interface and pass it to the +// NewCredentials method. +// +// type MyProvider struct{} +// func (m *MyProvider) Retrieve() (Value, error) {...} +// func (m *MyProvider) IsExpired() bool {...} +// +// creds := credentials.NewCredentials(&MyProvider{}) +// credValue, err := creds.Get() +// +package credentials + +import ( + "fmt" + "sync" + "time" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/internal/sync/singleflight" +) + +// AnonymousCredentials is an empty Credential object that can be used as +// dummy placeholder credentials for requests that do not need signed. +// +// This Credentials can be used to configure a service to not sign requests +// when making service API calls. For example, when accessing public +// s3 buckets. +// +// svc := s3.New(session.Must(session.NewSession(&aws.Config{ +// Credentials: credentials.AnonymousCredentials, +// }))) +// // Access public S3 buckets. +var AnonymousCredentials = NewStaticCredentials("", "", "") + +// A Value is the AWS credentials value for individual credential fields. +type Value struct { + // AWS Access key ID + AccessKeyID string + + // AWS Secret Access Key + SecretAccessKey string + + // AWS Session Token + SessionToken string + + // Provider used to get credentials + ProviderName string +} + +// HasKeys returns if the credentials Value has both AccessKeyID and +// SecretAccessKey value set. +func (v Value) HasKeys() bool { + return len(v.AccessKeyID) != 0 && len(v.SecretAccessKey) != 0 +} + +// A Provider is the interface for any component which will provide credentials +// Value. A provider is required to manage its own Expired state, and what to +// be expired means. +// +// The Provider should not need to implement its own mutexes, because +// that will be managed by Credentials. +type Provider interface { + // Retrieve returns nil if it successfully retrieved the value. + // Error is returned if the value were not obtainable, or empty. + Retrieve() (Value, error) + + // IsExpired returns if the credentials are no longer valid, and need + // to be retrieved. + IsExpired() bool +} + +// ProviderWithContext is a Provider that can retrieve credentials with a Context +type ProviderWithContext interface { + Provider + + RetrieveWithContext(Context) (Value, error) +} + +// An Expirer is an interface that Providers can implement to expose the expiration +// time, if known. If the Provider cannot accurately provide this info, +// it should not implement this interface. +type Expirer interface { + // The time at which the credentials are no longer valid + ExpiresAt() time.Time +} + +// An ErrorProvider is a stub credentials provider that always returns an error +// this is used by the SDK when construction a known provider is not possible +// due to an error. +type ErrorProvider struct { + // The error to be returned from Retrieve + Err error + + // The provider name to set on the Retrieved returned Value + ProviderName string +} + +// Retrieve will always return the error that the ErrorProvider was created with. +func (p ErrorProvider) Retrieve() (Value, error) { + return Value{ProviderName: p.ProviderName}, p.Err +} + +// IsExpired will always return not expired. +func (p ErrorProvider) IsExpired() bool { + return false +} + +// A Expiry provides shared expiration logic to be used by credentials +// providers to implement expiry functionality. +// +// The best method to use this struct is as an anonymous field within the +// provider's struct. +// +// Example: +// type EC2RoleProvider struct { +// Expiry +// ... +// } +type Expiry struct { + // The date/time when to expire on + expiration time.Time + + // If set will be used by IsExpired to determine the current time. + // Defaults to time.Now if CurrentTime is not set. Available for testing + // to be able to mock out the current time. + CurrentTime func() time.Time +} + +// SetExpiration sets the expiration IsExpired will check when called. +// +// If window is greater than 0 the expiration time will be reduced by the +// window value. +// +// Using a window is helpful to trigger credentials to expire sooner than +// the expiration time given to ensure no requests are made with expired +// tokens. +func (e *Expiry) SetExpiration(expiration time.Time, window time.Duration) { + // Passed in expirations should have the monotonic clock values stripped. + // This ensures time comparisons will be based on wall-time. + e.expiration = expiration.Round(0) + if window > 0 { + e.expiration = e.expiration.Add(-window) + } +} + +// IsExpired returns if the credentials are expired. +func (e *Expiry) IsExpired() bool { + curTime := e.CurrentTime + if curTime == nil { + curTime = time.Now + } + return e.expiration.Before(curTime()) +} + +// ExpiresAt returns the expiration time of the credential +func (e *Expiry) ExpiresAt() time.Time { + return e.expiration +} + +// A Credentials provides concurrency safe retrieval of AWS credentials Value. +// Credentials will cache the credentials value until they expire. Once the value +// expires the next Get will attempt to retrieve valid credentials. +// +// Credentials is safe to use across multiple goroutines and will manage the +// synchronous state so the Providers do not need to implement their own +// synchronization. +// +// The first Credentials.Get() will always call Provider.Retrieve() to get the +// first instance of the credentials Value. All calls to Get() after that +// will return the cached credentials Value until IsExpired() returns true. +type Credentials struct { + sf singleflight.Group + + m sync.RWMutex + creds Value + provider Provider +} + +// NewCredentials returns a pointer to a new Credentials with the provider set. +func NewCredentials(provider Provider) *Credentials { + c := &Credentials{ + provider: provider, + } + return c +} + +// GetWithContext returns the credentials value, or error if the credentials +// Value failed to be retrieved. Will return early if the passed in context is +// canceled. +// +// Will return the cached credentials Value if it has not expired. If the +// credentials Value has expired the Provider's Retrieve() will be called +// to refresh the credentials. +// +// If Credentials.Expire() was called the credentials Value will be force +// expired, and the next call to Get() will cause them to be refreshed. +// +// Passed in Context is equivalent to aws.Context, and context.Context. +func (c *Credentials) GetWithContext(ctx Context) (Value, error) { + // Check if credentials are cached, and not expired. + select { + case curCreds, ok := <-c.asyncIsExpired(): + // ok will only be true, of the credentials were not expired. ok will + // be false and have no value if the credentials are expired. + if ok { + return curCreds, nil + } + case <-ctx.Done(): + return Value{}, awserr.New("RequestCanceled", + "request context canceled", ctx.Err()) + } + + // Cannot pass context down to the actual retrieve, because the first + // context would cancel the whole group when there is not direct + // association of items in the group. + resCh := c.sf.DoChan("", func() (interface{}, error) { + return c.singleRetrieve(&suppressedContext{ctx}) + }) + select { + case res := <-resCh: + return res.Val.(Value), res.Err + case <-ctx.Done(): + return Value{}, awserr.New("RequestCanceled", + "request context canceled", ctx.Err()) + } +} + +func (c *Credentials) singleRetrieve(ctx Context) (interface{}, error) { + c.m.Lock() + defer c.m.Unlock() + + if curCreds := c.creds; !c.isExpiredLocked(curCreds) { + return curCreds, nil + } + + var creds Value + var err error + if p, ok := c.provider.(ProviderWithContext); ok { + creds, err = p.RetrieveWithContext(ctx) + } else { + creds, err = c.provider.Retrieve() + } + if err == nil { + c.creds = creds + } + + return creds, err +} + +// Get returns the credentials value, or error if the credentials Value failed +// to be retrieved. +// +// Will return the cached credentials Value if it has not expired. If the +// credentials Value has expired the Provider's Retrieve() will be called +// to refresh the credentials. +// +// If Credentials.Expire() was called the credentials Value will be force +// expired, and the next call to Get() will cause them to be refreshed. +func (c *Credentials) Get() (Value, error) { + return c.GetWithContext(backgroundContext()) +} + +// Expire expires the credentials and forces them to be retrieved on the +// next call to Get(). +// +// This will override the Provider's expired state, and force Credentials +// to call the Provider's Retrieve(). +func (c *Credentials) Expire() { + c.m.Lock() + defer c.m.Unlock() + + c.creds = Value{} +} + +// IsExpired returns if the credentials are no longer valid, and need +// to be retrieved. +// +// If the Credentials were forced to be expired with Expire() this will +// reflect that override. +func (c *Credentials) IsExpired() bool { + c.m.RLock() + defer c.m.RUnlock() + + return c.isExpiredLocked(c.creds) +} + +// asyncIsExpired returns a channel of credentials Value. If the channel is +// closed the credentials are expired and credentials value are not empty. +func (c *Credentials) asyncIsExpired() <-chan Value { + ch := make(chan Value, 1) + go func() { + c.m.RLock() + defer c.m.RUnlock() + + if curCreds := c.creds; !c.isExpiredLocked(curCreds) { + ch <- curCreds + } + + close(ch) + }() + + return ch +} + +// isExpiredLocked helper method wrapping the definition of expired credentials. +func (c *Credentials) isExpiredLocked(creds interface{}) bool { + return creds == nil || creds.(Value) == Value{} || c.provider.IsExpired() +} + +// ExpiresAt provides access to the functionality of the Expirer interface of +// the underlying Provider, if it supports that interface. Otherwise, it returns +// an error. +func (c *Credentials) ExpiresAt() (time.Time, error) { + c.m.RLock() + defer c.m.RUnlock() + + expirer, ok := c.provider.(Expirer) + if !ok { + return time.Time{}, awserr.New("ProviderNotExpirer", + fmt.Sprintf("provider %s does not support ExpiresAt()", + c.creds.ProviderName), + nil) + } + if c.creds == (Value{}) { + // set expiration time to the distant past + return time.Time{}, nil + } + return expirer.ExpiresAt(), nil +} + +type suppressedContext struct { + Context +} + +func (s *suppressedContext) Deadline() (deadline time.Time, ok bool) { + return time.Time{}, false +} + +func (s *suppressedContext) Done() <-chan struct{} { + return nil +} + +func (s *suppressedContext) Err() error { + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/env_provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/env_provider.go new file mode 100644 index 0000000..54c5cf7 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/env_provider.go @@ -0,0 +1,74 @@ +package credentials + +import ( + "os" + + "github.com/aws/aws-sdk-go/aws/awserr" +) + +// EnvProviderName provides a name of Env provider +const EnvProviderName = "EnvProvider" + +var ( + // ErrAccessKeyIDNotFound is returned when the AWS Access Key ID can't be + // found in the process's environment. + ErrAccessKeyIDNotFound = awserr.New("EnvAccessKeyNotFound", "AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY not found in environment", nil) + + // ErrSecretAccessKeyNotFound is returned when the AWS Secret Access Key + // can't be found in the process's environment. + ErrSecretAccessKeyNotFound = awserr.New("EnvSecretNotFound", "AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY not found in environment", nil) +) + +// A EnvProvider retrieves credentials from the environment variables of the +// running process. Environment credentials never expire. +// +// Environment variables used: +// +// * Access Key ID: AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY +// +// * Secret Access Key: AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY +type EnvProvider struct { + retrieved bool +} + +// NewEnvCredentials returns a pointer to a new Credentials object +// wrapping the environment variable provider. +func NewEnvCredentials() *Credentials { + return NewCredentials(&EnvProvider{}) +} + +// Retrieve retrieves the keys from the environment. +func (e *EnvProvider) Retrieve() (Value, error) { + e.retrieved = false + + id := os.Getenv("AWS_ACCESS_KEY_ID") + if id == "" { + id = os.Getenv("AWS_ACCESS_KEY") + } + + secret := os.Getenv("AWS_SECRET_ACCESS_KEY") + if secret == "" { + secret = os.Getenv("AWS_SECRET_KEY") + } + + if id == "" { + return Value{ProviderName: EnvProviderName}, ErrAccessKeyIDNotFound + } + + if secret == "" { + return Value{ProviderName: EnvProviderName}, ErrSecretAccessKeyNotFound + } + + e.retrieved = true + return Value{ + AccessKeyID: id, + SecretAccessKey: secret, + SessionToken: os.Getenv("AWS_SESSION_TOKEN"), + ProviderName: EnvProviderName, + }, nil +} + +// IsExpired returns if the credentials have been retrieved. +func (e *EnvProvider) IsExpired() bool { + return !e.retrieved +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/example.ini b/vendor/github.com/aws/aws-sdk-go/aws/credentials/example.ini new file mode 100644 index 0000000..7fc91d9 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/example.ini @@ -0,0 +1,12 @@ +[default] +aws_access_key_id = accessKey +aws_secret_access_key = secret +aws_session_token = token + +[no_token] +aws_access_key_id = accessKey +aws_secret_access_key = secret + +[with_colon] +aws_access_key_id: accessKey +aws_secret_access_key: secret diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go new file mode 100644 index 0000000..22b5c5d --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go @@ -0,0 +1,151 @@ +package credentials + +import ( + "fmt" + "os" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/internal/ini" + "github.com/aws/aws-sdk-go/internal/shareddefaults" +) + +// SharedCredsProviderName provides a name of SharedCreds provider +const SharedCredsProviderName = "SharedCredentialsProvider" + +var ( + // ErrSharedCredentialsHomeNotFound is emitted when the user directory cannot be found. + ErrSharedCredentialsHomeNotFound = awserr.New("UserHomeNotFound", "user home directory not found.", nil) +) + +// A SharedCredentialsProvider retrieves access key pair (access key ID, +// secret access key, and session token if present) credentials from the current +// user's home directory, and keeps track if those credentials are expired. +// +// Profile ini file example: $HOME/.aws/credentials +type SharedCredentialsProvider struct { + // Path to the shared credentials file. + // + // If empty will look for "AWS_SHARED_CREDENTIALS_FILE" env variable. If the + // env value is empty will default to current user's home directory. + // Linux/OSX: "$HOME/.aws/credentials" + // Windows: "%USERPROFILE%\.aws\credentials" + Filename string + + // AWS Profile to extract credentials from the shared credentials file. If empty + // will default to environment variable "AWS_PROFILE" or "default" if + // environment variable is also not set. + Profile string + + // retrieved states if the credentials have been successfully retrieved. + retrieved bool +} + +// NewSharedCredentials returns a pointer to a new Credentials object +// wrapping the Profile file provider. +func NewSharedCredentials(filename, profile string) *Credentials { + return NewCredentials(&SharedCredentialsProvider{ + Filename: filename, + Profile: profile, + }) +} + +// Retrieve reads and extracts the shared credentials from the current +// users home directory. +func (p *SharedCredentialsProvider) Retrieve() (Value, error) { + p.retrieved = false + + filename, err := p.filename() + if err != nil { + return Value{ProviderName: SharedCredsProviderName}, err + } + + creds, err := loadProfile(filename, p.profile()) + if err != nil { + return Value{ProviderName: SharedCredsProviderName}, err + } + + p.retrieved = true + return creds, nil +} + +// IsExpired returns if the shared credentials have expired. +func (p *SharedCredentialsProvider) IsExpired() bool { + return !p.retrieved +} + +// loadProfiles loads from the file pointed to by shared credentials filename for profile. +// The credentials retrieved from the profile will be returned or error. Error will be +// returned if it fails to read from the file, or the data is invalid. +func loadProfile(filename, profile string) (Value, error) { + config, err := ini.OpenFile(filename) + if err != nil { + return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsLoad", "failed to load shared credentials file", err) + } + + iniProfile, ok := config.GetSection(profile) + if !ok { + return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsLoad", "failed to get profile", nil) + } + + id := iniProfile.String("aws_access_key_id") + if len(id) == 0 { + return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsAccessKey", + fmt.Sprintf("shared credentials %s in %s did not contain aws_access_key_id", profile, filename), + nil) + } + + secret := iniProfile.String("aws_secret_access_key") + if len(secret) == 0 { + return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsSecret", + fmt.Sprintf("shared credentials %s in %s did not contain aws_secret_access_key", profile, filename), + nil) + } + + // Default to empty string if not found + token := iniProfile.String("aws_session_token") + + return Value{ + AccessKeyID: id, + SecretAccessKey: secret, + SessionToken: token, + ProviderName: SharedCredsProviderName, + }, nil +} + +// filename returns the filename to use to read AWS shared credentials. +// +// Will return an error if the user's home directory path cannot be found. +func (p *SharedCredentialsProvider) filename() (string, error) { + if len(p.Filename) != 0 { + return p.Filename, nil + } + + if p.Filename = os.Getenv("AWS_SHARED_CREDENTIALS_FILE"); len(p.Filename) != 0 { + return p.Filename, nil + } + + if home := shareddefaults.UserHomeDir(); len(home) == 0 { + // Backwards compatibility of home directly not found error being returned. + // This error is too verbose, failure when opening the file would of been + // a better error to return. + return "", ErrSharedCredentialsHomeNotFound + } + + p.Filename = shareddefaults.SharedCredentialsFilename() + + return p.Filename, nil +} + +// profile returns the AWS shared credentials profile. If empty will read +// environment variable "AWS_PROFILE". If that is not set profile will +// return "default". +func (p *SharedCredentialsProvider) profile() string { + if p.Profile == "" { + p.Profile = os.Getenv("AWS_PROFILE") + } + if p.Profile == "" { + p.Profile = "default" + } + + return p.Profile +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go new file mode 100644 index 0000000..cbba1e3 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go @@ -0,0 +1,57 @@ +package credentials + +import ( + "github.com/aws/aws-sdk-go/aws/awserr" +) + +// StaticProviderName provides a name of Static provider +const StaticProviderName = "StaticProvider" + +var ( + // ErrStaticCredentialsEmpty is emitted when static credentials are empty. + ErrStaticCredentialsEmpty = awserr.New("EmptyStaticCreds", "static credentials are empty", nil) +) + +// A StaticProvider is a set of credentials which are set programmatically, +// and will never expire. +type StaticProvider struct { + Value +} + +// NewStaticCredentials returns a pointer to a new Credentials object +// wrapping a static credentials value provider. Token is only required +// for temporary security credentials retrieved via STS, otherwise an empty +// string can be passed for this parameter. +func NewStaticCredentials(id, secret, token string) *Credentials { + return NewCredentials(&StaticProvider{Value: Value{ + AccessKeyID: id, + SecretAccessKey: secret, + SessionToken: token, + }}) +} + +// NewStaticCredentialsFromCreds returns a pointer to a new Credentials object +// wrapping the static credentials value provide. Same as NewStaticCredentials +// but takes the creds Value instead of individual fields +func NewStaticCredentialsFromCreds(creds Value) *Credentials { + return NewCredentials(&StaticProvider{Value: creds}) +} + +// Retrieve returns the credentials or error if the credentials are invalid. +func (s *StaticProvider) Retrieve() (Value, error) { + if s.AccessKeyID == "" || s.SecretAccessKey == "" { + return Value{ProviderName: StaticProviderName}, ErrStaticCredentialsEmpty + } + + if len(s.Value.ProviderName) == 0 { + s.Value.ProviderName = StaticProviderName + } + return s.Value, nil +} + +// IsExpired returns if the credentials are expired. +// +// For StaticProvider, the credentials never expired. +func (s *StaticProvider) IsExpired() bool { + return false +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/crr/cache.go b/vendor/github.com/aws/aws-sdk-go/aws/crr/cache.go new file mode 100644 index 0000000..c07f673 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/crr/cache.go @@ -0,0 +1,122 @@ +package crr + +import ( + "sync/atomic" +) + +// EndpointCache is an LRU cache that holds a series of endpoints +// based on some key. The datastructure makes use of a read write +// mutex to enable asynchronous use. +type EndpointCache struct { + endpoints syncMap + endpointLimit int64 + // size is used to count the number elements in the cache. + // The atomic package is used to ensure this size is accurate when + // using multiple goroutines. + size int64 +} + +// NewEndpointCache will return a newly initialized cache with a limit +// of endpointLimit entries. +func NewEndpointCache(endpointLimit int64) *EndpointCache { + return &EndpointCache{ + endpointLimit: endpointLimit, + endpoints: newSyncMap(), + } +} + +// get is a concurrent safe get operation that will retrieve an endpoint +// based on endpointKey. A boolean will also be returned to illustrate whether +// or not the endpoint had been found. +func (c *EndpointCache) get(endpointKey string) (Endpoint, bool) { + endpoint, ok := c.endpoints.Load(endpointKey) + if !ok { + return Endpoint{}, false + } + + ev := endpoint.(Endpoint) + ev.Prune() + + c.endpoints.Store(endpointKey, ev) + return endpoint.(Endpoint), true +} + +// Has returns if the enpoint cache contains a valid entry for the endpoint key +// provided. +func (c *EndpointCache) Has(endpointKey string) bool { + endpoint, ok := c.get(endpointKey) + _, found := endpoint.GetValidAddress() + + return ok && found +} + +// Get will retrieve a weighted address based off of the endpoint key. If an endpoint +// should be retrieved, due to not existing or the current endpoint has expired +// the Discoverer object that was passed in will attempt to discover a new endpoint +// and add that to the cache. +func (c *EndpointCache) Get(d Discoverer, endpointKey string, required bool) (WeightedAddress, error) { + var err error + endpoint, ok := c.get(endpointKey) + weighted, found := endpoint.GetValidAddress() + shouldGet := !ok || !found + + if required && shouldGet { + if endpoint, err = c.discover(d, endpointKey); err != nil { + return WeightedAddress{}, err + } + + weighted, _ = endpoint.GetValidAddress() + } else if shouldGet { + go c.discover(d, endpointKey) + } + + return weighted, nil +} + +// Add is a concurrent safe operation that will allow new endpoints to be added +// to the cache. If the cache is full, the number of endpoints equal endpointLimit, +// then this will remove the oldest entry before adding the new endpoint. +func (c *EndpointCache) Add(endpoint Endpoint) { + // de-dups multiple adds of an endpoint with a pre-existing key + if iface, ok := c.endpoints.Load(endpoint.Key); ok { + e := iface.(Endpoint) + if e.Len() > 0 { + return + } + } + c.endpoints.Store(endpoint.Key, endpoint) + + size := atomic.AddInt64(&c.size, 1) + if size > 0 && size > c.endpointLimit { + c.deleteRandomKey() + } +} + +// deleteRandomKey will delete a random key from the cache. If +// no key was deleted false will be returned. +func (c *EndpointCache) deleteRandomKey() bool { + atomic.AddInt64(&c.size, -1) + found := false + + c.endpoints.Range(func(key, value interface{}) bool { + found = true + c.endpoints.Delete(key) + + return false + }) + + return found +} + +// discover will get and store and endpoint using the Discoverer. +func (c *EndpointCache) discover(d Discoverer, endpointKey string) (Endpoint, error) { + endpoint, err := d.Discover() + if err != nil { + return Endpoint{}, err + } + + endpoint.Key = endpointKey + c.Add(endpoint) + + return endpoint, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/crr/endpoint.go b/vendor/github.com/aws/aws-sdk-go/aws/crr/endpoint.go new file mode 100644 index 0000000..2b088bd --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/crr/endpoint.go @@ -0,0 +1,132 @@ +package crr + +import ( + "net/url" + "sort" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" +) + +// Endpoint represents an endpoint used in endpoint discovery. +type Endpoint struct { + Key string + Addresses WeightedAddresses +} + +// WeightedAddresses represents a list of WeightedAddress. +type WeightedAddresses []WeightedAddress + +// WeightedAddress represents an address with a given weight. +type WeightedAddress struct { + URL *url.URL + Expired time.Time +} + +// HasExpired will return whether or not the endpoint has expired with +// the exception of a zero expiry meaning does not expire. +func (e WeightedAddress) HasExpired() bool { + return e.Expired.Before(time.Now()) +} + +// Add will add a given WeightedAddress to the address list of Endpoint. +func (e *Endpoint) Add(addr WeightedAddress) { + e.Addresses = append(e.Addresses, addr) +} + +// Len returns the number of valid endpoints where valid means the endpoint +// has not expired. +func (e *Endpoint) Len() int { + validEndpoints := 0 + for _, endpoint := range e.Addresses { + if endpoint.HasExpired() { + continue + } + + validEndpoints++ + } + return validEndpoints +} + +// GetValidAddress will return a non-expired weight endpoint +func (e *Endpoint) GetValidAddress() (WeightedAddress, bool) { + for i := 0; i < len(e.Addresses); i++ { + we := e.Addresses[i] + + if we.HasExpired() { + e.Addresses = append(e.Addresses[:i], e.Addresses[i+1:]...) + i-- + continue + } + + we.URL = cloneURL(we.URL) + + return we, true + } + + return WeightedAddress{}, false +} + +// Prune will prune the expired addresses from the endpoint by allocating a new []WeightAddress. +// This is not concurrent safe, and should be called from a single owning thread. +func (e *Endpoint) Prune() bool { + validLen := e.Len() + if validLen == len(e.Addresses) { + return false + } + wa := make([]WeightedAddress, 0, validLen) + for i := range e.Addresses { + if e.Addresses[i].HasExpired() { + continue + } + wa = append(wa, e.Addresses[i]) + } + e.Addresses = wa + return true +} + +// Discoverer is an interface used to discovery which endpoint hit. This +// allows for specifics about what parameters need to be used to be contained +// in the Discoverer implementor. +type Discoverer interface { + Discover() (Endpoint, error) +} + +// BuildEndpointKey will sort the keys in alphabetical order and then retrieve +// the values in that order. Those values are then concatenated together to form +// the endpoint key. +func BuildEndpointKey(params map[string]*string) string { + keys := make([]string, len(params)) + i := 0 + + for k := range params { + keys[i] = k + i++ + } + sort.Strings(keys) + + values := make([]string, len(params)) + for i, k := range keys { + if params[k] == nil { + continue + } + + values[i] = aws.StringValue(params[k]) + } + + return strings.Join(values, ".") +} + +func cloneURL(u *url.URL) (clone *url.URL) { + clone = &url.URL{} + + *clone = *u + + if u.User != nil { + user := *u.User + clone.User = &user + } + + return clone +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/crr/sync_map.go b/vendor/github.com/aws/aws-sdk-go/aws/crr/sync_map.go new file mode 100644 index 0000000..f7b65ac --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/crr/sync_map.go @@ -0,0 +1,30 @@ +//go:build go1.9 +// +build go1.9 + +package crr + +import ( + "sync" +) + +type syncMap sync.Map + +func newSyncMap() syncMap { + return syncMap{} +} + +func (m *syncMap) Load(key interface{}) (interface{}, bool) { + return (*sync.Map)(m).Load(key) +} + +func (m *syncMap) Store(key interface{}, value interface{}) { + (*sync.Map)(m).Store(key, value) +} + +func (m *syncMap) Delete(key interface{}) { + (*sync.Map)(m).Delete(key) +} + +func (m *syncMap) Range(f func(interface{}, interface{}) bool) { + (*sync.Map)(m).Range(f) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/crr/sync_map_1_8.go b/vendor/github.com/aws/aws-sdk-go/aws/crr/sync_map_1_8.go new file mode 100644 index 0000000..eb4f6ac --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/crr/sync_map_1_8.go @@ -0,0 +1,49 @@ +//go:build !go1.9 +// +build !go1.9 + +package crr + +import ( + "sync" +) + +type syncMap struct { + container map[interface{}]interface{} + lock sync.RWMutex +} + +func newSyncMap() syncMap { + return syncMap{ + container: map[interface{}]interface{}{}, + } +} + +func (m *syncMap) Load(key interface{}) (interface{}, bool) { + m.lock.RLock() + defer m.lock.RUnlock() + + v, ok := m.container[key] + return v, ok +} + +func (m *syncMap) Store(key interface{}, value interface{}) { + m.lock.Lock() + defer m.lock.Unlock() + + m.container[key] = value +} + +func (m *syncMap) Delete(key interface{}) { + m.lock.Lock() + defer m.lock.Unlock() + + delete(m.container, key) +} + +func (m *syncMap) Range(f func(interface{}, interface{}) bool) { + for k, v := range m.container { + if !f(k, v) { + return + } + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/doc.go b/vendor/github.com/aws/aws-sdk-go/aws/doc.go new file mode 100644 index 0000000..4fcb616 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/doc.go @@ -0,0 +1,56 @@ +// Package aws provides the core SDK's utilities and shared types. Use this package's +// utilities to simplify setting and reading API operations parameters. +// +// Value and Pointer Conversion Utilities +// +// This package includes a helper conversion utility for each scalar type the SDK's +// API use. These utilities make getting a pointer of the scalar, and dereferencing +// a pointer easier. +// +// Each conversion utility comes in two forms. Value to Pointer and Pointer to Value. +// The Pointer to value will safely dereference the pointer and return its value. +// If the pointer was nil, the scalar's zero value will be returned. +// +// The value to pointer functions will be named after the scalar type. So get a +// *string from a string value use the "String" function. This makes it easy to +// to get pointer of a literal string value, because getting the address of a +// literal requires assigning the value to a variable first. +// +// var strPtr *string +// +// // Without the SDK's conversion functions +// str := "my string" +// strPtr = &str +// +// // With the SDK's conversion functions +// strPtr = aws.String("my string") +// +// // Convert *string to string value +// str = aws.StringValue(strPtr) +// +// In addition to scalars the aws package also includes conversion utilities for +// map and slice for commonly types used in API parameters. The map and slice +// conversion functions use similar naming pattern as the scalar conversion +// functions. +// +// var strPtrs []*string +// var strs []string = []string{"Go", "Gophers", "Go"} +// +// // Convert []string to []*string +// strPtrs = aws.StringSlice(strs) +// +// // Convert []*string to []string +// strs = aws.StringValueSlice(strPtrs) +// +// SDK Default HTTP Client +// +// The SDK will use the http.DefaultClient if a HTTP client is not provided to +// the SDK's Session, or service client constructor. This means that if the +// http.DefaultClient is modified by other components of your application the +// modifications will be picked up by the SDK as well. +// +// In some cases this might be intended, but it is a better practice to create +// a custom HTTP Client to share explicitly through your application. You can +// configure the SDK to use the custom HTTP Client by setting the HTTPClient +// value of the SDK's Config type when creating a Session or service client. +package aws diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/decode.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/decode.go new file mode 100644 index 0000000..8d65ca1 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/decode.go @@ -0,0 +1,193 @@ +package endpoints + +import ( + "encoding/json" + "fmt" + "io" + + "github.com/aws/aws-sdk-go/aws/awserr" +) + +type modelDefinition map[string]json.RawMessage + +// A DecodeModelOptions are the options for how the endpoints model definition +// are decoded. +type DecodeModelOptions struct { + SkipCustomizations bool +} + +// Set combines all of the option functions together. +func (d *DecodeModelOptions) Set(optFns ...func(*DecodeModelOptions)) { + for _, fn := range optFns { + fn(d) + } +} + +// DecodeModel unmarshals a Regions and Endpoint model definition file into +// a endpoint Resolver. If the file format is not supported, or an error occurs +// when unmarshaling the model an error will be returned. +// +// Casting the return value of this func to a EnumPartitions will +// allow you to get a list of the partitions in the order the endpoints +// will be resolved in. +// +// resolver, err := endpoints.DecodeModel(reader) +// +// partitions := resolver.(endpoints.EnumPartitions).Partitions() +// for _, p := range partitions { +// // ... inspect partitions +// } +func DecodeModel(r io.Reader, optFns ...func(*DecodeModelOptions)) (Resolver, error) { + var opts DecodeModelOptions + opts.Set(optFns...) + + // Get the version of the partition file to determine what + // unmarshaling model to use. + modelDef := modelDefinition{} + if err := json.NewDecoder(r).Decode(&modelDef); err != nil { + return nil, newDecodeModelError("failed to decode endpoints model", err) + } + + var version string + if b, ok := modelDef["version"]; ok { + version = string(b) + } else { + return nil, newDecodeModelError("endpoints version not found in model", nil) + } + + if version == "3" { + return decodeV3Endpoints(modelDef, opts) + } + + return nil, newDecodeModelError( + fmt.Sprintf("endpoints version %s, not supported", version), nil) +} + +func decodeV3Endpoints(modelDef modelDefinition, opts DecodeModelOptions) (Resolver, error) { + b, ok := modelDef["partitions"] + if !ok { + return nil, newDecodeModelError("endpoints model missing partitions", nil) + } + + ps := partitions{} + if err := json.Unmarshal(b, &ps); err != nil { + return nil, newDecodeModelError("failed to decode endpoints model", err) + } + + if opts.SkipCustomizations { + return ps, nil + } + + // Customization + for i := 0; i < len(ps); i++ { + p := &ps[i] + custRegionalS3(p) + custRmIotDataService(p) + custFixAppAutoscalingChina(p) + custFixAppAutoscalingUsGov(p) + } + + return ps, nil +} + +func custRegionalS3(p *partition) { + if p.ID != "aws" { + return + } + + service, ok := p.Services["s3"] + if !ok { + return + } + + const awsGlobal = "aws-global" + const usEast1 = "us-east-1" + + // If global endpoint already exists no customization needed. + if _, ok := service.Endpoints[endpointKey{Region: awsGlobal}]; ok { + return + } + + service.PartitionEndpoint = awsGlobal + if _, ok := service.Endpoints[endpointKey{Region: usEast1}]; !ok { + service.Endpoints[endpointKey{Region: usEast1}] = endpoint{} + } + service.Endpoints[endpointKey{Region: awsGlobal}] = endpoint{ + Hostname: "s3.amazonaws.com", + CredentialScope: credentialScope{ + Region: usEast1, + }, + } + + p.Services["s3"] = service +} + +func custRmIotDataService(p *partition) { + delete(p.Services, "data.iot") +} + +func custFixAppAutoscalingChina(p *partition) { + if p.ID != "aws-cn" { + return + } + + const serviceName = "application-autoscaling" + s, ok := p.Services[serviceName] + if !ok { + return + } + + const expectHostname = `autoscaling.{region}.amazonaws.com` + serviceDefault := s.Defaults[defaultKey{}] + if e, a := expectHostname, serviceDefault.Hostname; e != a { + fmt.Printf("custFixAppAutoscalingChina: ignoring customization, expected %s, got %s\n", e, a) + return + } + serviceDefault.Hostname = expectHostname + ".cn" + s.Defaults[defaultKey{}] = serviceDefault + p.Services[serviceName] = s +} + +func custFixAppAutoscalingUsGov(p *partition) { + if p.ID != "aws-us-gov" { + return + } + + const serviceName = "application-autoscaling" + s, ok := p.Services[serviceName] + if !ok { + return + } + + serviceDefault := s.Defaults[defaultKey{}] + if a := serviceDefault.CredentialScope.Service; a != "" { + fmt.Printf("custFixAppAutoscalingUsGov: ignoring customization, expected empty credential scope service, got %s\n", a) + return + } + + if a := serviceDefault.Hostname; a != "" { + fmt.Printf("custFixAppAutoscalingUsGov: ignoring customization, expected empty hostname, got %s\n", a) + return + } + + serviceDefault.CredentialScope.Service = "application-autoscaling" + serviceDefault.Hostname = "autoscaling.{region}.amazonaws.com" + + if s.Defaults == nil { + s.Defaults = make(endpointDefaults) + } + + s.Defaults[defaultKey{}] = serviceDefault + + p.Services[serviceName] = s +} + +type decodeModelError struct { + awsError +} + +func newDecodeModelError(msg string, err error) decodeModelError { + return decodeModelError{ + awsError: awserr.New("DecodeEndpointsModelError", msg, err), + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go new file mode 100644 index 0000000..e29642d --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go @@ -0,0 +1,28572 @@ +// Code generated by aws/endpoints/v3model_codegen.go. DO NOT EDIT. + +package endpoints + +import ( + "regexp" +) + +// Partition identifiers +const ( + AwsPartitionID = "aws" // AWS Standard partition. + AwsCnPartitionID = "aws-cn" // AWS China partition. + AwsUsGovPartitionID = "aws-us-gov" // AWS GovCloud (US) partition. + AwsIsoPartitionID = "aws-iso" // AWS ISO (US) partition. + AwsIsoBPartitionID = "aws-iso-b" // AWS ISOB (US) partition. +) + +// AWS Standard partition's regions. +const ( + AfSouth1RegionID = "af-south-1" // Africa (Cape Town). + ApEast1RegionID = "ap-east-1" // Asia Pacific (Hong Kong). + ApNortheast1RegionID = "ap-northeast-1" // Asia Pacific (Tokyo). + ApNortheast2RegionID = "ap-northeast-2" // Asia Pacific (Seoul). + ApNortheast3RegionID = "ap-northeast-3" // Asia Pacific (Osaka). + ApSouth1RegionID = "ap-south-1" // Asia Pacific (Mumbai). + ApSoutheast1RegionID = "ap-southeast-1" // Asia Pacific (Singapore). + ApSoutheast2RegionID = "ap-southeast-2" // Asia Pacific (Sydney). + ApSoutheast3RegionID = "ap-southeast-3" // Asia Pacific (Jakarta). + CaCentral1RegionID = "ca-central-1" // Canada (Central). + EuCentral1RegionID = "eu-central-1" // Europe (Frankfurt). + EuNorth1RegionID = "eu-north-1" // Europe (Stockholm). + EuSouth1RegionID = "eu-south-1" // Europe (Milan). + EuWest1RegionID = "eu-west-1" // Europe (Ireland). + EuWest2RegionID = "eu-west-2" // Europe (London). + EuWest3RegionID = "eu-west-3" // Europe (Paris). + MeSouth1RegionID = "me-south-1" // Middle East (Bahrain). + SaEast1RegionID = "sa-east-1" // South America (Sao Paulo). + UsEast1RegionID = "us-east-1" // US East (N. Virginia). + UsEast2RegionID = "us-east-2" // US East (Ohio). + UsWest1RegionID = "us-west-1" // US West (N. California). + UsWest2RegionID = "us-west-2" // US West (Oregon). +) + +// AWS China partition's regions. +const ( + CnNorth1RegionID = "cn-north-1" // China (Beijing). + CnNorthwest1RegionID = "cn-northwest-1" // China (Ningxia). +) + +// AWS GovCloud (US) partition's regions. +const ( + UsGovEast1RegionID = "us-gov-east-1" // AWS GovCloud (US-East). + UsGovWest1RegionID = "us-gov-west-1" // AWS GovCloud (US-West). +) + +// AWS ISO (US) partition's regions. +const ( + UsIsoEast1RegionID = "us-iso-east-1" // US ISO East. + UsIsoWest1RegionID = "us-iso-west-1" // US ISO WEST. +) + +// AWS ISOB (US) partition's regions. +const ( + UsIsobEast1RegionID = "us-isob-east-1" // US ISOB East (Ohio). +) + +// DefaultResolver returns an Endpoint resolver that will be able +// to resolve endpoints for: AWS Standard, AWS China, AWS GovCloud (US), AWS ISO (US), and AWS ISOB (US). +// +// Use DefaultPartitions() to get the list of the default partitions. +func DefaultResolver() Resolver { + return defaultPartitions +} + +// DefaultPartitions returns a list of the partitions the SDK is bundled +// with. The available partitions are: AWS Standard, AWS China, AWS GovCloud (US), AWS ISO (US), and AWS ISOB (US). +// +// partitions := endpoints.DefaultPartitions +// for _, p := range partitions { +// // ... inspect partitions +// } +func DefaultPartitions() []Partition { + return defaultPartitions.Partitions() +} + +var defaultPartitions = partitions{ + awsPartition, + awscnPartition, + awsusgovPartition, + awsisoPartition, + awsisobPartition, +} + +// AwsPartition returns the Resolver for AWS Standard. +func AwsPartition() Partition { + return awsPartition.Partition() +} + +var awsPartition = partition{ + ID: "aws", + Name: "AWS Standard", + DNSSuffix: "amazonaws.com", + RegionRegex: regionRegex{ + Regexp: func() *regexp.Regexp { + reg, _ := regexp.Compile("^(us|eu|ap|sa|ca|me|af)\\-\\w+\\-\\d+$") + return reg + }(), + }, + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Hostname: "{service}.{region}.{dnsSuffix}", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + defaultKey{ + Variant: dualStackVariant, + }: endpoint{ + Hostname: "{service}.{region}.{dnsSuffix}", + DNSSuffix: "api.aws", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "{service}-fips.{region}.{dnsSuffix}", + DNSSuffix: "amazonaws.com", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + defaultKey{ + Variant: fipsVariant | dualStackVariant, + }: endpoint{ + Hostname: "{service}-fips.{region}.{dnsSuffix}", + DNSSuffix: "api.aws", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + }, + Regions: regions{ + "af-south-1": region{ + Description: "Africa (Cape Town)", + }, + "ap-east-1": region{ + Description: "Asia Pacific (Hong Kong)", + }, + "ap-northeast-1": region{ + Description: "Asia Pacific (Tokyo)", + }, + "ap-northeast-2": region{ + Description: "Asia Pacific (Seoul)", + }, + "ap-northeast-3": region{ + Description: "Asia Pacific (Osaka)", + }, + "ap-south-1": region{ + Description: "Asia Pacific (Mumbai)", + }, + "ap-southeast-1": region{ + Description: "Asia Pacific (Singapore)", + }, + "ap-southeast-2": region{ + Description: "Asia Pacific (Sydney)", + }, + "ap-southeast-3": region{ + Description: "Asia Pacific (Jakarta)", + }, + "ca-central-1": region{ + Description: "Canada (Central)", + }, + "eu-central-1": region{ + Description: "Europe (Frankfurt)", + }, + "eu-north-1": region{ + Description: "Europe (Stockholm)", + }, + "eu-south-1": region{ + Description: "Europe (Milan)", + }, + "eu-west-1": region{ + Description: "Europe (Ireland)", + }, + "eu-west-2": region{ + Description: "Europe (London)", + }, + "eu-west-3": region{ + Description: "Europe (Paris)", + }, + "me-south-1": region{ + Description: "Middle East (Bahrain)", + }, + "sa-east-1": region{ + Description: "South America (Sao Paulo)", + }, + "us-east-1": region{ + Description: "US East (N. Virginia)", + }, + "us-east-2": region{ + Description: "US East (Ohio)", + }, + "us-west-1": region{ + Description: "US West (N. California)", + }, + "us-west-2": region{ + Description: "US West (Oregon)", + }, + }, + Services: services{ + "a4b": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + }, + }, + "access-analyzer": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "access-analyzer-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-ca-central-1", + }: endpoint{ + Hostname: "access-analyzer-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "access-analyzer-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "access-analyzer-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "access-analyzer-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "access-analyzer-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "access-analyzer-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "access-analyzer-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "access-analyzer-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "access-analyzer-fips.us-west-2.amazonaws.com", + }, + }, + }, + "account": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-global", + }: endpoint{ + Hostname: "account.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + }, + }, + "acm": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "acm-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "ca-central-1-fips", + }: endpoint{ + Hostname: "acm-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "acm-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-1-fips", + }: endpoint{ + Hostname: "acm-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "acm-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2-fips", + }: endpoint{ + Hostname: "acm-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "acm-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1-fips", + }: endpoint{ + Hostname: "acm-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "acm-fips.us-west-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2-fips", + }: endpoint{ + Hostname: "acm-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + }, + }, + "acm-pca": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "acm-pca-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-ca-central-1", + }: endpoint{ + Hostname: "acm-pca-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "acm-pca-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "acm-pca-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "acm-pca-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "acm-pca-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "acm-pca-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "acm-pca-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "acm-pca-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "acm-pca-fips.us-west-2.amazonaws.com", + }, + }, + }, + "airflow": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "amplify": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "amplifybackend": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "api.detective": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "api.detective-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-1-fips", + }: endpoint{ + Hostname: "api.detective-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "api.detective-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2-fips", + }: endpoint{ + Hostname: "api.detective-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "api.detective-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1-fips", + }: endpoint{ + Hostname: "api.detective-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "api.detective-fips.us-west-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2-fips", + }: endpoint{ + Hostname: "api.detective-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + }, + }, + "api.ecr": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{}, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "ecr-fips.{region}.{dnsSuffix}", + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{ + Hostname: "api.ecr.af-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "af-south-1", + }, + }, + endpointKey{ + Region: "ap-east-1", + }: endpoint{ + Hostname: "api.ecr.ap-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-east-1", + }, + }, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{ + Hostname: "api.ecr.ap-northeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-1", + }, + }, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{ + Hostname: "api.ecr.ap-northeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-2", + }, + }, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{ + Hostname: "api.ecr.ap-northeast-3.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-3", + }, + }, + endpointKey{ + Region: "ap-south-1", + }: endpoint{ + Hostname: "api.ecr.ap-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-south-1", + }, + }, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{ + Hostname: "api.ecr.ap-southeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-1", + }, + }, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{ + Hostname: "api.ecr.ap-southeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-2", + }, + }, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{ + Hostname: "api.ecr.ap-southeast-3.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-3", + }, + }, + endpointKey{ + Region: "ca-central-1", + }: endpoint{ + Hostname: "api.ecr.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + }, + endpointKey{ + Region: "dkr-us-east-1", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "dkr-us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ecr-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "dkr-us-east-2", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "dkr-us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ecr-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "dkr-us-west-1", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "dkr-us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ecr-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "dkr-us-west-2", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "dkr-us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ecr-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{ + Hostname: "api.ecr.eu-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-central-1", + }, + }, + endpointKey{ + Region: "eu-north-1", + }: endpoint{ + Hostname: "api.ecr.eu-north-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-north-1", + }, + }, + endpointKey{ + Region: "eu-south-1", + }: endpoint{ + Hostname: "api.ecr.eu-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-south-1", + }, + }, + endpointKey{ + Region: "eu-west-1", + }: endpoint{ + Hostname: "api.ecr.eu-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-1", + }, + }, + endpointKey{ + Region: "eu-west-2", + }: endpoint{ + Hostname: "api.ecr.eu-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-2", + }, + }, + endpointKey{ + Region: "eu-west-3", + }: endpoint{ + Hostname: "api.ecr.eu-west-3.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-3", + }, + }, + endpointKey{ + Region: "fips-dkr-us-east-1", + }: endpoint{ + Hostname: "ecr-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-dkr-us-east-2", + }: endpoint{ + Hostname: "ecr-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-dkr-us-west-1", + }: endpoint{ + Hostname: "ecr-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-dkr-us-west-2", + }: endpoint{ + Hostname: "ecr-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "ecr-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "ecr-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "ecr-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "ecr-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{ + Hostname: "api.ecr.me-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "me-south-1", + }, + }, + endpointKey{ + Region: "sa-east-1", + }: endpoint{ + Hostname: "api.ecr.sa-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "sa-east-1", + }, + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{ + Hostname: "api.ecr.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ecr-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{ + Hostname: "api.ecr.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ecr-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{ + Hostname: "api.ecr.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + }, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ecr-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{ + Hostname: "api.ecr.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ecr-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + "api.elastic-inference": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{ + Hostname: "api.elastic-inference.ap-northeast-1.amazonaws.com", + }, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{ + Hostname: "api.elastic-inference.ap-northeast-2.amazonaws.com", + }, + endpointKey{ + Region: "eu-west-1", + }: endpoint{ + Hostname: "api.elastic-inference.eu-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{ + Hostname: "api.elastic-inference.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{ + Hostname: "api.elastic-inference.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{ + Hostname: "api.elastic-inference.us-west-2.amazonaws.com", + }, + }, + }, + "api.fleethub.iot": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "api.fleethub.iot-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "fips-ca-central-1", + }: endpoint{ + Hostname: "api.fleethub.iot-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "api.fleethub.iot-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "api.fleethub.iot-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "api.fleethub.iot-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "api.fleethub.iot-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "api.fleethub.iot-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "api.fleethub.iot-fips.us-west-2.amazonaws.com", + }, + }, + }, + "api.iotwireless": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{ + Hostname: "api.iotwireless.ap-northeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-1", + }, + }, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{ + Hostname: "api.iotwireless.ap-southeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-2", + }, + }, + endpointKey{ + Region: "eu-west-1", + }: endpoint{ + Hostname: "api.iotwireless.eu-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-1", + }, + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{ + Hostname: "api.iotwireless.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{ + Hostname: "api.iotwireless.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + "api.mediatailor": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "api.pricing": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + CredentialScope: credentialScope{ + Service: "pricing", + }, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + }, + }, + "api.sagemaker": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{}, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "api-fips.sagemaker.{region}.{dnsSuffix}", + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "api-fips.sagemaker.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-1-fips", + }: endpoint{ + Hostname: "api-fips.sagemaker.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "api-fips.sagemaker.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2-fips", + }: endpoint{ + Hostname: "api-fips.sagemaker.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "api-fips.sagemaker.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1-fips", + }: endpoint{ + Hostname: "api-fips.sagemaker.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "api-fips.sagemaker.us-west-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2-fips", + }: endpoint{ + Hostname: "api-fips.sagemaker.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + }, + }, + "apigateway": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "app-integrations": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "appconfigdata": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "appflow": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "application-autoscaling": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "applicationinsights": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "appmesh": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "apprunner": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "appstream2": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + CredentialScope: credentialScope{ + Service: "appstream", + }, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "fips", + }: endpoint{ + Hostname: "appstream2-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "appstream2-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-1-fips", + }: endpoint{ + Hostname: "appstream2-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "appstream2-fips.us-west-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2-fips", + }: endpoint{ + Hostname: "appstream2-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + }, + }, + "appsync": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "aps": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "athena": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "athena-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "athena-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "athena-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "athena-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "athena-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "athena-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "athena-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "athena-fips.us-west-2.amazonaws.com", + }, + }, + }, + "auditmanager": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "autoscaling": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "autoscaling-plans": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "backup": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "batch": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{}, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "fips.batch.{region}.{dnsSuffix}", + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "fips.batch.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "fips.batch.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "fips.batch.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "fips.batch.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fips.batch.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fips.batch.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fips.batch.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fips.batch.us-west-2.amazonaws.com", + }, + }, + }, + "braket": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "budgets": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-global", + }: endpoint{ + Hostname: "budgets.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + }, + }, + "ce": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-global", + }: endpoint{ + Hostname: "ce.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + }, + }, + "chime": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-global", + }: endpoint{ + Hostname: "chime.us-east-1.amazonaws.com", + Protocols: []string{"https"}, + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + }, + }, + "cloud9": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "cloudcontrolapi": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "cloudcontrolapi-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-ca-central-1", + }: endpoint{ + Hostname: "cloudcontrolapi-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "cloudcontrolapi-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "cloudcontrolapi-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "cloudcontrolapi-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "cloudcontrolapi-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "cloudcontrolapi-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "cloudcontrolapi-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "cloudcontrolapi-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "cloudcontrolapi-fips.us-west-2.amazonaws.com", + }, + }, + }, + "clouddirectory": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "cloudformation": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "cloudformation-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-1-fips", + }: endpoint{ + Hostname: "cloudformation-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "cloudformation-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2-fips", + }: endpoint{ + Hostname: "cloudformation-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "cloudformation-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1-fips", + }: endpoint{ + Hostname: "cloudformation-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "cloudformation-fips.us-west-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2-fips", + }: endpoint{ + Hostname: "cloudformation-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + }, + }, + "cloudfront": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-global", + }: endpoint{ + Hostname: "cloudfront.amazonaws.com", + Protocols: []string{"http", "https"}, + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + }, + }, + "cloudhsm": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + }, + }, + "cloudhsmv2": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + CredentialScope: credentialScope{ + Service: "cloudhsm", + }, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "cloudsearch": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "cloudtrail": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "cloudtrail-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "cloudtrail-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "cloudtrail-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "cloudtrail-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "cloudtrail-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "cloudtrail-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "cloudtrail-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "cloudtrail-fips.us-west-2.amazonaws.com", + }, + }, + }, + "codeartifact": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "codebuild": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "codebuild-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-1-fips", + }: endpoint{ + Hostname: "codebuild-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "codebuild-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2-fips", + }: endpoint{ + Hostname: "codebuild-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "codebuild-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1-fips", + }: endpoint{ + Hostname: "codebuild-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "codebuild-fips.us-west-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2-fips", + }: endpoint{ + Hostname: "codebuild-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + }, + }, + "codecommit": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "codecommit-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "ca-central-1-fips", + }: endpoint{ + Hostname: "codecommit-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips", + }: endpoint{ + Hostname: "codecommit-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "codecommit-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-1-fips", + }: endpoint{ + Hostname: "codecommit-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "codecommit-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2-fips", + }: endpoint{ + Hostname: "codecommit-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "codecommit-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1-fips", + }: endpoint{ + Hostname: "codecommit-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "codecommit-fips.us-west-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2-fips", + }: endpoint{ + Hostname: "codecommit-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + }, + }, + "codedeploy": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "codedeploy-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-1-fips", + }: endpoint{ + Hostname: "codedeploy-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "codedeploy-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2-fips", + }: endpoint{ + Hostname: "codedeploy-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "codedeploy-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1-fips", + }: endpoint{ + Hostname: "codedeploy-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "codedeploy-fips.us-west-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2-fips", + }: endpoint{ + Hostname: "codedeploy-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + }, + }, + "codeguru-reviewer": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "codepipeline": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "codepipeline-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-ca-central-1", + }: endpoint{ + Hostname: "codepipeline-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "codepipeline-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "codepipeline-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "codepipeline-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "codepipeline-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "codepipeline-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "codepipeline-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "codepipeline-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "codepipeline-fips.us-west-2.amazonaws.com", + }, + }, + }, + "codestar": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "codestar-connections": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "cognito-identity": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "cognito-identity-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "cognito-identity-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "cognito-identity-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "cognito-identity-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "cognito-identity-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "cognito-identity-fips.us-west-2.amazonaws.com", + }, + }, + }, + "cognito-idp": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "cognito-idp-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "cognito-idp-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "cognito-idp-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "cognito-idp-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "cognito-idp-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "cognito-idp-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "cognito-idp-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "cognito-idp-fips.us-west-2.amazonaws.com", + }, + }, + }, + "cognito-sync": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "comprehend": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "comprehend-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "comprehend-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "comprehend-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "comprehend-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "comprehend-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "comprehend-fips.us-west-2.amazonaws.com", + }, + }, + }, + "comprehendmedical": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "comprehendmedical-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "comprehendmedical-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "comprehendmedical-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "comprehendmedical-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "comprehendmedical-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "comprehendmedical-fips.us-west-2.amazonaws.com", + }, + }, + }, + "compute-optimizer": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{ + Hostname: "compute-optimizer.ap-northeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-1", + }, + }, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{ + Hostname: "compute-optimizer.ap-northeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-2", + }, + }, + endpointKey{ + Region: "ap-south-1", + }: endpoint{ + Hostname: "compute-optimizer.ap-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-south-1", + }, + }, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{ + Hostname: "compute-optimizer.ap-southeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-1", + }, + }, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{ + Hostname: "compute-optimizer.ap-southeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-2", + }, + }, + endpointKey{ + Region: "ca-central-1", + }: endpoint{ + Hostname: "compute-optimizer.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{ + Hostname: "compute-optimizer.eu-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-central-1", + }, + }, + endpointKey{ + Region: "eu-north-1", + }: endpoint{ + Hostname: "compute-optimizer.eu-north-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-north-1", + }, + }, + endpointKey{ + Region: "eu-west-1", + }: endpoint{ + Hostname: "compute-optimizer.eu-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-1", + }, + }, + endpointKey{ + Region: "eu-west-2", + }: endpoint{ + Hostname: "compute-optimizer.eu-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-2", + }, + }, + endpointKey{ + Region: "eu-west-3", + }: endpoint{ + Hostname: "compute-optimizer.eu-west-3.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-3", + }, + }, + endpointKey{ + Region: "sa-east-1", + }: endpoint{ + Hostname: "compute-optimizer.sa-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "sa-east-1", + }, + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{ + Hostname: "compute-optimizer.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{ + Hostname: "compute-optimizer.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{ + Hostname: "compute-optimizer.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{ + Hostname: "compute-optimizer.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + "config": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "config-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "config-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "config-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "config-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "config-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "config-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "config-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "config-fips.us-west-2.amazonaws.com", + }, + }, + }, + "connect": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "contact-lens": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "cur": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + }, + }, + "data.jobs.iot": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "data.jobs.iot-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-ca-central-1", + }: endpoint{ + Hostname: "data.jobs.iot-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "data.jobs.iot-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "data.jobs.iot-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "data.jobs.iot-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "data.jobs.iot-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "data.jobs.iot-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "data.jobs.iot-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "data.jobs.iot-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "data.jobs.iot-fips.us-west-2.amazonaws.com", + }, + }, + }, + "data.mediastore": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "databrew": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "dataexchange": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "datapipeline": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "datasync": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "datasync-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-ca-central-1", + }: endpoint{ + Hostname: "datasync-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "datasync-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "datasync-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "datasync-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "datasync-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "datasync-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "datasync-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "datasync-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "datasync-fips.us-west-2.amazonaws.com", + }, + }, + }, + "dax": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "devicefarm": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "directconnect": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "directconnect-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "directconnect-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "directconnect-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "directconnect-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "directconnect-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "directconnect-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "directconnect-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "directconnect-fips.us-west-2.amazonaws.com", + }, + }, + }, + "discovery": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "dms": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "dms", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "dms", + Variant: fipsVariant, + }: endpoint{ + Hostname: "dms-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "dms-fips", + }: endpoint{ + Hostname: "dms-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "dms-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-1-fips", + }: endpoint{ + Hostname: "dms-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "dms-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2-fips", + }: endpoint{ + Hostname: "dms-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "dms-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1-fips", + }: endpoint{ + Hostname: "dms-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "dms-fips.us-west-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2-fips", + }: endpoint{ + Hostname: "dms-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + }, + }, + "docdb": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{ + Hostname: "rds.ap-northeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-1", + }, + }, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{ + Hostname: "rds.ap-northeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-2", + }, + }, + endpointKey{ + Region: "ap-south-1", + }: endpoint{ + Hostname: "rds.ap-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-south-1", + }, + }, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{ + Hostname: "rds.ap-southeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-1", + }, + }, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{ + Hostname: "rds.ap-southeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-2", + }, + }, + endpointKey{ + Region: "ca-central-1", + }: endpoint{ + Hostname: "rds.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{ + Hostname: "rds.eu-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-central-1", + }, + }, + endpointKey{ + Region: "eu-west-1", + }: endpoint{ + Hostname: "rds.eu-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-1", + }, + }, + endpointKey{ + Region: "eu-west-2", + }: endpoint{ + Hostname: "rds.eu-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-2", + }, + }, + endpointKey{ + Region: "eu-west-3", + }: endpoint{ + Hostname: "rds.eu-west-3.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-3", + }, + }, + endpointKey{ + Region: "sa-east-1", + }: endpoint{ + Hostname: "rds.sa-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "sa-east-1", + }, + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{ + Hostname: "rds.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{ + Hostname: "rds.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{ + Hostname: "rds.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + "drs": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "ds": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ds-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-ca-central-1", + }: endpoint{ + Hostname: "ds-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "ds-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "ds-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "ds-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "ds-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ds-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ds-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ds-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ds-fips.us-west-2.amazonaws.com", + }, + }, + }, + "dynamodb": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "dynamodb-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "ca-central-1-fips", + }: endpoint{ + Hostname: "dynamodb-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "local", + }: endpoint{ + Hostname: "localhost:8000", + Protocols: []string{"http"}, + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "dynamodb-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-1-fips", + }: endpoint{ + Hostname: "dynamodb-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "dynamodb-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2-fips", + }: endpoint{ + Hostname: "dynamodb-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "dynamodb-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1-fips", + }: endpoint{ + Hostname: "dynamodb-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "dynamodb-fips.us-west-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2-fips", + }: endpoint{ + Hostname: "dynamodb-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + }, + }, + "ebs": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ebs-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-ca-central-1", + }: endpoint{ + Hostname: "ebs-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "ebs-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "ebs-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "ebs-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "ebs-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ebs-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ebs-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ebs-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ebs-fips.us-west-2.amazonaws.com", + }, + }, + }, + "ec2": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "api.ec2.ap-south-1.aws", + }, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ec2-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "api.ec2.eu-west-1.aws", + }, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-ca-central-1", + }: endpoint{ + Hostname: "ec2-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "ec2-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "ec2-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "ec2-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "ec2-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "api.ec2.sa-east-1.aws", + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "api.ec2.us-east-1.aws", + }, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ec2-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "api.ec2.us-east-2.aws", + }, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ec2-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ec2-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "api.ec2.us-west-2.aws", + }, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ec2-fips.us-west-2.amazonaws.com", + }, + }, + }, + "ecs": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "ecs-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "ecs-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "ecs-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "ecs-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ecs-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ecs-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ecs-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ecs-fips.us-west-2.amazonaws.com", + }, + }, + }, + "eks": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + }, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "fips.eks.{region}.{dnsSuffix}", + Protocols: []string{"http", "https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "fips.eks.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "fips.eks.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "fips.eks.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "fips.eks.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fips.eks.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fips.eks.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fips.eks.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fips.eks.us-west-2.amazonaws.com", + }, + }, + }, + "elasticache": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips", + }: endpoint{ + Hostname: "elasticache-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticache-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-1-fips", + }: endpoint{ + Hostname: "elasticache-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticache-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2-fips", + }: endpoint{ + Hostname: "elasticache-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticache-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1-fips", + }: endpoint{ + Hostname: "elasticache-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticache-fips.us-west-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2-fips", + }: endpoint{ + Hostname: "elasticache-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + }, + }, + "elasticbeanstalk": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "elasticbeanstalk-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "elasticbeanstalk-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "elasticbeanstalk-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "elasticbeanstalk-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticbeanstalk-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticbeanstalk-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticbeanstalk-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticbeanstalk-fips.us-west-2.amazonaws.com", + }, + }, + }, + "elasticfilesystem": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "af-south-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticfilesystem-fips.af-south-1.amazonaws.com", + }, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticfilesystem-fips.ap-east-1.amazonaws.com", + }, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticfilesystem-fips.ap-northeast-1.amazonaws.com", + }, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticfilesystem-fips.ap-northeast-2.amazonaws.com", + }, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticfilesystem-fips.ap-northeast-3.amazonaws.com", + }, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticfilesystem-fips.ap-south-1.amazonaws.com", + }, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticfilesystem-fips.ap-southeast-1.amazonaws.com", + }, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticfilesystem-fips.ap-southeast-2.amazonaws.com", + }, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticfilesystem-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticfilesystem-fips.eu-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticfilesystem-fips.eu-north-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticfilesystem-fips.eu-south-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticfilesystem-fips.eu-west-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticfilesystem-fips.eu-west-2.amazonaws.com", + }, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticfilesystem-fips.eu-west-3.amazonaws.com", + }, + endpointKey{ + Region: "fips-af-south-1", + }: endpoint{ + Hostname: "elasticfilesystem-fips.af-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "af-south-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-ap-east-1", + }: endpoint{ + Hostname: "elasticfilesystem-fips.ap-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-ap-northeast-1", + }: endpoint{ + Hostname: "elasticfilesystem-fips.ap-northeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-ap-northeast-2", + }: endpoint{ + Hostname: "elasticfilesystem-fips.ap-northeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-ap-northeast-3", + }: endpoint{ + Hostname: "elasticfilesystem-fips.ap-northeast-3.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-3", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-ap-south-1", + }: endpoint{ + Hostname: "elasticfilesystem-fips.ap-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-south-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-ap-southeast-1", + }: endpoint{ + Hostname: "elasticfilesystem-fips.ap-southeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-ap-southeast-2", + }: endpoint{ + Hostname: "elasticfilesystem-fips.ap-southeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-ca-central-1", + }: endpoint{ + Hostname: "elasticfilesystem-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-eu-central-1", + }: endpoint{ + Hostname: "elasticfilesystem-fips.eu-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-eu-north-1", + }: endpoint{ + Hostname: "elasticfilesystem-fips.eu-north-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-north-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-eu-south-1", + }: endpoint{ + Hostname: "elasticfilesystem-fips.eu-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-south-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-eu-west-1", + }: endpoint{ + Hostname: "elasticfilesystem-fips.eu-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-eu-west-2", + }: endpoint{ + Hostname: "elasticfilesystem-fips.eu-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-eu-west-3", + }: endpoint{ + Hostname: "elasticfilesystem-fips.eu-west-3.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-3", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-me-south-1", + }: endpoint{ + Hostname: "elasticfilesystem-fips.me-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "me-south-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-sa-east-1", + }: endpoint{ + Hostname: "elasticfilesystem-fips.sa-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "sa-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "elasticfilesystem-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "elasticfilesystem-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "elasticfilesystem-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "elasticfilesystem-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticfilesystem-fips.me-south-1.amazonaws.com", + }, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticfilesystem-fips.sa-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticfilesystem-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticfilesystem-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticfilesystem-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticfilesystem-fips.us-west-2.amazonaws.com", + }, + }, + }, + "elasticloadbalancing": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "elasticloadbalancing-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "elasticloadbalancing-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "elasticloadbalancing-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "elasticloadbalancing-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticloadbalancing-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticloadbalancing-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticloadbalancing-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticloadbalancing-fips.us-west-2.amazonaws.com", + }, + }, + }, + "elasticmapreduce": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + SSLCommonName: "{region}.{service}.{dnsSuffix}", + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticmapreduce-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{ + SSLCommonName: "{service}.{region}.{dnsSuffix}", + }, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-ca-central-1", + }: endpoint{ + Hostname: "elasticmapreduce-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "elasticmapreduce-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "elasticmapreduce-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "elasticmapreduce-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "elasticmapreduce-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{ + SSLCommonName: "{service}.{region}.{dnsSuffix}", + }, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticmapreduce-fips.us-east-1.amazonaws.com", + SSLCommonName: "{service}.{region}.{dnsSuffix}", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticmapreduce-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticmapreduce-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticmapreduce-fips.us-west-2.amazonaws.com", + }, + }, + }, + "elastictranscoder": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "email": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "emr-containers": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "emr-containers-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-ca-central-1", + }: endpoint{ + Hostname: "emr-containers-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "emr-containers-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "emr-containers-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "emr-containers-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "emr-containers-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "emr-containers-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "emr-containers-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "emr-containers-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "emr-containers-fips.us-west-2.amazonaws.com", + }, + }, + }, + "entitlement.marketplace": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + CredentialScope: credentialScope{ + Service: "aws-marketplace", + }, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + }, + }, + "es": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips", + }: endpoint{ + Hostname: "es-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "es-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-1-fips", + }: endpoint{ + Hostname: "es-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "es-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2-fips", + }: endpoint{ + Hostname: "es-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "es-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1-fips", + }: endpoint{ + Hostname: "es-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "es-fips.us-west-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2-fips", + }: endpoint{ + Hostname: "es-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + }, + }, + "events": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "events-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "events-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "events-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "events-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "events-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "events-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "events-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "events-fips.us-west-2.amazonaws.com", + }, + }, + }, + "evidently": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{ + Hostname: "evidently.ap-northeast-1.amazonaws.com", + }, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{ + Hostname: "evidently.ap-southeast-1.amazonaws.com", + }, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{ + Hostname: "evidently.ap-southeast-2.amazonaws.com", + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{ + Hostname: "evidently.eu-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-north-1", + }: endpoint{ + Hostname: "evidently.eu-north-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-west-1", + }: endpoint{ + Hostname: "evidently.eu-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{ + Hostname: "evidently.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{ + Hostname: "evidently.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{ + Hostname: "evidently.us-west-2.amazonaws.com", + }, + }, + }, + "finspace": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "finspace-api": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "firehose": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "firehose-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "firehose-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "firehose-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "firehose-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "firehose-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "firehose-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "firehose-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "firehose-fips.us-west-2.amazonaws.com", + }, + }, + }, + "fms": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "af-south-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fms-fips.af-south-1.amazonaws.com", + }, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fms-fips.ap-east-1.amazonaws.com", + }, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fms-fips.ap-northeast-1.amazonaws.com", + }, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fms-fips.ap-northeast-2.amazonaws.com", + }, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fms-fips.ap-south-1.amazonaws.com", + }, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fms-fips.ap-southeast-1.amazonaws.com", + }, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fms-fips.ap-southeast-2.amazonaws.com", + }, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fms-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fms-fips.eu-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fms-fips.eu-south-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fms-fips.eu-west-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fms-fips.eu-west-2.amazonaws.com", + }, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fms-fips.eu-west-3.amazonaws.com", + }, + endpointKey{ + Region: "fips-af-south-1", + }: endpoint{ + Hostname: "fms-fips.af-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "af-south-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-ap-east-1", + }: endpoint{ + Hostname: "fms-fips.ap-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-ap-northeast-1", + }: endpoint{ + Hostname: "fms-fips.ap-northeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-ap-northeast-2", + }: endpoint{ + Hostname: "fms-fips.ap-northeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-ap-south-1", + }: endpoint{ + Hostname: "fms-fips.ap-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-south-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-ap-southeast-1", + }: endpoint{ + Hostname: "fms-fips.ap-southeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-ap-southeast-2", + }: endpoint{ + Hostname: "fms-fips.ap-southeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-ca-central-1", + }: endpoint{ + Hostname: "fms-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-eu-central-1", + }: endpoint{ + Hostname: "fms-fips.eu-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-eu-south-1", + }: endpoint{ + Hostname: "fms-fips.eu-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-south-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-eu-west-1", + }: endpoint{ + Hostname: "fms-fips.eu-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-eu-west-2", + }: endpoint{ + Hostname: "fms-fips.eu-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-eu-west-3", + }: endpoint{ + Hostname: "fms-fips.eu-west-3.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-3", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-me-south-1", + }: endpoint{ + Hostname: "fms-fips.me-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "me-south-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-sa-east-1", + }: endpoint{ + Hostname: "fms-fips.sa-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "sa-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "fms-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "fms-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "fms-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "fms-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fms-fips.me-south-1.amazonaws.com", + }, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fms-fips.sa-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fms-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fms-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fms-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fms-fips.us-west-2.amazonaws.com", + }, + }, + }, + "forecast": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "forecast-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "forecast-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "forecast-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "forecast-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "forecast-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "forecast-fips.us-west-2.amazonaws.com", + }, + }, + }, + "forecastquery": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "forecastquery-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "forecastquery-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "forecastquery-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "forecastquery-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "forecastquery-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "forecastquery-fips.us-west-2.amazonaws.com", + }, + }, + }, + "frauddetector": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "fsx": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fsx-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-ca-central-1", + }: endpoint{ + Hostname: "fsx-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-prod-ca-central-1", + }: endpoint{ + Hostname: "fsx-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-prod-us-east-1", + }: endpoint{ + Hostname: "fsx-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-prod-us-east-2", + }: endpoint{ + Hostname: "fsx-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-prod-us-west-1", + }: endpoint{ + Hostname: "fsx-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-prod-us-west-2", + }: endpoint{ + Hostname: "fsx-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "fsx-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "fsx-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "fsx-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "fsx-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "prod-ca-central-1", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "prod-ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fsx-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "prod-us-east-1", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "prod-us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fsx-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "prod-us-east-2", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "prod-us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fsx-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "prod-us-west-1", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "prod-us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fsx-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "prod-us-west-2", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "prod-us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fsx-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fsx-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fsx-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fsx-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fsx-fips.us-west-2.amazonaws.com", + }, + }, + }, + "gamelift": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "glacier": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "glacier-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-ca-central-1", + }: endpoint{ + Hostname: "glacier-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "glacier-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "glacier-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "glacier-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "glacier-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "glacier-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "glacier-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "glacier-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "glacier-fips.us-west-2.amazonaws.com", + }, + }, + }, + "glue": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "glue-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "glue-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "glue-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "glue-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "glue-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "glue-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "glue-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "glue-fips.us-west-2.amazonaws.com", + }, + }, + }, + "grafana": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{ + Hostname: "grafana.ap-northeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-1", + }, + }, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{ + Hostname: "grafana.ap-northeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-2", + }, + }, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{ + Hostname: "grafana.ap-southeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-1", + }, + }, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{ + Hostname: "grafana.ap-southeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-2", + }, + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{ + Hostname: "grafana.eu-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-central-1", + }, + }, + endpointKey{ + Region: "eu-west-1", + }: endpoint{ + Hostname: "grafana.eu-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-1", + }, + }, + endpointKey{ + Region: "eu-west-2", + }: endpoint{ + Hostname: "grafana.eu-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-2", + }, + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{ + Hostname: "grafana.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{ + Hostname: "grafana.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{ + Hostname: "grafana.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + "greengrass": service{ + IsRegionalized: boxedTrue, + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "groundstation": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "groundstation-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "groundstation-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "groundstation-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "groundstation-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "groundstation-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "groundstation-fips.us-west-2.amazonaws.com", + }, + }, + }, + "guardduty": service{ + IsRegionalized: boxedTrue, + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "guardduty-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-1-fips", + }: endpoint{ + Hostname: "guardduty-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "guardduty-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2-fips", + }: endpoint{ + Hostname: "guardduty-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "guardduty-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1-fips", + }: endpoint{ + Hostname: "guardduty-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "guardduty-fips.us-west-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2-fips", + }: endpoint{ + Hostname: "guardduty-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + }, + }, + "health": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "health-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "health-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + }, + }, + "healthlake": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "honeycode": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "iam": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-global", + }: endpoint{ + Hostname: "iam.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "aws-global", + Variant: fipsVariant, + }: endpoint{ + Hostname: "iam-fips.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "aws-global-fips", + }: endpoint{ + Hostname: "iam-fips.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "iam", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "iam", + Variant: fipsVariant, + }: endpoint{ + Hostname: "iam-fips.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "iam-fips", + }: endpoint{ + Hostname: "iam-fips.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "identity-chime": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "identity-chime-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-1-fips", + }: endpoint{ + Hostname: "identity-chime-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "identitystore": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "importexport": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-global", + }: endpoint{ + Hostname: "importexport.amazonaws.com", + SignatureVersions: []string{"v2", "v4"}, + CredentialScope: credentialScope{ + Region: "us-east-1", + Service: "IngestionService", + }, + }, + }, + }, + "inspector": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "inspector-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "inspector-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "inspector-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "inspector-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "inspector-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "inspector-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "inspector-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "inspector-fips.us-west-2.amazonaws.com", + }, + }, + }, + "inspector2": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "iot": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + CredentialScope: credentialScope{ + Service: "execute-api", + }, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "iot-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-ca-central-1", + }: endpoint{ + Hostname: "iot-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Service: "execute-api", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "iot-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Service: "execute-api", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "iot-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Service: "execute-api", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "iot-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Service: "execute-api", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "iot-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Service: "execute-api", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "iot-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "iot-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "iot-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "iot-fips.us-west-2.amazonaws.com", + }, + }, + }, + "iotanalytics": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "iotevents": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "ioteventsdata": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{ + Hostname: "data.iotevents.ap-northeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-1", + }, + }, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{ + Hostname: "data.iotevents.ap-northeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-2", + }, + }, + endpointKey{ + Region: "ap-south-1", + }: endpoint{ + Hostname: "data.iotevents.ap-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-south-1", + }, + }, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{ + Hostname: "data.iotevents.ap-southeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-1", + }, + }, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{ + Hostname: "data.iotevents.ap-southeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-2", + }, + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{ + Hostname: "data.iotevents.eu-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-central-1", + }, + }, + endpointKey{ + Region: "eu-west-1", + }: endpoint{ + Hostname: "data.iotevents.eu-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-1", + }, + }, + endpointKey{ + Region: "eu-west-2", + }: endpoint{ + Hostname: "data.iotevents.eu-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-2", + }, + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{ + Hostname: "data.iotevents.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{ + Hostname: "data.iotevents.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{ + Hostname: "data.iotevents.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + "iotsecuredtunneling": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{}, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "api.tunneling.iot-fips.{region}.{dnsSuffix}", + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "api.tunneling.iot-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-ca-central-1", + }: endpoint{ + Hostname: "api.tunneling.iot-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "api.tunneling.iot-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "api.tunneling.iot-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "api.tunneling.iot-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "api.tunneling.iot-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "api.tunneling.iot-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "api.tunneling.iot-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "api.tunneling.iot-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "api.tunneling.iot-fips.us-west-2.amazonaws.com", + }, + }, + }, + "iotsitewise": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "iotthingsgraph": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + CredentialScope: credentialScope{ + Service: "iotthingsgraph", + }, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "iotwireless": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{ + Hostname: "api.iotwireless.ap-northeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-1", + }, + }, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{ + Hostname: "api.iotwireless.ap-southeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-2", + }, + }, + endpointKey{ + Region: "eu-west-1", + }: endpoint{ + Hostname: "api.iotwireless.eu-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-1", + }, + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{ + Hostname: "api.iotwireless.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{ + Hostname: "api.iotwireless.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + "ivs": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "kafka": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "kafkaconnect": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "kendra": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "kendra-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "kendra-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "kendra-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kendra-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kendra-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kendra-fips.us-west-2.amazonaws.com", + }, + }, + }, + "kinesis": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "kinesis-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "kinesis-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "kinesis-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "kinesis-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kinesis-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kinesis-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kinesis-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kinesis-fips.us-west-2.amazonaws.com", + }, + }, + }, + "kinesisanalytics": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "kinesisvideo": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "kms": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "af-south-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kms-fips.af-south-1.amazonaws.com", + }, + endpointKey{ + Region: "af-south-1-fips", + }: endpoint{ + Hostname: "kms-fips.af-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "af-south-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kms-fips.ap-east-1.amazonaws.com", + }, + endpointKey{ + Region: "ap-east-1-fips", + }: endpoint{ + Hostname: "kms-fips.ap-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kms-fips.ap-northeast-1.amazonaws.com", + }, + endpointKey{ + Region: "ap-northeast-1-fips", + }: endpoint{ + Hostname: "kms-fips.ap-northeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kms-fips.ap-northeast-2.amazonaws.com", + }, + endpointKey{ + Region: "ap-northeast-2-fips", + }: endpoint{ + Hostname: "kms-fips.ap-northeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kms-fips.ap-northeast-3.amazonaws.com", + }, + endpointKey{ + Region: "ap-northeast-3-fips", + }: endpoint{ + Hostname: "kms-fips.ap-northeast-3.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-3", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kms-fips.ap-south-1.amazonaws.com", + }, + endpointKey{ + Region: "ap-south-1-fips", + }: endpoint{ + Hostname: "kms-fips.ap-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-south-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kms-fips.ap-southeast-1.amazonaws.com", + }, + endpointKey{ + Region: "ap-southeast-1-fips", + }: endpoint{ + Hostname: "kms-fips.ap-southeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kms-fips.ap-southeast-2.amazonaws.com", + }, + endpointKey{ + Region: "ap-southeast-2-fips", + }: endpoint{ + Hostname: "kms-fips.ap-southeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kms-fips.ap-southeast-3.amazonaws.com", + }, + endpointKey{ + Region: "ap-southeast-3-fips", + }: endpoint{ + Hostname: "kms-fips.ap-southeast-3.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-3", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kms-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "ca-central-1-fips", + }: endpoint{ + Hostname: "kms-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kms-fips.eu-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-central-1-fips", + }: endpoint{ + Hostname: "kms-fips.eu-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kms-fips.eu-north-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-north-1-fips", + }: endpoint{ + Hostname: "kms-fips.eu-north-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-north-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kms-fips.eu-south-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-south-1-fips", + }: endpoint{ + Hostname: "kms-fips.eu-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-south-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kms-fips.eu-west-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-west-1-fips", + }: endpoint{ + Hostname: "kms-fips.eu-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kms-fips.eu-west-2.amazonaws.com", + }, + endpointKey{ + Region: "eu-west-2-fips", + }: endpoint{ + Hostname: "kms-fips.eu-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kms-fips.eu-west-3.amazonaws.com", + }, + endpointKey{ + Region: "eu-west-3-fips", + }: endpoint{ + Hostname: "kms-fips.eu-west-3.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-3", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kms-fips.me-south-1.amazonaws.com", + }, + endpointKey{ + Region: "me-south-1-fips", + }: endpoint{ + Hostname: "kms-fips.me-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "me-south-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kms-fips.sa-east-1.amazonaws.com", + }, + endpointKey{ + Region: "sa-east-1-fips", + }: endpoint{ + Hostname: "kms-fips.sa-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "sa-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kms-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-1-fips", + }: endpoint{ + Hostname: "kms-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kms-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2-fips", + }: endpoint{ + Hostname: "kms-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kms-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1-fips", + }: endpoint{ + Hostname: "kms-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kms-fips.us-west-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2-fips", + }: endpoint{ + Hostname: "kms-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + }, + }, + "lakeformation": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "lakeformation-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "lakeformation-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "lakeformation-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "lakeformation-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "lakeformation-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "lakeformation-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "lakeformation-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "lakeformation-fips.us-west-2.amazonaws.com", + }, + }, + }, + "lambda": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "lambda-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "lambda-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "lambda-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "lambda-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "lambda-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "lambda-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "lambda-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "lambda-fips.us-west-2.amazonaws.com", + }, + }, + }, + "license-manager": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "license-manager-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "license-manager-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "license-manager-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "license-manager-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "license-manager-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "license-manager-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "license-manager-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "license-manager-fips.us-west-2.amazonaws.com", + }, + }, + }, + "lightsail": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "logs": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "logs-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "logs-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "logs-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "logs-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "logs-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "logs-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "logs-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "logs-fips.us-west-2.amazonaws.com", + }, + }, + }, + "lookoutequipment": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + }, + }, + "lookoutvision": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "machinelearning": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + }, + }, + "macie": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "macie-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "macie-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "macie-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "macie-fips.us-west-2.amazonaws.com", + }, + }, + }, + "macie2": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "macie2-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "macie2-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "macie2-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "macie2-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "macie2-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "macie2-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "macie2-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "macie2-fips.us-west-2.amazonaws.com", + }, + }, + }, + "managedblockchain": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + }, + }, + "marketplacecommerceanalytics": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + }, + }, + "mediaconnect": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "mediaconvert": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "mediaconvert-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-ca-central-1", + }: endpoint{ + Hostname: "mediaconvert-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "mediaconvert-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "mediaconvert-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "mediaconvert-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "mediaconvert-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "mediaconvert-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "mediaconvert-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "mediaconvert-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "mediaconvert-fips.us-west-2.amazonaws.com", + }, + }, + }, + "medialive": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "medialive-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "medialive-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "medialive-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "medialive-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "medialive-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "medialive-fips.us-west-2.amazonaws.com", + }, + }, + }, + "mediapackage": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "mediapackage-vod": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "mediastore": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "messaging-chime": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "messaging-chime-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-1-fips", + }: endpoint{ + Hostname: "messaging-chime-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "metering.marketplace": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + CredentialScope: credentialScope{ + Service: "aws-marketplace", + }, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "mgh": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "mgn": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "migrationhub-strategy": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "mobileanalytics": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + }, + }, + "models-v2-lex": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "models.lex": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + CredentialScope: credentialScope{ + Service: "lex", + }, + }, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "models-fips.lex.{region}.{dnsSuffix}", + CredentialScope: credentialScope{ + Service: "lex", + }, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "models-fips.lex.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-1-fips", + }: endpoint{ + Hostname: "models-fips.lex.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "models-fips.lex.us-west-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2-fips", + }: endpoint{ + Hostname: "models-fips.lex.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + }, + }, + "monitoring": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "monitoring-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "monitoring-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "monitoring-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "monitoring-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "monitoring-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "monitoring-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "monitoring-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "monitoring-fips.us-west-2.amazonaws.com", + }, + }, + }, + "mq": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "mq-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "mq-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "mq-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "mq-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "mq-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "mq-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "mq-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "mq-fips.us-west-2.amazonaws.com", + }, + }, + }, + "mturk-requester": service{ + IsRegionalized: boxedFalse, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "sandbox", + }: endpoint{ + Hostname: "mturk-requester-sandbox.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + }, + }, + "neptune": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-east-1", + }: endpoint{ + Hostname: "rds.ap-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-east-1", + }, + }, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{ + Hostname: "rds.ap-northeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-1", + }, + }, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{ + Hostname: "rds.ap-northeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-2", + }, + }, + endpointKey{ + Region: "ap-south-1", + }: endpoint{ + Hostname: "rds.ap-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-south-1", + }, + }, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{ + Hostname: "rds.ap-southeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-1", + }, + }, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{ + Hostname: "rds.ap-southeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-2", + }, + }, + endpointKey{ + Region: "ca-central-1", + }: endpoint{ + Hostname: "rds.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{ + Hostname: "rds.eu-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-central-1", + }, + }, + endpointKey{ + Region: "eu-north-1", + }: endpoint{ + Hostname: "rds.eu-north-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-north-1", + }, + }, + endpointKey{ + Region: "eu-west-1", + }: endpoint{ + Hostname: "rds.eu-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-1", + }, + }, + endpointKey{ + Region: "eu-west-2", + }: endpoint{ + Hostname: "rds.eu-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-2", + }, + }, + endpointKey{ + Region: "eu-west-3", + }: endpoint{ + Hostname: "rds.eu-west-3.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-3", + }, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{ + Hostname: "rds.me-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "me-south-1", + }, + }, + endpointKey{ + Region: "sa-east-1", + }: endpoint{ + Hostname: "rds.sa-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "sa-east-1", + }, + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{ + Hostname: "rds.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{ + Hostname: "rds.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{ + Hostname: "rds.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{ + Hostname: "rds.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + "network-firewall": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "network-firewall-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-ca-central-1", + }: endpoint{ + Hostname: "network-firewall-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "network-firewall-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "network-firewall-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "network-firewall-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "network-firewall-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "network-firewall-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "network-firewall-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "network-firewall-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "network-firewall-fips.us-west-2.amazonaws.com", + }, + }, + }, + "networkmanager": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-global", + }: endpoint{ + Hostname: "networkmanager.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + "nimble": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "oidc": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{ + Hostname: "oidc.ap-northeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-1", + }, + }, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{ + Hostname: "oidc.ap-northeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-2", + }, + }, + endpointKey{ + Region: "ap-south-1", + }: endpoint{ + Hostname: "oidc.ap-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-south-1", + }, + }, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{ + Hostname: "oidc.ap-southeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-1", + }, + }, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{ + Hostname: "oidc.ap-southeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-2", + }, + }, + endpointKey{ + Region: "ca-central-1", + }: endpoint{ + Hostname: "oidc.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{ + Hostname: "oidc.eu-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-central-1", + }, + }, + endpointKey{ + Region: "eu-north-1", + }: endpoint{ + Hostname: "oidc.eu-north-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-north-1", + }, + }, + endpointKey{ + Region: "eu-west-1", + }: endpoint{ + Hostname: "oidc.eu-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-1", + }, + }, + endpointKey{ + Region: "eu-west-2", + }: endpoint{ + Hostname: "oidc.eu-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-2", + }, + }, + endpointKey{ + Region: "eu-west-3", + }: endpoint{ + Hostname: "oidc.eu-west-3.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-3", + }, + }, + endpointKey{ + Region: "sa-east-1", + }: endpoint{ + Hostname: "oidc.sa-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "sa-east-1", + }, + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{ + Hostname: "oidc.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{ + Hostname: "oidc.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{ + Hostname: "oidc.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + "opsworks": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "opsworks-cm": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "organizations": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-global", + }: endpoint{ + Hostname: "organizations.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "aws-global", + Variant: fipsVariant, + }: endpoint{ + Hostname: "organizations-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "fips-aws-global", + }: endpoint{ + Hostname: "organizations-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "outposts": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "outposts-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-ca-central-1", + }: endpoint{ + Hostname: "outposts-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "outposts-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "outposts-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "outposts-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "outposts-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "outposts-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "outposts-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "outposts-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "outposts-fips.us-west-2.amazonaws.com", + }, + }, + }, + "personalize": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "pi": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "pinpoint": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + CredentialScope: credentialScope{ + Service: "mobiletargeting", + }, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "pinpoint-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "pinpoint-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{ + Hostname: "pinpoint.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "pinpoint-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{ + Hostname: "pinpoint.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "pinpoint-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + "polly": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "polly-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "polly-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "polly-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "polly-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "polly-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "polly-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "polly-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "polly-fips.us-west-2.amazonaws.com", + }, + }, + }, + "portal.sso": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{ + Hostname: "portal.sso.ap-northeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-1", + }, + }, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{ + Hostname: "portal.sso.ap-northeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-2", + }, + }, + endpointKey{ + Region: "ap-south-1", + }: endpoint{ + Hostname: "portal.sso.ap-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-south-1", + }, + }, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{ + Hostname: "portal.sso.ap-southeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-1", + }, + }, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{ + Hostname: "portal.sso.ap-southeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-2", + }, + }, + endpointKey{ + Region: "ca-central-1", + }: endpoint{ + Hostname: "portal.sso.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{ + Hostname: "portal.sso.eu-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-central-1", + }, + }, + endpointKey{ + Region: "eu-north-1", + }: endpoint{ + Hostname: "portal.sso.eu-north-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-north-1", + }, + }, + endpointKey{ + Region: "eu-west-1", + }: endpoint{ + Hostname: "portal.sso.eu-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-1", + }, + }, + endpointKey{ + Region: "eu-west-2", + }: endpoint{ + Hostname: "portal.sso.eu-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-2", + }, + }, + endpointKey{ + Region: "eu-west-3", + }: endpoint{ + Hostname: "portal.sso.eu-west-3.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-3", + }, + }, + endpointKey{ + Region: "sa-east-1", + }: endpoint{ + Hostname: "portal.sso.sa-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "sa-east-1", + }, + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{ + Hostname: "portal.sso.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{ + Hostname: "portal.sso.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{ + Hostname: "portal.sso.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + "profile": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "projects.iot1click": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "qldb": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "qldb-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "qldb-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "qldb-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "qldb-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "qldb-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "qldb-fips.us-west-2.amazonaws.com", + }, + }, + }, + "quicksight": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "api", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "ram": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ram-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-ca-central-1", + }: endpoint{ + Hostname: "ram-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "ram-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "ram-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "ram-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "ram-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ram-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ram-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ram-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ram-fips.us-west-2.amazonaws.com", + }, + }, + }, + "rbin": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "rds": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "rds-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "ca-central-1-fips", + }: endpoint{ + Hostname: "rds-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "rds-fips.ca-central-1", + }: endpoint{ + Hostname: "rds-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "rds-fips.us-east-1", + }: endpoint{ + Hostname: "rds-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "rds-fips.us-east-2", + }: endpoint{ + Hostname: "rds-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "rds-fips.us-west-1", + }: endpoint{ + Hostname: "rds-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "rds-fips.us-west-2", + }: endpoint{ + Hostname: "rds-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "rds.ca-central-1", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "rds.ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "rds-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "rds.us-east-1", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "rds.us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "rds-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "rds.us-east-2", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "rds.us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "rds-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "rds.us-west-1", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "rds.us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "rds-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "rds.us-west-2", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "rds.us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "rds-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{ + SSLCommonName: "{service}.{dnsSuffix}", + }, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "rds-fips.us-east-1.amazonaws.com", + SSLCommonName: "{service}.{dnsSuffix}", + }, + endpointKey{ + Region: "us-east-1-fips", + }: endpoint{ + Hostname: "rds-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "rds-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2-fips", + }: endpoint{ + Hostname: "rds-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "rds-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1-fips", + }: endpoint{ + Hostname: "rds-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "rds-fips.us-west-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2-fips", + }: endpoint{ + Hostname: "rds-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + }, + }, + "redshift": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "redshift-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-ca-central-1", + }: endpoint{ + Hostname: "redshift-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "redshift-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "redshift-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "redshift-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "redshift-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "redshift-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "redshift-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "redshift-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "redshift-fips.us-west-2.amazonaws.com", + }, + }, + }, + "rekognition": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "rekognition-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "ca-central-1-fips", + }: endpoint{ + Hostname: "rekognition-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "rekognition-fips.ca-central-1", + }: endpoint{ + Hostname: "rekognition-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "rekognition-fips.us-east-1", + }: endpoint{ + Hostname: "rekognition-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "rekognition-fips.us-east-2", + }: endpoint{ + Hostname: "rekognition-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "rekognition-fips.us-west-1", + }: endpoint{ + Hostname: "rekognition-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "rekognition-fips.us-west-2", + }: endpoint{ + Hostname: "rekognition-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "rekognition.ca-central-1", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "rekognition.ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "rekognition-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "rekognition.us-east-1", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "rekognition.us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "rekognition-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "rekognition.us-east-2", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "rekognition.us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "rekognition-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "rekognition.us-west-1", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "rekognition.us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "rekognition-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "rekognition.us-west-2", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "rekognition.us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "rekognition-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "rekognition-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-1-fips", + }: endpoint{ + Hostname: "rekognition-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "rekognition-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2-fips", + }: endpoint{ + Hostname: "rekognition-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "rekognition-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1-fips", + }: endpoint{ + Hostname: "rekognition-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "rekognition-fips.us-west-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2-fips", + }: endpoint{ + Hostname: "rekognition-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + }, + }, + "resource-groups": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "resource-groups-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "resource-groups-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "resource-groups-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "resource-groups-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "resource-groups-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "resource-groups-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "resource-groups-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "resource-groups-fips.us-west-2.amazonaws.com", + }, + }, + }, + "robomaker": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "route53": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-global", + }: endpoint{ + Hostname: "route53.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "aws-global", + Variant: fipsVariant, + }: endpoint{ + Hostname: "route53-fips.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "fips-aws-global", + }: endpoint{ + Hostname: "route53-fips.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "route53-recovery-control-config": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-global", + }: endpoint{ + Hostname: "route53-recovery-control-config.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + "route53domains": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + }, + }, + "route53resolver": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "rum": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "runtime-v2-lex": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "runtime.lex": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + CredentialScope: credentialScope{ + Service: "lex", + }, + }, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "runtime-fips.lex.{region}.{dnsSuffix}", + CredentialScope: credentialScope{ + Service: "lex", + }, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "runtime-fips.lex.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-1-fips", + }: endpoint{ + Hostname: "runtime-fips.lex.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "runtime-fips.lex.us-west-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2-fips", + }: endpoint{ + Hostname: "runtime-fips.lex.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + }, + }, + "runtime.sagemaker": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{}, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "runtime-fips.sagemaker.{region}.{dnsSuffix}", + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "runtime-fips.sagemaker.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-1-fips", + }: endpoint{ + Hostname: "runtime-fips.sagemaker.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "runtime-fips.sagemaker.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2-fips", + }: endpoint{ + Hostname: "runtime-fips.sagemaker.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "runtime-fips.sagemaker.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1-fips", + }: endpoint{ + Hostname: "runtime-fips.sagemaker.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "runtime-fips.sagemaker.us-west-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2-fips", + }: endpoint{ + Hostname: "runtime-fips.sagemaker.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + }, + }, + "s3": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedTrue, + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + SignatureVersions: []string{"s3v4"}, + }, + defaultKey{ + Variant: dualStackVariant, + }: endpoint{ + Hostname: "{service}.dualstack.{region}.{dnsSuffix}", + DNSSuffix: "amazonaws.com", + Protocols: []string{"http", "https"}, + SignatureVersions: []string{"s3v4"}, + }, + defaultKey{ + Variant: fipsVariant | dualStackVariant, + }: endpoint{ + Hostname: "{service}-fips.dualstack.{region}.{dnsSuffix}", + DNSSuffix: "amazonaws.com", + Protocols: []string{"http", "https"}, + SignatureVersions: []string{"s3v4"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "af-south-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3.dualstack.af-south-1.amazonaws.com", + }, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3.dualstack.ap-east-1.amazonaws.com", + }, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{ + Hostname: "s3.ap-northeast-1.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + endpointKey{ + Region: "ap-northeast-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3.dualstack.ap-northeast-1.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3.dualstack.ap-northeast-2.amazonaws.com", + }, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3.dualstack.ap-northeast-3.amazonaws.com", + }, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3.dualstack.ap-south-1.amazonaws.com", + }, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{ + Hostname: "s3.ap-southeast-1.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + endpointKey{ + Region: "ap-southeast-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3.dualstack.ap-southeast-1.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{ + Hostname: "s3.ap-southeast-2.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + endpointKey{ + Region: "ap-southeast-2", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3.dualstack.ap-southeast-2.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + endpointKey{ + Region: "aws-global", + }: endpoint{ + Hostname: "s3.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3.dualstack.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "s3-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant | dualStackVariant, + }: endpoint{ + Hostname: "s3-fips.dualstack.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3.dualstack.eu-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3.dualstack.eu-north-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3.dualstack.eu-south-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-west-1", + }: endpoint{ + Hostname: "s3.eu-west-1.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + endpointKey{ + Region: "eu-west-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3.dualstack.eu-west-1.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3.dualstack.eu-west-2.amazonaws.com", + }, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3.dualstack.eu-west-3.amazonaws.com", + }, + endpointKey{ + Region: "fips-ca-central-1", + }: endpoint{ + Hostname: "s3-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "s3-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "s3-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "s3-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "s3-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3.dualstack.me-south-1.amazonaws.com", + }, + endpointKey{ + Region: "s3-external-1", + }: endpoint{ + Hostname: "s3-external-1.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "sa-east-1", + }: endpoint{ + Hostname: "s3.sa-east-1.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + endpointKey{ + Region: "sa-east-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3.dualstack.sa-east-1.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{ + Hostname: "s3.us-east-1.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + endpointKey{ + Region: "us-east-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3.dualstack.us-east-1.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "s3-fips.us-east-1.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant | dualStackVariant, + }: endpoint{ + Hostname: "s3-fips.dualstack.us-east-1.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3.dualstack.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "s3-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant | dualStackVariant, + }: endpoint{ + Hostname: "s3-fips.dualstack.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{ + Hostname: "s3.us-west-1.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + endpointKey{ + Region: "us-west-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3.dualstack.us-west-1.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "s3-fips.us-west-1.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant | dualStackVariant, + }: endpoint{ + Hostname: "s3-fips.dualstack.us-west-1.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{ + Hostname: "s3.us-west-2.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + endpointKey{ + Region: "us-west-2", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3.dualstack.us-west-2.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "s3-fips.us-west-2.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant | dualStackVariant, + }: endpoint{ + Hostname: "s3-fips.dualstack.us-west-2.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + }, + }, + "s3-control": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + SignatureVersions: []string{"s3v4"}, + }, + defaultKey{ + Variant: dualStackVariant, + }: endpoint{ + Hostname: "{service}.dualstack.{region}.{dnsSuffix}", + DNSSuffix: "amazonaws.com", + Protocols: []string{"https"}, + SignatureVersions: []string{"s3v4"}, + }, + defaultKey{ + Variant: fipsVariant | dualStackVariant, + }: endpoint{ + Hostname: "{service}-fips.dualstack.{region}.{dnsSuffix}", + DNSSuffix: "amazonaws.com", + Protocols: []string{"https"}, + SignatureVersions: []string{"s3v4"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{ + Hostname: "s3-control.ap-northeast-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "ap-northeast-1", + }, + }, + endpointKey{ + Region: "ap-northeast-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3-control.dualstack.ap-northeast-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "ap-northeast-1", + }, + }, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{ + Hostname: "s3-control.ap-northeast-2.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "ap-northeast-2", + }, + }, + endpointKey{ + Region: "ap-northeast-2", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3-control.dualstack.ap-northeast-2.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "ap-northeast-2", + }, + }, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{ + Hostname: "s3-control.ap-northeast-3.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "ap-northeast-3", + }, + }, + endpointKey{ + Region: "ap-northeast-3", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3-control.dualstack.ap-northeast-3.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "ap-northeast-3", + }, + }, + endpointKey{ + Region: "ap-south-1", + }: endpoint{ + Hostname: "s3-control.ap-south-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "ap-south-1", + }, + }, + endpointKey{ + Region: "ap-south-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3-control.dualstack.ap-south-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "ap-south-1", + }, + }, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{ + Hostname: "s3-control.ap-southeast-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "ap-southeast-1", + }, + }, + endpointKey{ + Region: "ap-southeast-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3-control.dualstack.ap-southeast-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "ap-southeast-1", + }, + }, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{ + Hostname: "s3-control.ap-southeast-2.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "ap-southeast-2", + }, + }, + endpointKey{ + Region: "ap-southeast-2", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3-control.dualstack.ap-southeast-2.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "ap-southeast-2", + }, + }, + endpointKey{ + Region: "ca-central-1", + }: endpoint{ + Hostname: "s3-control.ca-central-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + }, + endpointKey{ + Region: "ca-central-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3-control.dualstack.ca-central-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + }, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "s3-control-fips.ca-central-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + }, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant | dualStackVariant, + }: endpoint{ + Hostname: "s3-control-fips.dualstack.ca-central-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + }, + endpointKey{ + Region: "ca-central-1-fips", + }: endpoint{ + Hostname: "s3-control-fips.ca-central-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{ + Hostname: "s3-control.eu-central-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "eu-central-1", + }, + }, + endpointKey{ + Region: "eu-central-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3-control.dualstack.eu-central-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "eu-central-1", + }, + }, + endpointKey{ + Region: "eu-north-1", + }: endpoint{ + Hostname: "s3-control.eu-north-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "eu-north-1", + }, + }, + endpointKey{ + Region: "eu-north-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3-control.dualstack.eu-north-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "eu-north-1", + }, + }, + endpointKey{ + Region: "eu-west-1", + }: endpoint{ + Hostname: "s3-control.eu-west-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "eu-west-1", + }, + }, + endpointKey{ + Region: "eu-west-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3-control.dualstack.eu-west-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "eu-west-1", + }, + }, + endpointKey{ + Region: "eu-west-2", + }: endpoint{ + Hostname: "s3-control.eu-west-2.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "eu-west-2", + }, + }, + endpointKey{ + Region: "eu-west-2", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3-control.dualstack.eu-west-2.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "eu-west-2", + }, + }, + endpointKey{ + Region: "eu-west-3", + }: endpoint{ + Hostname: "s3-control.eu-west-3.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "eu-west-3", + }, + }, + endpointKey{ + Region: "eu-west-3", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3-control.dualstack.eu-west-3.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "eu-west-3", + }, + }, + endpointKey{ + Region: "sa-east-1", + }: endpoint{ + Hostname: "s3-control.sa-east-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "sa-east-1", + }, + }, + endpointKey{ + Region: "sa-east-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3-control.dualstack.sa-east-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "sa-east-1", + }, + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{ + Hostname: "s3-control.us-east-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "us-east-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3-control.dualstack.us-east-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "s3-control-fips.us-east-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant | dualStackVariant, + }: endpoint{ + Hostname: "s3-control-fips.dualstack.us-east-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "us-east-1-fips", + }: endpoint{ + Hostname: "s3-control-fips.us-east-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{ + Hostname: "s3-control.us-east-2.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + endpointKey{ + Region: "us-east-2", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3-control.dualstack.us-east-2.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "s3-control-fips.us-east-2.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant | dualStackVariant, + }: endpoint{ + Hostname: "s3-control-fips.dualstack.us-east-2.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + endpointKey{ + Region: "us-east-2-fips", + }: endpoint{ + Hostname: "s3-control-fips.us-east-2.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{ + Hostname: "s3-control.us-west-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + }, + endpointKey{ + Region: "us-west-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3-control.dualstack.us-west-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + }, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "s3-control-fips.us-west-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + }, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant | dualStackVariant, + }: endpoint{ + Hostname: "s3-control-fips.dualstack.us-west-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + }, + endpointKey{ + Region: "us-west-1-fips", + }: endpoint{ + Hostname: "s3-control-fips.us-west-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{ + Hostname: "s3-control.us-west-2.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + endpointKey{ + Region: "us-west-2", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3-control.dualstack.us-west-2.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "s3-control-fips.us-west-2.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant | dualStackVariant, + }: endpoint{ + Hostname: "s3-control-fips.dualstack.us-west-2.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + endpointKey{ + Region: "us-west-2-fips", + }: endpoint{ + Hostname: "s3-control-fips.us-west-2.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + }, + }, + "savingsplans": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-global", + }: endpoint{ + Hostname: "savingsplans.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + }, + }, + "schemas": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "sdb": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + SignatureVersions: []string{"v2"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{ + Hostname: "sdb.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "secretsmanager": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "secretsmanager-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-1-fips", + }: endpoint{ + Hostname: "secretsmanager-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "secretsmanager-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2-fips", + }: endpoint{ + Hostname: "secretsmanager-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "secretsmanager-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1-fips", + }: endpoint{ + Hostname: "secretsmanager-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "secretsmanager-fips.us-west-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2-fips", + }: endpoint{ + Hostname: "secretsmanager-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + }, + }, + "securityhub": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "securityhub-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "securityhub-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "securityhub-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "securityhub-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "securityhub-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "securityhub-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "securityhub-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "securityhub-fips.us-west-2.amazonaws.com", + }, + }, + }, + "serverlessrepo": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-east-1", + }: endpoint{ + Protocols: []string{"https"}, + }, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{ + Protocols: []string{"https"}, + }, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{ + Protocols: []string{"https"}, + }, + endpointKey{ + Region: "ap-south-1", + }: endpoint{ + Protocols: []string{"https"}, + }, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{ + Protocols: []string{"https"}, + }, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{ + Protocols: []string{"https"}, + }, + endpointKey{ + Region: "ca-central-1", + }: endpoint{ + Protocols: []string{"https"}, + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{ + Protocols: []string{"https"}, + }, + endpointKey{ + Region: "eu-north-1", + }: endpoint{ + Protocols: []string{"https"}, + }, + endpointKey{ + Region: "eu-west-1", + }: endpoint{ + Protocols: []string{"https"}, + }, + endpointKey{ + Region: "eu-west-2", + }: endpoint{ + Protocols: []string{"https"}, + }, + endpointKey{ + Region: "eu-west-3", + }: endpoint{ + Protocols: []string{"https"}, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{ + Protocols: []string{"https"}, + }, + endpointKey{ + Region: "sa-east-1", + }: endpoint{ + Protocols: []string{"https"}, + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{ + Protocols: []string{"https"}, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{ + Protocols: []string{"https"}, + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{ + Protocols: []string{"https"}, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{ + Protocols: []string{"https"}, + }, + }, + }, + "servicecatalog": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "servicecatalog-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-1-fips", + }: endpoint{ + Hostname: "servicecatalog-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "servicecatalog-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2-fips", + }: endpoint{ + Hostname: "servicecatalog-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "servicecatalog-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1-fips", + }: endpoint{ + Hostname: "servicecatalog-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "servicecatalog-fips.us-west-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2-fips", + }: endpoint{ + Hostname: "servicecatalog-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + }, + }, + "servicecatalog-appregistry": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "servicecatalog-appregistry-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-ca-central-1", + }: endpoint{ + Hostname: "servicecatalog-appregistry-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "servicecatalog-appregistry-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "servicecatalog-appregistry-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "servicecatalog-appregistry-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "servicecatalog-appregistry-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "servicecatalog-appregistry-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "servicecatalog-appregistry-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "servicecatalog-appregistry-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "servicecatalog-appregistry-fips.us-west-2.amazonaws.com", + }, + }, + }, + "servicediscovery": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "servicediscovery-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "ca-central-1-fips", + }: endpoint{ + Hostname: "servicediscovery-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "servicediscovery", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "servicediscovery", + Variant: fipsVariant, + }: endpoint{ + Hostname: "servicediscovery-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "servicediscovery-fips", + }: endpoint{ + Hostname: "servicediscovery-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "servicediscovery-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-1-fips", + }: endpoint{ + Hostname: "servicediscovery-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "servicediscovery-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2-fips", + }: endpoint{ + Hostname: "servicediscovery-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "servicediscovery-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1-fips", + }: endpoint{ + Hostname: "servicediscovery-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "servicediscovery-fips.us-west-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2-fips", + }: endpoint{ + Hostname: "servicediscovery-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + }, + }, + "servicequotas": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "session.qldb": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "session.qldb-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "session.qldb-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "session.qldb-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "session.qldb-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "session.qldb-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "session.qldb-fips.us-west-2.amazonaws.com", + }, + }, + }, + "shield": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + SSLCommonName: "shield.us-east-1.amazonaws.com", + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-global", + }: endpoint{ + Hostname: "shield.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "aws-global", + Variant: fipsVariant, + }: endpoint{ + Hostname: "shield-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "fips-aws-global", + }: endpoint{ + Hostname: "shield-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "sms": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "sms-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "sms-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "sms-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "sms-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "sms-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "sms-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "sms-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "sms-fips.us-west-2.amazonaws.com", + }, + }, + }, + "snowball": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "snowball-fips.ap-northeast-1.amazonaws.com", + }, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "snowball-fips.ap-northeast-2.amazonaws.com", + }, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + Variant: fipsVariant, + }: endpoint{ + Hostname: "snowball-fips.ap-northeast-3.amazonaws.com", + }, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "snowball-fips.ap-south-1.amazonaws.com", + }, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "snowball-fips.ap-southeast-1.amazonaws.com", + }, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "snowball-fips.ap-southeast-2.amazonaws.com", + }, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "snowball-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "snowball-fips.eu-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "snowball-fips.eu-west-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "snowball-fips.eu-west-2.amazonaws.com", + }, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + Variant: fipsVariant, + }: endpoint{ + Hostname: "snowball-fips.eu-west-3.amazonaws.com", + }, + endpointKey{ + Region: "fips-ap-northeast-1", + }: endpoint{ + Hostname: "snowball-fips.ap-northeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-ap-northeast-2", + }: endpoint{ + Hostname: "snowball-fips.ap-northeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-ap-northeast-3", + }: endpoint{ + Hostname: "snowball-fips.ap-northeast-3.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-3", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-ap-south-1", + }: endpoint{ + Hostname: "snowball-fips.ap-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-south-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-ap-southeast-1", + }: endpoint{ + Hostname: "snowball-fips.ap-southeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-ap-southeast-2", + }: endpoint{ + Hostname: "snowball-fips.ap-southeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-ca-central-1", + }: endpoint{ + Hostname: "snowball-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-eu-central-1", + }: endpoint{ + Hostname: "snowball-fips.eu-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-eu-west-1", + }: endpoint{ + Hostname: "snowball-fips.eu-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-eu-west-2", + }: endpoint{ + Hostname: "snowball-fips.eu-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-eu-west-3", + }: endpoint{ + Hostname: "snowball-fips.eu-west-3.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-3", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-sa-east-1", + }: endpoint{ + Hostname: "snowball-fips.sa-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "sa-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "snowball-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "snowball-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "snowball-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "snowball-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "snowball-fips.sa-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "snowball-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "snowball-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "snowball-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "snowball-fips.us-west-2.amazonaws.com", + }, + }, + }, + "sns": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "sns-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "sns-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "sns-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "sns-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "sns-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "sns-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "sns-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "sns-fips.us-west-2.amazonaws.com", + }, + }, + }, + "sqs": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + SSLCommonName: "{region}.queue.{dnsSuffix}", + Protocols: []string{"http", "https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "sqs-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "sqs-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "sqs-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "sqs-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{ + SSLCommonName: "queue.{dnsSuffix}", + }, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "sqs-fips.us-east-1.amazonaws.com", + SSLCommonName: "queue.{dnsSuffix}", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "sqs-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "sqs-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "sqs-fips.us-west-2.amazonaws.com", + }, + }, + }, + "ssm": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ssm-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-ca-central-1", + }: endpoint{ + Hostname: "ssm-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "ssm-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "ssm-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "ssm-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "ssm-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ssm-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ssm-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ssm-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ssm-fips.us-west-2.amazonaws.com", + }, + }, + }, + "ssm-incidents": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "states": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "states-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "states-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "states-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "states-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "states-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "states-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "states-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "states-fips.us-west-2.amazonaws.com", + }, + }, + }, + "storagegateway": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "storagegateway-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "ca-central-1-fips", + }: endpoint{ + Hostname: "storagegateway-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips", + }: endpoint{ + Hostname: "storagegateway-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "storagegateway-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-1-fips", + }: endpoint{ + Hostname: "storagegateway-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "storagegateway-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2-fips", + }: endpoint{ + Hostname: "storagegateway-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "storagegateway-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1-fips", + }: endpoint{ + Hostname: "storagegateway-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "storagegateway-fips.us-west-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2-fips", + }: endpoint{ + Hostname: "storagegateway-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + }, + }, + "streams.dynamodb": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + CredentialScope: credentialScope{ + Service: "dynamodb", + }, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "local", + }: endpoint{ + Hostname: "localhost:8000", + Protocols: []string{"http"}, + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "sts": service{ + PartitionEndpoint: "aws-global", + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "aws-global", + }: endpoint{ + Hostname: "sts.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "sts-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-1-fips", + }: endpoint{ + Hostname: "sts-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "sts-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2-fips", + }: endpoint{ + Hostname: "sts-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "sts-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1-fips", + }: endpoint{ + Hostname: "sts-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "sts-fips.us-west-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2-fips", + }: endpoint{ + Hostname: "sts-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + }, + }, + "support": service{ + PartitionEndpoint: "aws-global", + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-global", + }: endpoint{ + Hostname: "support.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + }, + }, + "swf": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "swf-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "swf-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "swf-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "swf-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "swf-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "swf-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "swf-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "swf-fips.us-west-2.amazonaws.com", + }, + }, + }, + "tagging": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "textract": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "textract-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-ca-central-1", + }: endpoint{ + Hostname: "textract-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "textract-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "textract-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "textract-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "textract-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "textract-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "textract-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "textract-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "textract-fips.us-west-2.amazonaws.com", + }, + }, + }, + "transcribe": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "fips.transcribe.{region}.{dnsSuffix}", + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fips.transcribe.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-ca-central-1", + }: endpoint{ + Hostname: "fips.transcribe.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "fips.transcribe.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "fips.transcribe.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "fips.transcribe.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "fips.transcribe.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fips.transcribe.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fips.transcribe.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fips.transcribe.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fips.transcribe.us-west-2.amazonaws.com", + }, + }, + }, + "transcribestreaming": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "transcribestreaming-ca-central-1", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "transcribestreaming-ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "transcribestreaming-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "transcribestreaming-fips-ca-central-1", + }: endpoint{ + Hostname: "transcribestreaming-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "transcribestreaming-fips-us-east-1", + }: endpoint{ + Hostname: "transcribestreaming-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "transcribestreaming-fips-us-east-2", + }: endpoint{ + Hostname: "transcribestreaming-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "transcribestreaming-fips-us-west-2", + }: endpoint{ + Hostname: "transcribestreaming-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "transcribestreaming-us-east-1", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "transcribestreaming-us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "transcribestreaming-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "transcribestreaming-us-east-2", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "transcribestreaming-us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "transcribestreaming-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "transcribestreaming-us-west-2", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "transcribestreaming-us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "transcribestreaming-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "transfer": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "transfer-fips.ca-central-1.amazonaws.com", + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-ca-central-1", + }: endpoint{ + Hostname: "transfer-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "transfer-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "transfer-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "transfer-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "transfer-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "transfer-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "transfer-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "transfer-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "transfer-fips.us-west-2.amazonaws.com", + }, + }, + }, + "translate": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "translate-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-1-fips", + }: endpoint{ + Hostname: "translate-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "translate-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2-fips", + }: endpoint{ + Hostname: "translate-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "translate-fips.us-west-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2-fips", + }: endpoint{ + Hostname: "translate-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + }, + }, + "voiceid": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "waf": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "aws", + Variant: fipsVariant, + }: endpoint{ + Hostname: "waf-fips.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "aws-fips", + }: endpoint{ + Hostname: "waf-fips.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "aws-global", + }: endpoint{ + Hostname: "waf.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "aws-global", + Variant: fipsVariant, + }: endpoint{ + Hostname: "waf-fips.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "aws-global-fips", + }: endpoint{ + Hostname: "waf-fips.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "waf-regional": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{ + Hostname: "waf-regional.af-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "af-south-1", + }, + }, + endpointKey{ + Region: "af-south-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "waf-regional-fips.af-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "af-south-1", + }, + }, + endpointKey{ + Region: "ap-east-1", + }: endpoint{ + Hostname: "waf-regional.ap-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-east-1", + }, + }, + endpointKey{ + Region: "ap-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "waf-regional-fips.ap-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-east-1", + }, + }, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{ + Hostname: "waf-regional.ap-northeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-1", + }, + }, + endpointKey{ + Region: "ap-northeast-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "waf-regional-fips.ap-northeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-1", + }, + }, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{ + Hostname: "waf-regional.ap-northeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-2", + }, + }, + endpointKey{ + Region: "ap-northeast-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "waf-regional-fips.ap-northeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-2", + }, + }, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{ + Hostname: "waf-regional.ap-northeast-3.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-3", + }, + }, + endpointKey{ + Region: "ap-northeast-3", + Variant: fipsVariant, + }: endpoint{ + Hostname: "waf-regional-fips.ap-northeast-3.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-3", + }, + }, + endpointKey{ + Region: "ap-south-1", + }: endpoint{ + Hostname: "waf-regional.ap-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-south-1", + }, + }, + endpointKey{ + Region: "ap-south-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "waf-regional-fips.ap-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-south-1", + }, + }, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{ + Hostname: "waf-regional.ap-southeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-1", + }, + }, + endpointKey{ + Region: "ap-southeast-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "waf-regional-fips.ap-southeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-1", + }, + }, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{ + Hostname: "waf-regional.ap-southeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-2", + }, + }, + endpointKey{ + Region: "ap-southeast-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "waf-regional-fips.ap-southeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-2", + }, + }, + endpointKey{ + Region: "ca-central-1", + }: endpoint{ + Hostname: "waf-regional.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + }, + endpointKey{ + Region: "ca-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "waf-regional-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + }, + endpointKey{ + Region: "eu-central-1", + }: endpoint{ + Hostname: "waf-regional.eu-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-central-1", + }, + }, + endpointKey{ + Region: "eu-central-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "waf-regional-fips.eu-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-central-1", + }, + }, + endpointKey{ + Region: "eu-north-1", + }: endpoint{ + Hostname: "waf-regional.eu-north-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-north-1", + }, + }, + endpointKey{ + Region: "eu-north-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "waf-regional-fips.eu-north-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-north-1", + }, + }, + endpointKey{ + Region: "eu-south-1", + }: endpoint{ + Hostname: "waf-regional.eu-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-south-1", + }, + }, + endpointKey{ + Region: "eu-south-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "waf-regional-fips.eu-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-south-1", + }, + }, + endpointKey{ + Region: "eu-west-1", + }: endpoint{ + Hostname: "waf-regional.eu-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-1", + }, + }, + endpointKey{ + Region: "eu-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "waf-regional-fips.eu-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-1", + }, + }, + endpointKey{ + Region: "eu-west-2", + }: endpoint{ + Hostname: "waf-regional.eu-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-2", + }, + }, + endpointKey{ + Region: "eu-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "waf-regional-fips.eu-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-2", + }, + }, + endpointKey{ + Region: "eu-west-3", + }: endpoint{ + Hostname: "waf-regional.eu-west-3.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-3", + }, + }, + endpointKey{ + Region: "eu-west-3", + Variant: fipsVariant, + }: endpoint{ + Hostname: "waf-regional-fips.eu-west-3.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-3", + }, + }, + endpointKey{ + Region: "fips-af-south-1", + }: endpoint{ + Hostname: "waf-regional-fips.af-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "af-south-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-ap-east-1", + }: endpoint{ + Hostname: "waf-regional-fips.ap-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-ap-northeast-1", + }: endpoint{ + Hostname: "waf-regional-fips.ap-northeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-ap-northeast-2", + }: endpoint{ + Hostname: "waf-regional-fips.ap-northeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-ap-northeast-3", + }: endpoint{ + Hostname: "waf-regional-fips.ap-northeast-3.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-3", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-ap-south-1", + }: endpoint{ + Hostname: "waf-regional-fips.ap-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-south-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-ap-southeast-1", + }: endpoint{ + Hostname: "waf-regional-fips.ap-southeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-ap-southeast-2", + }: endpoint{ + Hostname: "waf-regional-fips.ap-southeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-ca-central-1", + }: endpoint{ + Hostname: "waf-regional-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-eu-central-1", + }: endpoint{ + Hostname: "waf-regional-fips.eu-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-central-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-eu-north-1", + }: endpoint{ + Hostname: "waf-regional-fips.eu-north-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-north-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-eu-south-1", + }: endpoint{ + Hostname: "waf-regional-fips.eu-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-south-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-eu-west-1", + }: endpoint{ + Hostname: "waf-regional-fips.eu-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-eu-west-2", + }: endpoint{ + Hostname: "waf-regional-fips.eu-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-eu-west-3", + }: endpoint{ + Hostname: "waf-regional-fips.eu-west-3.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-3", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-me-south-1", + }: endpoint{ + Hostname: "waf-regional-fips.me-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "me-south-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-sa-east-1", + }: endpoint{ + Hostname: "waf-regional-fips.sa-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "sa-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "waf-regional-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "waf-regional-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "waf-regional-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "waf-regional-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{ + Hostname: "waf-regional.me-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "me-south-1", + }, + }, + endpointKey{ + Region: "me-south-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "waf-regional-fips.me-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "me-south-1", + }, + }, + endpointKey{ + Region: "sa-east-1", + }: endpoint{ + Hostname: "waf-regional.sa-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "sa-east-1", + }, + }, + endpointKey{ + Region: "sa-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "waf-regional-fips.sa-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "sa-east-1", + }, + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{ + Hostname: "waf-regional.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "waf-regional-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{ + Hostname: "waf-regional.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "waf-regional-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{ + Hostname: "waf-regional.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + }, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "waf-regional-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{ + Hostname: "waf-regional.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "waf-regional-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + "wisdom": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "workdocs": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "workdocs-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "workdocs-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "workdocs-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "workdocs-fips.us-west-2.amazonaws.com", + }, + }, + }, + "workmail": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "workspaces": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "workspaces-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "workspaces-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "workspaces-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "workspaces-fips.us-west-2.amazonaws.com", + }, + }, + }, + "workspaces-web": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + }, + }, + "xray": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-east-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, + endpointKey{ + Region: "eu-west-3", + }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "xray-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "xray-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-1", + }: endpoint{ + Hostname: "xray-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "xray-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "me-south-1", + }: endpoint{}, + endpointKey{ + Region: "sa-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "xray-fips.us-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-east-2", + }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "xray-fips.us-east-2.amazonaws.com", + }, + endpointKey{ + Region: "us-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "xray-fips.us-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-west-2", + }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "xray-fips.us-west-2.amazonaws.com", + }, + }, + }, + }, +} + +// AwsCnPartition returns the Resolver for AWS China. +func AwsCnPartition() Partition { + return awscnPartition.Partition() +} + +var awscnPartition = partition{ + ID: "aws-cn", + Name: "AWS China", + DNSSuffix: "amazonaws.com.cn", + RegionRegex: regionRegex{ + Regexp: func() *regexp.Regexp { + reg, _ := regexp.Compile("^cn\\-\\w+\\-\\d+$") + return reg + }(), + }, + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Hostname: "{service}.{region}.{dnsSuffix}", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + defaultKey{ + Variant: dualStackVariant, + }: endpoint{ + Hostname: "{service}.{region}.{dnsSuffix}", + DNSSuffix: "api.amazonwebservices.com.cn", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "{service}-fips.{region}.{dnsSuffix}", + DNSSuffix: "amazonaws.com.cn", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + defaultKey{ + Variant: fipsVariant | dualStackVariant, + }: endpoint{ + Hostname: "{service}-fips.{region}.{dnsSuffix}", + DNSSuffix: "api.amazonwebservices.com.cn", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + }, + Regions: regions{ + "cn-north-1": region{ + Description: "China (Beijing)", + }, + "cn-northwest-1": region{ + Description: "China (Ningxia)", + }, + }, + Services: services{ + "access-analyzer": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "account": service{ + PartitionEndpoint: "aws-cn-global", + IsRegionalized: boxedFalse, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-cn-global", + }: endpoint{ + Hostname: "account.cn-northwest-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-northwest-1", + }, + }, + }, + }, + "acm": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "api.ecr": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{ + Hostname: "api.ecr.cn-north-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-north-1", + }, + }, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{ + Hostname: "api.ecr.cn-northwest-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-northwest-1", + }, + }, + }, + }, + "api.sagemaker": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "apigateway": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "appconfigdata": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "application-autoscaling": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "applicationinsights": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "appmesh": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "appsync": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "athena": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "autoscaling": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "autoscaling-plans": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "backup": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "batch": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "budgets": service{ + PartitionEndpoint: "aws-cn-global", + IsRegionalized: boxedFalse, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-cn-global", + }: endpoint{ + Hostname: "budgets.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-northwest-1", + }, + }, + }, + }, + "ce": service{ + PartitionEndpoint: "aws-cn-global", + IsRegionalized: boxedFalse, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-cn-global", + }: endpoint{ + Hostname: "ce.cn-northwest-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-northwest-1", + }, + }, + }, + }, + "cloudformation": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "cloudfront": service{ + PartitionEndpoint: "aws-cn-global", + IsRegionalized: boxedFalse, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-cn-global", + }: endpoint{ + Hostname: "cloudfront.cn-northwest-1.amazonaws.com.cn", + Protocols: []string{"http", "https"}, + CredentialScope: credentialScope{ + Region: "cn-northwest-1", + }, + }, + }, + }, + "cloudtrail": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "codebuild": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "codecommit": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "codedeploy": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "cognito-identity": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + }, + }, + "compute-optimizer": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{ + Hostname: "compute-optimizer.cn-north-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-north-1", + }, + }, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{ + Hostname: "compute-optimizer.cn-northwest-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-northwest-1", + }, + }, + }, + }, + "config": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "cur": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "data.jobs.iot": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "databrew": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "dax": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "directconnect": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "dms": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "docdb": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{ + Hostname: "rds.cn-northwest-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-northwest-1", + }, + }, + }, + }, + "ds": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "dynamodb": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "ebs": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "ec2": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "ecs": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "eks": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "elasticache": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "elasticbeanstalk": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "elasticfilesystem": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-north-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticfilesystem-fips.cn-north-1.amazonaws.com.cn", + }, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticfilesystem-fips.cn-northwest-1.amazonaws.com.cn", + }, + endpointKey{ + Region: "fips-cn-north-1", + }: endpoint{ + Hostname: "elasticfilesystem-fips.cn-north-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-north-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-cn-northwest-1", + }: endpoint{ + Hostname: "elasticfilesystem-fips.cn-northwest-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-northwest-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "elasticloadbalancing": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "elasticmapreduce": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "emr-containers": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "es": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "events": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "firehose": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "fms": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "fsx": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "gamelift": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "glacier": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "glue": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "greengrass": service{ + IsRegionalized: boxedTrue, + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + }, + }, + "guardduty": service{ + IsRegionalized: boxedTrue, + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "health": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "iam": service{ + PartitionEndpoint: "aws-cn-global", + IsRegionalized: boxedFalse, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-cn-global", + }: endpoint{ + Hostname: "iam.cn-north-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-north-1", + }, + }, + }, + }, + "iot": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + CredentialScope: credentialScope{ + Service: "execute-api", + }, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "iotanalytics": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + }, + }, + "iotevents": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + }, + }, + "ioteventsdata": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{ + Hostname: "data.iotevents.cn-north-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-north-1", + }, + }, + }, + }, + "iotsecuredtunneling": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "iotsitewise": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + }, + }, + "kafka": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "kinesis": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "kinesisanalytics": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "kms": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "lakeformation": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "lambda": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "license-manager": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "logs": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "mediaconvert": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{ + Hostname: "subscribe.mediaconvert.cn-northwest-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-northwest-1", + }, + }, + }, + }, + "monitoring": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "mq": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "neptune": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{ + Hostname: "rds.cn-north-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-north-1", + }, + }, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{ + Hostname: "rds.cn-northwest-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-northwest-1", + }, + }, + }, + }, + "organizations": service{ + PartitionEndpoint: "aws-cn-global", + IsRegionalized: boxedFalse, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-cn-global", + }: endpoint{ + Hostname: "organizations.cn-northwest-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-northwest-1", + }, + }, + }, + }, + "personalize": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + }, + }, + "pi": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "polly": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "ram": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "rds": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "redshift": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "resource-groups": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "route53": service{ + PartitionEndpoint: "aws-cn-global", + IsRegionalized: boxedFalse, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-cn-global", + }: endpoint{ + Hostname: "route53.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-northwest-1", + }, + }, + }, + }, + "route53resolver": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "runtime.sagemaker": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "s3": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + SignatureVersions: []string{"s3v4"}, + }, + defaultKey{ + Variant: dualStackVariant, + }: endpoint{ + Hostname: "{service}.dualstack.{region}.{dnsSuffix}", + DNSSuffix: "amazonaws.com.cn", + Protocols: []string{"http", "https"}, + SignatureVersions: []string{"s3v4"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-north-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3.dualstack.cn-north-1.amazonaws.com.cn", + }, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3.dualstack.cn-northwest-1.amazonaws.com.cn", + }, + }, + }, + "s3-control": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + SignatureVersions: []string{"s3v4"}, + }, + defaultKey{ + Variant: dualStackVariant, + }: endpoint{ + Hostname: "{service}.dualstack.{region}.{dnsSuffix}", + DNSSuffix: "amazonaws.com.cn", + Protocols: []string{"https"}, + SignatureVersions: []string{"s3v4"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{ + Hostname: "s3-control.cn-north-1.amazonaws.com.cn", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "cn-north-1", + }, + }, + endpointKey{ + Region: "cn-north-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3-control.dualstack.cn-north-1.amazonaws.com.cn", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "cn-north-1", + }, + }, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{ + Hostname: "s3-control.cn-northwest-1.amazonaws.com.cn", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "cn-northwest-1", + }, + }, + endpointKey{ + Region: "cn-northwest-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3-control.dualstack.cn-northwest-1.amazonaws.com.cn", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "cn-northwest-1", + }, + }, + }, + }, + "secretsmanager": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "securityhub": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "serverlessrepo": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{ + Protocols: []string{"https"}, + }, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{ + Protocols: []string{"https"}, + }, + }, + }, + "servicecatalog": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "servicediscovery": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "sms": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "snowball": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-north-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "snowball-fips.cn-north-1.amazonaws.com.cn", + }, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "snowball-fips.cn-northwest-1.amazonaws.com.cn", + }, + endpointKey{ + Region: "fips-cn-north-1", + }: endpoint{ + Hostname: "snowball-fips.cn-north-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-north-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-cn-northwest-1", + }: endpoint{ + Hostname: "snowball-fips.cn-northwest-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-northwest-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "sns": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "sqs": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + SSLCommonName: "{region}.queue.{dnsSuffix}", + Protocols: []string{"http", "https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "ssm": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "states": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "storagegateway": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "streams.dynamodb": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + CredentialScope: credentialScope{ + Service: "dynamodb", + }, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "sts": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "support": service{ + PartitionEndpoint: "aws-cn-global", + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-cn-global", + }: endpoint{ + Hostname: "support.cn-north-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-north-1", + }, + }, + }, + }, + "swf": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "tagging": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "transcribe": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{ + Hostname: "cn.transcribe.cn-north-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-north-1", + }, + }, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{ + Hostname: "cn.transcribe.cn-northwest-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-northwest-1", + }, + }, + }, + }, + "transcribestreaming": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "transfer": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "waf-regional": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{ + Hostname: "waf-regional.cn-north-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-north-1", + }, + }, + endpointKey{ + Region: "cn-north-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "waf-regional-fips.cn-north-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-north-1", + }, + }, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{ + Hostname: "waf-regional.cn-northwest-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-northwest-1", + }, + }, + endpointKey{ + Region: "cn-northwest-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "waf-regional-fips.cn-northwest-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-northwest-1", + }, + }, + endpointKey{ + Region: "fips-cn-north-1", + }: endpoint{ + Hostname: "waf-regional-fips.cn-north-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-north-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-cn-northwest-1", + }: endpoint{ + Hostname: "waf-regional-fips.cn-northwest-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-northwest-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "workspaces": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + "xray": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, + }, +} + +// AwsUsGovPartition returns the Resolver for AWS GovCloud (US). +func AwsUsGovPartition() Partition { + return awsusgovPartition.Partition() +} + +var awsusgovPartition = partition{ + ID: "aws-us-gov", + Name: "AWS GovCloud (US)", + DNSSuffix: "amazonaws.com", + RegionRegex: regionRegex{ + Regexp: func() *regexp.Regexp { + reg, _ := regexp.Compile("^us\\-gov\\-\\w+\\-\\d+$") + return reg + }(), + }, + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Hostname: "{service}.{region}.{dnsSuffix}", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + defaultKey{ + Variant: dualStackVariant, + }: endpoint{ + Hostname: "{service}.{region}.{dnsSuffix}", + DNSSuffix: "api.aws", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "{service}-fips.{region}.{dnsSuffix}", + DNSSuffix: "amazonaws.com", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + defaultKey{ + Variant: fipsVariant | dualStackVariant, + }: endpoint{ + Hostname: "{service}-fips.{region}.{dnsSuffix}", + DNSSuffix: "api.aws", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + }, + Regions: regions{ + "us-gov-east-1": region{ + Description: "AWS GovCloud (US-East)", + }, + "us-gov-west-1": region{ + Description: "AWS GovCloud (US-West)", + }, + }, + Services: services{ + "access-analyzer": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{ + Hostname: "access-analyzer.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Hostname: "access-analyzer.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "acm": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{ + Hostname: "acm.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Hostname: "acm.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "acm-pca": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "acm-pca.{region}.{dnsSuffix}", + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "acm-pca.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "acm-pca.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "acm-pca.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "acm-pca.us-gov-west-1.amazonaws.com", + }, + }, + }, + "api.detective": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "api.detective-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-east-1-fips", + }: endpoint{ + Hostname: "api.detective-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "api.detective-fips.us-gov-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1-fips", + }: endpoint{ + Hostname: "api.detective-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "api.ecr": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{}, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "ecr-fips.{region}.{dnsSuffix}", + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "dkr-us-gov-east-1", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "dkr-us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ecr-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "dkr-us-gov-west-1", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "dkr-us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ecr-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-dkr-us-gov-east-1", + }: endpoint{ + Hostname: "ecr-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-dkr-us-gov-west-1", + }: endpoint{ + Hostname: "ecr-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "ecr-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "ecr-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{ + Hostname: "api.ecr.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ecr-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Hostname: "api.ecr.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ecr-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "api.sagemaker": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{}, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "api-fips.sagemaker.{region}.{dnsSuffix}", + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "api-fips.sagemaker.us-gov-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1-fips", + }: endpoint{ + Hostname: "api-fips.sagemaker.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1-fips-secondary", + }: endpoint{ + Hostname: "api.sagemaker.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1-secondary", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1-secondary", + Variant: fipsVariant, + }: endpoint{ + Hostname: "api.sagemaker.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "apigateway": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + }, + }, + "appconfigdata": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + }, + }, + "application-autoscaling": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Hostname: "autoscaling.{region}.amazonaws.com", + Protocols: []string{"http", "https"}, + CredentialScope: credentialScope{ + Service: "application-autoscaling", + }, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{ + Protocols: []string{"http", "https"}, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + }, + "applicationinsights": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{ + Hostname: "applicationinsights.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Hostname: "applicationinsights.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "appstream2": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + CredentialScope: credentialScope{ + Service: "appstream", + }, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips", + }: endpoint{ + Hostname: "appstream2-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "appstream2-fips.us-gov-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1-fips", + }: endpoint{ + Hostname: "appstream2-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "athena": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "athena-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "athena-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "athena-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "athena-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "autoscaling": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{ + Protocols: []string{"http", "https"}, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + }, + "autoscaling-plans": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{ + Protocols: []string{"http", "https"}, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + }, + "backup": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + }, + }, + "batch": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{}, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "batch.{region}.{dnsSuffix}", + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "batch.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "batch.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "batch.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "batch.us-gov-west-1.amazonaws.com", + }, + }, + }, + "cloudcontrolapi": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "cloudcontrolapi-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "cloudcontrolapi-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "cloudcontrolapi-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "cloudcontrolapi-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "clouddirectory": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + }, + }, + "cloudformation": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{ + Hostname: "cloudformation.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Hostname: "cloudformation.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "cloudhsm": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + }, + }, + "cloudhsmv2": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + CredentialScope: credentialScope{ + Service: "cloudhsm", + }, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + }, + }, + "cloudtrail": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{ + Hostname: "cloudtrail.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Hostname: "cloudtrail.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "codebuild": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "codebuild-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-east-1-fips", + }: endpoint{ + Hostname: "codebuild-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "codebuild-fips.us-gov-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1-fips", + }: endpoint{ + Hostname: "codebuild-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "codecommit": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips", + }: endpoint{ + Hostname: "codecommit-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "codecommit-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-east-1-fips", + }: endpoint{ + Hostname: "codecommit-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "codecommit-fips.us-gov-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1-fips", + }: endpoint{ + Hostname: "codecommit-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "codedeploy": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "codedeploy-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-east-1-fips", + }: endpoint{ + Hostname: "codedeploy-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "codedeploy-fips.us-gov-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1-fips", + }: endpoint{ + Hostname: "codedeploy-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "codepipeline": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "codepipeline-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "codepipeline-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "cognito-identity": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "cognito-identity-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "cognito-identity-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "cognito-idp": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "cognito-idp-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "cognito-idp-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "comprehend": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "comprehend-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "comprehend-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "comprehendmedical": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "comprehendmedical-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "comprehendmedical-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "config": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{}, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "config.{region}.{dnsSuffix}", + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "config.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "config.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "config.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "config.us-gov-west-1.amazonaws.com", + }, + }, + }, + "connect": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + }, + }, + "data.jobs.iot": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "data.jobs.iot-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "data.jobs.iot-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "data.jobs.iot-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "data.jobs.iot-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "databrew": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + }, + }, + "datasync": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "datasync-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "datasync-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "datasync-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "datasync-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "directconnect": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{ + Hostname: "directconnect.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Hostname: "directconnect.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "dms": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{}, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "dms.{region}.{dnsSuffix}", + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "dms", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "dms", + Variant: fipsVariant, + }: endpoint{ + Hostname: "dms.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "dms-fips", + }: endpoint{ + Hostname: "dms.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "dms.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-east-1-fips", + }: endpoint{ + Hostname: "dms.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "dms.us-gov-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1-fips", + }: endpoint{ + Hostname: "dms.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "docdb": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Hostname: "rds.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "ds": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "ds-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "ds-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ds-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ds-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "dynamodb": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{}, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "dynamodb.{region}.{dnsSuffix}", + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "dynamodb.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-east-1-fips", + }: endpoint{ + Hostname: "dynamodb.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "dynamodb.us-gov-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1-fips", + }: endpoint{ + Hostname: "dynamodb.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "ebs": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + }, + }, + "ec2": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{ + Hostname: "ec2.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Hostname: "ec2.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "ecs": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "ecs-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "ecs-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ecs-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ecs-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "eks": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + }, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "eks.{region}.{dnsSuffix}", + Protocols: []string{"http", "https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "eks.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "eks.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "eks.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "eks.us-gov-west-1.amazonaws.com", + }, + }, + }, + "elasticache": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{}, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticache.{region}.{dnsSuffix}", + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips", + }: endpoint{ + Hostname: "elasticache.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticache.us-gov-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1-fips", + }: endpoint{ + Hostname: "elasticache.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "elasticbeanstalk": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{ + Hostname: "elasticbeanstalk.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Hostname: "elasticbeanstalk.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "elasticfilesystem": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "elasticfilesystem-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "elasticfilesystem-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticfilesystem-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticfilesystem-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "elasticloadbalancing": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{}, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticloadbalancing.{region}.{dnsSuffix}", + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "elasticloadbalancing.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "elasticloadbalancing.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticloadbalancing.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Protocols: []string{"http", "https"}, + }, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticloadbalancing.us-gov-west-1.amazonaws.com", + Protocols: []string{"http", "https"}, + }, + }, + }, + "elasticmapreduce": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{}, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticmapreduce.{region}.{dnsSuffix}", + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "elasticmapreduce.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "elasticmapreduce.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticmapreduce.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Protocols: []string{"https"}, + }, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticmapreduce.us-gov-west-1.amazonaws.com", + Protocols: []string{"https"}, + }, + }, + }, + "email": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "email-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "email-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "es": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips", + }: endpoint{ + Hostname: "es-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "es-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-east-1-fips", + }: endpoint{ + Hostname: "es-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "es-fips.us-gov-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1-fips", + }: endpoint{ + Hostname: "es-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "events": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{ + Hostname: "events.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Hostname: "events.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "firehose": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "firehose-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "firehose-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "firehose-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "firehose-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "fms": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "fms-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "fms-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fms-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fms-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "fsx": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-prod-us-gov-east-1", + }: endpoint{ + Hostname: "fsx-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-prod-us-gov-west-1", + }: endpoint{ + Hostname: "fsx-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "fsx-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "fsx-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "prod-us-gov-east-1", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "prod-us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fsx-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "prod-us-gov-west-1", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "prod-us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fsx-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fsx-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fsx-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "glacier": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{ + Hostname: "glacier.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Hostname: "glacier.us-gov-west-1.amazonaws.com", + Protocols: []string{"http", "https"}, + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "glue": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "glue-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "glue-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "glue-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "glue-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "greengrass": service{ + IsRegionalized: boxedTrue, + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "dataplane-us-gov-east-1", + }: endpoint{ + Hostname: "greengrass-ats.iot.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + endpointKey{ + Region: "dataplane-us-gov-west-1", + }: endpoint{ + Hostname: "greengrass-ats.iot.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "greengrass-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{ + Hostname: "greengrass.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "greengrass-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Hostname: "greengrass.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "guardduty": service{ + IsRegionalized: boxedTrue, + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "guardduty.{region}.{dnsSuffix}", + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "guardduty.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-east-1-fips", + }: endpoint{ + Hostname: "guardduty.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "guardduty.us-gov-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1-fips", + }: endpoint{ + Hostname: "guardduty.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "health": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "health-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "health-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "iam": service{ + PartitionEndpoint: "aws-us-gov-global", + IsRegionalized: boxedFalse, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-us-gov-global", + }: endpoint{ + Hostname: "iam.us-gov.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + endpointKey{ + Region: "aws-us-gov-global", + Variant: fipsVariant, + }: endpoint{ + Hostname: "iam.us-gov.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + endpointKey{ + Region: "aws-us-gov-global-fips", + }: endpoint{ + Hostname: "iam.us-gov.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "iam-govcloud", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "iam-govcloud", + Variant: fipsVariant, + }: endpoint{ + Hostname: "iam.us-gov.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "iam-govcloud-fips", + }: endpoint{ + Hostname: "iam.us-gov.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "identitystore": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{}, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "identitystore.{region}.{dnsSuffix}", + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "identitystore.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "identitystore.us-gov-west-1.amazonaws.com", + }, + }, + }, + "inspector": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "inspector-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "inspector-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "inspector-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "inspector-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "iot": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + CredentialScope: credentialScope{ + Service: "execute-api", + }, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "iot-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Service: "execute-api", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "iot-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Service: "execute-api", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "iot-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "iot-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "iotevents": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + }, + }, + "ioteventsdata": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Hostname: "data.iotevents.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "iotsecuredtunneling": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{}, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "api.tunneling.iot-fips.{region}.{dnsSuffix}", + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "api.tunneling.iot-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "api.tunneling.iot-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "api.tunneling.iot-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "api.tunneling.iot-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "iotsitewise": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + }, + }, + "kafka": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + }, + }, + "kendra": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "kendra-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kendra-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "kinesis": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{ + Hostname: "kinesis.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Hostname: "kinesis.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "kinesisanalytics": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + }, + }, + "kms": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ProdFips", + }: endpoint{ + Hostname: "kms-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kms-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-east-1-fips", + }: endpoint{ + Hostname: "kms-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kms-fips.us-gov-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1-fips", + }: endpoint{ + Hostname: "kms-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "lakeformation": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "lakeformation-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "lakeformation-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "lambda": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "lambda-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "lambda-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "lambda-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "lambda-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "license-manager": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "license-manager-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "license-manager-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "license-manager-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "license-manager-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "logs": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{ + Hostname: "logs.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Hostname: "logs.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "mediaconvert": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Hostname: "mediaconvert.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "metering.marketplace": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + CredentialScope: credentialScope{ + Service: "aws-marketplace", + }, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + }, + }, + "models.lex": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + CredentialScope: credentialScope{ + Service: "lex", + }, + }, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "models-fips.lex.{region}.{dnsSuffix}", + CredentialScope: credentialScope{ + Service: "lex", + }, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "models-fips.lex.us-gov-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1-fips", + }: endpoint{ + Hostname: "models-fips.lex.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "monitoring": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{}, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "monitoring.{region}.{dnsSuffix}", + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "monitoring.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "monitoring.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "monitoring.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "monitoring.us-gov-west-1.amazonaws.com", + }, + }, + }, + "mq": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "mq-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "mq-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "mq-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "mq-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "neptune": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{ + Hostname: "rds.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Hostname: "rds.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "network-firewall": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "network-firewall-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "network-firewall-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "network-firewall-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "network-firewall-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "networkmanager": service{ + PartitionEndpoint: "aws-us-gov-global", + IsRegionalized: boxedFalse, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-us-gov-global", + }: endpoint{ + Hostname: "networkmanager.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "oidc": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Hostname: "oidc.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "organizations": service{ + PartitionEndpoint: "aws-us-gov-global", + IsRegionalized: boxedFalse, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-us-gov-global", + }: endpoint{ + Hostname: "organizations.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + endpointKey{ + Region: "aws-us-gov-global", + Variant: fipsVariant, + }: endpoint{ + Hostname: "organizations.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + endpointKey{ + Region: "fips-aws-us-gov-global", + }: endpoint{ + Hostname: "organizations.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "outposts": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{ + Hostname: "outposts.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Hostname: "outposts.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "pinpoint": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + CredentialScope: credentialScope{ + Service: "mobiletargeting", + }, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "pinpoint-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Hostname: "pinpoint.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "pinpoint-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "polly": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "polly-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "polly-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "portal.sso": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Hostname: "portal.sso.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "quicksight": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "api", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + }, + }, + "ram": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{ + Hostname: "ram.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Hostname: "ram.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "rds": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{}, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "rds.{region}.{dnsSuffix}", + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "rds.us-gov-east-1", + }: endpoint{ + Hostname: "rds.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "rds.us-gov-west-1", + }: endpoint{ + Hostname: "rds.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "rds.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-east-1-fips", + }: endpoint{ + Hostname: "rds.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "rds.us-gov-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1-fips", + }: endpoint{ + Hostname: "rds.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "redshift": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{ + Hostname: "redshift.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Hostname: "redshift.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "rekognition": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "rekognition-fips.us-gov-west-1", + }: endpoint{ + Hostname: "rekognition-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "rekognition.us-gov-west-1", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "rekognition.us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "rekognition-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "rekognition-fips.us-gov-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1-fips", + }: endpoint{ + Hostname: "rekognition-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "resource-groups": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{}, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "resource-groups.{region}.{dnsSuffix}", + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "resource-groups.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "resource-groups.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "resource-groups.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "resource-groups.us-gov-west-1.amazonaws.com", + }, + }, + }, + "route53": service{ + PartitionEndpoint: "aws-us-gov-global", + IsRegionalized: boxedFalse, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-us-gov-global", + }: endpoint{ + Hostname: "route53.us-gov.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + endpointKey{ + Region: "aws-us-gov-global", + Variant: fipsVariant, + }: endpoint{ + Hostname: "route53.us-gov.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + endpointKey{ + Region: "fips-aws-us-gov-global", + }: endpoint{ + Hostname: "route53.us-gov.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "route53resolver": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + }, + }, + "runtime.lex": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + CredentialScope: credentialScope{ + Service: "lex", + }, + }, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "runtime-fips.lex.{region}.{dnsSuffix}", + CredentialScope: credentialScope{ + Service: "lex", + }, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "runtime-fips.lex.us-gov-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1-fips", + }: endpoint{ + Hostname: "runtime-fips.lex.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "runtime.sagemaker": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{}, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "runtime.sagemaker.{region}.{dnsSuffix}", + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "runtime.sagemaker.us-gov-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1-fips", + }: endpoint{ + Hostname: "runtime.sagemaker.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "s3": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + SignatureVersions: []string{"s3", "s3v4"}, + }, + defaultKey{ + Variant: dualStackVariant, + }: endpoint{ + Hostname: "{service}.dualstack.{region}.{dnsSuffix}", + DNSSuffix: "amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + defaultKey{ + Variant: fipsVariant | dualStackVariant, + }: endpoint{ + Hostname: "{service}-fips.dualstack.{region}.{dnsSuffix}", + DNSSuffix: "amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "s3-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "s3-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{ + Hostname: "s3.us-gov-east-1.amazonaws.com", + Protocols: []string{"http", "https"}, + }, + endpointKey{ + Region: "us-gov-east-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3.dualstack.us-gov-east-1.amazonaws.com", + Protocols: []string{"http", "https"}, + }, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "s3-fips.us-gov-east-1.amazonaws.com", + Protocols: []string{"http", "https"}, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Hostname: "s3.us-gov-west-1.amazonaws.com", + Protocols: []string{"http", "https"}, + }, + endpointKey{ + Region: "us-gov-west-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3.dualstack.us-gov-west-1.amazonaws.com", + Protocols: []string{"http", "https"}, + }, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "s3-fips.us-gov-west-1.amazonaws.com", + Protocols: []string{"http", "https"}, + }, + }, + }, + "s3-control": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + SignatureVersions: []string{"s3v4"}, + }, + defaultKey{ + Variant: dualStackVariant, + }: endpoint{ + Hostname: "{service}.dualstack.{region}.{dnsSuffix}", + DNSSuffix: "amazonaws.com", + Protocols: []string{"https"}, + SignatureVersions: []string{"s3v4"}, + }, + defaultKey{ + Variant: fipsVariant | dualStackVariant, + }: endpoint{ + Hostname: "{service}-fips.dualstack.{region}.{dnsSuffix}", + DNSSuffix: "amazonaws.com", + Protocols: []string{"https"}, + SignatureVersions: []string{"s3v4"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{ + Hostname: "s3-control.us-gov-east-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + endpointKey{ + Region: "us-gov-east-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3-control.dualstack.us-gov-east-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "s3-control-fips.us-gov-east-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant | dualStackVariant, + }: endpoint{ + Hostname: "s3-control-fips.dualstack.us-gov-east-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + endpointKey{ + Region: "us-gov-east-1-fips", + }: endpoint{ + Hostname: "s3-control-fips.us-gov-east-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Hostname: "s3-control.us-gov-west-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + endpointKey{ + Region: "us-gov-west-1", + Variant: dualStackVariant, + }: endpoint{ + Hostname: "s3-control.dualstack.us-gov-west-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "s3-control-fips.us-gov-west-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant | dualStackVariant, + }: endpoint{ + Hostname: "s3-control-fips.dualstack.us-gov-west-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + endpointKey{ + Region: "us-gov-west-1-fips", + }: endpoint{ + Hostname: "s3-control-fips.us-gov-west-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "secretsmanager": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "secretsmanager-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-east-1-fips", + }: endpoint{ + Hostname: "secretsmanager-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "secretsmanager-fips.us-gov-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1-fips", + }: endpoint{ + Hostname: "secretsmanager-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "securityhub": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "securityhub-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "securityhub-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "securityhub-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "securityhub-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "serverlessrepo": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{ + Hostname: "serverlessrepo.us-gov-east-1.amazonaws.com", + Protocols: []string{"https"}, + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Hostname: "serverlessrepo.us-gov-west-1.amazonaws.com", + Protocols: []string{"https"}, + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "servicecatalog": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "servicecatalog-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-east-1-fips", + }: endpoint{ + Hostname: "servicecatalog-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "servicecatalog-fips.us-gov-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1-fips", + }: endpoint{ + Hostname: "servicecatalog-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "servicecatalog-appregistry": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{}, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "servicecatalog-appregistry.{region}.{dnsSuffix}", + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "servicecatalog-appregistry.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "servicecatalog-appregistry.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "servicecatalog-appregistry.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "servicecatalog-appregistry.us-gov-west-1.amazonaws.com", + }, + }, + }, + "servicediscovery": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "servicediscovery", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "servicediscovery", + Variant: fipsVariant, + }: endpoint{ + Hostname: "servicediscovery-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "servicediscovery-fips", + }: endpoint{ + Hostname: "servicediscovery-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "servicediscovery-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-east-1-fips", + }: endpoint{ + Hostname: "servicediscovery-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "servicediscovery-fips.us-gov-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1-fips", + }: endpoint{ + Hostname: "servicediscovery-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "servicequotas": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "servicequotas.{region}.{dnsSuffix}", + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "servicequotas.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "servicequotas.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "servicequotas.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "servicequotas.us-gov-west-1.amazonaws.com", + }, + }, + }, + "sms": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "sms-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "sms-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "sms-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "sms-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "snowball": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "snowball-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "snowball-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "snowball-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "snowball-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "sns": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{ + Hostname: "sns.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Hostname: "sns.us-gov-west-1.amazonaws.com", + Protocols: []string{"http", "https"}, + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "sqs": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{ + Hostname: "sqs.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Hostname: "sqs.us-gov-west-1.amazonaws.com", + SSLCommonName: "{region}.queue.{dnsSuffix}", + Protocols: []string{"http", "https"}, + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "ssm": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{}, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "ssm.{region}.{dnsSuffix}", + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "ssm.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "ssm.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ssm.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "ssm.us-gov-west-1.amazonaws.com", + }, + }, + }, + "states": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "states-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "states.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "states-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "states.us-gov-west-1.amazonaws.com", + }, + }, + }, + "storagegateway": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips", + }: endpoint{ + Hostname: "storagegateway-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "storagegateway-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-east-1-fips", + }: endpoint{ + Hostname: "storagegateway-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "storagegateway-fips.us-gov-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1-fips", + }: endpoint{ + Hostname: "storagegateway-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "streams.dynamodb": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + CredentialScope: credentialScope{ + Service: "dynamodb", + }, + }, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "streams.dynamodb.{region}.{dnsSuffix}", + CredentialScope: credentialScope{ + Service: "dynamodb", + }, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "streams.dynamodb.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-east-1-fips", + }: endpoint{ + Hostname: "streams.dynamodb.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "streams.dynamodb.us-gov-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1-fips", + }: endpoint{ + Hostname: "streams.dynamodb.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "sts": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{}, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "sts.{region}.{dnsSuffix}", + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "sts.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-east-1-fips", + }: endpoint{ + Hostname: "sts.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "sts.us-gov-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1-fips", + }: endpoint{ + Hostname: "sts.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "support": service{ + PartitionEndpoint: "aws-us-gov-global", + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-us-gov-global", + }: endpoint{ + Hostname: "support.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "support.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "support.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "swf": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{ + Hostname: "swf.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Hostname: "swf.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "tagging": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + }, + }, + "textract": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "textract-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "textract-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "textract-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "textract-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "transcribe": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "fips.transcribe.{region}.{dnsSuffix}", + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "fips.transcribe.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "fips.transcribe.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fips.transcribe.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "fips.transcribe.us-gov-west-1.amazonaws.com", + }, + }, + }, + "transfer": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "transfer-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "transfer-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "transfer-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "transfer-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "translate": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "translate-fips.us-gov-west-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1-fips", + }: endpoint{ + Hostname: "translate-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "waf-regional": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "waf-regional-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "waf-regional-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{ + Hostname: "waf-regional.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "waf-regional-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Hostname: "waf-regional.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "waf-regional-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "workspaces": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "workspaces-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "workspaces-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + "xray": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-gov-east-1", + }: endpoint{ + Hostname: "xray-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "xray-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "xray-fips.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "xray-fips.us-gov-west-1.amazonaws.com", + }, + }, + }, + }, +} + +// AwsIsoPartition returns the Resolver for AWS ISO (US). +func AwsIsoPartition() Partition { + return awsisoPartition.Partition() +} + +var awsisoPartition = partition{ + ID: "aws-iso", + Name: "AWS ISO (US)", + DNSSuffix: "c2s.ic.gov", + RegionRegex: regionRegex{ + Regexp: func() *regexp.Regexp { + reg, _ := regexp.Compile("^us\\-iso\\-\\w+\\-\\d+$") + return reg + }(), + }, + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Hostname: "{service}.{region}.{dnsSuffix}", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "{service}-fips.{region}.{dnsSuffix}", + DNSSuffix: "c2s.ic.gov", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + }, + Regions: regions{ + "us-iso-east-1": region{ + Description: "US ISO East", + }, + "us-iso-west-1": region{ + Description: "US ISO WEST", + }, + }, + Services: services{ + "api.ecr": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{ + Hostname: "api.ecr.us-iso-east-1.c2s.ic.gov", + CredentialScope: credentialScope{ + Region: "us-iso-east-1", + }, + }, + endpointKey{ + Region: "us-iso-west-1", + }: endpoint{ + Hostname: "api.ecr.us-iso-west-1.c2s.ic.gov", + CredentialScope: credentialScope{ + Region: "us-iso-west-1", + }, + }, + }, + }, + "api.sagemaker": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + }, + }, + "apigateway": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + }, + }, + "application-autoscaling": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-iso-west-1", + }: endpoint{}, + }, + }, + "autoscaling": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{ + Protocols: []string{"http", "https"}, + }, + endpointKey{ + Region: "us-iso-west-1", + }: endpoint{}, + }, + }, + "cloudformation": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-iso-west-1", + }: endpoint{}, + }, + }, + "cloudtrail": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-iso-west-1", + }: endpoint{}, + }, + }, + "codedeploy": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-iso-west-1", + }: endpoint{}, + }, + }, + "comprehend": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + }, + }, + "config": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-iso-west-1", + }: endpoint{}, + }, + }, + "datapipeline": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + }, + }, + "directconnect": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-iso-west-1", + }: endpoint{}, + }, + }, + "dms": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{}, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "dms.{region}.{dnsSuffix}", + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "dms", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-iso-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "dms", + Variant: fipsVariant, + }: endpoint{ + Hostname: "dms.us-iso-east-1.c2s.ic.gov", + CredentialScope: credentialScope{ + Region: "us-iso-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "dms-fips", + }: endpoint{ + Hostname: "dms.us-iso-east-1.c2s.ic.gov", + CredentialScope: credentialScope{ + Region: "us-iso-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-iso-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "dms.us-iso-east-1.c2s.ic.gov", + }, + endpointKey{ + Region: "us-iso-east-1-fips", + }: endpoint{ + Hostname: "dms.us-iso-east-1.c2s.ic.gov", + CredentialScope: credentialScope{ + Region: "us-iso-east-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "ds": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + }, + }, + "dynamodb": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{ + Protocols: []string{"http", "https"}, + }, + endpointKey{ + Region: "us-iso-west-1", + }: endpoint{}, + }, + }, + "ebs": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + }, + }, + "ec2": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-iso-west-1", + }: endpoint{}, + }, + }, + "ecs": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-iso-west-1", + }: endpoint{}, + }, + }, + "elasticache": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-iso-west-1", + }: endpoint{}, + }, + }, + "elasticfilesystem": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "fips-us-iso-east-1", + }: endpoint{ + Hostname: "elasticfilesystem-fips.us-iso-east-1.c2s.ic.gov", + CredentialScope: credentialScope{ + Region: "us-iso-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-iso-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticfilesystem-fips.us-iso-east-1.c2s.ic.gov", + }, + }, + }, + "elasticloadbalancing": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{ + Protocols: []string{"http", "https"}, + }, + endpointKey{ + Region: "us-iso-west-1", + }: endpoint{}, + }, + }, + "elasticmapreduce": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{ + Protocols: []string{"https"}, + }, + endpointKey{ + Region: "us-iso-west-1", + }: endpoint{}, + }, + }, + "es": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + }, + }, + "events": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-iso-west-1", + }: endpoint{}, + }, + }, + "firehose": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + }, + }, + "glacier": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{ + Protocols: []string{"http", "https"}, + }, + endpointKey{ + Region: "us-iso-west-1", + }: endpoint{}, + }, + }, + "health": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + }, + }, + "iam": service{ + PartitionEndpoint: "aws-iso-global", + IsRegionalized: boxedFalse, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-iso-global", + }: endpoint{ + Hostname: "iam.us-iso-east-1.c2s.ic.gov", + CredentialScope: credentialScope{ + Region: "us-iso-east-1", + }, + }, + }, + }, + "kinesis": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-iso-west-1", + }: endpoint{}, + }, + }, + "kms": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ProdFips", + }: endpoint{ + Hostname: "kms-fips.us-iso-east-1.c2s.ic.gov", + CredentialScope: credentialScope{ + Region: "us-iso-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-iso-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kms-fips.us-iso-east-1.c2s.ic.gov", + }, + endpointKey{ + Region: "us-iso-east-1-fips", + }: endpoint{ + Hostname: "kms-fips.us-iso-east-1.c2s.ic.gov", + CredentialScope: credentialScope{ + Region: "us-iso-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-iso-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-iso-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kms-fips.us-iso-west-1.c2s.ic.gov", + }, + endpointKey{ + Region: "us-iso-west-1-fips", + }: endpoint{ + Hostname: "kms-fips.us-iso-west-1.c2s.ic.gov", + CredentialScope: credentialScope{ + Region: "us-iso-west-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "lambda": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-iso-west-1", + }: endpoint{}, + }, + }, + "license-manager": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + }, + }, + "logs": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-iso-west-1", + }: endpoint{}, + }, + }, + "medialive": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + }, + }, + "mediapackage": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + }, + }, + "monitoring": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-iso-west-1", + }: endpoint{}, + }, + }, + "outposts": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + }, + }, + "ram": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + }, + }, + "rds": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-iso-west-1", + }: endpoint{}, + }, + }, + "redshift": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-iso-west-1", + }: endpoint{}, + }, + }, + "route53": service{ + PartitionEndpoint: "aws-iso-global", + IsRegionalized: boxedFalse, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-iso-global", + }: endpoint{ + Hostname: "route53.c2s.ic.gov", + CredentialScope: credentialScope{ + Region: "us-iso-east-1", + }, + }, + }, + }, + "route53resolver": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + }, + }, + "runtime.sagemaker": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + }, + }, + "s3": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + SignatureVersions: []string{"s3v4"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{ + Protocols: []string{"http", "https"}, + SignatureVersions: []string{"s3v4"}, + }, + endpointKey{ + Region: "us-iso-west-1", + }: endpoint{}, + }, + }, + "secretsmanager": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + }, + }, + "snowball": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + }, + }, + "sns": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{ + Protocols: []string{"http", "https"}, + }, + endpointKey{ + Region: "us-iso-west-1", + }: endpoint{}, + }, + }, + "sqs": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{ + Protocols: []string{"http", "https"}, + }, + endpointKey{ + Region: "us-iso-west-1", + }: endpoint{}, + }, + }, + "ssm": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + }, + }, + "states": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-iso-west-1", + }: endpoint{}, + }, + }, + "streams.dynamodb": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + CredentialScope: credentialScope{ + Service: "dynamodb", + }, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + }, + }, + "sts": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-iso-west-1", + }: endpoint{}, + }, + }, + "support": service{ + PartitionEndpoint: "aws-iso-global", + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-iso-global", + }: endpoint{ + Hostname: "support.us-iso-east-1.c2s.ic.gov", + CredentialScope: credentialScope{ + Region: "us-iso-east-1", + }, + }, + }, + }, + "swf": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-iso-west-1", + }: endpoint{}, + }, + }, + "transcribe": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + }, + }, + "transcribestreaming": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + }, + }, + "translate": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + }, + }, + "workspaces": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-iso-east-1", + }: endpoint{}, + }, + }, + }, +} + +// AwsIsoBPartition returns the Resolver for AWS ISOB (US). +func AwsIsoBPartition() Partition { + return awsisobPartition.Partition() +} + +var awsisobPartition = partition{ + ID: "aws-iso-b", + Name: "AWS ISOB (US)", + DNSSuffix: "sc2s.sgov.gov", + RegionRegex: regionRegex{ + Regexp: func() *regexp.Regexp { + reg, _ := regexp.Compile("^us\\-isob\\-\\w+\\-\\d+$") + return reg + }(), + }, + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Hostname: "{service}.{region}.{dnsSuffix}", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "{service}-fips.{region}.{dnsSuffix}", + DNSSuffix: "sc2s.sgov.gov", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + }, + Regions: regions{ + "us-isob-east-1": region{ + Description: "US ISOB East (Ohio)", + }, + }, + Services: services{ + "api.ecr": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{ + Hostname: "api.ecr.us-isob-east-1.sc2s.sgov.gov", + CredentialScope: credentialScope{ + Region: "us-isob-east-1", + }, + }, + }, + }, + "application-autoscaling": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "autoscaling": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "cloudformation": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "cloudtrail": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "codedeploy": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "config": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "directconnect": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "dms": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{}, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "dms.{region}.{dnsSuffix}", + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "dms", + }: endpoint{ + CredentialScope: credentialScope{ + Region: "us-isob-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "dms", + Variant: fipsVariant, + }: endpoint{ + Hostname: "dms.us-isob-east-1.sc2s.sgov.gov", + CredentialScope: credentialScope{ + Region: "us-isob-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "dms-fips", + }: endpoint{ + Hostname: "dms.us-isob-east-1.sc2s.sgov.gov", + CredentialScope: credentialScope{ + Region: "us-isob-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-isob-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "dms.us-isob-east-1.sc2s.sgov.gov", + }, + endpointKey{ + Region: "us-isob-east-1-fips", + }: endpoint{ + Hostname: "dms.us-isob-east-1.sc2s.sgov.gov", + CredentialScope: credentialScope{ + Region: "us-isob-east-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "ds": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "dynamodb": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "ebs": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "ec2": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "ecs": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "elasticache": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "elasticloadbalancing": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{ + Protocols: []string{"https"}, + }, + }, + }, + "elasticmapreduce": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "es": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "events": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "glacier": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "health": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "iam": service{ + PartitionEndpoint: "aws-iso-b-global", + IsRegionalized: boxedFalse, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-iso-b-global", + }: endpoint{ + Hostname: "iam.us-isob-east-1.sc2s.sgov.gov", + CredentialScope: credentialScope{ + Region: "us-isob-east-1", + }, + }, + }, + }, + "kinesis": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "kms": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ProdFips", + }: endpoint{ + Hostname: "kms-fips.us-isob-east-1.sc2s.sgov.gov", + CredentialScope: credentialScope{ + Region: "us-isob-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-isob-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "kms-fips.us-isob-east-1.sc2s.sgov.gov", + }, + endpointKey{ + Region: "us-isob-east-1-fips", + }: endpoint{ + Hostname: "kms-fips.us-isob-east-1.sc2s.sgov.gov", + CredentialScope: credentialScope{ + Region: "us-isob-east-1", + }, + Deprecated: boxedTrue, + }, + }, + }, + "lambda": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "license-manager": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "logs": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "monitoring": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "rds": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "redshift": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "route53": service{ + PartitionEndpoint: "aws-iso-b-global", + IsRegionalized: boxedFalse, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-iso-b-global", + }: endpoint{ + Hostname: "route53.sc2s.sgov.gov", + CredentialScope: credentialScope{ + Region: "us-isob-east-1", + }, + }, + }, + }, + "s3": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + SignatureVersions: []string{"s3v4"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "snowball": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "sns": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "sqs": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + SSLCommonName: "{region}.queue.{dnsSuffix}", + Protocols: []string{"http", "https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "ssm": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "states": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "streams.dynamodb": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"http", "https"}, + CredentialScope: credentialScope{ + Service: "dynamodb", + }, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "sts": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "support": service{ + PartitionEndpoint: "aws-iso-b-global", + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "aws-iso-b-global", + }: endpoint{ + Hostname: "support.us-isob-east-1.sc2s.sgov.gov", + CredentialScope: credentialScope{ + Region: "us-isob-east-1", + }, + }, + }, + }, + "swf": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + "tagging": service{ + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-isob-east-1", + }: endpoint{}, + }, + }, + }, +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/dep_service_ids.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/dep_service_ids.go new file mode 100644 index 0000000..ca8fc82 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/dep_service_ids.go @@ -0,0 +1,141 @@ +package endpoints + +// Service identifiers +// +// Deprecated: Use client package's EndpointsID value instead of these +// ServiceIDs. These IDs are not maintained, and are out of date. +const ( + A4bServiceID = "a4b" // A4b. + AcmServiceID = "acm" // Acm. + AcmPcaServiceID = "acm-pca" // AcmPca. + ApiMediatailorServiceID = "api.mediatailor" // ApiMediatailor. + ApiPricingServiceID = "api.pricing" // ApiPricing. + ApiSagemakerServiceID = "api.sagemaker" // ApiSagemaker. + ApigatewayServiceID = "apigateway" // Apigateway. + ApplicationAutoscalingServiceID = "application-autoscaling" // ApplicationAutoscaling. + Appstream2ServiceID = "appstream2" // Appstream2. + AppsyncServiceID = "appsync" // Appsync. + AthenaServiceID = "athena" // Athena. + AutoscalingServiceID = "autoscaling" // Autoscaling. + AutoscalingPlansServiceID = "autoscaling-plans" // AutoscalingPlans. + BatchServiceID = "batch" // Batch. + BudgetsServiceID = "budgets" // Budgets. + CeServiceID = "ce" // Ce. + ChimeServiceID = "chime" // Chime. + Cloud9ServiceID = "cloud9" // Cloud9. + ClouddirectoryServiceID = "clouddirectory" // Clouddirectory. + CloudformationServiceID = "cloudformation" // Cloudformation. + CloudfrontServiceID = "cloudfront" // Cloudfront. + CloudhsmServiceID = "cloudhsm" // Cloudhsm. + Cloudhsmv2ServiceID = "cloudhsmv2" // Cloudhsmv2. + CloudsearchServiceID = "cloudsearch" // Cloudsearch. + CloudtrailServiceID = "cloudtrail" // Cloudtrail. + CodebuildServiceID = "codebuild" // Codebuild. + CodecommitServiceID = "codecommit" // Codecommit. + CodedeployServiceID = "codedeploy" // Codedeploy. + CodepipelineServiceID = "codepipeline" // Codepipeline. + CodestarServiceID = "codestar" // Codestar. + CognitoIdentityServiceID = "cognito-identity" // CognitoIdentity. + CognitoIdpServiceID = "cognito-idp" // CognitoIdp. + CognitoSyncServiceID = "cognito-sync" // CognitoSync. + ComprehendServiceID = "comprehend" // Comprehend. + ConfigServiceID = "config" // Config. + CurServiceID = "cur" // Cur. + DatapipelineServiceID = "datapipeline" // Datapipeline. + DaxServiceID = "dax" // Dax. + DevicefarmServiceID = "devicefarm" // Devicefarm. + DirectconnectServiceID = "directconnect" // Directconnect. + DiscoveryServiceID = "discovery" // Discovery. + DmsServiceID = "dms" // Dms. + DsServiceID = "ds" // Ds. + DynamodbServiceID = "dynamodb" // Dynamodb. + Ec2ServiceID = "ec2" // Ec2. + Ec2metadataServiceID = "ec2metadata" // Ec2metadata. + EcrServiceID = "ecr" // Ecr. + EcsServiceID = "ecs" // Ecs. + ElasticacheServiceID = "elasticache" // Elasticache. + ElasticbeanstalkServiceID = "elasticbeanstalk" // Elasticbeanstalk. + ElasticfilesystemServiceID = "elasticfilesystem" // Elasticfilesystem. + ElasticloadbalancingServiceID = "elasticloadbalancing" // Elasticloadbalancing. + ElasticmapreduceServiceID = "elasticmapreduce" // Elasticmapreduce. + ElastictranscoderServiceID = "elastictranscoder" // Elastictranscoder. + EmailServiceID = "email" // Email. + EntitlementMarketplaceServiceID = "entitlement.marketplace" // EntitlementMarketplace. + EsServiceID = "es" // Es. + EventsServiceID = "events" // Events. + FirehoseServiceID = "firehose" // Firehose. + FmsServiceID = "fms" // Fms. + GameliftServiceID = "gamelift" // Gamelift. + GlacierServiceID = "glacier" // Glacier. + GlueServiceID = "glue" // Glue. + GreengrassServiceID = "greengrass" // Greengrass. + GuarddutyServiceID = "guardduty" // Guardduty. + HealthServiceID = "health" // Health. + IamServiceID = "iam" // Iam. + ImportexportServiceID = "importexport" // Importexport. + InspectorServiceID = "inspector" // Inspector. + IotServiceID = "iot" // Iot. + IotanalyticsServiceID = "iotanalytics" // Iotanalytics. + KinesisServiceID = "kinesis" // Kinesis. + KinesisanalyticsServiceID = "kinesisanalytics" // Kinesisanalytics. + KinesisvideoServiceID = "kinesisvideo" // Kinesisvideo. + KmsServiceID = "kms" // Kms. + LambdaServiceID = "lambda" // Lambda. + LightsailServiceID = "lightsail" // Lightsail. + LogsServiceID = "logs" // Logs. + MachinelearningServiceID = "machinelearning" // Machinelearning. + MarketplacecommerceanalyticsServiceID = "marketplacecommerceanalytics" // Marketplacecommerceanalytics. + MediaconvertServiceID = "mediaconvert" // Mediaconvert. + MedialiveServiceID = "medialive" // Medialive. + MediapackageServiceID = "mediapackage" // Mediapackage. + MediastoreServiceID = "mediastore" // Mediastore. + MeteringMarketplaceServiceID = "metering.marketplace" // MeteringMarketplace. + MghServiceID = "mgh" // Mgh. + MobileanalyticsServiceID = "mobileanalytics" // Mobileanalytics. + ModelsLexServiceID = "models.lex" // ModelsLex. + MonitoringServiceID = "monitoring" // Monitoring. + MturkRequesterServiceID = "mturk-requester" // MturkRequester. + NeptuneServiceID = "neptune" // Neptune. + OpsworksServiceID = "opsworks" // Opsworks. + OpsworksCmServiceID = "opsworks-cm" // OpsworksCm. + OrganizationsServiceID = "organizations" // Organizations. + PinpointServiceID = "pinpoint" // Pinpoint. + PollyServiceID = "polly" // Polly. + RdsServiceID = "rds" // Rds. + RedshiftServiceID = "redshift" // Redshift. + RekognitionServiceID = "rekognition" // Rekognition. + ResourceGroupsServiceID = "resource-groups" // ResourceGroups. + Route53ServiceID = "route53" // Route53. + Route53domainsServiceID = "route53domains" // Route53domains. + RuntimeLexServiceID = "runtime.lex" // RuntimeLex. + RuntimeSagemakerServiceID = "runtime.sagemaker" // RuntimeSagemaker. + S3ServiceID = "s3" // S3. + S3ControlServiceID = "s3-control" // S3Control. + SagemakerServiceID = "api.sagemaker" // Sagemaker. + SdbServiceID = "sdb" // Sdb. + SecretsmanagerServiceID = "secretsmanager" // Secretsmanager. + ServerlessrepoServiceID = "serverlessrepo" // Serverlessrepo. + ServicecatalogServiceID = "servicecatalog" // Servicecatalog. + ServicediscoveryServiceID = "servicediscovery" // Servicediscovery. + ShieldServiceID = "shield" // Shield. + SmsServiceID = "sms" // Sms. + SnowballServiceID = "snowball" // Snowball. + SnsServiceID = "sns" // Sns. + SqsServiceID = "sqs" // Sqs. + SsmServiceID = "ssm" // Ssm. + StatesServiceID = "states" // States. + StoragegatewayServiceID = "storagegateway" // Storagegateway. + StreamsDynamodbServiceID = "streams.dynamodb" // StreamsDynamodb. + StsServiceID = "sts" // Sts. + SupportServiceID = "support" // Support. + SwfServiceID = "swf" // Swf. + TaggingServiceID = "tagging" // Tagging. + TransferServiceID = "transfer" // Transfer. + TranslateServiceID = "translate" // Translate. + WafServiceID = "waf" // Waf. + WafRegionalServiceID = "waf-regional" // WafRegional. + WorkdocsServiceID = "workdocs" // Workdocs. + WorkmailServiceID = "workmail" // Workmail. + WorkspacesServiceID = "workspaces" // Workspaces. + XrayServiceID = "xray" // Xray. +) diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/doc.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/doc.go new file mode 100644 index 0000000..84316b9 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/doc.go @@ -0,0 +1,66 @@ +// Package endpoints provides the types and functionality for defining regions +// and endpoints, as well as querying those definitions. +// +// The SDK's Regions and Endpoints metadata is code generated into the endpoints +// package, and is accessible via the DefaultResolver function. This function +// returns a endpoint Resolver will search the metadata and build an associated +// endpoint if one is found. The default resolver will search all partitions +// known by the SDK. e.g AWS Standard (aws), AWS China (aws-cn), and +// AWS GovCloud (US) (aws-us-gov). +// . +// +// Enumerating Regions and Endpoint Metadata +// +// Casting the Resolver returned by DefaultResolver to a EnumPartitions interface +// will allow you to get access to the list of underlying Partitions with the +// Partitions method. This is helpful if you want to limit the SDK's endpoint +// resolving to a single partition, or enumerate regions, services, and endpoints +// in the partition. +// +// resolver := endpoints.DefaultResolver() +// partitions := resolver.(endpoints.EnumPartitions).Partitions() +// +// for _, p := range partitions { +// fmt.Println("Regions for", p.ID()) +// for id, _ := range p.Regions() { +// fmt.Println("*", id) +// } +// +// fmt.Println("Services for", p.ID()) +// for id, _ := range p.Services() { +// fmt.Println("*", id) +// } +// } +// +// Using Custom Endpoints +// +// The endpoints package also gives you the ability to use your own logic how +// endpoints are resolved. This is a great way to define a custom endpoint +// for select services, without passing that logic down through your code. +// +// If a type implements the Resolver interface it can be used to resolve +// endpoints. To use this with the SDK's Session and Config set the value +// of the type to the EndpointsResolver field of aws.Config when initializing +// the session, or service client. +// +// In addition the ResolverFunc is a wrapper for a func matching the signature +// of Resolver.EndpointFor, converting it to a type that satisfies the +// Resolver interface. +// +// +// myCustomResolver := func(service, region string, optFns ...func(*endpoints.Options)) (endpoints.ResolvedEndpoint, error) { +// if service == endpoints.S3ServiceID { +// return endpoints.ResolvedEndpoint{ +// URL: "s3.custom.endpoint.com", +// SigningRegion: "custom-signing-region", +// }, nil +// } +// +// return endpoints.DefaultResolver().EndpointFor(service, region, optFns...) +// } +// +// sess := session.Must(session.NewSession(&aws.Config{ +// Region: aws.String("us-west-2"), +// EndpointResolver: endpoints.ResolverFunc(myCustomResolver), +// })) +package endpoints diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/endpoints.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/endpoints.go new file mode 100644 index 0000000..8809861 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/endpoints.go @@ -0,0 +1,706 @@ +package endpoints + +import ( + "fmt" + "regexp" + "strings" + + "github.com/aws/aws-sdk-go/aws/awserr" +) + +// A Logger is a minimalistic interface for the SDK to log messages to. +type Logger interface { + Log(...interface{}) +} + +// DualStackEndpointState is a constant to describe the dual-stack endpoint resolution +// behavior. +type DualStackEndpointState uint + +const ( + // DualStackEndpointStateUnset is the default value behavior for dual-stack endpoint + // resolution. + DualStackEndpointStateUnset DualStackEndpointState = iota + + // DualStackEndpointStateEnabled enable dual-stack endpoint resolution for endpoints. + DualStackEndpointStateEnabled + + // DualStackEndpointStateDisabled disables dual-stack endpoint resolution for endpoints. + DualStackEndpointStateDisabled +) + +// FIPSEndpointState is a constant to describe the FIPS endpoint resolution behavior. +type FIPSEndpointState uint + +const ( + // FIPSEndpointStateUnset is the default value behavior for FIPS endpoint resolution. + FIPSEndpointStateUnset FIPSEndpointState = iota + + // FIPSEndpointStateEnabled enables FIPS endpoint resolution for service endpoints. + FIPSEndpointStateEnabled + + // FIPSEndpointStateDisabled disables FIPS endpoint resolution for endpoints. + FIPSEndpointStateDisabled +) + +// Options provide the configuration needed to direct how the +// endpoints will be resolved. +type Options struct { + // DisableSSL forces the endpoint to be resolved as HTTP. + // instead of HTTPS if the service supports it. + DisableSSL bool + + // Sets the resolver to resolve the endpoint as a dualstack endpoint + // for the service. If dualstack support for a service is not known and + // StrictMatching is not enabled a dualstack endpoint for the service will + // be returned. This endpoint may not be valid. If StrictMatching is + // enabled only services that are known to support dualstack will return + // dualstack endpoints. + // + // Deprecated: This option will continue to function for S3 and S3 Control for backwards compatibility. + // UseDualStackEndpoint should be used to enable usage of a service's dual-stack endpoint for all service clients + // moving forward. For S3 and S3 Control, when UseDualStackEndpoint is set to a non-zero value it takes higher + // precedence then this option. + UseDualStack bool + + // Sets the resolver to resolve a dual-stack endpoint for the service. + UseDualStackEndpoint DualStackEndpointState + + // UseFIPSEndpoint specifies the resolver must resolve a FIPS endpoint. + UseFIPSEndpoint FIPSEndpointState + + // Enables strict matching of services and regions resolved endpoints. + // If the partition doesn't enumerate the exact service and region an + // error will be returned. This option will prevent returning endpoints + // that look valid, but may not resolve to any real endpoint. + StrictMatching bool + + // Enables resolving a service endpoint based on the region provided if the + // service does not exist. The service endpoint ID will be used as the service + // domain name prefix. By default the endpoint resolver requires the service + // to be known when resolving endpoints. + // + // If resolving an endpoint on the partition list the provided region will + // be used to determine which partition's domain name pattern to the service + // endpoint ID with. If both the service and region are unknown and resolving + // the endpoint on partition list an UnknownEndpointError error will be returned. + // + // If resolving and endpoint on a partition specific resolver that partition's + // domain name pattern will be used with the service endpoint ID. If both + // region and service do not exist when resolving an endpoint on a specific + // partition the partition's domain pattern will be used to combine the + // endpoint and region together. + // + // This option is ignored if StrictMatching is enabled. + ResolveUnknownService bool + + // Specifies the EC2 Instance Metadata Service default endpoint selection mode (IPv4 or IPv6) + EC2MetadataEndpointMode EC2IMDSEndpointModeState + + // STS Regional Endpoint flag helps with resolving the STS endpoint + STSRegionalEndpoint STSRegionalEndpoint + + // S3 Regional Endpoint flag helps with resolving the S3 endpoint + S3UsEast1RegionalEndpoint S3UsEast1RegionalEndpoint + + // ResolvedRegion is the resolved region string. If provided (non-zero length) it takes priority + // over the region name passed to the ResolveEndpoint call. + ResolvedRegion string + + // Logger is the logger that will be used to log messages. + Logger Logger + + // Determines whether logging of deprecated endpoints usage is enabled. + LogDeprecated bool +} + +func (o Options) getEndpointVariant(service string) (v endpointVariant) { + const s3 = "s3" + const s3Control = "s3-control" + + if (o.UseDualStackEndpoint == DualStackEndpointStateEnabled) || + ((service == s3 || service == s3Control) && (o.UseDualStackEndpoint == DualStackEndpointStateUnset && o.UseDualStack)) { + v |= dualStackVariant + } + if o.UseFIPSEndpoint == FIPSEndpointStateEnabled { + v |= fipsVariant + } + return v +} + +// EC2IMDSEndpointModeState is an enum configuration variable describing the client endpoint mode. +type EC2IMDSEndpointModeState uint + +// Enumeration values for EC2IMDSEndpointModeState +const ( + EC2IMDSEndpointModeStateUnset EC2IMDSEndpointModeState = iota + EC2IMDSEndpointModeStateIPv4 + EC2IMDSEndpointModeStateIPv6 +) + +// SetFromString sets the EC2IMDSEndpointModeState based on the provided string value. Unknown values will default to EC2IMDSEndpointModeStateUnset +func (e *EC2IMDSEndpointModeState) SetFromString(v string) error { + v = strings.TrimSpace(v) + + switch { + case len(v) == 0: + *e = EC2IMDSEndpointModeStateUnset + case strings.EqualFold(v, "IPv6"): + *e = EC2IMDSEndpointModeStateIPv6 + case strings.EqualFold(v, "IPv4"): + *e = EC2IMDSEndpointModeStateIPv4 + default: + return fmt.Errorf("unknown EC2 IMDS endpoint mode, must be either IPv6 or IPv4") + } + return nil +} + +// STSRegionalEndpoint is an enum for the states of the STS Regional Endpoint +// options. +type STSRegionalEndpoint int + +func (e STSRegionalEndpoint) String() string { + switch e { + case LegacySTSEndpoint: + return "legacy" + case RegionalSTSEndpoint: + return "regional" + case UnsetSTSEndpoint: + return "" + default: + return "unknown" + } +} + +const ( + + // UnsetSTSEndpoint represents that STS Regional Endpoint flag is not specified. + UnsetSTSEndpoint STSRegionalEndpoint = iota + + // LegacySTSEndpoint represents when STS Regional Endpoint flag is specified + // to use legacy endpoints. + LegacySTSEndpoint + + // RegionalSTSEndpoint represents when STS Regional Endpoint flag is specified + // to use regional endpoints. + RegionalSTSEndpoint +) + +// GetSTSRegionalEndpoint function returns the STSRegionalEndpointFlag based +// on the input string provided in env config or shared config by the user. +// +// `legacy`, `regional` are the only case-insensitive valid strings for +// resolving the STS regional Endpoint flag. +func GetSTSRegionalEndpoint(s string) (STSRegionalEndpoint, error) { + switch { + case strings.EqualFold(s, "legacy"): + return LegacySTSEndpoint, nil + case strings.EqualFold(s, "regional"): + return RegionalSTSEndpoint, nil + default: + return UnsetSTSEndpoint, fmt.Errorf("unable to resolve the value of STSRegionalEndpoint for %v", s) + } +} + +// S3UsEast1RegionalEndpoint is an enum for the states of the S3 us-east-1 +// Regional Endpoint options. +type S3UsEast1RegionalEndpoint int + +func (e S3UsEast1RegionalEndpoint) String() string { + switch e { + case LegacyS3UsEast1Endpoint: + return "legacy" + case RegionalS3UsEast1Endpoint: + return "regional" + case UnsetS3UsEast1Endpoint: + return "" + default: + return "unknown" + } +} + +const ( + + // UnsetS3UsEast1Endpoint represents that S3 Regional Endpoint flag is not + // specified. + UnsetS3UsEast1Endpoint S3UsEast1RegionalEndpoint = iota + + // LegacyS3UsEast1Endpoint represents when S3 Regional Endpoint flag is + // specified to use legacy endpoints. + LegacyS3UsEast1Endpoint + + // RegionalS3UsEast1Endpoint represents when S3 Regional Endpoint flag is + // specified to use regional endpoints. + RegionalS3UsEast1Endpoint +) + +// GetS3UsEast1RegionalEndpoint function returns the S3UsEast1RegionalEndpointFlag based +// on the input string provided in env config or shared config by the user. +// +// `legacy`, `regional` are the only case-insensitive valid strings for +// resolving the S3 regional Endpoint flag. +func GetS3UsEast1RegionalEndpoint(s string) (S3UsEast1RegionalEndpoint, error) { + switch { + case strings.EqualFold(s, "legacy"): + return LegacyS3UsEast1Endpoint, nil + case strings.EqualFold(s, "regional"): + return RegionalS3UsEast1Endpoint, nil + default: + return UnsetS3UsEast1Endpoint, + fmt.Errorf("unable to resolve the value of S3UsEast1RegionalEndpoint for %v", s) + } +} + +// Set combines all of the option functions together. +func (o *Options) Set(optFns ...func(*Options)) { + for _, fn := range optFns { + fn(o) + } +} + +// DisableSSLOption sets the DisableSSL options. Can be used as a functional +// option when resolving endpoints. +func DisableSSLOption(o *Options) { + o.DisableSSL = true +} + +// UseDualStackOption sets the UseDualStack option. Can be used as a functional +// option when resolving endpoints. +// +// Deprecated: UseDualStackEndpointOption should be used to enable usage of a service's dual-stack endpoint. +// When DualStackEndpointState is set to a non-zero value it takes higher precedence then this option. +func UseDualStackOption(o *Options) { + o.UseDualStack = true +} + +// UseDualStackEndpointOption sets the UseDualStackEndpoint option to enabled. Can be used as a functional +// option when resolving endpoints. +func UseDualStackEndpointOption(o *Options) { + o.UseDualStackEndpoint = DualStackEndpointStateEnabled +} + +// UseFIPSEndpointOption sets the UseFIPSEndpoint option to enabled. Can be used as a functional +// option when resolving endpoints. +func UseFIPSEndpointOption(o *Options) { + o.UseFIPSEndpoint = FIPSEndpointStateEnabled +} + +// StrictMatchingOption sets the StrictMatching option. Can be used as a functional +// option when resolving endpoints. +func StrictMatchingOption(o *Options) { + o.StrictMatching = true +} + +// ResolveUnknownServiceOption sets the ResolveUnknownService option. Can be used +// as a functional option when resolving endpoints. +func ResolveUnknownServiceOption(o *Options) { + o.ResolveUnknownService = true +} + +// STSRegionalEndpointOption enables the STS endpoint resolver behavior to resolve +// STS endpoint to their regional endpoint, instead of the global endpoint. +func STSRegionalEndpointOption(o *Options) { + o.STSRegionalEndpoint = RegionalSTSEndpoint +} + +// A Resolver provides the interface for functionality to resolve endpoints. +// The build in Partition and DefaultResolver return value satisfy this interface. +type Resolver interface { + EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) +} + +// ResolverFunc is a helper utility that wraps a function so it satisfies the +// Resolver interface. This is useful when you want to add additional endpoint +// resolving logic, or stub out specific endpoints with custom values. +type ResolverFunc func(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) + +// EndpointFor wraps the ResolverFunc function to satisfy the Resolver interface. +func (fn ResolverFunc) EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) { + return fn(service, region, opts...) +} + +var schemeRE = regexp.MustCompile("^([^:]+)://") + +// AddScheme adds the HTTP or HTTPS schemes to a endpoint URL if there is no +// scheme. If disableSSL is true HTTP will set HTTP instead of the default HTTPS. +// +// If disableSSL is set, it will only set the URL's scheme if the URL does not +// contain a scheme. +func AddScheme(endpoint string, disableSSL bool) string { + if !schemeRE.MatchString(endpoint) { + scheme := "https" + if disableSSL { + scheme = "http" + } + endpoint = fmt.Sprintf("%s://%s", scheme, endpoint) + } + + return endpoint +} + +// EnumPartitions a provides a way to retrieve the underlying partitions that +// make up the SDK's default Resolver, or any resolver decoded from a model +// file. +// +// Use this interface with DefaultResolver and DecodeModels to get the list of +// Partitions. +type EnumPartitions interface { + Partitions() []Partition +} + +// RegionsForService returns a map of regions for the partition and service. +// If either the partition or service does not exist false will be returned +// as the second parameter. +// +// This example shows how to get the regions for DynamoDB in the AWS partition. +// rs, exists := endpoints.RegionsForService(endpoints.DefaultPartitions(), endpoints.AwsPartitionID, endpoints.DynamodbServiceID) +// +// This is equivalent to using the partition directly. +// rs := endpoints.AwsPartition().Services()[endpoints.DynamodbServiceID].Regions() +func RegionsForService(ps []Partition, partitionID, serviceID string) (map[string]Region, bool) { + for _, p := range ps { + if p.ID() != partitionID { + continue + } + if _, ok := p.p.Services[serviceID]; !(ok || serviceID == Ec2metadataServiceID) { + break + } + + s := Service{ + id: serviceID, + p: p.p, + } + return s.Regions(), true + } + + return map[string]Region{}, false +} + +// PartitionForRegion returns the first partition which includes the region +// passed in. This includes both known regions and regions which match +// a pattern supported by the partition which may include regions that are +// not explicitly known by the partition. Use the Regions method of the +// returned Partition if explicit support is needed. +func PartitionForRegion(ps []Partition, regionID string) (Partition, bool) { + for _, p := range ps { + if _, ok := p.p.Regions[regionID]; ok || p.p.RegionRegex.MatchString(regionID) { + return p, true + } + } + + return Partition{}, false +} + +// A Partition provides the ability to enumerate the partition's regions +// and services. +type Partition struct { + id, dnsSuffix string + p *partition +} + +// DNSSuffix returns the base domain name of the partition. +func (p Partition) DNSSuffix() string { return p.dnsSuffix } + +// ID returns the identifier of the partition. +func (p Partition) ID() string { return p.id } + +// EndpointFor attempts to resolve the endpoint based on service and region. +// See Options for information on configuring how the endpoint is resolved. +// +// If the service cannot be found in the metadata the UnknownServiceError +// error will be returned. This validation will occur regardless if +// StrictMatching is enabled. To enable resolving unknown services set the +// "ResolveUnknownService" option to true. When StrictMatching is disabled +// this option allows the partition resolver to resolve a endpoint based on +// the service endpoint ID provided. +// +// When resolving endpoints you can choose to enable StrictMatching. This will +// require the provided service and region to be known by the partition. +// If the endpoint cannot be strictly resolved an error will be returned. This +// mode is useful to ensure the endpoint resolved is valid. Without +// StrictMatching enabled the endpoint returned may look valid but may not work. +// StrictMatching requires the SDK to be updated if you want to take advantage +// of new regions and services expansions. +// +// Errors that can be returned. +// * UnknownServiceError +// * UnknownEndpointError +func (p Partition) EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) { + return p.p.EndpointFor(service, region, opts...) +} + +// Regions returns a map of Regions indexed by their ID. This is useful for +// enumerating over the regions in a partition. +func (p Partition) Regions() map[string]Region { + rs := make(map[string]Region, len(p.p.Regions)) + for id, r := range p.p.Regions { + rs[id] = Region{ + id: id, + desc: r.Description, + p: p.p, + } + } + + return rs +} + +// Services returns a map of Service indexed by their ID. This is useful for +// enumerating over the services in a partition. +func (p Partition) Services() map[string]Service { + ss := make(map[string]Service, len(p.p.Services)) + + for id := range p.p.Services { + ss[id] = Service{ + id: id, + p: p.p, + } + } + + // Since we have removed the customization that injected this into the model + // we still need to pretend that this is a modeled service. + if _, ok := ss[Ec2metadataServiceID]; !ok { + ss[Ec2metadataServiceID] = Service{ + id: Ec2metadataServiceID, + p: p.p, + } + } + + return ss +} + +// A Region provides information about a region, and ability to resolve an +// endpoint from the context of a region, given a service. +type Region struct { + id, desc string + p *partition +} + +// ID returns the region's identifier. +func (r Region) ID() string { return r.id } + +// Description returns the region's description. The region description +// is free text, it can be empty, and it may change between SDK releases. +func (r Region) Description() string { return r.desc } + +// ResolveEndpoint resolves an endpoint from the context of the region given +// a service. See Partition.EndpointFor for usage and errors that can be returned. +func (r Region) ResolveEndpoint(service string, opts ...func(*Options)) (ResolvedEndpoint, error) { + return r.p.EndpointFor(service, r.id, opts...) +} + +// Services returns a list of all services that are known to be in this region. +func (r Region) Services() map[string]Service { + ss := map[string]Service{} + for id, s := range r.p.Services { + if _, ok := s.Endpoints[endpointKey{Region: r.id}]; ok { + ss[id] = Service{ + id: id, + p: r.p, + } + } + } + + return ss +} + +// A Service provides information about a service, and ability to resolve an +// endpoint from the context of a service, given a region. +type Service struct { + id string + p *partition +} + +// ID returns the identifier for the service. +func (s Service) ID() string { return s.id } + +// ResolveEndpoint resolves an endpoint from the context of a service given +// a region. See Partition.EndpointFor for usage and errors that can be returned. +func (s Service) ResolveEndpoint(region string, opts ...func(*Options)) (ResolvedEndpoint, error) { + return s.p.EndpointFor(s.id, region, opts...) +} + +// Regions returns a map of Regions that the service is present in. +// +// A region is the AWS region the service exists in. Whereas a Endpoint is +// an URL that can be resolved to a instance of a service. +func (s Service) Regions() map[string]Region { + rs := map[string]Region{} + + service, ok := s.p.Services[s.id] + + // Since ec2metadata customization has been removed we need to check + // if it was defined in non-standard endpoints.json file. If it's not + // then we can return the empty map as there is no regional-endpoints for IMDS. + // Otherwise, we iterate need to iterate the non-standard model. + if s.id == Ec2metadataServiceID && !ok { + return rs + } + + for id := range service.Endpoints { + if id.Variant != 0 { + continue + } + if r, ok := s.p.Regions[id.Region]; ok { + rs[id.Region] = Region{ + id: id.Region, + desc: r.Description, + p: s.p, + } + } + } + + return rs +} + +// Endpoints returns a map of Endpoints indexed by their ID for all known +// endpoints for a service. +// +// A region is the AWS region the service exists in. Whereas a Endpoint is +// an URL that can be resolved to a instance of a service. +func (s Service) Endpoints() map[string]Endpoint { + es := make(map[string]Endpoint, len(s.p.Services[s.id].Endpoints)) + for id := range s.p.Services[s.id].Endpoints { + if id.Variant != 0 { + continue + } + es[id.Region] = Endpoint{ + id: id.Region, + serviceID: s.id, + p: s.p, + } + } + + return es +} + +// A Endpoint provides information about endpoints, and provides the ability +// to resolve that endpoint for the service, and the region the endpoint +// represents. +type Endpoint struct { + id string + serviceID string + p *partition +} + +// ID returns the identifier for an endpoint. +func (e Endpoint) ID() string { return e.id } + +// ServiceID returns the identifier the endpoint belongs to. +func (e Endpoint) ServiceID() string { return e.serviceID } + +// ResolveEndpoint resolves an endpoint from the context of a service and +// region the endpoint represents. See Partition.EndpointFor for usage and +// errors that can be returned. +func (e Endpoint) ResolveEndpoint(opts ...func(*Options)) (ResolvedEndpoint, error) { + return e.p.EndpointFor(e.serviceID, e.id, opts...) +} + +// A ResolvedEndpoint is an endpoint that has been resolved based on a partition +// service, and region. +type ResolvedEndpoint struct { + // The endpoint URL + URL string + + // The endpoint partition + PartitionID string + + // The region that should be used for signing requests. + SigningRegion string + + // The service name that should be used for signing requests. + SigningName string + + // States that the signing name for this endpoint was derived from metadata + // passed in, but was not explicitly modeled. + SigningNameDerived bool + + // The signing method that should be used for signing requests. + SigningMethod string +} + +// So that the Error interface type can be included as an anonymous field +// in the requestError struct and not conflict with the error.Error() method. +type awsError awserr.Error + +// A EndpointNotFoundError is returned when in StrictMatching mode, and the +// endpoint for the service and region cannot be found in any of the partitions. +type EndpointNotFoundError struct { + awsError + Partition string + Service string + Region string +} + +// A UnknownServiceError is returned when the service does not resolve to an +// endpoint. Includes a list of all known services for the partition. Returned +// when a partition does not support the service. +type UnknownServiceError struct { + awsError + Partition string + Service string + Known []string +} + +// NewUnknownServiceError builds and returns UnknownServiceError. +func NewUnknownServiceError(p, s string, known []string) UnknownServiceError { + return UnknownServiceError{ + awsError: awserr.New("UnknownServiceError", + "could not resolve endpoint for unknown service", nil), + Partition: p, + Service: s, + Known: known, + } +} + +// String returns the string representation of the error. +func (e UnknownServiceError) Error() string { + extra := fmt.Sprintf("partition: %q, service: %q", + e.Partition, e.Service) + if len(e.Known) > 0 { + extra += fmt.Sprintf(", known: %v", e.Known) + } + return awserr.SprintError(e.Code(), e.Message(), extra, e.OrigErr()) +} + +// String returns the string representation of the error. +func (e UnknownServiceError) String() string { + return e.Error() +} + +// A UnknownEndpointError is returned when in StrictMatching mode and the +// service is valid, but the region does not resolve to an endpoint. Includes +// a list of all known endpoints for the service. +type UnknownEndpointError struct { + awsError + Partition string + Service string + Region string + Known []string +} + +// NewUnknownEndpointError builds and returns UnknownEndpointError. +func NewUnknownEndpointError(p, s, r string, known []string) UnknownEndpointError { + return UnknownEndpointError{ + awsError: awserr.New("UnknownEndpointError", + "could not resolve endpoint", nil), + Partition: p, + Service: s, + Region: r, + Known: known, + } +} + +// String returns the string representation of the error. +func (e UnknownEndpointError) Error() string { + extra := fmt.Sprintf("partition: %q, service: %q, region: %q", + e.Partition, e.Service, e.Region) + if len(e.Known) > 0 { + extra += fmt.Sprintf(", known: %v", e.Known) + } + return awserr.SprintError(e.Code(), e.Message(), extra, e.OrigErr()) +} + +// String returns the string representation of the error. +func (e UnknownEndpointError) String() string { + return e.Error() +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/legacy_regions.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/legacy_regions.go new file mode 100644 index 0000000..df75e89 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/legacy_regions.go @@ -0,0 +1,24 @@ +package endpoints + +var legacyGlobalRegions = map[string]map[string]struct{}{ + "sts": { + "ap-northeast-1": {}, + "ap-south-1": {}, + "ap-southeast-1": {}, + "ap-southeast-2": {}, + "ca-central-1": {}, + "eu-central-1": {}, + "eu-north-1": {}, + "eu-west-1": {}, + "eu-west-2": {}, + "eu-west-3": {}, + "sa-east-1": {}, + "us-east-1": {}, + "us-east-2": {}, + "us-west-1": {}, + "us-west-2": {}, + }, + "s3": { + "us-east-1": {}, + }, +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model.go new file mode 100644 index 0000000..89f6627 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model.go @@ -0,0 +1,594 @@ +package endpoints + +import ( + "encoding/json" + "fmt" + "regexp" + "strconv" + "strings" +) + +const ( + ec2MetadataEndpointIPv6 = "http://[fd00:ec2::254]/latest" + ec2MetadataEndpointIPv4 = "http://169.254.169.254/latest" +) + +const dnsSuffixTemplateKey = "{dnsSuffix}" + +// defaultKey is a compound map key of a variant and other values. +type defaultKey struct { + Variant endpointVariant + ServiceVariant serviceVariant +} + +// endpointKey is a compound map key of a region and associated variant value. +type endpointKey struct { + Region string + Variant endpointVariant +} + +// endpointVariant is a bit field to describe the endpoints attributes. +type endpointVariant uint64 + +// serviceVariant is a bit field to describe the service endpoint attributes. +type serviceVariant uint64 + +const ( + // fipsVariant indicates that the endpoint is FIPS capable. + fipsVariant endpointVariant = 1 << (64 - 1 - iota) + + // dualStackVariant indicates that the endpoint is DualStack capable. + dualStackVariant +) + +var regionValidationRegex = regexp.MustCompile(`^[[:alnum:]]([[:alnum:]\-]*[[:alnum:]])?$`) + +type partitions []partition + +func (ps partitions) EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) { + var opt Options + opt.Set(opts...) + + if len(opt.ResolvedRegion) > 0 { + region = opt.ResolvedRegion + } + + for i := 0; i < len(ps); i++ { + if !ps[i].canResolveEndpoint(service, region, opt) { + continue + } + + return ps[i].EndpointFor(service, region, opts...) + } + + // If loose matching fallback to first partition format to use + // when resolving the endpoint. + if !opt.StrictMatching && len(ps) > 0 { + return ps[0].EndpointFor(service, region, opts...) + } + + return ResolvedEndpoint{}, NewUnknownEndpointError("all partitions", service, region, []string{}) +} + +// Partitions satisfies the EnumPartitions interface and returns a list +// of Partitions representing each partition represented in the SDK's +// endpoints model. +func (ps partitions) Partitions() []Partition { + parts := make([]Partition, 0, len(ps)) + for i := 0; i < len(ps); i++ { + parts = append(parts, ps[i].Partition()) + } + + return parts +} + +type endpointWithVariants struct { + endpoint + Variants []endpointWithTags `json:"variants"` +} + +type endpointWithTags struct { + endpoint + Tags []string `json:"tags"` +} + +type endpointDefaults map[defaultKey]endpoint + +func (p *endpointDefaults) UnmarshalJSON(data []byte) error { + if *p == nil { + *p = make(endpointDefaults) + } + + var e endpointWithVariants + if err := json.Unmarshal(data, &e); err != nil { + return err + } + + (*p)[defaultKey{Variant: 0}] = e.endpoint + + e.Hostname = "" + e.DNSSuffix = "" + + for _, variant := range e.Variants { + endpointVariant, unknown := parseVariantTags(variant.Tags) + if unknown { + continue + } + + var ve endpoint + ve.mergeIn(e.endpoint) + ve.mergeIn(variant.endpoint) + + (*p)[defaultKey{Variant: endpointVariant}] = ve + } + + return nil +} + +func parseVariantTags(tags []string) (ev endpointVariant, unknown bool) { + if len(tags) == 0 { + unknown = true + return + } + + for _, tag := range tags { + switch { + case strings.EqualFold("fips", tag): + ev |= fipsVariant + case strings.EqualFold("dualstack", tag): + ev |= dualStackVariant + default: + unknown = true + } + } + return ev, unknown +} + +type partition struct { + ID string `json:"partition"` + Name string `json:"partitionName"` + DNSSuffix string `json:"dnsSuffix"` + RegionRegex regionRegex `json:"regionRegex"` + Defaults endpointDefaults `json:"defaults"` + Regions regions `json:"regions"` + Services services `json:"services"` +} + +func (p partition) Partition() Partition { + return Partition{ + dnsSuffix: p.DNSSuffix, + id: p.ID, + p: &p, + } +} + +func (p partition) canResolveEndpoint(service, region string, options Options) bool { + s, hasService := p.Services[service] + _, hasEndpoint := s.Endpoints[endpointKey{ + Region: region, + Variant: options.getEndpointVariant(service), + }] + + if hasEndpoint && hasService { + return true + } + + if options.StrictMatching { + return false + } + + return p.RegionRegex.MatchString(region) +} + +func allowLegacyEmptyRegion(service string) bool { + legacy := map[string]struct{}{ + "budgets": {}, + "ce": {}, + "chime": {}, + "cloudfront": {}, + "ec2metadata": {}, + "iam": {}, + "importexport": {}, + "organizations": {}, + "route53": {}, + "sts": {}, + "support": {}, + "waf": {}, + } + + _, allowed := legacy[service] + return allowed +} + +func (p partition) EndpointFor(service, region string, opts ...func(*Options)) (resolved ResolvedEndpoint, err error) { + var opt Options + opt.Set(opts...) + + if len(opt.ResolvedRegion) > 0 { + region = opt.ResolvedRegion + } + + s, hasService := p.Services[service] + + if service == Ec2metadataServiceID && !hasService { + endpoint := getEC2MetadataEndpoint(p.ID, service, opt.EC2MetadataEndpointMode) + return endpoint, nil + } + + if len(service) == 0 || !(hasService || opt.ResolveUnknownService) { + // Only return error if the resolver will not fallback to creating + // endpoint based on service endpoint ID passed in. + return resolved, NewUnknownServiceError(p.ID, service, serviceList(p.Services)) + } + + if len(region) == 0 && allowLegacyEmptyRegion(service) && len(s.PartitionEndpoint) != 0 { + region = s.PartitionEndpoint + } + + if r, ok := isLegacyGlobalRegion(service, region, opt); ok { + region = r + } + + variant := opt.getEndpointVariant(service) + + endpoints := s.Endpoints + + serviceDefaults, hasServiceDefault := s.Defaults[defaultKey{Variant: variant}] + // If we searched for a variant which may have no explicit service defaults, + // then we need to inherit the standard service defaults except the hostname and dnsSuffix + if variant != 0 && !hasServiceDefault { + serviceDefaults = s.Defaults[defaultKey{}] + serviceDefaults.Hostname = "" + serviceDefaults.DNSSuffix = "" + } + + partitionDefaults, hasPartitionDefault := p.Defaults[defaultKey{Variant: variant}] + + var dnsSuffix string + if len(serviceDefaults.DNSSuffix) > 0 { + dnsSuffix = serviceDefaults.DNSSuffix + } else if variant == 0 { + // For legacy reasons the partition dnsSuffix is not in the defaults, so if we looked for + // a non-variant endpoint then we need to set the dnsSuffix. + dnsSuffix = p.DNSSuffix + } + + noDefaults := !hasServiceDefault && !hasPartitionDefault + + e, hasEndpoint := s.endpointForRegion(region, endpoints, variant) + if len(region) == 0 || (!hasEndpoint && (opt.StrictMatching || noDefaults)) { + return resolved, NewUnknownEndpointError(p.ID, service, region, endpointList(endpoints, variant)) + } + + defs := []endpoint{partitionDefaults, serviceDefaults} + + return e.resolve(service, p.ID, region, dnsSuffixTemplateKey, dnsSuffix, defs, opt) +} + +func getEC2MetadataEndpoint(partitionID, service string, mode EC2IMDSEndpointModeState) ResolvedEndpoint { + switch mode { + case EC2IMDSEndpointModeStateIPv6: + return ResolvedEndpoint{ + URL: ec2MetadataEndpointIPv6, + PartitionID: partitionID, + SigningRegion: "aws-global", + SigningName: service, + SigningNameDerived: true, + SigningMethod: "v4", + } + case EC2IMDSEndpointModeStateIPv4: + fallthrough + default: + return ResolvedEndpoint{ + URL: ec2MetadataEndpointIPv4, + PartitionID: partitionID, + SigningRegion: "aws-global", + SigningName: service, + SigningNameDerived: true, + SigningMethod: "v4", + } + } +} + +func isLegacyGlobalRegion(service string, region string, opt Options) (string, bool) { + if opt.getEndpointVariant(service) != 0 { + return "", false + } + + const ( + sts = "sts" + s3 = "s3" + awsGlobal = "aws-global" + ) + + switch { + case service == sts && opt.STSRegionalEndpoint == RegionalSTSEndpoint: + return region, false + case service == s3 && opt.S3UsEast1RegionalEndpoint == RegionalS3UsEast1Endpoint: + return region, false + default: + if _, ok := legacyGlobalRegions[service][region]; ok { + return awsGlobal, true + } + } + + return region, false +} + +func serviceList(ss services) []string { + list := make([]string, 0, len(ss)) + for k := range ss { + list = append(list, k) + } + return list +} +func endpointList(es serviceEndpoints, variant endpointVariant) []string { + list := make([]string, 0, len(es)) + for k := range es { + if k.Variant != variant { + continue + } + list = append(list, k.Region) + } + return list +} + +type regionRegex struct { + *regexp.Regexp +} + +func (rr *regionRegex) UnmarshalJSON(b []byte) (err error) { + // Strip leading and trailing quotes + regex, err := strconv.Unquote(string(b)) + if err != nil { + return fmt.Errorf("unable to strip quotes from regex, %v", err) + } + + rr.Regexp, err = regexp.Compile(regex) + if err != nil { + return fmt.Errorf("unable to unmarshal region regex, %v", err) + } + return nil +} + +type regions map[string]region + +type region struct { + Description string `json:"description"` +} + +type services map[string]service + +type service struct { + PartitionEndpoint string `json:"partitionEndpoint"` + IsRegionalized boxedBool `json:"isRegionalized,omitempty"` + Defaults endpointDefaults `json:"defaults"` + Endpoints serviceEndpoints `json:"endpoints"` +} + +func (s *service) endpointForRegion(region string, endpoints serviceEndpoints, variant endpointVariant) (endpoint, bool) { + if e, ok := endpoints[endpointKey{Region: region, Variant: variant}]; ok { + return e, true + } + + if s.IsRegionalized == boxedFalse { + return endpoints[endpointKey{Region: s.PartitionEndpoint, Variant: variant}], region == s.PartitionEndpoint + } + + // Unable to find any matching endpoint, return + // blank that will be used for generic endpoint creation. + return endpoint{}, false +} + +type serviceEndpoints map[endpointKey]endpoint + +func (s *serviceEndpoints) UnmarshalJSON(data []byte) error { + if *s == nil { + *s = make(serviceEndpoints) + } + + var regionToEndpoint map[string]endpointWithVariants + + if err := json.Unmarshal(data, ®ionToEndpoint); err != nil { + return err + } + + for region, e := range regionToEndpoint { + (*s)[endpointKey{Region: region}] = e.endpoint + + e.Hostname = "" + e.DNSSuffix = "" + + for _, variant := range e.Variants { + endpointVariant, unknown := parseVariantTags(variant.Tags) + if unknown { + continue + } + + var ve endpoint + ve.mergeIn(e.endpoint) + ve.mergeIn(variant.endpoint) + + (*s)[endpointKey{Region: region, Variant: endpointVariant}] = ve + } + } + + return nil +} + +type endpoint struct { + Hostname string `json:"hostname"` + Protocols []string `json:"protocols"` + CredentialScope credentialScope `json:"credentialScope"` + + DNSSuffix string `json:"dnsSuffix"` + + // Signature Version not used + SignatureVersions []string `json:"signatureVersions"` + + // SSLCommonName not used. + SSLCommonName string `json:"sslCommonName"` + + Deprecated boxedBool `json:"deprecated"` +} + +// isZero returns whether the endpoint structure is an empty (zero) value. +func (e endpoint) isZero() bool { + switch { + case len(e.Hostname) != 0: + return false + case len(e.Protocols) != 0: + return false + case e.CredentialScope != (credentialScope{}): + return false + case len(e.SignatureVersions) != 0: + return false + case len(e.SSLCommonName) != 0: + return false + } + return true +} + +const ( + defaultProtocol = "https" + defaultSigner = "v4" +) + +var ( + protocolPriority = []string{"https", "http"} + signerPriority = []string{"v4", "v2"} +) + +func getByPriority(s []string, p []string, def string) string { + if len(s) == 0 { + return def + } + + for i := 0; i < len(p); i++ { + for j := 0; j < len(s); j++ { + if s[j] == p[i] { + return s[j] + } + } + } + + return s[0] +} + +func (e endpoint) resolve(service, partitionID, region, dnsSuffixTemplateVariable, dnsSuffix string, defs []endpoint, opts Options) (ResolvedEndpoint, error) { + var merged endpoint + for _, def := range defs { + merged.mergeIn(def) + } + merged.mergeIn(e) + e = merged + + signingRegion := e.CredentialScope.Region + if len(signingRegion) == 0 { + signingRegion = region + } + + signingName := e.CredentialScope.Service + var signingNameDerived bool + if len(signingName) == 0 { + signingName = service + signingNameDerived = true + } + + hostname := e.Hostname + + if !validateInputRegion(region) { + return ResolvedEndpoint{}, fmt.Errorf("invalid region identifier format provided") + } + + if len(merged.DNSSuffix) > 0 { + dnsSuffix = merged.DNSSuffix + } + + u := strings.Replace(hostname, "{service}", service, 1) + u = strings.Replace(u, "{region}", region, 1) + u = strings.Replace(u, dnsSuffixTemplateVariable, dnsSuffix, 1) + + scheme := getEndpointScheme(e.Protocols, opts.DisableSSL) + u = fmt.Sprintf("%s://%s", scheme, u) + + if e.Deprecated == boxedTrue && opts.LogDeprecated && opts.Logger != nil { + opts.Logger.Log(fmt.Sprintf("endpoint identifier %q, url %q marked as deprecated", region, u)) + } + + return ResolvedEndpoint{ + URL: u, + PartitionID: partitionID, + SigningRegion: signingRegion, + SigningName: signingName, + SigningNameDerived: signingNameDerived, + SigningMethod: getByPriority(e.SignatureVersions, signerPriority, defaultSigner), + }, nil +} + +func getEndpointScheme(protocols []string, disableSSL bool) string { + if disableSSL { + return "http" + } + + return getByPriority(protocols, protocolPriority, defaultProtocol) +} + +func (e *endpoint) mergeIn(other endpoint) { + if len(other.Hostname) > 0 { + e.Hostname = other.Hostname + } + if len(other.Protocols) > 0 { + e.Protocols = other.Protocols + } + if len(other.SignatureVersions) > 0 { + e.SignatureVersions = other.SignatureVersions + } + if len(other.CredentialScope.Region) > 0 { + e.CredentialScope.Region = other.CredentialScope.Region + } + if len(other.CredentialScope.Service) > 0 { + e.CredentialScope.Service = other.CredentialScope.Service + } + if len(other.SSLCommonName) > 0 { + e.SSLCommonName = other.SSLCommonName + } + if len(other.DNSSuffix) > 0 { + e.DNSSuffix = other.DNSSuffix + } + if other.Deprecated != boxedBoolUnset { + e.Deprecated = other.Deprecated + } +} + +type credentialScope struct { + Region string `json:"region"` + Service string `json:"service"` +} + +type boxedBool int + +func (b *boxedBool) UnmarshalJSON(buf []byte) error { + v, err := strconv.ParseBool(string(buf)) + if err != nil { + return err + } + + if v { + *b = boxedTrue + } else { + *b = boxedFalse + } + + return nil +} + +const ( + boxedBoolUnset boxedBool = iota + boxedFalse + boxedTrue +) + +func validateInputRegion(region string) bool { + return regionValidationRegex.MatchString(region) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model_codegen.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model_codegen.go new file mode 100644 index 0000000..84922bc --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model_codegen.go @@ -0,0 +1,412 @@ +//go:build codegen +// +build codegen + +package endpoints + +import ( + "fmt" + "io" + "reflect" + "strings" + "text/template" + "unicode" +) + +// A CodeGenOptions are the options for code generating the endpoints into +// Go code from the endpoints model definition. +type CodeGenOptions struct { + // Options for how the model will be decoded. + DecodeModelOptions DecodeModelOptions + + // Disables code generation of the service endpoint prefix IDs defined in + // the model. + DisableGenerateServiceIDs bool +} + +// Set combines all of the option functions together +func (d *CodeGenOptions) Set(optFns ...func(*CodeGenOptions)) { + for _, fn := range optFns { + fn(d) + } +} + +// CodeGenModel given a endpoints model file will decode it and attempt to +// generate Go code from the model definition. Error will be returned if +// the code is unable to be generated, or decoded. +func CodeGenModel(modelFile io.Reader, outFile io.Writer, optFns ...func(*CodeGenOptions)) error { + var opts CodeGenOptions + opts.Set(optFns...) + + resolver, err := DecodeModel(modelFile, func(d *DecodeModelOptions) { + *d = opts.DecodeModelOptions + }) + if err != nil { + return err + } + + v := struct { + Resolver + CodeGenOptions + }{ + Resolver: resolver, + CodeGenOptions: opts, + } + + tmpl := template.Must(template.New("tmpl").Funcs(funcMap).Parse(v3Tmpl)) + if err := tmpl.ExecuteTemplate(outFile, "defaults", v); err != nil { + return fmt.Errorf("failed to execute template, %v", err) + } + + return nil +} + +func toSymbol(v string) string { + out := []rune{} + for _, c := range strings.Title(v) { + if !(unicode.IsNumber(c) || unicode.IsLetter(c)) { + continue + } + + out = append(out, c) + } + + return string(out) +} + +func quoteString(v string) string { + return fmt.Sprintf("%q", v) +} + +func regionConstName(p, r string) string { + return toSymbol(p) + toSymbol(r) +} + +func partitionGetter(id string) string { + return fmt.Sprintf("%sPartition", toSymbol(id)) +} + +func partitionVarName(id string) string { + return fmt.Sprintf("%sPartition", strings.ToLower(toSymbol(id))) +} + +func listPartitionNames(ps partitions) string { + names := []string{} + switch len(ps) { + case 1: + return ps[0].Name + case 2: + return fmt.Sprintf("%s and %s", ps[0].Name, ps[1].Name) + default: + for i, p := range ps { + if i == len(ps)-1 { + names = append(names, "and "+p.Name) + } else { + names = append(names, p.Name) + } + } + return strings.Join(names, ", ") + } +} + +func boxedBoolIfSet(msg string, v boxedBool) string { + switch v { + case boxedTrue: + return fmt.Sprintf(msg, "boxedTrue") + case boxedFalse: + return fmt.Sprintf(msg, "boxedFalse") + default: + return "" + } +} + +func stringIfSet(msg, v string) string { + if len(v) == 0 { + return "" + } + + return fmt.Sprintf(msg, v) +} + +func stringSliceIfSet(msg string, vs []string) string { + if len(vs) == 0 { + return "" + } + + names := []string{} + for _, v := range vs { + names = append(names, `"`+v+`"`) + } + + return fmt.Sprintf(msg, strings.Join(names, ",")) +} + +func endpointIsSet(v endpoint) bool { + return !reflect.DeepEqual(v, endpoint{}) +} + +func serviceSet(ps partitions) map[string]struct{} { + set := map[string]struct{}{} + for _, p := range ps { + for id := range p.Services { + set[id] = struct{}{} + } + } + + return set +} + +func endpointVariantSetter(variant endpointVariant) (string, error) { + if variant == 0 { + return "0", nil + } + + if variant > (fipsVariant | dualStackVariant) { + return "", fmt.Errorf("unknown endpoint variant") + } + + var symbols []string + if variant&fipsVariant != 0 { + symbols = append(symbols, "fipsVariant") + } + if variant&dualStackVariant != 0 { + symbols = append(symbols, "dualStackVariant") + } + v := strings.Join(symbols, "|") + + return v, nil +} + +func endpointKeySetter(e endpointKey) (string, error) { + var sb strings.Builder + sb.WriteString("endpointKey{\n") + sb.WriteString(fmt.Sprintf("Region: %q,\n", e.Region)) + if e.Variant != 0 { + variantSetter, err := endpointVariantSetter(e.Variant) + if err != nil { + return "", err + } + sb.WriteString(fmt.Sprintf("Variant: %s,\n", variantSetter)) + } + sb.WriteString("}") + return sb.String(), nil +} + +func defaultKeySetter(e defaultKey) (string, error) { + var sb strings.Builder + sb.WriteString("defaultKey{\n") + if e.Variant != 0 { + variantSetter, err := endpointVariantSetter(e.Variant) + if err != nil { + return "", err + } + sb.WriteString(fmt.Sprintf("Variant: %s,\n", variantSetter)) + } + sb.WriteString("}") + return sb.String(), nil +} + +var funcMap = template.FuncMap{ + "ToSymbol": toSymbol, + "QuoteString": quoteString, + "RegionConst": regionConstName, + "PartitionGetter": partitionGetter, + "PartitionVarName": partitionVarName, + "ListPartitionNames": listPartitionNames, + "BoxedBoolIfSet": boxedBoolIfSet, + "StringIfSet": stringIfSet, + "StringSliceIfSet": stringSliceIfSet, + "EndpointIsSet": endpointIsSet, + "ServicesSet": serviceSet, + "EndpointVariantSetter": endpointVariantSetter, + "EndpointKeySetter": endpointKeySetter, + "DefaultKeySetter": defaultKeySetter, +} + +const v3Tmpl = ` +{{ define "defaults" -}} +// Code generated by aws/endpoints/v3model_codegen.go. DO NOT EDIT. + +package endpoints + +import ( + "regexp" +) + + {{ template "partition consts" $.Resolver }} + + {{ range $_, $partition := $.Resolver }} + {{ template "partition region consts" $partition }} + {{ end }} + + {{ if not $.DisableGenerateServiceIDs -}} + {{ template "service consts" $.Resolver }} + {{- end }} + + {{ template "endpoint resolvers" $.Resolver }} +{{- end }} + +{{ define "partition consts" }} + // Partition identifiers + const ( + {{ range $_, $p := . -}} + {{ ToSymbol $p.ID }}PartitionID = {{ QuoteString $p.ID }} // {{ $p.Name }} partition. + {{ end -}} + ) +{{- end }} + +{{ define "partition region consts" }} + // {{ .Name }} partition's regions. + const ( + {{ range $id, $region := .Regions -}} + {{ ToSymbol $id }}RegionID = {{ QuoteString $id }} // {{ $region.Description }}. + {{ end -}} + ) +{{- end }} + +{{ define "service consts" }} + // Service identifiers + const ( + {{ $serviceSet := ServicesSet . -}} + {{ range $id, $_ := $serviceSet -}} + {{ ToSymbol $id }}ServiceID = {{ QuoteString $id }} // {{ ToSymbol $id }}. + {{ end -}} + ) +{{- end }} + +{{ define "endpoint resolvers" }} + // DefaultResolver returns an Endpoint resolver that will be able + // to resolve endpoints for: {{ ListPartitionNames . }}. + // + // Use DefaultPartitions() to get the list of the default partitions. + func DefaultResolver() Resolver { + return defaultPartitions + } + + // DefaultPartitions returns a list of the partitions the SDK is bundled + // with. The available partitions are: {{ ListPartitionNames . }}. + // + // partitions := endpoints.DefaultPartitions + // for _, p := range partitions { + // // ... inspect partitions + // } + func DefaultPartitions() []Partition { + return defaultPartitions.Partitions() + } + + var defaultPartitions = partitions{ + {{ range $_, $partition := . -}} + {{ PartitionVarName $partition.ID }}, + {{ end }} + } + + {{ range $_, $partition := . -}} + {{ $name := PartitionGetter $partition.ID -}} + // {{ $name }} returns the Resolver for {{ $partition.Name }}. + func {{ $name }}() Partition { + return {{ PartitionVarName $partition.ID }}.Partition() + } + var {{ PartitionVarName $partition.ID }} = {{ template "gocode Partition" $partition }} + {{ end }} +{{ end }} + +{{ define "default partitions" }} + func DefaultPartitions() []Partition { + return []partition{ + {{ range $_, $partition := . -}} + // {{ ToSymbol $partition.ID}}Partition(), + {{ end }} + } + } +{{ end }} + +{{ define "gocode Partition" -}} +partition{ + {{ StringIfSet "ID: %q,\n" .ID -}} + {{ StringIfSet "Name: %q,\n" .Name -}} + {{ StringIfSet "DNSSuffix: %q,\n" .DNSSuffix -}} + RegionRegex: {{ template "gocode RegionRegex" .RegionRegex }}, + {{ if (gt (len .Defaults) 0) -}} + Defaults: {{ template "gocode Defaults" .Defaults -}}, + {{ end -}} + Regions: {{ template "gocode Regions" .Regions }}, + Services: {{ template "gocode Services" .Services }}, +} +{{- end }} + +{{ define "gocode RegionRegex" -}} +regionRegex{ + Regexp: func() *regexp.Regexp{ + reg, _ := regexp.Compile({{ QuoteString .Regexp.String }}) + return reg + }(), +} +{{- end }} + +{{ define "gocode Regions" -}} +regions{ + {{ range $id, $region := . -}} + "{{ $id }}": {{ template "gocode Region" $region }}, + {{ end -}} +} +{{- end }} + +{{ define "gocode Region" -}} +region{ + {{ StringIfSet "Description: %q,\n" .Description -}} +} +{{- end }} + +{{ define "gocode Services" -}} +services{ + {{ range $id, $service := . -}} + "{{ $id }}": {{ template "gocode Service" $service }}, + {{ end }} +} +{{- end }} + +{{ define "gocode Service" -}} +service{ + {{ StringIfSet "PartitionEndpoint: %q,\n" .PartitionEndpoint -}} + {{ BoxedBoolIfSet "IsRegionalized: %s,\n" .IsRegionalized -}} + {{ if (gt (len .Defaults) 0) -}} + Defaults: {{ template "gocode Defaults" .Defaults -}}, + {{ end -}} + {{ if .Endpoints -}} + Endpoints: {{ template "gocode Endpoints" .Endpoints }}, + {{- end }} +} +{{- end }} + +{{ define "gocode Defaults" -}} +endpointDefaults{ + {{ range $id, $endpoint := . -}} + {{ DefaultKeySetter $id }}: {{ template "gocode Endpoint" $endpoint }}, + {{ end }} +} +{{- end }} + +{{ define "gocode Endpoints" -}} +serviceEndpoints{ + {{ range $id, $endpoint := . -}} + {{ EndpointKeySetter $id }}: {{ template "gocode Endpoint" $endpoint }}, + {{ end }} +} +{{- end }} + +{{ define "gocode Endpoint" -}} +endpoint{ + {{ StringIfSet "Hostname: %q,\n" .Hostname -}} + {{ StringIfSet "DNSSuffix: %q,\n" .DNSSuffix -}} + {{ StringIfSet "SSLCommonName: %q,\n" .SSLCommonName -}} + {{ StringSliceIfSet "Protocols: []string{%s},\n" .Protocols -}} + {{ StringSliceIfSet "SignatureVersions: []string{%s},\n" .SignatureVersions -}} + {{ if or .CredentialScope.Region .CredentialScope.Service -}} + CredentialScope: credentialScope{ + {{ StringIfSet "Region: %q,\n" .CredentialScope.Region -}} + {{ StringIfSet "Service: %q,\n" .CredentialScope.Service -}} + }, + {{- end }} + {{ BoxedBoolIfSet "Deprecated: %s,\n" .Deprecated -}} +} +{{- end }} +` diff --git a/vendor/github.com/aws/aws-sdk-go/aws/errors.go b/vendor/github.com/aws/aws-sdk-go/aws/errors.go new file mode 100644 index 0000000..fa06f7a --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/errors.go @@ -0,0 +1,13 @@ +package aws + +import "github.com/aws/aws-sdk-go/aws/awserr" + +var ( + // ErrMissingRegion is an error that is returned if region configuration is + // not found. + ErrMissingRegion = awserr.New("MissingRegion", "could not find region configuration", nil) + + // ErrMissingEndpoint is an error that is returned if an endpoint cannot be + // resolved for a service. + ErrMissingEndpoint = awserr.New("MissingEndpoint", "'Endpoint' configuration is required for this service", nil) +) diff --git a/vendor/github.com/aws/aws-sdk-go/aws/jsonvalue.go b/vendor/github.com/aws/aws-sdk-go/aws/jsonvalue.go new file mode 100644 index 0000000..91a6f27 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/jsonvalue.go @@ -0,0 +1,12 @@ +package aws + +// JSONValue is a representation of a grab bag type that will be marshaled +// into a json string. This type can be used just like any other map. +// +// Example: +// +// values := aws.JSONValue{ +// "Foo": "Bar", +// } +// values["Baz"] = "Qux" +type JSONValue map[string]interface{} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/logger.go b/vendor/github.com/aws/aws-sdk-go/aws/logger.go new file mode 100644 index 0000000..49674cc --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/logger.go @@ -0,0 +1,121 @@ +package aws + +import ( + "log" + "os" +) + +// A LogLevelType defines the level logging should be performed at. Used to instruct +// the SDK which statements should be logged. +type LogLevelType uint + +// LogLevel returns the pointer to a LogLevel. Should be used to workaround +// not being able to take the address of a non-composite literal. +func LogLevel(l LogLevelType) *LogLevelType { + return &l +} + +// Value returns the LogLevel value or the default value LogOff if the LogLevel +// is nil. Safe to use on nil value LogLevelTypes. +func (l *LogLevelType) Value() LogLevelType { + if l != nil { + return *l + } + return LogOff +} + +// Matches returns true if the v LogLevel is enabled by this LogLevel. Should be +// used with logging sub levels. Is safe to use on nil value LogLevelTypes. If +// LogLevel is nil, will default to LogOff comparison. +func (l *LogLevelType) Matches(v LogLevelType) bool { + c := l.Value() + return c&v == v +} + +// AtLeast returns true if this LogLevel is at least high enough to satisfies v. +// Is safe to use on nil value LogLevelTypes. If LogLevel is nil, will default +// to LogOff comparison. +func (l *LogLevelType) AtLeast(v LogLevelType) bool { + c := l.Value() + return c >= v +} + +const ( + // LogOff states that no logging should be performed by the SDK. This is the + // default state of the SDK, and should be use to disable all logging. + LogOff LogLevelType = iota * 0x1000 + + // LogDebug state that debug output should be logged by the SDK. This should + // be used to inspect request made and responses received. + LogDebug +) + +// Debug Logging Sub Levels +const ( + // LogDebugWithSigning states that the SDK should log request signing and + // presigning events. This should be used to log the signing details of + // requests for debugging. Will also enable LogDebug. + LogDebugWithSigning LogLevelType = LogDebug | (1 << iota) + + // LogDebugWithHTTPBody states the SDK should log HTTP request and response + // HTTP bodys in addition to the headers and path. This should be used to + // see the body content of requests and responses made while using the SDK + // Will also enable LogDebug. + LogDebugWithHTTPBody + + // LogDebugWithRequestRetries states the SDK should log when service requests will + // be retried. This should be used to log when you want to log when service + // requests are being retried. Will also enable LogDebug. + LogDebugWithRequestRetries + + // LogDebugWithRequestErrors states the SDK should log when service requests fail + // to build, send, validate, or unmarshal. + LogDebugWithRequestErrors + + // LogDebugWithEventStreamBody states the SDK should log EventStream + // request and response bodys. This should be used to log the EventStream + // wire unmarshaled message content of requests and responses made while + // using the SDK Will also enable LogDebug. + LogDebugWithEventStreamBody + + // LogDebugWithDeprecated states the SDK should log details about deprecated functionality. + LogDebugWithDeprecated +) + +// A Logger is a minimalistic interface for the SDK to log messages to. Should +// be used to provide custom logging writers for the SDK to use. +type Logger interface { + Log(...interface{}) +} + +// A LoggerFunc is a convenience type to convert a function taking a variadic +// list of arguments and wrap it so the Logger interface can be used. +// +// Example: +// s3.New(sess, &aws.Config{Logger: aws.LoggerFunc(func(args ...interface{}) { +// fmt.Fprintln(os.Stdout, args...) +// })}) +type LoggerFunc func(...interface{}) + +// Log calls the wrapped function with the arguments provided +func (f LoggerFunc) Log(args ...interface{}) { + f(args...) +} + +// NewDefaultLogger returns a Logger which will write log messages to stdout, and +// use same formatting runes as the stdlib log.Logger +func NewDefaultLogger() Logger { + return &defaultLogger{ + logger: log.New(os.Stdout, "", log.LstdFlags), + } +} + +// A defaultLogger provides a minimalistic logger satisfying the Logger interface. +type defaultLogger struct { + logger *log.Logger +} + +// Log logs the parameters to the stdlib logger. See log.Println. +func (l defaultLogger) Log(args ...interface{}) { + l.logger.Println(args...) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error.go b/vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error.go new file mode 100644 index 0000000..2ba3c56 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error.go @@ -0,0 +1,19 @@ +package request + +import ( + "strings" +) + +func isErrConnectionReset(err error) bool { + if strings.Contains(err.Error(), "read: connection reset") { + return false + } + + if strings.Contains(err.Error(), "use of closed network connection") || + strings.Contains(err.Error(), "connection reset") || + strings.Contains(err.Error(), "broken pipe") { + return true + } + + return false +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/handlers.go b/vendor/github.com/aws/aws-sdk-go/aws/request/handlers.go new file mode 100644 index 0000000..e819ab6 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/handlers.go @@ -0,0 +1,343 @@ +package request + +import ( + "fmt" + "strings" +) + +// A Handlers provides a collection of request handlers for various +// stages of handling requests. +type Handlers struct { + Validate HandlerList + Build HandlerList + BuildStream HandlerList + Sign HandlerList + Send HandlerList + ValidateResponse HandlerList + Unmarshal HandlerList + UnmarshalStream HandlerList + UnmarshalMeta HandlerList + UnmarshalError HandlerList + Retry HandlerList + AfterRetry HandlerList + CompleteAttempt HandlerList + Complete HandlerList +} + +// Copy returns a copy of this handler's lists. +func (h *Handlers) Copy() Handlers { + return Handlers{ + Validate: h.Validate.copy(), + Build: h.Build.copy(), + BuildStream: h.BuildStream.copy(), + Sign: h.Sign.copy(), + Send: h.Send.copy(), + ValidateResponse: h.ValidateResponse.copy(), + Unmarshal: h.Unmarshal.copy(), + UnmarshalStream: h.UnmarshalStream.copy(), + UnmarshalError: h.UnmarshalError.copy(), + UnmarshalMeta: h.UnmarshalMeta.copy(), + Retry: h.Retry.copy(), + AfterRetry: h.AfterRetry.copy(), + CompleteAttempt: h.CompleteAttempt.copy(), + Complete: h.Complete.copy(), + } +} + +// Clear removes callback functions for all handlers. +func (h *Handlers) Clear() { + h.Validate.Clear() + h.Build.Clear() + h.BuildStream.Clear() + h.Send.Clear() + h.Sign.Clear() + h.Unmarshal.Clear() + h.UnmarshalStream.Clear() + h.UnmarshalMeta.Clear() + h.UnmarshalError.Clear() + h.ValidateResponse.Clear() + h.Retry.Clear() + h.AfterRetry.Clear() + h.CompleteAttempt.Clear() + h.Complete.Clear() +} + +// IsEmpty returns if there are no handlers in any of the handlerlists. +func (h *Handlers) IsEmpty() bool { + if h.Validate.Len() != 0 { + return false + } + if h.Build.Len() != 0 { + return false + } + if h.BuildStream.Len() != 0 { + return false + } + if h.Send.Len() != 0 { + return false + } + if h.Sign.Len() != 0 { + return false + } + if h.Unmarshal.Len() != 0 { + return false + } + if h.UnmarshalStream.Len() != 0 { + return false + } + if h.UnmarshalMeta.Len() != 0 { + return false + } + if h.UnmarshalError.Len() != 0 { + return false + } + if h.ValidateResponse.Len() != 0 { + return false + } + if h.Retry.Len() != 0 { + return false + } + if h.AfterRetry.Len() != 0 { + return false + } + if h.CompleteAttempt.Len() != 0 { + return false + } + if h.Complete.Len() != 0 { + return false + } + + return true +} + +// A HandlerListRunItem represents an entry in the HandlerList which +// is being run. +type HandlerListRunItem struct { + Index int + Handler NamedHandler + Request *Request +} + +// A HandlerList manages zero or more handlers in a list. +type HandlerList struct { + list []NamedHandler + + // Called after each request handler in the list is called. If set + // and the func returns true the HandlerList will continue to iterate + // over the request handlers. If false is returned the HandlerList + // will stop iterating. + // + // Should be used if extra logic to be performed between each handler + // in the list. This can be used to terminate a list's iteration + // based on a condition such as error like, HandlerListStopOnError. + // Or for logging like HandlerListLogItem. + AfterEachFn func(item HandlerListRunItem) bool +} + +// A NamedHandler is a struct that contains a name and function callback. +type NamedHandler struct { + Name string + Fn func(*Request) +} + +// copy creates a copy of the handler list. +func (l *HandlerList) copy() HandlerList { + n := HandlerList{ + AfterEachFn: l.AfterEachFn, + } + if len(l.list) == 0 { + return n + } + + n.list = append(make([]NamedHandler, 0, len(l.list)), l.list...) + return n +} + +// Clear clears the handler list. +func (l *HandlerList) Clear() { + l.list = l.list[0:0] +} + +// Len returns the number of handlers in the list. +func (l *HandlerList) Len() int { + return len(l.list) +} + +// PushBack pushes handler f to the back of the handler list. +func (l *HandlerList) PushBack(f func(*Request)) { + l.PushBackNamed(NamedHandler{"__anonymous", f}) +} + +// PushBackNamed pushes named handler f to the back of the handler list. +func (l *HandlerList) PushBackNamed(n NamedHandler) { + if cap(l.list) == 0 { + l.list = make([]NamedHandler, 0, 5) + } + l.list = append(l.list, n) +} + +// PushFront pushes handler f to the front of the handler list. +func (l *HandlerList) PushFront(f func(*Request)) { + l.PushFrontNamed(NamedHandler{"__anonymous", f}) +} + +// PushFrontNamed pushes named handler f to the front of the handler list. +func (l *HandlerList) PushFrontNamed(n NamedHandler) { + if cap(l.list) == len(l.list) { + // Allocating new list required + l.list = append([]NamedHandler{n}, l.list...) + } else { + // Enough room to prepend into list. + l.list = append(l.list, NamedHandler{}) + copy(l.list[1:], l.list) + l.list[0] = n + } +} + +// Remove removes a NamedHandler n +func (l *HandlerList) Remove(n NamedHandler) { + l.RemoveByName(n.Name) +} + +// RemoveByName removes a NamedHandler by name. +func (l *HandlerList) RemoveByName(name string) { + for i := 0; i < len(l.list); i++ { + m := l.list[i] + if m.Name == name { + // Shift array preventing creating new arrays + copy(l.list[i:], l.list[i+1:]) + l.list[len(l.list)-1] = NamedHandler{} + l.list = l.list[:len(l.list)-1] + + // decrement list so next check to length is correct + i-- + } + } +} + +// SwapNamed will swap out any existing handlers with the same name as the +// passed in NamedHandler returning true if handlers were swapped. False is +// returned otherwise. +func (l *HandlerList) SwapNamed(n NamedHandler) (swapped bool) { + for i := 0; i < len(l.list); i++ { + if l.list[i].Name == n.Name { + l.list[i].Fn = n.Fn + swapped = true + } + } + + return swapped +} + +// Swap will swap out all handlers matching the name passed in. The matched +// handlers will be swapped in. True is returned if the handlers were swapped. +func (l *HandlerList) Swap(name string, replace NamedHandler) bool { + var swapped bool + + for i := 0; i < len(l.list); i++ { + if l.list[i].Name == name { + l.list[i] = replace + swapped = true + } + } + + return swapped +} + +// SetBackNamed will replace the named handler if it exists in the handler list. +// If the handler does not exist the handler will be added to the end of the list. +func (l *HandlerList) SetBackNamed(n NamedHandler) { + if !l.SwapNamed(n) { + l.PushBackNamed(n) + } +} + +// SetFrontNamed will replace the named handler if it exists in the handler list. +// If the handler does not exist the handler will be added to the beginning of +// the list. +func (l *HandlerList) SetFrontNamed(n NamedHandler) { + if !l.SwapNamed(n) { + l.PushFrontNamed(n) + } +} + +// Run executes all handlers in the list with a given request object. +func (l *HandlerList) Run(r *Request) { + for i, h := range l.list { + h.Fn(r) + item := HandlerListRunItem{ + Index: i, Handler: h, Request: r, + } + if l.AfterEachFn != nil && !l.AfterEachFn(item) { + return + } + } +} + +// HandlerListLogItem logs the request handler and the state of the +// request's Error value. Always returns true to continue iterating +// request handlers in a HandlerList. +func HandlerListLogItem(item HandlerListRunItem) bool { + if item.Request.Config.Logger == nil { + return true + } + item.Request.Config.Logger.Log("DEBUG: RequestHandler", + item.Index, item.Handler.Name, item.Request.Error) + + return true +} + +// HandlerListStopOnError returns false to stop the HandlerList iterating +// over request handlers if Request.Error is not nil. True otherwise +// to continue iterating. +func HandlerListStopOnError(item HandlerListRunItem) bool { + return item.Request.Error == nil +} + +// WithAppendUserAgent will add a string to the user agent prefixed with a +// single white space. +func WithAppendUserAgent(s string) Option { + return func(r *Request) { + r.Handlers.Build.PushBack(func(r2 *Request) { + AddToUserAgent(r, s) + }) + } +} + +// MakeAddToUserAgentHandler will add the name/version pair to the User-Agent request +// header. If the extra parameters are provided they will be added as metadata to the +// name/version pair resulting in the following format. +// "name/version (extra0; extra1; ...)" +// The user agent part will be concatenated with this current request's user agent string. +func MakeAddToUserAgentHandler(name, version string, extra ...string) func(*Request) { + ua := fmt.Sprintf("%s/%s", name, version) + if len(extra) > 0 { + ua += fmt.Sprintf(" (%s)", strings.Join(extra, "; ")) + } + return func(r *Request) { + AddToUserAgent(r, ua) + } +} + +// MakeAddToUserAgentFreeFormHandler adds the input to the User-Agent request header. +// The input string will be concatenated with the current request's user agent string. +func MakeAddToUserAgentFreeFormHandler(s string) func(*Request) { + return func(r *Request) { + AddToUserAgent(r, s) + } +} + +// WithSetRequestHeaders updates the operation request's HTTP header to contain +// the header key value pairs provided. If the header key already exists in the +// request's HTTP header set, the existing value(s) will be replaced. +func WithSetRequestHeaders(h map[string]string) Option { + return withRequestHeader(h).SetRequestHeaders +} + +type withRequestHeader map[string]string + +func (h withRequestHeader) SetRequestHeaders(r *Request) { + for k, v := range h { + r.HTTPRequest.Header[k] = []string{v} + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/http_request.go b/vendor/github.com/aws/aws-sdk-go/aws/request/http_request.go new file mode 100644 index 0000000..79f7960 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/http_request.go @@ -0,0 +1,24 @@ +package request + +import ( + "io" + "net/http" + "net/url" +) + +func copyHTTPRequest(r *http.Request, body io.ReadCloser) *http.Request { + req := new(http.Request) + *req = *r + req.URL = &url.URL{} + *req.URL = *r.URL + req.Body = body + + req.Header = http.Header{} + for k, v := range r.Header { + for _, vv := range v { + req.Header.Add(k, vv) + } + } + + return req +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/offset_reader.go b/vendor/github.com/aws/aws-sdk-go/aws/request/offset_reader.go new file mode 100644 index 0000000..9370fa5 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/offset_reader.go @@ -0,0 +1,65 @@ +package request + +import ( + "io" + "sync" + + "github.com/aws/aws-sdk-go/internal/sdkio" +) + +// offsetReader is a thread-safe io.ReadCloser to prevent racing +// with retrying requests +type offsetReader struct { + buf io.ReadSeeker + lock sync.Mutex + closed bool +} + +func newOffsetReader(buf io.ReadSeeker, offset int64) (*offsetReader, error) { + reader := &offsetReader{} + _, err := buf.Seek(offset, sdkio.SeekStart) + if err != nil { + return nil, err + } + + reader.buf = buf + return reader, nil +} + +// Close will close the instance of the offset reader's access to +// the underlying io.ReadSeeker. +func (o *offsetReader) Close() error { + o.lock.Lock() + defer o.lock.Unlock() + o.closed = true + return nil +} + +// Read is a thread-safe read of the underlying io.ReadSeeker +func (o *offsetReader) Read(p []byte) (int, error) { + o.lock.Lock() + defer o.lock.Unlock() + + if o.closed { + return 0, io.EOF + } + + return o.buf.Read(p) +} + +// Seek is a thread-safe seeking operation. +func (o *offsetReader) Seek(offset int64, whence int) (int64, error) { + o.lock.Lock() + defer o.lock.Unlock() + + return o.buf.Seek(offset, whence) +} + +// CloseAndCopy will return a new offsetReader with a copy of the old buffer +// and close the old buffer. +func (o *offsetReader) CloseAndCopy(offset int64) (*offsetReader, error) { + if err := o.Close(); err != nil { + return nil, err + } + return newOffsetReader(o.buf, offset) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request.go new file mode 100644 index 0000000..fb0a68f --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request.go @@ -0,0 +1,713 @@ +package request + +import ( + "bytes" + "fmt" + "io" + "net/http" + "net/url" + "reflect" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/client/metadata" + "github.com/aws/aws-sdk-go/internal/sdkio" +) + +const ( + // ErrCodeSerialization is the serialization error code that is received + // during protocol unmarshaling. + ErrCodeSerialization = "SerializationError" + + // ErrCodeRead is an error that is returned during HTTP reads. + ErrCodeRead = "ReadError" + + // ErrCodeResponseTimeout is the connection timeout error that is received + // during body reads. + ErrCodeResponseTimeout = "ResponseTimeout" + + // ErrCodeInvalidPresignExpire is returned when the expire time provided to + // presign is invalid + ErrCodeInvalidPresignExpire = "InvalidPresignExpireError" + + // CanceledErrorCode is the error code that will be returned by an + // API request that was canceled. Requests given a aws.Context may + // return this error when canceled. + CanceledErrorCode = "RequestCanceled" + + // ErrCodeRequestError is an error preventing the SDK from continuing to + // process the request. + ErrCodeRequestError = "RequestError" +) + +// A Request is the service request to be made. +type Request struct { + Config aws.Config + ClientInfo metadata.ClientInfo + Handlers Handlers + + Retryer + AttemptTime time.Time + Time time.Time + Operation *Operation + HTTPRequest *http.Request + HTTPResponse *http.Response + Body io.ReadSeeker + streamingBody io.ReadCloser + BodyStart int64 // offset from beginning of Body that the request body starts + Params interface{} + Error error + Data interface{} + RequestID string + RetryCount int + Retryable *bool + RetryDelay time.Duration + NotHoist bool + SignedHeaderVals http.Header + LastSignedAt time.Time + DisableFollowRedirects bool + + // Additional API error codes that should be retried. IsErrorRetryable + // will consider these codes in addition to its built in cases. + RetryErrorCodes []string + + // Additional API error codes that should be retried with throttle backoff + // delay. IsErrorThrottle will consider these codes in addition to its + // built in cases. + ThrottleErrorCodes []string + + // A value greater than 0 instructs the request to be signed as Presigned URL + // You should not set this field directly. Instead use Request's + // Presign or PresignRequest methods. + ExpireTime time.Duration + + context aws.Context + + built bool + + // Need to persist an intermediate body between the input Body and HTTP + // request body because the HTTP Client's transport can maintain a reference + // to the HTTP request's body after the client has returned. This value is + // safe to use concurrently and wrap the input Body for each HTTP request. + safeBody *offsetReader +} + +// An Operation is the service API operation to be made. +type Operation struct { + Name string + HTTPMethod string + HTTPPath string + *Paginator + + BeforePresignFn func(r *Request) error +} + +// New returns a new Request pointer for the service API operation and +// parameters. +// +// A Retryer should be provided to direct how the request is retried. If +// Retryer is nil, a default no retry value will be used. You can use +// NoOpRetryer in the Client package to disable retry behavior directly. +// +// Params is any value of input parameters to be the request payload. +// Data is pointer value to an object which the request's response +// payload will be deserialized to. +func New(cfg aws.Config, clientInfo metadata.ClientInfo, handlers Handlers, + retryer Retryer, operation *Operation, params interface{}, data interface{}) *Request { + + if retryer == nil { + retryer = noOpRetryer{} + } + + method := operation.HTTPMethod + if method == "" { + method = "POST" + } + + httpReq, _ := http.NewRequest(method, "", nil) + + var err error + httpReq.URL, err = url.Parse(clientInfo.Endpoint) + if err != nil { + httpReq.URL = &url.URL{} + err = awserr.New("InvalidEndpointURL", "invalid endpoint uri", err) + } + + if len(operation.HTTPPath) != 0 { + opHTTPPath := operation.HTTPPath + var opQueryString string + if idx := strings.Index(opHTTPPath, "?"); idx >= 0 { + opQueryString = opHTTPPath[idx+1:] + opHTTPPath = opHTTPPath[:idx] + } + + if strings.HasSuffix(httpReq.URL.Path, "/") && strings.HasPrefix(opHTTPPath, "/") { + opHTTPPath = opHTTPPath[1:] + } + httpReq.URL.Path += opHTTPPath + httpReq.URL.RawQuery = opQueryString + } + + r := &Request{ + Config: cfg, + ClientInfo: clientInfo, + Handlers: handlers.Copy(), + + Retryer: retryer, + Time: time.Now(), + ExpireTime: 0, + Operation: operation, + HTTPRequest: httpReq, + Body: nil, + Params: params, + Error: err, + Data: data, + } + r.SetBufferBody([]byte{}) + + return r +} + +// A Option is a functional option that can augment or modify a request when +// using a WithContext API operation method. +type Option func(*Request) + +// WithGetResponseHeader builds a request Option which will retrieve a single +// header value from the HTTP Response. If there are multiple values for the +// header key use WithGetResponseHeaders instead to access the http.Header +// map directly. The passed in val pointer must be non-nil. +// +// This Option can be used multiple times with a single API operation. +// +// var id2, versionID string +// svc.PutObjectWithContext(ctx, params, +// request.WithGetResponseHeader("x-amz-id-2", &id2), +// request.WithGetResponseHeader("x-amz-version-id", &versionID), +// ) +func WithGetResponseHeader(key string, val *string) Option { + return func(r *Request) { + r.Handlers.Complete.PushBack(func(req *Request) { + *val = req.HTTPResponse.Header.Get(key) + }) + } +} + +// WithGetResponseHeaders builds a request Option which will retrieve the +// headers from the HTTP response and assign them to the passed in headers +// variable. The passed in headers pointer must be non-nil. +// +// var headers http.Header +// svc.PutObjectWithContext(ctx, params, request.WithGetResponseHeaders(&headers)) +func WithGetResponseHeaders(headers *http.Header) Option { + return func(r *Request) { + r.Handlers.Complete.PushBack(func(req *Request) { + *headers = req.HTTPResponse.Header + }) + } +} + +// WithLogLevel is a request option that will set the request to use a specific +// log level when the request is made. +// +// svc.PutObjectWithContext(ctx, params, request.WithLogLevel(aws.LogDebugWithHTTPBody) +func WithLogLevel(l aws.LogLevelType) Option { + return func(r *Request) { + r.Config.LogLevel = aws.LogLevel(l) + } +} + +// ApplyOptions will apply each option to the request calling them in the order +// the were provided. +func (r *Request) ApplyOptions(opts ...Option) { + for _, opt := range opts { + opt(r) + } +} + +// Context will always returns a non-nil context. If Request does not have a +// context aws.BackgroundContext will be returned. +func (r *Request) Context() aws.Context { + if r.context != nil { + return r.context + } + return aws.BackgroundContext() +} + +// SetContext adds a Context to the current request that can be used to cancel +// a in-flight request. The Context value must not be nil, or this method will +// panic. +// +// Unlike http.Request.WithContext, SetContext does not return a copy of the +// Request. It is not safe to use use a single Request value for multiple +// requests. A new Request should be created for each API operation request. +// +// Go 1.6 and below: +// The http.Request's Cancel field will be set to the Done() value of +// the context. This will overwrite the Cancel field's value. +// +// Go 1.7 and above: +// The http.Request.WithContext will be used to set the context on the underlying +// http.Request. This will create a shallow copy of the http.Request. The SDK +// may create sub contexts in the future for nested requests such as retries. +func (r *Request) SetContext(ctx aws.Context) { + if ctx == nil { + panic("context cannot be nil") + } + setRequestContext(r, ctx) +} + +// WillRetry returns if the request's can be retried. +func (r *Request) WillRetry() bool { + if !aws.IsReaderSeekable(r.Body) && r.HTTPRequest.Body != NoBody { + return false + } + return r.Error != nil && aws.BoolValue(r.Retryable) && r.RetryCount < r.MaxRetries() +} + +func fmtAttemptCount(retryCount, maxRetries int) string { + return fmt.Sprintf("attempt %v/%v", retryCount, maxRetries) +} + +// ParamsFilled returns if the request's parameters have been populated +// and the parameters are valid. False is returned if no parameters are +// provided or invalid. +func (r *Request) ParamsFilled() bool { + return r.Params != nil && reflect.ValueOf(r.Params).Elem().IsValid() +} + +// DataFilled returns true if the request's data for response deserialization +// target has been set and is a valid. False is returned if data is not +// set, or is invalid. +func (r *Request) DataFilled() bool { + return r.Data != nil && reflect.ValueOf(r.Data).Elem().IsValid() +} + +// SetBufferBody will set the request's body bytes that will be sent to +// the service API. +func (r *Request) SetBufferBody(buf []byte) { + r.SetReaderBody(bytes.NewReader(buf)) +} + +// SetStringBody sets the body of the request to be backed by a string. +func (r *Request) SetStringBody(s string) { + r.SetReaderBody(strings.NewReader(s)) +} + +// SetReaderBody will set the request's body reader. +func (r *Request) SetReaderBody(reader io.ReadSeeker) { + r.Body = reader + + if aws.IsReaderSeekable(reader) { + var err error + // Get the Bodies current offset so retries will start from the same + // initial position. + r.BodyStart, err = reader.Seek(0, sdkio.SeekCurrent) + if err != nil { + r.Error = awserr.New(ErrCodeSerialization, + "failed to determine start of request body", err) + return + } + } + r.ResetBody() +} + +// SetStreamingBody set the reader to be used for the request that will stream +// bytes to the server. Request's Body must not be set to any reader. +func (r *Request) SetStreamingBody(reader io.ReadCloser) { + r.streamingBody = reader + r.SetReaderBody(aws.ReadSeekCloser(reader)) +} + +// Presign returns the request's signed URL. Error will be returned +// if the signing fails. The expire parameter is only used for presigned Amazon +// S3 API requests. All other AWS services will use a fixed expiration +// time of 15 minutes. +// +// It is invalid to create a presigned URL with a expire duration 0 or less. An +// error is returned if expire duration is 0 or less. +func (r *Request) Presign(expire time.Duration) (string, error) { + r = r.copy() + + // Presign requires all headers be hoisted. There is no way to retrieve + // the signed headers not hoisted without this. Making the presigned URL + // useless. + r.NotHoist = false + + u, _, err := getPresignedURL(r, expire) + return u, err +} + +// PresignRequest behaves just like presign, with the addition of returning a +// set of headers that were signed. The expire parameter is only used for +// presigned Amazon S3 API requests. All other AWS services will use a fixed +// expiration time of 15 minutes. +// +// It is invalid to create a presigned URL with a expire duration 0 or less. An +// error is returned if expire duration is 0 or less. +// +// Returns the URL string for the API operation with signature in the query string, +// and the HTTP headers that were included in the signature. These headers must +// be included in any HTTP request made with the presigned URL. +// +// To prevent hoisting any headers to the query string set NotHoist to true on +// this Request value prior to calling PresignRequest. +func (r *Request) PresignRequest(expire time.Duration) (string, http.Header, error) { + r = r.copy() + return getPresignedURL(r, expire) +} + +// IsPresigned returns true if the request represents a presigned API url. +func (r *Request) IsPresigned() bool { + return r.ExpireTime != 0 +} + +func getPresignedURL(r *Request, expire time.Duration) (string, http.Header, error) { + if expire <= 0 { + return "", nil, awserr.New( + ErrCodeInvalidPresignExpire, + "presigned URL requires an expire duration greater than 0", + nil, + ) + } + + r.ExpireTime = expire + + if r.Operation.BeforePresignFn != nil { + if err := r.Operation.BeforePresignFn(r); err != nil { + return "", nil, err + } + } + + if err := r.Sign(); err != nil { + return "", nil, err + } + + return r.HTTPRequest.URL.String(), r.SignedHeaderVals, nil +} + +const ( + notRetrying = "not retrying" +) + +func debugLogReqError(r *Request, stage, retryStr string, err error) { + if !r.Config.LogLevel.Matches(aws.LogDebugWithRequestErrors) { + return + } + + r.Config.Logger.Log(fmt.Sprintf("DEBUG: %s %s/%s failed, %s, error %v", + stage, r.ClientInfo.ServiceName, r.Operation.Name, retryStr, err)) +} + +// Build will build the request's object so it can be signed and sent +// to the service. Build will also validate all the request's parameters. +// Any additional build Handlers set on this request will be run +// in the order they were set. +// +// The request will only be built once. Multiple calls to build will have +// no effect. +// +// If any Validate or Build errors occur the build will stop and the error +// which occurred will be returned. +func (r *Request) Build() error { + if !r.built { + r.Handlers.Validate.Run(r) + if r.Error != nil { + debugLogReqError(r, "Validate Request", notRetrying, r.Error) + return r.Error + } + r.Handlers.Build.Run(r) + if r.Error != nil { + debugLogReqError(r, "Build Request", notRetrying, r.Error) + return r.Error + } + r.built = true + } + + return r.Error +} + +// Sign will sign the request, returning error if errors are encountered. +// +// Sign will build the request prior to signing. All Sign Handlers will +// be executed in the order they were set. +func (r *Request) Sign() error { + r.Build() + if r.Error != nil { + debugLogReqError(r, "Build Request", notRetrying, r.Error) + return r.Error + } + + SanitizeHostForHeader(r.HTTPRequest) + + r.Handlers.Sign.Run(r) + return r.Error +} + +func (r *Request) getNextRequestBody() (body io.ReadCloser, err error) { + if r.streamingBody != nil { + return r.streamingBody, nil + } + + if r.safeBody != nil { + r.safeBody.Close() + } + + r.safeBody, err = newOffsetReader(r.Body, r.BodyStart) + if err != nil { + return nil, awserr.New(ErrCodeSerialization, + "failed to get next request body reader", err) + } + + // Go 1.8 tightened and clarified the rules code needs to use when building + // requests with the http package. Go 1.8 removed the automatic detection + // of if the Request.Body was empty, or actually had bytes in it. The SDK + // always sets the Request.Body even if it is empty and should not actually + // be sent. This is incorrect. + // + // Go 1.8 did add a http.NoBody value that the SDK can use to tell the http + // client that the request really should be sent without a body. The + // Request.Body cannot be set to nil, which is preferable, because the + // field is exported and could introduce nil pointer dereferences for users + // of the SDK if they used that field. + // + // Related golang/go#18257 + l, err := aws.SeekerLen(r.Body) + if err != nil { + return nil, awserr.New(ErrCodeSerialization, + "failed to compute request body size", err) + } + + if l == 0 { + body = NoBody + } else if l > 0 { + body = r.safeBody + } else { + // Hack to prevent sending bodies for methods where the body + // should be ignored by the server. Sending bodies on these + // methods without an associated ContentLength will cause the + // request to socket timeout because the server does not handle + // Transfer-Encoding: chunked bodies for these methods. + // + // This would only happen if a aws.ReaderSeekerCloser was used with + // a io.Reader that was not also an io.Seeker, or did not implement + // Len() method. + switch r.Operation.HTTPMethod { + case "GET", "HEAD", "DELETE": + body = NoBody + default: + body = r.safeBody + } + } + + return body, nil +} + +// GetBody will return an io.ReadSeeker of the Request's underlying +// input body with a concurrency safe wrapper. +func (r *Request) GetBody() io.ReadSeeker { + return r.safeBody +} + +// Send will send the request, returning error if errors are encountered. +// +// Send will sign the request prior to sending. All Send Handlers will +// be executed in the order they were set. +// +// Canceling a request is non-deterministic. If a request has been canceled, +// then the transport will choose, randomly, one of the state channels during +// reads or getting the connection. +// +// readLoop() and getConn(req *Request, cm connectMethod) +// https://github.com/golang/go/blob/master/src/net/http/transport.go +// +// Send will not close the request.Request's body. +func (r *Request) Send() error { + defer func() { + // Regardless of success or failure of the request trigger the Complete + // request handlers. + r.Handlers.Complete.Run(r) + }() + + if err := r.Error; err != nil { + return err + } + + for { + r.Error = nil + r.AttemptTime = time.Now() + + if err := r.Sign(); err != nil { + debugLogReqError(r, "Sign Request", notRetrying, err) + return err + } + + if err := r.sendRequest(); err == nil { + return nil + } + r.Handlers.Retry.Run(r) + r.Handlers.AfterRetry.Run(r) + + if r.Error != nil || !aws.BoolValue(r.Retryable) { + return r.Error + } + + if err := r.prepareRetry(); err != nil { + r.Error = err + return err + } + } +} + +func (r *Request) prepareRetry() error { + if r.Config.LogLevel.Matches(aws.LogDebugWithRequestRetries) { + r.Config.Logger.Log(fmt.Sprintf("DEBUG: Retrying Request %s/%s, attempt %d", + r.ClientInfo.ServiceName, r.Operation.Name, r.RetryCount)) + } + + // The previous http.Request will have a reference to the r.Body + // and the HTTP Client's Transport may still be reading from + // the request's body even though the Client's Do returned. + r.HTTPRequest = copyHTTPRequest(r.HTTPRequest, nil) + r.ResetBody() + if err := r.Error; err != nil { + return awserr.New(ErrCodeSerialization, + "failed to prepare body for retry", err) + + } + + // Closing response body to ensure that no response body is leaked + // between retry attempts. + if r.HTTPResponse != nil && r.HTTPResponse.Body != nil { + r.HTTPResponse.Body.Close() + } + + return nil +} + +func (r *Request) sendRequest() (sendErr error) { + defer r.Handlers.CompleteAttempt.Run(r) + + r.Retryable = nil + r.Handlers.Send.Run(r) + if r.Error != nil { + debugLogReqError(r, "Send Request", + fmtAttemptCount(r.RetryCount, r.MaxRetries()), + r.Error) + return r.Error + } + + r.Handlers.UnmarshalMeta.Run(r) + r.Handlers.ValidateResponse.Run(r) + if r.Error != nil { + r.Handlers.UnmarshalError.Run(r) + debugLogReqError(r, "Validate Response", + fmtAttemptCount(r.RetryCount, r.MaxRetries()), + r.Error) + return r.Error + } + + r.Handlers.Unmarshal.Run(r) + if r.Error != nil { + debugLogReqError(r, "Unmarshal Response", + fmtAttemptCount(r.RetryCount, r.MaxRetries()), + r.Error) + return r.Error + } + + return nil +} + +// copy will copy a request which will allow for local manipulation of the +// request. +func (r *Request) copy() *Request { + req := &Request{} + *req = *r + req.Handlers = r.Handlers.Copy() + op := *r.Operation + req.Operation = &op + return req +} + +// AddToUserAgent adds the string to the end of the request's current user agent. +func AddToUserAgent(r *Request, s string) { + curUA := r.HTTPRequest.Header.Get("User-Agent") + if len(curUA) > 0 { + s = curUA + " " + s + } + r.HTTPRequest.Header.Set("User-Agent", s) +} + +// SanitizeHostForHeader removes default port from host and updates request.Host +func SanitizeHostForHeader(r *http.Request) { + host := getHost(r) + port := portOnly(host) + if port != "" && isDefaultPort(r.URL.Scheme, port) { + r.Host = stripPort(host) + } +} + +// Returns host from request +func getHost(r *http.Request) string { + if r.Host != "" { + return r.Host + } + + if r.URL == nil { + return "" + } + + return r.URL.Host +} + +// Hostname returns u.Host, without any port number. +// +// If Host is an IPv6 literal with a port number, Hostname returns the +// IPv6 literal without the square brackets. IPv6 literals may include +// a zone identifier. +// +// Copied from the Go 1.8 standard library (net/url) +func stripPort(hostport string) string { + colon := strings.IndexByte(hostport, ':') + if colon == -1 { + return hostport + } + if i := strings.IndexByte(hostport, ']'); i != -1 { + return strings.TrimPrefix(hostport[:i], "[") + } + return hostport[:colon] +} + +// Port returns the port part of u.Host, without the leading colon. +// If u.Host doesn't contain a port, Port returns an empty string. +// +// Copied from the Go 1.8 standard library (net/url) +func portOnly(hostport string) string { + colon := strings.IndexByte(hostport, ':') + if colon == -1 { + return "" + } + if i := strings.Index(hostport, "]:"); i != -1 { + return hostport[i+len("]:"):] + } + if strings.Contains(hostport, "]") { + return "" + } + return hostport[colon+len(":"):] +} + +// Returns true if the specified URI is using the standard port +// (i.e. port 80 for HTTP URIs or 443 for HTTPS URIs) +func isDefaultPort(scheme, port string) bool { + if port == "" { + return true + } + + lowerCaseScheme := strings.ToLower(scheme) + if (lowerCaseScheme == "http" && port == "80") || (lowerCaseScheme == "https" && port == "443") { + return true + } + + return false +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request_1_7.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request_1_7.go new file mode 100644 index 0000000..5921b8f --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request_1_7.go @@ -0,0 +1,40 @@ +//go:build !go1.8 +// +build !go1.8 + +package request + +import "io" + +// NoBody is an io.ReadCloser with no bytes. Read always returns EOF +// and Close always returns nil. It can be used in an outgoing client +// request to explicitly signal that a request has zero bytes. +// An alternative, however, is to simply set Request.Body to nil. +// +// Copy of Go 1.8 NoBody type from net/http/http.go +type noBody struct{} + +func (noBody) Read([]byte) (int, error) { return 0, io.EOF } +func (noBody) Close() error { return nil } +func (noBody) WriteTo(io.Writer) (int64, error) { return 0, nil } + +// NoBody is an empty reader that will trigger the Go HTTP client to not include +// and body in the HTTP request. +var NoBody = noBody{} + +// ResetBody rewinds the request body back to its starting position, and +// sets the HTTP Request body reference. When the body is read prior +// to being sent in the HTTP request it will need to be rewound. +// +// ResetBody will automatically be called by the SDK's build handler, but if +// the request is being used directly ResetBody must be called before the request +// is Sent. SetStringBody, SetBufferBody, and SetReaderBody will automatically +// call ResetBody. +func (r *Request) ResetBody() { + body, err := r.getNextRequestBody() + if err != nil { + r.Error = err + return + } + + r.HTTPRequest.Body = body +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request_1_8.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request_1_8.go new file mode 100644 index 0000000..ea643c9 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request_1_8.go @@ -0,0 +1,37 @@ +//go:build go1.8 +// +build go1.8 + +package request + +import ( + "net/http" + + "github.com/aws/aws-sdk-go/aws/awserr" +) + +// NoBody is a http.NoBody reader instructing Go HTTP client to not include +// and body in the HTTP request. +var NoBody = http.NoBody + +// ResetBody rewinds the request body back to its starting position, and +// sets the HTTP Request body reference. When the body is read prior +// to being sent in the HTTP request it will need to be rewound. +// +// ResetBody will automatically be called by the SDK's build handler, but if +// the request is being used directly ResetBody must be called before the request +// is Sent. SetStringBody, SetBufferBody, and SetReaderBody will automatically +// call ResetBody. +// +// Will also set the Go 1.8's http.Request.GetBody member to allow retrying +// PUT/POST redirects. +func (r *Request) ResetBody() { + body, err := r.getNextRequestBody() + if err != nil { + r.Error = awserr.New(ErrCodeSerialization, + "failed to reset request body", err) + return + } + + r.HTTPRequest.Body = body + r.HTTPRequest.GetBody = r.getNextRequestBody +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request_context.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request_context.go new file mode 100644 index 0000000..d8c5053 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request_context.go @@ -0,0 +1,15 @@ +//go:build go1.7 +// +build go1.7 + +package request + +import "github.com/aws/aws-sdk-go/aws" + +// setContext updates the Request to use the passed in context for cancellation. +// Context will also be used for request retry delay. +// +// Creates shallow copy of the http.Request with the WithContext method. +func setRequestContext(r *Request, ctx aws.Context) { + r.context = ctx + r.HTTPRequest = r.HTTPRequest.WithContext(ctx) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request_context_1_6.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request_context_1_6.go new file mode 100644 index 0000000..49a243e --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request_context_1_6.go @@ -0,0 +1,15 @@ +//go:build !go1.7 +// +build !go1.7 + +package request + +import "github.com/aws/aws-sdk-go/aws" + +// setContext updates the Request to use the passed in context for cancellation. +// Context will also be used for request retry delay. +// +// Creates shallow copy of the http.Request with the WithContext method. +func setRequestContext(r *Request, ctx aws.Context) { + r.context = ctx + r.HTTPRequest.Cancel = ctx.Done() +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go new file mode 100644 index 0000000..64784e1 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go @@ -0,0 +1,266 @@ +package request + +import ( + "reflect" + "sync/atomic" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awsutil" +) + +// A Pagination provides paginating of SDK API operations which are paginatable. +// Generally you should not use this type directly, but use the "Pages" API +// operations method to automatically perform pagination for you. Such as, +// "S3.ListObjectsPages", and "S3.ListObjectsPagesWithContext" methods. +// +// Pagination differs from a Paginator type in that pagination is the type that +// does the pagination between API operations, and Paginator defines the +// configuration that will be used per page request. +// +// for p.Next() { +// data := p.Page().(*s3.ListObjectsOutput) +// // process the page's data +// // ... +// // break out of loop to stop fetching additional pages +// } +// +// return p.Err() +// +// See service client API operation Pages methods for examples how the SDK will +// use the Pagination type. +type Pagination struct { + // Function to return a Request value for each pagination request. + // Any configuration or handlers that need to be applied to the request + // prior to getting the next page should be done here before the request + // returned. + // + // NewRequest should always be built from the same API operations. It is + // undefined if different API operations are returned on subsequent calls. + NewRequest func() (*Request, error) + // EndPageOnSameToken, when enabled, will allow the paginator to stop on + // token that are the same as its previous tokens. + EndPageOnSameToken bool + + started bool + prevTokens []interface{} + nextTokens []interface{} + + err error + curPage interface{} +} + +// HasNextPage will return true if Pagination is able to determine that the API +// operation has additional pages. False will be returned if there are no more +// pages remaining. +// +// Will always return true if Next has not been called yet. +func (p *Pagination) HasNextPage() bool { + if !p.started { + return true + } + + hasNextPage := len(p.nextTokens) != 0 + if p.EndPageOnSameToken { + return hasNextPage && !awsutil.DeepEqual(p.nextTokens, p.prevTokens) + } + return hasNextPage +} + +// Err returns the error Pagination encountered when retrieving the next page. +func (p *Pagination) Err() error { + return p.err +} + +// Page returns the current page. Page should only be called after a successful +// call to Next. It is undefined what Page will return if Page is called after +// Next returns false. +func (p *Pagination) Page() interface{} { + return p.curPage +} + +// Next will attempt to retrieve the next page for the API operation. When a page +// is retrieved true will be returned. If the page cannot be retrieved, or there +// are no more pages false will be returned. +// +// Use the Page method to retrieve the current page data. The data will need +// to be cast to the API operation's output type. +// +// Use the Err method to determine if an error occurred if Page returns false. +func (p *Pagination) Next() bool { + if !p.HasNextPage() { + return false + } + + req, err := p.NewRequest() + if err != nil { + p.err = err + return false + } + + if p.started { + for i, intok := range req.Operation.InputTokens { + awsutil.SetValueAtPath(req.Params, intok, p.nextTokens[i]) + } + } + p.started = true + + err = req.Send() + if err != nil { + p.err = err + return false + } + + p.prevTokens = p.nextTokens + p.nextTokens = req.nextPageTokens() + p.curPage = req.Data + + return true +} + +// A Paginator is the configuration data that defines how an API operation +// should be paginated. This type is used by the API service models to define +// the generated pagination config for service APIs. +// +// The Pagination type is what provides iterating between pages of an API. It +// is only used to store the token metadata the SDK should use for performing +// pagination. +type Paginator struct { + InputTokens []string + OutputTokens []string + LimitToken string + TruncationToken string +} + +// nextPageTokens returns the tokens to use when asking for the next page of data. +func (r *Request) nextPageTokens() []interface{} { + if r.Operation.Paginator == nil { + return nil + } + if r.Operation.TruncationToken != "" { + tr, _ := awsutil.ValuesAtPath(r.Data, r.Operation.TruncationToken) + if len(tr) == 0 { + return nil + } + + switch v := tr[0].(type) { + case *bool: + if !aws.BoolValue(v) { + return nil + } + case bool: + if !v { + return nil + } + } + } + + tokens := []interface{}{} + tokenAdded := false + for _, outToken := range r.Operation.OutputTokens { + vs, _ := awsutil.ValuesAtPath(r.Data, outToken) + if len(vs) == 0 { + tokens = append(tokens, nil) + continue + } + v := vs[0] + + switch tv := v.(type) { + case *string: + if len(aws.StringValue(tv)) == 0 { + tokens = append(tokens, nil) + continue + } + case string: + if len(tv) == 0 { + tokens = append(tokens, nil) + continue + } + } + + tokenAdded = true + tokens = append(tokens, v) + } + if !tokenAdded { + return nil + } + + return tokens +} + +// Ensure a deprecated item is only logged once instead of each time its used. +func logDeprecatedf(logger aws.Logger, flag *int32, msg string) { + if logger == nil { + return + } + if atomic.CompareAndSwapInt32(flag, 0, 1) { + logger.Log(msg) + } +} + +var ( + logDeprecatedHasNextPage int32 + logDeprecatedNextPage int32 + logDeprecatedEachPage int32 +) + +// HasNextPage returns true if this request has more pages of data available. +// +// Deprecated Use Pagination type for configurable pagination of API operations +func (r *Request) HasNextPage() bool { + logDeprecatedf(r.Config.Logger, &logDeprecatedHasNextPage, + "Request.HasNextPage deprecated. Use Pagination type for configurable pagination of API operations") + + return len(r.nextPageTokens()) > 0 +} + +// NextPage returns a new Request that can be executed to return the next +// page of result data. Call .Send() on this request to execute it. +// +// Deprecated Use Pagination type for configurable pagination of API operations +func (r *Request) NextPage() *Request { + logDeprecatedf(r.Config.Logger, &logDeprecatedNextPage, + "Request.NextPage deprecated. Use Pagination type for configurable pagination of API operations") + + tokens := r.nextPageTokens() + if len(tokens) == 0 { + return nil + } + + data := reflect.New(reflect.TypeOf(r.Data).Elem()).Interface() + nr := New(r.Config, r.ClientInfo, r.Handlers, r.Retryer, r.Operation, awsutil.CopyOf(r.Params), data) + for i, intok := range nr.Operation.InputTokens { + awsutil.SetValueAtPath(nr.Params, intok, tokens[i]) + } + return nr +} + +// EachPage iterates over each page of a paginated request object. The fn +// parameter should be a function with the following sample signature: +// +// func(page *T, lastPage bool) bool { +// return true // return false to stop iterating +// } +// +// Where "T" is the structure type matching the output structure of the given +// operation. For example, a request object generated by +// DynamoDB.ListTablesRequest() would expect to see dynamodb.ListTablesOutput +// as the structure "T". The lastPage value represents whether the page is +// the last page of data or not. The return value of this function should +// return true to keep iterating or false to stop. +// +// Deprecated Use Pagination type for configurable pagination of API operations +func (r *Request) EachPage(fn func(data interface{}, isLastPage bool) (shouldContinue bool)) error { + logDeprecatedf(r.Config.Logger, &logDeprecatedEachPage, + "Request.EachPage deprecated. Use Pagination type for configurable pagination of API operations") + + for page := r; page != nil; page = page.NextPage() { + if err := page.Send(); err != nil { + return err + } + if getNextPage := fn(page.Data, !page.HasNextPage()); !getNextPage { + return page.Error + } + } + + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go b/vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go new file mode 100644 index 0000000..752ae47 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go @@ -0,0 +1,309 @@ +package request + +import ( + "net" + "net/url" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" +) + +// Retryer provides the interface drive the SDK's request retry behavior. The +// Retryer implementation is responsible for implementing exponential backoff, +// and determine if a request API error should be retried. +// +// client.DefaultRetryer is the SDK's default implementation of the Retryer. It +// uses the which uses the Request.IsErrorRetryable and Request.IsErrorThrottle +// methods to determine if the request is retried. +type Retryer interface { + // RetryRules return the retry delay that should be used by the SDK before + // making another request attempt for the failed request. + RetryRules(*Request) time.Duration + + // ShouldRetry returns if the failed request is retryable. + // + // Implementations may consider request attempt count when determining if a + // request is retryable, but the SDK will use MaxRetries to limit the + // number of attempts a request are made. + ShouldRetry(*Request) bool + + // MaxRetries is the number of times a request may be retried before + // failing. + MaxRetries() int +} + +// WithRetryer sets a Retryer value to the given Config returning the Config +// value for chaining. The value must not be nil. +func WithRetryer(cfg *aws.Config, retryer Retryer) *aws.Config { + if retryer == nil { + if cfg.Logger != nil { + cfg.Logger.Log("ERROR: Request.WithRetryer called with nil retryer. Replacing with retry disabled Retryer.") + } + retryer = noOpRetryer{} + } + cfg.Retryer = retryer + return cfg + +} + +// noOpRetryer is a internal no op retryer used when a request is created +// without a retryer. +// +// Provides a retryer that performs no retries. +// It should be used when we do not want retries to be performed. +type noOpRetryer struct{} + +// MaxRetries returns the number of maximum returns the service will use to make +// an individual API; For NoOpRetryer the MaxRetries will always be zero. +func (d noOpRetryer) MaxRetries() int { + return 0 +} + +// ShouldRetry will always return false for NoOpRetryer, as it should never retry. +func (d noOpRetryer) ShouldRetry(_ *Request) bool { + return false +} + +// RetryRules returns the delay duration before retrying this request again; +// since NoOpRetryer does not retry, RetryRules always returns 0. +func (d noOpRetryer) RetryRules(_ *Request) time.Duration { + return 0 +} + +// retryableCodes is a collection of service response codes which are retry-able +// without any further action. +var retryableCodes = map[string]struct{}{ + ErrCodeRequestError: {}, + "RequestTimeout": {}, + ErrCodeResponseTimeout: {}, + "RequestTimeoutException": {}, // Glacier's flavor of RequestTimeout +} + +var throttleCodes = map[string]struct{}{ + "ProvisionedThroughputExceededException": {}, + "ThrottledException": {}, // SNS, XRay, ResourceGroupsTagging API + "Throttling": {}, + "ThrottlingException": {}, + "RequestLimitExceeded": {}, + "RequestThrottled": {}, + "RequestThrottledException": {}, + "TooManyRequestsException": {}, // Lambda functions + "PriorRequestNotComplete": {}, // Route53 + "TransactionInProgressException": {}, + "EC2ThrottledException": {}, // EC2 +} + +// credsExpiredCodes is a collection of error codes which signify the credentials +// need to be refreshed. Expired tokens require refreshing of credentials, and +// resigning before the request can be retried. +var credsExpiredCodes = map[string]struct{}{ + "ExpiredToken": {}, + "ExpiredTokenException": {}, + "RequestExpired": {}, // EC2 Only +} + +func isCodeThrottle(code string) bool { + _, ok := throttleCodes[code] + return ok +} + +func isCodeRetryable(code string) bool { + if _, ok := retryableCodes[code]; ok { + return true + } + + return isCodeExpiredCreds(code) +} + +func isCodeExpiredCreds(code string) bool { + _, ok := credsExpiredCodes[code] + return ok +} + +var validParentCodes = map[string]struct{}{ + ErrCodeSerialization: {}, + ErrCodeRead: {}, +} + +func isNestedErrorRetryable(parentErr awserr.Error) bool { + if parentErr == nil { + return false + } + + if _, ok := validParentCodes[parentErr.Code()]; !ok { + return false + } + + err := parentErr.OrigErr() + if err == nil { + return false + } + + if aerr, ok := err.(awserr.Error); ok { + return isCodeRetryable(aerr.Code()) + } + + if t, ok := err.(temporary); ok { + return t.Temporary() || isErrConnectionReset(err) + } + + return isErrConnectionReset(err) +} + +// IsErrorRetryable returns whether the error is retryable, based on its Code. +// Returns false if error is nil. +func IsErrorRetryable(err error) bool { + if err == nil { + return false + } + return shouldRetryError(err) +} + +type temporary interface { + Temporary() bool +} + +func shouldRetryError(origErr error) bool { + switch err := origErr.(type) { + case awserr.Error: + if err.Code() == CanceledErrorCode { + return false + } + if isNestedErrorRetryable(err) { + return true + } + + origErr := err.OrigErr() + var shouldRetry bool + if origErr != nil { + shouldRetry = shouldRetryError(origErr) + if err.Code() == ErrCodeRequestError && !shouldRetry { + return false + } + } + if isCodeRetryable(err.Code()) { + return true + } + return shouldRetry + + case *url.Error: + if strings.Contains(err.Error(), "connection refused") { + // Refused connections should be retried as the service may not yet + // be running on the port. Go TCP dial considers refused + // connections as not temporary. + return true + } + // *url.Error only implements Temporary after golang 1.6 but since + // url.Error only wraps the error: + return shouldRetryError(err.Err) + + case temporary: + if netErr, ok := err.(*net.OpError); ok && netErr.Op == "dial" { + return true + } + // If the error is temporary, we want to allow continuation of the + // retry process + return err.Temporary() || isErrConnectionReset(origErr) + + case nil: + // `awserr.Error.OrigErr()` can be nil, meaning there was an error but + // because we don't know the cause, it is marked as retryable. See + // TestRequest4xxUnretryable for an example. + return true + + default: + switch err.Error() { + case "net/http: request canceled", + "net/http: request canceled while waiting for connection": + // known 1.5 error case when an http request is cancelled + return false + } + // here we don't know the error; so we allow a retry. + return true + } +} + +// IsErrorThrottle returns whether the error is to be throttled based on its code. +// Returns false if error is nil. +func IsErrorThrottle(err error) bool { + if aerr, ok := err.(awserr.Error); ok && aerr != nil { + return isCodeThrottle(aerr.Code()) + } + return false +} + +// IsErrorExpiredCreds returns whether the error code is a credential expiry +// error. Returns false if error is nil. +func IsErrorExpiredCreds(err error) bool { + if aerr, ok := err.(awserr.Error); ok && aerr != nil { + return isCodeExpiredCreds(aerr.Code()) + } + return false +} + +// IsErrorRetryable returns whether the error is retryable, based on its Code. +// Returns false if the request has no Error set. +// +// Alias for the utility function IsErrorRetryable +func (r *Request) IsErrorRetryable() bool { + if isErrCode(r.Error, r.RetryErrorCodes) { + return true + } + + // HTTP response status code 501 should not be retried. + // 501 represents Not Implemented which means the request method is not + // supported by the server and cannot be handled. + if r.HTTPResponse != nil { + // HTTP response status code 500 represents internal server error and + // should be retried without any throttle. + if r.HTTPResponse.StatusCode == 500 { + return true + } + } + return IsErrorRetryable(r.Error) +} + +// IsErrorThrottle returns whether the error is to be throttled based on its +// code. Returns false if the request has no Error set. +// +// Alias for the utility function IsErrorThrottle +func (r *Request) IsErrorThrottle() bool { + if isErrCode(r.Error, r.ThrottleErrorCodes) { + return true + } + + if r.HTTPResponse != nil { + switch r.HTTPResponse.StatusCode { + case + 429, // error caused due to too many requests + 502, // Bad Gateway error should be throttled + 503, // caused when service is unavailable + 504: // error occurred due to gateway timeout + return true + } + } + + return IsErrorThrottle(r.Error) +} + +func isErrCode(err error, codes []string) bool { + if aerr, ok := err.(awserr.Error); ok && aerr != nil { + for _, code := range codes { + if code == aerr.Code() { + return true + } + } + } + + return false +} + +// IsErrorExpired returns whether the error code is a credential expiry error. +// Returns false if the request has no Error set. +// +// Alias for the utility function IsErrorExpiredCreds +func (r *Request) IsErrorExpired() bool { + return IsErrorExpiredCreds(r.Error) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/timeout_read_closer.go b/vendor/github.com/aws/aws-sdk-go/aws/request/timeout_read_closer.go new file mode 100644 index 0000000..09a44eb --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/timeout_read_closer.go @@ -0,0 +1,94 @@ +package request + +import ( + "io" + "time" + + "github.com/aws/aws-sdk-go/aws/awserr" +) + +var timeoutErr = awserr.New( + ErrCodeResponseTimeout, + "read on body has reached the timeout limit", + nil, +) + +type readResult struct { + n int + err error +} + +// timeoutReadCloser will handle body reads that take too long. +// We will return a ErrReadTimeout error if a timeout occurs. +type timeoutReadCloser struct { + reader io.ReadCloser + duration time.Duration +} + +// Read will spin off a goroutine to call the reader's Read method. We will +// select on the timer's channel or the read's channel. Whoever completes first +// will be returned. +func (r *timeoutReadCloser) Read(b []byte) (int, error) { + timer := time.NewTimer(r.duration) + c := make(chan readResult, 1) + + go func() { + n, err := r.reader.Read(b) + timer.Stop() + c <- readResult{n: n, err: err} + }() + + select { + case data := <-c: + return data.n, data.err + case <-timer.C: + return 0, timeoutErr + } +} + +func (r *timeoutReadCloser) Close() error { + return r.reader.Close() +} + +const ( + // HandlerResponseTimeout is what we use to signify the name of the + // response timeout handler. + HandlerResponseTimeout = "ResponseTimeoutHandler" +) + +// adaptToResponseTimeoutError is a handler that will replace any top level error +// to a ErrCodeResponseTimeout, if its child is that. +func adaptToResponseTimeoutError(req *Request) { + if err, ok := req.Error.(awserr.Error); ok { + aerr, ok := err.OrigErr().(awserr.Error) + if ok && aerr.Code() == ErrCodeResponseTimeout { + req.Error = aerr + } + } +} + +// WithResponseReadTimeout is a request option that will wrap the body in a timeout read closer. +// This will allow for per read timeouts. If a timeout occurred, we will return the +// ErrCodeResponseTimeout. +// +// svc.PutObjectWithContext(ctx, params, request.WithTimeoutReadCloser(30 * time.Second) +func WithResponseReadTimeout(duration time.Duration) Option { + return func(r *Request) { + + var timeoutHandler = NamedHandler{ + HandlerResponseTimeout, + func(req *Request) { + req.HTTPResponse.Body = &timeoutReadCloser{ + reader: req.HTTPResponse.Body, + duration: duration, + } + }} + + // remove the handler so we are not stomping over any new durations. + r.Handlers.Send.RemoveByName(HandlerResponseTimeout) + r.Handlers.Send.PushBackNamed(timeoutHandler) + + r.Handlers.Unmarshal.PushBack(adaptToResponseTimeoutError) + r.Handlers.UnmarshalError.PushBack(adaptToResponseTimeoutError) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/validation.go b/vendor/github.com/aws/aws-sdk-go/aws/request/validation.go new file mode 100644 index 0000000..8630683 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/validation.go @@ -0,0 +1,286 @@ +package request + +import ( + "bytes" + "fmt" + + "github.com/aws/aws-sdk-go/aws/awserr" +) + +const ( + // InvalidParameterErrCode is the error code for invalid parameters errors + InvalidParameterErrCode = "InvalidParameter" + // ParamRequiredErrCode is the error code for required parameter errors + ParamRequiredErrCode = "ParamRequiredError" + // ParamMinValueErrCode is the error code for fields with too low of a + // number value. + ParamMinValueErrCode = "ParamMinValueError" + // ParamMinLenErrCode is the error code for fields without enough elements. + ParamMinLenErrCode = "ParamMinLenError" + // ParamMaxLenErrCode is the error code for value being too long. + ParamMaxLenErrCode = "ParamMaxLenError" + + // ParamFormatErrCode is the error code for a field with invalid + // format or characters. + ParamFormatErrCode = "ParamFormatInvalidError" +) + +// Validator provides a way for types to perform validation logic on their +// input values that external code can use to determine if a type's values +// are valid. +type Validator interface { + Validate() error +} + +// An ErrInvalidParams provides wrapping of invalid parameter errors found when +// validating API operation input parameters. +type ErrInvalidParams struct { + // Context is the base context of the invalid parameter group. + Context string + errs []ErrInvalidParam +} + +// Add adds a new invalid parameter error to the collection of invalid +// parameters. The context of the invalid parameter will be updated to reflect +// this collection. +func (e *ErrInvalidParams) Add(err ErrInvalidParam) { + err.SetContext(e.Context) + e.errs = append(e.errs, err) +} + +// AddNested adds the invalid parameter errors from another ErrInvalidParams +// value into this collection. The nested errors will have their nested context +// updated and base context to reflect the merging. +// +// Use for nested validations errors. +func (e *ErrInvalidParams) AddNested(nestedCtx string, nested ErrInvalidParams) { + for _, err := range nested.errs { + err.SetContext(e.Context) + err.AddNestedContext(nestedCtx) + e.errs = append(e.errs, err) + } +} + +// Len returns the number of invalid parameter errors +func (e ErrInvalidParams) Len() int { + return len(e.errs) +} + +// Code returns the code of the error +func (e ErrInvalidParams) Code() string { + return InvalidParameterErrCode +} + +// Message returns the message of the error +func (e ErrInvalidParams) Message() string { + return fmt.Sprintf("%d validation error(s) found.", len(e.errs)) +} + +// Error returns the string formatted form of the invalid parameters. +func (e ErrInvalidParams) Error() string { + w := &bytes.Buffer{} + fmt.Fprintf(w, "%s: %s\n", e.Code(), e.Message()) + + for _, err := range e.errs { + fmt.Fprintf(w, "- %s\n", err.Message()) + } + + return w.String() +} + +// OrigErr returns the invalid parameters as a awserr.BatchedErrors value +func (e ErrInvalidParams) OrigErr() error { + return awserr.NewBatchError( + InvalidParameterErrCode, e.Message(), e.OrigErrs()) +} + +// OrigErrs returns a slice of the invalid parameters +func (e ErrInvalidParams) OrigErrs() []error { + errs := make([]error, len(e.errs)) + for i := 0; i < len(errs); i++ { + errs[i] = e.errs[i] + } + + return errs +} + +// An ErrInvalidParam represents an invalid parameter error type. +type ErrInvalidParam interface { + awserr.Error + + // Field name the error occurred on. + Field() string + + // SetContext updates the context of the error. + SetContext(string) + + // AddNestedContext updates the error's context to include a nested level. + AddNestedContext(string) +} + +type errInvalidParam struct { + context string + nestedContext string + field string + code string + msg string +} + +// Code returns the error code for the type of invalid parameter. +func (e *errInvalidParam) Code() string { + return e.code +} + +// Message returns the reason the parameter was invalid, and its context. +func (e *errInvalidParam) Message() string { + return fmt.Sprintf("%s, %s.", e.msg, e.Field()) +} + +// Error returns the string version of the invalid parameter error. +func (e *errInvalidParam) Error() string { + return fmt.Sprintf("%s: %s", e.code, e.Message()) +} + +// OrigErr returns nil, Implemented for awserr.Error interface. +func (e *errInvalidParam) OrigErr() error { + return nil +} + +// Field Returns the field and context the error occurred. +func (e *errInvalidParam) Field() string { + field := e.context + if len(field) > 0 { + field += "." + } + if len(e.nestedContext) > 0 { + field += fmt.Sprintf("%s.", e.nestedContext) + } + field += e.field + + return field +} + +// SetContext updates the base context of the error. +func (e *errInvalidParam) SetContext(ctx string) { + e.context = ctx +} + +// AddNestedContext prepends a context to the field's path. +func (e *errInvalidParam) AddNestedContext(ctx string) { + if len(e.nestedContext) == 0 { + e.nestedContext = ctx + } else { + e.nestedContext = fmt.Sprintf("%s.%s", ctx, e.nestedContext) + } + +} + +// An ErrParamRequired represents an required parameter error. +type ErrParamRequired struct { + errInvalidParam +} + +// NewErrParamRequired creates a new required parameter error. +func NewErrParamRequired(field string) *ErrParamRequired { + return &ErrParamRequired{ + errInvalidParam{ + code: ParamRequiredErrCode, + field: field, + msg: fmt.Sprintf("missing required field"), + }, + } +} + +// An ErrParamMinValue represents a minimum value parameter error. +type ErrParamMinValue struct { + errInvalidParam + min float64 +} + +// NewErrParamMinValue creates a new minimum value parameter error. +func NewErrParamMinValue(field string, min float64) *ErrParamMinValue { + return &ErrParamMinValue{ + errInvalidParam: errInvalidParam{ + code: ParamMinValueErrCode, + field: field, + msg: fmt.Sprintf("minimum field value of %v", min), + }, + min: min, + } +} + +// MinValue returns the field's require minimum value. +// +// float64 is returned for both int and float min values. +func (e *ErrParamMinValue) MinValue() float64 { + return e.min +} + +// An ErrParamMinLen represents a minimum length parameter error. +type ErrParamMinLen struct { + errInvalidParam + min int +} + +// NewErrParamMinLen creates a new minimum length parameter error. +func NewErrParamMinLen(field string, min int) *ErrParamMinLen { + return &ErrParamMinLen{ + errInvalidParam: errInvalidParam{ + code: ParamMinLenErrCode, + field: field, + msg: fmt.Sprintf("minimum field size of %v", min), + }, + min: min, + } +} + +// MinLen returns the field's required minimum length. +func (e *ErrParamMinLen) MinLen() int { + return e.min +} + +// An ErrParamMaxLen represents a maximum length parameter error. +type ErrParamMaxLen struct { + errInvalidParam + max int +} + +// NewErrParamMaxLen creates a new maximum length parameter error. +func NewErrParamMaxLen(field string, max int, value string) *ErrParamMaxLen { + return &ErrParamMaxLen{ + errInvalidParam: errInvalidParam{ + code: ParamMaxLenErrCode, + field: field, + msg: fmt.Sprintf("maximum size of %v, %v", max, value), + }, + max: max, + } +} + +// MaxLen returns the field's required minimum length. +func (e *ErrParamMaxLen) MaxLen() int { + return e.max +} + +// An ErrParamFormat represents a invalid format parameter error. +type ErrParamFormat struct { + errInvalidParam + format string +} + +// NewErrParamFormat creates a new invalid format parameter error. +func NewErrParamFormat(field string, format, value string) *ErrParamFormat { + return &ErrParamFormat{ + errInvalidParam: errInvalidParam{ + code: ParamFormatErrCode, + field: field, + msg: fmt.Sprintf("format %v, %v", format, value), + }, + format: format, + } +} + +// Format returns the field's required format. +func (e *ErrParamFormat) Format() string { + return e.format +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/waiter.go b/vendor/github.com/aws/aws-sdk-go/aws/request/waiter.go new file mode 100644 index 0000000..4601f88 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/waiter.go @@ -0,0 +1,295 @@ +package request + +import ( + "fmt" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/awsutil" +) + +// WaiterResourceNotReadyErrorCode is the error code returned by a waiter when +// the waiter's max attempts have been exhausted. +const WaiterResourceNotReadyErrorCode = "ResourceNotReady" + +// A WaiterOption is a function that will update the Waiter value's fields to +// configure the waiter. +type WaiterOption func(*Waiter) + +// WithWaiterMaxAttempts returns the maximum number of times the waiter should +// attempt to check the resource for the target state. +func WithWaiterMaxAttempts(max int) WaiterOption { + return func(w *Waiter) { + w.MaxAttempts = max + } +} + +// WaiterDelay will return a delay the waiter should pause between attempts to +// check the resource state. The passed in attempt is the number of times the +// Waiter has checked the resource state. +// +// Attempt is the number of attempts the Waiter has made checking the resource +// state. +type WaiterDelay func(attempt int) time.Duration + +// ConstantWaiterDelay returns a WaiterDelay that will always return a constant +// delay the waiter should use between attempts. It ignores the number of +// attempts made. +func ConstantWaiterDelay(delay time.Duration) WaiterDelay { + return func(attempt int) time.Duration { + return delay + } +} + +// WithWaiterDelay will set the Waiter to use the WaiterDelay passed in. +func WithWaiterDelay(delayer WaiterDelay) WaiterOption { + return func(w *Waiter) { + w.Delay = delayer + } +} + +// WithWaiterLogger returns a waiter option to set the logger a waiter +// should use to log warnings and errors to. +func WithWaiterLogger(logger aws.Logger) WaiterOption { + return func(w *Waiter) { + w.Logger = logger + } +} + +// WithWaiterRequestOptions returns a waiter option setting the request +// options for each request the waiter makes. Appends to waiter's request +// options already set. +func WithWaiterRequestOptions(opts ...Option) WaiterOption { + return func(w *Waiter) { + w.RequestOptions = append(w.RequestOptions, opts...) + } +} + +// A Waiter provides the functionality to perform a blocking call which will +// wait for a resource state to be satisfied by a service. +// +// This type should not be used directly. The API operations provided in the +// service packages prefixed with "WaitUntil" should be used instead. +type Waiter struct { + Name string + Acceptors []WaiterAcceptor + Logger aws.Logger + + MaxAttempts int + Delay WaiterDelay + + RequestOptions []Option + NewRequest func([]Option) (*Request, error) + SleepWithContext func(aws.Context, time.Duration) error +} + +// ApplyOptions updates the waiter with the list of waiter options provided. +func (w *Waiter) ApplyOptions(opts ...WaiterOption) { + for _, fn := range opts { + fn(w) + } +} + +// WaiterState are states the waiter uses based on WaiterAcceptor definitions +// to identify if the resource state the waiter is waiting on has occurred. +type WaiterState int + +// String returns the string representation of the waiter state. +func (s WaiterState) String() string { + switch s { + case SuccessWaiterState: + return "success" + case FailureWaiterState: + return "failure" + case RetryWaiterState: + return "retry" + default: + return "unknown waiter state" + } +} + +// States the waiter acceptors will use to identify target resource states. +const ( + SuccessWaiterState WaiterState = iota // waiter successful + FailureWaiterState // waiter failed + RetryWaiterState // waiter needs to be retried +) + +// WaiterMatchMode is the mode that the waiter will use to match the WaiterAcceptor +// definition's Expected attribute. +type WaiterMatchMode int + +// Modes the waiter will use when inspecting API response to identify target +// resource states. +const ( + PathAllWaiterMatch WaiterMatchMode = iota // match on all paths + PathWaiterMatch // match on specific path + PathAnyWaiterMatch // match on any path + PathListWaiterMatch // match on list of paths + StatusWaiterMatch // match on status code + ErrorWaiterMatch // match on error +) + +// String returns the string representation of the waiter match mode. +func (m WaiterMatchMode) String() string { + switch m { + case PathAllWaiterMatch: + return "pathAll" + case PathWaiterMatch: + return "path" + case PathAnyWaiterMatch: + return "pathAny" + case PathListWaiterMatch: + return "pathList" + case StatusWaiterMatch: + return "status" + case ErrorWaiterMatch: + return "error" + default: + return "unknown waiter match mode" + } +} + +// WaitWithContext will make requests for the API operation using NewRequest to +// build API requests. The request's response will be compared against the +// Waiter's Acceptors to determine the successful state of the resource the +// waiter is inspecting. +// +// The passed in context must not be nil. If it is nil a panic will occur. The +// Context will be used to cancel the waiter's pending requests and retry delays. +// Use aws.BackgroundContext if no context is available. +// +// The waiter will continue until the target state defined by the Acceptors, +// or the max attempts expires. +// +// Will return the WaiterResourceNotReadyErrorCode error code if the waiter's +// retryer ShouldRetry returns false. This normally will happen when the max +// wait attempts expires. +func (w Waiter) WaitWithContext(ctx aws.Context) error { + + for attempt := 1; ; attempt++ { + req, err := w.NewRequest(w.RequestOptions) + if err != nil { + waiterLogf(w.Logger, "unable to create request %v", err) + return err + } + req.Handlers.Build.PushBack(MakeAddToUserAgentFreeFormHandler("Waiter")) + err = req.Send() + + // See if any of the acceptors match the request's response, or error + for _, a := range w.Acceptors { + if matched, matchErr := a.match(w.Name, w.Logger, req, err); matched { + return matchErr + } + } + + // The Waiter should only check the resource state MaxAttempts times + // This is here instead of in the for loop above to prevent delaying + // unnecessary when the waiter will not retry. + if attempt == w.MaxAttempts { + break + } + + // Delay to wait before inspecting the resource again + delay := w.Delay(attempt) + if sleepFn := req.Config.SleepDelay; sleepFn != nil { + // Support SleepDelay for backwards compatibility and testing + sleepFn(delay) + } else { + sleepCtxFn := w.SleepWithContext + if sleepCtxFn == nil { + sleepCtxFn = aws.SleepWithContext + } + + if err := sleepCtxFn(ctx, delay); err != nil { + return awserr.New(CanceledErrorCode, "waiter context canceled", err) + } + } + } + + return awserr.New(WaiterResourceNotReadyErrorCode, "exceeded wait attempts", nil) +} + +// A WaiterAcceptor provides the information needed to wait for an API operation +// to complete. +type WaiterAcceptor struct { + State WaiterState + Matcher WaiterMatchMode + Argument string + Expected interface{} +} + +// match returns if the acceptor found a match with the passed in request +// or error. True is returned if the acceptor made a match, error is returned +// if there was an error attempting to perform the match. +func (a *WaiterAcceptor) match(name string, l aws.Logger, req *Request, err error) (bool, error) { + result := false + var vals []interface{} + + switch a.Matcher { + case PathAllWaiterMatch, PathWaiterMatch: + // Require all matches to be equal for result to match + vals, _ = awsutil.ValuesAtPath(req.Data, a.Argument) + if len(vals) == 0 { + break + } + result = true + for _, val := range vals { + if !awsutil.DeepEqual(val, a.Expected) { + result = false + break + } + } + case PathAnyWaiterMatch: + // Only a single match needs to equal for the result to match + vals, _ = awsutil.ValuesAtPath(req.Data, a.Argument) + for _, val := range vals { + if awsutil.DeepEqual(val, a.Expected) { + result = true + break + } + } + case PathListWaiterMatch: + // ignored matcher + case StatusWaiterMatch: + s := a.Expected.(int) + result = s == req.HTTPResponse.StatusCode + case ErrorWaiterMatch: + if aerr, ok := err.(awserr.Error); ok { + result = aerr.Code() == a.Expected.(string) + } + default: + waiterLogf(l, "WARNING: Waiter %s encountered unexpected matcher: %s", + name, a.Matcher) + } + + if !result { + // If there was no matching result found there is nothing more to do + // for this response, retry the request. + return false, nil + } + + switch a.State { + case SuccessWaiterState: + // waiter completed + return true, nil + case FailureWaiterState: + // Waiter failure state triggered + return true, awserr.New(WaiterResourceNotReadyErrorCode, + "failed waiting for successful resource state", err) + case RetryWaiterState: + // clear the error and retry the operation + return false, nil + default: + waiterLogf(l, "WARNING: Waiter %s encountered unexpected state: %s", + name, a.State) + return false, nil + } +} + +func waiterLogf(logger aws.Logger, msg string, args ...interface{}) { + if logger != nil { + logger.Log(fmt.Sprintf(msg, args...)) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/header_rules.go b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/header_rules.go new file mode 100644 index 0000000..9937538 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/header_rules.go @@ -0,0 +1,81 @@ +package v4 + +import ( + "github.com/aws/aws-sdk-go/internal/strings" +) + +// validator houses a set of rule needed for validation of a +// string value +type rules []rule + +// rule interface allows for more flexible rules and just simply +// checks whether or not a value adheres to that rule +type rule interface { + IsValid(value string) bool +} + +// IsValid will iterate through all rules and see if any rules +// apply to the value and supports nested rules +func (r rules) IsValid(value string) bool { + for _, rule := range r { + if rule.IsValid(value) { + return true + } + } + return false +} + +// mapRule generic rule for maps +type mapRule map[string]struct{} + +// IsValid for the map rule satisfies whether it exists in the map +func (m mapRule) IsValid(value string) bool { + _, ok := m[value] + return ok +} + +// allowList is a generic rule for allow listing +type allowList struct { + rule +} + +// IsValid for allow list checks if the value is within the allow list +func (w allowList) IsValid(value string) bool { + return w.rule.IsValid(value) +} + +// excludeList is a generic rule for exclude listing +type excludeList struct { + rule +} + +// IsValid for exclude list checks if the value is within the exclude list +func (b excludeList) IsValid(value string) bool { + return !b.rule.IsValid(value) +} + +type patterns []string + +// IsValid for patterns checks each pattern and returns if a match has +// been found +func (p patterns) IsValid(value string) bool { + for _, pattern := range p { + if strings.HasPrefixFold(value, pattern) { + return true + } + } + return false +} + +// inclusiveRules rules allow for rules to depend on one another +type inclusiveRules []rule + +// IsValid will return true if all rules are true +func (r inclusiveRules) IsValid(value string) bool { + for _, rule := range r { + if !rule.IsValid(value) { + return false + } + } + return true +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/options.go b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/options.go new file mode 100644 index 0000000..6aa2ed2 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/options.go @@ -0,0 +1,7 @@ +package v4 + +// WithUnsignedPayload will enable and set the UnsignedPayload field to +// true of the signer. +func WithUnsignedPayload(v4 *Signer) { + v4.UnsignedPayload = true +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/request_context_go1.5.go b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/request_context_go1.5.go new file mode 100644 index 0000000..cf672b6 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/request_context_go1.5.go @@ -0,0 +1,14 @@ +//go:build !go1.7 +// +build !go1.7 + +package v4 + +import ( + "net/http" + + "github.com/aws/aws-sdk-go/aws" +) + +func requestContext(r *http.Request) aws.Context { + return aws.BackgroundContext() +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/request_context_go1.7.go b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/request_context_go1.7.go new file mode 100644 index 0000000..21fe74e --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/request_context_go1.7.go @@ -0,0 +1,14 @@ +//go:build go1.7 +// +build go1.7 + +package v4 + +import ( + "net/http" + + "github.com/aws/aws-sdk-go/aws" +) + +func requestContext(r *http.Request) aws.Context { + return r.Context() +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/stream.go b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/stream.go new file mode 100644 index 0000000..02cbd97 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/stream.go @@ -0,0 +1,63 @@ +package v4 + +import ( + "encoding/hex" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws/credentials" +) + +type credentialValueProvider interface { + Get() (credentials.Value, error) +} + +// StreamSigner implements signing of event stream encoded payloads +type StreamSigner struct { + region string + service string + + credentials credentialValueProvider + + prevSig []byte +} + +// NewStreamSigner creates a SigV4 signer used to sign Event Stream encoded messages +func NewStreamSigner(region, service string, seedSignature []byte, credentials *credentials.Credentials) *StreamSigner { + return &StreamSigner{ + region: region, + service: service, + credentials: credentials, + prevSig: seedSignature, + } +} + +// GetSignature takes an event stream encoded headers and payload and returns a signature +func (s *StreamSigner) GetSignature(headers, payload []byte, date time.Time) ([]byte, error) { + credValue, err := s.credentials.Get() + if err != nil { + return nil, err + } + + sigKey := deriveSigningKey(s.region, s.service, credValue.SecretAccessKey, date) + + keyPath := buildSigningScope(s.region, s.service, date) + + stringToSign := buildEventStreamStringToSign(headers, payload, s.prevSig, keyPath, date) + + signature := hmacSHA256(sigKey, []byte(stringToSign)) + s.prevSig = signature + + return signature, nil +} + +func buildEventStreamStringToSign(headers, payload, prevSig []byte, scope string, date time.Time) string { + return strings.Join([]string{ + "AWS4-HMAC-SHA256-PAYLOAD", + formatTime(date), + scope, + hex.EncodeToString(prevSig), + hex.EncodeToString(hashSHA256(headers)), + hex.EncodeToString(hashSHA256(payload)), + }, "\n") +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/uri_path.go b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/uri_path.go new file mode 100644 index 0000000..7711ec7 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/uri_path.go @@ -0,0 +1,25 @@ +//go:build go1.5 +// +build go1.5 + +package v4 + +import ( + "net/url" + "strings" +) + +func getURIPath(u *url.URL) string { + var uri string + + if len(u.Opaque) > 0 { + uri = "/" + strings.Join(strings.Split(u.Opaque, "/")[3:], "/") + } else { + uri = u.EscapedPath() + } + + if len(uri) == 0 { + uri = "/" + } + + return uri +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go new file mode 100644 index 0000000..4d78162 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go @@ -0,0 +1,854 @@ +// Package v4 implements signing for AWS V4 signer +// +// Provides request signing for request that need to be signed with +// AWS V4 Signatures. +// +// Standalone Signer +// +// Generally using the signer outside of the SDK should not require any additional +// logic when using Go v1.5 or higher. The signer does this by taking advantage +// of the URL.EscapedPath method. If your request URI requires additional escaping +// you many need to use the URL.Opaque to define what the raw URI should be sent +// to the service as. +// +// The signer will first check the URL.Opaque field, and use its value if set. +// The signer does require the URL.Opaque field to be set in the form of: +// +// "///" +// +// // e.g. +// "//example.com/some/path" +// +// The leading "//" and hostname are required or the URL.Opaque escaping will +// not work correctly. +// +// If URL.Opaque is not set the signer will fallback to the URL.EscapedPath() +// method and using the returned value. If you're using Go v1.4 you must set +// URL.Opaque if the URI path needs escaping. If URL.Opaque is not set with +// Go v1.5 the signer will fallback to URL.Path. +// +// AWS v4 signature validation requires that the canonical string's URI path +// element must be the URI escaped form of the HTTP request's path. +// http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html +// +// The Go HTTP client will perform escaping automatically on the request. Some +// of these escaping may cause signature validation errors because the HTTP +// request differs from the URI path or query that the signature was generated. +// https://golang.org/pkg/net/url/#URL.EscapedPath +// +// Because of this, it is recommended that when using the signer outside of the +// SDK that explicitly escaping the request prior to being signed is preferable, +// and will help prevent signature validation errors. This can be done by setting +// the URL.Opaque or URL.RawPath. The SDK will use URL.Opaque first and then +// call URL.EscapedPath() if Opaque is not set. +// +// If signing a request intended for HTTP2 server, and you're using Go 1.6.2 +// through 1.7.4 you should use the URL.RawPath as the pre-escaped form of the +// request URL. https://github.com/golang/go/issues/16847 points to a bug in +// Go pre 1.8 that fails to make HTTP2 requests using absolute URL in the HTTP +// message. URL.Opaque generally will force Go to make requests with absolute URL. +// URL.RawPath does not do this, but RawPath must be a valid escaping of Path +// or url.EscapedPath will ignore the RawPath escaping. +// +// Test `TestStandaloneSign` provides a complete example of using the signer +// outside of the SDK and pre-escaping the URI path. +package v4 + +import ( + "crypto/hmac" + "crypto/sha256" + "encoding/hex" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "sort" + "strconv" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/internal/sdkio" + "github.com/aws/aws-sdk-go/private/protocol/rest" +) + +const ( + authorizationHeader = "Authorization" + authHeaderSignatureElem = "Signature=" + signatureQueryKey = "X-Amz-Signature" + + authHeaderPrefix = "AWS4-HMAC-SHA256" + timeFormat = "20060102T150405Z" + shortTimeFormat = "20060102" + awsV4Request = "aws4_request" + + // emptyStringSHA256 is a SHA256 of an empty string + emptyStringSHA256 = `e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855` +) + +var ignoredHeaders = rules{ + excludeList{ + mapRule{ + authorizationHeader: struct{}{}, + "User-Agent": struct{}{}, + "X-Amzn-Trace-Id": struct{}{}, + }, + }, +} + +// requiredSignedHeaders is a allow list for build canonical headers. +var requiredSignedHeaders = rules{ + allowList{ + mapRule{ + "Cache-Control": struct{}{}, + "Content-Disposition": struct{}{}, + "Content-Encoding": struct{}{}, + "Content-Language": struct{}{}, + "Content-Md5": struct{}{}, + "Content-Type": struct{}{}, + "Expires": struct{}{}, + "If-Match": struct{}{}, + "If-Modified-Since": struct{}{}, + "If-None-Match": struct{}{}, + "If-Unmodified-Since": struct{}{}, + "Range": struct{}{}, + "X-Amz-Acl": struct{}{}, + "X-Amz-Copy-Source": struct{}{}, + "X-Amz-Copy-Source-If-Match": struct{}{}, + "X-Amz-Copy-Source-If-Modified-Since": struct{}{}, + "X-Amz-Copy-Source-If-None-Match": struct{}{}, + "X-Amz-Copy-Source-If-Unmodified-Since": struct{}{}, + "X-Amz-Copy-Source-Range": struct{}{}, + "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Algorithm": struct{}{}, + "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key": struct{}{}, + "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key-Md5": struct{}{}, + "X-Amz-Grant-Full-control": struct{}{}, + "X-Amz-Grant-Read": struct{}{}, + "X-Amz-Grant-Read-Acp": struct{}{}, + "X-Amz-Grant-Write": struct{}{}, + "X-Amz-Grant-Write-Acp": struct{}{}, + "X-Amz-Metadata-Directive": struct{}{}, + "X-Amz-Mfa": struct{}{}, + "X-Amz-Request-Payer": struct{}{}, + "X-Amz-Server-Side-Encryption": struct{}{}, + "X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": struct{}{}, + "X-Amz-Server-Side-Encryption-Customer-Algorithm": struct{}{}, + "X-Amz-Server-Side-Encryption-Customer-Key": struct{}{}, + "X-Amz-Server-Side-Encryption-Customer-Key-Md5": struct{}{}, + "X-Amz-Storage-Class": struct{}{}, + "X-Amz-Tagging": struct{}{}, + "X-Amz-Website-Redirect-Location": struct{}{}, + "X-Amz-Content-Sha256": struct{}{}, + }, + }, + patterns{"X-Amz-Meta-"}, + patterns{"X-Amz-Object-Lock-"}, +} + +// allowedHoisting is a allow list for build query headers. The boolean value +// represents whether or not it is a pattern. +var allowedQueryHoisting = inclusiveRules{ + excludeList{requiredSignedHeaders}, + patterns{"X-Amz-"}, +} + +// Signer applies AWS v4 signing to given request. Use this to sign requests +// that need to be signed with AWS V4 Signatures. +type Signer struct { + // The authentication credentials the request will be signed against. + // This value must be set to sign requests. + Credentials *credentials.Credentials + + // Sets the log level the signer should use when reporting information to + // the logger. If the logger is nil nothing will be logged. See + // aws.LogLevelType for more information on available logging levels + // + // By default nothing will be logged. + Debug aws.LogLevelType + + // The logger loging information will be written to. If there the logger + // is nil, nothing will be logged. + Logger aws.Logger + + // Disables the Signer's moving HTTP header key/value pairs from the HTTP + // request header to the request's query string. This is most commonly used + // with pre-signed requests preventing headers from being added to the + // request's query string. + DisableHeaderHoisting bool + + // Disables the automatic escaping of the URI path of the request for the + // siganture's canonical string's path. For services that do not need additional + // escaping then use this to disable the signer escaping the path. + // + // S3 is an example of a service that does not need additional escaping. + // + // http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html + DisableURIPathEscaping bool + + // Disables the automatical setting of the HTTP request's Body field with the + // io.ReadSeeker passed in to the signer. This is useful if you're using a + // custom wrapper around the body for the io.ReadSeeker and want to preserve + // the Body value on the Request.Body. + // + // This does run the risk of signing a request with a body that will not be + // sent in the request. Need to ensure that the underlying data of the Body + // values are the same. + DisableRequestBodyOverwrite bool + + // currentTimeFn returns the time value which represents the current time. + // This value should only be used for testing. If it is nil the default + // time.Now will be used. + currentTimeFn func() time.Time + + // UnsignedPayload will prevent signing of the payload. This will only + // work for services that have support for this. + UnsignedPayload bool +} + +// NewSigner returns a Signer pointer configured with the credentials and optional +// option values provided. If not options are provided the Signer will use its +// default configuration. +func NewSigner(credentials *credentials.Credentials, options ...func(*Signer)) *Signer { + v4 := &Signer{ + Credentials: credentials, + } + + for _, option := range options { + option(v4) + } + + return v4 +} + +type signingCtx struct { + ServiceName string + Region string + Request *http.Request + Body io.ReadSeeker + Query url.Values + Time time.Time + ExpireTime time.Duration + SignedHeaderVals http.Header + + DisableURIPathEscaping bool + + credValues credentials.Value + isPresign bool + unsignedPayload bool + + bodyDigest string + signedHeaders string + canonicalHeaders string + canonicalString string + credentialString string + stringToSign string + signature string + authorization string +} + +// Sign signs AWS v4 requests with the provided body, service name, region the +// request is made to, and time the request is signed at. The signTime allows +// you to specify that a request is signed for the future, and cannot be +// used until then. +// +// Returns a list of HTTP headers that were included in the signature or an +// error if signing the request failed. Generally for signed requests this value +// is not needed as the full request context will be captured by the http.Request +// value. It is included for reference though. +// +// Sign will set the request's Body to be the `body` parameter passed in. If +// the body is not already an io.ReadCloser, it will be wrapped within one. If +// a `nil` body parameter passed to Sign, the request's Body field will be +// also set to nil. Its important to note that this functionality will not +// change the request's ContentLength of the request. +// +// Sign differs from Presign in that it will sign the request using HTTP +// header values. This type of signing is intended for http.Request values that +// will not be shared, or are shared in a way the header values on the request +// will not be lost. +// +// The requests body is an io.ReadSeeker so the SHA256 of the body can be +// generated. To bypass the signer computing the hash you can set the +// "X-Amz-Content-Sha256" header with a precomputed value. The signer will +// only compute the hash if the request header value is empty. +func (v4 Signer) Sign(r *http.Request, body io.ReadSeeker, service, region string, signTime time.Time) (http.Header, error) { + return v4.signWithBody(r, body, service, region, 0, false, signTime) +} + +// Presign signs AWS v4 requests with the provided body, service name, region +// the request is made to, and time the request is signed at. The signTime +// allows you to specify that a request is signed for the future, and cannot +// be used until then. +// +// Returns a list of HTTP headers that were included in the signature or an +// error if signing the request failed. For presigned requests these headers +// and their values must be included on the HTTP request when it is made. This +// is helpful to know what header values need to be shared with the party the +// presigned request will be distributed to. +// +// Presign differs from Sign in that it will sign the request using query string +// instead of header values. This allows you to share the Presigned Request's +// URL with third parties, or distribute it throughout your system with minimal +// dependencies. +// +// Presign also takes an exp value which is the duration the +// signed request will be valid after the signing time. This is allows you to +// set when the request will expire. +// +// The requests body is an io.ReadSeeker so the SHA256 of the body can be +// generated. To bypass the signer computing the hash you can set the +// "X-Amz-Content-Sha256" header with a precomputed value. The signer will +// only compute the hash if the request header value is empty. +// +// Presigning a S3 request will not compute the body's SHA256 hash by default. +// This is done due to the general use case for S3 presigned URLs is to share +// PUT/GET capabilities. If you would like to include the body's SHA256 in the +// presigned request's signature you can set the "X-Amz-Content-Sha256" +// HTTP header and that will be included in the request's signature. +func (v4 Signer) Presign(r *http.Request, body io.ReadSeeker, service, region string, exp time.Duration, signTime time.Time) (http.Header, error) { + return v4.signWithBody(r, body, service, region, exp, true, signTime) +} + +func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, region string, exp time.Duration, isPresign bool, signTime time.Time) (http.Header, error) { + currentTimeFn := v4.currentTimeFn + if currentTimeFn == nil { + currentTimeFn = time.Now + } + + ctx := &signingCtx{ + Request: r, + Body: body, + Query: r.URL.Query(), + Time: signTime, + ExpireTime: exp, + isPresign: isPresign, + ServiceName: service, + Region: region, + DisableURIPathEscaping: v4.DisableURIPathEscaping, + unsignedPayload: v4.UnsignedPayload, + } + + for key := range ctx.Query { + sort.Strings(ctx.Query[key]) + } + + if ctx.isRequestSigned() { + ctx.Time = currentTimeFn() + ctx.handlePresignRemoval() + } + + var err error + ctx.credValues, err = v4.Credentials.GetWithContext(requestContext(r)) + if err != nil { + return http.Header{}, err + } + + ctx.sanitizeHostForHeader() + ctx.assignAmzQueryValues() + if err := ctx.build(v4.DisableHeaderHoisting); err != nil { + return nil, err + } + + // If the request is not presigned the body should be attached to it. This + // prevents the confusion of wanting to send a signed request without + // the body the request was signed for attached. + if !(v4.DisableRequestBodyOverwrite || ctx.isPresign) { + var reader io.ReadCloser + if body != nil { + var ok bool + if reader, ok = body.(io.ReadCloser); !ok { + reader = ioutil.NopCloser(body) + } + } + r.Body = reader + } + + if v4.Debug.Matches(aws.LogDebugWithSigning) { + v4.logSigningInfo(ctx) + } + + return ctx.SignedHeaderVals, nil +} + +func (ctx *signingCtx) sanitizeHostForHeader() { + request.SanitizeHostForHeader(ctx.Request) +} + +func (ctx *signingCtx) handlePresignRemoval() { + if !ctx.isPresign { + return + } + + // The credentials have expired for this request. The current signing + // is invalid, and needs to be request because the request will fail. + ctx.removePresign() + + // Update the request's query string to ensure the values stays in + // sync in the case retrieving the new credentials fails. + ctx.Request.URL.RawQuery = ctx.Query.Encode() +} + +func (ctx *signingCtx) assignAmzQueryValues() { + if ctx.isPresign { + ctx.Query.Set("X-Amz-Algorithm", authHeaderPrefix) + if ctx.credValues.SessionToken != "" { + ctx.Query.Set("X-Amz-Security-Token", ctx.credValues.SessionToken) + } else { + ctx.Query.Del("X-Amz-Security-Token") + } + + return + } + + if ctx.credValues.SessionToken != "" { + ctx.Request.Header.Set("X-Amz-Security-Token", ctx.credValues.SessionToken) + } +} + +// SignRequestHandler is a named request handler the SDK will use to sign +// service client request with using the V4 signature. +var SignRequestHandler = request.NamedHandler{ + Name: "v4.SignRequestHandler", Fn: SignSDKRequest, +} + +// SignSDKRequest signs an AWS request with the V4 signature. This +// request handler should only be used with the SDK's built in service client's +// API operation requests. +// +// This function should not be used on its own, but in conjunction with +// an AWS service client's API operation call. To sign a standalone request +// not created by a service client's API operation method use the "Sign" or +// "Presign" functions of the "Signer" type. +// +// If the credentials of the request's config are set to +// credentials.AnonymousCredentials the request will not be signed. +func SignSDKRequest(req *request.Request) { + SignSDKRequestWithCurrentTime(req, time.Now) +} + +// BuildNamedHandler will build a generic handler for signing. +func BuildNamedHandler(name string, opts ...func(*Signer)) request.NamedHandler { + return request.NamedHandler{ + Name: name, + Fn: func(req *request.Request) { + SignSDKRequestWithCurrentTime(req, time.Now, opts...) + }, + } +} + +// SignSDKRequestWithCurrentTime will sign the SDK's request using the time +// function passed in. Behaves the same as SignSDKRequest with the exception +// the request is signed with the value returned by the current time function. +func SignSDKRequestWithCurrentTime(req *request.Request, curTimeFn func() time.Time, opts ...func(*Signer)) { + // If the request does not need to be signed ignore the signing of the + // request if the AnonymousCredentials object is used. + if req.Config.Credentials == credentials.AnonymousCredentials { + return + } + + region := req.ClientInfo.SigningRegion + if region == "" { + region = aws.StringValue(req.Config.Region) + } + + name := req.ClientInfo.SigningName + if name == "" { + name = req.ClientInfo.ServiceName + } + + v4 := NewSigner(req.Config.Credentials, func(v4 *Signer) { + v4.Debug = req.Config.LogLevel.Value() + v4.Logger = req.Config.Logger + v4.DisableHeaderHoisting = req.NotHoist + v4.currentTimeFn = curTimeFn + if name == "s3" { + // S3 service should not have any escaping applied + v4.DisableURIPathEscaping = true + } + // Prevents setting the HTTPRequest's Body. Since the Body could be + // wrapped in a custom io.Closer that we do not want to be stompped + // on top of by the signer. + v4.DisableRequestBodyOverwrite = true + }) + + for _, opt := range opts { + opt(v4) + } + + curTime := curTimeFn() + signedHeaders, err := v4.signWithBody(req.HTTPRequest, req.GetBody(), + name, region, req.ExpireTime, req.ExpireTime > 0, curTime, + ) + if err != nil { + req.Error = err + req.SignedHeaderVals = nil + return + } + + req.SignedHeaderVals = signedHeaders + req.LastSignedAt = curTime +} + +const logSignInfoMsg = `DEBUG: Request Signature: +---[ CANONICAL STRING ]----------------------------- +%s +---[ STRING TO SIGN ]-------------------------------- +%s%s +-----------------------------------------------------` +const logSignedURLMsg = ` +---[ SIGNED URL ]------------------------------------ +%s` + +func (v4 *Signer) logSigningInfo(ctx *signingCtx) { + signedURLMsg := "" + if ctx.isPresign { + signedURLMsg = fmt.Sprintf(logSignedURLMsg, ctx.Request.URL.String()) + } + msg := fmt.Sprintf(logSignInfoMsg, ctx.canonicalString, ctx.stringToSign, signedURLMsg) + v4.Logger.Log(msg) +} + +func (ctx *signingCtx) build(disableHeaderHoisting bool) error { + ctx.buildTime() // no depends + ctx.buildCredentialString() // no depends + + if err := ctx.buildBodyDigest(); err != nil { + return err + } + + unsignedHeaders := ctx.Request.Header + if ctx.isPresign { + if !disableHeaderHoisting { + urlValues := url.Values{} + urlValues, unsignedHeaders = buildQuery(allowedQueryHoisting, unsignedHeaders) // no depends + for k := range urlValues { + ctx.Query[k] = urlValues[k] + } + } + } + + ctx.buildCanonicalHeaders(ignoredHeaders, unsignedHeaders) + ctx.buildCanonicalString() // depends on canon headers / signed headers + ctx.buildStringToSign() // depends on canon string + ctx.buildSignature() // depends on string to sign + + if ctx.isPresign { + ctx.Request.URL.RawQuery += "&" + signatureQueryKey + "=" + ctx.signature + } else { + parts := []string{ + authHeaderPrefix + " Credential=" + ctx.credValues.AccessKeyID + "/" + ctx.credentialString, + "SignedHeaders=" + ctx.signedHeaders, + authHeaderSignatureElem + ctx.signature, + } + ctx.Request.Header.Set(authorizationHeader, strings.Join(parts, ", ")) + } + + return nil +} + +// GetSignedRequestSignature attempts to extract the signature of the request. +// Returning an error if the request is unsigned, or unable to extract the +// signature. +func GetSignedRequestSignature(r *http.Request) ([]byte, error) { + + if auth := r.Header.Get(authorizationHeader); len(auth) != 0 { + ps := strings.Split(auth, ", ") + for _, p := range ps { + if idx := strings.Index(p, authHeaderSignatureElem); idx >= 0 { + sig := p[len(authHeaderSignatureElem):] + if len(sig) == 0 { + return nil, fmt.Errorf("invalid request signature authorization header") + } + return hex.DecodeString(sig) + } + } + } + + if sig := r.URL.Query().Get("X-Amz-Signature"); len(sig) != 0 { + return hex.DecodeString(sig) + } + + return nil, fmt.Errorf("request not signed") +} + +func (ctx *signingCtx) buildTime() { + if ctx.isPresign { + duration := int64(ctx.ExpireTime / time.Second) + ctx.Query.Set("X-Amz-Date", formatTime(ctx.Time)) + ctx.Query.Set("X-Amz-Expires", strconv.FormatInt(duration, 10)) + } else { + ctx.Request.Header.Set("X-Amz-Date", formatTime(ctx.Time)) + } +} + +func (ctx *signingCtx) buildCredentialString() { + ctx.credentialString = buildSigningScope(ctx.Region, ctx.ServiceName, ctx.Time) + + if ctx.isPresign { + ctx.Query.Set("X-Amz-Credential", ctx.credValues.AccessKeyID+"/"+ctx.credentialString) + } +} + +func buildQuery(r rule, header http.Header) (url.Values, http.Header) { + query := url.Values{} + unsignedHeaders := http.Header{} + for k, h := range header { + if r.IsValid(k) { + query[k] = h + } else { + unsignedHeaders[k] = h + } + } + + return query, unsignedHeaders +} +func (ctx *signingCtx) buildCanonicalHeaders(r rule, header http.Header) { + var headers []string + headers = append(headers, "host") + for k, v := range header { + if !r.IsValid(k) { + continue // ignored header + } + if ctx.SignedHeaderVals == nil { + ctx.SignedHeaderVals = make(http.Header) + } + + lowerCaseKey := strings.ToLower(k) + if _, ok := ctx.SignedHeaderVals[lowerCaseKey]; ok { + // include additional values + ctx.SignedHeaderVals[lowerCaseKey] = append(ctx.SignedHeaderVals[lowerCaseKey], v...) + continue + } + + headers = append(headers, lowerCaseKey) + ctx.SignedHeaderVals[lowerCaseKey] = v + } + sort.Strings(headers) + + ctx.signedHeaders = strings.Join(headers, ";") + + if ctx.isPresign { + ctx.Query.Set("X-Amz-SignedHeaders", ctx.signedHeaders) + } + + headerItems := make([]string, len(headers)) + for i, k := range headers { + if k == "host" { + if ctx.Request.Host != "" { + headerItems[i] = "host:" + ctx.Request.Host + } else { + headerItems[i] = "host:" + ctx.Request.URL.Host + } + } else { + headerValues := make([]string, len(ctx.SignedHeaderVals[k])) + for i, v := range ctx.SignedHeaderVals[k] { + headerValues[i] = strings.TrimSpace(v) + } + headerItems[i] = k + ":" + + strings.Join(headerValues, ",") + } + } + stripExcessSpaces(headerItems) + ctx.canonicalHeaders = strings.Join(headerItems, "\n") +} + +func (ctx *signingCtx) buildCanonicalString() { + ctx.Request.URL.RawQuery = strings.Replace(ctx.Query.Encode(), "+", "%20", -1) + + uri := getURIPath(ctx.Request.URL) + + if !ctx.DisableURIPathEscaping { + uri = rest.EscapePath(uri, false) + } + + ctx.canonicalString = strings.Join([]string{ + ctx.Request.Method, + uri, + ctx.Request.URL.RawQuery, + ctx.canonicalHeaders + "\n", + ctx.signedHeaders, + ctx.bodyDigest, + }, "\n") +} + +func (ctx *signingCtx) buildStringToSign() { + ctx.stringToSign = strings.Join([]string{ + authHeaderPrefix, + formatTime(ctx.Time), + ctx.credentialString, + hex.EncodeToString(hashSHA256([]byte(ctx.canonicalString))), + }, "\n") +} + +func (ctx *signingCtx) buildSignature() { + creds := deriveSigningKey(ctx.Region, ctx.ServiceName, ctx.credValues.SecretAccessKey, ctx.Time) + signature := hmacSHA256(creds, []byte(ctx.stringToSign)) + ctx.signature = hex.EncodeToString(signature) +} + +func (ctx *signingCtx) buildBodyDigest() error { + hash := ctx.Request.Header.Get("X-Amz-Content-Sha256") + if hash == "" { + includeSHA256Header := ctx.unsignedPayload || + ctx.ServiceName == "s3" || + ctx.ServiceName == "s3-object-lambda" || + ctx.ServiceName == "glacier" + + s3Presign := ctx.isPresign && + (ctx.ServiceName == "s3" || + ctx.ServiceName == "s3-object-lambda") + + if ctx.unsignedPayload || s3Presign { + hash = "UNSIGNED-PAYLOAD" + includeSHA256Header = !s3Presign + } else if ctx.Body == nil { + hash = emptyStringSHA256 + } else { + if !aws.IsReaderSeekable(ctx.Body) { + return fmt.Errorf("cannot use unseekable request body %T, for signed request with body", ctx.Body) + } + hashBytes, err := makeSha256Reader(ctx.Body) + if err != nil { + return err + } + hash = hex.EncodeToString(hashBytes) + } + + if includeSHA256Header { + ctx.Request.Header.Set("X-Amz-Content-Sha256", hash) + } + } + ctx.bodyDigest = hash + + return nil +} + +// isRequestSigned returns if the request is currently signed or presigned +func (ctx *signingCtx) isRequestSigned() bool { + if ctx.isPresign && ctx.Query.Get("X-Amz-Signature") != "" { + return true + } + if ctx.Request.Header.Get("Authorization") != "" { + return true + } + + return false +} + +// unsign removes signing flags for both signed and presigned requests. +func (ctx *signingCtx) removePresign() { + ctx.Query.Del("X-Amz-Algorithm") + ctx.Query.Del("X-Amz-Signature") + ctx.Query.Del("X-Amz-Security-Token") + ctx.Query.Del("X-Amz-Date") + ctx.Query.Del("X-Amz-Expires") + ctx.Query.Del("X-Amz-Credential") + ctx.Query.Del("X-Amz-SignedHeaders") +} + +func hmacSHA256(key []byte, data []byte) []byte { + hash := hmac.New(sha256.New, key) + hash.Write(data) + return hash.Sum(nil) +} + +func hashSHA256(data []byte) []byte { + hash := sha256.New() + hash.Write(data) + return hash.Sum(nil) +} + +func makeSha256Reader(reader io.ReadSeeker) (hashBytes []byte, err error) { + hash := sha256.New() + start, err := reader.Seek(0, sdkio.SeekCurrent) + if err != nil { + return nil, err + } + defer func() { + // ensure error is return if unable to seek back to start of payload. + _, err = reader.Seek(start, sdkio.SeekStart) + }() + + // Use CopyN to avoid allocating the 32KB buffer in io.Copy for bodies + // smaller than 32KB. Fall back to io.Copy if we fail to determine the size. + size, err := aws.SeekerLen(reader) + if err != nil { + io.Copy(hash, reader) + } else { + io.CopyN(hash, reader, size) + } + + return hash.Sum(nil), nil +} + +const doubleSpace = " " + +// stripExcessSpaces will rewrite the passed in slice's string values to not +// contain multiple side-by-side spaces. +func stripExcessSpaces(vals []string) { + var j, k, l, m, spaces int + for i, str := range vals { + // Trim trailing spaces + for j = len(str) - 1; j >= 0 && str[j] == ' '; j-- { + } + + // Trim leading spaces + for k = 0; k < j && str[k] == ' '; k++ { + } + str = str[k : j+1] + + // Strip multiple spaces. + j = strings.Index(str, doubleSpace) + if j < 0 { + vals[i] = str + continue + } + + buf := []byte(str) + for k, m, l = j, j, len(buf); k < l; k++ { + if buf[k] == ' ' { + if spaces == 0 { + // First space. + buf[m] = buf[k] + m++ + } + spaces++ + } else { + // End of multiple spaces. + spaces = 0 + buf[m] = buf[k] + m++ + } + } + + vals[i] = string(buf[:m]) + } +} + +func buildSigningScope(region, service string, dt time.Time) string { + return strings.Join([]string{ + formatShortTime(dt), + region, + service, + awsV4Request, + }, "/") +} + +func deriveSigningKey(region, service, secretKey string, dt time.Time) []byte { + kDate := hmacSHA256([]byte("AWS4"+secretKey), []byte(formatShortTime(dt))) + kRegion := hmacSHA256(kDate, []byte(region)) + kService := hmacSHA256(kRegion, []byte(service)) + signingKey := hmacSHA256(kService, []byte(awsV4Request)) + return signingKey +} + +func formatShortTime(dt time.Time) string { + return dt.UTC().Format(shortTimeFormat) +} + +func formatTime(dt time.Time) string { + return dt.UTC().Format(timeFormat) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/types.go b/vendor/github.com/aws/aws-sdk-go/aws/types.go new file mode 100644 index 0000000..98751ee --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/types.go @@ -0,0 +1,264 @@ +package aws + +import ( + "io" + "strings" + "sync" + + "github.com/aws/aws-sdk-go/internal/sdkio" +) + +// ReadSeekCloser wraps a io.Reader returning a ReaderSeekerCloser. Allows the +// SDK to accept an io.Reader that is not also an io.Seeker for unsigned +// streaming payload API operations. +// +// A ReadSeekCloser wrapping an nonseekable io.Reader used in an API +// operation's input will prevent that operation being retried in the case of +// network errors, and cause operation requests to fail if the operation +// requires payload signing. +// +// Note: If using With S3 PutObject to stream an object upload The SDK's S3 +// Upload manager (s3manager.Uploader) provides support for streaming with the +// ability to retry network errors. +func ReadSeekCloser(r io.Reader) ReaderSeekerCloser { + return ReaderSeekerCloser{r} +} + +// ReaderSeekerCloser represents a reader that can also delegate io.Seeker and +// io.Closer interfaces to the underlying object if they are available. +type ReaderSeekerCloser struct { + r io.Reader +} + +// IsReaderSeekable returns if the underlying reader type can be seeked. A +// io.Reader might not actually be seekable if it is the ReaderSeekerCloser +// type. +func IsReaderSeekable(r io.Reader) bool { + switch v := r.(type) { + case ReaderSeekerCloser: + return v.IsSeeker() + case *ReaderSeekerCloser: + return v.IsSeeker() + case io.ReadSeeker: + return true + default: + return false + } +} + +// Read reads from the reader up to size of p. The number of bytes read, and +// error if it occurred will be returned. +// +// If the reader is not an io.Reader zero bytes read, and nil error will be +// returned. +// +// Performs the same functionality as io.Reader Read +func (r ReaderSeekerCloser) Read(p []byte) (int, error) { + switch t := r.r.(type) { + case io.Reader: + return t.Read(p) + } + return 0, nil +} + +// Seek sets the offset for the next Read to offset, interpreted according to +// whence: 0 means relative to the origin of the file, 1 means relative to the +// current offset, and 2 means relative to the end. Seek returns the new offset +// and an error, if any. +// +// If the ReaderSeekerCloser is not an io.Seeker nothing will be done. +func (r ReaderSeekerCloser) Seek(offset int64, whence int) (int64, error) { + switch t := r.r.(type) { + case io.Seeker: + return t.Seek(offset, whence) + } + return int64(0), nil +} + +// IsSeeker returns if the underlying reader is also a seeker. +func (r ReaderSeekerCloser) IsSeeker() bool { + _, ok := r.r.(io.Seeker) + return ok +} + +// HasLen returns the length of the underlying reader if the value implements +// the Len() int method. +func (r ReaderSeekerCloser) HasLen() (int, bool) { + type lenner interface { + Len() int + } + + if lr, ok := r.r.(lenner); ok { + return lr.Len(), true + } + + return 0, false +} + +// GetLen returns the length of the bytes remaining in the underlying reader. +// Checks first for Len(), then io.Seeker to determine the size of the +// underlying reader. +// +// Will return -1 if the length cannot be determined. +func (r ReaderSeekerCloser) GetLen() (int64, error) { + if l, ok := r.HasLen(); ok { + return int64(l), nil + } + + if s, ok := r.r.(io.Seeker); ok { + return seekerLen(s) + } + + return -1, nil +} + +// SeekerLen attempts to get the number of bytes remaining at the seeker's +// current position. Returns the number of bytes remaining or error. +func SeekerLen(s io.Seeker) (int64, error) { + // Determine if the seeker is actually seekable. ReaderSeekerCloser + // hides the fact that a io.Readers might not actually be seekable. + switch v := s.(type) { + case ReaderSeekerCloser: + return v.GetLen() + case *ReaderSeekerCloser: + return v.GetLen() + } + + return seekerLen(s) +} + +func seekerLen(s io.Seeker) (int64, error) { + curOffset, err := s.Seek(0, sdkio.SeekCurrent) + if err != nil { + return 0, err + } + + endOffset, err := s.Seek(0, sdkio.SeekEnd) + if err != nil { + return 0, err + } + + _, err = s.Seek(curOffset, sdkio.SeekStart) + if err != nil { + return 0, err + } + + return endOffset - curOffset, nil +} + +// Close closes the ReaderSeekerCloser. +// +// If the ReaderSeekerCloser is not an io.Closer nothing will be done. +func (r ReaderSeekerCloser) Close() error { + switch t := r.r.(type) { + case io.Closer: + return t.Close() + } + return nil +} + +// A WriteAtBuffer provides a in memory buffer supporting the io.WriterAt interface +// Can be used with the s3manager.Downloader to download content to a buffer +// in memory. Safe to use concurrently. +type WriteAtBuffer struct { + buf []byte + m sync.Mutex + + // GrowthCoeff defines the growth rate of the internal buffer. By + // default, the growth rate is 1, where expanding the internal + // buffer will allocate only enough capacity to fit the new expected + // length. + GrowthCoeff float64 +} + +// NewWriteAtBuffer creates a WriteAtBuffer with an internal buffer +// provided by buf. +func NewWriteAtBuffer(buf []byte) *WriteAtBuffer { + return &WriteAtBuffer{buf: buf} +} + +// WriteAt writes a slice of bytes to a buffer starting at the position provided +// The number of bytes written will be returned, or error. Can overwrite previous +// written slices if the write ats overlap. +func (b *WriteAtBuffer) WriteAt(p []byte, pos int64) (n int, err error) { + pLen := len(p) + expLen := pos + int64(pLen) + b.m.Lock() + defer b.m.Unlock() + if int64(len(b.buf)) < expLen { + if int64(cap(b.buf)) < expLen { + if b.GrowthCoeff < 1 { + b.GrowthCoeff = 1 + } + newBuf := make([]byte, expLen, int64(b.GrowthCoeff*float64(expLen))) + copy(newBuf, b.buf) + b.buf = newBuf + } + b.buf = b.buf[:expLen] + } + copy(b.buf[pos:], p) + return pLen, nil +} + +// Bytes returns a slice of bytes written to the buffer. +func (b *WriteAtBuffer) Bytes() []byte { + b.m.Lock() + defer b.m.Unlock() + return b.buf +} + +// MultiCloser is a utility to close multiple io.Closers within a single +// statement. +type MultiCloser []io.Closer + +// Close closes all of the io.Closers making up the MultiClosers. Any +// errors that occur while closing will be returned in the order they +// occur. +func (m MultiCloser) Close() error { + var errs errors + for _, c := range m { + err := c.Close() + if err != nil { + errs = append(errs, err) + } + } + if len(errs) != 0 { + return errs + } + + return nil +} + +type errors []error + +func (es errors) Error() string { + var parts []string + for _, e := range es { + parts = append(parts, e.Error()) + } + + return strings.Join(parts, "\n") +} + +// CopySeekableBody copies the seekable body to an io.Writer +func CopySeekableBody(dst io.Writer, src io.ReadSeeker) (int64, error) { + curPos, err := src.Seek(0, sdkio.SeekCurrent) + if err != nil { + return 0, err + } + + // copy errors may be assumed to be from the body. + n, err := io.Copy(dst, src) + if err != nil { + return n, err + } + + // seek back to the first position after reading to reset + // the body for transmission. + _, err = src.Seek(curPos, sdkio.SeekStart) + if err != nil { + return n, err + } + + return n, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/url.go b/vendor/github.com/aws/aws-sdk-go/aws/url.go new file mode 100644 index 0000000..fed561b --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/url.go @@ -0,0 +1,13 @@ +//go:build go1.8 +// +build go1.8 + +package aws + +import "net/url" + +// URLHostname will extract the Hostname without port from the URL value. +// +// Wrapper of net/url#URL.Hostname for backwards Go version compatibility. +func URLHostname(url *url.URL) string { + return url.Hostname() +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/url_1_7.go b/vendor/github.com/aws/aws-sdk-go/aws/url_1_7.go new file mode 100644 index 0000000..95282db --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/url_1_7.go @@ -0,0 +1,30 @@ +//go:build !go1.8 +// +build !go1.8 + +package aws + +import ( + "net/url" + "strings" +) + +// URLHostname will extract the Hostname without port from the URL value. +// +// Copy of Go 1.8's net/url#URL.Hostname functionality. +func URLHostname(url *url.URL) string { + return stripPort(url.Host) + +} + +// stripPort is copy of Go 1.8 url#URL.Hostname functionality. +// https://golang.org/src/net/url/url.go +func stripPort(hostport string) string { + colon := strings.IndexByte(hostport, ':') + if colon == -1 { + return hostport + } + if i := strings.IndexByte(hostport, ']'); i != -1 { + return strings.TrimPrefix(hostport[:i], "[") + } + return hostport[:colon] +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/version.go b/vendor/github.com/aws/aws-sdk-go/aws/version.go new file mode 100644 index 0000000..b6855f0 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/version.go @@ -0,0 +1,8 @@ +// Package aws provides core functionality for making requests to AWS services. +package aws + +// SDKName is the name of this AWS SDK +const SDKName = "aws-sdk-go" + +// SDKVersion is the version of this SDK +const SDKVersion = "1.42.23" diff --git a/vendor/github.com/aws/aws-sdk-go/internal/context/background_go1.5.go b/vendor/github.com/aws/aws-sdk-go/internal/context/background_go1.5.go new file mode 100644 index 0000000..3653453 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/context/background_go1.5.go @@ -0,0 +1,41 @@ +//go:build !go1.7 +// +build !go1.7 + +package context + +import "time" + +// An emptyCtx is a copy of the Go 1.7 context.emptyCtx type. This is copied to +// provide a 1.6 and 1.5 safe version of context that is compatible with Go +// 1.7's Context. +// +// An emptyCtx is never canceled, has no values, and has no deadline. It is not +// struct{}, since vars of this type must have distinct addresses. +type emptyCtx int + +func (*emptyCtx) Deadline() (deadline time.Time, ok bool) { + return +} + +func (*emptyCtx) Done() <-chan struct{} { + return nil +} + +func (*emptyCtx) Err() error { + return nil +} + +func (*emptyCtx) Value(key interface{}) interface{} { + return nil +} + +func (e *emptyCtx) String() string { + switch e { + case BackgroundCtx: + return "aws.BackgroundContext" + } + return "unknown empty Context" +} + +// BackgroundCtx is the common base context. +var BackgroundCtx = new(emptyCtx) diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/ast.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/ast.go new file mode 100644 index 0000000..e83a998 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/ast.go @@ -0,0 +1,120 @@ +package ini + +// ASTKind represents different states in the parse table +// and the type of AST that is being constructed +type ASTKind int + +// ASTKind* is used in the parse table to transition between +// the different states +const ( + ASTKindNone = ASTKind(iota) + ASTKindStart + ASTKindExpr + ASTKindEqualExpr + ASTKindStatement + ASTKindSkipStatement + ASTKindExprStatement + ASTKindSectionStatement + ASTKindNestedSectionStatement + ASTKindCompletedNestedSectionStatement + ASTKindCommentStatement + ASTKindCompletedSectionStatement +) + +func (k ASTKind) String() string { + switch k { + case ASTKindNone: + return "none" + case ASTKindStart: + return "start" + case ASTKindExpr: + return "expr" + case ASTKindStatement: + return "stmt" + case ASTKindSectionStatement: + return "section_stmt" + case ASTKindExprStatement: + return "expr_stmt" + case ASTKindCommentStatement: + return "comment" + case ASTKindNestedSectionStatement: + return "nested_section_stmt" + case ASTKindCompletedSectionStatement: + return "completed_stmt" + case ASTKindSkipStatement: + return "skip" + default: + return "" + } +} + +// AST interface allows us to determine what kind of node we +// are on and casting may not need to be necessary. +// +// The root is always the first node in Children +type AST struct { + Kind ASTKind + Root Token + RootToken bool + Children []AST +} + +func newAST(kind ASTKind, root AST, children ...AST) AST { + return AST{ + Kind: kind, + Children: append([]AST{root}, children...), + } +} + +func newASTWithRootToken(kind ASTKind, root Token, children ...AST) AST { + return AST{ + Kind: kind, + Root: root, + RootToken: true, + Children: children, + } +} + +// AppendChild will append to the list of children an AST has. +func (a *AST) AppendChild(child AST) { + a.Children = append(a.Children, child) +} + +// GetRoot will return the root AST which can be the first entry +// in the children list or a token. +func (a *AST) GetRoot() AST { + if a.RootToken { + return *a + } + + if len(a.Children) == 0 { + return AST{} + } + + return a.Children[0] +} + +// GetChildren will return the current AST's list of children +func (a *AST) GetChildren() []AST { + if len(a.Children) == 0 { + return []AST{} + } + + if a.RootToken { + return a.Children + } + + return a.Children[1:] +} + +// SetChildren will set and override all children of the AST. +func (a *AST) SetChildren(children []AST) { + if a.RootToken { + a.Children = children + } else { + a.Children = append(a.Children[:1], children...) + } +} + +// Start is used to indicate the starting state of the parse table. +var Start = newAST(ASTKindStart, AST{}) diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/comma_token.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/comma_token.go new file mode 100644 index 0000000..0895d53 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/comma_token.go @@ -0,0 +1,11 @@ +package ini + +var commaRunes = []rune(",") + +func isComma(b rune) bool { + return b == ',' +} + +func newCommaToken() Token { + return newToken(TokenComma, commaRunes, NoneType) +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/comment_token.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/comment_token.go new file mode 100644 index 0000000..0b76999 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/comment_token.go @@ -0,0 +1,35 @@ +package ini + +// isComment will return whether or not the next byte(s) is a +// comment. +func isComment(b []rune) bool { + if len(b) == 0 { + return false + } + + switch b[0] { + case ';': + return true + case '#': + return true + } + + return false +} + +// newCommentToken will create a comment token and +// return how many bytes were read. +func newCommentToken(b []rune) (Token, int, error) { + i := 0 + for ; i < len(b); i++ { + if b[i] == '\n' { + break + } + + if len(b)-i > 2 && b[i] == '\r' && b[i+1] == '\n' { + break + } + } + + return newToken(TokenComment, b[:i], NoneType), i, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/doc.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/doc.go new file mode 100644 index 0000000..1e55bbd --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/doc.go @@ -0,0 +1,42 @@ +// Package ini is an LL(1) parser for configuration files. +// +// Example: +// sections, err := ini.OpenFile("/path/to/file") +// if err != nil { +// panic(err) +// } +// +// profile := "foo" +// section, ok := sections.GetSection(profile) +// if !ok { +// fmt.Printf("section %q could not be found", profile) +// } +// +// Below is the BNF that describes this parser +// Grammar: +// stmt -> section | stmt' +// stmt' -> epsilon | expr +// expr -> value (stmt)* | equal_expr (stmt)* +// equal_expr -> value ( ':' | '=' ) equal_expr' +// equal_expr' -> number | string | quoted_string +// quoted_string -> " quoted_string' +// quoted_string' -> string quoted_string_end +// quoted_string_end -> " +// +// section -> [ section' +// section' -> section_value section_close +// section_value -> number | string_subset | boolean | quoted_string_subset +// quoted_string_subset -> " quoted_string_subset' +// quoted_string_subset' -> string_subset quoted_string_end +// quoted_string_subset -> " +// section_close -> ] +// +// value -> number | string_subset | boolean +// string -> ? UTF-8 Code-Points except '\n' (U+000A) and '\r\n' (U+000D U+000A) ? +// string_subset -> ? Code-points excepted by grammar except ':' (U+003A), '=' (U+003D), '[' (U+005B), and ']' (U+005D) ? +// +// SkipState will skip (NL WS)+ +// +// comment -> # comment' | ; comment' +// comment' -> epsilon | value +package ini diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/empty_token.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/empty_token.go new file mode 100644 index 0000000..04345a5 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/empty_token.go @@ -0,0 +1,4 @@ +package ini + +// emptyToken is used to satisfy the Token interface +var emptyToken = newToken(TokenNone, []rune{}, NoneType) diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/expression.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/expression.go new file mode 100644 index 0000000..91ba2a5 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/expression.go @@ -0,0 +1,24 @@ +package ini + +// newExpression will return an expression AST. +// Expr represents an expression +// +// grammar: +// expr -> string | number +func newExpression(tok Token) AST { + return newASTWithRootToken(ASTKindExpr, tok) +} + +func newEqualExpr(left AST, tok Token) AST { + return newASTWithRootToken(ASTKindEqualExpr, tok, left) +} + +// EqualExprKey will return a LHS value in the equal expr +func EqualExprKey(ast AST) string { + children := ast.GetChildren() + if len(children) == 0 || ast.Kind != ASTKindEqualExpr { + return "" + } + + return string(children[0].Root.Raw()) +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/fuzz.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/fuzz.go new file mode 100644 index 0000000..6e545b6 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/fuzz.go @@ -0,0 +1,18 @@ +//go:build gofuzz +// +build gofuzz + +package ini + +import ( + "bytes" +) + +func Fuzz(data []byte) int { + b := bytes.NewReader(data) + + if _, err := Parse(b); err != nil { + return 0 + } + + return 1 +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/ini.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/ini.go new file mode 100644 index 0000000..3b0ca7a --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/ini.go @@ -0,0 +1,51 @@ +package ini + +import ( + "io" + "os" + + "github.com/aws/aws-sdk-go/aws/awserr" +) + +// OpenFile takes a path to a given file, and will open and parse +// that file. +func OpenFile(path string) (Sections, error) { + f, err := os.Open(path) + if err != nil { + return Sections{}, awserr.New(ErrCodeUnableToReadFile, "unable to open file", err) + } + defer f.Close() + + return Parse(f) +} + +// Parse will parse the given file using the shared config +// visitor. +func Parse(f io.Reader) (Sections, error) { + tree, err := ParseAST(f) + if err != nil { + return Sections{}, err + } + + v := NewDefaultVisitor() + if err = Walk(tree, v); err != nil { + return Sections{}, err + } + + return v.Sections, nil +} + +// ParseBytes will parse the given bytes and return the parsed sections. +func ParseBytes(b []byte) (Sections, error) { + tree, err := ParseASTBytes(b) + if err != nil { + return Sections{}, err + } + + v := NewDefaultVisitor() + if err = Walk(tree, v); err != nil { + return Sections{}, err + } + + return v.Sections, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/ini_lexer.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/ini_lexer.go new file mode 100644 index 0000000..582c024 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/ini_lexer.go @@ -0,0 +1,165 @@ +package ini + +import ( + "bytes" + "io" + "io/ioutil" + + "github.com/aws/aws-sdk-go/aws/awserr" +) + +const ( + // ErrCodeUnableToReadFile is used when a file is failed to be + // opened or read from. + ErrCodeUnableToReadFile = "FailedRead" +) + +// TokenType represents the various different tokens types +type TokenType int + +func (t TokenType) String() string { + switch t { + case TokenNone: + return "none" + case TokenLit: + return "literal" + case TokenSep: + return "sep" + case TokenOp: + return "op" + case TokenWS: + return "ws" + case TokenNL: + return "newline" + case TokenComment: + return "comment" + case TokenComma: + return "comma" + default: + return "" + } +} + +// TokenType enums +const ( + TokenNone = TokenType(iota) + TokenLit + TokenSep + TokenComma + TokenOp + TokenWS + TokenNL + TokenComment +) + +type iniLexer struct{} + +// Tokenize will return a list of tokens during lexical analysis of the +// io.Reader. +func (l *iniLexer) Tokenize(r io.Reader) ([]Token, error) { + b, err := ioutil.ReadAll(r) + if err != nil { + return nil, awserr.New(ErrCodeUnableToReadFile, "unable to read file", err) + } + + return l.tokenize(b) +} + +func (l *iniLexer) tokenize(b []byte) ([]Token, error) { + runes := bytes.Runes(b) + var err error + n := 0 + tokenAmount := countTokens(runes) + tokens := make([]Token, tokenAmount) + count := 0 + + for len(runes) > 0 && count < tokenAmount { + switch { + case isWhitespace(runes[0]): + tokens[count], n, err = newWSToken(runes) + case isComma(runes[0]): + tokens[count], n = newCommaToken(), 1 + case isComment(runes): + tokens[count], n, err = newCommentToken(runes) + case isNewline(runes): + tokens[count], n, err = newNewlineToken(runes) + case isSep(runes): + tokens[count], n, err = newSepToken(runes) + case isOp(runes): + tokens[count], n, err = newOpToken(runes) + default: + tokens[count], n, err = newLitToken(runes) + } + + if err != nil { + return nil, err + } + + count++ + + runes = runes[n:] + } + + return tokens[:count], nil +} + +func countTokens(runes []rune) int { + count, n := 0, 0 + var err error + + for len(runes) > 0 { + switch { + case isWhitespace(runes[0]): + _, n, err = newWSToken(runes) + case isComma(runes[0]): + _, n = newCommaToken(), 1 + case isComment(runes): + _, n, err = newCommentToken(runes) + case isNewline(runes): + _, n, err = newNewlineToken(runes) + case isSep(runes): + _, n, err = newSepToken(runes) + case isOp(runes): + _, n, err = newOpToken(runes) + default: + _, n, err = newLitToken(runes) + } + + if err != nil { + return 0 + } + + count++ + runes = runes[n:] + } + + return count + 1 +} + +// Token indicates a metadata about a given value. +type Token struct { + t TokenType + ValueType ValueType + base int + raw []rune +} + +var emptyValue = Value{} + +func newToken(t TokenType, raw []rune, v ValueType) Token { + return Token{ + t: t, + raw: raw, + ValueType: v, + } +} + +// Raw return the raw runes that were consumed +func (tok Token) Raw() []rune { + return tok.raw +} + +// Type returns the token type +func (tok Token) Type() TokenType { + return tok.t +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/ini_parser.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/ini_parser.go new file mode 100644 index 0000000..0ba3194 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/ini_parser.go @@ -0,0 +1,350 @@ +package ini + +import ( + "fmt" + "io" +) + +// ParseState represents the current state of the parser. +type ParseState uint + +// State enums for the parse table +const ( + InvalidState ParseState = iota + // stmt -> value stmt' + StatementState + // stmt' -> MarkComplete | op stmt + StatementPrimeState + // value -> number | string | boolean | quoted_string + ValueState + // section -> [ section' + OpenScopeState + // section' -> value section_close + SectionState + // section_close -> ] + CloseScopeState + // SkipState will skip (NL WS)+ + SkipState + // SkipTokenState will skip any token and push the previous + // state onto the stack. + SkipTokenState + // comment -> # comment' | ; comment' + // comment' -> MarkComplete | value + CommentState + // MarkComplete state will complete statements and move that + // to the completed AST list + MarkCompleteState + // TerminalState signifies that the tokens have been fully parsed + TerminalState +) + +// parseTable is a state machine to dictate the grammar above. +var parseTable = map[ASTKind]map[TokenType]ParseState{ + ASTKindStart: { + TokenLit: StatementState, + TokenSep: OpenScopeState, + TokenWS: SkipTokenState, + TokenNL: SkipTokenState, + TokenComment: CommentState, + TokenNone: TerminalState, + }, + ASTKindCommentStatement: { + TokenLit: StatementState, + TokenSep: OpenScopeState, + TokenWS: SkipTokenState, + TokenNL: SkipTokenState, + TokenComment: CommentState, + TokenNone: MarkCompleteState, + }, + ASTKindExpr: { + TokenOp: StatementPrimeState, + TokenLit: ValueState, + TokenSep: OpenScopeState, + TokenWS: ValueState, + TokenNL: SkipState, + TokenComment: CommentState, + TokenNone: MarkCompleteState, + }, + ASTKindEqualExpr: { + TokenLit: ValueState, + TokenSep: ValueState, + TokenOp: ValueState, + TokenWS: SkipTokenState, + TokenNL: SkipState, + TokenNone: SkipState, + }, + ASTKindStatement: { + TokenLit: SectionState, + TokenSep: CloseScopeState, + TokenWS: SkipTokenState, + TokenNL: SkipTokenState, + TokenComment: CommentState, + TokenNone: MarkCompleteState, + }, + ASTKindExprStatement: { + TokenLit: ValueState, + TokenSep: ValueState, + TokenOp: ValueState, + TokenWS: ValueState, + TokenNL: MarkCompleteState, + TokenComment: CommentState, + TokenNone: TerminalState, + TokenComma: SkipState, + }, + ASTKindSectionStatement: { + TokenLit: SectionState, + TokenOp: SectionState, + TokenSep: CloseScopeState, + TokenWS: SectionState, + TokenNL: SkipTokenState, + }, + ASTKindCompletedSectionStatement: { + TokenWS: SkipTokenState, + TokenNL: SkipTokenState, + TokenLit: StatementState, + TokenSep: OpenScopeState, + TokenComment: CommentState, + TokenNone: MarkCompleteState, + }, + ASTKindSkipStatement: { + TokenLit: StatementState, + TokenSep: OpenScopeState, + TokenWS: SkipTokenState, + TokenNL: SkipTokenState, + TokenComment: CommentState, + TokenNone: TerminalState, + }, +} + +// ParseAST will parse input from an io.Reader using +// an LL(1) parser. +func ParseAST(r io.Reader) ([]AST, error) { + lexer := iniLexer{} + tokens, err := lexer.Tokenize(r) + if err != nil { + return []AST{}, err + } + + return parse(tokens) +} + +// ParseASTBytes will parse input from a byte slice using +// an LL(1) parser. +func ParseASTBytes(b []byte) ([]AST, error) { + lexer := iniLexer{} + tokens, err := lexer.tokenize(b) + if err != nil { + return []AST{}, err + } + + return parse(tokens) +} + +func parse(tokens []Token) ([]AST, error) { + start := Start + stack := newParseStack(3, len(tokens)) + + stack.Push(start) + s := newSkipper() + +loop: + for stack.Len() > 0 { + k := stack.Pop() + + var tok Token + if len(tokens) == 0 { + // this occurs when all the tokens have been processed + // but reduction of what's left on the stack needs to + // occur. + tok = emptyToken + } else { + tok = tokens[0] + } + + step := parseTable[k.Kind][tok.Type()] + if s.ShouldSkip(tok) { + // being in a skip state with no tokens will break out of + // the parse loop since there is nothing left to process. + if len(tokens) == 0 { + break loop + } + // if should skip is true, we skip the tokens until should skip is set to false. + step = SkipTokenState + } + + switch step { + case TerminalState: + // Finished parsing. Push what should be the last + // statement to the stack. If there is anything left + // on the stack, an error in parsing has occurred. + if k.Kind != ASTKindStart { + stack.MarkComplete(k) + } + break loop + case SkipTokenState: + // When skipping a token, the previous state was popped off the stack. + // To maintain the correct state, the previous state will be pushed + // onto the stack. + stack.Push(k) + case StatementState: + if k.Kind != ASTKindStart { + stack.MarkComplete(k) + } + expr := newExpression(tok) + stack.Push(expr) + case StatementPrimeState: + if tok.Type() != TokenOp { + stack.MarkComplete(k) + continue + } + + if k.Kind != ASTKindExpr { + return nil, NewParseError( + fmt.Sprintf("invalid expression: expected Expr type, but found %T type", k), + ) + } + + k = trimSpaces(k) + expr := newEqualExpr(k, tok) + stack.Push(expr) + case ValueState: + // ValueState requires the previous state to either be an equal expression + // or an expression statement. + switch k.Kind { + case ASTKindEqualExpr: + // assigning a value to some key + k.AppendChild(newExpression(tok)) + stack.Push(newExprStatement(k)) + case ASTKindExpr: + k.Root.raw = append(k.Root.raw, tok.Raw()...) + stack.Push(k) + case ASTKindExprStatement: + root := k.GetRoot() + children := root.GetChildren() + if len(children) == 0 { + return nil, NewParseError( + fmt.Sprintf("invalid expression: AST contains no children %s", k.Kind), + ) + } + + rhs := children[len(children)-1] + + if rhs.Root.ValueType != QuotedStringType { + rhs.Root.ValueType = StringType + rhs.Root.raw = append(rhs.Root.raw, tok.Raw()...) + + } + + children[len(children)-1] = rhs + root.SetChildren(children) + + stack.Push(k) + } + case OpenScopeState: + if !runeCompare(tok.Raw(), openBrace) { + return nil, NewParseError("expected '['") + } + // If OpenScopeState is not at the start, we must mark the previous ast as complete + // + // for example: if previous ast was a skip statement; + // we should mark it as complete before we create a new statement + if k.Kind != ASTKindStart { + stack.MarkComplete(k) + } + + stmt := newStatement() + stack.Push(stmt) + case CloseScopeState: + if !runeCompare(tok.Raw(), closeBrace) { + return nil, NewParseError("expected ']'") + } + + k = trimSpaces(k) + stack.Push(newCompletedSectionStatement(k)) + case SectionState: + var stmt AST + + switch k.Kind { + case ASTKindStatement: + // If there are multiple literals inside of a scope declaration, + // then the current token's raw value will be appended to the Name. + // + // This handles cases like [ profile default ] + // + // k will represent a SectionStatement with the children representing + // the label of the section + stmt = newSectionStatement(tok) + case ASTKindSectionStatement: + k.Root.raw = append(k.Root.raw, tok.Raw()...) + stmt = k + default: + return nil, NewParseError( + fmt.Sprintf("invalid statement: expected statement: %v", k.Kind), + ) + } + + stack.Push(stmt) + case MarkCompleteState: + if k.Kind != ASTKindStart { + stack.MarkComplete(k) + } + + if stack.Len() == 0 { + stack.Push(start) + } + case SkipState: + stack.Push(newSkipStatement(k)) + s.Skip() + case CommentState: + if k.Kind == ASTKindStart { + stack.Push(k) + } else { + stack.MarkComplete(k) + } + + stmt := newCommentStatement(tok) + stack.Push(stmt) + default: + return nil, NewParseError( + fmt.Sprintf("invalid state with ASTKind %v and TokenType %v", + k, tok.Type())) + } + + if len(tokens) > 0 { + tokens = tokens[1:] + } + } + + // this occurs when a statement has not been completed + if stack.top > 1 { + return nil, NewParseError(fmt.Sprintf("incomplete ini expression")) + } + + // returns a sublist which excludes the start symbol + return stack.List(), nil +} + +// trimSpaces will trim spaces on the left and right hand side of +// the literal. +func trimSpaces(k AST) AST { + // trim left hand side of spaces + for i := 0; i < len(k.Root.raw); i++ { + if !isWhitespace(k.Root.raw[i]) { + break + } + + k.Root.raw = k.Root.raw[1:] + i-- + } + + // trim right hand side of spaces + for i := len(k.Root.raw) - 1; i >= 0; i-- { + if !isWhitespace(k.Root.raw[i]) { + break + } + + k.Root.raw = k.Root.raw[:len(k.Root.raw)-1] + } + + return k +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/literal_tokens.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/literal_tokens.go new file mode 100644 index 0000000..34a481a --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/literal_tokens.go @@ -0,0 +1,340 @@ +package ini + +import ( + "fmt" + "strconv" + "strings" + "unicode" +) + +var ( + runesTrue = []rune("true") + runesFalse = []rune("false") +) + +var literalValues = [][]rune{ + runesTrue, + runesFalse, +} + +func isBoolValue(b []rune) bool { + for _, lv := range literalValues { + if isCaselessLitValue(lv, b) { + return true + } + } + return false +} + +func isLitValue(want, have []rune) bool { + if len(have) < len(want) { + return false + } + + for i := 0; i < len(want); i++ { + if want[i] != have[i] { + return false + } + } + + return true +} + +// isCaselessLitValue is a caseless value comparison, assumes want is already lower-cased for efficiency. +func isCaselessLitValue(want, have []rune) bool { + if len(have) < len(want) { + return false + } + + for i := 0; i < len(want); i++ { + if want[i] != unicode.ToLower(have[i]) { + return false + } + } + + return true +} + +// isNumberValue will return whether not the leading characters in +// a byte slice is a number. A number is delimited by whitespace or +// the newline token. +// +// A number is defined to be in a binary, octal, decimal (int | float), hex format, +// or in scientific notation. +func isNumberValue(b []rune) bool { + negativeIndex := 0 + helper := numberHelper{} + needDigit := false + + for i := 0; i < len(b); i++ { + negativeIndex++ + + switch b[i] { + case '-': + if helper.IsNegative() || negativeIndex != 1 { + return false + } + helper.Determine(b[i]) + needDigit = true + continue + case 'e', 'E': + if err := helper.Determine(b[i]); err != nil { + return false + } + negativeIndex = 0 + needDigit = true + continue + case 'b': + if helper.numberFormat == hex { + break + } + fallthrough + case 'o', 'x': + needDigit = true + if i == 0 { + return false + } + + fallthrough + case '.': + if err := helper.Determine(b[i]); err != nil { + return false + } + needDigit = true + continue + } + + if i > 0 && (isNewline(b[i:]) || isWhitespace(b[i])) { + return !needDigit + } + + if !helper.CorrectByte(b[i]) { + return false + } + needDigit = false + } + + return !needDigit +} + +func isValid(b []rune) (bool, int, error) { + if len(b) == 0 { + // TODO: should probably return an error + return false, 0, nil + } + + return isValidRune(b[0]), 1, nil +} + +func isValidRune(r rune) bool { + return r != ':' && r != '=' && r != '[' && r != ']' && r != ' ' && r != '\n' +} + +// ValueType is an enum that will signify what type +// the Value is +type ValueType int + +func (v ValueType) String() string { + switch v { + case NoneType: + return "NONE" + case DecimalType: + return "FLOAT" + case IntegerType: + return "INT" + case StringType: + return "STRING" + case BoolType: + return "BOOL" + } + + return "" +} + +// ValueType enums +const ( + NoneType = ValueType(iota) + DecimalType + IntegerType + StringType + QuotedStringType + BoolType +) + +// Value is a union container +type Value struct { + Type ValueType + raw []rune + + integer int64 + decimal float64 + boolean bool + str string +} + +func newValue(t ValueType, base int, raw []rune) (Value, error) { + v := Value{ + Type: t, + raw: raw, + } + var err error + + switch t { + case DecimalType: + v.decimal, err = strconv.ParseFloat(string(raw), 64) + case IntegerType: + if base != 10 { + raw = raw[2:] + } + + v.integer, err = strconv.ParseInt(string(raw), base, 64) + case StringType: + v.str = string(raw) + case QuotedStringType: + v.str = string(raw[1 : len(raw)-1]) + case BoolType: + v.boolean = isCaselessLitValue(runesTrue, v.raw) + } + + // issue 2253 + // + // if the value trying to be parsed is too large, then we will use + // the 'StringType' and raw value instead. + if nerr, ok := err.(*strconv.NumError); ok && nerr.Err == strconv.ErrRange { + v.Type = StringType + v.str = string(raw) + err = nil + } + + return v, err +} + +// Append will append values and change the type to a string +// type. +func (v *Value) Append(tok Token) { + r := tok.Raw() + if v.Type != QuotedStringType { + v.Type = StringType + r = tok.raw[1 : len(tok.raw)-1] + } + if tok.Type() != TokenLit { + v.raw = append(v.raw, tok.Raw()...) + } else { + v.raw = append(v.raw, r...) + } +} + +func (v Value) String() string { + switch v.Type { + case DecimalType: + return fmt.Sprintf("decimal: %f", v.decimal) + case IntegerType: + return fmt.Sprintf("integer: %d", v.integer) + case StringType: + return fmt.Sprintf("string: %s", string(v.raw)) + case QuotedStringType: + return fmt.Sprintf("quoted string: %s", string(v.raw)) + case BoolType: + return fmt.Sprintf("bool: %t", v.boolean) + default: + return "union not set" + } +} + +func newLitToken(b []rune) (Token, int, error) { + n := 0 + var err error + + token := Token{} + if b[0] == '"' { + n, err = getStringValue(b) + if err != nil { + return token, n, err + } + + token = newToken(TokenLit, b[:n], QuotedStringType) + } else if isNumberValue(b) { + var base int + base, n, err = getNumericalValue(b) + if err != nil { + return token, 0, err + } + + value := b[:n] + vType := IntegerType + if contains(value, '.') || hasExponent(value) { + vType = DecimalType + } + token = newToken(TokenLit, value, vType) + token.base = base + } else if isBoolValue(b) { + n, err = getBoolValue(b) + + token = newToken(TokenLit, b[:n], BoolType) + } else { + n, err = getValue(b) + token = newToken(TokenLit, b[:n], StringType) + } + + return token, n, err +} + +// IntValue returns an integer value +func (v Value) IntValue() int64 { + return v.integer +} + +// FloatValue returns a float value +func (v Value) FloatValue() float64 { + return v.decimal +} + +// BoolValue returns a bool value +func (v Value) BoolValue() bool { + return v.boolean +} + +func isTrimmable(r rune) bool { + switch r { + case '\n', ' ': + return true + } + return false +} + +// StringValue returns the string value +func (v Value) StringValue() string { + switch v.Type { + case StringType: + return strings.TrimFunc(string(v.raw), isTrimmable) + case QuotedStringType: + // preserve all characters in the quotes + return string(removeEscapedCharacters(v.raw[1 : len(v.raw)-1])) + default: + return strings.TrimFunc(string(v.raw), isTrimmable) + } +} + +func contains(runes []rune, c rune) bool { + for i := 0; i < len(runes); i++ { + if runes[i] == c { + return true + } + } + + return false +} + +func runeCompare(v1 []rune, v2 []rune) bool { + if len(v1) != len(v2) { + return false + } + + for i := 0; i < len(v1); i++ { + if v1[i] != v2[i] { + return false + } + } + + return true +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/newline_token.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/newline_token.go new file mode 100644 index 0000000..e52ac39 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/newline_token.go @@ -0,0 +1,30 @@ +package ini + +func isNewline(b []rune) bool { + if len(b) == 0 { + return false + } + + if b[0] == '\n' { + return true + } + + if len(b) < 2 { + return false + } + + return b[0] == '\r' && b[1] == '\n' +} + +func newNewlineToken(b []rune) (Token, int, error) { + i := 1 + if b[0] == '\r' && isNewline(b[1:]) { + i++ + } + + if !isNewline([]rune(b[:i])) { + return emptyToken, 0, NewParseError("invalid new line token") + } + + return newToken(TokenNL, b[:i], NoneType), i, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/number_helper.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/number_helper.go new file mode 100644 index 0000000..a45c0bc --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/number_helper.go @@ -0,0 +1,152 @@ +package ini + +import ( + "bytes" + "fmt" + "strconv" +) + +const ( + none = numberFormat(iota) + binary + octal + decimal + hex + exponent +) + +type numberFormat int + +// numberHelper is used to dictate what format a number is in +// and what to do for negative values. Since -1e-4 is a valid +// number, we cannot just simply check for duplicate negatives. +type numberHelper struct { + numberFormat numberFormat + + negative bool + negativeExponent bool +} + +func (b numberHelper) Exists() bool { + return b.numberFormat != none +} + +func (b numberHelper) IsNegative() bool { + return b.negative || b.negativeExponent +} + +func (b *numberHelper) Determine(c rune) error { + if b.Exists() { + return NewParseError(fmt.Sprintf("multiple number formats: 0%v", string(c))) + } + + switch c { + case 'b': + b.numberFormat = binary + case 'o': + b.numberFormat = octal + case 'x': + b.numberFormat = hex + case 'e', 'E': + b.numberFormat = exponent + case '-': + if b.numberFormat != exponent { + b.negative = true + } else { + b.negativeExponent = true + } + case '.': + b.numberFormat = decimal + default: + return NewParseError(fmt.Sprintf("invalid number character: %v", string(c))) + } + + return nil +} + +func (b numberHelper) CorrectByte(c rune) bool { + switch { + case b.numberFormat == binary: + if !isBinaryByte(c) { + return false + } + case b.numberFormat == octal: + if !isOctalByte(c) { + return false + } + case b.numberFormat == hex: + if !isHexByte(c) { + return false + } + case b.numberFormat == decimal: + if !isDigit(c) { + return false + } + case b.numberFormat == exponent: + if !isDigit(c) { + return false + } + case b.negativeExponent: + if !isDigit(c) { + return false + } + case b.negative: + if !isDigit(c) { + return false + } + default: + if !isDigit(c) { + return false + } + } + + return true +} + +func (b numberHelper) Base() int { + switch b.numberFormat { + case binary: + return 2 + case octal: + return 8 + case hex: + return 16 + default: + return 10 + } +} + +func (b numberHelper) String() string { + buf := bytes.Buffer{} + i := 0 + + switch b.numberFormat { + case binary: + i++ + buf.WriteString(strconv.Itoa(i) + ": binary format\n") + case octal: + i++ + buf.WriteString(strconv.Itoa(i) + ": octal format\n") + case hex: + i++ + buf.WriteString(strconv.Itoa(i) + ": hex format\n") + case exponent: + i++ + buf.WriteString(strconv.Itoa(i) + ": exponent format\n") + default: + i++ + buf.WriteString(strconv.Itoa(i) + ": integer format\n") + } + + if b.negative { + i++ + buf.WriteString(strconv.Itoa(i) + ": negative format\n") + } + + if b.negativeExponent { + i++ + buf.WriteString(strconv.Itoa(i) + ": negative exponent format\n") + } + + return buf.String() +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/op_tokens.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/op_tokens.go new file mode 100644 index 0000000..8a84c7c --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/op_tokens.go @@ -0,0 +1,39 @@ +package ini + +import ( + "fmt" +) + +var ( + equalOp = []rune("=") + equalColonOp = []rune(":") +) + +func isOp(b []rune) bool { + if len(b) == 0 { + return false + } + + switch b[0] { + case '=': + return true + case ':': + return true + default: + return false + } +} + +func newOpToken(b []rune) (Token, int, error) { + tok := Token{} + + switch b[0] { + case '=': + tok = newToken(TokenOp, equalOp, NoneType) + case ':': + tok = newToken(TokenOp, equalColonOp, NoneType) + default: + return tok, 0, NewParseError(fmt.Sprintf("unexpected op type, %v", b[0])) + } + return tok, 1, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/parse_error.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/parse_error.go new file mode 100644 index 0000000..4572870 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/parse_error.go @@ -0,0 +1,43 @@ +package ini + +import "fmt" + +const ( + // ErrCodeParseError is returned when a parsing error + // has occurred. + ErrCodeParseError = "INIParseError" +) + +// ParseError is an error which is returned during any part of +// the parsing process. +type ParseError struct { + msg string +} + +// NewParseError will return a new ParseError where message +// is the description of the error. +func NewParseError(message string) *ParseError { + return &ParseError{ + msg: message, + } +} + +// Code will return the ErrCodeParseError +func (err *ParseError) Code() string { + return ErrCodeParseError +} + +// Message returns the error's message +func (err *ParseError) Message() string { + return err.msg +} + +// OrigError return nothing since there will never be any +// original error. +func (err *ParseError) OrigError() error { + return nil +} + +func (err *ParseError) Error() string { + return fmt.Sprintf("%s: %s", err.Code(), err.Message()) +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/parse_stack.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/parse_stack.go new file mode 100644 index 0000000..7f01cf7 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/parse_stack.go @@ -0,0 +1,60 @@ +package ini + +import ( + "bytes" + "fmt" +) + +// ParseStack is a stack that contains a container, the stack portion, +// and the list which is the list of ASTs that have been successfully +// parsed. +type ParseStack struct { + top int + container []AST + list []AST + index int +} + +func newParseStack(sizeContainer, sizeList int) ParseStack { + return ParseStack{ + container: make([]AST, sizeContainer), + list: make([]AST, sizeList), + } +} + +// Pop will return and truncate the last container element. +func (s *ParseStack) Pop() AST { + s.top-- + return s.container[s.top] +} + +// Push will add the new AST to the container +func (s *ParseStack) Push(ast AST) { + s.container[s.top] = ast + s.top++ +} + +// MarkComplete will append the AST to the list of completed statements +func (s *ParseStack) MarkComplete(ast AST) { + s.list[s.index] = ast + s.index++ +} + +// List will return the completed statements +func (s ParseStack) List() []AST { + return s.list[:s.index] +} + +// Len will return the length of the container +func (s *ParseStack) Len() int { + return s.top +} + +func (s ParseStack) String() string { + buf := bytes.Buffer{} + for i, node := range s.list { + buf.WriteString(fmt.Sprintf("%d: %v\n", i+1, node)) + } + + return buf.String() +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/sep_tokens.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/sep_tokens.go new file mode 100644 index 0000000..f82095b --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/sep_tokens.go @@ -0,0 +1,41 @@ +package ini + +import ( + "fmt" +) + +var ( + emptyRunes = []rune{} +) + +func isSep(b []rune) bool { + if len(b) == 0 { + return false + } + + switch b[0] { + case '[', ']': + return true + default: + return false + } +} + +var ( + openBrace = []rune("[") + closeBrace = []rune("]") +) + +func newSepToken(b []rune) (Token, int, error) { + tok := Token{} + + switch b[0] { + case '[': + tok = newToken(TokenSep, openBrace, NoneType) + case ']': + tok = newToken(TokenSep, closeBrace, NoneType) + default: + return tok, 0, NewParseError(fmt.Sprintf("unexpected sep type, %v", b[0])) + } + return tok, 1, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/skipper.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/skipper.go new file mode 100644 index 0000000..da7a404 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/skipper.go @@ -0,0 +1,45 @@ +package ini + +// skipper is used to skip certain blocks of an ini file. +// Currently skipper is used to skip nested blocks of ini +// files. See example below +// +// [ foo ] +// nested = ; this section will be skipped +// a=b +// c=d +// bar=baz ; this will be included +type skipper struct { + shouldSkip bool + TokenSet bool + prevTok Token +} + +func newSkipper() skipper { + return skipper{ + prevTok: emptyToken, + } +} + +func (s *skipper) ShouldSkip(tok Token) bool { + // should skip state will be modified only if previous token was new line (NL); + // and the current token is not WhiteSpace (WS). + if s.shouldSkip && + s.prevTok.Type() == TokenNL && + tok.Type() != TokenWS { + s.Continue() + return false + } + s.prevTok = tok + return s.shouldSkip +} + +func (s *skipper) Skip() { + s.shouldSkip = true +} + +func (s *skipper) Continue() { + s.shouldSkip = false + // empty token is assigned as we return to default state, when should skip is false + s.prevTok = emptyToken +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/statement.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/statement.go new file mode 100644 index 0000000..18f3fe8 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/statement.go @@ -0,0 +1,35 @@ +package ini + +// Statement is an empty AST mostly used for transitioning states. +func newStatement() AST { + return newAST(ASTKindStatement, AST{}) +} + +// SectionStatement represents a section AST +func newSectionStatement(tok Token) AST { + return newASTWithRootToken(ASTKindSectionStatement, tok) +} + +// ExprStatement represents a completed expression AST +func newExprStatement(ast AST) AST { + return newAST(ASTKindExprStatement, ast) +} + +// CommentStatement represents a comment in the ini definition. +// +// grammar: +// comment -> #comment' | ;comment' +// comment' -> epsilon | value +func newCommentStatement(tok Token) AST { + return newAST(ASTKindCommentStatement, newExpression(tok)) +} + +// CompletedSectionStatement represents a completed section +func newCompletedSectionStatement(ast AST) AST { + return newAST(ASTKindCompletedSectionStatement, ast) +} + +// SkipStatement is used to skip whole statements +func newSkipStatement(ast AST) AST { + return newAST(ASTKindSkipStatement, ast) +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/value_util.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/value_util.go new file mode 100644 index 0000000..b5480fd --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/value_util.go @@ -0,0 +1,284 @@ +package ini + +import ( + "fmt" +) + +// getStringValue will return a quoted string and the amount +// of bytes read +// +// an error will be returned if the string is not properly formatted +func getStringValue(b []rune) (int, error) { + if b[0] != '"' { + return 0, NewParseError("strings must start with '\"'") + } + + endQuote := false + i := 1 + + for ; i < len(b) && !endQuote; i++ { + if escaped := isEscaped(b[:i], b[i]); b[i] == '"' && !escaped { + endQuote = true + break + } else if escaped { + /*c, err := getEscapedByte(b[i]) + if err != nil { + return 0, err + } + + b[i-1] = c + b = append(b[:i], b[i+1:]...) + i--*/ + + continue + } + } + + if !endQuote { + return 0, NewParseError("missing '\"' in string value") + } + + return i + 1, nil +} + +// getBoolValue will return a boolean and the amount +// of bytes read +// +// an error will be returned if the boolean is not of a correct +// value +func getBoolValue(b []rune) (int, error) { + if len(b) < 4 { + return 0, NewParseError("invalid boolean value") + } + + n := 0 + for _, lv := range literalValues { + if len(lv) > len(b) { + continue + } + + if isCaselessLitValue(lv, b) { + n = len(lv) + } + } + + if n == 0 { + return 0, NewParseError("invalid boolean value") + } + + return n, nil +} + +// getNumericalValue will return a numerical string, the amount +// of bytes read, and the base of the number +// +// an error will be returned if the number is not of a correct +// value +func getNumericalValue(b []rune) (int, int, error) { + if !isDigit(b[0]) { + return 0, 0, NewParseError("invalid digit value") + } + + i := 0 + helper := numberHelper{} + +loop: + for negativeIndex := 0; i < len(b); i++ { + negativeIndex++ + + if !isDigit(b[i]) { + switch b[i] { + case '-': + if helper.IsNegative() || negativeIndex != 1 { + return 0, 0, NewParseError("parse error '-'") + } + + n := getNegativeNumber(b[i:]) + i += (n - 1) + helper.Determine(b[i]) + continue + case '.': + if err := helper.Determine(b[i]); err != nil { + return 0, 0, err + } + case 'e', 'E': + if err := helper.Determine(b[i]); err != nil { + return 0, 0, err + } + + negativeIndex = 0 + case 'b': + if helper.numberFormat == hex { + break + } + fallthrough + case 'o', 'x': + if i == 0 && b[i] != '0' { + return 0, 0, NewParseError("incorrect base format, expected leading '0'") + } + + if i != 1 { + return 0, 0, NewParseError(fmt.Sprintf("incorrect base format found %s at %d index", string(b[i]), i)) + } + + if err := helper.Determine(b[i]); err != nil { + return 0, 0, err + } + default: + if isWhitespace(b[i]) { + break loop + } + + if isNewline(b[i:]) { + break loop + } + + if !(helper.numberFormat == hex && isHexByte(b[i])) { + if i+2 < len(b) && !isNewline(b[i:i+2]) { + return 0, 0, NewParseError("invalid numerical character") + } else if !isNewline([]rune{b[i]}) { + return 0, 0, NewParseError("invalid numerical character") + } + + break loop + } + } + } + } + + return helper.Base(), i, nil +} + +// isDigit will return whether or not something is an integer +func isDigit(b rune) bool { + return b >= '0' && b <= '9' +} + +func hasExponent(v []rune) bool { + return contains(v, 'e') || contains(v, 'E') +} + +func isBinaryByte(b rune) bool { + switch b { + case '0', '1': + return true + default: + return false + } +} + +func isOctalByte(b rune) bool { + switch b { + case '0', '1', '2', '3', '4', '5', '6', '7': + return true + default: + return false + } +} + +func isHexByte(b rune) bool { + if isDigit(b) { + return true + } + return (b >= 'A' && b <= 'F') || + (b >= 'a' && b <= 'f') +} + +func getValue(b []rune) (int, error) { + i := 0 + + for i < len(b) { + if isNewline(b[i:]) { + break + } + + if isOp(b[i:]) { + break + } + + valid, n, err := isValid(b[i:]) + if err != nil { + return 0, err + } + + if !valid { + break + } + + i += n + } + + return i, nil +} + +// getNegativeNumber will return a negative number from a +// byte slice. This will iterate through all characters until +// a non-digit has been found. +func getNegativeNumber(b []rune) int { + if b[0] != '-' { + return 0 + } + + i := 1 + for ; i < len(b); i++ { + if !isDigit(b[i]) { + return i + } + } + + return i +} + +// isEscaped will return whether or not the character is an escaped +// character. +func isEscaped(value []rune, b rune) bool { + if len(value) == 0 { + return false + } + + switch b { + case '\'': // single quote + case '"': // quote + case 'n': // newline + case 't': // tab + case '\\': // backslash + default: + return false + } + + return value[len(value)-1] == '\\' +} + +func getEscapedByte(b rune) (rune, error) { + switch b { + case '\'': // single quote + return '\'', nil + case '"': // quote + return '"', nil + case 'n': // newline + return '\n', nil + case 't': // table + return '\t', nil + case '\\': // backslash + return '\\', nil + default: + return b, NewParseError(fmt.Sprintf("invalid escaped character %c", b)) + } +} + +func removeEscapedCharacters(b []rune) []rune { + for i := 0; i < len(b); i++ { + if isEscaped(b[:i], b[i]) { + c, err := getEscapedByte(b[i]) + if err != nil { + return b + } + + b[i-1] = c + b = append(b[:i], b[i+1:]...) + i-- + } + } + + return b +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/visitor.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/visitor.go new file mode 100644 index 0000000..081cf43 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/visitor.go @@ -0,0 +1,169 @@ +package ini + +import ( + "fmt" + "sort" +) + +// Visitor is an interface used by walkers that will +// traverse an array of ASTs. +type Visitor interface { + VisitExpr(AST) error + VisitStatement(AST) error +} + +// DefaultVisitor is used to visit statements and expressions +// and ensure that they are both of the correct format. +// In addition, upon visiting this will build sections and populate +// the Sections field which can be used to retrieve profile +// configuration. +type DefaultVisitor struct { + scope string + Sections Sections +} + +// NewDefaultVisitor return a DefaultVisitor +func NewDefaultVisitor() *DefaultVisitor { + return &DefaultVisitor{ + Sections: Sections{ + container: map[string]Section{}, + }, + } +} + +// VisitExpr visits expressions... +func (v *DefaultVisitor) VisitExpr(expr AST) error { + t := v.Sections.container[v.scope] + if t.values == nil { + t.values = values{} + } + + switch expr.Kind { + case ASTKindExprStatement: + opExpr := expr.GetRoot() + switch opExpr.Kind { + case ASTKindEqualExpr: + children := opExpr.GetChildren() + if len(children) <= 1 { + return NewParseError("unexpected token type") + } + + rhs := children[1] + + // The right-hand value side the equality expression is allowed to contain '[', ']', ':', '=' in the values. + // If the token is not either a literal or one of the token types that identifies those four additional + // tokens then error. + if !(rhs.Root.Type() == TokenLit || rhs.Root.Type() == TokenOp || rhs.Root.Type() == TokenSep) { + return NewParseError("unexpected token type") + } + + key := EqualExprKey(opExpr) + v, err := newValue(rhs.Root.ValueType, rhs.Root.base, rhs.Root.Raw()) + if err != nil { + return err + } + + t.values[key] = v + default: + return NewParseError(fmt.Sprintf("unsupported expression %v", expr)) + } + default: + return NewParseError(fmt.Sprintf("unsupported expression %v", expr)) + } + + v.Sections.container[v.scope] = t + return nil +} + +// VisitStatement visits statements... +func (v *DefaultVisitor) VisitStatement(stmt AST) error { + switch stmt.Kind { + case ASTKindCompletedSectionStatement: + child := stmt.GetRoot() + if child.Kind != ASTKindSectionStatement { + return NewParseError(fmt.Sprintf("unsupported child statement: %T", child)) + } + + name := string(child.Root.Raw()) + v.Sections.container[name] = Section{} + v.scope = name + default: + return NewParseError(fmt.Sprintf("unsupported statement: %s", stmt.Kind)) + } + + return nil +} + +// Sections is a map of Section structures that represent +// a configuration. +type Sections struct { + container map[string]Section +} + +// GetSection will return section p. If section p does not exist, +// false will be returned in the second parameter. +func (t Sections) GetSection(p string) (Section, bool) { + v, ok := t.container[p] + return v, ok +} + +// values represents a map of union values. +type values map[string]Value + +// List will return a list of all sections that were successfully +// parsed. +func (t Sections) List() []string { + keys := make([]string, len(t.container)) + i := 0 + for k := range t.container { + keys[i] = k + i++ + } + + sort.Strings(keys) + return keys +} + +// Section contains a name and values. This represent +// a sectioned entry in a configuration file. +type Section struct { + Name string + values values +} + +// Has will return whether or not an entry exists in a given section +func (t Section) Has(k string) bool { + _, ok := t.values[k] + return ok +} + +// ValueType will returned what type the union is set to. If +// k was not found, the NoneType will be returned. +func (t Section) ValueType(k string) (ValueType, bool) { + v, ok := t.values[k] + return v.Type, ok +} + +// Bool returns a bool value at k +func (t Section) Bool(k string) bool { + return t.values[k].BoolValue() +} + +// Int returns an integer value at k +func (t Section) Int(k string) int64 { + return t.values[k].IntValue() +} + +// Float64 returns a float value at k +func (t Section) Float64(k string) float64 { + return t.values[k].FloatValue() +} + +// String returns the string value at k +func (t Section) String(k string) string { + _, ok := t.values[k] + if !ok { + return "" + } + return t.values[k].StringValue() +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/walker.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/walker.go new file mode 100644 index 0000000..99915f7 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/walker.go @@ -0,0 +1,25 @@ +package ini + +// Walk will traverse the AST using the v, the Visitor. +func Walk(tree []AST, v Visitor) error { + for _, node := range tree { + switch node.Kind { + case ASTKindExpr, + ASTKindExprStatement: + + if err := v.VisitExpr(node); err != nil { + return err + } + case ASTKindStatement, + ASTKindCompletedSectionStatement, + ASTKindNestedSectionStatement, + ASTKindCompletedNestedSectionStatement: + + if err := v.VisitStatement(node); err != nil { + return err + } + } + } + + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/ws_token.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/ws_token.go new file mode 100644 index 0000000..7ffb4ae --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/ws_token.go @@ -0,0 +1,24 @@ +package ini + +import ( + "unicode" +) + +// isWhitespace will return whether or not the character is +// a whitespace character. +// +// Whitespace is defined as a space or tab. +func isWhitespace(c rune) bool { + return unicode.IsSpace(c) && c != '\n' && c != '\r' +} + +func newWSToken(b []rune) (Token, int, error) { + i := 0 + for ; i < len(b); i++ { + if !isWhitespace(b[i]) { + break + } + } + + return newToken(TokenWS, b[:i], NoneType), i, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/sdkio/byte.go b/vendor/github.com/aws/aws-sdk-go/internal/sdkio/byte.go new file mode 100644 index 0000000..6c44398 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/sdkio/byte.go @@ -0,0 +1,12 @@ +package sdkio + +const ( + // Byte is 8 bits + Byte int64 = 1 + // KibiByte (KiB) is 1024 Bytes + KibiByte = Byte * 1024 + // MebiByte (MiB) is 1024 KiB + MebiByte = KibiByte * 1024 + // GibiByte (GiB) is 1024 MiB + GibiByte = MebiByte * 1024 +) diff --git a/vendor/github.com/aws/aws-sdk-go/internal/sdkio/io_go1.6.go b/vendor/github.com/aws/aws-sdk-go/internal/sdkio/io_go1.6.go new file mode 100644 index 0000000..037a998 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/sdkio/io_go1.6.go @@ -0,0 +1,11 @@ +//go:build !go1.7 +// +build !go1.7 + +package sdkio + +// Copy of Go 1.7 io package's Seeker constants. +const ( + SeekStart = 0 // seek relative to the origin of the file + SeekCurrent = 1 // seek relative to the current offset + SeekEnd = 2 // seek relative to the end +) diff --git a/vendor/github.com/aws/aws-sdk-go/internal/sdkio/io_go1.7.go b/vendor/github.com/aws/aws-sdk-go/internal/sdkio/io_go1.7.go new file mode 100644 index 0000000..65e7c60 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/sdkio/io_go1.7.go @@ -0,0 +1,13 @@ +//go:build go1.7 +// +build go1.7 + +package sdkio + +import "io" + +// Alias for Go 1.7 io package Seeker constants +const ( + SeekStart = io.SeekStart // seek relative to the origin of the file + SeekCurrent = io.SeekCurrent // seek relative to the current offset + SeekEnd = io.SeekEnd // seek relative to the end +) diff --git a/vendor/github.com/aws/aws-sdk-go/internal/sdkmath/floor.go b/vendor/github.com/aws/aws-sdk-go/internal/sdkmath/floor.go new file mode 100644 index 0000000..a845287 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/sdkmath/floor.go @@ -0,0 +1,16 @@ +//go:build go1.10 +// +build go1.10 + +package sdkmath + +import "math" + +// Round returns the nearest integer, rounding half away from zero. +// +// Special cases are: +// Round(±0) = ±0 +// Round(±Inf) = ±Inf +// Round(NaN) = NaN +func Round(x float64) float64 { + return math.Round(x) +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/sdkmath/floor_go1.9.go b/vendor/github.com/aws/aws-sdk-go/internal/sdkmath/floor_go1.9.go new file mode 100644 index 0000000..a3ae3e5 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/sdkmath/floor_go1.9.go @@ -0,0 +1,57 @@ +//go:build !go1.10 +// +build !go1.10 + +package sdkmath + +import "math" + +// Copied from the Go standard library's (Go 1.12) math/floor.go for use in +// Go version prior to Go 1.10. +const ( + uvone = 0x3FF0000000000000 + mask = 0x7FF + shift = 64 - 11 - 1 + bias = 1023 + signMask = 1 << 63 + fracMask = 1<= 0.5 { + // return t + Copysign(1, x) + // } + // return t + // } + bits := math.Float64bits(x) + e := uint(bits>>shift) & mask + if e < bias { + // Round abs(x) < 1 including denormals. + bits &= signMask // +-0 + if e == bias-1 { + bits |= uvone // +-1 + } + } else if e < bias+shift { + // Round any abs(x) >= 1 containing a fractional component [0,1). + // + // Numbers with larger exponents are returned unchanged since they + // must be either an integer, infinity, or NaN. + const half = 1 << (shift - 1) + e -= bias + bits += half >> e + bits &^= fracMask >> e + } + return math.Float64frombits(bits) +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/sdkrand/locked_source.go b/vendor/github.com/aws/aws-sdk-go/internal/sdkrand/locked_source.go new file mode 100644 index 0000000..0c9802d --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/sdkrand/locked_source.go @@ -0,0 +1,29 @@ +package sdkrand + +import ( + "math/rand" + "sync" + "time" +) + +// lockedSource is a thread-safe implementation of rand.Source +type lockedSource struct { + lk sync.Mutex + src rand.Source +} + +func (r *lockedSource) Int63() (n int64) { + r.lk.Lock() + n = r.src.Int63() + r.lk.Unlock() + return +} + +func (r *lockedSource) Seed(seed int64) { + r.lk.Lock() + r.src.Seed(seed) + r.lk.Unlock() +} + +// SeededRand is a new RNG using a thread safe implementation of rand.Source +var SeededRand = rand.New(&lockedSource{src: rand.NewSource(time.Now().UnixNano())}) diff --git a/vendor/github.com/aws/aws-sdk-go/internal/sdkrand/read.go b/vendor/github.com/aws/aws-sdk-go/internal/sdkrand/read.go new file mode 100644 index 0000000..4bae66c --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/sdkrand/read.go @@ -0,0 +1,12 @@ +//go:build go1.6 +// +build go1.6 + +package sdkrand + +import "math/rand" + +// Read provides the stub for math.Rand.Read method support for go version's +// 1.6 and greater. +func Read(r *rand.Rand, p []byte) (int, error) { + return r.Read(p) +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/sdkrand/read_1_5.go b/vendor/github.com/aws/aws-sdk-go/internal/sdkrand/read_1_5.go new file mode 100644 index 0000000..3a6ab88 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/sdkrand/read_1_5.go @@ -0,0 +1,25 @@ +//go:build !go1.6 +// +build !go1.6 + +package sdkrand + +import "math/rand" + +// Read backfills Go 1.6's math.Rand.Reader for Go 1.5 +func Read(r *rand.Rand, p []byte) (n int, err error) { + // Copy of Go standard libraries math package's read function not added to + // standard library until Go 1.6. + var pos int8 + var val int64 + for n = 0; n < len(p); n++ { + if pos == 0 { + val = r.Int63() + pos = 7 + } + p[n] = byte(val) + val >>= 8 + pos-- + } + + return n, err +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/shareddefaults/ecs_container.go b/vendor/github.com/aws/aws-sdk-go/internal/shareddefaults/ecs_container.go new file mode 100644 index 0000000..7da8a49 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/shareddefaults/ecs_container.go @@ -0,0 +1,12 @@ +package shareddefaults + +const ( + // ECSCredsProviderEnvVar is an environmental variable key used to + // determine which path needs to be hit. + ECSCredsProviderEnvVar = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" +) + +// ECSContainerCredentialsURI is the endpoint to retrieve container +// credentials. This can be overridden to test to ensure the credential process +// is behaving correctly. +var ECSContainerCredentialsURI = "http://169.254.170.2" diff --git a/vendor/github.com/aws/aws-sdk-go/internal/shareddefaults/shared_config.go b/vendor/github.com/aws/aws-sdk-go/internal/shareddefaults/shared_config.go new file mode 100644 index 0000000..ebcbc2b --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/shareddefaults/shared_config.go @@ -0,0 +1,40 @@ +package shareddefaults + +import ( + "os" + "path/filepath" + "runtime" +) + +// SharedCredentialsFilename returns the SDK's default file path +// for the shared credentials file. +// +// Builds the shared config file path based on the OS's platform. +// +// - Linux/Unix: $HOME/.aws/credentials +// - Windows: %USERPROFILE%\.aws\credentials +func SharedCredentialsFilename() string { + return filepath.Join(UserHomeDir(), ".aws", "credentials") +} + +// SharedConfigFilename returns the SDK's default file path for +// the shared config file. +// +// Builds the shared config file path based on the OS's platform. +// +// - Linux/Unix: $HOME/.aws/config +// - Windows: %USERPROFILE%\.aws\config +func SharedConfigFilename() string { + return filepath.Join(UserHomeDir(), ".aws", "config") +} + +// UserHomeDir returns the home directory for the user the process is +// running under. +func UserHomeDir() string { + if runtime.GOOS == "windows" { // Windows + return os.Getenv("USERPROFILE") + } + + // *nix + return os.Getenv("HOME") +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/strings/strings.go b/vendor/github.com/aws/aws-sdk-go/internal/strings/strings.go new file mode 100644 index 0000000..d008ae2 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/strings/strings.go @@ -0,0 +1,11 @@ +package strings + +import ( + "strings" +) + +// HasPrefixFold tests whether the string s begins with prefix, interpreted as UTF-8 strings, +// under Unicode case-folding. +func HasPrefixFold(s, prefix string) bool { + return len(s) >= len(prefix) && strings.EqualFold(s[0:len(prefix)], prefix) +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/sync/singleflight/LICENSE b/vendor/github.com/aws/aws-sdk-go/internal/sync/singleflight/LICENSE new file mode 100644 index 0000000..6a66aea --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/sync/singleflight/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/aws/aws-sdk-go/internal/sync/singleflight/singleflight.go b/vendor/github.com/aws/aws-sdk-go/internal/sync/singleflight/singleflight.go new file mode 100644 index 0000000..14ad0c5 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/sync/singleflight/singleflight.go @@ -0,0 +1,120 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package singleflight provides a duplicate function call suppression +// mechanism. +package singleflight + +import "sync" + +// call is an in-flight or completed singleflight.Do call +type call struct { + wg sync.WaitGroup + + // These fields are written once before the WaitGroup is done + // and are only read after the WaitGroup is done. + val interface{} + err error + + // forgotten indicates whether Forget was called with this call's key + // while the call was still in flight. + forgotten bool + + // These fields are read and written with the singleflight + // mutex held before the WaitGroup is done, and are read but + // not written after the WaitGroup is done. + dups int + chans []chan<- Result +} + +// Group represents a class of work and forms a namespace in +// which units of work can be executed with duplicate suppression. +type Group struct { + mu sync.Mutex // protects m + m map[string]*call // lazily initialized +} + +// Result holds the results of Do, so they can be passed +// on a channel. +type Result struct { + Val interface{} + Err error + Shared bool +} + +// Do executes and returns the results of the given function, making +// sure that only one execution is in-flight for a given key at a +// time. If a duplicate comes in, the duplicate caller waits for the +// original to complete and receives the same results. +// The return value shared indicates whether v was given to multiple callers. +func (g *Group) Do(key string, fn func() (interface{}, error)) (v interface{}, err error, shared bool) { + g.mu.Lock() + if g.m == nil { + g.m = make(map[string]*call) + } + if c, ok := g.m[key]; ok { + c.dups++ + g.mu.Unlock() + c.wg.Wait() + return c.val, c.err, true + } + c := new(call) + c.wg.Add(1) + g.m[key] = c + g.mu.Unlock() + + g.doCall(c, key, fn) + return c.val, c.err, c.dups > 0 +} + +// DoChan is like Do but returns a channel that will receive the +// results when they are ready. +func (g *Group) DoChan(key string, fn func() (interface{}, error)) <-chan Result { + ch := make(chan Result, 1) + g.mu.Lock() + if g.m == nil { + g.m = make(map[string]*call) + } + if c, ok := g.m[key]; ok { + c.dups++ + c.chans = append(c.chans, ch) + g.mu.Unlock() + return ch + } + c := &call{chans: []chan<- Result{ch}} + c.wg.Add(1) + g.m[key] = c + g.mu.Unlock() + + go g.doCall(c, key, fn) + + return ch +} + +// doCall handles the single call for a key. +func (g *Group) doCall(c *call, key string, fn func() (interface{}, error)) { + c.val, c.err = fn() + c.wg.Done() + + g.mu.Lock() + if !c.forgotten { + delete(g.m, key) + } + for _, ch := range c.chans { + ch <- Result{c.val, c.err, c.dups > 0} + } + g.mu.Unlock() +} + +// Forget tells the singleflight to forget about a key. Future calls +// to Do for this key will call the function rather than waiting for +// an earlier call to complete. +func (g *Group) Forget(key string) { + g.mu.Lock() + if c, ok := g.m[key]; ok { + c.forgotten = true + } + delete(g.m, key) + g.mu.Unlock() +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/host.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/host.go new file mode 100644 index 0000000..1f1d27a --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/host.go @@ -0,0 +1,104 @@ +package protocol + +import ( + "github.com/aws/aws-sdk-go/aws/request" + "net" + "strconv" + "strings" +) + +// ValidateEndpointHostHandler is a request handler that will validate the +// request endpoint's hosts is a valid RFC 3986 host. +var ValidateEndpointHostHandler = request.NamedHandler{ + Name: "awssdk.protocol.ValidateEndpointHostHandler", + Fn: func(r *request.Request) { + err := ValidateEndpointHost(r.Operation.Name, r.HTTPRequest.URL.Host) + if err != nil { + r.Error = err + } + }, +} + +// ValidateEndpointHost validates that the host string passed in is a valid RFC +// 3986 host. Returns error if the host is not valid. +func ValidateEndpointHost(opName, host string) error { + paramErrs := request.ErrInvalidParams{Context: opName} + + var hostname string + var port string + var err error + + if strings.Contains(host, ":") { + hostname, port, err = net.SplitHostPort(host) + + if err != nil { + paramErrs.Add(request.NewErrParamFormat("endpoint", err.Error(), host)) + } + + if !ValidPortNumber(port) { + paramErrs.Add(request.NewErrParamFormat("endpoint port number", "[0-65535]", port)) + } + } else { + hostname = host + } + + labels := strings.Split(hostname, ".") + for i, label := range labels { + if i == len(labels)-1 && len(label) == 0 { + // Allow trailing dot for FQDN hosts. + continue + } + + if !ValidHostLabel(label) { + paramErrs.Add(request.NewErrParamFormat( + "endpoint host label", "[a-zA-Z0-9-]{1,63}", label)) + } + } + + if len(hostname) == 0 { + paramErrs.Add(request.NewErrParamMinLen("endpoint host", 1)) + } + + if len(hostname) > 255 { + paramErrs.Add(request.NewErrParamMaxLen( + "endpoint host", 255, host, + )) + } + + if paramErrs.Len() > 0 { + return paramErrs + } + return nil +} + +// ValidHostLabel returns if the label is a valid RFC 3986 host label. +func ValidHostLabel(label string) bool { + if l := len(label); l == 0 || l > 63 { + return false + } + for _, r := range label { + switch { + case r >= '0' && r <= '9': + case r >= 'A' && r <= 'Z': + case r >= 'a' && r <= 'z': + case r == '-': + default: + return false + } + } + + return true +} + +// ValidPortNumber return if the port is valid RFC 3986 port +func ValidPortNumber(port string) bool { + i, err := strconv.Atoi(port) + if err != nil { + return false + } + + if i < 0 || i > 65535 { + return false + } + return true +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/host_prefix.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/host_prefix.go new file mode 100644 index 0000000..915b0fc --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/host_prefix.go @@ -0,0 +1,54 @@ +package protocol + +import ( + "strings" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/request" +) + +// HostPrefixHandlerName is the handler name for the host prefix request +// handler. +const HostPrefixHandlerName = "awssdk.endpoint.HostPrefixHandler" + +// NewHostPrefixHandler constructs a build handler +func NewHostPrefixHandler(prefix string, labelsFn func() map[string]string) request.NamedHandler { + builder := HostPrefixBuilder{ + Prefix: prefix, + LabelsFn: labelsFn, + } + + return request.NamedHandler{ + Name: HostPrefixHandlerName, + Fn: builder.Build, + } +} + +// HostPrefixBuilder provides the request handler to expand and prepend +// the host prefix into the operation's request endpoint host. +type HostPrefixBuilder struct { + Prefix string + LabelsFn func() map[string]string +} + +// Build updates the passed in Request with the HostPrefix template expanded. +func (h HostPrefixBuilder) Build(r *request.Request) { + if aws.BoolValue(r.Config.DisableEndpointHostPrefix) { + return + } + + var labels map[string]string + if h.LabelsFn != nil { + labels = h.LabelsFn() + } + + prefix := h.Prefix + for name, value := range labels { + prefix = strings.Replace(prefix, "{"+name+"}", value, -1) + } + + r.HTTPRequest.URL.Host = prefix + r.HTTPRequest.URL.Host + if len(r.HTTPRequest.Host) > 0 { + r.HTTPRequest.Host = prefix + r.HTTPRequest.Host + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/idempotency.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/idempotency.go new file mode 100644 index 0000000..53831df --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/idempotency.go @@ -0,0 +1,75 @@ +package protocol + +import ( + "crypto/rand" + "fmt" + "reflect" +) + +// RandReader is the random reader the protocol package will use to read +// random bytes from. This is exported for testing, and should not be used. +var RandReader = rand.Reader + +const idempotencyTokenFillTag = `idempotencyToken` + +// CanSetIdempotencyToken returns true if the struct field should be +// automatically populated with a Idempotency token. +// +// Only *string and string type fields that are tagged with idempotencyToken +// which are not already set can be auto filled. +func CanSetIdempotencyToken(v reflect.Value, f reflect.StructField) bool { + switch u := v.Interface().(type) { + // To auto fill an Idempotency token the field must be a string, + // tagged for auto fill, and have a zero value. + case *string: + return u == nil && len(f.Tag.Get(idempotencyTokenFillTag)) != 0 + case string: + return len(u) == 0 && len(f.Tag.Get(idempotencyTokenFillTag)) != 0 + } + + return false +} + +// GetIdempotencyToken returns a randomly generated idempotency token. +func GetIdempotencyToken() string { + b := make([]byte, 16) + RandReader.Read(b) + + return UUIDVersion4(b) +} + +// SetIdempotencyToken will set the value provided with a Idempotency Token. +// Given that the value can be set. Will panic if value is not setable. +func SetIdempotencyToken(v reflect.Value) { + if v.Kind() == reflect.Ptr { + if v.IsNil() && v.CanSet() { + v.Set(reflect.New(v.Type().Elem())) + } + v = v.Elem() + } + v = reflect.Indirect(v) + + if !v.CanSet() { + panic(fmt.Sprintf("unable to set idempotnecy token %v", v)) + } + + b := make([]byte, 16) + _, err := rand.Read(b) + if err != nil { + // TODO handle error + return + } + + v.Set(reflect.ValueOf(UUIDVersion4(b))) +} + +// UUIDVersion4 returns a Version 4 random UUID from the byte slice provided +func UUIDVersion4(u []byte) string { + // https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_.28random.29 + // 13th character is "4" + u[6] = (u[6] | 0x40) & 0x4F + // 17th character is "8", "9", "a", or "b" + u[8] = (u[8] | 0x80) & 0xBF + + return fmt.Sprintf(`%X-%X-%X-%X-%X`, u[0:4], u[4:6], u[6:8], u[8:10], u[10:]) +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/build.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/build.go new file mode 100644 index 0000000..2aec806 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/build.go @@ -0,0 +1,298 @@ +// Package jsonutil provides JSON serialization of AWS requests and responses. +package jsonutil + +import ( + "bytes" + "encoding/base64" + "encoding/json" + "fmt" + "math" + "reflect" + "sort" + "strconv" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/private/protocol" +) + +var timeType = reflect.ValueOf(time.Time{}).Type() +var byteSliceType = reflect.ValueOf([]byte{}).Type() + +// BuildJSON builds a JSON string for a given object v. +func BuildJSON(v interface{}) ([]byte, error) { + var buf bytes.Buffer + + err := buildAny(reflect.ValueOf(v), &buf, "") + return buf.Bytes(), err +} + +func buildAny(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error { + origVal := value + value = reflect.Indirect(value) + if !value.IsValid() { + return nil + } + + vtype := value.Type() + + t := tag.Get("type") + if t == "" { + switch vtype.Kind() { + case reflect.Struct: + // also it can't be a time object + if value.Type() != timeType { + t = "structure" + } + case reflect.Slice: + // also it can't be a byte slice + if _, ok := value.Interface().([]byte); !ok { + t = "list" + } + case reflect.Map: + // cannot be a JSONValue map + if _, ok := value.Interface().(aws.JSONValue); !ok { + t = "map" + } + } + } + + switch t { + case "structure": + if field, ok := vtype.FieldByName("_"); ok { + tag = field.Tag + } + return buildStruct(value, buf, tag) + case "list": + return buildList(value, buf, tag) + case "map": + return buildMap(value, buf, tag) + default: + return buildScalar(origVal, buf, tag) + } +} + +func buildStruct(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error { + if !value.IsValid() { + return nil + } + + // unwrap payloads + if payload := tag.Get("payload"); payload != "" { + field, _ := value.Type().FieldByName(payload) + tag = field.Tag + value = elemOf(value.FieldByName(payload)) + if !value.IsValid() && tag.Get("type") != "structure" { + return nil + } + } + + buf.WriteByte('{') + defer buf.WriteString("}") + + if !value.IsValid() { + return nil + } + + t := value.Type() + first := true + for i := 0; i < t.NumField(); i++ { + member := value.Field(i) + + // This allocates the most memory. + // Additionally, we cannot skip nil fields due to + // idempotency auto filling. + field := t.Field(i) + + if field.PkgPath != "" { + continue // ignore unexported fields + } + if field.Tag.Get("json") == "-" { + continue + } + if field.Tag.Get("location") != "" { + continue // ignore non-body elements + } + if field.Tag.Get("ignore") != "" { + continue + } + + if protocol.CanSetIdempotencyToken(member, field) { + token := protocol.GetIdempotencyToken() + member = reflect.ValueOf(&token) + } + + if (member.Kind() == reflect.Ptr || member.Kind() == reflect.Slice || member.Kind() == reflect.Map) && member.IsNil() { + continue // ignore unset fields + } + + if first { + first = false + } else { + buf.WriteByte(',') + } + + // figure out what this field is called + name := field.Name + if locName := field.Tag.Get("locationName"); locName != "" { + name = locName + } + + writeString(name, buf) + buf.WriteString(`:`) + + err := buildAny(member, buf, field.Tag) + if err != nil { + return err + } + + } + + return nil +} + +func buildList(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error { + buf.WriteString("[") + + for i := 0; i < value.Len(); i++ { + buildAny(value.Index(i), buf, "") + + if i < value.Len()-1 { + buf.WriteString(",") + } + } + + buf.WriteString("]") + + return nil +} + +type sortedValues []reflect.Value + +func (sv sortedValues) Len() int { return len(sv) } +func (sv sortedValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] } +func (sv sortedValues) Less(i, j int) bool { return sv[i].String() < sv[j].String() } + +func buildMap(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error { + buf.WriteString("{") + + sv := sortedValues(value.MapKeys()) + sort.Sort(sv) + + for i, k := range sv { + if i > 0 { + buf.WriteByte(',') + } + + writeString(k.String(), buf) + buf.WriteString(`:`) + + buildAny(value.MapIndex(k), buf, "") + } + + buf.WriteString("}") + + return nil +} + +func buildScalar(v reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error { + // prevents allocation on the heap. + scratch := [64]byte{} + switch value := reflect.Indirect(v); value.Kind() { + case reflect.String: + writeString(value.String(), buf) + case reflect.Bool: + if value.Bool() { + buf.WriteString("true") + } else { + buf.WriteString("false") + } + case reflect.Int64: + buf.Write(strconv.AppendInt(scratch[:0], value.Int(), 10)) + case reflect.Float64: + f := value.Float() + if math.IsInf(f, 0) || math.IsNaN(f) { + return &json.UnsupportedValueError{Value: v, Str: strconv.FormatFloat(f, 'f', -1, 64)} + } + buf.Write(strconv.AppendFloat(scratch[:0], f, 'f', -1, 64)) + default: + switch converted := value.Interface().(type) { + case time.Time: + format := tag.Get("timestampFormat") + if len(format) == 0 { + format = protocol.UnixTimeFormatName + } + + ts := protocol.FormatTime(format, converted) + if format != protocol.UnixTimeFormatName { + ts = `"` + ts + `"` + } + + buf.WriteString(ts) + case []byte: + if !value.IsNil() { + buf.WriteByte('"') + if len(converted) < 1024 { + // for small buffers, using Encode directly is much faster. + dst := make([]byte, base64.StdEncoding.EncodedLen(len(converted))) + base64.StdEncoding.Encode(dst, converted) + buf.Write(dst) + } else { + // for large buffers, avoid unnecessary extra temporary + // buffer space. + enc := base64.NewEncoder(base64.StdEncoding, buf) + enc.Write(converted) + enc.Close() + } + buf.WriteByte('"') + } + case aws.JSONValue: + str, err := protocol.EncodeJSONValue(converted, protocol.QuotedEscape) + if err != nil { + return fmt.Errorf("unable to encode JSONValue, %v", err) + } + buf.WriteString(str) + default: + return fmt.Errorf("unsupported JSON value %v (%s)", value.Interface(), value.Type()) + } + } + return nil +} + +var hex = "0123456789abcdef" + +func writeString(s string, buf *bytes.Buffer) { + buf.WriteByte('"') + for i := 0; i < len(s); i++ { + if s[i] == '"' { + buf.WriteString(`\"`) + } else if s[i] == '\\' { + buf.WriteString(`\\`) + } else if s[i] == '\b' { + buf.WriteString(`\b`) + } else if s[i] == '\f' { + buf.WriteString(`\f`) + } else if s[i] == '\r' { + buf.WriteString(`\r`) + } else if s[i] == '\t' { + buf.WriteString(`\t`) + } else if s[i] == '\n' { + buf.WriteString(`\n`) + } else if s[i] < 32 { + buf.WriteString("\\u00") + buf.WriteByte(hex[s[i]>>4]) + buf.WriteByte(hex[s[i]&0xF]) + } else { + buf.WriteByte(s[i]) + } + } + buf.WriteByte('"') +} + +// Returns the reflection element of a value, if it is a pointer. +func elemOf(value reflect.Value) reflect.Value { + for value.Kind() == reflect.Ptr { + value = value.Elem() + } + return value +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/unmarshal.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/unmarshal.go new file mode 100644 index 0000000..8b2c9bb --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/unmarshal.go @@ -0,0 +1,304 @@ +package jsonutil + +import ( + "bytes" + "encoding/base64" + "encoding/json" + "fmt" + "io" + "math/big" + "reflect" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/private/protocol" +) + +var millisecondsFloat = new(big.Float).SetInt64(1e3) + +// UnmarshalJSONError unmarshal's the reader's JSON document into the passed in +// type. The value to unmarshal the json document into must be a pointer to the +// type. +func UnmarshalJSONError(v interface{}, stream io.Reader) error { + var errBuf bytes.Buffer + body := io.TeeReader(stream, &errBuf) + + err := json.NewDecoder(body).Decode(v) + if err != nil { + msg := "failed decoding error message" + if err == io.EOF { + msg = "error message missing" + err = nil + } + return awserr.NewUnmarshalError(err, msg, errBuf.Bytes()) + } + + return nil +} + +// UnmarshalJSON reads a stream and unmarshals the results in object v. +func UnmarshalJSON(v interface{}, stream io.Reader) error { + var out interface{} + + decoder := json.NewDecoder(stream) + decoder.UseNumber() + err := decoder.Decode(&out) + if err == io.EOF { + return nil + } else if err != nil { + return err + } + + return unmarshaler{}.unmarshalAny(reflect.ValueOf(v), out, "") +} + +// UnmarshalJSONCaseInsensitive reads a stream and unmarshals the result into the +// object v. Ignores casing for structure members. +func UnmarshalJSONCaseInsensitive(v interface{}, stream io.Reader) error { + var out interface{} + + decoder := json.NewDecoder(stream) + decoder.UseNumber() + err := decoder.Decode(&out) + if err == io.EOF { + return nil + } else if err != nil { + return err + } + + return unmarshaler{ + caseInsensitive: true, + }.unmarshalAny(reflect.ValueOf(v), out, "") +} + +type unmarshaler struct { + caseInsensitive bool +} + +func (u unmarshaler) unmarshalAny(value reflect.Value, data interface{}, tag reflect.StructTag) error { + vtype := value.Type() + if vtype.Kind() == reflect.Ptr { + vtype = vtype.Elem() // check kind of actual element type + } + + t := tag.Get("type") + if t == "" { + switch vtype.Kind() { + case reflect.Struct: + // also it can't be a time object + if _, ok := value.Interface().(*time.Time); !ok { + t = "structure" + } + case reflect.Slice: + // also it can't be a byte slice + if _, ok := value.Interface().([]byte); !ok { + t = "list" + } + case reflect.Map: + // cannot be a JSONValue map + if _, ok := value.Interface().(aws.JSONValue); !ok { + t = "map" + } + } + } + + switch t { + case "structure": + if field, ok := vtype.FieldByName("_"); ok { + tag = field.Tag + } + return u.unmarshalStruct(value, data, tag) + case "list": + return u.unmarshalList(value, data, tag) + case "map": + return u.unmarshalMap(value, data, tag) + default: + return u.unmarshalScalar(value, data, tag) + } +} + +func (u unmarshaler) unmarshalStruct(value reflect.Value, data interface{}, tag reflect.StructTag) error { + if data == nil { + return nil + } + mapData, ok := data.(map[string]interface{}) + if !ok { + return fmt.Errorf("JSON value is not a structure (%#v)", data) + } + + t := value.Type() + if value.Kind() == reflect.Ptr { + if value.IsNil() { // create the structure if it's nil + s := reflect.New(value.Type().Elem()) + value.Set(s) + value = s + } + + value = value.Elem() + t = t.Elem() + } + + // unwrap any payloads + if payload := tag.Get("payload"); payload != "" { + field, _ := t.FieldByName(payload) + return u.unmarshalAny(value.FieldByName(payload), data, field.Tag) + } + + for i := 0; i < t.NumField(); i++ { + field := t.Field(i) + if field.PkgPath != "" { + continue // ignore unexported fields + } + + // figure out what this field is called + name := field.Name + if locName := field.Tag.Get("locationName"); locName != "" { + name = locName + } + if u.caseInsensitive { + if _, ok := mapData[name]; !ok { + // Fallback to uncased name search if the exact name didn't match. + for kn, v := range mapData { + if strings.EqualFold(kn, name) { + mapData[name] = v + } + } + } + } + + member := value.FieldByIndex(field.Index) + err := u.unmarshalAny(member, mapData[name], field.Tag) + if err != nil { + return err + } + } + return nil +} + +func (u unmarshaler) unmarshalList(value reflect.Value, data interface{}, tag reflect.StructTag) error { + if data == nil { + return nil + } + listData, ok := data.([]interface{}) + if !ok { + return fmt.Errorf("JSON value is not a list (%#v)", data) + } + + if value.IsNil() { + l := len(listData) + value.Set(reflect.MakeSlice(value.Type(), l, l)) + } + + for i, c := range listData { + err := u.unmarshalAny(value.Index(i), c, "") + if err != nil { + return err + } + } + + return nil +} + +func (u unmarshaler) unmarshalMap(value reflect.Value, data interface{}, tag reflect.StructTag) error { + if data == nil { + return nil + } + mapData, ok := data.(map[string]interface{}) + if !ok { + return fmt.Errorf("JSON value is not a map (%#v)", data) + } + + if value.IsNil() { + value.Set(reflect.MakeMap(value.Type())) + } + + for k, v := range mapData { + kvalue := reflect.ValueOf(k) + vvalue := reflect.New(value.Type().Elem()).Elem() + + u.unmarshalAny(vvalue, v, "") + value.SetMapIndex(kvalue, vvalue) + } + + return nil +} + +func (u unmarshaler) unmarshalScalar(value reflect.Value, data interface{}, tag reflect.StructTag) error { + + switch d := data.(type) { + case nil: + return nil // nothing to do here + case string: + switch value.Interface().(type) { + case *string: + value.Set(reflect.ValueOf(&d)) + case []byte: + b, err := base64.StdEncoding.DecodeString(d) + if err != nil { + return err + } + value.Set(reflect.ValueOf(b)) + case *time.Time: + format := tag.Get("timestampFormat") + if len(format) == 0 { + format = protocol.ISO8601TimeFormatName + } + + t, err := protocol.ParseTime(format, d) + if err != nil { + return err + } + value.Set(reflect.ValueOf(&t)) + case aws.JSONValue: + // No need to use escaping as the value is a non-quoted string. + v, err := protocol.DecodeJSONValue(d, protocol.NoEscape) + if err != nil { + return err + } + value.Set(reflect.ValueOf(v)) + default: + return fmt.Errorf("unsupported value: %v (%s)", value.Interface(), value.Type()) + } + case json.Number: + switch value.Interface().(type) { + case *int64: + // Retain the old behavior where we would just truncate the float64 + // calling d.Int64() here could cause an invalid syntax error due to the usage of strconv.ParseInt + f, err := d.Float64() + if err != nil { + return err + } + di := int64(f) + value.Set(reflect.ValueOf(&di)) + case *float64: + f, err := d.Float64() + if err != nil { + return err + } + value.Set(reflect.ValueOf(&f)) + case *time.Time: + float, ok := new(big.Float).SetString(d.String()) + if !ok { + return fmt.Errorf("unsupported float time representation: %v", d.String()) + } + float = float.Mul(float, millisecondsFloat) + ms, _ := float.Int64() + t := time.Unix(0, ms*1e6).UTC() + value.Set(reflect.ValueOf(&t)) + default: + return fmt.Errorf("unsupported value: %v (%s)", value.Interface(), value.Type()) + } + case bool: + switch value.Interface().(type) { + case *bool: + value.Set(reflect.ValueOf(&d)) + default: + return fmt.Errorf("unsupported value: %v (%s)", value.Interface(), value.Type()) + } + default: + return fmt.Errorf("unsupported JSON value (%v)", data) + } + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/jsonrpc/jsonrpc.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/jsonrpc/jsonrpc.go new file mode 100644 index 0000000..d9aa271 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/jsonrpc/jsonrpc.go @@ -0,0 +1,87 @@ +// Package jsonrpc provides JSON RPC utilities for serialization of AWS +// requests and responses. +package jsonrpc + +//go:generate go run -tags codegen ../../../private/model/cli/gen-protocol-tests ../../../models/protocol_tests/input/json.json build_test.go +//go:generate go run -tags codegen ../../../private/model/cli/gen-protocol-tests ../../../models/protocol_tests/output/json.json unmarshal_test.go + +import ( + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol/json/jsonutil" + "github.com/aws/aws-sdk-go/private/protocol/rest" +) + +var emptyJSON = []byte("{}") + +// BuildHandler is a named request handler for building jsonrpc protocol +// requests +var BuildHandler = request.NamedHandler{ + Name: "awssdk.jsonrpc.Build", + Fn: Build, +} + +// UnmarshalHandler is a named request handler for unmarshaling jsonrpc +// protocol requests +var UnmarshalHandler = request.NamedHandler{ + Name: "awssdk.jsonrpc.Unmarshal", + Fn: Unmarshal, +} + +// UnmarshalMetaHandler is a named request handler for unmarshaling jsonrpc +// protocol request metadata +var UnmarshalMetaHandler = request.NamedHandler{ + Name: "awssdk.jsonrpc.UnmarshalMeta", + Fn: UnmarshalMeta, +} + +// Build builds a JSON payload for a JSON RPC request. +func Build(req *request.Request) { + var buf []byte + var err error + if req.ParamsFilled() { + buf, err = jsonutil.BuildJSON(req.Params) + if err != nil { + req.Error = awserr.New(request.ErrCodeSerialization, "failed encoding JSON RPC request", err) + return + } + } else { + buf = emptyJSON + } + + // Always serialize the body, don't suppress it. + req.SetBufferBody(buf) + + if req.ClientInfo.TargetPrefix != "" { + target := req.ClientInfo.TargetPrefix + "." + req.Operation.Name + req.HTTPRequest.Header.Add("X-Amz-Target", target) + } + + // Only set the content type if one is not already specified and an + // JSONVersion is specified. + if ct, v := req.HTTPRequest.Header.Get("Content-Type"), req.ClientInfo.JSONVersion; len(ct) == 0 && len(v) != 0 { + jsonVersion := req.ClientInfo.JSONVersion + req.HTTPRequest.Header.Set("Content-Type", "application/x-amz-json-"+jsonVersion) + } +} + +// Unmarshal unmarshals a response for a JSON RPC service. +func Unmarshal(req *request.Request) { + defer req.HTTPResponse.Body.Close() + if req.DataFilled() { + err := jsonutil.UnmarshalJSON(req.Data, req.HTTPResponse.Body) + if err != nil { + req.Error = awserr.NewRequestFailure( + awserr.New(request.ErrCodeSerialization, "failed decoding JSON RPC response", err), + req.HTTPResponse.StatusCode, + req.RequestID, + ) + } + } + return +} + +// UnmarshalMeta unmarshals headers from a response for a JSON RPC service. +func UnmarshalMeta(req *request.Request) { + rest.UnmarshalMeta(req) +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/jsonrpc/unmarshal_error.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/jsonrpc/unmarshal_error.go new file mode 100644 index 0000000..c0c52e2 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/jsonrpc/unmarshal_error.go @@ -0,0 +1,107 @@ +package jsonrpc + +import ( + "bytes" + "io" + "io/ioutil" + "net/http" + "strings" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol" + "github.com/aws/aws-sdk-go/private/protocol/json/jsonutil" +) + +// UnmarshalTypedError provides unmarshaling errors API response errors +// for both typed and untyped errors. +type UnmarshalTypedError struct { + exceptions map[string]func(protocol.ResponseMetadata) error +} + +// NewUnmarshalTypedError returns an UnmarshalTypedError initialized for the +// set of exception names to the error unmarshalers +func NewUnmarshalTypedError(exceptions map[string]func(protocol.ResponseMetadata) error) *UnmarshalTypedError { + return &UnmarshalTypedError{ + exceptions: exceptions, + } +} + +// UnmarshalError attempts to unmarshal the HTTP response error as a known +// error type. If unable to unmarshal the error type, the generic SDK error +// type will be used. +func (u *UnmarshalTypedError) UnmarshalError( + resp *http.Response, + respMeta protocol.ResponseMetadata, +) (error, error) { + + var buf bytes.Buffer + var jsonErr jsonErrorResponse + teeReader := io.TeeReader(resp.Body, &buf) + err := jsonutil.UnmarshalJSONError(&jsonErr, teeReader) + if err != nil { + return nil, err + } + body := ioutil.NopCloser(&buf) + + // Code may be separated by hash(#), with the last element being the code + // used by the SDK. + codeParts := strings.SplitN(jsonErr.Code, "#", 2) + code := codeParts[len(codeParts)-1] + msg := jsonErr.Message + + if fn, ok := u.exceptions[code]; ok { + // If exception code is know, use associated constructor to get a value + // for the exception that the JSON body can be unmarshaled into. + v := fn(respMeta) + err := jsonutil.UnmarshalJSONCaseInsensitive(v, body) + if err != nil { + return nil, err + } + + return v, nil + } + + // fallback to unmodeled generic exceptions + return awserr.NewRequestFailure( + awserr.New(code, msg, nil), + respMeta.StatusCode, + respMeta.RequestID, + ), nil +} + +// UnmarshalErrorHandler is a named request handler for unmarshaling jsonrpc +// protocol request errors +var UnmarshalErrorHandler = request.NamedHandler{ + Name: "awssdk.jsonrpc.UnmarshalError", + Fn: UnmarshalError, +} + +// UnmarshalError unmarshals an error response for a JSON RPC service. +func UnmarshalError(req *request.Request) { + defer req.HTTPResponse.Body.Close() + + var jsonErr jsonErrorResponse + err := jsonutil.UnmarshalJSONError(&jsonErr, req.HTTPResponse.Body) + if err != nil { + req.Error = awserr.NewRequestFailure( + awserr.New(request.ErrCodeSerialization, + "failed to unmarshal error message", err), + req.HTTPResponse.StatusCode, + req.RequestID, + ) + return + } + + codes := strings.SplitN(jsonErr.Code, "#", 2) + req.Error = awserr.NewRequestFailure( + awserr.New(codes[len(codes)-1], jsonErr.Message, nil), + req.HTTPResponse.StatusCode, + req.RequestID, + ) +} + +type jsonErrorResponse struct { + Code string `json:"__type"` + Message string `json:"message"` +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/jsonvalue.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/jsonvalue.go new file mode 100644 index 0000000..776d110 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/jsonvalue.go @@ -0,0 +1,76 @@ +package protocol + +import ( + "encoding/base64" + "encoding/json" + "fmt" + "strconv" + + "github.com/aws/aws-sdk-go/aws" +) + +// EscapeMode is the mode that should be use for escaping a value +type EscapeMode uint + +// The modes for escaping a value before it is marshaled, and unmarshaled. +const ( + NoEscape EscapeMode = iota + Base64Escape + QuotedEscape +) + +// EncodeJSONValue marshals the value into a JSON string, and optionally base64 +// encodes the string before returning it. +// +// Will panic if the escape mode is unknown. +func EncodeJSONValue(v aws.JSONValue, escape EscapeMode) (string, error) { + b, err := json.Marshal(v) + if err != nil { + return "", err + } + + switch escape { + case NoEscape: + return string(b), nil + case Base64Escape: + return base64.StdEncoding.EncodeToString(b), nil + case QuotedEscape: + return strconv.Quote(string(b)), nil + } + + panic(fmt.Sprintf("EncodeJSONValue called with unknown EscapeMode, %v", escape)) +} + +// DecodeJSONValue will attempt to decode the string input as a JSONValue. +// Optionally decoding base64 the value first before JSON unmarshaling. +// +// Will panic if the escape mode is unknown. +func DecodeJSONValue(v string, escape EscapeMode) (aws.JSONValue, error) { + var b []byte + var err error + + switch escape { + case NoEscape: + b = []byte(v) + case Base64Escape: + b, err = base64.StdEncoding.DecodeString(v) + case QuotedEscape: + var u string + u, err = strconv.Unquote(v) + b = []byte(u) + default: + panic(fmt.Sprintf("DecodeJSONValue called with unknown EscapeMode, %v", escape)) + } + + if err != nil { + return nil, err + } + + m := aws.JSONValue{} + err = json.Unmarshal(b, &m) + if err != nil { + return nil, err + } + + return m, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/payload.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/payload.go new file mode 100644 index 0000000..0ea0647 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/payload.go @@ -0,0 +1,81 @@ +package protocol + +import ( + "io" + "io/ioutil" + "net/http" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/client/metadata" + "github.com/aws/aws-sdk-go/aws/request" +) + +// PayloadUnmarshaler provides the interface for unmarshaling a payload's +// reader into a SDK shape. +type PayloadUnmarshaler interface { + UnmarshalPayload(io.Reader, interface{}) error +} + +// HandlerPayloadUnmarshal implements the PayloadUnmarshaler from a +// HandlerList. This provides the support for unmarshaling a payload reader to +// a shape without needing a SDK request first. +type HandlerPayloadUnmarshal struct { + Unmarshalers request.HandlerList +} + +// UnmarshalPayload unmarshals the io.Reader payload into the SDK shape using +// the Unmarshalers HandlerList provided. Returns an error if unable +// unmarshaling fails. +func (h HandlerPayloadUnmarshal) UnmarshalPayload(r io.Reader, v interface{}) error { + req := &request.Request{ + HTTPRequest: &http.Request{}, + HTTPResponse: &http.Response{ + StatusCode: 200, + Header: http.Header{}, + Body: ioutil.NopCloser(r), + }, + Data: v, + } + + h.Unmarshalers.Run(req) + + return req.Error +} + +// PayloadMarshaler provides the interface for marshaling a SDK shape into and +// io.Writer. +type PayloadMarshaler interface { + MarshalPayload(io.Writer, interface{}) error +} + +// HandlerPayloadMarshal implements the PayloadMarshaler from a HandlerList. +// This provides support for marshaling a SDK shape into an io.Writer without +// needing a SDK request first. +type HandlerPayloadMarshal struct { + Marshalers request.HandlerList +} + +// MarshalPayload marshals the SDK shape into the io.Writer using the +// Marshalers HandlerList provided. Returns an error if unable if marshal +// fails. +func (h HandlerPayloadMarshal) MarshalPayload(w io.Writer, v interface{}) error { + req := request.New( + aws.Config{}, + metadata.ClientInfo{}, + request.Handlers{}, + nil, + &request.Operation{HTTPMethod: "PUT"}, + v, + nil, + ) + + h.Marshalers.Run(req) + + if req.Error != nil { + return req.Error + } + + io.Copy(w, req.GetBody()) + + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/protocol.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/protocol.go new file mode 100644 index 0000000..9d521dc --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/protocol.go @@ -0,0 +1,49 @@ +package protocol + +import ( + "fmt" + "strings" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" +) + +// RequireHTTPMinProtocol request handler is used to enforce that +// the target endpoint supports the given major and minor HTTP protocol version. +type RequireHTTPMinProtocol struct { + Major, Minor int +} + +// Handler will mark the request.Request with an error if the +// target endpoint did not connect with the required HTTP protocol +// major and minor version. +func (p RequireHTTPMinProtocol) Handler(r *request.Request) { + if r.Error != nil || r.HTTPResponse == nil { + return + } + + if !strings.HasPrefix(r.HTTPResponse.Proto, "HTTP") { + r.Error = newMinHTTPProtoError(p.Major, p.Minor, r) + } + + if r.HTTPResponse.ProtoMajor < p.Major || r.HTTPResponse.ProtoMinor < p.Minor { + r.Error = newMinHTTPProtoError(p.Major, p.Minor, r) + } +} + +// ErrCodeMinimumHTTPProtocolError error code is returned when the target endpoint +// did not match the required HTTP major and minor protocol version. +const ErrCodeMinimumHTTPProtocolError = "MinimumHTTPProtocolError" + +func newMinHTTPProtoError(major, minor int, r *request.Request) error { + return awserr.NewRequestFailure( + awserr.New("MinimumHTTPProtocolError", + fmt.Sprintf( + "operation requires minimum HTTP protocol of HTTP/%d.%d, but was %s", + major, minor, r.HTTPResponse.Proto, + ), + nil, + ), + r.HTTPResponse.StatusCode, r.RequestID, + ) +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go new file mode 100644 index 0000000..fb35fee --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go @@ -0,0 +1,310 @@ +// Package rest provides RESTful serialization of AWS requests and responses. +package rest + +import ( + "bytes" + "encoding/base64" + "fmt" + "io" + "net/http" + "net/url" + "path" + "reflect" + "strconv" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol" +) + +// Whether the byte value can be sent without escaping in AWS URLs +var noEscape [256]bool + +var errValueNotSet = fmt.Errorf("value not set") + +var byteSliceType = reflect.TypeOf([]byte{}) + +func init() { + for i := 0; i < len(noEscape); i++ { + // AWS expects every character except these to be escaped + noEscape[i] = (i >= 'A' && i <= 'Z') || + (i >= 'a' && i <= 'z') || + (i >= '0' && i <= '9') || + i == '-' || + i == '.' || + i == '_' || + i == '~' + } +} + +// BuildHandler is a named request handler for building rest protocol requests +var BuildHandler = request.NamedHandler{Name: "awssdk.rest.Build", Fn: Build} + +// Build builds the REST component of a service request. +func Build(r *request.Request) { + if r.ParamsFilled() { + v := reflect.ValueOf(r.Params).Elem() + buildLocationElements(r, v, false) + buildBody(r, v) + } +} + +// BuildAsGET builds the REST component of a service request with the ability to hoist +// data from the body. +func BuildAsGET(r *request.Request) { + if r.ParamsFilled() { + v := reflect.ValueOf(r.Params).Elem() + buildLocationElements(r, v, true) + buildBody(r, v) + } +} + +func buildLocationElements(r *request.Request, v reflect.Value, buildGETQuery bool) { + query := r.HTTPRequest.URL.Query() + + // Setup the raw path to match the base path pattern. This is needed + // so that when the path is mutated a custom escaped version can be + // stored in RawPath that will be used by the Go client. + r.HTTPRequest.URL.RawPath = r.HTTPRequest.URL.Path + + for i := 0; i < v.NumField(); i++ { + m := v.Field(i) + if n := v.Type().Field(i).Name; n[0:1] == strings.ToLower(n[0:1]) { + continue + } + + if m.IsValid() { + field := v.Type().Field(i) + name := field.Tag.Get("locationName") + if name == "" { + name = field.Name + } + if kind := m.Kind(); kind == reflect.Ptr { + m = m.Elem() + } else if kind == reflect.Interface { + if !m.Elem().IsValid() { + continue + } + } + if !m.IsValid() { + continue + } + if field.Tag.Get("ignore") != "" { + continue + } + + // Support the ability to customize values to be marshaled as a + // blob even though they were modeled as a string. Required for S3 + // API operations like SSECustomerKey is modeled as string but + // required to be base64 encoded in request. + if field.Tag.Get("marshal-as") == "blob" { + m = m.Convert(byteSliceType) + } + + var err error + switch field.Tag.Get("location") { + case "headers": // header maps + err = buildHeaderMap(&r.HTTPRequest.Header, m, field.Tag) + case "header": + err = buildHeader(&r.HTTPRequest.Header, m, name, field.Tag) + case "uri": + err = buildURI(r.HTTPRequest.URL, m, name, field.Tag) + case "querystring": + err = buildQueryString(query, m, name, field.Tag) + default: + if buildGETQuery { + err = buildQueryString(query, m, name, field.Tag) + } + } + r.Error = err + } + if r.Error != nil { + return + } + } + + r.HTTPRequest.URL.RawQuery = query.Encode() + if !aws.BoolValue(r.Config.DisableRestProtocolURICleaning) { + cleanPath(r.HTTPRequest.URL) + } +} + +func buildBody(r *request.Request, v reflect.Value) { + if field, ok := v.Type().FieldByName("_"); ok { + if payloadName := field.Tag.Get("payload"); payloadName != "" { + pfield, _ := v.Type().FieldByName(payloadName) + if ptag := pfield.Tag.Get("type"); ptag != "" && ptag != "structure" { + payload := reflect.Indirect(v.FieldByName(payloadName)) + if payload.IsValid() && payload.Interface() != nil { + switch reader := payload.Interface().(type) { + case io.ReadSeeker: + r.SetReaderBody(reader) + case []byte: + r.SetBufferBody(reader) + case string: + r.SetStringBody(reader) + default: + r.Error = awserr.New(request.ErrCodeSerialization, + "failed to encode REST request", + fmt.Errorf("unknown payload type %s", payload.Type())) + } + } + } + } + } +} + +func buildHeader(header *http.Header, v reflect.Value, name string, tag reflect.StructTag) error { + str, err := convertType(v, tag) + if err == errValueNotSet { + return nil + } else if err != nil { + return awserr.New(request.ErrCodeSerialization, "failed to encode REST request", err) + } + + name = strings.TrimSpace(name) + str = strings.TrimSpace(str) + + header.Add(name, str) + + return nil +} + +func buildHeaderMap(header *http.Header, v reflect.Value, tag reflect.StructTag) error { + prefix := tag.Get("locationName") + for _, key := range v.MapKeys() { + str, err := convertType(v.MapIndex(key), tag) + if err == errValueNotSet { + continue + } else if err != nil { + return awserr.New(request.ErrCodeSerialization, "failed to encode REST request", err) + + } + keyStr := strings.TrimSpace(key.String()) + str = strings.TrimSpace(str) + + header.Add(prefix+keyStr, str) + } + return nil +} + +func buildURI(u *url.URL, v reflect.Value, name string, tag reflect.StructTag) error { + value, err := convertType(v, tag) + if err == errValueNotSet { + return nil + } else if err != nil { + return awserr.New(request.ErrCodeSerialization, "failed to encode REST request", err) + } + + u.Path = strings.Replace(u.Path, "{"+name+"}", value, -1) + u.Path = strings.Replace(u.Path, "{"+name+"+}", value, -1) + + u.RawPath = strings.Replace(u.RawPath, "{"+name+"}", EscapePath(value, true), -1) + u.RawPath = strings.Replace(u.RawPath, "{"+name+"+}", EscapePath(value, false), -1) + + return nil +} + +func buildQueryString(query url.Values, v reflect.Value, name string, tag reflect.StructTag) error { + switch value := v.Interface().(type) { + case []*string: + for _, item := range value { + query.Add(name, *item) + } + case map[string]*string: + for key, item := range value { + query.Add(key, *item) + } + case map[string][]*string: + for key, items := range value { + for _, item := range items { + query.Add(key, *item) + } + } + default: + str, err := convertType(v, tag) + if err == errValueNotSet { + return nil + } else if err != nil { + return awserr.New(request.ErrCodeSerialization, "failed to encode REST request", err) + } + query.Set(name, str) + } + + return nil +} + +func cleanPath(u *url.URL) { + hasSlash := strings.HasSuffix(u.Path, "/") + + // clean up path, removing duplicate `/` + u.Path = path.Clean(u.Path) + u.RawPath = path.Clean(u.RawPath) + + if hasSlash && !strings.HasSuffix(u.Path, "/") { + u.Path += "/" + u.RawPath += "/" + } +} + +// EscapePath escapes part of a URL path in Amazon style +func EscapePath(path string, encodeSep bool) string { + var buf bytes.Buffer + for i := 0; i < len(path); i++ { + c := path[i] + if noEscape[c] || (c == '/' && !encodeSep) { + buf.WriteByte(c) + } else { + fmt.Fprintf(&buf, "%%%02X", c) + } + } + return buf.String() +} + +func convertType(v reflect.Value, tag reflect.StructTag) (str string, err error) { + v = reflect.Indirect(v) + if !v.IsValid() { + return "", errValueNotSet + } + + switch value := v.Interface().(type) { + case string: + str = value + case []byte: + str = base64.StdEncoding.EncodeToString(value) + case bool: + str = strconv.FormatBool(value) + case int64: + str = strconv.FormatInt(value, 10) + case float64: + str = strconv.FormatFloat(value, 'f', -1, 64) + case time.Time: + format := tag.Get("timestampFormat") + if len(format) == 0 { + format = protocol.RFC822TimeFormatName + if tag.Get("location") == "querystring" { + format = protocol.ISO8601TimeFormatName + } + } + str = protocol.FormatTime(format, value) + case aws.JSONValue: + if len(value) == 0 { + return "", errValueNotSet + } + escaping := protocol.NoEscape + if tag.Get("location") == "header" { + escaping = protocol.Base64Escape + } + str, err = protocol.EncodeJSONValue(value, escaping) + if err != nil { + return "", fmt.Errorf("unable to encode JSONValue, %v", err) + } + default: + err := fmt.Errorf("unsupported value for param %v (%s)", v.Interface(), v.Type()) + return "", err + } + return str, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/payload.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/payload.go new file mode 100644 index 0000000..b54c99e --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/payload.go @@ -0,0 +1,54 @@ +package rest + +import "reflect" + +// PayloadMember returns the payload field member of i if there is one, or nil. +func PayloadMember(i interface{}) interface{} { + if i == nil { + return nil + } + + v := reflect.ValueOf(i).Elem() + if !v.IsValid() { + return nil + } + if field, ok := v.Type().FieldByName("_"); ok { + if payloadName := field.Tag.Get("payload"); payloadName != "" { + field, _ := v.Type().FieldByName(payloadName) + if field.Tag.Get("type") != "structure" { + return nil + } + + payload := v.FieldByName(payloadName) + if payload.IsValid() || (payload.Kind() == reflect.Ptr && !payload.IsNil()) { + return payload.Interface() + } + } + } + return nil +} + +const nopayloadPayloadType = "nopayload" + +// PayloadType returns the type of a payload field member of i if there is one, +// or "". +func PayloadType(i interface{}) string { + v := reflect.Indirect(reflect.ValueOf(i)) + if !v.IsValid() { + return "" + } + + if field, ok := v.Type().FieldByName("_"); ok { + if noPayload := field.Tag.Get(nopayloadPayloadType); noPayload != "" { + return nopayloadPayloadType + } + + if payloadName := field.Tag.Get("payload"); payloadName != "" { + if member, ok := v.Type().FieldByName(payloadName); ok { + return member.Tag.Get("type") + } + } + } + + return "" +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/unmarshal.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/unmarshal.go new file mode 100644 index 0000000..c26fbfa --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/unmarshal.go @@ -0,0 +1,257 @@ +package rest + +import ( + "bytes" + "encoding/base64" + "fmt" + "io" + "io/ioutil" + "net/http" + "reflect" + "strconv" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" + awsStrings "github.com/aws/aws-sdk-go/internal/strings" + "github.com/aws/aws-sdk-go/private/protocol" +) + +// UnmarshalHandler is a named request handler for unmarshaling rest protocol requests +var UnmarshalHandler = request.NamedHandler{Name: "awssdk.rest.Unmarshal", Fn: Unmarshal} + +// UnmarshalMetaHandler is a named request handler for unmarshaling rest protocol request metadata +var UnmarshalMetaHandler = request.NamedHandler{Name: "awssdk.rest.UnmarshalMeta", Fn: UnmarshalMeta} + +// Unmarshal unmarshals the REST component of a response in a REST service. +func Unmarshal(r *request.Request) { + if r.DataFilled() { + v := reflect.Indirect(reflect.ValueOf(r.Data)) + if err := unmarshalBody(r, v); err != nil { + r.Error = err + } + } +} + +// UnmarshalMeta unmarshals the REST metadata of a response in a REST service +func UnmarshalMeta(r *request.Request) { + r.RequestID = r.HTTPResponse.Header.Get("X-Amzn-Requestid") + if r.RequestID == "" { + // Alternative version of request id in the header + r.RequestID = r.HTTPResponse.Header.Get("X-Amz-Request-Id") + } + if r.DataFilled() { + if err := UnmarshalResponse(r.HTTPResponse, r.Data, aws.BoolValue(r.Config.LowerCaseHeaderMaps)); err != nil { + r.Error = err + } + } +} + +// UnmarshalResponse attempts to unmarshal the REST response headers to +// the data type passed in. The type must be a pointer. An error is returned +// with any error unmarshaling the response into the target datatype. +func UnmarshalResponse(resp *http.Response, data interface{}, lowerCaseHeaderMaps bool) error { + v := reflect.Indirect(reflect.ValueOf(data)) + return unmarshalLocationElements(resp, v, lowerCaseHeaderMaps) +} + +func unmarshalBody(r *request.Request, v reflect.Value) error { + if field, ok := v.Type().FieldByName("_"); ok { + if payloadName := field.Tag.Get("payload"); payloadName != "" { + pfield, _ := v.Type().FieldByName(payloadName) + if ptag := pfield.Tag.Get("type"); ptag != "" && ptag != "structure" { + payload := v.FieldByName(payloadName) + if payload.IsValid() { + switch payload.Interface().(type) { + case []byte: + defer r.HTTPResponse.Body.Close() + b, err := ioutil.ReadAll(r.HTTPResponse.Body) + if err != nil { + return awserr.New(request.ErrCodeSerialization, "failed to decode REST response", err) + } + + payload.Set(reflect.ValueOf(b)) + + case *string: + defer r.HTTPResponse.Body.Close() + b, err := ioutil.ReadAll(r.HTTPResponse.Body) + if err != nil { + return awserr.New(request.ErrCodeSerialization, "failed to decode REST response", err) + } + + str := string(b) + payload.Set(reflect.ValueOf(&str)) + + default: + switch payload.Type().String() { + case "io.ReadCloser": + payload.Set(reflect.ValueOf(r.HTTPResponse.Body)) + + case "io.ReadSeeker": + b, err := ioutil.ReadAll(r.HTTPResponse.Body) + if err != nil { + return awserr.New(request.ErrCodeSerialization, + "failed to read response body", err) + } + payload.Set(reflect.ValueOf(ioutil.NopCloser(bytes.NewReader(b)))) + + default: + io.Copy(ioutil.Discard, r.HTTPResponse.Body) + r.HTTPResponse.Body.Close() + return awserr.New(request.ErrCodeSerialization, + "failed to decode REST response", + fmt.Errorf("unknown payload type %s", payload.Type())) + } + } + } + } + } + } + + return nil +} + +func unmarshalLocationElements(resp *http.Response, v reflect.Value, lowerCaseHeaderMaps bool) error { + for i := 0; i < v.NumField(); i++ { + m, field := v.Field(i), v.Type().Field(i) + if n := field.Name; n[0:1] == strings.ToLower(n[0:1]) { + continue + } + + if m.IsValid() { + name := field.Tag.Get("locationName") + if name == "" { + name = field.Name + } + + switch field.Tag.Get("location") { + case "statusCode": + unmarshalStatusCode(m, resp.StatusCode) + + case "header": + err := unmarshalHeader(m, resp.Header.Get(name), field.Tag) + if err != nil { + return awserr.New(request.ErrCodeSerialization, "failed to decode REST response", err) + } + + case "headers": + prefix := field.Tag.Get("locationName") + err := unmarshalHeaderMap(m, resp.Header, prefix, lowerCaseHeaderMaps) + if err != nil { + return awserr.New(request.ErrCodeSerialization, "failed to decode REST response", err) + } + } + } + } + + return nil +} + +func unmarshalStatusCode(v reflect.Value, statusCode int) { + if !v.IsValid() { + return + } + + switch v.Interface().(type) { + case *int64: + s := int64(statusCode) + v.Set(reflect.ValueOf(&s)) + } +} + +func unmarshalHeaderMap(r reflect.Value, headers http.Header, prefix string, normalize bool) error { + if len(headers) == 0 { + return nil + } + switch r.Interface().(type) { + case map[string]*string: // we only support string map value types + out := map[string]*string{} + for k, v := range headers { + if awsStrings.HasPrefixFold(k, prefix) { + if normalize == true { + k = strings.ToLower(k) + } else { + k = http.CanonicalHeaderKey(k) + } + out[k[len(prefix):]] = &v[0] + } + } + if len(out) != 0 { + r.Set(reflect.ValueOf(out)) + } + + } + return nil +} + +func unmarshalHeader(v reflect.Value, header string, tag reflect.StructTag) error { + switch tag.Get("type") { + case "jsonvalue": + if len(header) == 0 { + return nil + } + case "blob": + if len(header) == 0 { + return nil + } + default: + if !v.IsValid() || (header == "" && v.Elem().Kind() != reflect.String) { + return nil + } + } + + switch v.Interface().(type) { + case *string: + v.Set(reflect.ValueOf(&header)) + case []byte: + b, err := base64.StdEncoding.DecodeString(header) + if err != nil { + return err + } + v.Set(reflect.ValueOf(b)) + case *bool: + b, err := strconv.ParseBool(header) + if err != nil { + return err + } + v.Set(reflect.ValueOf(&b)) + case *int64: + i, err := strconv.ParseInt(header, 10, 64) + if err != nil { + return err + } + v.Set(reflect.ValueOf(&i)) + case *float64: + f, err := strconv.ParseFloat(header, 64) + if err != nil { + return err + } + v.Set(reflect.ValueOf(&f)) + case *time.Time: + format := tag.Get("timestampFormat") + if len(format) == 0 { + format = protocol.RFC822TimeFormatName + } + t, err := protocol.ParseTime(format, header) + if err != nil { + return err + } + v.Set(reflect.ValueOf(&t)) + case aws.JSONValue: + escaping := protocol.NoEscape + if tag.Get("location") == "header" { + escaping = protocol.Base64Escape + } + m, err := protocol.DecodeJSONValue(header, escaping) + if err != nil { + return err + } + v.Set(reflect.ValueOf(m)) + default: + err := fmt.Errorf("Unsupported value for param %v (%s)", v.Interface(), v.Type()) + return err + } + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/timestamp.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/timestamp.go new file mode 100644 index 0000000..d9a4e76 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/timestamp.go @@ -0,0 +1,134 @@ +package protocol + +import ( + "bytes" + "fmt" + "math" + "strconv" + "time" + + "github.com/aws/aws-sdk-go/internal/sdkmath" +) + +// Names of time formats supported by the SDK +const ( + RFC822TimeFormatName = "rfc822" + ISO8601TimeFormatName = "iso8601" + UnixTimeFormatName = "unixTimestamp" +) + +// Time formats supported by the SDK +// Output time is intended to not contain decimals +const ( + // RFC 7231#section-7.1.1.1 timetamp format. e.g Tue, 29 Apr 2014 18:30:38 GMT + RFC822TimeFormat = "Mon, 2 Jan 2006 15:04:05 GMT" + rfc822TimeFormatSingleDigitDay = "Mon, _2 Jan 2006 15:04:05 GMT" + rfc822TimeFormatSingleDigitDayTwoDigitYear = "Mon, _2 Jan 06 15:04:05 GMT" + + // This format is used for output time without seconds precision + RFC822OutputTimeFormat = "Mon, 02 Jan 2006 15:04:05 GMT" + + // RFC3339 a subset of the ISO8601 timestamp format. e.g 2014-04-29T18:30:38Z + ISO8601TimeFormat = "2006-01-02T15:04:05.999999999Z" + iso8601TimeFormatNoZ = "2006-01-02T15:04:05.999999999" + + // This format is used for output time with fractional second precision up to milliseconds + ISO8601OutputTimeFormat = "2006-01-02T15:04:05.999999999Z" +) + +// IsKnownTimestampFormat returns if the timestamp format name +// is know to the SDK's protocols. +func IsKnownTimestampFormat(name string) bool { + switch name { + case RFC822TimeFormatName: + fallthrough + case ISO8601TimeFormatName: + fallthrough + case UnixTimeFormatName: + return true + default: + return false + } +} + +// FormatTime returns a string value of the time. +func FormatTime(name string, t time.Time) string { + t = t.UTC().Truncate(time.Millisecond) + + switch name { + case RFC822TimeFormatName: + return t.Format(RFC822OutputTimeFormat) + case ISO8601TimeFormatName: + return t.Format(ISO8601OutputTimeFormat) + case UnixTimeFormatName: + ms := t.UnixNano() / int64(time.Millisecond) + return strconv.FormatFloat(float64(ms)/1e3, 'f', -1, 64) + default: + panic("unknown timestamp format name, " + name) + } +} + +// ParseTime attempts to parse the time given the format. Returns +// the time if it was able to be parsed, and fails otherwise. +func ParseTime(formatName, value string) (time.Time, error) { + switch formatName { + case RFC822TimeFormatName: // Smithy HTTPDate format + return tryParse(value, + RFC822TimeFormat, + rfc822TimeFormatSingleDigitDay, + rfc822TimeFormatSingleDigitDayTwoDigitYear, + time.RFC850, + time.ANSIC, + ) + case ISO8601TimeFormatName: // Smithy DateTime format + return tryParse(value, + ISO8601TimeFormat, + iso8601TimeFormatNoZ, + time.RFC3339Nano, + time.RFC3339, + ) + case UnixTimeFormatName: + v, err := strconv.ParseFloat(value, 64) + _, dec := math.Modf(v) + dec = sdkmath.Round(dec*1e3) / 1e3 //Rounds 0.1229999 to 0.123 + if err != nil { + return time.Time{}, err + } + return time.Unix(int64(v), int64(dec*(1e9))), nil + default: + panic("unknown timestamp format name, " + formatName) + } +} + +func tryParse(v string, formats ...string) (time.Time, error) { + var errs parseErrors + for _, f := range formats { + t, err := time.Parse(f, v) + if err != nil { + errs = append(errs, parseError{ + Format: f, + Err: err, + }) + continue + } + return t, nil + } + + return time.Time{}, fmt.Errorf("unable to parse time string, %v", errs) +} + +type parseErrors []parseError + +func (es parseErrors) Error() string { + var s bytes.Buffer + for _, e := range es { + fmt.Fprintf(&s, "\n * %q: %v", e.Format, e.Err) + } + + return "parse errors:" + s.String() +} + +type parseError struct { + Format string + Err error +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/unmarshal.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/unmarshal.go new file mode 100644 index 0000000..f614ef8 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/unmarshal.go @@ -0,0 +1,27 @@ +package protocol + +import ( + "io" + "io/ioutil" + + "github.com/aws/aws-sdk-go/aws/request" +) + +// UnmarshalDiscardBodyHandler is a named request handler to empty and close a response's body +var UnmarshalDiscardBodyHandler = request.NamedHandler{Name: "awssdk.shared.UnmarshalDiscardBody", Fn: UnmarshalDiscardBody} + +// UnmarshalDiscardBody is a request handler to empty a response's body and closing it. +func UnmarshalDiscardBody(r *request.Request) { + if r.HTTPResponse == nil || r.HTTPResponse.Body == nil { + return + } + + io.Copy(ioutil.Discard, r.HTTPResponse.Body) + r.HTTPResponse.Body.Close() +} + +// ResponseMetadata provides the SDK response metadata attributes. +type ResponseMetadata struct { + StatusCode int + RequestID string +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/unmarshal_error.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/unmarshal_error.go new file mode 100644 index 0000000..cc857f1 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/unmarshal_error.go @@ -0,0 +1,65 @@ +package protocol + +import ( + "net/http" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" +) + +// UnmarshalErrorHandler provides unmarshaling errors API response errors for +// both typed and untyped errors. +type UnmarshalErrorHandler struct { + unmarshaler ErrorUnmarshaler +} + +// ErrorUnmarshaler is an abstract interface for concrete implementations to +// unmarshal protocol specific response errors. +type ErrorUnmarshaler interface { + UnmarshalError(*http.Response, ResponseMetadata) (error, error) +} + +// NewUnmarshalErrorHandler returns an UnmarshalErrorHandler +// initialized for the set of exception names to the error unmarshalers +func NewUnmarshalErrorHandler(unmarshaler ErrorUnmarshaler) *UnmarshalErrorHandler { + return &UnmarshalErrorHandler{ + unmarshaler: unmarshaler, + } +} + +// UnmarshalErrorHandlerName is the name of the named handler. +const UnmarshalErrorHandlerName = "awssdk.protocol.UnmarshalError" + +// NamedHandler returns a NamedHandler for the unmarshaler using the set of +// errors the unmarshaler was initialized for. +func (u *UnmarshalErrorHandler) NamedHandler() request.NamedHandler { + return request.NamedHandler{ + Name: UnmarshalErrorHandlerName, + Fn: u.UnmarshalError, + } +} + +// UnmarshalError will attempt to unmarshal the API response's error message +// into either a generic SDK error type, or a typed error corresponding to the +// errors exception name. +func (u *UnmarshalErrorHandler) UnmarshalError(r *request.Request) { + defer r.HTTPResponse.Body.Close() + + respMeta := ResponseMetadata{ + StatusCode: r.HTTPResponse.StatusCode, + RequestID: r.RequestID, + } + + v, err := u.unmarshaler.UnmarshalError(r.HTTPResponse, respMeta) + if err != nil { + r.Error = awserr.NewRequestFailure( + awserr.New(request.ErrCodeSerialization, + "failed to unmarshal response error", err), + respMeta.StatusCode, + respMeta.RequestID, + ) + return + } + + r.Error = v +} diff --git a/vendor/github.com/aws/aws-sdk-go/service/dynamodb/api.go b/vendor/github.com/aws/aws-sdk-go/service/dynamodb/api.go new file mode 100644 index 0000000..017ed69 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/dynamodb/api.go @@ -0,0 +1,25348 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package dynamodb + +import ( + "fmt" + "net/url" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awsutil" + "github.com/aws/aws-sdk-go/aws/crr" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol" + "github.com/aws/aws-sdk-go/private/protocol/jsonrpc" +) + +const opBatchExecuteStatement = "BatchExecuteStatement" + +// BatchExecuteStatementRequest generates a "aws/request.Request" representing the +// client's request for the BatchExecuteStatement operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See BatchExecuteStatement for more information on using the BatchExecuteStatement +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the BatchExecuteStatementRequest method. +// req, resp := client.BatchExecuteStatementRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/BatchExecuteStatement +func (c *DynamoDB) BatchExecuteStatementRequest(input *BatchExecuteStatementInput) (req *request.Request, output *BatchExecuteStatementOutput) { + op := &request.Operation{ + Name: opBatchExecuteStatement, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &BatchExecuteStatementInput{} + } + + output = &BatchExecuteStatementOutput{} + req = c.newRequest(op, input, output) + return +} + +// BatchExecuteStatement API operation for Amazon DynamoDB. +// +// This operation allows you to perform batch reads or writes on data stored +// in DynamoDB, using PartiQL. +// +// The entire batch must consist of either read statements or write statements, +// you cannot mix both in one batch. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation BatchExecuteStatement for usage and error information. +// +// Returned Error Types: +// * RequestLimitExceeded +// Throughput exceeds the current throughput quota for your account. Please +// contact Amazon Web Services Support (https://aws.amazon.com/support) to request +// a quota increase. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/BatchExecuteStatement +func (c *DynamoDB) BatchExecuteStatement(input *BatchExecuteStatementInput) (*BatchExecuteStatementOutput, error) { + req, out := c.BatchExecuteStatementRequest(input) + return out, req.Send() +} + +// BatchExecuteStatementWithContext is the same as BatchExecuteStatement with the addition of +// the ability to pass a context and additional request options. +// +// See BatchExecuteStatement for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) BatchExecuteStatementWithContext(ctx aws.Context, input *BatchExecuteStatementInput, opts ...request.Option) (*BatchExecuteStatementOutput, error) { + req, out := c.BatchExecuteStatementRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opBatchGetItem = "BatchGetItem" + +// BatchGetItemRequest generates a "aws/request.Request" representing the +// client's request for the BatchGetItem operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See BatchGetItem for more information on using the BatchGetItem +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the BatchGetItemRequest method. +// req, resp := client.BatchGetItemRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/BatchGetItem +func (c *DynamoDB) BatchGetItemRequest(input *BatchGetItemInput) (req *request.Request, output *BatchGetItemOutput) { + op := &request.Operation{ + Name: opBatchGetItem, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"RequestItems"}, + OutputTokens: []string{"UnprocessedKeys"}, + LimitToken: "", + TruncationToken: "", + }, + } + + if input == nil { + input = &BatchGetItemInput{} + } + + output = &BatchGetItemOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// BatchGetItem API operation for Amazon DynamoDB. +// +// The BatchGetItem operation returns the attributes of one or more items from +// one or more tables. You identify requested items by primary key. +// +// A single operation can retrieve up to 16 MB of data, which can contain as +// many as 100 items. BatchGetItem returns a partial result if the response +// size limit is exceeded, the table's provisioned throughput is exceeded, or +// an internal processing failure occurs. If a partial result is returned, the +// operation returns a value for UnprocessedKeys. You can use this value to +// retry the operation starting with the next item to get. +// +// If you request more than 100 items, BatchGetItem returns a ValidationException +// with the message "Too many items requested for the BatchGetItem call." +// +// For example, if you ask to retrieve 100 items, but each individual item is +// 300 KB in size, the system returns 52 items (so as not to exceed the 16 MB +// limit). It also returns an appropriate UnprocessedKeys value so you can get +// the next page of results. If desired, your application can include its own +// logic to assemble the pages of results into one dataset. +// +// If none of the items can be processed due to insufficient provisioned throughput +// on all of the tables in the request, then BatchGetItem returns a ProvisionedThroughputExceededException. +// If at least one of the items is successfully processed, then BatchGetItem +// completes successfully, while returning the keys of the unread items in UnprocessedKeys. +// +// If DynamoDB returns any unprocessed items, you should retry the batch operation +// on those items. However, we strongly recommend that you use an exponential +// backoff algorithm. If you retry the batch operation immediately, the underlying +// read or write requests can still fail due to throttling on the individual +// tables. If you delay the batch operation using exponential backoff, the individual +// requests in the batch are much more likely to succeed. +// +// For more information, see Batch Operations and Error Handling (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ErrorHandling.html#BatchOperations) +// in the Amazon DynamoDB Developer Guide. +// +// By default, BatchGetItem performs eventually consistent reads on every table +// in the request. If you want strongly consistent reads instead, you can set +// ConsistentRead to true for any or all tables. +// +// In order to minimize response latency, BatchGetItem retrieves items in parallel. +// +// When designing your application, keep in mind that DynamoDB does not return +// items in any particular order. To help parse the response by item, include +// the primary key values for the items in your request in the ProjectionExpression +// parameter. +// +// If a requested item does not exist, it is not returned in the result. Requests +// for nonexistent items consume the minimum read capacity units according to +// the type of read. For more information, see Working with Tables (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithTables.html#CapacityUnitCalculations) +// in the Amazon DynamoDB Developer Guide. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation BatchGetItem for usage and error information. +// +// Returned Error Types: +// * ProvisionedThroughputExceededException +// Your request rate is too high. The Amazon Web Services SDKs for DynamoDB +// automatically retry requests that receive this exception. Your request is +// eventually successful, unless your retry queue is too large to finish. Reduce +// the frequency of requests and use exponential backoff. For more information, +// go to Error Retries and Exponential Backoff (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.Errors.html#Programming.Errors.RetryAndBackoff) +// in the Amazon DynamoDB Developer Guide. +// +// * ResourceNotFoundException +// The operation tried to access a nonexistent table or index. The resource +// might not be specified correctly, or its status might not be ACTIVE. +// +// * RequestLimitExceeded +// Throughput exceeds the current throughput quota for your account. Please +// contact Amazon Web Services Support (https://aws.amazon.com/support) to request +// a quota increase. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/BatchGetItem +func (c *DynamoDB) BatchGetItem(input *BatchGetItemInput) (*BatchGetItemOutput, error) { + req, out := c.BatchGetItemRequest(input) + return out, req.Send() +} + +// BatchGetItemWithContext is the same as BatchGetItem with the addition of +// the ability to pass a context and additional request options. +// +// See BatchGetItem for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) BatchGetItemWithContext(ctx aws.Context, input *BatchGetItemInput, opts ...request.Option) (*BatchGetItemOutput, error) { + req, out := c.BatchGetItemRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// BatchGetItemPages iterates over the pages of a BatchGetItem operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See BatchGetItem method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a BatchGetItem operation. +// pageNum := 0 +// err := client.BatchGetItemPages(params, +// func(page *dynamodb.BatchGetItemOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *DynamoDB) BatchGetItemPages(input *BatchGetItemInput, fn func(*BatchGetItemOutput, bool) bool) error { + return c.BatchGetItemPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// BatchGetItemPagesWithContext same as BatchGetItemPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) BatchGetItemPagesWithContext(ctx aws.Context, input *BatchGetItemInput, fn func(*BatchGetItemOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *BatchGetItemInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.BatchGetItemRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*BatchGetItemOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + +const opBatchWriteItem = "BatchWriteItem" + +// BatchWriteItemRequest generates a "aws/request.Request" representing the +// client's request for the BatchWriteItem operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See BatchWriteItem for more information on using the BatchWriteItem +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the BatchWriteItemRequest method. +// req, resp := client.BatchWriteItemRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/BatchWriteItem +func (c *DynamoDB) BatchWriteItemRequest(input *BatchWriteItemInput) (req *request.Request, output *BatchWriteItemOutput) { + op := &request.Operation{ + Name: opBatchWriteItem, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &BatchWriteItemInput{} + } + + output = &BatchWriteItemOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// BatchWriteItem API operation for Amazon DynamoDB. +// +// The BatchWriteItem operation puts or deletes multiple items in one or more +// tables. A single call to BatchWriteItem can write up to 16 MB of data, which +// can comprise as many as 25 put or delete requests. Individual items to be +// written can be as large as 400 KB. +// +// BatchWriteItem cannot update items. To update items, use the UpdateItem action. +// +// The individual PutItem and DeleteItem operations specified in BatchWriteItem +// are atomic; however BatchWriteItem as a whole is not. If any requested operations +// fail because the table's provisioned throughput is exceeded or an internal +// processing failure occurs, the failed operations are returned in the UnprocessedItems +// response parameter. You can investigate and optionally resend the requests. +// Typically, you would call BatchWriteItem in a loop. Each iteration would +// check for unprocessed items and submit a new BatchWriteItem request with +// those unprocessed items until all items have been processed. +// +// If none of the items can be processed due to insufficient provisioned throughput +// on all of the tables in the request, then BatchWriteItem returns a ProvisionedThroughputExceededException. +// +// If DynamoDB returns any unprocessed items, you should retry the batch operation +// on those items. However, we strongly recommend that you use an exponential +// backoff algorithm. If you retry the batch operation immediately, the underlying +// read or write requests can still fail due to throttling on the individual +// tables. If you delay the batch operation using exponential backoff, the individual +// requests in the batch are much more likely to succeed. +// +// For more information, see Batch Operations and Error Handling (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ErrorHandling.html#Programming.Errors.BatchOperations) +// in the Amazon DynamoDB Developer Guide. +// +// With BatchWriteItem, you can efficiently write or delete large amounts of +// data, such as from Amazon EMR, or copy data from another database into DynamoDB. +// In order to improve performance with these large-scale operations, BatchWriteItem +// does not behave in the same way as individual PutItem and DeleteItem calls +// would. For example, you cannot specify conditions on individual put and delete +// requests, and BatchWriteItem does not return deleted items in the response. +// +// If you use a programming language that supports concurrency, you can use +// threads to write items in parallel. Your application must include the necessary +// logic to manage the threads. With languages that don't support threading, +// you must update or delete the specified items one at a time. In both situations, +// BatchWriteItem performs the specified put and delete operations in parallel, +// giving you the power of the thread pool approach without having to introduce +// complexity into your application. +// +// Parallel processing reduces latency, but each specified put and delete request +// consumes the same number of write capacity units whether it is processed +// in parallel or not. Delete operations on nonexistent items consume one write +// capacity unit. +// +// If one or more of the following is true, DynamoDB rejects the entire batch +// write operation: +// +// * One or more tables specified in the BatchWriteItem request does not +// exist. +// +// * Primary key attributes specified on an item in the request do not match +// those in the corresponding table's primary key schema. +// +// * You try to perform multiple operations on the same item in the same +// BatchWriteItem request. For example, you cannot put and delete the same +// item in the same BatchWriteItem request. +// +// * Your request contains at least two items with identical hash and range +// keys (which essentially is two put operations). +// +// * There are more than 25 requests in the batch. +// +// * Any individual item in a batch exceeds 400 KB. +// +// * The total request size exceeds 16 MB. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation BatchWriteItem for usage and error information. +// +// Returned Error Types: +// * ProvisionedThroughputExceededException +// Your request rate is too high. The Amazon Web Services SDKs for DynamoDB +// automatically retry requests that receive this exception. Your request is +// eventually successful, unless your retry queue is too large to finish. Reduce +// the frequency of requests and use exponential backoff. For more information, +// go to Error Retries and Exponential Backoff (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.Errors.html#Programming.Errors.RetryAndBackoff) +// in the Amazon DynamoDB Developer Guide. +// +// * ResourceNotFoundException +// The operation tried to access a nonexistent table or index. The resource +// might not be specified correctly, or its status might not be ACTIVE. +// +// * ItemCollectionSizeLimitExceededException +// An item collection is too large. This exception is only returned for tables +// that have one or more local secondary indexes. +// +// * RequestLimitExceeded +// Throughput exceeds the current throughput quota for your account. Please +// contact Amazon Web Services Support (https://aws.amazon.com/support) to request +// a quota increase. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/BatchWriteItem +func (c *DynamoDB) BatchWriteItem(input *BatchWriteItemInput) (*BatchWriteItemOutput, error) { + req, out := c.BatchWriteItemRequest(input) + return out, req.Send() +} + +// BatchWriteItemWithContext is the same as BatchWriteItem with the addition of +// the ability to pass a context and additional request options. +// +// See BatchWriteItem for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) BatchWriteItemWithContext(ctx aws.Context, input *BatchWriteItemInput, opts ...request.Option) (*BatchWriteItemOutput, error) { + req, out := c.BatchWriteItemRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateBackup = "CreateBackup" + +// CreateBackupRequest generates a "aws/request.Request" representing the +// client's request for the CreateBackup operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateBackup for more information on using the CreateBackup +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateBackupRequest method. +// req, resp := client.CreateBackupRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/CreateBackup +func (c *DynamoDB) CreateBackupRequest(input *CreateBackupInput) (req *request.Request, output *CreateBackupOutput) { + op := &request.Operation{ + Name: opCreateBackup, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateBackupInput{} + } + + output = &CreateBackupOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// CreateBackup API operation for Amazon DynamoDB. +// +// Creates a backup for an existing table. +// +// Each time you create an on-demand backup, the entire table data is backed +// up. There is no limit to the number of on-demand backups that can be taken. +// +// When you create an on-demand backup, a time marker of the request is cataloged, +// and the backup is created asynchronously, by applying all changes until the +// time of the request to the last full table snapshot. Backup requests are +// processed instantaneously and become available for restore within minutes. +// +// You can call CreateBackup at a maximum rate of 50 times per second. +// +// All backups in DynamoDB work without consuming any provisioned throughput +// on the table. +// +// If you submit a backup request on 2018-12-14 at 14:25:00, the backup is guaranteed +// to contain all data committed to the table up to 14:24:00, and data committed +// after 14:26:00 will not be. The backup might contain data modifications made +// between 14:24:00 and 14:26:00. On-demand backup does not support causal consistency. +// +// Along with data, the following are also included on the backups: +// +// * Global secondary indexes (GSIs) +// +// * Local secondary indexes (LSIs) +// +// * Streams +// +// * Provisioned read and write capacity +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation CreateBackup for usage and error information. +// +// Returned Error Types: +// * TableNotFoundException +// A source table with the name TableName does not currently exist within the +// subscriber's account. +// +// * TableInUseException +// A target table with the specified name is either being created or deleted. +// +// * ContinuousBackupsUnavailableException +// Backups have not yet been enabled for this table. +// +// * BackupInUseException +// There is another ongoing conflicting backup control plane operation on the +// table. The backup is either being created, deleted or restored to a table. +// +// * LimitExceededException +// There is no limit to the number of daily on-demand backups that can be taken. +// +// Up to 50 simultaneous table operations are allowed per account. These operations +// include CreateTable, UpdateTable, DeleteTable,UpdateTimeToLive, RestoreTableFromBackup, +// and RestoreTableToPointInTime. +// +// The only exception is when you are creating a table with one or more secondary +// indexes. You can have up to 25 such requests running at a time; however, +// if the table or index specifications are complex, DynamoDB might temporarily +// reduce the number of concurrent operations. +// +// There is a soft account quota of 256 tables. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/CreateBackup +func (c *DynamoDB) CreateBackup(input *CreateBackupInput) (*CreateBackupOutput, error) { + req, out := c.CreateBackupRequest(input) + return out, req.Send() +} + +// CreateBackupWithContext is the same as CreateBackup with the addition of +// the ability to pass a context and additional request options. +// +// See CreateBackup for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) CreateBackupWithContext(ctx aws.Context, input *CreateBackupInput, opts ...request.Option) (*CreateBackupOutput, error) { + req, out := c.CreateBackupRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateGlobalTable = "CreateGlobalTable" + +// CreateGlobalTableRequest generates a "aws/request.Request" representing the +// client's request for the CreateGlobalTable operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateGlobalTable for more information on using the CreateGlobalTable +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateGlobalTableRequest method. +// req, resp := client.CreateGlobalTableRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/CreateGlobalTable +func (c *DynamoDB) CreateGlobalTableRequest(input *CreateGlobalTableInput) (req *request.Request, output *CreateGlobalTableOutput) { + op := &request.Operation{ + Name: opCreateGlobalTable, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateGlobalTableInput{} + } + + output = &CreateGlobalTableOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// CreateGlobalTable API operation for Amazon DynamoDB. +// +// Creates a global table from an existing table. A global table creates a replication +// relationship between two or more DynamoDB tables with the same table name +// in the provided Regions. +// +// This operation only applies to Version 2017.11.29 (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/globaltables.V1.html) +// of global tables. +// +// If you want to add a new replica table to a global table, each of the following +// conditions must be true: +// +// * The table must have the same primary key as all of the other replicas. +// +// * The table must have the same name as all of the other replicas. +// +// * The table must have DynamoDB Streams enabled, with the stream containing +// both the new and the old images of the item. +// +// * None of the replica tables in the global table can contain any data. +// +// If global secondary indexes are specified, then the following conditions +// must also be met: +// +// * The global secondary indexes must have the same name. +// +// * The global secondary indexes must have the same hash key and sort key +// (if present). +// +// If local secondary indexes are specified, then the following conditions must +// also be met: +// +// * The local secondary indexes must have the same name. +// +// * The local secondary indexes must have the same hash key and sort key +// (if present). +// +// Write capacity settings should be set consistently across your replica tables +// and secondary indexes. DynamoDB strongly recommends enabling auto scaling +// to manage the write capacity settings for all of your global tables replicas +// and indexes. +// +// If you prefer to manage write capacity settings manually, you should provision +// equal replicated write capacity units to your replica tables. You should +// also provision equal replicated write capacity units to matching secondary +// indexes across your global table. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation CreateGlobalTable for usage and error information. +// +// Returned Error Types: +// * LimitExceededException +// There is no limit to the number of daily on-demand backups that can be taken. +// +// Up to 50 simultaneous table operations are allowed per account. These operations +// include CreateTable, UpdateTable, DeleteTable,UpdateTimeToLive, RestoreTableFromBackup, +// and RestoreTableToPointInTime. +// +// The only exception is when you are creating a table with one or more secondary +// indexes. You can have up to 25 such requests running at a time; however, +// if the table or index specifications are complex, DynamoDB might temporarily +// reduce the number of concurrent operations. +// +// There is a soft account quota of 256 tables. +// +// * InternalServerError +// An error occurred on the server side. +// +// * GlobalTableAlreadyExistsException +// The specified global table already exists. +// +// * TableNotFoundException +// A source table with the name TableName does not currently exist within the +// subscriber's account. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/CreateGlobalTable +func (c *DynamoDB) CreateGlobalTable(input *CreateGlobalTableInput) (*CreateGlobalTableOutput, error) { + req, out := c.CreateGlobalTableRequest(input) + return out, req.Send() +} + +// CreateGlobalTableWithContext is the same as CreateGlobalTable with the addition of +// the ability to pass a context and additional request options. +// +// See CreateGlobalTable for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) CreateGlobalTableWithContext(ctx aws.Context, input *CreateGlobalTableInput, opts ...request.Option) (*CreateGlobalTableOutput, error) { + req, out := c.CreateGlobalTableRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateTable = "CreateTable" + +// CreateTableRequest generates a "aws/request.Request" representing the +// client's request for the CreateTable operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateTable for more information on using the CreateTable +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateTableRequest method. +// req, resp := client.CreateTableRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/CreateTable +func (c *DynamoDB) CreateTableRequest(input *CreateTableInput) (req *request.Request, output *CreateTableOutput) { + op := &request.Operation{ + Name: opCreateTable, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateTableInput{} + } + + output = &CreateTableOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// CreateTable API operation for Amazon DynamoDB. +// +// The CreateTable operation adds a new table to your account. In an Amazon +// Web Services account, table names must be unique within each Region. That +// is, you can have two tables with same name if you create the tables in different +// Regions. +// +// CreateTable is an asynchronous operation. Upon receiving a CreateTable request, +// DynamoDB immediately returns a response with a TableStatus of CREATING. After +// the table is created, DynamoDB sets the TableStatus to ACTIVE. You can perform +// read and write operations only on an ACTIVE table. +// +// You can optionally define secondary indexes on the new table, as part of +// the CreateTable operation. If you want to create multiple tables with secondary +// indexes on them, you must create the tables sequentially. Only one table +// with secondary indexes can be in the CREATING state at any given time. +// +// You can use the DescribeTable action to check the table status. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation CreateTable for usage and error information. +// +// Returned Error Types: +// * ResourceInUseException +// The operation conflicts with the resource's availability. For example, you +// attempted to recreate an existing table, or tried to delete a table currently +// in the CREATING state. +// +// * LimitExceededException +// There is no limit to the number of daily on-demand backups that can be taken. +// +// Up to 50 simultaneous table operations are allowed per account. These operations +// include CreateTable, UpdateTable, DeleteTable,UpdateTimeToLive, RestoreTableFromBackup, +// and RestoreTableToPointInTime. +// +// The only exception is when you are creating a table with one or more secondary +// indexes. You can have up to 25 such requests running at a time; however, +// if the table or index specifications are complex, DynamoDB might temporarily +// reduce the number of concurrent operations. +// +// There is a soft account quota of 256 tables. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/CreateTable +func (c *DynamoDB) CreateTable(input *CreateTableInput) (*CreateTableOutput, error) { + req, out := c.CreateTableRequest(input) + return out, req.Send() +} + +// CreateTableWithContext is the same as CreateTable with the addition of +// the ability to pass a context and additional request options. +// +// See CreateTable for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) CreateTableWithContext(ctx aws.Context, input *CreateTableInput, opts ...request.Option) (*CreateTableOutput, error) { + req, out := c.CreateTableRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteBackup = "DeleteBackup" + +// DeleteBackupRequest generates a "aws/request.Request" representing the +// client's request for the DeleteBackup operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteBackup for more information on using the DeleteBackup +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteBackupRequest method. +// req, resp := client.DeleteBackupRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/DeleteBackup +func (c *DynamoDB) DeleteBackupRequest(input *DeleteBackupInput) (req *request.Request, output *DeleteBackupOutput) { + op := &request.Operation{ + Name: opDeleteBackup, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteBackupInput{} + } + + output = &DeleteBackupOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// DeleteBackup API operation for Amazon DynamoDB. +// +// Deletes an existing backup of a table. +// +// You can call DeleteBackup at a maximum rate of 10 times per second. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation DeleteBackup for usage and error information. +// +// Returned Error Types: +// * BackupNotFoundException +// Backup not found for the given BackupARN. +// +// * BackupInUseException +// There is another ongoing conflicting backup control plane operation on the +// table. The backup is either being created, deleted or restored to a table. +// +// * LimitExceededException +// There is no limit to the number of daily on-demand backups that can be taken. +// +// Up to 50 simultaneous table operations are allowed per account. These operations +// include CreateTable, UpdateTable, DeleteTable,UpdateTimeToLive, RestoreTableFromBackup, +// and RestoreTableToPointInTime. +// +// The only exception is when you are creating a table with one or more secondary +// indexes. You can have up to 25 such requests running at a time; however, +// if the table or index specifications are complex, DynamoDB might temporarily +// reduce the number of concurrent operations. +// +// There is a soft account quota of 256 tables. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/DeleteBackup +func (c *DynamoDB) DeleteBackup(input *DeleteBackupInput) (*DeleteBackupOutput, error) { + req, out := c.DeleteBackupRequest(input) + return out, req.Send() +} + +// DeleteBackupWithContext is the same as DeleteBackup with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteBackup for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) DeleteBackupWithContext(ctx aws.Context, input *DeleteBackupInput, opts ...request.Option) (*DeleteBackupOutput, error) { + req, out := c.DeleteBackupRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteItem = "DeleteItem" + +// DeleteItemRequest generates a "aws/request.Request" representing the +// client's request for the DeleteItem operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteItem for more information on using the DeleteItem +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteItemRequest method. +// req, resp := client.DeleteItemRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/DeleteItem +func (c *DynamoDB) DeleteItemRequest(input *DeleteItemInput) (req *request.Request, output *DeleteItemOutput) { + op := &request.Operation{ + Name: opDeleteItem, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteItemInput{} + } + + output = &DeleteItemOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// DeleteItem API operation for Amazon DynamoDB. +// +// Deletes a single item in a table by primary key. You can perform a conditional +// delete operation that deletes the item if it exists, or if it has an expected +// attribute value. +// +// In addition to deleting an item, you can also return the item's attribute +// values in the same operation, using the ReturnValues parameter. +// +// Unless you specify conditions, the DeleteItem is an idempotent operation; +// running it multiple times on the same item or attribute does not result in +// an error response. +// +// Conditional deletes are useful for deleting items only if specific conditions +// are met. If those conditions are met, DynamoDB performs the delete. Otherwise, +// the item is not deleted. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation DeleteItem for usage and error information. +// +// Returned Error Types: +// * ConditionalCheckFailedException +// A condition specified in the operation could not be evaluated. +// +// * ProvisionedThroughputExceededException +// Your request rate is too high. The Amazon Web Services SDKs for DynamoDB +// automatically retry requests that receive this exception. Your request is +// eventually successful, unless your retry queue is too large to finish. Reduce +// the frequency of requests and use exponential backoff. For more information, +// go to Error Retries and Exponential Backoff (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.Errors.html#Programming.Errors.RetryAndBackoff) +// in the Amazon DynamoDB Developer Guide. +// +// * ResourceNotFoundException +// The operation tried to access a nonexistent table or index. The resource +// might not be specified correctly, or its status might not be ACTIVE. +// +// * ItemCollectionSizeLimitExceededException +// An item collection is too large. This exception is only returned for tables +// that have one or more local secondary indexes. +// +// * TransactionConflictException +// Operation was rejected because there is an ongoing transaction for the item. +// +// * RequestLimitExceeded +// Throughput exceeds the current throughput quota for your account. Please +// contact Amazon Web Services Support (https://aws.amazon.com/support) to request +// a quota increase. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/DeleteItem +func (c *DynamoDB) DeleteItem(input *DeleteItemInput) (*DeleteItemOutput, error) { + req, out := c.DeleteItemRequest(input) + return out, req.Send() +} + +// DeleteItemWithContext is the same as DeleteItem with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteItem for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) DeleteItemWithContext(ctx aws.Context, input *DeleteItemInput, opts ...request.Option) (*DeleteItemOutput, error) { + req, out := c.DeleteItemRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteTable = "DeleteTable" + +// DeleteTableRequest generates a "aws/request.Request" representing the +// client's request for the DeleteTable operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteTable for more information on using the DeleteTable +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteTableRequest method. +// req, resp := client.DeleteTableRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/DeleteTable +func (c *DynamoDB) DeleteTableRequest(input *DeleteTableInput) (req *request.Request, output *DeleteTableOutput) { + op := &request.Operation{ + Name: opDeleteTable, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteTableInput{} + } + + output = &DeleteTableOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// DeleteTable API operation for Amazon DynamoDB. +// +// The DeleteTable operation deletes a table and all of its items. After a DeleteTable +// request, the specified table is in the DELETING state until DynamoDB completes +// the deletion. If the table is in the ACTIVE state, you can delete it. If +// a table is in CREATING or UPDATING states, then DynamoDB returns a ResourceInUseException. +// If the specified table does not exist, DynamoDB returns a ResourceNotFoundException. +// If table is already in the DELETING state, no error is returned. +// +// DynamoDB might continue to accept data read and write operations, such as +// GetItem and PutItem, on a table in the DELETING state until the table deletion +// is complete. +// +// When you delete a table, any indexes on that table are also deleted. +// +// If you have DynamoDB Streams enabled on the table, then the corresponding +// stream on that table goes into the DISABLED state, and the stream is automatically +// deleted after 24 hours. +// +// Use the DescribeTable action to check the status of the table. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation DeleteTable for usage and error information. +// +// Returned Error Types: +// * ResourceInUseException +// The operation conflicts with the resource's availability. For example, you +// attempted to recreate an existing table, or tried to delete a table currently +// in the CREATING state. +// +// * ResourceNotFoundException +// The operation tried to access a nonexistent table or index. The resource +// might not be specified correctly, or its status might not be ACTIVE. +// +// * LimitExceededException +// There is no limit to the number of daily on-demand backups that can be taken. +// +// Up to 50 simultaneous table operations are allowed per account. These operations +// include CreateTable, UpdateTable, DeleteTable,UpdateTimeToLive, RestoreTableFromBackup, +// and RestoreTableToPointInTime. +// +// The only exception is when you are creating a table with one or more secondary +// indexes. You can have up to 25 such requests running at a time; however, +// if the table or index specifications are complex, DynamoDB might temporarily +// reduce the number of concurrent operations. +// +// There is a soft account quota of 256 tables. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/DeleteTable +func (c *DynamoDB) DeleteTable(input *DeleteTableInput) (*DeleteTableOutput, error) { + req, out := c.DeleteTableRequest(input) + return out, req.Send() +} + +// DeleteTableWithContext is the same as DeleteTable with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteTable for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) DeleteTableWithContext(ctx aws.Context, input *DeleteTableInput, opts ...request.Option) (*DeleteTableOutput, error) { + req, out := c.DeleteTableRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDescribeBackup = "DescribeBackup" + +// DescribeBackupRequest generates a "aws/request.Request" representing the +// client's request for the DescribeBackup operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DescribeBackup for more information on using the DescribeBackup +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DescribeBackupRequest method. +// req, resp := client.DescribeBackupRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/DescribeBackup +func (c *DynamoDB) DescribeBackupRequest(input *DescribeBackupInput) (req *request.Request, output *DescribeBackupOutput) { + op := &request.Operation{ + Name: opDescribeBackup, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeBackupInput{} + } + + output = &DescribeBackupOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// DescribeBackup API operation for Amazon DynamoDB. +// +// Describes an existing backup of a table. +// +// You can call DescribeBackup at a maximum rate of 10 times per second. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation DescribeBackup for usage and error information. +// +// Returned Error Types: +// * BackupNotFoundException +// Backup not found for the given BackupARN. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/DescribeBackup +func (c *DynamoDB) DescribeBackup(input *DescribeBackupInput) (*DescribeBackupOutput, error) { + req, out := c.DescribeBackupRequest(input) + return out, req.Send() +} + +// DescribeBackupWithContext is the same as DescribeBackup with the addition of +// the ability to pass a context and additional request options. +// +// See DescribeBackup for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) DescribeBackupWithContext(ctx aws.Context, input *DescribeBackupInput, opts ...request.Option) (*DescribeBackupOutput, error) { + req, out := c.DescribeBackupRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDescribeContinuousBackups = "DescribeContinuousBackups" + +// DescribeContinuousBackupsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeContinuousBackups operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DescribeContinuousBackups for more information on using the DescribeContinuousBackups +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DescribeContinuousBackupsRequest method. +// req, resp := client.DescribeContinuousBackupsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/DescribeContinuousBackups +func (c *DynamoDB) DescribeContinuousBackupsRequest(input *DescribeContinuousBackupsInput) (req *request.Request, output *DescribeContinuousBackupsOutput) { + op := &request.Operation{ + Name: opDescribeContinuousBackups, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeContinuousBackupsInput{} + } + + output = &DescribeContinuousBackupsOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// DescribeContinuousBackups API operation for Amazon DynamoDB. +// +// Checks the status of continuous backups and point in time recovery on the +// specified table. Continuous backups are ENABLED on all tables at table creation. +// If point in time recovery is enabled, PointInTimeRecoveryStatus will be set +// to ENABLED. +// +// After continuous backups and point in time recovery are enabled, you can +// restore to any point in time within EarliestRestorableDateTime and LatestRestorableDateTime. +// +// LatestRestorableDateTime is typically 5 minutes before the current time. +// You can restore your table to any point in time during the last 35 days. +// +// You can call DescribeContinuousBackups at a maximum rate of 10 times per +// second. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation DescribeContinuousBackups for usage and error information. +// +// Returned Error Types: +// * TableNotFoundException +// A source table with the name TableName does not currently exist within the +// subscriber's account. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/DescribeContinuousBackups +func (c *DynamoDB) DescribeContinuousBackups(input *DescribeContinuousBackupsInput) (*DescribeContinuousBackupsOutput, error) { + req, out := c.DescribeContinuousBackupsRequest(input) + return out, req.Send() +} + +// DescribeContinuousBackupsWithContext is the same as DescribeContinuousBackups with the addition of +// the ability to pass a context and additional request options. +// +// See DescribeContinuousBackups for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) DescribeContinuousBackupsWithContext(ctx aws.Context, input *DescribeContinuousBackupsInput, opts ...request.Option) (*DescribeContinuousBackupsOutput, error) { + req, out := c.DescribeContinuousBackupsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDescribeContributorInsights = "DescribeContributorInsights" + +// DescribeContributorInsightsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeContributorInsights operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DescribeContributorInsights for more information on using the DescribeContributorInsights +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DescribeContributorInsightsRequest method. +// req, resp := client.DescribeContributorInsightsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/DescribeContributorInsights +func (c *DynamoDB) DescribeContributorInsightsRequest(input *DescribeContributorInsightsInput) (req *request.Request, output *DescribeContributorInsightsOutput) { + op := &request.Operation{ + Name: opDescribeContributorInsights, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeContributorInsightsInput{} + } + + output = &DescribeContributorInsightsOutput{} + req = c.newRequest(op, input, output) + return +} + +// DescribeContributorInsights API operation for Amazon DynamoDB. +// +// Returns information about contributor insights, for a given table or global +// secondary index. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation DescribeContributorInsights for usage and error information. +// +// Returned Error Types: +// * ResourceNotFoundException +// The operation tried to access a nonexistent table or index. The resource +// might not be specified correctly, or its status might not be ACTIVE. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/DescribeContributorInsights +func (c *DynamoDB) DescribeContributorInsights(input *DescribeContributorInsightsInput) (*DescribeContributorInsightsOutput, error) { + req, out := c.DescribeContributorInsightsRequest(input) + return out, req.Send() +} + +// DescribeContributorInsightsWithContext is the same as DescribeContributorInsights with the addition of +// the ability to pass a context and additional request options. +// +// See DescribeContributorInsights for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) DescribeContributorInsightsWithContext(ctx aws.Context, input *DescribeContributorInsightsInput, opts ...request.Option) (*DescribeContributorInsightsOutput, error) { + req, out := c.DescribeContributorInsightsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDescribeEndpoints = "DescribeEndpoints" + +// DescribeEndpointsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeEndpoints operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DescribeEndpoints for more information on using the DescribeEndpoints +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DescribeEndpointsRequest method. +// req, resp := client.DescribeEndpointsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/DescribeEndpoints +func (c *DynamoDB) DescribeEndpointsRequest(input *DescribeEndpointsInput) (req *request.Request, output *DescribeEndpointsOutput) { + op := &request.Operation{ + Name: opDescribeEndpoints, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeEndpointsInput{} + } + + output = &DescribeEndpointsOutput{} + req = c.newRequest(op, input, output) + return +} + +// DescribeEndpoints API operation for Amazon DynamoDB. +// +// Returns the regional endpoint information. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation DescribeEndpoints for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/DescribeEndpoints +func (c *DynamoDB) DescribeEndpoints(input *DescribeEndpointsInput) (*DescribeEndpointsOutput, error) { + req, out := c.DescribeEndpointsRequest(input) + return out, req.Send() +} + +// DescribeEndpointsWithContext is the same as DescribeEndpoints with the addition of +// the ability to pass a context and additional request options. +// +// See DescribeEndpoints for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) DescribeEndpointsWithContext(ctx aws.Context, input *DescribeEndpointsInput, opts ...request.Option) (*DescribeEndpointsOutput, error) { + req, out := c.DescribeEndpointsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +type discovererDescribeEndpoints struct { + Client *DynamoDB + Required bool + EndpointCache *crr.EndpointCache + Params map[string]*string + Key string + req *request.Request +} + +func (d *discovererDescribeEndpoints) Discover() (crr.Endpoint, error) { + input := &DescribeEndpointsInput{} + + resp, err := d.Client.DescribeEndpoints(input) + if err != nil { + return crr.Endpoint{}, err + } + + endpoint := crr.Endpoint{ + Key: d.Key, + } + + for _, e := range resp.Endpoints { + if e.Address == nil { + continue + } + + address := *e.Address + + var scheme string + if idx := strings.Index(address, "://"); idx != -1 { + scheme = address[:idx] + } + + if len(scheme) == 0 { + address = fmt.Sprintf("%s://%s", d.req.HTTPRequest.URL.Scheme, address) + } + + cachedInMinutes := aws.Int64Value(e.CachePeriodInMinutes) + u, err := url.Parse(address) + if err != nil { + continue + } + + addr := crr.WeightedAddress{ + URL: u, + Expired: time.Now().Add(time.Duration(cachedInMinutes) * time.Minute), + } + + endpoint.Add(addr) + } + + d.EndpointCache.Add(endpoint) + + return endpoint, nil +} + +func (d *discovererDescribeEndpoints) Handler(r *request.Request) { + endpointKey := crr.BuildEndpointKey(d.Params) + d.Key = endpointKey + d.req = r + + endpoint, err := d.EndpointCache.Get(d, endpointKey, d.Required) + if err != nil { + r.Error = err + return + } + + if endpoint.URL != nil && len(endpoint.URL.String()) > 0 { + r.HTTPRequest.URL = endpoint.URL + } +} + +const opDescribeExport = "DescribeExport" + +// DescribeExportRequest generates a "aws/request.Request" representing the +// client's request for the DescribeExport operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DescribeExport for more information on using the DescribeExport +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DescribeExportRequest method. +// req, resp := client.DescribeExportRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/DescribeExport +func (c *DynamoDB) DescribeExportRequest(input *DescribeExportInput) (req *request.Request, output *DescribeExportOutput) { + op := &request.Operation{ + Name: opDescribeExport, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeExportInput{} + } + + output = &DescribeExportOutput{} + req = c.newRequest(op, input, output) + return +} + +// DescribeExport API operation for Amazon DynamoDB. +// +// Describes an existing table export. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation DescribeExport for usage and error information. +// +// Returned Error Types: +// * ExportNotFoundException +// The specified export was not found. +// +// * LimitExceededException +// There is no limit to the number of daily on-demand backups that can be taken. +// +// Up to 50 simultaneous table operations are allowed per account. These operations +// include CreateTable, UpdateTable, DeleteTable,UpdateTimeToLive, RestoreTableFromBackup, +// and RestoreTableToPointInTime. +// +// The only exception is when you are creating a table with one or more secondary +// indexes. You can have up to 25 such requests running at a time; however, +// if the table or index specifications are complex, DynamoDB might temporarily +// reduce the number of concurrent operations. +// +// There is a soft account quota of 256 tables. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/DescribeExport +func (c *DynamoDB) DescribeExport(input *DescribeExportInput) (*DescribeExportOutput, error) { + req, out := c.DescribeExportRequest(input) + return out, req.Send() +} + +// DescribeExportWithContext is the same as DescribeExport with the addition of +// the ability to pass a context and additional request options. +// +// See DescribeExport for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) DescribeExportWithContext(ctx aws.Context, input *DescribeExportInput, opts ...request.Option) (*DescribeExportOutput, error) { + req, out := c.DescribeExportRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDescribeGlobalTable = "DescribeGlobalTable" + +// DescribeGlobalTableRequest generates a "aws/request.Request" representing the +// client's request for the DescribeGlobalTable operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DescribeGlobalTable for more information on using the DescribeGlobalTable +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DescribeGlobalTableRequest method. +// req, resp := client.DescribeGlobalTableRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/DescribeGlobalTable +func (c *DynamoDB) DescribeGlobalTableRequest(input *DescribeGlobalTableInput) (req *request.Request, output *DescribeGlobalTableOutput) { + op := &request.Operation{ + Name: opDescribeGlobalTable, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeGlobalTableInput{} + } + + output = &DescribeGlobalTableOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// DescribeGlobalTable API operation for Amazon DynamoDB. +// +// Returns information about the specified global table. +// +// This operation only applies to Version 2017.11.29 (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/globaltables.V1.html) +// of global tables. If you are using global tables Version 2019.11.21 (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/globaltables.V2.html) +// you can use DescribeTable (https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DescribeTable.html) +// instead. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation DescribeGlobalTable for usage and error information. +// +// Returned Error Types: +// * InternalServerError +// An error occurred on the server side. +// +// * GlobalTableNotFoundException +// The specified global table does not exist. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/DescribeGlobalTable +func (c *DynamoDB) DescribeGlobalTable(input *DescribeGlobalTableInput) (*DescribeGlobalTableOutput, error) { + req, out := c.DescribeGlobalTableRequest(input) + return out, req.Send() +} + +// DescribeGlobalTableWithContext is the same as DescribeGlobalTable with the addition of +// the ability to pass a context and additional request options. +// +// See DescribeGlobalTable for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) DescribeGlobalTableWithContext(ctx aws.Context, input *DescribeGlobalTableInput, opts ...request.Option) (*DescribeGlobalTableOutput, error) { + req, out := c.DescribeGlobalTableRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDescribeGlobalTableSettings = "DescribeGlobalTableSettings" + +// DescribeGlobalTableSettingsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeGlobalTableSettings operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DescribeGlobalTableSettings for more information on using the DescribeGlobalTableSettings +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DescribeGlobalTableSettingsRequest method. +// req, resp := client.DescribeGlobalTableSettingsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/DescribeGlobalTableSettings +func (c *DynamoDB) DescribeGlobalTableSettingsRequest(input *DescribeGlobalTableSettingsInput) (req *request.Request, output *DescribeGlobalTableSettingsOutput) { + op := &request.Operation{ + Name: opDescribeGlobalTableSettings, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeGlobalTableSettingsInput{} + } + + output = &DescribeGlobalTableSettingsOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// DescribeGlobalTableSettings API operation for Amazon DynamoDB. +// +// Describes Region-specific settings for a global table. +// +// This operation only applies to Version 2017.11.29 (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/globaltables.V1.html) +// of global tables. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation DescribeGlobalTableSettings for usage and error information. +// +// Returned Error Types: +// * GlobalTableNotFoundException +// The specified global table does not exist. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/DescribeGlobalTableSettings +func (c *DynamoDB) DescribeGlobalTableSettings(input *DescribeGlobalTableSettingsInput) (*DescribeGlobalTableSettingsOutput, error) { + req, out := c.DescribeGlobalTableSettingsRequest(input) + return out, req.Send() +} + +// DescribeGlobalTableSettingsWithContext is the same as DescribeGlobalTableSettings with the addition of +// the ability to pass a context and additional request options. +// +// See DescribeGlobalTableSettings for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) DescribeGlobalTableSettingsWithContext(ctx aws.Context, input *DescribeGlobalTableSettingsInput, opts ...request.Option) (*DescribeGlobalTableSettingsOutput, error) { + req, out := c.DescribeGlobalTableSettingsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDescribeKinesisStreamingDestination = "DescribeKinesisStreamingDestination" + +// DescribeKinesisStreamingDestinationRequest generates a "aws/request.Request" representing the +// client's request for the DescribeKinesisStreamingDestination operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DescribeKinesisStreamingDestination for more information on using the DescribeKinesisStreamingDestination +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DescribeKinesisStreamingDestinationRequest method. +// req, resp := client.DescribeKinesisStreamingDestinationRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/DescribeKinesisStreamingDestination +func (c *DynamoDB) DescribeKinesisStreamingDestinationRequest(input *DescribeKinesisStreamingDestinationInput) (req *request.Request, output *DescribeKinesisStreamingDestinationOutput) { + op := &request.Operation{ + Name: opDescribeKinesisStreamingDestination, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeKinesisStreamingDestinationInput{} + } + + output = &DescribeKinesisStreamingDestinationOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// DescribeKinesisStreamingDestination API operation for Amazon DynamoDB. +// +// Returns information about the status of Kinesis streaming. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation DescribeKinesisStreamingDestination for usage and error information. +// +// Returned Error Types: +// * ResourceNotFoundException +// The operation tried to access a nonexistent table or index. The resource +// might not be specified correctly, or its status might not be ACTIVE. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/DescribeKinesisStreamingDestination +func (c *DynamoDB) DescribeKinesisStreamingDestination(input *DescribeKinesisStreamingDestinationInput) (*DescribeKinesisStreamingDestinationOutput, error) { + req, out := c.DescribeKinesisStreamingDestinationRequest(input) + return out, req.Send() +} + +// DescribeKinesisStreamingDestinationWithContext is the same as DescribeKinesisStreamingDestination with the addition of +// the ability to pass a context and additional request options. +// +// See DescribeKinesisStreamingDestination for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) DescribeKinesisStreamingDestinationWithContext(ctx aws.Context, input *DescribeKinesisStreamingDestinationInput, opts ...request.Option) (*DescribeKinesisStreamingDestinationOutput, error) { + req, out := c.DescribeKinesisStreamingDestinationRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDescribeLimits = "DescribeLimits" + +// DescribeLimitsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeLimits operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DescribeLimits for more information on using the DescribeLimits +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DescribeLimitsRequest method. +// req, resp := client.DescribeLimitsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/DescribeLimits +func (c *DynamoDB) DescribeLimitsRequest(input *DescribeLimitsInput) (req *request.Request, output *DescribeLimitsOutput) { + op := &request.Operation{ + Name: opDescribeLimits, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeLimitsInput{} + } + + output = &DescribeLimitsOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// DescribeLimits API operation for Amazon DynamoDB. +// +// Returns the current provisioned-capacity quotas for your Amazon Web Services +// account in a Region, both for the Region as a whole and for any one DynamoDB +// table that you create there. +// +// When you establish an Amazon Web Services account, the account has initial +// quotas on the maximum read capacity units and write capacity units that you +// can provision across all of your DynamoDB tables in a given Region. Also, +// there are per-table quotas that apply when you create a table there. For +// more information, see Service, Account, and Table Quotas (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Limits.html) +// page in the Amazon DynamoDB Developer Guide. +// +// Although you can increase these quotas by filing a case at Amazon Web Services +// Support Center (https://console.aws.amazon.com/support/home#/), obtaining +// the increase is not instantaneous. The DescribeLimits action lets you write +// code to compare the capacity you are currently using to those quotas imposed +// by your account so that you have enough time to apply for an increase before +// you hit a quota. +// +// For example, you could use one of the Amazon Web Services SDKs to do the +// following: +// +// Call DescribeLimits for a particular Region to obtain your current account +// quotas on provisioned capacity there. +// +// Create a variable to hold the aggregate read capacity units provisioned for +// all your tables in that Region, and one to hold the aggregate write capacity +// units. Zero them both. +// +// Call ListTables to obtain a list of all your DynamoDB tables. +// +// For each table name listed by ListTables, do the following: +// +// * Call DescribeTable with the table name. +// +// * Use the data returned by DescribeTable to add the read capacity units +// and write capacity units provisioned for the table itself to your variables. +// +// * If the table has one or more global secondary indexes (GSIs), loop over +// these GSIs and add their provisioned capacity values to your variables +// as well. +// +// Report the account quotas for that Region returned by DescribeLimits, along +// with the total current provisioned capacity levels you have calculated. +// +// This will let you see whether you are getting close to your account-level +// quotas. +// +// The per-table quotas apply only when you are creating a new table. They restrict +// the sum of the provisioned capacity of the new table itself and all its global +// secondary indexes. +// +// For existing tables and their GSIs, DynamoDB doesn't let you increase provisioned +// capacity extremely rapidly, but the only quota that applies is that the aggregate +// provisioned capacity over all your tables and GSIs cannot exceed either of +// the per-account quotas. +// +// DescribeLimits should only be called periodically. You can expect throttling +// errors if you call it more than once in a minute. +// +// The DescribeLimits Request element has no content. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation DescribeLimits for usage and error information. +// +// Returned Error Types: +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/DescribeLimits +func (c *DynamoDB) DescribeLimits(input *DescribeLimitsInput) (*DescribeLimitsOutput, error) { + req, out := c.DescribeLimitsRequest(input) + return out, req.Send() +} + +// DescribeLimitsWithContext is the same as DescribeLimits with the addition of +// the ability to pass a context and additional request options. +// +// See DescribeLimits for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) DescribeLimitsWithContext(ctx aws.Context, input *DescribeLimitsInput, opts ...request.Option) (*DescribeLimitsOutput, error) { + req, out := c.DescribeLimitsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDescribeTable = "DescribeTable" + +// DescribeTableRequest generates a "aws/request.Request" representing the +// client's request for the DescribeTable operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DescribeTable for more information on using the DescribeTable +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DescribeTableRequest method. +// req, resp := client.DescribeTableRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/DescribeTable +func (c *DynamoDB) DescribeTableRequest(input *DescribeTableInput) (req *request.Request, output *DescribeTableOutput) { + op := &request.Operation{ + Name: opDescribeTable, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeTableInput{} + } + + output = &DescribeTableOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// DescribeTable API operation for Amazon DynamoDB. +// +// Returns information about the table, including the current status of the +// table, when it was created, the primary key schema, and any indexes on the +// table. +// +// If you issue a DescribeTable request immediately after a CreateTable request, +// DynamoDB might return a ResourceNotFoundException. This is because DescribeTable +// uses an eventually consistent query, and the metadata for your table might +// not be available at that moment. Wait for a few seconds, and then try the +// DescribeTable request again. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation DescribeTable for usage and error information. +// +// Returned Error Types: +// * ResourceNotFoundException +// The operation tried to access a nonexistent table or index. The resource +// might not be specified correctly, or its status might not be ACTIVE. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/DescribeTable +func (c *DynamoDB) DescribeTable(input *DescribeTableInput) (*DescribeTableOutput, error) { + req, out := c.DescribeTableRequest(input) + return out, req.Send() +} + +// DescribeTableWithContext is the same as DescribeTable with the addition of +// the ability to pass a context and additional request options. +// +// See DescribeTable for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) DescribeTableWithContext(ctx aws.Context, input *DescribeTableInput, opts ...request.Option) (*DescribeTableOutput, error) { + req, out := c.DescribeTableRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDescribeTableReplicaAutoScaling = "DescribeTableReplicaAutoScaling" + +// DescribeTableReplicaAutoScalingRequest generates a "aws/request.Request" representing the +// client's request for the DescribeTableReplicaAutoScaling operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DescribeTableReplicaAutoScaling for more information on using the DescribeTableReplicaAutoScaling +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DescribeTableReplicaAutoScalingRequest method. +// req, resp := client.DescribeTableReplicaAutoScalingRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/DescribeTableReplicaAutoScaling +func (c *DynamoDB) DescribeTableReplicaAutoScalingRequest(input *DescribeTableReplicaAutoScalingInput) (req *request.Request, output *DescribeTableReplicaAutoScalingOutput) { + op := &request.Operation{ + Name: opDescribeTableReplicaAutoScaling, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeTableReplicaAutoScalingInput{} + } + + output = &DescribeTableReplicaAutoScalingOutput{} + req = c.newRequest(op, input, output) + return +} + +// DescribeTableReplicaAutoScaling API operation for Amazon DynamoDB. +// +// Describes auto scaling settings across replicas of the global table at once. +// +// This operation only applies to Version 2019.11.21 (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/globaltables.V2.html) +// of global tables. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation DescribeTableReplicaAutoScaling for usage and error information. +// +// Returned Error Types: +// * ResourceNotFoundException +// The operation tried to access a nonexistent table or index. The resource +// might not be specified correctly, or its status might not be ACTIVE. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/DescribeTableReplicaAutoScaling +func (c *DynamoDB) DescribeTableReplicaAutoScaling(input *DescribeTableReplicaAutoScalingInput) (*DescribeTableReplicaAutoScalingOutput, error) { + req, out := c.DescribeTableReplicaAutoScalingRequest(input) + return out, req.Send() +} + +// DescribeTableReplicaAutoScalingWithContext is the same as DescribeTableReplicaAutoScaling with the addition of +// the ability to pass a context and additional request options. +// +// See DescribeTableReplicaAutoScaling for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) DescribeTableReplicaAutoScalingWithContext(ctx aws.Context, input *DescribeTableReplicaAutoScalingInput, opts ...request.Option) (*DescribeTableReplicaAutoScalingOutput, error) { + req, out := c.DescribeTableReplicaAutoScalingRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDescribeTimeToLive = "DescribeTimeToLive" + +// DescribeTimeToLiveRequest generates a "aws/request.Request" representing the +// client's request for the DescribeTimeToLive operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DescribeTimeToLive for more information on using the DescribeTimeToLive +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DescribeTimeToLiveRequest method. +// req, resp := client.DescribeTimeToLiveRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/DescribeTimeToLive +func (c *DynamoDB) DescribeTimeToLiveRequest(input *DescribeTimeToLiveInput) (req *request.Request, output *DescribeTimeToLiveOutput) { + op := &request.Operation{ + Name: opDescribeTimeToLive, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeTimeToLiveInput{} + } + + output = &DescribeTimeToLiveOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// DescribeTimeToLive API operation for Amazon DynamoDB. +// +// Gives a description of the Time to Live (TTL) status on the specified table. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation DescribeTimeToLive for usage and error information. +// +// Returned Error Types: +// * ResourceNotFoundException +// The operation tried to access a nonexistent table or index. The resource +// might not be specified correctly, or its status might not be ACTIVE. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/DescribeTimeToLive +func (c *DynamoDB) DescribeTimeToLive(input *DescribeTimeToLiveInput) (*DescribeTimeToLiveOutput, error) { + req, out := c.DescribeTimeToLiveRequest(input) + return out, req.Send() +} + +// DescribeTimeToLiveWithContext is the same as DescribeTimeToLive with the addition of +// the ability to pass a context and additional request options. +// +// See DescribeTimeToLive for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) DescribeTimeToLiveWithContext(ctx aws.Context, input *DescribeTimeToLiveInput, opts ...request.Option) (*DescribeTimeToLiveOutput, error) { + req, out := c.DescribeTimeToLiveRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDisableKinesisStreamingDestination = "DisableKinesisStreamingDestination" + +// DisableKinesisStreamingDestinationRequest generates a "aws/request.Request" representing the +// client's request for the DisableKinesisStreamingDestination operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DisableKinesisStreamingDestination for more information on using the DisableKinesisStreamingDestination +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DisableKinesisStreamingDestinationRequest method. +// req, resp := client.DisableKinesisStreamingDestinationRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/DisableKinesisStreamingDestination +func (c *DynamoDB) DisableKinesisStreamingDestinationRequest(input *DisableKinesisStreamingDestinationInput) (req *request.Request, output *DisableKinesisStreamingDestinationOutput) { + op := &request.Operation{ + Name: opDisableKinesisStreamingDestination, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DisableKinesisStreamingDestinationInput{} + } + + output = &DisableKinesisStreamingDestinationOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// DisableKinesisStreamingDestination API operation for Amazon DynamoDB. +// +// Stops replication from the DynamoDB table to the Kinesis data stream. This +// is done without deleting either of the resources. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation DisableKinesisStreamingDestination for usage and error information. +// +// Returned Error Types: +// * InternalServerError +// An error occurred on the server side. +// +// * LimitExceededException +// There is no limit to the number of daily on-demand backups that can be taken. +// +// Up to 50 simultaneous table operations are allowed per account. These operations +// include CreateTable, UpdateTable, DeleteTable,UpdateTimeToLive, RestoreTableFromBackup, +// and RestoreTableToPointInTime. +// +// The only exception is when you are creating a table with one or more secondary +// indexes. You can have up to 25 such requests running at a time; however, +// if the table or index specifications are complex, DynamoDB might temporarily +// reduce the number of concurrent operations. +// +// There is a soft account quota of 256 tables. +// +// * ResourceInUseException +// The operation conflicts with the resource's availability. For example, you +// attempted to recreate an existing table, or tried to delete a table currently +// in the CREATING state. +// +// * ResourceNotFoundException +// The operation tried to access a nonexistent table or index. The resource +// might not be specified correctly, or its status might not be ACTIVE. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/DisableKinesisStreamingDestination +func (c *DynamoDB) DisableKinesisStreamingDestination(input *DisableKinesisStreamingDestinationInput) (*DisableKinesisStreamingDestinationOutput, error) { + req, out := c.DisableKinesisStreamingDestinationRequest(input) + return out, req.Send() +} + +// DisableKinesisStreamingDestinationWithContext is the same as DisableKinesisStreamingDestination with the addition of +// the ability to pass a context and additional request options. +// +// See DisableKinesisStreamingDestination for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) DisableKinesisStreamingDestinationWithContext(ctx aws.Context, input *DisableKinesisStreamingDestinationInput, opts ...request.Option) (*DisableKinesisStreamingDestinationOutput, error) { + req, out := c.DisableKinesisStreamingDestinationRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opEnableKinesisStreamingDestination = "EnableKinesisStreamingDestination" + +// EnableKinesisStreamingDestinationRequest generates a "aws/request.Request" representing the +// client's request for the EnableKinesisStreamingDestination operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See EnableKinesisStreamingDestination for more information on using the EnableKinesisStreamingDestination +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the EnableKinesisStreamingDestinationRequest method. +// req, resp := client.EnableKinesisStreamingDestinationRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/EnableKinesisStreamingDestination +func (c *DynamoDB) EnableKinesisStreamingDestinationRequest(input *EnableKinesisStreamingDestinationInput) (req *request.Request, output *EnableKinesisStreamingDestinationOutput) { + op := &request.Operation{ + Name: opEnableKinesisStreamingDestination, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &EnableKinesisStreamingDestinationInput{} + } + + output = &EnableKinesisStreamingDestinationOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// EnableKinesisStreamingDestination API operation for Amazon DynamoDB. +// +// Starts table data replication to the specified Kinesis data stream at a timestamp +// chosen during the enable workflow. If this operation doesn't return results +// immediately, use DescribeKinesisStreamingDestination to check if streaming +// to the Kinesis data stream is ACTIVE. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation EnableKinesisStreamingDestination for usage and error information. +// +// Returned Error Types: +// * InternalServerError +// An error occurred on the server side. +// +// * LimitExceededException +// There is no limit to the number of daily on-demand backups that can be taken. +// +// Up to 50 simultaneous table operations are allowed per account. These operations +// include CreateTable, UpdateTable, DeleteTable,UpdateTimeToLive, RestoreTableFromBackup, +// and RestoreTableToPointInTime. +// +// The only exception is when you are creating a table with one or more secondary +// indexes. You can have up to 25 such requests running at a time; however, +// if the table or index specifications are complex, DynamoDB might temporarily +// reduce the number of concurrent operations. +// +// There is a soft account quota of 256 tables. +// +// * ResourceInUseException +// The operation conflicts with the resource's availability. For example, you +// attempted to recreate an existing table, or tried to delete a table currently +// in the CREATING state. +// +// * ResourceNotFoundException +// The operation tried to access a nonexistent table or index. The resource +// might not be specified correctly, or its status might not be ACTIVE. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/EnableKinesisStreamingDestination +func (c *DynamoDB) EnableKinesisStreamingDestination(input *EnableKinesisStreamingDestinationInput) (*EnableKinesisStreamingDestinationOutput, error) { + req, out := c.EnableKinesisStreamingDestinationRequest(input) + return out, req.Send() +} + +// EnableKinesisStreamingDestinationWithContext is the same as EnableKinesisStreamingDestination with the addition of +// the ability to pass a context and additional request options. +// +// See EnableKinesisStreamingDestination for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) EnableKinesisStreamingDestinationWithContext(ctx aws.Context, input *EnableKinesisStreamingDestinationInput, opts ...request.Option) (*EnableKinesisStreamingDestinationOutput, error) { + req, out := c.EnableKinesisStreamingDestinationRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opExecuteStatement = "ExecuteStatement" + +// ExecuteStatementRequest generates a "aws/request.Request" representing the +// client's request for the ExecuteStatement operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ExecuteStatement for more information on using the ExecuteStatement +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ExecuteStatementRequest method. +// req, resp := client.ExecuteStatementRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/ExecuteStatement +func (c *DynamoDB) ExecuteStatementRequest(input *ExecuteStatementInput) (req *request.Request, output *ExecuteStatementOutput) { + op := &request.Operation{ + Name: opExecuteStatement, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ExecuteStatementInput{} + } + + output = &ExecuteStatementOutput{} + req = c.newRequest(op, input, output) + return +} + +// ExecuteStatement API operation for Amazon DynamoDB. +// +// This operation allows you to perform reads and singleton writes on data stored +// in DynamoDB, using PartiQL. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation ExecuteStatement for usage and error information. +// +// Returned Error Types: +// * ConditionalCheckFailedException +// A condition specified in the operation could not be evaluated. +// +// * ProvisionedThroughputExceededException +// Your request rate is too high. The Amazon Web Services SDKs for DynamoDB +// automatically retry requests that receive this exception. Your request is +// eventually successful, unless your retry queue is too large to finish. Reduce +// the frequency of requests and use exponential backoff. For more information, +// go to Error Retries and Exponential Backoff (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.Errors.html#Programming.Errors.RetryAndBackoff) +// in the Amazon DynamoDB Developer Guide. +// +// * ResourceNotFoundException +// The operation tried to access a nonexistent table or index. The resource +// might not be specified correctly, or its status might not be ACTIVE. +// +// * ItemCollectionSizeLimitExceededException +// An item collection is too large. This exception is only returned for tables +// that have one or more local secondary indexes. +// +// * TransactionConflictException +// Operation was rejected because there is an ongoing transaction for the item. +// +// * RequestLimitExceeded +// Throughput exceeds the current throughput quota for your account. Please +// contact Amazon Web Services Support (https://aws.amazon.com/support) to request +// a quota increase. +// +// * InternalServerError +// An error occurred on the server side. +// +// * DuplicateItemException +// There was an attempt to insert an item with the same primary key as an item +// that already exists in the DynamoDB table. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/ExecuteStatement +func (c *DynamoDB) ExecuteStatement(input *ExecuteStatementInput) (*ExecuteStatementOutput, error) { + req, out := c.ExecuteStatementRequest(input) + return out, req.Send() +} + +// ExecuteStatementWithContext is the same as ExecuteStatement with the addition of +// the ability to pass a context and additional request options. +// +// See ExecuteStatement for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) ExecuteStatementWithContext(ctx aws.Context, input *ExecuteStatementInput, opts ...request.Option) (*ExecuteStatementOutput, error) { + req, out := c.ExecuteStatementRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opExecuteTransaction = "ExecuteTransaction" + +// ExecuteTransactionRequest generates a "aws/request.Request" representing the +// client's request for the ExecuteTransaction operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ExecuteTransaction for more information on using the ExecuteTransaction +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ExecuteTransactionRequest method. +// req, resp := client.ExecuteTransactionRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/ExecuteTransaction +func (c *DynamoDB) ExecuteTransactionRequest(input *ExecuteTransactionInput) (req *request.Request, output *ExecuteTransactionOutput) { + op := &request.Operation{ + Name: opExecuteTransaction, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ExecuteTransactionInput{} + } + + output = &ExecuteTransactionOutput{} + req = c.newRequest(op, input, output) + return +} + +// ExecuteTransaction API operation for Amazon DynamoDB. +// +// This operation allows you to perform transactional reads or writes on data +// stored in DynamoDB, using PartiQL. +// +// The entire transaction must consist of either read statements or write statements, +// you cannot mix both in one transaction. The EXISTS function is an exception +// and can be used to check the condition of specific attributes of the item +// in a similar manner to ConditionCheck in the TransactWriteItems (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transaction-apis.html#transaction-apis-txwriteitems) +// API. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation ExecuteTransaction for usage and error information. +// +// Returned Error Types: +// * ResourceNotFoundException +// The operation tried to access a nonexistent table or index. The resource +// might not be specified correctly, or its status might not be ACTIVE. +// +// * TransactionCanceledException +// The entire transaction request was canceled. +// +// DynamoDB cancels a TransactWriteItems request under the following circumstances: +// +// * A condition in one of the condition expressions is not met. +// +// * A table in the TransactWriteItems request is in a different account +// or region. +// +// * More than one action in the TransactWriteItems operation targets the +// same item. +// +// * There is insufficient provisioned capacity for the transaction to be +// completed. +// +// * An item size becomes too large (larger than 400 KB), or a local secondary +// index (LSI) becomes too large, or a similar validation error occurs because +// of changes made by the transaction. +// +// * There is a user error, such as an invalid data format. +// +// DynamoDB cancels a TransactGetItems request under the following circumstances: +// +// * There is an ongoing TransactGetItems operation that conflicts with a +// concurrent PutItem, UpdateItem, DeleteItem or TransactWriteItems request. +// In this case the TransactGetItems operation fails with a TransactionCanceledException. +// +// * A table in the TransactGetItems request is in a different account or +// region. +// +// * There is insufficient provisioned capacity for the transaction to be +// completed. +// +// * There is a user error, such as an invalid data format. +// +// If using Java, DynamoDB lists the cancellation reasons on the CancellationReasons +// property. This property is not set for other languages. Transaction cancellation +// reasons are ordered in the order of requested items, if an item has no error +// it will have NONE code and Null message. +// +// Cancellation reason codes and possible error messages: +// +// * No Errors: Code: NONE Message: null +// +// * Conditional Check Failed: Code: ConditionalCheckFailed Message: The +// conditional request failed. +// +// * Item Collection Size Limit Exceeded: Code: ItemCollectionSizeLimitExceeded +// Message: Collection size exceeded. +// +// * Transaction Conflict: Code: TransactionConflict Message: Transaction +// is ongoing for the item. +// +// * Provisioned Throughput Exceeded: Code: ProvisionedThroughputExceeded +// Messages: The level of configured provisioned throughput for the table +// was exceeded. Consider increasing your provisioning level with the UpdateTable +// API. This Message is received when provisioned throughput is exceeded +// is on a provisioned DynamoDB table. The level of configured provisioned +// throughput for one or more global secondary indexes of the table was exceeded. +// Consider increasing your provisioning level for the under-provisioned +// global secondary indexes with the UpdateTable API. This message is returned +// when provisioned throughput is exceeded is on a provisioned GSI. +// +// * Throttling Error: Code: ThrottlingError Messages: Throughput exceeds +// the current capacity of your table or index. DynamoDB is automatically +// scaling your table or index so please try again shortly. If exceptions +// persist, check if you have a hot key: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-partition-key-design.html. +// This message is returned when writes get throttled on an On-Demand table +// as DynamoDB is automatically scaling the table. Throughput exceeds the +// current capacity for one or more global secondary indexes. DynamoDB is +// automatically scaling your index so please try again shortly. This message +// is returned when when writes get throttled on an On-Demand GSI as DynamoDB +// is automatically scaling the GSI. +// +// * Validation Error: Code: ValidationError Messages: One or more parameter +// values were invalid. The update expression attempted to update the secondary +// index key beyond allowed size limits. The update expression attempted +// to update the secondary index key to unsupported type. An operand in the +// update expression has an incorrect data type. Item size to update has +// exceeded the maximum allowed size. Number overflow. Attempting to store +// a number with magnitude larger than supported range. Type mismatch for +// attribute to update. Nesting Levels have exceeded supported limits. The +// document path provided in the update expression is invalid for update. +// The provided expression refers to an attribute that does not exist in +// the item. +// +// * TransactionInProgressException +// The transaction with the given request token is already in progress. +// +// * IdempotentParameterMismatchException +// DynamoDB rejected the request because you retried a request with a different +// payload but with an idempotent token that was already used. +// +// * ProvisionedThroughputExceededException +// Your request rate is too high. The Amazon Web Services SDKs for DynamoDB +// automatically retry requests that receive this exception. Your request is +// eventually successful, unless your retry queue is too large to finish. Reduce +// the frequency of requests and use exponential backoff. For more information, +// go to Error Retries and Exponential Backoff (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.Errors.html#Programming.Errors.RetryAndBackoff) +// in the Amazon DynamoDB Developer Guide. +// +// * RequestLimitExceeded +// Throughput exceeds the current throughput quota for your account. Please +// contact Amazon Web Services Support (https://aws.amazon.com/support) to request +// a quota increase. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/ExecuteTransaction +func (c *DynamoDB) ExecuteTransaction(input *ExecuteTransactionInput) (*ExecuteTransactionOutput, error) { + req, out := c.ExecuteTransactionRequest(input) + return out, req.Send() +} + +// ExecuteTransactionWithContext is the same as ExecuteTransaction with the addition of +// the ability to pass a context and additional request options. +// +// See ExecuteTransaction for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) ExecuteTransactionWithContext(ctx aws.Context, input *ExecuteTransactionInput, opts ...request.Option) (*ExecuteTransactionOutput, error) { + req, out := c.ExecuteTransactionRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opExportTableToPointInTime = "ExportTableToPointInTime" + +// ExportTableToPointInTimeRequest generates a "aws/request.Request" representing the +// client's request for the ExportTableToPointInTime operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ExportTableToPointInTime for more information on using the ExportTableToPointInTime +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ExportTableToPointInTimeRequest method. +// req, resp := client.ExportTableToPointInTimeRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/ExportTableToPointInTime +func (c *DynamoDB) ExportTableToPointInTimeRequest(input *ExportTableToPointInTimeInput) (req *request.Request, output *ExportTableToPointInTimeOutput) { + op := &request.Operation{ + Name: opExportTableToPointInTime, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ExportTableToPointInTimeInput{} + } + + output = &ExportTableToPointInTimeOutput{} + req = c.newRequest(op, input, output) + return +} + +// ExportTableToPointInTime API operation for Amazon DynamoDB. +// +// Exports table data to an S3 bucket. The table must have point in time recovery +// enabled, and you can export data from any time within the point in time recovery +// window. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation ExportTableToPointInTime for usage and error information. +// +// Returned Error Types: +// * TableNotFoundException +// A source table with the name TableName does not currently exist within the +// subscriber's account. +// +// * PointInTimeRecoveryUnavailableException +// Point in time recovery has not yet been enabled for this source table. +// +// * LimitExceededException +// There is no limit to the number of daily on-demand backups that can be taken. +// +// Up to 50 simultaneous table operations are allowed per account. These operations +// include CreateTable, UpdateTable, DeleteTable,UpdateTimeToLive, RestoreTableFromBackup, +// and RestoreTableToPointInTime. +// +// The only exception is when you are creating a table with one or more secondary +// indexes. You can have up to 25 such requests running at a time; however, +// if the table or index specifications are complex, DynamoDB might temporarily +// reduce the number of concurrent operations. +// +// There is a soft account quota of 256 tables. +// +// * InvalidExportTimeException +// The specified ExportTime is outside of the point in time recovery window. +// +// * ExportConflictException +// There was a conflict when writing to the specified S3 bucket. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/ExportTableToPointInTime +func (c *DynamoDB) ExportTableToPointInTime(input *ExportTableToPointInTimeInput) (*ExportTableToPointInTimeOutput, error) { + req, out := c.ExportTableToPointInTimeRequest(input) + return out, req.Send() +} + +// ExportTableToPointInTimeWithContext is the same as ExportTableToPointInTime with the addition of +// the ability to pass a context and additional request options. +// +// See ExportTableToPointInTime for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) ExportTableToPointInTimeWithContext(ctx aws.Context, input *ExportTableToPointInTimeInput, opts ...request.Option) (*ExportTableToPointInTimeOutput, error) { + req, out := c.ExportTableToPointInTimeRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetItem = "GetItem" + +// GetItemRequest generates a "aws/request.Request" representing the +// client's request for the GetItem operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetItem for more information on using the GetItem +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetItemRequest method. +// req, resp := client.GetItemRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/GetItem +func (c *DynamoDB) GetItemRequest(input *GetItemInput) (req *request.Request, output *GetItemOutput) { + op := &request.Operation{ + Name: opGetItem, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetItemInput{} + } + + output = &GetItemOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// GetItem API operation for Amazon DynamoDB. +// +// The GetItem operation returns a set of attributes for the item with the given +// primary key. If there is no matching item, GetItem does not return any data +// and there will be no Item element in the response. +// +// GetItem provides an eventually consistent read by default. If your application +// requires a strongly consistent read, set ConsistentRead to true. Although +// a strongly consistent read might take more time than an eventually consistent +// read, it always returns the last updated value. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation GetItem for usage and error information. +// +// Returned Error Types: +// * ProvisionedThroughputExceededException +// Your request rate is too high. The Amazon Web Services SDKs for DynamoDB +// automatically retry requests that receive this exception. Your request is +// eventually successful, unless your retry queue is too large to finish. Reduce +// the frequency of requests and use exponential backoff. For more information, +// go to Error Retries and Exponential Backoff (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.Errors.html#Programming.Errors.RetryAndBackoff) +// in the Amazon DynamoDB Developer Guide. +// +// * ResourceNotFoundException +// The operation tried to access a nonexistent table or index. The resource +// might not be specified correctly, or its status might not be ACTIVE. +// +// * RequestLimitExceeded +// Throughput exceeds the current throughput quota for your account. Please +// contact Amazon Web Services Support (https://aws.amazon.com/support) to request +// a quota increase. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/GetItem +func (c *DynamoDB) GetItem(input *GetItemInput) (*GetItemOutput, error) { + req, out := c.GetItemRequest(input) + return out, req.Send() +} + +// GetItemWithContext is the same as GetItem with the addition of +// the ability to pass a context and additional request options. +// +// See GetItem for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) GetItemWithContext(ctx aws.Context, input *GetItemInput, opts ...request.Option) (*GetItemOutput, error) { + req, out := c.GetItemRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opListBackups = "ListBackups" + +// ListBackupsRequest generates a "aws/request.Request" representing the +// client's request for the ListBackups operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ListBackups for more information on using the ListBackups +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ListBackupsRequest method. +// req, resp := client.ListBackupsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/ListBackups +func (c *DynamoDB) ListBackupsRequest(input *ListBackupsInput) (req *request.Request, output *ListBackupsOutput) { + op := &request.Operation{ + Name: opListBackups, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ListBackupsInput{} + } + + output = &ListBackupsOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// ListBackups API operation for Amazon DynamoDB. +// +// List backups associated with an Amazon Web Services account. To list backups +// for a given table, specify TableName. ListBackups returns a paginated list +// of results with at most 1 MB worth of items in a page. You can also specify +// a maximum number of entries to be returned in a page. +// +// In the request, start time is inclusive, but end time is exclusive. Note +// that these boundaries are for the time at which the original backup was requested. +// +// You can call ListBackups a maximum of five times per second. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation ListBackups for usage and error information. +// +// Returned Error Types: +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/ListBackups +func (c *DynamoDB) ListBackups(input *ListBackupsInput) (*ListBackupsOutput, error) { + req, out := c.ListBackupsRequest(input) + return out, req.Send() +} + +// ListBackupsWithContext is the same as ListBackups with the addition of +// the ability to pass a context and additional request options. +// +// See ListBackups for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) ListBackupsWithContext(ctx aws.Context, input *ListBackupsInput, opts ...request.Option) (*ListBackupsOutput, error) { + req, out := c.ListBackupsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opListContributorInsights = "ListContributorInsights" + +// ListContributorInsightsRequest generates a "aws/request.Request" representing the +// client's request for the ListContributorInsights operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ListContributorInsights for more information on using the ListContributorInsights +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ListContributorInsightsRequest method. +// req, resp := client.ListContributorInsightsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/ListContributorInsights +func (c *DynamoDB) ListContributorInsightsRequest(input *ListContributorInsightsInput) (req *request.Request, output *ListContributorInsightsOutput) { + op := &request.Operation{ + Name: opListContributorInsights, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, + } + + if input == nil { + input = &ListContributorInsightsInput{} + } + + output = &ListContributorInsightsOutput{} + req = c.newRequest(op, input, output) + return +} + +// ListContributorInsights API operation for Amazon DynamoDB. +// +// Returns a list of ContributorInsightsSummary for a table and all its global +// secondary indexes. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation ListContributorInsights for usage and error information. +// +// Returned Error Types: +// * ResourceNotFoundException +// The operation tried to access a nonexistent table or index. The resource +// might not be specified correctly, or its status might not be ACTIVE. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/ListContributorInsights +func (c *DynamoDB) ListContributorInsights(input *ListContributorInsightsInput) (*ListContributorInsightsOutput, error) { + req, out := c.ListContributorInsightsRequest(input) + return out, req.Send() +} + +// ListContributorInsightsWithContext is the same as ListContributorInsights with the addition of +// the ability to pass a context and additional request options. +// +// See ListContributorInsights for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) ListContributorInsightsWithContext(ctx aws.Context, input *ListContributorInsightsInput, opts ...request.Option) (*ListContributorInsightsOutput, error) { + req, out := c.ListContributorInsightsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// ListContributorInsightsPages iterates over the pages of a ListContributorInsights operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See ListContributorInsights method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a ListContributorInsights operation. +// pageNum := 0 +// err := client.ListContributorInsightsPages(params, +// func(page *dynamodb.ListContributorInsightsOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *DynamoDB) ListContributorInsightsPages(input *ListContributorInsightsInput, fn func(*ListContributorInsightsOutput, bool) bool) error { + return c.ListContributorInsightsPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// ListContributorInsightsPagesWithContext same as ListContributorInsightsPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) ListContributorInsightsPagesWithContext(ctx aws.Context, input *ListContributorInsightsInput, fn func(*ListContributorInsightsOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *ListContributorInsightsInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.ListContributorInsightsRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*ListContributorInsightsOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + +const opListExports = "ListExports" + +// ListExportsRequest generates a "aws/request.Request" representing the +// client's request for the ListExports operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ListExports for more information on using the ListExports +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ListExportsRequest method. +// req, resp := client.ListExportsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/ListExports +func (c *DynamoDB) ListExportsRequest(input *ListExportsInput) (req *request.Request, output *ListExportsOutput) { + op := &request.Operation{ + Name: opListExports, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, + } + + if input == nil { + input = &ListExportsInput{} + } + + output = &ListExportsOutput{} + req = c.newRequest(op, input, output) + return +} + +// ListExports API operation for Amazon DynamoDB. +// +// Lists completed exports within the past 90 days. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation ListExports for usage and error information. +// +// Returned Error Types: +// * LimitExceededException +// There is no limit to the number of daily on-demand backups that can be taken. +// +// Up to 50 simultaneous table operations are allowed per account. These operations +// include CreateTable, UpdateTable, DeleteTable,UpdateTimeToLive, RestoreTableFromBackup, +// and RestoreTableToPointInTime. +// +// The only exception is when you are creating a table with one or more secondary +// indexes. You can have up to 25 such requests running at a time; however, +// if the table or index specifications are complex, DynamoDB might temporarily +// reduce the number of concurrent operations. +// +// There is a soft account quota of 256 tables. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/ListExports +func (c *DynamoDB) ListExports(input *ListExportsInput) (*ListExportsOutput, error) { + req, out := c.ListExportsRequest(input) + return out, req.Send() +} + +// ListExportsWithContext is the same as ListExports with the addition of +// the ability to pass a context and additional request options. +// +// See ListExports for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) ListExportsWithContext(ctx aws.Context, input *ListExportsInput, opts ...request.Option) (*ListExportsOutput, error) { + req, out := c.ListExportsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// ListExportsPages iterates over the pages of a ListExports operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See ListExports method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a ListExports operation. +// pageNum := 0 +// err := client.ListExportsPages(params, +// func(page *dynamodb.ListExportsOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *DynamoDB) ListExportsPages(input *ListExportsInput, fn func(*ListExportsOutput, bool) bool) error { + return c.ListExportsPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// ListExportsPagesWithContext same as ListExportsPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) ListExportsPagesWithContext(ctx aws.Context, input *ListExportsInput, fn func(*ListExportsOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *ListExportsInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.ListExportsRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*ListExportsOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + +const opListGlobalTables = "ListGlobalTables" + +// ListGlobalTablesRequest generates a "aws/request.Request" representing the +// client's request for the ListGlobalTables operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ListGlobalTables for more information on using the ListGlobalTables +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ListGlobalTablesRequest method. +// req, resp := client.ListGlobalTablesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/ListGlobalTables +func (c *DynamoDB) ListGlobalTablesRequest(input *ListGlobalTablesInput) (req *request.Request, output *ListGlobalTablesOutput) { + op := &request.Operation{ + Name: opListGlobalTables, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ListGlobalTablesInput{} + } + + output = &ListGlobalTablesOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// ListGlobalTables API operation for Amazon DynamoDB. +// +// Lists all global tables that have a replica in the specified Region. +// +// This operation only applies to Version 2017.11.29 (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/globaltables.V1.html) +// of global tables. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation ListGlobalTables for usage and error information. +// +// Returned Error Types: +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/ListGlobalTables +func (c *DynamoDB) ListGlobalTables(input *ListGlobalTablesInput) (*ListGlobalTablesOutput, error) { + req, out := c.ListGlobalTablesRequest(input) + return out, req.Send() +} + +// ListGlobalTablesWithContext is the same as ListGlobalTables with the addition of +// the ability to pass a context and additional request options. +// +// See ListGlobalTables for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) ListGlobalTablesWithContext(ctx aws.Context, input *ListGlobalTablesInput, opts ...request.Option) (*ListGlobalTablesOutput, error) { + req, out := c.ListGlobalTablesRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opListTables = "ListTables" + +// ListTablesRequest generates a "aws/request.Request" representing the +// client's request for the ListTables operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ListTables for more information on using the ListTables +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ListTablesRequest method. +// req, resp := client.ListTablesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/ListTables +func (c *DynamoDB) ListTablesRequest(input *ListTablesInput) (req *request.Request, output *ListTablesOutput) { + op := &request.Operation{ + Name: opListTables, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"ExclusiveStartTableName"}, + OutputTokens: []string{"LastEvaluatedTableName"}, + LimitToken: "Limit", + TruncationToken: "", + }, + } + + if input == nil { + input = &ListTablesInput{} + } + + output = &ListTablesOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// ListTables API operation for Amazon DynamoDB. +// +// Returns an array of table names associated with the current account and endpoint. +// The output from ListTables is paginated, with each page returning a maximum +// of 100 table names. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation ListTables for usage and error information. +// +// Returned Error Types: +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/ListTables +func (c *DynamoDB) ListTables(input *ListTablesInput) (*ListTablesOutput, error) { + req, out := c.ListTablesRequest(input) + return out, req.Send() +} + +// ListTablesWithContext is the same as ListTables with the addition of +// the ability to pass a context and additional request options. +// +// See ListTables for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) ListTablesWithContext(ctx aws.Context, input *ListTablesInput, opts ...request.Option) (*ListTablesOutput, error) { + req, out := c.ListTablesRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// ListTablesPages iterates over the pages of a ListTables operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See ListTables method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a ListTables operation. +// pageNum := 0 +// err := client.ListTablesPages(params, +// func(page *dynamodb.ListTablesOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *DynamoDB) ListTablesPages(input *ListTablesInput, fn func(*ListTablesOutput, bool) bool) error { + return c.ListTablesPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// ListTablesPagesWithContext same as ListTablesPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) ListTablesPagesWithContext(ctx aws.Context, input *ListTablesInput, fn func(*ListTablesOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *ListTablesInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.ListTablesRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*ListTablesOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + +const opListTagsOfResource = "ListTagsOfResource" + +// ListTagsOfResourceRequest generates a "aws/request.Request" representing the +// client's request for the ListTagsOfResource operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ListTagsOfResource for more information on using the ListTagsOfResource +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ListTagsOfResourceRequest method. +// req, resp := client.ListTagsOfResourceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/ListTagsOfResource +func (c *DynamoDB) ListTagsOfResourceRequest(input *ListTagsOfResourceInput) (req *request.Request, output *ListTagsOfResourceOutput) { + op := &request.Operation{ + Name: opListTagsOfResource, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ListTagsOfResourceInput{} + } + + output = &ListTagsOfResourceOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// ListTagsOfResource API operation for Amazon DynamoDB. +// +// List all tags on an Amazon DynamoDB resource. You can call ListTagsOfResource +// up to 10 times per second, per account. +// +// For an overview on tagging DynamoDB resources, see Tagging for DynamoDB (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Tagging.html) +// in the Amazon DynamoDB Developer Guide. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation ListTagsOfResource for usage and error information. +// +// Returned Error Types: +// * ResourceNotFoundException +// The operation tried to access a nonexistent table or index. The resource +// might not be specified correctly, or its status might not be ACTIVE. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/ListTagsOfResource +func (c *DynamoDB) ListTagsOfResource(input *ListTagsOfResourceInput) (*ListTagsOfResourceOutput, error) { + req, out := c.ListTagsOfResourceRequest(input) + return out, req.Send() +} + +// ListTagsOfResourceWithContext is the same as ListTagsOfResource with the addition of +// the ability to pass a context and additional request options. +// +// See ListTagsOfResource for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) ListTagsOfResourceWithContext(ctx aws.Context, input *ListTagsOfResourceInput, opts ...request.Option) (*ListTagsOfResourceOutput, error) { + req, out := c.ListTagsOfResourceRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opPutItem = "PutItem" + +// PutItemRequest generates a "aws/request.Request" representing the +// client's request for the PutItem operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See PutItem for more information on using the PutItem +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the PutItemRequest method. +// req, resp := client.PutItemRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/PutItem +func (c *DynamoDB) PutItemRequest(input *PutItemInput) (req *request.Request, output *PutItemOutput) { + op := &request.Operation{ + Name: opPutItem, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &PutItemInput{} + } + + output = &PutItemOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// PutItem API operation for Amazon DynamoDB. +// +// Creates a new item, or replaces an old item with a new item. If an item that +// has the same primary key as the new item already exists in the specified +// table, the new item completely replaces the existing item. You can perform +// a conditional put operation (add a new item if one with the specified primary +// key doesn't exist), or replace an existing item if it has certain attribute +// values. You can return the item's attribute values in the same operation, +// using the ReturnValues parameter. +// +// This topic provides general information about the PutItem API. +// +// For information on how to call the PutItem API using the Amazon Web Services +// SDK in specific languages, see the following: +// +// * PutItem in the Command Line Interface (http://docs.aws.amazon.com/goto/aws-cli/dynamodb-2012-08-10/PutItem) +// +// * PutItem in the SDK for .NET (http://docs.aws.amazon.com/goto/DotNetSDKV3/dynamodb-2012-08-10/PutItem) +// +// * PutItem in the SDK for C++ (http://docs.aws.amazon.com/goto/SdkForCpp/dynamodb-2012-08-10/PutItem) +// +// * PutItem in the SDK for Go (http://docs.aws.amazon.com/goto/SdkForGoV1/dynamodb-2012-08-10/PutItem) +// +// * PutItem in the SDK for Java (http://docs.aws.amazon.com/goto/SdkForJava/dynamodb-2012-08-10/PutItem) +// +// * PutItem in the SDK for JavaScript (http://docs.aws.amazon.com/goto/AWSJavaScriptSDK/dynamodb-2012-08-10/PutItem) +// +// * PutItem in the SDK for PHP V3 (http://docs.aws.amazon.com/goto/SdkForPHPV3/dynamodb-2012-08-10/PutItem) +// +// * PutItem in the SDK for Python (Boto) (http://docs.aws.amazon.com/goto/boto3/dynamodb-2012-08-10/PutItem) +// +// * PutItem in the SDK for Ruby V2 (http://docs.aws.amazon.com/goto/SdkForRubyV2/dynamodb-2012-08-10/PutItem) +// +// When you add an item, the primary key attributes are the only required attributes. +// Attribute values cannot be null. +// +// Empty String and Binary attribute values are allowed. Attribute values of +// type String and Binary must have a length greater than zero if the attribute +// is used as a key attribute for a table or index. Set type attributes cannot +// be empty. +// +// Invalid Requests with empty values will be rejected with a ValidationException +// exception. +// +// To prevent a new item from replacing an existing item, use a conditional +// expression that contains the attribute_not_exists function with the name +// of the attribute being used as the partition key for the table. Since every +// record must contain that attribute, the attribute_not_exists function will +// only succeed if no matching item exists. +// +// For more information about PutItem, see Working with Items (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithItems.html) +// in the Amazon DynamoDB Developer Guide. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation PutItem for usage and error information. +// +// Returned Error Types: +// * ConditionalCheckFailedException +// A condition specified in the operation could not be evaluated. +// +// * ProvisionedThroughputExceededException +// Your request rate is too high. The Amazon Web Services SDKs for DynamoDB +// automatically retry requests that receive this exception. Your request is +// eventually successful, unless your retry queue is too large to finish. Reduce +// the frequency of requests and use exponential backoff. For more information, +// go to Error Retries and Exponential Backoff (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.Errors.html#Programming.Errors.RetryAndBackoff) +// in the Amazon DynamoDB Developer Guide. +// +// * ResourceNotFoundException +// The operation tried to access a nonexistent table or index. The resource +// might not be specified correctly, or its status might not be ACTIVE. +// +// * ItemCollectionSizeLimitExceededException +// An item collection is too large. This exception is only returned for tables +// that have one or more local secondary indexes. +// +// * TransactionConflictException +// Operation was rejected because there is an ongoing transaction for the item. +// +// * RequestLimitExceeded +// Throughput exceeds the current throughput quota for your account. Please +// contact Amazon Web Services Support (https://aws.amazon.com/support) to request +// a quota increase. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/PutItem +func (c *DynamoDB) PutItem(input *PutItemInput) (*PutItemOutput, error) { + req, out := c.PutItemRequest(input) + return out, req.Send() +} + +// PutItemWithContext is the same as PutItem with the addition of +// the ability to pass a context and additional request options. +// +// See PutItem for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) PutItemWithContext(ctx aws.Context, input *PutItemInput, opts ...request.Option) (*PutItemOutput, error) { + req, out := c.PutItemRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opQuery = "Query" + +// QueryRequest generates a "aws/request.Request" representing the +// client's request for the Query operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See Query for more information on using the Query +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the QueryRequest method. +// req, resp := client.QueryRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/Query +func (c *DynamoDB) QueryRequest(input *QueryInput) (req *request.Request, output *QueryOutput) { + op := &request.Operation{ + Name: opQuery, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"ExclusiveStartKey"}, + OutputTokens: []string{"LastEvaluatedKey"}, + LimitToken: "Limit", + TruncationToken: "", + }, + } + + if input == nil { + input = &QueryInput{} + } + + output = &QueryOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// Query API operation for Amazon DynamoDB. +// +// You must provide the name of the partition key attribute and a single value +// for that attribute. Query returns all items with that partition key value. +// Optionally, you can provide a sort key attribute and use a comparison operator +// to refine the search results. +// +// Use the KeyConditionExpression parameter to provide a specific value for +// the partition key. The Query operation will return all of the items from +// the table or index with that partition key value. You can optionally narrow +// the scope of the Query operation by specifying a sort key value and a comparison +// operator in KeyConditionExpression. To further refine the Query results, +// you can optionally provide a FilterExpression. A FilterExpression determines +// which items within the results should be returned to you. All of the other +// results are discarded. +// +// A Query operation always returns a result set. If no matching items are found, +// the result set will be empty. Queries that do not return results consume +// the minimum number of read capacity units for that type of read operation. +// +// DynamoDB calculates the number of read capacity units consumed based on item +// size, not on the amount of data that is returned to an application. The number +// of capacity units consumed will be the same whether you request all of the +// attributes (the default behavior) or just some of them (using a projection +// expression). The number will also be the same whether or not you use a FilterExpression. +// +// Query results are always sorted by the sort key value. If the data type of +// the sort key is Number, the results are returned in numeric order; otherwise, +// the results are returned in order of UTF-8 bytes. By default, the sort order +// is ascending. To reverse the order, set the ScanIndexForward parameter to +// false. +// +// A single Query operation will read up to the maximum number of items set +// (if using the Limit parameter) or a maximum of 1 MB of data and then apply +// any filtering to the results using FilterExpression. If LastEvaluatedKey +// is present in the response, you will need to paginate the result set. For +// more information, see Paginating the Results (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.html#Query.Pagination) +// in the Amazon DynamoDB Developer Guide. +// +// FilterExpression is applied after a Query finishes, but before the results +// are returned. A FilterExpression cannot contain partition key or sort key +// attributes. You need to specify those attributes in the KeyConditionExpression. +// +// A Query operation can return an empty result set and a LastEvaluatedKey if +// all the items read for the page of results are filtered out. +// +// You can query a table, a local secondary index, or a global secondary index. +// For a query on a table or on a local secondary index, you can set the ConsistentRead +// parameter to true and obtain a strongly consistent result. Global secondary +// indexes support eventually consistent reads only, so do not specify ConsistentRead +// when querying a global secondary index. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation Query for usage and error information. +// +// Returned Error Types: +// * ProvisionedThroughputExceededException +// Your request rate is too high. The Amazon Web Services SDKs for DynamoDB +// automatically retry requests that receive this exception. Your request is +// eventually successful, unless your retry queue is too large to finish. Reduce +// the frequency of requests and use exponential backoff. For more information, +// go to Error Retries and Exponential Backoff (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.Errors.html#Programming.Errors.RetryAndBackoff) +// in the Amazon DynamoDB Developer Guide. +// +// * ResourceNotFoundException +// The operation tried to access a nonexistent table or index. The resource +// might not be specified correctly, or its status might not be ACTIVE. +// +// * RequestLimitExceeded +// Throughput exceeds the current throughput quota for your account. Please +// contact Amazon Web Services Support (https://aws.amazon.com/support) to request +// a quota increase. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/Query +func (c *DynamoDB) Query(input *QueryInput) (*QueryOutput, error) { + req, out := c.QueryRequest(input) + return out, req.Send() +} + +// QueryWithContext is the same as Query with the addition of +// the ability to pass a context and additional request options. +// +// See Query for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) QueryWithContext(ctx aws.Context, input *QueryInput, opts ...request.Option) (*QueryOutput, error) { + req, out := c.QueryRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// QueryPages iterates over the pages of a Query operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See Query method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a Query operation. +// pageNum := 0 +// err := client.QueryPages(params, +// func(page *dynamodb.QueryOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *DynamoDB) QueryPages(input *QueryInput, fn func(*QueryOutput, bool) bool) error { + return c.QueryPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// QueryPagesWithContext same as QueryPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) QueryPagesWithContext(ctx aws.Context, input *QueryInput, fn func(*QueryOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *QueryInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.QueryRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*QueryOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + +const opRestoreTableFromBackup = "RestoreTableFromBackup" + +// RestoreTableFromBackupRequest generates a "aws/request.Request" representing the +// client's request for the RestoreTableFromBackup operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See RestoreTableFromBackup for more information on using the RestoreTableFromBackup +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the RestoreTableFromBackupRequest method. +// req, resp := client.RestoreTableFromBackupRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/RestoreTableFromBackup +func (c *DynamoDB) RestoreTableFromBackupRequest(input *RestoreTableFromBackupInput) (req *request.Request, output *RestoreTableFromBackupOutput) { + op := &request.Operation{ + Name: opRestoreTableFromBackup, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &RestoreTableFromBackupInput{} + } + + output = &RestoreTableFromBackupOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// RestoreTableFromBackup API operation for Amazon DynamoDB. +// +// Creates a new table from an existing backup. Any number of users can execute +// up to 4 concurrent restores (any type of restore) in a given account. +// +// You can call RestoreTableFromBackup at a maximum rate of 10 times per second. +// +// You must manually set up the following on the restored table: +// +// * Auto scaling policies +// +// * IAM policies +// +// * Amazon CloudWatch metrics and alarms +// +// * Tags +// +// * Stream settings +// +// * Time to Live (TTL) settings +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation RestoreTableFromBackup for usage and error information. +// +// Returned Error Types: +// * TableAlreadyExistsException +// A target table with the specified name already exists. +// +// * TableInUseException +// A target table with the specified name is either being created or deleted. +// +// * BackupNotFoundException +// Backup not found for the given BackupARN. +// +// * BackupInUseException +// There is another ongoing conflicting backup control plane operation on the +// table. The backup is either being created, deleted or restored to a table. +// +// * LimitExceededException +// There is no limit to the number of daily on-demand backups that can be taken. +// +// Up to 50 simultaneous table operations are allowed per account. These operations +// include CreateTable, UpdateTable, DeleteTable,UpdateTimeToLive, RestoreTableFromBackup, +// and RestoreTableToPointInTime. +// +// The only exception is when you are creating a table with one or more secondary +// indexes. You can have up to 25 such requests running at a time; however, +// if the table or index specifications are complex, DynamoDB might temporarily +// reduce the number of concurrent operations. +// +// There is a soft account quota of 256 tables. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/RestoreTableFromBackup +func (c *DynamoDB) RestoreTableFromBackup(input *RestoreTableFromBackupInput) (*RestoreTableFromBackupOutput, error) { + req, out := c.RestoreTableFromBackupRequest(input) + return out, req.Send() +} + +// RestoreTableFromBackupWithContext is the same as RestoreTableFromBackup with the addition of +// the ability to pass a context and additional request options. +// +// See RestoreTableFromBackup for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) RestoreTableFromBackupWithContext(ctx aws.Context, input *RestoreTableFromBackupInput, opts ...request.Option) (*RestoreTableFromBackupOutput, error) { + req, out := c.RestoreTableFromBackupRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opRestoreTableToPointInTime = "RestoreTableToPointInTime" + +// RestoreTableToPointInTimeRequest generates a "aws/request.Request" representing the +// client's request for the RestoreTableToPointInTime operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See RestoreTableToPointInTime for more information on using the RestoreTableToPointInTime +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the RestoreTableToPointInTimeRequest method. +// req, resp := client.RestoreTableToPointInTimeRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/RestoreTableToPointInTime +func (c *DynamoDB) RestoreTableToPointInTimeRequest(input *RestoreTableToPointInTimeInput) (req *request.Request, output *RestoreTableToPointInTimeOutput) { + op := &request.Operation{ + Name: opRestoreTableToPointInTime, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &RestoreTableToPointInTimeInput{} + } + + output = &RestoreTableToPointInTimeOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// RestoreTableToPointInTime API operation for Amazon DynamoDB. +// +// Restores the specified table to the specified point in time within EarliestRestorableDateTime +// and LatestRestorableDateTime. You can restore your table to any point in +// time during the last 35 days. Any number of users can execute up to 4 concurrent +// restores (any type of restore) in a given account. +// +// When you restore using point in time recovery, DynamoDB restores your table +// data to the state based on the selected date and time (day:hour:minute:second) +// to a new table. +// +// Along with data, the following are also included on the new restored table +// using point in time recovery: +// +// * Global secondary indexes (GSIs) +// +// * Local secondary indexes (LSIs) +// +// * Provisioned read and write capacity +// +// * Encryption settings All these settings come from the current settings +// of the source table at the time of restore. +// +// You must manually set up the following on the restored table: +// +// * Auto scaling policies +// +// * IAM policies +// +// * Amazon CloudWatch metrics and alarms +// +// * Tags +// +// * Stream settings +// +// * Time to Live (TTL) settings +// +// * Point in time recovery settings +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation RestoreTableToPointInTime for usage and error information. +// +// Returned Error Types: +// * TableAlreadyExistsException +// A target table with the specified name already exists. +// +// * TableNotFoundException +// A source table with the name TableName does not currently exist within the +// subscriber's account. +// +// * TableInUseException +// A target table with the specified name is either being created or deleted. +// +// * LimitExceededException +// There is no limit to the number of daily on-demand backups that can be taken. +// +// Up to 50 simultaneous table operations are allowed per account. These operations +// include CreateTable, UpdateTable, DeleteTable,UpdateTimeToLive, RestoreTableFromBackup, +// and RestoreTableToPointInTime. +// +// The only exception is when you are creating a table with one or more secondary +// indexes. You can have up to 25 such requests running at a time; however, +// if the table or index specifications are complex, DynamoDB might temporarily +// reduce the number of concurrent operations. +// +// There is a soft account quota of 256 tables. +// +// * InvalidRestoreTimeException +// An invalid restore time was specified. RestoreDateTime must be between EarliestRestorableDateTime +// and LatestRestorableDateTime. +// +// * PointInTimeRecoveryUnavailableException +// Point in time recovery has not yet been enabled for this source table. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/RestoreTableToPointInTime +func (c *DynamoDB) RestoreTableToPointInTime(input *RestoreTableToPointInTimeInput) (*RestoreTableToPointInTimeOutput, error) { + req, out := c.RestoreTableToPointInTimeRequest(input) + return out, req.Send() +} + +// RestoreTableToPointInTimeWithContext is the same as RestoreTableToPointInTime with the addition of +// the ability to pass a context and additional request options. +// +// See RestoreTableToPointInTime for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) RestoreTableToPointInTimeWithContext(ctx aws.Context, input *RestoreTableToPointInTimeInput, opts ...request.Option) (*RestoreTableToPointInTimeOutput, error) { + req, out := c.RestoreTableToPointInTimeRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opScan = "Scan" + +// ScanRequest generates a "aws/request.Request" representing the +// client's request for the Scan operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See Scan for more information on using the Scan +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ScanRequest method. +// req, resp := client.ScanRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/Scan +func (c *DynamoDB) ScanRequest(input *ScanInput) (req *request.Request, output *ScanOutput) { + op := &request.Operation{ + Name: opScan, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"ExclusiveStartKey"}, + OutputTokens: []string{"LastEvaluatedKey"}, + LimitToken: "Limit", + TruncationToken: "", + }, + } + + if input == nil { + input = &ScanInput{} + } + + output = &ScanOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// Scan API operation for Amazon DynamoDB. +// +// The Scan operation returns one or more items and item attributes by accessing +// every item in a table or a secondary index. To have DynamoDB return fewer +// items, you can provide a FilterExpression operation. +// +// If the total number of scanned items exceeds the maximum dataset size limit +// of 1 MB, the scan stops and results are returned to the user as a LastEvaluatedKey +// value to continue the scan in a subsequent operation. The results also include +// the number of items exceeding the limit. A scan can result in no table data +// meeting the filter criteria. +// +// A single Scan operation reads up to the maximum number of items set (if using +// the Limit parameter) or a maximum of 1 MB of data and then apply any filtering +// to the results using FilterExpression. If LastEvaluatedKey is present in +// the response, you need to paginate the result set. For more information, +// see Paginating the Results (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Scan.html#Scan.Pagination) +// in the Amazon DynamoDB Developer Guide. +// +// Scan operations proceed sequentially; however, for faster performance on +// a large table or secondary index, applications can request a parallel Scan +// operation by providing the Segment and TotalSegments parameters. For more +// information, see Parallel Scan (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Scan.html#Scan.ParallelScan) +// in the Amazon DynamoDB Developer Guide. +// +// Scan uses eventually consistent reads when accessing the data in a table; +// therefore, the result set might not include the changes to data in the table +// immediately before the operation began. If you need a consistent copy of +// the data, as of the time that the Scan begins, you can set the ConsistentRead +// parameter to true. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation Scan for usage and error information. +// +// Returned Error Types: +// * ProvisionedThroughputExceededException +// Your request rate is too high. The Amazon Web Services SDKs for DynamoDB +// automatically retry requests that receive this exception. Your request is +// eventually successful, unless your retry queue is too large to finish. Reduce +// the frequency of requests and use exponential backoff. For more information, +// go to Error Retries and Exponential Backoff (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.Errors.html#Programming.Errors.RetryAndBackoff) +// in the Amazon DynamoDB Developer Guide. +// +// * ResourceNotFoundException +// The operation tried to access a nonexistent table or index. The resource +// might not be specified correctly, or its status might not be ACTIVE. +// +// * RequestLimitExceeded +// Throughput exceeds the current throughput quota for your account. Please +// contact Amazon Web Services Support (https://aws.amazon.com/support) to request +// a quota increase. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/Scan +func (c *DynamoDB) Scan(input *ScanInput) (*ScanOutput, error) { + req, out := c.ScanRequest(input) + return out, req.Send() +} + +// ScanWithContext is the same as Scan with the addition of +// the ability to pass a context and additional request options. +// +// See Scan for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) ScanWithContext(ctx aws.Context, input *ScanInput, opts ...request.Option) (*ScanOutput, error) { + req, out := c.ScanRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// ScanPages iterates over the pages of a Scan operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See Scan method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a Scan operation. +// pageNum := 0 +// err := client.ScanPages(params, +// func(page *dynamodb.ScanOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *DynamoDB) ScanPages(input *ScanInput, fn func(*ScanOutput, bool) bool) error { + return c.ScanPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// ScanPagesWithContext same as ScanPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) ScanPagesWithContext(ctx aws.Context, input *ScanInput, fn func(*ScanOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *ScanInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.ScanRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*ScanOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + +const opTagResource = "TagResource" + +// TagResourceRequest generates a "aws/request.Request" representing the +// client's request for the TagResource operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See TagResource for more information on using the TagResource +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the TagResourceRequest method. +// req, resp := client.TagResourceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/TagResource +func (c *DynamoDB) TagResourceRequest(input *TagResourceInput) (req *request.Request, output *TagResourceOutput) { + op := &request.Operation{ + Name: opTagResource, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &TagResourceInput{} + } + + output = &TagResourceOutput{} + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Swap(jsonrpc.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// TagResource API operation for Amazon DynamoDB. +// +// Associate a set of tags with an Amazon DynamoDB resource. You can then activate +// these user-defined tags so that they appear on the Billing and Cost Management +// console for cost allocation tracking. You can call TagResource up to five +// times per second, per account. +// +// For an overview on tagging DynamoDB resources, see Tagging for DynamoDB (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Tagging.html) +// in the Amazon DynamoDB Developer Guide. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation TagResource for usage and error information. +// +// Returned Error Types: +// * LimitExceededException +// There is no limit to the number of daily on-demand backups that can be taken. +// +// Up to 50 simultaneous table operations are allowed per account. These operations +// include CreateTable, UpdateTable, DeleteTable,UpdateTimeToLive, RestoreTableFromBackup, +// and RestoreTableToPointInTime. +// +// The only exception is when you are creating a table with one or more secondary +// indexes. You can have up to 25 such requests running at a time; however, +// if the table or index specifications are complex, DynamoDB might temporarily +// reduce the number of concurrent operations. +// +// There is a soft account quota of 256 tables. +// +// * ResourceNotFoundException +// The operation tried to access a nonexistent table or index. The resource +// might not be specified correctly, or its status might not be ACTIVE. +// +// * InternalServerError +// An error occurred on the server side. +// +// * ResourceInUseException +// The operation conflicts with the resource's availability. For example, you +// attempted to recreate an existing table, or tried to delete a table currently +// in the CREATING state. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/TagResource +func (c *DynamoDB) TagResource(input *TagResourceInput) (*TagResourceOutput, error) { + req, out := c.TagResourceRequest(input) + return out, req.Send() +} + +// TagResourceWithContext is the same as TagResource with the addition of +// the ability to pass a context and additional request options. +// +// See TagResource for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) TagResourceWithContext(ctx aws.Context, input *TagResourceInput, opts ...request.Option) (*TagResourceOutput, error) { + req, out := c.TagResourceRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opTransactGetItems = "TransactGetItems" + +// TransactGetItemsRequest generates a "aws/request.Request" representing the +// client's request for the TransactGetItems operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See TransactGetItems for more information on using the TransactGetItems +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the TransactGetItemsRequest method. +// req, resp := client.TransactGetItemsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/TransactGetItems +func (c *DynamoDB) TransactGetItemsRequest(input *TransactGetItemsInput) (req *request.Request, output *TransactGetItemsOutput) { + op := &request.Operation{ + Name: opTransactGetItems, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &TransactGetItemsInput{} + } + + output = &TransactGetItemsOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// TransactGetItems API operation for Amazon DynamoDB. +// +// TransactGetItems is a synchronous operation that atomically retrieves multiple +// items from one or more tables (but not from indexes) in a single account +// and Region. A TransactGetItems call can contain up to 25 TransactGetItem +// objects, each of which contains a Get structure that specifies an item to +// retrieve from a table in the account and Region. A call to TransactGetItems +// cannot retrieve items from tables in more than one Amazon Web Services account +// or Region. The aggregate size of the items in the transaction cannot exceed +// 4 MB. +// +// DynamoDB rejects the entire TransactGetItems request if any of the following +// is true: +// +// * A conflicting operation is in the process of updating an item to be +// read. +// +// * There is insufficient provisioned capacity for the transaction to be +// completed. +// +// * There is a user error, such as an invalid data format. +// +// * The aggregate size of the items in the transaction cannot exceed 4 MB. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation TransactGetItems for usage and error information. +// +// Returned Error Types: +// * ResourceNotFoundException +// The operation tried to access a nonexistent table or index. The resource +// might not be specified correctly, or its status might not be ACTIVE. +// +// * TransactionCanceledException +// The entire transaction request was canceled. +// +// DynamoDB cancels a TransactWriteItems request under the following circumstances: +// +// * A condition in one of the condition expressions is not met. +// +// * A table in the TransactWriteItems request is in a different account +// or region. +// +// * More than one action in the TransactWriteItems operation targets the +// same item. +// +// * There is insufficient provisioned capacity for the transaction to be +// completed. +// +// * An item size becomes too large (larger than 400 KB), or a local secondary +// index (LSI) becomes too large, or a similar validation error occurs because +// of changes made by the transaction. +// +// * There is a user error, such as an invalid data format. +// +// DynamoDB cancels a TransactGetItems request under the following circumstances: +// +// * There is an ongoing TransactGetItems operation that conflicts with a +// concurrent PutItem, UpdateItem, DeleteItem or TransactWriteItems request. +// In this case the TransactGetItems operation fails with a TransactionCanceledException. +// +// * A table in the TransactGetItems request is in a different account or +// region. +// +// * There is insufficient provisioned capacity for the transaction to be +// completed. +// +// * There is a user error, such as an invalid data format. +// +// If using Java, DynamoDB lists the cancellation reasons on the CancellationReasons +// property. This property is not set for other languages. Transaction cancellation +// reasons are ordered in the order of requested items, if an item has no error +// it will have NONE code and Null message. +// +// Cancellation reason codes and possible error messages: +// +// * No Errors: Code: NONE Message: null +// +// * Conditional Check Failed: Code: ConditionalCheckFailed Message: The +// conditional request failed. +// +// * Item Collection Size Limit Exceeded: Code: ItemCollectionSizeLimitExceeded +// Message: Collection size exceeded. +// +// * Transaction Conflict: Code: TransactionConflict Message: Transaction +// is ongoing for the item. +// +// * Provisioned Throughput Exceeded: Code: ProvisionedThroughputExceeded +// Messages: The level of configured provisioned throughput for the table +// was exceeded. Consider increasing your provisioning level with the UpdateTable +// API. This Message is received when provisioned throughput is exceeded +// is on a provisioned DynamoDB table. The level of configured provisioned +// throughput for one or more global secondary indexes of the table was exceeded. +// Consider increasing your provisioning level for the under-provisioned +// global secondary indexes with the UpdateTable API. This message is returned +// when provisioned throughput is exceeded is on a provisioned GSI. +// +// * Throttling Error: Code: ThrottlingError Messages: Throughput exceeds +// the current capacity of your table or index. DynamoDB is automatically +// scaling your table or index so please try again shortly. If exceptions +// persist, check if you have a hot key: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-partition-key-design.html. +// This message is returned when writes get throttled on an On-Demand table +// as DynamoDB is automatically scaling the table. Throughput exceeds the +// current capacity for one or more global secondary indexes. DynamoDB is +// automatically scaling your index so please try again shortly. This message +// is returned when when writes get throttled on an On-Demand GSI as DynamoDB +// is automatically scaling the GSI. +// +// * Validation Error: Code: ValidationError Messages: One or more parameter +// values were invalid. The update expression attempted to update the secondary +// index key beyond allowed size limits. The update expression attempted +// to update the secondary index key to unsupported type. An operand in the +// update expression has an incorrect data type. Item size to update has +// exceeded the maximum allowed size. Number overflow. Attempting to store +// a number with magnitude larger than supported range. Type mismatch for +// attribute to update. Nesting Levels have exceeded supported limits. The +// document path provided in the update expression is invalid for update. +// The provided expression refers to an attribute that does not exist in +// the item. +// +// * ProvisionedThroughputExceededException +// Your request rate is too high. The Amazon Web Services SDKs for DynamoDB +// automatically retry requests that receive this exception. Your request is +// eventually successful, unless your retry queue is too large to finish. Reduce +// the frequency of requests and use exponential backoff. For more information, +// go to Error Retries and Exponential Backoff (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.Errors.html#Programming.Errors.RetryAndBackoff) +// in the Amazon DynamoDB Developer Guide. +// +// * RequestLimitExceeded +// Throughput exceeds the current throughput quota for your account. Please +// contact Amazon Web Services Support (https://aws.amazon.com/support) to request +// a quota increase. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/TransactGetItems +func (c *DynamoDB) TransactGetItems(input *TransactGetItemsInput) (*TransactGetItemsOutput, error) { + req, out := c.TransactGetItemsRequest(input) + return out, req.Send() +} + +// TransactGetItemsWithContext is the same as TransactGetItems with the addition of +// the ability to pass a context and additional request options. +// +// See TransactGetItems for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) TransactGetItemsWithContext(ctx aws.Context, input *TransactGetItemsInput, opts ...request.Option) (*TransactGetItemsOutput, error) { + req, out := c.TransactGetItemsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opTransactWriteItems = "TransactWriteItems" + +// TransactWriteItemsRequest generates a "aws/request.Request" representing the +// client's request for the TransactWriteItems operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See TransactWriteItems for more information on using the TransactWriteItems +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the TransactWriteItemsRequest method. +// req, resp := client.TransactWriteItemsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/TransactWriteItems +func (c *DynamoDB) TransactWriteItemsRequest(input *TransactWriteItemsInput) (req *request.Request, output *TransactWriteItemsOutput) { + op := &request.Operation{ + Name: opTransactWriteItems, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &TransactWriteItemsInput{} + } + + output = &TransactWriteItemsOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// TransactWriteItems API operation for Amazon DynamoDB. +// +// TransactWriteItems is a synchronous write operation that groups up to 25 +// action requests. These actions can target items in different tables, but +// not in different Amazon Web Services accounts or Regions, and no two actions +// can target the same item. For example, you cannot both ConditionCheck and +// Update the same item. The aggregate size of the items in the transaction +// cannot exceed 4 MB. +// +// The actions are completed atomically so that either all of them succeed, +// or all of them fail. They are defined by the following objects: +// +// * Put — Initiates a PutItem operation to write a new item. This structure +// specifies the primary key of the item to be written, the name of the table +// to write it in, an optional condition expression that must be satisfied +// for the write to succeed, a list of the item's attributes, and a field +// indicating whether to retrieve the item's attributes if the condition +// is not met. +// +// * Update — Initiates an UpdateItem operation to update an existing item. +// This structure specifies the primary key of the item to be updated, the +// name of the table where it resides, an optional condition expression that +// must be satisfied for the update to succeed, an expression that defines +// one or more attributes to be updated, and a field indicating whether to +// retrieve the item's attributes if the condition is not met. +// +// * Delete — Initiates a DeleteItem operation to delete an existing item. +// This structure specifies the primary key of the item to be deleted, the +// name of the table where it resides, an optional condition expression that +// must be satisfied for the deletion to succeed, and a field indicating +// whether to retrieve the item's attributes if the condition is not met. +// +// * ConditionCheck — Applies a condition to an item that is not being +// modified by the transaction. This structure specifies the primary key +// of the item to be checked, the name of the table where it resides, a condition +// expression that must be satisfied for the transaction to succeed, and +// a field indicating whether to retrieve the item's attributes if the condition +// is not met. +// +// DynamoDB rejects the entire TransactWriteItems request if any of the following +// is true: +// +// * A condition in one of the condition expressions is not met. +// +// * An ongoing operation is in the process of updating the same item. +// +// * There is insufficient provisioned capacity for the transaction to be +// completed. +// +// * An item size becomes too large (bigger than 400 KB), a local secondary +// index (LSI) becomes too large, or a similar validation error occurs because +// of changes made by the transaction. +// +// * The aggregate size of the items in the transaction exceeds 4 MB. +// +// * There is a user error, such as an invalid data format. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation TransactWriteItems for usage and error information. +// +// Returned Error Types: +// * ResourceNotFoundException +// The operation tried to access a nonexistent table or index. The resource +// might not be specified correctly, or its status might not be ACTIVE. +// +// * TransactionCanceledException +// The entire transaction request was canceled. +// +// DynamoDB cancels a TransactWriteItems request under the following circumstances: +// +// * A condition in one of the condition expressions is not met. +// +// * A table in the TransactWriteItems request is in a different account +// or region. +// +// * More than one action in the TransactWriteItems operation targets the +// same item. +// +// * There is insufficient provisioned capacity for the transaction to be +// completed. +// +// * An item size becomes too large (larger than 400 KB), or a local secondary +// index (LSI) becomes too large, or a similar validation error occurs because +// of changes made by the transaction. +// +// * There is a user error, such as an invalid data format. +// +// DynamoDB cancels a TransactGetItems request under the following circumstances: +// +// * There is an ongoing TransactGetItems operation that conflicts with a +// concurrent PutItem, UpdateItem, DeleteItem or TransactWriteItems request. +// In this case the TransactGetItems operation fails with a TransactionCanceledException. +// +// * A table in the TransactGetItems request is in a different account or +// region. +// +// * There is insufficient provisioned capacity for the transaction to be +// completed. +// +// * There is a user error, such as an invalid data format. +// +// If using Java, DynamoDB lists the cancellation reasons on the CancellationReasons +// property. This property is not set for other languages. Transaction cancellation +// reasons are ordered in the order of requested items, if an item has no error +// it will have NONE code and Null message. +// +// Cancellation reason codes and possible error messages: +// +// * No Errors: Code: NONE Message: null +// +// * Conditional Check Failed: Code: ConditionalCheckFailed Message: The +// conditional request failed. +// +// * Item Collection Size Limit Exceeded: Code: ItemCollectionSizeLimitExceeded +// Message: Collection size exceeded. +// +// * Transaction Conflict: Code: TransactionConflict Message: Transaction +// is ongoing for the item. +// +// * Provisioned Throughput Exceeded: Code: ProvisionedThroughputExceeded +// Messages: The level of configured provisioned throughput for the table +// was exceeded. Consider increasing your provisioning level with the UpdateTable +// API. This Message is received when provisioned throughput is exceeded +// is on a provisioned DynamoDB table. The level of configured provisioned +// throughput for one or more global secondary indexes of the table was exceeded. +// Consider increasing your provisioning level for the under-provisioned +// global secondary indexes with the UpdateTable API. This message is returned +// when provisioned throughput is exceeded is on a provisioned GSI. +// +// * Throttling Error: Code: ThrottlingError Messages: Throughput exceeds +// the current capacity of your table or index. DynamoDB is automatically +// scaling your table or index so please try again shortly. If exceptions +// persist, check if you have a hot key: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-partition-key-design.html. +// This message is returned when writes get throttled on an On-Demand table +// as DynamoDB is automatically scaling the table. Throughput exceeds the +// current capacity for one or more global secondary indexes. DynamoDB is +// automatically scaling your index so please try again shortly. This message +// is returned when when writes get throttled on an On-Demand GSI as DynamoDB +// is automatically scaling the GSI. +// +// * Validation Error: Code: ValidationError Messages: One or more parameter +// values were invalid. The update expression attempted to update the secondary +// index key beyond allowed size limits. The update expression attempted +// to update the secondary index key to unsupported type. An operand in the +// update expression has an incorrect data type. Item size to update has +// exceeded the maximum allowed size. Number overflow. Attempting to store +// a number with magnitude larger than supported range. Type mismatch for +// attribute to update. Nesting Levels have exceeded supported limits. The +// document path provided in the update expression is invalid for update. +// The provided expression refers to an attribute that does not exist in +// the item. +// +// * TransactionInProgressException +// The transaction with the given request token is already in progress. +// +// * IdempotentParameterMismatchException +// DynamoDB rejected the request because you retried a request with a different +// payload but with an idempotent token that was already used. +// +// * ProvisionedThroughputExceededException +// Your request rate is too high. The Amazon Web Services SDKs for DynamoDB +// automatically retry requests that receive this exception. Your request is +// eventually successful, unless your retry queue is too large to finish. Reduce +// the frequency of requests and use exponential backoff. For more information, +// go to Error Retries and Exponential Backoff (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.Errors.html#Programming.Errors.RetryAndBackoff) +// in the Amazon DynamoDB Developer Guide. +// +// * RequestLimitExceeded +// Throughput exceeds the current throughput quota for your account. Please +// contact Amazon Web Services Support (https://aws.amazon.com/support) to request +// a quota increase. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/TransactWriteItems +func (c *DynamoDB) TransactWriteItems(input *TransactWriteItemsInput) (*TransactWriteItemsOutput, error) { + req, out := c.TransactWriteItemsRequest(input) + return out, req.Send() +} + +// TransactWriteItemsWithContext is the same as TransactWriteItems with the addition of +// the ability to pass a context and additional request options. +// +// See TransactWriteItems for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) TransactWriteItemsWithContext(ctx aws.Context, input *TransactWriteItemsInput, opts ...request.Option) (*TransactWriteItemsOutput, error) { + req, out := c.TransactWriteItemsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opUntagResource = "UntagResource" + +// UntagResourceRequest generates a "aws/request.Request" representing the +// client's request for the UntagResource operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See UntagResource for more information on using the UntagResource +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the UntagResourceRequest method. +// req, resp := client.UntagResourceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/UntagResource +func (c *DynamoDB) UntagResourceRequest(input *UntagResourceInput) (req *request.Request, output *UntagResourceOutput) { + op := &request.Operation{ + Name: opUntagResource, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &UntagResourceInput{} + } + + output = &UntagResourceOutput{} + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Swap(jsonrpc.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// UntagResource API operation for Amazon DynamoDB. +// +// Removes the association of tags from an Amazon DynamoDB resource. You can +// call UntagResource up to five times per second, per account. +// +// For an overview on tagging DynamoDB resources, see Tagging for DynamoDB (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Tagging.html) +// in the Amazon DynamoDB Developer Guide. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation UntagResource for usage and error information. +// +// Returned Error Types: +// * LimitExceededException +// There is no limit to the number of daily on-demand backups that can be taken. +// +// Up to 50 simultaneous table operations are allowed per account. These operations +// include CreateTable, UpdateTable, DeleteTable,UpdateTimeToLive, RestoreTableFromBackup, +// and RestoreTableToPointInTime. +// +// The only exception is when you are creating a table with one or more secondary +// indexes. You can have up to 25 such requests running at a time; however, +// if the table or index specifications are complex, DynamoDB might temporarily +// reduce the number of concurrent operations. +// +// There is a soft account quota of 256 tables. +// +// * ResourceNotFoundException +// The operation tried to access a nonexistent table or index. The resource +// might not be specified correctly, or its status might not be ACTIVE. +// +// * InternalServerError +// An error occurred on the server side. +// +// * ResourceInUseException +// The operation conflicts with the resource's availability. For example, you +// attempted to recreate an existing table, or tried to delete a table currently +// in the CREATING state. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/UntagResource +func (c *DynamoDB) UntagResource(input *UntagResourceInput) (*UntagResourceOutput, error) { + req, out := c.UntagResourceRequest(input) + return out, req.Send() +} + +// UntagResourceWithContext is the same as UntagResource with the addition of +// the ability to pass a context and additional request options. +// +// See UntagResource for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) UntagResourceWithContext(ctx aws.Context, input *UntagResourceInput, opts ...request.Option) (*UntagResourceOutput, error) { + req, out := c.UntagResourceRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opUpdateContinuousBackups = "UpdateContinuousBackups" + +// UpdateContinuousBackupsRequest generates a "aws/request.Request" representing the +// client's request for the UpdateContinuousBackups operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See UpdateContinuousBackups for more information on using the UpdateContinuousBackups +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the UpdateContinuousBackupsRequest method. +// req, resp := client.UpdateContinuousBackupsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/UpdateContinuousBackups +func (c *DynamoDB) UpdateContinuousBackupsRequest(input *UpdateContinuousBackupsInput) (req *request.Request, output *UpdateContinuousBackupsOutput) { + op := &request.Operation{ + Name: opUpdateContinuousBackups, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &UpdateContinuousBackupsInput{} + } + + output = &UpdateContinuousBackupsOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// UpdateContinuousBackups API operation for Amazon DynamoDB. +// +// UpdateContinuousBackups enables or disables point in time recovery for the +// specified table. A successful UpdateContinuousBackups call returns the current +// ContinuousBackupsDescription. Continuous backups are ENABLED on all tables +// at table creation. If point in time recovery is enabled, PointInTimeRecoveryStatus +// will be set to ENABLED. +// +// Once continuous backups and point in time recovery are enabled, you can restore +// to any point in time within EarliestRestorableDateTime and LatestRestorableDateTime. +// +// LatestRestorableDateTime is typically 5 minutes before the current time. +// You can restore your table to any point in time during the last 35 days. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation UpdateContinuousBackups for usage and error information. +// +// Returned Error Types: +// * TableNotFoundException +// A source table with the name TableName does not currently exist within the +// subscriber's account. +// +// * ContinuousBackupsUnavailableException +// Backups have not yet been enabled for this table. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/UpdateContinuousBackups +func (c *DynamoDB) UpdateContinuousBackups(input *UpdateContinuousBackupsInput) (*UpdateContinuousBackupsOutput, error) { + req, out := c.UpdateContinuousBackupsRequest(input) + return out, req.Send() +} + +// UpdateContinuousBackupsWithContext is the same as UpdateContinuousBackups with the addition of +// the ability to pass a context and additional request options. +// +// See UpdateContinuousBackups for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) UpdateContinuousBackupsWithContext(ctx aws.Context, input *UpdateContinuousBackupsInput, opts ...request.Option) (*UpdateContinuousBackupsOutput, error) { + req, out := c.UpdateContinuousBackupsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opUpdateContributorInsights = "UpdateContributorInsights" + +// UpdateContributorInsightsRequest generates a "aws/request.Request" representing the +// client's request for the UpdateContributorInsights operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See UpdateContributorInsights for more information on using the UpdateContributorInsights +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the UpdateContributorInsightsRequest method. +// req, resp := client.UpdateContributorInsightsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/UpdateContributorInsights +func (c *DynamoDB) UpdateContributorInsightsRequest(input *UpdateContributorInsightsInput) (req *request.Request, output *UpdateContributorInsightsOutput) { + op := &request.Operation{ + Name: opUpdateContributorInsights, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &UpdateContributorInsightsInput{} + } + + output = &UpdateContributorInsightsOutput{} + req = c.newRequest(op, input, output) + return +} + +// UpdateContributorInsights API operation for Amazon DynamoDB. +// +// Updates the status for contributor insights for a specific table or index. +// CloudWatch Contributor Insights for DynamoDB graphs display the partition +// key and (if applicable) sort key of frequently accessed items and frequently +// throttled items in plaintext. If you require the use of AWS Key Management +// Service (KMS) to encrypt this table’s partition key and sort key data with +// an AWS managed key or customer managed key, you should not enable CloudWatch +// Contributor Insights for DynamoDB for this table. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation UpdateContributorInsights for usage and error information. +// +// Returned Error Types: +// * ResourceNotFoundException +// The operation tried to access a nonexistent table or index. The resource +// might not be specified correctly, or its status might not be ACTIVE. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/UpdateContributorInsights +func (c *DynamoDB) UpdateContributorInsights(input *UpdateContributorInsightsInput) (*UpdateContributorInsightsOutput, error) { + req, out := c.UpdateContributorInsightsRequest(input) + return out, req.Send() +} + +// UpdateContributorInsightsWithContext is the same as UpdateContributorInsights with the addition of +// the ability to pass a context and additional request options. +// +// See UpdateContributorInsights for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) UpdateContributorInsightsWithContext(ctx aws.Context, input *UpdateContributorInsightsInput, opts ...request.Option) (*UpdateContributorInsightsOutput, error) { + req, out := c.UpdateContributorInsightsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opUpdateGlobalTable = "UpdateGlobalTable" + +// UpdateGlobalTableRequest generates a "aws/request.Request" representing the +// client's request for the UpdateGlobalTable operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See UpdateGlobalTable for more information on using the UpdateGlobalTable +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the UpdateGlobalTableRequest method. +// req, resp := client.UpdateGlobalTableRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/UpdateGlobalTable +func (c *DynamoDB) UpdateGlobalTableRequest(input *UpdateGlobalTableInput) (req *request.Request, output *UpdateGlobalTableOutput) { + op := &request.Operation{ + Name: opUpdateGlobalTable, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &UpdateGlobalTableInput{} + } + + output = &UpdateGlobalTableOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// UpdateGlobalTable API operation for Amazon DynamoDB. +// +// Adds or removes replicas in the specified global table. The global table +// must already exist to be able to use this operation. Any replica to be added +// must be empty, have the same name as the global table, have the same key +// schema, have DynamoDB Streams enabled, and have the same provisioned and +// maximum write capacity units. +// +// Although you can use UpdateGlobalTable to add replicas and remove replicas +// in a single request, for simplicity we recommend that you issue separate +// requests for adding or removing replicas. +// +// If global secondary indexes are specified, then the following conditions +// must also be met: +// +// * The global secondary indexes must have the same name. +// +// * The global secondary indexes must have the same hash key and sort key +// (if present). +// +// * The global secondary indexes must have the same provisioned and maximum +// write capacity units. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation UpdateGlobalTable for usage and error information. +// +// Returned Error Types: +// * InternalServerError +// An error occurred on the server side. +// +// * GlobalTableNotFoundException +// The specified global table does not exist. +// +// * ReplicaAlreadyExistsException +// The specified replica is already part of the global table. +// +// * ReplicaNotFoundException +// The specified replica is no longer part of the global table. +// +// * TableNotFoundException +// A source table with the name TableName does not currently exist within the +// subscriber's account. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/UpdateGlobalTable +func (c *DynamoDB) UpdateGlobalTable(input *UpdateGlobalTableInput) (*UpdateGlobalTableOutput, error) { + req, out := c.UpdateGlobalTableRequest(input) + return out, req.Send() +} + +// UpdateGlobalTableWithContext is the same as UpdateGlobalTable with the addition of +// the ability to pass a context and additional request options. +// +// See UpdateGlobalTable for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) UpdateGlobalTableWithContext(ctx aws.Context, input *UpdateGlobalTableInput, opts ...request.Option) (*UpdateGlobalTableOutput, error) { + req, out := c.UpdateGlobalTableRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opUpdateGlobalTableSettings = "UpdateGlobalTableSettings" + +// UpdateGlobalTableSettingsRequest generates a "aws/request.Request" representing the +// client's request for the UpdateGlobalTableSettings operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See UpdateGlobalTableSettings for more information on using the UpdateGlobalTableSettings +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the UpdateGlobalTableSettingsRequest method. +// req, resp := client.UpdateGlobalTableSettingsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/UpdateGlobalTableSettings +func (c *DynamoDB) UpdateGlobalTableSettingsRequest(input *UpdateGlobalTableSettingsInput) (req *request.Request, output *UpdateGlobalTableSettingsOutput) { + op := &request.Operation{ + Name: opUpdateGlobalTableSettings, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &UpdateGlobalTableSettingsInput{} + } + + output = &UpdateGlobalTableSettingsOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// UpdateGlobalTableSettings API operation for Amazon DynamoDB. +// +// Updates settings for a global table. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation UpdateGlobalTableSettings for usage and error information. +// +// Returned Error Types: +// * GlobalTableNotFoundException +// The specified global table does not exist. +// +// * ReplicaNotFoundException +// The specified replica is no longer part of the global table. +// +// * IndexNotFoundException +// The operation tried to access a nonexistent index. +// +// * LimitExceededException +// There is no limit to the number of daily on-demand backups that can be taken. +// +// Up to 50 simultaneous table operations are allowed per account. These operations +// include CreateTable, UpdateTable, DeleteTable,UpdateTimeToLive, RestoreTableFromBackup, +// and RestoreTableToPointInTime. +// +// The only exception is when you are creating a table with one or more secondary +// indexes. You can have up to 25 such requests running at a time; however, +// if the table or index specifications are complex, DynamoDB might temporarily +// reduce the number of concurrent operations. +// +// There is a soft account quota of 256 tables. +// +// * ResourceInUseException +// The operation conflicts with the resource's availability. For example, you +// attempted to recreate an existing table, or tried to delete a table currently +// in the CREATING state. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/UpdateGlobalTableSettings +func (c *DynamoDB) UpdateGlobalTableSettings(input *UpdateGlobalTableSettingsInput) (*UpdateGlobalTableSettingsOutput, error) { + req, out := c.UpdateGlobalTableSettingsRequest(input) + return out, req.Send() +} + +// UpdateGlobalTableSettingsWithContext is the same as UpdateGlobalTableSettings with the addition of +// the ability to pass a context and additional request options. +// +// See UpdateGlobalTableSettings for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) UpdateGlobalTableSettingsWithContext(ctx aws.Context, input *UpdateGlobalTableSettingsInput, opts ...request.Option) (*UpdateGlobalTableSettingsOutput, error) { + req, out := c.UpdateGlobalTableSettingsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opUpdateItem = "UpdateItem" + +// UpdateItemRequest generates a "aws/request.Request" representing the +// client's request for the UpdateItem operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See UpdateItem for more information on using the UpdateItem +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the UpdateItemRequest method. +// req, resp := client.UpdateItemRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/UpdateItem +func (c *DynamoDB) UpdateItemRequest(input *UpdateItemInput) (req *request.Request, output *UpdateItemOutput) { + op := &request.Operation{ + Name: opUpdateItem, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &UpdateItemInput{} + } + + output = &UpdateItemOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// UpdateItem API operation for Amazon DynamoDB. +// +// Edits an existing item's attributes, or adds a new item to the table if it +// does not already exist. You can put, delete, or add attribute values. You +// can also perform a conditional update on an existing item (insert a new attribute +// name-value pair if it doesn't exist, or replace an existing name-value pair +// if it has certain expected attribute values). +// +// You can also return the item's attribute values in the same UpdateItem operation +// using the ReturnValues parameter. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation UpdateItem for usage and error information. +// +// Returned Error Types: +// * ConditionalCheckFailedException +// A condition specified in the operation could not be evaluated. +// +// * ProvisionedThroughputExceededException +// Your request rate is too high. The Amazon Web Services SDKs for DynamoDB +// automatically retry requests that receive this exception. Your request is +// eventually successful, unless your retry queue is too large to finish. Reduce +// the frequency of requests and use exponential backoff. For more information, +// go to Error Retries and Exponential Backoff (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.Errors.html#Programming.Errors.RetryAndBackoff) +// in the Amazon DynamoDB Developer Guide. +// +// * ResourceNotFoundException +// The operation tried to access a nonexistent table or index. The resource +// might not be specified correctly, or its status might not be ACTIVE. +// +// * ItemCollectionSizeLimitExceededException +// An item collection is too large. This exception is only returned for tables +// that have one or more local secondary indexes. +// +// * TransactionConflictException +// Operation was rejected because there is an ongoing transaction for the item. +// +// * RequestLimitExceeded +// Throughput exceeds the current throughput quota for your account. Please +// contact Amazon Web Services Support (https://aws.amazon.com/support) to request +// a quota increase. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/UpdateItem +func (c *DynamoDB) UpdateItem(input *UpdateItemInput) (*UpdateItemOutput, error) { + req, out := c.UpdateItemRequest(input) + return out, req.Send() +} + +// UpdateItemWithContext is the same as UpdateItem with the addition of +// the ability to pass a context and additional request options. +// +// See UpdateItem for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) UpdateItemWithContext(ctx aws.Context, input *UpdateItemInput, opts ...request.Option) (*UpdateItemOutput, error) { + req, out := c.UpdateItemRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opUpdateTable = "UpdateTable" + +// UpdateTableRequest generates a "aws/request.Request" representing the +// client's request for the UpdateTable operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See UpdateTable for more information on using the UpdateTable +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the UpdateTableRequest method. +// req, resp := client.UpdateTableRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/UpdateTable +func (c *DynamoDB) UpdateTableRequest(input *UpdateTableInput) (req *request.Request, output *UpdateTableOutput) { + op := &request.Operation{ + Name: opUpdateTable, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &UpdateTableInput{} + } + + output = &UpdateTableOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// UpdateTable API operation for Amazon DynamoDB. +// +// Modifies the provisioned throughput settings, global secondary indexes, or +// DynamoDB Streams settings for a given table. +// +// You can only perform one of the following operations at once: +// +// * Modify the provisioned throughput settings of the table. +// +// * Enable or disable DynamoDB Streams on the table. +// +// * Remove a global secondary index from the table. +// +// * Create a new global secondary index on the table. After the index begins +// backfilling, you can use UpdateTable to perform other operations. +// +// UpdateTable is an asynchronous operation; while it is executing, the table +// status changes from ACTIVE to UPDATING. While it is UPDATING, you cannot +// issue another UpdateTable request. When the table returns to the ACTIVE state, +// the UpdateTable operation is complete. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation UpdateTable for usage and error information. +// +// Returned Error Types: +// * ResourceInUseException +// The operation conflicts with the resource's availability. For example, you +// attempted to recreate an existing table, or tried to delete a table currently +// in the CREATING state. +// +// * ResourceNotFoundException +// The operation tried to access a nonexistent table or index. The resource +// might not be specified correctly, or its status might not be ACTIVE. +// +// * LimitExceededException +// There is no limit to the number of daily on-demand backups that can be taken. +// +// Up to 50 simultaneous table operations are allowed per account. These operations +// include CreateTable, UpdateTable, DeleteTable,UpdateTimeToLive, RestoreTableFromBackup, +// and RestoreTableToPointInTime. +// +// The only exception is when you are creating a table with one or more secondary +// indexes. You can have up to 25 such requests running at a time; however, +// if the table or index specifications are complex, DynamoDB might temporarily +// reduce the number of concurrent operations. +// +// There is a soft account quota of 256 tables. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/UpdateTable +func (c *DynamoDB) UpdateTable(input *UpdateTableInput) (*UpdateTableOutput, error) { + req, out := c.UpdateTableRequest(input) + return out, req.Send() +} + +// UpdateTableWithContext is the same as UpdateTable with the addition of +// the ability to pass a context and additional request options. +// +// See UpdateTable for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) UpdateTableWithContext(ctx aws.Context, input *UpdateTableInput, opts ...request.Option) (*UpdateTableOutput, error) { + req, out := c.UpdateTableRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opUpdateTableReplicaAutoScaling = "UpdateTableReplicaAutoScaling" + +// UpdateTableReplicaAutoScalingRequest generates a "aws/request.Request" representing the +// client's request for the UpdateTableReplicaAutoScaling operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See UpdateTableReplicaAutoScaling for more information on using the UpdateTableReplicaAutoScaling +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the UpdateTableReplicaAutoScalingRequest method. +// req, resp := client.UpdateTableReplicaAutoScalingRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/UpdateTableReplicaAutoScaling +func (c *DynamoDB) UpdateTableReplicaAutoScalingRequest(input *UpdateTableReplicaAutoScalingInput) (req *request.Request, output *UpdateTableReplicaAutoScalingOutput) { + op := &request.Operation{ + Name: opUpdateTableReplicaAutoScaling, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &UpdateTableReplicaAutoScalingInput{} + } + + output = &UpdateTableReplicaAutoScalingOutput{} + req = c.newRequest(op, input, output) + return +} + +// UpdateTableReplicaAutoScaling API operation for Amazon DynamoDB. +// +// Updates auto scaling settings on your global tables at once. +// +// This operation only applies to Version 2019.11.21 (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/globaltables.V2.html) +// of global tables. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation UpdateTableReplicaAutoScaling for usage and error information. +// +// Returned Error Types: +// * ResourceNotFoundException +// The operation tried to access a nonexistent table or index. The resource +// might not be specified correctly, or its status might not be ACTIVE. +// +// * ResourceInUseException +// The operation conflicts with the resource's availability. For example, you +// attempted to recreate an existing table, or tried to delete a table currently +// in the CREATING state. +// +// * LimitExceededException +// There is no limit to the number of daily on-demand backups that can be taken. +// +// Up to 50 simultaneous table operations are allowed per account. These operations +// include CreateTable, UpdateTable, DeleteTable,UpdateTimeToLive, RestoreTableFromBackup, +// and RestoreTableToPointInTime. +// +// The only exception is when you are creating a table with one or more secondary +// indexes. You can have up to 25 such requests running at a time; however, +// if the table or index specifications are complex, DynamoDB might temporarily +// reduce the number of concurrent operations. +// +// There is a soft account quota of 256 tables. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/UpdateTableReplicaAutoScaling +func (c *DynamoDB) UpdateTableReplicaAutoScaling(input *UpdateTableReplicaAutoScalingInput) (*UpdateTableReplicaAutoScalingOutput, error) { + req, out := c.UpdateTableReplicaAutoScalingRequest(input) + return out, req.Send() +} + +// UpdateTableReplicaAutoScalingWithContext is the same as UpdateTableReplicaAutoScaling with the addition of +// the ability to pass a context and additional request options. +// +// See UpdateTableReplicaAutoScaling for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) UpdateTableReplicaAutoScalingWithContext(ctx aws.Context, input *UpdateTableReplicaAutoScalingInput, opts ...request.Option) (*UpdateTableReplicaAutoScalingOutput, error) { + req, out := c.UpdateTableReplicaAutoScalingRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opUpdateTimeToLive = "UpdateTimeToLive" + +// UpdateTimeToLiveRequest generates a "aws/request.Request" representing the +// client's request for the UpdateTimeToLive operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See UpdateTimeToLive for more information on using the UpdateTimeToLive +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the UpdateTimeToLiveRequest method. +// req, resp := client.UpdateTimeToLiveRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/UpdateTimeToLive +func (c *DynamoDB) UpdateTimeToLiveRequest(input *UpdateTimeToLiveInput) (req *request.Request, output *UpdateTimeToLiveOutput) { + op := &request.Operation{ + Name: opUpdateTimeToLive, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &UpdateTimeToLiveInput{} + } + + output = &UpdateTimeToLiveOutput{} + req = c.newRequest(op, input, output) + // if custom endpoint for the request is set to a non empty string, + // we skip the endpoint discovery workflow. + if req.Config.Endpoint == nil || *req.Config.Endpoint == "" { + if aws.BoolValue(req.Config.EnableEndpointDiscovery) { + de := discovererDescribeEndpoints{ + Required: false, + EndpointCache: c.endpointCache, + Params: map[string]*string{ + "op": aws.String(req.Operation.Name), + }, + Client: c, + } + + for k, v := range de.Params { + if v == nil { + delete(de.Params, k) + } + } + + req.Handlers.Build.PushFrontNamed(request.NamedHandler{ + Name: "crr.endpointdiscovery", + Fn: de.Handler, + }) + } + } + return +} + +// UpdateTimeToLive API operation for Amazon DynamoDB. +// +// The UpdateTimeToLive method enables or disables Time to Live (TTL) for the +// specified table. A successful UpdateTimeToLive call returns the current TimeToLiveSpecification. +// It can take up to one hour for the change to fully process. Any additional +// UpdateTimeToLive calls for the same table during this one hour duration result +// in a ValidationException. +// +// TTL compares the current time in epoch time format to the time stored in +// the TTL attribute of an item. If the epoch time value stored in the attribute +// is less than the current time, the item is marked as expired and subsequently +// deleted. +// +// The epoch time format is the number of seconds elapsed since 12:00:00 AM +// January 1, 1970 UTC. +// +// DynamoDB deletes expired items on a best-effort basis to ensure availability +// of throughput for other data operations. +// +// DynamoDB typically deletes expired items within two days of expiration. The +// exact duration within which an item gets deleted after expiration is specific +// to the nature of the workload. Items that have expired and not been deleted +// will still show up in reads, queries, and scans. +// +// As items are deleted, they are removed from any local secondary index and +// global secondary index immediately in the same eventually consistent way +// as a standard delete operation. +// +// For more information, see Time To Live (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/TTL.html) +// in the Amazon DynamoDB Developer Guide. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon DynamoDB's +// API operation UpdateTimeToLive for usage and error information. +// +// Returned Error Types: +// * ResourceInUseException +// The operation conflicts with the resource's availability. For example, you +// attempted to recreate an existing table, or tried to delete a table currently +// in the CREATING state. +// +// * ResourceNotFoundException +// The operation tried to access a nonexistent table or index. The resource +// might not be specified correctly, or its status might not be ACTIVE. +// +// * LimitExceededException +// There is no limit to the number of daily on-demand backups that can be taken. +// +// Up to 50 simultaneous table operations are allowed per account. These operations +// include CreateTable, UpdateTable, DeleteTable,UpdateTimeToLive, RestoreTableFromBackup, +// and RestoreTableToPointInTime. +// +// The only exception is when you are creating a table with one or more secondary +// indexes. You can have up to 25 such requests running at a time; however, +// if the table or index specifications are complex, DynamoDB might temporarily +// reduce the number of concurrent operations. +// +// There is a soft account quota of 256 tables. +// +// * InternalServerError +// An error occurred on the server side. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10/UpdateTimeToLive +func (c *DynamoDB) UpdateTimeToLive(input *UpdateTimeToLiveInput) (*UpdateTimeToLiveOutput, error) { + req, out := c.UpdateTimeToLiveRequest(input) + return out, req.Send() +} + +// UpdateTimeToLiveWithContext is the same as UpdateTimeToLive with the addition of +// the ability to pass a context and additional request options. +// +// See UpdateTimeToLive for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) UpdateTimeToLiveWithContext(ctx aws.Context, input *UpdateTimeToLiveInput, opts ...request.Option) (*UpdateTimeToLiveOutput, error) { + req, out := c.UpdateTimeToLiveRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// Contains details of a table archival operation. +type ArchivalSummary struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the backup the table was archived to, when + // applicable in the archival reason. If you wish to restore this backup to + // the same table name, you will need to delete the original table. + ArchivalBackupArn *string `min:"37" type:"string"` + + // The date and time when table archival was initiated by DynamoDB, in UNIX + // epoch time format. + ArchivalDateTime *time.Time `type:"timestamp"` + + // The reason DynamoDB archived the table. Currently, the only possible value + // is: + // + // * INACCESSIBLE_ENCRYPTION_CREDENTIALS - The table was archived due to + // the table's KMS key being inaccessible for more than seven days. An On-Demand + // backup was created at the archival time. + ArchivalReason *string `type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ArchivalSummary) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ArchivalSummary) GoString() string { + return s.String() +} + +// SetArchivalBackupArn sets the ArchivalBackupArn field's value. +func (s *ArchivalSummary) SetArchivalBackupArn(v string) *ArchivalSummary { + s.ArchivalBackupArn = &v + return s +} + +// SetArchivalDateTime sets the ArchivalDateTime field's value. +func (s *ArchivalSummary) SetArchivalDateTime(v time.Time) *ArchivalSummary { + s.ArchivalDateTime = &v + return s +} + +// SetArchivalReason sets the ArchivalReason field's value. +func (s *ArchivalSummary) SetArchivalReason(v string) *ArchivalSummary { + s.ArchivalReason = &v + return s +} + +// Represents an attribute for describing the key schema for the table and indexes. +type AttributeDefinition struct { + _ struct{} `type:"structure"` + + // A name for the attribute. + // + // AttributeName is a required field + AttributeName *string `min:"1" type:"string" required:"true"` + + // The data type for the attribute, where: + // + // * S - the attribute is of type String + // + // * N - the attribute is of type Number + // + // * B - the attribute is of type Binary + // + // AttributeType is a required field + AttributeType *string `type:"string" required:"true" enum:"ScalarAttributeType"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s AttributeDefinition) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s AttributeDefinition) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AttributeDefinition) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AttributeDefinition"} + if s.AttributeName == nil { + invalidParams.Add(request.NewErrParamRequired("AttributeName")) + } + if s.AttributeName != nil && len(*s.AttributeName) < 1 { + invalidParams.Add(request.NewErrParamMinLen("AttributeName", 1)) + } + if s.AttributeType == nil { + invalidParams.Add(request.NewErrParamRequired("AttributeType")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAttributeName sets the AttributeName field's value. +func (s *AttributeDefinition) SetAttributeName(v string) *AttributeDefinition { + s.AttributeName = &v + return s +} + +// SetAttributeType sets the AttributeType field's value. +func (s *AttributeDefinition) SetAttributeType(v string) *AttributeDefinition { + s.AttributeType = &v + return s +} + +// Represents the data for an attribute. +// +// Each attribute value is described as a name-value pair. The name is the data +// type, and the value is the data itself. +// +// For more information, see Data Types (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html#HowItWorks.DataTypes) +// in the Amazon DynamoDB Developer Guide. +type AttributeValue struct { + _ struct{} `type:"structure"` + + // An attribute of type Binary. For example: + // + // "B": "dGhpcyB0ZXh0IGlzIGJhc2U2NC1lbmNvZGVk" + // B is automatically base64 encoded/decoded by the SDK. + B []byte `type:"blob"` + + // An attribute of type Boolean. For example: + // + // "BOOL": true + BOOL *bool `type:"boolean"` + + // An attribute of type Binary Set. For example: + // + // "BS": ["U3Vubnk=", "UmFpbnk=", "U25vd3k="] + BS [][]byte `type:"list"` + + // An attribute of type List. For example: + // + // "L": [ {"S": "Cookies"} , {"S": "Coffee"}, {"N", "3.14159"}] + L []*AttributeValue `type:"list"` + + // An attribute of type Map. For example: + // + // "M": {"Name": {"S": "Joe"}, "Age": {"N": "35"}} + M map[string]*AttributeValue `type:"map"` + + // An attribute of type Number. For example: + // + // "N": "123.45" + // + // Numbers are sent across the network to DynamoDB as strings, to maximize compatibility + // across languages and libraries. However, DynamoDB treats them as number type + // attributes for mathematical operations. + N *string `type:"string"` + + // An attribute of type Number Set. For example: + // + // "NS": ["42.2", "-19", "7.5", "3.14"] + // + // Numbers are sent across the network to DynamoDB as strings, to maximize compatibility + // across languages and libraries. However, DynamoDB treats them as number type + // attributes for mathematical operations. + NS []*string `type:"list"` + + // An attribute of type Null. For example: + // + // "NULL": true + NULL *bool `type:"boolean"` + + // An attribute of type String. For example: + // + // "S": "Hello" + S *string `type:"string"` + + // An attribute of type String Set. For example: + // + // "SS": ["Giraffe", "Hippo" ,"Zebra"] + SS []*string `type:"list"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s AttributeValue) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s AttributeValue) GoString() string { + return s.String() +} + +// SetB sets the B field's value. +func (s *AttributeValue) SetB(v []byte) *AttributeValue { + s.B = v + return s +} + +// SetBOOL sets the BOOL field's value. +func (s *AttributeValue) SetBOOL(v bool) *AttributeValue { + s.BOOL = &v + return s +} + +// SetBS sets the BS field's value. +func (s *AttributeValue) SetBS(v [][]byte) *AttributeValue { + s.BS = v + return s +} + +// SetL sets the L field's value. +func (s *AttributeValue) SetL(v []*AttributeValue) *AttributeValue { + s.L = v + return s +} + +// SetM sets the M field's value. +func (s *AttributeValue) SetM(v map[string]*AttributeValue) *AttributeValue { + s.M = v + return s +} + +// SetN sets the N field's value. +func (s *AttributeValue) SetN(v string) *AttributeValue { + s.N = &v + return s +} + +// SetNS sets the NS field's value. +func (s *AttributeValue) SetNS(v []*string) *AttributeValue { + s.NS = v + return s +} + +// SetNULL sets the NULL field's value. +func (s *AttributeValue) SetNULL(v bool) *AttributeValue { + s.NULL = &v + return s +} + +// SetS sets the S field's value. +func (s *AttributeValue) SetS(v string) *AttributeValue { + s.S = &v + return s +} + +// SetSS sets the SS field's value. +func (s *AttributeValue) SetSS(v []*string) *AttributeValue { + s.SS = v + return s +} + +// For the UpdateItem operation, represents the attributes to be modified, the +// action to perform on each, and the new value for each. +// +// You cannot use UpdateItem to update any primary key attributes. Instead, +// you will need to delete the item, and then use PutItem to create a new item +// with new attributes. +// +// Attribute values cannot be null; string and binary type attributes must have +// lengths greater than zero; and set type attributes must not be empty. Requests +// with empty values will be rejected with a ValidationException exception. +type AttributeValueUpdate struct { + _ struct{} `type:"structure"` + + // Specifies how to perform the update. Valid values are PUT (default), DELETE, + // and ADD. The behavior depends on whether the specified primary key already + // exists in the table. + // + // If an item with the specified Key is found in the table: + // + // * PUT - Adds the specified attribute to the item. If the attribute already + // exists, it is replaced by the new value. + // + // * DELETE - If no value is specified, the attribute and its value are removed + // from the item. The data type of the specified value must match the existing + // value's data type. If a set of values is specified, then those values + // are subtracted from the old set. For example, if the attribute value was + // the set [a,b,c] and the DELETE action specified [a,c], then the final + // attribute value would be [b]. Specifying an empty set is an error. + // + // * ADD - If the attribute does not already exist, then the attribute and + // its values are added to the item. If the attribute does exist, then the + // behavior of ADD depends on the data type of the attribute: If the existing + // attribute is a number, and if Value is also a number, then the Value is + // mathematically added to the existing attribute. If Value is a negative + // number, then it is subtracted from the existing attribute. If you use + // ADD to increment or decrement a number value for an item that doesn't + // exist before the update, DynamoDB uses 0 as the initial value. In addition, + // if you use ADD to update an existing item, and intend to increment or + // decrement an attribute value which does not yet exist, DynamoDB uses 0 + // as the initial value. For example, suppose that the item you want to update + // does not yet have an attribute named itemcount, but you decide to ADD + // the number 3 to this attribute anyway, even though it currently does not + // exist. DynamoDB will create the itemcount attribute, set its initial value + // to 0, and finally add 3 to it. The result will be a new itemcount attribute + // in the item, with a value of 3. If the existing data type is a set, and + // if the Value is also a set, then the Value is added to the existing set. + // (This is a set operation, not mathematical addition.) For example, if + // the attribute value was the set [1,2], and the ADD action specified [3], + // then the final attribute value would be [1,2,3]. An error occurs if an + // Add action is specified for a set attribute and the attribute type specified + // does not match the existing set type. Both sets must have the same primitive + // data type. For example, if the existing data type is a set of strings, + // the Value must also be a set of strings. The same holds true for number + // sets and binary sets. This action is only valid for an existing attribute + // whose data type is number or is a set. Do not use ADD for any other data + // types. + // + // If no item with the specified Key is found: + // + // * PUT - DynamoDB creates a new item with the specified primary key, and + // then adds the attribute. + // + // * DELETE - Nothing happens; there is no attribute to delete. + // + // * ADD - DynamoDB creates an item with the supplied primary key and number + // (or set of numbers) for the attribute value. The only data types allowed + // are number and number set; no other data types can be specified. + Action *string `type:"string" enum:"AttributeAction"` + + // Represents the data for an attribute. + // + // Each attribute value is described as a name-value pair. The name is the data + // type, and the value is the data itself. + // + // For more information, see Data Types (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html#HowItWorks.DataTypes) + // in the Amazon DynamoDB Developer Guide. + Value *AttributeValue `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s AttributeValueUpdate) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s AttributeValueUpdate) GoString() string { + return s.String() +} + +// SetAction sets the Action field's value. +func (s *AttributeValueUpdate) SetAction(v string) *AttributeValueUpdate { + s.Action = &v + return s +} + +// SetValue sets the Value field's value. +func (s *AttributeValueUpdate) SetValue(v *AttributeValue) *AttributeValueUpdate { + s.Value = v + return s +} + +// Represents the properties of the scaling policy. +type AutoScalingPolicyDescription struct { + _ struct{} `type:"structure"` + + // The name of the scaling policy. + PolicyName *string `min:"1" type:"string"` + + // Represents a target tracking scaling policy configuration. + TargetTrackingScalingPolicyConfiguration *AutoScalingTargetTrackingScalingPolicyConfigurationDescription `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s AutoScalingPolicyDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s AutoScalingPolicyDescription) GoString() string { + return s.String() +} + +// SetPolicyName sets the PolicyName field's value. +func (s *AutoScalingPolicyDescription) SetPolicyName(v string) *AutoScalingPolicyDescription { + s.PolicyName = &v + return s +} + +// SetTargetTrackingScalingPolicyConfiguration sets the TargetTrackingScalingPolicyConfiguration field's value. +func (s *AutoScalingPolicyDescription) SetTargetTrackingScalingPolicyConfiguration(v *AutoScalingTargetTrackingScalingPolicyConfigurationDescription) *AutoScalingPolicyDescription { + s.TargetTrackingScalingPolicyConfiguration = v + return s +} + +// Represents the auto scaling policy to be modified. +type AutoScalingPolicyUpdate struct { + _ struct{} `type:"structure"` + + // The name of the scaling policy. + PolicyName *string `min:"1" type:"string"` + + // Represents a target tracking scaling policy configuration. + // + // TargetTrackingScalingPolicyConfiguration is a required field + TargetTrackingScalingPolicyConfiguration *AutoScalingTargetTrackingScalingPolicyConfigurationUpdate `type:"structure" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s AutoScalingPolicyUpdate) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s AutoScalingPolicyUpdate) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AutoScalingPolicyUpdate) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AutoScalingPolicyUpdate"} + if s.PolicyName != nil && len(*s.PolicyName) < 1 { + invalidParams.Add(request.NewErrParamMinLen("PolicyName", 1)) + } + if s.TargetTrackingScalingPolicyConfiguration == nil { + invalidParams.Add(request.NewErrParamRequired("TargetTrackingScalingPolicyConfiguration")) + } + if s.TargetTrackingScalingPolicyConfiguration != nil { + if err := s.TargetTrackingScalingPolicyConfiguration.Validate(); err != nil { + invalidParams.AddNested("TargetTrackingScalingPolicyConfiguration", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetPolicyName sets the PolicyName field's value. +func (s *AutoScalingPolicyUpdate) SetPolicyName(v string) *AutoScalingPolicyUpdate { + s.PolicyName = &v + return s +} + +// SetTargetTrackingScalingPolicyConfiguration sets the TargetTrackingScalingPolicyConfiguration field's value. +func (s *AutoScalingPolicyUpdate) SetTargetTrackingScalingPolicyConfiguration(v *AutoScalingTargetTrackingScalingPolicyConfigurationUpdate) *AutoScalingPolicyUpdate { + s.TargetTrackingScalingPolicyConfiguration = v + return s +} + +// Represents the auto scaling settings for a global table or global secondary +// index. +type AutoScalingSettingsDescription struct { + _ struct{} `type:"structure"` + + // Disabled auto scaling for this global table or global secondary index. + AutoScalingDisabled *bool `type:"boolean"` + + // Role ARN used for configuring the auto scaling policy. + AutoScalingRoleArn *string `type:"string"` + + // The maximum capacity units that a global table or global secondary index + // should be scaled up to. + MaximumUnits *int64 `min:"1" type:"long"` + + // The minimum capacity units that a global table or global secondary index + // should be scaled down to. + MinimumUnits *int64 `min:"1" type:"long"` + + // Information about the scaling policies. + ScalingPolicies []*AutoScalingPolicyDescription `type:"list"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s AutoScalingSettingsDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s AutoScalingSettingsDescription) GoString() string { + return s.String() +} + +// SetAutoScalingDisabled sets the AutoScalingDisabled field's value. +func (s *AutoScalingSettingsDescription) SetAutoScalingDisabled(v bool) *AutoScalingSettingsDescription { + s.AutoScalingDisabled = &v + return s +} + +// SetAutoScalingRoleArn sets the AutoScalingRoleArn field's value. +func (s *AutoScalingSettingsDescription) SetAutoScalingRoleArn(v string) *AutoScalingSettingsDescription { + s.AutoScalingRoleArn = &v + return s +} + +// SetMaximumUnits sets the MaximumUnits field's value. +func (s *AutoScalingSettingsDescription) SetMaximumUnits(v int64) *AutoScalingSettingsDescription { + s.MaximumUnits = &v + return s +} + +// SetMinimumUnits sets the MinimumUnits field's value. +func (s *AutoScalingSettingsDescription) SetMinimumUnits(v int64) *AutoScalingSettingsDescription { + s.MinimumUnits = &v + return s +} + +// SetScalingPolicies sets the ScalingPolicies field's value. +func (s *AutoScalingSettingsDescription) SetScalingPolicies(v []*AutoScalingPolicyDescription) *AutoScalingSettingsDescription { + s.ScalingPolicies = v + return s +} + +// Represents the auto scaling settings to be modified for a global table or +// global secondary index. +type AutoScalingSettingsUpdate struct { + _ struct{} `type:"structure"` + + // Disabled auto scaling for this global table or global secondary index. + AutoScalingDisabled *bool `type:"boolean"` + + // Role ARN used for configuring auto scaling policy. + AutoScalingRoleArn *string `min:"1" type:"string"` + + // The maximum capacity units that a global table or global secondary index + // should be scaled up to. + MaximumUnits *int64 `min:"1" type:"long"` + + // The minimum capacity units that a global table or global secondary index + // should be scaled down to. + MinimumUnits *int64 `min:"1" type:"long"` + + // The scaling policy to apply for scaling target global table or global secondary + // index capacity units. + ScalingPolicyUpdate *AutoScalingPolicyUpdate `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s AutoScalingSettingsUpdate) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s AutoScalingSettingsUpdate) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AutoScalingSettingsUpdate) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AutoScalingSettingsUpdate"} + if s.AutoScalingRoleArn != nil && len(*s.AutoScalingRoleArn) < 1 { + invalidParams.Add(request.NewErrParamMinLen("AutoScalingRoleArn", 1)) + } + if s.MaximumUnits != nil && *s.MaximumUnits < 1 { + invalidParams.Add(request.NewErrParamMinValue("MaximumUnits", 1)) + } + if s.MinimumUnits != nil && *s.MinimumUnits < 1 { + invalidParams.Add(request.NewErrParamMinValue("MinimumUnits", 1)) + } + if s.ScalingPolicyUpdate != nil { + if err := s.ScalingPolicyUpdate.Validate(); err != nil { + invalidParams.AddNested("ScalingPolicyUpdate", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAutoScalingDisabled sets the AutoScalingDisabled field's value. +func (s *AutoScalingSettingsUpdate) SetAutoScalingDisabled(v bool) *AutoScalingSettingsUpdate { + s.AutoScalingDisabled = &v + return s +} + +// SetAutoScalingRoleArn sets the AutoScalingRoleArn field's value. +func (s *AutoScalingSettingsUpdate) SetAutoScalingRoleArn(v string) *AutoScalingSettingsUpdate { + s.AutoScalingRoleArn = &v + return s +} + +// SetMaximumUnits sets the MaximumUnits field's value. +func (s *AutoScalingSettingsUpdate) SetMaximumUnits(v int64) *AutoScalingSettingsUpdate { + s.MaximumUnits = &v + return s +} + +// SetMinimumUnits sets the MinimumUnits field's value. +func (s *AutoScalingSettingsUpdate) SetMinimumUnits(v int64) *AutoScalingSettingsUpdate { + s.MinimumUnits = &v + return s +} + +// SetScalingPolicyUpdate sets the ScalingPolicyUpdate field's value. +func (s *AutoScalingSettingsUpdate) SetScalingPolicyUpdate(v *AutoScalingPolicyUpdate) *AutoScalingSettingsUpdate { + s.ScalingPolicyUpdate = v + return s +} + +// Represents the properties of a target tracking scaling policy. +type AutoScalingTargetTrackingScalingPolicyConfigurationDescription struct { + _ struct{} `type:"structure"` + + // Indicates whether scale in by the target tracking policy is disabled. If + // the value is true, scale in is disabled and the target tracking policy won't + // remove capacity from the scalable resource. Otherwise, scale in is enabled + // and the target tracking policy can remove capacity from the scalable resource. + // The default value is false. + DisableScaleIn *bool `type:"boolean"` + + // The amount of time, in seconds, after a scale in activity completes before + // another scale in activity can start. The cooldown period is used to block + // subsequent scale in requests until it has expired. You should scale in conservatively + // to protect your application's availability. However, if another alarm triggers + // a scale out policy during the cooldown period after a scale-in, application + // auto scaling scales out your scalable target immediately. + ScaleInCooldown *int64 `type:"integer"` + + // The amount of time, in seconds, after a scale out activity completes before + // another scale out activity can start. While the cooldown period is in effect, + // the capacity that has been added by the previous scale out event that initiated + // the cooldown is calculated as part of the desired capacity for the next scale + // out. You should continuously (but not excessively) scale out. + ScaleOutCooldown *int64 `type:"integer"` + + // The target value for the metric. The range is 8.515920e-109 to 1.174271e+108 + // (Base 10) or 2e-360 to 2e360 (Base 2). + // + // TargetValue is a required field + TargetValue *float64 `type:"double" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s AutoScalingTargetTrackingScalingPolicyConfigurationDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s AutoScalingTargetTrackingScalingPolicyConfigurationDescription) GoString() string { + return s.String() +} + +// SetDisableScaleIn sets the DisableScaleIn field's value. +func (s *AutoScalingTargetTrackingScalingPolicyConfigurationDescription) SetDisableScaleIn(v bool) *AutoScalingTargetTrackingScalingPolicyConfigurationDescription { + s.DisableScaleIn = &v + return s +} + +// SetScaleInCooldown sets the ScaleInCooldown field's value. +func (s *AutoScalingTargetTrackingScalingPolicyConfigurationDescription) SetScaleInCooldown(v int64) *AutoScalingTargetTrackingScalingPolicyConfigurationDescription { + s.ScaleInCooldown = &v + return s +} + +// SetScaleOutCooldown sets the ScaleOutCooldown field's value. +func (s *AutoScalingTargetTrackingScalingPolicyConfigurationDescription) SetScaleOutCooldown(v int64) *AutoScalingTargetTrackingScalingPolicyConfigurationDescription { + s.ScaleOutCooldown = &v + return s +} + +// SetTargetValue sets the TargetValue field's value. +func (s *AutoScalingTargetTrackingScalingPolicyConfigurationDescription) SetTargetValue(v float64) *AutoScalingTargetTrackingScalingPolicyConfigurationDescription { + s.TargetValue = &v + return s +} + +// Represents the settings of a target tracking scaling policy that will be +// modified. +type AutoScalingTargetTrackingScalingPolicyConfigurationUpdate struct { + _ struct{} `type:"structure"` + + // Indicates whether scale in by the target tracking policy is disabled. If + // the value is true, scale in is disabled and the target tracking policy won't + // remove capacity from the scalable resource. Otherwise, scale in is enabled + // and the target tracking policy can remove capacity from the scalable resource. + // The default value is false. + DisableScaleIn *bool `type:"boolean"` + + // The amount of time, in seconds, after a scale in activity completes before + // another scale in activity can start. The cooldown period is used to block + // subsequent scale in requests until it has expired. You should scale in conservatively + // to protect your application's availability. However, if another alarm triggers + // a scale out policy during the cooldown period after a scale-in, application + // auto scaling scales out your scalable target immediately. + ScaleInCooldown *int64 `type:"integer"` + + // The amount of time, in seconds, after a scale out activity completes before + // another scale out activity can start. While the cooldown period is in effect, + // the capacity that has been added by the previous scale out event that initiated + // the cooldown is calculated as part of the desired capacity for the next scale + // out. You should continuously (but not excessively) scale out. + ScaleOutCooldown *int64 `type:"integer"` + + // The target value for the metric. The range is 8.515920e-109 to 1.174271e+108 + // (Base 10) or 2e-360 to 2e360 (Base 2). + // + // TargetValue is a required field + TargetValue *float64 `type:"double" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s AutoScalingTargetTrackingScalingPolicyConfigurationUpdate) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s AutoScalingTargetTrackingScalingPolicyConfigurationUpdate) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AutoScalingTargetTrackingScalingPolicyConfigurationUpdate) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AutoScalingTargetTrackingScalingPolicyConfigurationUpdate"} + if s.TargetValue == nil { + invalidParams.Add(request.NewErrParamRequired("TargetValue")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDisableScaleIn sets the DisableScaleIn field's value. +func (s *AutoScalingTargetTrackingScalingPolicyConfigurationUpdate) SetDisableScaleIn(v bool) *AutoScalingTargetTrackingScalingPolicyConfigurationUpdate { + s.DisableScaleIn = &v + return s +} + +// SetScaleInCooldown sets the ScaleInCooldown field's value. +func (s *AutoScalingTargetTrackingScalingPolicyConfigurationUpdate) SetScaleInCooldown(v int64) *AutoScalingTargetTrackingScalingPolicyConfigurationUpdate { + s.ScaleInCooldown = &v + return s +} + +// SetScaleOutCooldown sets the ScaleOutCooldown field's value. +func (s *AutoScalingTargetTrackingScalingPolicyConfigurationUpdate) SetScaleOutCooldown(v int64) *AutoScalingTargetTrackingScalingPolicyConfigurationUpdate { + s.ScaleOutCooldown = &v + return s +} + +// SetTargetValue sets the TargetValue field's value. +func (s *AutoScalingTargetTrackingScalingPolicyConfigurationUpdate) SetTargetValue(v float64) *AutoScalingTargetTrackingScalingPolicyConfigurationUpdate { + s.TargetValue = &v + return s +} + +// Contains the description of the backup created for the table. +type BackupDescription struct { + _ struct{} `type:"structure"` + + // Contains the details of the backup created for the table. + BackupDetails *BackupDetails `type:"structure"` + + // Contains the details of the table when the backup was created. + SourceTableDetails *SourceTableDetails `type:"structure"` + + // Contains the details of the features enabled on the table when the backup + // was created. For example, LSIs, GSIs, streams, TTL. + SourceTableFeatureDetails *SourceTableFeatureDetails `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s BackupDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s BackupDescription) GoString() string { + return s.String() +} + +// SetBackupDetails sets the BackupDetails field's value. +func (s *BackupDescription) SetBackupDetails(v *BackupDetails) *BackupDescription { + s.BackupDetails = v + return s +} + +// SetSourceTableDetails sets the SourceTableDetails field's value. +func (s *BackupDescription) SetSourceTableDetails(v *SourceTableDetails) *BackupDescription { + s.SourceTableDetails = v + return s +} + +// SetSourceTableFeatureDetails sets the SourceTableFeatureDetails field's value. +func (s *BackupDescription) SetSourceTableFeatureDetails(v *SourceTableFeatureDetails) *BackupDescription { + s.SourceTableFeatureDetails = v + return s +} + +// Contains the details of the backup created for the table. +type BackupDetails struct { + _ struct{} `type:"structure"` + + // ARN associated with the backup. + // + // BackupArn is a required field + BackupArn *string `min:"37" type:"string" required:"true"` + + // Time at which the backup was created. This is the request time of the backup. + // + // BackupCreationDateTime is a required field + BackupCreationDateTime *time.Time `type:"timestamp" required:"true"` + + // Time at which the automatic on-demand backup created by DynamoDB will expire. + // This SYSTEM on-demand backup expires automatically 35 days after its creation. + BackupExpiryDateTime *time.Time `type:"timestamp"` + + // Name of the requested backup. + // + // BackupName is a required field + BackupName *string `min:"3" type:"string" required:"true"` + + // Size of the backup in bytes. + BackupSizeBytes *int64 `type:"long"` + + // Backup can be in one of the following states: CREATING, ACTIVE, DELETED. + // + // BackupStatus is a required field + BackupStatus *string `type:"string" required:"true" enum:"BackupStatus"` + + // BackupType: + // + // * USER - You create and manage these using the on-demand backup feature. + // + // * SYSTEM - If you delete a table with point-in-time recovery enabled, + // a SYSTEM backup is automatically created and is retained for 35 days (at + // no additional cost). System backups allow you to restore the deleted table + // to the state it was in just before the point of deletion. + // + // * AWS_BACKUP - On-demand backup created by you from Backup service. + // + // BackupType is a required field + BackupType *string `type:"string" required:"true" enum:"BackupType"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s BackupDetails) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s BackupDetails) GoString() string { + return s.String() +} + +// SetBackupArn sets the BackupArn field's value. +func (s *BackupDetails) SetBackupArn(v string) *BackupDetails { + s.BackupArn = &v + return s +} + +// SetBackupCreationDateTime sets the BackupCreationDateTime field's value. +func (s *BackupDetails) SetBackupCreationDateTime(v time.Time) *BackupDetails { + s.BackupCreationDateTime = &v + return s +} + +// SetBackupExpiryDateTime sets the BackupExpiryDateTime field's value. +func (s *BackupDetails) SetBackupExpiryDateTime(v time.Time) *BackupDetails { + s.BackupExpiryDateTime = &v + return s +} + +// SetBackupName sets the BackupName field's value. +func (s *BackupDetails) SetBackupName(v string) *BackupDetails { + s.BackupName = &v + return s +} + +// SetBackupSizeBytes sets the BackupSizeBytes field's value. +func (s *BackupDetails) SetBackupSizeBytes(v int64) *BackupDetails { + s.BackupSizeBytes = &v + return s +} + +// SetBackupStatus sets the BackupStatus field's value. +func (s *BackupDetails) SetBackupStatus(v string) *BackupDetails { + s.BackupStatus = &v + return s +} + +// SetBackupType sets the BackupType field's value. +func (s *BackupDetails) SetBackupType(v string) *BackupDetails { + s.BackupType = &v + return s +} + +// There is another ongoing conflicting backup control plane operation on the +// table. The backup is either being created, deleted or restored to a table. +type BackupInUseException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + Message_ *string `locationName:"message" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s BackupInUseException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s BackupInUseException) GoString() string { + return s.String() +} + +func newErrorBackupInUseException(v protocol.ResponseMetadata) error { + return &BackupInUseException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *BackupInUseException) Code() string { + return "BackupInUseException" +} + +// Message returns the exception's message. +func (s *BackupInUseException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *BackupInUseException) OrigErr() error { + return nil +} + +func (s *BackupInUseException) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *BackupInUseException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *BackupInUseException) RequestID() string { + return s.RespMetadata.RequestID +} + +// Backup not found for the given BackupARN. +type BackupNotFoundException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + Message_ *string `locationName:"message" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s BackupNotFoundException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s BackupNotFoundException) GoString() string { + return s.String() +} + +func newErrorBackupNotFoundException(v protocol.ResponseMetadata) error { + return &BackupNotFoundException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *BackupNotFoundException) Code() string { + return "BackupNotFoundException" +} + +// Message returns the exception's message. +func (s *BackupNotFoundException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *BackupNotFoundException) OrigErr() error { + return nil +} + +func (s *BackupNotFoundException) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *BackupNotFoundException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *BackupNotFoundException) RequestID() string { + return s.RespMetadata.RequestID +} + +// Contains details for the backup. +type BackupSummary struct { + _ struct{} `type:"structure"` + + // ARN associated with the backup. + BackupArn *string `min:"37" type:"string"` + + // Time at which the backup was created. + BackupCreationDateTime *time.Time `type:"timestamp"` + + // Time at which the automatic on-demand backup created by DynamoDB will expire. + // This SYSTEM on-demand backup expires automatically 35 days after its creation. + BackupExpiryDateTime *time.Time `type:"timestamp"` + + // Name of the specified backup. + BackupName *string `min:"3" type:"string"` + + // Size of the backup in bytes. + BackupSizeBytes *int64 `type:"long"` + + // Backup can be in one of the following states: CREATING, ACTIVE, DELETED. + BackupStatus *string `type:"string" enum:"BackupStatus"` + + // BackupType: + // + // * USER - You create and manage these using the on-demand backup feature. + // + // * SYSTEM - If you delete a table with point-in-time recovery enabled, + // a SYSTEM backup is automatically created and is retained for 35 days (at + // no additional cost). System backups allow you to restore the deleted table + // to the state it was in just before the point of deletion. + // + // * AWS_BACKUP - On-demand backup created by you from Backup service. + BackupType *string `type:"string" enum:"BackupType"` + + // ARN associated with the table. + TableArn *string `type:"string"` + + // Unique identifier for the table. + TableId *string `type:"string"` + + // Name of the table. + TableName *string `min:"3" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s BackupSummary) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s BackupSummary) GoString() string { + return s.String() +} + +// SetBackupArn sets the BackupArn field's value. +func (s *BackupSummary) SetBackupArn(v string) *BackupSummary { + s.BackupArn = &v + return s +} + +// SetBackupCreationDateTime sets the BackupCreationDateTime field's value. +func (s *BackupSummary) SetBackupCreationDateTime(v time.Time) *BackupSummary { + s.BackupCreationDateTime = &v + return s +} + +// SetBackupExpiryDateTime sets the BackupExpiryDateTime field's value. +func (s *BackupSummary) SetBackupExpiryDateTime(v time.Time) *BackupSummary { + s.BackupExpiryDateTime = &v + return s +} + +// SetBackupName sets the BackupName field's value. +func (s *BackupSummary) SetBackupName(v string) *BackupSummary { + s.BackupName = &v + return s +} + +// SetBackupSizeBytes sets the BackupSizeBytes field's value. +func (s *BackupSummary) SetBackupSizeBytes(v int64) *BackupSummary { + s.BackupSizeBytes = &v + return s +} + +// SetBackupStatus sets the BackupStatus field's value. +func (s *BackupSummary) SetBackupStatus(v string) *BackupSummary { + s.BackupStatus = &v + return s +} + +// SetBackupType sets the BackupType field's value. +func (s *BackupSummary) SetBackupType(v string) *BackupSummary { + s.BackupType = &v + return s +} + +// SetTableArn sets the TableArn field's value. +func (s *BackupSummary) SetTableArn(v string) *BackupSummary { + s.TableArn = &v + return s +} + +// SetTableId sets the TableId field's value. +func (s *BackupSummary) SetTableId(v string) *BackupSummary { + s.TableId = &v + return s +} + +// SetTableName sets the TableName field's value. +func (s *BackupSummary) SetTableName(v string) *BackupSummary { + s.TableName = &v + return s +} + +type BatchExecuteStatementInput struct { + _ struct{} `type:"structure"` + + // Determines the level of detail about either provisioned or on-demand throughput + // consumption that is returned in the response: + // + // * INDEXES - The response includes the aggregate ConsumedCapacity for the + // operation, together with ConsumedCapacity for each table and secondary + // index that was accessed. Note that some operations, such as GetItem and + // BatchGetItem, do not access any indexes at all. In these cases, specifying + // INDEXES will only return ConsumedCapacity information for table(s). + // + // * TOTAL - The response includes only the aggregate ConsumedCapacity for + // the operation. + // + // * NONE - No ConsumedCapacity details are included in the response. + ReturnConsumedCapacity *string `type:"string" enum:"ReturnConsumedCapacity"` + + // The list of PartiQL statements representing the batch to run. + // + // Statements is a required field + Statements []*BatchStatementRequest `min:"1" type:"list" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s BatchExecuteStatementInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s BatchExecuteStatementInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *BatchExecuteStatementInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "BatchExecuteStatementInput"} + if s.Statements == nil { + invalidParams.Add(request.NewErrParamRequired("Statements")) + } + if s.Statements != nil && len(s.Statements) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Statements", 1)) + } + if s.Statements != nil { + for i, v := range s.Statements { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Statements", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetReturnConsumedCapacity sets the ReturnConsumedCapacity field's value. +func (s *BatchExecuteStatementInput) SetReturnConsumedCapacity(v string) *BatchExecuteStatementInput { + s.ReturnConsumedCapacity = &v + return s +} + +// SetStatements sets the Statements field's value. +func (s *BatchExecuteStatementInput) SetStatements(v []*BatchStatementRequest) *BatchExecuteStatementInput { + s.Statements = v + return s +} + +type BatchExecuteStatementOutput struct { + _ struct{} `type:"structure"` + + // The capacity units consumed by the entire operation. The values of the list + // are ordered according to the ordering of the statements. + ConsumedCapacity []*ConsumedCapacity `type:"list"` + + // The response to each PartiQL statement in the batch. + Responses []*BatchStatementResponse `type:"list"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s BatchExecuteStatementOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s BatchExecuteStatementOutput) GoString() string { + return s.String() +} + +// SetConsumedCapacity sets the ConsumedCapacity field's value. +func (s *BatchExecuteStatementOutput) SetConsumedCapacity(v []*ConsumedCapacity) *BatchExecuteStatementOutput { + s.ConsumedCapacity = v + return s +} + +// SetResponses sets the Responses field's value. +func (s *BatchExecuteStatementOutput) SetResponses(v []*BatchStatementResponse) *BatchExecuteStatementOutput { + s.Responses = v + return s +} + +// Represents the input of a BatchGetItem operation. +type BatchGetItemInput struct { + _ struct{} `type:"structure"` + + // A map of one or more table names and, for each table, a map that describes + // one or more items to retrieve from that table. Each table name can be used + // only once per BatchGetItem request. + // + // Each element in the map of items to retrieve consists of the following: + // + // * ConsistentRead - If true, a strongly consistent read is used; if false + // (the default), an eventually consistent read is used. + // + // * ExpressionAttributeNames - One or more substitution tokens for attribute + // names in the ProjectionExpression parameter. The following are some use + // cases for using ExpressionAttributeNames: To access an attribute whose + // name conflicts with a DynamoDB reserved word. To create a placeholder + // for repeating occurrences of an attribute name in an expression. To prevent + // special characters in an attribute name from being misinterpreted in an + // expression. Use the # character in an expression to dereference an attribute + // name. For example, consider the following attribute name: Percentile The + // name of this attribute conflicts with a reserved word, so it cannot be + // used directly in an expression. (For the complete list of reserved words, + // see Reserved Words (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html) + // in the Amazon DynamoDB Developer Guide). To work around this, you could + // specify the following for ExpressionAttributeNames: {"#P":"Percentile"} + // You could then use this substitution in an expression, as in this example: + // #P = :val Tokens that begin with the : character are expression attribute + // values, which are placeholders for the actual value at runtime. For more + // information about expression attribute names, see Accessing Item Attributes + // (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.AccessingItemAttributes.html) + // in the Amazon DynamoDB Developer Guide. + // + // * Keys - An array of primary key attribute values that define specific + // items in the table. For each primary key, you must provide all of the + // key attributes. For example, with a simple primary key, you only need + // to provide the partition key value. For a composite key, you must provide + // both the partition key value and the sort key value. + // + // * ProjectionExpression - A string that identifies one or more attributes + // to retrieve from the table. These attributes can include scalars, sets, + // or elements of a JSON document. The attributes in the expression must + // be separated by commas. If no attribute names are specified, then all + // attributes are returned. If any of the requested attributes are not found, + // they do not appear in the result. For more information, see Accessing + // Item Attributes (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.AccessingItemAttributes.html) + // in the Amazon DynamoDB Developer Guide. + // + // * AttributesToGet - This is a legacy parameter. Use ProjectionExpression + // instead. For more information, see AttributesToGet (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.AttributesToGet.html) + // in the Amazon DynamoDB Developer Guide. + // + // RequestItems is a required field + RequestItems map[string]*KeysAndAttributes `min:"1" type:"map" required:"true"` + + // Determines the level of detail about either provisioned or on-demand throughput + // consumption that is returned in the response: + // + // * INDEXES - The response includes the aggregate ConsumedCapacity for the + // operation, together with ConsumedCapacity for each table and secondary + // index that was accessed. Note that some operations, such as GetItem and + // BatchGetItem, do not access any indexes at all. In these cases, specifying + // INDEXES will only return ConsumedCapacity information for table(s). + // + // * TOTAL - The response includes only the aggregate ConsumedCapacity for + // the operation. + // + // * NONE - No ConsumedCapacity details are included in the response. + ReturnConsumedCapacity *string `type:"string" enum:"ReturnConsumedCapacity"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s BatchGetItemInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s BatchGetItemInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *BatchGetItemInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "BatchGetItemInput"} + if s.RequestItems == nil { + invalidParams.Add(request.NewErrParamRequired("RequestItems")) + } + if s.RequestItems != nil && len(s.RequestItems) < 1 { + invalidParams.Add(request.NewErrParamMinLen("RequestItems", 1)) + } + if s.RequestItems != nil { + for i, v := range s.RequestItems { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "RequestItems", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetRequestItems sets the RequestItems field's value. +func (s *BatchGetItemInput) SetRequestItems(v map[string]*KeysAndAttributes) *BatchGetItemInput { + s.RequestItems = v + return s +} + +// SetReturnConsumedCapacity sets the ReturnConsumedCapacity field's value. +func (s *BatchGetItemInput) SetReturnConsumedCapacity(v string) *BatchGetItemInput { + s.ReturnConsumedCapacity = &v + return s +} + +// Represents the output of a BatchGetItem operation. +type BatchGetItemOutput struct { + _ struct{} `type:"structure"` + + // The read capacity units consumed by the entire BatchGetItem operation. + // + // Each element consists of: + // + // * TableName - The table that consumed the provisioned throughput. + // + // * CapacityUnits - The total number of capacity units consumed. + ConsumedCapacity []*ConsumedCapacity `type:"list"` + + // A map of table name to a list of items. Each object in Responses consists + // of a table name, along with a map of attribute data consisting of the data + // type and attribute value. + Responses map[string][]map[string]*AttributeValue `type:"map"` + + // A map of tables and their respective keys that were not processed with the + // current response. The UnprocessedKeys value is in the same form as RequestItems, + // so the value can be provided directly to a subsequent BatchGetItem operation. + // For more information, see RequestItems in the Request Parameters section. + // + // Each element consists of: + // + // * Keys - An array of primary key attribute values that define specific + // items in the table. + // + // * ProjectionExpression - One or more attributes to be retrieved from the + // table or index. By default, all attributes are returned. If a requested + // attribute is not found, it does not appear in the result. + // + // * ConsistentRead - The consistency of a read operation. If set to true, + // then a strongly consistent read is used; otherwise, an eventually consistent + // read is used. + // + // If there are no unprocessed keys remaining, the response contains an empty + // UnprocessedKeys map. + UnprocessedKeys map[string]*KeysAndAttributes `min:"1" type:"map"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s BatchGetItemOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s BatchGetItemOutput) GoString() string { + return s.String() +} + +// SetConsumedCapacity sets the ConsumedCapacity field's value. +func (s *BatchGetItemOutput) SetConsumedCapacity(v []*ConsumedCapacity) *BatchGetItemOutput { + s.ConsumedCapacity = v + return s +} + +// SetResponses sets the Responses field's value. +func (s *BatchGetItemOutput) SetResponses(v map[string][]map[string]*AttributeValue) *BatchGetItemOutput { + s.Responses = v + return s +} + +// SetUnprocessedKeys sets the UnprocessedKeys field's value. +func (s *BatchGetItemOutput) SetUnprocessedKeys(v map[string]*KeysAndAttributes) *BatchGetItemOutput { + s.UnprocessedKeys = v + return s +} + +// An error associated with a statement in a PartiQL batch that was run. +type BatchStatementError struct { + _ struct{} `type:"structure"` + + // The error code associated with the failed PartiQL batch statement. + Code *string `type:"string" enum:"BatchStatementErrorCodeEnum"` + + // The error message associated with the PartiQL batch resposne. + Message *string `type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s BatchStatementError) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s BatchStatementError) GoString() string { + return s.String() +} + +// SetCode sets the Code field's value. +func (s *BatchStatementError) SetCode(v string) *BatchStatementError { + s.Code = &v + return s +} + +// SetMessage sets the Message field's value. +func (s *BatchStatementError) SetMessage(v string) *BatchStatementError { + s.Message = &v + return s +} + +// A PartiQL batch statement request. +type BatchStatementRequest struct { + _ struct{} `type:"structure"` + + // The read consistency of the PartiQL batch request. + ConsistentRead *bool `type:"boolean"` + + // The parameters associated with a PartiQL statement in the batch request. + Parameters []*AttributeValue `min:"1" type:"list"` + + // A valid PartiQL statement. + // + // Statement is a required field + Statement *string `min:"1" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s BatchStatementRequest) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s BatchStatementRequest) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *BatchStatementRequest) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "BatchStatementRequest"} + if s.Parameters != nil && len(s.Parameters) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Parameters", 1)) + } + if s.Statement == nil { + invalidParams.Add(request.NewErrParamRequired("Statement")) + } + if s.Statement != nil && len(*s.Statement) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Statement", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetConsistentRead sets the ConsistentRead field's value. +func (s *BatchStatementRequest) SetConsistentRead(v bool) *BatchStatementRequest { + s.ConsistentRead = &v + return s +} + +// SetParameters sets the Parameters field's value. +func (s *BatchStatementRequest) SetParameters(v []*AttributeValue) *BatchStatementRequest { + s.Parameters = v + return s +} + +// SetStatement sets the Statement field's value. +func (s *BatchStatementRequest) SetStatement(v string) *BatchStatementRequest { + s.Statement = &v + return s +} + +// A PartiQL batch statement response.. +type BatchStatementResponse struct { + _ struct{} `type:"structure"` + + // The error associated with a failed PartiQL batch statement. + Error *BatchStatementError `type:"structure"` + + // A DynamoDB item associated with a BatchStatementResponse + Item map[string]*AttributeValue `type:"map"` + + // The table name associated with a failed PartiQL batch statement. + TableName *string `min:"3" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s BatchStatementResponse) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s BatchStatementResponse) GoString() string { + return s.String() +} + +// SetError sets the Error field's value. +func (s *BatchStatementResponse) SetError(v *BatchStatementError) *BatchStatementResponse { + s.Error = v + return s +} + +// SetItem sets the Item field's value. +func (s *BatchStatementResponse) SetItem(v map[string]*AttributeValue) *BatchStatementResponse { + s.Item = v + return s +} + +// SetTableName sets the TableName field's value. +func (s *BatchStatementResponse) SetTableName(v string) *BatchStatementResponse { + s.TableName = &v + return s +} + +// Represents the input of a BatchWriteItem operation. +type BatchWriteItemInput struct { + _ struct{} `type:"structure"` + + // A map of one or more table names and, for each table, a list of operations + // to be performed (DeleteRequest or PutRequest). Each element in the map consists + // of the following: + // + // * DeleteRequest - Perform a DeleteItem operation on the specified item. + // The item to be deleted is identified by a Key subelement: Key - A map + // of primary key attribute values that uniquely identify the item. Each + // entry in this map consists of an attribute name and an attribute value. + // For each primary key, you must provide all of the key attributes. For + // example, with a simple primary key, you only need to provide a value for + // the partition key. For a composite primary key, you must provide values + // for both the partition key and the sort key. + // + // * PutRequest - Perform a PutItem operation on the specified item. The + // item to be put is identified by an Item subelement: Item - A map of attributes + // and their values. Each entry in this map consists of an attribute name + // and an attribute value. Attribute values must not be null; string and + // binary type attributes must have lengths greater than zero; and set type + // attributes must not be empty. Requests that contain empty values are rejected + // with a ValidationException exception. If you specify any attributes that + // are part of an index key, then the data types for those attributes must + // match those of the schema in the table's attribute definition. + // + // RequestItems is a required field + RequestItems map[string][]*WriteRequest `min:"1" type:"map" required:"true"` + + // Determines the level of detail about either provisioned or on-demand throughput + // consumption that is returned in the response: + // + // * INDEXES - The response includes the aggregate ConsumedCapacity for the + // operation, together with ConsumedCapacity for each table and secondary + // index that was accessed. Note that some operations, such as GetItem and + // BatchGetItem, do not access any indexes at all. In these cases, specifying + // INDEXES will only return ConsumedCapacity information for table(s). + // + // * TOTAL - The response includes only the aggregate ConsumedCapacity for + // the operation. + // + // * NONE - No ConsumedCapacity details are included in the response. + ReturnConsumedCapacity *string `type:"string" enum:"ReturnConsumedCapacity"` + + // Determines whether item collection metrics are returned. If set to SIZE, + // the response includes statistics about item collections, if any, that were + // modified during the operation are returned in the response. If set to NONE + // (the default), no statistics are returned. + ReturnItemCollectionMetrics *string `type:"string" enum:"ReturnItemCollectionMetrics"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s BatchWriteItemInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s BatchWriteItemInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *BatchWriteItemInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "BatchWriteItemInput"} + if s.RequestItems == nil { + invalidParams.Add(request.NewErrParamRequired("RequestItems")) + } + if s.RequestItems != nil && len(s.RequestItems) < 1 { + invalidParams.Add(request.NewErrParamMinLen("RequestItems", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetRequestItems sets the RequestItems field's value. +func (s *BatchWriteItemInput) SetRequestItems(v map[string][]*WriteRequest) *BatchWriteItemInput { + s.RequestItems = v + return s +} + +// SetReturnConsumedCapacity sets the ReturnConsumedCapacity field's value. +func (s *BatchWriteItemInput) SetReturnConsumedCapacity(v string) *BatchWriteItemInput { + s.ReturnConsumedCapacity = &v + return s +} + +// SetReturnItemCollectionMetrics sets the ReturnItemCollectionMetrics field's value. +func (s *BatchWriteItemInput) SetReturnItemCollectionMetrics(v string) *BatchWriteItemInput { + s.ReturnItemCollectionMetrics = &v + return s +} + +// Represents the output of a BatchWriteItem operation. +type BatchWriteItemOutput struct { + _ struct{} `type:"structure"` + + // The capacity units consumed by the entire BatchWriteItem operation. + // + // Each element consists of: + // + // * TableName - The table that consumed the provisioned throughput. + // + // * CapacityUnits - The total number of capacity units consumed. + ConsumedCapacity []*ConsumedCapacity `type:"list"` + + // A list of tables that were processed by BatchWriteItem and, for each table, + // information about any item collections that were affected by individual DeleteItem + // or PutItem operations. + // + // Each entry consists of the following subelements: + // + // * ItemCollectionKey - The partition key value of the item collection. + // This is the same as the partition key value of the item. + // + // * SizeEstimateRangeGB - An estimate of item collection size, expressed + // in GB. This is a two-element array containing a lower bound and an upper + // bound for the estimate. The estimate includes the size of all the items + // in the table, plus the size of all attributes projected into all of the + // local secondary indexes on the table. Use this estimate to measure whether + // a local secondary index is approaching its size limit. The estimate is + // subject to change over time; therefore, do not rely on the precision or + // accuracy of the estimate. + ItemCollectionMetrics map[string][]*ItemCollectionMetrics `type:"map"` + + // A map of tables and requests against those tables that were not processed. + // The UnprocessedItems value is in the same form as RequestItems, so you can + // provide this value directly to a subsequent BatchGetItem operation. For more + // information, see RequestItems in the Request Parameters section. + // + // Each UnprocessedItems entry consists of a table name and, for that table, + // a list of operations to perform (DeleteRequest or PutRequest). + // + // * DeleteRequest - Perform a DeleteItem operation on the specified item. + // The item to be deleted is identified by a Key subelement: Key - A map + // of primary key attribute values that uniquely identify the item. Each + // entry in this map consists of an attribute name and an attribute value. + // + // * PutRequest - Perform a PutItem operation on the specified item. The + // item to be put is identified by an Item subelement: Item - A map of attributes + // and their values. Each entry in this map consists of an attribute name + // and an attribute value. Attribute values must not be null; string and + // binary type attributes must have lengths greater than zero; and set type + // attributes must not be empty. Requests that contain empty values will + // be rejected with a ValidationException exception. If you specify any attributes + // that are part of an index key, then the data types for those attributes + // must match those of the schema in the table's attribute definition. + // + // If there are no unprocessed items remaining, the response contains an empty + // UnprocessedItems map. + UnprocessedItems map[string][]*WriteRequest `min:"1" type:"map"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s BatchWriteItemOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s BatchWriteItemOutput) GoString() string { + return s.String() +} + +// SetConsumedCapacity sets the ConsumedCapacity field's value. +func (s *BatchWriteItemOutput) SetConsumedCapacity(v []*ConsumedCapacity) *BatchWriteItemOutput { + s.ConsumedCapacity = v + return s +} + +// SetItemCollectionMetrics sets the ItemCollectionMetrics field's value. +func (s *BatchWriteItemOutput) SetItemCollectionMetrics(v map[string][]*ItemCollectionMetrics) *BatchWriteItemOutput { + s.ItemCollectionMetrics = v + return s +} + +// SetUnprocessedItems sets the UnprocessedItems field's value. +func (s *BatchWriteItemOutput) SetUnprocessedItems(v map[string][]*WriteRequest) *BatchWriteItemOutput { + s.UnprocessedItems = v + return s +} + +// Contains the details for the read/write capacity mode. +type BillingModeSummary struct { + _ struct{} `type:"structure"` + + // Controls how you are charged for read and write throughput and how you manage + // capacity. This setting can be changed later. + // + // * PROVISIONED - Sets the read/write capacity mode to PROVISIONED. We recommend + // using PROVISIONED for predictable workloads. + // + // * PAY_PER_REQUEST - Sets the read/write capacity mode to PAY_PER_REQUEST. + // We recommend using PAY_PER_REQUEST for unpredictable workloads. + BillingMode *string `type:"string" enum:"BillingMode"` + + // Represents the time when PAY_PER_REQUEST was last set as the read/write capacity + // mode. + LastUpdateToPayPerRequestDateTime *time.Time `type:"timestamp"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s BillingModeSummary) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s BillingModeSummary) GoString() string { + return s.String() +} + +// SetBillingMode sets the BillingMode field's value. +func (s *BillingModeSummary) SetBillingMode(v string) *BillingModeSummary { + s.BillingMode = &v + return s +} + +// SetLastUpdateToPayPerRequestDateTime sets the LastUpdateToPayPerRequestDateTime field's value. +func (s *BillingModeSummary) SetLastUpdateToPayPerRequestDateTime(v time.Time) *BillingModeSummary { + s.LastUpdateToPayPerRequestDateTime = &v + return s +} + +// An ordered list of errors for each item in the request which caused the transaction +// to get cancelled. The values of the list are ordered according to the ordering +// of the TransactWriteItems request parameter. If no error occurred for the +// associated item an error with a Null code and Null message will be present. +type CancellationReason struct { + _ struct{} `type:"structure"` + + // Status code for the result of the cancelled transaction. + Code *string `type:"string"` + + // Item in the request which caused the transaction to get cancelled. + Item map[string]*AttributeValue `type:"map"` + + // Cancellation reason message description. + Message *string `type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s CancellationReason) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s CancellationReason) GoString() string { + return s.String() +} + +// SetCode sets the Code field's value. +func (s *CancellationReason) SetCode(v string) *CancellationReason { + s.Code = &v + return s +} + +// SetItem sets the Item field's value. +func (s *CancellationReason) SetItem(v map[string]*AttributeValue) *CancellationReason { + s.Item = v + return s +} + +// SetMessage sets the Message field's value. +func (s *CancellationReason) SetMessage(v string) *CancellationReason { + s.Message = &v + return s +} + +// Represents the amount of provisioned throughput capacity consumed on a table +// or an index. +type Capacity struct { + _ struct{} `type:"structure"` + + // The total number of capacity units consumed on a table or an index. + CapacityUnits *float64 `type:"double"` + + // The total number of read capacity units consumed on a table or an index. + ReadCapacityUnits *float64 `type:"double"` + + // The total number of write capacity units consumed on a table or an index. + WriteCapacityUnits *float64 `type:"double"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s Capacity) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s Capacity) GoString() string { + return s.String() +} + +// SetCapacityUnits sets the CapacityUnits field's value. +func (s *Capacity) SetCapacityUnits(v float64) *Capacity { + s.CapacityUnits = &v + return s +} + +// SetReadCapacityUnits sets the ReadCapacityUnits field's value. +func (s *Capacity) SetReadCapacityUnits(v float64) *Capacity { + s.ReadCapacityUnits = &v + return s +} + +// SetWriteCapacityUnits sets the WriteCapacityUnits field's value. +func (s *Capacity) SetWriteCapacityUnits(v float64) *Capacity { + s.WriteCapacityUnits = &v + return s +} + +// Represents the selection criteria for a Query or Scan operation: +// +// * For a Query operation, Condition is used for specifying the KeyConditions +// to use when querying a table or an index. For KeyConditions, only the +// following comparison operators are supported: EQ | LE | LT | GE | GT | +// BEGINS_WITH | BETWEEN Condition is also used in a QueryFilter, which evaluates +// the query results and returns only the desired values. +// +// * For a Scan operation, Condition is used in a ScanFilter, which evaluates +// the scan results and returns only the desired values. +type Condition struct { + _ struct{} `type:"structure"` + + // One or more values to evaluate against the supplied attribute. The number + // of values in the list depends on the ComparisonOperator being used. + // + // For type Number, value comparisons are numeric. + // + // String value comparisons for greater than, equals, or less than are based + // on ASCII character code values. For example, a is greater than A, and a is + // greater than B. For a list of code values, see http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters + // (http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters). + // + // For Binary, DynamoDB treats each byte of the binary data as unsigned when + // it compares binary values. + AttributeValueList []*AttributeValue `type:"list"` + + // A comparator for evaluating attributes. For example, equals, greater than, + // less than, etc. + // + // The following comparison operators are available: + // + // EQ | NE | LE | LT | GE | GT | NOT_NULL | NULL | CONTAINS | NOT_CONTAINS | + // BEGINS_WITH | IN | BETWEEN + // + // The following are descriptions of each comparison operator. + // + // * EQ : Equal. EQ is supported for all data types, including lists and + // maps. AttributeValueList can contain only one AttributeValue element of + // type String, Number, Binary, String Set, Number Set, or Binary Set. If + // an item contains an AttributeValue element of a different type than the + // one provided in the request, the value does not match. For example, {"S":"6"} + // does not equal {"N":"6"}. Also, {"N":"6"} does not equal {"NS":["6", "2", + // "1"]}. + // + // * NE : Not equal. NE is supported for all data types, including lists + // and maps. AttributeValueList can contain only one AttributeValue of type + // String, Number, Binary, String Set, Number Set, or Binary Set. If an item + // contains an AttributeValue of a different type than the one provided in + // the request, the value does not match. For example, {"S":"6"} does not + // equal {"N":"6"}. Also, {"N":"6"} does not equal {"NS":["6", "2", "1"]}. + // + // * LE : Less than or equal. AttributeValueList can contain only one AttributeValue + // element of type String, Number, or Binary (not a set type). If an item + // contains an AttributeValue element of a different type than the one provided + // in the request, the value does not match. For example, {"S":"6"} does + // not equal {"N":"6"}. Also, {"N":"6"} does not compare to {"NS":["6", "2", + // "1"]}. + // + // * LT : Less than. AttributeValueList can contain only one AttributeValue + // of type String, Number, or Binary (not a set type). If an item contains + // an AttributeValue element of a different type than the one provided in + // the request, the value does not match. For example, {"S":"6"} does not + // equal {"N":"6"}. Also, {"N":"6"} does not compare to {"NS":["6", "2", + // "1"]}. + // + // * GE : Greater than or equal. AttributeValueList can contain only one + // AttributeValue element of type String, Number, or Binary (not a set type). + // If an item contains an AttributeValue element of a different type than + // the one provided in the request, the value does not match. For example, + // {"S":"6"} does not equal {"N":"6"}. Also, {"N":"6"} does not compare to + // {"NS":["6", "2", "1"]}. + // + // * GT : Greater than. AttributeValueList can contain only one AttributeValue + // element of type String, Number, or Binary (not a set type). If an item + // contains an AttributeValue element of a different type than the one provided + // in the request, the value does not match. For example, {"S":"6"} does + // not equal {"N":"6"}. Also, {"N":"6"} does not compare to {"NS":["6", "2", + // "1"]}. + // + // * NOT_NULL : The attribute exists. NOT_NULL is supported for all data + // types, including lists and maps. This operator tests for the existence + // of an attribute, not its data type. If the data type of attribute "a" + // is null, and you evaluate it using NOT_NULL, the result is a Boolean true. + // This result is because the attribute "a" exists; its data type is not + // relevant to the NOT_NULL comparison operator. + // + // * NULL : The attribute does not exist. NULL is supported for all data + // types, including lists and maps. This operator tests for the nonexistence + // of an attribute, not its data type. If the data type of attribute "a" + // is null, and you evaluate it using NULL, the result is a Boolean false. + // This is because the attribute "a" exists; its data type is not relevant + // to the NULL comparison operator. + // + // * CONTAINS : Checks for a subsequence, or value in a set. AttributeValueList + // can contain only one AttributeValue element of type String, Number, or + // Binary (not a set type). If the target attribute of the comparison is + // of type String, then the operator checks for a substring match. If the + // target attribute of the comparison is of type Binary, then the operator + // looks for a subsequence of the target that matches the input. If the target + // attribute of the comparison is a set ("SS", "NS", or "BS"), then the operator + // evaluates to true if it finds an exact match with any member of the set. + // CONTAINS is supported for lists: When evaluating "a CONTAINS b", "a" can + // be a list; however, "b" cannot be a set, a map, or a list. + // + // * NOT_CONTAINS : Checks for absence of a subsequence, or absence of a + // value in a set. AttributeValueList can contain only one AttributeValue + // element of type String, Number, or Binary (not a set type). If the target + // attribute of the comparison is a String, then the operator checks for + // the absence of a substring match. If the target attribute of the comparison + // is Binary, then the operator checks for the absence of a subsequence of + // the target that matches the input. If the target attribute of the comparison + // is a set ("SS", "NS", or "BS"), then the operator evaluates to true if + // it does not find an exact match with any member of the set. NOT_CONTAINS + // is supported for lists: When evaluating "a NOT CONTAINS b", "a" can be + // a list; however, "b" cannot be a set, a map, or a list. + // + // * BEGINS_WITH : Checks for a prefix. AttributeValueList can contain only + // one AttributeValue of type String or Binary (not a Number or a set type). + // The target attribute of the comparison must be of type String or Binary + // (not a Number or a set type). + // + // * IN : Checks for matching elements in a list. AttributeValueList can + // contain one or more AttributeValue elements of type String, Number, or + // Binary. These attributes are compared against an existing attribute of + // an item. If any elements of the input are equal to the item attribute, + // the expression evaluates to true. + // + // * BETWEEN : Greater than or equal to the first value, and less than or + // equal to the second value. AttributeValueList must contain two AttributeValue + // elements of the same type, either String, Number, or Binary (not a set + // type). A target attribute matches if the target value is greater than, + // or equal to, the first element and less than, or equal to, the second + // element. If an item contains an AttributeValue element of a different + // type than the one provided in the request, the value does not match. For + // example, {"S":"6"} does not compare to {"N":"6"}. Also, {"N":"6"} does + // not compare to {"NS":["6", "2", "1"]} + // + // For usage examples of AttributeValueList and ComparisonOperator, see Legacy + // Conditional Parameters (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.html) + // in the Amazon DynamoDB Developer Guide. + // + // ComparisonOperator is a required field + ComparisonOperator *string `type:"string" required:"true" enum:"ComparisonOperator"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s Condition) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s Condition) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *Condition) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "Condition"} + if s.ComparisonOperator == nil { + invalidParams.Add(request.NewErrParamRequired("ComparisonOperator")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAttributeValueList sets the AttributeValueList field's value. +func (s *Condition) SetAttributeValueList(v []*AttributeValue) *Condition { + s.AttributeValueList = v + return s +} + +// SetComparisonOperator sets the ComparisonOperator field's value. +func (s *Condition) SetComparisonOperator(v string) *Condition { + s.ComparisonOperator = &v + return s +} + +// Represents a request to perform a check that an item exists or to check the +// condition of specific attributes of the item. +type ConditionCheck struct { + _ struct{} `type:"structure"` + + // A condition that must be satisfied in order for a conditional update to succeed. + // + // ConditionExpression is a required field + ConditionExpression *string `type:"string" required:"true"` + + // One or more substitution tokens for attribute names in an expression. + ExpressionAttributeNames map[string]*string `type:"map"` + + // One or more values that can be substituted in an expression. + ExpressionAttributeValues map[string]*AttributeValue `type:"map"` + + // The primary key of the item to be checked. Each element consists of an attribute + // name and a value for that attribute. + // + // Key is a required field + Key map[string]*AttributeValue `type:"map" required:"true"` + + // Use ReturnValuesOnConditionCheckFailure to get the item attributes if the + // ConditionCheck condition fails. For ReturnValuesOnConditionCheckFailure, + // the valid values are: NONE and ALL_OLD. + ReturnValuesOnConditionCheckFailure *string `type:"string" enum:"ReturnValuesOnConditionCheckFailure"` + + // Name of the table for the check item request. + // + // TableName is a required field + TableName *string `min:"3" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ConditionCheck) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ConditionCheck) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ConditionCheck) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ConditionCheck"} + if s.ConditionExpression == nil { + invalidParams.Add(request.NewErrParamRequired("ConditionExpression")) + } + if s.Key == nil { + invalidParams.Add(request.NewErrParamRequired("Key")) + } + if s.TableName == nil { + invalidParams.Add(request.NewErrParamRequired("TableName")) + } + if s.TableName != nil && len(*s.TableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("TableName", 3)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetConditionExpression sets the ConditionExpression field's value. +func (s *ConditionCheck) SetConditionExpression(v string) *ConditionCheck { + s.ConditionExpression = &v + return s +} + +// SetExpressionAttributeNames sets the ExpressionAttributeNames field's value. +func (s *ConditionCheck) SetExpressionAttributeNames(v map[string]*string) *ConditionCheck { + s.ExpressionAttributeNames = v + return s +} + +// SetExpressionAttributeValues sets the ExpressionAttributeValues field's value. +func (s *ConditionCheck) SetExpressionAttributeValues(v map[string]*AttributeValue) *ConditionCheck { + s.ExpressionAttributeValues = v + return s +} + +// SetKey sets the Key field's value. +func (s *ConditionCheck) SetKey(v map[string]*AttributeValue) *ConditionCheck { + s.Key = v + return s +} + +// SetReturnValuesOnConditionCheckFailure sets the ReturnValuesOnConditionCheckFailure field's value. +func (s *ConditionCheck) SetReturnValuesOnConditionCheckFailure(v string) *ConditionCheck { + s.ReturnValuesOnConditionCheckFailure = &v + return s +} + +// SetTableName sets the TableName field's value. +func (s *ConditionCheck) SetTableName(v string) *ConditionCheck { + s.TableName = &v + return s +} + +// A condition specified in the operation could not be evaluated. +type ConditionalCheckFailedException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + // The conditional request failed. + Message_ *string `locationName:"message" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ConditionalCheckFailedException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ConditionalCheckFailedException) GoString() string { + return s.String() +} + +func newErrorConditionalCheckFailedException(v protocol.ResponseMetadata) error { + return &ConditionalCheckFailedException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *ConditionalCheckFailedException) Code() string { + return "ConditionalCheckFailedException" +} + +// Message returns the exception's message. +func (s *ConditionalCheckFailedException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *ConditionalCheckFailedException) OrigErr() error { + return nil +} + +func (s *ConditionalCheckFailedException) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *ConditionalCheckFailedException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *ConditionalCheckFailedException) RequestID() string { + return s.RespMetadata.RequestID +} + +// The capacity units consumed by an operation. The data returned includes the +// total provisioned throughput consumed, along with statistics for the table +// and any indexes involved in the operation. ConsumedCapacity is only returned +// if the request asked for it. For more information, see Provisioned Throughput +// (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ProvisionedThroughputIntro.html) +// in the Amazon DynamoDB Developer Guide. +type ConsumedCapacity struct { + _ struct{} `type:"structure"` + + // The total number of capacity units consumed by the operation. + CapacityUnits *float64 `type:"double"` + + // The amount of throughput consumed on each global index affected by the operation. + GlobalSecondaryIndexes map[string]*Capacity `type:"map"` + + // The amount of throughput consumed on each local index affected by the operation. + LocalSecondaryIndexes map[string]*Capacity `type:"map"` + + // The total number of read capacity units consumed by the operation. + ReadCapacityUnits *float64 `type:"double"` + + // The amount of throughput consumed on the table affected by the operation. + Table *Capacity `type:"structure"` + + // The name of the table that was affected by the operation. + TableName *string `min:"3" type:"string"` + + // The total number of write capacity units consumed by the operation. + WriteCapacityUnits *float64 `type:"double"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ConsumedCapacity) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ConsumedCapacity) GoString() string { + return s.String() +} + +// SetCapacityUnits sets the CapacityUnits field's value. +func (s *ConsumedCapacity) SetCapacityUnits(v float64) *ConsumedCapacity { + s.CapacityUnits = &v + return s +} + +// SetGlobalSecondaryIndexes sets the GlobalSecondaryIndexes field's value. +func (s *ConsumedCapacity) SetGlobalSecondaryIndexes(v map[string]*Capacity) *ConsumedCapacity { + s.GlobalSecondaryIndexes = v + return s +} + +// SetLocalSecondaryIndexes sets the LocalSecondaryIndexes field's value. +func (s *ConsumedCapacity) SetLocalSecondaryIndexes(v map[string]*Capacity) *ConsumedCapacity { + s.LocalSecondaryIndexes = v + return s +} + +// SetReadCapacityUnits sets the ReadCapacityUnits field's value. +func (s *ConsumedCapacity) SetReadCapacityUnits(v float64) *ConsumedCapacity { + s.ReadCapacityUnits = &v + return s +} + +// SetTable sets the Table field's value. +func (s *ConsumedCapacity) SetTable(v *Capacity) *ConsumedCapacity { + s.Table = v + return s +} + +// SetTableName sets the TableName field's value. +func (s *ConsumedCapacity) SetTableName(v string) *ConsumedCapacity { + s.TableName = &v + return s +} + +// SetWriteCapacityUnits sets the WriteCapacityUnits field's value. +func (s *ConsumedCapacity) SetWriteCapacityUnits(v float64) *ConsumedCapacity { + s.WriteCapacityUnits = &v + return s +} + +// Represents the continuous backups and point in time recovery settings on +// the table. +type ContinuousBackupsDescription struct { + _ struct{} `type:"structure"` + + // ContinuousBackupsStatus can be one of the following states: ENABLED, DISABLED + // + // ContinuousBackupsStatus is a required field + ContinuousBackupsStatus *string `type:"string" required:"true" enum:"ContinuousBackupsStatus"` + + // The description of the point in time recovery settings applied to the table. + PointInTimeRecoveryDescription *PointInTimeRecoveryDescription `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ContinuousBackupsDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ContinuousBackupsDescription) GoString() string { + return s.String() +} + +// SetContinuousBackupsStatus sets the ContinuousBackupsStatus field's value. +func (s *ContinuousBackupsDescription) SetContinuousBackupsStatus(v string) *ContinuousBackupsDescription { + s.ContinuousBackupsStatus = &v + return s +} + +// SetPointInTimeRecoveryDescription sets the PointInTimeRecoveryDescription field's value. +func (s *ContinuousBackupsDescription) SetPointInTimeRecoveryDescription(v *PointInTimeRecoveryDescription) *ContinuousBackupsDescription { + s.PointInTimeRecoveryDescription = v + return s +} + +// Backups have not yet been enabled for this table. +type ContinuousBackupsUnavailableException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + Message_ *string `locationName:"message" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ContinuousBackupsUnavailableException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ContinuousBackupsUnavailableException) GoString() string { + return s.String() +} + +func newErrorContinuousBackupsUnavailableException(v protocol.ResponseMetadata) error { + return &ContinuousBackupsUnavailableException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *ContinuousBackupsUnavailableException) Code() string { + return "ContinuousBackupsUnavailableException" +} + +// Message returns the exception's message. +func (s *ContinuousBackupsUnavailableException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *ContinuousBackupsUnavailableException) OrigErr() error { + return nil +} + +func (s *ContinuousBackupsUnavailableException) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *ContinuousBackupsUnavailableException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *ContinuousBackupsUnavailableException) RequestID() string { + return s.RespMetadata.RequestID +} + +// Represents a Contributor Insights summary entry. +type ContributorInsightsSummary struct { + _ struct{} `type:"structure"` + + // Describes the current status for contributor insights for the given table + // and index, if applicable. + ContributorInsightsStatus *string `type:"string" enum:"ContributorInsightsStatus"` + + // Name of the index associated with the summary, if any. + IndexName *string `min:"3" type:"string"` + + // Name of the table associated with the summary. + TableName *string `min:"3" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ContributorInsightsSummary) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ContributorInsightsSummary) GoString() string { + return s.String() +} + +// SetContributorInsightsStatus sets the ContributorInsightsStatus field's value. +func (s *ContributorInsightsSummary) SetContributorInsightsStatus(v string) *ContributorInsightsSummary { + s.ContributorInsightsStatus = &v + return s +} + +// SetIndexName sets the IndexName field's value. +func (s *ContributorInsightsSummary) SetIndexName(v string) *ContributorInsightsSummary { + s.IndexName = &v + return s +} + +// SetTableName sets the TableName field's value. +func (s *ContributorInsightsSummary) SetTableName(v string) *ContributorInsightsSummary { + s.TableName = &v + return s +} + +type CreateBackupInput struct { + _ struct{} `type:"structure"` + + // Specified name for the backup. + // + // BackupName is a required field + BackupName *string `min:"3" type:"string" required:"true"` + + // The name of the table. + // + // TableName is a required field + TableName *string `min:"3" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s CreateBackupInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s CreateBackupInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateBackupInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateBackupInput"} + if s.BackupName == nil { + invalidParams.Add(request.NewErrParamRequired("BackupName")) + } + if s.BackupName != nil && len(*s.BackupName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("BackupName", 3)) + } + if s.TableName == nil { + invalidParams.Add(request.NewErrParamRequired("TableName")) + } + if s.TableName != nil && len(*s.TableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("TableName", 3)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetBackupName sets the BackupName field's value. +func (s *CreateBackupInput) SetBackupName(v string) *CreateBackupInput { + s.BackupName = &v + return s +} + +// SetTableName sets the TableName field's value. +func (s *CreateBackupInput) SetTableName(v string) *CreateBackupInput { + s.TableName = &v + return s +} + +type CreateBackupOutput struct { + _ struct{} `type:"structure"` + + // Contains the details of the backup created for the table. + BackupDetails *BackupDetails `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s CreateBackupOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s CreateBackupOutput) GoString() string { + return s.String() +} + +// SetBackupDetails sets the BackupDetails field's value. +func (s *CreateBackupOutput) SetBackupDetails(v *BackupDetails) *CreateBackupOutput { + s.BackupDetails = v + return s +} + +// Represents a new global secondary index to be added to an existing table. +type CreateGlobalSecondaryIndexAction struct { + _ struct{} `type:"structure"` + + // The name of the global secondary index to be created. + // + // IndexName is a required field + IndexName *string `min:"3" type:"string" required:"true"` + + // The key schema for the global secondary index. + // + // KeySchema is a required field + KeySchema []*KeySchemaElement `min:"1" type:"list" required:"true"` + + // Represents attributes that are copied (projected) from the table into an + // index. These are in addition to the primary key attributes and index key + // attributes, which are automatically projected. + // + // Projection is a required field + Projection *Projection `type:"structure" required:"true"` + + // Represents the provisioned throughput settings for the specified global secondary + // index. + // + // For current minimum and maximum provisioned throughput values, see Service, + // Account, and Table Quotas (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Limits.html) + // in the Amazon DynamoDB Developer Guide. + ProvisionedThroughput *ProvisionedThroughput `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s CreateGlobalSecondaryIndexAction) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s CreateGlobalSecondaryIndexAction) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateGlobalSecondaryIndexAction) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateGlobalSecondaryIndexAction"} + if s.IndexName == nil { + invalidParams.Add(request.NewErrParamRequired("IndexName")) + } + if s.IndexName != nil && len(*s.IndexName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("IndexName", 3)) + } + if s.KeySchema == nil { + invalidParams.Add(request.NewErrParamRequired("KeySchema")) + } + if s.KeySchema != nil && len(s.KeySchema) < 1 { + invalidParams.Add(request.NewErrParamMinLen("KeySchema", 1)) + } + if s.Projection == nil { + invalidParams.Add(request.NewErrParamRequired("Projection")) + } + if s.KeySchema != nil { + for i, v := range s.KeySchema { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "KeySchema", i), err.(request.ErrInvalidParams)) + } + } + } + if s.Projection != nil { + if err := s.Projection.Validate(); err != nil { + invalidParams.AddNested("Projection", err.(request.ErrInvalidParams)) + } + } + if s.ProvisionedThroughput != nil { + if err := s.ProvisionedThroughput.Validate(); err != nil { + invalidParams.AddNested("ProvisionedThroughput", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetIndexName sets the IndexName field's value. +func (s *CreateGlobalSecondaryIndexAction) SetIndexName(v string) *CreateGlobalSecondaryIndexAction { + s.IndexName = &v + return s +} + +// SetKeySchema sets the KeySchema field's value. +func (s *CreateGlobalSecondaryIndexAction) SetKeySchema(v []*KeySchemaElement) *CreateGlobalSecondaryIndexAction { + s.KeySchema = v + return s +} + +// SetProjection sets the Projection field's value. +func (s *CreateGlobalSecondaryIndexAction) SetProjection(v *Projection) *CreateGlobalSecondaryIndexAction { + s.Projection = v + return s +} + +// SetProvisionedThroughput sets the ProvisionedThroughput field's value. +func (s *CreateGlobalSecondaryIndexAction) SetProvisionedThroughput(v *ProvisionedThroughput) *CreateGlobalSecondaryIndexAction { + s.ProvisionedThroughput = v + return s +} + +type CreateGlobalTableInput struct { + _ struct{} `type:"structure"` + + // The global table name. + // + // GlobalTableName is a required field + GlobalTableName *string `min:"3" type:"string" required:"true"` + + // The Regions where the global table needs to be created. + // + // ReplicationGroup is a required field + ReplicationGroup []*Replica `type:"list" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s CreateGlobalTableInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s CreateGlobalTableInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateGlobalTableInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateGlobalTableInput"} + if s.GlobalTableName == nil { + invalidParams.Add(request.NewErrParamRequired("GlobalTableName")) + } + if s.GlobalTableName != nil && len(*s.GlobalTableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("GlobalTableName", 3)) + } + if s.ReplicationGroup == nil { + invalidParams.Add(request.NewErrParamRequired("ReplicationGroup")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetGlobalTableName sets the GlobalTableName field's value. +func (s *CreateGlobalTableInput) SetGlobalTableName(v string) *CreateGlobalTableInput { + s.GlobalTableName = &v + return s +} + +// SetReplicationGroup sets the ReplicationGroup field's value. +func (s *CreateGlobalTableInput) SetReplicationGroup(v []*Replica) *CreateGlobalTableInput { + s.ReplicationGroup = v + return s +} + +type CreateGlobalTableOutput struct { + _ struct{} `type:"structure"` + + // Contains the details of the global table. + GlobalTableDescription *GlobalTableDescription `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s CreateGlobalTableOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s CreateGlobalTableOutput) GoString() string { + return s.String() +} + +// SetGlobalTableDescription sets the GlobalTableDescription field's value. +func (s *CreateGlobalTableOutput) SetGlobalTableDescription(v *GlobalTableDescription) *CreateGlobalTableOutput { + s.GlobalTableDescription = v + return s +} + +// Represents a replica to be added. +type CreateReplicaAction struct { + _ struct{} `type:"structure"` + + // The Region of the replica to be added. + // + // RegionName is a required field + RegionName *string `type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s CreateReplicaAction) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s CreateReplicaAction) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateReplicaAction) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateReplicaAction"} + if s.RegionName == nil { + invalidParams.Add(request.NewErrParamRequired("RegionName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetRegionName sets the RegionName field's value. +func (s *CreateReplicaAction) SetRegionName(v string) *CreateReplicaAction { + s.RegionName = &v + return s +} + +// Represents a replica to be created. +type CreateReplicationGroupMemberAction struct { + _ struct{} `type:"structure"` + + // Replica-specific global secondary index settings. + GlobalSecondaryIndexes []*ReplicaGlobalSecondaryIndex `min:"1" type:"list"` + + // The KMS key that should be used for KMS encryption in the new replica. To + // specify a key, use its key ID, Amazon Resource Name (ARN), alias name, or + // alias ARN. Note that you should only provide this parameter if the key is + // different from the default DynamoDB KMS key alias/aws/dynamodb. + KMSMasterKeyId *string `type:"string"` + + // Replica-specific provisioned throughput. If not specified, uses the source + // table's provisioned throughput settings. + ProvisionedThroughputOverride *ProvisionedThroughputOverride `type:"structure"` + + // The Region where the new replica will be created. + // + // RegionName is a required field + RegionName *string `type:"string" required:"true"` + + // Replica-specific table class. If not specified, uses the source table's table + // class. + TableClassOverride *string `type:"string" enum:"TableClass"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s CreateReplicationGroupMemberAction) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s CreateReplicationGroupMemberAction) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateReplicationGroupMemberAction) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateReplicationGroupMemberAction"} + if s.GlobalSecondaryIndexes != nil && len(s.GlobalSecondaryIndexes) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GlobalSecondaryIndexes", 1)) + } + if s.RegionName == nil { + invalidParams.Add(request.NewErrParamRequired("RegionName")) + } + if s.GlobalSecondaryIndexes != nil { + for i, v := range s.GlobalSecondaryIndexes { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "GlobalSecondaryIndexes", i), err.(request.ErrInvalidParams)) + } + } + } + if s.ProvisionedThroughputOverride != nil { + if err := s.ProvisionedThroughputOverride.Validate(); err != nil { + invalidParams.AddNested("ProvisionedThroughputOverride", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetGlobalSecondaryIndexes sets the GlobalSecondaryIndexes field's value. +func (s *CreateReplicationGroupMemberAction) SetGlobalSecondaryIndexes(v []*ReplicaGlobalSecondaryIndex) *CreateReplicationGroupMemberAction { + s.GlobalSecondaryIndexes = v + return s +} + +// SetKMSMasterKeyId sets the KMSMasterKeyId field's value. +func (s *CreateReplicationGroupMemberAction) SetKMSMasterKeyId(v string) *CreateReplicationGroupMemberAction { + s.KMSMasterKeyId = &v + return s +} + +// SetProvisionedThroughputOverride sets the ProvisionedThroughputOverride field's value. +func (s *CreateReplicationGroupMemberAction) SetProvisionedThroughputOverride(v *ProvisionedThroughputOverride) *CreateReplicationGroupMemberAction { + s.ProvisionedThroughputOverride = v + return s +} + +// SetRegionName sets the RegionName field's value. +func (s *CreateReplicationGroupMemberAction) SetRegionName(v string) *CreateReplicationGroupMemberAction { + s.RegionName = &v + return s +} + +// SetTableClassOverride sets the TableClassOverride field's value. +func (s *CreateReplicationGroupMemberAction) SetTableClassOverride(v string) *CreateReplicationGroupMemberAction { + s.TableClassOverride = &v + return s +} + +// Represents the input of a CreateTable operation. +type CreateTableInput struct { + _ struct{} `type:"structure"` + + // An array of attributes that describe the key schema for the table and indexes. + // + // AttributeDefinitions is a required field + AttributeDefinitions []*AttributeDefinition `type:"list" required:"true"` + + // Controls how you are charged for read and write throughput and how you manage + // capacity. This setting can be changed later. + // + // * PROVISIONED - We recommend using PROVISIONED for predictable workloads. + // PROVISIONED sets the billing mode to Provisioned Mode (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadWriteCapacityMode.html#HowItWorks.ProvisionedThroughput.Manual). + // + // * PAY_PER_REQUEST - We recommend using PAY_PER_REQUEST for unpredictable + // workloads. PAY_PER_REQUEST sets the billing mode to On-Demand Mode (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadWriteCapacityMode.html#HowItWorks.OnDemand). + BillingMode *string `type:"string" enum:"BillingMode"` + + // One or more global secondary indexes (the maximum is 20) to be created on + // the table. Each global secondary index in the array includes the following: + // + // * IndexName - The name of the global secondary index. Must be unique only + // for this table. + // + // * KeySchema - Specifies the key schema for the global secondary index. + // + // * Projection - Specifies attributes that are copied (projected) from the + // table into the index. These are in addition to the primary key attributes + // and index key attributes, which are automatically projected. Each attribute + // specification is composed of: ProjectionType - One of the following: KEYS_ONLY + // - Only the index and primary keys are projected into the index. INCLUDE + // - Only the specified table attributes are projected into the index. The + // list of projected attributes is in NonKeyAttributes. ALL - All of the + // table attributes are projected into the index. NonKeyAttributes - A list + // of one or more non-key attribute names that are projected into the secondary + // index. The total count of attributes provided in NonKeyAttributes, summed + // across all of the secondary indexes, must not exceed 100. If you project + // the same attribute into two different indexes, this counts as two distinct + // attributes when determining the total. + // + // * ProvisionedThroughput - The provisioned throughput settings for the + // global secondary index, consisting of read and write capacity units. + GlobalSecondaryIndexes []*GlobalSecondaryIndex `type:"list"` + + // Specifies the attributes that make up the primary key for a table or an index. + // The attributes in KeySchema must also be defined in the AttributeDefinitions + // array. For more information, see Data Model (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DataModel.html) + // in the Amazon DynamoDB Developer Guide. + // + // Each KeySchemaElement in the array is composed of: + // + // * AttributeName - The name of this key attribute. + // + // * KeyType - The role that the key attribute will assume: HASH - partition + // key RANGE - sort key + // + // The partition key of an item is also known as its hash attribute. The term + // "hash attribute" derives from the DynamoDB usage of an internal hash function + // to evenly distribute data items across partitions, based on their partition + // key values. + // + // The sort key of an item is also known as its range attribute. The term "range + // attribute" derives from the way DynamoDB stores items with the same partition + // key physically close together, in sorted order by the sort key value. + // + // For a simple primary key (partition key), you must provide exactly one element + // with a KeyType of HASH. + // + // For a composite primary key (partition key and sort key), you must provide + // exactly two elements, in this order: The first element must have a KeyType + // of HASH, and the second element must have a KeyType of RANGE. + // + // For more information, see Working with Tables (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithTables.html#WorkingWithTables.primary.key) + // in the Amazon DynamoDB Developer Guide. + // + // KeySchema is a required field + KeySchema []*KeySchemaElement `min:"1" type:"list" required:"true"` + + // One or more local secondary indexes (the maximum is 5) to be created on the + // table. Each index is scoped to a given partition key value. There is a 10 + // GB size limit per partition key value; otherwise, the size of a local secondary + // index is unconstrained. + // + // Each local secondary index in the array includes the following: + // + // * IndexName - The name of the local secondary index. Must be unique only + // for this table. + // + // * KeySchema - Specifies the key schema for the local secondary index. + // The key schema must begin with the same partition key as the table. + // + // * Projection - Specifies attributes that are copied (projected) from the + // table into the index. These are in addition to the primary key attributes + // and index key attributes, which are automatically projected. Each attribute + // specification is composed of: ProjectionType - One of the following: KEYS_ONLY + // - Only the index and primary keys are projected into the index. INCLUDE + // - Only the specified table attributes are projected into the index. The + // list of projected attributes is in NonKeyAttributes. ALL - All of the + // table attributes are projected into the index. NonKeyAttributes - A list + // of one or more non-key attribute names that are projected into the secondary + // index. The total count of attributes provided in NonKeyAttributes, summed + // across all of the secondary indexes, must not exceed 100. If you project + // the same attribute into two different indexes, this counts as two distinct + // attributes when determining the total. + LocalSecondaryIndexes []*LocalSecondaryIndex `type:"list"` + + // Represents the provisioned throughput settings for a specified table or index. + // The settings can be modified using the UpdateTable operation. + // + // If you set BillingMode as PROVISIONED, you must specify this property. If + // you set BillingMode as PAY_PER_REQUEST, you cannot specify this property. + // + // For current minimum and maximum provisioned throughput values, see Service, + // Account, and Table Quotas (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Limits.html) + // in the Amazon DynamoDB Developer Guide. + ProvisionedThroughput *ProvisionedThroughput `type:"structure"` + + // Represents the settings used to enable server-side encryption. + SSESpecification *SSESpecification `type:"structure"` + + // The settings for DynamoDB Streams on the table. These settings consist of: + // + // * StreamEnabled - Indicates whether DynamoDB Streams is to be enabled + // (true) or disabled (false). + // + // * StreamViewType - When an item in the table is modified, StreamViewType + // determines what information is written to the table's stream. Valid values + // for StreamViewType are: KEYS_ONLY - Only the key attributes of the modified + // item are written to the stream. NEW_IMAGE - The entire item, as it appears + // after it was modified, is written to the stream. OLD_IMAGE - The entire + // item, as it appeared before it was modified, is written to the stream. + // NEW_AND_OLD_IMAGES - Both the new and the old item images of the item + // are written to the stream. + StreamSpecification *StreamSpecification `type:"structure"` + + // The table class of the new table. Valid values are STANDARD and STANDARD_INFREQUENT_ACCESS. + TableClass *string `type:"string" enum:"TableClass"` + + // The name of the table to create. + // + // TableName is a required field + TableName *string `min:"3" type:"string" required:"true"` + + // A list of key-value pairs to label the table. For more information, see Tagging + // for DynamoDB (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Tagging.html). + Tags []*Tag `type:"list"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s CreateTableInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s CreateTableInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateTableInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateTableInput"} + if s.AttributeDefinitions == nil { + invalidParams.Add(request.NewErrParamRequired("AttributeDefinitions")) + } + if s.KeySchema == nil { + invalidParams.Add(request.NewErrParamRequired("KeySchema")) + } + if s.KeySchema != nil && len(s.KeySchema) < 1 { + invalidParams.Add(request.NewErrParamMinLen("KeySchema", 1)) + } + if s.TableName == nil { + invalidParams.Add(request.NewErrParamRequired("TableName")) + } + if s.TableName != nil && len(*s.TableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("TableName", 3)) + } + if s.AttributeDefinitions != nil { + for i, v := range s.AttributeDefinitions { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "AttributeDefinitions", i), err.(request.ErrInvalidParams)) + } + } + } + if s.GlobalSecondaryIndexes != nil { + for i, v := range s.GlobalSecondaryIndexes { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "GlobalSecondaryIndexes", i), err.(request.ErrInvalidParams)) + } + } + } + if s.KeySchema != nil { + for i, v := range s.KeySchema { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "KeySchema", i), err.(request.ErrInvalidParams)) + } + } + } + if s.LocalSecondaryIndexes != nil { + for i, v := range s.LocalSecondaryIndexes { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "LocalSecondaryIndexes", i), err.(request.ErrInvalidParams)) + } + } + } + if s.ProvisionedThroughput != nil { + if err := s.ProvisionedThroughput.Validate(); err != nil { + invalidParams.AddNested("ProvisionedThroughput", err.(request.ErrInvalidParams)) + } + } + if s.StreamSpecification != nil { + if err := s.StreamSpecification.Validate(); err != nil { + invalidParams.AddNested("StreamSpecification", err.(request.ErrInvalidParams)) + } + } + if s.Tags != nil { + for i, v := range s.Tags { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Tags", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAttributeDefinitions sets the AttributeDefinitions field's value. +func (s *CreateTableInput) SetAttributeDefinitions(v []*AttributeDefinition) *CreateTableInput { + s.AttributeDefinitions = v + return s +} + +// SetBillingMode sets the BillingMode field's value. +func (s *CreateTableInput) SetBillingMode(v string) *CreateTableInput { + s.BillingMode = &v + return s +} + +// SetGlobalSecondaryIndexes sets the GlobalSecondaryIndexes field's value. +func (s *CreateTableInput) SetGlobalSecondaryIndexes(v []*GlobalSecondaryIndex) *CreateTableInput { + s.GlobalSecondaryIndexes = v + return s +} + +// SetKeySchema sets the KeySchema field's value. +func (s *CreateTableInput) SetKeySchema(v []*KeySchemaElement) *CreateTableInput { + s.KeySchema = v + return s +} + +// SetLocalSecondaryIndexes sets the LocalSecondaryIndexes field's value. +func (s *CreateTableInput) SetLocalSecondaryIndexes(v []*LocalSecondaryIndex) *CreateTableInput { + s.LocalSecondaryIndexes = v + return s +} + +// SetProvisionedThroughput sets the ProvisionedThroughput field's value. +func (s *CreateTableInput) SetProvisionedThroughput(v *ProvisionedThroughput) *CreateTableInput { + s.ProvisionedThroughput = v + return s +} + +// SetSSESpecification sets the SSESpecification field's value. +func (s *CreateTableInput) SetSSESpecification(v *SSESpecification) *CreateTableInput { + s.SSESpecification = v + return s +} + +// SetStreamSpecification sets the StreamSpecification field's value. +func (s *CreateTableInput) SetStreamSpecification(v *StreamSpecification) *CreateTableInput { + s.StreamSpecification = v + return s +} + +// SetTableClass sets the TableClass field's value. +func (s *CreateTableInput) SetTableClass(v string) *CreateTableInput { + s.TableClass = &v + return s +} + +// SetTableName sets the TableName field's value. +func (s *CreateTableInput) SetTableName(v string) *CreateTableInput { + s.TableName = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *CreateTableInput) SetTags(v []*Tag) *CreateTableInput { + s.Tags = v + return s +} + +// Represents the output of a CreateTable operation. +type CreateTableOutput struct { + _ struct{} `type:"structure"` + + // Represents the properties of the table. + TableDescription *TableDescription `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s CreateTableOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s CreateTableOutput) GoString() string { + return s.String() +} + +// SetTableDescription sets the TableDescription field's value. +func (s *CreateTableOutput) SetTableDescription(v *TableDescription) *CreateTableOutput { + s.TableDescription = v + return s +} + +// Represents a request to perform a DeleteItem operation. +type Delete struct { + _ struct{} `type:"structure"` + + // A condition that must be satisfied in order for a conditional delete to succeed. + ConditionExpression *string `type:"string"` + + // One or more substitution tokens for attribute names in an expression. + ExpressionAttributeNames map[string]*string `type:"map"` + + // One or more values that can be substituted in an expression. + ExpressionAttributeValues map[string]*AttributeValue `type:"map"` + + // The primary key of the item to be deleted. Each element consists of an attribute + // name and a value for that attribute. + // + // Key is a required field + Key map[string]*AttributeValue `type:"map" required:"true"` + + // Use ReturnValuesOnConditionCheckFailure to get the item attributes if the + // Delete condition fails. For ReturnValuesOnConditionCheckFailure, the valid + // values are: NONE and ALL_OLD. + ReturnValuesOnConditionCheckFailure *string `type:"string" enum:"ReturnValuesOnConditionCheckFailure"` + + // Name of the table in which the item to be deleted resides. + // + // TableName is a required field + TableName *string `min:"3" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s Delete) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s Delete) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *Delete) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "Delete"} + if s.Key == nil { + invalidParams.Add(request.NewErrParamRequired("Key")) + } + if s.TableName == nil { + invalidParams.Add(request.NewErrParamRequired("TableName")) + } + if s.TableName != nil && len(*s.TableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("TableName", 3)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetConditionExpression sets the ConditionExpression field's value. +func (s *Delete) SetConditionExpression(v string) *Delete { + s.ConditionExpression = &v + return s +} + +// SetExpressionAttributeNames sets the ExpressionAttributeNames field's value. +func (s *Delete) SetExpressionAttributeNames(v map[string]*string) *Delete { + s.ExpressionAttributeNames = v + return s +} + +// SetExpressionAttributeValues sets the ExpressionAttributeValues field's value. +func (s *Delete) SetExpressionAttributeValues(v map[string]*AttributeValue) *Delete { + s.ExpressionAttributeValues = v + return s +} + +// SetKey sets the Key field's value. +func (s *Delete) SetKey(v map[string]*AttributeValue) *Delete { + s.Key = v + return s +} + +// SetReturnValuesOnConditionCheckFailure sets the ReturnValuesOnConditionCheckFailure field's value. +func (s *Delete) SetReturnValuesOnConditionCheckFailure(v string) *Delete { + s.ReturnValuesOnConditionCheckFailure = &v + return s +} + +// SetTableName sets the TableName field's value. +func (s *Delete) SetTableName(v string) *Delete { + s.TableName = &v + return s +} + +type DeleteBackupInput struct { + _ struct{} `type:"structure"` + + // The ARN associated with the backup. + // + // BackupArn is a required field + BackupArn *string `min:"37" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DeleteBackupInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DeleteBackupInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteBackupInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteBackupInput"} + if s.BackupArn == nil { + invalidParams.Add(request.NewErrParamRequired("BackupArn")) + } + if s.BackupArn != nil && len(*s.BackupArn) < 37 { + invalidParams.Add(request.NewErrParamMinLen("BackupArn", 37)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetBackupArn sets the BackupArn field's value. +func (s *DeleteBackupInput) SetBackupArn(v string) *DeleteBackupInput { + s.BackupArn = &v + return s +} + +type DeleteBackupOutput struct { + _ struct{} `type:"structure"` + + // Contains the description of the backup created for the table. + BackupDescription *BackupDescription `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DeleteBackupOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DeleteBackupOutput) GoString() string { + return s.String() +} + +// SetBackupDescription sets the BackupDescription field's value. +func (s *DeleteBackupOutput) SetBackupDescription(v *BackupDescription) *DeleteBackupOutput { + s.BackupDescription = v + return s +} + +// Represents a global secondary index to be deleted from an existing table. +type DeleteGlobalSecondaryIndexAction struct { + _ struct{} `type:"structure"` + + // The name of the global secondary index to be deleted. + // + // IndexName is a required field + IndexName *string `min:"3" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DeleteGlobalSecondaryIndexAction) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DeleteGlobalSecondaryIndexAction) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteGlobalSecondaryIndexAction) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteGlobalSecondaryIndexAction"} + if s.IndexName == nil { + invalidParams.Add(request.NewErrParamRequired("IndexName")) + } + if s.IndexName != nil && len(*s.IndexName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("IndexName", 3)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetIndexName sets the IndexName field's value. +func (s *DeleteGlobalSecondaryIndexAction) SetIndexName(v string) *DeleteGlobalSecondaryIndexAction { + s.IndexName = &v + return s +} + +// Represents the input of a DeleteItem operation. +type DeleteItemInput struct { + _ struct{} `type:"structure"` + + // A condition that must be satisfied in order for a conditional DeleteItem + // to succeed. + // + // An expression can contain any of the following: + // + // * Functions: attribute_exists | attribute_not_exists | attribute_type + // | contains | begins_with | size These function names are case-sensitive. + // + // * Comparison operators: = | <> | < | > | <= | >= | BETWEEN | IN + // + // * Logical operators: AND | OR | NOT + // + // For more information about condition expressions, see Condition Expressions + // (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.SpecifyingConditions.html) + // in the Amazon DynamoDB Developer Guide. + ConditionExpression *string `type:"string"` + + // This is a legacy parameter. Use ConditionExpression instead. For more information, + // see ConditionalOperator (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.ConditionalOperator.html) + // in the Amazon DynamoDB Developer Guide. + ConditionalOperator *string `type:"string" enum:"ConditionalOperator"` + + // This is a legacy parameter. Use ConditionExpression instead. For more information, + // see Expected (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.Expected.html) + // in the Amazon DynamoDB Developer Guide. + Expected map[string]*ExpectedAttributeValue `type:"map"` + + // One or more substitution tokens for attribute names in an expression. The + // following are some use cases for using ExpressionAttributeNames: + // + // * To access an attribute whose name conflicts with a DynamoDB reserved + // word. + // + // * To create a placeholder for repeating occurrences of an attribute name + // in an expression. + // + // * To prevent special characters in an attribute name from being misinterpreted + // in an expression. + // + // Use the # character in an expression to dereference an attribute name. For + // example, consider the following attribute name: + // + // * Percentile + // + // The name of this attribute conflicts with a reserved word, so it cannot be + // used directly in an expression. (For the complete list of reserved words, + // see Reserved Words (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html) + // in the Amazon DynamoDB Developer Guide). To work around this, you could specify + // the following for ExpressionAttributeNames: + // + // * {"#P":"Percentile"} + // + // You could then use this substitution in an expression, as in this example: + // + // * #P = :val + // + // Tokens that begin with the : character are expression attribute values, which + // are placeholders for the actual value at runtime. + // + // For more information on expression attribute names, see Specifying Item Attributes + // (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.AccessingItemAttributes.html) + // in the Amazon DynamoDB Developer Guide. + ExpressionAttributeNames map[string]*string `type:"map"` + + // One or more values that can be substituted in an expression. + // + // Use the : (colon) character in an expression to dereference an attribute + // value. For example, suppose that you wanted to check whether the value of + // the ProductStatus attribute was one of the following: + // + // Available | Backordered | Discontinued + // + // You would first need to specify ExpressionAttributeValues as follows: + // + // { ":avail":{"S":"Available"}, ":back":{"S":"Backordered"}, ":disc":{"S":"Discontinued"} + // } + // + // You could then use these values in an expression, such as this: + // + // ProductStatus IN (:avail, :back, :disc) + // + // For more information on expression attribute values, see Condition Expressions + // (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.SpecifyingConditions.html) + // in the Amazon DynamoDB Developer Guide. + ExpressionAttributeValues map[string]*AttributeValue `type:"map"` + + // A map of attribute names to AttributeValue objects, representing the primary + // key of the item to delete. + // + // For the primary key, you must provide all of the attributes. For example, + // with a simple primary key, you only need to provide a value for the partition + // key. For a composite primary key, you must provide values for both the partition + // key and the sort key. + // + // Key is a required field + Key map[string]*AttributeValue `type:"map" required:"true"` + + // Determines the level of detail about either provisioned or on-demand throughput + // consumption that is returned in the response: + // + // * INDEXES - The response includes the aggregate ConsumedCapacity for the + // operation, together with ConsumedCapacity for each table and secondary + // index that was accessed. Note that some operations, such as GetItem and + // BatchGetItem, do not access any indexes at all. In these cases, specifying + // INDEXES will only return ConsumedCapacity information for table(s). + // + // * TOTAL - The response includes only the aggregate ConsumedCapacity for + // the operation. + // + // * NONE - No ConsumedCapacity details are included in the response. + ReturnConsumedCapacity *string `type:"string" enum:"ReturnConsumedCapacity"` + + // Determines whether item collection metrics are returned. If set to SIZE, + // the response includes statistics about item collections, if any, that were + // modified during the operation are returned in the response. If set to NONE + // (the default), no statistics are returned. + ReturnItemCollectionMetrics *string `type:"string" enum:"ReturnItemCollectionMetrics"` + + // Use ReturnValues if you want to get the item attributes as they appeared + // before they were deleted. For DeleteItem, the valid values are: + // + // * NONE - If ReturnValues is not specified, or if its value is NONE, then + // nothing is returned. (This setting is the default for ReturnValues.) + // + // * ALL_OLD - The content of the old item is returned. + // + // The ReturnValues parameter is used by several DynamoDB operations; however, + // DeleteItem does not recognize any values other than NONE or ALL_OLD. + ReturnValues *string `type:"string" enum:"ReturnValue"` + + // The name of the table from which to delete the item. + // + // TableName is a required field + TableName *string `min:"3" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DeleteItemInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DeleteItemInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteItemInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteItemInput"} + if s.Key == nil { + invalidParams.Add(request.NewErrParamRequired("Key")) + } + if s.TableName == nil { + invalidParams.Add(request.NewErrParamRequired("TableName")) + } + if s.TableName != nil && len(*s.TableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("TableName", 3)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetConditionExpression sets the ConditionExpression field's value. +func (s *DeleteItemInput) SetConditionExpression(v string) *DeleteItemInput { + s.ConditionExpression = &v + return s +} + +// SetConditionalOperator sets the ConditionalOperator field's value. +func (s *DeleteItemInput) SetConditionalOperator(v string) *DeleteItemInput { + s.ConditionalOperator = &v + return s +} + +// SetExpected sets the Expected field's value. +func (s *DeleteItemInput) SetExpected(v map[string]*ExpectedAttributeValue) *DeleteItemInput { + s.Expected = v + return s +} + +// SetExpressionAttributeNames sets the ExpressionAttributeNames field's value. +func (s *DeleteItemInput) SetExpressionAttributeNames(v map[string]*string) *DeleteItemInput { + s.ExpressionAttributeNames = v + return s +} + +// SetExpressionAttributeValues sets the ExpressionAttributeValues field's value. +func (s *DeleteItemInput) SetExpressionAttributeValues(v map[string]*AttributeValue) *DeleteItemInput { + s.ExpressionAttributeValues = v + return s +} + +// SetKey sets the Key field's value. +func (s *DeleteItemInput) SetKey(v map[string]*AttributeValue) *DeleteItemInput { + s.Key = v + return s +} + +// SetReturnConsumedCapacity sets the ReturnConsumedCapacity field's value. +func (s *DeleteItemInput) SetReturnConsumedCapacity(v string) *DeleteItemInput { + s.ReturnConsumedCapacity = &v + return s +} + +// SetReturnItemCollectionMetrics sets the ReturnItemCollectionMetrics field's value. +func (s *DeleteItemInput) SetReturnItemCollectionMetrics(v string) *DeleteItemInput { + s.ReturnItemCollectionMetrics = &v + return s +} + +// SetReturnValues sets the ReturnValues field's value. +func (s *DeleteItemInput) SetReturnValues(v string) *DeleteItemInput { + s.ReturnValues = &v + return s +} + +// SetTableName sets the TableName field's value. +func (s *DeleteItemInput) SetTableName(v string) *DeleteItemInput { + s.TableName = &v + return s +} + +// Represents the output of a DeleteItem operation. +type DeleteItemOutput struct { + _ struct{} `type:"structure"` + + // A map of attribute names to AttributeValue objects, representing the item + // as it appeared before the DeleteItem operation. This map appears in the response + // only if ReturnValues was specified as ALL_OLD in the request. + Attributes map[string]*AttributeValue `type:"map"` + + // The capacity units consumed by the DeleteItem operation. The data returned + // includes the total provisioned throughput consumed, along with statistics + // for the table and any indexes involved in the operation. ConsumedCapacity + // is only returned if the ReturnConsumedCapacity parameter was specified. For + // more information, see Provisioned Mode (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ProvisionedThroughputIntro.html) + // in the Amazon DynamoDB Developer Guide. + ConsumedCapacity *ConsumedCapacity `type:"structure"` + + // Information about item collections, if any, that were affected by the DeleteItem + // operation. ItemCollectionMetrics is only returned if the ReturnItemCollectionMetrics + // parameter was specified. If the table does not have any local secondary indexes, + // this information is not returned in the response. + // + // Each ItemCollectionMetrics element consists of: + // + // * ItemCollectionKey - The partition key value of the item collection. + // This is the same as the partition key value of the item itself. + // + // * SizeEstimateRangeGB - An estimate of item collection size, in gigabytes. + // This value is a two-element array containing a lower bound and an upper + // bound for the estimate. The estimate includes the size of all the items + // in the table, plus the size of all attributes projected into all of the + // local secondary indexes on that table. Use this estimate to measure whether + // a local secondary index is approaching its size limit. The estimate is + // subject to change over time; therefore, do not rely on the precision or + // accuracy of the estimate. + ItemCollectionMetrics *ItemCollectionMetrics `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DeleteItemOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DeleteItemOutput) GoString() string { + return s.String() +} + +// SetAttributes sets the Attributes field's value. +func (s *DeleteItemOutput) SetAttributes(v map[string]*AttributeValue) *DeleteItemOutput { + s.Attributes = v + return s +} + +// SetConsumedCapacity sets the ConsumedCapacity field's value. +func (s *DeleteItemOutput) SetConsumedCapacity(v *ConsumedCapacity) *DeleteItemOutput { + s.ConsumedCapacity = v + return s +} + +// SetItemCollectionMetrics sets the ItemCollectionMetrics field's value. +func (s *DeleteItemOutput) SetItemCollectionMetrics(v *ItemCollectionMetrics) *DeleteItemOutput { + s.ItemCollectionMetrics = v + return s +} + +// Represents a replica to be removed. +type DeleteReplicaAction struct { + _ struct{} `type:"structure"` + + // The Region of the replica to be removed. + // + // RegionName is a required field + RegionName *string `type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DeleteReplicaAction) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DeleteReplicaAction) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteReplicaAction) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteReplicaAction"} + if s.RegionName == nil { + invalidParams.Add(request.NewErrParamRequired("RegionName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetRegionName sets the RegionName field's value. +func (s *DeleteReplicaAction) SetRegionName(v string) *DeleteReplicaAction { + s.RegionName = &v + return s +} + +// Represents a replica to be deleted. +type DeleteReplicationGroupMemberAction struct { + _ struct{} `type:"structure"` + + // The Region where the replica exists. + // + // RegionName is a required field + RegionName *string `type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DeleteReplicationGroupMemberAction) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DeleteReplicationGroupMemberAction) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteReplicationGroupMemberAction) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteReplicationGroupMemberAction"} + if s.RegionName == nil { + invalidParams.Add(request.NewErrParamRequired("RegionName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetRegionName sets the RegionName field's value. +func (s *DeleteReplicationGroupMemberAction) SetRegionName(v string) *DeleteReplicationGroupMemberAction { + s.RegionName = &v + return s +} + +// Represents a request to perform a DeleteItem operation on an item. +type DeleteRequest struct { + _ struct{} `type:"structure"` + + // A map of attribute name to attribute values, representing the primary key + // of the item to delete. All of the table's primary key attributes must be + // specified, and their data types must match those of the table's key schema. + // + // Key is a required field + Key map[string]*AttributeValue `type:"map" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DeleteRequest) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DeleteRequest) GoString() string { + return s.String() +} + +// SetKey sets the Key field's value. +func (s *DeleteRequest) SetKey(v map[string]*AttributeValue) *DeleteRequest { + s.Key = v + return s +} + +// Represents the input of a DeleteTable operation. +type DeleteTableInput struct { + _ struct{} `type:"structure"` + + // The name of the table to delete. + // + // TableName is a required field + TableName *string `min:"3" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DeleteTableInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DeleteTableInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteTableInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteTableInput"} + if s.TableName == nil { + invalidParams.Add(request.NewErrParamRequired("TableName")) + } + if s.TableName != nil && len(*s.TableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("TableName", 3)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetTableName sets the TableName field's value. +func (s *DeleteTableInput) SetTableName(v string) *DeleteTableInput { + s.TableName = &v + return s +} + +// Represents the output of a DeleteTable operation. +type DeleteTableOutput struct { + _ struct{} `type:"structure"` + + // Represents the properties of a table. + TableDescription *TableDescription `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DeleteTableOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DeleteTableOutput) GoString() string { + return s.String() +} + +// SetTableDescription sets the TableDescription field's value. +func (s *DeleteTableOutput) SetTableDescription(v *TableDescription) *DeleteTableOutput { + s.TableDescription = v + return s +} + +type DescribeBackupInput struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) associated with the backup. + // + // BackupArn is a required field + BackupArn *string `min:"37" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeBackupInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeBackupInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeBackupInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeBackupInput"} + if s.BackupArn == nil { + invalidParams.Add(request.NewErrParamRequired("BackupArn")) + } + if s.BackupArn != nil && len(*s.BackupArn) < 37 { + invalidParams.Add(request.NewErrParamMinLen("BackupArn", 37)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetBackupArn sets the BackupArn field's value. +func (s *DescribeBackupInput) SetBackupArn(v string) *DescribeBackupInput { + s.BackupArn = &v + return s +} + +type DescribeBackupOutput struct { + _ struct{} `type:"structure"` + + // Contains the description of the backup created for the table. + BackupDescription *BackupDescription `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeBackupOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeBackupOutput) GoString() string { + return s.String() +} + +// SetBackupDescription sets the BackupDescription field's value. +func (s *DescribeBackupOutput) SetBackupDescription(v *BackupDescription) *DescribeBackupOutput { + s.BackupDescription = v + return s +} + +type DescribeContinuousBackupsInput struct { + _ struct{} `type:"structure"` + + // Name of the table for which the customer wants to check the continuous backups + // and point in time recovery settings. + // + // TableName is a required field + TableName *string `min:"3" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeContinuousBackupsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeContinuousBackupsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeContinuousBackupsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeContinuousBackupsInput"} + if s.TableName == nil { + invalidParams.Add(request.NewErrParamRequired("TableName")) + } + if s.TableName != nil && len(*s.TableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("TableName", 3)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetTableName sets the TableName field's value. +func (s *DescribeContinuousBackupsInput) SetTableName(v string) *DescribeContinuousBackupsInput { + s.TableName = &v + return s +} + +type DescribeContinuousBackupsOutput struct { + _ struct{} `type:"structure"` + + // Represents the continuous backups and point in time recovery settings on + // the table. + ContinuousBackupsDescription *ContinuousBackupsDescription `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeContinuousBackupsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeContinuousBackupsOutput) GoString() string { + return s.String() +} + +// SetContinuousBackupsDescription sets the ContinuousBackupsDescription field's value. +func (s *DescribeContinuousBackupsOutput) SetContinuousBackupsDescription(v *ContinuousBackupsDescription) *DescribeContinuousBackupsOutput { + s.ContinuousBackupsDescription = v + return s +} + +type DescribeContributorInsightsInput struct { + _ struct{} `type:"structure"` + + // The name of the global secondary index to describe, if applicable. + IndexName *string `min:"3" type:"string"` + + // The name of the table to describe. + // + // TableName is a required field + TableName *string `min:"3" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeContributorInsightsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeContributorInsightsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeContributorInsightsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeContributorInsightsInput"} + if s.IndexName != nil && len(*s.IndexName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("IndexName", 3)) + } + if s.TableName == nil { + invalidParams.Add(request.NewErrParamRequired("TableName")) + } + if s.TableName != nil && len(*s.TableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("TableName", 3)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetIndexName sets the IndexName field's value. +func (s *DescribeContributorInsightsInput) SetIndexName(v string) *DescribeContributorInsightsInput { + s.IndexName = &v + return s +} + +// SetTableName sets the TableName field's value. +func (s *DescribeContributorInsightsInput) SetTableName(v string) *DescribeContributorInsightsInput { + s.TableName = &v + return s +} + +type DescribeContributorInsightsOutput struct { + _ struct{} `type:"structure"` + + // List of names of the associated contributor insights rules. + ContributorInsightsRuleList []*string `type:"list"` + + // Current status of contributor insights. + ContributorInsightsStatus *string `type:"string" enum:"ContributorInsightsStatus"` + + // Returns information about the last failure that was encountered. + // + // The most common exceptions for a FAILED status are: + // + // * LimitExceededException - Per-account Amazon CloudWatch Contributor Insights + // rule limit reached. Please disable Contributor Insights for other tables/indexes + // OR disable Contributor Insights rules before retrying. + // + // * AccessDeniedException - Amazon CloudWatch Contributor Insights rules + // cannot be modified due to insufficient permissions. + // + // * AccessDeniedException - Failed to create service-linked role for Contributor + // Insights due to insufficient permissions. + // + // * InternalServerError - Failed to create Amazon CloudWatch Contributor + // Insights rules. Please retry request. + FailureException *FailureException `type:"structure"` + + // The name of the global secondary index being described. + IndexName *string `min:"3" type:"string"` + + // Timestamp of the last time the status was changed. + LastUpdateDateTime *time.Time `type:"timestamp"` + + // The name of the table being described. + TableName *string `min:"3" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeContributorInsightsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeContributorInsightsOutput) GoString() string { + return s.String() +} + +// SetContributorInsightsRuleList sets the ContributorInsightsRuleList field's value. +func (s *DescribeContributorInsightsOutput) SetContributorInsightsRuleList(v []*string) *DescribeContributorInsightsOutput { + s.ContributorInsightsRuleList = v + return s +} + +// SetContributorInsightsStatus sets the ContributorInsightsStatus field's value. +func (s *DescribeContributorInsightsOutput) SetContributorInsightsStatus(v string) *DescribeContributorInsightsOutput { + s.ContributorInsightsStatus = &v + return s +} + +// SetFailureException sets the FailureException field's value. +func (s *DescribeContributorInsightsOutput) SetFailureException(v *FailureException) *DescribeContributorInsightsOutput { + s.FailureException = v + return s +} + +// SetIndexName sets the IndexName field's value. +func (s *DescribeContributorInsightsOutput) SetIndexName(v string) *DescribeContributorInsightsOutput { + s.IndexName = &v + return s +} + +// SetLastUpdateDateTime sets the LastUpdateDateTime field's value. +func (s *DescribeContributorInsightsOutput) SetLastUpdateDateTime(v time.Time) *DescribeContributorInsightsOutput { + s.LastUpdateDateTime = &v + return s +} + +// SetTableName sets the TableName field's value. +func (s *DescribeContributorInsightsOutput) SetTableName(v string) *DescribeContributorInsightsOutput { + s.TableName = &v + return s +} + +type DescribeEndpointsInput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeEndpointsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeEndpointsInput) GoString() string { + return s.String() +} + +type DescribeEndpointsOutput struct { + _ struct{} `type:"structure"` + + // List of endpoints. + // + // Endpoints is a required field + Endpoints []*Endpoint `type:"list" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeEndpointsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeEndpointsOutput) GoString() string { + return s.String() +} + +// SetEndpoints sets the Endpoints field's value. +func (s *DescribeEndpointsOutput) SetEndpoints(v []*Endpoint) *DescribeEndpointsOutput { + s.Endpoints = v + return s +} + +type DescribeExportInput struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) associated with the export. + // + // ExportArn is a required field + ExportArn *string `min:"37" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeExportInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeExportInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeExportInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeExportInput"} + if s.ExportArn == nil { + invalidParams.Add(request.NewErrParamRequired("ExportArn")) + } + if s.ExportArn != nil && len(*s.ExportArn) < 37 { + invalidParams.Add(request.NewErrParamMinLen("ExportArn", 37)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetExportArn sets the ExportArn field's value. +func (s *DescribeExportInput) SetExportArn(v string) *DescribeExportInput { + s.ExportArn = &v + return s +} + +type DescribeExportOutput struct { + _ struct{} `type:"structure"` + + // Represents the properties of the export. + ExportDescription *ExportDescription `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeExportOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeExportOutput) GoString() string { + return s.String() +} + +// SetExportDescription sets the ExportDescription field's value. +func (s *DescribeExportOutput) SetExportDescription(v *ExportDescription) *DescribeExportOutput { + s.ExportDescription = v + return s +} + +type DescribeGlobalTableInput struct { + _ struct{} `type:"structure"` + + // The name of the global table. + // + // GlobalTableName is a required field + GlobalTableName *string `min:"3" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeGlobalTableInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeGlobalTableInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeGlobalTableInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeGlobalTableInput"} + if s.GlobalTableName == nil { + invalidParams.Add(request.NewErrParamRequired("GlobalTableName")) + } + if s.GlobalTableName != nil && len(*s.GlobalTableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("GlobalTableName", 3)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetGlobalTableName sets the GlobalTableName field's value. +func (s *DescribeGlobalTableInput) SetGlobalTableName(v string) *DescribeGlobalTableInput { + s.GlobalTableName = &v + return s +} + +type DescribeGlobalTableOutput struct { + _ struct{} `type:"structure"` + + // Contains the details of the global table. + GlobalTableDescription *GlobalTableDescription `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeGlobalTableOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeGlobalTableOutput) GoString() string { + return s.String() +} + +// SetGlobalTableDescription sets the GlobalTableDescription field's value. +func (s *DescribeGlobalTableOutput) SetGlobalTableDescription(v *GlobalTableDescription) *DescribeGlobalTableOutput { + s.GlobalTableDescription = v + return s +} + +type DescribeGlobalTableSettingsInput struct { + _ struct{} `type:"structure"` + + // The name of the global table to describe. + // + // GlobalTableName is a required field + GlobalTableName *string `min:"3" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeGlobalTableSettingsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeGlobalTableSettingsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeGlobalTableSettingsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeGlobalTableSettingsInput"} + if s.GlobalTableName == nil { + invalidParams.Add(request.NewErrParamRequired("GlobalTableName")) + } + if s.GlobalTableName != nil && len(*s.GlobalTableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("GlobalTableName", 3)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetGlobalTableName sets the GlobalTableName field's value. +func (s *DescribeGlobalTableSettingsInput) SetGlobalTableName(v string) *DescribeGlobalTableSettingsInput { + s.GlobalTableName = &v + return s +} + +type DescribeGlobalTableSettingsOutput struct { + _ struct{} `type:"structure"` + + // The name of the global table. + GlobalTableName *string `min:"3" type:"string"` + + // The Region-specific settings for the global table. + ReplicaSettings []*ReplicaSettingsDescription `type:"list"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeGlobalTableSettingsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeGlobalTableSettingsOutput) GoString() string { + return s.String() +} + +// SetGlobalTableName sets the GlobalTableName field's value. +func (s *DescribeGlobalTableSettingsOutput) SetGlobalTableName(v string) *DescribeGlobalTableSettingsOutput { + s.GlobalTableName = &v + return s +} + +// SetReplicaSettings sets the ReplicaSettings field's value. +func (s *DescribeGlobalTableSettingsOutput) SetReplicaSettings(v []*ReplicaSettingsDescription) *DescribeGlobalTableSettingsOutput { + s.ReplicaSettings = v + return s +} + +type DescribeKinesisStreamingDestinationInput struct { + _ struct{} `type:"structure"` + + // The name of the table being described. + // + // TableName is a required field + TableName *string `min:"3" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeKinesisStreamingDestinationInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeKinesisStreamingDestinationInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeKinesisStreamingDestinationInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeKinesisStreamingDestinationInput"} + if s.TableName == nil { + invalidParams.Add(request.NewErrParamRequired("TableName")) + } + if s.TableName != nil && len(*s.TableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("TableName", 3)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetTableName sets the TableName field's value. +func (s *DescribeKinesisStreamingDestinationInput) SetTableName(v string) *DescribeKinesisStreamingDestinationInput { + s.TableName = &v + return s +} + +type DescribeKinesisStreamingDestinationOutput struct { + _ struct{} `type:"structure"` + + // The list of replica structures for the table being described. + KinesisDataStreamDestinations []*KinesisDataStreamDestination `type:"list"` + + // The name of the table being described. + TableName *string `min:"3" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeKinesisStreamingDestinationOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeKinesisStreamingDestinationOutput) GoString() string { + return s.String() +} + +// SetKinesisDataStreamDestinations sets the KinesisDataStreamDestinations field's value. +func (s *DescribeKinesisStreamingDestinationOutput) SetKinesisDataStreamDestinations(v []*KinesisDataStreamDestination) *DescribeKinesisStreamingDestinationOutput { + s.KinesisDataStreamDestinations = v + return s +} + +// SetTableName sets the TableName field's value. +func (s *DescribeKinesisStreamingDestinationOutput) SetTableName(v string) *DescribeKinesisStreamingDestinationOutput { + s.TableName = &v + return s +} + +// Represents the input of a DescribeLimits operation. Has no content. +type DescribeLimitsInput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeLimitsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeLimitsInput) GoString() string { + return s.String() +} + +// Represents the output of a DescribeLimits operation. +type DescribeLimitsOutput struct { + _ struct{} `type:"structure"` + + // The maximum total read capacity units that your account allows you to provision + // across all of your tables in this Region. + AccountMaxReadCapacityUnits *int64 `min:"1" type:"long"` + + // The maximum total write capacity units that your account allows you to provision + // across all of your tables in this Region. + AccountMaxWriteCapacityUnits *int64 `min:"1" type:"long"` + + // The maximum read capacity units that your account allows you to provision + // for a new table that you are creating in this Region, including the read + // capacity units provisioned for its global secondary indexes (GSIs). + TableMaxReadCapacityUnits *int64 `min:"1" type:"long"` + + // The maximum write capacity units that your account allows you to provision + // for a new table that you are creating in this Region, including the write + // capacity units provisioned for its global secondary indexes (GSIs). + TableMaxWriteCapacityUnits *int64 `min:"1" type:"long"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeLimitsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeLimitsOutput) GoString() string { + return s.String() +} + +// SetAccountMaxReadCapacityUnits sets the AccountMaxReadCapacityUnits field's value. +func (s *DescribeLimitsOutput) SetAccountMaxReadCapacityUnits(v int64) *DescribeLimitsOutput { + s.AccountMaxReadCapacityUnits = &v + return s +} + +// SetAccountMaxWriteCapacityUnits sets the AccountMaxWriteCapacityUnits field's value. +func (s *DescribeLimitsOutput) SetAccountMaxWriteCapacityUnits(v int64) *DescribeLimitsOutput { + s.AccountMaxWriteCapacityUnits = &v + return s +} + +// SetTableMaxReadCapacityUnits sets the TableMaxReadCapacityUnits field's value. +func (s *DescribeLimitsOutput) SetTableMaxReadCapacityUnits(v int64) *DescribeLimitsOutput { + s.TableMaxReadCapacityUnits = &v + return s +} + +// SetTableMaxWriteCapacityUnits sets the TableMaxWriteCapacityUnits field's value. +func (s *DescribeLimitsOutput) SetTableMaxWriteCapacityUnits(v int64) *DescribeLimitsOutput { + s.TableMaxWriteCapacityUnits = &v + return s +} + +// Represents the input of a DescribeTable operation. +type DescribeTableInput struct { + _ struct{} `type:"structure"` + + // The name of the table to describe. + // + // TableName is a required field + TableName *string `min:"3" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeTableInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeTableInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeTableInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeTableInput"} + if s.TableName == nil { + invalidParams.Add(request.NewErrParamRequired("TableName")) + } + if s.TableName != nil && len(*s.TableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("TableName", 3)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetTableName sets the TableName field's value. +func (s *DescribeTableInput) SetTableName(v string) *DescribeTableInput { + s.TableName = &v + return s +} + +// Represents the output of a DescribeTable operation. +type DescribeTableOutput struct { + _ struct{} `type:"structure"` + + // The properties of the table. + Table *TableDescription `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeTableOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeTableOutput) GoString() string { + return s.String() +} + +// SetTable sets the Table field's value. +func (s *DescribeTableOutput) SetTable(v *TableDescription) *DescribeTableOutput { + s.Table = v + return s +} + +type DescribeTableReplicaAutoScalingInput struct { + _ struct{} `type:"structure"` + + // The name of the table. + // + // TableName is a required field + TableName *string `min:"3" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeTableReplicaAutoScalingInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeTableReplicaAutoScalingInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeTableReplicaAutoScalingInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeTableReplicaAutoScalingInput"} + if s.TableName == nil { + invalidParams.Add(request.NewErrParamRequired("TableName")) + } + if s.TableName != nil && len(*s.TableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("TableName", 3)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetTableName sets the TableName field's value. +func (s *DescribeTableReplicaAutoScalingInput) SetTableName(v string) *DescribeTableReplicaAutoScalingInput { + s.TableName = &v + return s +} + +type DescribeTableReplicaAutoScalingOutput struct { + _ struct{} `type:"structure"` + + // Represents the auto scaling properties of the table. + TableAutoScalingDescription *TableAutoScalingDescription `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeTableReplicaAutoScalingOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeTableReplicaAutoScalingOutput) GoString() string { + return s.String() +} + +// SetTableAutoScalingDescription sets the TableAutoScalingDescription field's value. +func (s *DescribeTableReplicaAutoScalingOutput) SetTableAutoScalingDescription(v *TableAutoScalingDescription) *DescribeTableReplicaAutoScalingOutput { + s.TableAutoScalingDescription = v + return s +} + +type DescribeTimeToLiveInput struct { + _ struct{} `type:"structure"` + + // The name of the table to be described. + // + // TableName is a required field + TableName *string `min:"3" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeTimeToLiveInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeTimeToLiveInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeTimeToLiveInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeTimeToLiveInput"} + if s.TableName == nil { + invalidParams.Add(request.NewErrParamRequired("TableName")) + } + if s.TableName != nil && len(*s.TableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("TableName", 3)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetTableName sets the TableName field's value. +func (s *DescribeTimeToLiveInput) SetTableName(v string) *DescribeTimeToLiveInput { + s.TableName = &v + return s +} + +type DescribeTimeToLiveOutput struct { + _ struct{} `type:"structure"` + + // The description of the Time to Live (TTL) status on the specified table. + TimeToLiveDescription *TimeToLiveDescription `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeTimeToLiveOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DescribeTimeToLiveOutput) GoString() string { + return s.String() +} + +// SetTimeToLiveDescription sets the TimeToLiveDescription field's value. +func (s *DescribeTimeToLiveOutput) SetTimeToLiveDescription(v *TimeToLiveDescription) *DescribeTimeToLiveOutput { + s.TimeToLiveDescription = v + return s +} + +type DisableKinesisStreamingDestinationInput struct { + _ struct{} `type:"structure"` + + // The ARN for a Kinesis data stream. + // + // StreamArn is a required field + StreamArn *string `min:"37" type:"string" required:"true"` + + // The name of the DynamoDB table. + // + // TableName is a required field + TableName *string `min:"3" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DisableKinesisStreamingDestinationInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DisableKinesisStreamingDestinationInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DisableKinesisStreamingDestinationInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DisableKinesisStreamingDestinationInput"} + if s.StreamArn == nil { + invalidParams.Add(request.NewErrParamRequired("StreamArn")) + } + if s.StreamArn != nil && len(*s.StreamArn) < 37 { + invalidParams.Add(request.NewErrParamMinLen("StreamArn", 37)) + } + if s.TableName == nil { + invalidParams.Add(request.NewErrParamRequired("TableName")) + } + if s.TableName != nil && len(*s.TableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("TableName", 3)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetStreamArn sets the StreamArn field's value. +func (s *DisableKinesisStreamingDestinationInput) SetStreamArn(v string) *DisableKinesisStreamingDestinationInput { + s.StreamArn = &v + return s +} + +// SetTableName sets the TableName field's value. +func (s *DisableKinesisStreamingDestinationInput) SetTableName(v string) *DisableKinesisStreamingDestinationInput { + s.TableName = &v + return s +} + +type DisableKinesisStreamingDestinationOutput struct { + _ struct{} `type:"structure"` + + // The current status of the replication. + DestinationStatus *string `type:"string" enum:"DestinationStatus"` + + // The ARN for the specific Kinesis data stream. + StreamArn *string `min:"37" type:"string"` + + // The name of the table being modified. + TableName *string `min:"3" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DisableKinesisStreamingDestinationOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DisableKinesisStreamingDestinationOutput) GoString() string { + return s.String() +} + +// SetDestinationStatus sets the DestinationStatus field's value. +func (s *DisableKinesisStreamingDestinationOutput) SetDestinationStatus(v string) *DisableKinesisStreamingDestinationOutput { + s.DestinationStatus = &v + return s +} + +// SetStreamArn sets the StreamArn field's value. +func (s *DisableKinesisStreamingDestinationOutput) SetStreamArn(v string) *DisableKinesisStreamingDestinationOutput { + s.StreamArn = &v + return s +} + +// SetTableName sets the TableName field's value. +func (s *DisableKinesisStreamingDestinationOutput) SetTableName(v string) *DisableKinesisStreamingDestinationOutput { + s.TableName = &v + return s +} + +// There was an attempt to insert an item with the same primary key as an item +// that already exists in the DynamoDB table. +type DuplicateItemException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + Message_ *string `locationName:"message" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DuplicateItemException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s DuplicateItemException) GoString() string { + return s.String() +} + +func newErrorDuplicateItemException(v protocol.ResponseMetadata) error { + return &DuplicateItemException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *DuplicateItemException) Code() string { + return "DuplicateItemException" +} + +// Message returns the exception's message. +func (s *DuplicateItemException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *DuplicateItemException) OrigErr() error { + return nil +} + +func (s *DuplicateItemException) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *DuplicateItemException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *DuplicateItemException) RequestID() string { + return s.RespMetadata.RequestID +} + +type EnableKinesisStreamingDestinationInput struct { + _ struct{} `type:"structure"` + + // The ARN for a Kinesis data stream. + // + // StreamArn is a required field + StreamArn *string `min:"37" type:"string" required:"true"` + + // The name of the DynamoDB table. + // + // TableName is a required field + TableName *string `min:"3" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s EnableKinesisStreamingDestinationInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s EnableKinesisStreamingDestinationInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *EnableKinesisStreamingDestinationInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "EnableKinesisStreamingDestinationInput"} + if s.StreamArn == nil { + invalidParams.Add(request.NewErrParamRequired("StreamArn")) + } + if s.StreamArn != nil && len(*s.StreamArn) < 37 { + invalidParams.Add(request.NewErrParamMinLen("StreamArn", 37)) + } + if s.TableName == nil { + invalidParams.Add(request.NewErrParamRequired("TableName")) + } + if s.TableName != nil && len(*s.TableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("TableName", 3)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetStreamArn sets the StreamArn field's value. +func (s *EnableKinesisStreamingDestinationInput) SetStreamArn(v string) *EnableKinesisStreamingDestinationInput { + s.StreamArn = &v + return s +} + +// SetTableName sets the TableName field's value. +func (s *EnableKinesisStreamingDestinationInput) SetTableName(v string) *EnableKinesisStreamingDestinationInput { + s.TableName = &v + return s +} + +type EnableKinesisStreamingDestinationOutput struct { + _ struct{} `type:"structure"` + + // The current status of the replication. + DestinationStatus *string `type:"string" enum:"DestinationStatus"` + + // The ARN for the specific Kinesis data stream. + StreamArn *string `min:"37" type:"string"` + + // The name of the table being modified. + TableName *string `min:"3" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s EnableKinesisStreamingDestinationOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s EnableKinesisStreamingDestinationOutput) GoString() string { + return s.String() +} + +// SetDestinationStatus sets the DestinationStatus field's value. +func (s *EnableKinesisStreamingDestinationOutput) SetDestinationStatus(v string) *EnableKinesisStreamingDestinationOutput { + s.DestinationStatus = &v + return s +} + +// SetStreamArn sets the StreamArn field's value. +func (s *EnableKinesisStreamingDestinationOutput) SetStreamArn(v string) *EnableKinesisStreamingDestinationOutput { + s.StreamArn = &v + return s +} + +// SetTableName sets the TableName field's value. +func (s *EnableKinesisStreamingDestinationOutput) SetTableName(v string) *EnableKinesisStreamingDestinationOutput { + s.TableName = &v + return s +} + +// An endpoint information details. +type Endpoint struct { + _ struct{} `type:"structure"` + + // IP address of the endpoint. + // + // Address is a required field + Address *string `type:"string" required:"true"` + + // Endpoint cache time to live (TTL) value. + // + // CachePeriodInMinutes is a required field + CachePeriodInMinutes *int64 `type:"long" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s Endpoint) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s Endpoint) GoString() string { + return s.String() +} + +// SetAddress sets the Address field's value. +func (s *Endpoint) SetAddress(v string) *Endpoint { + s.Address = &v + return s +} + +// SetCachePeriodInMinutes sets the CachePeriodInMinutes field's value. +func (s *Endpoint) SetCachePeriodInMinutes(v int64) *Endpoint { + s.CachePeriodInMinutes = &v + return s +} + +type ExecuteStatementInput struct { + _ struct{} `type:"structure"` + + // The consistency of a read operation. If set to true, then a strongly consistent + // read is used; otherwise, an eventually consistent read is used. + ConsistentRead *bool `type:"boolean"` + + // Set this value to get remaining results, if NextToken was returned in the + // statement response. + NextToken *string `min:"1" type:"string"` + + // The parameters for the PartiQL statement, if any. + Parameters []*AttributeValue `min:"1" type:"list"` + + // Determines the level of detail about either provisioned or on-demand throughput + // consumption that is returned in the response: + // + // * INDEXES - The response includes the aggregate ConsumedCapacity for the + // operation, together with ConsumedCapacity for each table and secondary + // index that was accessed. Note that some operations, such as GetItem and + // BatchGetItem, do not access any indexes at all. In these cases, specifying + // INDEXES will only return ConsumedCapacity information for table(s). + // + // * TOTAL - The response includes only the aggregate ConsumedCapacity for + // the operation. + // + // * NONE - No ConsumedCapacity details are included in the response. + ReturnConsumedCapacity *string `type:"string" enum:"ReturnConsumedCapacity"` + + // The PartiQL statement representing the operation to run. + // + // Statement is a required field + Statement *string `min:"1" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ExecuteStatementInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ExecuteStatementInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ExecuteStatementInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ExecuteStatementInput"} + if s.NextToken != nil && len(*s.NextToken) < 1 { + invalidParams.Add(request.NewErrParamMinLen("NextToken", 1)) + } + if s.Parameters != nil && len(s.Parameters) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Parameters", 1)) + } + if s.Statement == nil { + invalidParams.Add(request.NewErrParamRequired("Statement")) + } + if s.Statement != nil && len(*s.Statement) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Statement", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetConsistentRead sets the ConsistentRead field's value. +func (s *ExecuteStatementInput) SetConsistentRead(v bool) *ExecuteStatementInput { + s.ConsistentRead = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *ExecuteStatementInput) SetNextToken(v string) *ExecuteStatementInput { + s.NextToken = &v + return s +} + +// SetParameters sets the Parameters field's value. +func (s *ExecuteStatementInput) SetParameters(v []*AttributeValue) *ExecuteStatementInput { + s.Parameters = v + return s +} + +// SetReturnConsumedCapacity sets the ReturnConsumedCapacity field's value. +func (s *ExecuteStatementInput) SetReturnConsumedCapacity(v string) *ExecuteStatementInput { + s.ReturnConsumedCapacity = &v + return s +} + +// SetStatement sets the Statement field's value. +func (s *ExecuteStatementInput) SetStatement(v string) *ExecuteStatementInput { + s.Statement = &v + return s +} + +type ExecuteStatementOutput struct { + _ struct{} `type:"structure"` + + // The capacity units consumed by an operation. The data returned includes the + // total provisioned throughput consumed, along with statistics for the table + // and any indexes involved in the operation. ConsumedCapacity is only returned + // if the request asked for it. For more information, see Provisioned Throughput + // (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ProvisionedThroughputIntro.html) + // in the Amazon DynamoDB Developer Guide. + ConsumedCapacity *ConsumedCapacity `type:"structure"` + + // If a read operation was used, this property will contain the result of the + // read operation; a map of attribute names and their values. For the write + // operations this value will be empty. + Items []map[string]*AttributeValue `type:"list"` + + // If the response of a read request exceeds the response payload limit DynamoDB + // will set this value in the response. If set, you can use that this value + // in the subsequent request to get the remaining results. + NextToken *string `min:"1" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ExecuteStatementOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ExecuteStatementOutput) GoString() string { + return s.String() +} + +// SetConsumedCapacity sets the ConsumedCapacity field's value. +func (s *ExecuteStatementOutput) SetConsumedCapacity(v *ConsumedCapacity) *ExecuteStatementOutput { + s.ConsumedCapacity = v + return s +} + +// SetItems sets the Items field's value. +func (s *ExecuteStatementOutput) SetItems(v []map[string]*AttributeValue) *ExecuteStatementOutput { + s.Items = v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *ExecuteStatementOutput) SetNextToken(v string) *ExecuteStatementOutput { + s.NextToken = &v + return s +} + +type ExecuteTransactionInput struct { + _ struct{} `type:"structure"` + + // Set this value to get remaining results, if NextToken was returned in the + // statement response. + ClientRequestToken *string `min:"1" type:"string" idempotencyToken:"true"` + + // Determines the level of detail about either provisioned or on-demand throughput + // consumption that is returned in the response. For more information, see TransactGetItems + // (https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactGetItems.html) + // and TransactWriteItems (https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactWriteItems.html). + ReturnConsumedCapacity *string `type:"string" enum:"ReturnConsumedCapacity"` + + // The list of PartiQL statements representing the transaction to run. + // + // TransactStatements is a required field + TransactStatements []*ParameterizedStatement `min:"1" type:"list" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ExecuteTransactionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ExecuteTransactionInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ExecuteTransactionInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ExecuteTransactionInput"} + if s.ClientRequestToken != nil && len(*s.ClientRequestToken) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ClientRequestToken", 1)) + } + if s.TransactStatements == nil { + invalidParams.Add(request.NewErrParamRequired("TransactStatements")) + } + if s.TransactStatements != nil && len(s.TransactStatements) < 1 { + invalidParams.Add(request.NewErrParamMinLen("TransactStatements", 1)) + } + if s.TransactStatements != nil { + for i, v := range s.TransactStatements { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "TransactStatements", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetClientRequestToken sets the ClientRequestToken field's value. +func (s *ExecuteTransactionInput) SetClientRequestToken(v string) *ExecuteTransactionInput { + s.ClientRequestToken = &v + return s +} + +// SetReturnConsumedCapacity sets the ReturnConsumedCapacity field's value. +func (s *ExecuteTransactionInput) SetReturnConsumedCapacity(v string) *ExecuteTransactionInput { + s.ReturnConsumedCapacity = &v + return s +} + +// SetTransactStatements sets the TransactStatements field's value. +func (s *ExecuteTransactionInput) SetTransactStatements(v []*ParameterizedStatement) *ExecuteTransactionInput { + s.TransactStatements = v + return s +} + +type ExecuteTransactionOutput struct { + _ struct{} `type:"structure"` + + // The capacity units consumed by the entire operation. The values of the list + // are ordered according to the ordering of the statements. + ConsumedCapacity []*ConsumedCapacity `type:"list"` + + // The response to a PartiQL transaction. + Responses []*ItemResponse `min:"1" type:"list"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ExecuteTransactionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ExecuteTransactionOutput) GoString() string { + return s.String() +} + +// SetConsumedCapacity sets the ConsumedCapacity field's value. +func (s *ExecuteTransactionOutput) SetConsumedCapacity(v []*ConsumedCapacity) *ExecuteTransactionOutput { + s.ConsumedCapacity = v + return s +} + +// SetResponses sets the Responses field's value. +func (s *ExecuteTransactionOutput) SetResponses(v []*ItemResponse) *ExecuteTransactionOutput { + s.Responses = v + return s +} + +// Represents a condition to be compared with an attribute value. This condition +// can be used with DeleteItem, PutItem, or UpdateItem operations; if the comparison +// evaluates to true, the operation succeeds; if not, the operation fails. You +// can use ExpectedAttributeValue in one of two different ways: +// +// * Use AttributeValueList to specify one or more values to compare against +// an attribute. Use ComparisonOperator to specify how you want to perform +// the comparison. If the comparison evaluates to true, then the conditional +// operation succeeds. +// +// * Use Value to specify a value that DynamoDB will compare against an attribute. +// If the values match, then ExpectedAttributeValue evaluates to true and +// the conditional operation succeeds. Optionally, you can also set Exists +// to false, indicating that you do not expect to find the attribute value +// in the table. In this case, the conditional operation succeeds only if +// the comparison evaluates to false. +// +// Value and Exists are incompatible with AttributeValueList and ComparisonOperator. +// Note that if you use both sets of parameters at once, DynamoDB will return +// a ValidationException exception. +type ExpectedAttributeValue struct { + _ struct{} `type:"structure"` + + // One or more values to evaluate against the supplied attribute. The number + // of values in the list depends on the ComparisonOperator being used. + // + // For type Number, value comparisons are numeric. + // + // String value comparisons for greater than, equals, or less than are based + // on ASCII character code values. For example, a is greater than A, and a is + // greater than B. For a list of code values, see http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters + // (http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters). + // + // For Binary, DynamoDB treats each byte of the binary data as unsigned when + // it compares binary values. + // + // For information on specifying data types in JSON, see JSON Data Format (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DataFormat.html) + // in the Amazon DynamoDB Developer Guide. + AttributeValueList []*AttributeValue `type:"list"` + + // A comparator for evaluating attributes in the AttributeValueList. For example, + // equals, greater than, less than, etc. + // + // The following comparison operators are available: + // + // EQ | NE | LE | LT | GE | GT | NOT_NULL | NULL | CONTAINS | NOT_CONTAINS | + // BEGINS_WITH | IN | BETWEEN + // + // The following are descriptions of each comparison operator. + // + // * EQ : Equal. EQ is supported for all data types, including lists and + // maps. AttributeValueList can contain only one AttributeValue element of + // type String, Number, Binary, String Set, Number Set, or Binary Set. If + // an item contains an AttributeValue element of a different type than the + // one provided in the request, the value does not match. For example, {"S":"6"} + // does not equal {"N":"6"}. Also, {"N":"6"} does not equal {"NS":["6", "2", + // "1"]}. + // + // * NE : Not equal. NE is supported for all data types, including lists + // and maps. AttributeValueList can contain only one AttributeValue of type + // String, Number, Binary, String Set, Number Set, or Binary Set. If an item + // contains an AttributeValue of a different type than the one provided in + // the request, the value does not match. For example, {"S":"6"} does not + // equal {"N":"6"}. Also, {"N":"6"} does not equal {"NS":["6", "2", "1"]}. + // + // * LE : Less than or equal. AttributeValueList can contain only one AttributeValue + // element of type String, Number, or Binary (not a set type). If an item + // contains an AttributeValue element of a different type than the one provided + // in the request, the value does not match. For example, {"S":"6"} does + // not equal {"N":"6"}. Also, {"N":"6"} does not compare to {"NS":["6", "2", + // "1"]}. + // + // * LT : Less than. AttributeValueList can contain only one AttributeValue + // of type String, Number, or Binary (not a set type). If an item contains + // an AttributeValue element of a different type than the one provided in + // the request, the value does not match. For example, {"S":"6"} does not + // equal {"N":"6"}. Also, {"N":"6"} does not compare to {"NS":["6", "2", + // "1"]}. + // + // * GE : Greater than or equal. AttributeValueList can contain only one + // AttributeValue element of type String, Number, or Binary (not a set type). + // If an item contains an AttributeValue element of a different type than + // the one provided in the request, the value does not match. For example, + // {"S":"6"} does not equal {"N":"6"}. Also, {"N":"6"} does not compare to + // {"NS":["6", "2", "1"]}. + // + // * GT : Greater than. AttributeValueList can contain only one AttributeValue + // element of type String, Number, or Binary (not a set type). If an item + // contains an AttributeValue element of a different type than the one provided + // in the request, the value does not match. For example, {"S":"6"} does + // not equal {"N":"6"}. Also, {"N":"6"} does not compare to {"NS":["6", "2", + // "1"]}. + // + // * NOT_NULL : The attribute exists. NOT_NULL is supported for all data + // types, including lists and maps. This operator tests for the existence + // of an attribute, not its data type. If the data type of attribute "a" + // is null, and you evaluate it using NOT_NULL, the result is a Boolean true. + // This result is because the attribute "a" exists; its data type is not + // relevant to the NOT_NULL comparison operator. + // + // * NULL : The attribute does not exist. NULL is supported for all data + // types, including lists and maps. This operator tests for the nonexistence + // of an attribute, not its data type. If the data type of attribute "a" + // is null, and you evaluate it using NULL, the result is a Boolean false. + // This is because the attribute "a" exists; its data type is not relevant + // to the NULL comparison operator. + // + // * CONTAINS : Checks for a subsequence, or value in a set. AttributeValueList + // can contain only one AttributeValue element of type String, Number, or + // Binary (not a set type). If the target attribute of the comparison is + // of type String, then the operator checks for a substring match. If the + // target attribute of the comparison is of type Binary, then the operator + // looks for a subsequence of the target that matches the input. If the target + // attribute of the comparison is a set ("SS", "NS", or "BS"), then the operator + // evaluates to true if it finds an exact match with any member of the set. + // CONTAINS is supported for lists: When evaluating "a CONTAINS b", "a" can + // be a list; however, "b" cannot be a set, a map, or a list. + // + // * NOT_CONTAINS : Checks for absence of a subsequence, or absence of a + // value in a set. AttributeValueList can contain only one AttributeValue + // element of type String, Number, or Binary (not a set type). If the target + // attribute of the comparison is a String, then the operator checks for + // the absence of a substring match. If the target attribute of the comparison + // is Binary, then the operator checks for the absence of a subsequence of + // the target that matches the input. If the target attribute of the comparison + // is a set ("SS", "NS", or "BS"), then the operator evaluates to true if + // it does not find an exact match with any member of the set. NOT_CONTAINS + // is supported for lists: When evaluating "a NOT CONTAINS b", "a" can be + // a list; however, "b" cannot be a set, a map, or a list. + // + // * BEGINS_WITH : Checks for a prefix. AttributeValueList can contain only + // one AttributeValue of type String or Binary (not a Number or a set type). + // The target attribute of the comparison must be of type String or Binary + // (not a Number or a set type). + // + // * IN : Checks for matching elements in a list. AttributeValueList can + // contain one or more AttributeValue elements of type String, Number, or + // Binary. These attributes are compared against an existing attribute of + // an item. If any elements of the input are equal to the item attribute, + // the expression evaluates to true. + // + // * BETWEEN : Greater than or equal to the first value, and less than or + // equal to the second value. AttributeValueList must contain two AttributeValue + // elements of the same type, either String, Number, or Binary (not a set + // type). A target attribute matches if the target value is greater than, + // or equal to, the first element and less than, or equal to, the second + // element. If an item contains an AttributeValue element of a different + // type than the one provided in the request, the value does not match. For + // example, {"S":"6"} does not compare to {"N":"6"}. Also, {"N":"6"} does + // not compare to {"NS":["6", "2", "1"]} + ComparisonOperator *string `type:"string" enum:"ComparisonOperator"` + + // Causes DynamoDB to evaluate the value before attempting a conditional operation: + // + // * If Exists is true, DynamoDB will check to see if that attribute value + // already exists in the table. If it is found, then the operation succeeds. + // If it is not found, the operation fails with a ConditionCheckFailedException. + // + // * If Exists is false, DynamoDB assumes that the attribute value does not + // exist in the table. If in fact the value does not exist, then the assumption + // is valid and the operation succeeds. If the value is found, despite the + // assumption that it does not exist, the operation fails with a ConditionCheckFailedException. + // + // The default setting for Exists is true. If you supply a Value all by itself, + // DynamoDB assumes the attribute exists: You don't have to set Exists to true, + // because it is implied. + // + // DynamoDB returns a ValidationException if: + // + // * Exists is true but there is no Value to check. (You expect a value to + // exist, but don't specify what that value is.) + // + // * Exists is false but you also provide a Value. (You cannot expect an + // attribute to have a value, while also expecting it not to exist.) + Exists *bool `type:"boolean"` + + // Represents the data for the expected attribute. + // + // Each attribute value is described as a name-value pair. The name is the data + // type, and the value is the data itself. + // + // For more information, see Data Types (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html#HowItWorks.DataTypes) + // in the Amazon DynamoDB Developer Guide. + Value *AttributeValue `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ExpectedAttributeValue) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ExpectedAttributeValue) GoString() string { + return s.String() +} + +// SetAttributeValueList sets the AttributeValueList field's value. +func (s *ExpectedAttributeValue) SetAttributeValueList(v []*AttributeValue) *ExpectedAttributeValue { + s.AttributeValueList = v + return s +} + +// SetComparisonOperator sets the ComparisonOperator field's value. +func (s *ExpectedAttributeValue) SetComparisonOperator(v string) *ExpectedAttributeValue { + s.ComparisonOperator = &v + return s +} + +// SetExists sets the Exists field's value. +func (s *ExpectedAttributeValue) SetExists(v bool) *ExpectedAttributeValue { + s.Exists = &v + return s +} + +// SetValue sets the Value field's value. +func (s *ExpectedAttributeValue) SetValue(v *AttributeValue) *ExpectedAttributeValue { + s.Value = v + return s +} + +// There was a conflict when writing to the specified S3 bucket. +type ExportConflictException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + Message_ *string `locationName:"message" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ExportConflictException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ExportConflictException) GoString() string { + return s.String() +} + +func newErrorExportConflictException(v protocol.ResponseMetadata) error { + return &ExportConflictException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *ExportConflictException) Code() string { + return "ExportConflictException" +} + +// Message returns the exception's message. +func (s *ExportConflictException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *ExportConflictException) OrigErr() error { + return nil +} + +func (s *ExportConflictException) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *ExportConflictException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *ExportConflictException) RequestID() string { + return s.RespMetadata.RequestID +} + +// Represents the properties of the exported table. +type ExportDescription struct { + _ struct{} `type:"structure"` + + // The billable size of the table export. + BilledSizeBytes *int64 `type:"long"` + + // The client token that was provided for the export task. A client token makes + // calls to ExportTableToPointInTimeInput idempotent, meaning that multiple + // identical calls have the same effect as one single call. + ClientToken *string `type:"string"` + + // The time at which the export task completed. + EndTime *time.Time `type:"timestamp"` + + // The Amazon Resource Name (ARN) of the table export. + ExportArn *string `min:"37" type:"string"` + + // The format of the exported data. Valid values for ExportFormat are DYNAMODB_JSON + // or ION. + ExportFormat *string `type:"string" enum:"ExportFormat"` + + // The name of the manifest file for the export task. + ExportManifest *string `type:"string"` + + // Export can be in one of the following states: IN_PROGRESS, COMPLETED, or + // FAILED. + ExportStatus *string `type:"string" enum:"ExportStatus"` + + // Point in time from which table data was exported. + ExportTime *time.Time `type:"timestamp"` + + // Status code for the result of the failed export. + FailureCode *string `type:"string"` + + // Export failure reason description. + FailureMessage *string `type:"string"` + + // The number of items exported. + ItemCount *int64 `type:"long"` + + // The name of the Amazon S3 bucket containing the export. + S3Bucket *string `type:"string"` + + // The ID of the Amazon Web Services account that owns the bucket containing + // the export. + S3BucketOwner *string `type:"string"` + + // The Amazon S3 bucket prefix used as the file name and path of the exported + // snapshot. + S3Prefix *string `type:"string"` + + // Type of encryption used on the bucket where export data is stored. Valid + // values for S3SseAlgorithm are: + // + // * AES256 - server-side encryption with Amazon S3 managed keys + // + // * KMS - server-side encryption with KMS managed keys + S3SseAlgorithm *string `type:"string" enum:"S3SseAlgorithm"` + + // The ID of the KMS managed key used to encrypt the S3 bucket where export + // data is stored (if applicable). + S3SseKmsKeyId *string `min:"1" type:"string"` + + // The time at which the export task began. + StartTime *time.Time `type:"timestamp"` + + // The Amazon Resource Name (ARN) of the table that was exported. + TableArn *string `type:"string"` + + // Unique ID of the table that was exported. + TableId *string `type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ExportDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ExportDescription) GoString() string { + return s.String() +} + +// SetBilledSizeBytes sets the BilledSizeBytes field's value. +func (s *ExportDescription) SetBilledSizeBytes(v int64) *ExportDescription { + s.BilledSizeBytes = &v + return s +} + +// SetClientToken sets the ClientToken field's value. +func (s *ExportDescription) SetClientToken(v string) *ExportDescription { + s.ClientToken = &v + return s +} + +// SetEndTime sets the EndTime field's value. +func (s *ExportDescription) SetEndTime(v time.Time) *ExportDescription { + s.EndTime = &v + return s +} + +// SetExportArn sets the ExportArn field's value. +func (s *ExportDescription) SetExportArn(v string) *ExportDescription { + s.ExportArn = &v + return s +} + +// SetExportFormat sets the ExportFormat field's value. +func (s *ExportDescription) SetExportFormat(v string) *ExportDescription { + s.ExportFormat = &v + return s +} + +// SetExportManifest sets the ExportManifest field's value. +func (s *ExportDescription) SetExportManifest(v string) *ExportDescription { + s.ExportManifest = &v + return s +} + +// SetExportStatus sets the ExportStatus field's value. +func (s *ExportDescription) SetExportStatus(v string) *ExportDescription { + s.ExportStatus = &v + return s +} + +// SetExportTime sets the ExportTime field's value. +func (s *ExportDescription) SetExportTime(v time.Time) *ExportDescription { + s.ExportTime = &v + return s +} + +// SetFailureCode sets the FailureCode field's value. +func (s *ExportDescription) SetFailureCode(v string) *ExportDescription { + s.FailureCode = &v + return s +} + +// SetFailureMessage sets the FailureMessage field's value. +func (s *ExportDescription) SetFailureMessage(v string) *ExportDescription { + s.FailureMessage = &v + return s +} + +// SetItemCount sets the ItemCount field's value. +func (s *ExportDescription) SetItemCount(v int64) *ExportDescription { + s.ItemCount = &v + return s +} + +// SetS3Bucket sets the S3Bucket field's value. +func (s *ExportDescription) SetS3Bucket(v string) *ExportDescription { + s.S3Bucket = &v + return s +} + +// SetS3BucketOwner sets the S3BucketOwner field's value. +func (s *ExportDescription) SetS3BucketOwner(v string) *ExportDescription { + s.S3BucketOwner = &v + return s +} + +// SetS3Prefix sets the S3Prefix field's value. +func (s *ExportDescription) SetS3Prefix(v string) *ExportDescription { + s.S3Prefix = &v + return s +} + +// SetS3SseAlgorithm sets the S3SseAlgorithm field's value. +func (s *ExportDescription) SetS3SseAlgorithm(v string) *ExportDescription { + s.S3SseAlgorithm = &v + return s +} + +// SetS3SseKmsKeyId sets the S3SseKmsKeyId field's value. +func (s *ExportDescription) SetS3SseKmsKeyId(v string) *ExportDescription { + s.S3SseKmsKeyId = &v + return s +} + +// SetStartTime sets the StartTime field's value. +func (s *ExportDescription) SetStartTime(v time.Time) *ExportDescription { + s.StartTime = &v + return s +} + +// SetTableArn sets the TableArn field's value. +func (s *ExportDescription) SetTableArn(v string) *ExportDescription { + s.TableArn = &v + return s +} + +// SetTableId sets the TableId field's value. +func (s *ExportDescription) SetTableId(v string) *ExportDescription { + s.TableId = &v + return s +} + +// The specified export was not found. +type ExportNotFoundException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + Message_ *string `locationName:"message" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ExportNotFoundException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ExportNotFoundException) GoString() string { + return s.String() +} + +func newErrorExportNotFoundException(v protocol.ResponseMetadata) error { + return &ExportNotFoundException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *ExportNotFoundException) Code() string { + return "ExportNotFoundException" +} + +// Message returns the exception's message. +func (s *ExportNotFoundException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *ExportNotFoundException) OrigErr() error { + return nil +} + +func (s *ExportNotFoundException) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *ExportNotFoundException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *ExportNotFoundException) RequestID() string { + return s.RespMetadata.RequestID +} + +// Summary information about an export task. +type ExportSummary struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the export. + ExportArn *string `min:"37" type:"string"` + + // Export can be in one of the following states: IN_PROGRESS, COMPLETED, or + // FAILED. + ExportStatus *string `type:"string" enum:"ExportStatus"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ExportSummary) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ExportSummary) GoString() string { + return s.String() +} + +// SetExportArn sets the ExportArn field's value. +func (s *ExportSummary) SetExportArn(v string) *ExportSummary { + s.ExportArn = &v + return s +} + +// SetExportStatus sets the ExportStatus field's value. +func (s *ExportSummary) SetExportStatus(v string) *ExportSummary { + s.ExportStatus = &v + return s +} + +type ExportTableToPointInTimeInput struct { + _ struct{} `type:"structure"` + + // Providing a ClientToken makes the call to ExportTableToPointInTimeInput idempotent, + // meaning that multiple identical calls have the same effect as one single + // call. + // + // A client token is valid for 8 hours after the first request that uses it + // is completed. After 8 hours, any request with the same client token is treated + // as a new request. Do not resubmit the same request with the same client token + // for more than 8 hours, or the result might not be idempotent. + // + // If you submit a request with the same client token but a change in other + // parameters within the 8-hour idempotency window, DynamoDB returns an IdempotentParameterMismatch + // exception. + ClientToken *string `type:"string" idempotencyToken:"true"` + + // The format for the exported data. Valid values for ExportFormat are DYNAMODB_JSON + // or ION. + ExportFormat *string `type:"string" enum:"ExportFormat"` + + // Time in the past from which to export table data. The table export will be + // a snapshot of the table's state at this point in time. + ExportTime *time.Time `type:"timestamp"` + + // The name of the Amazon S3 bucket to export the snapshot to. + // + // S3Bucket is a required field + S3Bucket *string `type:"string" required:"true"` + + // The ID of the Amazon Web Services account that owns the bucket the export + // will be stored in. + S3BucketOwner *string `type:"string"` + + // The Amazon S3 bucket prefix to use as the file name and path of the exported + // snapshot. + S3Prefix *string `type:"string"` + + // Type of encryption used on the bucket where export data will be stored. Valid + // values for S3SseAlgorithm are: + // + // * AES256 - server-side encryption with Amazon S3 managed keys + // + // * KMS - server-side encryption with KMS managed keys + S3SseAlgorithm *string `type:"string" enum:"S3SseAlgorithm"` + + // The ID of the KMS managed key used to encrypt the S3 bucket where export + // data will be stored (if applicable). + S3SseKmsKeyId *string `min:"1" type:"string"` + + // The Amazon Resource Name (ARN) associated with the table to export. + // + // TableArn is a required field + TableArn *string `type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ExportTableToPointInTimeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ExportTableToPointInTimeInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ExportTableToPointInTimeInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ExportTableToPointInTimeInput"} + if s.S3Bucket == nil { + invalidParams.Add(request.NewErrParamRequired("S3Bucket")) + } + if s.S3SseKmsKeyId != nil && len(*s.S3SseKmsKeyId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("S3SseKmsKeyId", 1)) + } + if s.TableArn == nil { + invalidParams.Add(request.NewErrParamRequired("TableArn")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetClientToken sets the ClientToken field's value. +func (s *ExportTableToPointInTimeInput) SetClientToken(v string) *ExportTableToPointInTimeInput { + s.ClientToken = &v + return s +} + +// SetExportFormat sets the ExportFormat field's value. +func (s *ExportTableToPointInTimeInput) SetExportFormat(v string) *ExportTableToPointInTimeInput { + s.ExportFormat = &v + return s +} + +// SetExportTime sets the ExportTime field's value. +func (s *ExportTableToPointInTimeInput) SetExportTime(v time.Time) *ExportTableToPointInTimeInput { + s.ExportTime = &v + return s +} + +// SetS3Bucket sets the S3Bucket field's value. +func (s *ExportTableToPointInTimeInput) SetS3Bucket(v string) *ExportTableToPointInTimeInput { + s.S3Bucket = &v + return s +} + +// SetS3BucketOwner sets the S3BucketOwner field's value. +func (s *ExportTableToPointInTimeInput) SetS3BucketOwner(v string) *ExportTableToPointInTimeInput { + s.S3BucketOwner = &v + return s +} + +// SetS3Prefix sets the S3Prefix field's value. +func (s *ExportTableToPointInTimeInput) SetS3Prefix(v string) *ExportTableToPointInTimeInput { + s.S3Prefix = &v + return s +} + +// SetS3SseAlgorithm sets the S3SseAlgorithm field's value. +func (s *ExportTableToPointInTimeInput) SetS3SseAlgorithm(v string) *ExportTableToPointInTimeInput { + s.S3SseAlgorithm = &v + return s +} + +// SetS3SseKmsKeyId sets the S3SseKmsKeyId field's value. +func (s *ExportTableToPointInTimeInput) SetS3SseKmsKeyId(v string) *ExportTableToPointInTimeInput { + s.S3SseKmsKeyId = &v + return s +} + +// SetTableArn sets the TableArn field's value. +func (s *ExportTableToPointInTimeInput) SetTableArn(v string) *ExportTableToPointInTimeInput { + s.TableArn = &v + return s +} + +type ExportTableToPointInTimeOutput struct { + _ struct{} `type:"structure"` + + // Contains a description of the table export. + ExportDescription *ExportDescription `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ExportTableToPointInTimeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ExportTableToPointInTimeOutput) GoString() string { + return s.String() +} + +// SetExportDescription sets the ExportDescription field's value. +func (s *ExportTableToPointInTimeOutput) SetExportDescription(v *ExportDescription) *ExportTableToPointInTimeOutput { + s.ExportDescription = v + return s +} + +// Represents a failure a contributor insights operation. +type FailureException struct { + _ struct{} `type:"structure"` + + // Description of the failure. + ExceptionDescription *string `type:"string"` + + // Exception name. + ExceptionName *string `type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s FailureException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s FailureException) GoString() string { + return s.String() +} + +// SetExceptionDescription sets the ExceptionDescription field's value. +func (s *FailureException) SetExceptionDescription(v string) *FailureException { + s.ExceptionDescription = &v + return s +} + +// SetExceptionName sets the ExceptionName field's value. +func (s *FailureException) SetExceptionName(v string) *FailureException { + s.ExceptionName = &v + return s +} + +// Specifies an item and related attribute values to retrieve in a TransactGetItem +// object. +type Get struct { + _ struct{} `type:"structure"` + + // One or more substitution tokens for attribute names in the ProjectionExpression + // parameter. + ExpressionAttributeNames map[string]*string `type:"map"` + + // A map of attribute names to AttributeValue objects that specifies the primary + // key of the item to retrieve. + // + // Key is a required field + Key map[string]*AttributeValue `type:"map" required:"true"` + + // A string that identifies one or more attributes of the specified item to + // retrieve from the table. The attributes in the expression must be separated + // by commas. If no attribute names are specified, then all attributes of the + // specified item are returned. If any of the requested attributes are not found, + // they do not appear in the result. + ProjectionExpression *string `type:"string"` + + // The name of the table from which to retrieve the specified item. + // + // TableName is a required field + TableName *string `min:"3" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s Get) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s Get) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *Get) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "Get"} + if s.Key == nil { + invalidParams.Add(request.NewErrParamRequired("Key")) + } + if s.TableName == nil { + invalidParams.Add(request.NewErrParamRequired("TableName")) + } + if s.TableName != nil && len(*s.TableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("TableName", 3)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetExpressionAttributeNames sets the ExpressionAttributeNames field's value. +func (s *Get) SetExpressionAttributeNames(v map[string]*string) *Get { + s.ExpressionAttributeNames = v + return s +} + +// SetKey sets the Key field's value. +func (s *Get) SetKey(v map[string]*AttributeValue) *Get { + s.Key = v + return s +} + +// SetProjectionExpression sets the ProjectionExpression field's value. +func (s *Get) SetProjectionExpression(v string) *Get { + s.ProjectionExpression = &v + return s +} + +// SetTableName sets the TableName field's value. +func (s *Get) SetTableName(v string) *Get { + s.TableName = &v + return s +} + +// Represents the input of a GetItem operation. +type GetItemInput struct { + _ struct{} `type:"structure"` + + // This is a legacy parameter. Use ProjectionExpression instead. For more information, + // see AttributesToGet (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.AttributesToGet.html) + // in the Amazon DynamoDB Developer Guide. + AttributesToGet []*string `min:"1" type:"list"` + + // Determines the read consistency model: If set to true, then the operation + // uses strongly consistent reads; otherwise, the operation uses eventually + // consistent reads. + ConsistentRead *bool `type:"boolean"` + + // One or more substitution tokens for attribute names in an expression. The + // following are some use cases for using ExpressionAttributeNames: + // + // * To access an attribute whose name conflicts with a DynamoDB reserved + // word. + // + // * To create a placeholder for repeating occurrences of an attribute name + // in an expression. + // + // * To prevent special characters in an attribute name from being misinterpreted + // in an expression. + // + // Use the # character in an expression to dereference an attribute name. For + // example, consider the following attribute name: + // + // * Percentile + // + // The name of this attribute conflicts with a reserved word, so it cannot be + // used directly in an expression. (For the complete list of reserved words, + // see Reserved Words (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html) + // in the Amazon DynamoDB Developer Guide). To work around this, you could specify + // the following for ExpressionAttributeNames: + // + // * {"#P":"Percentile"} + // + // You could then use this substitution in an expression, as in this example: + // + // * #P = :val + // + // Tokens that begin with the : character are expression attribute values, which + // are placeholders for the actual value at runtime. + // + // For more information on expression attribute names, see Specifying Item Attributes + // (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.AccessingItemAttributes.html) + // in the Amazon DynamoDB Developer Guide. + ExpressionAttributeNames map[string]*string `type:"map"` + + // A map of attribute names to AttributeValue objects, representing the primary + // key of the item to retrieve. + // + // For the primary key, you must provide all of the attributes. For example, + // with a simple primary key, you only need to provide a value for the partition + // key. For a composite primary key, you must provide values for both the partition + // key and the sort key. + // + // Key is a required field + Key map[string]*AttributeValue `type:"map" required:"true"` + + // A string that identifies one or more attributes to retrieve from the table. + // These attributes can include scalars, sets, or elements of a JSON document. + // The attributes in the expression must be separated by commas. + // + // If no attribute names are specified, then all attributes are returned. If + // any of the requested attributes are not found, they do not appear in the + // result. + // + // For more information, see Specifying Item Attributes (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.AccessingItemAttributes.html) + // in the Amazon DynamoDB Developer Guide. + ProjectionExpression *string `type:"string"` + + // Determines the level of detail about either provisioned or on-demand throughput + // consumption that is returned in the response: + // + // * INDEXES - The response includes the aggregate ConsumedCapacity for the + // operation, together with ConsumedCapacity for each table and secondary + // index that was accessed. Note that some operations, such as GetItem and + // BatchGetItem, do not access any indexes at all. In these cases, specifying + // INDEXES will only return ConsumedCapacity information for table(s). + // + // * TOTAL - The response includes only the aggregate ConsumedCapacity for + // the operation. + // + // * NONE - No ConsumedCapacity details are included in the response. + ReturnConsumedCapacity *string `type:"string" enum:"ReturnConsumedCapacity"` + + // The name of the table containing the requested item. + // + // TableName is a required field + TableName *string `min:"3" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s GetItemInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s GetItemInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetItemInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetItemInput"} + if s.AttributesToGet != nil && len(s.AttributesToGet) < 1 { + invalidParams.Add(request.NewErrParamMinLen("AttributesToGet", 1)) + } + if s.Key == nil { + invalidParams.Add(request.NewErrParamRequired("Key")) + } + if s.TableName == nil { + invalidParams.Add(request.NewErrParamRequired("TableName")) + } + if s.TableName != nil && len(*s.TableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("TableName", 3)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAttributesToGet sets the AttributesToGet field's value. +func (s *GetItemInput) SetAttributesToGet(v []*string) *GetItemInput { + s.AttributesToGet = v + return s +} + +// SetConsistentRead sets the ConsistentRead field's value. +func (s *GetItemInput) SetConsistentRead(v bool) *GetItemInput { + s.ConsistentRead = &v + return s +} + +// SetExpressionAttributeNames sets the ExpressionAttributeNames field's value. +func (s *GetItemInput) SetExpressionAttributeNames(v map[string]*string) *GetItemInput { + s.ExpressionAttributeNames = v + return s +} + +// SetKey sets the Key field's value. +func (s *GetItemInput) SetKey(v map[string]*AttributeValue) *GetItemInput { + s.Key = v + return s +} + +// SetProjectionExpression sets the ProjectionExpression field's value. +func (s *GetItemInput) SetProjectionExpression(v string) *GetItemInput { + s.ProjectionExpression = &v + return s +} + +// SetReturnConsumedCapacity sets the ReturnConsumedCapacity field's value. +func (s *GetItemInput) SetReturnConsumedCapacity(v string) *GetItemInput { + s.ReturnConsumedCapacity = &v + return s +} + +// SetTableName sets the TableName field's value. +func (s *GetItemInput) SetTableName(v string) *GetItemInput { + s.TableName = &v + return s +} + +// Represents the output of a GetItem operation. +type GetItemOutput struct { + _ struct{} `type:"structure"` + + // The capacity units consumed by the GetItem operation. The data returned includes + // the total provisioned throughput consumed, along with statistics for the + // table and any indexes involved in the operation. ConsumedCapacity is only + // returned if the ReturnConsumedCapacity parameter was specified. For more + // information, see Read/Write Capacity Mode (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ProvisionedThroughputIntro.html) + // in the Amazon DynamoDB Developer Guide. + ConsumedCapacity *ConsumedCapacity `type:"structure"` + + // A map of attribute names to AttributeValue objects, as specified by ProjectionExpression. + Item map[string]*AttributeValue `type:"map"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s GetItemOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s GetItemOutput) GoString() string { + return s.String() +} + +// SetConsumedCapacity sets the ConsumedCapacity field's value. +func (s *GetItemOutput) SetConsumedCapacity(v *ConsumedCapacity) *GetItemOutput { + s.ConsumedCapacity = v + return s +} + +// SetItem sets the Item field's value. +func (s *GetItemOutput) SetItem(v map[string]*AttributeValue) *GetItemOutput { + s.Item = v + return s +} + +// Represents the properties of a global secondary index. +type GlobalSecondaryIndex struct { + _ struct{} `type:"structure"` + + // The name of the global secondary index. The name must be unique among all + // other indexes on this table. + // + // IndexName is a required field + IndexName *string `min:"3" type:"string" required:"true"` + + // The complete key schema for a global secondary index, which consists of one + // or more pairs of attribute names and key types: + // + // * HASH - partition key + // + // * RANGE - sort key + // + // The partition key of an item is also known as its hash attribute. The term + // "hash attribute" derives from DynamoDB's usage of an internal hash function + // to evenly distribute data items across partitions, based on their partition + // key values. + // + // The sort key of an item is also known as its range attribute. The term "range + // attribute" derives from the way DynamoDB stores items with the same partition + // key physically close together, in sorted order by the sort key value. + // + // KeySchema is a required field + KeySchema []*KeySchemaElement `min:"1" type:"list" required:"true"` + + // Represents attributes that are copied (projected) from the table into the + // global secondary index. These are in addition to the primary key attributes + // and index key attributes, which are automatically projected. + // + // Projection is a required field + Projection *Projection `type:"structure" required:"true"` + + // Represents the provisioned throughput settings for the specified global secondary + // index. + // + // For current minimum and maximum provisioned throughput values, see Service, + // Account, and Table Quotas (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Limits.html) + // in the Amazon DynamoDB Developer Guide. + ProvisionedThroughput *ProvisionedThroughput `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s GlobalSecondaryIndex) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s GlobalSecondaryIndex) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GlobalSecondaryIndex) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GlobalSecondaryIndex"} + if s.IndexName == nil { + invalidParams.Add(request.NewErrParamRequired("IndexName")) + } + if s.IndexName != nil && len(*s.IndexName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("IndexName", 3)) + } + if s.KeySchema == nil { + invalidParams.Add(request.NewErrParamRequired("KeySchema")) + } + if s.KeySchema != nil && len(s.KeySchema) < 1 { + invalidParams.Add(request.NewErrParamMinLen("KeySchema", 1)) + } + if s.Projection == nil { + invalidParams.Add(request.NewErrParamRequired("Projection")) + } + if s.KeySchema != nil { + for i, v := range s.KeySchema { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "KeySchema", i), err.(request.ErrInvalidParams)) + } + } + } + if s.Projection != nil { + if err := s.Projection.Validate(); err != nil { + invalidParams.AddNested("Projection", err.(request.ErrInvalidParams)) + } + } + if s.ProvisionedThroughput != nil { + if err := s.ProvisionedThroughput.Validate(); err != nil { + invalidParams.AddNested("ProvisionedThroughput", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetIndexName sets the IndexName field's value. +func (s *GlobalSecondaryIndex) SetIndexName(v string) *GlobalSecondaryIndex { + s.IndexName = &v + return s +} + +// SetKeySchema sets the KeySchema field's value. +func (s *GlobalSecondaryIndex) SetKeySchema(v []*KeySchemaElement) *GlobalSecondaryIndex { + s.KeySchema = v + return s +} + +// SetProjection sets the Projection field's value. +func (s *GlobalSecondaryIndex) SetProjection(v *Projection) *GlobalSecondaryIndex { + s.Projection = v + return s +} + +// SetProvisionedThroughput sets the ProvisionedThroughput field's value. +func (s *GlobalSecondaryIndex) SetProvisionedThroughput(v *ProvisionedThroughput) *GlobalSecondaryIndex { + s.ProvisionedThroughput = v + return s +} + +// Represents the auto scaling settings of a global secondary index for a global +// table that will be modified. +type GlobalSecondaryIndexAutoScalingUpdate struct { + _ struct{} `type:"structure"` + + // The name of the global secondary index. + IndexName *string `min:"3" type:"string"` + + // Represents the auto scaling settings to be modified for a global table or + // global secondary index. + ProvisionedWriteCapacityAutoScalingUpdate *AutoScalingSettingsUpdate `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s GlobalSecondaryIndexAutoScalingUpdate) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s GlobalSecondaryIndexAutoScalingUpdate) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GlobalSecondaryIndexAutoScalingUpdate) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GlobalSecondaryIndexAutoScalingUpdate"} + if s.IndexName != nil && len(*s.IndexName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("IndexName", 3)) + } + if s.ProvisionedWriteCapacityAutoScalingUpdate != nil { + if err := s.ProvisionedWriteCapacityAutoScalingUpdate.Validate(); err != nil { + invalidParams.AddNested("ProvisionedWriteCapacityAutoScalingUpdate", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetIndexName sets the IndexName field's value. +func (s *GlobalSecondaryIndexAutoScalingUpdate) SetIndexName(v string) *GlobalSecondaryIndexAutoScalingUpdate { + s.IndexName = &v + return s +} + +// SetProvisionedWriteCapacityAutoScalingUpdate sets the ProvisionedWriteCapacityAutoScalingUpdate field's value. +func (s *GlobalSecondaryIndexAutoScalingUpdate) SetProvisionedWriteCapacityAutoScalingUpdate(v *AutoScalingSettingsUpdate) *GlobalSecondaryIndexAutoScalingUpdate { + s.ProvisionedWriteCapacityAutoScalingUpdate = v + return s +} + +// Represents the properties of a global secondary index. +type GlobalSecondaryIndexDescription struct { + _ struct{} `type:"structure"` + + // Indicates whether the index is currently backfilling. Backfilling is the + // process of reading items from the table and determining whether they can + // be added to the index. (Not all items will qualify: For example, a partition + // key cannot have any duplicate values.) If an item can be added to the index, + // DynamoDB will do so. After all items have been processed, the backfilling + // operation is complete and Backfilling is false. + // + // You can delete an index that is being created during the Backfilling phase + // when IndexStatus is set to CREATING and Backfilling is true. You can't delete + // the index that is being created when IndexStatus is set to CREATING and Backfilling + // is false. + // + // For indexes that were created during a CreateTable operation, the Backfilling + // attribute does not appear in the DescribeTable output. + Backfilling *bool `type:"boolean"` + + // The Amazon Resource Name (ARN) that uniquely identifies the index. + IndexArn *string `type:"string"` + + // The name of the global secondary index. + IndexName *string `min:"3" type:"string"` + + // The total size of the specified index, in bytes. DynamoDB updates this value + // approximately every six hours. Recent changes might not be reflected in this + // value. + IndexSizeBytes *int64 `type:"long"` + + // The current state of the global secondary index: + // + // * CREATING - The index is being created. + // + // * UPDATING - The index is being updated. + // + // * DELETING - The index is being deleted. + // + // * ACTIVE - The index is ready for use. + IndexStatus *string `type:"string" enum:"IndexStatus"` + + // The number of items in the specified index. DynamoDB updates this value approximately + // every six hours. Recent changes might not be reflected in this value. + ItemCount *int64 `type:"long"` + + // The complete key schema for a global secondary index, which consists of one + // or more pairs of attribute names and key types: + // + // * HASH - partition key + // + // * RANGE - sort key + // + // The partition key of an item is also known as its hash attribute. The term + // "hash attribute" derives from DynamoDB's usage of an internal hash function + // to evenly distribute data items across partitions, based on their partition + // key values. + // + // The sort key of an item is also known as its range attribute. The term "range + // attribute" derives from the way DynamoDB stores items with the same partition + // key physically close together, in sorted order by the sort key value. + KeySchema []*KeySchemaElement `min:"1" type:"list"` + + // Represents attributes that are copied (projected) from the table into the + // global secondary index. These are in addition to the primary key attributes + // and index key attributes, which are automatically projected. + Projection *Projection `type:"structure"` + + // Represents the provisioned throughput settings for the specified global secondary + // index. + // + // For current minimum and maximum provisioned throughput values, see Service, + // Account, and Table Quotas (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Limits.html) + // in the Amazon DynamoDB Developer Guide. + ProvisionedThroughput *ProvisionedThroughputDescription `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s GlobalSecondaryIndexDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s GlobalSecondaryIndexDescription) GoString() string { + return s.String() +} + +// SetBackfilling sets the Backfilling field's value. +func (s *GlobalSecondaryIndexDescription) SetBackfilling(v bool) *GlobalSecondaryIndexDescription { + s.Backfilling = &v + return s +} + +// SetIndexArn sets the IndexArn field's value. +func (s *GlobalSecondaryIndexDescription) SetIndexArn(v string) *GlobalSecondaryIndexDescription { + s.IndexArn = &v + return s +} + +// SetIndexName sets the IndexName field's value. +func (s *GlobalSecondaryIndexDescription) SetIndexName(v string) *GlobalSecondaryIndexDescription { + s.IndexName = &v + return s +} + +// SetIndexSizeBytes sets the IndexSizeBytes field's value. +func (s *GlobalSecondaryIndexDescription) SetIndexSizeBytes(v int64) *GlobalSecondaryIndexDescription { + s.IndexSizeBytes = &v + return s +} + +// SetIndexStatus sets the IndexStatus field's value. +func (s *GlobalSecondaryIndexDescription) SetIndexStatus(v string) *GlobalSecondaryIndexDescription { + s.IndexStatus = &v + return s +} + +// SetItemCount sets the ItemCount field's value. +func (s *GlobalSecondaryIndexDescription) SetItemCount(v int64) *GlobalSecondaryIndexDescription { + s.ItemCount = &v + return s +} + +// SetKeySchema sets the KeySchema field's value. +func (s *GlobalSecondaryIndexDescription) SetKeySchema(v []*KeySchemaElement) *GlobalSecondaryIndexDescription { + s.KeySchema = v + return s +} + +// SetProjection sets the Projection field's value. +func (s *GlobalSecondaryIndexDescription) SetProjection(v *Projection) *GlobalSecondaryIndexDescription { + s.Projection = v + return s +} + +// SetProvisionedThroughput sets the ProvisionedThroughput field's value. +func (s *GlobalSecondaryIndexDescription) SetProvisionedThroughput(v *ProvisionedThroughputDescription) *GlobalSecondaryIndexDescription { + s.ProvisionedThroughput = v + return s +} + +// Represents the properties of a global secondary index for the table when +// the backup was created. +type GlobalSecondaryIndexInfo struct { + _ struct{} `type:"structure"` + + // The name of the global secondary index. + IndexName *string `min:"3" type:"string"` + + // The complete key schema for a global secondary index, which consists of one + // or more pairs of attribute names and key types: + // + // * HASH - partition key + // + // * RANGE - sort key + // + // The partition key of an item is also known as its hash attribute. The term + // "hash attribute" derives from DynamoDB's usage of an internal hash function + // to evenly distribute data items across partitions, based on their partition + // key values. + // + // The sort key of an item is also known as its range attribute. The term "range + // attribute" derives from the way DynamoDB stores items with the same partition + // key physically close together, in sorted order by the sort key value. + KeySchema []*KeySchemaElement `min:"1" type:"list"` + + // Represents attributes that are copied (projected) from the table into the + // global secondary index. These are in addition to the primary key attributes + // and index key attributes, which are automatically projected. + Projection *Projection `type:"structure"` + + // Represents the provisioned throughput settings for the specified global secondary + // index. + ProvisionedThroughput *ProvisionedThroughput `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s GlobalSecondaryIndexInfo) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s GlobalSecondaryIndexInfo) GoString() string { + return s.String() +} + +// SetIndexName sets the IndexName field's value. +func (s *GlobalSecondaryIndexInfo) SetIndexName(v string) *GlobalSecondaryIndexInfo { + s.IndexName = &v + return s +} + +// SetKeySchema sets the KeySchema field's value. +func (s *GlobalSecondaryIndexInfo) SetKeySchema(v []*KeySchemaElement) *GlobalSecondaryIndexInfo { + s.KeySchema = v + return s +} + +// SetProjection sets the Projection field's value. +func (s *GlobalSecondaryIndexInfo) SetProjection(v *Projection) *GlobalSecondaryIndexInfo { + s.Projection = v + return s +} + +// SetProvisionedThroughput sets the ProvisionedThroughput field's value. +func (s *GlobalSecondaryIndexInfo) SetProvisionedThroughput(v *ProvisionedThroughput) *GlobalSecondaryIndexInfo { + s.ProvisionedThroughput = v + return s +} + +// Represents one of the following: +// +// * A new global secondary index to be added to an existing table. +// +// * New provisioned throughput parameters for an existing global secondary +// index. +// +// * An existing global secondary index to be removed from an existing table. +type GlobalSecondaryIndexUpdate struct { + _ struct{} `type:"structure"` + + // The parameters required for creating a global secondary index on an existing + // table: + // + // * IndexName + // + // * KeySchema + // + // * AttributeDefinitions + // + // * Projection + // + // * ProvisionedThroughput + Create *CreateGlobalSecondaryIndexAction `type:"structure"` + + // The name of an existing global secondary index to be removed. + Delete *DeleteGlobalSecondaryIndexAction `type:"structure"` + + // The name of an existing global secondary index, along with new provisioned + // throughput settings to be applied to that index. + Update *UpdateGlobalSecondaryIndexAction `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s GlobalSecondaryIndexUpdate) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s GlobalSecondaryIndexUpdate) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GlobalSecondaryIndexUpdate) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GlobalSecondaryIndexUpdate"} + if s.Create != nil { + if err := s.Create.Validate(); err != nil { + invalidParams.AddNested("Create", err.(request.ErrInvalidParams)) + } + } + if s.Delete != nil { + if err := s.Delete.Validate(); err != nil { + invalidParams.AddNested("Delete", err.(request.ErrInvalidParams)) + } + } + if s.Update != nil { + if err := s.Update.Validate(); err != nil { + invalidParams.AddNested("Update", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetCreate sets the Create field's value. +func (s *GlobalSecondaryIndexUpdate) SetCreate(v *CreateGlobalSecondaryIndexAction) *GlobalSecondaryIndexUpdate { + s.Create = v + return s +} + +// SetDelete sets the Delete field's value. +func (s *GlobalSecondaryIndexUpdate) SetDelete(v *DeleteGlobalSecondaryIndexAction) *GlobalSecondaryIndexUpdate { + s.Delete = v + return s +} + +// SetUpdate sets the Update field's value. +func (s *GlobalSecondaryIndexUpdate) SetUpdate(v *UpdateGlobalSecondaryIndexAction) *GlobalSecondaryIndexUpdate { + s.Update = v + return s +} + +// Represents the properties of a global table. +type GlobalTable struct { + _ struct{} `type:"structure"` + + // The global table name. + GlobalTableName *string `min:"3" type:"string"` + + // The Regions where the global table has replicas. + ReplicationGroup []*Replica `type:"list"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s GlobalTable) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s GlobalTable) GoString() string { + return s.String() +} + +// SetGlobalTableName sets the GlobalTableName field's value. +func (s *GlobalTable) SetGlobalTableName(v string) *GlobalTable { + s.GlobalTableName = &v + return s +} + +// SetReplicationGroup sets the ReplicationGroup field's value. +func (s *GlobalTable) SetReplicationGroup(v []*Replica) *GlobalTable { + s.ReplicationGroup = v + return s +} + +// The specified global table already exists. +type GlobalTableAlreadyExistsException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + Message_ *string `locationName:"message" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s GlobalTableAlreadyExistsException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s GlobalTableAlreadyExistsException) GoString() string { + return s.String() +} + +func newErrorGlobalTableAlreadyExistsException(v protocol.ResponseMetadata) error { + return &GlobalTableAlreadyExistsException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *GlobalTableAlreadyExistsException) Code() string { + return "GlobalTableAlreadyExistsException" +} + +// Message returns the exception's message. +func (s *GlobalTableAlreadyExistsException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *GlobalTableAlreadyExistsException) OrigErr() error { + return nil +} + +func (s *GlobalTableAlreadyExistsException) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *GlobalTableAlreadyExistsException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *GlobalTableAlreadyExistsException) RequestID() string { + return s.RespMetadata.RequestID +} + +// Contains details about the global table. +type GlobalTableDescription struct { + _ struct{} `type:"structure"` + + // The creation time of the global table. + CreationDateTime *time.Time `type:"timestamp"` + + // The unique identifier of the global table. + GlobalTableArn *string `type:"string"` + + // The global table name. + GlobalTableName *string `min:"3" type:"string"` + + // The current state of the global table: + // + // * CREATING - The global table is being created. + // + // * UPDATING - The global table is being updated. + // + // * DELETING - The global table is being deleted. + // + // * ACTIVE - The global table is ready for use. + GlobalTableStatus *string `type:"string" enum:"GlobalTableStatus"` + + // The Regions where the global table has replicas. + ReplicationGroup []*ReplicaDescription `type:"list"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s GlobalTableDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s GlobalTableDescription) GoString() string { + return s.String() +} + +// SetCreationDateTime sets the CreationDateTime field's value. +func (s *GlobalTableDescription) SetCreationDateTime(v time.Time) *GlobalTableDescription { + s.CreationDateTime = &v + return s +} + +// SetGlobalTableArn sets the GlobalTableArn field's value. +func (s *GlobalTableDescription) SetGlobalTableArn(v string) *GlobalTableDescription { + s.GlobalTableArn = &v + return s +} + +// SetGlobalTableName sets the GlobalTableName field's value. +func (s *GlobalTableDescription) SetGlobalTableName(v string) *GlobalTableDescription { + s.GlobalTableName = &v + return s +} + +// SetGlobalTableStatus sets the GlobalTableStatus field's value. +func (s *GlobalTableDescription) SetGlobalTableStatus(v string) *GlobalTableDescription { + s.GlobalTableStatus = &v + return s +} + +// SetReplicationGroup sets the ReplicationGroup field's value. +func (s *GlobalTableDescription) SetReplicationGroup(v []*ReplicaDescription) *GlobalTableDescription { + s.ReplicationGroup = v + return s +} + +// Represents the settings of a global secondary index for a global table that +// will be modified. +type GlobalTableGlobalSecondaryIndexSettingsUpdate struct { + _ struct{} `type:"structure"` + + // The name of the global secondary index. The name must be unique among all + // other indexes on this table. + // + // IndexName is a required field + IndexName *string `min:"3" type:"string" required:"true"` + + // Auto scaling settings for managing a global secondary index's write capacity + // units. + ProvisionedWriteCapacityAutoScalingSettingsUpdate *AutoScalingSettingsUpdate `type:"structure"` + + // The maximum number of writes consumed per second before DynamoDB returns + // a ThrottlingException. + ProvisionedWriteCapacityUnits *int64 `min:"1" type:"long"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s GlobalTableGlobalSecondaryIndexSettingsUpdate) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s GlobalTableGlobalSecondaryIndexSettingsUpdate) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GlobalTableGlobalSecondaryIndexSettingsUpdate) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GlobalTableGlobalSecondaryIndexSettingsUpdate"} + if s.IndexName == nil { + invalidParams.Add(request.NewErrParamRequired("IndexName")) + } + if s.IndexName != nil && len(*s.IndexName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("IndexName", 3)) + } + if s.ProvisionedWriteCapacityUnits != nil && *s.ProvisionedWriteCapacityUnits < 1 { + invalidParams.Add(request.NewErrParamMinValue("ProvisionedWriteCapacityUnits", 1)) + } + if s.ProvisionedWriteCapacityAutoScalingSettingsUpdate != nil { + if err := s.ProvisionedWriteCapacityAutoScalingSettingsUpdate.Validate(); err != nil { + invalidParams.AddNested("ProvisionedWriteCapacityAutoScalingSettingsUpdate", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetIndexName sets the IndexName field's value. +func (s *GlobalTableGlobalSecondaryIndexSettingsUpdate) SetIndexName(v string) *GlobalTableGlobalSecondaryIndexSettingsUpdate { + s.IndexName = &v + return s +} + +// SetProvisionedWriteCapacityAutoScalingSettingsUpdate sets the ProvisionedWriteCapacityAutoScalingSettingsUpdate field's value. +func (s *GlobalTableGlobalSecondaryIndexSettingsUpdate) SetProvisionedWriteCapacityAutoScalingSettingsUpdate(v *AutoScalingSettingsUpdate) *GlobalTableGlobalSecondaryIndexSettingsUpdate { + s.ProvisionedWriteCapacityAutoScalingSettingsUpdate = v + return s +} + +// SetProvisionedWriteCapacityUnits sets the ProvisionedWriteCapacityUnits field's value. +func (s *GlobalTableGlobalSecondaryIndexSettingsUpdate) SetProvisionedWriteCapacityUnits(v int64) *GlobalTableGlobalSecondaryIndexSettingsUpdate { + s.ProvisionedWriteCapacityUnits = &v + return s +} + +// The specified global table does not exist. +type GlobalTableNotFoundException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + Message_ *string `locationName:"message" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s GlobalTableNotFoundException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s GlobalTableNotFoundException) GoString() string { + return s.String() +} + +func newErrorGlobalTableNotFoundException(v protocol.ResponseMetadata) error { + return &GlobalTableNotFoundException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *GlobalTableNotFoundException) Code() string { + return "GlobalTableNotFoundException" +} + +// Message returns the exception's message. +func (s *GlobalTableNotFoundException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *GlobalTableNotFoundException) OrigErr() error { + return nil +} + +func (s *GlobalTableNotFoundException) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *GlobalTableNotFoundException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *GlobalTableNotFoundException) RequestID() string { + return s.RespMetadata.RequestID +} + +// DynamoDB rejected the request because you retried a request with a different +// payload but with an idempotent token that was already used. +type IdempotentParameterMismatchException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + Message_ *string `locationName:"Message" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s IdempotentParameterMismatchException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s IdempotentParameterMismatchException) GoString() string { + return s.String() +} + +func newErrorIdempotentParameterMismatchException(v protocol.ResponseMetadata) error { + return &IdempotentParameterMismatchException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *IdempotentParameterMismatchException) Code() string { + return "IdempotentParameterMismatchException" +} + +// Message returns the exception's message. +func (s *IdempotentParameterMismatchException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *IdempotentParameterMismatchException) OrigErr() error { + return nil +} + +func (s *IdempotentParameterMismatchException) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *IdempotentParameterMismatchException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *IdempotentParameterMismatchException) RequestID() string { + return s.RespMetadata.RequestID +} + +// The operation tried to access a nonexistent index. +type IndexNotFoundException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + Message_ *string `locationName:"message" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s IndexNotFoundException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s IndexNotFoundException) GoString() string { + return s.String() +} + +func newErrorIndexNotFoundException(v protocol.ResponseMetadata) error { + return &IndexNotFoundException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *IndexNotFoundException) Code() string { + return "IndexNotFoundException" +} + +// Message returns the exception's message. +func (s *IndexNotFoundException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *IndexNotFoundException) OrigErr() error { + return nil +} + +func (s *IndexNotFoundException) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *IndexNotFoundException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *IndexNotFoundException) RequestID() string { + return s.RespMetadata.RequestID +} + +// An error occurred on the server side. +type InternalServerError struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + // The server encountered an internal error trying to fulfill the request. + Message_ *string `locationName:"message" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s InternalServerError) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s InternalServerError) GoString() string { + return s.String() +} + +func newErrorInternalServerError(v protocol.ResponseMetadata) error { + return &InternalServerError{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *InternalServerError) Code() string { + return "InternalServerError" +} + +// Message returns the exception's message. +func (s *InternalServerError) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *InternalServerError) OrigErr() error { + return nil +} + +func (s *InternalServerError) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *InternalServerError) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *InternalServerError) RequestID() string { + return s.RespMetadata.RequestID +} + +// The specified ExportTime is outside of the point in time recovery window. +type InvalidExportTimeException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + Message_ *string `locationName:"message" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s InvalidExportTimeException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s InvalidExportTimeException) GoString() string { + return s.String() +} + +func newErrorInvalidExportTimeException(v protocol.ResponseMetadata) error { + return &InvalidExportTimeException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *InvalidExportTimeException) Code() string { + return "InvalidExportTimeException" +} + +// Message returns the exception's message. +func (s *InvalidExportTimeException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *InvalidExportTimeException) OrigErr() error { + return nil +} + +func (s *InvalidExportTimeException) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *InvalidExportTimeException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *InvalidExportTimeException) RequestID() string { + return s.RespMetadata.RequestID +} + +// An invalid restore time was specified. RestoreDateTime must be between EarliestRestorableDateTime +// and LatestRestorableDateTime. +type InvalidRestoreTimeException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + Message_ *string `locationName:"message" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s InvalidRestoreTimeException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s InvalidRestoreTimeException) GoString() string { + return s.String() +} + +func newErrorInvalidRestoreTimeException(v protocol.ResponseMetadata) error { + return &InvalidRestoreTimeException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *InvalidRestoreTimeException) Code() string { + return "InvalidRestoreTimeException" +} + +// Message returns the exception's message. +func (s *InvalidRestoreTimeException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *InvalidRestoreTimeException) OrigErr() error { + return nil +} + +func (s *InvalidRestoreTimeException) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *InvalidRestoreTimeException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *InvalidRestoreTimeException) RequestID() string { + return s.RespMetadata.RequestID +} + +// Information about item collections, if any, that were affected by the operation. +// ItemCollectionMetrics is only returned if the request asked for it. If the +// table does not have any local secondary indexes, this information is not +// returned in the response. +type ItemCollectionMetrics struct { + _ struct{} `type:"structure"` + + // The partition key value of the item collection. This value is the same as + // the partition key value of the item. + ItemCollectionKey map[string]*AttributeValue `type:"map"` + + // An estimate of item collection size, in gigabytes. This value is a two-element + // array containing a lower bound and an upper bound for the estimate. The estimate + // includes the size of all the items in the table, plus the size of all attributes + // projected into all of the local secondary indexes on that table. Use this + // estimate to measure whether a local secondary index is approaching its size + // limit. + // + // The estimate is subject to change over time; therefore, do not rely on the + // precision or accuracy of the estimate. + SizeEstimateRangeGB []*float64 `type:"list"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ItemCollectionMetrics) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ItemCollectionMetrics) GoString() string { + return s.String() +} + +// SetItemCollectionKey sets the ItemCollectionKey field's value. +func (s *ItemCollectionMetrics) SetItemCollectionKey(v map[string]*AttributeValue) *ItemCollectionMetrics { + s.ItemCollectionKey = v + return s +} + +// SetSizeEstimateRangeGB sets the SizeEstimateRangeGB field's value. +func (s *ItemCollectionMetrics) SetSizeEstimateRangeGB(v []*float64) *ItemCollectionMetrics { + s.SizeEstimateRangeGB = v + return s +} + +// An item collection is too large. This exception is only returned for tables +// that have one or more local secondary indexes. +type ItemCollectionSizeLimitExceededException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + // The total size of an item collection has exceeded the maximum limit of 10 + // gigabytes. + Message_ *string `locationName:"message" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ItemCollectionSizeLimitExceededException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ItemCollectionSizeLimitExceededException) GoString() string { + return s.String() +} + +func newErrorItemCollectionSizeLimitExceededException(v protocol.ResponseMetadata) error { + return &ItemCollectionSizeLimitExceededException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *ItemCollectionSizeLimitExceededException) Code() string { + return "ItemCollectionSizeLimitExceededException" +} + +// Message returns the exception's message. +func (s *ItemCollectionSizeLimitExceededException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *ItemCollectionSizeLimitExceededException) OrigErr() error { + return nil +} + +func (s *ItemCollectionSizeLimitExceededException) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *ItemCollectionSizeLimitExceededException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *ItemCollectionSizeLimitExceededException) RequestID() string { + return s.RespMetadata.RequestID +} + +// Details for the requested item. +type ItemResponse struct { + _ struct{} `type:"structure"` + + // Map of attribute data consisting of the data type and attribute value. + Item map[string]*AttributeValue `type:"map"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ItemResponse) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ItemResponse) GoString() string { + return s.String() +} + +// SetItem sets the Item field's value. +func (s *ItemResponse) SetItem(v map[string]*AttributeValue) *ItemResponse { + s.Item = v + return s +} + +// Represents a single element of a key schema. A key schema specifies the attributes +// that make up the primary key of a table, or the key attributes of an index. +// +// A KeySchemaElement represents exactly one attribute of the primary key. For +// example, a simple primary key would be represented by one KeySchemaElement +// (for the partition key). A composite primary key would require one KeySchemaElement +// for the partition key, and another KeySchemaElement for the sort key. +// +// A KeySchemaElement must be a scalar, top-level attribute (not a nested attribute). +// The data type must be one of String, Number, or Binary. The attribute cannot +// be nested within a List or a Map. +type KeySchemaElement struct { + _ struct{} `type:"structure"` + + // The name of a key attribute. + // + // AttributeName is a required field + AttributeName *string `min:"1" type:"string" required:"true"` + + // The role that this key attribute will assume: + // + // * HASH - partition key + // + // * RANGE - sort key + // + // The partition key of an item is also known as its hash attribute. The term + // "hash attribute" derives from DynamoDB's usage of an internal hash function + // to evenly distribute data items across partitions, based on their partition + // key values. + // + // The sort key of an item is also known as its range attribute. The term "range + // attribute" derives from the way DynamoDB stores items with the same partition + // key physically close together, in sorted order by the sort key value. + // + // KeyType is a required field + KeyType *string `type:"string" required:"true" enum:"KeyType"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s KeySchemaElement) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s KeySchemaElement) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *KeySchemaElement) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "KeySchemaElement"} + if s.AttributeName == nil { + invalidParams.Add(request.NewErrParamRequired("AttributeName")) + } + if s.AttributeName != nil && len(*s.AttributeName) < 1 { + invalidParams.Add(request.NewErrParamMinLen("AttributeName", 1)) + } + if s.KeyType == nil { + invalidParams.Add(request.NewErrParamRequired("KeyType")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAttributeName sets the AttributeName field's value. +func (s *KeySchemaElement) SetAttributeName(v string) *KeySchemaElement { + s.AttributeName = &v + return s +} + +// SetKeyType sets the KeyType field's value. +func (s *KeySchemaElement) SetKeyType(v string) *KeySchemaElement { + s.KeyType = &v + return s +} + +// Represents a set of primary keys and, for each key, the attributes to retrieve +// from the table. +// +// For each primary key, you must provide all of the key attributes. For example, +// with a simple primary key, you only need to provide the partition key. For +// a composite primary key, you must provide both the partition key and the +// sort key. +type KeysAndAttributes struct { + _ struct{} `type:"structure"` + + // This is a legacy parameter. Use ProjectionExpression instead. For more information, + // see Legacy Conditional Parameters (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.html) + // in the Amazon DynamoDB Developer Guide. + AttributesToGet []*string `min:"1" type:"list"` + + // The consistency of a read operation. If set to true, then a strongly consistent + // read is used; otherwise, an eventually consistent read is used. + ConsistentRead *bool `type:"boolean"` + + // One or more substitution tokens for attribute names in an expression. The + // following are some use cases for using ExpressionAttributeNames: + // + // * To access an attribute whose name conflicts with a DynamoDB reserved + // word. + // + // * To create a placeholder for repeating occurrences of an attribute name + // in an expression. + // + // * To prevent special characters in an attribute name from being misinterpreted + // in an expression. + // + // Use the # character in an expression to dereference an attribute name. For + // example, consider the following attribute name: + // + // * Percentile + // + // The name of this attribute conflicts with a reserved word, so it cannot be + // used directly in an expression. (For the complete list of reserved words, + // see Reserved Words (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html) + // in the Amazon DynamoDB Developer Guide). To work around this, you could specify + // the following for ExpressionAttributeNames: + // + // * {"#P":"Percentile"} + // + // You could then use this substitution in an expression, as in this example: + // + // * #P = :val + // + // Tokens that begin with the : character are expression attribute values, which + // are placeholders for the actual value at runtime. + // + // For more information on expression attribute names, see Accessing Item Attributes + // (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.AccessingItemAttributes.html) + // in the Amazon DynamoDB Developer Guide. + ExpressionAttributeNames map[string]*string `type:"map"` + + // The primary key attribute values that define the items and the attributes + // associated with the items. + // + // Keys is a required field + Keys []map[string]*AttributeValue `min:"1" type:"list" required:"true"` + + // A string that identifies one or more attributes to retrieve from the table. + // These attributes can include scalars, sets, or elements of a JSON document. + // The attributes in the ProjectionExpression must be separated by commas. + // + // If no attribute names are specified, then all attributes will be returned. + // If any of the requested attributes are not found, they will not appear in + // the result. + // + // For more information, see Accessing Item Attributes (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.AccessingItemAttributes.html) + // in the Amazon DynamoDB Developer Guide. + ProjectionExpression *string `type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s KeysAndAttributes) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s KeysAndAttributes) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *KeysAndAttributes) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "KeysAndAttributes"} + if s.AttributesToGet != nil && len(s.AttributesToGet) < 1 { + invalidParams.Add(request.NewErrParamMinLen("AttributesToGet", 1)) + } + if s.Keys == nil { + invalidParams.Add(request.NewErrParamRequired("Keys")) + } + if s.Keys != nil && len(s.Keys) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Keys", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAttributesToGet sets the AttributesToGet field's value. +func (s *KeysAndAttributes) SetAttributesToGet(v []*string) *KeysAndAttributes { + s.AttributesToGet = v + return s +} + +// SetConsistentRead sets the ConsistentRead field's value. +func (s *KeysAndAttributes) SetConsistentRead(v bool) *KeysAndAttributes { + s.ConsistentRead = &v + return s +} + +// SetExpressionAttributeNames sets the ExpressionAttributeNames field's value. +func (s *KeysAndAttributes) SetExpressionAttributeNames(v map[string]*string) *KeysAndAttributes { + s.ExpressionAttributeNames = v + return s +} + +// SetKeys sets the Keys field's value. +func (s *KeysAndAttributes) SetKeys(v []map[string]*AttributeValue) *KeysAndAttributes { + s.Keys = v + return s +} + +// SetProjectionExpression sets the ProjectionExpression field's value. +func (s *KeysAndAttributes) SetProjectionExpression(v string) *KeysAndAttributes { + s.ProjectionExpression = &v + return s +} + +// Describes a Kinesis data stream destination. +type KinesisDataStreamDestination struct { + _ struct{} `type:"structure"` + + // The current status of replication. + DestinationStatus *string `type:"string" enum:"DestinationStatus"` + + // The human-readable string that corresponds to the replica status. + DestinationStatusDescription *string `type:"string"` + + // The ARN for a specific Kinesis data stream. + StreamArn *string `min:"37" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s KinesisDataStreamDestination) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s KinesisDataStreamDestination) GoString() string { + return s.String() +} + +// SetDestinationStatus sets the DestinationStatus field's value. +func (s *KinesisDataStreamDestination) SetDestinationStatus(v string) *KinesisDataStreamDestination { + s.DestinationStatus = &v + return s +} + +// SetDestinationStatusDescription sets the DestinationStatusDescription field's value. +func (s *KinesisDataStreamDestination) SetDestinationStatusDescription(v string) *KinesisDataStreamDestination { + s.DestinationStatusDescription = &v + return s +} + +// SetStreamArn sets the StreamArn field's value. +func (s *KinesisDataStreamDestination) SetStreamArn(v string) *KinesisDataStreamDestination { + s.StreamArn = &v + return s +} + +// There is no limit to the number of daily on-demand backups that can be taken. +// +// Up to 50 simultaneous table operations are allowed per account. These operations +// include CreateTable, UpdateTable, DeleteTable,UpdateTimeToLive, RestoreTableFromBackup, +// and RestoreTableToPointInTime. +// +// The only exception is when you are creating a table with one or more secondary +// indexes. You can have up to 25 such requests running at a time; however, +// if the table or index specifications are complex, DynamoDB might temporarily +// reduce the number of concurrent operations. +// +// There is a soft account quota of 256 tables. +type LimitExceededException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + // Too many operations for a given subscriber. + Message_ *string `locationName:"message" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s LimitExceededException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s LimitExceededException) GoString() string { + return s.String() +} + +func newErrorLimitExceededException(v protocol.ResponseMetadata) error { + return &LimitExceededException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *LimitExceededException) Code() string { + return "LimitExceededException" +} + +// Message returns the exception's message. +func (s *LimitExceededException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *LimitExceededException) OrigErr() error { + return nil +} + +func (s *LimitExceededException) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *LimitExceededException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *LimitExceededException) RequestID() string { + return s.RespMetadata.RequestID +} + +type ListBackupsInput struct { + _ struct{} `type:"structure"` + + // The backups from the table specified by BackupType are listed. + // + // Where BackupType can be: + // + // * USER - On-demand backup created by you. + // + // * SYSTEM - On-demand backup automatically created by DynamoDB. + // + // * ALL - All types of on-demand backups (USER and SYSTEM). + BackupType *string `type:"string" enum:"BackupTypeFilter"` + + // LastEvaluatedBackupArn is the Amazon Resource Name (ARN) of the backup last + // evaluated when the current page of results was returned, inclusive of the + // current page of results. This value may be specified as the ExclusiveStartBackupArn + // of a new ListBackups operation in order to fetch the next page of results. + ExclusiveStartBackupArn *string `min:"37" type:"string"` + + // Maximum number of backups to return at once. + Limit *int64 `min:"1" type:"integer"` + + // The backups from the table specified by TableName are listed. + TableName *string `min:"3" type:"string"` + + // Only backups created after this time are listed. TimeRangeLowerBound is inclusive. + TimeRangeLowerBound *time.Time `type:"timestamp"` + + // Only backups created before this time are listed. TimeRangeUpperBound is + // exclusive. + TimeRangeUpperBound *time.Time `type:"timestamp"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ListBackupsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ListBackupsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ListBackupsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ListBackupsInput"} + if s.ExclusiveStartBackupArn != nil && len(*s.ExclusiveStartBackupArn) < 37 { + invalidParams.Add(request.NewErrParamMinLen("ExclusiveStartBackupArn", 37)) + } + if s.Limit != nil && *s.Limit < 1 { + invalidParams.Add(request.NewErrParamMinValue("Limit", 1)) + } + if s.TableName != nil && len(*s.TableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("TableName", 3)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetBackupType sets the BackupType field's value. +func (s *ListBackupsInput) SetBackupType(v string) *ListBackupsInput { + s.BackupType = &v + return s +} + +// SetExclusiveStartBackupArn sets the ExclusiveStartBackupArn field's value. +func (s *ListBackupsInput) SetExclusiveStartBackupArn(v string) *ListBackupsInput { + s.ExclusiveStartBackupArn = &v + return s +} + +// SetLimit sets the Limit field's value. +func (s *ListBackupsInput) SetLimit(v int64) *ListBackupsInput { + s.Limit = &v + return s +} + +// SetTableName sets the TableName field's value. +func (s *ListBackupsInput) SetTableName(v string) *ListBackupsInput { + s.TableName = &v + return s +} + +// SetTimeRangeLowerBound sets the TimeRangeLowerBound field's value. +func (s *ListBackupsInput) SetTimeRangeLowerBound(v time.Time) *ListBackupsInput { + s.TimeRangeLowerBound = &v + return s +} + +// SetTimeRangeUpperBound sets the TimeRangeUpperBound field's value. +func (s *ListBackupsInput) SetTimeRangeUpperBound(v time.Time) *ListBackupsInput { + s.TimeRangeUpperBound = &v + return s +} + +type ListBackupsOutput struct { + _ struct{} `type:"structure"` + + // List of BackupSummary objects. + BackupSummaries []*BackupSummary `type:"list"` + + // The ARN of the backup last evaluated when the current page of results was + // returned, inclusive of the current page of results. This value may be specified + // as the ExclusiveStartBackupArn of a new ListBackups operation in order to + // fetch the next page of results. + // + // If LastEvaluatedBackupArn is empty, then the last page of results has been + // processed and there are no more results to be retrieved. + // + // If LastEvaluatedBackupArn is not empty, this may or may not indicate that + // there is more data to be returned. All results are guaranteed to have been + // returned if and only if no value for LastEvaluatedBackupArn is returned. + LastEvaluatedBackupArn *string `min:"37" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ListBackupsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ListBackupsOutput) GoString() string { + return s.String() +} + +// SetBackupSummaries sets the BackupSummaries field's value. +func (s *ListBackupsOutput) SetBackupSummaries(v []*BackupSummary) *ListBackupsOutput { + s.BackupSummaries = v + return s +} + +// SetLastEvaluatedBackupArn sets the LastEvaluatedBackupArn field's value. +func (s *ListBackupsOutput) SetLastEvaluatedBackupArn(v string) *ListBackupsOutput { + s.LastEvaluatedBackupArn = &v + return s +} + +type ListContributorInsightsInput struct { + _ struct{} `type:"structure"` + + // Maximum number of results to return per page. + MaxResults *int64 `type:"integer"` + + // A token to for the desired page, if there is one. + NextToken *string `type:"string"` + + // The name of the table. + TableName *string `min:"3" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ListContributorInsightsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ListContributorInsightsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ListContributorInsightsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ListContributorInsightsInput"} + if s.TableName != nil && len(*s.TableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("TableName", 3)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetMaxResults sets the MaxResults field's value. +func (s *ListContributorInsightsInput) SetMaxResults(v int64) *ListContributorInsightsInput { + s.MaxResults = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *ListContributorInsightsInput) SetNextToken(v string) *ListContributorInsightsInput { + s.NextToken = &v + return s +} + +// SetTableName sets the TableName field's value. +func (s *ListContributorInsightsInput) SetTableName(v string) *ListContributorInsightsInput { + s.TableName = &v + return s +} + +type ListContributorInsightsOutput struct { + _ struct{} `type:"structure"` + + // A list of ContributorInsightsSummary. + ContributorInsightsSummaries []*ContributorInsightsSummary `type:"list"` + + // A token to go to the next page if there is one. + NextToken *string `type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ListContributorInsightsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ListContributorInsightsOutput) GoString() string { + return s.String() +} + +// SetContributorInsightsSummaries sets the ContributorInsightsSummaries field's value. +func (s *ListContributorInsightsOutput) SetContributorInsightsSummaries(v []*ContributorInsightsSummary) *ListContributorInsightsOutput { + s.ContributorInsightsSummaries = v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *ListContributorInsightsOutput) SetNextToken(v string) *ListContributorInsightsOutput { + s.NextToken = &v + return s +} + +type ListExportsInput struct { + _ struct{} `type:"structure"` + + // Maximum number of results to return per page. + MaxResults *int64 `min:"1" type:"integer"` + + // An optional string that, if supplied, must be copied from the output of a + // previous call to ListExports. When provided in this manner, the API fetches + // the next page of results. + NextToken *string `type:"string"` + + // The Amazon Resource Name (ARN) associated with the exported table. + TableArn *string `type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ListExportsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ListExportsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ListExportsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ListExportsInput"} + if s.MaxResults != nil && *s.MaxResults < 1 { + invalidParams.Add(request.NewErrParamMinValue("MaxResults", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetMaxResults sets the MaxResults field's value. +func (s *ListExportsInput) SetMaxResults(v int64) *ListExportsInput { + s.MaxResults = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *ListExportsInput) SetNextToken(v string) *ListExportsInput { + s.NextToken = &v + return s +} + +// SetTableArn sets the TableArn field's value. +func (s *ListExportsInput) SetTableArn(v string) *ListExportsInput { + s.TableArn = &v + return s +} + +type ListExportsOutput struct { + _ struct{} `type:"structure"` + + // A list of ExportSummary objects. + ExportSummaries []*ExportSummary `type:"list"` + + // If this value is returned, there are additional results to be displayed. + // To retrieve them, call ListExports again, with NextToken set to this value. + NextToken *string `type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ListExportsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ListExportsOutput) GoString() string { + return s.String() +} + +// SetExportSummaries sets the ExportSummaries field's value. +func (s *ListExportsOutput) SetExportSummaries(v []*ExportSummary) *ListExportsOutput { + s.ExportSummaries = v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *ListExportsOutput) SetNextToken(v string) *ListExportsOutput { + s.NextToken = &v + return s +} + +type ListGlobalTablesInput struct { + _ struct{} `type:"structure"` + + // The first global table name that this operation will evaluate. + ExclusiveStartGlobalTableName *string `min:"3" type:"string"` + + // The maximum number of table names to return, if the parameter is not specified + // DynamoDB defaults to 100. + // + // If the number of global tables DynamoDB finds reaches this limit, it stops + // the operation and returns the table names collected up to that point, with + // a table name in the LastEvaluatedGlobalTableName to apply in a subsequent + // operation to the ExclusiveStartGlobalTableName parameter. + Limit *int64 `min:"1" type:"integer"` + + // Lists the global tables in a specific Region. + RegionName *string `type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ListGlobalTablesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ListGlobalTablesInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ListGlobalTablesInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ListGlobalTablesInput"} + if s.ExclusiveStartGlobalTableName != nil && len(*s.ExclusiveStartGlobalTableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("ExclusiveStartGlobalTableName", 3)) + } + if s.Limit != nil && *s.Limit < 1 { + invalidParams.Add(request.NewErrParamMinValue("Limit", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetExclusiveStartGlobalTableName sets the ExclusiveStartGlobalTableName field's value. +func (s *ListGlobalTablesInput) SetExclusiveStartGlobalTableName(v string) *ListGlobalTablesInput { + s.ExclusiveStartGlobalTableName = &v + return s +} + +// SetLimit sets the Limit field's value. +func (s *ListGlobalTablesInput) SetLimit(v int64) *ListGlobalTablesInput { + s.Limit = &v + return s +} + +// SetRegionName sets the RegionName field's value. +func (s *ListGlobalTablesInput) SetRegionName(v string) *ListGlobalTablesInput { + s.RegionName = &v + return s +} + +type ListGlobalTablesOutput struct { + _ struct{} `type:"structure"` + + // List of global table names. + GlobalTables []*GlobalTable `type:"list"` + + // Last evaluated global table name. + LastEvaluatedGlobalTableName *string `min:"3" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ListGlobalTablesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ListGlobalTablesOutput) GoString() string { + return s.String() +} + +// SetGlobalTables sets the GlobalTables field's value. +func (s *ListGlobalTablesOutput) SetGlobalTables(v []*GlobalTable) *ListGlobalTablesOutput { + s.GlobalTables = v + return s +} + +// SetLastEvaluatedGlobalTableName sets the LastEvaluatedGlobalTableName field's value. +func (s *ListGlobalTablesOutput) SetLastEvaluatedGlobalTableName(v string) *ListGlobalTablesOutput { + s.LastEvaluatedGlobalTableName = &v + return s +} + +// Represents the input of a ListTables operation. +type ListTablesInput struct { + _ struct{} `type:"structure"` + + // The first table name that this operation will evaluate. Use the value that + // was returned for LastEvaluatedTableName in a previous operation, so that + // you can obtain the next page of results. + ExclusiveStartTableName *string `min:"3" type:"string"` + + // A maximum number of table names to return. If this parameter is not specified, + // the limit is 100. + Limit *int64 `min:"1" type:"integer"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ListTablesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ListTablesInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ListTablesInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ListTablesInput"} + if s.ExclusiveStartTableName != nil && len(*s.ExclusiveStartTableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("ExclusiveStartTableName", 3)) + } + if s.Limit != nil && *s.Limit < 1 { + invalidParams.Add(request.NewErrParamMinValue("Limit", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetExclusiveStartTableName sets the ExclusiveStartTableName field's value. +func (s *ListTablesInput) SetExclusiveStartTableName(v string) *ListTablesInput { + s.ExclusiveStartTableName = &v + return s +} + +// SetLimit sets the Limit field's value. +func (s *ListTablesInput) SetLimit(v int64) *ListTablesInput { + s.Limit = &v + return s +} + +// Represents the output of a ListTables operation. +type ListTablesOutput struct { + _ struct{} `type:"structure"` + + // The name of the last table in the current page of results. Use this value + // as the ExclusiveStartTableName in a new request to obtain the next page of + // results, until all the table names are returned. + // + // If you do not receive a LastEvaluatedTableName value in the response, this + // means that there are no more table names to be retrieved. + LastEvaluatedTableName *string `min:"3" type:"string"` + + // The names of the tables associated with the current account at the current + // endpoint. The maximum size of this array is 100. + // + // If LastEvaluatedTableName also appears in the output, you can use this value + // as the ExclusiveStartTableName parameter in a subsequent ListTables request + // and obtain the next page of results. + TableNames []*string `type:"list"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ListTablesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ListTablesOutput) GoString() string { + return s.String() +} + +// SetLastEvaluatedTableName sets the LastEvaluatedTableName field's value. +func (s *ListTablesOutput) SetLastEvaluatedTableName(v string) *ListTablesOutput { + s.LastEvaluatedTableName = &v + return s +} + +// SetTableNames sets the TableNames field's value. +func (s *ListTablesOutput) SetTableNames(v []*string) *ListTablesOutput { + s.TableNames = v + return s +} + +type ListTagsOfResourceInput struct { + _ struct{} `type:"structure"` + + // An optional string that, if supplied, must be copied from the output of a + // previous call to ListTagOfResource. When provided in this manner, this API + // fetches the next page of results. + NextToken *string `type:"string"` + + // The Amazon DynamoDB resource with tags to be listed. This value is an Amazon + // Resource Name (ARN). + // + // ResourceArn is a required field + ResourceArn *string `min:"1" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ListTagsOfResourceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ListTagsOfResourceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ListTagsOfResourceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ListTagsOfResourceInput"} + if s.ResourceArn == nil { + invalidParams.Add(request.NewErrParamRequired("ResourceArn")) + } + if s.ResourceArn != nil && len(*s.ResourceArn) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ResourceArn", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetNextToken sets the NextToken field's value. +func (s *ListTagsOfResourceInput) SetNextToken(v string) *ListTagsOfResourceInput { + s.NextToken = &v + return s +} + +// SetResourceArn sets the ResourceArn field's value. +func (s *ListTagsOfResourceInput) SetResourceArn(v string) *ListTagsOfResourceInput { + s.ResourceArn = &v + return s +} + +type ListTagsOfResourceOutput struct { + _ struct{} `type:"structure"` + + // If this value is returned, there are additional results to be displayed. + // To retrieve them, call ListTagsOfResource again, with NextToken set to this + // value. + NextToken *string `type:"string"` + + // The tags currently associated with the Amazon DynamoDB resource. + Tags []*Tag `type:"list"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ListTagsOfResourceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ListTagsOfResourceOutput) GoString() string { + return s.String() +} + +// SetNextToken sets the NextToken field's value. +func (s *ListTagsOfResourceOutput) SetNextToken(v string) *ListTagsOfResourceOutput { + s.NextToken = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *ListTagsOfResourceOutput) SetTags(v []*Tag) *ListTagsOfResourceOutput { + s.Tags = v + return s +} + +// Represents the properties of a local secondary index. +type LocalSecondaryIndex struct { + _ struct{} `type:"structure"` + + // The name of the local secondary index. The name must be unique among all + // other indexes on this table. + // + // IndexName is a required field + IndexName *string `min:"3" type:"string" required:"true"` + + // The complete key schema for the local secondary index, consisting of one + // or more pairs of attribute names and key types: + // + // * HASH - partition key + // + // * RANGE - sort key + // + // The partition key of an item is also known as its hash attribute. The term + // "hash attribute" derives from DynamoDB's usage of an internal hash function + // to evenly distribute data items across partitions, based on their partition + // key values. + // + // The sort key of an item is also known as its range attribute. The term "range + // attribute" derives from the way DynamoDB stores items with the same partition + // key physically close together, in sorted order by the sort key value. + // + // KeySchema is a required field + KeySchema []*KeySchemaElement `min:"1" type:"list" required:"true"` + + // Represents attributes that are copied (projected) from the table into the + // local secondary index. These are in addition to the primary key attributes + // and index key attributes, which are automatically projected. + // + // Projection is a required field + Projection *Projection `type:"structure" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s LocalSecondaryIndex) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s LocalSecondaryIndex) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *LocalSecondaryIndex) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "LocalSecondaryIndex"} + if s.IndexName == nil { + invalidParams.Add(request.NewErrParamRequired("IndexName")) + } + if s.IndexName != nil && len(*s.IndexName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("IndexName", 3)) + } + if s.KeySchema == nil { + invalidParams.Add(request.NewErrParamRequired("KeySchema")) + } + if s.KeySchema != nil && len(s.KeySchema) < 1 { + invalidParams.Add(request.NewErrParamMinLen("KeySchema", 1)) + } + if s.Projection == nil { + invalidParams.Add(request.NewErrParamRequired("Projection")) + } + if s.KeySchema != nil { + for i, v := range s.KeySchema { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "KeySchema", i), err.(request.ErrInvalidParams)) + } + } + } + if s.Projection != nil { + if err := s.Projection.Validate(); err != nil { + invalidParams.AddNested("Projection", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetIndexName sets the IndexName field's value. +func (s *LocalSecondaryIndex) SetIndexName(v string) *LocalSecondaryIndex { + s.IndexName = &v + return s +} + +// SetKeySchema sets the KeySchema field's value. +func (s *LocalSecondaryIndex) SetKeySchema(v []*KeySchemaElement) *LocalSecondaryIndex { + s.KeySchema = v + return s +} + +// SetProjection sets the Projection field's value. +func (s *LocalSecondaryIndex) SetProjection(v *Projection) *LocalSecondaryIndex { + s.Projection = v + return s +} + +// Represents the properties of a local secondary index. +type LocalSecondaryIndexDescription struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) that uniquely identifies the index. + IndexArn *string `type:"string"` + + // Represents the name of the local secondary index. + IndexName *string `min:"3" type:"string"` + + // The total size of the specified index, in bytes. DynamoDB updates this value + // approximately every six hours. Recent changes might not be reflected in this + // value. + IndexSizeBytes *int64 `type:"long"` + + // The number of items in the specified index. DynamoDB updates this value approximately + // every six hours. Recent changes might not be reflected in this value. + ItemCount *int64 `type:"long"` + + // The complete key schema for the local secondary index, consisting of one + // or more pairs of attribute names and key types: + // + // * HASH - partition key + // + // * RANGE - sort key + // + // The partition key of an item is also known as its hash attribute. The term + // "hash attribute" derives from DynamoDB's usage of an internal hash function + // to evenly distribute data items across partitions, based on their partition + // key values. + // + // The sort key of an item is also known as its range attribute. The term "range + // attribute" derives from the way DynamoDB stores items with the same partition + // key physically close together, in sorted order by the sort key value. + KeySchema []*KeySchemaElement `min:"1" type:"list"` + + // Represents attributes that are copied (projected) from the table into the + // global secondary index. These are in addition to the primary key attributes + // and index key attributes, which are automatically projected. + Projection *Projection `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s LocalSecondaryIndexDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s LocalSecondaryIndexDescription) GoString() string { + return s.String() +} + +// SetIndexArn sets the IndexArn field's value. +func (s *LocalSecondaryIndexDescription) SetIndexArn(v string) *LocalSecondaryIndexDescription { + s.IndexArn = &v + return s +} + +// SetIndexName sets the IndexName field's value. +func (s *LocalSecondaryIndexDescription) SetIndexName(v string) *LocalSecondaryIndexDescription { + s.IndexName = &v + return s +} + +// SetIndexSizeBytes sets the IndexSizeBytes field's value. +func (s *LocalSecondaryIndexDescription) SetIndexSizeBytes(v int64) *LocalSecondaryIndexDescription { + s.IndexSizeBytes = &v + return s +} + +// SetItemCount sets the ItemCount field's value. +func (s *LocalSecondaryIndexDescription) SetItemCount(v int64) *LocalSecondaryIndexDescription { + s.ItemCount = &v + return s +} + +// SetKeySchema sets the KeySchema field's value. +func (s *LocalSecondaryIndexDescription) SetKeySchema(v []*KeySchemaElement) *LocalSecondaryIndexDescription { + s.KeySchema = v + return s +} + +// SetProjection sets the Projection field's value. +func (s *LocalSecondaryIndexDescription) SetProjection(v *Projection) *LocalSecondaryIndexDescription { + s.Projection = v + return s +} + +// Represents the properties of a local secondary index for the table when the +// backup was created. +type LocalSecondaryIndexInfo struct { + _ struct{} `type:"structure"` + + // Represents the name of the local secondary index. + IndexName *string `min:"3" type:"string"` + + // The complete key schema for a local secondary index, which consists of one + // or more pairs of attribute names and key types: + // + // * HASH - partition key + // + // * RANGE - sort key + // + // The partition key of an item is also known as its hash attribute. The term + // "hash attribute" derives from DynamoDB's usage of an internal hash function + // to evenly distribute data items across partitions, based on their partition + // key values. + // + // The sort key of an item is also known as its range attribute. The term "range + // attribute" derives from the way DynamoDB stores items with the same partition + // key physically close together, in sorted order by the sort key value. + KeySchema []*KeySchemaElement `min:"1" type:"list"` + + // Represents attributes that are copied (projected) from the table into the + // global secondary index. These are in addition to the primary key attributes + // and index key attributes, which are automatically projected. + Projection *Projection `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s LocalSecondaryIndexInfo) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s LocalSecondaryIndexInfo) GoString() string { + return s.String() +} + +// SetIndexName sets the IndexName field's value. +func (s *LocalSecondaryIndexInfo) SetIndexName(v string) *LocalSecondaryIndexInfo { + s.IndexName = &v + return s +} + +// SetKeySchema sets the KeySchema field's value. +func (s *LocalSecondaryIndexInfo) SetKeySchema(v []*KeySchemaElement) *LocalSecondaryIndexInfo { + s.KeySchema = v + return s +} + +// SetProjection sets the Projection field's value. +func (s *LocalSecondaryIndexInfo) SetProjection(v *Projection) *LocalSecondaryIndexInfo { + s.Projection = v + return s +} + +// Represents a PartiQL statment that uses parameters. +type ParameterizedStatement struct { + _ struct{} `type:"structure"` + + // The parameter values. + Parameters []*AttributeValue `min:"1" type:"list"` + + // A PartiQL statment that uses parameters. + // + // Statement is a required field + Statement *string `min:"1" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ParameterizedStatement) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ParameterizedStatement) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ParameterizedStatement) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ParameterizedStatement"} + if s.Parameters != nil && len(s.Parameters) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Parameters", 1)) + } + if s.Statement == nil { + invalidParams.Add(request.NewErrParamRequired("Statement")) + } + if s.Statement != nil && len(*s.Statement) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Statement", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetParameters sets the Parameters field's value. +func (s *ParameterizedStatement) SetParameters(v []*AttributeValue) *ParameterizedStatement { + s.Parameters = v + return s +} + +// SetStatement sets the Statement field's value. +func (s *ParameterizedStatement) SetStatement(v string) *ParameterizedStatement { + s.Statement = &v + return s +} + +// The description of the point in time settings applied to the table. +type PointInTimeRecoveryDescription struct { + _ struct{} `type:"structure"` + + // Specifies the earliest point in time you can restore your table to. You can + // restore your table to any point in time during the last 35 days. + EarliestRestorableDateTime *time.Time `type:"timestamp"` + + // LatestRestorableDateTime is typically 5 minutes before the current time. + LatestRestorableDateTime *time.Time `type:"timestamp"` + + // The current state of point in time recovery: + // + // * ENABLING - Point in time recovery is being enabled. + // + // * ENABLED - Point in time recovery is enabled. + // + // * DISABLED - Point in time recovery is disabled. + PointInTimeRecoveryStatus *string `type:"string" enum:"PointInTimeRecoveryStatus"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s PointInTimeRecoveryDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s PointInTimeRecoveryDescription) GoString() string { + return s.String() +} + +// SetEarliestRestorableDateTime sets the EarliestRestorableDateTime field's value. +func (s *PointInTimeRecoveryDescription) SetEarliestRestorableDateTime(v time.Time) *PointInTimeRecoveryDescription { + s.EarliestRestorableDateTime = &v + return s +} + +// SetLatestRestorableDateTime sets the LatestRestorableDateTime field's value. +func (s *PointInTimeRecoveryDescription) SetLatestRestorableDateTime(v time.Time) *PointInTimeRecoveryDescription { + s.LatestRestorableDateTime = &v + return s +} + +// SetPointInTimeRecoveryStatus sets the PointInTimeRecoveryStatus field's value. +func (s *PointInTimeRecoveryDescription) SetPointInTimeRecoveryStatus(v string) *PointInTimeRecoveryDescription { + s.PointInTimeRecoveryStatus = &v + return s +} + +// Represents the settings used to enable point in time recovery. +type PointInTimeRecoverySpecification struct { + _ struct{} `type:"structure"` + + // Indicates whether point in time recovery is enabled (true) or disabled (false) + // on the table. + // + // PointInTimeRecoveryEnabled is a required field + PointInTimeRecoveryEnabled *bool `type:"boolean" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s PointInTimeRecoverySpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s PointInTimeRecoverySpecification) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *PointInTimeRecoverySpecification) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "PointInTimeRecoverySpecification"} + if s.PointInTimeRecoveryEnabled == nil { + invalidParams.Add(request.NewErrParamRequired("PointInTimeRecoveryEnabled")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetPointInTimeRecoveryEnabled sets the PointInTimeRecoveryEnabled field's value. +func (s *PointInTimeRecoverySpecification) SetPointInTimeRecoveryEnabled(v bool) *PointInTimeRecoverySpecification { + s.PointInTimeRecoveryEnabled = &v + return s +} + +// Point in time recovery has not yet been enabled for this source table. +type PointInTimeRecoveryUnavailableException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + Message_ *string `locationName:"message" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s PointInTimeRecoveryUnavailableException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s PointInTimeRecoveryUnavailableException) GoString() string { + return s.String() +} + +func newErrorPointInTimeRecoveryUnavailableException(v protocol.ResponseMetadata) error { + return &PointInTimeRecoveryUnavailableException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *PointInTimeRecoveryUnavailableException) Code() string { + return "PointInTimeRecoveryUnavailableException" +} + +// Message returns the exception's message. +func (s *PointInTimeRecoveryUnavailableException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *PointInTimeRecoveryUnavailableException) OrigErr() error { + return nil +} + +func (s *PointInTimeRecoveryUnavailableException) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *PointInTimeRecoveryUnavailableException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *PointInTimeRecoveryUnavailableException) RequestID() string { + return s.RespMetadata.RequestID +} + +// Represents attributes that are copied (projected) from the table into an +// index. These are in addition to the primary key attributes and index key +// attributes, which are automatically projected. +type Projection struct { + _ struct{} `type:"structure"` + + // Represents the non-key attribute names which will be projected into the index. + // + // For local secondary indexes, the total count of NonKeyAttributes summed across + // all of the local secondary indexes, must not exceed 20. If you project the + // same attribute into two different indexes, this counts as two distinct attributes + // when determining the total. + NonKeyAttributes []*string `min:"1" type:"list"` + + // The set of attributes that are projected into the index: + // + // * KEYS_ONLY - Only the index and primary keys are projected into the index. + // + // * INCLUDE - In addition to the attributes described in KEYS_ONLY, the + // secondary index will include other non-key attributes that you specify. + // + // * ALL - All of the table attributes are projected into the index. + ProjectionType *string `type:"string" enum:"ProjectionType"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s Projection) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s Projection) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *Projection) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "Projection"} + if s.NonKeyAttributes != nil && len(s.NonKeyAttributes) < 1 { + invalidParams.Add(request.NewErrParamMinLen("NonKeyAttributes", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetNonKeyAttributes sets the NonKeyAttributes field's value. +func (s *Projection) SetNonKeyAttributes(v []*string) *Projection { + s.NonKeyAttributes = v + return s +} + +// SetProjectionType sets the ProjectionType field's value. +func (s *Projection) SetProjectionType(v string) *Projection { + s.ProjectionType = &v + return s +} + +// Represents the provisioned throughput settings for a specified table or index. +// The settings can be modified using the UpdateTable operation. +// +// For current minimum and maximum provisioned throughput values, see Service, +// Account, and Table Quotas (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Limits.html) +// in the Amazon DynamoDB Developer Guide. +type ProvisionedThroughput struct { + _ struct{} `type:"structure"` + + // The maximum number of strongly consistent reads consumed per second before + // DynamoDB returns a ThrottlingException. For more information, see Specifying + // Read and Write Requirements (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithTables.html#ProvisionedThroughput) + // in the Amazon DynamoDB Developer Guide. + // + // If read/write capacity mode is PAY_PER_REQUEST the value is set to 0. + // + // ReadCapacityUnits is a required field + ReadCapacityUnits *int64 `min:"1" type:"long" required:"true"` + + // The maximum number of writes consumed per second before DynamoDB returns + // a ThrottlingException. For more information, see Specifying Read and Write + // Requirements (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithTables.html#ProvisionedThroughput) + // in the Amazon DynamoDB Developer Guide. + // + // If read/write capacity mode is PAY_PER_REQUEST the value is set to 0. + // + // WriteCapacityUnits is a required field + WriteCapacityUnits *int64 `min:"1" type:"long" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ProvisionedThroughput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ProvisionedThroughput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ProvisionedThroughput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ProvisionedThroughput"} + if s.ReadCapacityUnits == nil { + invalidParams.Add(request.NewErrParamRequired("ReadCapacityUnits")) + } + if s.ReadCapacityUnits != nil && *s.ReadCapacityUnits < 1 { + invalidParams.Add(request.NewErrParamMinValue("ReadCapacityUnits", 1)) + } + if s.WriteCapacityUnits == nil { + invalidParams.Add(request.NewErrParamRequired("WriteCapacityUnits")) + } + if s.WriteCapacityUnits != nil && *s.WriteCapacityUnits < 1 { + invalidParams.Add(request.NewErrParamMinValue("WriteCapacityUnits", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetReadCapacityUnits sets the ReadCapacityUnits field's value. +func (s *ProvisionedThroughput) SetReadCapacityUnits(v int64) *ProvisionedThroughput { + s.ReadCapacityUnits = &v + return s +} + +// SetWriteCapacityUnits sets the WriteCapacityUnits field's value. +func (s *ProvisionedThroughput) SetWriteCapacityUnits(v int64) *ProvisionedThroughput { + s.WriteCapacityUnits = &v + return s +} + +// Represents the provisioned throughput settings for the table, consisting +// of read and write capacity units, along with data about increases and decreases. +type ProvisionedThroughputDescription struct { + _ struct{} `type:"structure"` + + // The date and time of the last provisioned throughput decrease for this table. + LastDecreaseDateTime *time.Time `type:"timestamp"` + + // The date and time of the last provisioned throughput increase for this table. + LastIncreaseDateTime *time.Time `type:"timestamp"` + + // The number of provisioned throughput decreases for this table during this + // UTC calendar day. For current maximums on provisioned throughput decreases, + // see Service, Account, and Table Quotas (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Limits.html) + // in the Amazon DynamoDB Developer Guide. + NumberOfDecreasesToday *int64 `min:"1" type:"long"` + + // The maximum number of strongly consistent reads consumed per second before + // DynamoDB returns a ThrottlingException. Eventually consistent reads require + // less effort than strongly consistent reads, so a setting of 50 ReadCapacityUnits + // per second provides 100 eventually consistent ReadCapacityUnits per second. + ReadCapacityUnits *int64 `type:"long"` + + // The maximum number of writes consumed per second before DynamoDB returns + // a ThrottlingException. + WriteCapacityUnits *int64 `type:"long"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ProvisionedThroughputDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ProvisionedThroughputDescription) GoString() string { + return s.String() +} + +// SetLastDecreaseDateTime sets the LastDecreaseDateTime field's value. +func (s *ProvisionedThroughputDescription) SetLastDecreaseDateTime(v time.Time) *ProvisionedThroughputDescription { + s.LastDecreaseDateTime = &v + return s +} + +// SetLastIncreaseDateTime sets the LastIncreaseDateTime field's value. +func (s *ProvisionedThroughputDescription) SetLastIncreaseDateTime(v time.Time) *ProvisionedThroughputDescription { + s.LastIncreaseDateTime = &v + return s +} + +// SetNumberOfDecreasesToday sets the NumberOfDecreasesToday field's value. +func (s *ProvisionedThroughputDescription) SetNumberOfDecreasesToday(v int64) *ProvisionedThroughputDescription { + s.NumberOfDecreasesToday = &v + return s +} + +// SetReadCapacityUnits sets the ReadCapacityUnits field's value. +func (s *ProvisionedThroughputDescription) SetReadCapacityUnits(v int64) *ProvisionedThroughputDescription { + s.ReadCapacityUnits = &v + return s +} + +// SetWriteCapacityUnits sets the WriteCapacityUnits field's value. +func (s *ProvisionedThroughputDescription) SetWriteCapacityUnits(v int64) *ProvisionedThroughputDescription { + s.WriteCapacityUnits = &v + return s +} + +// Your request rate is too high. The Amazon Web Services SDKs for DynamoDB +// automatically retry requests that receive this exception. Your request is +// eventually successful, unless your retry queue is too large to finish. Reduce +// the frequency of requests and use exponential backoff. For more information, +// go to Error Retries and Exponential Backoff (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.Errors.html#Programming.Errors.RetryAndBackoff) +// in the Amazon DynamoDB Developer Guide. +type ProvisionedThroughputExceededException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + // You exceeded your maximum allowed provisioned throughput. + Message_ *string `locationName:"message" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ProvisionedThroughputExceededException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ProvisionedThroughputExceededException) GoString() string { + return s.String() +} + +func newErrorProvisionedThroughputExceededException(v protocol.ResponseMetadata) error { + return &ProvisionedThroughputExceededException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *ProvisionedThroughputExceededException) Code() string { + return "ProvisionedThroughputExceededException" +} + +// Message returns the exception's message. +func (s *ProvisionedThroughputExceededException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *ProvisionedThroughputExceededException) OrigErr() error { + return nil +} + +func (s *ProvisionedThroughputExceededException) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *ProvisionedThroughputExceededException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *ProvisionedThroughputExceededException) RequestID() string { + return s.RespMetadata.RequestID +} + +// Replica-specific provisioned throughput settings. If not specified, uses +// the source table's provisioned throughput settings. +type ProvisionedThroughputOverride struct { + _ struct{} `type:"structure"` + + // Replica-specific read capacity units. If not specified, uses the source table's + // read capacity settings. + ReadCapacityUnits *int64 `min:"1" type:"long"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ProvisionedThroughputOverride) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ProvisionedThroughputOverride) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ProvisionedThroughputOverride) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ProvisionedThroughputOverride"} + if s.ReadCapacityUnits != nil && *s.ReadCapacityUnits < 1 { + invalidParams.Add(request.NewErrParamMinValue("ReadCapacityUnits", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetReadCapacityUnits sets the ReadCapacityUnits field's value. +func (s *ProvisionedThroughputOverride) SetReadCapacityUnits(v int64) *ProvisionedThroughputOverride { + s.ReadCapacityUnits = &v + return s +} + +// Represents a request to perform a PutItem operation. +type Put struct { + _ struct{} `type:"structure"` + + // A condition that must be satisfied in order for a conditional update to succeed. + ConditionExpression *string `type:"string"` + + // One or more substitution tokens for attribute names in an expression. + ExpressionAttributeNames map[string]*string `type:"map"` + + // One or more values that can be substituted in an expression. + ExpressionAttributeValues map[string]*AttributeValue `type:"map"` + + // A map of attribute name to attribute values, representing the primary key + // of the item to be written by PutItem. All of the table's primary key attributes + // must be specified, and their data types must match those of the table's key + // schema. If any attributes are present in the item that are part of an index + // key schema for the table, their types must match the index key schema. + // + // Item is a required field + Item map[string]*AttributeValue `type:"map" required:"true"` + + // Use ReturnValuesOnConditionCheckFailure to get the item attributes if the + // Put condition fails. For ReturnValuesOnConditionCheckFailure, the valid values + // are: NONE and ALL_OLD. + ReturnValuesOnConditionCheckFailure *string `type:"string" enum:"ReturnValuesOnConditionCheckFailure"` + + // Name of the table in which to write the item. + // + // TableName is a required field + TableName *string `min:"3" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s Put) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s Put) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *Put) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "Put"} + if s.Item == nil { + invalidParams.Add(request.NewErrParamRequired("Item")) + } + if s.TableName == nil { + invalidParams.Add(request.NewErrParamRequired("TableName")) + } + if s.TableName != nil && len(*s.TableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("TableName", 3)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetConditionExpression sets the ConditionExpression field's value. +func (s *Put) SetConditionExpression(v string) *Put { + s.ConditionExpression = &v + return s +} + +// SetExpressionAttributeNames sets the ExpressionAttributeNames field's value. +func (s *Put) SetExpressionAttributeNames(v map[string]*string) *Put { + s.ExpressionAttributeNames = v + return s +} + +// SetExpressionAttributeValues sets the ExpressionAttributeValues field's value. +func (s *Put) SetExpressionAttributeValues(v map[string]*AttributeValue) *Put { + s.ExpressionAttributeValues = v + return s +} + +// SetItem sets the Item field's value. +func (s *Put) SetItem(v map[string]*AttributeValue) *Put { + s.Item = v + return s +} + +// SetReturnValuesOnConditionCheckFailure sets the ReturnValuesOnConditionCheckFailure field's value. +func (s *Put) SetReturnValuesOnConditionCheckFailure(v string) *Put { + s.ReturnValuesOnConditionCheckFailure = &v + return s +} + +// SetTableName sets the TableName field's value. +func (s *Put) SetTableName(v string) *Put { + s.TableName = &v + return s +} + +// Represents the input of a PutItem operation. +type PutItemInput struct { + _ struct{} `type:"structure"` + + // A condition that must be satisfied in order for a conditional PutItem operation + // to succeed. + // + // An expression can contain any of the following: + // + // * Functions: attribute_exists | attribute_not_exists | attribute_type + // | contains | begins_with | size These function names are case-sensitive. + // + // * Comparison operators: = | <> | < | > | <= | >= | BETWEEN | IN + // + // * Logical operators: AND | OR | NOT + // + // For more information on condition expressions, see Condition Expressions + // (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.SpecifyingConditions.html) + // in the Amazon DynamoDB Developer Guide. + ConditionExpression *string `type:"string"` + + // This is a legacy parameter. Use ConditionExpression instead. For more information, + // see ConditionalOperator (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.ConditionalOperator.html) + // in the Amazon DynamoDB Developer Guide. + ConditionalOperator *string `type:"string" enum:"ConditionalOperator"` + + // This is a legacy parameter. Use ConditionExpression instead. For more information, + // see Expected (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.Expected.html) + // in the Amazon DynamoDB Developer Guide. + Expected map[string]*ExpectedAttributeValue `type:"map"` + + // One or more substitution tokens for attribute names in an expression. The + // following are some use cases for using ExpressionAttributeNames: + // + // * To access an attribute whose name conflicts with a DynamoDB reserved + // word. + // + // * To create a placeholder for repeating occurrences of an attribute name + // in an expression. + // + // * To prevent special characters in an attribute name from being misinterpreted + // in an expression. + // + // Use the # character in an expression to dereference an attribute name. For + // example, consider the following attribute name: + // + // * Percentile + // + // The name of this attribute conflicts with a reserved word, so it cannot be + // used directly in an expression. (For the complete list of reserved words, + // see Reserved Words (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html) + // in the Amazon DynamoDB Developer Guide). To work around this, you could specify + // the following for ExpressionAttributeNames: + // + // * {"#P":"Percentile"} + // + // You could then use this substitution in an expression, as in this example: + // + // * #P = :val + // + // Tokens that begin with the : character are expression attribute values, which + // are placeholders for the actual value at runtime. + // + // For more information on expression attribute names, see Specifying Item Attributes + // (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.AccessingItemAttributes.html) + // in the Amazon DynamoDB Developer Guide. + ExpressionAttributeNames map[string]*string `type:"map"` + + // One or more values that can be substituted in an expression. + // + // Use the : (colon) character in an expression to dereference an attribute + // value. For example, suppose that you wanted to check whether the value of + // the ProductStatus attribute was one of the following: + // + // Available | Backordered | Discontinued + // + // You would first need to specify ExpressionAttributeValues as follows: + // + // { ":avail":{"S":"Available"}, ":back":{"S":"Backordered"}, ":disc":{"S":"Discontinued"} + // } + // + // You could then use these values in an expression, such as this: + // + // ProductStatus IN (:avail, :back, :disc) + // + // For more information on expression attribute values, see Condition Expressions + // (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.SpecifyingConditions.html) + // in the Amazon DynamoDB Developer Guide. + ExpressionAttributeValues map[string]*AttributeValue `type:"map"` + + // A map of attribute name/value pairs, one for each attribute. Only the primary + // key attributes are required; you can optionally provide other attribute name-value + // pairs for the item. + // + // You must provide all of the attributes for the primary key. For example, + // with a simple primary key, you only need to provide a value for the partition + // key. For a composite primary key, you must provide both values for both the + // partition key and the sort key. + // + // If you specify any attributes that are part of an index key, then the data + // types for those attributes must match those of the schema in the table's + // attribute definition. + // + // Empty String and Binary attribute values are allowed. Attribute values of + // type String and Binary must have a length greater than zero if the attribute + // is used as a key attribute for a table or index. + // + // For more information about primary keys, see Primary Key (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.PrimaryKey) + // in the Amazon DynamoDB Developer Guide. + // + // Each element in the Item map is an AttributeValue object. + // + // Item is a required field + Item map[string]*AttributeValue `type:"map" required:"true"` + + // Determines the level of detail about either provisioned or on-demand throughput + // consumption that is returned in the response: + // + // * INDEXES - The response includes the aggregate ConsumedCapacity for the + // operation, together with ConsumedCapacity for each table and secondary + // index that was accessed. Note that some operations, such as GetItem and + // BatchGetItem, do not access any indexes at all. In these cases, specifying + // INDEXES will only return ConsumedCapacity information for table(s). + // + // * TOTAL - The response includes only the aggregate ConsumedCapacity for + // the operation. + // + // * NONE - No ConsumedCapacity details are included in the response. + ReturnConsumedCapacity *string `type:"string" enum:"ReturnConsumedCapacity"` + + // Determines whether item collection metrics are returned. If set to SIZE, + // the response includes statistics about item collections, if any, that were + // modified during the operation are returned in the response. If set to NONE + // (the default), no statistics are returned. + ReturnItemCollectionMetrics *string `type:"string" enum:"ReturnItemCollectionMetrics"` + + // Use ReturnValues if you want to get the item attributes as they appeared + // before they were updated with the PutItem request. For PutItem, the valid + // values are: + // + // * NONE - If ReturnValues is not specified, or if its value is NONE, then + // nothing is returned. (This setting is the default for ReturnValues.) + // + // * ALL_OLD - If PutItem overwrote an attribute name-value pair, then the + // content of the old item is returned. + // + // The values returned are strongly consistent. + // + // The ReturnValues parameter is used by several DynamoDB operations; however, + // PutItem does not recognize any values other than NONE or ALL_OLD. + ReturnValues *string `type:"string" enum:"ReturnValue"` + + // The name of the table to contain the item. + // + // TableName is a required field + TableName *string `min:"3" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s PutItemInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s PutItemInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *PutItemInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "PutItemInput"} + if s.Item == nil { + invalidParams.Add(request.NewErrParamRequired("Item")) + } + if s.TableName == nil { + invalidParams.Add(request.NewErrParamRequired("TableName")) + } + if s.TableName != nil && len(*s.TableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("TableName", 3)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetConditionExpression sets the ConditionExpression field's value. +func (s *PutItemInput) SetConditionExpression(v string) *PutItemInput { + s.ConditionExpression = &v + return s +} + +// SetConditionalOperator sets the ConditionalOperator field's value. +func (s *PutItemInput) SetConditionalOperator(v string) *PutItemInput { + s.ConditionalOperator = &v + return s +} + +// SetExpected sets the Expected field's value. +func (s *PutItemInput) SetExpected(v map[string]*ExpectedAttributeValue) *PutItemInput { + s.Expected = v + return s +} + +// SetExpressionAttributeNames sets the ExpressionAttributeNames field's value. +func (s *PutItemInput) SetExpressionAttributeNames(v map[string]*string) *PutItemInput { + s.ExpressionAttributeNames = v + return s +} + +// SetExpressionAttributeValues sets the ExpressionAttributeValues field's value. +func (s *PutItemInput) SetExpressionAttributeValues(v map[string]*AttributeValue) *PutItemInput { + s.ExpressionAttributeValues = v + return s +} + +// SetItem sets the Item field's value. +func (s *PutItemInput) SetItem(v map[string]*AttributeValue) *PutItemInput { + s.Item = v + return s +} + +// SetReturnConsumedCapacity sets the ReturnConsumedCapacity field's value. +func (s *PutItemInput) SetReturnConsumedCapacity(v string) *PutItemInput { + s.ReturnConsumedCapacity = &v + return s +} + +// SetReturnItemCollectionMetrics sets the ReturnItemCollectionMetrics field's value. +func (s *PutItemInput) SetReturnItemCollectionMetrics(v string) *PutItemInput { + s.ReturnItemCollectionMetrics = &v + return s +} + +// SetReturnValues sets the ReturnValues field's value. +func (s *PutItemInput) SetReturnValues(v string) *PutItemInput { + s.ReturnValues = &v + return s +} + +// SetTableName sets the TableName field's value. +func (s *PutItemInput) SetTableName(v string) *PutItemInput { + s.TableName = &v + return s +} + +// Represents the output of a PutItem operation. +type PutItemOutput struct { + _ struct{} `type:"structure"` + + // The attribute values as they appeared before the PutItem operation, but only + // if ReturnValues is specified as ALL_OLD in the request. Each element consists + // of an attribute name and an attribute value. + Attributes map[string]*AttributeValue `type:"map"` + + // The capacity units consumed by the PutItem operation. The data returned includes + // the total provisioned throughput consumed, along with statistics for the + // table and any indexes involved in the operation. ConsumedCapacity is only + // returned if the ReturnConsumedCapacity parameter was specified. For more + // information, see Read/Write Capacity Mode (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ProvisionedThroughputIntro.html) + // in the Amazon DynamoDB Developer Guide. + ConsumedCapacity *ConsumedCapacity `type:"structure"` + + // Information about item collections, if any, that were affected by the PutItem + // operation. ItemCollectionMetrics is only returned if the ReturnItemCollectionMetrics + // parameter was specified. If the table does not have any local secondary indexes, + // this information is not returned in the response. + // + // Each ItemCollectionMetrics element consists of: + // + // * ItemCollectionKey - The partition key value of the item collection. + // This is the same as the partition key value of the item itself. + // + // * SizeEstimateRangeGB - An estimate of item collection size, in gigabytes. + // This value is a two-element array containing a lower bound and an upper + // bound for the estimate. The estimate includes the size of all the items + // in the table, plus the size of all attributes projected into all of the + // local secondary indexes on that table. Use this estimate to measure whether + // a local secondary index is approaching its size limit. The estimate is + // subject to change over time; therefore, do not rely on the precision or + // accuracy of the estimate. + ItemCollectionMetrics *ItemCollectionMetrics `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s PutItemOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s PutItemOutput) GoString() string { + return s.String() +} + +// SetAttributes sets the Attributes field's value. +func (s *PutItemOutput) SetAttributes(v map[string]*AttributeValue) *PutItemOutput { + s.Attributes = v + return s +} + +// SetConsumedCapacity sets the ConsumedCapacity field's value. +func (s *PutItemOutput) SetConsumedCapacity(v *ConsumedCapacity) *PutItemOutput { + s.ConsumedCapacity = v + return s +} + +// SetItemCollectionMetrics sets the ItemCollectionMetrics field's value. +func (s *PutItemOutput) SetItemCollectionMetrics(v *ItemCollectionMetrics) *PutItemOutput { + s.ItemCollectionMetrics = v + return s +} + +// Represents a request to perform a PutItem operation on an item. +type PutRequest struct { + _ struct{} `type:"structure"` + + // A map of attribute name to attribute values, representing the primary key + // of an item to be processed by PutItem. All of the table's primary key attributes + // must be specified, and their data types must match those of the table's key + // schema. If any attributes are present in the item that are part of an index + // key schema for the table, their types must match the index key schema. + // + // Item is a required field + Item map[string]*AttributeValue `type:"map" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s PutRequest) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s PutRequest) GoString() string { + return s.String() +} + +// SetItem sets the Item field's value. +func (s *PutRequest) SetItem(v map[string]*AttributeValue) *PutRequest { + s.Item = v + return s +} + +// Represents the input of a Query operation. +type QueryInput struct { + _ struct{} `type:"structure"` + + // This is a legacy parameter. Use ProjectionExpression instead. For more information, + // see AttributesToGet (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.AttributesToGet.html) + // in the Amazon DynamoDB Developer Guide. + AttributesToGet []*string `min:"1" type:"list"` + + // This is a legacy parameter. Use FilterExpression instead. For more information, + // see ConditionalOperator (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.ConditionalOperator.html) + // in the Amazon DynamoDB Developer Guide. + ConditionalOperator *string `type:"string" enum:"ConditionalOperator"` + + // Determines the read consistency model: If set to true, then the operation + // uses strongly consistent reads; otherwise, the operation uses eventually + // consistent reads. + // + // Strongly consistent reads are not supported on global secondary indexes. + // If you query a global secondary index with ConsistentRead set to true, you + // will receive a ValidationException. + ConsistentRead *bool `type:"boolean"` + + // The primary key of the first item that this operation will evaluate. Use + // the value that was returned for LastEvaluatedKey in the previous operation. + // + // The data type for ExclusiveStartKey must be String, Number, or Binary. No + // set data types are allowed. + ExclusiveStartKey map[string]*AttributeValue `type:"map"` + + // One or more substitution tokens for attribute names in an expression. The + // following are some use cases for using ExpressionAttributeNames: + // + // * To access an attribute whose name conflicts with a DynamoDB reserved + // word. + // + // * To create a placeholder for repeating occurrences of an attribute name + // in an expression. + // + // * To prevent special characters in an attribute name from being misinterpreted + // in an expression. + // + // Use the # character in an expression to dereference an attribute name. For + // example, consider the following attribute name: + // + // * Percentile + // + // The name of this attribute conflicts with a reserved word, so it cannot be + // used directly in an expression. (For the complete list of reserved words, + // see Reserved Words (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html) + // in the Amazon DynamoDB Developer Guide). To work around this, you could specify + // the following for ExpressionAttributeNames: + // + // * {"#P":"Percentile"} + // + // You could then use this substitution in an expression, as in this example: + // + // * #P = :val + // + // Tokens that begin with the : character are expression attribute values, which + // are placeholders for the actual value at runtime. + // + // For more information on expression attribute names, see Specifying Item Attributes + // (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.AccessingItemAttributes.html) + // in the Amazon DynamoDB Developer Guide. + ExpressionAttributeNames map[string]*string `type:"map"` + + // One or more values that can be substituted in an expression. + // + // Use the : (colon) character in an expression to dereference an attribute + // value. For example, suppose that you wanted to check whether the value of + // the ProductStatus attribute was one of the following: + // + // Available | Backordered | Discontinued + // + // You would first need to specify ExpressionAttributeValues as follows: + // + // { ":avail":{"S":"Available"}, ":back":{"S":"Backordered"}, ":disc":{"S":"Discontinued"} + // } + // + // You could then use these values in an expression, such as this: + // + // ProductStatus IN (:avail, :back, :disc) + // + // For more information on expression attribute values, see Specifying Conditions + // (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.SpecifyingConditions.html) + // in the Amazon DynamoDB Developer Guide. + ExpressionAttributeValues map[string]*AttributeValue `type:"map"` + + // A string that contains conditions that DynamoDB applies after the Query operation, + // but before the data is returned to you. Items that do not satisfy the FilterExpression + // criteria are not returned. + // + // A FilterExpression does not allow key attributes. You cannot define a filter + // expression based on a partition key or a sort key. + // + // A FilterExpression is applied after the items have already been read; the + // process of filtering does not consume any additional read capacity units. + // + // For more information, see Filter Expressions (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html#FilteringResults) + // in the Amazon DynamoDB Developer Guide. + FilterExpression *string `type:"string"` + + // The name of an index to query. This index can be any local secondary index + // or global secondary index on the table. Note that if you use the IndexName + // parameter, you must also provide TableName. + IndexName *string `min:"3" type:"string"` + + // The condition that specifies the key values for items to be retrieved by + // the Query action. + // + // The condition must perform an equality test on a single partition key value. + // + // The condition can optionally perform one of several comparison tests on a + // single sort key value. This allows Query to retrieve one item with a given + // partition key value and sort key value, or several items that have the same + // partition key value but different sort key values. + // + // The partition key equality test is required, and must be specified in the + // following format: + // + // partitionKeyName = :partitionkeyval + // + // If you also want to provide a condition for the sort key, it must be combined + // using AND with the condition for the sort key. Following is an example, using + // the = comparison operator for the sort key: + // + // partitionKeyName = :partitionkeyval AND sortKeyName = :sortkeyval + // + // Valid comparisons for the sort key condition are as follows: + // + // * sortKeyName = :sortkeyval - true if the sort key value is equal to :sortkeyval. + // + // * sortKeyName < :sortkeyval - true if the sort key value is less than + // :sortkeyval. + // + // * sortKeyName <= :sortkeyval - true if the sort key value is less than + // or equal to :sortkeyval. + // + // * sortKeyName > :sortkeyval - true if the sort key value is greater than + // :sortkeyval. + // + // * sortKeyName >= :sortkeyval - true if the sort key value is greater than + // or equal to :sortkeyval. + // + // * sortKeyName BETWEEN :sortkeyval1 AND :sortkeyval2 - true if the sort + // key value is greater than or equal to :sortkeyval1, and less than or equal + // to :sortkeyval2. + // + // * begins_with ( sortKeyName, :sortkeyval ) - true if the sort key value + // begins with a particular operand. (You cannot use this function with a + // sort key that is of type Number.) Note that the function name begins_with + // is case-sensitive. + // + // Use the ExpressionAttributeValues parameter to replace tokens such as :partitionval + // and :sortval with actual values at runtime. + // + // You can optionally use the ExpressionAttributeNames parameter to replace + // the names of the partition key and sort key with placeholder tokens. This + // option might be necessary if an attribute name conflicts with a DynamoDB + // reserved word. For example, the following KeyConditionExpression parameter + // causes an error because Size is a reserved word: + // + // * Size = :myval + // + // To work around this, define a placeholder (such a #S) to represent the attribute + // name Size. KeyConditionExpression then is as follows: + // + // * #S = :myval + // + // For a list of reserved words, see Reserved Words (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html) + // in the Amazon DynamoDB Developer Guide. + // + // For more information on ExpressionAttributeNames and ExpressionAttributeValues, + // see Using Placeholders for Attribute Names and Values (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ExpressionPlaceholders.html) + // in the Amazon DynamoDB Developer Guide. + KeyConditionExpression *string `type:"string"` + + // This is a legacy parameter. Use KeyConditionExpression instead. For more + // information, see KeyConditions (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.KeyConditions.html) + // in the Amazon DynamoDB Developer Guide. + KeyConditions map[string]*Condition `type:"map"` + + // The maximum number of items to evaluate (not necessarily the number of matching + // items). If DynamoDB processes the number of items up to the limit while processing + // the results, it stops the operation and returns the matching values up to + // that point, and a key in LastEvaluatedKey to apply in a subsequent operation, + // so that you can pick up where you left off. Also, if the processed dataset + // size exceeds 1 MB before DynamoDB reaches this limit, it stops the operation + // and returns the matching values up to the limit, and a key in LastEvaluatedKey + // to apply in a subsequent operation to continue the operation. For more information, + // see Query and Scan (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html) + // in the Amazon DynamoDB Developer Guide. + Limit *int64 `min:"1" type:"integer"` + + // A string that identifies one or more attributes to retrieve from the table. + // These attributes can include scalars, sets, or elements of a JSON document. + // The attributes in the expression must be separated by commas. + // + // If no attribute names are specified, then all attributes will be returned. + // If any of the requested attributes are not found, they will not appear in + // the result. + // + // For more information, see Accessing Item Attributes (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.AccessingItemAttributes.html) + // in the Amazon DynamoDB Developer Guide. + ProjectionExpression *string `type:"string"` + + // This is a legacy parameter. Use FilterExpression instead. For more information, + // see QueryFilter (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.QueryFilter.html) + // in the Amazon DynamoDB Developer Guide. + QueryFilter map[string]*Condition `type:"map"` + + // Determines the level of detail about either provisioned or on-demand throughput + // consumption that is returned in the response: + // + // * INDEXES - The response includes the aggregate ConsumedCapacity for the + // operation, together with ConsumedCapacity for each table and secondary + // index that was accessed. Note that some operations, such as GetItem and + // BatchGetItem, do not access any indexes at all. In these cases, specifying + // INDEXES will only return ConsumedCapacity information for table(s). + // + // * TOTAL - The response includes only the aggregate ConsumedCapacity for + // the operation. + // + // * NONE - No ConsumedCapacity details are included in the response. + ReturnConsumedCapacity *string `type:"string" enum:"ReturnConsumedCapacity"` + + // Specifies the order for index traversal: If true (default), the traversal + // is performed in ascending order; if false, the traversal is performed in + // descending order. + // + // Items with the same partition key value are stored in sorted order by sort + // key. If the sort key data type is Number, the results are stored in numeric + // order. For type String, the results are stored in order of UTF-8 bytes. For + // type Binary, DynamoDB treats each byte of the binary data as unsigned. + // + // If ScanIndexForward is true, DynamoDB returns the results in the order in + // which they are stored (by sort key value). This is the default behavior. + // If ScanIndexForward is false, DynamoDB reads the results in reverse order + // by sort key value, and then returns the results to the client. + ScanIndexForward *bool `type:"boolean"` + + // The attributes to be returned in the result. You can retrieve all item attributes, + // specific item attributes, the count of matching items, or in the case of + // an index, some or all of the attributes projected into the index. + // + // * ALL_ATTRIBUTES - Returns all of the item attributes from the specified + // table or index. If you query a local secondary index, then for each matching + // item in the index, DynamoDB fetches the entire item from the parent table. + // If the index is configured to project all item attributes, then all of + // the data can be obtained from the local secondary index, and no fetching + // is required. + // + // * ALL_PROJECTED_ATTRIBUTES - Allowed only when querying an index. Retrieves + // all attributes that have been projected into the index. If the index is + // configured to project all attributes, this return value is equivalent + // to specifying ALL_ATTRIBUTES. + // + // * COUNT - Returns the number of matching items, rather than the matching + // items themselves. + // + // * SPECIFIC_ATTRIBUTES - Returns only the attributes listed in AttributesToGet. + // This return value is equivalent to specifying AttributesToGet without + // specifying any value for Select. If you query or scan a local secondary + // index and request only attributes that are projected into that index, + // the operation will read only the index and not the table. If any of the + // requested attributes are not projected into the local secondary index, + // DynamoDB fetches each of these attributes from the parent table. This + // extra fetching incurs additional throughput cost and latency. If you query + // or scan a global secondary index, you can only request attributes that + // are projected into the index. Global secondary index queries cannot fetch + // attributes from the parent table. + // + // If neither Select nor AttributesToGet are specified, DynamoDB defaults to + // ALL_ATTRIBUTES when accessing a table, and ALL_PROJECTED_ATTRIBUTES when + // accessing an index. You cannot use both Select and AttributesToGet together + // in a single request, unless the value for Select is SPECIFIC_ATTRIBUTES. + // (This usage is equivalent to specifying AttributesToGet without any value + // for Select.) + // + // If you use the ProjectionExpression parameter, then the value for Select + // can only be SPECIFIC_ATTRIBUTES. Any other value for Select will return an + // error. + Select *string `type:"string" enum:"Select"` + + // The name of the table containing the requested items. + // + // TableName is a required field + TableName *string `min:"3" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s QueryInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s QueryInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *QueryInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "QueryInput"} + if s.AttributesToGet != nil && len(s.AttributesToGet) < 1 { + invalidParams.Add(request.NewErrParamMinLen("AttributesToGet", 1)) + } + if s.IndexName != nil && len(*s.IndexName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("IndexName", 3)) + } + if s.Limit != nil && *s.Limit < 1 { + invalidParams.Add(request.NewErrParamMinValue("Limit", 1)) + } + if s.TableName == nil { + invalidParams.Add(request.NewErrParamRequired("TableName")) + } + if s.TableName != nil && len(*s.TableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("TableName", 3)) + } + if s.KeyConditions != nil { + for i, v := range s.KeyConditions { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "KeyConditions", i), err.(request.ErrInvalidParams)) + } + } + } + if s.QueryFilter != nil { + for i, v := range s.QueryFilter { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "QueryFilter", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAttributesToGet sets the AttributesToGet field's value. +func (s *QueryInput) SetAttributesToGet(v []*string) *QueryInput { + s.AttributesToGet = v + return s +} + +// SetConditionalOperator sets the ConditionalOperator field's value. +func (s *QueryInput) SetConditionalOperator(v string) *QueryInput { + s.ConditionalOperator = &v + return s +} + +// SetConsistentRead sets the ConsistentRead field's value. +func (s *QueryInput) SetConsistentRead(v bool) *QueryInput { + s.ConsistentRead = &v + return s +} + +// SetExclusiveStartKey sets the ExclusiveStartKey field's value. +func (s *QueryInput) SetExclusiveStartKey(v map[string]*AttributeValue) *QueryInput { + s.ExclusiveStartKey = v + return s +} + +// SetExpressionAttributeNames sets the ExpressionAttributeNames field's value. +func (s *QueryInput) SetExpressionAttributeNames(v map[string]*string) *QueryInput { + s.ExpressionAttributeNames = v + return s +} + +// SetExpressionAttributeValues sets the ExpressionAttributeValues field's value. +func (s *QueryInput) SetExpressionAttributeValues(v map[string]*AttributeValue) *QueryInput { + s.ExpressionAttributeValues = v + return s +} + +// SetFilterExpression sets the FilterExpression field's value. +func (s *QueryInput) SetFilterExpression(v string) *QueryInput { + s.FilterExpression = &v + return s +} + +// SetIndexName sets the IndexName field's value. +func (s *QueryInput) SetIndexName(v string) *QueryInput { + s.IndexName = &v + return s +} + +// SetKeyConditionExpression sets the KeyConditionExpression field's value. +func (s *QueryInput) SetKeyConditionExpression(v string) *QueryInput { + s.KeyConditionExpression = &v + return s +} + +// SetKeyConditions sets the KeyConditions field's value. +func (s *QueryInput) SetKeyConditions(v map[string]*Condition) *QueryInput { + s.KeyConditions = v + return s +} + +// SetLimit sets the Limit field's value. +func (s *QueryInput) SetLimit(v int64) *QueryInput { + s.Limit = &v + return s +} + +// SetProjectionExpression sets the ProjectionExpression field's value. +func (s *QueryInput) SetProjectionExpression(v string) *QueryInput { + s.ProjectionExpression = &v + return s +} + +// SetQueryFilter sets the QueryFilter field's value. +func (s *QueryInput) SetQueryFilter(v map[string]*Condition) *QueryInput { + s.QueryFilter = v + return s +} + +// SetReturnConsumedCapacity sets the ReturnConsumedCapacity field's value. +func (s *QueryInput) SetReturnConsumedCapacity(v string) *QueryInput { + s.ReturnConsumedCapacity = &v + return s +} + +// SetScanIndexForward sets the ScanIndexForward field's value. +func (s *QueryInput) SetScanIndexForward(v bool) *QueryInput { + s.ScanIndexForward = &v + return s +} + +// SetSelect sets the Select field's value. +func (s *QueryInput) SetSelect(v string) *QueryInput { + s.Select = &v + return s +} + +// SetTableName sets the TableName field's value. +func (s *QueryInput) SetTableName(v string) *QueryInput { + s.TableName = &v + return s +} + +// Represents the output of a Query operation. +type QueryOutput struct { + _ struct{} `type:"structure"` + + // The capacity units consumed by the Query operation. The data returned includes + // the total provisioned throughput consumed, along with statistics for the + // table and any indexes involved in the operation. ConsumedCapacity is only + // returned if the ReturnConsumedCapacity parameter was specified. For more + // information, see Provisioned Throughput (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ProvisionedThroughputIntro.html) + // in the Amazon DynamoDB Developer Guide. + ConsumedCapacity *ConsumedCapacity `type:"structure"` + + // The number of items in the response. + // + // If you used a QueryFilter in the request, then Count is the number of items + // returned after the filter was applied, and ScannedCount is the number of + // matching items before the filter was applied. + // + // If you did not use a filter in the request, then Count and ScannedCount are + // the same. + Count *int64 `type:"integer"` + + // An array of item attributes that match the query criteria. Each element in + // this array consists of an attribute name and the value for that attribute. + Items []map[string]*AttributeValue `type:"list"` + + // The primary key of the item where the operation stopped, inclusive of the + // previous result set. Use this value to start a new operation, excluding this + // value in the new request. + // + // If LastEvaluatedKey is empty, then the "last page" of results has been processed + // and there is no more data to be retrieved. + // + // If LastEvaluatedKey is not empty, it does not necessarily mean that there + // is more data in the result set. The only way to know when you have reached + // the end of the result set is when LastEvaluatedKey is empty. + LastEvaluatedKey map[string]*AttributeValue `type:"map"` + + // The number of items evaluated, before any QueryFilter is applied. A high + // ScannedCount value with few, or no, Count results indicates an inefficient + // Query operation. For more information, see Count and ScannedCount (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html#Count) + // in the Amazon DynamoDB Developer Guide. + // + // If you did not use a filter in the request, then ScannedCount is the same + // as Count. + ScannedCount *int64 `type:"integer"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s QueryOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s QueryOutput) GoString() string { + return s.String() +} + +// SetConsumedCapacity sets the ConsumedCapacity field's value. +func (s *QueryOutput) SetConsumedCapacity(v *ConsumedCapacity) *QueryOutput { + s.ConsumedCapacity = v + return s +} + +// SetCount sets the Count field's value. +func (s *QueryOutput) SetCount(v int64) *QueryOutput { + s.Count = &v + return s +} + +// SetItems sets the Items field's value. +func (s *QueryOutput) SetItems(v []map[string]*AttributeValue) *QueryOutput { + s.Items = v + return s +} + +// SetLastEvaluatedKey sets the LastEvaluatedKey field's value. +func (s *QueryOutput) SetLastEvaluatedKey(v map[string]*AttributeValue) *QueryOutput { + s.LastEvaluatedKey = v + return s +} + +// SetScannedCount sets the ScannedCount field's value. +func (s *QueryOutput) SetScannedCount(v int64) *QueryOutput { + s.ScannedCount = &v + return s +} + +// Represents the properties of a replica. +type Replica struct { + _ struct{} `type:"structure"` + + // The Region where the replica needs to be created. + RegionName *string `type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s Replica) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s Replica) GoString() string { + return s.String() +} + +// SetRegionName sets the RegionName field's value. +func (s *Replica) SetRegionName(v string) *Replica { + s.RegionName = &v + return s +} + +// The specified replica is already part of the global table. +type ReplicaAlreadyExistsException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + Message_ *string `locationName:"message" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ReplicaAlreadyExistsException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ReplicaAlreadyExistsException) GoString() string { + return s.String() +} + +func newErrorReplicaAlreadyExistsException(v protocol.ResponseMetadata) error { + return &ReplicaAlreadyExistsException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *ReplicaAlreadyExistsException) Code() string { + return "ReplicaAlreadyExistsException" +} + +// Message returns the exception's message. +func (s *ReplicaAlreadyExistsException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *ReplicaAlreadyExistsException) OrigErr() error { + return nil +} + +func (s *ReplicaAlreadyExistsException) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *ReplicaAlreadyExistsException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *ReplicaAlreadyExistsException) RequestID() string { + return s.RespMetadata.RequestID +} + +// Represents the auto scaling settings of the replica. +type ReplicaAutoScalingDescription struct { + _ struct{} `type:"structure"` + + // Replica-specific global secondary index auto scaling settings. + GlobalSecondaryIndexes []*ReplicaGlobalSecondaryIndexAutoScalingDescription `type:"list"` + + // The Region where the replica exists. + RegionName *string `type:"string"` + + // Represents the auto scaling settings for a global table or global secondary + // index. + ReplicaProvisionedReadCapacityAutoScalingSettings *AutoScalingSettingsDescription `type:"structure"` + + // Represents the auto scaling settings for a global table or global secondary + // index. + ReplicaProvisionedWriteCapacityAutoScalingSettings *AutoScalingSettingsDescription `type:"structure"` + + // The current state of the replica: + // + // * CREATING - The replica is being created. + // + // * UPDATING - The replica is being updated. + // + // * DELETING - The replica is being deleted. + // + // * ACTIVE - The replica is ready for use. + ReplicaStatus *string `type:"string" enum:"ReplicaStatus"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ReplicaAutoScalingDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ReplicaAutoScalingDescription) GoString() string { + return s.String() +} + +// SetGlobalSecondaryIndexes sets the GlobalSecondaryIndexes field's value. +func (s *ReplicaAutoScalingDescription) SetGlobalSecondaryIndexes(v []*ReplicaGlobalSecondaryIndexAutoScalingDescription) *ReplicaAutoScalingDescription { + s.GlobalSecondaryIndexes = v + return s +} + +// SetRegionName sets the RegionName field's value. +func (s *ReplicaAutoScalingDescription) SetRegionName(v string) *ReplicaAutoScalingDescription { + s.RegionName = &v + return s +} + +// SetReplicaProvisionedReadCapacityAutoScalingSettings sets the ReplicaProvisionedReadCapacityAutoScalingSettings field's value. +func (s *ReplicaAutoScalingDescription) SetReplicaProvisionedReadCapacityAutoScalingSettings(v *AutoScalingSettingsDescription) *ReplicaAutoScalingDescription { + s.ReplicaProvisionedReadCapacityAutoScalingSettings = v + return s +} + +// SetReplicaProvisionedWriteCapacityAutoScalingSettings sets the ReplicaProvisionedWriteCapacityAutoScalingSettings field's value. +func (s *ReplicaAutoScalingDescription) SetReplicaProvisionedWriteCapacityAutoScalingSettings(v *AutoScalingSettingsDescription) *ReplicaAutoScalingDescription { + s.ReplicaProvisionedWriteCapacityAutoScalingSettings = v + return s +} + +// SetReplicaStatus sets the ReplicaStatus field's value. +func (s *ReplicaAutoScalingDescription) SetReplicaStatus(v string) *ReplicaAutoScalingDescription { + s.ReplicaStatus = &v + return s +} + +// Represents the auto scaling settings of a replica that will be modified. +type ReplicaAutoScalingUpdate struct { + _ struct{} `type:"structure"` + + // The Region where the replica exists. + // + // RegionName is a required field + RegionName *string `type:"string" required:"true"` + + // Represents the auto scaling settings of global secondary indexes that will + // be modified. + ReplicaGlobalSecondaryIndexUpdates []*ReplicaGlobalSecondaryIndexAutoScalingUpdate `type:"list"` + + // Represents the auto scaling settings to be modified for a global table or + // global secondary index. + ReplicaProvisionedReadCapacityAutoScalingUpdate *AutoScalingSettingsUpdate `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ReplicaAutoScalingUpdate) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ReplicaAutoScalingUpdate) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ReplicaAutoScalingUpdate) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ReplicaAutoScalingUpdate"} + if s.RegionName == nil { + invalidParams.Add(request.NewErrParamRequired("RegionName")) + } + if s.ReplicaGlobalSecondaryIndexUpdates != nil { + for i, v := range s.ReplicaGlobalSecondaryIndexUpdates { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "ReplicaGlobalSecondaryIndexUpdates", i), err.(request.ErrInvalidParams)) + } + } + } + if s.ReplicaProvisionedReadCapacityAutoScalingUpdate != nil { + if err := s.ReplicaProvisionedReadCapacityAutoScalingUpdate.Validate(); err != nil { + invalidParams.AddNested("ReplicaProvisionedReadCapacityAutoScalingUpdate", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetRegionName sets the RegionName field's value. +func (s *ReplicaAutoScalingUpdate) SetRegionName(v string) *ReplicaAutoScalingUpdate { + s.RegionName = &v + return s +} + +// SetReplicaGlobalSecondaryIndexUpdates sets the ReplicaGlobalSecondaryIndexUpdates field's value. +func (s *ReplicaAutoScalingUpdate) SetReplicaGlobalSecondaryIndexUpdates(v []*ReplicaGlobalSecondaryIndexAutoScalingUpdate) *ReplicaAutoScalingUpdate { + s.ReplicaGlobalSecondaryIndexUpdates = v + return s +} + +// SetReplicaProvisionedReadCapacityAutoScalingUpdate sets the ReplicaProvisionedReadCapacityAutoScalingUpdate field's value. +func (s *ReplicaAutoScalingUpdate) SetReplicaProvisionedReadCapacityAutoScalingUpdate(v *AutoScalingSettingsUpdate) *ReplicaAutoScalingUpdate { + s.ReplicaProvisionedReadCapacityAutoScalingUpdate = v + return s +} + +// Contains the details of the replica. +type ReplicaDescription struct { + _ struct{} `type:"structure"` + + // Replica-specific global secondary index settings. + GlobalSecondaryIndexes []*ReplicaGlobalSecondaryIndexDescription `type:"list"` + + // The KMS key of the replica that will be used for KMS encryption. + KMSMasterKeyId *string `type:"string"` + + // Replica-specific provisioned throughput. If not described, uses the source + // table's provisioned throughput settings. + ProvisionedThroughputOverride *ProvisionedThroughputOverride `type:"structure"` + + // The name of the Region. + RegionName *string `type:"string"` + + // The time at which the replica was first detected as inaccessible. To determine + // cause of inaccessibility check the ReplicaStatus property. + ReplicaInaccessibleDateTime *time.Time `type:"timestamp"` + + // The current state of the replica: + // + // * CREATING - The replica is being created. + // + // * UPDATING - The replica is being updated. + // + // * DELETING - The replica is being deleted. + // + // * ACTIVE - The replica is ready for use. + // + // * REGION_DISABLED - The replica is inaccessible because the Amazon Web + // Services Region has been disabled. If the Amazon Web Services Region remains + // inaccessible for more than 20 hours, DynamoDB will remove this replica + // from the replication group. The replica will not be deleted and replication + // will stop from and to this region. + // + // * INACCESSIBLE_ENCRYPTION_CREDENTIALS - The KMS key used to encrypt the + // table is inaccessible. If the KMS key remains inaccessible for more than + // 20 hours, DynamoDB will remove this replica from the replication group. + // The replica will not be deleted and replication will stop from and to + // this region. + ReplicaStatus *string `type:"string" enum:"ReplicaStatus"` + + // Detailed information about the replica status. + ReplicaStatusDescription *string `type:"string"` + + // Specifies the progress of a Create, Update, or Delete action on the replica + // as a percentage. + ReplicaStatusPercentProgress *string `type:"string"` + + // Contains details of the table class. + ReplicaTableClassSummary *TableClassSummary `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ReplicaDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ReplicaDescription) GoString() string { + return s.String() +} + +// SetGlobalSecondaryIndexes sets the GlobalSecondaryIndexes field's value. +func (s *ReplicaDescription) SetGlobalSecondaryIndexes(v []*ReplicaGlobalSecondaryIndexDescription) *ReplicaDescription { + s.GlobalSecondaryIndexes = v + return s +} + +// SetKMSMasterKeyId sets the KMSMasterKeyId field's value. +func (s *ReplicaDescription) SetKMSMasterKeyId(v string) *ReplicaDescription { + s.KMSMasterKeyId = &v + return s +} + +// SetProvisionedThroughputOverride sets the ProvisionedThroughputOverride field's value. +func (s *ReplicaDescription) SetProvisionedThroughputOverride(v *ProvisionedThroughputOverride) *ReplicaDescription { + s.ProvisionedThroughputOverride = v + return s +} + +// SetRegionName sets the RegionName field's value. +func (s *ReplicaDescription) SetRegionName(v string) *ReplicaDescription { + s.RegionName = &v + return s +} + +// SetReplicaInaccessibleDateTime sets the ReplicaInaccessibleDateTime field's value. +func (s *ReplicaDescription) SetReplicaInaccessibleDateTime(v time.Time) *ReplicaDescription { + s.ReplicaInaccessibleDateTime = &v + return s +} + +// SetReplicaStatus sets the ReplicaStatus field's value. +func (s *ReplicaDescription) SetReplicaStatus(v string) *ReplicaDescription { + s.ReplicaStatus = &v + return s +} + +// SetReplicaStatusDescription sets the ReplicaStatusDescription field's value. +func (s *ReplicaDescription) SetReplicaStatusDescription(v string) *ReplicaDescription { + s.ReplicaStatusDescription = &v + return s +} + +// SetReplicaStatusPercentProgress sets the ReplicaStatusPercentProgress field's value. +func (s *ReplicaDescription) SetReplicaStatusPercentProgress(v string) *ReplicaDescription { + s.ReplicaStatusPercentProgress = &v + return s +} + +// SetReplicaTableClassSummary sets the ReplicaTableClassSummary field's value. +func (s *ReplicaDescription) SetReplicaTableClassSummary(v *TableClassSummary) *ReplicaDescription { + s.ReplicaTableClassSummary = v + return s +} + +// Represents the properties of a replica global secondary index. +type ReplicaGlobalSecondaryIndex struct { + _ struct{} `type:"structure"` + + // The name of the global secondary index. + // + // IndexName is a required field + IndexName *string `min:"3" type:"string" required:"true"` + + // Replica table GSI-specific provisioned throughput. If not specified, uses + // the source table GSI's read capacity settings. + ProvisionedThroughputOverride *ProvisionedThroughputOverride `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ReplicaGlobalSecondaryIndex) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ReplicaGlobalSecondaryIndex) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ReplicaGlobalSecondaryIndex) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ReplicaGlobalSecondaryIndex"} + if s.IndexName == nil { + invalidParams.Add(request.NewErrParamRequired("IndexName")) + } + if s.IndexName != nil && len(*s.IndexName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("IndexName", 3)) + } + if s.ProvisionedThroughputOverride != nil { + if err := s.ProvisionedThroughputOverride.Validate(); err != nil { + invalidParams.AddNested("ProvisionedThroughputOverride", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetIndexName sets the IndexName field's value. +func (s *ReplicaGlobalSecondaryIndex) SetIndexName(v string) *ReplicaGlobalSecondaryIndex { + s.IndexName = &v + return s +} + +// SetProvisionedThroughputOverride sets the ProvisionedThroughputOverride field's value. +func (s *ReplicaGlobalSecondaryIndex) SetProvisionedThroughputOverride(v *ProvisionedThroughputOverride) *ReplicaGlobalSecondaryIndex { + s.ProvisionedThroughputOverride = v + return s +} + +// Represents the auto scaling configuration for a replica global secondary +// index. +type ReplicaGlobalSecondaryIndexAutoScalingDescription struct { + _ struct{} `type:"structure"` + + // The name of the global secondary index. + IndexName *string `min:"3" type:"string"` + + // The current state of the replica global secondary index: + // + // * CREATING - The index is being created. + // + // * UPDATING - The index is being updated. + // + // * DELETING - The index is being deleted. + // + // * ACTIVE - The index is ready for use. + IndexStatus *string `type:"string" enum:"IndexStatus"` + + // Represents the auto scaling settings for a global table or global secondary + // index. + ProvisionedReadCapacityAutoScalingSettings *AutoScalingSettingsDescription `type:"structure"` + + // Represents the auto scaling settings for a global table or global secondary + // index. + ProvisionedWriteCapacityAutoScalingSettings *AutoScalingSettingsDescription `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ReplicaGlobalSecondaryIndexAutoScalingDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ReplicaGlobalSecondaryIndexAutoScalingDescription) GoString() string { + return s.String() +} + +// SetIndexName sets the IndexName field's value. +func (s *ReplicaGlobalSecondaryIndexAutoScalingDescription) SetIndexName(v string) *ReplicaGlobalSecondaryIndexAutoScalingDescription { + s.IndexName = &v + return s +} + +// SetIndexStatus sets the IndexStatus field's value. +func (s *ReplicaGlobalSecondaryIndexAutoScalingDescription) SetIndexStatus(v string) *ReplicaGlobalSecondaryIndexAutoScalingDescription { + s.IndexStatus = &v + return s +} + +// SetProvisionedReadCapacityAutoScalingSettings sets the ProvisionedReadCapacityAutoScalingSettings field's value. +func (s *ReplicaGlobalSecondaryIndexAutoScalingDescription) SetProvisionedReadCapacityAutoScalingSettings(v *AutoScalingSettingsDescription) *ReplicaGlobalSecondaryIndexAutoScalingDescription { + s.ProvisionedReadCapacityAutoScalingSettings = v + return s +} + +// SetProvisionedWriteCapacityAutoScalingSettings sets the ProvisionedWriteCapacityAutoScalingSettings field's value. +func (s *ReplicaGlobalSecondaryIndexAutoScalingDescription) SetProvisionedWriteCapacityAutoScalingSettings(v *AutoScalingSettingsDescription) *ReplicaGlobalSecondaryIndexAutoScalingDescription { + s.ProvisionedWriteCapacityAutoScalingSettings = v + return s +} + +// Represents the auto scaling settings of a global secondary index for a replica +// that will be modified. +type ReplicaGlobalSecondaryIndexAutoScalingUpdate struct { + _ struct{} `type:"structure"` + + // The name of the global secondary index. + IndexName *string `min:"3" type:"string"` + + // Represents the auto scaling settings to be modified for a global table or + // global secondary index. + ProvisionedReadCapacityAutoScalingUpdate *AutoScalingSettingsUpdate `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ReplicaGlobalSecondaryIndexAutoScalingUpdate) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ReplicaGlobalSecondaryIndexAutoScalingUpdate) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ReplicaGlobalSecondaryIndexAutoScalingUpdate) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ReplicaGlobalSecondaryIndexAutoScalingUpdate"} + if s.IndexName != nil && len(*s.IndexName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("IndexName", 3)) + } + if s.ProvisionedReadCapacityAutoScalingUpdate != nil { + if err := s.ProvisionedReadCapacityAutoScalingUpdate.Validate(); err != nil { + invalidParams.AddNested("ProvisionedReadCapacityAutoScalingUpdate", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetIndexName sets the IndexName field's value. +func (s *ReplicaGlobalSecondaryIndexAutoScalingUpdate) SetIndexName(v string) *ReplicaGlobalSecondaryIndexAutoScalingUpdate { + s.IndexName = &v + return s +} + +// SetProvisionedReadCapacityAutoScalingUpdate sets the ProvisionedReadCapacityAutoScalingUpdate field's value. +func (s *ReplicaGlobalSecondaryIndexAutoScalingUpdate) SetProvisionedReadCapacityAutoScalingUpdate(v *AutoScalingSettingsUpdate) *ReplicaGlobalSecondaryIndexAutoScalingUpdate { + s.ProvisionedReadCapacityAutoScalingUpdate = v + return s +} + +// Represents the properties of a replica global secondary index. +type ReplicaGlobalSecondaryIndexDescription struct { + _ struct{} `type:"structure"` + + // The name of the global secondary index. + IndexName *string `min:"3" type:"string"` + + // If not described, uses the source table GSI's read capacity settings. + ProvisionedThroughputOverride *ProvisionedThroughputOverride `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ReplicaGlobalSecondaryIndexDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ReplicaGlobalSecondaryIndexDescription) GoString() string { + return s.String() +} + +// SetIndexName sets the IndexName field's value. +func (s *ReplicaGlobalSecondaryIndexDescription) SetIndexName(v string) *ReplicaGlobalSecondaryIndexDescription { + s.IndexName = &v + return s +} + +// SetProvisionedThroughputOverride sets the ProvisionedThroughputOverride field's value. +func (s *ReplicaGlobalSecondaryIndexDescription) SetProvisionedThroughputOverride(v *ProvisionedThroughputOverride) *ReplicaGlobalSecondaryIndexDescription { + s.ProvisionedThroughputOverride = v + return s +} + +// Represents the properties of a global secondary index. +type ReplicaGlobalSecondaryIndexSettingsDescription struct { + _ struct{} `type:"structure"` + + // The name of the global secondary index. The name must be unique among all + // other indexes on this table. + // + // IndexName is a required field + IndexName *string `min:"3" type:"string" required:"true"` + + // The current status of the global secondary index: + // + // * CREATING - The global secondary index is being created. + // + // * UPDATING - The global secondary index is being updated. + // + // * DELETING - The global secondary index is being deleted. + // + // * ACTIVE - The global secondary index is ready for use. + IndexStatus *string `type:"string" enum:"IndexStatus"` + + // Auto scaling settings for a global secondary index replica's read capacity + // units. + ProvisionedReadCapacityAutoScalingSettings *AutoScalingSettingsDescription `type:"structure"` + + // The maximum number of strongly consistent reads consumed per second before + // DynamoDB returns a ThrottlingException. + ProvisionedReadCapacityUnits *int64 `min:"1" type:"long"` + + // Auto scaling settings for a global secondary index replica's write capacity + // units. + ProvisionedWriteCapacityAutoScalingSettings *AutoScalingSettingsDescription `type:"structure"` + + // The maximum number of writes consumed per second before DynamoDB returns + // a ThrottlingException. + ProvisionedWriteCapacityUnits *int64 `min:"1" type:"long"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ReplicaGlobalSecondaryIndexSettingsDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ReplicaGlobalSecondaryIndexSettingsDescription) GoString() string { + return s.String() +} + +// SetIndexName sets the IndexName field's value. +func (s *ReplicaGlobalSecondaryIndexSettingsDescription) SetIndexName(v string) *ReplicaGlobalSecondaryIndexSettingsDescription { + s.IndexName = &v + return s +} + +// SetIndexStatus sets the IndexStatus field's value. +func (s *ReplicaGlobalSecondaryIndexSettingsDescription) SetIndexStatus(v string) *ReplicaGlobalSecondaryIndexSettingsDescription { + s.IndexStatus = &v + return s +} + +// SetProvisionedReadCapacityAutoScalingSettings sets the ProvisionedReadCapacityAutoScalingSettings field's value. +func (s *ReplicaGlobalSecondaryIndexSettingsDescription) SetProvisionedReadCapacityAutoScalingSettings(v *AutoScalingSettingsDescription) *ReplicaGlobalSecondaryIndexSettingsDescription { + s.ProvisionedReadCapacityAutoScalingSettings = v + return s +} + +// SetProvisionedReadCapacityUnits sets the ProvisionedReadCapacityUnits field's value. +func (s *ReplicaGlobalSecondaryIndexSettingsDescription) SetProvisionedReadCapacityUnits(v int64) *ReplicaGlobalSecondaryIndexSettingsDescription { + s.ProvisionedReadCapacityUnits = &v + return s +} + +// SetProvisionedWriteCapacityAutoScalingSettings sets the ProvisionedWriteCapacityAutoScalingSettings field's value. +func (s *ReplicaGlobalSecondaryIndexSettingsDescription) SetProvisionedWriteCapacityAutoScalingSettings(v *AutoScalingSettingsDescription) *ReplicaGlobalSecondaryIndexSettingsDescription { + s.ProvisionedWriteCapacityAutoScalingSettings = v + return s +} + +// SetProvisionedWriteCapacityUnits sets the ProvisionedWriteCapacityUnits field's value. +func (s *ReplicaGlobalSecondaryIndexSettingsDescription) SetProvisionedWriteCapacityUnits(v int64) *ReplicaGlobalSecondaryIndexSettingsDescription { + s.ProvisionedWriteCapacityUnits = &v + return s +} + +// Represents the settings of a global secondary index for a global table that +// will be modified. +type ReplicaGlobalSecondaryIndexSettingsUpdate struct { + _ struct{} `type:"structure"` + + // The name of the global secondary index. The name must be unique among all + // other indexes on this table. + // + // IndexName is a required field + IndexName *string `min:"3" type:"string" required:"true"` + + // Auto scaling settings for managing a global secondary index replica's read + // capacity units. + ProvisionedReadCapacityAutoScalingSettingsUpdate *AutoScalingSettingsUpdate `type:"structure"` + + // The maximum number of strongly consistent reads consumed per second before + // DynamoDB returns a ThrottlingException. + ProvisionedReadCapacityUnits *int64 `min:"1" type:"long"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ReplicaGlobalSecondaryIndexSettingsUpdate) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ReplicaGlobalSecondaryIndexSettingsUpdate) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ReplicaGlobalSecondaryIndexSettingsUpdate) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ReplicaGlobalSecondaryIndexSettingsUpdate"} + if s.IndexName == nil { + invalidParams.Add(request.NewErrParamRequired("IndexName")) + } + if s.IndexName != nil && len(*s.IndexName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("IndexName", 3)) + } + if s.ProvisionedReadCapacityUnits != nil && *s.ProvisionedReadCapacityUnits < 1 { + invalidParams.Add(request.NewErrParamMinValue("ProvisionedReadCapacityUnits", 1)) + } + if s.ProvisionedReadCapacityAutoScalingSettingsUpdate != nil { + if err := s.ProvisionedReadCapacityAutoScalingSettingsUpdate.Validate(); err != nil { + invalidParams.AddNested("ProvisionedReadCapacityAutoScalingSettingsUpdate", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetIndexName sets the IndexName field's value. +func (s *ReplicaGlobalSecondaryIndexSettingsUpdate) SetIndexName(v string) *ReplicaGlobalSecondaryIndexSettingsUpdate { + s.IndexName = &v + return s +} + +// SetProvisionedReadCapacityAutoScalingSettingsUpdate sets the ProvisionedReadCapacityAutoScalingSettingsUpdate field's value. +func (s *ReplicaGlobalSecondaryIndexSettingsUpdate) SetProvisionedReadCapacityAutoScalingSettingsUpdate(v *AutoScalingSettingsUpdate) *ReplicaGlobalSecondaryIndexSettingsUpdate { + s.ProvisionedReadCapacityAutoScalingSettingsUpdate = v + return s +} + +// SetProvisionedReadCapacityUnits sets the ProvisionedReadCapacityUnits field's value. +func (s *ReplicaGlobalSecondaryIndexSettingsUpdate) SetProvisionedReadCapacityUnits(v int64) *ReplicaGlobalSecondaryIndexSettingsUpdate { + s.ProvisionedReadCapacityUnits = &v + return s +} + +// The specified replica is no longer part of the global table. +type ReplicaNotFoundException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + Message_ *string `locationName:"message" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ReplicaNotFoundException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ReplicaNotFoundException) GoString() string { + return s.String() +} + +func newErrorReplicaNotFoundException(v protocol.ResponseMetadata) error { + return &ReplicaNotFoundException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *ReplicaNotFoundException) Code() string { + return "ReplicaNotFoundException" +} + +// Message returns the exception's message. +func (s *ReplicaNotFoundException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *ReplicaNotFoundException) OrigErr() error { + return nil +} + +func (s *ReplicaNotFoundException) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *ReplicaNotFoundException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *ReplicaNotFoundException) RequestID() string { + return s.RespMetadata.RequestID +} + +// Represents the properties of a replica. +type ReplicaSettingsDescription struct { + _ struct{} `type:"structure"` + + // The Region name of the replica. + // + // RegionName is a required field + RegionName *string `type:"string" required:"true"` + + // The read/write capacity mode of the replica. + ReplicaBillingModeSummary *BillingModeSummary `type:"structure"` + + // Replica global secondary index settings for the global table. + ReplicaGlobalSecondaryIndexSettings []*ReplicaGlobalSecondaryIndexSettingsDescription `type:"list"` + + // Auto scaling settings for a global table replica's read capacity units. + ReplicaProvisionedReadCapacityAutoScalingSettings *AutoScalingSettingsDescription `type:"structure"` + + // The maximum number of strongly consistent reads consumed per second before + // DynamoDB returns a ThrottlingException. For more information, see Specifying + // Read and Write Requirements (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithTables.html#ProvisionedThroughput) + // in the Amazon DynamoDB Developer Guide. + ReplicaProvisionedReadCapacityUnits *int64 `type:"long"` + + // Auto scaling settings for a global table replica's write capacity units. + ReplicaProvisionedWriteCapacityAutoScalingSettings *AutoScalingSettingsDescription `type:"structure"` + + // The maximum number of writes consumed per second before DynamoDB returns + // a ThrottlingException. For more information, see Specifying Read and Write + // Requirements (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithTables.html#ProvisionedThroughput) + // in the Amazon DynamoDB Developer Guide. + ReplicaProvisionedWriteCapacityUnits *int64 `type:"long"` + + // The current state of the Region: + // + // * CREATING - The Region is being created. + // + // * UPDATING - The Region is being updated. + // + // * DELETING - The Region is being deleted. + // + // * ACTIVE - The Region is ready for use. + ReplicaStatus *string `type:"string" enum:"ReplicaStatus"` + + // Contains details of the table class. + ReplicaTableClassSummary *TableClassSummary `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ReplicaSettingsDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ReplicaSettingsDescription) GoString() string { + return s.String() +} + +// SetRegionName sets the RegionName field's value. +func (s *ReplicaSettingsDescription) SetRegionName(v string) *ReplicaSettingsDescription { + s.RegionName = &v + return s +} + +// SetReplicaBillingModeSummary sets the ReplicaBillingModeSummary field's value. +func (s *ReplicaSettingsDescription) SetReplicaBillingModeSummary(v *BillingModeSummary) *ReplicaSettingsDescription { + s.ReplicaBillingModeSummary = v + return s +} + +// SetReplicaGlobalSecondaryIndexSettings sets the ReplicaGlobalSecondaryIndexSettings field's value. +func (s *ReplicaSettingsDescription) SetReplicaGlobalSecondaryIndexSettings(v []*ReplicaGlobalSecondaryIndexSettingsDescription) *ReplicaSettingsDescription { + s.ReplicaGlobalSecondaryIndexSettings = v + return s +} + +// SetReplicaProvisionedReadCapacityAutoScalingSettings sets the ReplicaProvisionedReadCapacityAutoScalingSettings field's value. +func (s *ReplicaSettingsDescription) SetReplicaProvisionedReadCapacityAutoScalingSettings(v *AutoScalingSettingsDescription) *ReplicaSettingsDescription { + s.ReplicaProvisionedReadCapacityAutoScalingSettings = v + return s +} + +// SetReplicaProvisionedReadCapacityUnits sets the ReplicaProvisionedReadCapacityUnits field's value. +func (s *ReplicaSettingsDescription) SetReplicaProvisionedReadCapacityUnits(v int64) *ReplicaSettingsDescription { + s.ReplicaProvisionedReadCapacityUnits = &v + return s +} + +// SetReplicaProvisionedWriteCapacityAutoScalingSettings sets the ReplicaProvisionedWriteCapacityAutoScalingSettings field's value. +func (s *ReplicaSettingsDescription) SetReplicaProvisionedWriteCapacityAutoScalingSettings(v *AutoScalingSettingsDescription) *ReplicaSettingsDescription { + s.ReplicaProvisionedWriteCapacityAutoScalingSettings = v + return s +} + +// SetReplicaProvisionedWriteCapacityUnits sets the ReplicaProvisionedWriteCapacityUnits field's value. +func (s *ReplicaSettingsDescription) SetReplicaProvisionedWriteCapacityUnits(v int64) *ReplicaSettingsDescription { + s.ReplicaProvisionedWriteCapacityUnits = &v + return s +} + +// SetReplicaStatus sets the ReplicaStatus field's value. +func (s *ReplicaSettingsDescription) SetReplicaStatus(v string) *ReplicaSettingsDescription { + s.ReplicaStatus = &v + return s +} + +// SetReplicaTableClassSummary sets the ReplicaTableClassSummary field's value. +func (s *ReplicaSettingsDescription) SetReplicaTableClassSummary(v *TableClassSummary) *ReplicaSettingsDescription { + s.ReplicaTableClassSummary = v + return s +} + +// Represents the settings for a global table in a Region that will be modified. +type ReplicaSettingsUpdate struct { + _ struct{} `type:"structure"` + + // The Region of the replica to be added. + // + // RegionName is a required field + RegionName *string `type:"string" required:"true"` + + // Represents the settings of a global secondary index for a global table that + // will be modified. + ReplicaGlobalSecondaryIndexSettingsUpdate []*ReplicaGlobalSecondaryIndexSettingsUpdate `min:"1" type:"list"` + + // Auto scaling settings for managing a global table replica's read capacity + // units. + ReplicaProvisionedReadCapacityAutoScalingSettingsUpdate *AutoScalingSettingsUpdate `type:"structure"` + + // The maximum number of strongly consistent reads consumed per second before + // DynamoDB returns a ThrottlingException. For more information, see Specifying + // Read and Write Requirements (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithTables.html#ProvisionedThroughput) + // in the Amazon DynamoDB Developer Guide. + ReplicaProvisionedReadCapacityUnits *int64 `min:"1" type:"long"` + + // Replica-specific table class. If not specified, uses the source table's table + // class. + ReplicaTableClass *string `type:"string" enum:"TableClass"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ReplicaSettingsUpdate) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ReplicaSettingsUpdate) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ReplicaSettingsUpdate) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ReplicaSettingsUpdate"} + if s.RegionName == nil { + invalidParams.Add(request.NewErrParamRequired("RegionName")) + } + if s.ReplicaGlobalSecondaryIndexSettingsUpdate != nil && len(s.ReplicaGlobalSecondaryIndexSettingsUpdate) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ReplicaGlobalSecondaryIndexSettingsUpdate", 1)) + } + if s.ReplicaProvisionedReadCapacityUnits != nil && *s.ReplicaProvisionedReadCapacityUnits < 1 { + invalidParams.Add(request.NewErrParamMinValue("ReplicaProvisionedReadCapacityUnits", 1)) + } + if s.ReplicaGlobalSecondaryIndexSettingsUpdate != nil { + for i, v := range s.ReplicaGlobalSecondaryIndexSettingsUpdate { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "ReplicaGlobalSecondaryIndexSettingsUpdate", i), err.(request.ErrInvalidParams)) + } + } + } + if s.ReplicaProvisionedReadCapacityAutoScalingSettingsUpdate != nil { + if err := s.ReplicaProvisionedReadCapacityAutoScalingSettingsUpdate.Validate(); err != nil { + invalidParams.AddNested("ReplicaProvisionedReadCapacityAutoScalingSettingsUpdate", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetRegionName sets the RegionName field's value. +func (s *ReplicaSettingsUpdate) SetRegionName(v string) *ReplicaSettingsUpdate { + s.RegionName = &v + return s +} + +// SetReplicaGlobalSecondaryIndexSettingsUpdate sets the ReplicaGlobalSecondaryIndexSettingsUpdate field's value. +func (s *ReplicaSettingsUpdate) SetReplicaGlobalSecondaryIndexSettingsUpdate(v []*ReplicaGlobalSecondaryIndexSettingsUpdate) *ReplicaSettingsUpdate { + s.ReplicaGlobalSecondaryIndexSettingsUpdate = v + return s +} + +// SetReplicaProvisionedReadCapacityAutoScalingSettingsUpdate sets the ReplicaProvisionedReadCapacityAutoScalingSettingsUpdate field's value. +func (s *ReplicaSettingsUpdate) SetReplicaProvisionedReadCapacityAutoScalingSettingsUpdate(v *AutoScalingSettingsUpdate) *ReplicaSettingsUpdate { + s.ReplicaProvisionedReadCapacityAutoScalingSettingsUpdate = v + return s +} + +// SetReplicaProvisionedReadCapacityUnits sets the ReplicaProvisionedReadCapacityUnits field's value. +func (s *ReplicaSettingsUpdate) SetReplicaProvisionedReadCapacityUnits(v int64) *ReplicaSettingsUpdate { + s.ReplicaProvisionedReadCapacityUnits = &v + return s +} + +// SetReplicaTableClass sets the ReplicaTableClass field's value. +func (s *ReplicaSettingsUpdate) SetReplicaTableClass(v string) *ReplicaSettingsUpdate { + s.ReplicaTableClass = &v + return s +} + +// Represents one of the following: +// +// * A new replica to be added to an existing global table. +// +// * New parameters for an existing replica. +// +// * An existing replica to be removed from an existing global table. +type ReplicaUpdate struct { + _ struct{} `type:"structure"` + + // The parameters required for creating a replica on an existing global table. + Create *CreateReplicaAction `type:"structure"` + + // The name of the existing replica to be removed. + Delete *DeleteReplicaAction `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ReplicaUpdate) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ReplicaUpdate) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ReplicaUpdate) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ReplicaUpdate"} + if s.Create != nil { + if err := s.Create.Validate(); err != nil { + invalidParams.AddNested("Create", err.(request.ErrInvalidParams)) + } + } + if s.Delete != nil { + if err := s.Delete.Validate(); err != nil { + invalidParams.AddNested("Delete", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetCreate sets the Create field's value. +func (s *ReplicaUpdate) SetCreate(v *CreateReplicaAction) *ReplicaUpdate { + s.Create = v + return s +} + +// SetDelete sets the Delete field's value. +func (s *ReplicaUpdate) SetDelete(v *DeleteReplicaAction) *ReplicaUpdate { + s.Delete = v + return s +} + +// Represents one of the following: +// +// * A new replica to be added to an existing regional table or global table. +// This request invokes the CreateTableReplica action in the destination +// Region. +// +// * New parameters for an existing replica. This request invokes the UpdateTable +// action in the destination Region. +// +// * An existing replica to be deleted. The request invokes the DeleteTableReplica +// action in the destination Region, deleting the replica and all if its +// items in the destination Region. +type ReplicationGroupUpdate struct { + _ struct{} `type:"structure"` + + // The parameters required for creating a replica for the table. + Create *CreateReplicationGroupMemberAction `type:"structure"` + + // The parameters required for deleting a replica for the table. + Delete *DeleteReplicationGroupMemberAction `type:"structure"` + + // The parameters required for updating a replica for the table. + Update *UpdateReplicationGroupMemberAction `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ReplicationGroupUpdate) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ReplicationGroupUpdate) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ReplicationGroupUpdate) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ReplicationGroupUpdate"} + if s.Create != nil { + if err := s.Create.Validate(); err != nil { + invalidParams.AddNested("Create", err.(request.ErrInvalidParams)) + } + } + if s.Delete != nil { + if err := s.Delete.Validate(); err != nil { + invalidParams.AddNested("Delete", err.(request.ErrInvalidParams)) + } + } + if s.Update != nil { + if err := s.Update.Validate(); err != nil { + invalidParams.AddNested("Update", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetCreate sets the Create field's value. +func (s *ReplicationGroupUpdate) SetCreate(v *CreateReplicationGroupMemberAction) *ReplicationGroupUpdate { + s.Create = v + return s +} + +// SetDelete sets the Delete field's value. +func (s *ReplicationGroupUpdate) SetDelete(v *DeleteReplicationGroupMemberAction) *ReplicationGroupUpdate { + s.Delete = v + return s +} + +// SetUpdate sets the Update field's value. +func (s *ReplicationGroupUpdate) SetUpdate(v *UpdateReplicationGroupMemberAction) *ReplicationGroupUpdate { + s.Update = v + return s +} + +// Throughput exceeds the current throughput quota for your account. Please +// contact Amazon Web Services Support (https://aws.amazon.com/support) to request +// a quota increase. +type RequestLimitExceeded struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + Message_ *string `locationName:"message" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s RequestLimitExceeded) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s RequestLimitExceeded) GoString() string { + return s.String() +} + +func newErrorRequestLimitExceeded(v protocol.ResponseMetadata) error { + return &RequestLimitExceeded{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *RequestLimitExceeded) Code() string { + return "RequestLimitExceeded" +} + +// Message returns the exception's message. +func (s *RequestLimitExceeded) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *RequestLimitExceeded) OrigErr() error { + return nil +} + +func (s *RequestLimitExceeded) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *RequestLimitExceeded) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *RequestLimitExceeded) RequestID() string { + return s.RespMetadata.RequestID +} + +// The operation conflicts with the resource's availability. For example, you +// attempted to recreate an existing table, or tried to delete a table currently +// in the CREATING state. +type ResourceInUseException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + // The resource which is being attempted to be changed is in use. + Message_ *string `locationName:"message" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ResourceInUseException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ResourceInUseException) GoString() string { + return s.String() +} + +func newErrorResourceInUseException(v protocol.ResponseMetadata) error { + return &ResourceInUseException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *ResourceInUseException) Code() string { + return "ResourceInUseException" +} + +// Message returns the exception's message. +func (s *ResourceInUseException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *ResourceInUseException) OrigErr() error { + return nil +} + +func (s *ResourceInUseException) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *ResourceInUseException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *ResourceInUseException) RequestID() string { + return s.RespMetadata.RequestID +} + +// The operation tried to access a nonexistent table or index. The resource +// might not be specified correctly, or its status might not be ACTIVE. +type ResourceNotFoundException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + // The resource which is being requested does not exist. + Message_ *string `locationName:"message" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ResourceNotFoundException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ResourceNotFoundException) GoString() string { + return s.String() +} + +func newErrorResourceNotFoundException(v protocol.ResponseMetadata) error { + return &ResourceNotFoundException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *ResourceNotFoundException) Code() string { + return "ResourceNotFoundException" +} + +// Message returns the exception's message. +func (s *ResourceNotFoundException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *ResourceNotFoundException) OrigErr() error { + return nil +} + +func (s *ResourceNotFoundException) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *ResourceNotFoundException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *ResourceNotFoundException) RequestID() string { + return s.RespMetadata.RequestID +} + +// Contains details for the restore. +type RestoreSummary struct { + _ struct{} `type:"structure"` + + // Point in time or source backup time. + // + // RestoreDateTime is a required field + RestoreDateTime *time.Time `type:"timestamp" required:"true"` + + // Indicates if a restore is in progress or not. + // + // RestoreInProgress is a required field + RestoreInProgress *bool `type:"boolean" required:"true"` + + // The Amazon Resource Name (ARN) of the backup from which the table was restored. + SourceBackupArn *string `min:"37" type:"string"` + + // The ARN of the source table of the backup that is being restored. + SourceTableArn *string `type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s RestoreSummary) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s RestoreSummary) GoString() string { + return s.String() +} + +// SetRestoreDateTime sets the RestoreDateTime field's value. +func (s *RestoreSummary) SetRestoreDateTime(v time.Time) *RestoreSummary { + s.RestoreDateTime = &v + return s +} + +// SetRestoreInProgress sets the RestoreInProgress field's value. +func (s *RestoreSummary) SetRestoreInProgress(v bool) *RestoreSummary { + s.RestoreInProgress = &v + return s +} + +// SetSourceBackupArn sets the SourceBackupArn field's value. +func (s *RestoreSummary) SetSourceBackupArn(v string) *RestoreSummary { + s.SourceBackupArn = &v + return s +} + +// SetSourceTableArn sets the SourceTableArn field's value. +func (s *RestoreSummary) SetSourceTableArn(v string) *RestoreSummary { + s.SourceTableArn = &v + return s +} + +type RestoreTableFromBackupInput struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) associated with the backup. + // + // BackupArn is a required field + BackupArn *string `min:"37" type:"string" required:"true"` + + // The billing mode of the restored table. + BillingModeOverride *string `type:"string" enum:"BillingMode"` + + // List of global secondary indexes for the restored table. The indexes provided + // should match existing secondary indexes. You can choose to exclude some or + // all of the indexes at the time of restore. + GlobalSecondaryIndexOverride []*GlobalSecondaryIndex `type:"list"` + + // List of local secondary indexes for the restored table. The indexes provided + // should match existing secondary indexes. You can choose to exclude some or + // all of the indexes at the time of restore. + LocalSecondaryIndexOverride []*LocalSecondaryIndex `type:"list"` + + // Provisioned throughput settings for the restored table. + ProvisionedThroughputOverride *ProvisionedThroughput `type:"structure"` + + // The new server-side encryption settings for the restored table. + SSESpecificationOverride *SSESpecification `type:"structure"` + + // The name of the new table to which the backup must be restored. + // + // TargetTableName is a required field + TargetTableName *string `min:"3" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s RestoreTableFromBackupInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s RestoreTableFromBackupInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *RestoreTableFromBackupInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "RestoreTableFromBackupInput"} + if s.BackupArn == nil { + invalidParams.Add(request.NewErrParamRequired("BackupArn")) + } + if s.BackupArn != nil && len(*s.BackupArn) < 37 { + invalidParams.Add(request.NewErrParamMinLen("BackupArn", 37)) + } + if s.TargetTableName == nil { + invalidParams.Add(request.NewErrParamRequired("TargetTableName")) + } + if s.TargetTableName != nil && len(*s.TargetTableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("TargetTableName", 3)) + } + if s.GlobalSecondaryIndexOverride != nil { + for i, v := range s.GlobalSecondaryIndexOverride { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "GlobalSecondaryIndexOverride", i), err.(request.ErrInvalidParams)) + } + } + } + if s.LocalSecondaryIndexOverride != nil { + for i, v := range s.LocalSecondaryIndexOverride { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "LocalSecondaryIndexOverride", i), err.(request.ErrInvalidParams)) + } + } + } + if s.ProvisionedThroughputOverride != nil { + if err := s.ProvisionedThroughputOverride.Validate(); err != nil { + invalidParams.AddNested("ProvisionedThroughputOverride", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetBackupArn sets the BackupArn field's value. +func (s *RestoreTableFromBackupInput) SetBackupArn(v string) *RestoreTableFromBackupInput { + s.BackupArn = &v + return s +} + +// SetBillingModeOverride sets the BillingModeOverride field's value. +func (s *RestoreTableFromBackupInput) SetBillingModeOverride(v string) *RestoreTableFromBackupInput { + s.BillingModeOverride = &v + return s +} + +// SetGlobalSecondaryIndexOverride sets the GlobalSecondaryIndexOverride field's value. +func (s *RestoreTableFromBackupInput) SetGlobalSecondaryIndexOverride(v []*GlobalSecondaryIndex) *RestoreTableFromBackupInput { + s.GlobalSecondaryIndexOverride = v + return s +} + +// SetLocalSecondaryIndexOverride sets the LocalSecondaryIndexOverride field's value. +func (s *RestoreTableFromBackupInput) SetLocalSecondaryIndexOverride(v []*LocalSecondaryIndex) *RestoreTableFromBackupInput { + s.LocalSecondaryIndexOverride = v + return s +} + +// SetProvisionedThroughputOverride sets the ProvisionedThroughputOverride field's value. +func (s *RestoreTableFromBackupInput) SetProvisionedThroughputOverride(v *ProvisionedThroughput) *RestoreTableFromBackupInput { + s.ProvisionedThroughputOverride = v + return s +} + +// SetSSESpecificationOverride sets the SSESpecificationOverride field's value. +func (s *RestoreTableFromBackupInput) SetSSESpecificationOverride(v *SSESpecification) *RestoreTableFromBackupInput { + s.SSESpecificationOverride = v + return s +} + +// SetTargetTableName sets the TargetTableName field's value. +func (s *RestoreTableFromBackupInput) SetTargetTableName(v string) *RestoreTableFromBackupInput { + s.TargetTableName = &v + return s +} + +type RestoreTableFromBackupOutput struct { + _ struct{} `type:"structure"` + + // The description of the table created from an existing backup. + TableDescription *TableDescription `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s RestoreTableFromBackupOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s RestoreTableFromBackupOutput) GoString() string { + return s.String() +} + +// SetTableDescription sets the TableDescription field's value. +func (s *RestoreTableFromBackupOutput) SetTableDescription(v *TableDescription) *RestoreTableFromBackupOutput { + s.TableDescription = v + return s +} + +type RestoreTableToPointInTimeInput struct { + _ struct{} `type:"structure"` + + // The billing mode of the restored table. + BillingModeOverride *string `type:"string" enum:"BillingMode"` + + // List of global secondary indexes for the restored table. The indexes provided + // should match existing secondary indexes. You can choose to exclude some or + // all of the indexes at the time of restore. + GlobalSecondaryIndexOverride []*GlobalSecondaryIndex `type:"list"` + + // List of local secondary indexes for the restored table. The indexes provided + // should match existing secondary indexes. You can choose to exclude some or + // all of the indexes at the time of restore. + LocalSecondaryIndexOverride []*LocalSecondaryIndex `type:"list"` + + // Provisioned throughput settings for the restored table. + ProvisionedThroughputOverride *ProvisionedThroughput `type:"structure"` + + // Time in the past to restore the table to. + RestoreDateTime *time.Time `type:"timestamp"` + + // The new server-side encryption settings for the restored table. + SSESpecificationOverride *SSESpecification `type:"structure"` + + // The DynamoDB table that will be restored. This value is an Amazon Resource + // Name (ARN). + SourceTableArn *string `type:"string"` + + // Name of the source table that is being restored. + SourceTableName *string `min:"3" type:"string"` + + // The name of the new table to which it must be restored to. + // + // TargetTableName is a required field + TargetTableName *string `min:"3" type:"string" required:"true"` + + // Restore the table to the latest possible time. LatestRestorableDateTime is + // typically 5 minutes before the current time. + UseLatestRestorableTime *bool `type:"boolean"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s RestoreTableToPointInTimeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s RestoreTableToPointInTimeInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *RestoreTableToPointInTimeInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "RestoreTableToPointInTimeInput"} + if s.SourceTableName != nil && len(*s.SourceTableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("SourceTableName", 3)) + } + if s.TargetTableName == nil { + invalidParams.Add(request.NewErrParamRequired("TargetTableName")) + } + if s.TargetTableName != nil && len(*s.TargetTableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("TargetTableName", 3)) + } + if s.GlobalSecondaryIndexOverride != nil { + for i, v := range s.GlobalSecondaryIndexOverride { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "GlobalSecondaryIndexOverride", i), err.(request.ErrInvalidParams)) + } + } + } + if s.LocalSecondaryIndexOverride != nil { + for i, v := range s.LocalSecondaryIndexOverride { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "LocalSecondaryIndexOverride", i), err.(request.ErrInvalidParams)) + } + } + } + if s.ProvisionedThroughputOverride != nil { + if err := s.ProvisionedThroughputOverride.Validate(); err != nil { + invalidParams.AddNested("ProvisionedThroughputOverride", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetBillingModeOverride sets the BillingModeOverride field's value. +func (s *RestoreTableToPointInTimeInput) SetBillingModeOverride(v string) *RestoreTableToPointInTimeInput { + s.BillingModeOverride = &v + return s +} + +// SetGlobalSecondaryIndexOverride sets the GlobalSecondaryIndexOverride field's value. +func (s *RestoreTableToPointInTimeInput) SetGlobalSecondaryIndexOverride(v []*GlobalSecondaryIndex) *RestoreTableToPointInTimeInput { + s.GlobalSecondaryIndexOverride = v + return s +} + +// SetLocalSecondaryIndexOverride sets the LocalSecondaryIndexOverride field's value. +func (s *RestoreTableToPointInTimeInput) SetLocalSecondaryIndexOverride(v []*LocalSecondaryIndex) *RestoreTableToPointInTimeInput { + s.LocalSecondaryIndexOverride = v + return s +} + +// SetProvisionedThroughputOverride sets the ProvisionedThroughputOverride field's value. +func (s *RestoreTableToPointInTimeInput) SetProvisionedThroughputOverride(v *ProvisionedThroughput) *RestoreTableToPointInTimeInput { + s.ProvisionedThroughputOverride = v + return s +} + +// SetRestoreDateTime sets the RestoreDateTime field's value. +func (s *RestoreTableToPointInTimeInput) SetRestoreDateTime(v time.Time) *RestoreTableToPointInTimeInput { + s.RestoreDateTime = &v + return s +} + +// SetSSESpecificationOverride sets the SSESpecificationOverride field's value. +func (s *RestoreTableToPointInTimeInput) SetSSESpecificationOverride(v *SSESpecification) *RestoreTableToPointInTimeInput { + s.SSESpecificationOverride = v + return s +} + +// SetSourceTableArn sets the SourceTableArn field's value. +func (s *RestoreTableToPointInTimeInput) SetSourceTableArn(v string) *RestoreTableToPointInTimeInput { + s.SourceTableArn = &v + return s +} + +// SetSourceTableName sets the SourceTableName field's value. +func (s *RestoreTableToPointInTimeInput) SetSourceTableName(v string) *RestoreTableToPointInTimeInput { + s.SourceTableName = &v + return s +} + +// SetTargetTableName sets the TargetTableName field's value. +func (s *RestoreTableToPointInTimeInput) SetTargetTableName(v string) *RestoreTableToPointInTimeInput { + s.TargetTableName = &v + return s +} + +// SetUseLatestRestorableTime sets the UseLatestRestorableTime field's value. +func (s *RestoreTableToPointInTimeInput) SetUseLatestRestorableTime(v bool) *RestoreTableToPointInTimeInput { + s.UseLatestRestorableTime = &v + return s +} + +type RestoreTableToPointInTimeOutput struct { + _ struct{} `type:"structure"` + + // Represents the properties of a table. + TableDescription *TableDescription `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s RestoreTableToPointInTimeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s RestoreTableToPointInTimeOutput) GoString() string { + return s.String() +} + +// SetTableDescription sets the TableDescription field's value. +func (s *RestoreTableToPointInTimeOutput) SetTableDescription(v *TableDescription) *RestoreTableToPointInTimeOutput { + s.TableDescription = v + return s +} + +// The description of the server-side encryption status on the specified table. +type SSEDescription struct { + _ struct{} `type:"structure"` + + // Indicates the time, in UNIX epoch date format, when DynamoDB detected that + // the table's KMS key was inaccessible. This attribute will automatically be + // cleared when DynamoDB detects that the table's KMS key is accessible again. + // DynamoDB will initiate the table archival process when table's KMS key remains + // inaccessible for more than seven days from this date. + InaccessibleEncryptionDateTime *time.Time `type:"timestamp"` + + // The KMS key ARN used for the KMS encryption. + KMSMasterKeyArn *string `type:"string"` + + // Server-side encryption type. The only supported value is: + // + // * KMS - Server-side encryption that uses Key Management Service. The key + // is stored in your account and is managed by KMS (KMS charges apply). + SSEType *string `type:"string" enum:"SSEType"` + + // Represents the current state of server-side encryption. The only supported + // values are: + // + // * ENABLED - Server-side encryption is enabled. + // + // * UPDATING - Server-side encryption is being updated. + Status *string `type:"string" enum:"SSEStatus"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s SSEDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s SSEDescription) GoString() string { + return s.String() +} + +// SetInaccessibleEncryptionDateTime sets the InaccessibleEncryptionDateTime field's value. +func (s *SSEDescription) SetInaccessibleEncryptionDateTime(v time.Time) *SSEDescription { + s.InaccessibleEncryptionDateTime = &v + return s +} + +// SetKMSMasterKeyArn sets the KMSMasterKeyArn field's value. +func (s *SSEDescription) SetKMSMasterKeyArn(v string) *SSEDescription { + s.KMSMasterKeyArn = &v + return s +} + +// SetSSEType sets the SSEType field's value. +func (s *SSEDescription) SetSSEType(v string) *SSEDescription { + s.SSEType = &v + return s +} + +// SetStatus sets the Status field's value. +func (s *SSEDescription) SetStatus(v string) *SSEDescription { + s.Status = &v + return s +} + +// Represents the settings used to enable server-side encryption. +type SSESpecification struct { + _ struct{} `type:"structure"` + + // Indicates whether server-side encryption is done using an Amazon Web Services + // managed key or an Amazon Web Services owned key. If enabled (true), server-side + // encryption type is set to KMS and an Amazon Web Services managed key is used + // (KMS charges apply). If disabled (false) or not specified, server-side encryption + // is set to Amazon Web Services owned key. + Enabled *bool `type:"boolean"` + + // The KMS key that should be used for the KMS encryption. To specify a key, + // use its key ID, Amazon Resource Name (ARN), alias name, or alias ARN. Note + // that you should only provide this parameter if the key is different from + // the default DynamoDB key alias/aws/dynamodb. + KMSMasterKeyId *string `type:"string"` + + // Server-side encryption type. The only supported value is: + // + // * KMS - Server-side encryption that uses Key Management Service. The key + // is stored in your account and is managed by KMS (KMS charges apply). + SSEType *string `type:"string" enum:"SSEType"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s SSESpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s SSESpecification) GoString() string { + return s.String() +} + +// SetEnabled sets the Enabled field's value. +func (s *SSESpecification) SetEnabled(v bool) *SSESpecification { + s.Enabled = &v + return s +} + +// SetKMSMasterKeyId sets the KMSMasterKeyId field's value. +func (s *SSESpecification) SetKMSMasterKeyId(v string) *SSESpecification { + s.KMSMasterKeyId = &v + return s +} + +// SetSSEType sets the SSEType field's value. +func (s *SSESpecification) SetSSEType(v string) *SSESpecification { + s.SSEType = &v + return s +} + +// Represents the input of a Scan operation. +type ScanInput struct { + _ struct{} `type:"structure"` + + // This is a legacy parameter. Use ProjectionExpression instead. For more information, + // see AttributesToGet (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.AttributesToGet.html) + // in the Amazon DynamoDB Developer Guide. + AttributesToGet []*string `min:"1" type:"list"` + + // This is a legacy parameter. Use FilterExpression instead. For more information, + // see ConditionalOperator (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.ConditionalOperator.html) + // in the Amazon DynamoDB Developer Guide. + ConditionalOperator *string `type:"string" enum:"ConditionalOperator"` + + // A Boolean value that determines the read consistency model during the scan: + // + // * If ConsistentRead is false, then the data returned from Scan might not + // contain the results from other recently completed write operations (PutItem, + // UpdateItem, or DeleteItem). + // + // * If ConsistentRead is true, then all of the write operations that completed + // before the Scan began are guaranteed to be contained in the Scan response. + // + // The default setting for ConsistentRead is false. + // + // The ConsistentRead parameter is not supported on global secondary indexes. + // If you scan a global secondary index with ConsistentRead set to true, you + // will receive a ValidationException. + ConsistentRead *bool `type:"boolean"` + + // The primary key of the first item that this operation will evaluate. Use + // the value that was returned for LastEvaluatedKey in the previous operation. + // + // The data type for ExclusiveStartKey must be String, Number or Binary. No + // set data types are allowed. + // + // In a parallel scan, a Scan request that includes ExclusiveStartKey must specify + // the same segment whose previous Scan returned the corresponding value of + // LastEvaluatedKey. + ExclusiveStartKey map[string]*AttributeValue `type:"map"` + + // One or more substitution tokens for attribute names in an expression. The + // following are some use cases for using ExpressionAttributeNames: + // + // * To access an attribute whose name conflicts with a DynamoDB reserved + // word. + // + // * To create a placeholder for repeating occurrences of an attribute name + // in an expression. + // + // * To prevent special characters in an attribute name from being misinterpreted + // in an expression. + // + // Use the # character in an expression to dereference an attribute name. For + // example, consider the following attribute name: + // + // * Percentile + // + // The name of this attribute conflicts with a reserved word, so it cannot be + // used directly in an expression. (For the complete list of reserved words, + // see Reserved Words (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html) + // in the Amazon DynamoDB Developer Guide). To work around this, you could specify + // the following for ExpressionAttributeNames: + // + // * {"#P":"Percentile"} + // + // You could then use this substitution in an expression, as in this example: + // + // * #P = :val + // + // Tokens that begin with the : character are expression attribute values, which + // are placeholders for the actual value at runtime. + // + // For more information on expression attribute names, see Specifying Item Attributes + // (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.AccessingItemAttributes.html) + // in the Amazon DynamoDB Developer Guide. + ExpressionAttributeNames map[string]*string `type:"map"` + + // One or more values that can be substituted in an expression. + // + // Use the : (colon) character in an expression to dereference an attribute + // value. For example, suppose that you wanted to check whether the value of + // the ProductStatus attribute was one of the following: + // + // Available | Backordered | Discontinued + // + // You would first need to specify ExpressionAttributeValues as follows: + // + // { ":avail":{"S":"Available"}, ":back":{"S":"Backordered"}, ":disc":{"S":"Discontinued"} + // } + // + // You could then use these values in an expression, such as this: + // + // ProductStatus IN (:avail, :back, :disc) + // + // For more information on expression attribute values, see Condition Expressions + // (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.SpecifyingConditions.html) + // in the Amazon DynamoDB Developer Guide. + ExpressionAttributeValues map[string]*AttributeValue `type:"map"` + + // A string that contains conditions that DynamoDB applies after the Scan operation, + // but before the data is returned to you. Items that do not satisfy the FilterExpression + // criteria are not returned. + // + // A FilterExpression is applied after the items have already been read; the + // process of filtering does not consume any additional read capacity units. + // + // For more information, see Filter Expressions (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html#FilteringResults) + // in the Amazon DynamoDB Developer Guide. + FilterExpression *string `type:"string"` + + // The name of a secondary index to scan. This index can be any local secondary + // index or global secondary index. Note that if you use the IndexName parameter, + // you must also provide TableName. + IndexName *string `min:"3" type:"string"` + + // The maximum number of items to evaluate (not necessarily the number of matching + // items). If DynamoDB processes the number of items up to the limit while processing + // the results, it stops the operation and returns the matching values up to + // that point, and a key in LastEvaluatedKey to apply in a subsequent operation, + // so that you can pick up where you left off. Also, if the processed dataset + // size exceeds 1 MB before DynamoDB reaches this limit, it stops the operation + // and returns the matching values up to the limit, and a key in LastEvaluatedKey + // to apply in a subsequent operation to continue the operation. For more information, + // see Working with Queries (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html) + // in the Amazon DynamoDB Developer Guide. + Limit *int64 `min:"1" type:"integer"` + + // A string that identifies one or more attributes to retrieve from the specified + // table or index. These attributes can include scalars, sets, or elements of + // a JSON document. The attributes in the expression must be separated by commas. + // + // If no attribute names are specified, then all attributes will be returned. + // If any of the requested attributes are not found, they will not appear in + // the result. + // + // For more information, see Specifying Item Attributes (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.AccessingItemAttributes.html) + // in the Amazon DynamoDB Developer Guide. + ProjectionExpression *string `type:"string"` + + // Determines the level of detail about either provisioned or on-demand throughput + // consumption that is returned in the response: + // + // * INDEXES - The response includes the aggregate ConsumedCapacity for the + // operation, together with ConsumedCapacity for each table and secondary + // index that was accessed. Note that some operations, such as GetItem and + // BatchGetItem, do not access any indexes at all. In these cases, specifying + // INDEXES will only return ConsumedCapacity information for table(s). + // + // * TOTAL - The response includes only the aggregate ConsumedCapacity for + // the operation. + // + // * NONE - No ConsumedCapacity details are included in the response. + ReturnConsumedCapacity *string `type:"string" enum:"ReturnConsumedCapacity"` + + // This is a legacy parameter. Use FilterExpression instead. For more information, + // see ScanFilter (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.ScanFilter.html) + // in the Amazon DynamoDB Developer Guide. + ScanFilter map[string]*Condition `type:"map"` + + // For a parallel Scan request, Segment identifies an individual segment to + // be scanned by an application worker. + // + // Segment IDs are zero-based, so the first segment is always 0. For example, + // if you want to use four application threads to scan a table or an index, + // then the first thread specifies a Segment value of 0, the second thread specifies + // 1, and so on. + // + // The value of LastEvaluatedKey returned from a parallel Scan request must + // be used as ExclusiveStartKey with the same segment ID in a subsequent Scan + // operation. + // + // The value for Segment must be greater than or equal to 0, and less than the + // value provided for TotalSegments. + // + // If you provide Segment, you must also provide TotalSegments. + Segment *int64 `type:"integer"` + + // The attributes to be returned in the result. You can retrieve all item attributes, + // specific item attributes, the count of matching items, or in the case of + // an index, some or all of the attributes projected into the index. + // + // * ALL_ATTRIBUTES - Returns all of the item attributes from the specified + // table or index. If you query a local secondary index, then for each matching + // item in the index, DynamoDB fetches the entire item from the parent table. + // If the index is configured to project all item attributes, then all of + // the data can be obtained from the local secondary index, and no fetching + // is required. + // + // * ALL_PROJECTED_ATTRIBUTES - Allowed only when querying an index. Retrieves + // all attributes that have been projected into the index. If the index is + // configured to project all attributes, this return value is equivalent + // to specifying ALL_ATTRIBUTES. + // + // * COUNT - Returns the number of matching items, rather than the matching + // items themselves. + // + // * SPECIFIC_ATTRIBUTES - Returns only the attributes listed in AttributesToGet. + // This return value is equivalent to specifying AttributesToGet without + // specifying any value for Select. If you query or scan a local secondary + // index and request only attributes that are projected into that index, + // the operation reads only the index and not the table. If any of the requested + // attributes are not projected into the local secondary index, DynamoDB + // fetches each of these attributes from the parent table. This extra fetching + // incurs additional throughput cost and latency. If you query or scan a + // global secondary index, you can only request attributes that are projected + // into the index. Global secondary index queries cannot fetch attributes + // from the parent table. + // + // If neither Select nor AttributesToGet are specified, DynamoDB defaults to + // ALL_ATTRIBUTES when accessing a table, and ALL_PROJECTED_ATTRIBUTES when + // accessing an index. You cannot use both Select and AttributesToGet together + // in a single request, unless the value for Select is SPECIFIC_ATTRIBUTES. + // (This usage is equivalent to specifying AttributesToGet without any value + // for Select.) + // + // If you use the ProjectionExpression parameter, then the value for Select + // can only be SPECIFIC_ATTRIBUTES. Any other value for Select will return an + // error. + Select *string `type:"string" enum:"Select"` + + // The name of the table containing the requested items; or, if you provide + // IndexName, the name of the table to which that index belongs. + // + // TableName is a required field + TableName *string `min:"3" type:"string" required:"true"` + + // For a parallel Scan request, TotalSegments represents the total number of + // segments into which the Scan operation will be divided. The value of TotalSegments + // corresponds to the number of application workers that will perform the parallel + // scan. For example, if you want to use four application threads to scan a + // table or an index, specify a TotalSegments value of 4. + // + // The value for TotalSegments must be greater than or equal to 1, and less + // than or equal to 1000000. If you specify a TotalSegments value of 1, the + // Scan operation will be sequential rather than parallel. + // + // If you specify TotalSegments, you must also specify Segment. + TotalSegments *int64 `min:"1" type:"integer"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ScanInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ScanInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ScanInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ScanInput"} + if s.AttributesToGet != nil && len(s.AttributesToGet) < 1 { + invalidParams.Add(request.NewErrParamMinLen("AttributesToGet", 1)) + } + if s.IndexName != nil && len(*s.IndexName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("IndexName", 3)) + } + if s.Limit != nil && *s.Limit < 1 { + invalidParams.Add(request.NewErrParamMinValue("Limit", 1)) + } + if s.TableName == nil { + invalidParams.Add(request.NewErrParamRequired("TableName")) + } + if s.TableName != nil && len(*s.TableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("TableName", 3)) + } + if s.TotalSegments != nil && *s.TotalSegments < 1 { + invalidParams.Add(request.NewErrParamMinValue("TotalSegments", 1)) + } + if s.ScanFilter != nil { + for i, v := range s.ScanFilter { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "ScanFilter", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAttributesToGet sets the AttributesToGet field's value. +func (s *ScanInput) SetAttributesToGet(v []*string) *ScanInput { + s.AttributesToGet = v + return s +} + +// SetConditionalOperator sets the ConditionalOperator field's value. +func (s *ScanInput) SetConditionalOperator(v string) *ScanInput { + s.ConditionalOperator = &v + return s +} + +// SetConsistentRead sets the ConsistentRead field's value. +func (s *ScanInput) SetConsistentRead(v bool) *ScanInput { + s.ConsistentRead = &v + return s +} + +// SetExclusiveStartKey sets the ExclusiveStartKey field's value. +func (s *ScanInput) SetExclusiveStartKey(v map[string]*AttributeValue) *ScanInput { + s.ExclusiveStartKey = v + return s +} + +// SetExpressionAttributeNames sets the ExpressionAttributeNames field's value. +func (s *ScanInput) SetExpressionAttributeNames(v map[string]*string) *ScanInput { + s.ExpressionAttributeNames = v + return s +} + +// SetExpressionAttributeValues sets the ExpressionAttributeValues field's value. +func (s *ScanInput) SetExpressionAttributeValues(v map[string]*AttributeValue) *ScanInput { + s.ExpressionAttributeValues = v + return s +} + +// SetFilterExpression sets the FilterExpression field's value. +func (s *ScanInput) SetFilterExpression(v string) *ScanInput { + s.FilterExpression = &v + return s +} + +// SetIndexName sets the IndexName field's value. +func (s *ScanInput) SetIndexName(v string) *ScanInput { + s.IndexName = &v + return s +} + +// SetLimit sets the Limit field's value. +func (s *ScanInput) SetLimit(v int64) *ScanInput { + s.Limit = &v + return s +} + +// SetProjectionExpression sets the ProjectionExpression field's value. +func (s *ScanInput) SetProjectionExpression(v string) *ScanInput { + s.ProjectionExpression = &v + return s +} + +// SetReturnConsumedCapacity sets the ReturnConsumedCapacity field's value. +func (s *ScanInput) SetReturnConsumedCapacity(v string) *ScanInput { + s.ReturnConsumedCapacity = &v + return s +} + +// SetScanFilter sets the ScanFilter field's value. +func (s *ScanInput) SetScanFilter(v map[string]*Condition) *ScanInput { + s.ScanFilter = v + return s +} + +// SetSegment sets the Segment field's value. +func (s *ScanInput) SetSegment(v int64) *ScanInput { + s.Segment = &v + return s +} + +// SetSelect sets the Select field's value. +func (s *ScanInput) SetSelect(v string) *ScanInput { + s.Select = &v + return s +} + +// SetTableName sets the TableName field's value. +func (s *ScanInput) SetTableName(v string) *ScanInput { + s.TableName = &v + return s +} + +// SetTotalSegments sets the TotalSegments field's value. +func (s *ScanInput) SetTotalSegments(v int64) *ScanInput { + s.TotalSegments = &v + return s +} + +// Represents the output of a Scan operation. +type ScanOutput struct { + _ struct{} `type:"structure"` + + // The capacity units consumed by the Scan operation. The data returned includes + // the total provisioned throughput consumed, along with statistics for the + // table and any indexes involved in the operation. ConsumedCapacity is only + // returned if the ReturnConsumedCapacity parameter was specified. For more + // information, see Provisioned Throughput (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ProvisionedThroughputIntro.html) + // in the Amazon DynamoDB Developer Guide. + ConsumedCapacity *ConsumedCapacity `type:"structure"` + + // The number of items in the response. + // + // If you set ScanFilter in the request, then Count is the number of items returned + // after the filter was applied, and ScannedCount is the number of matching + // items before the filter was applied. + // + // If you did not use a filter in the request, then Count is the same as ScannedCount. + Count *int64 `type:"integer"` + + // An array of item attributes that match the scan criteria. Each element in + // this array consists of an attribute name and the value for that attribute. + Items []map[string]*AttributeValue `type:"list"` + + // The primary key of the item where the operation stopped, inclusive of the + // previous result set. Use this value to start a new operation, excluding this + // value in the new request. + // + // If LastEvaluatedKey is empty, then the "last page" of results has been processed + // and there is no more data to be retrieved. + // + // If LastEvaluatedKey is not empty, it does not necessarily mean that there + // is more data in the result set. The only way to know when you have reached + // the end of the result set is when LastEvaluatedKey is empty. + LastEvaluatedKey map[string]*AttributeValue `type:"map"` + + // The number of items evaluated, before any ScanFilter is applied. A high ScannedCount + // value with few, or no, Count results indicates an inefficient Scan operation. + // For more information, see Count and ScannedCount (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html#Count) + // in the Amazon DynamoDB Developer Guide. + // + // If you did not use a filter in the request, then ScannedCount is the same + // as Count. + ScannedCount *int64 `type:"integer"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ScanOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s ScanOutput) GoString() string { + return s.String() +} + +// SetConsumedCapacity sets the ConsumedCapacity field's value. +func (s *ScanOutput) SetConsumedCapacity(v *ConsumedCapacity) *ScanOutput { + s.ConsumedCapacity = v + return s +} + +// SetCount sets the Count field's value. +func (s *ScanOutput) SetCount(v int64) *ScanOutput { + s.Count = &v + return s +} + +// SetItems sets the Items field's value. +func (s *ScanOutput) SetItems(v []map[string]*AttributeValue) *ScanOutput { + s.Items = v + return s +} + +// SetLastEvaluatedKey sets the LastEvaluatedKey field's value. +func (s *ScanOutput) SetLastEvaluatedKey(v map[string]*AttributeValue) *ScanOutput { + s.LastEvaluatedKey = v + return s +} + +// SetScannedCount sets the ScannedCount field's value. +func (s *ScanOutput) SetScannedCount(v int64) *ScanOutput { + s.ScannedCount = &v + return s +} + +// Contains the details of the table when the backup was created. +type SourceTableDetails struct { + _ struct{} `type:"structure"` + + // Controls how you are charged for read and write throughput and how you manage + // capacity. This setting can be changed later. + // + // * PROVISIONED - Sets the read/write capacity mode to PROVISIONED. We recommend + // using PROVISIONED for predictable workloads. + // + // * PAY_PER_REQUEST - Sets the read/write capacity mode to PAY_PER_REQUEST. + // We recommend using PAY_PER_REQUEST for unpredictable workloads. + BillingMode *string `type:"string" enum:"BillingMode"` + + // Number of items in the table. Note that this is an approximate value. + ItemCount *int64 `type:"long"` + + // Schema of the table. + // + // KeySchema is a required field + KeySchema []*KeySchemaElement `min:"1" type:"list" required:"true"` + + // Read IOPs and Write IOPS on the table when the backup was created. + // + // ProvisionedThroughput is a required field + ProvisionedThroughput *ProvisionedThroughput `type:"structure" required:"true"` + + // ARN of the table for which backup was created. + TableArn *string `type:"string"` + + // Time when the source table was created. + // + // TableCreationDateTime is a required field + TableCreationDateTime *time.Time `type:"timestamp" required:"true"` + + // Unique identifier for the table for which the backup was created. + // + // TableId is a required field + TableId *string `type:"string" required:"true"` + + // The name of the table for which the backup was created. + // + // TableName is a required field + TableName *string `min:"3" type:"string" required:"true"` + + // Size of the table in bytes. Note that this is an approximate value. + TableSizeBytes *int64 `type:"long"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s SourceTableDetails) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s SourceTableDetails) GoString() string { + return s.String() +} + +// SetBillingMode sets the BillingMode field's value. +func (s *SourceTableDetails) SetBillingMode(v string) *SourceTableDetails { + s.BillingMode = &v + return s +} + +// SetItemCount sets the ItemCount field's value. +func (s *SourceTableDetails) SetItemCount(v int64) *SourceTableDetails { + s.ItemCount = &v + return s +} + +// SetKeySchema sets the KeySchema field's value. +func (s *SourceTableDetails) SetKeySchema(v []*KeySchemaElement) *SourceTableDetails { + s.KeySchema = v + return s +} + +// SetProvisionedThroughput sets the ProvisionedThroughput field's value. +func (s *SourceTableDetails) SetProvisionedThroughput(v *ProvisionedThroughput) *SourceTableDetails { + s.ProvisionedThroughput = v + return s +} + +// SetTableArn sets the TableArn field's value. +func (s *SourceTableDetails) SetTableArn(v string) *SourceTableDetails { + s.TableArn = &v + return s +} + +// SetTableCreationDateTime sets the TableCreationDateTime field's value. +func (s *SourceTableDetails) SetTableCreationDateTime(v time.Time) *SourceTableDetails { + s.TableCreationDateTime = &v + return s +} + +// SetTableId sets the TableId field's value. +func (s *SourceTableDetails) SetTableId(v string) *SourceTableDetails { + s.TableId = &v + return s +} + +// SetTableName sets the TableName field's value. +func (s *SourceTableDetails) SetTableName(v string) *SourceTableDetails { + s.TableName = &v + return s +} + +// SetTableSizeBytes sets the TableSizeBytes field's value. +func (s *SourceTableDetails) SetTableSizeBytes(v int64) *SourceTableDetails { + s.TableSizeBytes = &v + return s +} + +// Contains the details of the features enabled on the table when the backup +// was created. For example, LSIs, GSIs, streams, TTL. +type SourceTableFeatureDetails struct { + _ struct{} `type:"structure"` + + // Represents the GSI properties for the table when the backup was created. + // It includes the IndexName, KeySchema, Projection, and ProvisionedThroughput + // for the GSIs on the table at the time of backup. + GlobalSecondaryIndexes []*GlobalSecondaryIndexInfo `type:"list"` + + // Represents the LSI properties for the table when the backup was created. + // It includes the IndexName, KeySchema and Projection for the LSIs on the table + // at the time of backup. + LocalSecondaryIndexes []*LocalSecondaryIndexInfo `type:"list"` + + // The description of the server-side encryption status on the table when the + // backup was created. + SSEDescription *SSEDescription `type:"structure"` + + // Stream settings on the table when the backup was created. + StreamDescription *StreamSpecification `type:"structure"` + + // Time to Live settings on the table when the backup was created. + TimeToLiveDescription *TimeToLiveDescription `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s SourceTableFeatureDetails) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s SourceTableFeatureDetails) GoString() string { + return s.String() +} + +// SetGlobalSecondaryIndexes sets the GlobalSecondaryIndexes field's value. +func (s *SourceTableFeatureDetails) SetGlobalSecondaryIndexes(v []*GlobalSecondaryIndexInfo) *SourceTableFeatureDetails { + s.GlobalSecondaryIndexes = v + return s +} + +// SetLocalSecondaryIndexes sets the LocalSecondaryIndexes field's value. +func (s *SourceTableFeatureDetails) SetLocalSecondaryIndexes(v []*LocalSecondaryIndexInfo) *SourceTableFeatureDetails { + s.LocalSecondaryIndexes = v + return s +} + +// SetSSEDescription sets the SSEDescription field's value. +func (s *SourceTableFeatureDetails) SetSSEDescription(v *SSEDescription) *SourceTableFeatureDetails { + s.SSEDescription = v + return s +} + +// SetStreamDescription sets the StreamDescription field's value. +func (s *SourceTableFeatureDetails) SetStreamDescription(v *StreamSpecification) *SourceTableFeatureDetails { + s.StreamDescription = v + return s +} + +// SetTimeToLiveDescription sets the TimeToLiveDescription field's value. +func (s *SourceTableFeatureDetails) SetTimeToLiveDescription(v *TimeToLiveDescription) *SourceTableFeatureDetails { + s.TimeToLiveDescription = v + return s +} + +// Represents the DynamoDB Streams configuration for a table in DynamoDB. +type StreamSpecification struct { + _ struct{} `type:"structure"` + + // Indicates whether DynamoDB Streams is enabled (true) or disabled (false) + // on the table. + // + // StreamEnabled is a required field + StreamEnabled *bool `type:"boolean" required:"true"` + + // When an item in the table is modified, StreamViewType determines what information + // is written to the stream for this table. Valid values for StreamViewType + // are: + // + // * KEYS_ONLY - Only the key attributes of the modified item are written + // to the stream. + // + // * NEW_IMAGE - The entire item, as it appears after it was modified, is + // written to the stream. + // + // * OLD_IMAGE - The entire item, as it appeared before it was modified, + // is written to the stream. + // + // * NEW_AND_OLD_IMAGES - Both the new and the old item images of the item + // are written to the stream. + StreamViewType *string `type:"string" enum:"StreamViewType"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s StreamSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s StreamSpecification) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *StreamSpecification) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "StreamSpecification"} + if s.StreamEnabled == nil { + invalidParams.Add(request.NewErrParamRequired("StreamEnabled")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetStreamEnabled sets the StreamEnabled field's value. +func (s *StreamSpecification) SetStreamEnabled(v bool) *StreamSpecification { + s.StreamEnabled = &v + return s +} + +// SetStreamViewType sets the StreamViewType field's value. +func (s *StreamSpecification) SetStreamViewType(v string) *StreamSpecification { + s.StreamViewType = &v + return s +} + +// A target table with the specified name already exists. +type TableAlreadyExistsException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + Message_ *string `locationName:"message" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TableAlreadyExistsException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TableAlreadyExistsException) GoString() string { + return s.String() +} + +func newErrorTableAlreadyExistsException(v protocol.ResponseMetadata) error { + return &TableAlreadyExistsException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *TableAlreadyExistsException) Code() string { + return "TableAlreadyExistsException" +} + +// Message returns the exception's message. +func (s *TableAlreadyExistsException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *TableAlreadyExistsException) OrigErr() error { + return nil +} + +func (s *TableAlreadyExistsException) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *TableAlreadyExistsException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *TableAlreadyExistsException) RequestID() string { + return s.RespMetadata.RequestID +} + +// Represents the auto scaling configuration for a global table. +type TableAutoScalingDescription struct { + _ struct{} `type:"structure"` + + // Represents replicas of the global table. + Replicas []*ReplicaAutoScalingDescription `type:"list"` + + // The name of the table. + TableName *string `min:"3" type:"string"` + + // The current state of the table: + // + // * CREATING - The table is being created. + // + // * UPDATING - The table is being updated. + // + // * DELETING - The table is being deleted. + // + // * ACTIVE - The table is ready for use. + TableStatus *string `type:"string" enum:"TableStatus"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TableAutoScalingDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TableAutoScalingDescription) GoString() string { + return s.String() +} + +// SetReplicas sets the Replicas field's value. +func (s *TableAutoScalingDescription) SetReplicas(v []*ReplicaAutoScalingDescription) *TableAutoScalingDescription { + s.Replicas = v + return s +} + +// SetTableName sets the TableName field's value. +func (s *TableAutoScalingDescription) SetTableName(v string) *TableAutoScalingDescription { + s.TableName = &v + return s +} + +// SetTableStatus sets the TableStatus field's value. +func (s *TableAutoScalingDescription) SetTableStatus(v string) *TableAutoScalingDescription { + s.TableStatus = &v + return s +} + +// Contains details of the table class. +type TableClassSummary struct { + _ struct{} `type:"structure"` + + // The date and time at which the table class was last updated. + LastUpdateDateTime *time.Time `type:"timestamp"` + + // The table class of the specified table. Valid values are STANDARD and STANDARD_INFREQUENT_ACCESS. + TableClass *string `type:"string" enum:"TableClass"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TableClassSummary) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TableClassSummary) GoString() string { + return s.String() +} + +// SetLastUpdateDateTime sets the LastUpdateDateTime field's value. +func (s *TableClassSummary) SetLastUpdateDateTime(v time.Time) *TableClassSummary { + s.LastUpdateDateTime = &v + return s +} + +// SetTableClass sets the TableClass field's value. +func (s *TableClassSummary) SetTableClass(v string) *TableClassSummary { + s.TableClass = &v + return s +} + +// Represents the properties of a table. +type TableDescription struct { + _ struct{} `type:"structure"` + + // Contains information about the table archive. + ArchivalSummary *ArchivalSummary `type:"structure"` + + // An array of AttributeDefinition objects. Each of these objects describes + // one attribute in the table and index key schema. + // + // Each AttributeDefinition object in this array is composed of: + // + // * AttributeName - The name of the attribute. + // + // * AttributeType - The data type for the attribute. + AttributeDefinitions []*AttributeDefinition `type:"list"` + + // Contains the details for the read/write capacity mode. + BillingModeSummary *BillingModeSummary `type:"structure"` + + // The date and time when the table was created, in UNIX epoch time (http://www.epochconverter.com/) + // format. + CreationDateTime *time.Time `type:"timestamp"` + + // The global secondary indexes, if any, on the table. Each index is scoped + // to a given partition key value. Each element is composed of: + // + // * Backfilling - If true, then the index is currently in the backfilling + // phase. Backfilling occurs only when a new global secondary index is added + // to the table. It is the process by which DynamoDB populates the new index + // with data from the table. (This attribute does not appear for indexes + // that were created during a CreateTable operation.) You can delete an index + // that is being created during the Backfilling phase when IndexStatus is + // set to CREATING and Backfilling is true. You can't delete the index that + // is being created when IndexStatus is set to CREATING and Backfilling is + // false. (This attribute does not appear for indexes that were created during + // a CreateTable operation.) + // + // * IndexName - The name of the global secondary index. + // + // * IndexSizeBytes - The total size of the global secondary index, in bytes. + // DynamoDB updates this value approximately every six hours. Recent changes + // might not be reflected in this value. + // + // * IndexStatus - The current status of the global secondary index: CREATING + // - The index is being created. UPDATING - The index is being updated. DELETING + // - The index is being deleted. ACTIVE - The index is ready for use. + // + // * ItemCount - The number of items in the global secondary index. DynamoDB + // updates this value approximately every six hours. Recent changes might + // not be reflected in this value. + // + // * KeySchema - Specifies the complete index key schema. The attribute names + // in the key schema must be between 1 and 255 characters (inclusive). The + // key schema must begin with the same partition key as the table. + // + // * Projection - Specifies attributes that are copied (projected) from the + // table into the index. These are in addition to the primary key attributes + // and index key attributes, which are automatically projected. Each attribute + // specification is composed of: ProjectionType - One of the following: KEYS_ONLY + // - Only the index and primary keys are projected into the index. INCLUDE + // - In addition to the attributes described in KEYS_ONLY, the secondary + // index will include other non-key attributes that you specify. ALL - All + // of the table attributes are projected into the index. NonKeyAttributes + // - A list of one or more non-key attribute names that are projected into + // the secondary index. The total count of attributes provided in NonKeyAttributes, + // summed across all of the secondary indexes, must not exceed 20. If you + // project the same attribute into two different indexes, this counts as + // two distinct attributes when determining the total. + // + // * ProvisionedThroughput - The provisioned throughput settings for the + // global secondary index, consisting of read and write capacity units, along + // with data about increases and decreases. + // + // If the table is in the DELETING state, no information about indexes will + // be returned. + GlobalSecondaryIndexes []*GlobalSecondaryIndexDescription `type:"list"` + + // Represents the version of global tables (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GlobalTables.html) + // in use, if the table is replicated across Amazon Web Services Regions. + GlobalTableVersion *string `type:"string"` + + // The number of items in the specified table. DynamoDB updates this value approximately + // every six hours. Recent changes might not be reflected in this value. + ItemCount *int64 `type:"long"` + + // The primary key structure for the table. Each KeySchemaElement consists of: + // + // * AttributeName - The name of the attribute. + // + // * KeyType - The role of the attribute: HASH - partition key RANGE - sort + // key The partition key of an item is also known as its hash attribute. + // The term "hash attribute" derives from DynamoDB's usage of an internal + // hash function to evenly distribute data items across partitions, based + // on their partition key values. The sort key of an item is also known as + // its range attribute. The term "range attribute" derives from the way DynamoDB + // stores items with the same partition key physically close together, in + // sorted order by the sort key value. + // + // For more information about primary keys, see Primary Key (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DataModel.html#DataModelPrimaryKey) + // in the Amazon DynamoDB Developer Guide. + KeySchema []*KeySchemaElement `min:"1" type:"list"` + + // The Amazon Resource Name (ARN) that uniquely identifies the latest stream + // for this table. + LatestStreamArn *string `min:"37" type:"string"` + + // A timestamp, in ISO 8601 format, for this stream. + // + // Note that LatestStreamLabel is not a unique identifier for the stream, because + // it is possible that a stream from another table might have the same timestamp. + // However, the combination of the following three elements is guaranteed to + // be unique: + // + // * Amazon Web Services customer ID + // + // * Table name + // + // * StreamLabel + LatestStreamLabel *string `type:"string"` + + // Represents one or more local secondary indexes on the table. Each index is + // scoped to a given partition key value. Tables with one or more local secondary + // indexes are subject to an item collection size limit, where the amount of + // data within a given item collection cannot exceed 10 GB. Each element is + // composed of: + // + // * IndexName - The name of the local secondary index. + // + // * KeySchema - Specifies the complete index key schema. The attribute names + // in the key schema must be between 1 and 255 characters (inclusive). The + // key schema must begin with the same partition key as the table. + // + // * Projection - Specifies attributes that are copied (projected) from the + // table into the index. These are in addition to the primary key attributes + // and index key attributes, which are automatically projected. Each attribute + // specification is composed of: ProjectionType - One of the following: KEYS_ONLY + // - Only the index and primary keys are projected into the index. INCLUDE + // - Only the specified table attributes are projected into the index. The + // list of projected attributes is in NonKeyAttributes. ALL - All of the + // table attributes are projected into the index. NonKeyAttributes - A list + // of one or more non-key attribute names that are projected into the secondary + // index. The total count of attributes provided in NonKeyAttributes, summed + // across all of the secondary indexes, must not exceed 20. If you project + // the same attribute into two different indexes, this counts as two distinct + // attributes when determining the total. + // + // * IndexSizeBytes - Represents the total size of the index, in bytes. DynamoDB + // updates this value approximately every six hours. Recent changes might + // not be reflected in this value. + // + // * ItemCount - Represents the number of items in the index. DynamoDB updates + // this value approximately every six hours. Recent changes might not be + // reflected in this value. + // + // If the table is in the DELETING state, no information about indexes will + // be returned. + LocalSecondaryIndexes []*LocalSecondaryIndexDescription `type:"list"` + + // The provisioned throughput settings for the table, consisting of read and + // write capacity units, along with data about increases and decreases. + ProvisionedThroughput *ProvisionedThroughputDescription `type:"structure"` + + // Represents replicas of the table. + Replicas []*ReplicaDescription `type:"list"` + + // Contains details for the restore. + RestoreSummary *RestoreSummary `type:"structure"` + + // The description of the server-side encryption status on the specified table. + SSEDescription *SSEDescription `type:"structure"` + + // The current DynamoDB Streams configuration for the table. + StreamSpecification *StreamSpecification `type:"structure"` + + // The Amazon Resource Name (ARN) that uniquely identifies the table. + TableArn *string `type:"string"` + + // Contains details of the table class. + TableClassSummary *TableClassSummary `type:"structure"` + + // Unique identifier for the table for which the backup was created. + TableId *string `type:"string"` + + // The name of the table. + TableName *string `min:"3" type:"string"` + + // The total size of the specified table, in bytes. DynamoDB updates this value + // approximately every six hours. Recent changes might not be reflected in this + // value. + TableSizeBytes *int64 `type:"long"` + + // The current state of the table: + // + // * CREATING - The table is being created. + // + // * UPDATING - The table is being updated. + // + // * DELETING - The table is being deleted. + // + // * ACTIVE - The table is ready for use. + // + // * INACCESSIBLE_ENCRYPTION_CREDENTIALS - The KMS key used to encrypt the + // table in inaccessible. Table operations may fail due to failure to use + // the KMS key. DynamoDB will initiate the table archival process when a + // table's KMS key remains inaccessible for more than seven days. + // + // * ARCHIVING - The table is being archived. Operations are not allowed + // until archival is complete. + // + // * ARCHIVED - The table has been archived. See the ArchivalReason for more + // information. + TableStatus *string `type:"string" enum:"TableStatus"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TableDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TableDescription) GoString() string { + return s.String() +} + +// SetArchivalSummary sets the ArchivalSummary field's value. +func (s *TableDescription) SetArchivalSummary(v *ArchivalSummary) *TableDescription { + s.ArchivalSummary = v + return s +} + +// SetAttributeDefinitions sets the AttributeDefinitions field's value. +func (s *TableDescription) SetAttributeDefinitions(v []*AttributeDefinition) *TableDescription { + s.AttributeDefinitions = v + return s +} + +// SetBillingModeSummary sets the BillingModeSummary field's value. +func (s *TableDescription) SetBillingModeSummary(v *BillingModeSummary) *TableDescription { + s.BillingModeSummary = v + return s +} + +// SetCreationDateTime sets the CreationDateTime field's value. +func (s *TableDescription) SetCreationDateTime(v time.Time) *TableDescription { + s.CreationDateTime = &v + return s +} + +// SetGlobalSecondaryIndexes sets the GlobalSecondaryIndexes field's value. +func (s *TableDescription) SetGlobalSecondaryIndexes(v []*GlobalSecondaryIndexDescription) *TableDescription { + s.GlobalSecondaryIndexes = v + return s +} + +// SetGlobalTableVersion sets the GlobalTableVersion field's value. +func (s *TableDescription) SetGlobalTableVersion(v string) *TableDescription { + s.GlobalTableVersion = &v + return s +} + +// SetItemCount sets the ItemCount field's value. +func (s *TableDescription) SetItemCount(v int64) *TableDescription { + s.ItemCount = &v + return s +} + +// SetKeySchema sets the KeySchema field's value. +func (s *TableDescription) SetKeySchema(v []*KeySchemaElement) *TableDescription { + s.KeySchema = v + return s +} + +// SetLatestStreamArn sets the LatestStreamArn field's value. +func (s *TableDescription) SetLatestStreamArn(v string) *TableDescription { + s.LatestStreamArn = &v + return s +} + +// SetLatestStreamLabel sets the LatestStreamLabel field's value. +func (s *TableDescription) SetLatestStreamLabel(v string) *TableDescription { + s.LatestStreamLabel = &v + return s +} + +// SetLocalSecondaryIndexes sets the LocalSecondaryIndexes field's value. +func (s *TableDescription) SetLocalSecondaryIndexes(v []*LocalSecondaryIndexDescription) *TableDescription { + s.LocalSecondaryIndexes = v + return s +} + +// SetProvisionedThroughput sets the ProvisionedThroughput field's value. +func (s *TableDescription) SetProvisionedThroughput(v *ProvisionedThroughputDescription) *TableDescription { + s.ProvisionedThroughput = v + return s +} + +// SetReplicas sets the Replicas field's value. +func (s *TableDescription) SetReplicas(v []*ReplicaDescription) *TableDescription { + s.Replicas = v + return s +} + +// SetRestoreSummary sets the RestoreSummary field's value. +func (s *TableDescription) SetRestoreSummary(v *RestoreSummary) *TableDescription { + s.RestoreSummary = v + return s +} + +// SetSSEDescription sets the SSEDescription field's value. +func (s *TableDescription) SetSSEDescription(v *SSEDescription) *TableDescription { + s.SSEDescription = v + return s +} + +// SetStreamSpecification sets the StreamSpecification field's value. +func (s *TableDescription) SetStreamSpecification(v *StreamSpecification) *TableDescription { + s.StreamSpecification = v + return s +} + +// SetTableArn sets the TableArn field's value. +func (s *TableDescription) SetTableArn(v string) *TableDescription { + s.TableArn = &v + return s +} + +// SetTableClassSummary sets the TableClassSummary field's value. +func (s *TableDescription) SetTableClassSummary(v *TableClassSummary) *TableDescription { + s.TableClassSummary = v + return s +} + +// SetTableId sets the TableId field's value. +func (s *TableDescription) SetTableId(v string) *TableDescription { + s.TableId = &v + return s +} + +// SetTableName sets the TableName field's value. +func (s *TableDescription) SetTableName(v string) *TableDescription { + s.TableName = &v + return s +} + +// SetTableSizeBytes sets the TableSizeBytes field's value. +func (s *TableDescription) SetTableSizeBytes(v int64) *TableDescription { + s.TableSizeBytes = &v + return s +} + +// SetTableStatus sets the TableStatus field's value. +func (s *TableDescription) SetTableStatus(v string) *TableDescription { + s.TableStatus = &v + return s +} + +// A target table with the specified name is either being created or deleted. +type TableInUseException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + Message_ *string `locationName:"message" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TableInUseException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TableInUseException) GoString() string { + return s.String() +} + +func newErrorTableInUseException(v protocol.ResponseMetadata) error { + return &TableInUseException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *TableInUseException) Code() string { + return "TableInUseException" +} + +// Message returns the exception's message. +func (s *TableInUseException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *TableInUseException) OrigErr() error { + return nil +} + +func (s *TableInUseException) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *TableInUseException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *TableInUseException) RequestID() string { + return s.RespMetadata.RequestID +} + +// A source table with the name TableName does not currently exist within the +// subscriber's account. +type TableNotFoundException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + Message_ *string `locationName:"message" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TableNotFoundException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TableNotFoundException) GoString() string { + return s.String() +} + +func newErrorTableNotFoundException(v protocol.ResponseMetadata) error { + return &TableNotFoundException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *TableNotFoundException) Code() string { + return "TableNotFoundException" +} + +// Message returns the exception's message. +func (s *TableNotFoundException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *TableNotFoundException) OrigErr() error { + return nil +} + +func (s *TableNotFoundException) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *TableNotFoundException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *TableNotFoundException) RequestID() string { + return s.RespMetadata.RequestID +} + +// Describes a tag. A tag is a key-value pair. You can add up to 50 tags to +// a single DynamoDB table. +// +// Amazon Web Services-assigned tag names and values are automatically assigned +// the aws: prefix, which the user cannot assign. Amazon Web Services-assigned +// tag names do not count towards the tag limit of 50. User-assigned tag names +// have the prefix user: in the Cost Allocation Report. You cannot backdate +// the application of a tag. +// +// For an overview on tagging DynamoDB resources, see Tagging for DynamoDB (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Tagging.html) +// in the Amazon DynamoDB Developer Guide. +type Tag struct { + _ struct{} `type:"structure"` + + // The key of the tag. Tag keys are case sensitive. Each DynamoDB table can + // only have up to one tag with the same key. If you try to add an existing + // tag (same key), the existing tag value will be updated to the new value. + // + // Key is a required field + Key *string `min:"1" type:"string" required:"true"` + + // The value of the tag. Tag values are case-sensitive and can be null. + // + // Value is a required field + Value *string `type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s Tag) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s Tag) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *Tag) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "Tag"} + if s.Key == nil { + invalidParams.Add(request.NewErrParamRequired("Key")) + } + if s.Key != nil && len(*s.Key) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Key", 1)) + } + if s.Value == nil { + invalidParams.Add(request.NewErrParamRequired("Value")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetKey sets the Key field's value. +func (s *Tag) SetKey(v string) *Tag { + s.Key = &v + return s +} + +// SetValue sets the Value field's value. +func (s *Tag) SetValue(v string) *Tag { + s.Value = &v + return s +} + +type TagResourceInput struct { + _ struct{} `type:"structure"` + + // Identifies the Amazon DynamoDB resource to which tags should be added. This + // value is an Amazon Resource Name (ARN). + // + // ResourceArn is a required field + ResourceArn *string `min:"1" type:"string" required:"true"` + + // The tags to be assigned to the Amazon DynamoDB resource. + // + // Tags is a required field + Tags []*Tag `type:"list" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TagResourceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TagResourceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *TagResourceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "TagResourceInput"} + if s.ResourceArn == nil { + invalidParams.Add(request.NewErrParamRequired("ResourceArn")) + } + if s.ResourceArn != nil && len(*s.ResourceArn) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ResourceArn", 1)) + } + if s.Tags == nil { + invalidParams.Add(request.NewErrParamRequired("Tags")) + } + if s.Tags != nil { + for i, v := range s.Tags { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Tags", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetResourceArn sets the ResourceArn field's value. +func (s *TagResourceInput) SetResourceArn(v string) *TagResourceInput { + s.ResourceArn = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *TagResourceInput) SetTags(v []*Tag) *TagResourceInput { + s.Tags = v + return s +} + +type TagResourceOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TagResourceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TagResourceOutput) GoString() string { + return s.String() +} + +// The description of the Time to Live (TTL) status on the specified table. +type TimeToLiveDescription struct { + _ struct{} `type:"structure"` + + // The name of the TTL attribute for items in the table. + AttributeName *string `min:"1" type:"string"` + + // The TTL status for the table. + TimeToLiveStatus *string `type:"string" enum:"TimeToLiveStatus"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TimeToLiveDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TimeToLiveDescription) GoString() string { + return s.String() +} + +// SetAttributeName sets the AttributeName field's value. +func (s *TimeToLiveDescription) SetAttributeName(v string) *TimeToLiveDescription { + s.AttributeName = &v + return s +} + +// SetTimeToLiveStatus sets the TimeToLiveStatus field's value. +func (s *TimeToLiveDescription) SetTimeToLiveStatus(v string) *TimeToLiveDescription { + s.TimeToLiveStatus = &v + return s +} + +// Represents the settings used to enable or disable Time to Live (TTL) for +// the specified table. +type TimeToLiveSpecification struct { + _ struct{} `type:"structure"` + + // The name of the TTL attribute used to store the expiration time for items + // in the table. + // + // AttributeName is a required field + AttributeName *string `min:"1" type:"string" required:"true"` + + // Indicates whether TTL is to be enabled (true) or disabled (false) on the + // table. + // + // Enabled is a required field + Enabled *bool `type:"boolean" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TimeToLiveSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TimeToLiveSpecification) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *TimeToLiveSpecification) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "TimeToLiveSpecification"} + if s.AttributeName == nil { + invalidParams.Add(request.NewErrParamRequired("AttributeName")) + } + if s.AttributeName != nil && len(*s.AttributeName) < 1 { + invalidParams.Add(request.NewErrParamMinLen("AttributeName", 1)) + } + if s.Enabled == nil { + invalidParams.Add(request.NewErrParamRequired("Enabled")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAttributeName sets the AttributeName field's value. +func (s *TimeToLiveSpecification) SetAttributeName(v string) *TimeToLiveSpecification { + s.AttributeName = &v + return s +} + +// SetEnabled sets the Enabled field's value. +func (s *TimeToLiveSpecification) SetEnabled(v bool) *TimeToLiveSpecification { + s.Enabled = &v + return s +} + +// Specifies an item to be retrieved as part of the transaction. +type TransactGetItem struct { + _ struct{} `type:"structure"` + + // Contains the primary key that identifies the item to get, together with the + // name of the table that contains the item, and optionally the specific attributes + // of the item to retrieve. + // + // Get is a required field + Get *Get `type:"structure" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TransactGetItem) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TransactGetItem) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *TransactGetItem) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "TransactGetItem"} + if s.Get == nil { + invalidParams.Add(request.NewErrParamRequired("Get")) + } + if s.Get != nil { + if err := s.Get.Validate(); err != nil { + invalidParams.AddNested("Get", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetGet sets the Get field's value. +func (s *TransactGetItem) SetGet(v *Get) *TransactGetItem { + s.Get = v + return s +} + +type TransactGetItemsInput struct { + _ struct{} `type:"structure"` + + // A value of TOTAL causes consumed capacity information to be returned, and + // a value of NONE prevents that information from being returned. No other value + // is valid. + ReturnConsumedCapacity *string `type:"string" enum:"ReturnConsumedCapacity"` + + // An ordered array of up to 25 TransactGetItem objects, each of which contains + // a Get structure. + // + // TransactItems is a required field + TransactItems []*TransactGetItem `min:"1" type:"list" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TransactGetItemsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TransactGetItemsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *TransactGetItemsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "TransactGetItemsInput"} + if s.TransactItems == nil { + invalidParams.Add(request.NewErrParamRequired("TransactItems")) + } + if s.TransactItems != nil && len(s.TransactItems) < 1 { + invalidParams.Add(request.NewErrParamMinLen("TransactItems", 1)) + } + if s.TransactItems != nil { + for i, v := range s.TransactItems { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "TransactItems", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetReturnConsumedCapacity sets the ReturnConsumedCapacity field's value. +func (s *TransactGetItemsInput) SetReturnConsumedCapacity(v string) *TransactGetItemsInput { + s.ReturnConsumedCapacity = &v + return s +} + +// SetTransactItems sets the TransactItems field's value. +func (s *TransactGetItemsInput) SetTransactItems(v []*TransactGetItem) *TransactGetItemsInput { + s.TransactItems = v + return s +} + +type TransactGetItemsOutput struct { + _ struct{} `type:"structure"` + + // If the ReturnConsumedCapacity value was TOTAL, this is an array of ConsumedCapacity + // objects, one for each table addressed by TransactGetItem objects in the TransactItems + // parameter. These ConsumedCapacity objects report the read-capacity units + // consumed by the TransactGetItems call in that table. + ConsumedCapacity []*ConsumedCapacity `type:"list"` + + // An ordered array of up to 25 ItemResponse objects, each of which corresponds + // to the TransactGetItem object in the same position in the TransactItems array. + // Each ItemResponse object contains a Map of the name-value pairs that are + // the projected attributes of the requested item. + // + // If a requested item could not be retrieved, the corresponding ItemResponse + // object is Null, or if the requested item has no projected attributes, the + // corresponding ItemResponse object is an empty Map. + Responses []*ItemResponse `min:"1" type:"list"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TransactGetItemsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TransactGetItemsOutput) GoString() string { + return s.String() +} + +// SetConsumedCapacity sets the ConsumedCapacity field's value. +func (s *TransactGetItemsOutput) SetConsumedCapacity(v []*ConsumedCapacity) *TransactGetItemsOutput { + s.ConsumedCapacity = v + return s +} + +// SetResponses sets the Responses field's value. +func (s *TransactGetItemsOutput) SetResponses(v []*ItemResponse) *TransactGetItemsOutput { + s.Responses = v + return s +} + +// A list of requests that can perform update, put, delete, or check operations +// on multiple items in one or more tables atomically. +type TransactWriteItem struct { + _ struct{} `type:"structure"` + + // A request to perform a check item operation. + ConditionCheck *ConditionCheck `type:"structure"` + + // A request to perform a DeleteItem operation. + Delete *Delete `type:"structure"` + + // A request to perform a PutItem operation. + Put *Put `type:"structure"` + + // A request to perform an UpdateItem operation. + Update *Update `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TransactWriteItem) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TransactWriteItem) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *TransactWriteItem) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "TransactWriteItem"} + if s.ConditionCheck != nil { + if err := s.ConditionCheck.Validate(); err != nil { + invalidParams.AddNested("ConditionCheck", err.(request.ErrInvalidParams)) + } + } + if s.Delete != nil { + if err := s.Delete.Validate(); err != nil { + invalidParams.AddNested("Delete", err.(request.ErrInvalidParams)) + } + } + if s.Put != nil { + if err := s.Put.Validate(); err != nil { + invalidParams.AddNested("Put", err.(request.ErrInvalidParams)) + } + } + if s.Update != nil { + if err := s.Update.Validate(); err != nil { + invalidParams.AddNested("Update", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetConditionCheck sets the ConditionCheck field's value. +func (s *TransactWriteItem) SetConditionCheck(v *ConditionCheck) *TransactWriteItem { + s.ConditionCheck = v + return s +} + +// SetDelete sets the Delete field's value. +func (s *TransactWriteItem) SetDelete(v *Delete) *TransactWriteItem { + s.Delete = v + return s +} + +// SetPut sets the Put field's value. +func (s *TransactWriteItem) SetPut(v *Put) *TransactWriteItem { + s.Put = v + return s +} + +// SetUpdate sets the Update field's value. +func (s *TransactWriteItem) SetUpdate(v *Update) *TransactWriteItem { + s.Update = v + return s +} + +type TransactWriteItemsInput struct { + _ struct{} `type:"structure"` + + // Providing a ClientRequestToken makes the call to TransactWriteItems idempotent, + // meaning that multiple identical calls have the same effect as one single + // call. + // + // Although multiple identical calls using the same client request token produce + // the same result on the server (no side effects), the responses to the calls + // might not be the same. If the ReturnConsumedCapacity> parameter is set, then + // the initial TransactWriteItems call returns the amount of write capacity + // units consumed in making the changes. Subsequent TransactWriteItems calls + // with the same client token return the number of read capacity units consumed + // in reading the item. + // + // A client request token is valid for 10 minutes after the first request that + // uses it is completed. After 10 minutes, any request with the same client + // token is treated as a new request. Do not resubmit the same request with + // the same client token for more than 10 minutes, or the result might not be + // idempotent. + // + // If you submit a request with the same client token but a change in other + // parameters within the 10-minute idempotency window, DynamoDB returns an IdempotentParameterMismatch + // exception. + ClientRequestToken *string `min:"1" type:"string" idempotencyToken:"true"` + + // Determines the level of detail about either provisioned or on-demand throughput + // consumption that is returned in the response: + // + // * INDEXES - The response includes the aggregate ConsumedCapacity for the + // operation, together with ConsumedCapacity for each table and secondary + // index that was accessed. Note that some operations, such as GetItem and + // BatchGetItem, do not access any indexes at all. In these cases, specifying + // INDEXES will only return ConsumedCapacity information for table(s). + // + // * TOTAL - The response includes only the aggregate ConsumedCapacity for + // the operation. + // + // * NONE - No ConsumedCapacity details are included in the response. + ReturnConsumedCapacity *string `type:"string" enum:"ReturnConsumedCapacity"` + + // Determines whether item collection metrics are returned. If set to SIZE, + // the response includes statistics about item collections (if any), that were + // modified during the operation and are returned in the response. If set to + // NONE (the default), no statistics are returned. + ReturnItemCollectionMetrics *string `type:"string" enum:"ReturnItemCollectionMetrics"` + + // An ordered array of up to 25 TransactWriteItem objects, each of which contains + // a ConditionCheck, Put, Update, or Delete object. These can operate on items + // in different tables, but the tables must reside in the same Amazon Web Services + // account and Region, and no two of them can operate on the same item. + // + // TransactItems is a required field + TransactItems []*TransactWriteItem `min:"1" type:"list" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TransactWriteItemsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TransactWriteItemsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *TransactWriteItemsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "TransactWriteItemsInput"} + if s.ClientRequestToken != nil && len(*s.ClientRequestToken) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ClientRequestToken", 1)) + } + if s.TransactItems == nil { + invalidParams.Add(request.NewErrParamRequired("TransactItems")) + } + if s.TransactItems != nil && len(s.TransactItems) < 1 { + invalidParams.Add(request.NewErrParamMinLen("TransactItems", 1)) + } + if s.TransactItems != nil { + for i, v := range s.TransactItems { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "TransactItems", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetClientRequestToken sets the ClientRequestToken field's value. +func (s *TransactWriteItemsInput) SetClientRequestToken(v string) *TransactWriteItemsInput { + s.ClientRequestToken = &v + return s +} + +// SetReturnConsumedCapacity sets the ReturnConsumedCapacity field's value. +func (s *TransactWriteItemsInput) SetReturnConsumedCapacity(v string) *TransactWriteItemsInput { + s.ReturnConsumedCapacity = &v + return s +} + +// SetReturnItemCollectionMetrics sets the ReturnItemCollectionMetrics field's value. +func (s *TransactWriteItemsInput) SetReturnItemCollectionMetrics(v string) *TransactWriteItemsInput { + s.ReturnItemCollectionMetrics = &v + return s +} + +// SetTransactItems sets the TransactItems field's value. +func (s *TransactWriteItemsInput) SetTransactItems(v []*TransactWriteItem) *TransactWriteItemsInput { + s.TransactItems = v + return s +} + +type TransactWriteItemsOutput struct { + _ struct{} `type:"structure"` + + // The capacity units consumed by the entire TransactWriteItems operation. The + // values of the list are ordered according to the ordering of the TransactItems + // request parameter. + ConsumedCapacity []*ConsumedCapacity `type:"list"` + + // A list of tables that were processed by TransactWriteItems and, for each + // table, information about any item collections that were affected by individual + // UpdateItem, PutItem, or DeleteItem operations. + ItemCollectionMetrics map[string][]*ItemCollectionMetrics `type:"map"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TransactWriteItemsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TransactWriteItemsOutput) GoString() string { + return s.String() +} + +// SetConsumedCapacity sets the ConsumedCapacity field's value. +func (s *TransactWriteItemsOutput) SetConsumedCapacity(v []*ConsumedCapacity) *TransactWriteItemsOutput { + s.ConsumedCapacity = v + return s +} + +// SetItemCollectionMetrics sets the ItemCollectionMetrics field's value. +func (s *TransactWriteItemsOutput) SetItemCollectionMetrics(v map[string][]*ItemCollectionMetrics) *TransactWriteItemsOutput { + s.ItemCollectionMetrics = v + return s +} + +// The entire transaction request was canceled. +// +// DynamoDB cancels a TransactWriteItems request under the following circumstances: +// +// * A condition in one of the condition expressions is not met. +// +// * A table in the TransactWriteItems request is in a different account +// or region. +// +// * More than one action in the TransactWriteItems operation targets the +// same item. +// +// * There is insufficient provisioned capacity for the transaction to be +// completed. +// +// * An item size becomes too large (larger than 400 KB), or a local secondary +// index (LSI) becomes too large, or a similar validation error occurs because +// of changes made by the transaction. +// +// * There is a user error, such as an invalid data format. +// +// DynamoDB cancels a TransactGetItems request under the following circumstances: +// +// * There is an ongoing TransactGetItems operation that conflicts with a +// concurrent PutItem, UpdateItem, DeleteItem or TransactWriteItems request. +// In this case the TransactGetItems operation fails with a TransactionCanceledException. +// +// * A table in the TransactGetItems request is in a different account or +// region. +// +// * There is insufficient provisioned capacity for the transaction to be +// completed. +// +// * There is a user error, such as an invalid data format. +// +// If using Java, DynamoDB lists the cancellation reasons on the CancellationReasons +// property. This property is not set for other languages. Transaction cancellation +// reasons are ordered in the order of requested items, if an item has no error +// it will have NONE code and Null message. +// +// Cancellation reason codes and possible error messages: +// +// * No Errors: Code: NONE Message: null +// +// * Conditional Check Failed: Code: ConditionalCheckFailed Message: The +// conditional request failed. +// +// * Item Collection Size Limit Exceeded: Code: ItemCollectionSizeLimitExceeded +// Message: Collection size exceeded. +// +// * Transaction Conflict: Code: TransactionConflict Message: Transaction +// is ongoing for the item. +// +// * Provisioned Throughput Exceeded: Code: ProvisionedThroughputExceeded +// Messages: The level of configured provisioned throughput for the table +// was exceeded. Consider increasing your provisioning level with the UpdateTable +// API. This Message is received when provisioned throughput is exceeded +// is on a provisioned DynamoDB table. The level of configured provisioned +// throughput for one or more global secondary indexes of the table was exceeded. +// Consider increasing your provisioning level for the under-provisioned +// global secondary indexes with the UpdateTable API. This message is returned +// when provisioned throughput is exceeded is on a provisioned GSI. +// +// * Throttling Error: Code: ThrottlingError Messages: Throughput exceeds +// the current capacity of your table or index. DynamoDB is automatically +// scaling your table or index so please try again shortly. If exceptions +// persist, check if you have a hot key: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-partition-key-design.html. +// This message is returned when writes get throttled on an On-Demand table +// as DynamoDB is automatically scaling the table. Throughput exceeds the +// current capacity for one or more global secondary indexes. DynamoDB is +// automatically scaling your index so please try again shortly. This message +// is returned when when writes get throttled on an On-Demand GSI as DynamoDB +// is automatically scaling the GSI. +// +// * Validation Error: Code: ValidationError Messages: One or more parameter +// values were invalid. The update expression attempted to update the secondary +// index key beyond allowed size limits. The update expression attempted +// to update the secondary index key to unsupported type. An operand in the +// update expression has an incorrect data type. Item size to update has +// exceeded the maximum allowed size. Number overflow. Attempting to store +// a number with magnitude larger than supported range. Type mismatch for +// attribute to update. Nesting Levels have exceeded supported limits. The +// document path provided in the update expression is invalid for update. +// The provided expression refers to an attribute that does not exist in +// the item. +type TransactionCanceledException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + // A list of cancellation reasons. + CancellationReasons []*CancellationReason `min:"1" type:"list"` + + Message_ *string `locationName:"Message" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TransactionCanceledException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TransactionCanceledException) GoString() string { + return s.String() +} + +func newErrorTransactionCanceledException(v protocol.ResponseMetadata) error { + return &TransactionCanceledException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *TransactionCanceledException) Code() string { + return "TransactionCanceledException" +} + +// Message returns the exception's message. +func (s *TransactionCanceledException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *TransactionCanceledException) OrigErr() error { + return nil +} + +func (s *TransactionCanceledException) Error() string { + return fmt.Sprintf("%s: %s\n%s", s.Code(), s.Message(), s.String()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *TransactionCanceledException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *TransactionCanceledException) RequestID() string { + return s.RespMetadata.RequestID +} + +// Operation was rejected because there is an ongoing transaction for the item. +type TransactionConflictException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + Message_ *string `locationName:"message" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TransactionConflictException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TransactionConflictException) GoString() string { + return s.String() +} + +func newErrorTransactionConflictException(v protocol.ResponseMetadata) error { + return &TransactionConflictException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *TransactionConflictException) Code() string { + return "TransactionConflictException" +} + +// Message returns the exception's message. +func (s *TransactionConflictException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *TransactionConflictException) OrigErr() error { + return nil +} + +func (s *TransactionConflictException) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *TransactionConflictException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *TransactionConflictException) RequestID() string { + return s.RespMetadata.RequestID +} + +// The transaction with the given request token is already in progress. +type TransactionInProgressException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + Message_ *string `locationName:"Message" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TransactionInProgressException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s TransactionInProgressException) GoString() string { + return s.String() +} + +func newErrorTransactionInProgressException(v protocol.ResponseMetadata) error { + return &TransactionInProgressException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *TransactionInProgressException) Code() string { + return "TransactionInProgressException" +} + +// Message returns the exception's message. +func (s *TransactionInProgressException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *TransactionInProgressException) OrigErr() error { + return nil +} + +func (s *TransactionInProgressException) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *TransactionInProgressException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *TransactionInProgressException) RequestID() string { + return s.RespMetadata.RequestID +} + +type UntagResourceInput struct { + _ struct{} `type:"structure"` + + // The DynamoDB resource that the tags will be removed from. This value is an + // Amazon Resource Name (ARN). + // + // ResourceArn is a required field + ResourceArn *string `min:"1" type:"string" required:"true"` + + // A list of tag keys. Existing tags of the resource whose keys are members + // of this list will be removed from the DynamoDB resource. + // + // TagKeys is a required field + TagKeys []*string `type:"list" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UntagResourceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UntagResourceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UntagResourceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UntagResourceInput"} + if s.ResourceArn == nil { + invalidParams.Add(request.NewErrParamRequired("ResourceArn")) + } + if s.ResourceArn != nil && len(*s.ResourceArn) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ResourceArn", 1)) + } + if s.TagKeys == nil { + invalidParams.Add(request.NewErrParamRequired("TagKeys")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetResourceArn sets the ResourceArn field's value. +func (s *UntagResourceInput) SetResourceArn(v string) *UntagResourceInput { + s.ResourceArn = &v + return s +} + +// SetTagKeys sets the TagKeys field's value. +func (s *UntagResourceInput) SetTagKeys(v []*string) *UntagResourceInput { + s.TagKeys = v + return s +} + +type UntagResourceOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UntagResourceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UntagResourceOutput) GoString() string { + return s.String() +} + +// Represents a request to perform an UpdateItem operation. +type Update struct { + _ struct{} `type:"structure"` + + // A condition that must be satisfied in order for a conditional update to succeed. + ConditionExpression *string `type:"string"` + + // One or more substitution tokens for attribute names in an expression. + ExpressionAttributeNames map[string]*string `type:"map"` + + // One or more values that can be substituted in an expression. + ExpressionAttributeValues map[string]*AttributeValue `type:"map"` + + // The primary key of the item to be updated. Each element consists of an attribute + // name and a value for that attribute. + // + // Key is a required field + Key map[string]*AttributeValue `type:"map" required:"true"` + + // Use ReturnValuesOnConditionCheckFailure to get the item attributes if the + // Update condition fails. For ReturnValuesOnConditionCheckFailure, the valid + // values are: NONE, ALL_OLD, UPDATED_OLD, ALL_NEW, UPDATED_NEW. + ReturnValuesOnConditionCheckFailure *string `type:"string" enum:"ReturnValuesOnConditionCheckFailure"` + + // Name of the table for the UpdateItem request. + // + // TableName is a required field + TableName *string `min:"3" type:"string" required:"true"` + + // An expression that defines one or more attributes to be updated, the action + // to be performed on them, and new value(s) for them. + // + // UpdateExpression is a required field + UpdateExpression *string `type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s Update) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s Update) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *Update) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "Update"} + if s.Key == nil { + invalidParams.Add(request.NewErrParamRequired("Key")) + } + if s.TableName == nil { + invalidParams.Add(request.NewErrParamRequired("TableName")) + } + if s.TableName != nil && len(*s.TableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("TableName", 3)) + } + if s.UpdateExpression == nil { + invalidParams.Add(request.NewErrParamRequired("UpdateExpression")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetConditionExpression sets the ConditionExpression field's value. +func (s *Update) SetConditionExpression(v string) *Update { + s.ConditionExpression = &v + return s +} + +// SetExpressionAttributeNames sets the ExpressionAttributeNames field's value. +func (s *Update) SetExpressionAttributeNames(v map[string]*string) *Update { + s.ExpressionAttributeNames = v + return s +} + +// SetExpressionAttributeValues sets the ExpressionAttributeValues field's value. +func (s *Update) SetExpressionAttributeValues(v map[string]*AttributeValue) *Update { + s.ExpressionAttributeValues = v + return s +} + +// SetKey sets the Key field's value. +func (s *Update) SetKey(v map[string]*AttributeValue) *Update { + s.Key = v + return s +} + +// SetReturnValuesOnConditionCheckFailure sets the ReturnValuesOnConditionCheckFailure field's value. +func (s *Update) SetReturnValuesOnConditionCheckFailure(v string) *Update { + s.ReturnValuesOnConditionCheckFailure = &v + return s +} + +// SetTableName sets the TableName field's value. +func (s *Update) SetTableName(v string) *Update { + s.TableName = &v + return s +} + +// SetUpdateExpression sets the UpdateExpression field's value. +func (s *Update) SetUpdateExpression(v string) *Update { + s.UpdateExpression = &v + return s +} + +type UpdateContinuousBackupsInput struct { + _ struct{} `type:"structure"` + + // Represents the settings used to enable point in time recovery. + // + // PointInTimeRecoverySpecification is a required field + PointInTimeRecoverySpecification *PointInTimeRecoverySpecification `type:"structure" required:"true"` + + // The name of the table. + // + // TableName is a required field + TableName *string `min:"3" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateContinuousBackupsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateContinuousBackupsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateContinuousBackupsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateContinuousBackupsInput"} + if s.PointInTimeRecoverySpecification == nil { + invalidParams.Add(request.NewErrParamRequired("PointInTimeRecoverySpecification")) + } + if s.TableName == nil { + invalidParams.Add(request.NewErrParamRequired("TableName")) + } + if s.TableName != nil && len(*s.TableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("TableName", 3)) + } + if s.PointInTimeRecoverySpecification != nil { + if err := s.PointInTimeRecoverySpecification.Validate(); err != nil { + invalidParams.AddNested("PointInTimeRecoverySpecification", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetPointInTimeRecoverySpecification sets the PointInTimeRecoverySpecification field's value. +func (s *UpdateContinuousBackupsInput) SetPointInTimeRecoverySpecification(v *PointInTimeRecoverySpecification) *UpdateContinuousBackupsInput { + s.PointInTimeRecoverySpecification = v + return s +} + +// SetTableName sets the TableName field's value. +func (s *UpdateContinuousBackupsInput) SetTableName(v string) *UpdateContinuousBackupsInput { + s.TableName = &v + return s +} + +type UpdateContinuousBackupsOutput struct { + _ struct{} `type:"structure"` + + // Represents the continuous backups and point in time recovery settings on + // the table. + ContinuousBackupsDescription *ContinuousBackupsDescription `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateContinuousBackupsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateContinuousBackupsOutput) GoString() string { + return s.String() +} + +// SetContinuousBackupsDescription sets the ContinuousBackupsDescription field's value. +func (s *UpdateContinuousBackupsOutput) SetContinuousBackupsDescription(v *ContinuousBackupsDescription) *UpdateContinuousBackupsOutput { + s.ContinuousBackupsDescription = v + return s +} + +type UpdateContributorInsightsInput struct { + _ struct{} `type:"structure"` + + // Represents the contributor insights action. + // + // ContributorInsightsAction is a required field + ContributorInsightsAction *string `type:"string" required:"true" enum:"ContributorInsightsAction"` + + // The global secondary index name, if applicable. + IndexName *string `min:"3" type:"string"` + + // The name of the table. + // + // TableName is a required field + TableName *string `min:"3" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateContributorInsightsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateContributorInsightsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateContributorInsightsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateContributorInsightsInput"} + if s.ContributorInsightsAction == nil { + invalidParams.Add(request.NewErrParamRequired("ContributorInsightsAction")) + } + if s.IndexName != nil && len(*s.IndexName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("IndexName", 3)) + } + if s.TableName == nil { + invalidParams.Add(request.NewErrParamRequired("TableName")) + } + if s.TableName != nil && len(*s.TableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("TableName", 3)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetContributorInsightsAction sets the ContributorInsightsAction field's value. +func (s *UpdateContributorInsightsInput) SetContributorInsightsAction(v string) *UpdateContributorInsightsInput { + s.ContributorInsightsAction = &v + return s +} + +// SetIndexName sets the IndexName field's value. +func (s *UpdateContributorInsightsInput) SetIndexName(v string) *UpdateContributorInsightsInput { + s.IndexName = &v + return s +} + +// SetTableName sets the TableName field's value. +func (s *UpdateContributorInsightsInput) SetTableName(v string) *UpdateContributorInsightsInput { + s.TableName = &v + return s +} + +type UpdateContributorInsightsOutput struct { + _ struct{} `type:"structure"` + + // The status of contributor insights + ContributorInsightsStatus *string `type:"string" enum:"ContributorInsightsStatus"` + + // The name of the global secondary index, if applicable. + IndexName *string `min:"3" type:"string"` + + // The name of the table. + TableName *string `min:"3" type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateContributorInsightsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateContributorInsightsOutput) GoString() string { + return s.String() +} + +// SetContributorInsightsStatus sets the ContributorInsightsStatus field's value. +func (s *UpdateContributorInsightsOutput) SetContributorInsightsStatus(v string) *UpdateContributorInsightsOutput { + s.ContributorInsightsStatus = &v + return s +} + +// SetIndexName sets the IndexName field's value. +func (s *UpdateContributorInsightsOutput) SetIndexName(v string) *UpdateContributorInsightsOutput { + s.IndexName = &v + return s +} + +// SetTableName sets the TableName field's value. +func (s *UpdateContributorInsightsOutput) SetTableName(v string) *UpdateContributorInsightsOutput { + s.TableName = &v + return s +} + +// Represents the new provisioned throughput settings to be applied to a global +// secondary index. +type UpdateGlobalSecondaryIndexAction struct { + _ struct{} `type:"structure"` + + // The name of the global secondary index to be updated. + // + // IndexName is a required field + IndexName *string `min:"3" type:"string" required:"true"` + + // Represents the provisioned throughput settings for the specified global secondary + // index. + // + // For current minimum and maximum provisioned throughput values, see Service, + // Account, and Table Quotas (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Limits.html) + // in the Amazon DynamoDB Developer Guide. + // + // ProvisionedThroughput is a required field + ProvisionedThroughput *ProvisionedThroughput `type:"structure" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateGlobalSecondaryIndexAction) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateGlobalSecondaryIndexAction) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateGlobalSecondaryIndexAction) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateGlobalSecondaryIndexAction"} + if s.IndexName == nil { + invalidParams.Add(request.NewErrParamRequired("IndexName")) + } + if s.IndexName != nil && len(*s.IndexName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("IndexName", 3)) + } + if s.ProvisionedThroughput == nil { + invalidParams.Add(request.NewErrParamRequired("ProvisionedThroughput")) + } + if s.ProvisionedThroughput != nil { + if err := s.ProvisionedThroughput.Validate(); err != nil { + invalidParams.AddNested("ProvisionedThroughput", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetIndexName sets the IndexName field's value. +func (s *UpdateGlobalSecondaryIndexAction) SetIndexName(v string) *UpdateGlobalSecondaryIndexAction { + s.IndexName = &v + return s +} + +// SetProvisionedThroughput sets the ProvisionedThroughput field's value. +func (s *UpdateGlobalSecondaryIndexAction) SetProvisionedThroughput(v *ProvisionedThroughput) *UpdateGlobalSecondaryIndexAction { + s.ProvisionedThroughput = v + return s +} + +type UpdateGlobalTableInput struct { + _ struct{} `type:"structure"` + + // The global table name. + // + // GlobalTableName is a required field + GlobalTableName *string `min:"3" type:"string" required:"true"` + + // A list of Regions that should be added or removed from the global table. + // + // ReplicaUpdates is a required field + ReplicaUpdates []*ReplicaUpdate `type:"list" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateGlobalTableInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateGlobalTableInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateGlobalTableInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateGlobalTableInput"} + if s.GlobalTableName == nil { + invalidParams.Add(request.NewErrParamRequired("GlobalTableName")) + } + if s.GlobalTableName != nil && len(*s.GlobalTableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("GlobalTableName", 3)) + } + if s.ReplicaUpdates == nil { + invalidParams.Add(request.NewErrParamRequired("ReplicaUpdates")) + } + if s.ReplicaUpdates != nil { + for i, v := range s.ReplicaUpdates { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "ReplicaUpdates", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetGlobalTableName sets the GlobalTableName field's value. +func (s *UpdateGlobalTableInput) SetGlobalTableName(v string) *UpdateGlobalTableInput { + s.GlobalTableName = &v + return s +} + +// SetReplicaUpdates sets the ReplicaUpdates field's value. +func (s *UpdateGlobalTableInput) SetReplicaUpdates(v []*ReplicaUpdate) *UpdateGlobalTableInput { + s.ReplicaUpdates = v + return s +} + +type UpdateGlobalTableOutput struct { + _ struct{} `type:"structure"` + + // Contains the details of the global table. + GlobalTableDescription *GlobalTableDescription `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateGlobalTableOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateGlobalTableOutput) GoString() string { + return s.String() +} + +// SetGlobalTableDescription sets the GlobalTableDescription field's value. +func (s *UpdateGlobalTableOutput) SetGlobalTableDescription(v *GlobalTableDescription) *UpdateGlobalTableOutput { + s.GlobalTableDescription = v + return s +} + +type UpdateGlobalTableSettingsInput struct { + _ struct{} `type:"structure"` + + // The billing mode of the global table. If GlobalTableBillingMode is not specified, + // the global table defaults to PROVISIONED capacity billing mode. + // + // * PROVISIONED - We recommend using PROVISIONED for predictable workloads. + // PROVISIONED sets the billing mode to Provisioned Mode (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadWriteCapacityMode.html#HowItWorks.ProvisionedThroughput.Manual). + // + // * PAY_PER_REQUEST - We recommend using PAY_PER_REQUEST for unpredictable + // workloads. PAY_PER_REQUEST sets the billing mode to On-Demand Mode (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadWriteCapacityMode.html#HowItWorks.OnDemand). + GlobalTableBillingMode *string `type:"string" enum:"BillingMode"` + + // Represents the settings of a global secondary index for a global table that + // will be modified. + GlobalTableGlobalSecondaryIndexSettingsUpdate []*GlobalTableGlobalSecondaryIndexSettingsUpdate `min:"1" type:"list"` + + // The name of the global table + // + // GlobalTableName is a required field + GlobalTableName *string `min:"3" type:"string" required:"true"` + + // Auto scaling settings for managing provisioned write capacity for the global + // table. + GlobalTableProvisionedWriteCapacityAutoScalingSettingsUpdate *AutoScalingSettingsUpdate `type:"structure"` + + // The maximum number of writes consumed per second before DynamoDB returns + // a ThrottlingException. + GlobalTableProvisionedWriteCapacityUnits *int64 `min:"1" type:"long"` + + // Represents the settings for a global table in a Region that will be modified. + ReplicaSettingsUpdate []*ReplicaSettingsUpdate `min:"1" type:"list"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateGlobalTableSettingsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateGlobalTableSettingsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateGlobalTableSettingsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateGlobalTableSettingsInput"} + if s.GlobalTableGlobalSecondaryIndexSettingsUpdate != nil && len(s.GlobalTableGlobalSecondaryIndexSettingsUpdate) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GlobalTableGlobalSecondaryIndexSettingsUpdate", 1)) + } + if s.GlobalTableName == nil { + invalidParams.Add(request.NewErrParamRequired("GlobalTableName")) + } + if s.GlobalTableName != nil && len(*s.GlobalTableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("GlobalTableName", 3)) + } + if s.GlobalTableProvisionedWriteCapacityUnits != nil && *s.GlobalTableProvisionedWriteCapacityUnits < 1 { + invalidParams.Add(request.NewErrParamMinValue("GlobalTableProvisionedWriteCapacityUnits", 1)) + } + if s.ReplicaSettingsUpdate != nil && len(s.ReplicaSettingsUpdate) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ReplicaSettingsUpdate", 1)) + } + if s.GlobalTableGlobalSecondaryIndexSettingsUpdate != nil { + for i, v := range s.GlobalTableGlobalSecondaryIndexSettingsUpdate { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "GlobalTableGlobalSecondaryIndexSettingsUpdate", i), err.(request.ErrInvalidParams)) + } + } + } + if s.GlobalTableProvisionedWriteCapacityAutoScalingSettingsUpdate != nil { + if err := s.GlobalTableProvisionedWriteCapacityAutoScalingSettingsUpdate.Validate(); err != nil { + invalidParams.AddNested("GlobalTableProvisionedWriteCapacityAutoScalingSettingsUpdate", err.(request.ErrInvalidParams)) + } + } + if s.ReplicaSettingsUpdate != nil { + for i, v := range s.ReplicaSettingsUpdate { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "ReplicaSettingsUpdate", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetGlobalTableBillingMode sets the GlobalTableBillingMode field's value. +func (s *UpdateGlobalTableSettingsInput) SetGlobalTableBillingMode(v string) *UpdateGlobalTableSettingsInput { + s.GlobalTableBillingMode = &v + return s +} + +// SetGlobalTableGlobalSecondaryIndexSettingsUpdate sets the GlobalTableGlobalSecondaryIndexSettingsUpdate field's value. +func (s *UpdateGlobalTableSettingsInput) SetGlobalTableGlobalSecondaryIndexSettingsUpdate(v []*GlobalTableGlobalSecondaryIndexSettingsUpdate) *UpdateGlobalTableSettingsInput { + s.GlobalTableGlobalSecondaryIndexSettingsUpdate = v + return s +} + +// SetGlobalTableName sets the GlobalTableName field's value. +func (s *UpdateGlobalTableSettingsInput) SetGlobalTableName(v string) *UpdateGlobalTableSettingsInput { + s.GlobalTableName = &v + return s +} + +// SetGlobalTableProvisionedWriteCapacityAutoScalingSettingsUpdate sets the GlobalTableProvisionedWriteCapacityAutoScalingSettingsUpdate field's value. +func (s *UpdateGlobalTableSettingsInput) SetGlobalTableProvisionedWriteCapacityAutoScalingSettingsUpdate(v *AutoScalingSettingsUpdate) *UpdateGlobalTableSettingsInput { + s.GlobalTableProvisionedWriteCapacityAutoScalingSettingsUpdate = v + return s +} + +// SetGlobalTableProvisionedWriteCapacityUnits sets the GlobalTableProvisionedWriteCapacityUnits field's value. +func (s *UpdateGlobalTableSettingsInput) SetGlobalTableProvisionedWriteCapacityUnits(v int64) *UpdateGlobalTableSettingsInput { + s.GlobalTableProvisionedWriteCapacityUnits = &v + return s +} + +// SetReplicaSettingsUpdate sets the ReplicaSettingsUpdate field's value. +func (s *UpdateGlobalTableSettingsInput) SetReplicaSettingsUpdate(v []*ReplicaSettingsUpdate) *UpdateGlobalTableSettingsInput { + s.ReplicaSettingsUpdate = v + return s +} + +type UpdateGlobalTableSettingsOutput struct { + _ struct{} `type:"structure"` + + // The name of the global table. + GlobalTableName *string `min:"3" type:"string"` + + // The Region-specific settings for the global table. + ReplicaSettings []*ReplicaSettingsDescription `type:"list"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateGlobalTableSettingsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateGlobalTableSettingsOutput) GoString() string { + return s.String() +} + +// SetGlobalTableName sets the GlobalTableName field's value. +func (s *UpdateGlobalTableSettingsOutput) SetGlobalTableName(v string) *UpdateGlobalTableSettingsOutput { + s.GlobalTableName = &v + return s +} + +// SetReplicaSettings sets the ReplicaSettings field's value. +func (s *UpdateGlobalTableSettingsOutput) SetReplicaSettings(v []*ReplicaSettingsDescription) *UpdateGlobalTableSettingsOutput { + s.ReplicaSettings = v + return s +} + +// Represents the input of an UpdateItem operation. +type UpdateItemInput struct { + _ struct{} `type:"structure"` + + // This is a legacy parameter. Use UpdateExpression instead. For more information, + // see AttributeUpdates (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.AttributeUpdates.html) + // in the Amazon DynamoDB Developer Guide. + AttributeUpdates map[string]*AttributeValueUpdate `type:"map"` + + // A condition that must be satisfied in order for a conditional update to succeed. + // + // An expression can contain any of the following: + // + // * Functions: attribute_exists | attribute_not_exists | attribute_type + // | contains | begins_with | size These function names are case-sensitive. + // + // * Comparison operators: = | <> | < | > | <= | >= | BETWEEN | IN + // + // * Logical operators: AND | OR | NOT + // + // For more information about condition expressions, see Specifying Conditions + // (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.SpecifyingConditions.html) + // in the Amazon DynamoDB Developer Guide. + ConditionExpression *string `type:"string"` + + // This is a legacy parameter. Use ConditionExpression instead. For more information, + // see ConditionalOperator (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.ConditionalOperator.html) + // in the Amazon DynamoDB Developer Guide. + ConditionalOperator *string `type:"string" enum:"ConditionalOperator"` + + // This is a legacy parameter. Use ConditionExpression instead. For more information, + // see Expected (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.Expected.html) + // in the Amazon DynamoDB Developer Guide. + Expected map[string]*ExpectedAttributeValue `type:"map"` + + // One or more substitution tokens for attribute names in an expression. The + // following are some use cases for using ExpressionAttributeNames: + // + // * To access an attribute whose name conflicts with a DynamoDB reserved + // word. + // + // * To create a placeholder for repeating occurrences of an attribute name + // in an expression. + // + // * To prevent special characters in an attribute name from being misinterpreted + // in an expression. + // + // Use the # character in an expression to dereference an attribute name. For + // example, consider the following attribute name: + // + // * Percentile + // + // The name of this attribute conflicts with a reserved word, so it cannot be + // used directly in an expression. (For the complete list of reserved words, + // see Reserved Words (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html) + // in the Amazon DynamoDB Developer Guide.) To work around this, you could specify + // the following for ExpressionAttributeNames: + // + // * {"#P":"Percentile"} + // + // You could then use this substitution in an expression, as in this example: + // + // * #P = :val + // + // Tokens that begin with the : character are expression attribute values, which + // are placeholders for the actual value at runtime. + // + // For more information about expression attribute names, see Specifying Item + // Attributes (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.AccessingItemAttributes.html) + // in the Amazon DynamoDB Developer Guide. + ExpressionAttributeNames map[string]*string `type:"map"` + + // One or more values that can be substituted in an expression. + // + // Use the : (colon) character in an expression to dereference an attribute + // value. For example, suppose that you wanted to check whether the value of + // the ProductStatus attribute was one of the following: + // + // Available | Backordered | Discontinued + // + // You would first need to specify ExpressionAttributeValues as follows: + // + // { ":avail":{"S":"Available"}, ":back":{"S":"Backordered"}, ":disc":{"S":"Discontinued"} + // } + // + // You could then use these values in an expression, such as this: + // + // ProductStatus IN (:avail, :back, :disc) + // + // For more information on expression attribute values, see Condition Expressions + // (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.SpecifyingConditions.html) + // in the Amazon DynamoDB Developer Guide. + ExpressionAttributeValues map[string]*AttributeValue `type:"map"` + + // The primary key of the item to be updated. Each element consists of an attribute + // name and a value for that attribute. + // + // For the primary key, you must provide all of the attributes. For example, + // with a simple primary key, you only need to provide a value for the partition + // key. For a composite primary key, you must provide values for both the partition + // key and the sort key. + // + // Key is a required field + Key map[string]*AttributeValue `type:"map" required:"true"` + + // Determines the level of detail about either provisioned or on-demand throughput + // consumption that is returned in the response: + // + // * INDEXES - The response includes the aggregate ConsumedCapacity for the + // operation, together with ConsumedCapacity for each table and secondary + // index that was accessed. Note that some operations, such as GetItem and + // BatchGetItem, do not access any indexes at all. In these cases, specifying + // INDEXES will only return ConsumedCapacity information for table(s). + // + // * TOTAL - The response includes only the aggregate ConsumedCapacity for + // the operation. + // + // * NONE - No ConsumedCapacity details are included in the response. + ReturnConsumedCapacity *string `type:"string" enum:"ReturnConsumedCapacity"` + + // Determines whether item collection metrics are returned. If set to SIZE, + // the response includes statistics about item collections, if any, that were + // modified during the operation are returned in the response. If set to NONE + // (the default), no statistics are returned. + ReturnItemCollectionMetrics *string `type:"string" enum:"ReturnItemCollectionMetrics"` + + // Use ReturnValues if you want to get the item attributes as they appear before + // or after they are updated. For UpdateItem, the valid values are: + // + // * NONE - If ReturnValues is not specified, or if its value is NONE, then + // nothing is returned. (This setting is the default for ReturnValues.) + // + // * ALL_OLD - Returns all of the attributes of the item, as they appeared + // before the UpdateItem operation. + // + // * UPDATED_OLD - Returns only the updated attributes, as they appeared + // before the UpdateItem operation. + // + // * ALL_NEW - Returns all of the attributes of the item, as they appear + // after the UpdateItem operation. + // + // * UPDATED_NEW - Returns only the updated attributes, as they appear after + // the UpdateItem operation. + // + // There is no additional cost associated with requesting a return value aside + // from the small network and processing overhead of receiving a larger response. + // No read capacity units are consumed. + // + // The values returned are strongly consistent. + ReturnValues *string `type:"string" enum:"ReturnValue"` + + // The name of the table containing the item to update. + // + // TableName is a required field + TableName *string `min:"3" type:"string" required:"true"` + + // An expression that defines one or more attributes to be updated, the action + // to be performed on them, and new values for them. + // + // The following action values are available for UpdateExpression. + // + // * SET - Adds one or more attributes and values to an item. If any of these + // attributes already exist, they are replaced by the new values. You can + // also use SET to add or subtract from an attribute that is of type Number. + // For example: SET myNum = myNum + :val SET supports the following functions: + // if_not_exists (path, operand) - if the item does not contain an attribute + // at the specified path, then if_not_exists evaluates to operand; otherwise, + // it evaluates to path. You can use this function to avoid overwriting an + // attribute that may already be present in the item. list_append (operand, + // operand) - evaluates to a list with a new element added to it. You can + // append the new element to the start or the end of the list by reversing + // the order of the operands. These function names are case-sensitive. + // + // * REMOVE - Removes one or more attributes from an item. + // + // * ADD - Adds the specified value to the item, if the attribute does not + // already exist. If the attribute does exist, then the behavior of ADD depends + // on the data type of the attribute: If the existing attribute is a number, + // and if Value is also a number, then Value is mathematically added to the + // existing attribute. If Value is a negative number, then it is subtracted + // from the existing attribute. If you use ADD to increment or decrement + // a number value for an item that doesn't exist before the update, DynamoDB + // uses 0 as the initial value. Similarly, if you use ADD for an existing + // item to increment or decrement an attribute value that doesn't exist before + // the update, DynamoDB uses 0 as the initial value. For example, suppose + // that the item you want to update doesn't have an attribute named itemcount, + // but you decide to ADD the number 3 to this attribute anyway. DynamoDB + // will create the itemcount attribute, set its initial value to 0, and finally + // add 3 to it. The result will be a new itemcount attribute in the item, + // with a value of 3. If the existing data type is a set and if Value is + // also a set, then Value is added to the existing set. For example, if the + // attribute value is the set [1,2], and the ADD action specified [3], then + // the final attribute value is [1,2,3]. An error occurs if an ADD action + // is specified for a set attribute and the attribute type specified does + // not match the existing set type. Both sets must have the same primitive + // data type. For example, if the existing data type is a set of strings, + // the Value must also be a set of strings. The ADD action only supports + // Number and set data types. In addition, ADD can only be used on top-level + // attributes, not nested attributes. + // + // * DELETE - Deletes an element from a set. If a set of values is specified, + // then those values are subtracted from the old set. For example, if the + // attribute value was the set [a,b,c] and the DELETE action specifies [a,c], + // then the final attribute value is [b]. Specifying an empty set is an error. + // The DELETE action only supports set data types. In addition, DELETE can + // only be used on top-level attributes, not nested attributes. + // + // You can have many actions in a single expression, such as the following: + // SET a=:value1, b=:value2 DELETE :value3, :value4, :value5 + // + // For more information on update expressions, see Modifying Items and Attributes + // (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.Modifying.html) + // in the Amazon DynamoDB Developer Guide. + UpdateExpression *string `type:"string"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateItemInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateItemInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateItemInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateItemInput"} + if s.Key == nil { + invalidParams.Add(request.NewErrParamRequired("Key")) + } + if s.TableName == nil { + invalidParams.Add(request.NewErrParamRequired("TableName")) + } + if s.TableName != nil && len(*s.TableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("TableName", 3)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAttributeUpdates sets the AttributeUpdates field's value. +func (s *UpdateItemInput) SetAttributeUpdates(v map[string]*AttributeValueUpdate) *UpdateItemInput { + s.AttributeUpdates = v + return s +} + +// SetConditionExpression sets the ConditionExpression field's value. +func (s *UpdateItemInput) SetConditionExpression(v string) *UpdateItemInput { + s.ConditionExpression = &v + return s +} + +// SetConditionalOperator sets the ConditionalOperator field's value. +func (s *UpdateItemInput) SetConditionalOperator(v string) *UpdateItemInput { + s.ConditionalOperator = &v + return s +} + +// SetExpected sets the Expected field's value. +func (s *UpdateItemInput) SetExpected(v map[string]*ExpectedAttributeValue) *UpdateItemInput { + s.Expected = v + return s +} + +// SetExpressionAttributeNames sets the ExpressionAttributeNames field's value. +func (s *UpdateItemInput) SetExpressionAttributeNames(v map[string]*string) *UpdateItemInput { + s.ExpressionAttributeNames = v + return s +} + +// SetExpressionAttributeValues sets the ExpressionAttributeValues field's value. +func (s *UpdateItemInput) SetExpressionAttributeValues(v map[string]*AttributeValue) *UpdateItemInput { + s.ExpressionAttributeValues = v + return s +} + +// SetKey sets the Key field's value. +func (s *UpdateItemInput) SetKey(v map[string]*AttributeValue) *UpdateItemInput { + s.Key = v + return s +} + +// SetReturnConsumedCapacity sets the ReturnConsumedCapacity field's value. +func (s *UpdateItemInput) SetReturnConsumedCapacity(v string) *UpdateItemInput { + s.ReturnConsumedCapacity = &v + return s +} + +// SetReturnItemCollectionMetrics sets the ReturnItemCollectionMetrics field's value. +func (s *UpdateItemInput) SetReturnItemCollectionMetrics(v string) *UpdateItemInput { + s.ReturnItemCollectionMetrics = &v + return s +} + +// SetReturnValues sets the ReturnValues field's value. +func (s *UpdateItemInput) SetReturnValues(v string) *UpdateItemInput { + s.ReturnValues = &v + return s +} + +// SetTableName sets the TableName field's value. +func (s *UpdateItemInput) SetTableName(v string) *UpdateItemInput { + s.TableName = &v + return s +} + +// SetUpdateExpression sets the UpdateExpression field's value. +func (s *UpdateItemInput) SetUpdateExpression(v string) *UpdateItemInput { + s.UpdateExpression = &v + return s +} + +// Represents the output of an UpdateItem operation. +type UpdateItemOutput struct { + _ struct{} `type:"structure"` + + // A map of attribute values as they appear before or after the UpdateItem operation, + // as determined by the ReturnValues parameter. + // + // The Attributes map is only present if ReturnValues was specified as something + // other than NONE in the request. Each element represents one attribute. + Attributes map[string]*AttributeValue `type:"map"` + + // The capacity units consumed by the UpdateItem operation. The data returned + // includes the total provisioned throughput consumed, along with statistics + // for the table and any indexes involved in the operation. ConsumedCapacity + // is only returned if the ReturnConsumedCapacity parameter was specified. For + // more information, see Provisioned Throughput (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ProvisionedThroughputIntro.html) + // in the Amazon DynamoDB Developer Guide. + ConsumedCapacity *ConsumedCapacity `type:"structure"` + + // Information about item collections, if any, that were affected by the UpdateItem + // operation. ItemCollectionMetrics is only returned if the ReturnItemCollectionMetrics + // parameter was specified. If the table does not have any local secondary indexes, + // this information is not returned in the response. + // + // Each ItemCollectionMetrics element consists of: + // + // * ItemCollectionKey - The partition key value of the item collection. + // This is the same as the partition key value of the item itself. + // + // * SizeEstimateRangeGB - An estimate of item collection size, in gigabytes. + // This value is a two-element array containing a lower bound and an upper + // bound for the estimate. The estimate includes the size of all the items + // in the table, plus the size of all attributes projected into all of the + // local secondary indexes on that table. Use this estimate to measure whether + // a local secondary index is approaching its size limit. The estimate is + // subject to change over time; therefore, do not rely on the precision or + // accuracy of the estimate. + ItemCollectionMetrics *ItemCollectionMetrics `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateItemOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateItemOutput) GoString() string { + return s.String() +} + +// SetAttributes sets the Attributes field's value. +func (s *UpdateItemOutput) SetAttributes(v map[string]*AttributeValue) *UpdateItemOutput { + s.Attributes = v + return s +} + +// SetConsumedCapacity sets the ConsumedCapacity field's value. +func (s *UpdateItemOutput) SetConsumedCapacity(v *ConsumedCapacity) *UpdateItemOutput { + s.ConsumedCapacity = v + return s +} + +// SetItemCollectionMetrics sets the ItemCollectionMetrics field's value. +func (s *UpdateItemOutput) SetItemCollectionMetrics(v *ItemCollectionMetrics) *UpdateItemOutput { + s.ItemCollectionMetrics = v + return s +} + +// Represents a replica to be modified. +type UpdateReplicationGroupMemberAction struct { + _ struct{} `type:"structure"` + + // Replica-specific global secondary index settings. + GlobalSecondaryIndexes []*ReplicaGlobalSecondaryIndex `min:"1" type:"list"` + + // The KMS key of the replica that should be used for KMS encryption. To specify + // a key, use its key ID, Amazon Resource Name (ARN), alias name, or alias ARN. + // Note that you should only provide this parameter if the key is different + // from the default DynamoDB KMS key alias/aws/dynamodb. + KMSMasterKeyId *string `type:"string"` + + // Replica-specific provisioned throughput. If not specified, uses the source + // table's provisioned throughput settings. + ProvisionedThroughputOverride *ProvisionedThroughputOverride `type:"structure"` + + // The Region where the replica exists. + // + // RegionName is a required field + RegionName *string `type:"string" required:"true"` + + // Replica-specific table class. If not specified, uses the source table's table + // class. + TableClassOverride *string `type:"string" enum:"TableClass"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateReplicationGroupMemberAction) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateReplicationGroupMemberAction) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateReplicationGroupMemberAction) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateReplicationGroupMemberAction"} + if s.GlobalSecondaryIndexes != nil && len(s.GlobalSecondaryIndexes) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GlobalSecondaryIndexes", 1)) + } + if s.RegionName == nil { + invalidParams.Add(request.NewErrParamRequired("RegionName")) + } + if s.GlobalSecondaryIndexes != nil { + for i, v := range s.GlobalSecondaryIndexes { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "GlobalSecondaryIndexes", i), err.(request.ErrInvalidParams)) + } + } + } + if s.ProvisionedThroughputOverride != nil { + if err := s.ProvisionedThroughputOverride.Validate(); err != nil { + invalidParams.AddNested("ProvisionedThroughputOverride", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetGlobalSecondaryIndexes sets the GlobalSecondaryIndexes field's value. +func (s *UpdateReplicationGroupMemberAction) SetGlobalSecondaryIndexes(v []*ReplicaGlobalSecondaryIndex) *UpdateReplicationGroupMemberAction { + s.GlobalSecondaryIndexes = v + return s +} + +// SetKMSMasterKeyId sets the KMSMasterKeyId field's value. +func (s *UpdateReplicationGroupMemberAction) SetKMSMasterKeyId(v string) *UpdateReplicationGroupMemberAction { + s.KMSMasterKeyId = &v + return s +} + +// SetProvisionedThroughputOverride sets the ProvisionedThroughputOverride field's value. +func (s *UpdateReplicationGroupMemberAction) SetProvisionedThroughputOverride(v *ProvisionedThroughputOverride) *UpdateReplicationGroupMemberAction { + s.ProvisionedThroughputOverride = v + return s +} + +// SetRegionName sets the RegionName field's value. +func (s *UpdateReplicationGroupMemberAction) SetRegionName(v string) *UpdateReplicationGroupMemberAction { + s.RegionName = &v + return s +} + +// SetTableClassOverride sets the TableClassOverride field's value. +func (s *UpdateReplicationGroupMemberAction) SetTableClassOverride(v string) *UpdateReplicationGroupMemberAction { + s.TableClassOverride = &v + return s +} + +// Represents the input of an UpdateTable operation. +type UpdateTableInput struct { + _ struct{} `type:"structure"` + + // An array of attributes that describe the key schema for the table and indexes. + // If you are adding a new global secondary index to the table, AttributeDefinitions + // must include the key element(s) of the new index. + AttributeDefinitions []*AttributeDefinition `type:"list"` + + // Controls how you are charged for read and write throughput and how you manage + // capacity. When switching from pay-per-request to provisioned capacity, initial + // provisioned capacity values must be set. The initial provisioned capacity + // values are estimated based on the consumed read and write capacity of your + // table and global secondary indexes over the past 30 minutes. + // + // * PROVISIONED - We recommend using PROVISIONED for predictable workloads. + // PROVISIONED sets the billing mode to Provisioned Mode (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadWriteCapacityMode.html#HowItWorks.ProvisionedThroughput.Manual). + // + // * PAY_PER_REQUEST - We recommend using PAY_PER_REQUEST for unpredictable + // workloads. PAY_PER_REQUEST sets the billing mode to On-Demand Mode (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadWriteCapacityMode.html#HowItWorks.OnDemand). + BillingMode *string `type:"string" enum:"BillingMode"` + + // An array of one or more global secondary indexes for the table. For each + // index in the array, you can request one action: + // + // * Create - add a new global secondary index to the table. + // + // * Update - modify the provisioned throughput settings of an existing global + // secondary index. + // + // * Delete - remove a global secondary index from the table. + // + // You can create or delete only one global secondary index per UpdateTable + // operation. + // + // For more information, see Managing Global Secondary Indexes (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.OnlineOps.html) + // in the Amazon DynamoDB Developer Guide. + GlobalSecondaryIndexUpdates []*GlobalSecondaryIndexUpdate `type:"list"` + + // The new provisioned throughput settings for the specified table or index. + ProvisionedThroughput *ProvisionedThroughput `type:"structure"` + + // A list of replica update actions (create, delete, or update) for the table. + // + // This property only applies to Version 2019.11.21 (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/globaltables.V2.html) + // of global tables. + ReplicaUpdates []*ReplicationGroupUpdate `min:"1" type:"list"` + + // The new server-side encryption settings for the specified table. + SSESpecification *SSESpecification `type:"structure"` + + // Represents the DynamoDB Streams configuration for the table. + // + // You receive a ResourceInUseException if you try to enable a stream on a table + // that already has a stream, or if you try to disable a stream on a table that + // doesn't have a stream. + StreamSpecification *StreamSpecification `type:"structure"` + + // The table class of the table to be updated. Valid values are STANDARD and + // STANDARD_INFREQUENT_ACCESS. + TableClass *string `type:"string" enum:"TableClass"` + + // The name of the table to be updated. + // + // TableName is a required field + TableName *string `min:"3" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateTableInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateTableInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateTableInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateTableInput"} + if s.ReplicaUpdates != nil && len(s.ReplicaUpdates) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ReplicaUpdates", 1)) + } + if s.TableName == nil { + invalidParams.Add(request.NewErrParamRequired("TableName")) + } + if s.TableName != nil && len(*s.TableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("TableName", 3)) + } + if s.AttributeDefinitions != nil { + for i, v := range s.AttributeDefinitions { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "AttributeDefinitions", i), err.(request.ErrInvalidParams)) + } + } + } + if s.GlobalSecondaryIndexUpdates != nil { + for i, v := range s.GlobalSecondaryIndexUpdates { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "GlobalSecondaryIndexUpdates", i), err.(request.ErrInvalidParams)) + } + } + } + if s.ProvisionedThroughput != nil { + if err := s.ProvisionedThroughput.Validate(); err != nil { + invalidParams.AddNested("ProvisionedThroughput", err.(request.ErrInvalidParams)) + } + } + if s.ReplicaUpdates != nil { + for i, v := range s.ReplicaUpdates { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "ReplicaUpdates", i), err.(request.ErrInvalidParams)) + } + } + } + if s.StreamSpecification != nil { + if err := s.StreamSpecification.Validate(); err != nil { + invalidParams.AddNested("StreamSpecification", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAttributeDefinitions sets the AttributeDefinitions field's value. +func (s *UpdateTableInput) SetAttributeDefinitions(v []*AttributeDefinition) *UpdateTableInput { + s.AttributeDefinitions = v + return s +} + +// SetBillingMode sets the BillingMode field's value. +func (s *UpdateTableInput) SetBillingMode(v string) *UpdateTableInput { + s.BillingMode = &v + return s +} + +// SetGlobalSecondaryIndexUpdates sets the GlobalSecondaryIndexUpdates field's value. +func (s *UpdateTableInput) SetGlobalSecondaryIndexUpdates(v []*GlobalSecondaryIndexUpdate) *UpdateTableInput { + s.GlobalSecondaryIndexUpdates = v + return s +} + +// SetProvisionedThroughput sets the ProvisionedThroughput field's value. +func (s *UpdateTableInput) SetProvisionedThroughput(v *ProvisionedThroughput) *UpdateTableInput { + s.ProvisionedThroughput = v + return s +} + +// SetReplicaUpdates sets the ReplicaUpdates field's value. +func (s *UpdateTableInput) SetReplicaUpdates(v []*ReplicationGroupUpdate) *UpdateTableInput { + s.ReplicaUpdates = v + return s +} + +// SetSSESpecification sets the SSESpecification field's value. +func (s *UpdateTableInput) SetSSESpecification(v *SSESpecification) *UpdateTableInput { + s.SSESpecification = v + return s +} + +// SetStreamSpecification sets the StreamSpecification field's value. +func (s *UpdateTableInput) SetStreamSpecification(v *StreamSpecification) *UpdateTableInput { + s.StreamSpecification = v + return s +} + +// SetTableClass sets the TableClass field's value. +func (s *UpdateTableInput) SetTableClass(v string) *UpdateTableInput { + s.TableClass = &v + return s +} + +// SetTableName sets the TableName field's value. +func (s *UpdateTableInput) SetTableName(v string) *UpdateTableInput { + s.TableName = &v + return s +} + +// Represents the output of an UpdateTable operation. +type UpdateTableOutput struct { + _ struct{} `type:"structure"` + + // Represents the properties of the table. + TableDescription *TableDescription `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateTableOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateTableOutput) GoString() string { + return s.String() +} + +// SetTableDescription sets the TableDescription field's value. +func (s *UpdateTableOutput) SetTableDescription(v *TableDescription) *UpdateTableOutput { + s.TableDescription = v + return s +} + +type UpdateTableReplicaAutoScalingInput struct { + _ struct{} `type:"structure"` + + // Represents the auto scaling settings of the global secondary indexes of the + // replica to be updated. + GlobalSecondaryIndexUpdates []*GlobalSecondaryIndexAutoScalingUpdate `min:"1" type:"list"` + + // Represents the auto scaling settings to be modified for a global table or + // global secondary index. + ProvisionedWriteCapacityAutoScalingUpdate *AutoScalingSettingsUpdate `type:"structure"` + + // Represents the auto scaling settings of replicas of the table that will be + // modified. + ReplicaUpdates []*ReplicaAutoScalingUpdate `min:"1" type:"list"` + + // The name of the global table to be updated. + // + // TableName is a required field + TableName *string `min:"3" type:"string" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateTableReplicaAutoScalingInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateTableReplicaAutoScalingInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateTableReplicaAutoScalingInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateTableReplicaAutoScalingInput"} + if s.GlobalSecondaryIndexUpdates != nil && len(s.GlobalSecondaryIndexUpdates) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GlobalSecondaryIndexUpdates", 1)) + } + if s.ReplicaUpdates != nil && len(s.ReplicaUpdates) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ReplicaUpdates", 1)) + } + if s.TableName == nil { + invalidParams.Add(request.NewErrParamRequired("TableName")) + } + if s.TableName != nil && len(*s.TableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("TableName", 3)) + } + if s.GlobalSecondaryIndexUpdates != nil { + for i, v := range s.GlobalSecondaryIndexUpdates { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "GlobalSecondaryIndexUpdates", i), err.(request.ErrInvalidParams)) + } + } + } + if s.ProvisionedWriteCapacityAutoScalingUpdate != nil { + if err := s.ProvisionedWriteCapacityAutoScalingUpdate.Validate(); err != nil { + invalidParams.AddNested("ProvisionedWriteCapacityAutoScalingUpdate", err.(request.ErrInvalidParams)) + } + } + if s.ReplicaUpdates != nil { + for i, v := range s.ReplicaUpdates { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "ReplicaUpdates", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetGlobalSecondaryIndexUpdates sets the GlobalSecondaryIndexUpdates field's value. +func (s *UpdateTableReplicaAutoScalingInput) SetGlobalSecondaryIndexUpdates(v []*GlobalSecondaryIndexAutoScalingUpdate) *UpdateTableReplicaAutoScalingInput { + s.GlobalSecondaryIndexUpdates = v + return s +} + +// SetProvisionedWriteCapacityAutoScalingUpdate sets the ProvisionedWriteCapacityAutoScalingUpdate field's value. +func (s *UpdateTableReplicaAutoScalingInput) SetProvisionedWriteCapacityAutoScalingUpdate(v *AutoScalingSettingsUpdate) *UpdateTableReplicaAutoScalingInput { + s.ProvisionedWriteCapacityAutoScalingUpdate = v + return s +} + +// SetReplicaUpdates sets the ReplicaUpdates field's value. +func (s *UpdateTableReplicaAutoScalingInput) SetReplicaUpdates(v []*ReplicaAutoScalingUpdate) *UpdateTableReplicaAutoScalingInput { + s.ReplicaUpdates = v + return s +} + +// SetTableName sets the TableName field's value. +func (s *UpdateTableReplicaAutoScalingInput) SetTableName(v string) *UpdateTableReplicaAutoScalingInput { + s.TableName = &v + return s +} + +type UpdateTableReplicaAutoScalingOutput struct { + _ struct{} `type:"structure"` + + // Returns information about the auto scaling settings of a table with replicas. + TableAutoScalingDescription *TableAutoScalingDescription `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateTableReplicaAutoScalingOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateTableReplicaAutoScalingOutput) GoString() string { + return s.String() +} + +// SetTableAutoScalingDescription sets the TableAutoScalingDescription field's value. +func (s *UpdateTableReplicaAutoScalingOutput) SetTableAutoScalingDescription(v *TableAutoScalingDescription) *UpdateTableReplicaAutoScalingOutput { + s.TableAutoScalingDescription = v + return s +} + +// Represents the input of an UpdateTimeToLive operation. +type UpdateTimeToLiveInput struct { + _ struct{} `type:"structure"` + + // The name of the table to be configured. + // + // TableName is a required field + TableName *string `min:"3" type:"string" required:"true"` + + // Represents the settings used to enable or disable Time to Live for the specified + // table. + // + // TimeToLiveSpecification is a required field + TimeToLiveSpecification *TimeToLiveSpecification `type:"structure" required:"true"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateTimeToLiveInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateTimeToLiveInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateTimeToLiveInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateTimeToLiveInput"} + if s.TableName == nil { + invalidParams.Add(request.NewErrParamRequired("TableName")) + } + if s.TableName != nil && len(*s.TableName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("TableName", 3)) + } + if s.TimeToLiveSpecification == nil { + invalidParams.Add(request.NewErrParamRequired("TimeToLiveSpecification")) + } + if s.TimeToLiveSpecification != nil { + if err := s.TimeToLiveSpecification.Validate(); err != nil { + invalidParams.AddNested("TimeToLiveSpecification", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetTableName sets the TableName field's value. +func (s *UpdateTimeToLiveInput) SetTableName(v string) *UpdateTimeToLiveInput { + s.TableName = &v + return s +} + +// SetTimeToLiveSpecification sets the TimeToLiveSpecification field's value. +func (s *UpdateTimeToLiveInput) SetTimeToLiveSpecification(v *TimeToLiveSpecification) *UpdateTimeToLiveInput { + s.TimeToLiveSpecification = v + return s +} + +type UpdateTimeToLiveOutput struct { + _ struct{} `type:"structure"` + + // Represents the output of an UpdateTimeToLive operation. + TimeToLiveSpecification *TimeToLiveSpecification `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateTimeToLiveOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s UpdateTimeToLiveOutput) GoString() string { + return s.String() +} + +// SetTimeToLiveSpecification sets the TimeToLiveSpecification field's value. +func (s *UpdateTimeToLiveOutput) SetTimeToLiveSpecification(v *TimeToLiveSpecification) *UpdateTimeToLiveOutput { + s.TimeToLiveSpecification = v + return s +} + +// Represents an operation to perform - either DeleteItem or PutItem. You can +// only request one of these operations, not both, in a single WriteRequest. +// If you do need to perform both of these operations, you need to provide two +// separate WriteRequest objects. +type WriteRequest struct { + _ struct{} `type:"structure"` + + // A request to perform a DeleteItem operation. + DeleteRequest *DeleteRequest `type:"structure"` + + // A request to perform a PutItem operation. + PutRequest *PutRequest `type:"structure"` +} + +// String returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s WriteRequest) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation. +// +// API parameter values that are decorated as "sensitive" in the API will not +// be included in the string output. The member name will be present, but the +// value will be replaced with "sensitive". +func (s WriteRequest) GoString() string { + return s.String() +} + +// SetDeleteRequest sets the DeleteRequest field's value. +func (s *WriteRequest) SetDeleteRequest(v *DeleteRequest) *WriteRequest { + s.DeleteRequest = v + return s +} + +// SetPutRequest sets the PutRequest field's value. +func (s *WriteRequest) SetPutRequest(v *PutRequest) *WriteRequest { + s.PutRequest = v + return s +} + +const ( + // AttributeActionAdd is a AttributeAction enum value + AttributeActionAdd = "ADD" + + // AttributeActionPut is a AttributeAction enum value + AttributeActionPut = "PUT" + + // AttributeActionDelete is a AttributeAction enum value + AttributeActionDelete = "DELETE" +) + +// AttributeAction_Values returns all elements of the AttributeAction enum +func AttributeAction_Values() []string { + return []string{ + AttributeActionAdd, + AttributeActionPut, + AttributeActionDelete, + } +} + +const ( + // BackupStatusCreating is a BackupStatus enum value + BackupStatusCreating = "CREATING" + + // BackupStatusDeleted is a BackupStatus enum value + BackupStatusDeleted = "DELETED" + + // BackupStatusAvailable is a BackupStatus enum value + BackupStatusAvailable = "AVAILABLE" +) + +// BackupStatus_Values returns all elements of the BackupStatus enum +func BackupStatus_Values() []string { + return []string{ + BackupStatusCreating, + BackupStatusDeleted, + BackupStatusAvailable, + } +} + +const ( + // BackupTypeUser is a BackupType enum value + BackupTypeUser = "USER" + + // BackupTypeSystem is a BackupType enum value + BackupTypeSystem = "SYSTEM" + + // BackupTypeAwsBackup is a BackupType enum value + BackupTypeAwsBackup = "AWS_BACKUP" +) + +// BackupType_Values returns all elements of the BackupType enum +func BackupType_Values() []string { + return []string{ + BackupTypeUser, + BackupTypeSystem, + BackupTypeAwsBackup, + } +} + +const ( + // BackupTypeFilterUser is a BackupTypeFilter enum value + BackupTypeFilterUser = "USER" + + // BackupTypeFilterSystem is a BackupTypeFilter enum value + BackupTypeFilterSystem = "SYSTEM" + + // BackupTypeFilterAwsBackup is a BackupTypeFilter enum value + BackupTypeFilterAwsBackup = "AWS_BACKUP" + + // BackupTypeFilterAll is a BackupTypeFilter enum value + BackupTypeFilterAll = "ALL" +) + +// BackupTypeFilter_Values returns all elements of the BackupTypeFilter enum +func BackupTypeFilter_Values() []string { + return []string{ + BackupTypeFilterUser, + BackupTypeFilterSystem, + BackupTypeFilterAwsBackup, + BackupTypeFilterAll, + } +} + +const ( + // BatchStatementErrorCodeEnumConditionalCheckFailed is a BatchStatementErrorCodeEnum enum value + BatchStatementErrorCodeEnumConditionalCheckFailed = "ConditionalCheckFailed" + + // BatchStatementErrorCodeEnumItemCollectionSizeLimitExceeded is a BatchStatementErrorCodeEnum enum value + BatchStatementErrorCodeEnumItemCollectionSizeLimitExceeded = "ItemCollectionSizeLimitExceeded" + + // BatchStatementErrorCodeEnumRequestLimitExceeded is a BatchStatementErrorCodeEnum enum value + BatchStatementErrorCodeEnumRequestLimitExceeded = "RequestLimitExceeded" + + // BatchStatementErrorCodeEnumValidationError is a BatchStatementErrorCodeEnum enum value + BatchStatementErrorCodeEnumValidationError = "ValidationError" + + // BatchStatementErrorCodeEnumProvisionedThroughputExceeded is a BatchStatementErrorCodeEnum enum value + BatchStatementErrorCodeEnumProvisionedThroughputExceeded = "ProvisionedThroughputExceeded" + + // BatchStatementErrorCodeEnumTransactionConflict is a BatchStatementErrorCodeEnum enum value + BatchStatementErrorCodeEnumTransactionConflict = "TransactionConflict" + + // BatchStatementErrorCodeEnumThrottlingError is a BatchStatementErrorCodeEnum enum value + BatchStatementErrorCodeEnumThrottlingError = "ThrottlingError" + + // BatchStatementErrorCodeEnumInternalServerError is a BatchStatementErrorCodeEnum enum value + BatchStatementErrorCodeEnumInternalServerError = "InternalServerError" + + // BatchStatementErrorCodeEnumResourceNotFound is a BatchStatementErrorCodeEnum enum value + BatchStatementErrorCodeEnumResourceNotFound = "ResourceNotFound" + + // BatchStatementErrorCodeEnumAccessDenied is a BatchStatementErrorCodeEnum enum value + BatchStatementErrorCodeEnumAccessDenied = "AccessDenied" + + // BatchStatementErrorCodeEnumDuplicateItem is a BatchStatementErrorCodeEnum enum value + BatchStatementErrorCodeEnumDuplicateItem = "DuplicateItem" +) + +// BatchStatementErrorCodeEnum_Values returns all elements of the BatchStatementErrorCodeEnum enum +func BatchStatementErrorCodeEnum_Values() []string { + return []string{ + BatchStatementErrorCodeEnumConditionalCheckFailed, + BatchStatementErrorCodeEnumItemCollectionSizeLimitExceeded, + BatchStatementErrorCodeEnumRequestLimitExceeded, + BatchStatementErrorCodeEnumValidationError, + BatchStatementErrorCodeEnumProvisionedThroughputExceeded, + BatchStatementErrorCodeEnumTransactionConflict, + BatchStatementErrorCodeEnumThrottlingError, + BatchStatementErrorCodeEnumInternalServerError, + BatchStatementErrorCodeEnumResourceNotFound, + BatchStatementErrorCodeEnumAccessDenied, + BatchStatementErrorCodeEnumDuplicateItem, + } +} + +const ( + // BillingModeProvisioned is a BillingMode enum value + BillingModeProvisioned = "PROVISIONED" + + // BillingModePayPerRequest is a BillingMode enum value + BillingModePayPerRequest = "PAY_PER_REQUEST" +) + +// BillingMode_Values returns all elements of the BillingMode enum +func BillingMode_Values() []string { + return []string{ + BillingModeProvisioned, + BillingModePayPerRequest, + } +} + +const ( + // ComparisonOperatorEq is a ComparisonOperator enum value + ComparisonOperatorEq = "EQ" + + // ComparisonOperatorNe is a ComparisonOperator enum value + ComparisonOperatorNe = "NE" + + // ComparisonOperatorIn is a ComparisonOperator enum value + ComparisonOperatorIn = "IN" + + // ComparisonOperatorLe is a ComparisonOperator enum value + ComparisonOperatorLe = "LE" + + // ComparisonOperatorLt is a ComparisonOperator enum value + ComparisonOperatorLt = "LT" + + // ComparisonOperatorGe is a ComparisonOperator enum value + ComparisonOperatorGe = "GE" + + // ComparisonOperatorGt is a ComparisonOperator enum value + ComparisonOperatorGt = "GT" + + // ComparisonOperatorBetween is a ComparisonOperator enum value + ComparisonOperatorBetween = "BETWEEN" + + // ComparisonOperatorNotNull is a ComparisonOperator enum value + ComparisonOperatorNotNull = "NOT_NULL" + + // ComparisonOperatorNull is a ComparisonOperator enum value + ComparisonOperatorNull = "NULL" + + // ComparisonOperatorContains is a ComparisonOperator enum value + ComparisonOperatorContains = "CONTAINS" + + // ComparisonOperatorNotContains is a ComparisonOperator enum value + ComparisonOperatorNotContains = "NOT_CONTAINS" + + // ComparisonOperatorBeginsWith is a ComparisonOperator enum value + ComparisonOperatorBeginsWith = "BEGINS_WITH" +) + +// ComparisonOperator_Values returns all elements of the ComparisonOperator enum +func ComparisonOperator_Values() []string { + return []string{ + ComparisonOperatorEq, + ComparisonOperatorNe, + ComparisonOperatorIn, + ComparisonOperatorLe, + ComparisonOperatorLt, + ComparisonOperatorGe, + ComparisonOperatorGt, + ComparisonOperatorBetween, + ComparisonOperatorNotNull, + ComparisonOperatorNull, + ComparisonOperatorContains, + ComparisonOperatorNotContains, + ComparisonOperatorBeginsWith, + } +} + +const ( + // ConditionalOperatorAnd is a ConditionalOperator enum value + ConditionalOperatorAnd = "AND" + + // ConditionalOperatorOr is a ConditionalOperator enum value + ConditionalOperatorOr = "OR" +) + +// ConditionalOperator_Values returns all elements of the ConditionalOperator enum +func ConditionalOperator_Values() []string { + return []string{ + ConditionalOperatorAnd, + ConditionalOperatorOr, + } +} + +const ( + // ContinuousBackupsStatusEnabled is a ContinuousBackupsStatus enum value + ContinuousBackupsStatusEnabled = "ENABLED" + + // ContinuousBackupsStatusDisabled is a ContinuousBackupsStatus enum value + ContinuousBackupsStatusDisabled = "DISABLED" +) + +// ContinuousBackupsStatus_Values returns all elements of the ContinuousBackupsStatus enum +func ContinuousBackupsStatus_Values() []string { + return []string{ + ContinuousBackupsStatusEnabled, + ContinuousBackupsStatusDisabled, + } +} + +const ( + // ContributorInsightsActionEnable is a ContributorInsightsAction enum value + ContributorInsightsActionEnable = "ENABLE" + + // ContributorInsightsActionDisable is a ContributorInsightsAction enum value + ContributorInsightsActionDisable = "DISABLE" +) + +// ContributorInsightsAction_Values returns all elements of the ContributorInsightsAction enum +func ContributorInsightsAction_Values() []string { + return []string{ + ContributorInsightsActionEnable, + ContributorInsightsActionDisable, + } +} + +const ( + // ContributorInsightsStatusEnabling is a ContributorInsightsStatus enum value + ContributorInsightsStatusEnabling = "ENABLING" + + // ContributorInsightsStatusEnabled is a ContributorInsightsStatus enum value + ContributorInsightsStatusEnabled = "ENABLED" + + // ContributorInsightsStatusDisabling is a ContributorInsightsStatus enum value + ContributorInsightsStatusDisabling = "DISABLING" + + // ContributorInsightsStatusDisabled is a ContributorInsightsStatus enum value + ContributorInsightsStatusDisabled = "DISABLED" + + // ContributorInsightsStatusFailed is a ContributorInsightsStatus enum value + ContributorInsightsStatusFailed = "FAILED" +) + +// ContributorInsightsStatus_Values returns all elements of the ContributorInsightsStatus enum +func ContributorInsightsStatus_Values() []string { + return []string{ + ContributorInsightsStatusEnabling, + ContributorInsightsStatusEnabled, + ContributorInsightsStatusDisabling, + ContributorInsightsStatusDisabled, + ContributorInsightsStatusFailed, + } +} + +const ( + // DestinationStatusEnabling is a DestinationStatus enum value + DestinationStatusEnabling = "ENABLING" + + // DestinationStatusActive is a DestinationStatus enum value + DestinationStatusActive = "ACTIVE" + + // DestinationStatusDisabling is a DestinationStatus enum value + DestinationStatusDisabling = "DISABLING" + + // DestinationStatusDisabled is a DestinationStatus enum value + DestinationStatusDisabled = "DISABLED" + + // DestinationStatusEnableFailed is a DestinationStatus enum value + DestinationStatusEnableFailed = "ENABLE_FAILED" +) + +// DestinationStatus_Values returns all elements of the DestinationStatus enum +func DestinationStatus_Values() []string { + return []string{ + DestinationStatusEnabling, + DestinationStatusActive, + DestinationStatusDisabling, + DestinationStatusDisabled, + DestinationStatusEnableFailed, + } +} + +const ( + // ExportFormatDynamodbJson is a ExportFormat enum value + ExportFormatDynamodbJson = "DYNAMODB_JSON" + + // ExportFormatIon is a ExportFormat enum value + ExportFormatIon = "ION" +) + +// ExportFormat_Values returns all elements of the ExportFormat enum +func ExportFormat_Values() []string { + return []string{ + ExportFormatDynamodbJson, + ExportFormatIon, + } +} + +const ( + // ExportStatusInProgress is a ExportStatus enum value + ExportStatusInProgress = "IN_PROGRESS" + + // ExportStatusCompleted is a ExportStatus enum value + ExportStatusCompleted = "COMPLETED" + + // ExportStatusFailed is a ExportStatus enum value + ExportStatusFailed = "FAILED" +) + +// ExportStatus_Values returns all elements of the ExportStatus enum +func ExportStatus_Values() []string { + return []string{ + ExportStatusInProgress, + ExportStatusCompleted, + ExportStatusFailed, + } +} + +const ( + // GlobalTableStatusCreating is a GlobalTableStatus enum value + GlobalTableStatusCreating = "CREATING" + + // GlobalTableStatusActive is a GlobalTableStatus enum value + GlobalTableStatusActive = "ACTIVE" + + // GlobalTableStatusDeleting is a GlobalTableStatus enum value + GlobalTableStatusDeleting = "DELETING" + + // GlobalTableStatusUpdating is a GlobalTableStatus enum value + GlobalTableStatusUpdating = "UPDATING" +) + +// GlobalTableStatus_Values returns all elements of the GlobalTableStatus enum +func GlobalTableStatus_Values() []string { + return []string{ + GlobalTableStatusCreating, + GlobalTableStatusActive, + GlobalTableStatusDeleting, + GlobalTableStatusUpdating, + } +} + +const ( + // IndexStatusCreating is a IndexStatus enum value + IndexStatusCreating = "CREATING" + + // IndexStatusUpdating is a IndexStatus enum value + IndexStatusUpdating = "UPDATING" + + // IndexStatusDeleting is a IndexStatus enum value + IndexStatusDeleting = "DELETING" + + // IndexStatusActive is a IndexStatus enum value + IndexStatusActive = "ACTIVE" +) + +// IndexStatus_Values returns all elements of the IndexStatus enum +func IndexStatus_Values() []string { + return []string{ + IndexStatusCreating, + IndexStatusUpdating, + IndexStatusDeleting, + IndexStatusActive, + } +} + +const ( + // KeyTypeHash is a KeyType enum value + KeyTypeHash = "HASH" + + // KeyTypeRange is a KeyType enum value + KeyTypeRange = "RANGE" +) + +// KeyType_Values returns all elements of the KeyType enum +func KeyType_Values() []string { + return []string{ + KeyTypeHash, + KeyTypeRange, + } +} + +const ( + // PointInTimeRecoveryStatusEnabled is a PointInTimeRecoveryStatus enum value + PointInTimeRecoveryStatusEnabled = "ENABLED" + + // PointInTimeRecoveryStatusDisabled is a PointInTimeRecoveryStatus enum value + PointInTimeRecoveryStatusDisabled = "DISABLED" +) + +// PointInTimeRecoveryStatus_Values returns all elements of the PointInTimeRecoveryStatus enum +func PointInTimeRecoveryStatus_Values() []string { + return []string{ + PointInTimeRecoveryStatusEnabled, + PointInTimeRecoveryStatusDisabled, + } +} + +const ( + // ProjectionTypeAll is a ProjectionType enum value + ProjectionTypeAll = "ALL" + + // ProjectionTypeKeysOnly is a ProjectionType enum value + ProjectionTypeKeysOnly = "KEYS_ONLY" + + // ProjectionTypeInclude is a ProjectionType enum value + ProjectionTypeInclude = "INCLUDE" +) + +// ProjectionType_Values returns all elements of the ProjectionType enum +func ProjectionType_Values() []string { + return []string{ + ProjectionTypeAll, + ProjectionTypeKeysOnly, + ProjectionTypeInclude, + } +} + +const ( + // ReplicaStatusCreating is a ReplicaStatus enum value + ReplicaStatusCreating = "CREATING" + + // ReplicaStatusCreationFailed is a ReplicaStatus enum value + ReplicaStatusCreationFailed = "CREATION_FAILED" + + // ReplicaStatusUpdating is a ReplicaStatus enum value + ReplicaStatusUpdating = "UPDATING" + + // ReplicaStatusDeleting is a ReplicaStatus enum value + ReplicaStatusDeleting = "DELETING" + + // ReplicaStatusActive is a ReplicaStatus enum value + ReplicaStatusActive = "ACTIVE" + + // ReplicaStatusRegionDisabled is a ReplicaStatus enum value + ReplicaStatusRegionDisabled = "REGION_DISABLED" + + // ReplicaStatusInaccessibleEncryptionCredentials is a ReplicaStatus enum value + ReplicaStatusInaccessibleEncryptionCredentials = "INACCESSIBLE_ENCRYPTION_CREDENTIALS" +) + +// ReplicaStatus_Values returns all elements of the ReplicaStatus enum +func ReplicaStatus_Values() []string { + return []string{ + ReplicaStatusCreating, + ReplicaStatusCreationFailed, + ReplicaStatusUpdating, + ReplicaStatusDeleting, + ReplicaStatusActive, + ReplicaStatusRegionDisabled, + ReplicaStatusInaccessibleEncryptionCredentials, + } +} + +// Determines the level of detail about either provisioned or on-demand throughput +// consumption that is returned in the response: +// +// * INDEXES - The response includes the aggregate ConsumedCapacity for the +// operation, together with ConsumedCapacity for each table and secondary +// index that was accessed. Note that some operations, such as GetItem and +// BatchGetItem, do not access any indexes at all. In these cases, specifying +// INDEXES will only return ConsumedCapacity information for table(s). +// +// * TOTAL - The response includes only the aggregate ConsumedCapacity for +// the operation. +// +// * NONE - No ConsumedCapacity details are included in the response. +const ( + // ReturnConsumedCapacityIndexes is a ReturnConsumedCapacity enum value + ReturnConsumedCapacityIndexes = "INDEXES" + + // ReturnConsumedCapacityTotal is a ReturnConsumedCapacity enum value + ReturnConsumedCapacityTotal = "TOTAL" + + // ReturnConsumedCapacityNone is a ReturnConsumedCapacity enum value + ReturnConsumedCapacityNone = "NONE" +) + +// ReturnConsumedCapacity_Values returns all elements of the ReturnConsumedCapacity enum +func ReturnConsumedCapacity_Values() []string { + return []string{ + ReturnConsumedCapacityIndexes, + ReturnConsumedCapacityTotal, + ReturnConsumedCapacityNone, + } +} + +const ( + // ReturnItemCollectionMetricsSize is a ReturnItemCollectionMetrics enum value + ReturnItemCollectionMetricsSize = "SIZE" + + // ReturnItemCollectionMetricsNone is a ReturnItemCollectionMetrics enum value + ReturnItemCollectionMetricsNone = "NONE" +) + +// ReturnItemCollectionMetrics_Values returns all elements of the ReturnItemCollectionMetrics enum +func ReturnItemCollectionMetrics_Values() []string { + return []string{ + ReturnItemCollectionMetricsSize, + ReturnItemCollectionMetricsNone, + } +} + +const ( + // ReturnValueNone is a ReturnValue enum value + ReturnValueNone = "NONE" + + // ReturnValueAllOld is a ReturnValue enum value + ReturnValueAllOld = "ALL_OLD" + + // ReturnValueUpdatedOld is a ReturnValue enum value + ReturnValueUpdatedOld = "UPDATED_OLD" + + // ReturnValueAllNew is a ReturnValue enum value + ReturnValueAllNew = "ALL_NEW" + + // ReturnValueUpdatedNew is a ReturnValue enum value + ReturnValueUpdatedNew = "UPDATED_NEW" +) + +// ReturnValue_Values returns all elements of the ReturnValue enum +func ReturnValue_Values() []string { + return []string{ + ReturnValueNone, + ReturnValueAllOld, + ReturnValueUpdatedOld, + ReturnValueAllNew, + ReturnValueUpdatedNew, + } +} + +const ( + // ReturnValuesOnConditionCheckFailureAllOld is a ReturnValuesOnConditionCheckFailure enum value + ReturnValuesOnConditionCheckFailureAllOld = "ALL_OLD" + + // ReturnValuesOnConditionCheckFailureNone is a ReturnValuesOnConditionCheckFailure enum value + ReturnValuesOnConditionCheckFailureNone = "NONE" +) + +// ReturnValuesOnConditionCheckFailure_Values returns all elements of the ReturnValuesOnConditionCheckFailure enum +func ReturnValuesOnConditionCheckFailure_Values() []string { + return []string{ + ReturnValuesOnConditionCheckFailureAllOld, + ReturnValuesOnConditionCheckFailureNone, + } +} + +const ( + // S3SseAlgorithmAes256 is a S3SseAlgorithm enum value + S3SseAlgorithmAes256 = "AES256" + + // S3SseAlgorithmKms is a S3SseAlgorithm enum value + S3SseAlgorithmKms = "KMS" +) + +// S3SseAlgorithm_Values returns all elements of the S3SseAlgorithm enum +func S3SseAlgorithm_Values() []string { + return []string{ + S3SseAlgorithmAes256, + S3SseAlgorithmKms, + } +} + +const ( + // SSEStatusEnabling is a SSEStatus enum value + SSEStatusEnabling = "ENABLING" + + // SSEStatusEnabled is a SSEStatus enum value + SSEStatusEnabled = "ENABLED" + + // SSEStatusDisabling is a SSEStatus enum value + SSEStatusDisabling = "DISABLING" + + // SSEStatusDisabled is a SSEStatus enum value + SSEStatusDisabled = "DISABLED" + + // SSEStatusUpdating is a SSEStatus enum value + SSEStatusUpdating = "UPDATING" +) + +// SSEStatus_Values returns all elements of the SSEStatus enum +func SSEStatus_Values() []string { + return []string{ + SSEStatusEnabling, + SSEStatusEnabled, + SSEStatusDisabling, + SSEStatusDisabled, + SSEStatusUpdating, + } +} + +const ( + // SSETypeAes256 is a SSEType enum value + SSETypeAes256 = "AES256" + + // SSETypeKms is a SSEType enum value + SSETypeKms = "KMS" +) + +// SSEType_Values returns all elements of the SSEType enum +func SSEType_Values() []string { + return []string{ + SSETypeAes256, + SSETypeKms, + } +} + +const ( + // ScalarAttributeTypeS is a ScalarAttributeType enum value + ScalarAttributeTypeS = "S" + + // ScalarAttributeTypeN is a ScalarAttributeType enum value + ScalarAttributeTypeN = "N" + + // ScalarAttributeTypeB is a ScalarAttributeType enum value + ScalarAttributeTypeB = "B" +) + +// ScalarAttributeType_Values returns all elements of the ScalarAttributeType enum +func ScalarAttributeType_Values() []string { + return []string{ + ScalarAttributeTypeS, + ScalarAttributeTypeN, + ScalarAttributeTypeB, + } +} + +const ( + // SelectAllAttributes is a Select enum value + SelectAllAttributes = "ALL_ATTRIBUTES" + + // SelectAllProjectedAttributes is a Select enum value + SelectAllProjectedAttributes = "ALL_PROJECTED_ATTRIBUTES" + + // SelectSpecificAttributes is a Select enum value + SelectSpecificAttributes = "SPECIFIC_ATTRIBUTES" + + // SelectCount is a Select enum value + SelectCount = "COUNT" +) + +// Select_Values returns all elements of the Select enum +func Select_Values() []string { + return []string{ + SelectAllAttributes, + SelectAllProjectedAttributes, + SelectSpecificAttributes, + SelectCount, + } +} + +const ( + // StreamViewTypeNewImage is a StreamViewType enum value + StreamViewTypeNewImage = "NEW_IMAGE" + + // StreamViewTypeOldImage is a StreamViewType enum value + StreamViewTypeOldImage = "OLD_IMAGE" + + // StreamViewTypeNewAndOldImages is a StreamViewType enum value + StreamViewTypeNewAndOldImages = "NEW_AND_OLD_IMAGES" + + // StreamViewTypeKeysOnly is a StreamViewType enum value + StreamViewTypeKeysOnly = "KEYS_ONLY" +) + +// StreamViewType_Values returns all elements of the StreamViewType enum +func StreamViewType_Values() []string { + return []string{ + StreamViewTypeNewImage, + StreamViewTypeOldImage, + StreamViewTypeNewAndOldImages, + StreamViewTypeKeysOnly, + } +} + +const ( + // TableClassStandard is a TableClass enum value + TableClassStandard = "STANDARD" + + // TableClassStandardInfrequentAccess is a TableClass enum value + TableClassStandardInfrequentAccess = "STANDARD_INFREQUENT_ACCESS" +) + +// TableClass_Values returns all elements of the TableClass enum +func TableClass_Values() []string { + return []string{ + TableClassStandard, + TableClassStandardInfrequentAccess, + } +} + +const ( + // TableStatusCreating is a TableStatus enum value + TableStatusCreating = "CREATING" + + // TableStatusUpdating is a TableStatus enum value + TableStatusUpdating = "UPDATING" + + // TableStatusDeleting is a TableStatus enum value + TableStatusDeleting = "DELETING" + + // TableStatusActive is a TableStatus enum value + TableStatusActive = "ACTIVE" + + // TableStatusInaccessibleEncryptionCredentials is a TableStatus enum value + TableStatusInaccessibleEncryptionCredentials = "INACCESSIBLE_ENCRYPTION_CREDENTIALS" + + // TableStatusArchiving is a TableStatus enum value + TableStatusArchiving = "ARCHIVING" + + // TableStatusArchived is a TableStatus enum value + TableStatusArchived = "ARCHIVED" +) + +// TableStatus_Values returns all elements of the TableStatus enum +func TableStatus_Values() []string { + return []string{ + TableStatusCreating, + TableStatusUpdating, + TableStatusDeleting, + TableStatusActive, + TableStatusInaccessibleEncryptionCredentials, + TableStatusArchiving, + TableStatusArchived, + } +} + +const ( + // TimeToLiveStatusEnabling is a TimeToLiveStatus enum value + TimeToLiveStatusEnabling = "ENABLING" + + // TimeToLiveStatusDisabling is a TimeToLiveStatus enum value + TimeToLiveStatusDisabling = "DISABLING" + + // TimeToLiveStatusEnabled is a TimeToLiveStatus enum value + TimeToLiveStatusEnabled = "ENABLED" + + // TimeToLiveStatusDisabled is a TimeToLiveStatus enum value + TimeToLiveStatusDisabled = "DISABLED" +) + +// TimeToLiveStatus_Values returns all elements of the TimeToLiveStatus enum +func TimeToLiveStatus_Values() []string { + return []string{ + TimeToLiveStatusEnabling, + TimeToLiveStatusDisabling, + TimeToLiveStatusEnabled, + TimeToLiveStatusDisabled, + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/service/dynamodb/customizations.go b/vendor/github.com/aws/aws-sdk-go/service/dynamodb/customizations.go new file mode 100644 index 0000000..c019e63 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/dynamodb/customizations.go @@ -0,0 +1,98 @@ +package dynamodb + +import ( + "bytes" + "hash/crc32" + "io" + "io/ioutil" + "strconv" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/request" +) + +func init() { + initClient = func(c *client.Client) { + if c.Config.Retryer == nil { + // Only override the retryer with a custom one if the config + // does not already contain a retryer + setCustomRetryer(c) + } + + c.Handlers.Build.PushBack(disableCompression) + c.Handlers.Unmarshal.PushFront(validateCRC32) + } +} + +func setCustomRetryer(c *client.Client) { + maxRetries := aws.IntValue(c.Config.MaxRetries) + if c.Config.MaxRetries == nil || maxRetries == aws.UseServiceDefaultRetries { + maxRetries = 10 + } + + c.Retryer = client.DefaultRetryer{ + NumMaxRetries: maxRetries, + MinRetryDelay: 50 * time.Millisecond, + } +} + +func drainBody(b io.ReadCloser, length int64) (out *bytes.Buffer, err error) { + if length < 0 { + length = 0 + } + buf := bytes.NewBuffer(make([]byte, 0, length)) + + if _, err = buf.ReadFrom(b); err != nil { + return nil, err + } + if err = b.Close(); err != nil { + return nil, err + } + return buf, nil +} + +func disableCompression(r *request.Request) { + r.HTTPRequest.Header.Set("Accept-Encoding", "identity") +} + +func validateCRC32(r *request.Request) { + if r.Error != nil { + return // already have an error, no need to verify CRC + } + + // Checksum validation is off, skip + if aws.BoolValue(r.Config.DisableComputeChecksums) { + return + } + + // Try to get CRC from response + header := r.HTTPResponse.Header.Get("X-Amz-Crc32") + if header == "" { + return // No header, skip + } + + expected, err := strconv.ParseUint(header, 10, 32) + if err != nil { + return // Could not determine CRC value, skip + } + + buf, err := drainBody(r.HTTPResponse.Body, r.HTTPResponse.ContentLength) + if err != nil { // failed to read the response body, skip + return + } + + // Reset body for subsequent reads + r.HTTPResponse.Body = ioutil.NopCloser(bytes.NewReader(buf.Bytes())) + + // Compute the CRC checksum + crc := crc32.ChecksumIEEE(buf.Bytes()) + + if crc != uint32(expected) { + // CRC does not match, set a retryable error + r.Retryable = aws.Bool(true) + r.Error = awserr.New("CRC32CheckFailed", "CRC32 integrity check failed", nil) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/service/dynamodb/doc.go b/vendor/github.com/aws/aws-sdk-go/service/dynamodb/doc.go new file mode 100644 index 0000000..c1fe449 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/dynamodb/doc.go @@ -0,0 +1,45 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +// Package dynamodb provides the client and types for making API +// requests to Amazon DynamoDB. +// +// Amazon DynamoDB is a fully managed NoSQL database service that provides fast +// and predictable performance with seamless scalability. DynamoDB lets you +// offload the administrative burdens of operating and scaling a distributed +// database, so that you don't have to worry about hardware provisioning, setup +// and configuration, replication, software patching, or cluster scaling. +// +// With DynamoDB, you can create database tables that can store and retrieve +// any amount of data, and serve any level of request traffic. You can scale +// up or scale down your tables' throughput capacity without downtime or performance +// degradation, and use the Amazon Web Services Management Console to monitor +// resource utilization and performance metrics. +// +// DynamoDB automatically spreads the data and traffic for your tables over +// a sufficient number of servers to handle your throughput and storage requirements, +// while maintaining consistent and fast performance. All of your data is stored +// on solid state disks (SSDs) and automatically replicated across multiple +// Availability Zones in an Amazon Web Services Region, providing built-in high +// availability and data durability. +// +// See https://docs.aws.amazon.com/goto/WebAPI/dynamodb-2012-08-10 for more information on this service. +// +// See dynamodb package documentation for more information. +// https://docs.aws.amazon.com/sdk-for-go/api/service/dynamodb/ +// +// Using the Client +// +// To contact Amazon DynamoDB with the SDK use the New function to create +// a new service client. With that client you can make API requests to the service. +// These clients are safe to use concurrently. +// +// See the SDK's documentation for more information on how to use the SDK. +// https://docs.aws.amazon.com/sdk-for-go/api/ +// +// See aws.Config documentation for more information on configuring SDK clients. +// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config +// +// See the Amazon DynamoDB client DynamoDB for more +// information on creating client for this service. +// https://docs.aws.amazon.com/sdk-for-go/api/service/dynamodb/#New +package dynamodb diff --git a/vendor/github.com/aws/aws-sdk-go/service/dynamodb/doc_custom.go b/vendor/github.com/aws/aws-sdk-go/service/dynamodb/doc_custom.go new file mode 100644 index 0000000..013e9b1 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/dynamodb/doc_custom.go @@ -0,0 +1,27 @@ +/* +AttributeValue Marshaling and Unmarshaling Helpers + +Utility helpers to marshal and unmarshal AttributeValue to and +from Go types can be found in the dynamodbattribute sub package. This package +provides specialized functions for the common ways of working with +AttributeValues. Such as map[string]*AttributeValue, []*AttributeValue, and +directly with *AttributeValue. This is helpful for marshaling Go types for API +operations such as PutItem, and unmarshaling Query and Scan APIs' responses. + +See the dynamodbattribute package documentation for more information. +https://docs.aws.amazon.com/sdk-for-go/api/service/dynamodb/dynamodbattribute/ + +Expression Builders + +The expression package provides utility types and functions to build DynamoDB +expression for type safe construction of API ExpressionAttributeNames, and +ExpressionAttribute Values. + +The package represents the various DynamoDB Expressions as structs named +accordingly. For example, ConditionBuilder represents a DynamoDB Condition +Expression, an UpdateBuilder represents a DynamoDB Update Expression, and so on. + +See the expression package documentation for more information. +https://docs.aws.amazon.com/sdk-for-go/api/service/dynamodb/expression/ +*/ +package dynamodb diff --git a/vendor/github.com/aws/aws-sdk-go/service/dynamodb/errors.go b/vendor/github.com/aws/aws-sdk-go/service/dynamodb/errors.go new file mode 100644 index 0000000..9ffd8f2 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/dynamodb/errors.go @@ -0,0 +1,327 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package dynamodb + +import ( + "github.com/aws/aws-sdk-go/private/protocol" +) + +const ( + + // ErrCodeBackupInUseException for service response error code + // "BackupInUseException". + // + // There is another ongoing conflicting backup control plane operation on the + // table. The backup is either being created, deleted or restored to a table. + ErrCodeBackupInUseException = "BackupInUseException" + + // ErrCodeBackupNotFoundException for service response error code + // "BackupNotFoundException". + // + // Backup not found for the given BackupARN. + ErrCodeBackupNotFoundException = "BackupNotFoundException" + + // ErrCodeConditionalCheckFailedException for service response error code + // "ConditionalCheckFailedException". + // + // A condition specified in the operation could not be evaluated. + ErrCodeConditionalCheckFailedException = "ConditionalCheckFailedException" + + // ErrCodeContinuousBackupsUnavailableException for service response error code + // "ContinuousBackupsUnavailableException". + // + // Backups have not yet been enabled for this table. + ErrCodeContinuousBackupsUnavailableException = "ContinuousBackupsUnavailableException" + + // ErrCodeDuplicateItemException for service response error code + // "DuplicateItemException". + // + // There was an attempt to insert an item with the same primary key as an item + // that already exists in the DynamoDB table. + ErrCodeDuplicateItemException = "DuplicateItemException" + + // ErrCodeExportConflictException for service response error code + // "ExportConflictException". + // + // There was a conflict when writing to the specified S3 bucket. + ErrCodeExportConflictException = "ExportConflictException" + + // ErrCodeExportNotFoundException for service response error code + // "ExportNotFoundException". + // + // The specified export was not found. + ErrCodeExportNotFoundException = "ExportNotFoundException" + + // ErrCodeGlobalTableAlreadyExistsException for service response error code + // "GlobalTableAlreadyExistsException". + // + // The specified global table already exists. + ErrCodeGlobalTableAlreadyExistsException = "GlobalTableAlreadyExistsException" + + // ErrCodeGlobalTableNotFoundException for service response error code + // "GlobalTableNotFoundException". + // + // The specified global table does not exist. + ErrCodeGlobalTableNotFoundException = "GlobalTableNotFoundException" + + // ErrCodeIdempotentParameterMismatchException for service response error code + // "IdempotentParameterMismatchException". + // + // DynamoDB rejected the request because you retried a request with a different + // payload but with an idempotent token that was already used. + ErrCodeIdempotentParameterMismatchException = "IdempotentParameterMismatchException" + + // ErrCodeIndexNotFoundException for service response error code + // "IndexNotFoundException". + // + // The operation tried to access a nonexistent index. + ErrCodeIndexNotFoundException = "IndexNotFoundException" + + // ErrCodeInternalServerError for service response error code + // "InternalServerError". + // + // An error occurred on the server side. + ErrCodeInternalServerError = "InternalServerError" + + // ErrCodeInvalidExportTimeException for service response error code + // "InvalidExportTimeException". + // + // The specified ExportTime is outside of the point in time recovery window. + ErrCodeInvalidExportTimeException = "InvalidExportTimeException" + + // ErrCodeInvalidRestoreTimeException for service response error code + // "InvalidRestoreTimeException". + // + // An invalid restore time was specified. RestoreDateTime must be between EarliestRestorableDateTime + // and LatestRestorableDateTime. + ErrCodeInvalidRestoreTimeException = "InvalidRestoreTimeException" + + // ErrCodeItemCollectionSizeLimitExceededException for service response error code + // "ItemCollectionSizeLimitExceededException". + // + // An item collection is too large. This exception is only returned for tables + // that have one or more local secondary indexes. + ErrCodeItemCollectionSizeLimitExceededException = "ItemCollectionSizeLimitExceededException" + + // ErrCodeLimitExceededException for service response error code + // "LimitExceededException". + // + // There is no limit to the number of daily on-demand backups that can be taken. + // + // Up to 50 simultaneous table operations are allowed per account. These operations + // include CreateTable, UpdateTable, DeleteTable,UpdateTimeToLive, RestoreTableFromBackup, + // and RestoreTableToPointInTime. + // + // The only exception is when you are creating a table with one or more secondary + // indexes. You can have up to 25 such requests running at a time; however, + // if the table or index specifications are complex, DynamoDB might temporarily + // reduce the number of concurrent operations. + // + // There is a soft account quota of 256 tables. + ErrCodeLimitExceededException = "LimitExceededException" + + // ErrCodePointInTimeRecoveryUnavailableException for service response error code + // "PointInTimeRecoveryUnavailableException". + // + // Point in time recovery has not yet been enabled for this source table. + ErrCodePointInTimeRecoveryUnavailableException = "PointInTimeRecoveryUnavailableException" + + // ErrCodeProvisionedThroughputExceededException for service response error code + // "ProvisionedThroughputExceededException". + // + // Your request rate is too high. The Amazon Web Services SDKs for DynamoDB + // automatically retry requests that receive this exception. Your request is + // eventually successful, unless your retry queue is too large to finish. Reduce + // the frequency of requests and use exponential backoff. For more information, + // go to Error Retries and Exponential Backoff (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.Errors.html#Programming.Errors.RetryAndBackoff) + // in the Amazon DynamoDB Developer Guide. + ErrCodeProvisionedThroughputExceededException = "ProvisionedThroughputExceededException" + + // ErrCodeReplicaAlreadyExistsException for service response error code + // "ReplicaAlreadyExistsException". + // + // The specified replica is already part of the global table. + ErrCodeReplicaAlreadyExistsException = "ReplicaAlreadyExistsException" + + // ErrCodeReplicaNotFoundException for service response error code + // "ReplicaNotFoundException". + // + // The specified replica is no longer part of the global table. + ErrCodeReplicaNotFoundException = "ReplicaNotFoundException" + + // ErrCodeRequestLimitExceeded for service response error code + // "RequestLimitExceeded". + // + // Throughput exceeds the current throughput quota for your account. Please + // contact Amazon Web Services Support (https://aws.amazon.com/support) to request + // a quota increase. + ErrCodeRequestLimitExceeded = "RequestLimitExceeded" + + // ErrCodeResourceInUseException for service response error code + // "ResourceInUseException". + // + // The operation conflicts with the resource's availability. For example, you + // attempted to recreate an existing table, or tried to delete a table currently + // in the CREATING state. + ErrCodeResourceInUseException = "ResourceInUseException" + + // ErrCodeResourceNotFoundException for service response error code + // "ResourceNotFoundException". + // + // The operation tried to access a nonexistent table or index. The resource + // might not be specified correctly, or its status might not be ACTIVE. + ErrCodeResourceNotFoundException = "ResourceNotFoundException" + + // ErrCodeTableAlreadyExistsException for service response error code + // "TableAlreadyExistsException". + // + // A target table with the specified name already exists. + ErrCodeTableAlreadyExistsException = "TableAlreadyExistsException" + + // ErrCodeTableInUseException for service response error code + // "TableInUseException". + // + // A target table with the specified name is either being created or deleted. + ErrCodeTableInUseException = "TableInUseException" + + // ErrCodeTableNotFoundException for service response error code + // "TableNotFoundException". + // + // A source table with the name TableName does not currently exist within the + // subscriber's account. + ErrCodeTableNotFoundException = "TableNotFoundException" + + // ErrCodeTransactionCanceledException for service response error code + // "TransactionCanceledException". + // + // The entire transaction request was canceled. + // + // DynamoDB cancels a TransactWriteItems request under the following circumstances: + // + // * A condition in one of the condition expressions is not met. + // + // * A table in the TransactWriteItems request is in a different account + // or region. + // + // * More than one action in the TransactWriteItems operation targets the + // same item. + // + // * There is insufficient provisioned capacity for the transaction to be + // completed. + // + // * An item size becomes too large (larger than 400 KB), or a local secondary + // index (LSI) becomes too large, or a similar validation error occurs because + // of changes made by the transaction. + // + // * There is a user error, such as an invalid data format. + // + // DynamoDB cancels a TransactGetItems request under the following circumstances: + // + // * There is an ongoing TransactGetItems operation that conflicts with a + // concurrent PutItem, UpdateItem, DeleteItem or TransactWriteItems request. + // In this case the TransactGetItems operation fails with a TransactionCanceledException. + // + // * A table in the TransactGetItems request is in a different account or + // region. + // + // * There is insufficient provisioned capacity for the transaction to be + // completed. + // + // * There is a user error, such as an invalid data format. + // + // If using Java, DynamoDB lists the cancellation reasons on the CancellationReasons + // property. This property is not set for other languages. Transaction cancellation + // reasons are ordered in the order of requested items, if an item has no error + // it will have NONE code and Null message. + // + // Cancellation reason codes and possible error messages: + // + // * No Errors: Code: NONE Message: null + // + // * Conditional Check Failed: Code: ConditionalCheckFailed Message: The + // conditional request failed. + // + // * Item Collection Size Limit Exceeded: Code: ItemCollectionSizeLimitExceeded + // Message: Collection size exceeded. + // + // * Transaction Conflict: Code: TransactionConflict Message: Transaction + // is ongoing for the item. + // + // * Provisioned Throughput Exceeded: Code: ProvisionedThroughputExceeded + // Messages: The level of configured provisioned throughput for the table + // was exceeded. Consider increasing your provisioning level with the UpdateTable + // API. This Message is received when provisioned throughput is exceeded + // is on a provisioned DynamoDB table. The level of configured provisioned + // throughput for one or more global secondary indexes of the table was exceeded. + // Consider increasing your provisioning level for the under-provisioned + // global secondary indexes with the UpdateTable API. This message is returned + // when provisioned throughput is exceeded is on a provisioned GSI. + // + // * Throttling Error: Code: ThrottlingError Messages: Throughput exceeds + // the current capacity of your table or index. DynamoDB is automatically + // scaling your table or index so please try again shortly. If exceptions + // persist, check if you have a hot key: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-partition-key-design.html. + // This message is returned when writes get throttled on an On-Demand table + // as DynamoDB is automatically scaling the table. Throughput exceeds the + // current capacity for one or more global secondary indexes. DynamoDB is + // automatically scaling your index so please try again shortly. This message + // is returned when when writes get throttled on an On-Demand GSI as DynamoDB + // is automatically scaling the GSI. + // + // * Validation Error: Code: ValidationError Messages: One or more parameter + // values were invalid. The update expression attempted to update the secondary + // index key beyond allowed size limits. The update expression attempted + // to update the secondary index key to unsupported type. An operand in the + // update expression has an incorrect data type. Item size to update has + // exceeded the maximum allowed size. Number overflow. Attempting to store + // a number with magnitude larger than supported range. Type mismatch for + // attribute to update. Nesting Levels have exceeded supported limits. The + // document path provided in the update expression is invalid for update. + // The provided expression refers to an attribute that does not exist in + // the item. + ErrCodeTransactionCanceledException = "TransactionCanceledException" + + // ErrCodeTransactionConflictException for service response error code + // "TransactionConflictException". + // + // Operation was rejected because there is an ongoing transaction for the item. + ErrCodeTransactionConflictException = "TransactionConflictException" + + // ErrCodeTransactionInProgressException for service response error code + // "TransactionInProgressException". + // + // The transaction with the given request token is already in progress. + ErrCodeTransactionInProgressException = "TransactionInProgressException" +) + +var exceptionFromCode = map[string]func(protocol.ResponseMetadata) error{ + "BackupInUseException": newErrorBackupInUseException, + "BackupNotFoundException": newErrorBackupNotFoundException, + "ConditionalCheckFailedException": newErrorConditionalCheckFailedException, + "ContinuousBackupsUnavailableException": newErrorContinuousBackupsUnavailableException, + "DuplicateItemException": newErrorDuplicateItemException, + "ExportConflictException": newErrorExportConflictException, + "ExportNotFoundException": newErrorExportNotFoundException, + "GlobalTableAlreadyExistsException": newErrorGlobalTableAlreadyExistsException, + "GlobalTableNotFoundException": newErrorGlobalTableNotFoundException, + "IdempotentParameterMismatchException": newErrorIdempotentParameterMismatchException, + "IndexNotFoundException": newErrorIndexNotFoundException, + "InternalServerError": newErrorInternalServerError, + "InvalidExportTimeException": newErrorInvalidExportTimeException, + "InvalidRestoreTimeException": newErrorInvalidRestoreTimeException, + "ItemCollectionSizeLimitExceededException": newErrorItemCollectionSizeLimitExceededException, + "LimitExceededException": newErrorLimitExceededException, + "PointInTimeRecoveryUnavailableException": newErrorPointInTimeRecoveryUnavailableException, + "ProvisionedThroughputExceededException": newErrorProvisionedThroughputExceededException, + "ReplicaAlreadyExistsException": newErrorReplicaAlreadyExistsException, + "ReplicaNotFoundException": newErrorReplicaNotFoundException, + "RequestLimitExceeded": newErrorRequestLimitExceeded, + "ResourceInUseException": newErrorResourceInUseException, + "ResourceNotFoundException": newErrorResourceNotFoundException, + "TableAlreadyExistsException": newErrorTableAlreadyExistsException, + "TableInUseException": newErrorTableInUseException, + "TableNotFoundException": newErrorTableNotFoundException, + "TransactionCanceledException": newErrorTransactionCanceledException, + "TransactionConflictException": newErrorTransactionConflictException, + "TransactionInProgressException": newErrorTransactionInProgressException, +} diff --git a/vendor/github.com/aws/aws-sdk-go/service/dynamodb/service.go b/vendor/github.com/aws/aws-sdk-go/service/dynamodb/service.go new file mode 100644 index 0000000..f879ed5 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/dynamodb/service.go @@ -0,0 +1,107 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package dynamodb + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/client/metadata" + "github.com/aws/aws-sdk-go/aws/crr" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/aws/signer/v4" + "github.com/aws/aws-sdk-go/private/protocol" + "github.com/aws/aws-sdk-go/private/protocol/jsonrpc" +) + +// DynamoDB provides the API operation methods for making requests to +// Amazon DynamoDB. See this package's package overview docs +// for details on the service. +// +// DynamoDB methods are safe to use concurrently. It is not safe to +// modify mutate any of the struct's properties though. +type DynamoDB struct { + *client.Client + endpointCache *crr.EndpointCache +} + +// Used for custom client initialization logic +var initClient func(*client.Client) + +// Used for custom request initialization logic +var initRequest func(*request.Request) + +// Service information constants +const ( + ServiceName = "dynamodb" // Name of service. + EndpointsID = ServiceName // ID to lookup a service endpoint with. + ServiceID = "DynamoDB" // ServiceID is a unique identifier of a specific service. +) + +// New creates a new instance of the DynamoDB client with a session. +// If additional configuration is needed for the client instance use the optional +// aws.Config parameter to add your extra config. +// +// Example: +// mySession := session.Must(session.NewSession()) +// +// // Create a DynamoDB client from just a session. +// svc := dynamodb.New(mySession) +// +// // Create a DynamoDB client with additional configuration +// svc := dynamodb.New(mySession, aws.NewConfig().WithRegion("us-west-2")) +func New(p client.ConfigProvider, cfgs ...*aws.Config) *DynamoDB { + c := p.ClientConfig(EndpointsID, cfgs...) + return newClient(*c.Config, c.Handlers, c.PartitionID, c.Endpoint, c.SigningRegion, c.SigningName, c.ResolvedRegion) +} + +// newClient creates, initializes and returns a new service client instance. +func newClient(cfg aws.Config, handlers request.Handlers, partitionID, endpoint, signingRegion, signingName, resolvedRegion string) *DynamoDB { + svc := &DynamoDB{ + Client: client.New( + cfg, + metadata.ClientInfo{ + ServiceName: ServiceName, + ServiceID: ServiceID, + SigningName: signingName, + SigningRegion: signingRegion, + PartitionID: partitionID, + Endpoint: endpoint, + APIVersion: "2012-08-10", + ResolvedRegion: resolvedRegion, + JSONVersion: "1.0", + TargetPrefix: "DynamoDB_20120810", + }, + handlers, + ), + } + svc.endpointCache = crr.NewEndpointCache(10) + + // Handlers + svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler) + svc.Handlers.Build.PushBackNamed(jsonrpc.BuildHandler) + svc.Handlers.Unmarshal.PushBackNamed(jsonrpc.UnmarshalHandler) + svc.Handlers.UnmarshalMeta.PushBackNamed(jsonrpc.UnmarshalMetaHandler) + svc.Handlers.UnmarshalError.PushBackNamed( + protocol.NewUnmarshalErrorHandler(jsonrpc.NewUnmarshalTypedError(exceptionFromCode)).NamedHandler(), + ) + + // Run custom client initialization if present + if initClient != nil { + initClient(svc.Client) + } + + return svc +} + +// newRequest creates a new request for a DynamoDB operation and runs any +// custom request initialization. +func (c *DynamoDB) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) + + // Run custom request initialization if present + if initRequest != nil { + initRequest(req) + } + + return req +} diff --git a/vendor/github.com/aws/aws-sdk-go/service/dynamodb/waiters.go b/vendor/github.com/aws/aws-sdk-go/service/dynamodb/waiters.go new file mode 100644 index 0000000..ae515f7 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/dynamodb/waiters.go @@ -0,0 +1,107 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package dynamodb + +import ( + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/request" +) + +// WaitUntilTableExists uses the DynamoDB API operation +// DescribeTable to wait for a condition to be met before returning. +// If the condition is not met within the max attempt window, an error will +// be returned. +func (c *DynamoDB) WaitUntilTableExists(input *DescribeTableInput) error { + return c.WaitUntilTableExistsWithContext(aws.BackgroundContext(), input) +} + +// WaitUntilTableExistsWithContext is an extended version of WaitUntilTableExists. +// With the support for passing in a context and options to configure the +// Waiter and the underlying request options. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) WaitUntilTableExistsWithContext(ctx aws.Context, input *DescribeTableInput, opts ...request.WaiterOption) error { + w := request.Waiter{ + Name: "WaitUntilTableExists", + MaxAttempts: 25, + Delay: request.ConstantWaiterDelay(20 * time.Second), + Acceptors: []request.WaiterAcceptor{ + { + State: request.SuccessWaiterState, + Matcher: request.PathWaiterMatch, Argument: "Table.TableStatus", + Expected: "ACTIVE", + }, + { + State: request.RetryWaiterState, + Matcher: request.ErrorWaiterMatch, + Expected: "ResourceNotFoundException", + }, + }, + Logger: c.Config.Logger, + NewRequest: func(opts []request.Option) (*request.Request, error) { + var inCpy *DescribeTableInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.DescribeTableRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + w.ApplyOptions(opts...) + + return w.WaitWithContext(ctx) +} + +// WaitUntilTableNotExists uses the DynamoDB API operation +// DescribeTable to wait for a condition to be met before returning. +// If the condition is not met within the max attempt window, an error will +// be returned. +func (c *DynamoDB) WaitUntilTableNotExists(input *DescribeTableInput) error { + return c.WaitUntilTableNotExistsWithContext(aws.BackgroundContext(), input) +} + +// WaitUntilTableNotExistsWithContext is an extended version of WaitUntilTableNotExists. +// With the support for passing in a context and options to configure the +// Waiter and the underlying request options. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *DynamoDB) WaitUntilTableNotExistsWithContext(ctx aws.Context, input *DescribeTableInput, opts ...request.WaiterOption) error { + w := request.Waiter{ + Name: "WaitUntilTableNotExists", + MaxAttempts: 25, + Delay: request.ConstantWaiterDelay(20 * time.Second), + Acceptors: []request.WaiterAcceptor{ + { + State: request.SuccessWaiterState, + Matcher: request.ErrorWaiterMatch, + Expected: "ResourceNotFoundException", + }, + }, + Logger: c.Config.Logger, + NewRequest: func(opts []request.Option) (*request.Request, error) { + var inCpy *DescribeTableInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.DescribeTableRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + w.ApplyOptions(opts...) + + return w.WaitWithContext(ctx) +} diff --git a/vendor/github.com/benbjohnson/clock/LICENSE b/vendor/github.com/benbjohnson/clock/LICENSE new file mode 100644 index 0000000..ce212cb --- /dev/null +++ b/vendor/github.com/benbjohnson/clock/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Ben Johnson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/benbjohnson/clock/README.md b/vendor/github.com/benbjohnson/clock/README.md new file mode 100644 index 0000000..ee37dfe --- /dev/null +++ b/vendor/github.com/benbjohnson/clock/README.md @@ -0,0 +1,104 @@ +clock +===== + +Clock is a small library for mocking time in Go. It provides an interface +around the standard library's [`time`][time] package so that the application +can use the realtime clock while tests can use the mock clock. + +[time]: http://golang.org/pkg/time/ + + +## Usage + +### Realtime Clock + +Your application can maintain a `Clock` variable that will allow realtime and +mock clocks to be interchangeable. For example, if you had an `Application` type: + +```go +import "github.com/benbjohnson/clock" + +type Application struct { + Clock clock.Clock +} +``` + +You could initialize it to use the realtime clock like this: + +```go +var app Application +app.Clock = clock.New() +... +``` + +Then all timers and time-related functionality should be performed from the +`Clock` variable. + + +### Mocking time + +In your tests, you will want to use a `Mock` clock: + +```go +import ( + "testing" + + "github.com/benbjohnson/clock" +) + +func TestApplication_DoSomething(t *testing.T) { + mock := clock.NewMock() + app := Application{Clock: mock} + ... +} +``` + +Now that you've initialized your application to use the mock clock, you can +adjust the time programmatically. The mock clock always starts from the Unix +epoch (midnight UTC on Jan 1, 1970). + + +### Controlling time + +The mock clock provides the same functions that the standard library's `time` +package provides. For example, to find the current time, you use the `Now()` +function: + +```go +mock := clock.NewMock() + +// Find the current time. +mock.Now().UTC() // 1970-01-01 00:00:00 +0000 UTC + +// Move the clock forward. +mock.Add(2 * time.Hour) + +// Check the time again. It's 2 hours later! +mock.Now().UTC() // 1970-01-01 02:00:00 +0000 UTC +``` + +Timers and Tickers are also controlled by this same mock clock. They will only +execute when the clock is moved forward: + +```go +mock := clock.NewMock() +count := 0 + +// Kick off a timer to increment every 1 mock second. +go func() { + ticker := clock.Ticker(1 * time.Second) + for { + <-ticker.C + count++ + } +}() +runtime.Gosched() + +// Move the clock forward 10 seconds. +mock.Add(10 * time.Second) + +// This prints 10. +fmt.Println(count) +``` + + diff --git a/vendor/github.com/benbjohnson/clock/clock.go b/vendor/github.com/benbjohnson/clock/clock.go new file mode 100644 index 0000000..6a4edb2 --- /dev/null +++ b/vendor/github.com/benbjohnson/clock/clock.go @@ -0,0 +1,340 @@ +package clock + +import ( + "sort" + "sync" + "time" +) + +// Clock represents an interface to the functions in the standard library time +// package. Two implementations are available in the clock package. The first +// is a real-time clock which simply wraps the time package's functions. The +// second is a mock clock which will only change when +// programmatically adjusted. +type Clock interface { + After(d time.Duration) <-chan time.Time + AfterFunc(d time.Duration, f func()) *Timer + Now() time.Time + Since(t time.Time) time.Duration + Sleep(d time.Duration) + Tick(d time.Duration) <-chan time.Time + Ticker(d time.Duration) *Ticker + Timer(d time.Duration) *Timer +} + +// New returns an instance of a real-time clock. +func New() Clock { + return &clock{} +} + +// clock implements a real-time clock by simply wrapping the time package functions. +type clock struct{} + +func (c *clock) After(d time.Duration) <-chan time.Time { return time.After(d) } + +func (c *clock) AfterFunc(d time.Duration, f func()) *Timer { + return &Timer{timer: time.AfterFunc(d, f)} +} + +func (c *clock) Now() time.Time { return time.Now() } + +func (c *clock) Since(t time.Time) time.Duration { return time.Since(t) } + +func (c *clock) Sleep(d time.Duration) { time.Sleep(d) } + +func (c *clock) Tick(d time.Duration) <-chan time.Time { return time.Tick(d) } + +func (c *clock) Ticker(d time.Duration) *Ticker { + t := time.NewTicker(d) + return &Ticker{C: t.C, ticker: t} +} + +func (c *clock) Timer(d time.Duration) *Timer { + t := time.NewTimer(d) + return &Timer{C: t.C, timer: t} +} + +// Mock represents a mock clock that only moves forward programmatically. +// It can be preferable to a real-time clock when testing time-based functionality. +type Mock struct { + mu sync.Mutex + now time.Time // current time + timers clockTimers // tickers & timers +} + +// NewMock returns an instance of a mock clock. +// The current time of the mock clock on initialization is the Unix epoch. +func NewMock() *Mock { + return &Mock{now: time.Unix(0, 0)} +} + +// Add moves the current time of the mock clock forward by the specified duration. +// This should only be called from a single goroutine at a time. +func (m *Mock) Add(d time.Duration) { + // Calculate the final current time. + t := m.now.Add(d) + + // Continue to execute timers until there are no more before the new time. + for { + if !m.runNextTimer(t) { + break + } + } + + // Ensure that we end with the new time. + m.mu.Lock() + m.now = t + m.mu.Unlock() + + // Give a small buffer to make sure that other goroutines get handled. + gosched() +} + +// Set sets the current time of the mock clock to a specific one. +// This should only be called from a single goroutine at a time. +func (m *Mock) Set(t time.Time) { + // Continue to execute timers until there are no more before the new time. + for { + if !m.runNextTimer(t) { + break + } + } + + // Ensure that we end with the new time. + m.mu.Lock() + m.now = t + m.mu.Unlock() + + // Give a small buffer to make sure that other goroutines get handled. + gosched() +} + +// runNextTimer executes the next timer in chronological order and moves the +// current time to the timer's next tick time. The next time is not executed if +// its next time is after the max time. Returns true if a timer was executed. +func (m *Mock) runNextTimer(max time.Time) bool { + m.mu.Lock() + + // Sort timers by time. + sort.Sort(m.timers) + + // If we have no more timers then exit. + if len(m.timers) == 0 { + m.mu.Unlock() + return false + } + + // Retrieve next timer. Exit if next tick is after new time. + t := m.timers[0] + if t.Next().After(max) { + m.mu.Unlock() + return false + } + + // Move "now" forward and unlock clock. + m.now = t.Next() + m.mu.Unlock() + + // Execute timer. + t.Tick(m.now) + return true +} + +// After waits for the duration to elapse and then sends the current time on the returned channel. +func (m *Mock) After(d time.Duration) <-chan time.Time { + return m.Timer(d).C +} + +// AfterFunc waits for the duration to elapse and then executes a function. +// A Timer is returned that can be stopped. +func (m *Mock) AfterFunc(d time.Duration, f func()) *Timer { + t := m.Timer(d) + t.C = nil + t.fn = f + return t +} + +// Now returns the current wall time on the mock clock. +func (m *Mock) Now() time.Time { + m.mu.Lock() + defer m.mu.Unlock() + return m.now +} + +// Since returns time since the mock clock's wall time. +func (m *Mock) Since(t time.Time) time.Duration { + return m.Now().Sub(t) +} + +// Sleep pauses the goroutine for the given duration on the mock clock. +// The clock must be moved forward in a separate goroutine. +func (m *Mock) Sleep(d time.Duration) { + <-m.After(d) +} + +// Tick is a convenience function for Ticker(). +// It will return a ticker channel that cannot be stopped. +func (m *Mock) Tick(d time.Duration) <-chan time.Time { + return m.Ticker(d).C +} + +// Ticker creates a new instance of Ticker. +func (m *Mock) Ticker(d time.Duration) *Ticker { + m.mu.Lock() + defer m.mu.Unlock() + ch := make(chan time.Time, 1) + t := &Ticker{ + C: ch, + c: ch, + mock: m, + d: d, + next: m.now.Add(d), + } + m.timers = append(m.timers, (*internalTicker)(t)) + return t +} + +// Timer creates a new instance of Timer. +func (m *Mock) Timer(d time.Duration) *Timer { + m.mu.Lock() + defer m.mu.Unlock() + ch := make(chan time.Time, 1) + t := &Timer{ + C: ch, + c: ch, + mock: m, + next: m.now.Add(d), + stopped: false, + } + m.timers = append(m.timers, (*internalTimer)(t)) + return t +} + +func (m *Mock) removeClockTimer(t clockTimer) { + for i, timer := range m.timers { + if timer == t { + copy(m.timers[i:], m.timers[i+1:]) + m.timers[len(m.timers)-1] = nil + m.timers = m.timers[:len(m.timers)-1] + break + } + } + sort.Sort(m.timers) +} + +// clockTimer represents an object with an associated start time. +type clockTimer interface { + Next() time.Time + Tick(time.Time) +} + +// clockTimers represents a list of sortable timers. +type clockTimers []clockTimer + +func (a clockTimers) Len() int { return len(a) } +func (a clockTimers) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a clockTimers) Less(i, j int) bool { return a[i].Next().Before(a[j].Next()) } + +// Timer represents a single event. +// The current time will be sent on C, unless the timer was created by AfterFunc. +type Timer struct { + C <-chan time.Time + c chan time.Time + timer *time.Timer // realtime impl, if set + next time.Time // next tick time + mock *Mock // mock clock, if set + fn func() // AfterFunc function, if set + stopped bool // True if stopped, false if running +} + +// Stop turns off the ticker. +func (t *Timer) Stop() bool { + if t.timer != nil { + return t.timer.Stop() + } + + t.mock.mu.Lock() + registered := !t.stopped + t.mock.removeClockTimer((*internalTimer)(t)) + t.stopped = true + t.mock.mu.Unlock() + return registered +} + +// Reset changes the expiry time of the timer +func (t *Timer) Reset(d time.Duration) bool { + if t.timer != nil { + return t.timer.Reset(d) + } + + t.mock.mu.Lock() + t.next = t.mock.now.Add(d) + defer t.mock.mu.Unlock() + + registered := !t.stopped + if t.stopped { + t.mock.timers = append(t.mock.timers, (*internalTimer)(t)) + } + + t.stopped = false + return registered +} + +type internalTimer Timer + +func (t *internalTimer) Next() time.Time { return t.next } +func (t *internalTimer) Tick(now time.Time) { + t.mock.mu.Lock() + if t.fn != nil { + t.fn() + } else { + t.c <- now + } + t.mock.removeClockTimer((*internalTimer)(t)) + t.stopped = true + t.mock.mu.Unlock() + gosched() +} + +// Ticker holds a channel that receives "ticks" at regular intervals. +type Ticker struct { + C <-chan time.Time + c chan time.Time + ticker *time.Ticker // realtime impl, if set + next time.Time // next tick time + mock *Mock // mock clock, if set + d time.Duration // time between ticks +} + +// Stop turns off the ticker. +func (t *Ticker) Stop() { + if t.ticker != nil { + t.ticker.Stop() + } else { + t.mock.mu.Lock() + t.mock.removeClockTimer((*internalTicker)(t)) + t.mock.mu.Unlock() + } +} + +// Reset resets the ticker to a new duration. +func (t *Ticker) Reset(dur time.Duration) { + if t.ticker != nil { + t.ticker.Reset(dur) + } +} + +type internalTicker Ticker + +func (t *internalTicker) Next() time.Time { return t.next } +func (t *internalTicker) Tick(now time.Time) { + select { + case t.c <- now: + default: + } + t.next = now.Add(t.d) + gosched() +} + +// Sleep momentarily so that other goroutines can process. +func gosched() { time.Sleep(1 * time.Millisecond) } diff --git a/vendor/github.com/benbjohnson/clock/go.mod b/vendor/github.com/benbjohnson/clock/go.mod new file mode 100644 index 0000000..758903a --- /dev/null +++ b/vendor/github.com/benbjohnson/clock/go.mod @@ -0,0 +1,3 @@ +module github.com/benbjohnson/clock + +go 1.15 diff --git a/vendor/github.com/bnkamalesh/webgo/v4/.gitignore b/vendor/github.com/bnkamalesh/webgo/v4/.gitignore new file mode 100644 index 0000000..364bf73 --- /dev/null +++ b/vendor/github.com/bnkamalesh/webgo/v4/.gitignore @@ -0,0 +1,87 @@ +# Created by https://www.gitignore.io/api/go,osx,linux,windows + +### Go ### +# Binaries for programs and plugins +*.exe +*.dll +*.so +*.dylib + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 +.glide/ + +# Golang project vendor packages which should be ignored +vendor/ + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### OSX ### +*.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# End of https://www.gitignore.io/api/go,osx,linux,windows + +.vscode \ No newline at end of file diff --git a/vendor/github.com/bnkamalesh/webgo/v4/.travis.yml b/vendor/github.com/bnkamalesh/webgo/v4/.travis.yml new file mode 100644 index 0000000..804d33f --- /dev/null +++ b/vendor/github.com/bnkamalesh/webgo/v4/.travis.yml @@ -0,0 +1,18 @@ +language: go +go: + # webgo is still compatible with 1.8, but the tests are importing versioned + # modules which fails for older Go versions. + # - "1.8" + - "1.11" + - master + +before_install: + - go get -t -v ./... + +script: + # go.mod is overwritten to avoid go version being part of the mod file, which fails tests on mismatching version + - echo "module github.com/bnkamalesh/webgo/v4" > go.mod + - go test -coverprofile=coverage.txt -covermode=atomic $(go list ./... | grep -v /cmd) + +after_success: + - bash <(curl -s https://codecov.io/bash) \ No newline at end of file diff --git a/vendor/github.com/bnkamalesh/webgo/v4/CODE_OF_CONDUCT.md b/vendor/github.com/bnkamalesh/webgo/v4/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..b7a06a5 --- /dev/null +++ b/vendor/github.com/bnkamalesh/webgo/v4/CODE_OF_CONDUCT.md @@ -0,0 +1,46 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at bn_kamalesh@yahoo.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff --git a/vendor/github.com/bnkamalesh/webgo/v4/CONTRIBUTING.md b/vendor/github.com/bnkamalesh/webgo/v4/CONTRIBUTING.md new file mode 100644 index 0000000..797b0fa --- /dev/null +++ b/vendor/github.com/bnkamalesh/webgo/v4/CONTRIBUTING.md @@ -0,0 +1,24 @@ +Contributions are welcome from everyone. Please adhere to the [code of conduct](https://github.com/bnkamalesh/webgo/blob/master/CODE_OF_CONDUCT.md) of the project, and be respectful to all. + +Please follow the guidelines provided for contribution + +1. Updates to the project are only accepted via Pull Requests (PR) +2. Pull requests will be reviewed & tested +3. Every PR should be accompanied by its test wherever applicable +4. While creating an issue + 1. Mention the steps to reproduce the issue + 2. Mention the environment in which it was run + 3. Include your 1st level of troubleshooting results +5. Provide meaningful commit messages + + +### Versioning & PR messages + +WebGo tries to use [semantic versioning](https://semver.org/) and starting recently, have decided to adhere to the following syntax in PR description. List down the changes as bulleted list, as follows: + +```markdown +[major] any backward incompatible or breaking change +[minor] any new feature +[patch] enhancements of existing features, refactor, bug fix etc. +[-] for changes which does not require a version number update +``` diff --git a/vendor/github.com/bnkamalesh/webgo/v4/LICENSE b/vendor/github.com/bnkamalesh/webgo/v4/LICENSE new file mode 100644 index 0000000..680becd --- /dev/null +++ b/vendor/github.com/bnkamalesh/webgo/v4/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 Kamaleshwar + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/vendor/github.com/bnkamalesh/webgo/v4/README.md b/vendor/github.com/bnkamalesh/webgo/v4/README.md new file mode 100644 index 0000000..927d196 --- /dev/null +++ b/vendor/github.com/bnkamalesh/webgo/v4/README.md @@ -0,0 +1,363 @@ +

webgo gopher

+ +[![](https://travis-ci.org/bnkamalesh/webgo.svg?branch=master)](https://travis-ci.org/bnkamalesh/webgo) +[![coverage](https://img.shields.io/codecov/c/github/bnkamalesh/webgo.svg)](https://codecov.io/gh/bnkamalesh/webgo) +[![](https://goreportcard.com/badge/github.com/bnkamalesh/webgo)](https://goreportcard.com/report/github.com/bnkamalesh/webgo) +[![](https://api.codeclimate.com/v1/badges/85b3a55c3fa6b4c5338d/maintainability)](https://codeclimate.com/github/bnkamalesh/webgo/maintainability) +[![](https://godoc.org/github.com/nathany/looper?status.svg)](http://godoc.org/github.com/bnkamalesh/webgo) +[![](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go#web-frameworks) + +# WebGo v4.1.11 + +WebGo is a minimalistic framework for [Go](https://golang.org) to build web applications (server side) with zero 3rd party dependencies. WebGo will always be Go standard library compliant; with the HTTP handlers having the same signature as [http.HandlerFunc](https://golang.org/pkg/net/http/#HandlerFunc). + +### Index + +1. [Router](https://github.com/bnkamalesh/webgo#router) +2. [Handler chaining](https://github.com/bnkamalesh/webgo#handler-chaining) +3. [Middleware](https://github.com/bnkamalesh/webgo#middleware) +4. [Helper functions](https://github.com/bnkamalesh/webgo#helper-functions) +5. [HTTPS ready](https://github.com/bnkamalesh/webgo#https-ready) +6. [Graceful shutdown](https://github.com/bnkamalesh/webgo#graceful-shutdown) +7. [Logging](https://github.com/bnkamalesh/webgo#logging) +8. [Usage](https://github.com/bnkamalesh/webgo#usage) + + +## Router + +Router routes multiple paths/[URI](https://developer.mozilla.org/en-US/docs/Glossary/URI)s to its respective HTTP handler. It supports defining URIs with the following patterns + +1. `/api/users` + - Static URI pattern with no variables +2. `/api/users/:userID` + - URI pattern with named variable `userID` (named URI parameter) + - This will **_not_** match `/api/users/johndoe/account`. It only matches till `/api/users/johndoe/` + - If TrailingSlash is set to true, refer to [sample](https://github.com/bnkamalesh/webgo#sample) +3. `/api/users/:misc*` + - Named URI variable `misc` + - This matches everything after `/api/users`. e.g. `/api/users/a/b/c/d` + +If multiple patterns match the same URI, the first matching handler would be executed. Refer to the [sample](https://github.com/bnkamalesh/webgo#sample) to see how routes are configured. A WebGo [Route](https://godoc.org/github.com/bnkamalesh/webgo#Route) is defined as following: + +```golang +webgo.Route{ + // A name for the API (preferrably unique) + Name string + // HTTP verb, i.e. GET, POST, PUT, PATCH, HEAD, DELETE + Method string + // The URI pattern + Pattern string + // If the URI ends with a '/', should it be considered valid or not? e.g. '/api/users' vs '/api/users/' + TrailingSlash bool + // In case of chained handlers, should the execution continue after one of the handlers have + // responded to the HTTP request + FallThroughPostResponse bool + // The list of HTTP handlers + Handlers []http.HandlerFunc +} +``` + +You can access named parameters of the URI using the `Context` function. Note: webgo Context is **not** available inside special handlers, since it serves no purpose + +```golang +func helloWorld(w http.ResponseWriter, r *http.Request) { + // WebGo context + wctx := webgo.Context(r) + // URI paramaters, map[string]string + params := wctx.Params() + // route, the webgo.Route which is executing this request + route := wctx.Route + webgo.R200( + w, + fmt.Sprintf( + "Route name: '%s', params: '%s'", + route.Name, + params, + ), + ) +} +``` + +## Handler chaining + +Handler chaining lets you execute multiple handlers for a given route. Execution of a chain can be configured to run even after a handler has written a response to the HTTP request. This is made possible by setting `FallThroughPostResponse` to `true` (refer [sample](https://github.com/bnkamalesh/webgo#sample)). + +```golang +webgo.Route{ + Name: "chained", + Method: http.MethodGet, + Pattern: "/api", + TrailingSlash: false, + FallThroughPostResponse: true, + Handlers []http.HandlerFunc{ + handler1, + handler2, + . + . + . + } +} +``` + +## Middleware + +WebGo [middlware](https://godoc.org/github.com/bnkamalesh/webgo#Middleware) lets you wrap all the routes with a middleware unlike handler chaining. The router exposes a method [Use](https://godoc.org/github.com/bnkamalesh/webgo#Router.Use) && [UseOnSpecialHandlers](https://godoc.org/github.com/bnkamalesh/webgo#Router.UseOnSpecialHandlers) to add a Middleware to the router. Following code shows how a middleware can be used. + +NotFound && NotImplemented are the handlers which are considered `Special` handlers. `webgo.Context(r)` within special handlers will return `nil`. + +```golang +import ( + "github.com/bnkamalesh/webgo/v4" + "github.com/bnkamalesh/webgo/v4/middleware" +) + +func routes() []*webgo.Route { + return []*webgo.Route{ + &webo.Route{ + Name: "home", + Method: http.http.MethodGet, + Pattern: "/", + Handlers: []http.HandlerFunc{ + func(w http.ResponseWriter, r *http.Request) { + webgo.R200(w, "home") + } + }, + }, + } +} + +func main() { + router := webgo.NewRouter(*webgo.Config{ + Host: "", + Port: "8080", + ReadTimeout: 15 * time.Second, + WriteTimeout: 60 * time.Second, + }, routes()) + + router.UseOnSpecialHandlers(middleware.AccessLog) + + router.Use(middleware.AccessLog) + + router.Start() +} + +``` + +Any number of middleware can be added to the router, the order of execution of middleware would be [LIFO](https://en.wikipedia.org/wiki/Stack_(abstract_data_type)) (Last In First Out). i.e. in case of the following code + +```golang +func main() { + router.Use(middleware.AccessLog) + router.Use(middleware.CorsWrap()) +} +``` + +**_CorsWrap_** would be executed first, followed by **_AccessLog_**. + +## Helper functions + +WebGo provides a few helper functions. + +1. [ResponseStatus(w http.ResponseWriter)](https://godoc.org/github.com/bnkamalesh/webgo#ResponseStatus) get the HTTP status code from response writer +2. [SendHeader(w http.ResponseWriter, rCode int)](https://godoc.org/github.com/bnkamalesh/webgo#SendHeader) - Send only an HTTP response header with the provided response code. +3. [Send(w http.ResponseWriter, contentType string, data interface{}, rCode int)](https://godoc.org/github.com/bnkamalesh/webgo#Send) - Send any response as is, with the provided content type and response code +4. [SendResponse(w http.ResponseWriter, data interface{}, rCode int)](https://godoc.org/github.com/bnkamalesh/webgo#SendResponse) - Send a JSON response wrapped in WebGo's default response struct. +5. [SendError(w http.ResponseWriter, data interface{}, rCode int)](https://godoc.org/github.com/bnkamalesh/webgo#SendError) - Send a JSON response wrapped in WebGo's default error response struct +6. [Render(w http.ResponseWriter, data interface{}, rCode int, tpl *template.Template)](https://godoc.org/github.com/bnkamalesh/webgo#Render) - Render renders a Go template, with the provided data & response code. + +You can find other helper functions [here](https://godoc.org/github.com/bnkamalesh/webgo#R200). + +When using `Send` or `SendResponse`, the response is wrapped in WebGo's [response struct](https://github.com/bnkamalesh/webgo/blob/master/responses.go#L17) and is serialized as JSON. + +```json +{ + "data": "", + "status": "" +} +``` + +When using `SendError`, the response is wrapped in WebGo's [error response struct](https://github.com/bnkamalesh/webgo/blob/master/responses.go#L23) and is serialzied as JSON. + +```json +{ + "errors": "", + "status": "" +} +``` + +## HTTPS ready + +HTTPS server can be started easily, by providing the key & cert file. You can also have both HTTP & HTTPS servers running side by side. + +Start HTTPS server + +```golang +cfg := &webgo.Config{ + Port: "80", + HTTPSPort: "443", + CertFile: "/path/to/certfile", + KeyFile: "/path/to/keyfile", +} +router := webgo.NewRouter(cfg, routes()) +router.StartHTTPS() +``` + +Starting both HTTP & HTTPS server + +```golang +cfg := &webgo.Config{ + Port: "80", + HTTPSPort: "443", + CertFile: "/path/to/certfile", + KeyFile: "/path/to/keyfile", +} + +router := webgo.NewRouter(cfg, routes()) +go router.StartHTTPS() +router.Start() +``` + +## Graceful shutdown + +Graceful shutdown lets you shutdown the server without affecting any live connections/clients connected to the server. It will complete executing all the active/live requests before shutting down. + +Sample code to show how to use shutdown + +```golang +func main() { + osSig := make(chan os.Signal, 5) + + cfg := &webgo.Config{ + Host: "", + Port: "8080", + ReadTimeout: 15 * time.Second, + WriteTimeout: 60 * time.Second, + ShutdownTimeout: 15 * time.Second, + } + router := webgo.NewRouter(cfg, routes()) + + go func() { + <-osSig + // Initiate HTTP server shutdown + err := router.Shutdown() + if err != nil { + fmt.Println(err) + os.Exit(1) + } else { + fmt.Println("shutdown complete") + os.Exit(0) + } + + // If you have HTTPS server running, you can use the following code + // err := router.ShutdownHTTPS() + // if err != nil { + // fmt.Println(err) + // os.Exit(1) + // } else { + // fmt.Println("shutdown complete") + // os.Exit(0) + // } + }() + + signal.Notify(osSig, os.Interrupt, syscall.SIGTERM) + + router.Start() + + for { + // Prevent main thread from exiting, and wait for shutdown to complete + time.Sleep(time.Second * 1) + } +} +``` + +## Logging + +WebGo exposes a singleton & global scoped logger variable [LOGHANDLER](https://godoc.org/github.com/bnkamalesh/webgo#Logger) with which you can plug in your custom logger by implementing the [Logger](https://godoc.org/github.com/bnkamalesh/webgo#Logger) interface. + +```golang +type Logger interface { + Debug(data ...interface{}) + Info(data ...interface{}) + Warn(data ...interface{}) + Error(data ...interface{}) + Fatal(data ...interface{}) +} +``` + +### Configuring the default Logger + +The default logger uses Go standard library's `log.Logger` with `os.Stdout` (for debug and info logs) & `os.Stderr` (for warning, error, fatal) as default io.Writers. You can set the io.Writer as well as disable specific types of logs using the `GlobalLoggerConfig(stdout, stderr, cfgs...)` function. + +```golang +GlobalLoggerConfig(nil, nil, LogCfgDisableDebug, LogCfgDisableInfo...) +``` + +Usage is shown in `cmd/main.go`. + +## Usage + +A fully functional sample is provided [here](https://github.com/bnkamalesh/webgo/blob/master/cmd/main.go). You can try the following API calls with the sample app. + +1. `http://localhost:8080/` + - Route with no named parameters configured +2. `http://localhost:8080/matchall/` + - Route with wildcard parameter configured + - All URIs which begin with `/matchall` will be matched because it has a wildcard variable + - e.g. + - http://localhost:8080/matchall/hello + - http://localhost:8080/matchall/hello/world + - http://localhost:8080/matchall/hello/world/user +3. `http://localhost:8080/api/ + - Route with a named 'param' configured + - It will match all requests which match `/api/` + - e.g. + - http://localhost:8080/api/hello + - http://localhost:8080/api/world + +### How to run the sample + +If you have Go installed on your computer, open the terminal and: + +```bash +$ cd $GOPATH/src +$ mkdir -p github.com/bnkamalesh +$ cd github.com/bnkamalesh +$ git clone https://github.com/bnkamalesh/webgo.git +$ cd webgo +$ go run cmd/main.go + +Info 2020/06/03 12:55:26 HTTP server, listening on :8080 +``` + +Or if you have [Docker](https://www.docker.com/), open the terminal and: + +```bash +$ git clone https://github.com/bnkamalesh/webgo.git +$ cd webgo +$ docker run \ +-p 8080:8080 \ +-v ${PWD}:/go/src/github.com/bnkamalesh/webgo/ \ +-w /go/src/github.com/bnkamalesh/webgo/cmd \ +--rm -ti golang:latest go run main.go + +Info 2020/06/03 12:55:26 HTTP server, listening on :8080 +``` + +### Benchmark + +You can view benchmark results at the following repos: + +1. [the-benchmarker](https://github.com/the-benchmarker/web-frameworks) +2. [go-web-framework-benchmark](https://github.com/smallnest/go-web-framework-benchmark) + +### Contributing + +Refer [here](https://github.com/bnkamalesh/webgo/blob/master/CONTRIBUTING.md) to find out details about making a contribution + +### Credits + +Thanks to all the [contributors](https://github.com/bnkamalesh/webgo/graphs/contributors) + +## The gopher + +The gopher used here was created using [Gopherize.me](https://gopherize.me/). WebGo stays out of developers' way, so sitback and enjoy a cup of coffee like this gopher. diff --git a/vendor/github.com/bnkamalesh/webgo/v4/_config.yml b/vendor/github.com/bnkamalesh/webgo/v4/_config.yml new file mode 100644 index 0000000..c419263 --- /dev/null +++ b/vendor/github.com/bnkamalesh/webgo/v4/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-cayman \ No newline at end of file diff --git a/vendor/github.com/bnkamalesh/webgo/v4/config.go b/vendor/github.com/bnkamalesh/webgo/v4/config.go new file mode 100644 index 0000000..b608726 --- /dev/null +++ b/vendor/github.com/bnkamalesh/webgo/v4/config.go @@ -0,0 +1,66 @@ +package webgo + +import ( + "encoding/json" + "io/ioutil" + "strconv" + "time" +) + +// Config is used for reading app's configuration from json file +type Config struct { + // Host is the host on which the server is listening + Host string `json:"host,omitempty"` + // Port is the port number where the server has to listen for the HTTP requests + Port string `json:"port,omitempty"` + + // CertFile is the TLS/SSL certificate file path, required for HTTPS + CertFile string `json:"certFile,omitempty"` + // KeyFile is the filepath of private key of the certificate + KeyFile string `json:"keyFile,omitempty"` + // HTTPSPort is the port number where the server has to listen for the HTTP requests + HTTPSPort string `json:"httpsPort,omitempty"` + + // ReadTimeout is the maximum duration for which the server would read a request + ReadTimeout time.Duration `json:"readTimeout,omitempty"` + // WriteTimeout is the maximum duration for which the server would try to respond + WriteTimeout time.Duration `json:"writeTimeout,omitempty"` + + // InsecureSkipVerify is the HTTP certificate verification + InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty"` + + // ShutdownTimeout is the duration in which graceful shutdown is completed, in seconds + ShutdownTimeout time.Duration +} + +// Load config file from the provided filepath and validate +func (cfg *Config) Load(filepath string) { + file, err := ioutil.ReadFile(filepath) + if err != nil { + LOGHANDLER.Fatal(err) + } + + err = json.Unmarshal(file, cfg) + if err != nil { + LOGHANDLER.Fatal(err) + } + + err = cfg.Validate() + if err != nil { + LOGHANDLER.Fatal(ErrInvalidPort) + } +} + +// Validate the config parsed into the Config struct +func (cfg *Config) Validate() error { + i, err := strconv.Atoi(cfg.Port) + if err != nil { + return ErrInvalidPort + } + + if i <= 0 || i > 65535 { + return ErrInvalidPort + } + + return nil +} diff --git a/vendor/github.com/bnkamalesh/webgo/v4/contributors.txt b/vendor/github.com/bnkamalesh/webgo/v4/contributors.txt new file mode 100644 index 0000000..9d71fab --- /dev/null +++ b/vendor/github.com/bnkamalesh/webgo/v4/contributors.txt @@ -0,0 +1 @@ +Kamaleshwar BN diff --git a/vendor/github.com/bnkamalesh/webgo/v4/errors.go b/vendor/github.com/bnkamalesh/webgo/v4/errors.go new file mode 100644 index 0000000..0ebeff3 --- /dev/null +++ b/vendor/github.com/bnkamalesh/webgo/v4/errors.go @@ -0,0 +1,145 @@ +package webgo + +import ( + "errors" + "io" + "log" + "os" +) + +var ( + // ErrInvalidPort is the error returned when the port number provided in the config file is invalid + ErrInvalidPort = errors.New("Port number not provided or is invalid (should be between 0 - 65535)") + + lh *logHandler +) + +type logCfg string + +const ( + // LogCfgDisableDebug is used to disable debug logs + LogCfgDisableDebug = logCfg("disable-debug") + // LogCfgDisableInfo is used to disable info logs + LogCfgDisableInfo = logCfg("disable-info") + // LogCfgDisableWarn is used to disable warning logs + LogCfgDisableWarn = logCfg("disable-warn") + // LogCfgDisableError is used to disable error logs + LogCfgDisableError = logCfg("disable-err") + // LogCfgDisableFatal is used to disable fatal logs + LogCfgDisableFatal = logCfg("disable-fatal") +) + +// Logger defines all the logging methods to be implemented +type Logger interface { + Debug(data ...interface{}) + Info(data ...interface{}) + Warn(data ...interface{}) + Error(data ...interface{}) + Fatal(data ...interface{}) +} + +// logHandler has all the log writer handlers +type logHandler struct { + debug *log.Logger + info *log.Logger + warn *log.Logger + err *log.Logger + fatal *log.Logger +} + +// Debug prints log of severity 5 +func (lh *logHandler) Debug(data ...interface{}) { + if lh.debug == nil { + return + } + lh.debug.Println(data...) +} + +// Info prints logs of severity 4 +func (lh *logHandler) Info(data ...interface{}) { + if lh.info == nil { + return + } + lh.info.Println(data...) +} + +// Warn prints log of severity 3 +func (lh *logHandler) Warn(data ...interface{}) { + if lh.warn == nil { + return + } + lh.warn.Println(data...) +} + +// Error prints log of severity 2 +func (lh *logHandler) Error(data ...interface{}) { + if lh.err == nil { + return + } + lh.err.Println(data...) +} + +// Fatal prints log of severity 1 +func (lh *logHandler) Fatal(data ...interface{}) { + if lh.fatal == nil { + return + } + lh.fatal.Fatalln(data...) +} + +// LOGHANDLER is a global variable which webgo uses to log messages +var LOGHANDLER Logger + +func init() { + GlobalLoggerConfig(nil, nil) +} + +func loggerWithCfg(stdout io.Writer, stderr io.Writer, cfgs ...logCfg) *logHandler { + lh = &logHandler{ + debug: log.New(stdout, "Debug ", log.LstdFlags), + info: log.New(stdout, "Info ", log.LstdFlags), + warn: log.New(stderr, "Warning ", log.LstdFlags), + err: log.New(stderr, "Error ", log.LstdFlags), + fatal: log.New(stderr, "Fatal ", log.LstdFlags|log.Llongfile), + } + + for _, c := range cfgs { + switch c { + case LogCfgDisableDebug: + { + lh.debug = nil + } + case LogCfgDisableInfo: + { + lh.info = nil + } + case LogCfgDisableWarn: + { + lh.warn = nil + } + case LogCfgDisableError: + { + lh.err = nil + } + case LogCfgDisableFatal: + { + lh.fatal = nil + } + } + } + return lh +} + +// GlobalLoggerConfig is used to configure the global/default logger of webgo +// IMPORTANT: This is not concurrent safe +func GlobalLoggerConfig(stdout io.Writer, stderr io.Writer, cfgs ...logCfg) { + if stdout == nil { + stdout = os.Stdout + } + + if stderr == nil { + stderr = os.Stderr + } + + LOGHANDLER = loggerWithCfg(stdout, stderr, cfgs...) +} diff --git a/vendor/github.com/bnkamalesh/webgo/v4/go.mod b/vendor/github.com/bnkamalesh/webgo/v4/go.mod new file mode 100644 index 0000000..19f5e58 --- /dev/null +++ b/vendor/github.com/bnkamalesh/webgo/v4/go.mod @@ -0,0 +1,3 @@ +module github.com/bnkamalesh/webgo/v4 + +go 1.14 diff --git a/vendor/github.com/bnkamalesh/webgo/v4/responses.go b/vendor/github.com/bnkamalesh/webgo/v4/responses.go new file mode 100644 index 0000000..9bb1ef8 --- /dev/null +++ b/vendor/github.com/bnkamalesh/webgo/v4/responses.go @@ -0,0 +1,171 @@ +package webgo + +import ( + "encoding/json" + "fmt" + "html/template" + "net/http" +) + +// ErrorData used to render the error page +type ErrorData struct { + ErrCode int + ErrDescription string +} + +// dOutput is the standard/valid output wrapped in `{data: , status: }` +type dOutput struct { + Data interface{} `json:"data"` + Status int `json:"status"` +} + +// errOutput is the error output wrapped in `{errors:, status: }` +type errOutput struct { + Errors interface{} `json:"errors"` + Status int `json:"status"` +} + +const ( + // HeaderContentType is the key for mentioning the response header content type + HeaderContentType = "Content-Type" + // JSONContentType is the MIME type when the response is JSON + JSONContentType = "application/json" + // HTMLContentType is the MIME type when the response is HTML + HTMLContentType = "text/html; charset=UTF-8" + + // ErrInternalServer to send when there's an internal server error + ErrInternalServer = "Internal server error" +) + +// SendHeader is used to send only a response header, i.e no response body +func SendHeader(w http.ResponseWriter, rCode int) { + w.WriteHeader(rCode) +} + +func crwAsserter(w http.ResponseWriter, rCode int) http.ResponseWriter { + if crw, ok := w.(*customResponseWriter); ok { + crw.statusCode = rCode + return crw + } + + return newCRW(w, rCode) +} + +// Send sends a completely custom response without wrapping in the +// `{data: , status: ` struct +func Send(w http.ResponseWriter, contentType string, data interface{}, rCode int) { + w = crwAsserter(w, rCode) + w.Header().Set(HeaderContentType, contentType) + _, err := fmt.Fprint(w, data) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(ErrInternalServer)) + LOGHANDLER.Error(err) + } +} + +// SendResponse is used to respond to any request (JSON response) based on the code, data etc. +func SendResponse(w http.ResponseWriter, data interface{}, rCode int) { + w = crwAsserter(w, rCode) + w.Header().Add(HeaderContentType, JSONContentType) + err := json.NewEncoder(w).Encode(dOutput{Data: data, Status: rCode}) + if err != nil { + /* + In case of encoding error, send "internal server error" and + log the actual error. + */ + R500(w, ErrInternalServer) + LOGHANDLER.Error(err) + } +} + +// SendError is used to respond to any request with an error +func SendError(w http.ResponseWriter, data interface{}, rCode int) { + w = crwAsserter(w, rCode) + w.Header().Add(HeaderContentType, JSONContentType) + err := json.NewEncoder(w).Encode(errOutput{data, rCode}) + if err != nil { + /* + In case of encoding error, send "internal server error" and + log the actual error. + */ + R500(w, ErrInternalServer) + LOGHANDLER.Error(err) + } +} + +// Render is used for rendering templates (HTML) +func Render(w http.ResponseWriter, data interface{}, rCode int, tpl *template.Template) { + w = crwAsserter(w, rCode) + + // In case of HTML response, setting appropriate header type for text/HTML response + w.Header().Set(HeaderContentType, HTMLContentType) + + // Rendering an HTML template with appropriate data + err := tpl.Execute(w, data) + if err != nil { + Send(w, "text/plain", ErrInternalServer, http.StatusInternalServerError) + LOGHANDLER.Error(err.Error()) + } +} + +// Render404 - used to render a 404 page +func Render404(w http.ResponseWriter, tpl *template.Template) { + Render(w, ErrorData{ + http.StatusNotFound, + "Sorry, the URL you requested was not found on this server... Or you're lost :-/", + }, + http.StatusNotFound, + tpl, + ) +} + +// R200 - Successful/OK response +func R200(w http.ResponseWriter, data interface{}) { + SendResponse(w, data, http.StatusOK) +} + +// R201 - New item created +func R201(w http.ResponseWriter, data interface{}) { + SendResponse(w, data, http.StatusCreated) +} + +// R204 - empty, no content +func R204(w http.ResponseWriter) { + SendHeader(w, http.StatusNoContent) +} + +// R302 - Temporary redirect +func R302(w http.ResponseWriter, data interface{}) { + SendResponse(w, data, http.StatusFound) +} + +// R400 - Invalid request, any incorrect/erraneous value in the request body +func R400(w http.ResponseWriter, data interface{}) { + SendError(w, data, http.StatusBadRequest) +} + +// R403 - Unauthorized access +func R403(w http.ResponseWriter, data interface{}) { + SendError(w, data, http.StatusForbidden) +} + +// R404 - Resource not found +func R404(w http.ResponseWriter, data interface{}) { + SendError(w, data, http.StatusNotFound) +} + +// R406 - Unacceptable header. For any error related to values set in header +func R406(w http.ResponseWriter, data interface{}) { + SendError(w, data, http.StatusNotAcceptable) +} + +// R451 - Resource taken down because of a legal request +func R451(w http.ResponseWriter, data interface{}) { + SendError(w, data, http.StatusUnavailableForLegalReasons) +} + +// R500 - Internal server error +func R500(w http.ResponseWriter, data interface{}) { + SendError(w, data, http.StatusInternalServerError) +} diff --git a/vendor/github.com/bnkamalesh/webgo/v4/route.go b/vendor/github.com/bnkamalesh/webgo/v4/route.go new file mode 100644 index 0000000..0135731 --- /dev/null +++ b/vendor/github.com/bnkamalesh/webgo/v4/route.go @@ -0,0 +1,184 @@ +package webgo + +import ( + "fmt" + "net/http" + "regexp" + "strings" +) + +// Route defines a route for each API +type Route struct { + // Name is unique identifier for the route + Name string + // Method is the HTTP request method/type + Method string + // Pattern is the URI pattern to match + Pattern string + // TrailingSlash if set to true, the URI will be matched with or without + // a trailing slash. Note: It does not *do* a redirect. + TrailingSlash bool + + // FallThroughPostResponse if enabled will execute all the handlers even if a response was already sent to the client + FallThroughPostResponse bool + + // Handlers is a slice of http.HandlerFunc which can be middlewares or anything else. Though only 1 of them will be allowed to respond to client. + // subsequent writes from the following handlers will be ignored + Handlers []http.HandlerFunc + + // uriKeys is the list of URI parameter variables available for this route + uriKeys []string + // uriPatternString is the pattern string which is compiled to regex object + uriPatternString string + // uriPattern is the compiled regex to match the URI pattern + uriPattern *regexp.Regexp + + serve http.HandlerFunc +} + +// computePatternStr computes the pattern string required for generating the route's regex. +// It also adds the URI parameter key to the route's `keys` field +func (r *Route) computePatternStr(patternString string, hasWildcard bool, key string) (string, error) { + regexPattern := "" + patternKey := "" + if hasWildcard { + patternKey = fmt.Sprintf(":%s*", key) + regexPattern = urlwildcard + } else { + patternKey = fmt.Sprintf(":%s", key) + regexPattern = urlchars + } + + patternString = strings.Replace(patternString, patternKey, regexPattern, 1) + + for idx, k := range r.uriKeys { + if key == k { + return "", fmt.Errorf( + "%s\nURI:%s\nKey:%s, Position: %d", + errDuplicateKey, + r.Pattern, + k, + idx+1, + ) + } + } + + r.uriKeys = append(r.uriKeys, key) + return patternString, nil +} + +func (r *Route) parseURIWithParams(patternString string) (string, error) { + if !strings.Contains(r.Pattern, ":") { + return patternString, nil + } + + var err error + // uriValues is a map of URI Key and its respective value, + // this is calculated per request + key := "" + hasKey := false + hasWildcard := false + + for i := 0; i < len(r.Pattern); i++ { + char := string(r.Pattern[i]) + + if char == ":" { + hasKey = true + } else if char == "*" { + hasWildcard = true + } else if hasKey && char != "/" { + key += char + } else if hasKey && len(key) > 0 { + patternString, err = r.computePatternStr(patternString, hasWildcard, key) + if err != nil { + return "", err + } + hasWildcard, hasKey = false, false + key = "" + } + } + + if hasKey && len(key) > 0 { + patternString, err = r.computePatternStr(patternString, hasWildcard, key) + if err != nil { + return "", err + } + } + return patternString, nil +} + +// init prepares the URIKeys, compile regex for the provided pattern +func (r *Route) init() error { + patternString := r.Pattern + + patternString, err := r.parseURIWithParams(patternString) + if err != nil { + return err + } + + if r.TrailingSlash { + patternString = fmt.Sprintf("^%s%s$", patternString, trailingSlash) + } else { + patternString = fmt.Sprintf("^%s$", patternString) + } + + // compile the regex for the pattern string calculated + reg, err := regexp.Compile(patternString) + if err != nil { + return err + } + + r.uriPattern = reg + r.uriPatternString = patternString + r.serve = defaultRouteServe(r) + + return nil +} + +// matchPath matches the requestURI with the URI pattern of the route. +// If the path is an exact match (i.e. no URI parameters), then the second parameter ('isExactMatch') is true +func (r *Route) matchPath(requestURI string) (bool, isExactMatch bool) { + if r.Pattern == requestURI { + return true, true + } + + return r.uriPattern.Match([]byte(requestURI)), false +} + +func (r *Route) params(requestURI string) map[string]string { + params := r.uriPattern.FindStringSubmatch(requestURI)[1:] + uriValues := make(map[string]string, len(params)) + + for i := 0; i < len(params); i++ { + uriValues[r.uriKeys[i]] = params[i] + } + + return uriValues +} + +func routeServeChainedHandlers(r *Route) http.HandlerFunc { + return func(rw http.ResponseWriter, req *http.Request) { + + crw, ok := rw.(*customResponseWriter) + if !ok { + crw = newCRW(rw, http.StatusOK) + } + + for _, handler := range r.Handlers { + if crw.written && !r.FallThroughPostResponse { + break + } + handler(crw, req) + } + } +} + +func defaultRouteServe(r *Route) http.HandlerFunc { + if len(r.Handlers) > 1 { + return routeServeChainedHandlers(r) + } + + // when there is only 1 handler, custom response writer is not required to check if response + // is already written or fallthrough is enabled + return r.Handlers[0] +} diff --git a/vendor/github.com/bnkamalesh/webgo/v4/router.go b/vendor/github.com/bnkamalesh/webgo/v4/router.go new file mode 100644 index 0000000..5192c08 --- /dev/null +++ b/vendor/github.com/bnkamalesh/webgo/v4/router.go @@ -0,0 +1,389 @@ +package webgo + +import ( + "bufio" + "context" + "errors" + "fmt" + "net" + "net/http" + "sync" +) + +// urlchars is regex to validate characters in a URI parameter +// const urlchars = `([a-zA-Z0-9\*\-+._~!$()=&',;:@%]+)` +// Regex prepared based on http://stackoverflow.com/a/4669750/1359163, +// https://tools.ietf.org/html/rfc3986 +// Though the current one allows invalid characters in the URI parameter, it has better performance. +const ( + urlchars = `([^/]+)` + urlwildcard = `(.*)` + trailingSlash = `[\/]?` + errMultiHeaderWrite = `http: multiple response.WriteHeader calls` + errMultiWrite = `http: multiple response.Write calls` + errDuplicateKey = `Error: Duplicate URI keys found` +) + +var ( + validHTTPMethods = []string{ + http.MethodOptions, + http.MethodHead, + http.MethodGet, + http.MethodPost, + http.MethodPut, + http.MethodPatch, + http.MethodDelete, + } + + ctxPool = &sync.Pool{ + New: func() interface{} { + return new(ContextPayload) + }, + } + crwPool = &sync.Pool{ + New: func() interface{} { + return new(customResponseWriter) + }, + } +) + +// customResponseWriter is a custom HTTP response writer +type customResponseWriter struct { + http.ResponseWriter + statusCode int + written bool + headerWritten bool +} + +// WriteHeader is the interface implementation to get HTTP response code and add +// it to the custom response writer +func (crw *customResponseWriter) WriteHeader(code int) { + if crw.written || crw.headerWritten { + return + } + + crw.headerWritten = true + crw.statusCode = code + crw.ResponseWriter.WriteHeader(code) +} + +// Write is the interface implementation to respond to the HTTP request, +// but check if a response was already sent. +func (crw *customResponseWriter) Write(body []byte) (int, error) { + if crw.written { + LOGHANDLER.Warn(errMultiWrite) + return 0, nil + } + + crw.WriteHeader(crw.statusCode) + + crw.written = true + return crw.ResponseWriter.Write(body) +} + +// Flush calls the http.Flusher to clear/flush the buffer +func (crw *customResponseWriter) Flush() { + if rw, ok := crw.ResponseWriter.(http.Flusher); ok { + rw.Flush() + } +} + +// Hijack implements the http.Hijacker interface +func (crw *customResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { + if hj, ok := crw.ResponseWriter.(http.Hijacker); ok { + return hj.Hijack() + } + + return nil, nil, errors.New("unable to create hijacker") +} + +// CloseNotify implements the http.CloseNotifier interface +func (crw *customResponseWriter) CloseNotify() <-chan bool { + if n, ok := crw.ResponseWriter.(http.CloseNotifier); ok { + return n.CloseNotify() + } + return nil +} + +func (crw *customResponseWriter) reset() { + crw.statusCode = 0 + crw.written = false + crw.headerWritten = false + crw.ResponseWriter = nil +} + +// Middleware is the signature of WebGo's middleware +type Middleware func(http.ResponseWriter, *http.Request, http.HandlerFunc) + +// discoverRoute returns the correct 'route', for the given request +func discoverRoute(path string, routes []*Route) *Route { + for _, route := range routes { + if ok, _ := route.matchPath(path); ok { + return route + } + } + return nil +} + +// Router is the HTTP router +type Router struct { + optHandlers []*Route + headHandlers []*Route + getHandlers []*Route + postHandlers []*Route + putHandlers []*Route + patchHandlers []*Route + deleteHandlers []*Route + allHandlers map[string][]*Route + + // NotFound is the generic handler for 404 resource not found response + NotFound http.HandlerFunc + + // NotImplemented is the generic handler for 501 method not implemented + NotImplemented http.HandlerFunc + + // config has all the app config + config *Config + + // httpServer is the server handler for the active HTTP server + httpServer *http.Server + // httpsServer is the server handler for the active HTTPS server + httpsServer *http.Server +} + +// methodRoutes returns the list of Routes handling the HTTP method given the request +func (rtr *Router) methodRoutes(method string) (routes []*Route) { + switch method { + case http.MethodOptions: + return rtr.optHandlers + case http.MethodHead: + return rtr.headHandlers + case http.MethodGet: + return rtr.getHandlers + case http.MethodPost: + return rtr.postHandlers + case http.MethodPut: + return rtr.putHandlers + case http.MethodPatch: + return rtr.patchHandlers + case http.MethodDelete: + return rtr.deleteHandlers + } + + return nil +} + +func (rtr *Router) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + // a custom response writer is used to set appropriate HTTP status code in case of + // encoding errors. i.e. if there's a JSON encoding issue while responding, + // the HTTP status code would say 200, and and the JSON payload {"status": 500} + crw := newCRW(rw, http.StatusOK) + + routes := rtr.methodRoutes(r.Method) + if routes == nil { + // serve 501 when HTTP method is not implemented + crw.statusCode = http.StatusNotImplemented + rtr.NotImplemented(crw, r) + releaseCRW(crw) + return + } + + path := r.URL.EscapedPath() + route := discoverRoute(path, routes) + if route == nil { + // serve 404 when there are no matching routes + crw.statusCode = http.StatusNotFound + rtr.NotFound(crw, r) + releaseCRW(crw) + return + } + + ctxPayload := newContext() + ctxPayload.path = path + ctxPayload.Route = route + + // webgo context is injected to the HTTP request context + *r = *r.WithContext( + context.WithValue( + r.Context(), + wgoCtxKey, + ctxPayload, + ), + ) + + route.serve(crw, r) + + // IMPORTANT/TODO: if the handler panics, resources are not released from the pool. + // `defer releasePoolResources(crw, ctxPayload)` would solve the problem but with a potential performance hit + releasePoolResources(crw, ctxPayload) +} + +// Use adds a middleware layer +func (rtr *Router) Use(f Middleware) { + for _, handlers := range rtr.allHandlers { + for _, route := range handlers { + srv := route.serve + route.serve = func(rw http.ResponseWriter, req *http.Request) { + f(rw, req, srv) + } + } + } +} + +// UseOnSpecialHandlers adds middleware to the 2 special handlers of webgo +func (rtr *Router) UseOnSpecialHandlers(f Middleware) { + // v3.2.1 introduced the feature of adding middleware to both notfound & not implemented + // handlers + /* + - It was added considering an `accesslog` middleware, where all requests should be logged + # This is now being moved to a separate function considering an authentication middleware, where all requests + including 404 & 501 would respond with `not authenticated` if you do not have special handling + within the middleware. It is a cleaner implementation to avoid this and let users add their + middleware separately to NOTFOUND & NOTIMPLEMENTED handlers + */ + + nf := rtr.NotFound + rtr.NotFound = func(rw http.ResponseWriter, req *http.Request) { + f(rw, req, nf) + } + + ni := rtr.NotImplemented + rtr.NotImplemented = func(rw http.ResponseWriter, req *http.Request) { + f(rw, req, ni) + } +} + +func newCRW(rw http.ResponseWriter, rCode int) *customResponseWriter { + crw := crwPool.Get().(*customResponseWriter) + crw.ResponseWriter = rw + crw.statusCode = rCode + return crw +} + +func releaseCRW(crw *customResponseWriter) { + crw.reset() + crwPool.Put(crw) +} + +func newContext() *ContextPayload { + return ctxPool.Get().(*ContextPayload) +} + +func releaseContext(cp *ContextPayload) { + cp.reset() + ctxPool.Put(cp) +} + +func releasePoolResources(crw *customResponseWriter, cp *ContextPayload) { + releaseCRW(crw) + releaseContext(cp) +} + +// NewRouter initializes & returns a new router instance with all the configurations and routes set +func NewRouter(cfg *Config, routes []*Route) *Router { + handlers := httpHandlers(routes) + r := &Router{ + optHandlers: handlers[http.MethodOptions], + headHandlers: handlers[http.MethodHead], + getHandlers: handlers[http.MethodGet], + postHandlers: handlers[http.MethodPost], + putHandlers: handlers[http.MethodPut], + patchHandlers: handlers[http.MethodPatch], + deleteHandlers: handlers[http.MethodDelete], + allHandlers: handlers, + + NotFound: http.NotFound, + NotImplemented: func(rw http.ResponseWriter, req *http.Request) { + Send(rw, "", "501 Not Implemented", http.StatusNotImplemented) + }, + config: cfg, + } + + return r +} + +// checkDuplicateRoutes checks if any of the routes have duplicate name or URI pattern +func checkDuplicateRoutes(idx int, route *Route, routes []*Route) { + // checking if the URI pattern is duplicated + for i := 0; i < idx; i++ { + rt := routes[i] + + if rt.Name == route.Name { + LOGHANDLER.Info( + fmt.Sprintf( + "Duplicate route name('%s') detected", + rt.Name, + ), + ) + } + + if rt.Method != route.Method { + continue + } + + // regex pattern match + if ok, _ := rt.matchPath(route.Pattern); !ok { + continue + } + + LOGHANDLER.Warn( + fmt.Sprintf( + "Duplicate URI pattern detected.\nPattern: '%s'\nDuplicate pattern: '%s'", + rt.Pattern, + route.Pattern, + ), + ) + LOGHANDLER.Warn("Only the first route to match the URI pattern would handle the request") + } +} + +// httpHandlers returns all the handlers in a map, for each HTTP method +func httpHandlers(routes []*Route) map[string][]*Route { + handlers := map[string][]*Route{} + + handlers[http.MethodHead] = []*Route{} + handlers[http.MethodGet] = []*Route{} + + for idx, route := range routes { + found := false + for _, validMethod := range validHTTPMethods { + if route.Method == validMethod { + found = true + break + } + } + + if !found { + LOGHANDLER.Fatal( + fmt.Sprintf( + "Unsupported HTTP method provided. Method: '%s'", + route.Method, + ), + ) + return nil + } + + if route.Handlers == nil || len(route.Handlers) == 0 { + LOGHANDLER.Fatal( + fmt.Sprintf( + "No handlers provided for the route '%s', method '%s'", + route.Pattern, + route.Method, + ), + ) + return nil + } + + err := route.init() + if err != nil { + LOGHANDLER.Fatal("Unsupported URI pattern.", route.Pattern, err) + return nil + } + + checkDuplicateRoutes(idx, route, routes) + + handlers[route.Method] = append(handlers[route.Method], route) + } + + return handlers +} diff --git a/vendor/github.com/bnkamalesh/webgo/v4/webgo.go b/vendor/github.com/bnkamalesh/webgo/v4/webgo.go new file mode 100644 index 0000000..eb4a08e --- /dev/null +++ b/vendor/github.com/bnkamalesh/webgo/v4/webgo.go @@ -0,0 +1,144 @@ +/* +Package webgo is a lightweight framework for building web apps. It has a multiplexer, +middleware plugging mechanism & context management of its own. The primary goal +of webgo is to get out of the developer's way as much as possible. i.e. it does +not enforce you to build your app in any particular pattern, instead just helps you +get all the trivial things done faster and easier. + +e.g. +1. Getting named URI parameters. +2. Multiplexer for regex matching of URI and such. +3. Inject special app level configurations or any such objects to the request context as required. +*/ +package webgo + +import ( + "context" + "crypto/tls" + "net/http" +) + +// ctxkey is a custom string type to store the WebGo context inside HTTP request context +type ctxkey string + +const wgoCtxKey = ctxkey("webgocontext") + +// ContextPayload is the WebgoContext. A new instance of ContextPayload is injected inside every request's context object +type ContextPayload struct { + Route *Route + path string +} + +// Params returns the URI parameters of the respective route +func (cp *ContextPayload) Params() map[string]string { + return cp.Route.params(cp.path) +} + +func (cp *ContextPayload) reset() { + cp.Route = nil + cp.path = "" +} + +// Context returns the ContextPayload injected inside the HTTP request context +func Context(r *http.Request) *ContextPayload { + return r.Context().Value(wgoCtxKey).(*ContextPayload) +} + +// ResponseStatus returns the response status code. It works only if the http.ResponseWriter +// is not wrapped in another response writer before calling ResponseStatus +func ResponseStatus(rw http.ResponseWriter) int { + crw, ok := rw.(*customResponseWriter) + if !ok { + return http.StatusOK + } + return crw.statusCode +} + +// StartHTTPS starts the server with HTTPS enabled +func (router *Router) StartHTTPS() { + cfg := router.config + if cfg.CertFile == "" { + LOGHANDLER.Fatal("No certificate provided for HTTPS") + } + + if cfg.KeyFile == "" { + LOGHANDLER.Fatal("No key file provided for HTTPS") + } + + host := cfg.Host + if len(cfg.HTTPSPort) > 0 { + host += ":" + cfg.HTTPSPort + } + + router.httpsServer = &http.Server{ + Addr: host, + Handler: router, + ReadTimeout: cfg.ReadTimeout, + WriteTimeout: cfg.WriteTimeout, + TLSConfig: &tls.Config{ + InsecureSkipVerify: cfg.InsecureSkipVerify, + }, + } + + LOGHANDLER.Info("HTTPS server, listening on", host) + err := router.httpsServer.ListenAndServeTLS(cfg.CertFile, cfg.KeyFile) + if err != nil && err != http.ErrServerClosed { + LOGHANDLER.Error("HTTPS server exited with error:", err.Error()) + } +} + +// Start starts the HTTP server with the appropriate configurations +func (router *Router) Start() { + cfg := router.config + host := cfg.Host + + if len(cfg.Port) > 0 { + host += ":" + cfg.Port + } + + router.httpServer = &http.Server{ + Addr: host, + Handler: router, + ReadTimeout: cfg.ReadTimeout, + WriteTimeout: cfg.WriteTimeout, + } + LOGHANDLER.Info("HTTP server, listening on", host) + err := router.httpServer.ListenAndServe() + if err != nil && err != http.ErrServerClosed { + LOGHANDLER.Error("HTTP server exited with error:", err.Error()) + } +} + +// Shutdown gracefully shuts down HTTP server +func (router *Router) Shutdown() error { + if router.httpServer == nil { + return nil + } + timer := router.config.ShutdownTimeout + + ctx, cancel := context.WithTimeout(context.Background(), timer) + defer cancel() + + err := router.httpServer.Shutdown(ctx) + if err != nil { + LOGHANDLER.Error(err) + } + return err +} + +// ShutdownHTTPS gracefully shuts down HTTPS server +func (router *Router) ShutdownHTTPS() error { + if router.httpsServer == nil { + return nil + } + timer := router.config.ShutdownTimeout + + ctx, cancel := context.WithTimeout(context.Background(), timer) + defer cancel() + + err := router.httpsServer.Shutdown(ctx) + if err != nil && err != http.ErrServerClosed { + LOGHANDLER.Error(err) + } + return err +} diff --git a/vendor/github.com/bnkamalesh/webgo/v6/.gitignore b/vendor/github.com/bnkamalesh/webgo/v6/.gitignore new file mode 100644 index 0000000..364bf73 --- /dev/null +++ b/vendor/github.com/bnkamalesh/webgo/v6/.gitignore @@ -0,0 +1,87 @@ +# Created by https://www.gitignore.io/api/go,osx,linux,windows + +### Go ### +# Binaries for programs and plugins +*.exe +*.dll +*.so +*.dylib + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 +.glide/ + +# Golang project vendor packages which should be ignored +vendor/ + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### OSX ### +*.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# End of https://www.gitignore.io/api/go,osx,linux,windows + +.vscode \ No newline at end of file diff --git a/vendor/github.com/bnkamalesh/webgo/v6/.travis.yml b/vendor/github.com/bnkamalesh/webgo/v6/.travis.yml new file mode 100644 index 0000000..315aa1b --- /dev/null +++ b/vendor/github.com/bnkamalesh/webgo/v6/.travis.yml @@ -0,0 +1,18 @@ +language: go +go: + # webgo is still compatible with 1.8, but the tests are importing versioned + # modules which fails for older Go versions and using `errors.Is` which was introduced in Go 1.13 + # - "1.8" + - "1.13" + - master + +before_install: + - go get -t -v ./... + +script: + # go.mod is overwritten to avoid go version being part of the mod file, which fails tests on mismatching version + - sed -i 's/go [0-9]*\.[0-9]*//' go.mod + - go test -coverprofile=coverage.txt -covermode=atomic $(go list ./... | grep -v /cmd) + +after_success: + - bash <(curl -s https://codecov.io/bash) \ No newline at end of file diff --git a/vendor/github.com/bnkamalesh/webgo/v6/CODE_OF_CONDUCT.md b/vendor/github.com/bnkamalesh/webgo/v6/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..b7a06a5 --- /dev/null +++ b/vendor/github.com/bnkamalesh/webgo/v6/CODE_OF_CONDUCT.md @@ -0,0 +1,46 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at bn_kamalesh@yahoo.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff --git a/vendor/github.com/bnkamalesh/webgo/v6/CONTRIBUTING.md b/vendor/github.com/bnkamalesh/webgo/v6/CONTRIBUTING.md new file mode 100644 index 0000000..797b0fa --- /dev/null +++ b/vendor/github.com/bnkamalesh/webgo/v6/CONTRIBUTING.md @@ -0,0 +1,24 @@ +Contributions are welcome from everyone. Please adhere to the [code of conduct](https://github.com/bnkamalesh/webgo/blob/master/CODE_OF_CONDUCT.md) of the project, and be respectful to all. + +Please follow the guidelines provided for contribution + +1. Updates to the project are only accepted via Pull Requests (PR) +2. Pull requests will be reviewed & tested +3. Every PR should be accompanied by its test wherever applicable +4. While creating an issue + 1. Mention the steps to reproduce the issue + 2. Mention the environment in which it was run + 3. Include your 1st level of troubleshooting results +5. Provide meaningful commit messages + + +### Versioning & PR messages + +WebGo tries to use [semantic versioning](https://semver.org/) and starting recently, have decided to adhere to the following syntax in PR description. List down the changes as bulleted list, as follows: + +```markdown +[major] any backward incompatible or breaking change +[minor] any new feature +[patch] enhancements of existing features, refactor, bug fix etc. +[-] for changes which does not require a version number update +``` diff --git a/vendor/github.com/bnkamalesh/webgo/v6/LICENSE b/vendor/github.com/bnkamalesh/webgo/v6/LICENSE new file mode 100644 index 0000000..680becd --- /dev/null +++ b/vendor/github.com/bnkamalesh/webgo/v6/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 Kamaleshwar + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/vendor/github.com/bnkamalesh/webgo/v6/README.md b/vendor/github.com/bnkamalesh/webgo/v6/README.md new file mode 100644 index 0000000..4fc8162 --- /dev/null +++ b/vendor/github.com/bnkamalesh/webgo/v6/README.md @@ -0,0 +1,219 @@ +

webgo gopher

+ +[![](https://travis-ci.org/bnkamalesh/webgo.svg?branch=master)](https://travis-ci.org/bnkamalesh/webgo) +[![coverage](https://img.shields.io/codecov/c/github/bnkamalesh/webgo.svg)](https://codecov.io/gh/bnkamalesh/webgo) +[![](https://goreportcard.com/badge/github.com/bnkamalesh/webgo)](https://goreportcard.com/report/github.com/bnkamalesh/webgo) +[![](https://api.codeclimate.com/v1/badges/85b3a55c3fa6b4c5338d/maintainability)](https://codeclimate.com/github/bnkamalesh/webgo/maintainability) +[![](https://godoc.org/github.com/nathany/looper?status.svg)](http://godoc.org/github.com/bnkamalesh/webgo) +[![](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go#web-frameworks) + +# WebGo v6.2.1 + +WebGo is a minimalistic framework for [Go](https://golang.org) to build web applications (server side) with no 3rd party dependencies. WebGo will always be Go standard library compliant; with the HTTP handlers having the same signature as [http.HandlerFunc](https://golang.org/pkg/net/http/#HandlerFunc). + +### Contents + +1. [Router](https://github.com/bnkamalesh/webgo#router) +2. [Handler chaining](https://github.com/bnkamalesh/webgo#handler-chaining) +3. [Middleware](https://github.com/bnkamalesh/webgo#middleware) +4. [Error handling](https://github.com/bnkamalesh/webgo#error-handling) +5. [Helper functions](https://github.com/bnkamalesh/webgo#helper-functions) +6. [HTTPS ready](https://github.com/bnkamalesh/webgo#https-ready) +7. [Graceful shutdown](https://github.com/bnkamalesh/webgo#graceful-shutdown) +8. [Logging](https://github.com/bnkamalesh/webgo#logging) +9. [Usage](https://github.com/bnkamalesh/webgo#usage) + + +## Router + +Webgo has a simplistic, regex based router and supports defining [URI](https://developer.mozilla.org/en-US/docs/Glossary/URI)s with the following patterns + +1. `/api/users` - URI with no dynamic values +2. `/api/users/:userID` + - URI with a named parameter, `userID` + - If TrailingSlash is set to true, it will accept the URI ending with a '/', refer to [sample](https://github.com/bnkamalesh/webgo#sample) +3. `/api/users/:misc*` + - Named URI parameter `misc`, with a wildcard suffix '*' + - This matches everything after `/api/users`. e.g. `/api/users/a/b/c/d` + +When there are multiple handlers matching the same URI, only the first occurring handler will handle the request. +Refer to the [sample](https://github.com/bnkamalesh/webgo#sample) to see how routes are configured. You can access named parameters of the URI using the `Context` function. + +Note: webgo Context is **not** available inside the special handlers (not found & method not implemented) + +```golang +func helloWorld(w http.ResponseWriter, r *http.Request) { + // WebGo context + wctx := webgo.Context(r) + // URI paramaters, map[string]string + params := wctx.Params() + // route, the webgo.Route which is executing this request + route := wctx.Route + webgo.R200( + w, + fmt.Sprintf( + "Route name: '%s', params: '%s'", + route.Name, + params, + ), + ) +} +``` + +## Handler chaining + +Handler chaining lets you execute multiple handlers for a given route. Execution of a chain can be configured to run even after a handler has written a response to the HTTP request, if you set `FallThroughPostResponse` to `true` (refer [sample](https://github.com/bnkamalesh/webgo/blob/master/cmd/main.go#L70)). + +## Middleware + +WebGo [middlware](https://godoc.org/github.com/bnkamalesh/webgo#Middleware) lets you wrap all the routes with a middleware unlike handler chaining. The router exposes a method [Use](https://godoc.org/github.com/bnkamalesh/webgo#Router.Use) && [UseOnSpecialHandlers](https://godoc.org/github.com/bnkamalesh/webgo#Router.UseOnSpecialHandlers) to add a Middleware to the router. + +NotFound && NotImplemented are considered `Special` handlers. `webgo.Context(r)` within special handlers will return `nil`. + +Any number of middleware can be added to the router, the order of execution of middleware would be [LIFO](https://en.wikipedia.org/wiki/Stack_(abstract_data_type)) (Last In First Out). i.e. in case of the following code + +```golang +func main() { + router.Use(accesslog.AccessLog, cors.CORS(nil)) + router.Use() +} +``` + +**_CorsWrap_** would be executed first, followed by **_AccessLog_**. + +## Error handling + +Webgo context has 2 methods to [set](https://github.com/bnkamalesh/webgo/blob/master/webgo.go#L60) & [get](https://github.com/bnkamalesh/webgo/blob/master/webgo.go#L66) erro within a request context. It enables Webgo to implement a single middleware where you can handle error returned within an HTTP handler. [set error](https://github.com/bnkamalesh/webgo/blob/master/cmd/main.go#L45), [get error](https://github.com/bnkamalesh/webgo/blob/master/cmd/main.go#L51). + +## Helper functions + +WebGo provides a few helper functions. When using `Send` or `SendResponse` (other Rxxx responder functions), the response is wrapped in WebGo's [response struct](https://github.com/bnkamalesh/webgo/blob/master/responses.go#L17) and is serialized as JSON. + +```json +{ + "data": "", + "status": "" +} +``` + +When using `SendError`, the response is wrapped in WebGo's [error response struct](https://github.com/bnkamalesh/webgo/blob/master/responses.go#L23) and is serialzied as JSON. + +```json +{ + "errors": "", + "status": "" +} +``` + +## HTTPS ready + +HTTPS server can be started easily, by providing the key & cert file. You can also have both HTTP & HTTPS servers running side by side. + +Start HTTPS server + +```golang +cfg := &webgo.Config{ + Port: "80", + HTTPSPort: "443", + CertFile: "/path/to/certfile", + KeyFile: "/path/to/keyfile", +} +router := webgo.NewRouter(cfg, routes()...) +router.StartHTTPS() +``` + +Starting both HTTP & HTTPS server + +```golang +cfg := &webgo.Config{ + Port: "80", + HTTPSPort: "443", + CertFile: "/path/to/certfile", + KeyFile: "/path/to/keyfile", +} + +router := webgo.NewRouter(cfg, routes()...) +go router.StartHTTPS() +router.Start() +``` + +## Graceful shutdown + +Graceful shutdown lets you shutdown the server without affecting any live connections/clients connected to the server. Any new connection request after initiating a shutdown would be ignored. + +Sample code to show how to use shutdown + +```golang +func main() { + osSig := make(chan os.Signal, 5) + + cfg := &webgo.Config{ + Host: "", + Port: "8080", + ReadTimeout: 15 * time.Second, + WriteTimeout: 60 * time.Second, + ShutdownTimeout: 15 * time.Second, + } + router := webgo.NewRouter(cfg, routes()...) + + go func() { + <-osSig + // Initiate HTTP server shutdown + err := router.Shutdown() + if err != nil { + fmt.Println(err) + os.Exit(1) + } else { + fmt.Println("shutdown complete") + os.Exit(0) + } + + // If you have HTTPS server running, you can use the following code + // err := router.ShutdownHTTPS() + // if err != nil { + // fmt.Println(err) + // os.Exit(1) + // } else { + // fmt.Println("shutdown complete") + // os.Exit(0) + // } + }() + + signal.Notify(osSig, os.Interrupt, syscall.SIGTERM) + + router.Start() + + for { + // Prevent main thread from exiting, and wait for shutdown to complete + time.Sleep(time.Second * 1) + } +} +``` + +## Logging + +WebGo exposes a singleton & global scoped logger variable [LOGHANDLER](https://godoc.org/github.com/bnkamalesh/webgo#Logger) with which you can plug in your custom logger by implementing the [Logger](https://godoc.org/github.com/bnkamalesh/webgo#Logger) interface. + +### Configuring the default Logger + +The default logger uses Go standard library's `log.Logger` with `os.Stdout` (for debug and info logs) & `os.Stderr` (for warning, error, fatal) as default io.Writers. You can set the io.Writer as well as disable specific types of logs using the `GlobalLoggerConfig(stdout, stderr, cfgs...)` function. + +## Usage + +A fully functional sample is provided [here](https://github.com/bnkamalesh/webgo/blob/master/cmd/main.go). +### Benchmark + +1. [the-benchmarker](https://github.com/the-benchmarker/web-frameworks) +2. [go-web-framework-benchmark](https://github.com/smallnest/go-web-framework-benchmark) + +### Contributing + +Refer [here](https://github.com/bnkamalesh/webgo/blob/master/CONTRIBUTING.md) to find out details about making a contribution + +### Credits + +Thanks to all the [contributors](https://github.com/bnkamalesh/webgo/graphs/contributors) + +## The gopher + +The gopher used here was created using [Gopherize.me](https://gopherize.me/). WebGo stays out of developers' way, so sitback and enjoy a cup of coffee. diff --git a/vendor/github.com/bnkamalesh/webgo/v6/_config.yml b/vendor/github.com/bnkamalesh/webgo/v6/_config.yml new file mode 100644 index 0000000..c419263 --- /dev/null +++ b/vendor/github.com/bnkamalesh/webgo/v6/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-cayman \ No newline at end of file diff --git a/vendor/github.com/bnkamalesh/webgo/v6/config.go b/vendor/github.com/bnkamalesh/webgo/v6/config.go new file mode 100644 index 0000000..e9b4df0 --- /dev/null +++ b/vendor/github.com/bnkamalesh/webgo/v6/config.go @@ -0,0 +1,66 @@ +package webgo + +import ( + "encoding/json" + "io/ioutil" + "strconv" + "time" +) + +// Config is used for reading app's configuration from json file +type Config struct { + // Host is the host on which the server is listening + Host string `json:"host,omitempty"` + // Port is the port number where the server has to listen for the HTTP requests + Port string `json:"port,omitempty"` + + // CertFile is the TLS/SSL certificate file path, required for HTTPS + CertFile string `json:"certFile,omitempty"` + // KeyFile is the filepath of private key of the certificate + KeyFile string `json:"keyFile,omitempty"` + // HTTPSPort is the port number where the server has to listen for the HTTP requests + HTTPSPort string `json:"httpsPort,omitempty"` + + // ReadTimeout is the maximum duration for which the server would read a request + ReadTimeout time.Duration `json:"readTimeout,omitempty"` + // WriteTimeout is the maximum duration for which the server would try to respond + WriteTimeout time.Duration `json:"writeTimeout,omitempty"` + + // InsecureSkipVerify is the HTTP certificate verification + InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty"` + + // ShutdownTimeout is the duration in which graceful shutdown is completed + ShutdownTimeout time.Duration +} + +// Load config file from the provided filepath and validate +func (cfg *Config) Load(filepath string) { + file, err := ioutil.ReadFile(filepath) + if err != nil { + LOGHANDLER.Fatal(err) + } + + err = json.Unmarshal(file, cfg) + if err != nil { + LOGHANDLER.Fatal(err) + } + + err = cfg.Validate() + if err != nil { + LOGHANDLER.Fatal(ErrInvalidPort) + } +} + +// Validate the config parsed into the Config struct +func (cfg *Config) Validate() error { + i, err := strconv.Atoi(cfg.Port) + if err != nil { + return ErrInvalidPort + } + + if i <= 0 || i > 65535 { + return ErrInvalidPort + } + + return nil +} diff --git a/vendor/github.com/bnkamalesh/webgo/v6/errors.go b/vendor/github.com/bnkamalesh/webgo/v6/errors.go new file mode 100644 index 0000000..0ebeff3 --- /dev/null +++ b/vendor/github.com/bnkamalesh/webgo/v6/errors.go @@ -0,0 +1,145 @@ +package webgo + +import ( + "errors" + "io" + "log" + "os" +) + +var ( + // ErrInvalidPort is the error returned when the port number provided in the config file is invalid + ErrInvalidPort = errors.New("Port number not provided or is invalid (should be between 0 - 65535)") + + lh *logHandler +) + +type logCfg string + +const ( + // LogCfgDisableDebug is used to disable debug logs + LogCfgDisableDebug = logCfg("disable-debug") + // LogCfgDisableInfo is used to disable info logs + LogCfgDisableInfo = logCfg("disable-info") + // LogCfgDisableWarn is used to disable warning logs + LogCfgDisableWarn = logCfg("disable-warn") + // LogCfgDisableError is used to disable error logs + LogCfgDisableError = logCfg("disable-err") + // LogCfgDisableFatal is used to disable fatal logs + LogCfgDisableFatal = logCfg("disable-fatal") +) + +// Logger defines all the logging methods to be implemented +type Logger interface { + Debug(data ...interface{}) + Info(data ...interface{}) + Warn(data ...interface{}) + Error(data ...interface{}) + Fatal(data ...interface{}) +} + +// logHandler has all the log writer handlers +type logHandler struct { + debug *log.Logger + info *log.Logger + warn *log.Logger + err *log.Logger + fatal *log.Logger +} + +// Debug prints log of severity 5 +func (lh *logHandler) Debug(data ...interface{}) { + if lh.debug == nil { + return + } + lh.debug.Println(data...) +} + +// Info prints logs of severity 4 +func (lh *logHandler) Info(data ...interface{}) { + if lh.info == nil { + return + } + lh.info.Println(data...) +} + +// Warn prints log of severity 3 +func (lh *logHandler) Warn(data ...interface{}) { + if lh.warn == nil { + return + } + lh.warn.Println(data...) +} + +// Error prints log of severity 2 +func (lh *logHandler) Error(data ...interface{}) { + if lh.err == nil { + return + } + lh.err.Println(data...) +} + +// Fatal prints log of severity 1 +func (lh *logHandler) Fatal(data ...interface{}) { + if lh.fatal == nil { + return + } + lh.fatal.Fatalln(data...) +} + +// LOGHANDLER is a global variable which webgo uses to log messages +var LOGHANDLER Logger + +func init() { + GlobalLoggerConfig(nil, nil) +} + +func loggerWithCfg(stdout io.Writer, stderr io.Writer, cfgs ...logCfg) *logHandler { + lh = &logHandler{ + debug: log.New(stdout, "Debug ", log.LstdFlags), + info: log.New(stdout, "Info ", log.LstdFlags), + warn: log.New(stderr, "Warning ", log.LstdFlags), + err: log.New(stderr, "Error ", log.LstdFlags), + fatal: log.New(stderr, "Fatal ", log.LstdFlags|log.Llongfile), + } + + for _, c := range cfgs { + switch c { + case LogCfgDisableDebug: + { + lh.debug = nil + } + case LogCfgDisableInfo: + { + lh.info = nil + } + case LogCfgDisableWarn: + { + lh.warn = nil + } + case LogCfgDisableError: + { + lh.err = nil + } + case LogCfgDisableFatal: + { + lh.fatal = nil + } + } + } + return lh +} + +// GlobalLoggerConfig is used to configure the global/default logger of webgo +// IMPORTANT: This is not concurrent safe +func GlobalLoggerConfig(stdout io.Writer, stderr io.Writer, cfgs ...logCfg) { + if stdout == nil { + stdout = os.Stdout + } + + if stderr == nil { + stderr = os.Stderr + } + + LOGHANDLER = loggerWithCfg(stdout, stderr, cfgs...) +} diff --git a/vendor/github.com/bnkamalesh/webgo/v6/go.mod b/vendor/github.com/bnkamalesh/webgo/v6/go.mod new file mode 100644 index 0000000..9859f9c --- /dev/null +++ b/vendor/github.com/bnkamalesh/webgo/v6/go.mod @@ -0,0 +1,3 @@ +module github.com/bnkamalesh/webgo/v6 + +go 1.17 diff --git a/vendor/github.com/bnkamalesh/webgo/v6/responses.go b/vendor/github.com/bnkamalesh/webgo/v6/responses.go new file mode 100644 index 0000000..206cb09 --- /dev/null +++ b/vendor/github.com/bnkamalesh/webgo/v6/responses.go @@ -0,0 +1,160 @@ +package webgo + +import ( + "encoding/json" + "fmt" + "html/template" + "net/http" +) + +// ErrorData used to render the error page +type ErrorData struct { + ErrCode int + ErrDescription string +} + +// dOutput is the standard/valid output wrapped in `{data: , status: }` +type dOutput struct { + Data interface{} `json:"data"` + Status int `json:"status"` +} + +// errOutput is the error output wrapped in `{errors:, status: }` +type errOutput struct { + Errors interface{} `json:"errors"` + Status int `json:"status"` +} + +const ( + // HeaderContentType is the key for mentioning the response header content type + HeaderContentType = "Content-Type" + // JSONContentType is the MIME type when the response is JSON + JSONContentType = "application/json" + // HTMLContentType is the MIME type when the response is HTML + HTMLContentType = "text/html; charset=UTF-8" + + // ErrInternalServer to send when there's an internal server error + ErrInternalServer = "Internal server error" +) + +// SendHeader is used to send only a response header, i.e no response body +func SendHeader(w http.ResponseWriter, rCode int) { + w.WriteHeader(rCode) +} + +func crwAsserter(w http.ResponseWriter, rCode int) http.ResponseWriter { + if crw, ok := w.(*customResponseWriter); ok { + crw.statusCode = rCode + return crw + } + + return newCRW(w, rCode) +} + +// Send sends a completely custom response without wrapping in the +// `{data: , status: ` struct +func Send(w http.ResponseWriter, contentType string, data interface{}, rCode int) { + w = crwAsserter(w, rCode) + w.Header().Set(HeaderContentType, contentType) + _, err := fmt.Fprint(w, data) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(ErrInternalServer)) + LOGHANDLER.Error(err) + } +} + +// SendResponse is used to respond to any request (JSON response) based on the code, data etc. +func SendResponse(w http.ResponseWriter, data interface{}, rCode int) { + w = crwAsserter(w, rCode) + w.Header().Add(HeaderContentType, JSONContentType) + err := json.NewEncoder(w).Encode(dOutput{Data: data, Status: rCode}) + if err != nil { + /* + In case of encoding error, send "internal server error" and + log the actual error. + */ + R500(w, ErrInternalServer) + LOGHANDLER.Error(err) + } +} + +// SendError is used to respond to any request with an error +func SendError(w http.ResponseWriter, data interface{}, rCode int) { + w = crwAsserter(w, rCode) + w.Header().Add(HeaderContentType, JSONContentType) + err := json.NewEncoder(w).Encode(errOutput{data, rCode}) + if err != nil { + /* + In case of encoding error, send "internal server error" and + log the actual error. + */ + R500(w, ErrInternalServer) + LOGHANDLER.Error(err) + } +} + +// Render is used for rendering templates (HTML) +func Render(w http.ResponseWriter, data interface{}, rCode int, tpl *template.Template) { + w = crwAsserter(w, rCode) + + // In case of HTML response, setting appropriate header type for text/HTML response + w.Header().Set(HeaderContentType, HTMLContentType) + + // Rendering an HTML template with appropriate data + err := tpl.Execute(w, data) + if err != nil { + Send(w, "text/plain", ErrInternalServer, http.StatusInternalServerError) + LOGHANDLER.Error(err.Error()) + } +} + +// R200 - Successful/OK response +func R200(w http.ResponseWriter, data interface{}) { + SendResponse(w, data, http.StatusOK) +} + +// R201 - New item created +func R201(w http.ResponseWriter, data interface{}) { + SendResponse(w, data, http.StatusCreated) +} + +// R204 - empty, no content +func R204(w http.ResponseWriter) { + SendHeader(w, http.StatusNoContent) +} + +// R302 - Temporary redirect +func R302(w http.ResponseWriter, data interface{}) { + SendResponse(w, data, http.StatusFound) +} + +// R400 - Invalid request, any incorrect/erraneous value in the request body +func R400(w http.ResponseWriter, data interface{}) { + SendError(w, data, http.StatusBadRequest) +} + +// R403 - Unauthorized access +func R403(w http.ResponseWriter, data interface{}) { + SendError(w, data, http.StatusForbidden) +} + +// R404 - Resource not found +func R404(w http.ResponseWriter, data interface{}) { + SendError(w, data, http.StatusNotFound) +} + +// R406 - Unacceptable header. For any error related to values set in header +func R406(w http.ResponseWriter, data interface{}) { + SendError(w, data, http.StatusNotAcceptable) +} + +// R451 - Resource taken down because of a legal request +func R451(w http.ResponseWriter, data interface{}) { + SendError(w, data, http.StatusUnavailableForLegalReasons) +} + +// R500 - Internal server error +func R500(w http.ResponseWriter, data interface{}) { + SendError(w, data, http.StatusInternalServerError) +} diff --git a/vendor/github.com/bnkamalesh/webgo/v6/route.go b/vendor/github.com/bnkamalesh/webgo/v6/route.go new file mode 100644 index 0000000..f38f420 --- /dev/null +++ b/vendor/github.com/bnkamalesh/webgo/v6/route.go @@ -0,0 +1,247 @@ +package webgo + +import ( + "fmt" + "net/http" + "regexp" + "strings" +) + +// Route defines a route for each API +type Route struct { + // Name is unique identifier for the route + Name string + // Method is the HTTP request method/type + Method string + // Pattern is the URI pattern to match + Pattern string + // TrailingSlash if set to true, the URI will be matched with or without + // a trailing slash. IMPORTANT: It does not redirect. + TrailingSlash bool + + // FallThroughPostResponse if enabled will execute all the handlers even if a response was already sent to the client + FallThroughPostResponse bool + + // Handlers is a slice of http.HandlerFunc which can be middlewares or anything else. Though only 1 of them will be allowed to respond to client. + // subsequent writes from the following handlers will be ignored + Handlers []http.HandlerFunc + + // uriKeys is the list of URI parameter variables available for this route + uriKeys []string + // uriPatternString is the pattern string which is compiled to regex object + uriPatternString string + // uriPattern is the compiled regex to match the URI pattern + uriPattern *regexp.Regexp + + // skipMiddleware if true, middleware added using `router` will not be applied to this Route. + // This is used only when a Route is set using the RouteGroup, which can have its own set of middleware + skipMiddleware bool + + initialized bool + + serve http.HandlerFunc +} + +// computePatternStr computes the pattern string required for generating the route's regex. +// It also adds the URI parameter key to the route's `keys` field +func (r *Route) computePatternStr(patternString string, hasWildcard bool, key string) (string, error) { + regexPattern := "" + patternKey := "" + if hasWildcard { + patternKey = fmt.Sprintf(":%s*", key) + regexPattern = urlwildcard + if r.TrailingSlash { + regexPattern = urlwildcardWithTrailslash + } + } else { + patternKey = fmt.Sprintf(":%s", key) + regexPattern = urlchars + } + + patternString = strings.Replace(patternString, patternKey, regexPattern, 1) + + for idx, k := range r.uriKeys { + if key == k { + return "", fmt.Errorf( + "%s\nURI:%s\nKey:%s, Position: %d", + errDuplicateKey, + r.Pattern, + k, + idx+1, + ) + } + } + + r.uriKeys = append(r.uriKeys, key) + return patternString, nil +} + +func (r *Route) parseURIWithParams(patternString string) (string, error) { + if !strings.Contains(r.Pattern, ":") { + return patternString, nil + } + + var err error + // uriValues is a map of URI Key and its respective value, + // this is calculated per request + key := "" + hasKey := false + hasWildcard := false + + for i := 0; i < len(r.Pattern); i++ { + char := string(r.Pattern[i]) + + if char == ":" { + hasKey = true + } else if char == "*" { + hasWildcard = true + } else if hasKey && char != "/" { + key += char + } else if hasKey && len(key) > 0 { + patternString, err = r.computePatternStr(patternString, hasWildcard, key) + if err != nil { + return "", err + } + hasWildcard, hasKey = false, false + key = "" + } + } + + if hasKey && len(key) > 0 { + patternString, err = r.computePatternStr(patternString, hasWildcard, key) + if err != nil { + return "", err + } + } + return patternString, nil +} + +// init prepares the URIKeys, compile regex for the provided pattern +func (r *Route) init() error { + if r.initialized { + return nil + } + + patternString := r.Pattern + + patternString, err := r.parseURIWithParams(patternString) + if err != nil { + return err + } + + if r.TrailingSlash { + patternString = fmt.Sprintf("^%s%s$", patternString, trailingSlash) + } else { + patternString = fmt.Sprintf("^%s$", patternString) + } + + // compile the regex for the pattern string calculated + reg, err := regexp.Compile(patternString) + if err != nil { + return err + } + + r.uriPattern = reg + r.uriPatternString = patternString + r.serve = defaultRouteServe(r) + + r.initialized = true + return nil +} + +// matchPath matches the requestURI with the URI pattern of the route. +// If the path is an exact match (i.e. no URI parameters), then the second parameter ('isExactMatch') is true +func (r *Route) matchPath(requestURI string) (bool, isExactMatch bool) { + if r.Pattern == requestURI { + return true, true + } + + return r.uriPattern.Match([]byte(requestURI)), false +} + +func (r *Route) params(requestURI string) map[string]string { + params := r.uriPattern.FindStringSubmatch(requestURI)[1:] + uriValues := make(map[string]string, len(params)) + + for i := 0; i < len(params); i++ { + uriValues[r.uriKeys[i]] = params[i] + } + + return uriValues +} + +func (r *Route) use(mm ...Middleware) { + for idx := range mm { + m := mm[idx] + srv := r.serve + r.serve = func(rw http.ResponseWriter, req *http.Request) { + m(rw, req, srv) + } + } +} + +func routeServeChainedHandlers(r *Route) http.HandlerFunc { + return func(rw http.ResponseWriter, req *http.Request) { + + crw, ok := rw.(*customResponseWriter) + if !ok { + crw = newCRW(rw, http.StatusOK) + } + + for _, handler := range r.Handlers { + if crw.written && !r.FallThroughPostResponse { + break + } + handler(crw, req) + } + } +} + +func defaultRouteServe(r *Route) http.HandlerFunc { + if len(r.Handlers) > 1 { + return routeServeChainedHandlers(r) + } + + // when there is only 1 handler, custom response writer is not required to check if response + // is already written or fallthrough is enabled + return r.Handlers[0] +} + +type RouteGroup struct { + routes []*Route + // skipRouterMiddleware if set to true, middleware applied to the router will not be applied + // to this route group. + skipRouterMiddleware bool + // PathPrefix is the URI prefix for all routes in this group + PathPrefix string +} + +func (rg *RouteGroup) Add(rr ...Route) { + for idx := range rr { + route := rr[idx] + route.skipMiddleware = rg.skipRouterMiddleware + route.Pattern = fmt.Sprintf("%s%s", rg.PathPrefix, route.Pattern) + _ = route.init() + rg.routes = append(rg.routes, &route) + } +} + +func (rg *RouteGroup) Use(mm ...Middleware) { + for idx := range rg.routes { + route := rg.routes[idx] + route.use(mm...) + } +} + +func (rg *RouteGroup) Routes() []*Route { + return rg.routes +} + +func NewRouteGroup(pathPrefix string, skipRouterMiddleware bool, rr ...Route) *RouteGroup { + rg := RouteGroup{ + PathPrefix: pathPrefix, + skipRouterMiddleware: skipRouterMiddleware, + } + rg.Add(rr...) + return &rg +} diff --git a/vendor/github.com/bnkamalesh/webgo/v6/router.go b/vendor/github.com/bnkamalesh/webgo/v6/router.go new file mode 100644 index 0000000..78b02d1 --- /dev/null +++ b/vendor/github.com/bnkamalesh/webgo/v6/router.go @@ -0,0 +1,410 @@ +package webgo + +import ( + "bufio" + "context" + "errors" + "fmt" + "net" + "net/http" + "sync" +) + +// urlchars is regex to validate characters in a URI parameter +// const urlchars = `([a-zA-Z0-9\*\-+._~!$()=&',;:@%]+)` +// Regex prepared based on http://stackoverflow.com/a/4669750/1359163, +// https://tools.ietf.org/html/rfc3986 +// Though the current one allows invalid characters in the URI parameter, it has better performance. +const ( + urlchars = `([^/]+)` + urlwildcard = `(.*)[^/]` + urlwildcardWithTrailslash = `(.*)[/]?` + trailingSlash = `[/]?` + errDuplicateKey = `Error: Duplicate URI keys found` +) + +var ( + validHTTPMethods = []string{ + http.MethodOptions, + http.MethodHead, + http.MethodGet, + http.MethodPost, + http.MethodPut, + http.MethodPatch, + http.MethodDelete, + } + + ctxPool = &sync.Pool{ + New: func() interface{} { + return new(ContextPayload) + }, + } + crwPool = &sync.Pool{ + New: func() interface{} { + return new(customResponseWriter) + }, + } +) + +// customResponseWriter is a custom HTTP response writer +type customResponseWriter struct { + http.ResponseWriter + statusCode int + written bool + headerWritten bool +} + +// WriteHeader is the interface implementation to get HTTP response code and add +// it to the custom response writer +func (crw *customResponseWriter) WriteHeader(code int) { + if crw.headerWritten { + return + } + + crw.headerWritten = true + crw.statusCode = code + crw.ResponseWriter.WriteHeader(code) +} + +// Write is the interface implementation to respond to the HTTP request, +// but check if a response was already sent. +func (crw *customResponseWriter) Write(body []byte) (int, error) { + crw.WriteHeader(crw.statusCode) + crw.written = true + return crw.ResponseWriter.Write(body) +} + +// Flush calls the http.Flusher to clear/flush the buffer +func (crw *customResponseWriter) Flush() { + if rw, ok := crw.ResponseWriter.(http.Flusher); ok { + rw.Flush() + } +} + +// Hijack implements the http.Hijacker interface +func (crw *customResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { + if hj, ok := crw.ResponseWriter.(http.Hijacker); ok { + return hj.Hijack() + } + + return nil, nil, errors.New("unable to create hijacker") +} + +// CloseNotify implements the http.CloseNotifier interface +func (crw *customResponseWriter) CloseNotify() <-chan bool { + if n, ok := crw.ResponseWriter.(http.CloseNotifier); ok { + return n.CloseNotify() + } + return nil +} + +func (crw *customResponseWriter) reset() { + crw.statusCode = 0 + crw.written = false + crw.headerWritten = false + crw.ResponseWriter = nil +} + +// Middleware is the signature of WebGo's middleware +type Middleware func(http.ResponseWriter, *http.Request, http.HandlerFunc) + +// discoverRoute returns the correct 'route', for the given request +func discoverRoute(path string, routes []*Route) *Route { + for _, route := range routes { + if ok, _ := route.matchPath(path); ok { + return route + } + } + return nil +} + +// Router is the HTTP router +type Router struct { + optHandlers []*Route + headHandlers []*Route + getHandlers []*Route + postHandlers []*Route + putHandlers []*Route + patchHandlers []*Route + deleteHandlers []*Route + allHandlers map[string][]*Route + + // NotFound is the generic handler for 404 resource not found response + NotFound http.HandlerFunc + + // NotImplemented is the generic handler for 501 method not implemented + NotImplemented http.HandlerFunc + + // config has all the app config + config *Config + + // httpServer is the server handler for the active HTTP server + httpServer *http.Server + // httpsServer is the server handler for the active HTTPS server + httpsServer *http.Server +} + +// methodRoutes returns the list of Routes handling the HTTP method given the request +func (rtr *Router) methodRoutes(method string) (routes []*Route) { + switch method { + case http.MethodOptions: + return rtr.optHandlers + case http.MethodHead: + return rtr.headHandlers + case http.MethodGet: + return rtr.getHandlers + case http.MethodPost: + return rtr.postHandlers + case http.MethodPut: + return rtr.putHandlers + case http.MethodPatch: + return rtr.patchHandlers + case http.MethodDelete: + return rtr.deleteHandlers + } + + return nil +} + +func (rtr *Router) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + // a custom response writer is used to set appropriate HTTP status code in case of + // encoding errors. i.e. if there's a JSON encoding issue while responding, + // the HTTP status code would say 200, and and the JSON payload {"status": 500} + crw := newCRW(rw, http.StatusOK) + + routes := rtr.methodRoutes(r.Method) + if routes == nil { + // serve 501 when HTTP method is not implemented + crw.statusCode = http.StatusNotImplemented + rtr.NotImplemented(crw, r) + releaseCRW(crw) + return + } + + path := r.URL.EscapedPath() + route := discoverRoute(path, routes) + if route == nil { + // serve 404 when there are no matching routes + crw.statusCode = http.StatusNotFound + rtr.NotFound(crw, r) + releaseCRW(crw) + return + } + + ctxPayload := newContext() + ctxPayload.path = path + ctxPayload.Route = route + + // webgo context is injected to the HTTP request context + *r = *r.WithContext( + context.WithValue( + r.Context(), + wgoCtxKey, + ctxPayload, + ), + ) + + route.serve(crw, r) + + // IMPORTANT/TODO: if the handler panics, resources are not released from the pool. + // `defer releasePoolResources(crw, ctxPayload)` would solve the problem but with a potential performance hit + releasePoolResources(crw, ctxPayload) +} + +// Use adds a middleware layer +func (rtr *Router) Use(mm ...Middleware) { + for _, handlers := range rtr.allHandlers { + for idx := range handlers { + route := handlers[idx] + if route.skipMiddleware { + continue + } + + route.use(mm...) + } + } +} + +// UseOnSpecialHandlers adds middleware to the 2 special handlers of webgo +func (rtr *Router) UseOnSpecialHandlers(mm ...Middleware) { + // v3.2.1 introduced the feature of adding middleware to both notfound & not implemented + // handlers + /* + - It was added considering an `accesslog` middleware, where all requests should be logged + # This is now being moved to a separate function considering an authentication middleware, where all requests + including 404 & 501 would respond with `not authenticated` if you do not have special handling + within the middleware. It is a cleaner implementation to avoid this and let users add their + middleware separately to NOTFOUND & NOTIMPLEMENTED handlers + */ + + for idx := range mm { + m := mm[idx] + nf := rtr.NotFound + rtr.NotFound = func(rw http.ResponseWriter, req *http.Request) { + m(rw, req, nf) + } + + ni := rtr.NotImplemented + rtr.NotImplemented = func(rw http.ResponseWriter, req *http.Request) { + m(rw, req, ni) + } + } +} + +// Add is a convenience method used to add a new route to an already initialized router +// Important: `.Use` should be used only after all routes are added +func (rtr *Router) Add(routes ...*Route) { + hmap := httpHandlers(routes) + rtr.optHandlers = append(rtr.optHandlers, hmap[http.MethodOptions]...) + rtr.headHandlers = append(rtr.headHandlers, hmap[http.MethodHead]...) + rtr.getHandlers = append(rtr.getHandlers, hmap[http.MethodGet]...) + rtr.postHandlers = append(rtr.postHandlers, hmap[http.MethodPost]...) + rtr.putHandlers = append(rtr.putHandlers, hmap[http.MethodPut]...) + rtr.patchHandlers = append(rtr.patchHandlers, hmap[http.MethodPatch]...) + rtr.deleteHandlers = append(rtr.deleteHandlers, hmap[http.MethodDelete]...) + + all := rtr.allHandlers + if all == nil { + all = map[string][]*Route{} + } + + for _, key := range supportedHTTPMethods { + newlist, hasKey := hmap[key] + if !hasKey { + continue + } + if all[key] == nil { + all[key] = make([]*Route, 0, len(hmap)) + } + all[key] = append(all[key], newlist...) + } + + rtr.allHandlers = all +} + +func newCRW(rw http.ResponseWriter, rCode int) *customResponseWriter { + crw := crwPool.Get().(*customResponseWriter) + crw.ResponseWriter = rw + crw.statusCode = rCode + return crw +} + +func releaseCRW(crw *customResponseWriter) { + crw.reset() + crwPool.Put(crw) +} + +func newContext() *ContextPayload { + return ctxPool.Get().(*ContextPayload) +} + +func releaseContext(cp *ContextPayload) { + cp.reset() + ctxPool.Put(cp) +} + +func releasePoolResources(crw *customResponseWriter, cp *ContextPayload) { + releaseCRW(crw) + releaseContext(cp) +} + +// NewRouter initializes & returns a new router instance with all the configurations and routes set +func NewRouter(cfg *Config, routes ...*Route) *Router { + r := &Router{ + NotFound: http.NotFound, + NotImplemented: func(rw http.ResponseWriter, req *http.Request) { + Send(rw, "", "501 Not Implemented", http.StatusNotImplemented) + }, + config: cfg, + } + + r.Add(routes...) + + return r +} + +// checkDuplicateRoutes checks if any of the routes have duplicate name or URI pattern +func checkDuplicateRoutes(idx int, route *Route, routes []*Route) { + // checking if the URI pattern is duplicated + for i := 0; i < idx; i++ { + rt := routes[i] + + if rt.Name == route.Name { + LOGHANDLER.Info( + fmt.Sprintf( + "Duplicate route name('%s') detected", + rt.Name, + ), + ) + } + + if rt.Method != route.Method { + continue + } + + // regex pattern match + if ok, _ := rt.matchPath(route.Pattern); !ok { + continue + } + + LOGHANDLER.Warn( + fmt.Sprintf( + "Duplicate URI pattern detected.\nPattern: '%s'\nDuplicate pattern: '%s'", + rt.Pattern, + route.Pattern, + ), + ) + LOGHANDLER.Warn("Only the first route to match the URI pattern would handle the request") + } +} + +// httpHandlers returns all the handlers in a map, for each HTTP method +func httpHandlers(routes []*Route) map[string][]*Route { + handlers := map[string][]*Route{} + + handlers[http.MethodHead] = []*Route{} + handlers[http.MethodGet] = []*Route{} + + for idx, route := range routes { + found := false + for _, validMethod := range validHTTPMethods { + if route.Method == validMethod { + found = true + break + } + } + + if !found { + LOGHANDLER.Fatal( + fmt.Sprintf( + "Unsupported HTTP method provided. Method: '%s'", + route.Method, + ), + ) + return nil + } + + if route.Handlers == nil || len(route.Handlers) == 0 { + LOGHANDLER.Fatal( + fmt.Sprintf( + "No handlers provided for the route '%s', method '%s'", + route.Pattern, + route.Method, + ), + ) + return nil + } + + err := route.init() + if err != nil { + LOGHANDLER.Fatal("Unsupported URI pattern.", route.Pattern, err) + return nil + } + + checkDuplicateRoutes(idx, route, routes) + + handlers[route.Method] = append(handlers[route.Method], route) + } + + return handlers +} diff --git a/vendor/github.com/bnkamalesh/webgo/v6/webgo.go b/vendor/github.com/bnkamalesh/webgo/v6/webgo.go new file mode 100644 index 0000000..e75ae8b --- /dev/null +++ b/vendor/github.com/bnkamalesh/webgo/v6/webgo.go @@ -0,0 +1,188 @@ +/* +Package webgo is a lightweight framework for building web apps. It has a multiplexer, +middleware plugging mechanism & context management of its own. The primary goal +of webgo is to get out of the developer's way as much as possible. i.e. it does +not enforce you to build your app in any particular pattern, instead just helps you +get all the trivial things done faster and easier. + +e.g. +1. Getting named URI parameters. +2. Multiplexer for regex matching of URI and such. +3. Inject special app level configurations or any such objects to the request context as required. +*/ +package webgo + +import ( + "context" + "crypto/tls" + "net/http" +) + +var supportedHTTPMethods = []string{ + http.MethodOptions, + http.MethodHead, + http.MethodGet, + http.MethodPost, + http.MethodPut, + http.MethodPatch, + http.MethodDelete, +} + +// ctxkey is a custom string type to store the WebGo context inside HTTP request context +type ctxkey string + +const wgoCtxKey = ctxkey("webgocontext") + +// ContextPayload is the WebgoContext. A new instance of ContextPayload is injected inside every request's context object +type ContextPayload struct { + Route *Route + Err error + path string +} + +// Params returns the URI parameters of the respective route +func (cp *ContextPayload) Params() map[string]string { + return cp.Route.params(cp.path) +} + +func (cp *ContextPayload) reset() { + cp.Route = nil + cp.path = "" + cp.Err = nil +} + +// SetError sets the err within the context +func (cp *ContextPayload) SetError(err error) { + cp.Err = err +} + +// Error returns the error set within the context +func (cp *ContextPayload) Error() error { + return cp.Err +} + +// Context returns the ContextPayload injected inside the HTTP request context +func Context(r *http.Request) *ContextPayload { + return r.Context().Value(wgoCtxKey).(*ContextPayload) +} + +// SetError is a helper function to set the error in webgo context +func SetError(r *http.Request, err error) { + ctx := Context(r) + ctx.SetError(err) +} + +// GetError is a helper function to get the error from webgo context +func GetError(r *http.Request) error { + return Context(r).Error() +} + +// ResponseStatus returns the response status code. It works only if the http.ResponseWriter +// is not wrapped in another response writer before calling ResponseStatus +func ResponseStatus(rw http.ResponseWriter) int { + crw, ok := rw.(*customResponseWriter) + if !ok { + return http.StatusOK + } + return crw.statusCode +} + +// StartHTTPS starts the server with HTTPS enabled +func (router *Router) StartHTTPS() { + cfg := router.config + if cfg.CertFile == "" { + LOGHANDLER.Fatal("No certificate provided for HTTPS") + } + + if cfg.KeyFile == "" { + LOGHANDLER.Fatal("No key file provided for HTTPS") + } + + host := cfg.Host + if len(cfg.HTTPSPort) > 0 { + host += ":" + cfg.HTTPSPort + } + + router.httpsServer = &http.Server{ + Addr: host, + Handler: router, + ReadTimeout: cfg.ReadTimeout, + WriteTimeout: cfg.WriteTimeout, + TLSConfig: &tls.Config{ + InsecureSkipVerify: cfg.InsecureSkipVerify, + }, + } + + LOGHANDLER.Info("HTTPS server, listening on", host) + err := router.httpsServer.ListenAndServeTLS(cfg.CertFile, cfg.KeyFile) + if err != nil && err != http.ErrServerClosed { + LOGHANDLER.Error("HTTPS server exited with error:", err.Error()) + } +} + +// Start starts the HTTP server with the appropriate configurations +func (router *Router) Start() { + cfg := router.config + host := cfg.Host + + if len(cfg.Port) > 0 { + host += ":" + cfg.Port + } + + router.httpServer = &http.Server{ + Addr: host, + Handler: router, + ReadTimeout: cfg.ReadTimeout, + WriteTimeout: cfg.WriteTimeout, + } + LOGHANDLER.Info("HTTP server, listening on", host) + err := router.httpServer.ListenAndServe() + if err != nil && err != http.ErrServerClosed { + LOGHANDLER.Error("HTTP server exited with error:", err.Error()) + } +} + +// Shutdown gracefully shuts down HTTP server +func (router *Router) Shutdown() error { + if router.httpServer == nil { + return nil + } + timer := router.config.ShutdownTimeout + + ctx, cancel := context.WithTimeout(context.TODO(), timer) + defer cancel() + + err := router.httpServer.Shutdown(ctx) + if err != nil { + LOGHANDLER.Error(err) + } + return err +} + +// ShutdownHTTPS gracefully shuts down HTTPS server +func (router *Router) ShutdownHTTPS() error { + if router.httpsServer == nil { + return nil + } + timer := router.config.ShutdownTimeout + + ctx, cancel := context.WithTimeout(context.TODO(), timer) + defer cancel() + + err := router.httpsServer.Shutdown(ctx) + if err != nil && err != http.ErrServerClosed { + LOGHANDLER.Error(err) + } + return err +} + +// OriginalResponseWriter returns the Go response writer stored within the webgo custom response +// writer +func OriginalResponseWriter(rw http.ResponseWriter) http.ResponseWriter { + crw, ok := rw.(*customResponseWriter) + if !ok { + return nil + } + + return crw.ResponseWriter +} diff --git a/vendor/github.com/cespare/xxhash/v2/LICENSE.txt b/vendor/github.com/cespare/xxhash/v2/LICENSE.txt new file mode 100644 index 0000000..24b5306 --- /dev/null +++ b/vendor/github.com/cespare/xxhash/v2/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright (c) 2016 Caleb Spare + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/cespare/xxhash/v2/README.md b/vendor/github.com/cespare/xxhash/v2/README.md new file mode 100644 index 0000000..792b4a6 --- /dev/null +++ b/vendor/github.com/cespare/xxhash/v2/README.md @@ -0,0 +1,69 @@ +# xxhash + +[![Go Reference](https://pkg.go.dev/badge/github.com/cespare/xxhash/v2.svg)](https://pkg.go.dev/github.com/cespare/xxhash/v2) +[![Test](https://github.com/cespare/xxhash/actions/workflows/test.yml/badge.svg)](https://github.com/cespare/xxhash/actions/workflows/test.yml) + +xxhash is a Go implementation of the 64-bit +[xxHash](http://cyan4973.github.io/xxHash/) algorithm, XXH64. This is a +high-quality hashing algorithm that is much faster than anything in the Go +standard library. + +This package provides a straightforward API: + +``` +func Sum64(b []byte) uint64 +func Sum64String(s string) uint64 +type Digest struct{ ... } + func New() *Digest +``` + +The `Digest` type implements hash.Hash64. Its key methods are: + +``` +func (*Digest) Write([]byte) (int, error) +func (*Digest) WriteString(string) (int, error) +func (*Digest) Sum64() uint64 +``` + +This implementation provides a fast pure-Go implementation and an even faster +assembly implementation for amd64. + +## Compatibility + +This package is in a module and the latest code is in version 2 of the module. +You need a version of Go with at least "minimal module compatibility" to use +github.com/cespare/xxhash/v2: + +* 1.9.7+ for Go 1.9 +* 1.10.3+ for Go 1.10 +* Go 1.11 or later + +I recommend using the latest release of Go. + +## Benchmarks + +Here are some quick benchmarks comparing the pure-Go and assembly +implementations of Sum64. + +| input size | purego | asm | +| --- | --- | --- | +| 5 B | 979.66 MB/s | 1291.17 MB/s | +| 100 B | 7475.26 MB/s | 7973.40 MB/s | +| 4 KB | 17573.46 MB/s | 17602.65 MB/s | +| 10 MB | 17131.46 MB/s | 17142.16 MB/s | + +These numbers were generated on Ubuntu 18.04 with an Intel i7-8700K CPU using +the following commands under Go 1.11.2: + +``` +$ go test -tags purego -benchtime 10s -bench '/xxhash,direct,bytes' +$ go test -benchtime 10s -bench '/xxhash,direct,bytes' +``` + +## Projects using this package + +- [InfluxDB](https://github.com/influxdata/influxdb) +- [Prometheus](https://github.com/prometheus/prometheus) +- [VictoriaMetrics](https://github.com/VictoriaMetrics/VictoriaMetrics) +- [FreeCache](https://github.com/coocood/freecache) +- [FastCache](https://github.com/VictoriaMetrics/fastcache) diff --git a/vendor/github.com/cespare/xxhash/v2/go.mod b/vendor/github.com/cespare/xxhash/v2/go.mod new file mode 100644 index 0000000..49f6760 --- /dev/null +++ b/vendor/github.com/cespare/xxhash/v2/go.mod @@ -0,0 +1,3 @@ +module github.com/cespare/xxhash/v2 + +go 1.11 diff --git a/vendor/github.com/cespare/xxhash/v2/go.sum b/vendor/github.com/cespare/xxhash/v2/go.sum new file mode 100644 index 0000000..e69de29 diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash.go b/vendor/github.com/cespare/xxhash/v2/xxhash.go new file mode 100644 index 0000000..15c835d --- /dev/null +++ b/vendor/github.com/cespare/xxhash/v2/xxhash.go @@ -0,0 +1,235 @@ +// Package xxhash implements the 64-bit variant of xxHash (XXH64) as described +// at http://cyan4973.github.io/xxHash/. +package xxhash + +import ( + "encoding/binary" + "errors" + "math/bits" +) + +const ( + prime1 uint64 = 11400714785074694791 + prime2 uint64 = 14029467366897019727 + prime3 uint64 = 1609587929392839161 + prime4 uint64 = 9650029242287828579 + prime5 uint64 = 2870177450012600261 +) + +// NOTE(caleb): I'm using both consts and vars of the primes. Using consts where +// possible in the Go code is worth a small (but measurable) performance boost +// by avoiding some MOVQs. Vars are needed for the asm and also are useful for +// convenience in the Go code in a few places where we need to intentionally +// avoid constant arithmetic (e.g., v1 := prime1 + prime2 fails because the +// result overflows a uint64). +var ( + prime1v = prime1 + prime2v = prime2 + prime3v = prime3 + prime4v = prime4 + prime5v = prime5 +) + +// Digest implements hash.Hash64. +type Digest struct { + v1 uint64 + v2 uint64 + v3 uint64 + v4 uint64 + total uint64 + mem [32]byte + n int // how much of mem is used +} + +// New creates a new Digest that computes the 64-bit xxHash algorithm. +func New() *Digest { + var d Digest + d.Reset() + return &d +} + +// Reset clears the Digest's state so that it can be reused. +func (d *Digest) Reset() { + d.v1 = prime1v + prime2 + d.v2 = prime2 + d.v3 = 0 + d.v4 = -prime1v + d.total = 0 + d.n = 0 +} + +// Size always returns 8 bytes. +func (d *Digest) Size() int { return 8 } + +// BlockSize always returns 32 bytes. +func (d *Digest) BlockSize() int { return 32 } + +// Write adds more data to d. It always returns len(b), nil. +func (d *Digest) Write(b []byte) (n int, err error) { + n = len(b) + d.total += uint64(n) + + if d.n+n < 32 { + // This new data doesn't even fill the current block. + copy(d.mem[d.n:], b) + d.n += n + return + } + + if d.n > 0 { + // Finish off the partial block. + copy(d.mem[d.n:], b) + d.v1 = round(d.v1, u64(d.mem[0:8])) + d.v2 = round(d.v2, u64(d.mem[8:16])) + d.v3 = round(d.v3, u64(d.mem[16:24])) + d.v4 = round(d.v4, u64(d.mem[24:32])) + b = b[32-d.n:] + d.n = 0 + } + + if len(b) >= 32 { + // One or more full blocks left. + nw := writeBlocks(d, b) + b = b[nw:] + } + + // Store any remaining partial block. + copy(d.mem[:], b) + d.n = len(b) + + return +} + +// Sum appends the current hash to b and returns the resulting slice. +func (d *Digest) Sum(b []byte) []byte { + s := d.Sum64() + return append( + b, + byte(s>>56), + byte(s>>48), + byte(s>>40), + byte(s>>32), + byte(s>>24), + byte(s>>16), + byte(s>>8), + byte(s), + ) +} + +// Sum64 returns the current hash. +func (d *Digest) Sum64() uint64 { + var h uint64 + + if d.total >= 32 { + v1, v2, v3, v4 := d.v1, d.v2, d.v3, d.v4 + h = rol1(v1) + rol7(v2) + rol12(v3) + rol18(v4) + h = mergeRound(h, v1) + h = mergeRound(h, v2) + h = mergeRound(h, v3) + h = mergeRound(h, v4) + } else { + h = d.v3 + prime5 + } + + h += d.total + + i, end := 0, d.n + for ; i+8 <= end; i += 8 { + k1 := round(0, u64(d.mem[i:i+8])) + h ^= k1 + h = rol27(h)*prime1 + prime4 + } + if i+4 <= end { + h ^= uint64(u32(d.mem[i:i+4])) * prime1 + h = rol23(h)*prime2 + prime3 + i += 4 + } + for i < end { + h ^= uint64(d.mem[i]) * prime5 + h = rol11(h) * prime1 + i++ + } + + h ^= h >> 33 + h *= prime2 + h ^= h >> 29 + h *= prime3 + h ^= h >> 32 + + return h +} + +const ( + magic = "xxh\x06" + marshaledSize = len(magic) + 8*5 + 32 +) + +// MarshalBinary implements the encoding.BinaryMarshaler interface. +func (d *Digest) MarshalBinary() ([]byte, error) { + b := make([]byte, 0, marshaledSize) + b = append(b, magic...) + b = appendUint64(b, d.v1) + b = appendUint64(b, d.v2) + b = appendUint64(b, d.v3) + b = appendUint64(b, d.v4) + b = appendUint64(b, d.total) + b = append(b, d.mem[:d.n]...) + b = b[:len(b)+len(d.mem)-d.n] + return b, nil +} + +// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface. +func (d *Digest) UnmarshalBinary(b []byte) error { + if len(b) < len(magic) || string(b[:len(magic)]) != magic { + return errors.New("xxhash: invalid hash state identifier") + } + if len(b) != marshaledSize { + return errors.New("xxhash: invalid hash state size") + } + b = b[len(magic):] + b, d.v1 = consumeUint64(b) + b, d.v2 = consumeUint64(b) + b, d.v3 = consumeUint64(b) + b, d.v4 = consumeUint64(b) + b, d.total = consumeUint64(b) + copy(d.mem[:], b) + d.n = int(d.total % uint64(len(d.mem))) + return nil +} + +func appendUint64(b []byte, x uint64) []byte { + var a [8]byte + binary.LittleEndian.PutUint64(a[:], x) + return append(b, a[:]...) +} + +func consumeUint64(b []byte) ([]byte, uint64) { + x := u64(b) + return b[8:], x +} + +func u64(b []byte) uint64 { return binary.LittleEndian.Uint64(b) } +func u32(b []byte) uint32 { return binary.LittleEndian.Uint32(b) } + +func round(acc, input uint64) uint64 { + acc += input * prime2 + acc = rol31(acc) + acc *= prime1 + return acc +} + +func mergeRound(acc, val uint64) uint64 { + val = round(0, val) + acc ^= val + acc = acc*prime1 + prime4 + return acc +} + +func rol1(x uint64) uint64 { return bits.RotateLeft64(x, 1) } +func rol7(x uint64) uint64 { return bits.RotateLeft64(x, 7) } +func rol11(x uint64) uint64 { return bits.RotateLeft64(x, 11) } +func rol12(x uint64) uint64 { return bits.RotateLeft64(x, 12) } +func rol18(x uint64) uint64 { return bits.RotateLeft64(x, 18) } +func rol23(x uint64) uint64 { return bits.RotateLeft64(x, 23) } +func rol27(x uint64) uint64 { return bits.RotateLeft64(x, 27) } +func rol31(x uint64) uint64 { return bits.RotateLeft64(x, 31) } diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.go b/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.go new file mode 100644 index 0000000..ad14b80 --- /dev/null +++ b/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.go @@ -0,0 +1,13 @@ +// +build !appengine +// +build gc +// +build !purego + +package xxhash + +// Sum64 computes the 64-bit xxHash digest of b. +// +//go:noescape +func Sum64(b []byte) uint64 + +//go:noescape +func writeBlocks(d *Digest, b []byte) int diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.s b/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.s new file mode 100644 index 0000000..be8db5b --- /dev/null +++ b/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.s @@ -0,0 +1,215 @@ +// +build !appengine +// +build gc +// +build !purego + +#include "textflag.h" + +// Register allocation: +// AX h +// SI pointer to advance through b +// DX n +// BX loop end +// R8 v1, k1 +// R9 v2 +// R10 v3 +// R11 v4 +// R12 tmp +// R13 prime1v +// R14 prime2v +// DI prime4v + +// round reads from and advances the buffer pointer in SI. +// It assumes that R13 has prime1v and R14 has prime2v. +#define round(r) \ + MOVQ (SI), R12 \ + ADDQ $8, SI \ + IMULQ R14, R12 \ + ADDQ R12, r \ + ROLQ $31, r \ + IMULQ R13, r + +// mergeRound applies a merge round on the two registers acc and val. +// It assumes that R13 has prime1v, R14 has prime2v, and DI has prime4v. +#define mergeRound(acc, val) \ + IMULQ R14, val \ + ROLQ $31, val \ + IMULQ R13, val \ + XORQ val, acc \ + IMULQ R13, acc \ + ADDQ DI, acc + +// func Sum64(b []byte) uint64 +TEXT ·Sum64(SB), NOSPLIT, $0-32 + // Load fixed primes. + MOVQ ·prime1v(SB), R13 + MOVQ ·prime2v(SB), R14 + MOVQ ·prime4v(SB), DI + + // Load slice. + MOVQ b_base+0(FP), SI + MOVQ b_len+8(FP), DX + LEAQ (SI)(DX*1), BX + + // The first loop limit will be len(b)-32. + SUBQ $32, BX + + // Check whether we have at least one block. + CMPQ DX, $32 + JLT noBlocks + + // Set up initial state (v1, v2, v3, v4). + MOVQ R13, R8 + ADDQ R14, R8 + MOVQ R14, R9 + XORQ R10, R10 + XORQ R11, R11 + SUBQ R13, R11 + + // Loop until SI > BX. +blockLoop: + round(R8) + round(R9) + round(R10) + round(R11) + + CMPQ SI, BX + JLE blockLoop + + MOVQ R8, AX + ROLQ $1, AX + MOVQ R9, R12 + ROLQ $7, R12 + ADDQ R12, AX + MOVQ R10, R12 + ROLQ $12, R12 + ADDQ R12, AX + MOVQ R11, R12 + ROLQ $18, R12 + ADDQ R12, AX + + mergeRound(AX, R8) + mergeRound(AX, R9) + mergeRound(AX, R10) + mergeRound(AX, R11) + + JMP afterBlocks + +noBlocks: + MOVQ ·prime5v(SB), AX + +afterBlocks: + ADDQ DX, AX + + // Right now BX has len(b)-32, and we want to loop until SI > len(b)-8. + ADDQ $24, BX + + CMPQ SI, BX + JG fourByte + +wordLoop: + // Calculate k1. + MOVQ (SI), R8 + ADDQ $8, SI + IMULQ R14, R8 + ROLQ $31, R8 + IMULQ R13, R8 + + XORQ R8, AX + ROLQ $27, AX + IMULQ R13, AX + ADDQ DI, AX + + CMPQ SI, BX + JLE wordLoop + +fourByte: + ADDQ $4, BX + CMPQ SI, BX + JG singles + + MOVL (SI), R8 + ADDQ $4, SI + IMULQ R13, R8 + XORQ R8, AX + + ROLQ $23, AX + IMULQ R14, AX + ADDQ ·prime3v(SB), AX + +singles: + ADDQ $4, BX + CMPQ SI, BX + JGE finalize + +singlesLoop: + MOVBQZX (SI), R12 + ADDQ $1, SI + IMULQ ·prime5v(SB), R12 + XORQ R12, AX + + ROLQ $11, AX + IMULQ R13, AX + + CMPQ SI, BX + JL singlesLoop + +finalize: + MOVQ AX, R12 + SHRQ $33, R12 + XORQ R12, AX + IMULQ R14, AX + MOVQ AX, R12 + SHRQ $29, R12 + XORQ R12, AX + IMULQ ·prime3v(SB), AX + MOVQ AX, R12 + SHRQ $32, R12 + XORQ R12, AX + + MOVQ AX, ret+24(FP) + RET + +// writeBlocks uses the same registers as above except that it uses AX to store +// the d pointer. + +// func writeBlocks(d *Digest, b []byte) int +TEXT ·writeBlocks(SB), NOSPLIT, $0-40 + // Load fixed primes needed for round. + MOVQ ·prime1v(SB), R13 + MOVQ ·prime2v(SB), R14 + + // Load slice. + MOVQ b_base+8(FP), SI + MOVQ b_len+16(FP), DX + LEAQ (SI)(DX*1), BX + SUBQ $32, BX + + // Load vN from d. + MOVQ d+0(FP), AX + MOVQ 0(AX), R8 // v1 + MOVQ 8(AX), R9 // v2 + MOVQ 16(AX), R10 // v3 + MOVQ 24(AX), R11 // v4 + + // We don't need to check the loop condition here; this function is + // always called with at least one block of data to process. +blockLoop: + round(R8) + round(R9) + round(R10) + round(R11) + + CMPQ SI, BX + JLE blockLoop + + // Copy vN back to d. + MOVQ R8, 0(AX) + MOVQ R9, 8(AX) + MOVQ R10, 16(AX) + MOVQ R11, 24(AX) + + // The number of bytes written is SI minus the old base pointer. + SUBQ b_base+8(FP), SI + MOVQ SI, ret+32(FP) + + RET diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_other.go b/vendor/github.com/cespare/xxhash/v2/xxhash_other.go new file mode 100644 index 0000000..4a5a821 --- /dev/null +++ b/vendor/github.com/cespare/xxhash/v2/xxhash_other.go @@ -0,0 +1,76 @@ +// +build !amd64 appengine !gc purego + +package xxhash + +// Sum64 computes the 64-bit xxHash digest of b. +func Sum64(b []byte) uint64 { + // A simpler version would be + // d := New() + // d.Write(b) + // return d.Sum64() + // but this is faster, particularly for small inputs. + + n := len(b) + var h uint64 + + if n >= 32 { + v1 := prime1v + prime2 + v2 := prime2 + v3 := uint64(0) + v4 := -prime1v + for len(b) >= 32 { + v1 = round(v1, u64(b[0:8:len(b)])) + v2 = round(v2, u64(b[8:16:len(b)])) + v3 = round(v3, u64(b[16:24:len(b)])) + v4 = round(v4, u64(b[24:32:len(b)])) + b = b[32:len(b):len(b)] + } + h = rol1(v1) + rol7(v2) + rol12(v3) + rol18(v4) + h = mergeRound(h, v1) + h = mergeRound(h, v2) + h = mergeRound(h, v3) + h = mergeRound(h, v4) + } else { + h = prime5 + } + + h += uint64(n) + + i, end := 0, len(b) + for ; i+8 <= end; i += 8 { + k1 := round(0, u64(b[i:i+8:len(b)])) + h ^= k1 + h = rol27(h)*prime1 + prime4 + } + if i+4 <= end { + h ^= uint64(u32(b[i:i+4:len(b)])) * prime1 + h = rol23(h)*prime2 + prime3 + i += 4 + } + for ; i < end; i++ { + h ^= uint64(b[i]) * prime5 + h = rol11(h) * prime1 + } + + h ^= h >> 33 + h *= prime2 + h ^= h >> 29 + h *= prime3 + h ^= h >> 32 + + return h +} + +func writeBlocks(d *Digest, b []byte) int { + v1, v2, v3, v4 := d.v1, d.v2, d.v3, d.v4 + n := len(b) + for len(b) >= 32 { + v1 = round(v1, u64(b[0:8:len(b)])) + v2 = round(v2, u64(b[8:16:len(b)])) + v3 = round(v3, u64(b[16:24:len(b)])) + v4 = round(v4, u64(b[24:32:len(b)])) + b = b[32:len(b):len(b)] + } + d.v1, d.v2, d.v3, d.v4 = v1, v2, v3, v4 + return n - len(b) +} diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_safe.go b/vendor/github.com/cespare/xxhash/v2/xxhash_safe.go new file mode 100644 index 0000000..fc9bea7 --- /dev/null +++ b/vendor/github.com/cespare/xxhash/v2/xxhash_safe.go @@ -0,0 +1,15 @@ +// +build appengine + +// This file contains the safe implementations of otherwise unsafe-using code. + +package xxhash + +// Sum64String computes the 64-bit xxHash digest of s. +func Sum64String(s string) uint64 { + return Sum64([]byte(s)) +} + +// WriteString adds more data to d. It always returns len(s), nil. +func (d *Digest) WriteString(s string) (n int, err error) { + return d.Write([]byte(s)) +} diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go b/vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go new file mode 100644 index 0000000..376e0ca --- /dev/null +++ b/vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go @@ -0,0 +1,57 @@ +// +build !appengine + +// This file encapsulates usage of unsafe. +// xxhash_safe.go contains the safe implementations. + +package xxhash + +import ( + "unsafe" +) + +// In the future it's possible that compiler optimizations will make these +// XxxString functions unnecessary by realizing that calls such as +// Sum64([]byte(s)) don't need to copy s. See https://golang.org/issue/2205. +// If that happens, even if we keep these functions they can be replaced with +// the trivial safe code. + +// NOTE: The usual way of doing an unsafe string-to-[]byte conversion is: +// +// var b []byte +// bh := (*reflect.SliceHeader)(unsafe.Pointer(&b)) +// bh.Data = (*reflect.StringHeader)(unsafe.Pointer(&s)).Data +// bh.Len = len(s) +// bh.Cap = len(s) +// +// Unfortunately, as of Go 1.15.3 the inliner's cost model assigns a high enough +// weight to this sequence of expressions that any function that uses it will +// not be inlined. Instead, the functions below use a different unsafe +// conversion designed to minimize the inliner weight and allow both to be +// inlined. There is also a test (TestInlining) which verifies that these are +// inlined. +// +// See https://github.com/golang/go/issues/42739 for discussion. + +// Sum64String computes the 64-bit xxHash digest of s. +// It may be faster than Sum64([]byte(s)) by avoiding a copy. +func Sum64String(s string) uint64 { + b := *(*[]byte)(unsafe.Pointer(&sliceHeader{s, len(s)})) + return Sum64(b) +} + +// WriteString adds more data to d. It always returns len(s), nil. +// It may be faster than Write([]byte(s)) by avoiding a copy. +func (d *Digest) WriteString(s string) (n int, err error) { + d.Write(*(*[]byte)(unsafe.Pointer(&sliceHeader{s, len(s)}))) + // d.Write always returns len(s), nil. + // Ignoring the return output and returning these fixed values buys a + // savings of 6 in the inliner's cost model. + return len(s), nil +} + +// sliceHeader is similar to reflect.SliceHeader, but it assumes that the layout +// of the first two words is the same as the layout of a string. +type sliceHeader struct { + s string + cap int +} diff --git a/vendor/github.com/cpuguy83/go-md2man/v2/LICENSE.md b/vendor/github.com/cpuguy83/go-md2man/v2/LICENSE.md new file mode 100644 index 0000000..1cade6c --- /dev/null +++ b/vendor/github.com/cpuguy83/go-md2man/v2/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Brian Goff + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go b/vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go new file mode 100644 index 0000000..b480056 --- /dev/null +++ b/vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go @@ -0,0 +1,14 @@ +package md2man + +import ( + "github.com/russross/blackfriday/v2" +) + +// Render converts a markdown document into a roff formatted document. +func Render(doc []byte) []byte { + renderer := NewRoffRenderer() + + return blackfriday.Run(doc, + []blackfriday.Option{blackfriday.WithRenderer(renderer), + blackfriday.WithExtensions(renderer.GetExtensions())}...) +} diff --git a/vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go b/vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go new file mode 100644 index 0000000..be2b343 --- /dev/null +++ b/vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go @@ -0,0 +1,336 @@ +package md2man + +import ( + "fmt" + "io" + "os" + "strings" + + "github.com/russross/blackfriday/v2" +) + +// roffRenderer implements the blackfriday.Renderer interface for creating +// roff format (manpages) from markdown text +type roffRenderer struct { + extensions blackfriday.Extensions + listCounters []int + firstHeader bool + firstDD bool + listDepth int +} + +const ( + titleHeader = ".TH " + topLevelHeader = "\n\n.SH " + secondLevelHdr = "\n.SH " + otherHeader = "\n.SS " + crTag = "\n" + emphTag = "\\fI" + emphCloseTag = "\\fP" + strongTag = "\\fB" + strongCloseTag = "\\fP" + breakTag = "\n.br\n" + paraTag = "\n.PP\n" + hruleTag = "\n.ti 0\n\\l'\\n(.lu'\n" + linkTag = "\n\\[la]" + linkCloseTag = "\\[ra]" + codespanTag = "\\fB\\fC" + codespanCloseTag = "\\fR" + codeTag = "\n.PP\n.RS\n\n.nf\n" + codeCloseTag = "\n.fi\n.RE\n" + quoteTag = "\n.PP\n.RS\n" + quoteCloseTag = "\n.RE\n" + listTag = "\n.RS\n" + listCloseTag = "\n.RE\n" + dtTag = "\n.TP\n" + dd2Tag = "\n" + tableStart = "\n.TS\nallbox;\n" + tableEnd = ".TE\n" + tableCellStart = "T{\n" + tableCellEnd = "\nT}\n" +) + +// NewRoffRenderer creates a new blackfriday Renderer for generating roff documents +// from markdown +func NewRoffRenderer() *roffRenderer { // nolint: golint + var extensions blackfriday.Extensions + + extensions |= blackfriday.NoIntraEmphasis + extensions |= blackfriday.Tables + extensions |= blackfriday.FencedCode + extensions |= blackfriday.SpaceHeadings + extensions |= blackfriday.Footnotes + extensions |= blackfriday.Titleblock + extensions |= blackfriday.DefinitionLists + return &roffRenderer{ + extensions: extensions, + } +} + +// GetExtensions returns the list of extensions used by this renderer implementation +func (r *roffRenderer) GetExtensions() blackfriday.Extensions { + return r.extensions +} + +// RenderHeader handles outputting the header at document start +func (r *roffRenderer) RenderHeader(w io.Writer, ast *blackfriday.Node) { + // disable hyphenation + out(w, ".nh\n") +} + +// RenderFooter handles outputting the footer at the document end; the roff +// renderer has no footer information +func (r *roffRenderer) RenderFooter(w io.Writer, ast *blackfriday.Node) { +} + +// RenderNode is called for each node in a markdown document; based on the node +// type the equivalent roff output is sent to the writer +func (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering bool) blackfriday.WalkStatus { + + var walkAction = blackfriday.GoToNext + + switch node.Type { + case blackfriday.Text: + escapeSpecialChars(w, node.Literal) + case blackfriday.Softbreak: + out(w, crTag) + case blackfriday.Hardbreak: + out(w, breakTag) + case blackfriday.Emph: + if entering { + out(w, emphTag) + } else { + out(w, emphCloseTag) + } + case blackfriday.Strong: + if entering { + out(w, strongTag) + } else { + out(w, strongCloseTag) + } + case blackfriday.Link: + if !entering { + out(w, linkTag+string(node.LinkData.Destination)+linkCloseTag) + } + case blackfriday.Image: + // ignore images + walkAction = blackfriday.SkipChildren + case blackfriday.Code: + out(w, codespanTag) + escapeSpecialChars(w, node.Literal) + out(w, codespanCloseTag) + case blackfriday.Document: + break + case blackfriday.Paragraph: + // roff .PP markers break lists + if r.listDepth > 0 { + return blackfriday.GoToNext + } + if entering { + out(w, paraTag) + } else { + out(w, crTag) + } + case blackfriday.BlockQuote: + if entering { + out(w, quoteTag) + } else { + out(w, quoteCloseTag) + } + case blackfriday.Heading: + r.handleHeading(w, node, entering) + case blackfriday.HorizontalRule: + out(w, hruleTag) + case blackfriday.List: + r.handleList(w, node, entering) + case blackfriday.Item: + r.handleItem(w, node, entering) + case blackfriday.CodeBlock: + out(w, codeTag) + escapeSpecialChars(w, node.Literal) + out(w, codeCloseTag) + case blackfriday.Table: + r.handleTable(w, node, entering) + case blackfriday.TableHead: + case blackfriday.TableBody: + case blackfriday.TableRow: + // no action as cell entries do all the nroff formatting + return blackfriday.GoToNext + case blackfriday.TableCell: + r.handleTableCell(w, node, entering) + case blackfriday.HTMLSpan: + // ignore other HTML tags + default: + fmt.Fprintln(os.Stderr, "WARNING: go-md2man does not handle node type "+node.Type.String()) + } + return walkAction +} + +func (r *roffRenderer) handleHeading(w io.Writer, node *blackfriday.Node, entering bool) { + if entering { + switch node.Level { + case 1: + if !r.firstHeader { + out(w, titleHeader) + r.firstHeader = true + break + } + out(w, topLevelHeader) + case 2: + out(w, secondLevelHdr) + default: + out(w, otherHeader) + } + } +} + +func (r *roffRenderer) handleList(w io.Writer, node *blackfriday.Node, entering bool) { + openTag := listTag + closeTag := listCloseTag + if node.ListFlags&blackfriday.ListTypeDefinition != 0 { + // tags for definition lists handled within Item node + openTag = "" + closeTag = "" + } + if entering { + r.listDepth++ + if node.ListFlags&blackfriday.ListTypeOrdered != 0 { + r.listCounters = append(r.listCounters, 1) + } + out(w, openTag) + } else { + if node.ListFlags&blackfriday.ListTypeOrdered != 0 { + r.listCounters = r.listCounters[:len(r.listCounters)-1] + } + out(w, closeTag) + r.listDepth-- + } +} + +func (r *roffRenderer) handleItem(w io.Writer, node *blackfriday.Node, entering bool) { + if entering { + if node.ListFlags&blackfriday.ListTypeOrdered != 0 { + out(w, fmt.Sprintf(".IP \"%3d.\" 5\n", r.listCounters[len(r.listCounters)-1])) + r.listCounters[len(r.listCounters)-1]++ + } else if node.ListFlags&blackfriday.ListTypeTerm != 0 { + // DT (definition term): line just before DD (see below). + out(w, dtTag) + r.firstDD = true + } else if node.ListFlags&blackfriday.ListTypeDefinition != 0 { + // DD (definition description): line that starts with ": ". + // + // We have to distinguish between the first DD and the + // subsequent ones, as there should be no vertical + // whitespace between the DT and the first DD. + if r.firstDD { + r.firstDD = false + } else { + out(w, dd2Tag) + } + } else { + out(w, ".IP \\(bu 2\n") + } + } else { + out(w, "\n") + } +} + +func (r *roffRenderer) handleTable(w io.Writer, node *blackfriday.Node, entering bool) { + if entering { + out(w, tableStart) + // call walker to count cells (and rows?) so format section can be produced + columns := countColumns(node) + out(w, strings.Repeat("l ", columns)+"\n") + out(w, strings.Repeat("l ", columns)+".\n") + } else { + out(w, tableEnd) + } +} + +func (r *roffRenderer) handleTableCell(w io.Writer, node *blackfriday.Node, entering bool) { + if entering { + var start string + if node.Prev != nil && node.Prev.Type == blackfriday.TableCell { + start = "\t" + } + if node.IsHeader { + start += codespanTag + } else if nodeLiteralSize(node) > 30 { + start += tableCellStart + } + out(w, start) + } else { + var end string + if node.IsHeader { + end = codespanCloseTag + } else if nodeLiteralSize(node) > 30 { + end = tableCellEnd + } + if node.Next == nil && end != tableCellEnd { + // Last cell: need to carriage return if we are at the end of the + // header row and content isn't wrapped in a "tablecell" + end += crTag + } + out(w, end) + } +} + +func nodeLiteralSize(node *blackfriday.Node) int { + total := 0 + for n := node.FirstChild; n != nil; n = n.FirstChild { + total += len(n.Literal) + } + return total +} + +// because roff format requires knowing the column count before outputting any table +// data we need to walk a table tree and count the columns +func countColumns(node *blackfriday.Node) int { + var columns int + + node.Walk(func(node *blackfriday.Node, entering bool) blackfriday.WalkStatus { + switch node.Type { + case blackfriday.TableRow: + if !entering { + return blackfriday.Terminate + } + case blackfriday.TableCell: + if entering { + columns++ + } + default: + } + return blackfriday.GoToNext + }) + return columns +} + +func out(w io.Writer, output string) { + io.WriteString(w, output) // nolint: errcheck +} + +func escapeSpecialChars(w io.Writer, text []byte) { + for i := 0; i < len(text); i++ { + // escape initial apostrophe or period + if len(text) >= 1 && (text[0] == '\'' || text[0] == '.') { + out(w, "\\&") + } + + // directly copy normal characters + org := i + + for i < len(text) && text[i] != '\\' { + i++ + } + if i > org { + w.Write(text[org:i]) // nolint: errcheck + } + + // escape a character + if i >= len(text) { + break + } + + w.Write([]byte{'\\', text[i]}) // nolint: errcheck + } +} diff --git a/vendor/github.com/creasty/defaults/.gitignore b/vendor/github.com/creasty/defaults/.gitignore new file mode 100644 index 0000000..e43b0f9 --- /dev/null +++ b/vendor/github.com/creasty/defaults/.gitignore @@ -0,0 +1 @@ +.DS_Store diff --git a/vendor/github.com/creasty/defaults/LICENSE b/vendor/github.com/creasty/defaults/LICENSE new file mode 100644 index 0000000..1483dd2 --- /dev/null +++ b/vendor/github.com/creasty/defaults/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2017-present Yuki Iwanaga + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/creasty/defaults/Makefile b/vendor/github.com/creasty/defaults/Makefile new file mode 100644 index 0000000..bd42d46 --- /dev/null +++ b/vendor/github.com/creasty/defaults/Makefile @@ -0,0 +1,30 @@ +SHELL := /bin/bash -eu -o pipefail + +GO_TEST_FLAGS := -v + +PACKAGE_DIRS := $(shell go list ./... 2> /dev/null | grep -v /vendor/) +SRC_FILES := $(shell find . -name '*.go' -not -path './vendor/*') + + +# Tasks +#----------------------------------------------- +.PHONY: lint +lint: + @gofmt -e -d -s $(SRC_FILES) | awk '{ e = 1; print $0 } END { if (e) exit(1) }' + @echo $(SRC_FILES) | xargs -n1 golint -set_exit_status + @go vet $(PACKAGE_DIRS) + +.PHONY: test +test: lint + @go test $(GO_TEST_FLAGS) $(PACKAGE_DIRS) + +.PHONY: ci-test +ci-test: lint + @echo > coverage.txt + @for d in $(PACKAGE_DIRS); do \ + go test -coverprofile=profile.out -covermode=atomic -race -v $$d; \ + if [ -f profile.out ]; then \ + cat profile.out >> coverage.txt; \ + rm profile.out; \ + fi; \ + done diff --git a/vendor/github.com/creasty/defaults/README.md b/vendor/github.com/creasty/defaults/README.md new file mode 100644 index 0000000..de1ca3d --- /dev/null +++ b/vendor/github.com/creasty/defaults/README.md @@ -0,0 +1,73 @@ +defaults +======== + +[![CircleCI](https://circleci.com/gh/creasty/defaults/tree/master.svg?style=svg)](https://circleci.com/gh/creasty/defaults/tree/master) +[![codecov](https://codecov.io/gh/creasty/defaults/branch/master/graph/badge.svg)](https://codecov.io/gh/creasty/defaults) +[![GitHub release](https://img.shields.io/github/release/creasty/defaults.svg)](https://github.com/creasty/defaults/releases) +[![License](https://img.shields.io/github/license/creasty/defaults.svg)](./LICENSE) + +Initialize structs with default values + +- Supports almost all kind of types + - Scalar types + - `int/8/16/32/64`, `uint/8/16/32/64`, `float32/64` + - `uintptr`, `bool`, `string` + - Complex types + - `map`, `slice`, `struct` + - Aliased types + - `time.Duration` + - e.g., `type Enum string` + - Pointer types + - e.g., `*SampleStruct`, `*int` +- Recursively initializes fields in a struct +- Dynamically sets default values by [`defaults.Setter`](./setter.go) interface +- Preserves non-initial values from being reset with a default value + + +Usage +----- + +```go +type Gender string + +type Sample struct { + Name string `default:"John Smith"` + Age int `default:"27"` + Gender Gender `default:"m"` + + Slice []string `default:"[]"` + SliceByJSON []int `default:"[1, 2, 3]"` // Supports JSON + + Map map[string]int `default:"{}"` + MapByJSON map[string]int `default:"{\"foo\": 123}"` + MapOfStruct map[string]OtherStruct + MapOfPtrStruct map[string]*OtherStruct + MapOfStructWithTag map[string]OtherStruct `default:"{\"Key1\": {\"Foo\":123}}"` + + Struct OtherStruct `default:"{}"` + StructPtr *OtherStruct `default:"{\"Foo\": 123}"` + + NoTag OtherStruct // Recurses into a nested struct by default + OptOut OtherStruct `default:"-"` // Opt-out +} + +type OtherStruct struct { + Hello string `default:"world"` // Tags in a nested struct also work + Foo int `default:"-"` + Random int `default:"-"` +} + +// SetDefaults implements defaults.Setter interface +func (s *OtherStruct) SetDefaults() { + if defaults.CanUpdate(s.Random) { // Check if it's a zero value (recommended) + s.Random = rand.Int() // Set a dynamic value + } +} +``` + +```go +obj := &Sample{} +if err := defaults.Set(obj); err != nil { + panic(err) +} +``` diff --git a/vendor/github.com/creasty/defaults/defaults.go b/vendor/github.com/creasty/defaults/defaults.go new file mode 100644 index 0000000..3bb2c22 --- /dev/null +++ b/vendor/github.com/creasty/defaults/defaults.go @@ -0,0 +1,221 @@ +package defaults + +import ( + "encoding/json" + "errors" + "reflect" + "strconv" + "time" +) + +var ( + errInvalidType = errors.New("not a struct pointer") +) + +const ( + fieldName = "default" +) + +// Set initializes members in a struct referenced by a pointer. +// Maps and slices are initialized by `make` and other primitive types are set with default values. +// `ptr` should be a struct pointer +func Set(ptr interface{}) error { + if reflect.TypeOf(ptr).Kind() != reflect.Ptr { + return errInvalidType + } + + v := reflect.ValueOf(ptr).Elem() + t := v.Type() + + if t.Kind() != reflect.Struct { + return errInvalidType + } + + for i := 0; i < t.NumField(); i++ { + if defaultVal := t.Field(i).Tag.Get(fieldName); defaultVal != "-" { + if err := setField(v.Field(i), defaultVal); err != nil { + return err + } + } + } + callSetter(ptr) + return nil +} + +// MustSet function is a wrapper of Set function +// It will call Set and panic if err not equals nil. +func MustSet(ptr interface{}) { + if err := Set(ptr); err != nil { + panic(err) + } +} + +func setField(field reflect.Value, defaultVal string) error { + if !field.CanSet() { + return nil + } + + if !shouldInitializeField(field, defaultVal) { + return nil + } + + isInitial := isInitialValue(field) + if isInitial { + switch field.Kind() { + case reflect.Bool: + if val, err := strconv.ParseBool(defaultVal); err == nil { + field.Set(reflect.ValueOf(val).Convert(field.Type())) + } + case reflect.Int: + if val, err := strconv.ParseInt(defaultVal, 0, strconv.IntSize); err == nil { + field.Set(reflect.ValueOf(int(val)).Convert(field.Type())) + } + case reflect.Int8: + if val, err := strconv.ParseInt(defaultVal, 0, 8); err == nil { + field.Set(reflect.ValueOf(int8(val)).Convert(field.Type())) + } + case reflect.Int16: + if val, err := strconv.ParseInt(defaultVal, 0, 16); err == nil { + field.Set(reflect.ValueOf(int16(val)).Convert(field.Type())) + } + case reflect.Int32: + if val, err := strconv.ParseInt(defaultVal, 0, 32); err == nil { + field.Set(reflect.ValueOf(int32(val)).Convert(field.Type())) + } + case reflect.Int64: + if val, err := time.ParseDuration(defaultVal); err == nil { + field.Set(reflect.ValueOf(val).Convert(field.Type())) + } else if val, err := strconv.ParseInt(defaultVal, 0, 64); err == nil { + field.Set(reflect.ValueOf(val).Convert(field.Type())) + } + case reflect.Uint: + if val, err := strconv.ParseUint(defaultVal, 0, strconv.IntSize); err == nil { + field.Set(reflect.ValueOf(uint(val)).Convert(field.Type())) + } + case reflect.Uint8: + if val, err := strconv.ParseUint(defaultVal, 0, 8); err == nil { + field.Set(reflect.ValueOf(uint8(val)).Convert(field.Type())) + } + case reflect.Uint16: + if val, err := strconv.ParseUint(defaultVal, 0, 16); err == nil { + field.Set(reflect.ValueOf(uint16(val)).Convert(field.Type())) + } + case reflect.Uint32: + if val, err := strconv.ParseUint(defaultVal, 0, 32); err == nil { + field.Set(reflect.ValueOf(uint32(val)).Convert(field.Type())) + } + case reflect.Uint64: + if val, err := strconv.ParseUint(defaultVal, 0, 64); err == nil { + field.Set(reflect.ValueOf(val).Convert(field.Type())) + } + case reflect.Uintptr: + if val, err := strconv.ParseUint(defaultVal, 0, strconv.IntSize); err == nil { + field.Set(reflect.ValueOf(uintptr(val)).Convert(field.Type())) + } + case reflect.Float32: + if val, err := strconv.ParseFloat(defaultVal, 32); err == nil { + field.Set(reflect.ValueOf(float32(val)).Convert(field.Type())) + } + case reflect.Float64: + if val, err := strconv.ParseFloat(defaultVal, 64); err == nil { + field.Set(reflect.ValueOf(val).Convert(field.Type())) + } + case reflect.String: + field.Set(reflect.ValueOf(defaultVal).Convert(field.Type())) + + case reflect.Slice: + ref := reflect.New(field.Type()) + ref.Elem().Set(reflect.MakeSlice(field.Type(), 0, 0)) + if defaultVal != "" && defaultVal != "[]" { + if err := json.Unmarshal([]byte(defaultVal), ref.Interface()); err != nil { + return err + } + } + field.Set(ref.Elem().Convert(field.Type())) + case reflect.Map: + ref := reflect.New(field.Type()) + ref.Elem().Set(reflect.MakeMap(field.Type())) + if defaultVal != "" && defaultVal != "{}" { + if err := json.Unmarshal([]byte(defaultVal), ref.Interface()); err != nil { + return err + } + } + field.Set(ref.Elem().Convert(field.Type())) + case reflect.Struct: + if defaultVal != "" && defaultVal != "{}" { + if err := json.Unmarshal([]byte(defaultVal), field.Addr().Interface()); err != nil { + return err + } + } + case reflect.Ptr: + field.Set(reflect.New(field.Type().Elem())) + } + } + + switch field.Kind() { + case reflect.Ptr: + if isInitial || field.Elem().Kind() == reflect.Struct { + setField(field.Elem(), defaultVal) + callSetter(field.Interface()) + } + case reflect.Struct: + if err := Set(field.Addr().Interface()); err != nil { + return err + } + case reflect.Slice: + for j := 0; j < field.Len(); j++ { + if err := setField(field.Index(j), defaultVal); err != nil { + return err + } + } + case reflect.Map: + for _, e := range field.MapKeys() { + var v = field.MapIndex(e) + + switch v.Kind() { + case reflect.Ptr: + switch v.Elem().Kind() { + case reflect.Struct, reflect.Slice, reflect.Map: + if err := setField(v.Elem(), ""); err != nil { + return err + } + } + case reflect.Struct, reflect.Slice, reflect.Map: + ref := reflect.New(v.Type()) + ref.Elem().Set(v) + if err := setField(ref.Elem(), ""); err != nil { + return err + } + field.SetMapIndex(e, ref.Elem().Convert(v.Type())) + } + } + } + + return nil +} + +func isInitialValue(field reflect.Value) bool { + return reflect.DeepEqual(reflect.Zero(field.Type()).Interface(), field.Interface()) +} + +func shouldInitializeField(field reflect.Value, tag string) bool { + switch field.Kind() { + case reflect.Struct: + return true + case reflect.Ptr: + if !field.IsNil() && field.Elem().Kind() == reflect.Struct { + return true + } + case reflect.Slice: + return field.Len() > 0 || tag != "" + case reflect.Map: + return field.Len() > 0 || tag != "" + } + + return tag != "" +} + +// CanUpdate returns true when the given value is an initial value of its type +func CanUpdate(v interface{}) bool { + return isInitialValue(reflect.ValueOf(v)) +} diff --git a/vendor/github.com/creasty/defaults/go.mod b/vendor/github.com/creasty/defaults/go.mod new file mode 100644 index 0000000..2b71726 --- /dev/null +++ b/vendor/github.com/creasty/defaults/go.mod @@ -0,0 +1,3 @@ +module github.com/creasty/defaults + +go 1.14 diff --git a/vendor/github.com/creasty/defaults/go.sum b/vendor/github.com/creasty/defaults/go.sum new file mode 100644 index 0000000..e69de29 diff --git a/vendor/github.com/creasty/defaults/setter.go b/vendor/github.com/creasty/defaults/setter.go new file mode 100644 index 0000000..1f64aa6 --- /dev/null +++ b/vendor/github.com/creasty/defaults/setter.go @@ -0,0 +1,12 @@ +package defaults + +// Setter is an interface for setting default values +type Setter interface { + SetDefaults() +} + +func callSetter(v interface{}) { + if ds, ok := v.(Setter); ok { + ds.SetDefaults() + } +} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/LICENSE b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/LICENSE new file mode 100644 index 0000000..d2d1dd9 --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/LICENSE @@ -0,0 +1,17 @@ +ISC License + +Copyright (c) 2013-2017 The btcsuite developers +Copyright (c) 2015-2020 The Decred developers +Copyright (c) 2017 The Lightning Network Developers + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/README.md b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/README.md new file mode 100644 index 0000000..4ae25db --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/README.md @@ -0,0 +1,72 @@ +secp256k1 +========= + +[![Build Status](https://github.com/decred/dcrd/workflows/Build%20and%20Test/badge.svg)](https://github.com/decred/dcrd/actions) +[![ISC License](https://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) +[![Doc](https://img.shields.io/badge/doc-reference-blue.svg)](https://pkg.go.dev/github.com/decred/dcrd/dcrec/secp256k1/v4) + +Package secp256k1 implements optimized secp256k1 elliptic curve operations. + +This package provides an optimized pure Go implementation of elliptic curve +cryptography operations over the secp256k1 curve as well as data structures and +functions for working with public and private secp256k1 keys. See +https://www.secg.org/sec2-v2.pdf for details on the standard. + +In addition, sub packages are provided to produce, verify, parse, and serialize +ECDSA signatures and EC-Schnorr-DCRv0 (a custom Schnorr-based signature scheme +specific to Decred) signatures. See the README.md files in the relevant sub +packages for more details about those aspects. + +An overview of the features provided by this package are as follows: + +- Private key generation, serialization, and parsing +- Public key generation, serialization and parsing per ANSI X9.62-1998 + - Parses uncompressed, compressed, and hybrid public keys + - Serializes uncompressed and compressed public keys +- Specialized types for performing optimized and constant time field operations + - `FieldVal` type for working modulo the secp256k1 field prime + - `ModNScalar` type for working modulo the secp256k1 group order +- Elliptic curve operations in Jacobian projective coordinates + - Point addition + - Point doubling + - Scalar multiplication with an arbitrary point + - Scalar multiplication with the base point (group generator) +- Point decompression from a given x coordinate +- Nonce generation via RFC6979 with support for extra data and version + information that can be used to prevent nonce reuse between signing algorithms + +It also provides an implementation of the Go standard library `crypto/elliptic` +`Curve` interface via the `S256` function so that it may be used with other +packages in the standard library such as `crypto/tls`, `crypto/x509`, and +`crypto/ecdsa`. However, in the case of ECDSA, it is highly recommended to use +the `ecdsa` sub package of this package instead since it is optimized +specifically for secp256k1 and is significantly faster as a result. + +Although this package was primarily written for dcrd, it has intentionally been +designed so it can be used as a standalone package for any projects needing to +use optimized secp256k1 elliptic curve cryptography. + +Finally, a comprehensive suite of tests is provided to provide a high level of +quality assurance. + +## secp256k1 use in Decred + +At the time of this writing, the primary public key cryptography in widespread +use on the Decred network used to secure coins is based on elliptic curves +defined by the secp256k1 domain parameters. + +## Installation and Updating + +This package is part of the `github.com/decred/dcrd/dcrec/secp256k1/v3` module. +Use the standard go tooling for working with modules to incorporate it. + +## Examples + +* [Encryption](https://pkg.go.dev/github.com/decred/dcrd/dcrec/secp256k1/v4#example-package-EncryptDecryptMessage) + Demonstrates encrypting and decrypting a message using a shared key derived + through ECDHE. + +## License + +Package secp256k1 is licensed under the [copyfree](http://copyfree.org) ISC +License. diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/compressedbytepoints.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/compressedbytepoints.go new file mode 100644 index 0000000..ca4be12 --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/compressedbytepoints.go @@ -0,0 +1,11 @@ +// Copyright (c) 2015 The btcsuite developers +// Copyright (c) 2015-2021 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +// Auto-generated file (see genprecomps.go) +// DO NOT EDIT + +var compressedBytePoints = "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" diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve.go new file mode 100644 index 0000000..e862060 --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve.go @@ -0,0 +1,943 @@ +// Copyright (c) 2015-2021 The Decred developers +// Copyright 2013-2014 The btcsuite developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +import ( + "encoding/hex" + "math/big" +) + +// References: +// [SECG]: Recommended Elliptic Curve Domain Parameters +// https://www.secg.org/sec2-v2.pdf +// +// [GECC]: Guide to Elliptic Curve Cryptography (Hankerson, Menezes, Vanstone) +// +// [BRID]: On Binary Representations of Integers with Digits -1, 0, 1 +// (Prodinger, Helmut) + +// All group operations are performed using Jacobian coordinates. For a given +// (x, y) position on the curve, the Jacobian coordinates are (x1, y1, z1) +// where x = x1/z1^2 and y = y1/z1^3. + +// hexToFieldVal converts the passed hex string into a FieldVal and will panic +// if there is an error. This is only provided for the hard-coded constants so +// errors in the source code can be detected. It will only (and must only) be +// called with hard-coded values. +func hexToFieldVal(s string) *FieldVal { + b, err := hex.DecodeString(s) + if err != nil { + panic("invalid hex in source file: " + s) + } + var f FieldVal + if overflow := f.SetByteSlice(b); overflow { + panic("hex in source file overflows mod P: " + s) + } + return &f +} + +var ( + // Next 6 constants are from Hal Finney's bitcointalk.org post: + // https://bitcointalk.org/index.php?topic=3238.msg45565#msg45565 + // May he rest in peace. + // + // They have also been independently derived from the code in the + // EndomorphismVectors function in genstatics.go. + endomorphismLambda = fromHex("5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72") + endomorphismBeta = hexToFieldVal("7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee") + endomorphismA1 = fromHex("3086d221a7d46bcde86c90e49284eb15") + endomorphismB1 = fromHex("-e4437ed6010e88286f547fa90abfe4c3") + endomorphismA2 = fromHex("114ca50f7a8e2f3f657c1108d9d44cfd8") + endomorphismB2 = fromHex("3086d221a7d46bcde86c90e49284eb15") + + // Alternatively, the following parameters are valid as well, however, they + // seem to be about 8% slower in practice. + // + // endomorphismLambda = fromHex("AC9C52B33FA3CF1F5AD9E3FD77ED9BA4A880B9FC8EC739C2E0CFC810B51283CE") + // endomorphismBeta = hexToFieldVal("851695D49A83F8EF919BB86153CBCB16630FB68AED0A766A3EC693D68E6AFA40") + // endomorphismA1 = fromHex("E4437ED6010E88286F547FA90ABFE4C3") + // endomorphismB1 = fromHex("-3086D221A7D46BCDE86C90E49284EB15") + // endomorphismA2 = fromHex("3086D221A7D46BCDE86C90E49284EB15") + // endomorphismB2 = fromHex("114CA50F7A8E2F3F657C1108D9D44CFD8") +) + +// JacobianPoint is an element of the group formed by the secp256k1 curve in +// Jacobian projective coordinates and thus represents a point on the curve. +type JacobianPoint struct { + // The X coordinate in Jacobian projective coordinates. The affine point is + // X/z^2. + X FieldVal + + // The Y coordinate in Jacobian projective coordinates. The affine point is + // Y/z^3. + Y FieldVal + + // The Z coordinate in Jacobian projective coordinates. + Z FieldVal +} + +// MakeJacobianPoint returns a Jacobian point with the provided X, Y, and Z +// coordinates. +func MakeJacobianPoint(x, y, z *FieldVal) JacobianPoint { + var p JacobianPoint + p.X.Set(x) + p.Y.Set(y) + p.Z.Set(z) + return p +} + +// Set sets the Jacobian point to the provided point. +func (p *JacobianPoint) Set(other *JacobianPoint) { + p.X.Set(&other.X) + p.Y.Set(&other.Y) + p.Z.Set(&other.Z) +} + +// ToAffine reduces the Z value of the existing point to 1 effectively +// making it an affine coordinate in constant time. The point will be +// normalized. +func (p *JacobianPoint) ToAffine() { + // Inversions are expensive and both point addition and point doubling + // are faster when working with points that have a z value of one. So, + // if the point needs to be converted to affine, go ahead and normalize + // the point itself at the same time as the calculation is the same. + var zInv, tempZ FieldVal + zInv.Set(&p.Z).Inverse() // zInv = Z^-1 + tempZ.SquareVal(&zInv) // tempZ = Z^-2 + p.X.Mul(&tempZ) // X = X/Z^2 (mag: 1) + p.Y.Mul(tempZ.Mul(&zInv)) // Y = Y/Z^3 (mag: 1) + p.Z.SetInt(1) // Z = 1 (mag: 1) + + // Normalize the x and y values. + p.X.Normalize() + p.Y.Normalize() +} + +// addZ1AndZ2EqualsOne adds two Jacobian points that are already known to have +// z values of 1 and stores the result in the provided result param. That is to +// say result = p1 + p2. It performs faster addition than the generic add +// routine since less arithmetic is needed due to the ability to avoid the z +// value multiplications. +// +// NOTE: The points must be normalized for this function to return the correct +// result. The resulting point will be normalized. +func addZ1AndZ2EqualsOne(p1, p2, result *JacobianPoint) { + // To compute the point addition efficiently, this implementation splits + // the equation into intermediate elements which are used to minimize + // the number of field multiplications using the method shown at: + // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl + // + // In particular it performs the calculations using the following: + // H = X2-X1, HH = H^2, I = 4*HH, J = H*I, r = 2*(Y2-Y1), V = X1*I + // X3 = r^2-J-2*V, Y3 = r*(V-X3)-2*Y1*J, Z3 = 2*H + // + // This results in a cost of 4 field multiplications, 2 field squarings, + // 6 field additions, and 5 integer multiplications. + x1, y1 := &p1.X, &p1.Y + x2, y2 := &p2.X, &p2.Y + x3, y3, z3 := &result.X, &result.Y, &result.Z + + // When the x coordinates are the same for two points on the curve, the + // y coordinates either must be the same, in which case it is point + // doubling, or they are opposite and the result is the point at + // infinity per the group law for elliptic curve cryptography. + if x1.Equals(x2) { + if y1.Equals(y2) { + // Since x1 == x2 and y1 == y2, point doubling must be + // done, otherwise the addition would end up dividing + // by zero. + DoubleNonConst(p1, result) + return + } + + // Since x1 == x2 and y1 == -y2, the sum is the point at + // infinity per the group law. + x3.SetInt(0) + y3.SetInt(0) + z3.SetInt(0) + return + } + + // Calculate X3, Y3, and Z3 according to the intermediate elements + // breakdown above. + var h, i, j, r, v FieldVal + var negJ, neg2V, negX3 FieldVal + h.Set(x1).Negate(1).Add(x2) // H = X2-X1 (mag: 3) + i.SquareVal(&h).MulInt(4) // I = 4*H^2 (mag: 4) + j.Mul2(&h, &i) // J = H*I (mag: 1) + r.Set(y1).Negate(1).Add(y2).MulInt(2) // r = 2*(Y2-Y1) (mag: 6) + v.Mul2(x1, &i) // V = X1*I (mag: 1) + negJ.Set(&j).Negate(1) // negJ = -J (mag: 2) + neg2V.Set(&v).MulInt(2).Negate(2) // neg2V = -(2*V) (mag: 3) + x3.Set(&r).Square().Add(&negJ).Add(&neg2V) // X3 = r^2-J-2*V (mag: 6) + negX3.Set(x3).Negate(6) // negX3 = -X3 (mag: 7) + j.Mul(y1).MulInt(2).Negate(2) // J = -(2*Y1*J) (mag: 3) + y3.Set(&v).Add(&negX3).Mul(&r).Add(&j) // Y3 = r*(V-X3)-2*Y1*J (mag: 4) + z3.Set(&h).MulInt(2) // Z3 = 2*H (mag: 6) + + // Normalize the resulting field values to a magnitude of 1 as needed. + x3.Normalize() + y3.Normalize() + z3.Normalize() +} + +// addZ1EqualsZ2 adds two Jacobian points that are already known to have the +// same z value and stores the result in the provided result param. That is to +// say result = p1 + p2. It performs faster addition than the generic add +// routine since less arithmetic is needed due to the known equivalence. +// +// NOTE: The points must be normalized for this function to return the correct +// result. The resulting point will be normalized. +func addZ1EqualsZ2(p1, p2, result *JacobianPoint) { + // To compute the point addition efficiently, this implementation splits + // the equation into intermediate elements which are used to minimize + // the number of field multiplications using a slightly modified version + // of the method shown at: + // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl + // + // In particular it performs the calculations using the following: + // A = X2-X1, B = A^2, C=Y2-Y1, D = C^2, E = X1*B, F = X2*B + // X3 = D-E-F, Y3 = C*(E-X3)-Y1*(F-E), Z3 = Z1*A + // + // This results in a cost of 5 field multiplications, 2 field squarings, + // 9 field additions, and 0 integer multiplications. + x1, y1, z1 := &p1.X, &p1.Y, &p1.Z + x2, y2 := &p2.X, &p2.Y + x3, y3, z3 := &result.X, &result.Y, &result.Z + + // When the x coordinates are the same for two points on the curve, the + // y coordinates either must be the same, in which case it is point + // doubling, or they are opposite and the result is the point at + // infinity per the group law for elliptic curve cryptography. + if x1.Equals(x2) { + if y1.Equals(y2) { + // Since x1 == x2 and y1 == y2, point doubling must be + // done, otherwise the addition would end up dividing + // by zero. + DoubleNonConst(p1, result) + return + } + + // Since x1 == x2 and y1 == -y2, the sum is the point at + // infinity per the group law. + x3.SetInt(0) + y3.SetInt(0) + z3.SetInt(0) + return + } + + // Calculate X3, Y3, and Z3 according to the intermediate elements + // breakdown above. + var a, b, c, d, e, f FieldVal + var negX1, negY1, negE, negX3 FieldVal + negX1.Set(x1).Negate(1) // negX1 = -X1 (mag: 2) + negY1.Set(y1).Negate(1) // negY1 = -Y1 (mag: 2) + a.Set(&negX1).Add(x2) // A = X2-X1 (mag: 3) + b.SquareVal(&a) // B = A^2 (mag: 1) + c.Set(&negY1).Add(y2) // C = Y2-Y1 (mag: 3) + d.SquareVal(&c) // D = C^2 (mag: 1) + e.Mul2(x1, &b) // E = X1*B (mag: 1) + negE.Set(&e).Negate(1) // negE = -E (mag: 2) + f.Mul2(x2, &b) // F = X2*B (mag: 1) + x3.Add2(&e, &f).Negate(3).Add(&d) // X3 = D-E-F (mag: 5) + negX3.Set(x3).Negate(5).Normalize() // negX3 = -X3 (mag: 1) + y3.Set(y1).Mul(f.Add(&negE)).Negate(3) // Y3 = -(Y1*(F-E)) (mag: 4) + y3.Add(e.Add(&negX3).Mul(&c)) // Y3 = C*(E-X3)+Y3 (mag: 5) + z3.Mul2(z1, &a) // Z3 = Z1*A (mag: 1) + + // Normalize the resulting field values to a magnitude of 1 as needed. + x3.Normalize() + y3.Normalize() + z3.Normalize() +} + +// addZ2EqualsOne adds two Jacobian points when the second point is already +// known to have a z value of 1 (and the z value for the first point is not 1) +// and stores the result in the provided result param. That is to say result = +// p1 + p2. It performs faster addition than the generic add routine since +// less arithmetic is needed due to the ability to avoid multiplications by the +// second point's z value. +// +// NOTE: The points must be normalized for this function to return the correct +// result. The resulting point will be normalized. +func addZ2EqualsOne(p1, p2, result *JacobianPoint) { + // To compute the point addition efficiently, this implementation splits + // the equation into intermediate elements which are used to minimize + // the number of field multiplications using the method shown at: + // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl + // + // In particular it performs the calculations using the following: + // Z1Z1 = Z1^2, U2 = X2*Z1Z1, S2 = Y2*Z1*Z1Z1, H = U2-X1, HH = H^2, + // I = 4*HH, J = H*I, r = 2*(S2-Y1), V = X1*I + // X3 = r^2-J-2*V, Y3 = r*(V-X3)-2*Y1*J, Z3 = (Z1+H)^2-Z1Z1-HH + // + // This results in a cost of 7 field multiplications, 4 field squarings, + // 9 field additions, and 4 integer multiplications. + x1, y1, z1 := &p1.X, &p1.Y, &p1.Z + x2, y2 := &p2.X, &p2.Y + x3, y3, z3 := &result.X, &result.Y, &result.Z + + // When the x coordinates are the same for two points on the curve, the + // y coordinates either must be the same, in which case it is point + // doubling, or they are opposite and the result is the point at + // infinity per the group law for elliptic curve cryptography. Since + // any number of Jacobian coordinates can represent the same affine + // point, the x and y values need to be converted to like terms. Due to + // the assumption made for this function that the second point has a z + // value of 1 (z2=1), the first point is already "converted". + var z1z1, u2, s2 FieldVal + z1z1.SquareVal(z1) // Z1Z1 = Z1^2 (mag: 1) + u2.Set(x2).Mul(&z1z1).Normalize() // U2 = X2*Z1Z1 (mag: 1) + s2.Set(y2).Mul(&z1z1).Mul(z1).Normalize() // S2 = Y2*Z1*Z1Z1 (mag: 1) + if x1.Equals(&u2) { + if y1.Equals(&s2) { + // Since x1 == x2 and y1 == y2, point doubling must be + // done, otherwise the addition would end up dividing + // by zero. + DoubleNonConst(p1, result) + return + } + + // Since x1 == x2 and y1 == -y2, the sum is the point at + // infinity per the group law. + x3.SetInt(0) + y3.SetInt(0) + z3.SetInt(0) + return + } + + // Calculate X3, Y3, and Z3 according to the intermediate elements + // breakdown above. + var h, hh, i, j, r, rr, v FieldVal + var negX1, negY1, negX3 FieldVal + negX1.Set(x1).Negate(1) // negX1 = -X1 (mag: 2) + h.Add2(&u2, &negX1) // H = U2-X1 (mag: 3) + hh.SquareVal(&h) // HH = H^2 (mag: 1) + i.Set(&hh).MulInt(4) // I = 4 * HH (mag: 4) + j.Mul2(&h, &i) // J = H*I (mag: 1) + negY1.Set(y1).Negate(1) // negY1 = -Y1 (mag: 2) + r.Set(&s2).Add(&negY1).MulInt(2) // r = 2*(S2-Y1) (mag: 6) + rr.SquareVal(&r) // rr = r^2 (mag: 1) + v.Mul2(x1, &i) // V = X1*I (mag: 1) + x3.Set(&v).MulInt(2).Add(&j).Negate(3) // X3 = -(J+2*V) (mag: 4) + x3.Add(&rr) // X3 = r^2+X3 (mag: 5) + negX3.Set(x3).Negate(5) // negX3 = -X3 (mag: 6) + y3.Set(y1).Mul(&j).MulInt(2).Negate(2) // Y3 = -(2*Y1*J) (mag: 3) + y3.Add(v.Add(&negX3).Mul(&r)) // Y3 = r*(V-X3)+Y3 (mag: 4) + z3.Add2(z1, &h).Square() // Z3 = (Z1+H)^2 (mag: 1) + z3.Add(z1z1.Add(&hh).Negate(2)) // Z3 = Z3-(Z1Z1+HH) (mag: 4) + + // Normalize the resulting field values to a magnitude of 1 as needed. + x3.Normalize() + y3.Normalize() + z3.Normalize() +} + +// addGeneric adds two Jacobian points without any assumptions about the z +// values of the two points and stores the result in the provided result param. +// That is to say result = p1 + p2. It is the slowest of the add routines due +// to requiring the most arithmetic. +// +// NOTE: The points must be normalized for this function to return the correct +// result. The resulting point will be normalized. +func addGeneric(p1, p2, result *JacobianPoint) { + // To compute the point addition efficiently, this implementation splits + // the equation into intermediate elements which are used to minimize + // the number of field multiplications using the method shown at: + // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl + // + // In particular it performs the calculations using the following: + // Z1Z1 = Z1^2, Z2Z2 = Z2^2, U1 = X1*Z2Z2, U2 = X2*Z1Z1, S1 = Y1*Z2*Z2Z2 + // S2 = Y2*Z1*Z1Z1, H = U2-U1, I = (2*H)^2, J = H*I, r = 2*(S2-S1) + // V = U1*I + // X3 = r^2-J-2*V, Y3 = r*(V-X3)-2*S1*J, Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H + // + // This results in a cost of 11 field multiplications, 5 field squarings, + // 9 field additions, and 4 integer multiplications. + x1, y1, z1 := &p1.X, &p1.Y, &p1.Z + x2, y2, z2 := &p2.X, &p2.Y, &p2.Z + x3, y3, z3 := &result.X, &result.Y, &result.Z + + // When the x coordinates are the same for two points on the curve, the + // y coordinates either must be the same, in which case it is point + // doubling, or they are opposite and the result is the point at + // infinity. Since any number of Jacobian coordinates can represent the + // same affine point, the x and y values need to be converted to like + // terms. + var z1z1, z2z2, u1, u2, s1, s2 FieldVal + z1z1.SquareVal(z1) // Z1Z1 = Z1^2 (mag: 1) + z2z2.SquareVal(z2) // Z2Z2 = Z2^2 (mag: 1) + u1.Set(x1).Mul(&z2z2).Normalize() // U1 = X1*Z2Z2 (mag: 1) + u2.Set(x2).Mul(&z1z1).Normalize() // U2 = X2*Z1Z1 (mag: 1) + s1.Set(y1).Mul(&z2z2).Mul(z2).Normalize() // S1 = Y1*Z2*Z2Z2 (mag: 1) + s2.Set(y2).Mul(&z1z1).Mul(z1).Normalize() // S2 = Y2*Z1*Z1Z1 (mag: 1) + if u1.Equals(&u2) { + if s1.Equals(&s2) { + // Since x1 == x2 and y1 == y2, point doubling must be + // done, otherwise the addition would end up dividing + // by zero. + DoubleNonConst(p1, result) + return + } + + // Since x1 == x2 and y1 == -y2, the sum is the point at + // infinity per the group law. + x3.SetInt(0) + y3.SetInt(0) + z3.SetInt(0) + return + } + + // Calculate X3, Y3, and Z3 according to the intermediate elements + // breakdown above. + var h, i, j, r, rr, v FieldVal + var negU1, negS1, negX3 FieldVal + negU1.Set(&u1).Negate(1) // negU1 = -U1 (mag: 2) + h.Add2(&u2, &negU1) // H = U2-U1 (mag: 3) + i.Set(&h).MulInt(2).Square() // I = (2*H)^2 (mag: 2) + j.Mul2(&h, &i) // J = H*I (mag: 1) + negS1.Set(&s1).Negate(1) // negS1 = -S1 (mag: 2) + r.Set(&s2).Add(&negS1).MulInt(2) // r = 2*(S2-S1) (mag: 6) + rr.SquareVal(&r) // rr = r^2 (mag: 1) + v.Mul2(&u1, &i) // V = U1*I (mag: 1) + x3.Set(&v).MulInt(2).Add(&j).Negate(3) // X3 = -(J+2*V) (mag: 4) + x3.Add(&rr) // X3 = r^2+X3 (mag: 5) + negX3.Set(x3).Negate(5) // negX3 = -X3 (mag: 6) + y3.Mul2(&s1, &j).MulInt(2).Negate(2) // Y3 = -(2*S1*J) (mag: 3) + y3.Add(v.Add(&negX3).Mul(&r)) // Y3 = r*(V-X3)+Y3 (mag: 4) + z3.Add2(z1, z2).Square() // Z3 = (Z1+Z2)^2 (mag: 1) + z3.Add(z1z1.Add(&z2z2).Negate(2)) // Z3 = Z3-(Z1Z1+Z2Z2) (mag: 4) + z3.Mul(&h) // Z3 = Z3*H (mag: 1) + + // Normalize the resulting field values to a magnitude of 1 as needed. + x3.Normalize() + y3.Normalize() + z3.Normalize() +} + +// AddNonConst adds the passed Jacobian points together and stores the result in +// the provided result param in *non-constant* time. +// +// NOTE: The points must be normalized for this function to return the correct +// result. The resulting point will be normalized. +func AddNonConst(p1, p2, result *JacobianPoint) { + // A point at infinity is the identity according to the group law for + // elliptic curve cryptography. Thus, ∞ + P = P and P + ∞ = P. + if (p1.X.IsZero() && p1.Y.IsZero()) || p1.Z.IsZero() { + result.Set(p2) + return + } + if (p2.X.IsZero() && p2.Y.IsZero()) || p2.Z.IsZero() { + result.Set(p1) + return + } + + // Faster point addition can be achieved when certain assumptions are + // met. For example, when both points have the same z value, arithmetic + // on the z values can be avoided. This section thus checks for these + // conditions and calls an appropriate add function which is accelerated + // by using those assumptions. + isZ1One := p1.Z.IsOne() + isZ2One := p2.Z.IsOne() + switch { + case isZ1One && isZ2One: + addZ1AndZ2EqualsOne(p1, p2, result) + return + case p1.Z.Equals(&p2.Z): + addZ1EqualsZ2(p1, p2, result) + return + case isZ2One: + addZ2EqualsOne(p1, p2, result) + return + } + + // None of the above assumptions are true, so fall back to generic + // point addition. + addGeneric(p1, p2, result) +} + +// doubleZ1EqualsOne performs point doubling on the passed Jacobian point when +// the point is already known to have a z value of 1 and stores the result in +// the provided result param. That is to say result = 2*p. It performs faster +// point doubling than the generic routine since less arithmetic is needed due +// to the ability to avoid multiplication by the z value. +// +// NOTE: The resulting point will be normalized. +func doubleZ1EqualsOne(p, result *JacobianPoint) { + // This function uses the assumptions that z1 is 1, thus the point + // doubling formulas reduce to: + // + // X3 = (3*X1^2)^2 - 8*X1*Y1^2 + // Y3 = (3*X1^2)*(4*X1*Y1^2 - X3) - 8*Y1^4 + // Z3 = 2*Y1 + // + // To compute the above efficiently, this implementation splits the + // equation into intermediate elements which are used to minimize the + // number of field multiplications in favor of field squarings which + // are roughly 35% faster than field multiplications with the current + // implementation at the time this was written. + // + // This uses a slightly modified version of the method shown at: + // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl + // + // In particular it performs the calculations using the following: + // A = X1^2, B = Y1^2, C = B^2, D = 2*((X1+B)^2-A-C) + // E = 3*A, F = E^2, X3 = F-2*D, Y3 = E*(D-X3)-8*C + // Z3 = 2*Y1 + // + // This results in a cost of 1 field multiplication, 5 field squarings, + // 6 field additions, and 5 integer multiplications. + x1, y1 := &p.X, &p.Y + x3, y3, z3 := &result.X, &result.Y, &result.Z + var a, b, c, d, e, f FieldVal + z3.Set(y1).MulInt(2) // Z3 = 2*Y1 (mag: 2) + a.SquareVal(x1) // A = X1^2 (mag: 1) + b.SquareVal(y1) // B = Y1^2 (mag: 1) + c.SquareVal(&b) // C = B^2 (mag: 1) + b.Add(x1).Square() // B = (X1+B)^2 (mag: 1) + d.Set(&a).Add(&c).Negate(2) // D = -(A+C) (mag: 3) + d.Add(&b).MulInt(2) // D = 2*(B+D)(mag: 8) + e.Set(&a).MulInt(3) // E = 3*A (mag: 3) + f.SquareVal(&e) // F = E^2 (mag: 1) + x3.Set(&d).MulInt(2).Negate(16) // X3 = -(2*D) (mag: 17) + x3.Add(&f) // X3 = F+X3 (mag: 18) + f.Set(x3).Negate(18).Add(&d).Normalize() // F = D-X3 (mag: 1) + y3.Set(&c).MulInt(8).Negate(8) // Y3 = -(8*C) (mag: 9) + y3.Add(f.Mul(&e)) // Y3 = E*F+Y3 (mag: 10) + + // Normalize the field values back to a magnitude of 1. + x3.Normalize() + y3.Normalize() + z3.Normalize() +} + +// doubleGeneric performs point doubling on the passed Jacobian point without +// any assumptions about the z value and stores the result in the provided +// result param. That is to say result = 2*p. It is the slowest of the point +// doubling routines due to requiring the most arithmetic. +// +// NOTE: The resulting point will be normalized. +func doubleGeneric(p, result *JacobianPoint) { + // Point doubling formula for Jacobian coordinates for the secp256k1 + // curve: + // + // X3 = (3*X1^2)^2 - 8*X1*Y1^2 + // Y3 = (3*X1^2)*(4*X1*Y1^2 - X3) - 8*Y1^4 + // Z3 = 2*Y1*Z1 + // + // To compute the above efficiently, this implementation splits the + // equation into intermediate elements which are used to minimize the + // number of field multiplications in favor of field squarings which + // are roughly 35% faster than field multiplications with the current + // implementation at the time this was written. + // + // This uses a slightly modified version of the method shown at: + // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l + // + // In particular it performs the calculations using the following: + // A = X1^2, B = Y1^2, C = B^2, D = 2*((X1+B)^2-A-C) + // E = 3*A, F = E^2, X3 = F-2*D, Y3 = E*(D-X3)-8*C + // Z3 = 2*Y1*Z1 + // + // This results in a cost of 1 field multiplication, 5 field squarings, + // 6 field additions, and 5 integer multiplications. + x1, y1, z1 := &p.X, &p.Y, &p.Z + x3, y3, z3 := &result.X, &result.Y, &result.Z + var a, b, c, d, e, f FieldVal + z3.Mul2(y1, z1).MulInt(2) // Z3 = 2*Y1*Z1 (mag: 2) + a.SquareVal(x1) // A = X1^2 (mag: 1) + b.SquareVal(y1) // B = Y1^2 (mag: 1) + c.SquareVal(&b) // C = B^2 (mag: 1) + b.Add(x1).Square() // B = (X1+B)^2 (mag: 1) + d.Set(&a).Add(&c).Negate(2) // D = -(A+C) (mag: 3) + d.Add(&b).MulInt(2) // D = 2*(B+D)(mag: 8) + e.Set(&a).MulInt(3) // E = 3*A (mag: 3) + f.SquareVal(&e) // F = E^2 (mag: 1) + x3.Set(&d).MulInt(2).Negate(16) // X3 = -(2*D) (mag: 17) + x3.Add(&f) // X3 = F+X3 (mag: 18) + f.Set(x3).Negate(18).Add(&d).Normalize() // F = D-X3 (mag: 1) + y3.Set(&c).MulInt(8).Negate(8) // Y3 = -(8*C) (mag: 9) + y3.Add(f.Mul(&e)) // Y3 = E*F+Y3 (mag: 10) + + // Normalize the field values back to a magnitude of 1. + x3.Normalize() + y3.Normalize() + z3.Normalize() +} + +// DoubleNonConst doubles the passed Jacobian point and stores the result in the +// provided result parameter in *non-constant* time. +// +// NOTE: The point must be normalized for this function to return the correct +// result. The resulting point will be normalized. +func DoubleNonConst(p, result *JacobianPoint) { + // Doubling a point at infinity is still infinity. + if p.Y.IsZero() || p.Z.IsZero() { + result.X.SetInt(0) + result.Y.SetInt(0) + result.Z.SetInt(0) + return + } + + // Slightly faster point doubling can be achieved when the z value is 1 + // by avoiding the multiplication on the z value. This section calls + // a point doubling function which is accelerated by using that + // assumption when possible. + if p.Z.IsOne() { + doubleZ1EqualsOne(p, result) + return + } + + // Fall back to generic point doubling which works with arbitrary z + // values. + doubleGeneric(p, result) +} + +// splitK returns a balanced length-two representation of k and their signs. +// This is algorithm 3.74 from [GECC]. +// +// One thing of note about this algorithm is that no matter what c1 and c2 are, +// the final equation of k = k1 + k2 * lambda (mod n) will hold. This is +// provable mathematically due to how a1/b1/a2/b2 are computed. +// +// c1 and c2 are chosen to minimize the max(k1,k2). +func splitK(k []byte) ([]byte, []byte, int, int) { + // All math here is done with big.Int, which is slow. + // At some point, it might be useful to write something similar to + // FieldVal but for N instead of P as the prime field if this ends up + // being a bottleneck. + bigIntK := new(big.Int) + c1, c2 := new(big.Int), new(big.Int) + tmp1, tmp2 := new(big.Int), new(big.Int) + k1, k2 := new(big.Int), new(big.Int) + + bigIntK.SetBytes(k) + // c1 = round(b2 * k / n) from step 4. + // Rounding isn't really necessary and costs too much, hence skipped + c1.Mul(endomorphismB2, bigIntK) + c1.Div(c1, curveParams.N) + // c2 = round(b1 * k / n) from step 4 (sign reversed to optimize one step) + // Rounding isn't really necessary and costs too much, hence skipped + c2.Mul(endomorphismB1, bigIntK) + c2.Div(c2, curveParams.N) + // k1 = k - c1 * a1 - c2 * a2 from step 5 (note c2's sign is reversed) + tmp1.Mul(c1, endomorphismA1) + tmp2.Mul(c2, endomorphismA2) + k1.Sub(bigIntK, tmp1) + k1.Add(k1, tmp2) + // k2 = - c1 * b1 - c2 * b2 from step 5 (note c2's sign is reversed) + tmp1.Mul(c1, endomorphismB1) + tmp2.Mul(c2, endomorphismB2) + k2.Sub(tmp2, tmp1) + + // Note Bytes() throws out the sign of k1 and k2. This matters + // since k1 and/or k2 can be negative. Hence, we pass that + // back separately. + return k1.Bytes(), k2.Bytes(), k1.Sign(), k2.Sign() +} + +// nafScalar represents a positive integer up to a maximum value of 2^256 - 1 +// encoded in non-adjacent form. +// +// NAF is a signed-digit representation where each digit can be +1, 0, or -1. +// +// In order to efficiently encode that information, this type uses two arrays, a +// "positive" array where set bits represent the +1 signed digits and a +// "negative" array where set bits represent the -1 signed digits. 0 is +// represented by neither array having a bit set in that position. +// +// The Pos and Neg methods return the aforementioned positive and negative +// arrays, respectively. +type nafScalar struct { + // pos houses the positive portion of the representation. An additional + // byte is required for the positive portion because the NAF encoding can be + // up to 1 bit longer than the normal binary encoding of the value. + // + // neg houses the negative portion of the representation. Even though the + // additional byte is not required for the negative portion, since it can + // never exceed the length of the normal binary encoding of the value, + // keeping the same length for positive and negative portions simplifies + // working with the representation and allows extra conditional branches to + // be avoided. + // + // start and end specify the starting and ending index to use within the pos + // and neg arrays, respectively. This allows fixed size arrays to be used + // versus needing to dynamically allocate space on the heap. + // + // NOTE: The fields are defined in the order that they are to minimize the + // padding on 32-bit and 64-bit platforms. + pos [33]byte + start, end uint8 + neg [33]byte +} + +// Pos returns the bytes of the encoded value with bits set in the positions +// that represent a signed digit of +1. +func (s *nafScalar) Pos() []byte { + return s.pos[s.start:s.end] +} + +// Neg returns the bytes of the encoded value with bits set in the positions +// that represent a signed digit of -1. +func (s *nafScalar) Neg() []byte { + return s.neg[s.start:s.end] +} + +// naf takes a positive integer up to a maximum value of 2^256 - 1 and returns +// its non-adjacent form (NAF), which is a unique signed-digit representation +// such that no two consecutive digits are nonzero. See the documentation for +// the returned type for details on how the representation is encoded +// efficiently and how to interpret it +// +// NAF is useful in that it has the fewest nonzero digits of any signed digit +// representation, only 1/3rd of its digits are nonzero on average, and at least +// half of the digits will be 0. +// +// The aforementioned properties are particularly beneficial for optimizing +// elliptic curve point multiplication because they effectively minimize the +// number of required point additions in exchange for needing to perform a mix +// of fewer point additions and subtractions and possibly one additional point +// doubling. This is an excellent tradeoff because subtraction of points has +// the same computational complexity as addition of points and point doubling is +// faster than both. +func naf(k []byte) nafScalar { + // Strip leading zero bytes. + for len(k) > 0 && k[0] == 0x00 { + k = k[1:] + } + + // The non-adjacent form (NAF) of a positive integer k is an expression + // k = ∑_(i=0, l-1) k_i * 2^i where k_i ∈ {0,±1}, k_(l-1) != 0, and no two + // consecutive digits k_i are nonzero. + // + // The traditional method of computing the NAF of a positive integer is + // given by algorithm 3.30 in [GECC]. It consists of repeatedly dividing k + // by 2 and choosing the remainder so that the quotient (k−r)/2 is even + // which ensures the next NAF digit is 0. This requires log_2(k) steps. + // + // However, in [BRID], Prodinger notes that a closed form expression for the + // NAF representation is the bitwise difference 3k/2 - k/2. This is more + // efficient as it can be computed in O(1) versus the O(log(n)) of the + // traditional approach. + // + // The following code makes use of that formula to compute the NAF more + // efficiently. + // + // To understand the logic here, observe that the only way the NAF has a + // nonzero digit at a given bit is when either 3k/2 or k/2 has a bit set in + // that position, but not both. In other words, the result of a bitwise + // xor. This can be seen simply by considering that when the bits are the + // same, the subtraction is either 0-0 or 1-1, both of which are 0. + // + // Further, observe that the "+1" digits in the result are contributed by + // 3k/2 while the "-1" digits are from k/2. So, they can be determined by + // taking the bitwise and of each respective value with the result of the + // xor which identifies which bits are nonzero. + // + // Using that information, this loops backwards from the least significant + // byte to the most significant byte while performing the aforementioned + // calculations by propagating the potential carry and high order bit from + // the next word during the right shift. + kLen := len(k) + var result nafScalar + var carry uint8 + for byteNum := kLen - 1; byteNum >= 0; byteNum-- { + // Calculate k/2. Notice the carry from the previous word is added and + // the low order bit from the next word is shifted in accordingly. + kc := uint16(k[byteNum]) + uint16(carry) + var nextWord uint8 + if byteNum > 0 { + nextWord = k[byteNum-1] + } + halfK := kc>>1 | uint16(nextWord<<7) + + // Calculate 3k/2 and determine the non-zero digits in the result. + threeHalfK := kc + halfK + nonZeroResultDigits := threeHalfK ^ halfK + + // Determine the signed digits {0, ±1}. + result.pos[byteNum+1] = uint8(threeHalfK & nonZeroResultDigits) + result.neg[byteNum+1] = uint8(halfK & nonZeroResultDigits) + + // Propagate the potential carry from the 3k/2 calculation. + carry = uint8(threeHalfK >> 8) + } + result.pos[0] = carry + + // Set the starting and ending positions within the fixed size arrays to + // identify the bytes that are actually used. This is important since the + // encoding is big endian and thus trailing zero bytes changes its value. + result.start = 1 - carry + result.end = uint8(kLen + 1) + return result +} + +// ScalarMultNonConst multiplies k*P where k is a big endian integer modulo the +// curve order and P is a point in Jacobian projective coordinates and stores +// the result in the provided Jacobian point. +// +// NOTE: The point must be normalized for this function to return the correct +// result. The resulting point will be normalized. +func ScalarMultNonConst(k *ModNScalar, point, result *JacobianPoint) { + // Decompose K into k1 and k2 in order to halve the number of EC ops. + // See Algorithm 3.74 in [GECC]. + kBytes := k.Bytes() + k1, k2, signK1, signK2 := splitK(kBytes[:]) + zeroArray32(&kBytes) + + // The main equation here to remember is: + // k * P = k1 * P + k2 * ϕ(P) + // + // P1 below is P in the equation, P2 below is ϕ(P) in the equation + p1, p1Neg := new(JacobianPoint), new(JacobianPoint) + p1.Set(point) + p1Neg.Set(p1) + p1Neg.Y.Negate(1).Normalize() + + // NOTE: ϕ(x,y) = (βx,y). The Jacobian z coordinates are the same, so this + // math goes through. + p2, p2Neg := new(JacobianPoint), new(JacobianPoint) + p2.Set(p1) + p2.X.Mul(endomorphismBeta).Normalize() + p2Neg.Set(p2) + p2Neg.Y.Negate(1).Normalize() + + // Flip the positive and negative values of the points as needed + // depending on the signs of k1 and k2. As mentioned in the equation + // above, each of k1 and k2 are multiplied by the respective point. + // Since -k * P is the same thing as k * -P, and the group law for + // elliptic curves states that P(x, y) = -P(x, -y), it's faster and + // simplifies the code to just make the point negative. + if signK1 == -1 { + p1, p1Neg = p1Neg, p1 + } + if signK2 == -1 { + p2, p2Neg = p2Neg, p2 + } + + // NAF versions of k1 and k2 should have a lot more zeros. + // + // The Pos version of the bytes contain the +1s and the Neg versions + // contain the -1s. + k1NAF, k2NAF := naf(k1), naf(k2) + k1PosNAF, k1NegNAF := k1NAF.Pos(), k1NAF.Neg() + k2PosNAF, k2NegNAF := k2NAF.Pos(), k2NAF.Neg() + k1Len, k2Len := len(k1PosNAF), len(k2PosNAF) + + m := k1Len + if m < k2Len { + m = k2Len + } + + // Point Q = ∞ (point at infinity). + var q JacobianPoint + + // Add left-to-right using the NAF optimization. See algorithm 3.77 + // from [GECC]. This should be faster overall since there will be a lot + // more instances of 0, hence reducing the number of Jacobian additions + // at the cost of 1 possible extra doubling. + for i := 0; i < m; i++ { + // Since k1 and k2 are potentially different lengths and the calculation + // is being done left to right, pad the front of the shorter one with + // 0s. + var k1BytePos, k1ByteNeg, k2BytePos, k2ByteNeg byte + if i >= m-k1Len { + k1BytePos, k1ByteNeg = k1PosNAF[i-(m-k1Len)], k1NegNAF[i-(m-k1Len)] + } + if i >= m-k2Len { + k2BytePos, k2ByteNeg = k2PosNAF[i-(m-k2Len)], k2NegNAF[i-(m-k2Len)] + } + for bit, mask := 7, uint8(1<<7); bit >= 0; bit, mask = bit-1, mask>>1 { + // Q = 2 * Q + DoubleNonConst(&q, &q) + + // Add or subtract the first point based on the signed digit of the + // NAF representation of k1 at this bit position. + // + // +1: Q = Q + p1 + // -1: Q = Q - p1 + // 0: Q = Q (no change) + if k1BytePos&mask == mask { + AddNonConst(&q, p1, &q) + } else if k1ByteNeg&mask == mask { + AddNonConst(&q, p1Neg, &q) + } + + // Add or subtract the second point based on the signed digit of the + // NAF representation of k2 at this bit position. + // + // +1: Q = Q + p2 + // -1: Q = Q - p2 + // 0: Q = Q (no change) + if k2BytePos&mask == mask { + AddNonConst(&q, p2, &q) + } else if k2ByteNeg&mask == mask { + AddNonConst(&q, p2Neg, &q) + } + } + } + + result.Set(&q) +} + +// ScalarBaseMultNonConst multiplies k*G where G is the base point of the group +// and k is a big endian integer. The result is stored in Jacobian coordinates +// (x1, y1, z1). +// +// NOTE: The resulting point will be normalized. +func ScalarBaseMultNonConst(k *ModNScalar, result *JacobianPoint) { + bytePoints := s256BytePoints() + + // Point Q = ∞ (point at infinity). + var q JacobianPoint + + // curve.bytePoints has all 256 byte points for each 8-bit window. The + // strategy is to add up the byte points. This is best understood by + // expressing k in base-256 which it already sort of is. Each "digit" in + // the 8-bit window can be looked up using bytePoints and added together. + var pt JacobianPoint + for i, byteVal := range k.Bytes() { + p := bytePoints[i][byteVal] + pt.X.Set(&p[0]) + pt.Y.Set(&p[1]) + pt.Z.SetInt(1) + AddNonConst(&q, &pt, &q) + } + + result.Set(&q) +} + +// isOnCurve returns whether or not the affine point (x,y) is on the curve. +func isOnCurve(fx, fy *FieldVal) bool { + // Elliptic curve equation for secp256k1 is: y^2 = x^3 + 7 + y2 := new(FieldVal).SquareVal(fy).Normalize() + result := new(FieldVal).SquareVal(fx).Mul(fx).AddInt(7).Normalize() + return y2.Equals(result) +} + +// DecompressY attempts to calculate the Y coordinate for the given X coordinate +// such that the result pair is a point on the secp256k1 curve. It adjusts Y +// based on the desired oddness and returns whether or not it was successful +// since not all X coordinates are valid. +// +// The magnitude of the provided X coordinate field val must be a max of 8 for a +// correct result. The resulting Y field val will have a max magnitude of 2. +func DecompressY(x *FieldVal, odd bool, resultY *FieldVal) bool { + // The curve equation for secp256k1 is: y^2 = x^3 + 7. Thus + // y = +-sqrt(x^3 + 7). + // + // The x coordinate must be invalid if there is no square root for the + // calculated rhs because it means the X coordinate is not for a point on + // the curve. + x3PlusB := new(FieldVal).SquareVal(x).Mul(x).AddInt(7) + if hasSqrt := resultY.SquareRootVal(x3PlusB); !hasSqrt { + return false + } + if resultY.Normalize().IsOdd() != odd { + resultY.Negate(1) + } + return true +} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/doc.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/doc.go new file mode 100644 index 0000000..91a670e --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/doc.go @@ -0,0 +1,58 @@ +// Copyright (c) 2013-2014 The btcsuite developers +// Copyright (c) 2015-2019 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +/* +Package secp256k1 implements optimized secp256k1 elliptic curve operations. + +This package provides an optimized pure Go implementation of elliptic curve +cryptography operations over the secp256k1 curve as well as data structures and +functions for working with public and private secp256k1 keys. See +https://www.secg.org/sec2-v2.pdf for details on the standard. + +In addition, sub packages are provided to produce, verify, parse, and serialize +ECDSA signatures and EC-Schnorr-DCRv0 (a custom Schnorr-based signature scheme +specific to Decred) signatures. See the README.md files in the relevant sub +packages for more details about those aspects. + +An overview of the features provided by this package are as follows: + + - Private key generation, serialization, and parsing + - Public key generation, serialization and parsing per ANSI X9.62-1998 + - Parses uncompressed, compressed, and hybrid public keys + - Serializes uncompressed and compressed public keys + - Specialized types for performing optimized and constant time field operations + - FieldVal type for working modulo the secp256k1 field prime + - ModNScalar type for working modulo the secp256k1 group order + - Elliptic curve operations in Jacobian projective coordinates + - Point addition + - Point doubling + - Scalar multiplication with an arbitrary point + - Scalar multiplication with the base point (group generator) + - Point decompression from a given x coordinate + - Nonce generation via RFC6979 with support for extra data and version + information that can be used to prevent nonce reuse between signing + algorithms + +It also provides an implementation of the Go standard library crypto/elliptic +Curve interface via the S256 function so that it may be used with other packages +in the standard library such as crypto/tls, crypto/x509, and crypto/ecdsa. +However, in the case of ECDSA, it is highly recommended to use the ecdsa sub +package of this package instead since it is optimized specifically for secp256k1 +and is significantly faster as a result. + +Although this package was primarily written for dcrd, it has intentionally been +designed so it can be used as a standalone package for any projects needing to +use optimized secp256k1 elliptic curve cryptography. + +Finally, a comprehensive suite of tests is provided to provide a high level of +quality assurance. + +Use of secp256k1 in Decred + +At the time of this writing, the primary public key cryptography in widespread +use on the Decred network used to secure coins is based on elliptic curves +defined by the secp256k1 domain parameters. +*/ +package secp256k1 diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdh.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdh.go new file mode 100644 index 0000000..ebbdfc5 --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdh.go @@ -0,0 +1,21 @@ +// Copyright (c) 2015 The btcsuite developers +// Copyright (c) 2015-2016 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +// GenerateSharedSecret generates a shared secret based on a private key and a +// public key using Diffie-Hellman key exchange (ECDH) (RFC 5903). +// RFC5903 Section 9 states we should only return x. +// +// It is recommended to securily hash the result before using as a cryptographic +// key. +func GenerateSharedSecret(privkey *PrivateKey, pubkey *PublicKey) []byte { + var point, result JacobianPoint + pubkey.AsJacobian(&point) + ScalarMultNonConst(&privkey.Key, &point, &result) + result.ToAffine() + xBytes := result.X.Bytes() + return xBytes[:] +} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ellipticadaptor.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ellipticadaptor.go new file mode 100644 index 0000000..a271ff6 --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ellipticadaptor.go @@ -0,0 +1,255 @@ +// Copyright 2020-2021 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +// References: +// [SECG]: Recommended Elliptic Curve Domain Parameters +// https://www.secg.org/sec2-v2.pdf +// +// [GECC]: Guide to Elliptic Curve Cryptography (Hankerson, Menezes, Vanstone) + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "math/big" +) + +// CurveParams contains the parameters for the secp256k1 curve. +type CurveParams struct { + // P is the prime used in the secp256k1 field. + P *big.Int + + // N is the order of the secp256k1 curve group generated by the base point. + N *big.Int + + // Gx and Gy are the x and y coordinate of the base point, respectively. + Gx, Gy *big.Int + + // BitSize is the size of the underlying secp256k1 field in bits. + BitSize int + + // H is the cofactor of the secp256k1 curve. + H int + + // ByteSize is simply the bit size / 8 and is provided for convenience + // since it is calculated repeatedly. + ByteSize int +} + +// Curve parameters taken from [SECG] section 2.4.1. +var curveParams = CurveParams{ + P: fromHex("fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"), + N: fromHex("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"), + Gx: fromHex("79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"), + Gy: fromHex("483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8"), + BitSize: 256, + H: 1, + ByteSize: 256 / 8, +} + +// Params returns the secp256k1 curve parameters for convenience. +func Params() *CurveParams { + return &curveParams +} + +// KoblitzCurve provides an implementation for secp256k1 that fits the ECC Curve +// interface from crypto/elliptic. +type KoblitzCurve struct { + *elliptic.CurveParams +} + +// bigAffineToJacobian takes an affine point (x, y) as big integers and converts +// it to Jacobian point with Z=1. +func bigAffineToJacobian(x, y *big.Int, result *JacobianPoint) { + result.X.SetByteSlice(x.Bytes()) + result.Y.SetByteSlice(y.Bytes()) + result.Z.SetInt(1) +} + +// jacobianToBigAffine takes a Jacobian point (x, y, z) as field values and +// converts it to an affine point as big integers. +func jacobianToBigAffine(point *JacobianPoint) (*big.Int, *big.Int) { + point.ToAffine() + + // Convert the field values for the now affine point to big.Ints. + x3, y3 := new(big.Int), new(big.Int) + x3.SetBytes(point.X.Bytes()[:]) + y3.SetBytes(point.Y.Bytes()[:]) + return x3, y3 +} + +// Params returns the parameters for the curve. +// +// This is part of the elliptic.Curve interface implementation. +func (curve *KoblitzCurve) Params() *elliptic.CurveParams { + return curve.CurveParams +} + +// IsOnCurve returns whether or not the affine point (x,y) is on the curve. +// +// This is part of the elliptic.Curve interface implementation. This function +// differs from the crypto/elliptic algorithm since a = 0 not -3. +func (curve *KoblitzCurve) IsOnCurve(x, y *big.Int) bool { + // Convert big ints to a Jacobian point for faster arithmetic. + var point JacobianPoint + bigAffineToJacobian(x, y, &point) + return isOnCurve(&point.X, &point.Y) +} + +// Add returns the sum of (x1,y1) and (x2,y2). +// +// This is part of the elliptic.Curve interface implementation. +func (curve *KoblitzCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) { + // A point at infinity is the identity according to the group law for + // elliptic curve cryptography. Thus, ∞ + P = P and P + ∞ = P. + if x1.Sign() == 0 && y1.Sign() == 0 { + return x2, y2 + } + if x2.Sign() == 0 && y2.Sign() == 0 { + return x1, y1 + } + + // Convert the affine coordinates from big integers to Jacobian points, + // do the point addition in Jacobian projective space, and convert the + // Jacobian point back to affine big.Ints. + var p1, p2, result JacobianPoint + bigAffineToJacobian(x1, y1, &p1) + bigAffineToJacobian(x2, y2, &p2) + AddNonConst(&p1, &p2, &result) + return jacobianToBigAffine(&result) +} + +// Double returns 2*(x1,y1). +// +// This is part of the elliptic.Curve interface implementation. +func (curve *KoblitzCurve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) { + if y1.Sign() == 0 { + return new(big.Int), new(big.Int) + } + + // Convert the affine coordinates from big integers to Jacobian points, + // do the point doubling in Jacobian projective space, and convert the + // Jacobian point back to affine big.Ints. + var point, result JacobianPoint + bigAffineToJacobian(x1, y1, &point) + DoubleNonConst(&point, &result) + return jacobianToBigAffine(&result) +} + +// moduloReduce reduces k from more than 32 bytes to 32 bytes and under. This +// is done by doing a simple modulo curve.N. We can do this since G^N = 1 and +// thus any other valid point on the elliptic curve has the same order. +func moduloReduce(k []byte) []byte { + // Since the order of G is curve.N, we can use a much smaller number by + // doing modulo curve.N + if len(k) > curveParams.ByteSize { + tmpK := new(big.Int).SetBytes(k) + tmpK.Mod(tmpK, curveParams.N) + return tmpK.Bytes() + } + + return k +} + +// ScalarMult returns k*(Bx, By) where k is a big endian integer. +// +// This is part of the elliptic.Curve interface implementation. +func (curve *KoblitzCurve) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int) { + // Convert the affine coordinates from big integers to Jacobian points, + // do the multiplication in Jacobian projective space, and convert the + // Jacobian point back to affine big.Ints. + var kModN ModNScalar + kModN.SetByteSlice(moduloReduce(k)) + var point, result JacobianPoint + bigAffineToJacobian(Bx, By, &point) + ScalarMultNonConst(&kModN, &point, &result) + return jacobianToBigAffine(&result) +} + +// ScalarBaseMult returns k*G where G is the base point of the group and k is a +// big endian integer. +// +// This is part of the elliptic.Curve interface implementation. +func (curve *KoblitzCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) { + // Perform the multiplication and convert the Jacobian point back to affine + // big.Ints. + var kModN ModNScalar + kModN.SetByteSlice(moduloReduce(k)) + var result JacobianPoint + ScalarBaseMultNonConst(&kModN, &result) + return jacobianToBigAffine(&result) +} + +// X returns the x coordinate of the public key. +func (p *PublicKey) X() *big.Int { + return new(big.Int).SetBytes(p.x.Bytes()[:]) +} + +// Y returns the y coordinate of the public key. +func (p *PublicKey) Y() *big.Int { + return new(big.Int).SetBytes(p.y.Bytes()[:]) +} + +// ToECDSA returns the public key as a *ecdsa.PublicKey. +func (p *PublicKey) ToECDSA() *ecdsa.PublicKey { + return &ecdsa.PublicKey{ + Curve: S256(), + X: p.X(), + Y: p.Y(), + } +} + +// ToECDSA returns the private key as a *ecdsa.PrivateKey. +func (p *PrivateKey) ToECDSA() *ecdsa.PrivateKey { + var privKeyBytes [PrivKeyBytesLen]byte + p.Key.PutBytes(&privKeyBytes) + var result JacobianPoint + ScalarBaseMultNonConst(&p.Key, &result) + x, y := jacobianToBigAffine(&result) + newPrivKey := &ecdsa.PrivateKey{ + PublicKey: ecdsa.PublicKey{ + Curve: S256(), + X: x, + Y: y, + }, + D: new(big.Int).SetBytes(privKeyBytes[:]), + } + zeroArray32(&privKeyBytes) + return newPrivKey +} + +// fromHex converts the passed hex string into a big integer pointer and will +// panic is there is an error. This is only provided for the hard-coded +// constants so errors in the source code can bet detected. It will only (and +// must only) be called for initialization purposes. +func fromHex(s string) *big.Int { + if s == "" { + return big.NewInt(0) + } + r, ok := new(big.Int).SetString(s, 16) + if !ok { + panic("invalid hex in source file: " + s) + } + return r +} + +// secp256k1 is a global instance of the KoblitzCurve implementation which in +// turn embeds and implements elliptic.CurveParams. +var secp256k1 = &KoblitzCurve{ + CurveParams: &elliptic.CurveParams{ + P: curveParams.P, + N: curveParams.N, + B: fromHex("0000000000000000000000000000000000000000000000000000000000000007"), + Gx: curveParams.Gx, + Gy: curveParams.Gy, + BitSize: curveParams.BitSize, + Name: "secp256k1", + }, +} + +// S256 returns a Curve which implements secp256k1. +func S256() *KoblitzCurve { + return secp256k1 +} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/error.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/error.go new file mode 100644 index 0000000..ac8c451 --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/error.go @@ -0,0 +1,67 @@ +// Copyright (c) 2020 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +// ErrorKind identifies a kind of error. It has full support for errors.Is and +// errors.As, so the caller can directly check against an error kind when +// determining the reason for an error. +type ErrorKind string + +// These constants are used to identify a specific RuleError. +const ( + // ErrPubKeyInvalidLen indicates that the length of a serialized public + // key is not one of the allowed lengths. + ErrPubKeyInvalidLen = ErrorKind("ErrPubKeyInvalidLen") + + // ErrPubKeyInvalidFormat indicates an attempt was made to parse a public + // key that does not specify one of the supported formats. + ErrPubKeyInvalidFormat = ErrorKind("ErrPubKeyInvalidFormat") + + // ErrPubKeyXTooBig indicates that the x coordinate for a public key + // is greater than or equal to the prime of the field underlying the group. + ErrPubKeyXTooBig = ErrorKind("ErrPubKeyXTooBig") + + // ErrPubKeyYTooBig indicates that the y coordinate for a public key is + // greater than or equal to the prime of the field underlying the group. + ErrPubKeyYTooBig = ErrorKind("ErrPubKeyYTooBig") + + // ErrPubKeyNotOnCurve indicates that a public key is not a point on the + // secp256k1 curve. + ErrPubKeyNotOnCurve = ErrorKind("ErrPubKeyNotOnCurve") + + // ErrPubKeyMismatchedOddness indicates that a hybrid public key specified + // an oddness of the y coordinate that does not match the actual oddness of + // the provided y coordinate. + ErrPubKeyMismatchedOddness = ErrorKind("ErrPubKeyMismatchedOddness") +) + +// Error satisfies the error interface and prints human-readable errors. +func (e ErrorKind) Error() string { + return string(e) +} + +// Error identifies an error related to public key cryptography using a +// sec256k1 curve. It has full support for errors.Is and errors.As, so the +// caller can ascertain the specific reason for the error by checking +// the underlying error. +type Error struct { + Err error + Description string +} + +// Error satisfies the error interface and prints human-readable errors. +func (e Error) Error() string { + return e.Description +} + +// Unwrap returns the underlying wrapped error. +func (e Error) Unwrap() error { + return e.Err +} + +// makeError creates an Error given a set of arguments. +func makeError(kind ErrorKind, desc string) Error { + return Error{Err: kind, Description: desc} +} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/field.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/field.go new file mode 100644 index 0000000..959a9a1 --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/field.go @@ -0,0 +1,1680 @@ +// Copyright (c) 2013-2014 The btcsuite developers +// Copyright (c) 2015-2020 The Decred developers +// Copyright (c) 2013-2020 Dave Collins +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +// References: +// [HAC]: Handbook of Applied Cryptography Menezes, van Oorschot, Vanstone. +// http://cacr.uwaterloo.ca/hac/ + +// All elliptic curve operations for secp256k1 are done in a finite field +// characterized by a 256-bit prime. Given this precision is larger than the +// biggest available native type, obviously some form of bignum math is needed. +// This package implements specialized fixed-precision field arithmetic rather +// than relying on an arbitrary-precision arithmetic package such as math/big +// for dealing with the field math since the size is known. As a result, rather +// large performance gains are achieved by taking advantage of many +// optimizations not available to arbitrary-precision arithmetic and generic +// modular arithmetic algorithms. +// +// There are various ways to internally represent each finite field element. +// For example, the most obvious representation would be to use an array of 4 +// uint64s (64 bits * 4 = 256 bits). However, that representation suffers from +// a couple of issues. First, there is no native Go type large enough to handle +// the intermediate results while adding or multiplying two 64-bit numbers, and +// second there is no space left for overflows when performing the intermediate +// arithmetic between each array element which would lead to expensive carry +// propagation. +// +// Given the above, this implementation represents the field elements as +// 10 uint32s with each word (array entry) treated as base 2^26. This was +// chosen for the following reasons: +// 1) Most systems at the current time are 64-bit (or at least have 64-bit +// registers available for specialized purposes such as MMX) so the +// intermediate results can typically be done using a native register (and +// using uint64s to avoid the need for additional half-word arithmetic) +// 2) In order to allow addition of the internal words without having to +// propagate the carry, the max normalized value for each register must +// be less than the number of bits available in the register +// 3) Since we're dealing with 32-bit values, 64-bits of overflow is a +// reasonable choice for #2 +// 4) Given the need for 256-bits of precision and the properties stated in #1, +// #2, and #3, the representation which best accommodates this is 10 uint32s +// with base 2^26 (26 bits * 10 = 260 bits, so the final word only needs 22 +// bits) which leaves the desired 64 bits (32 * 10 = 320, 320 - 256 = 64) for +// overflow +// +// Since it is so important that the field arithmetic is extremely fast for high +// performance crypto, this type does not perform any validation where it +// ordinarily would. See the documentation for FieldVal for more details. + +import ( + "encoding/hex" +) + +// Constants used to make the code more readable. +const ( + twoBitsMask = 0x3 + fourBitsMask = 0xf + sixBitsMask = 0x3f + eightBitsMask = 0xff +) + +// Constants related to the field representation. +const ( + // fieldWords is the number of words used to internally represent the + // 256-bit value. + fieldWords = 10 + + // fieldBase is the exponent used to form the numeric base of each word. + // 2^(fieldBase*i) where i is the word position. + fieldBase = 26 + + // fieldBaseMask is the mask for the bits in each word needed to + // represent the numeric base of each word (except the most significant + // word). + fieldBaseMask = (1 << fieldBase) - 1 + + // fieldMSBBits is the number of bits in the most significant word used + // to represent the value. + fieldMSBBits = 256 - (fieldBase * (fieldWords - 1)) + + // fieldMSBMask is the mask for the bits in the most significant word + // needed to represent the value. + fieldMSBMask = (1 << fieldMSBBits) - 1 + + // These fields provide convenient access to each of the words of the + // secp256k1 prime in the internal field representation to improve code + // readability. + fieldPrimeWordZero = 0x03fffc2f + fieldPrimeWordOne = 0x03ffffbf + fieldPrimeWordTwo = 0x03ffffff + fieldPrimeWordThree = 0x03ffffff + fieldPrimeWordFour = 0x03ffffff + fieldPrimeWordFive = 0x03ffffff + fieldPrimeWordSix = 0x03ffffff + fieldPrimeWordSeven = 0x03ffffff + fieldPrimeWordEight = 0x03ffffff + fieldPrimeWordNine = 0x003fffff +) + +// FieldVal implements optimized fixed-precision arithmetic over the +// secp256k1 finite field. This means all arithmetic is performed modulo +// 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f. +// +// WARNING: Since it is so important for the field arithmetic to be extremely +// fast for high performance crypto, this type does not perform any validation +// of documented preconditions where it ordinarily would. As a result, it is +// IMPERATIVE for callers to understand some key concepts that are described +// below and ensure the methods are called with the necessary preconditions that +// each method is documented with. For example, some methods only give the +// correct result if the field value is normalized and others require the field +// values involved to have a maximum magnitude and THERE ARE NO EXPLICIT CHECKS +// TO ENSURE THOSE PRECONDITIONS ARE SATISFIED. This does, unfortunately, make +// the type more difficult to use correctly and while I typically prefer to +// ensure all state and input is valid for most code, this is a bit of an +// exception because those extra checks really add up in what ends up being +// critical hot paths. +// +// The first key concept when working with this type is normalization. In order +// to avoid the need to propagate a ton of carries, the internal representation +// provides additional overflow bits for each word of the overall 256-bit value. +// This means that there are multiple internal representations for the same +// value and, as a result, any methods that rely on comparison of the value, +// such as equality and oddness determination, require the caller to provide a +// normalized value. +// +// The second key concept when working with this type is magnitude. As +// previously mentioned, the internal representation provides additional +// overflow bits which means that the more math operations that are performed on +// the field value between normalizations, the more those overflow bits +// accumulate. The magnitude is effectively that maximum possible number of +// those overflow bits that could possibly be required as a result of a given +// operation. Since there are only a limited number of overflow bits available, +// this implies that the max possible magnitude MUST be tracked by the caller +// and the caller MUST normalize the field value if a given operation would +// cause the magnitude of the result to exceed the max allowed value. +// +// IMPORTANT: The max allowed magnitude of a field value is 64. +type FieldVal struct { + // Each 256-bit value is represented as 10 32-bit integers in base 2^26. + // This provides 6 bits of overflow in each word (10 bits in the most + // significant word) for a total of 64 bits of overflow (9*6 + 10 = 64). It + // only implements the arithmetic needed for elliptic curve operations. + // + // The following depicts the internal representation: + // ----------------------------------------------------------------- + // | n[9] | n[8] | ... | n[0] | + // | 32 bits available | 32 bits available | ... | 32 bits available | + // | 22 bits for value | 26 bits for value | ... | 26 bits for value | + // | 10 bits overflow | 6 bits overflow | ... | 6 bits overflow | + // | Mult: 2^(26*9) | Mult: 2^(26*8) | ... | Mult: 2^(26*0) | + // ----------------------------------------------------------------- + // + // For example, consider the number 2^49 + 1. It would be represented as: + // n[0] = 1 + // n[1] = 2^23 + // n[2..9] = 0 + // + // The full 256-bit value is then calculated by looping i from 9..0 and + // doing sum(n[i] * 2^(26i)) like so: + // n[9] * 2^(26*9) = 0 * 2^234 = 0 + // n[8] * 2^(26*8) = 0 * 2^208 = 0 + // ... + // n[1] * 2^(26*1) = 2^23 * 2^26 = 2^49 + // n[0] * 2^(26*0) = 1 * 2^0 = 1 + // Sum: 0 + 0 + ... + 2^49 + 1 = 2^49 + 1 + n [10]uint32 +} + +// String returns the field value as a normalized human-readable hex string. +// +// Preconditions: None +// Output Normalized: Field is not modified -- same as input value +// Output Max Magnitude: Field is not modified -- same as input value +func (f FieldVal) String() string { + // f is a copy, so it's safe to normalize it without mutating the original. + f.Normalize() + return hex.EncodeToString(f.Bytes()[:]) +} + +// Zero sets the field value to zero in constant time. A newly created field +// value is already set to zero. This function can be useful to clear an +// existing field value for reuse. +// +// Preconditions: None +// Output Normalized: Yes +// Output Max Magnitude: 1 +func (f *FieldVal) Zero() { + f.n[0] = 0 + f.n[1] = 0 + f.n[2] = 0 + f.n[3] = 0 + f.n[4] = 0 + f.n[5] = 0 + f.n[6] = 0 + f.n[7] = 0 + f.n[8] = 0 + f.n[9] = 0 +} + +// Set sets the field value equal to the passed value in constant time. The +// normalization and magnitude of the two fields will be identical. +// +// The field value is returned to support chaining. This enables syntax like: +// f := new(FieldVal).Set(f2).Add(1) so that f = f2 + 1 where f2 is not +// modified. +// +// Preconditions: None +// Output Normalized: Same as input value +// Output Max Magnitude: Same as input value +func (f *FieldVal) Set(val *FieldVal) *FieldVal { + *f = *val + return f +} + +// SetInt sets the field value to the passed integer in constant time. This is +// a convenience function since it is fairly common to perform some arithmetic +// with small native integers. +// +// The field value is returned to support chaining. This enables syntax such +// as f := new(FieldVal).SetInt(2).Mul(f2) so that f = 2 * f2. +// +// Preconditions: None +// Output Normalized: Yes +// Output Max Magnitude: 1 +func (f *FieldVal) SetInt(ui uint16) *FieldVal { + f.Zero() + f.n[0] = uint32(ui) + return f +} + +// SetBytes packs the passed 32-byte big-endian value into the internal field +// value representation in constant time. SetBytes interprets the provided +// array as a 256-bit big-endian unsigned integer, packs it into the internal +// field value representation, and returns either 1 if it is greater than or +// equal to the field prime (aka it overflowed) or 0 otherwise in constant time. +// +// Note that a bool is not used here because it is not possible in Go to convert +// from a bool to numeric value in constant time and many constant-time +// operations require a numeric value. +// +// Preconditions: None +// Output Normalized: Yes if no overflow, no otherwise +// Output Max Magnitude: 1 +func (f *FieldVal) SetBytes(b *[32]byte) uint32 { + // Pack the 256 total bits across the 10 uint32 words with a max of + // 26-bits per word. This could be done with a couple of for loops, + // but this unrolled version is significantly faster. Benchmarks show + // this is about 34 times faster than the variant which uses loops. + f.n[0] = uint32(b[31]) | uint32(b[30])<<8 | uint32(b[29])<<16 | + (uint32(b[28])&twoBitsMask)<<24 + f.n[1] = uint32(b[28])>>2 | uint32(b[27])<<6 | uint32(b[26])<<14 | + (uint32(b[25])&fourBitsMask)<<22 + f.n[2] = uint32(b[25])>>4 | uint32(b[24])<<4 | uint32(b[23])<<12 | + (uint32(b[22])&sixBitsMask)<<20 + f.n[3] = uint32(b[22])>>6 | uint32(b[21])<<2 | uint32(b[20])<<10 | + uint32(b[19])<<18 + f.n[4] = uint32(b[18]) | uint32(b[17])<<8 | uint32(b[16])<<16 | + (uint32(b[15])&twoBitsMask)<<24 + f.n[5] = uint32(b[15])>>2 | uint32(b[14])<<6 | uint32(b[13])<<14 | + (uint32(b[12])&fourBitsMask)<<22 + f.n[6] = uint32(b[12])>>4 | uint32(b[11])<<4 | uint32(b[10])<<12 | + (uint32(b[9])&sixBitsMask)<<20 + f.n[7] = uint32(b[9])>>6 | uint32(b[8])<<2 | uint32(b[7])<<10 | + uint32(b[6])<<18 + f.n[8] = uint32(b[5]) | uint32(b[4])<<8 | uint32(b[3])<<16 | + (uint32(b[2])&twoBitsMask)<<24 + f.n[9] = uint32(b[2])>>2 | uint32(b[1])<<6 | uint32(b[0])<<14 + + // The intuition here is that the field value is greater than the prime if + // one of the higher individual words is greater than corresponding word of + // the prime and all higher words in the field value are equal to their + // corresponding word of the prime. Since this type is modulo the prime, + // being equal is also an overflow back to 0. + // + // Note that because the input is 32 bytes and it was just packed into the + // field representation, the only words that can possibly be greater are + // zero and one, because ceil(log_2(2^256 - 1 - P)) = 33 bits max and the + // internal field representation encodes 26 bits with each word. + // + // Thus, there is no need to test if the upper words of the field value + // exceeds them, hence, only equality is checked for them. + highWordsEq := constantTimeEq(f.n[9], fieldPrimeWordNine) + highWordsEq &= constantTimeEq(f.n[8], fieldPrimeWordEight) + highWordsEq &= constantTimeEq(f.n[7], fieldPrimeWordSeven) + highWordsEq &= constantTimeEq(f.n[6], fieldPrimeWordSix) + highWordsEq &= constantTimeEq(f.n[5], fieldPrimeWordFive) + highWordsEq &= constantTimeEq(f.n[4], fieldPrimeWordFour) + highWordsEq &= constantTimeEq(f.n[3], fieldPrimeWordThree) + highWordsEq &= constantTimeEq(f.n[2], fieldPrimeWordTwo) + overflow := highWordsEq & constantTimeGreater(f.n[1], fieldPrimeWordOne) + highWordsEq &= constantTimeEq(f.n[1], fieldPrimeWordOne) + overflow |= highWordsEq & constantTimeGreaterOrEq(f.n[0], fieldPrimeWordZero) + + return overflow +} + +// SetByteSlice interprets the provided slice as a 256-bit big-endian unsigned +// integer (meaning it is truncated to the first 32 bytes), packs it into the +// internal field value representation, and returns whether or not the resulting +// truncated 256-bit integer is greater than or equal to the field prime (aka it +// overflowed) in constant time. +// +// Note that since passing a slice with more than 32 bytes is truncated, it is +// possible that the truncated value is less than the field prime and hence it +// will not be reported as having overflowed in that case. It is up to the +// caller to decide whether it needs to provide numbers of the appropriate size +// or it if is acceptable to use this function with the described truncation and +// overflow behavior. +// +// Preconditions: None +// Output Normalized: Yes if no overflow, no otherwise +// Output Max Magnitude: 1 +func (f *FieldVal) SetByteSlice(b []byte) bool { + var b32 [32]byte + b = b[:constantTimeMin(uint32(len(b)), 32)] + copy(b32[:], b32[:32-len(b)]) + copy(b32[32-len(b):], b) + result := f.SetBytes(&b32) + zeroArray32(&b32) + return result != 0 +} + +// Normalize normalizes the internal field words into the desired range and +// performs fast modular reduction over the secp256k1 prime by making use of the +// special form of the prime in constant time. +// +// Preconditions: None +// Output Normalized: Yes +// Output Max Magnitude: 1 +func (f *FieldVal) Normalize() *FieldVal { + // The field representation leaves 6 bits of overflow in each word so + // intermediate calculations can be performed without needing to + // propagate the carry to each higher word during the calculations. In + // order to normalize, we need to "compact" the full 256-bit value to + // the right while propagating any carries through to the high order + // word. + // + // Since this field is doing arithmetic modulo the secp256k1 prime, we + // also need to perform modular reduction over the prime. + // + // Per [HAC] section 14.3.4: Reduction method of moduli of special form, + // when the modulus is of the special form m = b^t - c, highly efficient + // reduction can be achieved. + // + // The secp256k1 prime is equivalent to 2^256 - 4294968273, so it fits + // this criteria. + // + // 4294968273 in field representation (base 2^26) is: + // n[0] = 977 + // n[1] = 64 + // That is to say (2^26 * 64) + 977 = 4294968273 + // + // The algorithm presented in the referenced section typically repeats + // until the quotient is zero. However, due to our field representation + // we already know to within one reduction how many times we would need + // to repeat as it's the uppermost bits of the high order word. Thus we + // can simply multiply the magnitude by the field representation of the + // prime and do a single iteration. After this step there might be an + // additional carry to bit 256 (bit 22 of the high order word). + t9 := f.n[9] + m := t9 >> fieldMSBBits + t9 = t9 & fieldMSBMask + t0 := f.n[0] + m*977 + t1 := (t0 >> fieldBase) + f.n[1] + (m << 6) + t0 = t0 & fieldBaseMask + t2 := (t1 >> fieldBase) + f.n[2] + t1 = t1 & fieldBaseMask + t3 := (t2 >> fieldBase) + f.n[3] + t2 = t2 & fieldBaseMask + t4 := (t3 >> fieldBase) + f.n[4] + t3 = t3 & fieldBaseMask + t5 := (t4 >> fieldBase) + f.n[5] + t4 = t4 & fieldBaseMask + t6 := (t5 >> fieldBase) + f.n[6] + t5 = t5 & fieldBaseMask + t7 := (t6 >> fieldBase) + f.n[7] + t6 = t6 & fieldBaseMask + t8 := (t7 >> fieldBase) + f.n[8] + t7 = t7 & fieldBaseMask + t9 = (t8 >> fieldBase) + t9 + t8 = t8 & fieldBaseMask + + // At this point, the magnitude is guaranteed to be one, however, the + // value could still be greater than the prime if there was either a + // carry through to bit 256 (bit 22 of the higher order word) or the + // value is greater than or equal to the field characteristic. The + // following determines if either or these conditions are true and does + // the final reduction in constant time. + // + // Also note that 'm' will be zero when neither of the aforementioned + // conditions are true and the value will not be changed when 'm' is zero. + m = constantTimeEq(t9, fieldMSBMask) + m &= constantTimeEq(t8&t7&t6&t5&t4&t3&t2, fieldBaseMask) + m &= constantTimeGreater(t1+64+((t0+977)>>fieldBase), fieldBaseMask) + m |= t9 >> fieldMSBBits + t0 = t0 + m*977 + t1 = (t0 >> fieldBase) + t1 + (m << 6) + t0 = t0 & fieldBaseMask + t2 = (t1 >> fieldBase) + t2 + t1 = t1 & fieldBaseMask + t3 = (t2 >> fieldBase) + t3 + t2 = t2 & fieldBaseMask + t4 = (t3 >> fieldBase) + t4 + t3 = t3 & fieldBaseMask + t5 = (t4 >> fieldBase) + t5 + t4 = t4 & fieldBaseMask + t6 = (t5 >> fieldBase) + t6 + t5 = t5 & fieldBaseMask + t7 = (t6 >> fieldBase) + t7 + t6 = t6 & fieldBaseMask + t8 = (t7 >> fieldBase) + t8 + t7 = t7 & fieldBaseMask + t9 = (t8 >> fieldBase) + t9 + t8 = t8 & fieldBaseMask + t9 = t9 & fieldMSBMask // Remove potential multiple of 2^256. + + // Finally, set the normalized and reduced words. + f.n[0] = t0 + f.n[1] = t1 + f.n[2] = t2 + f.n[3] = t3 + f.n[4] = t4 + f.n[5] = t5 + f.n[6] = t6 + f.n[7] = t7 + f.n[8] = t8 + f.n[9] = t9 + return f +} + +// PutBytesUnchecked unpacks the field value to a 32-byte big-endian value +// directly into the passed byte slice in constant time. The target slice must +// must have at least 32 bytes available or it will panic. +// +// There is a similar function, PutBytes, which unpacks the field value into a +// 32-byte array directly. This version is provided since it can be useful +// to write directly into part of a larger buffer without needing a separate +// allocation. +// +// Preconditions: +// - The field value MUST be normalized +// - The target slice MUST have at least 32 bytes available +func (f *FieldVal) PutBytesUnchecked(b []byte) { + // Unpack the 256 total bits from the 10 uint32 words with a max of + // 26-bits per word. This could be done with a couple of for loops, + // but this unrolled version is a bit faster. Benchmarks show this is + // about 10 times faster than the variant which uses loops. + b[31] = byte(f.n[0] & eightBitsMask) + b[30] = byte((f.n[0] >> 8) & eightBitsMask) + b[29] = byte((f.n[0] >> 16) & eightBitsMask) + b[28] = byte((f.n[0]>>24)&twoBitsMask | (f.n[1]&sixBitsMask)<<2) + b[27] = byte((f.n[1] >> 6) & eightBitsMask) + b[26] = byte((f.n[1] >> 14) & eightBitsMask) + b[25] = byte((f.n[1]>>22)&fourBitsMask | (f.n[2]&fourBitsMask)<<4) + b[24] = byte((f.n[2] >> 4) & eightBitsMask) + b[23] = byte((f.n[2] >> 12) & eightBitsMask) + b[22] = byte((f.n[2]>>20)&sixBitsMask | (f.n[3]&twoBitsMask)<<6) + b[21] = byte((f.n[3] >> 2) & eightBitsMask) + b[20] = byte((f.n[3] >> 10) & eightBitsMask) + b[19] = byte((f.n[3] >> 18) & eightBitsMask) + b[18] = byte(f.n[4] & eightBitsMask) + b[17] = byte((f.n[4] >> 8) & eightBitsMask) + b[16] = byte((f.n[4] >> 16) & eightBitsMask) + b[15] = byte((f.n[4]>>24)&twoBitsMask | (f.n[5]&sixBitsMask)<<2) + b[14] = byte((f.n[5] >> 6) & eightBitsMask) + b[13] = byte((f.n[5] >> 14) & eightBitsMask) + b[12] = byte((f.n[5]>>22)&fourBitsMask | (f.n[6]&fourBitsMask)<<4) + b[11] = byte((f.n[6] >> 4) & eightBitsMask) + b[10] = byte((f.n[6] >> 12) & eightBitsMask) + b[9] = byte((f.n[6]>>20)&sixBitsMask | (f.n[7]&twoBitsMask)<<6) + b[8] = byte((f.n[7] >> 2) & eightBitsMask) + b[7] = byte((f.n[7] >> 10) & eightBitsMask) + b[6] = byte((f.n[7] >> 18) & eightBitsMask) + b[5] = byte(f.n[8] & eightBitsMask) + b[4] = byte((f.n[8] >> 8) & eightBitsMask) + b[3] = byte((f.n[8] >> 16) & eightBitsMask) + b[2] = byte((f.n[8]>>24)&twoBitsMask | (f.n[9]&sixBitsMask)<<2) + b[1] = byte((f.n[9] >> 6) & eightBitsMask) + b[0] = byte((f.n[9] >> 14) & eightBitsMask) +} + +// PutBytes unpacks the field value to a 32-byte big-endian value using the +// passed byte array in constant time. +// +// There is a similar function, PutBytesUnchecked, which unpacks the field value +// into a slice that must have at least 32 bytes available. This version is +// provided since it can be useful to write directly into an array that is type +// checked. +// +// Alternatively, there is also Bytes, which unpacks the field value into a new +// array and returns that which can sometimes be more ergonomic in applications +// that aren't concerned about an additional copy. +// +// Preconditions: +// - The field value MUST be normalized +func (f *FieldVal) PutBytes(b *[32]byte) { + f.PutBytesUnchecked(b[:]) +} + +// Bytes unpacks the field value to a 32-byte big-endian value in constant time. +// +// See PutBytes and PutBytesUnchecked for variants that allow an array or slice +// to be passed which can be useful to cut down on the number of allocations by +// allowing the caller to reuse a buffer or write directly into part of a larger +// buffer. +// +// Preconditions: +// - The field value MUST be normalized +func (f *FieldVal) Bytes() *[32]byte { + b := new([32]byte) + f.PutBytesUnchecked(b[:]) + return b +} + +// IsZeroBit returns 1 when the field value is equal to zero or 0 otherwise in +// constant time. +// +// Note that a bool is not used here because it is not possible in Go to convert +// from a bool to numeric value in constant time and many constant-time +// operations require a numeric value. See IsZero for the version that returns +// a bool. +// +// Preconditions: +// - The field value MUST be normalized +func (f *FieldVal) IsZeroBit() uint32 { + // The value can only be zero if no bits are set in any of the words. + // This is a constant time implementation. + bits := f.n[0] | f.n[1] | f.n[2] | f.n[3] | f.n[4] | + f.n[5] | f.n[6] | f.n[7] | f.n[8] | f.n[9] + + return constantTimeEq(bits, 0) +} + +// IsZero returns whether or not the field value is equal to zero in constant +// time. +// +// Preconditions: +// - The field value MUST be normalized +func (f *FieldVal) IsZero() bool { + // The value can only be zero if no bits are set in any of the words. + // This is a constant time implementation. + bits := f.n[0] | f.n[1] | f.n[2] | f.n[3] | f.n[4] | + f.n[5] | f.n[6] | f.n[7] | f.n[8] | f.n[9] + + return bits == 0 +} + +// IsOneBit returns 1 when the field value is equal to one or 0 otherwise in +// constant time. +// +// Note that a bool is not used here because it is not possible in Go to convert +// from a bool to numeric value in constant time and many constant-time +// operations require a numeric value. See IsOne for the version that returns a +// bool. +// +// Preconditions: +// - The field value MUST be normalized +func (f *FieldVal) IsOneBit() uint32 { + // The value can only be one if the single lowest significant bit is set in + // the first word and no other bits are set in any of the other words. + // This is a constant time implementation. + bits := (f.n[0] ^ 1) | f.n[1] | f.n[2] | f.n[3] | f.n[4] | f.n[5] | + f.n[6] | f.n[7] | f.n[8] | f.n[9] + + return constantTimeEq(bits, 0) +} + +// IsOne returns whether or not the field value is equal to one in constant +// time. +// +// Preconditions: +// - The field value MUST be normalized +func (f *FieldVal) IsOne() bool { + // The value can only be one if the single lowest significant bit is set in + // the first word and no other bits are set in any of the other words. + // This is a constant time implementation. + bits := (f.n[0] ^ 1) | f.n[1] | f.n[2] | f.n[3] | f.n[4] | f.n[5] | + f.n[6] | f.n[7] | f.n[8] | f.n[9] + + return bits == 0 +} + +// IsOddBit returns 1 when the field value is an odd number or 0 otherwise in +// constant time. +// +// Note that a bool is not used here because it is not possible in Go to convert +// from a bool to numeric value in constant time and many constant-time +// operations require a numeric value. See IsOdd for the version that returns a +// bool. +// +// Preconditions: +// - The field value MUST be normalized +func (f *FieldVal) IsOddBit() uint32 { + // Only odd numbers have the bottom bit set. + return f.n[0] & 1 +} + +// IsOdd returns whether or not the field value is an odd number in constant +// time. +// +// Preconditions: +// - The field value MUST be normalized +func (f *FieldVal) IsOdd() bool { + // Only odd numbers have the bottom bit set. + return f.n[0]&1 == 1 +} + +// Equals returns whether or not the two field values are the same in constant +// time. +// +// Preconditions: +// - Both field values being compared MUST be normalized +func (f *FieldVal) Equals(val *FieldVal) bool { + // Xor only sets bits when they are different, so the two field values + // can only be the same if no bits are set after xoring each word. + // This is a constant time implementation. + bits := (f.n[0] ^ val.n[0]) | (f.n[1] ^ val.n[1]) | (f.n[2] ^ val.n[2]) | + (f.n[3] ^ val.n[3]) | (f.n[4] ^ val.n[4]) | (f.n[5] ^ val.n[5]) | + (f.n[6] ^ val.n[6]) | (f.n[7] ^ val.n[7]) | (f.n[8] ^ val.n[8]) | + (f.n[9] ^ val.n[9]) + + return bits == 0 +} + +// NegateVal negates the passed value and stores the result in f in constant +// time. The caller must provide the magnitude of the passed value for a +// correct result. +// +// The field value is returned to support chaining. This enables syntax like: +// f.NegateVal(f2).AddInt(1) so that f = -f2 + 1. +// +// Preconditions: +// - The max magnitude MUST be 63 +// Output Normalized: No +// Output Max Magnitude: Input magnitude + 1 +func (f *FieldVal) NegateVal(val *FieldVal, magnitude uint32) *FieldVal { + // Negation in the field is just the prime minus the value. However, + // in order to allow negation against a field value without having to + // normalize/reduce it first, multiply by the magnitude (that is how + // "far" away it is from the normalized value) to adjust. Also, since + // negating a value pushes it one more order of magnitude away from the + // normalized range, add 1 to compensate. + // + // For some intuition here, imagine you're performing mod 12 arithmetic + // (picture a clock) and you are negating the number 7. So you start at + // 12 (which is of course 0 under mod 12) and count backwards (left on + // the clock) 7 times to arrive at 5. Notice this is just 12-7 = 5. + // Now, assume you're starting with 19, which is a number that is + // already larger than the modulus and congruent to 7 (mod 12). When a + // value is already in the desired range, its magnitude is 1. Since 19 + // is an additional "step", its magnitude (mod 12) is 2. Since any + // multiple of the modulus is congruent to zero (mod m), the answer can + // be shortcut by simply multiplying the magnitude by the modulus and + // subtracting. Keeping with the example, this would be (2*12)-19 = 5. + f.n[0] = (magnitude+1)*fieldPrimeWordZero - val.n[0] + f.n[1] = (magnitude+1)*fieldPrimeWordOne - val.n[1] + f.n[2] = (magnitude+1)*fieldBaseMask - val.n[2] + f.n[3] = (magnitude+1)*fieldBaseMask - val.n[3] + f.n[4] = (magnitude+1)*fieldBaseMask - val.n[4] + f.n[5] = (magnitude+1)*fieldBaseMask - val.n[5] + f.n[6] = (magnitude+1)*fieldBaseMask - val.n[6] + f.n[7] = (magnitude+1)*fieldBaseMask - val.n[7] + f.n[8] = (magnitude+1)*fieldBaseMask - val.n[8] + f.n[9] = (magnitude+1)*fieldMSBMask - val.n[9] + + return f +} + +// Negate negates the field value in constant time. The existing field value is +// modified. The caller must provide the magnitude of the field value for a +// correct result. +// +// The field value is returned to support chaining. This enables syntax like: +// f.Negate().AddInt(1) so that f = -f + 1. +// +// Preconditions: +// - The max magnitude MUST be 63 +// Output Normalized: No +// Output Max Magnitude: Input magnitude + 1 +func (f *FieldVal) Negate(magnitude uint32) *FieldVal { + return f.NegateVal(f, magnitude) +} + +// AddInt adds the passed integer to the existing field value and stores the +// result in f in constant time. This is a convenience function since it is +// fairly common to perform some arithmetic with small native integers. +// +// The field value is returned to support chaining. This enables syntax like: +// f.AddInt(1).Add(f2) so that f = f + 1 + f2. +// +// Preconditions: +// - The field value MUST have a max magnitude of 63 +// Output Normalized: No +// Output Max Magnitude: Existing field magnitude + 1 +func (f *FieldVal) AddInt(ui uint16) *FieldVal { + // Since the field representation intentionally provides overflow bits, + // it's ok to use carryless addition as the carry bit is safely part of + // the word and will be normalized out. + f.n[0] += uint32(ui) + + return f +} + +// Add adds the passed value to the existing field value and stores the result +// in f in constant time. +// +// The field value is returned to support chaining. This enables syntax like: +// f.Add(f2).AddInt(1) so that f = f + f2 + 1. +// +// Preconditions: +// - The sum of the magnitudes of the two field values MUST be a max of 64 +// Output Normalized: No +// Output Max Magnitude: Sum of the magnitude of the two individual field values +func (f *FieldVal) Add(val *FieldVal) *FieldVal { + // Since the field representation intentionally provides overflow bits, + // it's ok to use carryless addition as the carry bit is safely part of + // each word and will be normalized out. This could obviously be done + // in a loop, but the unrolled version is faster. + f.n[0] += val.n[0] + f.n[1] += val.n[1] + f.n[2] += val.n[2] + f.n[3] += val.n[3] + f.n[4] += val.n[4] + f.n[5] += val.n[5] + f.n[6] += val.n[6] + f.n[7] += val.n[7] + f.n[8] += val.n[8] + f.n[9] += val.n[9] + + return f +} + +// Add2 adds the passed two field values together and stores the result in f in +// constant time. +// +// The field value is returned to support chaining. This enables syntax like: +// f3.Add2(f, f2).AddInt(1) so that f3 = f + f2 + 1. +// +// Preconditions: +// - The sum of the magnitudes of the two field values MUST be a max of 64 +// Output Normalized: No +// Output Max Magnitude: Sum of the magnitude of the two field values +func (f *FieldVal) Add2(val *FieldVal, val2 *FieldVal) *FieldVal { + // Since the field representation intentionally provides overflow bits, + // it's ok to use carryless addition as the carry bit is safely part of + // each word and will be normalized out. This could obviously be done + // in a loop, but the unrolled version is faster. + f.n[0] = val.n[0] + val2.n[0] + f.n[1] = val.n[1] + val2.n[1] + f.n[2] = val.n[2] + val2.n[2] + f.n[3] = val.n[3] + val2.n[3] + f.n[4] = val.n[4] + val2.n[4] + f.n[5] = val.n[5] + val2.n[5] + f.n[6] = val.n[6] + val2.n[6] + f.n[7] = val.n[7] + val2.n[7] + f.n[8] = val.n[8] + val2.n[8] + f.n[9] = val.n[9] + val2.n[9] + + return f +} + +// MulInt multiplies the field value by the passed int and stores the result in +// f in constant time. Note that this function can overflow if multiplying the +// value by any of the individual words exceeds a max uint32. Therefore it is +// important that the caller ensures no overflows will occur before using this +// function. +// +// The field value is returned to support chaining. This enables syntax like: +// f.MulInt(2).Add(f2) so that f = 2 * f + f2. +// +// Preconditions: +// - The field value magnitude multiplied by given val MUST be a max of 64 +// Output Normalized: No +// Output Max Magnitude: Existing field magnitude times the provided integer val +func (f *FieldVal) MulInt(val uint8) *FieldVal { + // Since each word of the field representation can hold up to + // 32 - fieldBase extra bits which will be normalized out, it's safe + // to multiply each word without using a larger type or carry + // propagation so long as the values won't overflow a uint32. This + // could obviously be done in a loop, but the unrolled version is + // faster. + ui := uint32(val) + f.n[0] *= ui + f.n[1] *= ui + f.n[2] *= ui + f.n[3] *= ui + f.n[4] *= ui + f.n[5] *= ui + f.n[6] *= ui + f.n[7] *= ui + f.n[8] *= ui + f.n[9] *= ui + + return f +} + +// Mul multiplies the passed value to the existing field value and stores the +// result in f in constant time. Note that this function can overflow if +// multiplying any of the individual words exceeds a max uint32. In practice, +// this means the magnitude of either value involved in the multiplication must +// be a max of 8. +// +// The field value is returned to support chaining. This enables syntax like: +// f.Mul(f2).AddInt(1) so that f = (f * f2) + 1. +// +// Preconditions: +// - Both field values MUST have a max magnitude of 8 +// Output Normalized: No +// Output Max Magnitude: 1 +func (f *FieldVal) Mul(val *FieldVal) *FieldVal { + return f.Mul2(f, val) +} + +// Mul2 multiplies the passed two field values together and stores the result +// result in f in constant time. Note that this function can overflow if +// multiplying any of the individual words exceeds a max uint32. In practice, +// this means the magnitude of either value involved in the multiplication must +// be a max of 8. +// +// The field value is returned to support chaining. This enables syntax like: +// f3.Mul2(f, f2).AddInt(1) so that f3 = (f * f2) + 1. +// +// Preconditions: +// - Both input field values MUST have a max magnitude of 8 +// Output Normalized: No +// Output Max Magnitude: 1 +func (f *FieldVal) Mul2(val *FieldVal, val2 *FieldVal) *FieldVal { + // This could be done with a couple of for loops and an array to store + // the intermediate terms, but this unrolled version is significantly + // faster. + + // Terms for 2^(fieldBase*0). + m := uint64(val.n[0]) * uint64(val2.n[0]) + t0 := m & fieldBaseMask + + // Terms for 2^(fieldBase*1). + m = (m >> fieldBase) + + uint64(val.n[0])*uint64(val2.n[1]) + + uint64(val.n[1])*uint64(val2.n[0]) + t1 := m & fieldBaseMask + + // Terms for 2^(fieldBase*2). + m = (m >> fieldBase) + + uint64(val.n[0])*uint64(val2.n[2]) + + uint64(val.n[1])*uint64(val2.n[1]) + + uint64(val.n[2])*uint64(val2.n[0]) + t2 := m & fieldBaseMask + + // Terms for 2^(fieldBase*3). + m = (m >> fieldBase) + + uint64(val.n[0])*uint64(val2.n[3]) + + uint64(val.n[1])*uint64(val2.n[2]) + + uint64(val.n[2])*uint64(val2.n[1]) + + uint64(val.n[3])*uint64(val2.n[0]) + t3 := m & fieldBaseMask + + // Terms for 2^(fieldBase*4). + m = (m >> fieldBase) + + uint64(val.n[0])*uint64(val2.n[4]) + + uint64(val.n[1])*uint64(val2.n[3]) + + uint64(val.n[2])*uint64(val2.n[2]) + + uint64(val.n[3])*uint64(val2.n[1]) + + uint64(val.n[4])*uint64(val2.n[0]) + t4 := m & fieldBaseMask + + // Terms for 2^(fieldBase*5). + m = (m >> fieldBase) + + uint64(val.n[0])*uint64(val2.n[5]) + + uint64(val.n[1])*uint64(val2.n[4]) + + uint64(val.n[2])*uint64(val2.n[3]) + + uint64(val.n[3])*uint64(val2.n[2]) + + uint64(val.n[4])*uint64(val2.n[1]) + + uint64(val.n[5])*uint64(val2.n[0]) + t5 := m & fieldBaseMask + + // Terms for 2^(fieldBase*6). + m = (m >> fieldBase) + + uint64(val.n[0])*uint64(val2.n[6]) + + uint64(val.n[1])*uint64(val2.n[5]) + + uint64(val.n[2])*uint64(val2.n[4]) + + uint64(val.n[3])*uint64(val2.n[3]) + + uint64(val.n[4])*uint64(val2.n[2]) + + uint64(val.n[5])*uint64(val2.n[1]) + + uint64(val.n[6])*uint64(val2.n[0]) + t6 := m & fieldBaseMask + + // Terms for 2^(fieldBase*7). + m = (m >> fieldBase) + + uint64(val.n[0])*uint64(val2.n[7]) + + uint64(val.n[1])*uint64(val2.n[6]) + + uint64(val.n[2])*uint64(val2.n[5]) + + uint64(val.n[3])*uint64(val2.n[4]) + + uint64(val.n[4])*uint64(val2.n[3]) + + uint64(val.n[5])*uint64(val2.n[2]) + + uint64(val.n[6])*uint64(val2.n[1]) + + uint64(val.n[7])*uint64(val2.n[0]) + t7 := m & fieldBaseMask + + // Terms for 2^(fieldBase*8). + m = (m >> fieldBase) + + uint64(val.n[0])*uint64(val2.n[8]) + + uint64(val.n[1])*uint64(val2.n[7]) + + uint64(val.n[2])*uint64(val2.n[6]) + + uint64(val.n[3])*uint64(val2.n[5]) + + uint64(val.n[4])*uint64(val2.n[4]) + + uint64(val.n[5])*uint64(val2.n[3]) + + uint64(val.n[6])*uint64(val2.n[2]) + + uint64(val.n[7])*uint64(val2.n[1]) + + uint64(val.n[8])*uint64(val2.n[0]) + t8 := m & fieldBaseMask + + // Terms for 2^(fieldBase*9). + m = (m >> fieldBase) + + uint64(val.n[0])*uint64(val2.n[9]) + + uint64(val.n[1])*uint64(val2.n[8]) + + uint64(val.n[2])*uint64(val2.n[7]) + + uint64(val.n[3])*uint64(val2.n[6]) + + uint64(val.n[4])*uint64(val2.n[5]) + + uint64(val.n[5])*uint64(val2.n[4]) + + uint64(val.n[6])*uint64(val2.n[3]) + + uint64(val.n[7])*uint64(val2.n[2]) + + uint64(val.n[8])*uint64(val2.n[1]) + + uint64(val.n[9])*uint64(val2.n[0]) + t9 := m & fieldBaseMask + + // Terms for 2^(fieldBase*10). + m = (m >> fieldBase) + + uint64(val.n[1])*uint64(val2.n[9]) + + uint64(val.n[2])*uint64(val2.n[8]) + + uint64(val.n[3])*uint64(val2.n[7]) + + uint64(val.n[4])*uint64(val2.n[6]) + + uint64(val.n[5])*uint64(val2.n[5]) + + uint64(val.n[6])*uint64(val2.n[4]) + + uint64(val.n[7])*uint64(val2.n[3]) + + uint64(val.n[8])*uint64(val2.n[2]) + + uint64(val.n[9])*uint64(val2.n[1]) + t10 := m & fieldBaseMask + + // Terms for 2^(fieldBase*11). + m = (m >> fieldBase) + + uint64(val.n[2])*uint64(val2.n[9]) + + uint64(val.n[3])*uint64(val2.n[8]) + + uint64(val.n[4])*uint64(val2.n[7]) + + uint64(val.n[5])*uint64(val2.n[6]) + + uint64(val.n[6])*uint64(val2.n[5]) + + uint64(val.n[7])*uint64(val2.n[4]) + + uint64(val.n[8])*uint64(val2.n[3]) + + uint64(val.n[9])*uint64(val2.n[2]) + t11 := m & fieldBaseMask + + // Terms for 2^(fieldBase*12). + m = (m >> fieldBase) + + uint64(val.n[3])*uint64(val2.n[9]) + + uint64(val.n[4])*uint64(val2.n[8]) + + uint64(val.n[5])*uint64(val2.n[7]) + + uint64(val.n[6])*uint64(val2.n[6]) + + uint64(val.n[7])*uint64(val2.n[5]) + + uint64(val.n[8])*uint64(val2.n[4]) + + uint64(val.n[9])*uint64(val2.n[3]) + t12 := m & fieldBaseMask + + // Terms for 2^(fieldBase*13). + m = (m >> fieldBase) + + uint64(val.n[4])*uint64(val2.n[9]) + + uint64(val.n[5])*uint64(val2.n[8]) + + uint64(val.n[6])*uint64(val2.n[7]) + + uint64(val.n[7])*uint64(val2.n[6]) + + uint64(val.n[8])*uint64(val2.n[5]) + + uint64(val.n[9])*uint64(val2.n[4]) + t13 := m & fieldBaseMask + + // Terms for 2^(fieldBase*14). + m = (m >> fieldBase) + + uint64(val.n[5])*uint64(val2.n[9]) + + uint64(val.n[6])*uint64(val2.n[8]) + + uint64(val.n[7])*uint64(val2.n[7]) + + uint64(val.n[8])*uint64(val2.n[6]) + + uint64(val.n[9])*uint64(val2.n[5]) + t14 := m & fieldBaseMask + + // Terms for 2^(fieldBase*15). + m = (m >> fieldBase) + + uint64(val.n[6])*uint64(val2.n[9]) + + uint64(val.n[7])*uint64(val2.n[8]) + + uint64(val.n[8])*uint64(val2.n[7]) + + uint64(val.n[9])*uint64(val2.n[6]) + t15 := m & fieldBaseMask + + // Terms for 2^(fieldBase*16). + m = (m >> fieldBase) + + uint64(val.n[7])*uint64(val2.n[9]) + + uint64(val.n[8])*uint64(val2.n[8]) + + uint64(val.n[9])*uint64(val2.n[7]) + t16 := m & fieldBaseMask + + // Terms for 2^(fieldBase*17). + m = (m >> fieldBase) + + uint64(val.n[8])*uint64(val2.n[9]) + + uint64(val.n[9])*uint64(val2.n[8]) + t17 := m & fieldBaseMask + + // Terms for 2^(fieldBase*18). + m = (m >> fieldBase) + uint64(val.n[9])*uint64(val2.n[9]) + t18 := m & fieldBaseMask + + // What's left is for 2^(fieldBase*19). + t19 := m >> fieldBase + + // At this point, all of the terms are grouped into their respective + // base. + // + // Per [HAC] section 14.3.4: Reduction method of moduli of special form, + // when the modulus is of the special form m = b^t - c, highly efficient + // reduction can be achieved per the provided algorithm. + // + // The secp256k1 prime is equivalent to 2^256 - 4294968273, so it fits + // this criteria. + // + // 4294968273 in field representation (base 2^26) is: + // n[0] = 977 + // n[1] = 64 + // That is to say (2^26 * 64) + 977 = 4294968273 + // + // Since each word is in base 26, the upper terms (t10 and up) start + // at 260 bits (versus the final desired range of 256 bits), so the + // field representation of 'c' from above needs to be adjusted for the + // extra 4 bits by multiplying it by 2^4 = 16. 4294968273 * 16 = + // 68719492368. Thus, the adjusted field representation of 'c' is: + // n[0] = 977 * 16 = 15632 + // n[1] = 64 * 16 = 1024 + // That is to say (2^26 * 1024) + 15632 = 68719492368 + // + // To reduce the final term, t19, the entire 'c' value is needed instead + // of only n[0] because there are no more terms left to handle n[1]. + // This means there might be some magnitude left in the upper bits that + // is handled below. + m = t0 + t10*15632 + t0 = m & fieldBaseMask + m = (m >> fieldBase) + t1 + t10*1024 + t11*15632 + t1 = m & fieldBaseMask + m = (m >> fieldBase) + t2 + t11*1024 + t12*15632 + t2 = m & fieldBaseMask + m = (m >> fieldBase) + t3 + t12*1024 + t13*15632 + t3 = m & fieldBaseMask + m = (m >> fieldBase) + t4 + t13*1024 + t14*15632 + t4 = m & fieldBaseMask + m = (m >> fieldBase) + t5 + t14*1024 + t15*15632 + t5 = m & fieldBaseMask + m = (m >> fieldBase) + t6 + t15*1024 + t16*15632 + t6 = m & fieldBaseMask + m = (m >> fieldBase) + t7 + t16*1024 + t17*15632 + t7 = m & fieldBaseMask + m = (m >> fieldBase) + t8 + t17*1024 + t18*15632 + t8 = m & fieldBaseMask + m = (m >> fieldBase) + t9 + t18*1024 + t19*68719492368 + t9 = m & fieldMSBMask + m = m >> fieldMSBBits + + // At this point, if the magnitude is greater than 0, the overall value + // is greater than the max possible 256-bit value. In particular, it is + // "how many times larger" than the max value it is. + // + // The algorithm presented in [HAC] section 14.3.4 repeats until the + // quotient is zero. However, due to the above, we already know at + // least how many times we would need to repeat as it's the value + // currently in m. Thus we can simply multiply the magnitude by the + // field representation of the prime and do a single iteration. Notice + // that nothing will be changed when the magnitude is zero, so we could + // skip this in that case, however always running regardless allows it + // to run in constant time. The final result will be in the range + // 0 <= result <= prime + (2^64 - c), so it is guaranteed to have a + // magnitude of 1, but it is denormalized. + d := t0 + m*977 + f.n[0] = uint32(d & fieldBaseMask) + d = (d >> fieldBase) + t1 + m*64 + f.n[1] = uint32(d & fieldBaseMask) + f.n[2] = uint32((d >> fieldBase) + t2) + f.n[3] = uint32(t3) + f.n[4] = uint32(t4) + f.n[5] = uint32(t5) + f.n[6] = uint32(t6) + f.n[7] = uint32(t7) + f.n[8] = uint32(t8) + f.n[9] = uint32(t9) + + return f +} + +// SquareRootVal either calculates the square root of the passed value when it +// exists or the square root of the negation of the value when it does not exist +// and stores the result in f in constant time. The return flag is true when +// the calculated square root is for the passed value itself and false when it +// is for its negation. +// +// Note that this function can overflow if multiplying any of the individual +// words exceeds a max uint32. In practice, this means the magnitude of the +// field must be a max of 8 to prevent overflow. The magnitude of the result +// will be 1. +// +// Preconditions: +// - The input field value MUST have a max magnitude of 8 +// Output Normalized: No +// Output Max Magnitude: 1 +func (f *FieldVal) SquareRootVal(val *FieldVal) bool { + // This uses the Tonelli-Shanks method for calculating the square root of + // the value when it exists. The key principles of the method follow. + // + // Fermat's little theorem states that for a nonzero number 'a' and prime + // 'p', a^(p-1) ≡ 1 (mod p). + // + // Further, Euler's criterion states that an integer 'a' has a square root + // (aka is a quadratic residue) modulo a prime if a^((p-1)/2) ≡ 1 (mod p) + // and, conversely, when it does NOT have a square root (aka 'a' is a + // non-residue) a^((p-1)/2) ≡ -1 (mod p). + // + // This can be seen by considering that Fermat's little theorem can be + // written as (a^((p-1)/2) - 1)(a^((p-1)/2) + 1) ≡ 0 (mod p). Therefore, + // one of the two factors must be 0. Then, when a ≡ x^2 (aka 'a' is a + // quadratic residue), (x^2)^((p-1)/2) ≡ x^(p-1) ≡ 1 (mod p) which implies + // the first factor must be zero. Finally, per Lagrange's theorem, the + // non-residues are the only remaining possible solutions and thus must make + // the second factor zero to satisfy Fermat's little theorem implying that + // a^((p-1)/2) ≡ -1 (mod p) for that case. + // + // The Tonelli-Shanks method uses these facts along with factoring out + // powers of two to solve a congruence that results in either the solution + // when the square root exists or the square root of the negation of the + // value when it does not. In the case of primes that are ≡ 3 (mod 4), the + // possible solutions are r = ±a^((p+1)/4) (mod p). Therefore, either r^2 ≡ + // a (mod p) is true in which case ±r are the two solutions, or r^2 ≡ -a + // (mod p) in which case 'a' is a non-residue and there are no solutions. + // + // The secp256k1 prime is ≡ 3 (mod 4), so this result applies. + // + // In other words, calculate a^((p+1)/4) and then square it and check it + // against the original value to determine if it is actually the square + // root. + // + // In order to efficiently compute a^((p+1)/4), (p+1)/4 needs to be split + // into a sequence of squares and multiplications that minimizes the number + // of multiplications needed (since they are more costly than squarings). + // + // The secp256k1 prime + 1 / 4 is 2^254 - 2^30 - 244. In binary, that is: + // + // 00111111 11111111 11111111 11111111 + // 11111111 11111111 11111111 11111111 + // 11111111 11111111 11111111 11111111 + // 11111111 11111111 11111111 11111111 + // 11111111 11111111 11111111 11111111 + // 11111111 11111111 11111111 11111111 + // 11111111 11111111 11111111 11111111 + // 10111111 11111111 11111111 00001100 + // + // Notice that can be broken up into three windows of consecutive 1s (in + // order of least to most signifcant) as: + // + // 6-bit window with two bits set (bits 4, 5, 6, 7 unset) + // 23-bit window with 22 bits set (bit 30 unset) + // 223-bit window with all 223 bits set + // + // Thus, the groups of 1 bits in each window forms the set: + // S = {2, 22, 223}. + // + // The strategy is to calculate a^(2^n - 1) for each grouping via an + // addition chain with a sliding window. + // + // The addition chain used is (credits to Peter Dettman): + // (0,0),(1,0),(2,2),(3,2),(4,1),(5,5),(6,6),(7,7),(8,8),(9,7),(10,2) + // => 2^1 2^[2] 2^3 2^6 2^9 2^11 2^[22] 2^44 2^88 2^176 2^220 2^[223] + // + // This has a cost of 254 field squarings and 13 field multiplications. + var a, a2, a3, a6, a9, a11, a22, a44, a88, a176, a220, a223 FieldVal + a.Set(val) + a2.SquareVal(&a).Mul(&a) // a2 = a^(2^2 - 1) + a3.SquareVal(&a2).Mul(&a) // a3 = a^(2^3 - 1) + a6.SquareVal(&a3).Square().Square() // a6 = a^(2^6 - 2^3) + a6.Mul(&a3) // a6 = a^(2^6 - 1) + a9.SquareVal(&a6).Square().Square() // a9 = a^(2^9 - 2^3) + a9.Mul(&a3) // a9 = a^(2^9 - 1) + a11.SquareVal(&a9).Square() // a11 = a^(2^11 - 2^2) + a11.Mul(&a2) // a11 = a^(2^11 - 1) + a22.SquareVal(&a11).Square().Square().Square().Square() // a22 = a^(2^16 - 2^5) + a22.Square().Square().Square().Square().Square() // a22 = a^(2^21 - 2^10) + a22.Square() // a22 = a^(2^22 - 2^11) + a22.Mul(&a11) // a22 = a^(2^22 - 1) + a44.SquareVal(&a22).Square().Square().Square().Square() // a44 = a^(2^27 - 2^5) + a44.Square().Square().Square().Square().Square() // a44 = a^(2^32 - 2^10) + a44.Square().Square().Square().Square().Square() // a44 = a^(2^37 - 2^15) + a44.Square().Square().Square().Square().Square() // a44 = a^(2^42 - 2^20) + a44.Square().Square() // a44 = a^(2^44 - 2^22) + a44.Mul(&a22) // a44 = a^(2^44 - 1) + a88.SquareVal(&a44).Square().Square().Square().Square() // a88 = a^(2^49 - 2^5) + a88.Square().Square().Square().Square().Square() // a88 = a^(2^54 - 2^10) + a88.Square().Square().Square().Square().Square() // a88 = a^(2^59 - 2^15) + a88.Square().Square().Square().Square().Square() // a88 = a^(2^64 - 2^20) + a88.Square().Square().Square().Square().Square() // a88 = a^(2^69 - 2^25) + a88.Square().Square().Square().Square().Square() // a88 = a^(2^74 - 2^30) + a88.Square().Square().Square().Square().Square() // a88 = a^(2^79 - 2^35) + a88.Square().Square().Square().Square().Square() // a88 = a^(2^84 - 2^40) + a88.Square().Square().Square().Square() // a88 = a^(2^88 - 2^44) + a88.Mul(&a44) // a88 = a^(2^88 - 1) + a176.SquareVal(&a88).Square().Square().Square().Square() // a176 = a^(2^93 - 2^5) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^98 - 2^10) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^103 - 2^15) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^108 - 2^20) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^113 - 2^25) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^118 - 2^30) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^123 - 2^35) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^128 - 2^40) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^133 - 2^45) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^138 - 2^50) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^143 - 2^55) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^148 - 2^60) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^153 - 2^65) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^158 - 2^70) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^163 - 2^75) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^168 - 2^80) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^173 - 2^85) + a176.Square().Square().Square() // a176 = a^(2^176 - 2^88) + a176.Mul(&a88) // a176 = a^(2^176 - 1) + a220.SquareVal(&a176).Square().Square().Square().Square() // a220 = a^(2^181 - 2^5) + a220.Square().Square().Square().Square().Square() // a220 = a^(2^186 - 2^10) + a220.Square().Square().Square().Square().Square() // a220 = a^(2^191 - 2^15) + a220.Square().Square().Square().Square().Square() // a220 = a^(2^196 - 2^20) + a220.Square().Square().Square().Square().Square() // a220 = a^(2^201 - 2^25) + a220.Square().Square().Square().Square().Square() // a220 = a^(2^206 - 2^30) + a220.Square().Square().Square().Square().Square() // a220 = a^(2^211 - 2^35) + a220.Square().Square().Square().Square().Square() // a220 = a^(2^216 - 2^40) + a220.Square().Square().Square().Square() // a220 = a^(2^220 - 2^44) + a220.Mul(&a44) // a220 = a^(2^220 - 1) + a223.SquareVal(&a220).Square().Square() // a223 = a^(2^223 - 2^3) + a223.Mul(&a3) // a223 = a^(2^223 - 1) + + f.SquareVal(&a223).Square().Square().Square().Square() // f = a^(2^228 - 2^5) + f.Square().Square().Square().Square().Square() // f = a^(2^233 - 2^10) + f.Square().Square().Square().Square().Square() // f = a^(2^238 - 2^15) + f.Square().Square().Square().Square().Square() // f = a^(2^243 - 2^20) + f.Square().Square().Square() // f = a^(2^246 - 2^23) + f.Mul(&a22) // f = a^(2^246 - 2^22 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^251 - 2^27 - 2^5) + f.Square() // f = a^(2^252 - 2^28 - 2^6) + f.Mul(&a2) // f = a^(2^252 - 2^28 - 2^6 - 2^1 - 1) + f.Square().Square() // f = a^(2^254 - 2^30 - 2^8 - 2^3 - 2^2) + // // = a^(2^254 - 2^30 - 244) + // // = a^((p+1)/4) + + // Ensure the calculated result is actually the square root by squaring it + // and checking against the original value. + var sqr FieldVal + return sqr.SquareVal(f).Normalize().Equals(val.Normalize()) +} + +// Square squares the field value in constant time. The existing field value is +// modified. Note that this function can overflow if multiplying any of the +// individual words exceeds a max uint32. In practice, this means the magnitude +// of the field must be a max of 8 to prevent overflow. +// +// The field value is returned to support chaining. This enables syntax like: +// f.Square().Mul(f2) so that f = f^2 * f2. +// +// Preconditions: +// - The field value MUST have a max magnitude of 8 +// Output Normalized: No +// Output Max Magnitude: 1 +func (f *FieldVal) Square() *FieldVal { + return f.SquareVal(f) +} + +// SquareVal squares the passed value and stores the result in f in constant +// time. Note that this function can overflow if multiplying any of the +// individual words exceeds a max uint32. In practice, this means the magnitude +// of the field being squared must be a max of 8 to prevent overflow. +// +// The field value is returned to support chaining. This enables syntax like: +// f3.SquareVal(f).Mul(f) so that f3 = f^2 * f = f^3. +// +// Preconditions: +// - The input field value MUST have a max magnitude of 8 +// Output Normalized: No +// Output Max Magnitude: 1 +func (f *FieldVal) SquareVal(val *FieldVal) *FieldVal { + // This could be done with a couple of for loops and an array to store + // the intermediate terms, but this unrolled version is significantly + // faster. + + // Terms for 2^(fieldBase*0). + m := uint64(val.n[0]) * uint64(val.n[0]) + t0 := m & fieldBaseMask + + // Terms for 2^(fieldBase*1). + m = (m >> fieldBase) + 2*uint64(val.n[0])*uint64(val.n[1]) + t1 := m & fieldBaseMask + + // Terms for 2^(fieldBase*2). + m = (m >> fieldBase) + + 2*uint64(val.n[0])*uint64(val.n[2]) + + uint64(val.n[1])*uint64(val.n[1]) + t2 := m & fieldBaseMask + + // Terms for 2^(fieldBase*3). + m = (m >> fieldBase) + + 2*uint64(val.n[0])*uint64(val.n[3]) + + 2*uint64(val.n[1])*uint64(val.n[2]) + t3 := m & fieldBaseMask + + // Terms for 2^(fieldBase*4). + m = (m >> fieldBase) + + 2*uint64(val.n[0])*uint64(val.n[4]) + + 2*uint64(val.n[1])*uint64(val.n[3]) + + uint64(val.n[2])*uint64(val.n[2]) + t4 := m & fieldBaseMask + + // Terms for 2^(fieldBase*5). + m = (m >> fieldBase) + + 2*uint64(val.n[0])*uint64(val.n[5]) + + 2*uint64(val.n[1])*uint64(val.n[4]) + + 2*uint64(val.n[2])*uint64(val.n[3]) + t5 := m & fieldBaseMask + + // Terms for 2^(fieldBase*6). + m = (m >> fieldBase) + + 2*uint64(val.n[0])*uint64(val.n[6]) + + 2*uint64(val.n[1])*uint64(val.n[5]) + + 2*uint64(val.n[2])*uint64(val.n[4]) + + uint64(val.n[3])*uint64(val.n[3]) + t6 := m & fieldBaseMask + + // Terms for 2^(fieldBase*7). + m = (m >> fieldBase) + + 2*uint64(val.n[0])*uint64(val.n[7]) + + 2*uint64(val.n[1])*uint64(val.n[6]) + + 2*uint64(val.n[2])*uint64(val.n[5]) + + 2*uint64(val.n[3])*uint64(val.n[4]) + t7 := m & fieldBaseMask + + // Terms for 2^(fieldBase*8). + m = (m >> fieldBase) + + 2*uint64(val.n[0])*uint64(val.n[8]) + + 2*uint64(val.n[1])*uint64(val.n[7]) + + 2*uint64(val.n[2])*uint64(val.n[6]) + + 2*uint64(val.n[3])*uint64(val.n[5]) + + uint64(val.n[4])*uint64(val.n[4]) + t8 := m & fieldBaseMask + + // Terms for 2^(fieldBase*9). + m = (m >> fieldBase) + + 2*uint64(val.n[0])*uint64(val.n[9]) + + 2*uint64(val.n[1])*uint64(val.n[8]) + + 2*uint64(val.n[2])*uint64(val.n[7]) + + 2*uint64(val.n[3])*uint64(val.n[6]) + + 2*uint64(val.n[4])*uint64(val.n[5]) + t9 := m & fieldBaseMask + + // Terms for 2^(fieldBase*10). + m = (m >> fieldBase) + + 2*uint64(val.n[1])*uint64(val.n[9]) + + 2*uint64(val.n[2])*uint64(val.n[8]) + + 2*uint64(val.n[3])*uint64(val.n[7]) + + 2*uint64(val.n[4])*uint64(val.n[6]) + + uint64(val.n[5])*uint64(val.n[5]) + t10 := m & fieldBaseMask + + // Terms for 2^(fieldBase*11). + m = (m >> fieldBase) + + 2*uint64(val.n[2])*uint64(val.n[9]) + + 2*uint64(val.n[3])*uint64(val.n[8]) + + 2*uint64(val.n[4])*uint64(val.n[7]) + + 2*uint64(val.n[5])*uint64(val.n[6]) + t11 := m & fieldBaseMask + + // Terms for 2^(fieldBase*12). + m = (m >> fieldBase) + + 2*uint64(val.n[3])*uint64(val.n[9]) + + 2*uint64(val.n[4])*uint64(val.n[8]) + + 2*uint64(val.n[5])*uint64(val.n[7]) + + uint64(val.n[6])*uint64(val.n[6]) + t12 := m & fieldBaseMask + + // Terms for 2^(fieldBase*13). + m = (m >> fieldBase) + + 2*uint64(val.n[4])*uint64(val.n[9]) + + 2*uint64(val.n[5])*uint64(val.n[8]) + + 2*uint64(val.n[6])*uint64(val.n[7]) + t13 := m & fieldBaseMask + + // Terms for 2^(fieldBase*14). + m = (m >> fieldBase) + + 2*uint64(val.n[5])*uint64(val.n[9]) + + 2*uint64(val.n[6])*uint64(val.n[8]) + + uint64(val.n[7])*uint64(val.n[7]) + t14 := m & fieldBaseMask + + // Terms for 2^(fieldBase*15). + m = (m >> fieldBase) + + 2*uint64(val.n[6])*uint64(val.n[9]) + + 2*uint64(val.n[7])*uint64(val.n[8]) + t15 := m & fieldBaseMask + + // Terms for 2^(fieldBase*16). + m = (m >> fieldBase) + + 2*uint64(val.n[7])*uint64(val.n[9]) + + uint64(val.n[8])*uint64(val.n[8]) + t16 := m & fieldBaseMask + + // Terms for 2^(fieldBase*17). + m = (m >> fieldBase) + 2*uint64(val.n[8])*uint64(val.n[9]) + t17 := m & fieldBaseMask + + // Terms for 2^(fieldBase*18). + m = (m >> fieldBase) + uint64(val.n[9])*uint64(val.n[9]) + t18 := m & fieldBaseMask + + // What's left is for 2^(fieldBase*19). + t19 := m >> fieldBase + + // At this point, all of the terms are grouped into their respective + // base. + // + // Per [HAC] section 14.3.4: Reduction method of moduli of special form, + // when the modulus is of the special form m = b^t - c, highly efficient + // reduction can be achieved per the provided algorithm. + // + // The secp256k1 prime is equivalent to 2^256 - 4294968273, so it fits + // this criteria. + // + // 4294968273 in field representation (base 2^26) is: + // n[0] = 977 + // n[1] = 64 + // That is to say (2^26 * 64) + 977 = 4294968273 + // + // Since each word is in base 26, the upper terms (t10 and up) start + // at 260 bits (versus the final desired range of 256 bits), so the + // field representation of 'c' from above needs to be adjusted for the + // extra 4 bits by multiplying it by 2^4 = 16. 4294968273 * 16 = + // 68719492368. Thus, the adjusted field representation of 'c' is: + // n[0] = 977 * 16 = 15632 + // n[1] = 64 * 16 = 1024 + // That is to say (2^26 * 1024) + 15632 = 68719492368 + // + // To reduce the final term, t19, the entire 'c' value is needed instead + // of only n[0] because there are no more terms left to handle n[1]. + // This means there might be some magnitude left in the upper bits that + // is handled below. + m = t0 + t10*15632 + t0 = m & fieldBaseMask + m = (m >> fieldBase) + t1 + t10*1024 + t11*15632 + t1 = m & fieldBaseMask + m = (m >> fieldBase) + t2 + t11*1024 + t12*15632 + t2 = m & fieldBaseMask + m = (m >> fieldBase) + t3 + t12*1024 + t13*15632 + t3 = m & fieldBaseMask + m = (m >> fieldBase) + t4 + t13*1024 + t14*15632 + t4 = m & fieldBaseMask + m = (m >> fieldBase) + t5 + t14*1024 + t15*15632 + t5 = m & fieldBaseMask + m = (m >> fieldBase) + t6 + t15*1024 + t16*15632 + t6 = m & fieldBaseMask + m = (m >> fieldBase) + t7 + t16*1024 + t17*15632 + t7 = m & fieldBaseMask + m = (m >> fieldBase) + t8 + t17*1024 + t18*15632 + t8 = m & fieldBaseMask + m = (m >> fieldBase) + t9 + t18*1024 + t19*68719492368 + t9 = m & fieldMSBMask + m = m >> fieldMSBBits + + // At this point, if the magnitude is greater than 0, the overall value + // is greater than the max possible 256-bit value. In particular, it is + // "how many times larger" than the max value it is. + // + // The algorithm presented in [HAC] section 14.3.4 repeats until the + // quotient is zero. However, due to the above, we already know at + // least how many times we would need to repeat as it's the value + // currently in m. Thus we can simply multiply the magnitude by the + // field representation of the prime and do a single iteration. Notice + // that nothing will be changed when the magnitude is zero, so we could + // skip this in that case, however always running regardless allows it + // to run in constant time. The final result will be in the range + // 0 <= result <= prime + (2^64 - c), so it is guaranteed to have a + // magnitude of 1, but it is denormalized. + n := t0 + m*977 + f.n[0] = uint32(n & fieldBaseMask) + n = (n >> fieldBase) + t1 + m*64 + f.n[1] = uint32(n & fieldBaseMask) + f.n[2] = uint32((n >> fieldBase) + t2) + f.n[3] = uint32(t3) + f.n[4] = uint32(t4) + f.n[5] = uint32(t5) + f.n[6] = uint32(t6) + f.n[7] = uint32(t7) + f.n[8] = uint32(t8) + f.n[9] = uint32(t9) + + return f +} + +// Inverse finds the modular multiplicative inverse of the field value in +// constant time. The existing field value is modified. +// +// The field value is returned to support chaining. This enables syntax like: +// f.Inverse().Mul(f2) so that f = f^-1 * f2. +// +// Preconditions: +// - The field value MUST have a max magnitude of 8 +// Output Normalized: No +// Output Max Magnitude: 1 +func (f *FieldVal) Inverse() *FieldVal { + // Fermat's little theorem states that for a nonzero number a and prime + // prime p, a^(p-1) = 1 (mod p). Since the multiplicative inverse is + // a*b = 1 (mod p), it follows that b = a*a^(p-2) = a^(p-1) = 1 (mod p). + // Thus, a^(p-2) is the multiplicative inverse. + // + // In order to efficiently compute a^(p-2), p-2 needs to be split into + // a sequence of squares and multiplications that minimizes the number + // of multiplications needed (since they are more costly than + // squarings). Intermediate results are saved and reused as well. + // + // The secp256k1 prime - 2 is 2^256 - 4294968275. + // + // This has a cost of 258 field squarings and 33 field multiplications. + var a2, a3, a4, a10, a11, a21, a42, a45, a63, a1019, a1023 FieldVal + a2.SquareVal(f) + a3.Mul2(&a2, f) + a4.SquareVal(&a2) + a10.SquareVal(&a4).Mul(&a2) + a11.Mul2(&a10, f) + a21.Mul2(&a10, &a11) + a42.SquareVal(&a21) + a45.Mul2(&a42, &a3) + a63.Mul2(&a42, &a21) + a1019.SquareVal(&a63).Square().Square().Square().Mul(&a11) + a1023.Mul2(&a1019, &a4) + f.Set(&a63) // f = a^(2^6 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^11 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^16 - 1024) + f.Mul(&a1023) // f = a^(2^16 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^21 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^26 - 1024) + f.Mul(&a1023) // f = a^(2^26 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^31 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^36 - 1024) + f.Mul(&a1023) // f = a^(2^36 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^41 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^46 - 1024) + f.Mul(&a1023) // f = a^(2^46 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^51 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^56 - 1024) + f.Mul(&a1023) // f = a^(2^56 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^61 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^66 - 1024) + f.Mul(&a1023) // f = a^(2^66 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^71 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^76 - 1024) + f.Mul(&a1023) // f = a^(2^76 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^81 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^86 - 1024) + f.Mul(&a1023) // f = a^(2^86 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^91 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^96 - 1024) + f.Mul(&a1023) // f = a^(2^96 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^101 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^106 - 1024) + f.Mul(&a1023) // f = a^(2^106 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^111 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^116 - 1024) + f.Mul(&a1023) // f = a^(2^116 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^121 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^126 - 1024) + f.Mul(&a1023) // f = a^(2^126 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^131 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^136 - 1024) + f.Mul(&a1023) // f = a^(2^136 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^141 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^146 - 1024) + f.Mul(&a1023) // f = a^(2^146 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^151 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^156 - 1024) + f.Mul(&a1023) // f = a^(2^156 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^161 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^166 - 1024) + f.Mul(&a1023) // f = a^(2^166 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^171 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^176 - 1024) + f.Mul(&a1023) // f = a^(2^176 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^181 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^186 - 1024) + f.Mul(&a1023) // f = a^(2^186 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^191 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^196 - 1024) + f.Mul(&a1023) // f = a^(2^196 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^201 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^206 - 1024) + f.Mul(&a1023) // f = a^(2^206 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^211 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^216 - 1024) + f.Mul(&a1023) // f = a^(2^216 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^221 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^226 - 1024) + f.Mul(&a1019) // f = a^(2^226 - 5) + f.Square().Square().Square().Square().Square() // f = a^(2^231 - 160) + f.Square().Square().Square().Square().Square() // f = a^(2^236 - 5120) + f.Mul(&a1023) // f = a^(2^236 - 4097) + f.Square().Square().Square().Square().Square() // f = a^(2^241 - 131104) + f.Square().Square().Square().Square().Square() // f = a^(2^246 - 4195328) + f.Mul(&a1023) // f = a^(2^246 - 4194305) + f.Square().Square().Square().Square().Square() // f = a^(2^251 - 134217760) + f.Square().Square().Square().Square().Square() // f = a^(2^256 - 4294968320) + return f.Mul(&a45) // f = a^(2^256 - 4294968275) = a^(p-2) +} + +// IsGtOrEqPrimeMinusOrder returns whether or not the field value exceeds the +// group order divided by 2 in constant time. +// +// Preconditions: +// - The field value MUST be normalized +func (f *FieldVal) IsGtOrEqPrimeMinusOrder() bool { + // The secp256k1 prime is equivalent to 2^256 - 4294968273 and the group + // order is 2^256 - 432420386565659656852420866394968145599. Thus, + // the prime minus the group order is: + // 432420386565659656852420866390673177326 + // + // In hex that is: + // 0x00000000 00000000 00000000 00000001 45512319 50b75fc4 402da172 2fc9baee + // + // Converting that to field representation (base 2^26) is: + // + // n[0] = 0x03c9baee + // n[1] = 0x03685c8b + // n[2] = 0x01fc4402 + // n[3] = 0x006542dd + // n[4] = 0x01455123 + // + // This can be verified with the following test code: + // pMinusN := new(big.Int).Sub(curveParams.P, curveParams.N) + // var fv FieldVal + // fv.SetByteSlice(pMinusN.Bytes()) + // t.Logf("%x", fv.n) + // + // Outputs: [3c9baee 3685c8b 1fc4402 6542dd 1455123 0 0 0 0 0] + const ( + pMinusNWordZero = 0x03c9baee + pMinusNWordOne = 0x03685c8b + pMinusNWordTwo = 0x01fc4402 + pMinusNWordThree = 0x006542dd + pMinusNWordFour = 0x01455123 + pMinusNWordFive = 0x00000000 + pMinusNWordSix = 0x00000000 + pMinusNWordSeven = 0x00000000 + pMinusNWordEight = 0x00000000 + pMinusNWordNine = 0x00000000 + ) + + // The intuition here is that the value is greater than field prime minus + // the group order if one of the higher individual words is greater than the + // corresponding word and all higher words in the value are equal. + result := constantTimeGreater(f.n[9], pMinusNWordNine) + highWordsEqual := constantTimeEq(f.n[9], pMinusNWordNine) + result |= highWordsEqual & constantTimeGreater(f.n[8], pMinusNWordEight) + highWordsEqual &= constantTimeEq(f.n[8], pMinusNWordEight) + result |= highWordsEqual & constantTimeGreater(f.n[7], pMinusNWordSeven) + highWordsEqual &= constantTimeEq(f.n[7], pMinusNWordSeven) + result |= highWordsEqual & constantTimeGreater(f.n[6], pMinusNWordSix) + highWordsEqual &= constantTimeEq(f.n[6], pMinusNWordSix) + result |= highWordsEqual & constantTimeGreater(f.n[5], pMinusNWordFive) + highWordsEqual &= constantTimeEq(f.n[5], pMinusNWordFive) + result |= highWordsEqual & constantTimeGreater(f.n[4], pMinusNWordFour) + highWordsEqual &= constantTimeEq(f.n[4], pMinusNWordFour) + result |= highWordsEqual & constantTimeGreater(f.n[3], pMinusNWordThree) + highWordsEqual &= constantTimeEq(f.n[3], pMinusNWordThree) + result |= highWordsEqual & constantTimeGreater(f.n[2], pMinusNWordTwo) + highWordsEqual &= constantTimeEq(f.n[2], pMinusNWordTwo) + result |= highWordsEqual & constantTimeGreater(f.n[1], pMinusNWordOne) + highWordsEqual &= constantTimeEq(f.n[1], pMinusNWordOne) + result |= highWordsEqual & constantTimeGreaterOrEq(f.n[0], pMinusNWordZero) + + return result != 0 +} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/genstatics.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/genstatics.go new file mode 100644 index 0000000..00534c5 --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/genstatics.go @@ -0,0 +1,195 @@ +// Copyright (c) 2014-2015 The btcsuite developers +// Copyright (c) 2015-2021 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +// This file is ignored during the regular build due to the following build tag. +// This build tag is set during go generate. +// +build gensecp256k1 + +package secp256k1 + +// References: +// [GECC]: Guide to Elliptic Curve Cryptography (Hankerson, Menezes, Vanstone) + +import ( + "encoding/binary" + "math/big" +) + +// compressedBytePoints are dummy points used so the code which generates the +// real values can compile. +var compressedBytePoints = "" + +// SerializedBytePoints returns a serialized byte slice which contains all of +// the possible points per 8-bit window. This is used to when generating +// compressedbytepoints.go. +func SerializedBytePoints() []byte { + // Calculate G^(2^i) for i in 0..255. These are used to avoid recomputing + // them for each digit of the 8-bit windows. + doublingPoints := make([]JacobianPoint, curveParams.BitSize) + var q JacobianPoint + bigAffineToJacobian(curveParams.Gx, curveParams.Gy, &q) + for i := 0; i < curveParams.BitSize; i++ { + // Q = 2*Q. + doublingPoints[i] = q + DoubleNonConst(&q, &q) + } + + // Separate the bits into byte-sized windows. + curveByteSize := curveParams.BitSize / 8 + serialized := make([]byte, curveByteSize*256*2*10*4) + offset := 0 + for byteNum := 0; byteNum < curveByteSize; byteNum++ { + // Grab the 8 bits that make up this byte from doubling points. + startingBit := 8 * (curveByteSize - byteNum - 1) + windowPoints := doublingPoints[startingBit : startingBit+8] + + // Compute all points in this window, convert them to affine, and + // serialize them. + for i := 0; i < 256; i++ { + var point JacobianPoint + for bit := 0; bit < 8; bit++ { + if i>>uint(bit)&1 == 1 { + AddNonConst(&point, &windowPoints[bit], &point) + } + } + point.ToAffine() + + for i := 0; i < len(point.X.n); i++ { + binary.LittleEndian.PutUint32(serialized[offset:], point.X.n[i]) + offset += 4 + } + for i := 0; i < len(point.Y.n); i++ { + binary.LittleEndian.PutUint32(serialized[offset:], point.Y.n[i]) + offset += 4 + } + } + } + + return serialized +} + +// sqrt returns the square root of the provided big integer using Newton's +// method. It's only compiled and used during generation of pre-computed +// values, so speed is not a huge concern. +func sqrt(n *big.Int) *big.Int { + // Initial guess = 2^(log_2(n)/2) + guess := big.NewInt(2) + guess.Exp(guess, big.NewInt(int64(n.BitLen()/2)), nil) + + // Now refine using Newton's method. + big2 := big.NewInt(2) + prevGuess := big.NewInt(0) + for { + prevGuess.Set(guess) + guess.Add(guess, new(big.Int).Div(n, guess)) + guess.Div(guess, big2) + if guess.Cmp(prevGuess) == 0 { + break + } + } + return guess +} + +// EndomorphismVectors runs the first 3 steps of algorithm 3.74 from [GECC] to +// generate the linearly independent vectors needed to generate a balanced +// length-two representation of a multiplier such that k = k1 + k2λ (mod N) and +// returns them. Since the values will always be the same given the fact that N +// and λ are fixed, the final results can be accelerated by storing the +// precomputed values. +func EndomorphismVectors() (a1, b1, a2, b2 *big.Int) { + bigMinus1 := big.NewInt(-1) + + // This section uses an extended Euclidean algorithm to generate a + // sequence of equations: + // s[i] * N + t[i] * λ = r[i] + + nSqrt := sqrt(curveParams.N) + u, v := new(big.Int).Set(curveParams.N), new(big.Int).Set(endomorphismLambda) + x1, y1 := big.NewInt(1), big.NewInt(0) + x2, y2 := big.NewInt(0), big.NewInt(1) + q, r := new(big.Int), new(big.Int) + qu, qx1, qy1 := new(big.Int), new(big.Int), new(big.Int) + s, t := new(big.Int), new(big.Int) + ri, ti := new(big.Int), new(big.Int) + a1, b1, a2, b2 = new(big.Int), new(big.Int), new(big.Int), new(big.Int) + found, oneMore := false, false + for u.Sign() != 0 { + // q = v/u + q.Div(v, u) + + // r = v - q*u + qu.Mul(q, u) + r.Sub(v, qu) + + // s = x2 - q*x1 + qx1.Mul(q, x1) + s.Sub(x2, qx1) + + // t = y2 - q*y1 + qy1.Mul(q, y1) + t.Sub(y2, qy1) + + // v = u, u = r, x2 = x1, x1 = s, y2 = y1, y1 = t + v.Set(u) + u.Set(r) + x2.Set(x1) + x1.Set(s) + y2.Set(y1) + y1.Set(t) + + // As soon as the remainder is less than the sqrt of n, the + // values of a1 and b1 are known. + if !found && r.Cmp(nSqrt) < 0 { + // When this condition executes ri and ti represent the + // r[i] and t[i] values such that i is the greatest + // index for which r >= sqrt(n). Meanwhile, the current + // r and t values are r[i+1] and t[i+1], respectively. + + // a1 = r[i+1], b1 = -t[i+1] + a1.Set(r) + b1.Mul(t, bigMinus1) + found = true + oneMore = true + + // Skip to the next iteration so ri and ti are not + // modified. + continue + + } else if oneMore { + // When this condition executes ri and ti still + // represent the r[i] and t[i] values while the current + // r and t are r[i+2] and t[i+2], respectively. + + // sum1 = r[i]^2 + t[i]^2 + rSquared := new(big.Int).Mul(ri, ri) + tSquared := new(big.Int).Mul(ti, ti) + sum1 := new(big.Int).Add(rSquared, tSquared) + + // sum2 = r[i+2]^2 + t[i+2]^2 + r2Squared := new(big.Int).Mul(r, r) + t2Squared := new(big.Int).Mul(t, t) + sum2 := new(big.Int).Add(r2Squared, t2Squared) + + // if (r[i]^2 + t[i]^2) <= (r[i+2]^2 + t[i+2]^2) + if sum1.Cmp(sum2) <= 0 { + // a2 = r[i], b2 = -t[i] + a2.Set(ri) + b2.Mul(ti, bigMinus1) + } else { + // a2 = r[i+2], b2 = -t[i+2] + a2.Set(r) + b2.Mul(t, bigMinus1) + } + + // All done. + break + } + + ri.Set(r) + ti.Set(t) + } + + return a1, b1, a2, b2 +} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/go.mod b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/go.mod new file mode 100644 index 0000000..d15095a --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/go.mod @@ -0,0 +1,5 @@ +module github.com/decred/dcrd/dcrec/secp256k1/v4 + +go 1.13 + +require github.com/decred/dcrd/crypto/blake256 v1.0.0 diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/go.sum b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/go.sum new file mode 100644 index 0000000..1687242 --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/go.sum @@ -0,0 +1,2 @@ +github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/loadprecomputed.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/loadprecomputed.go new file mode 100644 index 0000000..d7d014a --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/loadprecomputed.go @@ -0,0 +1,91 @@ +// Copyright 2015 The btcsuite developers +// Copyright (c) 2015-2021 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +import ( + "compress/zlib" + "encoding/base64" + "encoding/binary" + "io/ioutil" + "strings" + "sync" +) + +//go:generate go run -tags gensecp256k1 genprecomps.go + +// bytePointTable describes a table used to house pre-computed values for +// accelerating scalar base multiplication. +type bytePointTable [32][256][2]FieldVal + +// s256BytePoints houses pre-computed values used to accelerate scalar base +// multiplication such that they are only loaded on first use. +var s256BytePoints = func() func() *bytePointTable { + // mustLoadBytePoints decompresses and deserializes the pre-computed byte + // points used to accelerate scalar base multiplication for the secp256k1 + // curve. + // + // This approach is used since it allows the compile to use significantly + // less ram and be performed much faster than it is with hard-coding the + // final in-memory data structure. At the same time, it is quite fast to + // generate the in-memory data structure on first use with this approach + // versus computing the table. + // + // It will panic on any errors because the data is hard coded and thus any + // errors means something is wrong in the source code. + var data *bytePointTable + mustLoadBytePoints := func() { + // There will be no byte points to load when generating them. + bp := compressedBytePoints + if len(bp) == 0 { + return + } + + // Decompress the pre-computed table used to accelerate scalar base + // multiplication. + decoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(bp)) + r, err := zlib.NewReader(decoder) + if err != nil { + panic(err) + } + serialized, err := ioutil.ReadAll(r) + if err != nil { + panic(err) + } + + // Deserialize the precomputed byte points and set the memory table to + // them. + offset := 0 + var bytePoints bytePointTable + for byteNum := 0; byteNum < len(bytePoints); byteNum++ { + // All points in this window. + for i := 0; i < len(bytePoints[byteNum]); i++ { + px := &bytePoints[byteNum][i][0] + py := &bytePoints[byteNum][i][1] + for i := 0; i < len(px.n); i++ { + px.n[i] = binary.LittleEndian.Uint32(serialized[offset:]) + offset += 4 + } + for i := 0; i < len(py.n); i++ { + py.n[i] = binary.LittleEndian.Uint32(serialized[offset:]) + offset += 4 + } + } + } + data = &bytePoints + } + + // Return a closure that initializes the data on first access. This is done + // because the table takes a non-trivial amount of memory and initializing + // it unconditionally would cause anything that imports the package, either + // directly, or indirectly via transitive deps, to use that memory even if + // the caller never accesses any parts of the package that actually needs + // access to it. + var loadBytePointsOnce sync.Once + return func() *bytePointTable { + loadBytePointsOnce.Do(mustLoadBytePoints) + return data + } +}() diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/modnscalar.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/modnscalar.go new file mode 100644 index 0000000..581b904 --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/modnscalar.go @@ -0,0 +1,1088 @@ +// Copyright (c) 2020 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +import ( + "encoding/hex" + "math/big" +) + +// References: +// [SECG]: Recommended Elliptic Curve Domain Parameters +// https://www.secg.org/sec2-v2.pdf +// +// [HAC]: Handbook of Applied Cryptography Menezes, van Oorschot, Vanstone. +// http://cacr.uwaterloo.ca/hac/ + +// Many elliptic curve operations require working with scalars in a finite field +// characterized by the order of the group underlying the secp256k1 curve. +// Given this precision is larger than the biggest available native type, +// obviously some form of bignum math is needed. This code implements +// specialized fixed-precision field arithmetic rather than relying on an +// arbitrary-precision arithmetic package such as math/big for dealing with the +// math modulo the group order since the size is known. As a result, rather +// large performance gains are achieved by taking advantage of many +// optimizations not available to arbitrary-precision arithmetic and generic +// modular arithmetic algorithms. +// +// There are various ways to internally represent each element. For example, +// the most obvious representation would be to use an array of 4 uint64s (64 +// bits * 4 = 256 bits). However, that representation suffers from the fact +// that there is no native Go type large enough to handle the intermediate +// results while adding or multiplying two 64-bit numbers. +// +// Given the above, this implementation represents the field elements as 8 +// uint32s with each word (array entry) treated as base 2^32. This was chosen +// because most systems at the current time are 64-bit (or at least have 64-bit +// registers available for specialized purposes such as MMX) so the intermediate +// results can typically be done using a native register (and using uint64s to +// avoid the need for additional half-word arithmetic) + +const ( + // These fields provide convenient access to each of the words of the + // secp256k1 curve group order N to improve code readability. + // + // The group order of the curve per [SECG] is: + // 0xffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141 + orderWordZero uint32 = 0xd0364141 + orderWordOne uint32 = 0xbfd25e8c + orderWordTwo uint32 = 0xaf48a03b + orderWordThree uint32 = 0xbaaedce6 + orderWordFour uint32 = 0xfffffffe + orderWordFive uint32 = 0xffffffff + orderWordSix uint32 = 0xffffffff + orderWordSeven uint32 = 0xffffffff + + // These fields provide convenient access to each of the words of the two's + // complement of the secp256k1 curve group order N to improve code + // readability. + // + // The two's complement of the group order is: + // 0x00000000 00000000 00000000 00000001 45512319 50b75fc4 402da173 2fc9bebf + orderComplementWordZero uint32 = (^orderWordZero) + 1 + orderComplementWordOne uint32 = ^orderWordOne + orderComplementWordTwo uint32 = ^orderWordTwo + orderComplementWordThree uint32 = ^orderWordThree + //orderComplementWordFour uint32 = ^orderWordFour // unused + //orderComplementWordFive uint32 = ^orderWordFive // unused + //orderComplementWordSix uint32 = ^orderWordSix // unused + //orderComplementWordSeven uint32 = ^orderWordSeven // unused + + // These fields provide convenient access to each of the words of the + // secp256k1 curve group order N / 2 to improve code readability and avoid + // the need to recalculate them. + // + // The half order of the secp256k1 curve group is: + // 0x7fffffff ffffffff ffffffff ffffffff 5d576e73 57a4501d dfe92f46 681b20a0 + halfOrderWordZero uint32 = 0x681b20a0 + halfOrderWordOne uint32 = 0xdfe92f46 + halfOrderWordTwo uint32 = 0x57a4501d + halfOrderWordThree uint32 = 0x5d576e73 + halfOrderWordFour uint32 = 0xffffffff + halfOrderWordFive uint32 = 0xffffffff + halfOrderWordSix uint32 = 0xffffffff + halfOrderWordSeven uint32 = 0x7fffffff + + // uint32Mask is simply a mask with all bits set for a uint32 and is used to + // improve the readability of the code. + uint32Mask = 0xffffffff +) + +var ( + // zero32 is an array of 32 bytes used for the purposes of zeroing and is + // defined here to avoid extra allocations. + zero32 = [32]byte{} +) + +// ModNScalar implements optimized 256-bit constant-time fixed-precision +// arithmetic over the secp256k1 group order. This means all arithmetic is +// performed modulo: +// +// 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141 +// +// It only implements the arithmetic needed for elliptic curve operations, +// however, the operations that are not implemented can typically be worked +// around if absolutely needed. For example, subtraction can be performed by +// adding the negation. +// +// Should it be absolutely necessary, conversion to the standard library +// math/big.Int can be accomplished by using the Bytes method, slicing the +// resulting fixed-size array, and feeding it to big.Int.SetBytes. However, +// that should typically be avoided when possible as conversion to big.Ints +// requires allocations, is not constant time, and is slower when working modulo +// the group order. +type ModNScalar struct { + // The scalar is represented as 8 32-bit integers in base 2^32. + // + // The following depicts the internal representation: + // --------------------------------------------------------- + // | n[7] | n[6] | ... | n[0] | + // | 32 bits | 32 bits | ... | 32 bits | + // | Mult: 2^(32*7) | Mult: 2^(32*6) | ... | Mult: 2^(32*0) | + // --------------------------------------------------------- + // + // For example, consider the number 2^87 + 2^42 + 1. It would be + // represented as: + // n[0] = 1 + // n[1] = 2^10 + // n[2] = 2^23 + // n[3..7] = 0 + // + // The full 256-bit value is then calculated by looping i from 7..0 and + // doing sum(n[i] * 2^(32i)) like so: + // n[7] * 2^(32*7) = 0 * 2^224 = 0 + // n[6] * 2^(32*6) = 0 * 2^192 = 0 + // ... + // n[2] * 2^(32*2) = 2^23 * 2^64 = 2^87 + // n[1] * 2^(32*1) = 2^10 * 2^32 = 2^42 + // n[0] * 2^(32*0) = 1 * 2^0 = 1 + // Sum: 0 + 0 + ... + 2^87 + 2^42 + 1 = 2^87 + 2^42 + 1 + n [8]uint32 +} + +// String returns the scalar as a human-readable hex string. +// +// This is NOT constant time. +func (s ModNScalar) String() string { + b := s.Bytes() + return hex.EncodeToString(b[:]) +} + +// Set sets the scalar equal to a copy of the passed one in constant time. +// +// The scalar is returned to support chaining. This enables syntax like: +// s := new(ModNScalar).Set(s2).Add(1) so that s = s2 + 1 where s2 is not +// modified. +func (s *ModNScalar) Set(val *ModNScalar) *ModNScalar { + *s = *val + return s +} + +// Zero sets the scalar to zero in constant time. A newly created scalar is +// already set to zero. This function can be useful to clear an existing scalar +// for reuse. +func (s *ModNScalar) Zero() { + s.n[0] = 0 + s.n[1] = 0 + s.n[2] = 0 + s.n[3] = 0 + s.n[4] = 0 + s.n[5] = 0 + s.n[6] = 0 + s.n[7] = 0 +} + +// IsZero returns whether or not the scalar is equal to zero in constant time. +func (s *ModNScalar) IsZero() bool { + // The scalar can only be zero if no bits are set in any of the words. + bits := s.n[0] | s.n[1] | s.n[2] | s.n[3] | s.n[4] | s.n[5] | s.n[6] | s.n[7] + return bits == 0 +} + +// SetInt sets the scalar to the passed integer in constant time. This is a +// convenience function since it is fairly common to perform some arithmetic +// with small native integers. +// +// The scalar is returned to support chaining. This enables syntax like: +// s := new(ModNScalar).SetInt(2).Mul(s2) so that s = 2 * s2. +func (s *ModNScalar) SetInt(ui uint32) *ModNScalar { + s.Zero() + s.n[0] = ui + return s +} + +// constantTimeEq returns 1 if a == b or 0 otherwise in constant time. +func constantTimeEq(a, b uint32) uint32 { + return uint32((uint64(a^b) - 1) >> 63) +} + +// constantTimeNotEq returns 1 if a != b or 0 otherwise in constant time. +func constantTimeNotEq(a, b uint32) uint32 { + return ^uint32((uint64(a^b)-1)>>63) & 1 +} + +// constantTimeLess returns 1 if a < b or 0 otherwise in constant time. +func constantTimeLess(a, b uint32) uint32 { + return uint32((uint64(a) - uint64(b)) >> 63) +} + +// constantTimeLessOrEq returns 1 if a <= b or 0 otherwise in constant time. +func constantTimeLessOrEq(a, b uint32) uint32 { + return uint32((uint64(a) - uint64(b) - 1) >> 63) +} + +// constantTimeGreater returns 1 if a > b or 0 otherwise in constant time. +func constantTimeGreater(a, b uint32) uint32 { + return constantTimeLess(b, a) +} + +// constantTimeGreaterOrEq returns 1 if a >= b or 0 otherwise in constant time. +func constantTimeGreaterOrEq(a, b uint32) uint32 { + return constantTimeLessOrEq(b, a) +} + +// constantTimeMin returns min(a,b) in constant time. +func constantTimeMin(a, b uint32) uint32 { + return b ^ ((a ^ b) & -constantTimeLess(a, b)) +} + +// overflows determines if the current scalar is greater than or equal to the +// group order in constant time and returns 1 if it is or 0 otherwise. +func (s *ModNScalar) overflows() uint32 { + // The intuition here is that the scalar is greater than the group order if + // one of the higher individual words is greater than corresponding word of + // the group order and all higher words in the scalar are equal to their + // corresponding word of the group order. Since this type is modulo the + // group order, being equal is also an overflow back to 0. + // + // Note that the words 5, 6, and 7 are all the max uint32 value, so there is + // no need to test if those individual words of the scalar exceeds them, + // hence, only equality is checked for them. + highWordsEqual := constantTimeEq(s.n[7], orderWordSeven) + highWordsEqual &= constantTimeEq(s.n[6], orderWordSix) + highWordsEqual &= constantTimeEq(s.n[5], orderWordFive) + overflow := highWordsEqual & constantTimeGreater(s.n[4], orderWordFour) + highWordsEqual &= constantTimeEq(s.n[4], orderWordFour) + overflow |= highWordsEqual & constantTimeGreater(s.n[3], orderWordThree) + highWordsEqual &= constantTimeEq(s.n[3], orderWordThree) + overflow |= highWordsEqual & constantTimeGreater(s.n[2], orderWordTwo) + highWordsEqual &= constantTimeEq(s.n[2], orderWordTwo) + overflow |= highWordsEqual & constantTimeGreater(s.n[1], orderWordOne) + highWordsEqual &= constantTimeEq(s.n[1], orderWordOne) + overflow |= highWordsEqual & constantTimeGreaterOrEq(s.n[0], orderWordZero) + + return overflow +} + +// reduce256 reduces the current scalar modulo the group order in accordance +// with the overflows parameter in constant time. The overflows parameter +// specifies whether or not the scalar is known to be greater than the group +// order and MUST either be 1 in the case it is or 0 in the case it is not for a +// correct result. +func (s *ModNScalar) reduce256(overflows uint32) { + // Notice that since s < 2^256 < 2N (where N is the group order), the max + // possible number of reductions required is one. Therefore, in the case a + // reduction is needed, it can be performed with a single subtraction of N. + // Also, recall that subtraction is equivalent to addition by the two's + // complement while ignoring the carry. + // + // When s >= N, the overflows parameter will be 1. Conversely, it will be 0 + // when s < N. Thus multiplying by the overflows parameter will either + // result in 0 or the multiplicand itself. + // + // Combining the above along with the fact that s + 0 = s, the following is + // a constant time implementation that works by either adding 0 or the two's + // complement of N as needed. + // + // The final result will be in the range 0 <= s < N as expected. + overflows64 := uint64(overflows) + c := uint64(s.n[0]) + overflows64*uint64(orderComplementWordZero) + s.n[0] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(s.n[1]) + overflows64*uint64(orderComplementWordOne) + s.n[1] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(s.n[2]) + overflows64*uint64(orderComplementWordTwo) + s.n[2] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(s.n[3]) + overflows64*uint64(orderComplementWordThree) + s.n[3] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(s.n[4]) + overflows64 // * 1 + s.n[4] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(s.n[5]) // + overflows64 * 0 + s.n[5] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(s.n[6]) // + overflows64 * 0 + s.n[6] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(s.n[7]) // + overflows64 * 0 + s.n[7] = uint32(c & uint32Mask) +} + +// SetBytes interprets the provided array as a 256-bit big-endian unsigned +// integer, reduces it modulo the group order, sets the scalar to the result, +// and returns either 1 if it was reduced (aka it overflowed) or 0 otherwise in +// constant time. +// +// Note that a bool is not used here because it is not possible in Go to convert +// from a bool to numeric value in constant time and many constant-time +// operations require a numeric value. +func (s *ModNScalar) SetBytes(b *[32]byte) uint32 { + // Pack the 256 total bits across the 8 uint32 words. This could be done + // with a for loop, but benchmarks show this unrolled version is about 2 + // times faster than the variant that uses a loop. + s.n[0] = uint32(b[31]) | uint32(b[30])<<8 | uint32(b[29])<<16 | uint32(b[28])<<24 + s.n[1] = uint32(b[27]) | uint32(b[26])<<8 | uint32(b[25])<<16 | uint32(b[24])<<24 + s.n[2] = uint32(b[23]) | uint32(b[22])<<8 | uint32(b[21])<<16 | uint32(b[20])<<24 + s.n[3] = uint32(b[19]) | uint32(b[18])<<8 | uint32(b[17])<<16 | uint32(b[16])<<24 + s.n[4] = uint32(b[15]) | uint32(b[14])<<8 | uint32(b[13])<<16 | uint32(b[12])<<24 + s.n[5] = uint32(b[11]) | uint32(b[10])<<8 | uint32(b[9])<<16 | uint32(b[8])<<24 + s.n[6] = uint32(b[7]) | uint32(b[6])<<8 | uint32(b[5])<<16 | uint32(b[4])<<24 + s.n[7] = uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24 + + // The value might be >= N, so reduce it as required and return whether or + // not it was reduced. + needsReduce := s.overflows() + s.reduce256(needsReduce) + return needsReduce +} + +// zeroArray32 zeroes the provided 32-byte buffer. +func zeroArray32(b *[32]byte) { + copy(b[:], zero32[:]) +} + +// SetByteSlice interprets the provided slice as a 256-bit big-endian unsigned +// integer (meaning it is truncated to the first 32 bytes), reduces it modulo +// the group order, sets the scalar to the result, and returns whether or not +// the resulting truncated 256-bit integer overflowed in constant time. +// +// Note that since passing a slice with more than 32 bytes is truncated, it is +// possible that the truncated value is less than the order of the curve and +// hence it will not be reported as having overflowed in that case. It is up to +// the caller to decide whether it needs to provide numbers of the appropriate +// size or it is acceptable to use this function with the described truncation +// and overflow behavior. +func (s *ModNScalar) SetByteSlice(b []byte) bool { + var b32 [32]byte + b = b[:constantTimeMin(uint32(len(b)), 32)] + copy(b32[:], b32[:32-len(b)]) + copy(b32[32-len(b):], b) + result := s.SetBytes(&b32) + zeroArray32(&b32) + return result != 0 +} + +// PutBytesUnchecked unpacks the scalar to a 32-byte big-endian value directly +// into the passed byte slice in constant time. The target slice must must have +// at least 32 bytes available or it will panic. +// +// There is a similar function, PutBytes, which unpacks the scalar into a +// 32-byte array directly. This version is provided since it can be useful to +// write directly into part of a larger buffer without needing a separate +// allocation. +// +// Preconditions: +// - The target slice MUST have at least 32 bytes available +func (s *ModNScalar) PutBytesUnchecked(b []byte) { + // Unpack the 256 total bits from the 8 uint32 words. This could be done + // with a for loop, but benchmarks show this unrolled version is about 2 + // times faster than the variant which uses a loop. + b[31] = byte(s.n[0]) + b[30] = byte(s.n[0] >> 8) + b[29] = byte(s.n[0] >> 16) + b[28] = byte(s.n[0] >> 24) + b[27] = byte(s.n[1]) + b[26] = byte(s.n[1] >> 8) + b[25] = byte(s.n[1] >> 16) + b[24] = byte(s.n[1] >> 24) + b[23] = byte(s.n[2]) + b[22] = byte(s.n[2] >> 8) + b[21] = byte(s.n[2] >> 16) + b[20] = byte(s.n[2] >> 24) + b[19] = byte(s.n[3]) + b[18] = byte(s.n[3] >> 8) + b[17] = byte(s.n[3] >> 16) + b[16] = byte(s.n[3] >> 24) + b[15] = byte(s.n[4]) + b[14] = byte(s.n[4] >> 8) + b[13] = byte(s.n[4] >> 16) + b[12] = byte(s.n[4] >> 24) + b[11] = byte(s.n[5]) + b[10] = byte(s.n[5] >> 8) + b[9] = byte(s.n[5] >> 16) + b[8] = byte(s.n[5] >> 24) + b[7] = byte(s.n[6]) + b[6] = byte(s.n[6] >> 8) + b[5] = byte(s.n[6] >> 16) + b[4] = byte(s.n[6] >> 24) + b[3] = byte(s.n[7]) + b[2] = byte(s.n[7] >> 8) + b[1] = byte(s.n[7] >> 16) + b[0] = byte(s.n[7] >> 24) +} + +// PutBytes unpacks the scalar to a 32-byte big-endian value using the passed +// byte array in constant time. +// +// There is a similar function, PutBytesUnchecked, which unpacks the scalar into +// a slice that must have at least 32 bytes available. This version is provided +// since it can be useful to write directly into an array that is type checked. +// +// Alternatively, there is also Bytes, which unpacks the scalar into a new array +// and returns that which can sometimes be more ergonomic in applications that +// aren't concerned about an additional copy. +func (s *ModNScalar) PutBytes(b *[32]byte) { + s.PutBytesUnchecked(b[:]) +} + +// Bytes unpacks the scalar to a 32-byte big-endian value in constant time. +// +// See PutBytes and PutBytesUnchecked for variants that allow an array or slice +// to be passed which can be useful to cut down on the number of allocations +// by allowing the caller to reuse a buffer or write directly into part of a +// larger buffer. +func (s *ModNScalar) Bytes() [32]byte { + var b [32]byte + s.PutBytesUnchecked(b[:]) + return b +} + +// IsOdd returns whether or not the scalar is an odd number in constant time. +func (s *ModNScalar) IsOdd() bool { + // Only odd numbers have the bottom bit set. + return s.n[0]&1 == 1 +} + +// Equals returns whether or not the two scalars are the same in constant time. +func (s *ModNScalar) Equals(val *ModNScalar) bool { + // Xor only sets bits when they are different, so the two scalars can only + // be the same if no bits are set after xoring each word. + bits := (s.n[0] ^ val.n[0]) | (s.n[1] ^ val.n[1]) | (s.n[2] ^ val.n[2]) | + (s.n[3] ^ val.n[3]) | (s.n[4] ^ val.n[4]) | (s.n[5] ^ val.n[5]) | + (s.n[6] ^ val.n[6]) | (s.n[7] ^ val.n[7]) + + return bits == 0 +} + +// Add2 adds the passed two scalars together modulo the group order in constant +// time and stores the result in s. +// +// The scalar is returned to support chaining. This enables syntax like: +// s3.Add2(s, s2).AddInt(1) so that s3 = s + s2 + 1. +func (s *ModNScalar) Add2(val1, val2 *ModNScalar) *ModNScalar { + c := uint64(val1.n[0]) + uint64(val2.n[0]) + s.n[0] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(val1.n[1]) + uint64(val2.n[1]) + s.n[1] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(val1.n[2]) + uint64(val2.n[2]) + s.n[2] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(val1.n[3]) + uint64(val2.n[3]) + s.n[3] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(val1.n[4]) + uint64(val2.n[4]) + s.n[4] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(val1.n[5]) + uint64(val2.n[5]) + s.n[5] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(val1.n[6]) + uint64(val2.n[6]) + s.n[6] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(val1.n[7]) + uint64(val2.n[7]) + s.n[7] = uint32(c & uint32Mask) + + // The result is now 256 bits, but it might still be >= N, so use the + // existing normal reduce method for 256-bit values. + s.reduce256(uint32(c>>32) + s.overflows()) + return s +} + +// Add adds the passed scalar to the existing one modulo the group order in +// constant time and stores the result in s. +// +// The scalar is returned to support chaining. This enables syntax like: +// s.Add(s2).AddInt(1) so that s = s + s2 + 1. +func (s *ModNScalar) Add(val *ModNScalar) *ModNScalar { + return s.Add2(s, val) +} + +// accumulator96 provides a 96-bit accumulator for use in the intermediate +// calculations requiring more than 64-bits. +type accumulator96 struct { + n [3]uint32 +} + +// Add adds the passed unsigned 64-bit value to the accumulator. +func (a *accumulator96) Add(v uint64) { + low := uint32(v & uint32Mask) + hi := uint32(v >> 32) + a.n[0] += low + a.n[1] += constantTimeLess(a.n[0], low) // Carry if overflow in n[0]. + a.n[1] += hi + a.n[2] += constantTimeLess(a.n[1], hi) // Carry if overflow in n[1]. +} + +// Rsh32 right shifts the accumulator by 32 bits. +func (a *accumulator96) Rsh32() { + a.n[0] = a.n[1] + a.n[1] = a.n[2] + a.n[2] = 0 +} + +// reduce385 reduces the 385-bit intermediate result in the passed terms modulo +// the group order in constant time and stores the result in s. +func (s *ModNScalar) reduce385(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12 uint64) { + // At this point, the intermediate result in the passed terms has been + // reduced to fit within 385 bits, so reduce it again using the same method + // described in reduce512. As before, the intermediate result will end up + // being reduced by another 127 bits to 258 bits, thus 9 32-bit terms are + // needed for this iteration. The reduced terms are assigned back to t0 + // through t8. + // + // Note that several of the intermediate calculations require adding 64-bit + // products together which would overflow a uint64, so a 96-bit accumulator + // is used instead until the value is reduced enough to use native uint64s. + + // Terms for 2^(32*0). + var acc accumulator96 + acc.n[0] = uint32(t0) // == acc.Add(t0) because acc is guaranteed to be 0. + acc.Add(t8 * uint64(orderComplementWordZero)) + t0 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*1). + acc.Add(t1) + acc.Add(t8 * uint64(orderComplementWordOne)) + acc.Add(t9 * uint64(orderComplementWordZero)) + t1 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*2). + acc.Add(t2) + acc.Add(t8 * uint64(orderComplementWordTwo)) + acc.Add(t9 * uint64(orderComplementWordOne)) + acc.Add(t10 * uint64(orderComplementWordZero)) + t2 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*3). + acc.Add(t3) + acc.Add(t8 * uint64(orderComplementWordThree)) + acc.Add(t9 * uint64(orderComplementWordTwo)) + acc.Add(t10 * uint64(orderComplementWordOne)) + acc.Add(t11 * uint64(orderComplementWordZero)) + t3 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*4). + acc.Add(t4) + acc.Add(t8) // * uint64(orderComplementWordFour) // * 1 + acc.Add(t9 * uint64(orderComplementWordThree)) + acc.Add(t10 * uint64(orderComplementWordTwo)) + acc.Add(t11 * uint64(orderComplementWordOne)) + acc.Add(t12 * uint64(orderComplementWordZero)) + t4 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*5). + acc.Add(t5) + // acc.Add(t8 * uint64(orderComplementWordFive)) // 0 + acc.Add(t9) // * uint64(orderComplementWordFour) // * 1 + acc.Add(t10 * uint64(orderComplementWordThree)) + acc.Add(t11 * uint64(orderComplementWordTwo)) + acc.Add(t12 * uint64(orderComplementWordOne)) + t5 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*6). + acc.Add(t6) + // acc.Add(t8 * uint64(orderComplementWordSix)) // 0 + // acc.Add(t9 * uint64(orderComplementWordFive)) // 0 + acc.Add(t10) // * uint64(orderComplementWordFour) // * 1 + acc.Add(t11 * uint64(orderComplementWordThree)) + acc.Add(t12 * uint64(orderComplementWordTwo)) + t6 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*7). + acc.Add(t7) + // acc.Add(t8 * uint64(orderComplementWordSeven)) // 0 + // acc.Add(t9 * uint64(orderComplementWordSix)) // 0 + // acc.Add(t10 * uint64(orderComplementWordFive)) // 0 + acc.Add(t11) // * uint64(orderComplementWordFour) // * 1 + acc.Add(t12 * uint64(orderComplementWordThree)) + t7 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*8). + // acc.Add(t9 * uint64(orderComplementWordSeven)) // 0 + // acc.Add(t10 * uint64(orderComplementWordSix)) // 0 + // acc.Add(t11 * uint64(orderComplementWordFive)) // 0 + acc.Add(t12) // * uint64(orderComplementWordFour) // * 1 + t8 = uint64(acc.n[0]) + // acc.Rsh32() // No need since not used after this. Guaranteed to be 0. + + // NOTE: All of the remaining multiplications for this iteration result in 0 + // as they all involve multiplying by combinations of the fifth, sixth, and + // seventh words of the two's complement of N, which are 0, so skip them. + + // At this point, the result is reduced to fit within 258 bits, so reduce it + // again using a slightly modified version of the same method. The maximum + // value in t8 is 2 at this point and therefore multiplying it by each word + // of the two's complement of N and adding it to a 32-bit term will result + // in a maximum requirement of 33 bits, so it is safe to use native uint64s + // here for the intermediate term carry propagation. + // + // Also, since the maximum value in t8 is 2, this ends up reducing by + // another 2 bits to 256 bits. + c := t0 + t8*uint64(orderComplementWordZero) + s.n[0] = uint32(c & uint32Mask) + c = (c >> 32) + t1 + t8*uint64(orderComplementWordOne) + s.n[1] = uint32(c & uint32Mask) + c = (c >> 32) + t2 + t8*uint64(orderComplementWordTwo) + s.n[2] = uint32(c & uint32Mask) + c = (c >> 32) + t3 + t8*uint64(orderComplementWordThree) + s.n[3] = uint32(c & uint32Mask) + c = (c >> 32) + t4 + t8 // * uint64(orderComplementWordFour) == * 1 + s.n[4] = uint32(c & uint32Mask) + c = (c >> 32) + t5 // + t8*uint64(orderComplementWordFive) == 0 + s.n[5] = uint32(c & uint32Mask) + c = (c >> 32) + t6 // + t8*uint64(orderComplementWordSix) == 0 + s.n[6] = uint32(c & uint32Mask) + c = (c >> 32) + t7 // + t8*uint64(orderComplementWordSeven) == 0 + s.n[7] = uint32(c & uint32Mask) + + // The result is now 256 bits, but it might still be >= N, so use the + // existing normal reduce method for 256-bit values. + s.reduce256(uint32(c>>32) + s.overflows()) +} + +// reduce512 reduces the 512-bit intermediate result in the passed terms modulo +// the group order down to 385 bits in constant time and stores the result in s. +func (s *ModNScalar) reduce512(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15 uint64) { + // At this point, the intermediate result in the passed terms is grouped + // into the respective bases. + // + // Per [HAC] section 14.3.4: Reduction method of moduli of special form, + // when the modulus is of the special form m = b^t - c, where log_2(c) < t, + // highly efficient reduction can be achieved per the provided algorithm. + // + // The secp256k1 group order fits this criteria since it is: + // 2^256 - 432420386565659656852420866394968145599 + // + // Technically the max possible value here is (N-1)^2 since the two scalars + // being multiplied are always mod N. Nevertheless, it is safer to consider + // it to be (2^256-1)^2 = 2^512 - 2^256 + 1 since it is the product of two + // 256-bit values. + // + // The algorithm is to reduce the result modulo the prime by subtracting + // multiples of the group order N. However, in order simplify carry + // propagation, this adds with the two's complement of N to achieve the same + // result. + // + // Since the two's complement of N has 127 leading zero bits, this will end + // up reducing the intermediate result from 512 bits to 385 bits, resulting + // in 13 32-bit terms. The reduced terms are assigned back to t0 through + // t12. + // + // Note that several of the intermediate calculations require adding 64-bit + // products together which would overflow a uint64, so a 96-bit accumulator + // is used instead. + + // Terms for 2^(32*0). + var acc accumulator96 + acc.n[0] = uint32(t0) // == acc.Add(t0) because acc is guaranteed to be 0. + acc.Add(t8 * uint64(orderComplementWordZero)) + t0 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*1). + acc.Add(t1) + acc.Add(t8 * uint64(orderComplementWordOne)) + acc.Add(t9 * uint64(orderComplementWordZero)) + t1 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*2). + acc.Add(t2) + acc.Add(t8 * uint64(orderComplementWordTwo)) + acc.Add(t9 * uint64(orderComplementWordOne)) + acc.Add(t10 * uint64(orderComplementWordZero)) + t2 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*3). + acc.Add(t3) + acc.Add(t8 * uint64(orderComplementWordThree)) + acc.Add(t9 * uint64(orderComplementWordTwo)) + acc.Add(t10 * uint64(orderComplementWordOne)) + acc.Add(t11 * uint64(orderComplementWordZero)) + t3 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*4). + acc.Add(t4) + acc.Add(t8) // * uint64(orderComplementWordFour) // * 1 + acc.Add(t9 * uint64(orderComplementWordThree)) + acc.Add(t10 * uint64(orderComplementWordTwo)) + acc.Add(t11 * uint64(orderComplementWordOne)) + acc.Add(t12 * uint64(orderComplementWordZero)) + t4 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*5). + acc.Add(t5) + // acc.Add(t8 * uint64(orderComplementWordFive)) // 0 + acc.Add(t9) // * uint64(orderComplementWordFour) // * 1 + acc.Add(t10 * uint64(orderComplementWordThree)) + acc.Add(t11 * uint64(orderComplementWordTwo)) + acc.Add(t12 * uint64(orderComplementWordOne)) + acc.Add(t13 * uint64(orderComplementWordZero)) + t5 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*6). + acc.Add(t6) + // acc.Add(t8 * uint64(orderComplementWordSix)) // 0 + // acc.Add(t9 * uint64(orderComplementWordFive)) // 0 + acc.Add(t10) // * uint64(orderComplementWordFour)) // * 1 + acc.Add(t11 * uint64(orderComplementWordThree)) + acc.Add(t12 * uint64(orderComplementWordTwo)) + acc.Add(t13 * uint64(orderComplementWordOne)) + acc.Add(t14 * uint64(orderComplementWordZero)) + t6 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*7). + acc.Add(t7) + // acc.Add(t8 * uint64(orderComplementWordSeven)) // 0 + // acc.Add(t9 * uint64(orderComplementWordSix)) // 0 + // acc.Add(t10 * uint64(orderComplementWordFive)) // 0 + acc.Add(t11) // * uint64(orderComplementWordFour) // * 1 + acc.Add(t12 * uint64(orderComplementWordThree)) + acc.Add(t13 * uint64(orderComplementWordTwo)) + acc.Add(t14 * uint64(orderComplementWordOne)) + acc.Add(t15 * uint64(orderComplementWordZero)) + t7 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*8). + // acc.Add(t9 * uint64(orderComplementWordSeven)) // 0 + // acc.Add(t10 * uint64(orderComplementWordSix)) // 0 + // acc.Add(t11 * uint64(orderComplementWordFive)) // 0 + acc.Add(t12) // * uint64(orderComplementWordFour) // * 1 + acc.Add(t13 * uint64(orderComplementWordThree)) + acc.Add(t14 * uint64(orderComplementWordTwo)) + acc.Add(t15 * uint64(orderComplementWordOne)) + t8 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*9). + // acc.Add(t10 * uint64(orderComplementWordSeven)) // 0 + // acc.Add(t11 * uint64(orderComplementWordSix)) // 0 + // acc.Add(t12 * uint64(orderComplementWordFive)) // 0 + acc.Add(t13) // * uint64(orderComplementWordFour) // * 1 + acc.Add(t14 * uint64(orderComplementWordThree)) + acc.Add(t15 * uint64(orderComplementWordTwo)) + t9 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*10). + // acc.Add(t11 * uint64(orderComplementWordSeven)) // 0 + // acc.Add(t12 * uint64(orderComplementWordSix)) // 0 + // acc.Add(t13 * uint64(orderComplementWordFive)) // 0 + acc.Add(t14) // * uint64(orderComplementWordFour) // * 1 + acc.Add(t15 * uint64(orderComplementWordThree)) + t10 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*11). + // acc.Add(t12 * uint64(orderComplementWordSeven)) // 0 + // acc.Add(t13 * uint64(orderComplementWordSix)) // 0 + // acc.Add(t14 * uint64(orderComplementWordFive)) // 0 + acc.Add(t15) // * uint64(orderComplementWordFour) // * 1 + t11 = uint64(acc.n[0]) + acc.Rsh32() + + // NOTE: All of the remaining multiplications for this iteration result in 0 + // as they all involve multiplying by combinations of the fifth, sixth, and + // seventh words of the two's complement of N, which are 0, so skip them. + + // Terms for 2^(32*12). + t12 = uint64(acc.n[0]) + // acc.Rsh32() // No need since not used after this. Guaranteed to be 0. + + // At this point, the result is reduced to fit within 385 bits, so reduce it + // again using the same method accordingly. + s.reduce385(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12) +} + +// Mul2 multiplies the passed two scalars together modulo the group order in +// constant time and stores the result in s. +// +// The scalar is returned to support chaining. This enables syntax like: +// s3.Mul2(s, s2).AddInt(1) so that s3 = (s * s2) + 1. +func (s *ModNScalar) Mul2(val, val2 *ModNScalar) *ModNScalar { + // This could be done with for loops and an array to store the intermediate + // terms, but this unrolled version is significantly faster. + + // The overall strategy employed here is: + // 1) Calculate the 512-bit product of the two scalars using the standard + // pencil-and-paper method. + // 2) Reduce the result modulo the prime by effectively subtracting + // multiples of the group order N (actually performed by adding multiples + // of the two's complement of N to avoid implementing subtraction). + // 3) Repeat step 2 noting that each iteration reduces the required number + // of bits by 127 because the two's complement of N has 127 leading zero + // bits. + // 4) Once reduced to 256 bits, call the existing reduce method to perform + // a final reduction as needed. + // + // Note that several of the intermediate calculations require adding 64-bit + // products together which would overflow a uint64, so a 96-bit accumulator + // is used instead. + + // Terms for 2^(32*0). + var acc accumulator96 + acc.Add(uint64(val.n[0]) * uint64(val2.n[0])) + t0 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*1). + acc.Add(uint64(val.n[0]) * uint64(val2.n[1])) + acc.Add(uint64(val.n[1]) * uint64(val2.n[0])) + t1 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*2). + acc.Add(uint64(val.n[0]) * uint64(val2.n[2])) + acc.Add(uint64(val.n[1]) * uint64(val2.n[1])) + acc.Add(uint64(val.n[2]) * uint64(val2.n[0])) + t2 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*3). + acc.Add(uint64(val.n[0]) * uint64(val2.n[3])) + acc.Add(uint64(val.n[1]) * uint64(val2.n[2])) + acc.Add(uint64(val.n[2]) * uint64(val2.n[1])) + acc.Add(uint64(val.n[3]) * uint64(val2.n[0])) + t3 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*4). + acc.Add(uint64(val.n[0]) * uint64(val2.n[4])) + acc.Add(uint64(val.n[1]) * uint64(val2.n[3])) + acc.Add(uint64(val.n[2]) * uint64(val2.n[2])) + acc.Add(uint64(val.n[3]) * uint64(val2.n[1])) + acc.Add(uint64(val.n[4]) * uint64(val2.n[0])) + t4 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*5). + acc.Add(uint64(val.n[0]) * uint64(val2.n[5])) + acc.Add(uint64(val.n[1]) * uint64(val2.n[4])) + acc.Add(uint64(val.n[2]) * uint64(val2.n[3])) + acc.Add(uint64(val.n[3]) * uint64(val2.n[2])) + acc.Add(uint64(val.n[4]) * uint64(val2.n[1])) + acc.Add(uint64(val.n[5]) * uint64(val2.n[0])) + t5 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*6). + acc.Add(uint64(val.n[0]) * uint64(val2.n[6])) + acc.Add(uint64(val.n[1]) * uint64(val2.n[5])) + acc.Add(uint64(val.n[2]) * uint64(val2.n[4])) + acc.Add(uint64(val.n[3]) * uint64(val2.n[3])) + acc.Add(uint64(val.n[4]) * uint64(val2.n[2])) + acc.Add(uint64(val.n[5]) * uint64(val2.n[1])) + acc.Add(uint64(val.n[6]) * uint64(val2.n[0])) + t6 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*7). + acc.Add(uint64(val.n[0]) * uint64(val2.n[7])) + acc.Add(uint64(val.n[1]) * uint64(val2.n[6])) + acc.Add(uint64(val.n[2]) * uint64(val2.n[5])) + acc.Add(uint64(val.n[3]) * uint64(val2.n[4])) + acc.Add(uint64(val.n[4]) * uint64(val2.n[3])) + acc.Add(uint64(val.n[5]) * uint64(val2.n[2])) + acc.Add(uint64(val.n[6]) * uint64(val2.n[1])) + acc.Add(uint64(val.n[7]) * uint64(val2.n[0])) + t7 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*8). + acc.Add(uint64(val.n[1]) * uint64(val2.n[7])) + acc.Add(uint64(val.n[2]) * uint64(val2.n[6])) + acc.Add(uint64(val.n[3]) * uint64(val2.n[5])) + acc.Add(uint64(val.n[4]) * uint64(val2.n[4])) + acc.Add(uint64(val.n[5]) * uint64(val2.n[3])) + acc.Add(uint64(val.n[6]) * uint64(val2.n[2])) + acc.Add(uint64(val.n[7]) * uint64(val2.n[1])) + t8 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*9). + acc.Add(uint64(val.n[2]) * uint64(val2.n[7])) + acc.Add(uint64(val.n[3]) * uint64(val2.n[6])) + acc.Add(uint64(val.n[4]) * uint64(val2.n[5])) + acc.Add(uint64(val.n[5]) * uint64(val2.n[4])) + acc.Add(uint64(val.n[6]) * uint64(val2.n[3])) + acc.Add(uint64(val.n[7]) * uint64(val2.n[2])) + t9 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*10). + acc.Add(uint64(val.n[3]) * uint64(val2.n[7])) + acc.Add(uint64(val.n[4]) * uint64(val2.n[6])) + acc.Add(uint64(val.n[5]) * uint64(val2.n[5])) + acc.Add(uint64(val.n[6]) * uint64(val2.n[4])) + acc.Add(uint64(val.n[7]) * uint64(val2.n[3])) + t10 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*11). + acc.Add(uint64(val.n[4]) * uint64(val2.n[7])) + acc.Add(uint64(val.n[5]) * uint64(val2.n[6])) + acc.Add(uint64(val.n[6]) * uint64(val2.n[5])) + acc.Add(uint64(val.n[7]) * uint64(val2.n[4])) + t11 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*12). + acc.Add(uint64(val.n[5]) * uint64(val2.n[7])) + acc.Add(uint64(val.n[6]) * uint64(val2.n[6])) + acc.Add(uint64(val.n[7]) * uint64(val2.n[5])) + t12 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*13). + acc.Add(uint64(val.n[6]) * uint64(val2.n[7])) + acc.Add(uint64(val.n[7]) * uint64(val2.n[6])) + t13 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*14). + acc.Add(uint64(val.n[7]) * uint64(val2.n[7])) + t14 := uint64(acc.n[0]) + acc.Rsh32() + + // What's left is for 2^(32*15). + t15 := uint64(acc.n[0]) + // acc.Rsh32() // No need since not used after this. Guaranteed to be 0. + + // At this point, all of the terms are grouped into their respective base + // and occupy up to 512 bits. Reduce the result accordingly. + s.reduce512(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, + t15) + return s +} + +// Mul multiplies the passed scalar with the existing one modulo the group order +// in constant time and stores the result in s. +// +// The scalar is returned to support chaining. This enables syntax like: +// s.Mul(s2).AddInt(1) so that s = (s * s2) + 1. +func (s *ModNScalar) Mul(val *ModNScalar) *ModNScalar { + return s.Mul2(s, val) +} + +// SquareVal squares the passed scalar modulo the group order in constant time +// and stores the result in s. +// +// The scalar is returned to support chaining. This enables syntax like: +// s3.SquareVal(s).Mul(s) so that s3 = s^2 * s = s^3. +func (s *ModNScalar) SquareVal(val *ModNScalar) *ModNScalar { + // This could technically be optimized slightly to take advantage of the + // fact that many of the intermediate calculations in squaring are just + // doubling, however, benchmarking has shown that due to the need to use a + // 96-bit accumulator, any savings are essentially offset by that and + // consequently there is no real difference in performance over just + // multiplying the value by itself to justify the extra code for now. This + // can be revisited in the future if it becomes a bottleneck in practice. + + return s.Mul2(val, val) +} + +// Square squares the scalar modulo the group order in constant time. The +// existing scalar is modified. +// +// The scalar is returned to support chaining. This enables syntax like: +// s.Square().Mul(s2) so that s = s^2 * s2. +func (s *ModNScalar) Square() *ModNScalar { + return s.SquareVal(s) +} + +// NegateVal negates the passed scalar modulo the group order and stores the +// result in s in constant time. +// +// The scalar is returned to support chaining. This enables syntax like: +// s.NegateVal(s2).AddInt(1) so that s = -s2 + 1. +func (s *ModNScalar) NegateVal(val *ModNScalar) *ModNScalar { + // Since the scalar is already in the range 0 <= val < N, where N is the + // group order, negation modulo the group order is just the group order + // minus the value. This implies that the result will always be in the + // desired range with the sole exception of 0 because N - 0 = N itself. + // + // Therefore, in order to avoid the need to reduce the result for every + // other case in order to achieve constant time, this creates a mask that is + // all 0s in the case of the scalar being negated is 0 and all 1s otherwise + // and bitwise ands that mask with each word. + // + // Finally, to simplify the carry propagation, this adds the two's + // complement of the scalar to N in order to achieve the same result. + bits := val.n[0] | val.n[1] | val.n[2] | val.n[3] | val.n[4] | val.n[5] | + val.n[6] | val.n[7] + mask := uint64(uint32Mask * constantTimeNotEq(bits, 0)) + c := uint64(orderWordZero) + (uint64(^val.n[0]) + 1) + s.n[0] = uint32(c & mask) + c = (c >> 32) + uint64(orderWordOne) + uint64(^val.n[1]) + s.n[1] = uint32(c & mask) + c = (c >> 32) + uint64(orderWordTwo) + uint64(^val.n[2]) + s.n[2] = uint32(c & mask) + c = (c >> 32) + uint64(orderWordThree) + uint64(^val.n[3]) + s.n[3] = uint32(c & mask) + c = (c >> 32) + uint64(orderWordFour) + uint64(^val.n[4]) + s.n[4] = uint32(c & mask) + c = (c >> 32) + uint64(orderWordFive) + uint64(^val.n[5]) + s.n[5] = uint32(c & mask) + c = (c >> 32) + uint64(orderWordSix) + uint64(^val.n[6]) + s.n[6] = uint32(c & mask) + c = (c >> 32) + uint64(orderWordSeven) + uint64(^val.n[7]) + s.n[7] = uint32(c & mask) + return s +} + +// Negate negates the scalar modulo the group order in constant time. The +// existing scalar is modified. +// +// The scalar is returned to support chaining. This enables syntax like: +// s.Negate().AddInt(1) so that s = -s + 1. +func (s *ModNScalar) Negate() *ModNScalar { + return s.NegateVal(s) +} + +// InverseValNonConst finds the modular multiplicative inverse of the passed +// scalar and stores result in s in *non-constant* time. +// +// The scalar is returned to support chaining. This enables syntax like: +// s3.InverseVal(s1).Mul(s2) so that s3 = s1^-1 * s2. +func (s *ModNScalar) InverseValNonConst(val *ModNScalar) *ModNScalar { + // This is making use of big integers for now. Ideally it will be replaced + // with an implementation that does not depend on big integers. + valBytes := val.Bytes() + bigVal := new(big.Int).SetBytes(valBytes[:]) + bigVal.ModInverse(bigVal, curveParams.N) + s.SetByteSlice(bigVal.Bytes()) + return s +} + +// InverseNonConst finds the modular multiplicative inverse of the scalar in +// *non-constant* time. The existing scalar is modified. +// +// The scalar is returned to support chaining. This enables syntax like: +// s.Inverse().Mul(s2) so that s = s^-1 * s2. +func (s *ModNScalar) InverseNonConst() *ModNScalar { + return s.InverseValNonConst(s) +} + +// IsOverHalfOrder returns whether or not the scalar exceeds the group order +// divided by 2 in constant time. +func (s *ModNScalar) IsOverHalfOrder() bool { + // The intuition here is that the scalar is greater than half of the group + // order if one of the higher individual words is greater than the + // corresponding word of the half group order and all higher words in the + // scalar are equal to their corresponding word of the half group order. + // + // Note that the words 4, 5, and 6 are all the max uint32 value, so there is + // no need to test if those individual words of the scalar exceeds them, + // hence, only equality is checked for them. + result := constantTimeGreater(s.n[7], halfOrderWordSeven) + highWordsEqual := constantTimeEq(s.n[7], halfOrderWordSeven) + highWordsEqual &= constantTimeEq(s.n[6], halfOrderWordSix) + highWordsEqual &= constantTimeEq(s.n[5], halfOrderWordFive) + highWordsEqual &= constantTimeEq(s.n[4], halfOrderWordFour) + result |= highWordsEqual & constantTimeGreater(s.n[3], halfOrderWordThree) + highWordsEqual &= constantTimeEq(s.n[3], halfOrderWordThree) + result |= highWordsEqual & constantTimeGreater(s.n[2], halfOrderWordTwo) + highWordsEqual &= constantTimeEq(s.n[2], halfOrderWordTwo) + result |= highWordsEqual & constantTimeGreater(s.n[1], halfOrderWordOne) + highWordsEqual &= constantTimeEq(s.n[1], halfOrderWordOne) + result |= highWordsEqual & constantTimeGreater(s.n[0], halfOrderWordZero) + + return result != 0 +} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/nonce.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/nonce.go new file mode 100644 index 0000000..81b205d --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/nonce.go @@ -0,0 +1,263 @@ +// Copyright (c) 2013-2014 The btcsuite developers +// Copyright (c) 2015-2020 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +import ( + "bytes" + "crypto/sha256" + "hash" +) + +// References: +// [GECC]: Guide to Elliptic Curve Cryptography (Hankerson, Menezes, Vanstone) +// +// [ISO/IEC 8825-1]: Information technology — ASN.1 encoding rules: +// Specification of Basic Encoding Rules (BER), Canonical Encoding Rules +// (CER) and Distinguished Encoding Rules (DER) +// +// [SEC1]: Elliptic Curve Cryptography (May 31, 2009, Version 2.0) +// https://www.secg.org/sec1-v2.pdf + +var ( + // singleZero is used during RFC6979 nonce generation. It is provided + // here to avoid the need to create it multiple times. + singleZero = []byte{0x00} + + // zeroInitializer is used during RFC6979 nonce generation. It is provided + // here to avoid the need to create it multiple times. + zeroInitializer = bytes.Repeat([]byte{0x00}, sha256.BlockSize) + + // singleOne is used during RFC6979 nonce generation. It is provided + // here to avoid the need to create it multiple times. + singleOne = []byte{0x01} + + // oneInitializer is used during RFC6979 nonce generation. It is provided + // here to avoid the need to create it multiple times. + oneInitializer = bytes.Repeat([]byte{0x01}, sha256.Size) +) + +// hmacsha256 implements a resettable version of HMAC-SHA256. +type hmacsha256 struct { + inner, outer hash.Hash + ipad, opad [sha256.BlockSize]byte +} + +// Write adds data to the running hash. +func (h *hmacsha256) Write(p []byte) { + h.inner.Write(p) +} + +// initKey initializes the HMAC-SHA256 instance to the provided key. +func (h *hmacsha256) initKey(key []byte) { + // Hash the key if it is too large. + if len(key) > sha256.BlockSize { + h.outer.Write(key) + key = h.outer.Sum(nil) + } + copy(h.ipad[:], key) + copy(h.opad[:], key) + for i := range h.ipad { + h.ipad[i] ^= 0x36 + } + for i := range h.opad { + h.opad[i] ^= 0x5c + } + h.inner.Write(h.ipad[:]) +} + +// ResetKey resets the HMAC-SHA256 to its initial state and then initializes it +// with the provided key. It is equivalent to creating a new instance with the +// provided key without allocating more memory. +func (h *hmacsha256) ResetKey(key []byte) { + h.inner.Reset() + h.outer.Reset() + copy(h.ipad[:], zeroInitializer) + copy(h.opad[:], zeroInitializer) + h.initKey(key) +} + +// Resets the HMAC-SHA256 to its initial state using the current key. +func (h *hmacsha256) Reset() { + h.inner.Reset() + h.inner.Write(h.ipad[:]) +} + +// Sum returns the hash of the written data. +func (h *hmacsha256) Sum() []byte { + h.outer.Reset() + h.outer.Write(h.opad[:]) + h.outer.Write(h.inner.Sum(nil)) + return h.outer.Sum(nil) +} + +// newHMACSHA256 returns a new HMAC-SHA256 hasher using the provided key. +func newHMACSHA256(key []byte) *hmacsha256 { + h := new(hmacsha256) + h.inner = sha256.New() + h.outer = sha256.New() + h.initKey(key) + return h +} + +// NonceRFC6979 generates a nonce deterministically according to RFC 6979 using +// HMAC-SHA256 for the hashing function. It takes a 32-byte hash as an input +// and returns a 32-byte nonce to be used for deterministic signing. The extra +// and version arguments are optional, but allow additional data to be added to +// the input of the HMAC. When provided, the extra data must be 32-bytes and +// version must be 16 bytes or they will be ignored. +// +// Finally, the extraIterations parameter provides a method to produce a stream +// of deterministic nonces to ensure the signing code is able to produce a nonce +// that results in a valid signature in the extremely unlikely event the +// original nonce produced results in an invalid signature (e.g. R == 0). +// Signing code should start with 0 and increment it if necessary. +func NonceRFC6979(privKey []byte, hash []byte, extra []byte, version []byte, extraIterations uint32) *ModNScalar { + // Input to HMAC is the 32-byte private key and the 32-byte hash. In + // addition, it may include the optional 32-byte extra data and 16-byte + // version. Create a fixed-size array to avoid extra allocs and slice it + // properly. + const ( + privKeyLen = 32 + hashLen = 32 + extraLen = 32 + versionLen = 16 + ) + var keyBuf [privKeyLen + hashLen + extraLen + versionLen]byte + + // Truncate rightmost bytes of private key and hash if they are too long and + // leave left padding of zeros when they're too short. + if len(privKey) > privKeyLen { + privKey = privKey[:privKeyLen] + } + if len(hash) > hashLen { + hash = hash[:hashLen] + } + offset := privKeyLen - len(privKey) // Zero left padding if needed. + offset += copy(keyBuf[offset:], privKey) + offset += hashLen - len(hash) // Zero left padding if needed. + offset += copy(keyBuf[offset:], hash) + if len(extra) == extraLen { + offset += copy(keyBuf[offset:], extra) + if len(version) == versionLen { + offset += copy(keyBuf[offset:], version) + } + } else if len(version) == versionLen { + // When the version was specified, but not the extra data, leave the + // extra data portion all zero. + offset += privKeyLen + offset += copy(keyBuf[offset:], version) + } + key := keyBuf[:offset] + + // Step B. + // + // V = 0x01 0x01 0x01 ... 0x01 such that the length of V, in bits, is + // equal to 8*ceil(hashLen/8). + // + // Note that since the hash length is a multiple of 8 for the chosen hash + // function in this optimized implementation, the result is just the hash + // length, so avoid the extra calculations. Also, since it isn't modified, + // start with a global value. + v := oneInitializer + + // Step C (Go zeroes all allocated memory). + // + // K = 0x00 0x00 0x00 ... 0x00 such that the length of K, in bits, is + // equal to 8*ceil(hashLen/8). + // + // As above, since the hash length is a multiple of 8 for the chosen hash + // function in this optimized implementation, the result is just the hash + // length, so avoid the extra calculations. + k := zeroInitializer[:hashLen] + + // Step D. + // + // K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1)) + // + // Note that key is the "int2octets(x) || bits2octets(h1)" portion along + // with potential additional data as described by section 3.6 of the RFC. + hasher := newHMACSHA256(k) + hasher.Write(oneInitializer) + hasher.Write(singleZero[:]) + hasher.Write(key) + k = hasher.Sum() + + // Step E. + // + // V = HMAC_K(V) + hasher.ResetKey(k) + hasher.Write(v) + v = hasher.Sum() + + // Step F. + // + // K = HMAC_K(V || 0x01 || int2octets(x) || bits2octets(h1)) + // + // Note that key is the "int2octets(x) || bits2octets(h1)" portion along + // with potential additional data as described by section 3.6 of the RFC. + hasher.Reset() + hasher.Write(v) + hasher.Write(singleOne[:]) + hasher.Write(key[:]) + k = hasher.Sum() + + // Step G. + // + // V = HMAC_K(V) + hasher.ResetKey(k) + hasher.Write(v) + v = hasher.Sum() + + // Step H. + // + // Repeat until the value is nonzero and less than the curve order. + var generated uint32 + for { + // Step H1 and H2. + // + // Set T to the empty sequence. The length of T (in bits) is denoted + // tlen; thus, at that point, tlen = 0. + // + // While tlen < qlen, do the following: + // V = HMAC_K(V) + // T = T || V + // + // Note that because the hash function output is the same length as the + // private key in this optimized implementation, there is no need to + // loop or create an intermediate T. + hasher.Reset() + hasher.Write(v) + v = hasher.Sum() + + // Step H3. + // + // k = bits2int(T) + // If k is within the range [1,q-1], return it. + // + // Otherwise, compute: + // K = HMAC_K(V || 0x00) + // V = HMAC_K(V) + var secret ModNScalar + overflow := secret.SetByteSlice(v) + if !overflow && !secret.IsZero() { + generated++ + if generated > extraIterations { + return &secret + } + } + + // K = HMAC_K(V || 0x00) + hasher.Reset() + hasher.Write(v) + hasher.Write(singleZero[:]) + k = hasher.Sum() + + // V = HMAC_K(V) + hasher.ResetKey(k) + hasher.Write(v) + v = hasher.Sum() + } +} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/privkey.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/privkey.go new file mode 100644 index 0000000..3590346 --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/privkey.go @@ -0,0 +1,77 @@ +// Copyright (c) 2013-2014 The btcsuite developers +// Copyright (c) 2015-2020 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +import ( + "crypto/ecdsa" + "crypto/rand" +) + +// PrivateKey provides facilities for working with secp256k1 private keys within +// this package and includes functionality such as serializing and parsing them +// as well as computing their associated public key. +type PrivateKey struct { + Key ModNScalar +} + +// NewPrivateKey instantiates a new private key from a scalar encoded as a +// big integer. +func NewPrivateKey(key *ModNScalar) *PrivateKey { + return &PrivateKey{Key: *key} +} + +// PrivKeyFromBytes returns a private based on the provided byte slice which is +// interpreted as an unsigned 256-bit big-endian integer in the range [0, N-1], +// where N is the order of the curve. +// +// Note that this means passing a slice with more than 32 bytes is truncated and +// that truncated value is reduced modulo N. It is up to the caller to either +// provide a value in the appropriate range or choose to accept the described +// behavior. +// +// Typically callers should simply make use of GeneratePrivateKey when creating +// private keys which properly handles generation of appropriate values. +func PrivKeyFromBytes(privKeyBytes []byte) *PrivateKey { + var privKey PrivateKey + privKey.Key.SetByteSlice(privKeyBytes) + return &privKey +} + +// GeneratePrivateKey returns a private key that is suitable for use with +// secp256k1. +func GeneratePrivateKey() (*PrivateKey, error) { + key, err := ecdsa.GenerateKey(S256(), rand.Reader) + if err != nil { + return nil, err + } + return PrivKeyFromBytes(key.D.Bytes()), nil +} + +// PubKey computes and returns the public key corresponding to this private key. +func (p *PrivateKey) PubKey() *PublicKey { + var result JacobianPoint + ScalarBaseMultNonConst(&p.Key, &result) + result.ToAffine() + return NewPublicKey(&result.X, &result.Y) +} + +// Zero manually clears the memory associated with the private key. This can be +// used to explicitly clear key material from memory for enhanced security +// against memory scraping. +func (p *PrivateKey) Zero() { + p.Key.Zero() +} + +// PrivKeyBytesLen defines the length in bytes of a serialized private key. +const PrivKeyBytesLen = 32 + +// Serialize returns the private key as a 256-bit big-endian binary-encoded +// number, padded to a length of 32 bytes. +func (p PrivateKey) Serialize() []byte { + var privKeyBytes [PrivKeyBytesLen]byte + p.Key.PutBytes(&privKeyBytes) + return privKeyBytes[:] +} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/pubkey.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/pubkey.go new file mode 100644 index 0000000..6716583 --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/pubkey.go @@ -0,0 +1,232 @@ +// Copyright (c) 2013-2014 The btcsuite developers +// Copyright (c) 2015-2021 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +// References: +// [SEC1] Elliptic Curve Cryptography +// https://www.secg.org/sec1-v2.pdf +// +// [SEC2] Recommended Elliptic Curve Domain Parameters +// https://www.secg.org/sec2-v2.pdf +// +// [ANSI X9.62-1998] Public Key Cryptography For The Financial Services +// Industry: The Elliptic Curve Digital Signature Algorithm (ECDSA) + +import ( + "fmt" +) + +const ( + // PubKeyBytesLenCompressed is the number of bytes of a serialized + // compressed public key. + PubKeyBytesLenCompressed = 33 + + // PubKeyBytesLenUncompressed is the number of bytes of a serialized + // uncompressed public key. + PubKeyBytesLenUncompressed = 65 + + // PubKeyFormatCompressedEven is the identifier prefix byte for a public key + // whose Y coordinate is even when serialized in the compressed format per + // section 2.3.4 of [SEC1](https://secg.org/sec1-v2.pdf#subsubsection.2.3.4). + PubKeyFormatCompressedEven byte = 0x02 + + // PubKeyFormatCompressedOdd is the identifier prefix byte for a public key + // whose Y coordinate is odd when serialized in the compressed format per + // section 2.3.4 of [SEC1](https://secg.org/sec1-v2.pdf#subsubsection.2.3.4). + PubKeyFormatCompressedOdd byte = 0x03 + + // PubKeyFormatUncompressed is the identifier prefix byte for a public key + // when serialized according in the uncompressed format per section 2.3.3 of + // [SEC1](https://secg.org/sec1-v2.pdf#subsubsection.2.3.3). + PubKeyFormatUncompressed byte = 0x04 + + // PubKeyFormatHybridEven is the identifier prefix byte for a public key + // whose Y coordinate is even when serialized according to the hybrid format + // per section 4.3.6 of [ANSI X9.62-1998]. + // + // NOTE: This format makes little sense in practice an therefore this + // package will not produce public keys serialized in this format. However, + // it will parse them since they exist in the wild. + PubKeyFormatHybridEven byte = 0x06 + + // PubKeyFormatHybridOdd is the identifier prefix byte for a public key + // whose Y coordingate is odd when serialized according to the hybrid format + // per section 4.3.6 of [ANSI X9.62-1998]. + // + // NOTE: This format makes little sense in practice an therefore this + // package will not produce public keys serialized in this format. However, + // it will parse them since they exist in the wild. + PubKeyFormatHybridOdd byte = 0x07 +) + +// PublicKey provides facilities for efficiently working with secp256k1 public +// keys within this package and includes functions to serialize in both +// uncompressed and compressed SEC (Standards for Efficient Cryptography) +// formats. +type PublicKey struct { + x FieldVal + y FieldVal +} + +// NewPublicKey instantiates a new public key with the given x and y +// coordinates. +// +// It should be noted that, unlike ParsePubKey, since this accepts arbitrary x +// and y coordinates, it allows creation of public keys that are not valid +// points on the secp256k1 curve. The IsOnCurve method of the returned instance +// can be used to determine validity. +func NewPublicKey(x, y *FieldVal) *PublicKey { + var pubKey PublicKey + pubKey.x.Set(x) + pubKey.y.Set(y) + return &pubKey +} + +// ParsePubKey parses a secp256k1 public key encoded according to the format +// specified by ANSI X9.62-1998, which means it is also compatible with the +// SEC (Standards for Efficient Cryptography) specification which is a subset of +// the former. In other words, it supports the uncompressed, compressed, and +// hybrid formats as follows: +// +// Compressed: +// <32-byte X coordinate> +// Uncompressed: +// <32-byte X coordinate><32-byte Y coordinate> +// Hybrid: +// <32-byte X coordinate><32-byte Y coordinate> +// +// NOTE: The hybrid format makes little sense in practice an therefore this +// package will not produce public keys serialized in this format. However, +// this function will properly parse them since they exist in the wild. +func ParsePubKey(serialized []byte) (key *PublicKey, err error) { + var x, y FieldVal + switch len(serialized) { + case PubKeyBytesLenUncompressed: + // Reject unsupported public key formats for the given length. + format := serialized[0] + switch format { + case PubKeyFormatUncompressed: + case PubKeyFormatHybridEven, PubKeyFormatHybridOdd: + default: + str := fmt.Sprintf("invalid public key: unsupported format: %x", + format) + return nil, makeError(ErrPubKeyInvalidFormat, str) + } + + // Parse the x and y coordinates while ensuring that they are in the + // allowed range. + if overflow := x.SetByteSlice(serialized[1:33]); overflow { + str := "invalid public key: x >= field prime" + return nil, makeError(ErrPubKeyXTooBig, str) + } + if overflow := y.SetByteSlice(serialized[33:]); overflow { + str := "invalid public key: y >= field prime" + return nil, makeError(ErrPubKeyYTooBig, str) + } + + // Ensure the oddness of the y coordinate matches the specified format + // for hybrid public keys. + if format == PubKeyFormatHybridEven || format == PubKeyFormatHybridOdd { + wantOddY := format == PubKeyFormatHybridOdd + if y.IsOdd() != wantOddY { + str := fmt.Sprintf("invalid public key: y oddness does not "+ + "match specified value of %v", wantOddY) + return nil, makeError(ErrPubKeyMismatchedOddness, str) + } + } + + // Reject public keys that are not on the secp256k1 curve. + if !isOnCurve(&x, &y) { + str := fmt.Sprintf("invalid public key: [%v,%v] not on secp256k1 "+ + "curve", x, y) + return nil, makeError(ErrPubKeyNotOnCurve, str) + } + + case PubKeyBytesLenCompressed: + // Reject unsupported public key formats for the given length. + format := serialized[0] + switch format { + case PubKeyFormatCompressedEven, PubKeyFormatCompressedOdd: + default: + str := fmt.Sprintf("invalid public key: unsupported format: %x", + format) + return nil, makeError(ErrPubKeyInvalidFormat, str) + } + + // Parse the x coordinate while ensuring that it is in the allowed + // range. + if overflow := x.SetByteSlice(serialized[1:33]); overflow { + str := "invalid public key: x >= field prime" + return nil, makeError(ErrPubKeyXTooBig, str) + } + + // Attempt to calculate the y coordinate for the given x coordinate such + // that the result pair is a point on the secp256k1 curve and the + // solution with desired oddness is chosen. + wantOddY := format == PubKeyFormatCompressedOdd + if !DecompressY(&x, wantOddY, &y) { + str := fmt.Sprintf("invalid public key: x coordinate %v is not on "+ + "the secp256k1 curve", x) + return nil, makeError(ErrPubKeyNotOnCurve, str) + } + y.Normalize() + + default: + str := fmt.Sprintf("malformed public key: invalid length: %d", + len(serialized)) + return nil, makeError(ErrPubKeyInvalidLen, str) + } + + return NewPublicKey(&x, &y), nil +} + +// SerializeUncompressed serializes a public key in the 65-byte uncompressed +// format. +func (p PublicKey) SerializeUncompressed() []byte { + // 0x04 || 32-byte x coordinate || 32-byte y coordinate + var b [PubKeyBytesLenUncompressed]byte + b[0] = PubKeyFormatUncompressed + p.x.PutBytesUnchecked(b[1:33]) + p.y.PutBytesUnchecked(b[33:65]) + return b[:] +} + +// SerializeCompressed serializes a public key in the 33-byte compressed format. +func (p PublicKey) SerializeCompressed() []byte { + // Choose the format byte depending on the oddness of the Y coordinate. + format := PubKeyFormatCompressedEven + if p.y.IsOdd() { + format = PubKeyFormatCompressedOdd + } + + // 0x02 or 0x03 || 32-byte x coordinate + var b [PubKeyBytesLenCompressed]byte + b[0] = format + p.x.PutBytesUnchecked(b[1:33]) + return b[:] +} + +// IsEqual compares this PublicKey instance to the one passed, returning true if +// both PublicKeys are equivalent. A PublicKey is equivalent to another, if they +// both have the same X and Y coordinate. +func (p *PublicKey) IsEqual(otherPubKey *PublicKey) bool { + return p.x.Equals(&otherPubKey.x) && p.y.Equals(&otherPubKey.y) +} + +// AsJacobian converts the public key into a Jacobian point with Z=1 and stores +// the result in the provided result param. This allows the public key to be +// treated a Jacobian point in the secp256k1 group in calculations. +func (p *PublicKey) AsJacobian(result *JacobianPoint) { + result.X.Set(&p.x) + result.Y.Set(&p.y) + result.Z.SetInt(1) +} + +// IsOnCurve returns whether or not the public key represents a point on the +// secp256k1 curve. +func (p *PublicKey) IsOnCurve() bool { + return isOnCurve(&p.x, &p.y) +} diff --git a/vendor/github.com/dgryski/go-rendezvous/LICENSE b/vendor/github.com/dgryski/go-rendezvous/LICENSE new file mode 100644 index 0000000..22080f7 --- /dev/null +++ b/vendor/github.com/dgryski/go-rendezvous/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2017-2020 Damian Gryski + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/dgryski/go-rendezvous/rdv.go b/vendor/github.com/dgryski/go-rendezvous/rdv.go new file mode 100644 index 0000000..7a6f820 --- /dev/null +++ b/vendor/github.com/dgryski/go-rendezvous/rdv.go @@ -0,0 +1,79 @@ +package rendezvous + +type Rendezvous struct { + nodes map[string]int + nstr []string + nhash []uint64 + hash Hasher +} + +type Hasher func(s string) uint64 + +func New(nodes []string, hash Hasher) *Rendezvous { + r := &Rendezvous{ + nodes: make(map[string]int, len(nodes)), + nstr: make([]string, len(nodes)), + nhash: make([]uint64, len(nodes)), + hash: hash, + } + + for i, n := range nodes { + r.nodes[n] = i + r.nstr[i] = n + r.nhash[i] = hash(n) + } + + return r +} + +func (r *Rendezvous) Lookup(k string) string { + // short-circuit if we're empty + if len(r.nodes) == 0 { + return "" + } + + khash := r.hash(k) + + var midx int + var mhash = xorshiftMult64(khash ^ r.nhash[0]) + + for i, nhash := range r.nhash[1:] { + if h := xorshiftMult64(khash ^ nhash); h > mhash { + midx = i + 1 + mhash = h + } + } + + return r.nstr[midx] +} + +func (r *Rendezvous) Add(node string) { + r.nodes[node] = len(r.nstr) + r.nstr = append(r.nstr, node) + r.nhash = append(r.nhash, r.hash(node)) +} + +func (r *Rendezvous) Remove(node string) { + // find index of node to remove + nidx := r.nodes[node] + + // remove from the slices + l := len(r.nstr) + r.nstr[nidx] = r.nstr[l] + r.nstr = r.nstr[:l] + + r.nhash[nidx] = r.nhash[l] + r.nhash = r.nhash[:l] + + // update the map + delete(r.nodes, node) + moved := r.nstr[nidx] + r.nodes[moved] = nidx +} + +func xorshiftMult64(x uint64) uint64 { + x ^= x >> 12 // a + x ^= x << 25 // b + x ^= x >> 27 // c + return x * 2685821657736338717 +} diff --git a/vendor/github.com/fullstorydev/grpcurl/.gitignore b/vendor/github.com/fullstorydev/grpcurl/.gitignore new file mode 100644 index 0000000..1faa9a6 --- /dev/null +++ b/vendor/github.com/fullstorydev/grpcurl/.gitignore @@ -0,0 +1,3 @@ +dist/ +.idea/ +VERSION diff --git a/vendor/github.com/fullstorydev/grpcurl/.goreleaser.yml b/vendor/github.com/fullstorydev/grpcurl/.goreleaser.yml new file mode 100644 index 0000000..f302352 --- /dev/null +++ b/vendor/github.com/fullstorydev/grpcurl/.goreleaser.yml @@ -0,0 +1,40 @@ +builds: + - binary: grpcurl + main: ./cmd/grpcurl + goos: + - linux + - darwin + - windows + goarch: + - amd64 + - 386 + - arm64 + - s390x + - ppc64le + ignore: + - goos: darwin + goarch: 386 + - goos: windows + goarch: arm64 + - goos: darwin + goarch: s390x + - goos: windows + goarch: s390x + - goos: darwin + goarch: ppc64le + - goos: windows + goarch: ppc64le + ldflags: + - -s -w -X main.version=v{{.Version}} + +archives: + - format: tar.gz + format_overrides: + - goos: windows + format: zip + replacements: + amd64: x86_64 + 386: x86_32 + darwin: osx + files: + - LICENSE diff --git a/vendor/github.com/fullstorydev/grpcurl/Dockerfile b/vendor/github.com/fullstorydev/grpcurl/Dockerfile new file mode 100644 index 0000000..0ec7104 --- /dev/null +++ b/vendor/github.com/fullstorydev/grpcurl/Dockerfile @@ -0,0 +1,36 @@ +FROM golang:1.18-alpine as builder +MAINTAINER FullStory Engineering + +# create non-privileged group and user +RUN addgroup -S grpcurl && adduser -S grpcurl -G grpcurl + +WORKDIR /tmp/fullstorydev/grpcurl +# copy just the files/sources we need to build grpcurl +COPY VERSION *.go go.* /tmp/fullstorydev/grpcurl/ +COPY cmd /tmp/fullstorydev/grpcurl/cmd +# and build a completely static binary (so we can use +# scratch as basis for the final image) +ENV CGO_ENABLED=0 +ENV GO111MODULE=on +RUN go build -o /grpcurl \ + -ldflags "-w -extldflags \"-static\" -X \"main.version=$(cat VERSION)\"" \ + ./cmd/grpcurl + +FROM alpine:3 as alpine +WORKDIR / +COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt +COPY --from=builder /etc/passwd /etc/passwd +COPY --from=builder /grpcurl /bin/grpcurl +USER grpcurl + +ENTRYPOINT ["/bin/grpcurl"] + +# New FROM so we have a nice'n'tiny image +FROM scratch +WORKDIR / +COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt +COPY --from=builder /etc/passwd /etc/passwd +COPY --from=builder /grpcurl /bin/grpcurl +USER grpcurl + +ENTRYPOINT ["/bin/grpcurl"] diff --git a/vendor/github.com/fullstorydev/grpcurl/LICENSE b/vendor/github.com/fullstorydev/grpcurl/LICENSE new file mode 100644 index 0000000..6b678c5 --- /dev/null +++ b/vendor/github.com/fullstorydev/grpcurl/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2017 FullStory, Inc + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/vendor/github.com/fullstorydev/grpcurl/Makefile b/vendor/github.com/fullstorydev/grpcurl/Makefile new file mode 100644 index 0000000..3de66ee --- /dev/null +++ b/vendor/github.com/fullstorydev/grpcurl/Makefile @@ -0,0 +1,78 @@ +dev_build_version=$(shell git describe --tags --always --dirty) + +# TODO: run golint and errcheck, but only to catch *new* violations and +# decide whether to change code or not (e.g. we need to be able to whitelist +# violations already in the code). They can be useful to catch errors, but +# they are just too noisy to be a requirement for a CI -- we don't even *want* +# to fix some of the things they consider to be violations. +.PHONY: ci +ci: deps checkgofmt vet staticcheck ineffassign predeclared test + +.PHONY: deps +deps: + go get -d -v -t ./... + +.PHONY: updatedeps +updatedeps: + go get -d -v -t -u -f ./... + +.PHONY: install +install: + go install -ldflags '-X "main.version=dev build $(dev_build_version)"' ./... + +.PHONY: release +release: + @go install github.com/goreleaser/goreleaser@v1.5.0 + goreleaser release --rm-dist + +.PHONY: docker +docker: + @echo $(dev_build_version) > VERSION + docker build -t fullstorydev/grpcurl:$(dev_build_version) . + @rm VERSION + +.PHONY: checkgofmt +checkgofmt: + gofmt -s -l . + @if [ -n "$$(gofmt -s -l .)" ]; then \ + exit 1; \ + fi + +.PHONY: vet +vet: + go vet ./... + +# This all works fine with Go modules, but without modules, +# CI is just getting latest master for dependencies like grpc. +.PHONY: staticcheck +staticcheck: + @go install honnef.co/go/tools/cmd/staticcheck@v0.0.1-2020.1.4 + staticcheck ./... + +.PHONY: ineffassign +ineffassign: + @go install github.com/gordonklaus/ineffassign@7953dde2c7bf + ineffassign . + +.PHONY: predeclared +predeclared: + @go install github.com/nishanths/predeclared@86fad755b4d3 + predeclared . + +# Intentionally omitted from CI, but target here for ad-hoc reports. +.PHONY: golint +golint: + # TODO: pin version + @go install golang.org/x/lint/golint@latest + golint -min_confidence 0.9 -set_exit_status ./... + +# Intentionally omitted from CI, but target here for ad-hoc reports. +.PHONY: errcheck +errcheck: + # TODO: pin version + @go install github.com/kisielk/errcheck@latest + errcheck ./... + +.PHONY: test +test: + go test -race ./... diff --git a/vendor/github.com/fullstorydev/grpcurl/README.md b/vendor/github.com/fullstorydev/grpcurl/README.md new file mode 100644 index 0000000..cbb7e4f --- /dev/null +++ b/vendor/github.com/fullstorydev/grpcurl/README.md @@ -0,0 +1,242 @@ +# gRPCurl +[![Build Status](https://circleci.com/gh/fullstorydev/grpcurl/tree/master.svg?style=svg)](https://circleci.com/gh/fullstorydev/grpcurl/tree/master) +[![Go Report Card](https://goreportcard.com/badge/github.com/fullstorydev/grpcurl)](https://goreportcard.com/report/github.com/fullstorydev/grpcurl) + +`grpcurl` is a command-line tool that lets you interact with gRPC servers. It's +basically `curl` for gRPC servers. + +The main purpose for this tool is to invoke RPC methods on a gRPC server from the +command-line. gRPC servers use a binary encoding on the wire +([protocol buffers](https://developers.google.com/protocol-buffers/), or "protobufs" +for short). So they are basically impossible to interact with using regular `curl` +(and older versions of `curl` that do not support HTTP/2 are of course non-starters). +This program accepts messages using JSON encoding, which is much more friendly for both +humans and scripts. + +With this tool you can also browse the schema for gRPC services, either by querying +a server that supports [server reflection](https://github.com/grpc/grpc/blob/master/src/proto/grpc/reflection/v1alpha/reflection.proto), +by reading proto source files, or by loading in compiled "protoset" files (files that contain +encoded file [descriptor protos](https://github.com/google/protobuf/blob/master/src/google/protobuf/descriptor.proto)). +In fact, the way the tool transforms JSON request data into a binary encoded protobuf +is using that very same schema. So, if the server you interact with does not support +reflection, you will either need the proto source files that define the service or need +protoset files that `grpcurl` can use. + +This repo also provides a library package, `github.com/fullstorydev/grpcurl`, that has +functions for simplifying the construction of other command-line tools that dynamically +invoke gRPC endpoints. This code is a great example of how to use the various packages of +the [protoreflect](https://godoc.org/github.com/jhump/protoreflect) library, and shows +off what they can do. + +See also the [`grpcurl` talk at GopherCon 2018](https://www.youtube.com/watch?v=dDr-8kbMnaw). + +## Features +`grpcurl` supports all kinds of RPC methods, including streaming methods. You can even +operate bi-directional streaming methods interactively by running `grpcurl` from an +interactive terminal and using stdin as the request body! + +`grpcurl` supports both secure/TLS servers _and_ plain-text servers (i.e. no TLS) and has +numerous options for TLS configuration. It also supports mutual TLS, where the client is +required to present a client certificate. + +As mentioned above, `grpcurl` works seamlessly if the server supports the reflection +service. If not, you can supply the `.proto` source files or you can supply protoset +files (containing compiled descriptors, produced by `protoc`) to `grpcurl`. + +## Installation + +### Binaries + +Download the binary from the [releases](https://github.com/fullstorydev/grpcurl/releases) page. + +### Homebrew (macOS) + +On macOS, `grpcurl` is available via Homebrew: +```shell +brew install grpcurl +``` + +### Docker + +For platforms that support Docker, you can download an image that lets you run `grpcurl`: +```shell +# Download image +docker pull fullstorydev/grpcurl:latest +# Run the tool +docker run fullstorydev/grpcurl api.grpc.me:443 list +``` +Note that there are some pitfalls when using docker: +- If you need to interact with a server listening on the host's loopback network, you must specify the host as `host.docker.internal` instead of `localhost` (for Mac or Windows) _OR_ have the container use the host network with `-network="host"` (Linux only). +- If you need to provide proto source files or descriptor sets, you must mount the folder containing the files as a volume (`-v $(pwd):/protos`) and adjust the import paths to container paths accordingly. +- If you want to provide the request message via stdin, using the `-d @` option, you need to use the `-i` flag on the docker command. + +### Other Packages + +There are numerous other ways to install `grpcurl`, thanks to support from third parties that +have created recipes/packages for it. These include other ways to install `grpcurl` on a variety +of environments, including Windows and myriad Linux distributions. + +You can see more details and the full list of other packages for `grpcurl` at _repology.org_: +https://repology.org/project/grpcurl/information + +### From Source +If you already have the [Go SDK](https://golang.org/doc/install) installed, you can use the `go` +tool to install `grpcurl`: +```shell +go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest +``` + +This installs the command into the `bin` sub-folder of wherever your `$GOPATH` +environment variable points. (If you have no `GOPATH` environment variable set, +the default install location is `$HOME/go/bin`). If this directory is already in +your `$PATH`, then you should be good to go. + +If you have already pulled down this repo to a location that is not in your +`$GOPATH` and want to build from the sources, you can `cd` into the repo and then +run `make install`. + +If you encounter compile errors and are using a version of the Go SDK older than 1.13, +you could have out-dated versions of `grpcurl`'s dependencies. You can update the +dependencies by running `make updatedeps`. Or, if you are using Go 1.11 or 1.12, you +can add `GO111MODULE=on` as a prefix to the commands above, which will also build using +the right versions of dependencies (vs. whatever you may already have in your `GOPATH`). + +## Usage +The usage doc for the tool explains the numerous options: +```shell +grpcurl -help +``` + +In the sections below, you will find numerous examples demonstrating how to use +`grpcurl`. + +### Invoking RPCs +Invoking an RPC on a trusted server (e.g. TLS without self-signed key or custom CA) +that requires no client certs and supports server reflection is the simplest thing to +do with `grpcurl`. This minimal invocation sends an empty request body: +```shell +grpcurl grpc.server.com:443 my.custom.server.Service/Method + +# no TLS +grpcurl -plaintext grpc.server.com:80 my.custom.server.Service/Method +``` + +To send a non-empty request, use the `-d` argument. Note that all arguments must come +*before* the server address and method name: +```shell +grpcurl -d '{"id": 1234, "tags": ["foo","bar"]}' \ + grpc.server.com:443 my.custom.server.Service/Method +``` + +As can be seen in the example, the supplied body must be in JSON format. The body will +be parsed and then transmitted to the server in the protobuf binary format. + +If you want to include `grpcurl` in a command pipeline, such as when using `jq` to +create a request body, you can use `-d @`, which tells `grpcurl` to read the actual +request body from stdin: +```shell +grpcurl -d @ grpc.server.com:443 my.custom.server.Service/Method < 0 && b[len(b)-1] == textSeparatorChar { + b = b[:len(b)-1] + } + + f.requestCount++ + + return proto.UnmarshalText(string(b), m) +} + +func (f *textRequestParser) NumRequests() int { + return f.requestCount +} + +// Formatter translates messages into string representations. +type Formatter func(proto.Message) (string, error) + +// NewJSONFormatter returns a formatter that returns JSON strings. The JSON will +// include empty/default values (instead of just omitted them) if emitDefaults +// is true. The given resolver is used to assist with encoding of +// google.protobuf.Any messages. +func NewJSONFormatter(emitDefaults bool, resolver jsonpb.AnyResolver) Formatter { + marshaler := jsonpb.Marshaler{ + EmitDefaults: emitDefaults, + Indent: " ", + AnyResolver: resolver, + } + return marshaler.MarshalToString +} + +// NewTextFormatter returns a formatter that returns strings in the protobuf +// text format. If includeSeparator is true then, when invoked to format +// multiple messages, all messages after the first one will be prefixed with the +// ASCII 'Record Separator' character (0x1E). +func NewTextFormatter(includeSeparator bool) Formatter { + tf := textFormatter{useSeparator: includeSeparator} + return tf.format +} + +type textFormatter struct { + useSeparator bool + numFormatted int +} + +var protoTextMarshaler = proto.TextMarshaler{ExpandAny: true} + +func (tf *textFormatter) format(m proto.Message) (string, error) { + var buf bytes.Buffer + if tf.useSeparator && tf.numFormatted > 0 { + if err := buf.WriteByte(textSeparatorChar); err != nil { + return "", err + } + } + + // If message implements MarshalText method (such as a *dynamic.Message), + // it won't get details about whether or not to format to text compactly + // or with indentation. So first see if the message also implements a + // MarshalTextIndent method and use that instead if available. + type indentMarshaler interface { + MarshalTextIndent() ([]byte, error) + } + + if indenter, ok := m.(indentMarshaler); ok { + b, err := indenter.MarshalTextIndent() + if err != nil { + return "", err + } + if _, err := buf.Write(b); err != nil { + return "", err + } + } else if err := protoTextMarshaler.Marshal(&buf, m); err != nil { + return "", err + } + + // no trailing newline needed + str := buf.String() + if len(str) > 0 && str[len(str)-1] == '\n' { + str = str[:len(str)-1] + } + + tf.numFormatted++ + + return str, nil +} + +type Format string + +const ( + FormatJSON = Format("json") + FormatText = Format("text") +) + +// AnyResolverFromDescriptorSource returns an AnyResolver that will search for +// types using the given descriptor source. +func AnyResolverFromDescriptorSource(source DescriptorSource) jsonpb.AnyResolver { + return &anyResolver{source: source} +} + +// AnyResolverFromDescriptorSourceWithFallback returns an AnyResolver that will +// search for types using the given descriptor source and then fallback to a +// special message if the type is not found. The fallback type will render to +// JSON with a "@type" property, just like an Any message, but also with a +// custom "@value" property that includes the binary encoded payload. +func AnyResolverFromDescriptorSourceWithFallback(source DescriptorSource) jsonpb.AnyResolver { + res := anyResolver{source: source} + return &anyResolverWithFallback{AnyResolver: &res} +} + +type anyResolver struct { + source DescriptorSource + + er dynamic.ExtensionRegistry + + mu sync.RWMutex + mf *dynamic.MessageFactory + resolved map[string]func() proto.Message +} + +func (r *anyResolver) Resolve(typeUrl string) (proto.Message, error) { + mname := typeUrl + if slash := strings.LastIndex(mname, "/"); slash >= 0 { + mname = mname[slash+1:] + } + + r.mu.RLock() + factory := r.resolved[mname] + r.mu.RUnlock() + + // already resolved? + if factory != nil { + return factory(), nil + } + + r.mu.Lock() + defer r.mu.Unlock() + + // double-check, in case we were racing with another goroutine + // that resolved this one + factory = r.resolved[mname] + if factory != nil { + return factory(), nil + } + + // use descriptor source to resolve message type + d, err := r.source.FindSymbol(mname) + if err != nil { + return nil, err + } + md, ok := d.(*desc.MessageDescriptor) + if !ok { + return nil, fmt.Errorf("unknown message: %s", typeUrl) + } + // populate any extensions for this message, too + if exts, err := r.source.AllExtensionsForType(mname); err != nil { + return nil, err + } else if err := r.er.AddExtension(exts...); err != nil { + return nil, err + } + + if r.mf == nil { + r.mf = dynamic.NewMessageFactoryWithExtensionRegistry(&r.er) + } + + factory = func() proto.Message { + return r.mf.NewMessage(md) + } + if r.resolved == nil { + r.resolved = map[string]func() proto.Message{} + } + r.resolved[mname] = factory + return factory(), nil +} + +// anyResolverWithFallback can provide a fallback value for unknown +// messages that will format itself to JSON using an "@value" field +// that has the base64-encoded data for the unknown message value. +type anyResolverWithFallback struct { + jsonpb.AnyResolver +} + +func (r anyResolverWithFallback) Resolve(typeUrl string) (proto.Message, error) { + msg, err := r.AnyResolver.Resolve(typeUrl) + if err == nil { + return msg, err + } + + // Try "default" resolution logic. This mirrors the default behavior + // of jsonpb, which checks to see if the given message name is registered + // in the proto package. + mname := typeUrl + if slash := strings.LastIndex(mname, "/"); slash >= 0 { + mname = mname[slash+1:] + } + //lint:ignore SA1019 new non-deprecated API requires other code changes; deferring... + mt := proto.MessageType(mname) + if mt != nil { + return reflect.New(mt.Elem()).Interface().(proto.Message), nil + } + + // finally, fallback to a special placeholder that can marshal itself + // to JSON using a special "@value" property to show base64-encoded + // data for the embedded message + return &unknownAny{TypeUrl: typeUrl, Error: fmt.Sprintf("%s is not recognized; see @value for raw binary message data", mname)}, nil +} + +type unknownAny struct { + TypeUrl string `json:"@type"` + Error string `json:"@error"` + Value string `json:"@value"` +} + +func (a *unknownAny) MarshalJSONPB(jsm *jsonpb.Marshaler) ([]byte, error) { + if jsm.Indent != "" { + return json.MarshalIndent(a, "", jsm.Indent) + } + return json.Marshal(a) +} + +func (a *unknownAny) Unmarshal(b []byte) error { + a.Value = base64.StdEncoding.EncodeToString(b) + return nil +} + +func (a *unknownAny) Reset() { + a.Value = "" +} + +func (a *unknownAny) String() string { + b, err := a.MarshalJSONPB(&jsonpb.Marshaler{}) + if err != nil { + return fmt.Sprintf("ERROR: %v", err.Error()) + } + return string(b) +} + +func (a *unknownAny) ProtoMessage() { +} + +var _ proto.Message = (*unknownAny)(nil) + +// FormatOptions is a set of flags that are passed to a JSON or text formatter. +type FormatOptions struct { + // EmitJSONDefaultFields flag, when true, includes empty/default values in the output. + // FormatJSON only flag. + EmitJSONDefaultFields bool + + // AllowUnknownFields is an option for the parser. When true, + // it accepts input which includes unknown fields. These unknown fields + // are skipped instead of returning an error. + // FormatJSON only flag. + AllowUnknownFields bool + + // IncludeTextSeparator is true then, when invoked to format multiple messages, + // all messages after the first one will be prefixed with the + // ASCII 'Record Separator' character (0x1E). + // It might be useful when the output is piped to another grpcurl process. + // FormatText only flag. + IncludeTextSeparator bool +} + +// RequestParserAndFormatter returns a request parser and formatter for the +// given format. The given descriptor source may be used for parsing message +// data (if needed by the format). +// It accepts a set of options. The field EmitJSONDefaultFields and IncludeTextSeparator +// are options for JSON and protobuf text formats, respectively. The AllowUnknownFields field +// is a JSON-only format flag. +// Requests will be parsed from the given in. +func RequestParserAndFormatter(format Format, descSource DescriptorSource, in io.Reader, opts FormatOptions) (RequestParser, Formatter, error) { + switch format { + case FormatJSON: + resolver := AnyResolverFromDescriptorSource(descSource) + unmarshaler := jsonpb.Unmarshaler{AnyResolver: resolver, AllowUnknownFields: opts.AllowUnknownFields} + return NewJSONRequestParserWithUnmarshaler(in, unmarshaler), NewJSONFormatter(opts.EmitJSONDefaultFields, anyResolverWithFallback{AnyResolver: resolver}), nil + case FormatText: + return NewTextRequestParser(in), NewTextFormatter(opts.IncludeTextSeparator), nil + default: + return nil, nil, fmt.Errorf("unknown format: %s", format) + } +} + +// RequestParserAndFormatterFor returns a request parser and formatter for the +// given format. The given descriptor source may be used for parsing message +// data (if needed by the format). The flags emitJSONDefaultFields and +// includeTextSeparator are options for JSON and protobuf text formats, +// respectively. Requests will be parsed from the given in. +// This function is deprecated. Please use RequestParserAndFormatter instead. +// DEPRECATED +func RequestParserAndFormatterFor(format Format, descSource DescriptorSource, emitJSONDefaultFields, includeTextSeparator bool, in io.Reader) (RequestParser, Formatter, error) { + return RequestParserAndFormatter(format, descSource, in, FormatOptions{ + EmitJSONDefaultFields: emitJSONDefaultFields, + IncludeTextSeparator: includeTextSeparator, + }) +} + +// DefaultEventHandler logs events to a writer. This is not thread-safe, but is +// safe for use with InvokeRPC as long as NumResponses and Status are not read +// until the call to InvokeRPC completes. +type DefaultEventHandler struct { + Out io.Writer + Formatter Formatter + // 0 = default + // 1 = verbose + // 2 = very verbose + VerbosityLevel int + + // NumResponses is the number of responses that have been received. + NumResponses int + // Status is the status that was received at the end of an RPC. It is + // nil if the RPC is still in progress. + Status *status.Status +} + +// NewDefaultEventHandler returns an InvocationEventHandler that logs events to +// the given output. If verbose is true, all events are logged. Otherwise, only +// response messages are logged. +// +// Deprecated: NewDefaultEventHandler exists for compatibility. +// It doesn't allow fine control over the `VerbosityLevel` +// and provides only 0 and 1 options (which corresponds to the `verbose` argument). +// Use DefaultEventHandler{} initializer directly. +func NewDefaultEventHandler(out io.Writer, descSource DescriptorSource, formatter Formatter, verbose bool) *DefaultEventHandler { + verbosityLevel := 0 + if verbose { + verbosityLevel = 1 + } + return &DefaultEventHandler{ + Out: out, + Formatter: formatter, + VerbosityLevel: verbosityLevel, + } +} + +var _ InvocationEventHandler = (*DefaultEventHandler)(nil) + +func (h *DefaultEventHandler) OnResolveMethod(md *desc.MethodDescriptor) { + if h.VerbosityLevel > 0 { + txt, err := GetDescriptorText(md, nil) + if err == nil { + fmt.Fprintf(h.Out, "\nResolved method descriptor:\n%s\n", txt) + } + } +} + +func (h *DefaultEventHandler) OnSendHeaders(md metadata.MD) { + if h.VerbosityLevel > 0 { + fmt.Fprintf(h.Out, "\nRequest metadata to send:\n%s\n", MetadataToString(md)) + } +} + +func (h *DefaultEventHandler) OnReceiveHeaders(md metadata.MD) { + if h.VerbosityLevel > 0 { + fmt.Fprintf(h.Out, "\nResponse headers received:\n%s\n", MetadataToString(md)) + } +} + +func (h *DefaultEventHandler) OnReceiveResponse(resp proto.Message) { + h.NumResponses++ + if h.VerbosityLevel > 1 { + fmt.Fprintf(h.Out, "\nEstimated response size: %d bytes\n", proto.Size(resp)) + } + if h.VerbosityLevel > 0 { + fmt.Fprint(h.Out, "\nResponse contents:\n") + } + if respStr, err := h.Formatter(resp); err != nil { + fmt.Fprintf(h.Out, "Failed to format response message %d: %v\n", h.NumResponses, err) + } else { + fmt.Fprintln(h.Out, respStr) + } +} + +func (h *DefaultEventHandler) OnReceiveTrailers(stat *status.Status, md metadata.MD) { + h.Status = stat + if h.VerbosityLevel > 0 { + fmt.Fprintf(h.Out, "\nResponse trailers received:\n%s\n", MetadataToString(md)) + } +} + +// PrintStatus prints details about the given status to the given writer. The given +// formatter is used to print any detail messages that may be included in the status. +// If the given status has a code of OK, "OK" is printed and that is all. Otherwise, +// "ERROR:" is printed along with a line showing the code, one showing the message +// string, and each detail message if any are present. The detail messages will be +// printed as proto text format or JSON, depending on the given formatter. +func PrintStatus(w io.Writer, stat *status.Status, formatter Formatter) { + if stat.Code() == codes.OK { + fmt.Fprintln(w, "OK") + return + } + fmt.Fprintf(w, "ERROR:\n Code: %s\n Message: %s\n", stat.Code().String(), stat.Message()) + + statpb := stat.Proto() + if len(statpb.Details) > 0 { + fmt.Fprintf(w, " Details:\n") + for i, det := range statpb.Details { + prefix := fmt.Sprintf(" %d)", i+1) + fmt.Fprintf(w, "%s\t", prefix) + prefix = strings.Repeat(" ", len(prefix)) + "\t" + + output, err := formatter(det) + if err != nil { + fmt.Fprintf(w, "Error parsing detail message: %v\n", err) + } else { + lines := strings.Split(output, "\n") + for i, line := range lines { + if i == 0 { + // first line is already indented + fmt.Fprintf(w, "%s\n", line) + } else { + fmt.Fprintf(w, "%s%s\n", prefix, line) + } + } + } + } + } +} diff --git a/vendor/github.com/fullstorydev/grpcurl/go.mod b/vendor/github.com/fullstorydev/grpcurl/go.mod new file mode 100644 index 0000000..4b27b57 --- /dev/null +++ b/vendor/github.com/fullstorydev/grpcurl/go.mod @@ -0,0 +1,13 @@ +module github.com/fullstorydev/grpcurl + +go 1.15 + +require ( + cloud.google.com/go v0.56.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/golang/protobuf v1.5.2 + github.com/jhump/protoreflect v1.12.0 + golang.org/x/text v0.3.7 // indirect + google.golang.org/grpc v1.48.0 + google.golang.org/protobuf v1.28.1 +) diff --git a/vendor/github.com/fullstorydev/grpcurl/go.sum b/vendor/github.com/fullstorydev/grpcurl/go.sum new file mode 100644 index 0000000..b4963c7 --- /dev/null +++ b/vendor/github.com/fullstorydev/grpcurl/go.sum @@ -0,0 +1,358 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.56.0 h1:WRz29PgAsVEyPSDHyk+0fpEkwEFyfhHn+JbksT6gIL4= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 h1:hzAQntlaYRkVSFEfj9OTWlVV1H155FMD8BTKktLv0QI= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1 h1:zH8ljVhhq7yC0MIeUL/IviMtY8hx2mK8cN9wEYb8ggw= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1 h1:xvqufLtNVwAhN8NMyWklVgxnWohi+wtMGQMhtxexlm0= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= +github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/jhump/gopoet v0.0.0-20190322174617-17282ff210b3/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI= +github.com/jhump/gopoet v0.1.0/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI= +github.com/jhump/goprotoc v0.5.0/go.mod h1:VrbvcYrQOrTi3i0Vf+m+oqQWk9l72mjkJCYo7UvLHRQ= +github.com/jhump/protoreflect v1.11.0/go.mod h1:U7aMIjN0NWq9swDP7xDdoMfRHb35uiuTd3Z9nFXJf5E= +github.com/jhump/protoreflect v1.12.0 h1:1NQ4FpWMgn3by/n1X0fbeKEUxP1wBt7+Oitpv01HR10= +github.com/jhump/protoreflect v1.12.0/go.mod h1:JytZfP5d0r8pVNLZvai7U/MCuTWITgrI4tTg7puQFKI= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 h1:myAQVi0cGEoqQVR5POX+8RR2mrocKqNN1hmeMqhX27k= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w= +google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/vendor/github.com/fullstorydev/grpcurl/grpcurl.go b/vendor/github.com/fullstorydev/grpcurl/grpcurl.go new file mode 100644 index 0000000..f36fc9e --- /dev/null +++ b/vendor/github.com/fullstorydev/grpcurl/grpcurl.go @@ -0,0 +1,699 @@ +// Package grpcurl provides the core functionality exposed by the grpcurl command, for +// dynamically connecting to a server, using the reflection service to inspect the server, +// and invoking RPCs. The grpcurl command-line tool constructs a DescriptorSource, based +// on the command-line parameters, and supplies an InvocationEventHandler to supply request +// data (which can come from command-line args or the process's stdin) and to log the +// events (to the process's stdout). +package grpcurl + +import ( + "bytes" + "context" + "crypto/tls" + "crypto/x509" + "encoding/base64" + "errors" + "fmt" + "io/ioutil" + "net" + "os" + "regexp" + "sort" + "strings" + + "github.com/golang/protobuf/proto" //lint:ignore SA1019 we have to import this because it appears in exported API + "github.com/jhump/protoreflect/desc" + "github.com/jhump/protoreflect/desc/protoprint" + "github.com/jhump/protoreflect/dynamic" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/credentials/insecure" + "google.golang.org/grpc/metadata" + protov2 "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/descriptorpb" + "google.golang.org/protobuf/types/known/anypb" + "google.golang.org/protobuf/types/known/emptypb" + "google.golang.org/protobuf/types/known/structpb" +) + +// ListServices uses the given descriptor source to return a sorted list of fully-qualified +// service names. +func ListServices(source DescriptorSource) ([]string, error) { + svcs, err := source.ListServices() + if err != nil { + return nil, err + } + sort.Strings(svcs) + return svcs, nil +} + +type sourceWithFiles interface { + GetAllFiles() ([]*desc.FileDescriptor, error) +} + +var _ sourceWithFiles = (*fileSource)(nil) + +// GetAllFiles uses the given descriptor source to return a list of file descriptors. +func GetAllFiles(source DescriptorSource) ([]*desc.FileDescriptor, error) { + var files []*desc.FileDescriptor + srcFiles, ok := source.(sourceWithFiles) + + // If an error occurs, we still try to load as many files as we can, so that + // caller can decide whether to ignore error or not. + var firstError error + if ok { + files, firstError = srcFiles.GetAllFiles() + } else { + // Source does not implement GetAllFiles method, so use ListServices + // and grab files from there. + svcNames, err := source.ListServices() + if err != nil { + firstError = err + } else { + allFiles := map[string]*desc.FileDescriptor{} + for _, name := range svcNames { + d, err := source.FindSymbol(name) + if err != nil { + if firstError == nil { + firstError = err + } + } else { + addAllFilesToSet(d.GetFile(), allFiles) + } + } + files = make([]*desc.FileDescriptor, len(allFiles)) + i := 0 + for _, fd := range allFiles { + files[i] = fd + i++ + } + } + } + + sort.Sort(filesByName(files)) + return files, firstError +} + +type filesByName []*desc.FileDescriptor + +func (f filesByName) Len() int { + return len(f) +} + +func (f filesByName) Less(i, j int) bool { + return f[i].GetName() < f[j].GetName() +} + +func (f filesByName) Swap(i, j int) { + f[i], f[j] = f[j], f[i] +} + +func addAllFilesToSet(fd *desc.FileDescriptor, all map[string]*desc.FileDescriptor) { + if _, ok := all[fd.GetName()]; ok { + // already added + return + } + all[fd.GetName()] = fd + for _, dep := range fd.GetDependencies() { + addAllFilesToSet(dep, all) + } +} + +// ListMethods uses the given descriptor source to return a sorted list of method names +// for the specified fully-qualified service name. +func ListMethods(source DescriptorSource, serviceName string) ([]string, error) { + dsc, err := source.FindSymbol(serviceName) + if err != nil { + return nil, err + } + if sd, ok := dsc.(*desc.ServiceDescriptor); !ok { + return nil, notFound("Service", serviceName) + } else { + methods := make([]string, 0, len(sd.GetMethods())) + for _, method := range sd.GetMethods() { + methods = append(methods, method.GetFullyQualifiedName()) + } + sort.Strings(methods) + return methods, nil + } +} + +// MetadataFromHeaders converts a list of header strings (each string in +// "Header-Name: Header-Value" form) into metadata. If a string has a header +// name without a value (e.g. does not contain a colon), the value is assumed +// to be blank. Binary headers (those whose names end in "-bin") should be +// base64-encoded. But if they cannot be base64-decoded, they will be assumed to +// be in raw form and used as is. +func MetadataFromHeaders(headers []string) metadata.MD { + md := make(metadata.MD) + for _, part := range headers { + if part != "" { + pieces := strings.SplitN(part, ":", 2) + if len(pieces) == 1 { + pieces = append(pieces, "") // if no value was specified, just make it "" (maybe the header value doesn't matter) + } + headerName := strings.ToLower(strings.TrimSpace(pieces[0])) + val := strings.TrimSpace(pieces[1]) + if strings.HasSuffix(headerName, "-bin") { + if v, err := decode(val); err == nil { + val = v + } + } + md[headerName] = append(md[headerName], val) + } + } + return md +} + +var envVarRegex = regexp.MustCompile(`\${\w+}`) + +// ExpandHeaders expands environment variables contained in the header string. +// If no corresponding environment variable is found an error is returned. +// TODO: Add escaping for `${` +func ExpandHeaders(headers []string) ([]string, error) { + expandedHeaders := make([]string, len(headers)) + for idx, header := range headers { + if header == "" { + continue + } + results := envVarRegex.FindAllString(header, -1) + if len(results) == 0 { + expandedHeaders[idx] = headers[idx] + continue + } + expandedHeader := header + for _, result := range results { + envVarName := result[2 : len(result)-1] // strip leading `${` and trailing `}` + envVarValue, ok := os.LookupEnv(envVarName) + if !ok { + return nil, fmt.Errorf("header %q refers to missing environment variable %q", header, envVarName) + } + expandedHeader = strings.Replace(expandedHeader, result, envVarValue, -1) + } + expandedHeaders[idx] = expandedHeader + } + return expandedHeaders, nil +} + +var base64Codecs = []*base64.Encoding{base64.StdEncoding, base64.URLEncoding, base64.RawStdEncoding, base64.RawURLEncoding} + +func decode(val string) (string, error) { + var firstErr error + var b []byte + // we are lenient and can accept any of the flavors of base64 encoding + for _, d := range base64Codecs { + var err error + b, err = d.DecodeString(val) + if err != nil { + if firstErr == nil { + firstErr = err + } + continue + } + return string(b), nil + } + return "", firstErr +} + +// MetadataToString returns a string representation of the given metadata, for +// displaying to users. +func MetadataToString(md metadata.MD) string { + if len(md) == 0 { + return "(empty)" + } + + keys := make([]string, 0, len(md)) + for k := range md { + keys = append(keys, k) + } + sort.Strings(keys) + + var b bytes.Buffer + first := true + for _, k := range keys { + vs := md[k] + for _, v := range vs { + if first { + first = false + } else { + b.WriteString("\n") + } + b.WriteString(k) + b.WriteString(": ") + if strings.HasSuffix(k, "-bin") { + v = base64.StdEncoding.EncodeToString([]byte(v)) + } + b.WriteString(v) + } + } + return b.String() +} + +var printer = &protoprint.Printer{ + Compact: true, + OmitComments: protoprint.CommentsNonDoc, + SortElements: true, + ForceFullyQualifiedNames: true, +} + +// GetDescriptorText returns a string representation of the given descriptor. +// This returns a snippet of proto source that describes the given element. +func GetDescriptorText(dsc desc.Descriptor, _ DescriptorSource) (string, error) { + // Note: DescriptorSource is not used, but remains an argument for backwards + // compatibility with previous implementation. + txt, err := printer.PrintProtoToString(dsc) + if err != nil { + return "", err + } + // callers don't expect trailing newlines + if txt[len(txt)-1] == '\n' { + txt = txt[:len(txt)-1] + } + return txt, nil +} + +// EnsureExtensions uses the given descriptor source to download extensions for +// the given message. It returns a copy of the given message, but as a dynamic +// message that knows about all extensions known to the given descriptor source. +func EnsureExtensions(source DescriptorSource, msg proto.Message) proto.Message { + // load any server extensions so we can properly describe custom options + dsc, err := desc.LoadMessageDescriptorForMessage(msg) + if err != nil { + return msg + } + + var ext dynamic.ExtensionRegistry + if err = fetchAllExtensions(source, &ext, dsc, map[string]bool{}); err != nil { + return msg + } + + // convert message into dynamic message that knows about applicable extensions + // (that way we can show meaningful info for custom options instead of printing as unknown) + msgFactory := dynamic.NewMessageFactoryWithExtensionRegistry(&ext) + dm, err := fullyConvertToDynamic(msgFactory, msg) + if err != nil { + return msg + } + return dm +} + +// fetchAllExtensions recursively fetches from the server extensions for the given message type as well as +// for all message types of nested fields. The extensions are added to the given dynamic registry of extensions +// so that all server-known extensions can be correctly parsed by grpcurl. +func fetchAllExtensions(source DescriptorSource, ext *dynamic.ExtensionRegistry, md *desc.MessageDescriptor, alreadyFetched map[string]bool) error { + msgTypeName := md.GetFullyQualifiedName() + if alreadyFetched[msgTypeName] { + return nil + } + alreadyFetched[msgTypeName] = true + if len(md.GetExtensionRanges()) > 0 { + fds, err := source.AllExtensionsForType(msgTypeName) + if err != nil { + return fmt.Errorf("failed to query for extensions of type %s: %v", msgTypeName, err) + } + for _, fd := range fds { + if err := ext.AddExtension(fd); err != nil { + return fmt.Errorf("could not register extension %s of type %s: %v", fd.GetFullyQualifiedName(), msgTypeName, err) + } + } + } + // recursively fetch extensions for the types of any message fields + for _, fd := range md.GetFields() { + if fd.GetMessageType() != nil { + err := fetchAllExtensions(source, ext, fd.GetMessageType(), alreadyFetched) + if err != nil { + return err + } + } + } + return nil +} + +// fullConvertToDynamic attempts to convert the given message to a dynamic message as well +// as any nested messages it may contain as field values. If the given message factory has +// extensions registered that were not known when the given message was parsed, this effectively +// allows re-parsing to identify those extensions. +func fullyConvertToDynamic(msgFact *dynamic.MessageFactory, msg proto.Message) (proto.Message, error) { + if _, ok := msg.(*dynamic.Message); ok { + return msg, nil // already a dynamic message + } + md, err := desc.LoadMessageDescriptorForMessage(msg) + if err != nil { + return nil, err + } + newMsg := msgFact.NewMessage(md) + dm, ok := newMsg.(*dynamic.Message) + if !ok { + // if message factory didn't produce a dynamic message, then we should leave msg as is + return msg, nil + } + + if err := dm.ConvertFrom(msg); err != nil { + return nil, err + } + + // recursively convert all field values, too + for _, fd := range md.GetFields() { + if fd.IsMap() { + if fd.GetMapValueType().GetMessageType() != nil { + m := dm.GetField(fd).(map[interface{}]interface{}) + for k, v := range m { + // keys can't be nested messages; so we only need to recurse through map values, not keys + newVal, err := fullyConvertToDynamic(msgFact, v.(proto.Message)) + if err != nil { + return nil, err + } + dm.PutMapField(fd, k, newVal) + } + } + } else if fd.IsRepeated() { + if fd.GetMessageType() != nil { + s := dm.GetField(fd).([]interface{}) + for i, e := range s { + newVal, err := fullyConvertToDynamic(msgFact, e.(proto.Message)) + if err != nil { + return nil, err + } + dm.SetRepeatedField(fd, i, newVal) + } + } + } else { + if fd.GetMessageType() != nil { + v := dm.GetField(fd) + newVal, err := fullyConvertToDynamic(msgFact, v.(proto.Message)) + if err != nil { + return nil, err + } + dm.SetField(fd, newVal) + } + } + } + return dm, nil +} + +// MakeTemplate returns a message instance for the given descriptor that is a +// suitable template for creating an instance of that message in JSON. In +// particular, it ensures that any repeated fields (which include map fields) +// are not empty, so they will render with a single element (to show the types +// and optionally nested fields). It also ensures that nested messages are not +// nil by setting them to a message that is also fleshed out as a template +// message. +func MakeTemplate(md *desc.MessageDescriptor) proto.Message { + return makeTemplate(md, nil) +} + +func makeTemplate(md *desc.MessageDescriptor, path []*desc.MessageDescriptor) proto.Message { + switch md.GetFullyQualifiedName() { + case "google.protobuf.Any": + // empty type URL is not allowed by JSON representation + // so we must give it a dummy type + var any anypb.Any + _ = anypb.MarshalFrom(&any, &emptypb.Empty{}, protov2.MarshalOptions{}) + return &any + case "google.protobuf.Value": + // unset kind is not allowed by JSON representation + // so we must give it something + return &structpb.Value{ + Kind: &structpb.Value_StructValue{StructValue: &structpb.Struct{ + Fields: map[string]*structpb.Value{ + "google.protobuf.Value": {Kind: &structpb.Value_StringValue{ + StringValue: "supports arbitrary JSON", + }}, + }, + }}, + } + case "google.protobuf.ListValue": + return &structpb.ListValue{ + Values: []*structpb.Value{ + { + Kind: &structpb.Value_StructValue{StructValue: &structpb.Struct{ + Fields: map[string]*structpb.Value{ + "google.protobuf.ListValue": {Kind: &structpb.Value_StringValue{ + StringValue: "is an array of arbitrary JSON values", + }}, + }, + }}, + }, + }, + } + case "google.protobuf.Struct": + return &structpb.Struct{ + Fields: map[string]*structpb.Value{ + "google.protobuf.Struct": {Kind: &structpb.Value_StringValue{ + StringValue: "supports arbitrary JSON objects", + }}, + }, + } + } + + dm := dynamic.NewMessage(md) + + // if the message is a recursive structure, we don't want to blow the stack + for _, seen := range path { + if seen == md { + // already visited this type; avoid infinite recursion + return dm + } + } + path = append(path, dm.GetMessageDescriptor()) + + // for repeated fields, add a single element with default value + // and for message fields, add a message with all default fields + // that also has non-nil message and non-empty repeated fields + + for _, fd := range dm.GetMessageDescriptor().GetFields() { + if fd.IsRepeated() { + switch fd.GetType() { + case descriptorpb.FieldDescriptorProto_TYPE_FIXED32, + descriptorpb.FieldDescriptorProto_TYPE_UINT32: + dm.AddRepeatedField(fd, uint32(0)) + + case descriptorpb.FieldDescriptorProto_TYPE_SFIXED32, + descriptorpb.FieldDescriptorProto_TYPE_SINT32, + descriptorpb.FieldDescriptorProto_TYPE_INT32, + descriptorpb.FieldDescriptorProto_TYPE_ENUM: + dm.AddRepeatedField(fd, int32(0)) + + case descriptorpb.FieldDescriptorProto_TYPE_FIXED64, + descriptorpb.FieldDescriptorProto_TYPE_UINT64: + dm.AddRepeatedField(fd, uint64(0)) + + case descriptorpb.FieldDescriptorProto_TYPE_SFIXED64, + descriptorpb.FieldDescriptorProto_TYPE_SINT64, + descriptorpb.FieldDescriptorProto_TYPE_INT64: + dm.AddRepeatedField(fd, int64(0)) + + case descriptorpb.FieldDescriptorProto_TYPE_STRING: + dm.AddRepeatedField(fd, "") + + case descriptorpb.FieldDescriptorProto_TYPE_BYTES: + dm.AddRepeatedField(fd, []byte{}) + + case descriptorpb.FieldDescriptorProto_TYPE_BOOL: + dm.AddRepeatedField(fd, false) + + case descriptorpb.FieldDescriptorProto_TYPE_FLOAT: + dm.AddRepeatedField(fd, float32(0)) + + case descriptorpb.FieldDescriptorProto_TYPE_DOUBLE: + dm.AddRepeatedField(fd, float64(0)) + + case descriptorpb.FieldDescriptorProto_TYPE_MESSAGE, + descriptorpb.FieldDescriptorProto_TYPE_GROUP: + dm.AddRepeatedField(fd, makeTemplate(fd.GetMessageType(), path)) + } + } else if fd.GetMessageType() != nil { + dm.SetField(fd, makeTemplate(fd.GetMessageType(), path)) + } + } + return dm +} + +// ClientTransportCredentials is a helper function that constructs a TLS config with +// the given properties (see ClientTLSConfig) and then constructs and returns gRPC +// transport credentials using that config. +// +// Deprecated: Use grpcurl.ClientTLSConfig and credentials.NewTLS instead. +func ClientTransportCredentials(insecureSkipVerify bool, cacertFile, clientCertFile, clientKeyFile string) (credentials.TransportCredentials, error) { + tlsConf, err := ClientTLSConfig(insecureSkipVerify, cacertFile, clientCertFile, clientKeyFile) + if err != nil { + return nil, err + } + + return credentials.NewTLS(tlsConf), nil +} + +// ClientTLSConfig builds transport-layer config for a gRPC client using the +// given properties. If cacertFile is blank, only standard trusted certs are used to +// verify the server certs. If clientCertFile is blank, the client will not use a client +// certificate. If clientCertFile is not blank then clientKeyFile must not be blank. +func ClientTLSConfig(insecureSkipVerify bool, cacertFile, clientCertFile, clientKeyFile string) (*tls.Config, error) { + var tlsConf tls.Config + + if clientCertFile != "" { + // Load the client certificates from disk + certificate, err := tls.LoadX509KeyPair(clientCertFile, clientKeyFile) + if err != nil { + return nil, fmt.Errorf("could not load client key pair: %v", err) + } + tlsConf.Certificates = []tls.Certificate{certificate} + } + + if insecureSkipVerify { + tlsConf.InsecureSkipVerify = true + } else if cacertFile != "" { + // Create a certificate pool from the certificate authority + certPool := x509.NewCertPool() + ca, err := ioutil.ReadFile(cacertFile) + if err != nil { + return nil, fmt.Errorf("could not read ca certificate: %v", err) + } + + // Append the certificates from the CA + if ok := certPool.AppendCertsFromPEM(ca); !ok { + return nil, errors.New("failed to append ca certs") + } + + tlsConf.RootCAs = certPool + } + + return &tlsConf, nil +} + +// ServerTransportCredentials builds transport credentials for a gRPC server using the +// given properties. If cacertFile is blank, the server will not request client certs +// unless requireClientCerts is true. When requireClientCerts is false and cacertFile is +// not blank, the server will verify client certs when presented, but will not require +// client certs. The serverCertFile and serverKeyFile must both not be blank. +func ServerTransportCredentials(cacertFile, serverCertFile, serverKeyFile string, requireClientCerts bool) (credentials.TransportCredentials, error) { + var tlsConf tls.Config + // TODO(jh): Remove this line once https://github.com/golang/go/issues/28779 is fixed + // in Go tip. Until then, the recently merged TLS 1.3 support breaks the TLS tests. + tlsConf.MaxVersion = tls.VersionTLS12 + + // Load the server certificates from disk + certificate, err := tls.LoadX509KeyPair(serverCertFile, serverKeyFile) + if err != nil { + return nil, fmt.Errorf("could not load key pair: %v", err) + } + tlsConf.Certificates = []tls.Certificate{certificate} + + if cacertFile != "" { + // Create a certificate pool from the certificate authority + certPool := x509.NewCertPool() + ca, err := ioutil.ReadFile(cacertFile) + if err != nil { + return nil, fmt.Errorf("could not read ca certificate: %v", err) + } + + // Append the certificates from the CA + if ok := certPool.AppendCertsFromPEM(ca); !ok { + return nil, errors.New("failed to append ca certs") + } + + tlsConf.ClientCAs = certPool + } + + if requireClientCerts { + tlsConf.ClientAuth = tls.RequireAndVerifyClientCert + } else if cacertFile != "" { + tlsConf.ClientAuth = tls.VerifyClientCertIfGiven + } else { + tlsConf.ClientAuth = tls.NoClientCert + } + + return credentials.NewTLS(&tlsConf), nil +} + +// BlockingDial is a helper method to dial the given address, using optional TLS credentials, +// and blocking until the returned connection is ready. If the given credentials are nil, the +// connection will be insecure (plain-text). +func BlockingDial(ctx context.Context, network, address string, creds credentials.TransportCredentials, opts ...grpc.DialOption) (*grpc.ClientConn, error) { + // grpc.Dial doesn't provide any information on permanent connection errors (like + // TLS handshake failures). So in order to provide good error messages, we need a + // custom dialer that can provide that info. That means we manage the TLS handshake. + result := make(chan interface{}, 1) + + writeResult := func(res interface{}) { + // non-blocking write: we only need the first result + select { + case result <- res: + default: + } + } + + // custom credentials and dialer will notify on error via the + // writeResult function + if creds != nil { + creds = &errSignalingCreds{ + TransportCredentials: creds, + writeResult: writeResult, + } + } + dialer := func(ctx context.Context, address string) (net.Conn, error) { + // NB: We *could* handle the TLS handshake ourselves, in the custom + // dialer (instead of customizing both the dialer and the credentials). + // But that requires using insecure.NewCredentials() dial transport + // option (so that the gRPC library doesn't *also* try to do a + // handshake). And that would mean that the library would send the + // wrong ":scheme" metaheader to servers: it would send "http" instead + // of "https" because it is unaware that TLS is actually in use. + conn, err := (&net.Dialer{}).DialContext(ctx, network, address) + if err != nil { + writeResult(err) + } + return conn, err + } + + // Even with grpc.FailOnNonTempDialError, this call will usually timeout in + // the face of TLS handshake errors. So we can't rely on grpc.WithBlock() to + // know when we're done. So we run it in a goroutine and then use result + // channel to either get the connection or fail-fast. + go func() { + // We put grpc.FailOnNonTempDialError *before* the explicitly provided + // options so that it could be overridden. + opts = append([]grpc.DialOption{grpc.FailOnNonTempDialError(true)}, opts...) + // But we don't want caller to be able to override these two, so we put + // them *after* the explicitly provided options. + opts = append(opts, grpc.WithBlock(), grpc.WithContextDialer(dialer)) + + if creds == nil { + opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials())) + } else { + opts = append(opts, grpc.WithTransportCredentials(creds)) + } + conn, err := grpc.DialContext(ctx, address, opts...) + var res interface{} + if err != nil { + res = err + } else { + res = conn + } + writeResult(res) + }() + + select { + case res := <-result: + if conn, ok := res.(*grpc.ClientConn); ok { + return conn, nil + } + return nil, res.(error) + case <-ctx.Done(): + return nil, ctx.Err() + } +} + +// errSignalingCreds is a wrapper around a TransportCredentials value, but +// it will use the writeResult function to notify on error. +type errSignalingCreds struct { + credentials.TransportCredentials + writeResult func(res interface{}) +} + +func (c *errSignalingCreds) ClientHandshake(ctx context.Context, addr string, rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) { + conn, auth, err := c.TransportCredentials.ClientHandshake(ctx, addr, rawConn) + if err != nil { + c.writeResult(err) + } + return conn, auth, err +} diff --git a/vendor/github.com/fullstorydev/grpcurl/invoke.go b/vendor/github.com/fullstorydev/grpcurl/invoke.go new file mode 100644 index 0000000..b5bae4b --- /dev/null +++ b/vendor/github.com/fullstorydev/grpcurl/invoke.go @@ -0,0 +1,405 @@ +package grpcurl + +import ( + "bytes" + "context" + "fmt" + "io" + "strings" + "sync" + "sync/atomic" + + "github.com/golang/protobuf/jsonpb" //lint:ignore SA1019 we have to import this because it appears in exported API + "github.com/golang/protobuf/proto" //lint:ignore SA1019 we have to import this because it appears in exported API + "github.com/jhump/protoreflect/desc" + "github.com/jhump/protoreflect/dynamic" + "github.com/jhump/protoreflect/dynamic/grpcdynamic" + "github.com/jhump/protoreflect/grpcreflect" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" +) + +// InvocationEventHandler is a bag of callbacks for handling events that occur in the course +// of invoking an RPC. The handler also provides request data that is sent. The callbacks are +// generally called in the order they are listed below. +type InvocationEventHandler interface { + // OnResolveMethod is called with a descriptor of the method that is being invoked. + OnResolveMethod(*desc.MethodDescriptor) + // OnSendHeaders is called with the request metadata that is being sent. + OnSendHeaders(metadata.MD) + // OnReceiveHeaders is called when response headers have been received. + OnReceiveHeaders(metadata.MD) + // OnReceiveResponse is called for each response message received. + OnReceiveResponse(proto.Message) + // OnReceiveTrailers is called when response trailers and final RPC status have been received. + OnReceiveTrailers(*status.Status, metadata.MD) +} + +// RequestMessageSupplier is a function that is called to retrieve request +// messages for a GRPC operation. This type is deprecated and will be removed in +// a future release. +// +// Deprecated: This is only used with the deprecated InvokeRpc. Instead, use +// RequestSupplier with InvokeRPC. +type RequestMessageSupplier func() ([]byte, error) + +// InvokeRpc uses the given gRPC connection to invoke the given method. This function is deprecated +// and will be removed in a future release. It just delegates to the similarly named InvokeRPC +// method, whose signature is only slightly different. +// +// Deprecated: use InvokeRPC instead. +func InvokeRpc(ctx context.Context, source DescriptorSource, cc *grpc.ClientConn, methodName string, + headers []string, handler InvocationEventHandler, requestData RequestMessageSupplier) error { + + return InvokeRPC(ctx, source, cc, methodName, headers, handler, func(m proto.Message) error { + // New function is almost identical, but the request supplier function works differently. + // So we adapt the logic here to maintain compatibility. + data, err := requestData() + if err != nil { + return err + } + return jsonpb.Unmarshal(bytes.NewReader(data), m) + }) +} + +// RequestSupplier is a function that is called to populate messages for a gRPC operation. The +// function should populate the given message or return a non-nil error. If the supplier has no +// more messages, it should return io.EOF. When it returns io.EOF, it should not in any way +// modify the given message argument. +type RequestSupplier func(proto.Message) error + +// InvokeRPC uses the given gRPC channel to invoke the given method. The given descriptor source +// is used to determine the type of method and the type of request and response message. The given +// headers are sent as request metadata. Methods on the given event handler are called as the +// invocation proceeds. +// +// The given requestData function supplies the actual data to send. It should return io.EOF when +// there is no more request data. If the method being invoked is a unary or server-streaming RPC +// (e.g. exactly one request message) and there is no request data (e.g. the first invocation of +// the function returns io.EOF), then an empty request message is sent. +// +// If the requestData function and the given event handler coordinate or share any state, they should +// be thread-safe. This is because the requestData function may be called from a different goroutine +// than the one invoking event callbacks. (This only happens for bi-directional streaming RPCs, where +// one goroutine sends request messages and another consumes the response messages). +func InvokeRPC(ctx context.Context, source DescriptorSource, ch grpcdynamic.Channel, methodName string, + headers []string, handler InvocationEventHandler, requestData RequestSupplier) error { + + md := MetadataFromHeaders(headers) + + svc, mth := parseSymbol(methodName) + if svc == "" || mth == "" { + return fmt.Errorf("given method name %q is not in expected format: 'service/method' or 'service.method'", methodName) + } + + dsc, err := source.FindSymbol(svc) + if err != nil { + // return a gRPC status error if hasStatus is true + errStatus, hasStatus := status.FromError(err) + switch { + case hasStatus && isNotFoundError(err): + return status.Errorf(errStatus.Code(), "target server does not expose service %q: %s", svc, errStatus.Message()) + case hasStatus: + return status.Errorf(errStatus.Code(), "failed to query for service descriptor %q: %s", svc, errStatus.Message()) + case isNotFoundError(err): + return fmt.Errorf("target server does not expose service %q", svc) + } + return fmt.Errorf("failed to query for service descriptor %q: %v", svc, err) + } + sd, ok := dsc.(*desc.ServiceDescriptor) + if !ok { + return fmt.Errorf("target server does not expose service %q", svc) + } + mtd := sd.FindMethodByName(mth) + if mtd == nil { + return fmt.Errorf("service %q does not include a method named %q", svc, mth) + } + + handler.OnResolveMethod(mtd) + + // we also download any applicable extensions so we can provide full support for parsing user-provided data + var ext dynamic.ExtensionRegistry + alreadyFetched := map[string]bool{} + if err = fetchAllExtensions(source, &ext, mtd.GetInputType(), alreadyFetched); err != nil { + return fmt.Errorf("error resolving server extensions for message %s: %v", mtd.GetInputType().GetFullyQualifiedName(), err) + } + if err = fetchAllExtensions(source, &ext, mtd.GetOutputType(), alreadyFetched); err != nil { + return fmt.Errorf("error resolving server extensions for message %s: %v", mtd.GetOutputType().GetFullyQualifiedName(), err) + } + + msgFactory := dynamic.NewMessageFactoryWithExtensionRegistry(&ext) + req := msgFactory.NewMessage(mtd.GetInputType()) + + handler.OnSendHeaders(md) + ctx = metadata.NewOutgoingContext(ctx, md) + + stub := grpcdynamic.NewStubWithMessageFactory(ch, msgFactory) + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + if mtd.IsClientStreaming() && mtd.IsServerStreaming() { + return invokeBidi(ctx, stub, mtd, handler, requestData, req) + } else if mtd.IsClientStreaming() { + return invokeClientStream(ctx, stub, mtd, handler, requestData, req) + } else if mtd.IsServerStreaming() { + return invokeServerStream(ctx, stub, mtd, handler, requestData, req) + } else { + return invokeUnary(ctx, stub, mtd, handler, requestData, req) + } +} + +func invokeUnary(ctx context.Context, stub grpcdynamic.Stub, md *desc.MethodDescriptor, handler InvocationEventHandler, + requestData RequestSupplier, req proto.Message) error { + + err := requestData(req) + if err != nil && err != io.EOF { + return fmt.Errorf("error getting request data: %v", err) + } + if err != io.EOF { + // verify there is no second message, which is a usage error + err := requestData(req) + if err == nil { + return fmt.Errorf("method %q is a unary RPC, but request data contained more than 1 message", md.GetFullyQualifiedName()) + } else if err != io.EOF { + return fmt.Errorf("error getting request data: %v", err) + } + } + + // Now we can actually invoke the RPC! + var respHeaders metadata.MD + var respTrailers metadata.MD + resp, err := stub.InvokeRpc(ctx, md, req, grpc.Trailer(&respTrailers), grpc.Header(&respHeaders)) + + stat, ok := status.FromError(err) + if !ok { + // Error codes sent from the server will get printed differently below. + // So just bail for other kinds of errors here. + return fmt.Errorf("grpc call for %q failed: %v", md.GetFullyQualifiedName(), err) + } + + handler.OnReceiveHeaders(respHeaders) + + if stat.Code() == codes.OK { + handler.OnReceiveResponse(resp) + } + + handler.OnReceiveTrailers(stat, respTrailers) + + return nil +} + +func invokeClientStream(ctx context.Context, stub grpcdynamic.Stub, md *desc.MethodDescriptor, handler InvocationEventHandler, + requestData RequestSupplier, req proto.Message) error { + + // invoke the RPC! + str, err := stub.InvokeRpcClientStream(ctx, md) + + // Upload each request message in the stream + var resp proto.Message + for err == nil { + err = requestData(req) + if err == io.EOF { + resp, err = str.CloseAndReceive() + break + } + if err != nil { + return fmt.Errorf("error getting request data: %v", err) + } + + err = str.SendMsg(req) + if err == io.EOF { + // We get EOF on send if the server says "go away" + // We have to use CloseAndReceive to get the actual code + resp, err = str.CloseAndReceive() + break + } + + req.Reset() + } + + // finally, process response data + stat, ok := status.FromError(err) + if !ok { + // Error codes sent from the server will get printed differently below. + // So just bail for other kinds of errors here. + return fmt.Errorf("grpc call for %q failed: %v", md.GetFullyQualifiedName(), err) + } + + if str != nil { + if respHeaders, err := str.Header(); err == nil { + handler.OnReceiveHeaders(respHeaders) + } + } + + if stat.Code() == codes.OK { + handler.OnReceiveResponse(resp) + } + + if str != nil { + handler.OnReceiveTrailers(stat, str.Trailer()) + } + + return nil +} + +func invokeServerStream(ctx context.Context, stub grpcdynamic.Stub, md *desc.MethodDescriptor, handler InvocationEventHandler, + requestData RequestSupplier, req proto.Message) error { + + err := requestData(req) + if err != nil && err != io.EOF { + return fmt.Errorf("error getting request data: %v", err) + } + if err != io.EOF { + // verify there is no second message, which is a usage error + err := requestData(req) + if err == nil { + return fmt.Errorf("method %q is a server-streaming RPC, but request data contained more than 1 message", md.GetFullyQualifiedName()) + } else if err != io.EOF { + return fmt.Errorf("error getting request data: %v", err) + } + } + + // Now we can actually invoke the RPC! + str, err := stub.InvokeRpcServerStream(ctx, md, req) + + if respHeaders, err := str.Header(); err == nil { + handler.OnReceiveHeaders(respHeaders) + } + + // Download each response message + for err == nil { + var resp proto.Message + resp, err = str.RecvMsg() + if err != nil { + if err == io.EOF { + err = nil + } + break + } + handler.OnReceiveResponse(resp) + } + + stat, ok := status.FromError(err) + if !ok { + // Error codes sent from the server will get printed differently below. + // So just bail for other kinds of errors here. + return fmt.Errorf("grpc call for %q failed: %v", md.GetFullyQualifiedName(), err) + } + + handler.OnReceiveTrailers(stat, str.Trailer()) + + return nil +} + +func invokeBidi(ctx context.Context, stub grpcdynamic.Stub, md *desc.MethodDescriptor, handler InvocationEventHandler, + requestData RequestSupplier, req proto.Message) error { + + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + // invoke the RPC! + str, err := stub.InvokeRpcBidiStream(ctx, md) + + var wg sync.WaitGroup + var sendErr atomic.Value + + defer wg.Wait() + + if err == nil { + wg.Add(1) + go func() { + defer wg.Done() + + // Concurrently upload each request message in the stream + var err error + for err == nil { + err = requestData(req) + + if err == io.EOF { + err = str.CloseSend() + break + } + if err != nil { + err = fmt.Errorf("error getting request data: %v", err) + cancel() + break + } + + err = str.SendMsg(req) + + req.Reset() + } + + if err != nil { + sendErr.Store(err) + } + }() + } + + if str != nil { + if respHeaders, err := str.Header(); err == nil { + handler.OnReceiveHeaders(respHeaders) + } + } + + // Download each response message + for err == nil { + var resp proto.Message + resp, err = str.RecvMsg() + if err != nil { + if err == io.EOF { + err = nil + } + break + } + handler.OnReceiveResponse(resp) + } + + if se, ok := sendErr.Load().(error); ok && se != io.EOF { + err = se + } + + stat, ok := status.FromError(err) + if !ok { + // Error codes sent from the server will get printed differently below. + // So just bail for other kinds of errors here. + return fmt.Errorf("grpc call for %q failed: %v", md.GetFullyQualifiedName(), err) + } + + if str != nil { + handler.OnReceiveTrailers(stat, str.Trailer()) + } + + return nil +} + +type notFoundError string + +func notFound(kind, name string) error { + return notFoundError(fmt.Sprintf("%s not found: %s", kind, name)) +} + +func (e notFoundError) Error() string { + return string(e) +} + +func isNotFoundError(err error) bool { + if grpcreflect.IsElementNotFoundError(err) { + return true + } + _, ok := err.(notFoundError) + return ok +} + +func parseSymbol(svcAndMethod string) (string, string) { + pos := strings.LastIndex(svcAndMethod, "/") + if pos < 0 { + pos = strings.LastIndex(svcAndMethod, ".") + if pos < 0 { + return "", "" + } + } + return svcAndMethod[:pos], svcAndMethod[pos+1:] +} diff --git a/vendor/github.com/fullstorydev/grpcurl/mk-test-files.sh b/vendor/github.com/fullstorydev/grpcurl/mk-test-files.sh new file mode 100644 index 0000000..51db6f4 --- /dev/null +++ b/vendor/github.com/fullstorydev/grpcurl/mk-test-files.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +set -e + +cd "$(dirname $0)" + +# Run this script to generate files used by tests. + +echo "Creating protosets..." +protoc testing/test.proto \ + --include_imports \ + --descriptor_set_out=testing/test.protoset + +protoc testing/example.proto \ + --include_imports \ + --descriptor_set_out=testing/example.protoset + +protoc testing/jsonpb_test_proto/test_objects.proto \ + --go_out=paths=source_relative:. + +echo "Creating certs for TLS testing..." +if ! hash certstrap 2>/dev/null; then + # certstrap not found: try to install it + go get github.com/square/certstrap + go install github.com/square/certstrap +fi + +function cs() { + certstrap --depot-path testing/tls "$@" --passphrase "" +} + +rm -rf testing/tls + +# Create CA +cs init --years 10 --common-name ca + +# Create client cert +cs request-cert --common-name client +cs sign client --years 10 --CA ca + +# Create server cert +cs request-cert --common-name server --ip 127.0.0.1 --domain localhost +cs sign server --years 10 --CA ca + +# Create another server cert for error testing +cs request-cert --common-name other --ip 1.2.3.4 --domain foobar.com +cs sign other --years 10 --CA ca + +# Create another CA and client cert for more +# error testing +cs init --years 10 --common-name wrong-ca +cs request-cert --common-name wrong-client +cs sign wrong-client --years 10 --CA wrong-ca + +# Create expired cert +cs request-cert --common-name expired --ip 127.0.0.1 --domain localhost +cs sign expired --years 0 --CA ca diff --git a/vendor/github.com/gin-contrib/sse/.travis.yml b/vendor/github.com/gin-contrib/sse/.travis.yml new file mode 100644 index 0000000..d0e8fcf --- /dev/null +++ b/vendor/github.com/gin-contrib/sse/.travis.yml @@ -0,0 +1,26 @@ +language: go +sudo: false +go: + - 1.8.x + - 1.9.x + - 1.10.x + - 1.11.x + - 1.12.x + - master + +git: + depth: 10 + +matrix: + fast_finish: true + include: + - go: 1.11.x + env: GO111MODULE=on + - go: 1.12.x + env: GO111MODULE=on + +script: + - go test -v -covermode=count -coverprofile=coverage.out + +after_success: + - bash <(curl -s https://codecov.io/bash) diff --git a/vendor/github.com/gin-contrib/sse/LICENSE b/vendor/github.com/gin-contrib/sse/LICENSE new file mode 100644 index 0000000..1ff7f37 --- /dev/null +++ b/vendor/github.com/gin-contrib/sse/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Manuel Martínez-Almeida + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/gin-contrib/sse/README.md b/vendor/github.com/gin-contrib/sse/README.md new file mode 100644 index 0000000..c9c49cf --- /dev/null +++ b/vendor/github.com/gin-contrib/sse/README.md @@ -0,0 +1,58 @@ +# Server-Sent Events + +[![GoDoc](https://godoc.org/github.com/gin-contrib/sse?status.svg)](https://godoc.org/github.com/gin-contrib/sse) +[![Build Status](https://travis-ci.org/gin-contrib/sse.svg)](https://travis-ci.org/gin-contrib/sse) +[![codecov](https://codecov.io/gh/gin-contrib/sse/branch/master/graph/badge.svg)](https://codecov.io/gh/gin-contrib/sse) +[![Go Report Card](https://goreportcard.com/badge/github.com/gin-contrib/sse)](https://goreportcard.com/report/github.com/gin-contrib/sse) + +Server-sent events (SSE) is a technology where a browser receives automatic updates from a server via HTTP connection. The Server-Sent Events EventSource API is [standardized as part of HTML5[1] by the W3C](http://www.w3.org/TR/2009/WD-eventsource-20091029/). + +- [Read this great SSE introduction by the HTML5Rocks guys](http://www.html5rocks.com/en/tutorials/eventsource/basics/) +- [Browser support](http://caniuse.com/#feat=eventsource) + +## Sample code + +```go +import "github.com/gin-contrib/sse" + +func httpHandler(w http.ResponseWriter, req *http.Request) { + // data can be a primitive like a string, an integer or a float + sse.Encode(w, sse.Event{ + Event: "message", + Data: "some data\nmore data", + }) + + // also a complex type, like a map, a struct or a slice + sse.Encode(w, sse.Event{ + Id: "124", + Event: "message", + Data: map[string]interface{}{ + "user": "manu", + "date": time.Now().Unix(), + "content": "hi!", + }, + }) +} +``` +``` +event: message +data: some data\\nmore data + +id: 124 +event: message +data: {"content":"hi!","date":1431540810,"user":"manu"} + +``` + +## Content-Type + +```go +fmt.Println(sse.ContentType) +``` +``` +text/event-stream +``` + +## Decoding support + +There is a client-side implementation of SSE coming soon. diff --git a/vendor/github.com/gin-contrib/sse/go.mod b/vendor/github.com/gin-contrib/sse/go.mod new file mode 100644 index 0000000..b9c03f4 --- /dev/null +++ b/vendor/github.com/gin-contrib/sse/go.mod @@ -0,0 +1,5 @@ +module github.com/gin-contrib/sse + +go 1.12 + +require github.com/stretchr/testify v1.3.0 diff --git a/vendor/github.com/gin-contrib/sse/go.sum b/vendor/github.com/gin-contrib/sse/go.sum new file mode 100644 index 0000000..4347755 --- /dev/null +++ b/vendor/github.com/gin-contrib/sse/go.sum @@ -0,0 +1,7 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= diff --git a/vendor/github.com/gin-contrib/sse/sse-decoder.go b/vendor/github.com/gin-contrib/sse/sse-decoder.go new file mode 100644 index 0000000..fd49b9c --- /dev/null +++ b/vendor/github.com/gin-contrib/sse/sse-decoder.go @@ -0,0 +1,116 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package sse + +import ( + "bytes" + "io" + "io/ioutil" +) + +type decoder struct { + events []Event +} + +func Decode(r io.Reader) ([]Event, error) { + var dec decoder + return dec.decode(r) +} + +func (d *decoder) dispatchEvent(event Event, data string) { + dataLength := len(data) + if dataLength > 0 { + //If the data buffer's last character is a U+000A LINE FEED (LF) character, then remove the last character from the data buffer. + data = data[:dataLength-1] + dataLength-- + } + if dataLength == 0 && event.Event == "" { + return + } + if event.Event == "" { + event.Event = "message" + } + event.Data = data + d.events = append(d.events, event) +} + +func (d *decoder) decode(r io.Reader) ([]Event, error) { + buf, err := ioutil.ReadAll(r) + if err != nil { + return nil, err + } + + var currentEvent Event + var dataBuffer *bytes.Buffer = new(bytes.Buffer) + // TODO (and unit tests) + // Lines must be separated by either a U+000D CARRIAGE RETURN U+000A LINE FEED (CRLF) character pair, + // a single U+000A LINE FEED (LF) character, + // or a single U+000D CARRIAGE RETURN (CR) character. + lines := bytes.Split(buf, []byte{'\n'}) + for _, line := range lines { + if len(line) == 0 { + // If the line is empty (a blank line). Dispatch the event. + d.dispatchEvent(currentEvent, dataBuffer.String()) + + // reset current event and data buffer + currentEvent = Event{} + dataBuffer.Reset() + continue + } + if line[0] == byte(':') { + // If the line starts with a U+003A COLON character (:), ignore the line. + continue + } + + var field, value []byte + colonIndex := bytes.IndexRune(line, ':') + if colonIndex != -1 { + // If the line contains a U+003A COLON character character (:) + // Collect the characters on the line before the first U+003A COLON character (:), + // and let field be that string. + field = line[:colonIndex] + // Collect the characters on the line after the first U+003A COLON character (:), + // and let value be that string. + value = line[colonIndex+1:] + // If value starts with a single U+0020 SPACE character, remove it from value. + if len(value) > 0 && value[0] == ' ' { + value = value[1:] + } + } else { + // Otherwise, the string is not empty but does not contain a U+003A COLON character character (:) + // Use the whole line as the field name, and the empty string as the field value. + field = line + value = []byte{} + } + // The steps to process the field given a field name and a field value depend on the field name, + // as given in the following list. Field names must be compared literally, + // with no case folding performed. + switch string(field) { + case "event": + // Set the event name buffer to field value. + currentEvent.Event = string(value) + case "id": + // Set the event stream's last event ID to the field value. + currentEvent.Id = string(value) + case "retry": + // If the field value consists of only characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), + // then interpret the field value as an integer in base ten, and set the event stream's reconnection time to that integer. + // Otherwise, ignore the field. + currentEvent.Id = string(value) + case "data": + // Append the field value to the data buffer, + dataBuffer.Write(value) + // then append a single U+000A LINE FEED (LF) character to the data buffer. + dataBuffer.WriteString("\n") + default: + //Otherwise. The field is ignored. + continue + } + } + // Once the end of the file is reached, the user agent must dispatch the event one final time. + d.dispatchEvent(currentEvent, dataBuffer.String()) + + return d.events, nil +} diff --git a/vendor/github.com/gin-contrib/sse/sse-encoder.go b/vendor/github.com/gin-contrib/sse/sse-encoder.go new file mode 100644 index 0000000..f9c8087 --- /dev/null +++ b/vendor/github.com/gin-contrib/sse/sse-encoder.go @@ -0,0 +1,110 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package sse + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + "reflect" + "strconv" + "strings" +) + +// Server-Sent Events +// W3C Working Draft 29 October 2009 +// http://www.w3.org/TR/2009/WD-eventsource-20091029/ + +const ContentType = "text/event-stream" + +var contentType = []string{ContentType} +var noCache = []string{"no-cache"} + +var fieldReplacer = strings.NewReplacer( + "\n", "\\n", + "\r", "\\r") + +var dataReplacer = strings.NewReplacer( + "\n", "\ndata:", + "\r", "\\r") + +type Event struct { + Event string + Id string + Retry uint + Data interface{} +} + +func Encode(writer io.Writer, event Event) error { + w := checkWriter(writer) + writeId(w, event.Id) + writeEvent(w, event.Event) + writeRetry(w, event.Retry) + return writeData(w, event.Data) +} + +func writeId(w stringWriter, id string) { + if len(id) > 0 { + w.WriteString("id:") + fieldReplacer.WriteString(w, id) + w.WriteString("\n") + } +} + +func writeEvent(w stringWriter, event string) { + if len(event) > 0 { + w.WriteString("event:") + fieldReplacer.WriteString(w, event) + w.WriteString("\n") + } +} + +func writeRetry(w stringWriter, retry uint) { + if retry > 0 { + w.WriteString("retry:") + w.WriteString(strconv.FormatUint(uint64(retry), 10)) + w.WriteString("\n") + } +} + +func writeData(w stringWriter, data interface{}) error { + w.WriteString("data:") + switch kindOfData(data) { + case reflect.Struct, reflect.Slice, reflect.Map: + err := json.NewEncoder(w).Encode(data) + if err != nil { + return err + } + w.WriteString("\n") + default: + dataReplacer.WriteString(w, fmt.Sprint(data)) + w.WriteString("\n\n") + } + return nil +} + +func (r Event) Render(w http.ResponseWriter) error { + r.WriteContentType(w) + return Encode(w, r) +} + +func (r Event) WriteContentType(w http.ResponseWriter) { + header := w.Header() + header["Content-Type"] = contentType + + if _, exist := header["Cache-Control"]; !exist { + header["Cache-Control"] = noCache + } +} + +func kindOfData(data interface{}) reflect.Kind { + value := reflect.ValueOf(data) + valueType := value.Kind() + if valueType == reflect.Ptr { + valueType = value.Elem().Kind() + } + return valueType +} diff --git a/vendor/github.com/gin-contrib/sse/writer.go b/vendor/github.com/gin-contrib/sse/writer.go new file mode 100644 index 0000000..6f9806c --- /dev/null +++ b/vendor/github.com/gin-contrib/sse/writer.go @@ -0,0 +1,24 @@ +package sse + +import "io" + +type stringWriter interface { + io.Writer + WriteString(string) (int, error) +} + +type stringWrapper struct { + io.Writer +} + +func (w stringWrapper) WriteString(str string) (int, error) { + return w.Writer.Write([]byte(str)) +} + +func checkWriter(writer io.Writer) stringWriter { + if w, ok := writer.(stringWriter); ok { + return w + } else { + return stringWrapper{writer} + } +} diff --git a/vendor/github.com/gin-gonic/gin/.gitignore b/vendor/github.com/gin-gonic/gin/.gitignore new file mode 100644 index 0000000..bdd50c9 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/.gitignore @@ -0,0 +1,7 @@ +vendor/* +!vendor/vendor.json +coverage.out +count.out +test +profile.out +tmp.out diff --git a/vendor/github.com/gin-gonic/gin/.golangci.yml b/vendor/github.com/gin-gonic/gin/.golangci.yml new file mode 100644 index 0000000..c5e1de3 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/.golangci.yml @@ -0,0 +1,39 @@ +run: + timeout: 5m +linters: + enable: + - asciicheck + - depguard + - dogsled + - durationcheck + - errcheck + - errorlint + - exportloopref + - gci + - gofmt + - goimports + - gosec + - misspell + - nakedret + - nilerr + - nolintlint + - revive + - wastedassign +issues: + exclude-rules: + - linters: + - structcheck + - unused + text: "`data` is unused" + - linters: + - staticcheck + text: "SA1019:" + - linters: + - revive + text: "var-naming:" + - linters: + - revive + text: "exported:" + - path: _test\.go + linters: + - gosec # security is not make sense in tests diff --git a/vendor/github.com/gin-gonic/gin/.goreleaser.yaml b/vendor/github.com/gin-gonic/gin/.goreleaser.yaml new file mode 100644 index 0000000..e435e56 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/.goreleaser.yaml @@ -0,0 +1,57 @@ +project_name: gin + +builds: + - + # If true, skip the build. + # Useful for library projects. + # Default is false + skip: true + +changelog: + # Set it to true if you wish to skip the changelog generation. + # This may result in an empty release notes on GitHub/GitLab/Gitea. + skip: false + + # Changelog generation implementation to use. + # + # Valid options are: + # - `git`: uses `git log`; + # - `github`: uses the compare GitHub API, appending the author login to the changelog. + # - `gitlab`: uses the compare GitLab API, appending the author name and email to the changelog. + # - `github-native`: uses the GitHub release notes generation API, disables the groups feature. + # + # Defaults to `git`. + use: git + + # Sorts the changelog by the commit's messages. + # Could either be asc, desc or empty + # Default is empty + sort: asc + + # Group commits messages by given regex and title. + # Order value defines the order of the groups. + # Proving no regex means all commits will be grouped under the default group. + # Groups are disabled when using github-native, as it already groups things by itself. + # + # Default is no groups. + groups: + - title: Features + regexp: "^.*feat[(\\w)]*:+.*$" + order: 0 + - title: 'Bug fixes' + regexp: "^.*fix[(\\w)]*:+.*$" + order: 1 + - title: 'Enhancements' + regexp: "^.*chore[(\\w)]*:+.*$" + order: 2 + - title: Others + order: 999 + + filters: + # Commit messages matching the regexp listed here will be removed from + # the changelog + # Default is empty + exclude: + - '^docs' + - 'CICD' + - typo diff --git a/vendor/github.com/gin-gonic/gin/AUTHORS.md b/vendor/github.com/gin-gonic/gin/AUTHORS.md new file mode 100644 index 0000000..b4773ef --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/AUTHORS.md @@ -0,0 +1,406 @@ +List of all the awesome people working to make Gin the best Web Framework in Go. + +## gin 1.x series authors + +**Gin Core Team:** Bo-Yi Wu (@appleboy), thinkerou (@thinkerou), Javier Provecho (@javierprovecho) + +## gin 0.x series authors + +**Maintainers:** Manu Martinez-Almeida (@manucorporat), Javier Provecho (@javierprovecho) + +------ + +People and companies, who have contributed, in alphabetical order. + +- 178inaba <178inaba@users.noreply.github.com> +- A. F +- ABHISHEK SONI +- Abhishek Chanda +- Abner Chen +- AcoNCodes +- Adam Dratwinski +- Adam Mckaig +- Adam Zielinski +- Adonis +- Alan Wang +- Albin Gilles +- Aleksandr Didenko +- Alessandro (Ale) Segala <43508+ItalyPaleAle@users.noreply.github.com> +- Alex +- Alexander +- Alexander Lokhman +- Alexander Melentyev <55826637+alexander-melentyev@users.noreply.github.com> +- Alexander Nyquist +- Allen Ren +- AllinGo +- Ammar Bandukwala +- An Xiao (Luffy) +- Andre Dublin <81dublin@gmail.com> +- Andrew Szeto +- Andrey Abramov +- Andrey Nering +- Andrey Smirnov +- Andrii Bubis +- André Bazaglia +- Andy Pan +- Antoine GIRARD +- Anup Kumar Panwar <1anuppanwar@gmail.com> +- Aravinth Sundaram +- Artem +- Ashwani +- Aurelien Regat-Barrel +- Austin Heap +- Barnabus +- Bo-Yi Wu +- Boris Borshevsky +- Boyi Wu +- BradyBromley <51128276+BradyBromley@users.noreply.github.com> +- Brendan Fosberry +- Brian Wigginton +- Carlos Eduardo +- Chad Russell +- Charles +- Christian Muehlhaeuser +- Christian Persson +- Christopher Harrington +- Damon Zhao +- Dan Markham +- Dang Nguyen +- Daniel Krom +- Daniel M. Lambea +- Danieliu +- David Irvine +- David Zhang +- Davor Kapsa +- DeathKing +- Dennis Cho <47404603+forest747@users.noreply.github.com> +- Dmitry Dorogin +- Dmitry Kutakov +- Dmitry Sedykh +- Don2Quixote <35610661+Don2Quixote@users.noreply.github.com> +- Donn Pebe +- Dustin Decker +- Eason Lin +- Edward Betts +- Egor Seredin <4819888+agmt@users.noreply.github.com> +- Emmanuel Goh +- Equim +- Eren A. Akyol +- Eric_Lee +- Erik Bender +- Ethan Kan +- Evgeny Persienko +- Faisal Alam +- Fareed Dudhia +- Filip Figiel +- Florian Polster +- Frank Bille +- Franz Bettag +- Ganlv +- Gaozhen Ying +- George Gabolaev +- George Kirilenko +- Georges Varouchas +- Gordon Tyler +- Harindu Perera +- Helios <674876158@qq.com> +- Henry Kwan +- Henry Yee +- Himanshu Mishra +- Hiroyuki Tanaka +- Ibraheem Ahmed +- Ignacio Galindo +- Igor H. Vieira +- Ildar1111 <54001462+Ildar1111@users.noreply.github.com> +- Iskander (Alex) Sharipov +- Ismail Gjevori +- Ivan Chen +- JINNOUCHI Yasushi +- James Pettyjohn +- Jamie Stackhouse +- Jason Lee +- Javier Provecho +- Javier Provecho +- Javier Provecho +- Javier Provecho Fernandez +- Javier Provecho Fernandez +- Jean-Christophe Lebreton +- Jeff +- Jeremy Loy +- Jim Filippou +- Jimmy Pettersson +- John Bampton +- Johnny Dallas +- Johnny Dallas +- Jonathan (JC) Chen +- Josep Jesus Bigorra Algaba <42377845+averageflow@users.noreply.github.com> +- Josh Horowitz +- Joshua Loper +- Julien Schmidt +- Jun Kimura +- Justin Beckwith +- Justin Israel +- Justin Mayhew +- Jérôme Laforge +- Kacper Bąk <56700396+53jk1@users.noreply.github.com> +- Kamron Batman +- Kane Rogers +- Kaushik Neelichetty +- Keiji Yoshida +- Kel Cecil +- Kevin Mulvey +- Kevin Zhu +- Kirill Motkov +- Klemen Sever +- Kristoffer A. Iversen +- Krzysztof Szafrański +- Kumar McMillan +- Kyle Mcgill +- Lanco <35420416+lancoLiu@users.noreply.github.com> +- Levi Olson +- Lin Kao-Yuan +- Linus Unnebäck +- Lucas Clemente +- Ludwig Valda Vasquez +- Luis GG +- MW Lim +- Maksimov Sergey +- Manjusaka +- Manu MA +- Manu MA +- Manu Mtz-Almeida +- Manu Mtz.-Almeida +- Manuel Alonso +- Mara Kim +- Mario Kostelac +- Martin Karlsch +- Matt Newberry +- Matt Williams +- Matthieu MOREL +- Max Hilbrunner +- Maxime Soulé +- MetalBreaker +- Michael Puncel +- MichaelDeSteven <51652084+MichaelDeSteven@users.noreply.github.com> +- Mike <38686456+icy4ever@users.noreply.github.com> +- Mike Stipicevic +- Miki Tebeka +- Miles +- Mirza Ceric +- Mykyta Semenistyi +- Naoki Takano +- Ngalim Siregar +- Ni Hao +- Nick Gerakines +- Nikifor Seryakov +- Notealot <714804968@qq.com> +- Olivier Mengué +- Olivier Robardet +- Pablo Moncada +- Pablo Moncada +- Panmax <967168@qq.com> +- Peperoncino <2wua4nlyi@gmail.com> +- Philipp Meinen +- Pierre Massat +- Qt +- Quentin ROYER +- README Bot <35302948+codetriage-readme-bot@users.noreply.github.com> +- Rafal Zajac +- Rahul Datta Roy +- Rajiv Kilaparti +- Raphael Gavache +- Ray Rodriguez +- Regner Blok-Andersen +- Remco +- Rex Lee(李俊) +- Richard Lee +- Riverside +- Robert Wilkinson +- Rogier Lommers +- Rohan Pai +- Romain Beuque +- Roman Belyakovsky +- Roman Zaynetdinov <627197+zaynetro@users.noreply.github.com> +- Roman Zaynetdinov +- Ronald Petty +- Ross Wolf <31489089+rw-access@users.noreply.github.com> +- Roy Lou +- Rubi <14269809+codenoid@users.noreply.github.com> +- Ryan <46182144+ryanker@users.noreply.github.com> +- Ryan J. Yoder +- SRK.Lyu +- Sai +- Samuel Abreu +- Santhosh Kumar +- Sasha Melentyev +- Sasha Myasoedov +- Segev Finer +- Sergey Egorov +- Sergey Fedchenko +- Sergey Gonimar +- Sergey Ponomarev +- Serica <943914044@qq.com> +- Shamus Taylor +- Shilin Wang +- Shuo +- Skuli Oskarsson +- Snawoot +- Sridhar Ratnakumar +- Steeve Chailloux +- Sudhir Mishra +- Suhas Karanth +- TaeJun Park +- Tatsuya Hoshino +- Tevic +- Tevin Jeffrey +- The Gitter Badger +- Thibault Jamet +- Thomas Boerger +- Thomas Schaffer +- Tommy Chu +- Tudor Roman +- Uwe Dauernheim +- Valentine Oragbakosi +- Vas N +- Vasilyuk Vasiliy +- Victor Castell +- Vince Yuan +- Vyacheslav Dubinin +- Waynerv +- Weilin Shi <934587911@qq.com> +- Xudong Cai +- Yasuhiro Matsumoto +- Yehezkiel Syamsuhadi +- Yoshiki Nakagawa +- Yoshiyuki Kinjo +- Yue Yang +- ZYunH +- Zach Newburgh +- Zasda Yusuf Mikail +- ZhangYunHao +- ZhiFeng Hu +- Zhu Xi +- a2tt +- ahuigo <1781999+ahuigo@users.noreply.github.com> +- ali +- aljun +- andrea +- andriikushch +- anoty +- awkj +- axiaoxin <254606826@qq.com> +- bbiao +- bestgopher <84328409@qq.com> +- betahu +- bigwheel +- bn4t <17193640+bn4t@users.noreply.github.com> +- bullgare +- chainhelen +- chenyang929 +- chriswhelix +- collinmsn <4130944@qq.com> +- cssivision +- danielalves +- delphinus +- dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +- dickeyxxx +- edebernis +- error10 +- esplo +- eudore <30709860+eudore@users.noreply.github.com> +- ffhelicopter <32922889+ffhelicopter@users.noreply.github.com> +- filikos <11477309+filikos@users.noreply.github.com> +- forging2012 +- goqihoo +- grapeVine +- guonaihong +- heige +- heige +- hellojukay +- henrylee2cn +- htobenothing +- iamhesir <78344375+iamhesir@users.noreply.github.com> +- ijaa +- ishanray +- ishanray +- itcloudy <272685110@qq.com> +- jarodsong6 +- jasonrhansen +- jincheng9 +- joeADSP <75027008+joeADSP@users.noreply.github.com> +- junfengye +- kaiiak +- kebo +- keke <19yamashita15@gmail.com> +- kishor kunal raj <68464660+kishorkunal-raj@users.noreply.github.com> +- kyledinh +- lantw44 +- likakuli <1154584512@qq.com> +- linfangrong +- linzi <873804682@qq.com> +- llgoer +- long-road <13412081338@163.com> +- mbesancon +- mehdy +- metal A-wing +- micanzhang +- minarc +- mllu +- mopemoepe +- msoedov +- mstmdev +- novaeye +- olebedev +- phithon +- pjgg +- qm012 <67568757+qm012@users.noreply.github.com> +- raymonder jin +- rns +- root@andrea:~# +- sekky0905 <20237968+sekky0905@users.noreply.github.com> +- senhtry +- shadrus +- silasb +- solos +- songjiayang +- sope +- srt180 <30768686+srt180@users.noreply.github.com> +- stackerzzq +- sunshineplan +- syssam +- techjanitor +- techjanitor +- thinkerou +- thinkgo <49174849+thinkgos@users.noreply.github.com> +- tsirolnik +- tyltr <31768692+tylitianrui@users.noreply.github.com> +- vinhha96 +- voidman +- vz +- wei +- weibaohui +- whirosan +- willnewrelic +- wssccc +- wuhuizuo +- xyb +- y-yagi +- yiranzai +- youzeliang +- yugu +- yuyabe +- zebozhuang +- zero11-0203 <93071220+zero11-0203@users.noreply.github.com> +- zesani <7sin@outlook.co.th> +- zhanweidu +- zhing +- ziheng +- zzjin +- 森 優太 <59682979+uta-mori@users.noreply.github.com> +- 杰哥 <858806258@qq.com> +- 涛叔 +- 市民233 +- 尹宝强 +- 梦溪笔谈 +- 飞雪无情 +- 寻寻觅觅的Gopher diff --git a/vendor/github.com/gin-gonic/gin/BENCHMARKS.md b/vendor/github.com/gin-gonic/gin/BENCHMARKS.md new file mode 100644 index 0000000..c11ee99 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/BENCHMARKS.md @@ -0,0 +1,666 @@ + +# Benchmark System + +**VM HOST:** Travis +**Machine:** Ubuntu 16.04.6 LTS x64 +**Date:** May 04th, 2020 +**Version:** Gin v1.6.3 +**Go Version:** 1.14.2 linux/amd64 +**Source:** [Go HTTP Router Benchmark](https://github.com/gin-gonic/go-http-routing-benchmark) +**Result:** [See the gist](https://gist.github.com/appleboy/b5f2ecfaf50824ae9c64dcfb9165ae5e) or [Travis result](https://travis-ci.org/github/gin-gonic/go-http-routing-benchmark/jobs/682947061) + +## Static Routes: 157 + +```sh +Gin: 34936 Bytes + +HttpServeMux: 14512 Bytes +Ace: 30680 Bytes +Aero: 34536 Bytes +Bear: 30456 Bytes +Beego: 98456 Bytes +Bone: 40224 Bytes +Chi: 83608 Bytes +Denco: 10216 Bytes +Echo: 80328 Bytes +GocraftWeb: 55288 Bytes +Goji: 29744 Bytes +Gojiv2: 105840 Bytes +GoJsonRest: 137496 Bytes +GoRestful: 816936 Bytes +GorillaMux: 585632 Bytes +GowwwRouter: 24968 Bytes +HttpRouter: 21712 Bytes +HttpTreeMux: 73448 Bytes +Kocha: 115472 Bytes +LARS: 30640 Bytes +Macaron: 38592 Bytes +Martini: 310864 Bytes +Pat: 19696 Bytes +Possum: 89920 Bytes +R2router: 23712 Bytes +Rivet: 24608 Bytes +Tango: 28264 Bytes +TigerTonic: 78768 Bytes +Traffic: 538976 Bytes +Vulcan: 369960 Bytes +``` + +## GithubAPI Routes: 203 + +```sh +Gin: 58512 Bytes + +Ace: 48688 Bytes +Aero: 318568 Bytes +Bear: 84248 Bytes +Beego: 150936 Bytes +Bone: 100976 Bytes +Chi: 95112 Bytes +Denco: 36736 Bytes +Echo: 100296 Bytes +GocraftWeb: 95432 Bytes +Goji: 49680 Bytes +Gojiv2: 104704 Bytes +GoJsonRest: 141976 Bytes +GoRestful: 1241656 Bytes +GorillaMux: 1322784 Bytes +GowwwRouter: 80008 Bytes +HttpRouter: 37144 Bytes +HttpTreeMux: 78800 Bytes +Kocha: 785120 Bytes +LARS: 48600 Bytes +Macaron: 92784 Bytes +Martini: 485264 Bytes +Pat: 21200 Bytes +Possum: 85312 Bytes +R2router: 47104 Bytes +Rivet: 42840 Bytes +Tango: 54840 Bytes +TigerTonic: 95264 Bytes +Traffic: 921744 Bytes +Vulcan: 425992 Bytes +``` + +## GPlusAPI Routes: 13 + +```sh +Gin: 4384 Bytes + +Ace: 3712 Bytes +Aero: 26056 Bytes +Bear: 7112 Bytes +Beego: 10272 Bytes +Bone: 6688 Bytes +Chi: 8024 Bytes +Denco: 3264 Bytes +Echo: 9688 Bytes +GocraftWeb: 7496 Bytes +Goji: 3152 Bytes +Gojiv2: 7376 Bytes +GoJsonRest: 11400 Bytes +GoRestful: 74328 Bytes +GorillaMux: 66208 Bytes +GowwwRouter: 5744 Bytes +HttpRouter: 2808 Bytes +HttpTreeMux: 7440 Bytes +Kocha: 128880 Bytes +LARS: 3656 Bytes +Macaron: 8656 Bytes +Martini: 23920 Bytes +Pat: 1856 Bytes +Possum: 7248 Bytes +R2router: 3928 Bytes +Rivet: 3064 Bytes +Tango: 5168 Bytes +TigerTonic: 9408 Bytes +Traffic: 46400 Bytes +Vulcan: 25544 Bytes +``` + +## ParseAPI Routes: 26 + +```sh +Gin: 7776 Bytes + +Ace: 6704 Bytes +Aero: 28488 Bytes +Bear: 12320 Bytes +Beego: 19280 Bytes +Bone: 11440 Bytes +Chi: 9744 Bytes +Denco: 4192 Bytes +Echo: 11664 Bytes +GocraftWeb: 12800 Bytes +Goji: 5680 Bytes +Gojiv2: 14464 Bytes +GoJsonRest: 14072 Bytes +GoRestful: 116264 Bytes +GorillaMux: 105880 Bytes +GowwwRouter: 9344 Bytes +HttpRouter: 5072 Bytes +HttpTreeMux: 7848 Bytes +Kocha: 181712 Bytes +LARS: 6632 Bytes +Macaron: 13648 Bytes +Martini: 45888 Bytes +Pat: 2560 Bytes +Possum: 9200 Bytes +R2router: 7056 Bytes +Rivet: 5680 Bytes +Tango: 8920 Bytes +TigerTonic: 9840 Bytes +Traffic: 79096 Bytes +Vulcan: 44504 Bytes +``` + +## Static Routes + +```sh +BenchmarkGin_StaticAll 62169 19319 ns/op 0 B/op 0 allocs/op + +BenchmarkAce_StaticAll 65428 18313 ns/op 0 B/op 0 allocs/op +BenchmarkAero_StaticAll 121132 9632 ns/op 0 B/op 0 allocs/op +BenchmarkHttpServeMux_StaticAll 52626 22758 ns/op 0 B/op 0 allocs/op +BenchmarkBeego_StaticAll 9962 179058 ns/op 55264 B/op 471 allocs/op +BenchmarkBear_StaticAll 14894 80966 ns/op 20272 B/op 469 allocs/op +BenchmarkBone_StaticAll 18718 64065 ns/op 0 B/op 0 allocs/op +BenchmarkChi_StaticAll 10000 149827 ns/op 67824 B/op 471 allocs/op +BenchmarkDenco_StaticAll 211393 5680 ns/op 0 B/op 0 allocs/op +BenchmarkEcho_StaticAll 49341 24343 ns/op 0 B/op 0 allocs/op +BenchmarkGocraftWeb_StaticAll 10000 126209 ns/op 46312 B/op 785 allocs/op +BenchmarkGoji_StaticAll 27956 43174 ns/op 0 B/op 0 allocs/op +BenchmarkGojiv2_StaticAll 3430 370718 ns/op 205984 B/op 1570 allocs/op +BenchmarkGoJsonRest_StaticAll 9134 188888 ns/op 51653 B/op 1727 allocs/op +BenchmarkGoRestful_StaticAll 706 1703330 ns/op 613280 B/op 2053 allocs/op +BenchmarkGorillaMux_StaticAll 1268 924083 ns/op 153233 B/op 1413 allocs/op +BenchmarkGowwwRouter_StaticAll 63374 18935 ns/op 0 B/op 0 allocs/op +BenchmarkHttpRouter_StaticAll 109938 10902 ns/op 0 B/op 0 allocs/op +BenchmarkHttpTreeMux_StaticAll 109166 10861 ns/op 0 B/op 0 allocs/op +BenchmarkKocha_StaticAll 92258 12992 ns/op 0 B/op 0 allocs/op +BenchmarkLARS_StaticAll 65200 18387 ns/op 0 B/op 0 allocs/op +BenchmarkMacaron_StaticAll 5671 291501 ns/op 115553 B/op 1256 allocs/op +BenchmarkMartini_StaticAll 807 1460498 ns/op 125444 B/op 1717 allocs/op +BenchmarkPat_StaticAll 513 2342396 ns/op 602832 B/op 12559 allocs/op +BenchmarkPossum_StaticAll 10000 128270 ns/op 65312 B/op 471 allocs/op +BenchmarkR2router_StaticAll 16726 71760 ns/op 22608 B/op 628 allocs/op +BenchmarkRivet_StaticAll 41722 28723 ns/op 0 B/op 0 allocs/op +BenchmarkTango_StaticAll 7606 205082 ns/op 39209 B/op 1256 allocs/op +BenchmarkTigerTonic_StaticAll 26247 45806 ns/op 7376 B/op 157 allocs/op +BenchmarkTraffic_StaticAll 550 2284518 ns/op 754864 B/op 14601 allocs/op +BenchmarkVulcan_StaticAll 10000 131343 ns/op 15386 B/op 471 allocs/op +``` + +## Micro Benchmarks + +```sh +BenchmarkGin_Param 18785022 63.9 ns/op 0 B/op 0 allocs/op + +BenchmarkAce_Param 14689765 81.5 ns/op 0 B/op 0 allocs/op +BenchmarkAero_Param 23094770 51.2 ns/op 0 B/op 0 allocs/op +BenchmarkBear_Param 1417045 845 ns/op 456 B/op 5 allocs/op +BenchmarkBeego_Param 1000000 1080 ns/op 352 B/op 3 allocs/op +BenchmarkBone_Param 1000000 1463 ns/op 816 B/op 6 allocs/op +BenchmarkChi_Param 1378756 885 ns/op 432 B/op 3 allocs/op +BenchmarkDenco_Param 8557899 143 ns/op 32 B/op 1 allocs/op +BenchmarkEcho_Param 16433347 75.5 ns/op 0 B/op 0 allocs/op +BenchmarkGocraftWeb_Param 1000000 1218 ns/op 648 B/op 8 allocs/op +BenchmarkGoji_Param 1921248 617 ns/op 336 B/op 2 allocs/op +BenchmarkGojiv2_Param 561848 2156 ns/op 1328 B/op 11 allocs/op +BenchmarkGoJsonRest_Param 1000000 1358 ns/op 649 B/op 13 allocs/op +BenchmarkGoRestful_Param 224857 5307 ns/op 4192 B/op 14 allocs/op +BenchmarkGorillaMux_Param 498313 2459 ns/op 1280 B/op 10 allocs/op +BenchmarkGowwwRouter_Param 1864354 654 ns/op 432 B/op 3 allocs/op +BenchmarkHttpRouter_Param 26269074 47.7 ns/op 0 B/op 0 allocs/op +BenchmarkHttpTreeMux_Param 2109829 557 ns/op 352 B/op 3 allocs/op +BenchmarkKocha_Param 5050216 243 ns/op 56 B/op 3 allocs/op +BenchmarkLARS_Param 19811712 59.9 ns/op 0 B/op 0 allocs/op +BenchmarkMacaron_Param 662746 2329 ns/op 1072 B/op 10 allocs/op +BenchmarkMartini_Param 279902 4260 ns/op 1072 B/op 10 allocs/op +BenchmarkPat_Param 1000000 1382 ns/op 536 B/op 11 allocs/op +BenchmarkPossum_Param 1000000 1014 ns/op 496 B/op 5 allocs/op +BenchmarkR2router_Param 1712559 707 ns/op 432 B/op 5 allocs/op +BenchmarkRivet_Param 6648086 182 ns/op 48 B/op 1 allocs/op +BenchmarkTango_Param 1221504 994 ns/op 248 B/op 8 allocs/op +BenchmarkTigerTonic_Param 891661 2261 ns/op 776 B/op 16 allocs/op +BenchmarkTraffic_Param 350059 3598 ns/op 1856 B/op 21 allocs/op +BenchmarkVulcan_Param 2517823 472 ns/op 98 B/op 3 allocs/op +BenchmarkAce_Param5 9214365 130 ns/op 0 B/op 0 allocs/op +BenchmarkAero_Param5 15369013 77.9 ns/op 0 B/op 0 allocs/op +BenchmarkBear_Param5 1000000 1113 ns/op 501 B/op 5 allocs/op +BenchmarkBeego_Param5 1000000 1269 ns/op 352 B/op 3 allocs/op +BenchmarkBone_Param5 986820 1873 ns/op 864 B/op 6 allocs/op +BenchmarkChi_Param5 1000000 1156 ns/op 432 B/op 3 allocs/op +BenchmarkDenco_Param5 3036331 400 ns/op 160 B/op 1 allocs/op +BenchmarkEcho_Param5 6447133 186 ns/op 0 B/op 0 allocs/op +BenchmarkGin_Param5 10786068 110 ns/op 0 B/op 0 allocs/op +BenchmarkGocraftWeb_Param5 844820 1944 ns/op 920 B/op 11 allocs/op +BenchmarkGoji_Param5 1474965 827 ns/op 336 B/op 2 allocs/op +BenchmarkGojiv2_Param5 442820 2516 ns/op 1392 B/op 11 allocs/op +BenchmarkGoJsonRest_Param5 507555 2711 ns/op 1097 B/op 16 allocs/op +BenchmarkGoRestful_Param5 216481 6093 ns/op 4288 B/op 14 allocs/op +BenchmarkGorillaMux_Param5 314402 3628 ns/op 1344 B/op 10 allocs/op +BenchmarkGowwwRouter_Param5 1624660 733 ns/op 432 B/op 3 allocs/op +BenchmarkHttpRouter_Param5 13167324 92.0 ns/op 0 B/op 0 allocs/op +BenchmarkHttpTreeMux_Param5 1000000 1295 ns/op 576 B/op 6 allocs/op +BenchmarkKocha_Param5 1000000 1138 ns/op 440 B/op 10 allocs/op +BenchmarkLARS_Param5 11580613 105 ns/op 0 B/op 0 allocs/op +BenchmarkMacaron_Param5 473596 2755 ns/op 1072 B/op 10 allocs/op +BenchmarkMartini_Param5 230756 5111 ns/op 1232 B/op 11 allocs/op +BenchmarkPat_Param5 469190 3370 ns/op 888 B/op 29 allocs/op +BenchmarkPossum_Param5 1000000 1002 ns/op 496 B/op 5 allocs/op +BenchmarkR2router_Param5 1422129 844 ns/op 432 B/op 5 allocs/op +BenchmarkRivet_Param5 2263789 539 ns/op 240 B/op 1 allocs/op +BenchmarkTango_Param5 1000000 1256 ns/op 360 B/op 8 allocs/op +BenchmarkTigerTonic_Param5 175500 7492 ns/op 2279 B/op 39 allocs/op +BenchmarkTraffic_Param5 233631 5816 ns/op 2208 B/op 27 allocs/op +BenchmarkVulcan_Param5 1923416 629 ns/op 98 B/op 3 allocs/op +BenchmarkAce_Param20 4321266 281 ns/op 0 B/op 0 allocs/op +BenchmarkAero_Param20 31501641 35.2 ns/op 0 B/op 0 allocs/op +BenchmarkBear_Param20 335204 3489 ns/op 1665 B/op 5 allocs/op +BenchmarkBeego_Param20 503674 2860 ns/op 352 B/op 3 allocs/op +BenchmarkBone_Param20 298922 4741 ns/op 2031 B/op 6 allocs/op +BenchmarkChi_Param20 878181 1957 ns/op 432 B/op 3 allocs/op +BenchmarkDenco_Param20 1000000 1360 ns/op 640 B/op 1 allocs/op +BenchmarkEcho_Param20 2104946 580 ns/op 0 B/op 0 allocs/op +BenchmarkGin_Param20 4167204 290 ns/op 0 B/op 0 allocs/op +BenchmarkGocraftWeb_Param20 173064 7514 ns/op 3796 B/op 15 allocs/op +BenchmarkGoji_Param20 458778 2651 ns/op 1247 B/op 2 allocs/op +BenchmarkGojiv2_Param20 364862 3178 ns/op 1632 B/op 11 allocs/op +BenchmarkGoJsonRest_Param20 125514 9760 ns/op 4485 B/op 20 allocs/op +BenchmarkGoRestful_Param20 101217 11964 ns/op 6715 B/op 18 allocs/op +BenchmarkGorillaMux_Param20 147654 8132 ns/op 3452 B/op 12 allocs/op +BenchmarkGowwwRouter_Param20 1000000 1225 ns/op 432 B/op 3 allocs/op +BenchmarkHttpRouter_Param20 4920895 247 ns/op 0 B/op 0 allocs/op +BenchmarkHttpTreeMux_Param20 173202 6605 ns/op 3196 B/op 10 allocs/op +BenchmarkKocha_Param20 345988 3620 ns/op 1808 B/op 27 allocs/op +BenchmarkLARS_Param20 4592326 262 ns/op 0 B/op 0 allocs/op +BenchmarkMacaron_Param20 166492 7286 ns/op 2924 B/op 12 allocs/op +BenchmarkMartini_Param20 122162 10653 ns/op 3595 B/op 13 allocs/op +BenchmarkPat_Param20 78630 15239 ns/op 4424 B/op 93 allocs/op +BenchmarkPossum_Param20 1000000 1008 ns/op 496 B/op 5 allocs/op +BenchmarkR2router_Param20 294981 4587 ns/op 2284 B/op 7 allocs/op +BenchmarkRivet_Param20 691798 2090 ns/op 1024 B/op 1 allocs/op +BenchmarkTango_Param20 842440 2505 ns/op 856 B/op 8 allocs/op +BenchmarkTigerTonic_Param20 38614 31509 ns/op 9870 B/op 119 allocs/op +BenchmarkTraffic_Param20 57633 21107 ns/op 7853 B/op 47 allocs/op +BenchmarkVulcan_Param20 1000000 1178 ns/op 98 B/op 3 allocs/op +BenchmarkAce_ParamWrite 7330743 180 ns/op 8 B/op 1 allocs/op +BenchmarkAero_ParamWrite 13833598 86.7 ns/op 0 B/op 0 allocs/op +BenchmarkBear_ParamWrite 1363321 867 ns/op 456 B/op 5 allocs/op +BenchmarkBeego_ParamWrite 1000000 1104 ns/op 360 B/op 4 allocs/op +BenchmarkBone_ParamWrite 1000000 1475 ns/op 816 B/op 6 allocs/op +BenchmarkChi_ParamWrite 1320590 892 ns/op 432 B/op 3 allocs/op +BenchmarkDenco_ParamWrite 7093605 172 ns/op 32 B/op 1 allocs/op +BenchmarkEcho_ParamWrite 8434424 161 ns/op 8 B/op 1 allocs/op +BenchmarkGin_ParamWrite 10377034 118 ns/op 0 B/op 0 allocs/op +BenchmarkGocraftWeb_ParamWrite 1000000 1266 ns/op 656 B/op 9 allocs/op +BenchmarkGoji_ParamWrite 1874168 654 ns/op 336 B/op 2 allocs/op +BenchmarkGojiv2_ParamWrite 459032 2352 ns/op 1360 B/op 13 allocs/op +BenchmarkGoJsonRest_ParamWrite 499434 2145 ns/op 1128 B/op 18 allocs/op +BenchmarkGoRestful_ParamWrite 241087 5470 ns/op 4200 B/op 15 allocs/op +BenchmarkGorillaMux_ParamWrite 425686 2522 ns/op 1280 B/op 10 allocs/op +BenchmarkGowwwRouter_ParamWrite 922172 1778 ns/op 976 B/op 8 allocs/op +BenchmarkHttpRouter_ParamWrite 15392049 77.7 ns/op 0 B/op 0 allocs/op +BenchmarkHttpTreeMux_ParamWrite 1973385 597 ns/op 352 B/op 3 allocs/op +BenchmarkKocha_ParamWrite 4262500 281 ns/op 56 B/op 3 allocs/op +BenchmarkLARS_ParamWrite 10764410 113 ns/op 0 B/op 0 allocs/op +BenchmarkMacaron_ParamWrite 486769 2726 ns/op 1176 B/op 14 allocs/op +BenchmarkMartini_ParamWrite 264804 4842 ns/op 1176 B/op 14 allocs/op +BenchmarkPat_ParamWrite 735116 2047 ns/op 960 B/op 15 allocs/op +BenchmarkPossum_ParamWrite 1000000 1004 ns/op 496 B/op 5 allocs/op +BenchmarkR2router_ParamWrite 1592136 768 ns/op 432 B/op 5 allocs/op +BenchmarkRivet_ParamWrite 3582051 339 ns/op 112 B/op 2 allocs/op +BenchmarkTango_ParamWrite 2237337 534 ns/op 136 B/op 4 allocs/op +BenchmarkTigerTonic_ParamWrite 439608 3136 ns/op 1216 B/op 21 allocs/op +BenchmarkTraffic_ParamWrite 306979 4328 ns/op 2280 B/op 25 allocs/op +BenchmarkVulcan_ParamWrite 2529973 472 ns/op 98 B/op 3 allocs/op +``` + +## GitHub + +```sh +BenchmarkGin_GithubStatic 15629472 76.7 ns/op 0 B/op 0 allocs/op + +BenchmarkAce_GithubStatic 15542612 75.9 ns/op 0 B/op 0 allocs/op +BenchmarkAero_GithubStatic 24777151 48.5 ns/op 0 B/op 0 allocs/op +BenchmarkBear_GithubStatic 2788894 435 ns/op 120 B/op 3 allocs/op +BenchmarkBeego_GithubStatic 1000000 1064 ns/op 352 B/op 3 allocs/op +BenchmarkBone_GithubStatic 93507 12838 ns/op 2880 B/op 60 allocs/op +BenchmarkChi_GithubStatic 1387743 860 ns/op 432 B/op 3 allocs/op +BenchmarkDenco_GithubStatic 39384996 30.4 ns/op 0 B/op 0 allocs/op +BenchmarkEcho_GithubStatic 12076382 99.1 ns/op 0 B/op 0 allocs/op +BenchmarkGocraftWeb_GithubStatic 1596495 756 ns/op 296 B/op 5 allocs/op +BenchmarkGoji_GithubStatic 6364876 189 ns/op 0 B/op 0 allocs/op +BenchmarkGojiv2_GithubStatic 550202 2098 ns/op 1312 B/op 10 allocs/op +BenchmarkGoRestful_GithubStatic 102183 12552 ns/op 4256 B/op 13 allocs/op +BenchmarkGoJsonRest_GithubStatic 1000000 1029 ns/op 329 B/op 11 allocs/op +BenchmarkGorillaMux_GithubStatic 255552 5190 ns/op 976 B/op 9 allocs/op +BenchmarkGowwwRouter_GithubStatic 15531916 77.1 ns/op 0 B/op 0 allocs/op +BenchmarkHttpRouter_GithubStatic 27920724 43.1 ns/op 0 B/op 0 allocs/op +BenchmarkHttpTreeMux_GithubStatic 21448953 55.8 ns/op 0 B/op 0 allocs/op +BenchmarkKocha_GithubStatic 21405310 56.0 ns/op 0 B/op 0 allocs/op +BenchmarkLARS_GithubStatic 13625156 89.0 ns/op 0 B/op 0 allocs/op +BenchmarkMacaron_GithubStatic 1000000 1747 ns/op 736 B/op 8 allocs/op +BenchmarkMartini_GithubStatic 187186 7326 ns/op 768 B/op 9 allocs/op +BenchmarkPat_GithubStatic 109143 11563 ns/op 3648 B/op 76 allocs/op +BenchmarkPossum_GithubStatic 1575898 770 ns/op 416 B/op 3 allocs/op +BenchmarkR2router_GithubStatic 3046231 404 ns/op 144 B/op 4 allocs/op +BenchmarkRivet_GithubStatic 11484826 105 ns/op 0 B/op 0 allocs/op +BenchmarkTango_GithubStatic 1000000 1153 ns/op 248 B/op 8 allocs/op +BenchmarkTigerTonic_GithubStatic 4929780 249 ns/op 48 B/op 1 allocs/op +BenchmarkTraffic_GithubStatic 106351 11819 ns/op 4664 B/op 90 allocs/op +BenchmarkVulcan_GithubStatic 1613271 722 ns/op 98 B/op 3 allocs/op +BenchmarkAce_GithubParam 8386032 143 ns/op 0 B/op 0 allocs/op +BenchmarkAero_GithubParam 11816200 102 ns/op 0 B/op 0 allocs/op +BenchmarkBear_GithubParam 1000000 1012 ns/op 496 B/op 5 allocs/op +BenchmarkBeego_GithubParam 1000000 1157 ns/op 352 B/op 3 allocs/op +BenchmarkBone_GithubParam 184653 6912 ns/op 1888 B/op 19 allocs/op +BenchmarkChi_GithubParam 1000000 1102 ns/op 432 B/op 3 allocs/op +BenchmarkDenco_GithubParam 3484798 352 ns/op 128 B/op 1 allocs/op +BenchmarkEcho_GithubParam 6337380 189 ns/op 0 B/op 0 allocs/op +BenchmarkGin_GithubParam 9132032 131 ns/op 0 B/op 0 allocs/op +BenchmarkGocraftWeb_GithubParam 1000000 1446 ns/op 712 B/op 9 allocs/op +BenchmarkGoji_GithubParam 1248640 977 ns/op 336 B/op 2 allocs/op +BenchmarkGojiv2_GithubParam 383233 2784 ns/op 1408 B/op 13 allocs/op +BenchmarkGoJsonRest_GithubParam 1000000 1991 ns/op 713 B/op 14 allocs/op +BenchmarkGoRestful_GithubParam 76414 16015 ns/op 4352 B/op 16 allocs/op +BenchmarkGorillaMux_GithubParam 150026 7663 ns/op 1296 B/op 10 allocs/op +BenchmarkGowwwRouter_GithubParam 1592044 751 ns/op 432 B/op 3 allocs/op +BenchmarkHttpRouter_GithubParam 10420628 115 ns/op 0 B/op 0 allocs/op +BenchmarkHttpTreeMux_GithubParam 1403755 835 ns/op 384 B/op 4 allocs/op +BenchmarkKocha_GithubParam 2286170 533 ns/op 128 B/op 5 allocs/op +BenchmarkLARS_GithubParam 9540374 129 ns/op 0 B/op 0 allocs/op +BenchmarkMacaron_GithubParam 533154 2742 ns/op 1072 B/op 10 allocs/op +BenchmarkMartini_GithubParam 119397 9638 ns/op 1152 B/op 11 allocs/op +BenchmarkPat_GithubParam 150675 8858 ns/op 2408 B/op 48 allocs/op +BenchmarkPossum_GithubParam 1000000 1001 ns/op 496 B/op 5 allocs/op +BenchmarkR2router_GithubParam 1602886 761 ns/op 432 B/op 5 allocs/op +BenchmarkRivet_GithubParam 2986579 409 ns/op 96 B/op 1 allocs/op +BenchmarkTango_GithubParam 1000000 1356 ns/op 344 B/op 8 allocs/op +BenchmarkTigerTonic_GithubParam 388899 3429 ns/op 1176 B/op 22 allocs/op +BenchmarkTraffic_GithubParam 123160 9734 ns/op 2816 B/op 40 allocs/op +BenchmarkVulcan_GithubParam 1000000 1138 ns/op 98 B/op 3 allocs/op +BenchmarkAce_GithubAll 40543 29670 ns/op 0 B/op 0 allocs/op +BenchmarkAero_GithubAll 57632 20648 ns/op 0 B/op 0 allocs/op +BenchmarkBear_GithubAll 9234 216179 ns/op 86448 B/op 943 allocs/op +BenchmarkBeego_GithubAll 7407 243496 ns/op 71456 B/op 609 allocs/op +BenchmarkBone_GithubAll 420 2922835 ns/op 720160 B/op 8620 allocs/op +BenchmarkChi_GithubAll 7620 238331 ns/op 87696 B/op 609 allocs/op +BenchmarkDenco_GithubAll 18355 64494 ns/op 20224 B/op 167 allocs/op +BenchmarkEcho_GithubAll 31251 38479 ns/op 0 B/op 0 allocs/op +BenchmarkGin_GithubAll 43550 27364 ns/op 0 B/op 0 allocs/op +BenchmarkGocraftWeb_GithubAll 4117 300062 ns/op 131656 B/op 1686 allocs/op +BenchmarkGoji_GithubAll 3274 416158 ns/op 56112 B/op 334 allocs/op +BenchmarkGojiv2_GithubAll 1402 870518 ns/op 352720 B/op 4321 allocs/op +BenchmarkGoJsonRest_GithubAll 2976 401507 ns/op 134371 B/op 2737 allocs/op +BenchmarkGoRestful_GithubAll 410 2913158 ns/op 910144 B/op 2938 allocs/op +BenchmarkGorillaMux_GithubAll 346 3384987 ns/op 251650 B/op 1994 allocs/op +BenchmarkGowwwRouter_GithubAll 10000 143025 ns/op 72144 B/op 501 allocs/op +BenchmarkHttpRouter_GithubAll 55938 21360 ns/op 0 B/op 0 allocs/op +BenchmarkHttpTreeMux_GithubAll 10000 153944 ns/op 65856 B/op 671 allocs/op +BenchmarkKocha_GithubAll 10000 106315 ns/op 23304 B/op 843 allocs/op +BenchmarkLARS_GithubAll 47779 25084 ns/op 0 B/op 0 allocs/op +BenchmarkMacaron_GithubAll 3266 371907 ns/op 149409 B/op 1624 allocs/op +BenchmarkMartini_GithubAll 331 3444706 ns/op 226551 B/op 2325 allocs/op +BenchmarkPat_GithubAll 273 4381818 ns/op 1483152 B/op 26963 allocs/op +BenchmarkPossum_GithubAll 10000 164367 ns/op 84448 B/op 609 allocs/op +BenchmarkR2router_GithubAll 10000 160220 ns/op 77328 B/op 979 allocs/op +BenchmarkRivet_GithubAll 14625 82453 ns/op 16272 B/op 167 allocs/op +BenchmarkTango_GithubAll 6255 279611 ns/op 63826 B/op 1618 allocs/op +BenchmarkTigerTonic_GithubAll 2008 687874 ns/op 193856 B/op 4474 allocs/op +BenchmarkTraffic_GithubAll 355 3478508 ns/op 820744 B/op 14114 allocs/op +BenchmarkVulcan_GithubAll 6885 193333 ns/op 19894 B/op 609 allocs/op +``` + +## Google+ + +```sh +BenchmarkGin_GPlusStatic 19247326 62.2 ns/op 0 B/op 0 allocs/op + +BenchmarkAce_GPlusStatic 20235060 59.2 ns/op 0 B/op 0 allocs/op +BenchmarkAero_GPlusStatic 31978935 37.6 ns/op 0 B/op 0 allocs/op +BenchmarkBear_GPlusStatic 3516523 341 ns/op 104 B/op 3 allocs/op +BenchmarkBeego_GPlusStatic 1212036 991 ns/op 352 B/op 3 allocs/op +BenchmarkBone_GPlusStatic 6736242 183 ns/op 32 B/op 1 allocs/op +BenchmarkChi_GPlusStatic 1490640 814 ns/op 432 B/op 3 allocs/op +BenchmarkDenco_GPlusStatic 55006856 21.8 ns/op 0 B/op 0 allocs/op +BenchmarkEcho_GPlusStatic 17688258 67.9 ns/op 0 B/op 0 allocs/op +BenchmarkGocraftWeb_GPlusStatic 1829181 666 ns/op 280 B/op 5 allocs/op +BenchmarkGoji_GPlusStatic 9147451 130 ns/op 0 B/op 0 allocs/op +BenchmarkGojiv2_GPlusStatic 594015 2063 ns/op 1312 B/op 10 allocs/op +BenchmarkGoJsonRest_GPlusStatic 1264906 950 ns/op 329 B/op 11 allocs/op +BenchmarkGoRestful_GPlusStatic 231558 5341 ns/op 3872 B/op 13 allocs/op +BenchmarkGorillaMux_GPlusStatic 908418 1809 ns/op 976 B/op 9 allocs/op +BenchmarkGowwwRouter_GPlusStatic 40684604 29.5 ns/op 0 B/op 0 allocs/op +BenchmarkHttpRouter_GPlusStatic 46742804 25.7 ns/op 0 B/op 0 allocs/op +BenchmarkHttpTreeMux_GPlusStatic 32567161 36.9 ns/op 0 B/op 0 allocs/op +BenchmarkKocha_GPlusStatic 33800060 35.3 ns/op 0 B/op 0 allocs/op +BenchmarkLARS_GPlusStatic 20431858 60.0 ns/op 0 B/op 0 allocs/op +BenchmarkMacaron_GPlusStatic 1000000 1745 ns/op 736 B/op 8 allocs/op +BenchmarkMartini_GPlusStatic 442248 3619 ns/op 768 B/op 9 allocs/op +BenchmarkPat_GPlusStatic 4328004 292 ns/op 96 B/op 2 allocs/op +BenchmarkPossum_GPlusStatic 1570753 763 ns/op 416 B/op 3 allocs/op +BenchmarkR2router_GPlusStatic 3339474 355 ns/op 144 B/op 4 allocs/op +BenchmarkRivet_GPlusStatic 18570961 64.7 ns/op 0 B/op 0 allocs/op +BenchmarkTango_GPlusStatic 1388702 860 ns/op 200 B/op 8 allocs/op +BenchmarkTigerTonic_GPlusStatic 7803543 159 ns/op 32 B/op 1 allocs/op +BenchmarkTraffic_GPlusStatic 878605 2171 ns/op 1112 B/op 16 allocs/op +BenchmarkVulcan_GPlusStatic 2742446 437 ns/op 98 B/op 3 allocs/op +BenchmarkAce_GPlusParam 11626975 105 ns/op 0 B/op 0 allocs/op +BenchmarkAero_GPlusParam 16914322 71.6 ns/op 0 B/op 0 allocs/op +BenchmarkBear_GPlusParam 1405173 832 ns/op 480 B/op 5 allocs/op +BenchmarkBeego_GPlusParam 1000000 1075 ns/op 352 B/op 3 allocs/op +BenchmarkBone_GPlusParam 1000000 1557 ns/op 816 B/op 6 allocs/op +BenchmarkChi_GPlusParam 1347926 894 ns/op 432 B/op 3 allocs/op +BenchmarkDenco_GPlusParam 5513000 212 ns/op 64 B/op 1 allocs/op +BenchmarkEcho_GPlusParam 11884383 101 ns/op 0 B/op 0 allocs/op +BenchmarkGin_GPlusParam 12898952 93.1 ns/op 0 B/op 0 allocs/op +BenchmarkGocraftWeb_GPlusParam 1000000 1194 ns/op 648 B/op 8 allocs/op +BenchmarkGoji_GPlusParam 1857229 645 ns/op 336 B/op 2 allocs/op +BenchmarkGojiv2_GPlusParam 520939 2322 ns/op 1328 B/op 11 allocs/op +BenchmarkGoJsonRest_GPlusParam 1000000 1536 ns/op 649 B/op 13 allocs/op +BenchmarkGoRestful_GPlusParam 205449 5800 ns/op 4192 B/op 14 allocs/op +BenchmarkGorillaMux_GPlusParam 395310 3188 ns/op 1280 B/op 10 allocs/op +BenchmarkGowwwRouter_GPlusParam 1851798 667 ns/op 432 B/op 3 allocs/op +BenchmarkHttpRouter_GPlusParam 18420789 65.2 ns/op 0 B/op 0 allocs/op +BenchmarkHttpTreeMux_GPlusParam 1878463 629 ns/op 352 B/op 3 allocs/op +BenchmarkKocha_GPlusParam 4495610 273 ns/op 56 B/op 3 allocs/op +BenchmarkLARS_GPlusParam 14615976 83.2 ns/op 0 B/op 0 allocs/op +BenchmarkMacaron_GPlusParam 584145 2549 ns/op 1072 B/op 10 allocs/op +BenchmarkMartini_GPlusParam 250501 4583 ns/op 1072 B/op 10 allocs/op +BenchmarkPat_GPlusParam 1000000 1645 ns/op 576 B/op 11 allocs/op +BenchmarkPossum_GPlusParam 1000000 1008 ns/op 496 B/op 5 allocs/op +BenchmarkR2router_GPlusParam 1708191 688 ns/op 432 B/op 5 allocs/op +BenchmarkRivet_GPlusParam 5795014 211 ns/op 48 B/op 1 allocs/op +BenchmarkTango_GPlusParam 1000000 1091 ns/op 264 B/op 8 allocs/op +BenchmarkTigerTonic_GPlusParam 760221 2489 ns/op 856 B/op 16 allocs/op +BenchmarkTraffic_GPlusParam 309774 4039 ns/op 1872 B/op 21 allocs/op +BenchmarkVulcan_GPlusParam 1935730 623 ns/op 98 B/op 3 allocs/op +BenchmarkAce_GPlus2Params 9158314 134 ns/op 0 B/op 0 allocs/op +BenchmarkAero_GPlus2Params 11300517 107 ns/op 0 B/op 0 allocs/op +BenchmarkBear_GPlus2Params 1239238 961 ns/op 496 B/op 5 allocs/op +BenchmarkBeego_GPlus2Params 1000000 1202 ns/op 352 B/op 3 allocs/op +BenchmarkBone_GPlus2Params 335576 3725 ns/op 1168 B/op 10 allocs/op +BenchmarkChi_GPlus2Params 1000000 1014 ns/op 432 B/op 3 allocs/op +BenchmarkDenco_GPlus2Params 4394598 280 ns/op 64 B/op 1 allocs/op +BenchmarkEcho_GPlus2Params 7851861 154 ns/op 0 B/op 0 allocs/op +BenchmarkGin_GPlus2Params 9958588 120 ns/op 0 B/op 0 allocs/op +BenchmarkGocraftWeb_GPlus2Params 1000000 1433 ns/op 712 B/op 9 allocs/op +BenchmarkGoji_GPlus2Params 1325134 909 ns/op 336 B/op 2 allocs/op +BenchmarkGojiv2_GPlus2Params 405955 2870 ns/op 1408 B/op 14 allocs/op +BenchmarkGoJsonRest_GPlus2Params 977038 1987 ns/op 713 B/op 14 allocs/op +BenchmarkGoRestful_GPlus2Params 205018 6142 ns/op 4384 B/op 16 allocs/op +BenchmarkGorillaMux_GPlus2Params 205641 6015 ns/op 1296 B/op 10 allocs/op +BenchmarkGowwwRouter_GPlus2Params 1748542 684 ns/op 432 B/op 3 allocs/op +BenchmarkHttpRouter_GPlus2Params 14047102 87.7 ns/op 0 B/op 0 allocs/op +BenchmarkHttpTreeMux_GPlus2Params 1418673 828 ns/op 384 B/op 4 allocs/op +BenchmarkKocha_GPlus2Params 2334562 520 ns/op 128 B/op 5 allocs/op +BenchmarkLARS_GPlus2Params 11954094 101 ns/op 0 B/op 0 allocs/op +BenchmarkMacaron_GPlus2Params 491552 2890 ns/op 1072 B/op 10 allocs/op +BenchmarkMartini_GPlus2Params 120532 9545 ns/op 1200 B/op 13 allocs/op +BenchmarkPat_GPlus2Params 194739 6766 ns/op 2168 B/op 33 allocs/op +BenchmarkPossum_GPlus2Params 1201224 1009 ns/op 496 B/op 5 allocs/op +BenchmarkR2router_GPlus2Params 1575535 756 ns/op 432 B/op 5 allocs/op +BenchmarkRivet_GPlus2Params 3698930 325 ns/op 96 B/op 1 allocs/op +BenchmarkTango_GPlus2Params 1000000 1212 ns/op 344 B/op 8 allocs/op +BenchmarkTigerTonic_GPlus2Params 349350 3660 ns/op 1200 B/op 22 allocs/op +BenchmarkTraffic_GPlus2Params 169714 7862 ns/op 2248 B/op 28 allocs/op +BenchmarkVulcan_GPlus2Params 1222288 974 ns/op 98 B/op 3 allocs/op +BenchmarkAce_GPlusAll 845606 1398 ns/op 0 B/op 0 allocs/op +BenchmarkAero_GPlusAll 1000000 1009 ns/op 0 B/op 0 allocs/op +BenchmarkBear_GPlusAll 103830 11386 ns/op 5488 B/op 61 allocs/op +BenchmarkBeego_GPlusAll 82653 14784 ns/op 4576 B/op 39 allocs/op +BenchmarkBone_GPlusAll 36601 33123 ns/op 11744 B/op 109 allocs/op +BenchmarkChi_GPlusAll 95264 12831 ns/op 5616 B/op 39 allocs/op +BenchmarkDenco_GPlusAll 567681 2950 ns/op 672 B/op 11 allocs/op +BenchmarkEcho_GPlusAll 720366 1665 ns/op 0 B/op 0 allocs/op +BenchmarkGin_GPlusAll 1000000 1185 ns/op 0 B/op 0 allocs/op +BenchmarkGocraftWeb_GPlusAll 71575 16365 ns/op 8040 B/op 103 allocs/op +BenchmarkGoji_GPlusAll 136352 9191 ns/op 3696 B/op 22 allocs/op +BenchmarkGojiv2_GPlusAll 38006 31802 ns/op 17616 B/op 154 allocs/op +BenchmarkGoJsonRest_GPlusAll 57238 21561 ns/op 8117 B/op 170 allocs/op +BenchmarkGoRestful_GPlusAll 15147 79276 ns/op 55520 B/op 192 allocs/op +BenchmarkGorillaMux_GPlusAll 24446 48410 ns/op 16112 B/op 128 allocs/op +BenchmarkGowwwRouter_GPlusAll 150112 7770 ns/op 4752 B/op 33 allocs/op +BenchmarkHttpRouter_GPlusAll 1367820 878 ns/op 0 B/op 0 allocs/op +BenchmarkHttpTreeMux_GPlusAll 166628 8004 ns/op 4032 B/op 38 allocs/op +BenchmarkKocha_GPlusAll 265694 4570 ns/op 976 B/op 43 allocs/op +BenchmarkLARS_GPlusAll 1000000 1068 ns/op 0 B/op 0 allocs/op +BenchmarkMacaron_GPlusAll 54564 23305 ns/op 9568 B/op 104 allocs/op +BenchmarkMartini_GPlusAll 16274 73845 ns/op 14016 B/op 145 allocs/op +BenchmarkPat_GPlusAll 27181 44478 ns/op 15264 B/op 271 allocs/op +BenchmarkPossum_GPlusAll 122587 10277 ns/op 5408 B/op 39 allocs/op +BenchmarkR2router_GPlusAll 130137 9297 ns/op 5040 B/op 63 allocs/op +BenchmarkRivet_GPlusAll 532438 3323 ns/op 768 B/op 11 allocs/op +BenchmarkTango_GPlusAll 86054 14531 ns/op 3656 B/op 104 allocs/op +BenchmarkTigerTonic_GPlusAll 33936 35356 ns/op 11600 B/op 242 allocs/op +BenchmarkTraffic_GPlusAll 17833 68181 ns/op 26248 B/op 341 allocs/op +BenchmarkVulcan_GPlusAll 120109 9861 ns/op 1274 B/op 39 allocs/op +``` + +## Parse.com + +```sh +BenchmarkGin_ParseStatic 18877833 63.5 ns/op 0 B/op 0 allocs/op + +BenchmarkAce_ParseStatic 19663731 60.8 ns/op 0 B/op 0 allocs/op +BenchmarkAero_ParseStatic 28967341 41.5 ns/op 0 B/op 0 allocs/op +BenchmarkBear_ParseStatic 3006984 402 ns/op 120 B/op 3 allocs/op +BenchmarkBeego_ParseStatic 1000000 1031 ns/op 352 B/op 3 allocs/op +BenchmarkBone_ParseStatic 1782482 675 ns/op 144 B/op 3 allocs/op +BenchmarkChi_ParseStatic 1453261 819 ns/op 432 B/op 3 allocs/op +BenchmarkDenco_ParseStatic 45023595 26.5 ns/op 0 B/op 0 allocs/op +BenchmarkEcho_ParseStatic 17330470 69.3 ns/op 0 B/op 0 allocs/op +BenchmarkGocraftWeb_ParseStatic 1644006 731 ns/op 296 B/op 5 allocs/op +BenchmarkGoji_ParseStatic 7026930 170 ns/op 0 B/op 0 allocs/op +BenchmarkGojiv2_ParseStatic 517618 2037 ns/op 1312 B/op 10 allocs/op +BenchmarkGoJsonRest_ParseStatic 1227080 975 ns/op 329 B/op 11 allocs/op +BenchmarkGoRestful_ParseStatic 192458 6659 ns/op 4256 B/op 13 allocs/op +BenchmarkGorillaMux_ParseStatic 744062 2109 ns/op 976 B/op 9 allocs/op +BenchmarkGowwwRouter_ParseStatic 37781062 31.8 ns/op 0 B/op 0 allocs/op +BenchmarkHttpRouter_ParseStatic 45311223 26.5 ns/op 0 B/op 0 allocs/op +BenchmarkHttpTreeMux_ParseStatic 21383475 56.1 ns/op 0 B/op 0 allocs/op +BenchmarkKocha_ParseStatic 29953290 40.1 ns/op 0 B/op 0 allocs/op +BenchmarkLARS_ParseStatic 20036196 62.7 ns/op 0 B/op 0 allocs/op +BenchmarkMacaron_ParseStatic 1000000 1740 ns/op 736 B/op 8 allocs/op +BenchmarkMartini_ParseStatic 404156 3801 ns/op 768 B/op 9 allocs/op +BenchmarkPat_ParseStatic 1547180 772 ns/op 240 B/op 5 allocs/op +BenchmarkPossum_ParseStatic 1608991 757 ns/op 416 B/op 3 allocs/op +BenchmarkR2router_ParseStatic 3177936 385 ns/op 144 B/op 4 allocs/op +BenchmarkRivet_ParseStatic 17783205 67.4 ns/op 0 B/op 0 allocs/op +BenchmarkTango_ParseStatic 1210777 990 ns/op 248 B/op 8 allocs/op +BenchmarkTigerTonic_ParseStatic 5316440 231 ns/op 48 B/op 1 allocs/op +BenchmarkTraffic_ParseStatic 496050 2539 ns/op 1256 B/op 19 allocs/op +BenchmarkVulcan_ParseStatic 2462798 488 ns/op 98 B/op 3 allocs/op +BenchmarkAce_ParseParam 13393669 89.6 ns/op 0 B/op 0 allocs/op +BenchmarkAero_ParseParam 19836619 60.4 ns/op 0 B/op 0 allocs/op +BenchmarkBear_ParseParam 1405954 864 ns/op 467 B/op 5 allocs/op +BenchmarkBeego_ParseParam 1000000 1065 ns/op 352 B/op 3 allocs/op +BenchmarkBone_ParseParam 1000000 1698 ns/op 896 B/op 7 allocs/op +BenchmarkChi_ParseParam 1356037 873 ns/op 432 B/op 3 allocs/op +BenchmarkDenco_ParseParam 6241392 204 ns/op 64 B/op 1 allocs/op +BenchmarkEcho_ParseParam 14088100 85.1 ns/op 0 B/op 0 allocs/op +BenchmarkGin_ParseParam 17426064 68.9 ns/op 0 B/op 0 allocs/op +BenchmarkGocraftWeb_ParseParam 1000000 1254 ns/op 664 B/op 8 allocs/op +BenchmarkGoji_ParseParam 1682574 713 ns/op 336 B/op 2 allocs/op +BenchmarkGojiv2_ParseParam 502224 2333 ns/op 1360 B/op 12 allocs/op +BenchmarkGoJsonRest_ParseParam 1000000 1401 ns/op 649 B/op 13 allocs/op +BenchmarkGoRestful_ParseParam 182623 7097 ns/op 4576 B/op 14 allocs/op +BenchmarkGorillaMux_ParseParam 482332 2477 ns/op 1280 B/op 10 allocs/op +BenchmarkGowwwRouter_ParseParam 1834873 657 ns/op 432 B/op 3 allocs/op +BenchmarkHttpRouter_ParseParam 23593393 51.0 ns/op 0 B/op 0 allocs/op +BenchmarkHttpTreeMux_ParseParam 2100160 574 ns/op 352 B/op 3 allocs/op +BenchmarkKocha_ParseParam 4837220 252 ns/op 56 B/op 3 allocs/op +BenchmarkLARS_ParseParam 18411192 66.2 ns/op 0 B/op 0 allocs/op +BenchmarkMacaron_ParseParam 571870 2398 ns/op 1072 B/op 10 allocs/op +BenchmarkMartini_ParseParam 286262 4268 ns/op 1072 B/op 10 allocs/op +BenchmarkPat_ParseParam 692906 2157 ns/op 992 B/op 15 allocs/op +BenchmarkPossum_ParseParam 1000000 1011 ns/op 496 B/op 5 allocs/op +BenchmarkR2router_ParseParam 1722735 697 ns/op 432 B/op 5 allocs/op +BenchmarkRivet_ParseParam 6058054 203 ns/op 48 B/op 1 allocs/op +BenchmarkTango_ParseParam 1000000 1061 ns/op 280 B/op 8 allocs/op +BenchmarkTigerTonic_ParseParam 890275 2277 ns/op 784 B/op 15 allocs/op +BenchmarkTraffic_ParseParam 351322 3543 ns/op 1896 B/op 21 allocs/op +BenchmarkVulcan_ParseParam 2076544 572 ns/op 98 B/op 3 allocs/op +BenchmarkAce_Parse2Params 11718074 101 ns/op 0 B/op 0 allocs/op +BenchmarkAero_Parse2Params 16264988 73.4 ns/op 0 B/op 0 allocs/op +BenchmarkBear_Parse2Params 1238322 973 ns/op 496 B/op 5 allocs/op +BenchmarkBeego_Parse2Params 1000000 1120 ns/op 352 B/op 3 allocs/op +BenchmarkBone_Parse2Params 1000000 1632 ns/op 848 B/op 6 allocs/op +BenchmarkChi_Parse2Params 1239477 955 ns/op 432 B/op 3 allocs/op +BenchmarkDenco_Parse2Params 4944133 245 ns/op 64 B/op 1 allocs/op +BenchmarkEcho_Parse2Params 10518286 114 ns/op 0 B/op 0 allocs/op +BenchmarkGin_Parse2Params 14505195 82.7 ns/op 0 B/op 0 allocs/op +BenchmarkGocraftWeb_Parse2Params 1000000 1437 ns/op 712 B/op 9 allocs/op +BenchmarkGoji_Parse2Params 1689883 707 ns/op 336 B/op 2 allocs/op +BenchmarkGojiv2_Parse2Params 502334 2308 ns/op 1344 B/op 11 allocs/op +BenchmarkGoJsonRest_Parse2Params 1000000 1771 ns/op 713 B/op 14 allocs/op +BenchmarkGoRestful_Parse2Params 159092 7583 ns/op 4928 B/op 14 allocs/op +BenchmarkGorillaMux_Parse2Params 417548 2980 ns/op 1296 B/op 10 allocs/op +BenchmarkGowwwRouter_Parse2Params 1751737 686 ns/op 432 B/op 3 allocs/op +BenchmarkHttpRouter_Parse2Params 18089204 66.3 ns/op 0 B/op 0 allocs/op +BenchmarkHttpTreeMux_Parse2Params 1556986 777 ns/op 384 B/op 4 allocs/op +BenchmarkKocha_Parse2Params 2493082 485 ns/op 128 B/op 5 allocs/op +BenchmarkLARS_Parse2Params 15350108 78.5 ns/op 0 B/op 0 allocs/op +BenchmarkMacaron_Parse2Params 530974 2605 ns/op 1072 B/op 10 allocs/op +BenchmarkMartini_Parse2Params 247069 4673 ns/op 1152 B/op 11 allocs/op +BenchmarkPat_Parse2Params 816295 2126 ns/op 752 B/op 16 allocs/op +BenchmarkPossum_Parse2Params 1000000 1002 ns/op 496 B/op 5 allocs/op +BenchmarkR2router_Parse2Params 1569771 733 ns/op 432 B/op 5 allocs/op +BenchmarkRivet_Parse2Params 4080546 295 ns/op 96 B/op 1 allocs/op +BenchmarkTango_Parse2Params 1000000 1121 ns/op 312 B/op 8 allocs/op +BenchmarkTigerTonic_Parse2Params 399556 3470 ns/op 1168 B/op 22 allocs/op +BenchmarkTraffic_Parse2Params 314194 4159 ns/op 1944 B/op 22 allocs/op +BenchmarkVulcan_Parse2Params 1827559 664 ns/op 98 B/op 3 allocs/op +BenchmarkAce_ParseAll 478395 2503 ns/op 0 B/op 0 allocs/op +BenchmarkAero_ParseAll 715392 1658 ns/op 0 B/op 0 allocs/op +BenchmarkBear_ParseAll 59191 20124 ns/op 8928 B/op 110 allocs/op +BenchmarkBeego_ParseAll 45507 27266 ns/op 9152 B/op 78 allocs/op +BenchmarkBone_ParseAll 29328 41459 ns/op 16208 B/op 147 allocs/op +BenchmarkChi_ParseAll 48531 25053 ns/op 11232 B/op 78 allocs/op +BenchmarkDenco_ParseAll 325532 4284 ns/op 928 B/op 16 allocs/op +BenchmarkEcho_ParseAll 433771 2759 ns/op 0 B/op 0 allocs/op +BenchmarkGin_ParseAll 576316 2082 ns/op 0 B/op 0 allocs/op +BenchmarkGocraftWeb_ParseAll 41500 29692 ns/op 13728 B/op 181 allocs/op +BenchmarkGoji_ParseAll 80833 15563 ns/op 5376 B/op 32 allocs/op +BenchmarkGojiv2_ParseAll 19836 60335 ns/op 34448 B/op 277 allocs/op +BenchmarkGoJsonRest_ParseAll 32210 38027 ns/op 13866 B/op 321 allocs/op +BenchmarkGoRestful_ParseAll 6644 190842 ns/op 117600 B/op 354 allocs/op +BenchmarkGorillaMux_ParseAll 12634 95894 ns/op 30288 B/op 250 allocs/op +BenchmarkGowwwRouter_ParseAll 98152 12159 ns/op 6912 B/op 48 allocs/op +BenchmarkHttpRouter_ParseAll 933208 1273 ns/op 0 B/op 0 allocs/op +BenchmarkHttpTreeMux_ParseAll 107191 11554 ns/op 5728 B/op 51 allocs/op +BenchmarkKocha_ParseAll 184862 6225 ns/op 1112 B/op 54 allocs/op +BenchmarkLARS_ParseAll 644546 1858 ns/op 0 B/op 0 allocs/op +BenchmarkMacaron_ParseAll 26145 46484 ns/op 19136 B/op 208 allocs/op +BenchmarkMartini_ParseAll 10000 121838 ns/op 25072 B/op 253 allocs/op +BenchmarkPat_ParseAll 25417 47196 ns/op 15216 B/op 308 allocs/op +BenchmarkPossum_ParseAll 58550 20735 ns/op 10816 B/op 78 allocs/op +BenchmarkR2router_ParseAll 72732 16584 ns/op 8352 B/op 120 allocs/op +BenchmarkRivet_ParseAll 281365 4968 ns/op 912 B/op 16 allocs/op +BenchmarkTango_ParseAll 42831 28668 ns/op 7168 B/op 208 allocs/op +BenchmarkTigerTonic_ParseAll 23774 49972 ns/op 16048 B/op 332 allocs/op +BenchmarkTraffic_ParseAll 10000 104679 ns/op 45520 B/op 605 allocs/op +BenchmarkVulcan_ParseAll 64810 18108 ns/op 2548 B/op 78 allocs/op +``` diff --git a/vendor/github.com/gin-gonic/gin/CHANGELOG.md b/vendor/github.com/gin-gonic/gin/CHANGELOG.md new file mode 100644 index 0000000..1bc51a8 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/CHANGELOG.md @@ -0,0 +1,502 @@ +# Gin ChangeLog + +## Gin v1.8.1 + +### ENHANCEMENTS + +* feat(context): add ContextWithFallback feature flag [#3172](https://github.com/gin-gonic/gin/pull/3172) + +## Gin v1.8.0 + +## Break Changes + +* TrustedProxies: Add default IPv6 support and refactor [#2967](https://github.com/gin-gonic/gin/pull/2967). Please replace `RemoteIP() (net.IP, bool)` with `RemoteIP() net.IP` +* gin.Context with fallback value from gin.Context.Request.Context() [#2751](https://github.com/gin-gonic/gin/pull/2751) + +### BUGFIXES + +* Fixed SetOutput() panics on go 1.17 [#2861](https://github.com/gin-gonic/gin/pull/2861) +* Fix: wrong when wildcard follows named param [#2983](https://github.com/gin-gonic/gin/pull/2983) +* Fix: missing sameSite when do context.reset() [#3123](https://github.com/gin-gonic/gin/pull/3123) + +### ENHANCEMENTS + +* Use Header() instead of deprecated HeaderMap [#2694](https://github.com/gin-gonic/gin/pull/2694) +* RouterGroup.Handle regular match optimization of http method [#2685](https://github.com/gin-gonic/gin/pull/2685) +* Add support go-json, another drop-in json replacement [#2680](https://github.com/gin-gonic/gin/pull/2680) +* Use errors.New to replace fmt.Errorf will much better [#2707](https://github.com/gin-gonic/gin/pull/2707) +* Use Duration.Truncate for truncating precision [#2711](https://github.com/gin-gonic/gin/pull/2711) +* Get client IP when using Cloudflare [#2723](https://github.com/gin-gonic/gin/pull/2723) +* Optimize code adjust [#2700](https://github.com/gin-gonic/gin/pull/2700/files) +* Optimize code and reduce code cyclomatic complexity [#2737](https://github.com/gin-gonic/gin/pull/2737) +* Improve sliceValidateError.Error performance [#2765](https://github.com/gin-gonic/gin/pull/2765) +* Support custom struct tag [#2720](https://github.com/gin-gonic/gin/pull/2720) +* Improve router group tests [#2787](https://github.com/gin-gonic/gin/pull/2787) +* Fallback Context.Deadline() Context.Done() Context.Err() to Context.Request.Context() [#2769](https://github.com/gin-gonic/gin/pull/2769) +* Some codes optimize [#2830](https://github.com/gin-gonic/gin/pull/2830) [#2834](https://github.com/gin-gonic/gin/pull/2834) [#2838](https://github.com/gin-gonic/gin/pull/2838) [#2837](https://github.com/gin-gonic/gin/pull/2837) [#2788](https://github.com/gin-gonic/gin/pull/2788) [#2848](https://github.com/gin-gonic/gin/pull/2848) [#2851](https://github.com/gin-gonic/gin/pull/2851) [#2701](https://github.com/gin-gonic/gin/pull/2701) +* TrustedProxies: Add default IPv6 support and refactor [#2967](https://github.com/gin-gonic/gin/pull/2967) +* Test(route): expose performRequest func [#3012](https://github.com/gin-gonic/gin/pull/3012) +* Support h2c with prior knowledge [#1398](https://github.com/gin-gonic/gin/pull/1398) +* Feat attachment filename support utf8 [#3071](https://github.com/gin-gonic/gin/pull/3071) +* Feat: add StaticFileFS [#2749](https://github.com/gin-gonic/gin/pull/2749) +* Feat(context): return GIN Context from Value method [#2825](https://github.com/gin-gonic/gin/pull/2825) +* Feat: automatically SetMode to TestMode when run go test [#3139](https://github.com/gin-gonic/gin/pull/3139) +* Add TOML bining for gin [#3081](https://github.com/gin-gonic/gin/pull/3081) +* IPv6 add default trusted proxies [#3033](https://github.com/gin-gonic/gin/pull/3033) + +### DOCS + +* Add note about nomsgpack tag to the readme [#2703](https://github.com/gin-gonic/gin/pull/2703) + +## Gin v1.7.7 + +### BUGFIXES + +* Fixed X-Forwarded-For unsafe handling of CVE-2020-28483 [#2844](https://github.com/gin-gonic/gin/pull/2844), closed issue [#2862](https://github.com/gin-gonic/gin/issues/2862). +* Tree: updated the code logic for `latestNode` [#2897](https://github.com/gin-gonic/gin/pull/2897), closed issue [#2894](https://github.com/gin-gonic/gin/issues/2894) [#2878](https://github.com/gin-gonic/gin/issues/2878). +* Tree: fixed the misplacement of adding slashes [#2847](https://github.com/gin-gonic/gin/pull/2847), closed issue [#2843](https://github.com/gin-gonic/gin/issues/2843). +* Tree: fixed tsr with mixed static and wildcard paths [#2924](https://github.com/gin-gonic/gin/pull/2924), closed issue [#2918](https://github.com/gin-gonic/gin/issues/2918). + +### ENHANCEMENTS + +* TrustedProxies: make it backward-compatible [#2887](https://github.com/gin-gonic/gin/pull/2887), closed issue [#2819](https://github.com/gin-gonic/gin/issues/2819). +* TrustedPlatform: provide custom options for another CDN services [#2906](https://github.com/gin-gonic/gin/pull/2906). + +### DOCS + +* NoMethod: added usage annotation ([#2832](https://github.com/gin-gonic/gin/pull/2832#issuecomment-929954463)). + +## Gin v1.7.6 + +### BUGFIXES + +* bump new release to fix v1.7.5 release error by using v1.7.4 codes. + +## Gin v1.7.4 + +### BUGFIXES + +* bump new release to fix checksum mismatch + +## Gin v1.7.3 + +### BUGFIXES + +* fix level 1 router match [#2767](https://github.com/gin-gonic/gin/issues/2767), [#2796](https://github.com/gin-gonic/gin/issues/2796) + +## Gin v1.7.2 + +### BUGFIXES + +* Fix conflict between param and exact path [#2706](https://github.com/gin-gonic/gin/issues/2706). Close issue [#2682](https://github.com/gin-gonic/gin/issues/2682) [#2696](https://github.com/gin-gonic/gin/issues/2696). + +## Gin v1.7.1 + +### BUGFIXES + +* fix: data race with trustedCIDRs from [#2674](https://github.com/gin-gonic/gin/issues/2674)([#2675](https://github.com/gin-gonic/gin/pull/2675)) + +## Gin v1.7.0 + +### BUGFIXES + +* fix compile error from [#2572](https://github.com/gin-gonic/gin/pull/2572) ([#2600](https://github.com/gin-gonic/gin/pull/2600)) +* fix: print headers without Authorization header on broken pipe ([#2528](https://github.com/gin-gonic/gin/pull/2528)) +* fix(tree): reassign fullpath when register new node ([#2366](https://github.com/gin-gonic/gin/pull/2366)) + +### ENHANCEMENTS + +* Support params and exact routes without creating conflicts ([#2663](https://github.com/gin-gonic/gin/pull/2663)) +* chore: improve render string performance ([#2365](https://github.com/gin-gonic/gin/pull/2365)) +* Sync route tree to httprouter latest code ([#2368](https://github.com/gin-gonic/gin/pull/2368)) +* chore: rename getQueryCache/getFormCache to initQueryCache/initFormCa ([#2375](https://github.com/gin-gonic/gin/pull/2375)) +* chore(performance): improve countParams ([#2378](https://github.com/gin-gonic/gin/pull/2378)) +* Remove some functions that have the same effect as the bytes package ([#2387](https://github.com/gin-gonic/gin/pull/2387)) +* update:SetMode function ([#2321](https://github.com/gin-gonic/gin/pull/2321)) +* remove a unused type SecureJSONPrefix ([#2391](https://github.com/gin-gonic/gin/pull/2391)) +* Add a redirect sample for POST method ([#2389](https://github.com/gin-gonic/gin/pull/2389)) +* Add CustomRecovery builtin middleware ([#2322](https://github.com/gin-gonic/gin/pull/2322)) +* binding: avoid 2038 problem on 32-bit architectures ([#2450](https://github.com/gin-gonic/gin/pull/2450)) +* Prevent panic in Context.GetQuery() when there is no Request ([#2412](https://github.com/gin-gonic/gin/pull/2412)) +* Add GetUint and GetUint64 method on gin.context ([#2487](https://github.com/gin-gonic/gin/pull/2487)) +* update content-disposition header to MIME-style ([#2512](https://github.com/gin-gonic/gin/pull/2512)) +* reduce allocs and improve the render `WriteString` ([#2508](https://github.com/gin-gonic/gin/pull/2508)) +* implement ".Unwrap() error" on Error type ([#2525](https://github.com/gin-gonic/gin/pull/2525)) ([#2526](https://github.com/gin-gonic/gin/pull/2526)) +* Allow bind with a map[string]string ([#2484](https://github.com/gin-gonic/gin/pull/2484)) +* chore: update tree ([#2371](https://github.com/gin-gonic/gin/pull/2371)) +* Support binding for slice/array obj [Rewrite] ([#2302](https://github.com/gin-gonic/gin/pull/2302)) +* basic auth: fix timing oracle ([#2609](https://github.com/gin-gonic/gin/pull/2609)) +* Add mixed param and non-param paths (port of httprouter[#329](https://github.com/gin-gonic/gin/pull/329)) ([#2663](https://github.com/gin-gonic/gin/pull/2663)) +* feat(engine): add trustedproxies and remoteIP ([#2632](https://github.com/gin-gonic/gin/pull/2632)) + +## Gin v1.6.3 + +### ENHANCEMENTS + + * Improve performance: Change `*sync.RWMutex` to `sync.RWMutex` in context. [#2351](https://github.com/gin-gonic/gin/pull/2351) + +## Gin v1.6.2 + +### BUGFIXES + * fix missing initial sync.RWMutex [#2305](https://github.com/gin-gonic/gin/pull/2305) +### ENHANCEMENTS + * Add set samesite in cookie. [#2306](https://github.com/gin-gonic/gin/pull/2306) + +## Gin v1.6.1 + +### BUGFIXES + * Revert "fix accept incoming network connections" [#2294](https://github.com/gin-gonic/gin/pull/2294) + +## Gin v1.6.0 + +### BREAKING + * chore(performance): Improve performance for adding RemoveExtraSlash flag [#2159](https://github.com/gin-gonic/gin/pull/2159) + * drop support govendor [#2148](https://github.com/gin-gonic/gin/pull/2148) + * Added support for SameSite cookie flag [#1615](https://github.com/gin-gonic/gin/pull/1615) +### FEATURES + * add yaml negotiation [#2220](https://github.com/gin-gonic/gin/pull/2220) + * FileFromFS [#2112](https://github.com/gin-gonic/gin/pull/2112) +### BUGFIXES + * Unix Socket Handling [#2280](https://github.com/gin-gonic/gin/pull/2280) + * Use json marshall in context json to fix breaking new line issue. Fixes #2209 [#2228](https://github.com/gin-gonic/gin/pull/2228) + * fix accept incoming network connections [#2216](https://github.com/gin-gonic/gin/pull/2216) + * Fixed a bug in the calculation of the maximum number of parameters [#2166](https://github.com/gin-gonic/gin/pull/2166) + * [FIX] allow empty headers on DataFromReader [#2121](https://github.com/gin-gonic/gin/pull/2121) + * Add mutex for protect Context.Keys map [#1391](https://github.com/gin-gonic/gin/pull/1391) +### ENHANCEMENTS + * Add mitigation for log injection [#2277](https://github.com/gin-gonic/gin/pull/2277) + * tree: range over nodes values [#2229](https://github.com/gin-gonic/gin/pull/2229) + * tree: remove duplicate assignment [#2222](https://github.com/gin-gonic/gin/pull/2222) + * chore: upgrade go-isatty and json-iterator/go [#2215](https://github.com/gin-gonic/gin/pull/2215) + * path: sync code with httprouter [#2212](https://github.com/gin-gonic/gin/pull/2212) + * Use zero-copy approach to convert types between string and byte slice [#2206](https://github.com/gin-gonic/gin/pull/2206) + * Reuse bytes when cleaning the URL paths [#2179](https://github.com/gin-gonic/gin/pull/2179) + * tree: remove one else statement [#2177](https://github.com/gin-gonic/gin/pull/2177) + * tree: sync httprouter update (#2173) (#2172) [#2171](https://github.com/gin-gonic/gin/pull/2171) + * tree: sync part httprouter codes and reduce if/else [#2163](https://github.com/gin-gonic/gin/pull/2163) + * use http method constant [#2155](https://github.com/gin-gonic/gin/pull/2155) + * upgrade go-validator to v10 [#2149](https://github.com/gin-gonic/gin/pull/2149) + * Refactor redirect request in gin.go [#1970](https://github.com/gin-gonic/gin/pull/1970) + * Add build tag nomsgpack [#1852](https://github.com/gin-gonic/gin/pull/1852) +### DOCS + * docs(path): improve comments [#2223](https://github.com/gin-gonic/gin/pull/2223) + * Renew README to fit the modification of SetCookie method [#2217](https://github.com/gin-gonic/gin/pull/2217) + * Fix spelling [#2202](https://github.com/gin-gonic/gin/pull/2202) + * Remove broken link from README. [#2198](https://github.com/gin-gonic/gin/pull/2198) + * Update docs on Context.Done(), Context.Deadline() and Context.Err() [#2196](https://github.com/gin-gonic/gin/pull/2196) + * Update validator to v10 [#2190](https://github.com/gin-gonic/gin/pull/2190) + * upgrade go-validator to v10 for README [#2189](https://github.com/gin-gonic/gin/pull/2189) + * Update to currently output [#2188](https://github.com/gin-gonic/gin/pull/2188) + * Fix "Custom Validators" example [#2186](https://github.com/gin-gonic/gin/pull/2186) + * Add project to README [#2165](https://github.com/gin-gonic/gin/pull/2165) + * docs(benchmarks): for gin v1.5 [#2153](https://github.com/gin-gonic/gin/pull/2153) + * Changed wording for clarity in README.md [#2122](https://github.com/gin-gonic/gin/pull/2122) +### MISC + * ci support go1.14 [#2262](https://github.com/gin-gonic/gin/pull/2262) + * chore: upgrade depend version [#2231](https://github.com/gin-gonic/gin/pull/2231) + * Drop support go1.10 [#2147](https://github.com/gin-gonic/gin/pull/2147) + * fix comment in `mode.go` [#2129](https://github.com/gin-gonic/gin/pull/2129) + +## Gin v1.5.0 + +- [FIX] Use DefaultWriter and DefaultErrorWriter for debug messages [#1891](https://github.com/gin-gonic/gin/pull/1891) +- [NEW] Now you can parse the inline lowercase start structure [#1893](https://github.com/gin-gonic/gin/pull/1893) +- [FIX] Some code improvements [#1909](https://github.com/gin-gonic/gin/pull/1909) +- [FIX] Use encode replace json marshal increase json encoder speed [#1546](https://github.com/gin-gonic/gin/pull/1546) +- [NEW] Hold matched route full path in the Context [#1826](https://github.com/gin-gonic/gin/pull/1826) +- [FIX] Fix context.Params race condition on Copy() [#1841](https://github.com/gin-gonic/gin/pull/1841) +- [NEW] Add context param query cache [#1450](https://github.com/gin-gonic/gin/pull/1450) +- [FIX] Improve GetQueryMap performance [#1918](https://github.com/gin-gonic/gin/pull/1918) +- [FIX] Improve get post data [#1920](https://github.com/gin-gonic/gin/pull/1920) +- [FIX] Use context instead of x/net/context [#1922](https://github.com/gin-gonic/gin/pull/1922) +- [FIX] Attempt to fix PostForm cache bug [#1931](https://github.com/gin-gonic/gin/pull/1931) +- [NEW] Add support of multipart multi files [#1949](https://github.com/gin-gonic/gin/pull/1949) +- [NEW] Support bind http header param [#1957](https://github.com/gin-gonic/gin/pull/1957) +- [FIX] Drop support for go1.8 and go1.9 [#1933](https://github.com/gin-gonic/gin/pull/1933) +- [FIX] Bugfix for the FullPath feature [#1919](https://github.com/gin-gonic/gin/pull/1919) +- [FIX] Gin1.5 bytes.Buffer to strings.Builder [#1939](https://github.com/gin-gonic/gin/pull/1939) +- [FIX] Upgrade github.com/ugorji/go/codec [#1969](https://github.com/gin-gonic/gin/pull/1969) +- [NEW] Support bind unix time [#1980](https://github.com/gin-gonic/gin/pull/1980) +- [FIX] Simplify code [#2004](https://github.com/gin-gonic/gin/pull/2004) +- [NEW] Support negative Content-Length in DataFromReader [#1981](https://github.com/gin-gonic/gin/pull/1981) +- [FIX] Identify terminal on a RISC-V architecture for auto-colored logs [#2019](https://github.com/gin-gonic/gin/pull/2019) +- [BREAKING] `Context.JSONP()` now expects a semicolon (`;`) at the end [#2007](https://github.com/gin-gonic/gin/pull/2007) +- [BREAKING] Upgrade default `binding.Validator` to v9 (see [its changelog](https://github.com/go-playground/validator/releases/tag/v9.0.0)) [#1015](https://github.com/gin-gonic/gin/pull/1015) +- [NEW] Add `DisallowUnknownFields()` in `Context.BindJSON()` [#2028](https://github.com/gin-gonic/gin/pull/2028) +- [NEW] Use specific `net.Listener` with `Engine.RunListener()` [#2023](https://github.com/gin-gonic/gin/pull/2023) +- [FIX] Fix some typo [#2079](https://github.com/gin-gonic/gin/pull/2079) [#2080](https://github.com/gin-gonic/gin/pull/2080) +- [FIX] Relocate binding body tests [#2086](https://github.com/gin-gonic/gin/pull/2086) +- [FIX] Use Writer in Context.Status [#1606](https://github.com/gin-gonic/gin/pull/1606) +- [FIX] `Engine.RunUnix()` now returns the error if it can't change the file mode [#2093](https://github.com/gin-gonic/gin/pull/2093) +- [FIX] `RouterGroup.StaticFS()` leaked files. Now it closes them. [#2118](https://github.com/gin-gonic/gin/pull/2118) +- [FIX] `Context.Request.FormFile` leaked file. Now it closes it. [#2114](https://github.com/gin-gonic/gin/pull/2114) +- [FIX] Ignore walking on `form:"-"` mapping [#1943](https://github.com/gin-gonic/gin/pull/1943) + +### Gin v1.4.0 + +- [NEW] Support for [Go Modules](https://github.com/golang/go/wiki/Modules) [#1569](https://github.com/gin-gonic/gin/pull/1569) +- [NEW] Refactor of form mapping multipart request [#1829](https://github.com/gin-gonic/gin/pull/1829) +- [FIX] Truncate Latency precision in long running request [#1830](https://github.com/gin-gonic/gin/pull/1830) +- [FIX] IsTerm flag should not be affected by DisableConsoleColor method. [#1802](https://github.com/gin-gonic/gin/pull/1802) +- [NEW] Supporting file binding [#1264](https://github.com/gin-gonic/gin/pull/1264) +- [NEW] Add support for mapping arrays [#1797](https://github.com/gin-gonic/gin/pull/1797) +- [FIX] Readme updates [#1793](https://github.com/gin-gonic/gin/pull/1793) [#1788](https://github.com/gin-gonic/gin/pull/1788) [1789](https://github.com/gin-gonic/gin/pull/1789) +- [FIX] StaticFS: Fixed Logging two log lines on 404. [#1805](https://github.com/gin-gonic/gin/pull/1805), [#1804](https://github.com/gin-gonic/gin/pull/1804) +- [NEW] Make context.Keys available as LogFormatterParams [#1779](https://github.com/gin-gonic/gin/pull/1779) +- [NEW] Use internal/json for Marshal/Unmarshal [#1791](https://github.com/gin-gonic/gin/pull/1791) +- [NEW] Support mapping time.Duration [#1794](https://github.com/gin-gonic/gin/pull/1794) +- [NEW] Refactor form mappings [#1749](https://github.com/gin-gonic/gin/pull/1749) +- [NEW] Added flag to context.Stream indicates if client disconnected in middle of stream [#1252](https://github.com/gin-gonic/gin/pull/1252) +- [FIX] Moved [examples](https://github.com/gin-gonic/examples) to stand alone Repo [#1775](https://github.com/gin-gonic/gin/pull/1775) +- [NEW] Extend context.File to allow for the content-disposition attachments via a new method context.Attachment [#1260](https://github.com/gin-gonic/gin/pull/1260) +- [FIX] Support HTTP content negotiation wildcards [#1112](https://github.com/gin-gonic/gin/pull/1112) +- [NEW] Add prefix from X-Forwarded-Prefix in redirectTrailingSlash [#1238](https://github.com/gin-gonic/gin/pull/1238) +- [FIX] context.Copy() race condition [#1020](https://github.com/gin-gonic/gin/pull/1020) +- [NEW] Add context.HandlerNames() [#1729](https://github.com/gin-gonic/gin/pull/1729) +- [FIX] Change color methods to public in the defaultLogger. [#1771](https://github.com/gin-gonic/gin/pull/1771) +- [FIX] Update writeHeaders method to use http.Header.Set [#1722](https://github.com/gin-gonic/gin/pull/1722) +- [NEW] Add response size to LogFormatterParams [#1752](https://github.com/gin-gonic/gin/pull/1752) +- [NEW] Allow ignoring field on form mapping [#1733](https://github.com/gin-gonic/gin/pull/1733) +- [NEW] Add a function to force color in console output. [#1724](https://github.com/gin-gonic/gin/pull/1724) +- [FIX] Context.Next() - recheck len of handlers on every iteration. [#1745](https://github.com/gin-gonic/gin/pull/1745) +- [FIX] Fix all errcheck warnings [#1739](https://github.com/gin-gonic/gin/pull/1739) [#1653](https://github.com/gin-gonic/gin/pull/1653) +- [NEW] context: inherits context cancellation and deadline from http.Request context for Go>=1.7 [#1690](https://github.com/gin-gonic/gin/pull/1690) +- [NEW] Binding for URL Params [#1694](https://github.com/gin-gonic/gin/pull/1694) +- [NEW] Add LoggerWithFormatter method [#1677](https://github.com/gin-gonic/gin/pull/1677) +- [FIX] CI testing updates [#1671](https://github.com/gin-gonic/gin/pull/1671) [#1670](https://github.com/gin-gonic/gin/pull/1670) [#1682](https://github.com/gin-gonic/gin/pull/1682) [#1669](https://github.com/gin-gonic/gin/pull/1669) +- [FIX] StaticFS(): Send 404 when path does not exist [#1663](https://github.com/gin-gonic/gin/pull/1663) +- [FIX] Handle nil body for JSON binding [#1638](https://github.com/gin-gonic/gin/pull/1638) +- [FIX] Support bind uri param [#1612](https://github.com/gin-gonic/gin/pull/1612) +- [FIX] recovery: fix issue with syscall import on google app engine [#1640](https://github.com/gin-gonic/gin/pull/1640) +- [FIX] Make sure the debug log contains line breaks [#1650](https://github.com/gin-gonic/gin/pull/1650) +- [FIX] Panic stack trace being printed during recovery of broken pipe [#1089](https://github.com/gin-gonic/gin/pull/1089) [#1259](https://github.com/gin-gonic/gin/pull/1259) +- [NEW] RunFd method to run http.Server through a file descriptor [#1609](https://github.com/gin-gonic/gin/pull/1609) +- [NEW] Yaml binding support [#1618](https://github.com/gin-gonic/gin/pull/1618) +- [FIX] Pass MaxMultipartMemory when FormFile is called [#1600](https://github.com/gin-gonic/gin/pull/1600) +- [FIX] LoadHTML* tests [#1559](https://github.com/gin-gonic/gin/pull/1559) +- [FIX] Removed use of sync.pool from HandleContext [#1565](https://github.com/gin-gonic/gin/pull/1565) +- [FIX] Format output log to os.Stderr [#1571](https://github.com/gin-gonic/gin/pull/1571) +- [FIX] Make logger use a yellow background and a darkgray text for legibility [#1570](https://github.com/gin-gonic/gin/pull/1570) +- [FIX] Remove sensitive request information from panic log. [#1370](https://github.com/gin-gonic/gin/pull/1370) +- [FIX] log.Println() does not print timestamp [#829](https://github.com/gin-gonic/gin/pull/829) [#1560](https://github.com/gin-gonic/gin/pull/1560) +- [NEW] Add PureJSON renderer [#694](https://github.com/gin-gonic/gin/pull/694) +- [FIX] Add missing copyright and update if/else [#1497](https://github.com/gin-gonic/gin/pull/1497) +- [FIX] Update msgpack usage [#1498](https://github.com/gin-gonic/gin/pull/1498) +- [FIX] Use protobuf on render [#1496](https://github.com/gin-gonic/gin/pull/1496) +- [FIX] Add support for Protobuf format response [#1479](https://github.com/gin-gonic/gin/pull/1479) +- [NEW] Set default time format in form binding [#1487](https://github.com/gin-gonic/gin/pull/1487) +- [FIX] Add BindXML and ShouldBindXML [#1485](https://github.com/gin-gonic/gin/pull/1485) +- [NEW] Upgrade dependency libraries [#1491](https://github.com/gin-gonic/gin/pull/1491) + + +## Gin v1.3.0 + +- [NEW] Add [`func (*Context) QueryMap`](https://godoc.org/github.com/gin-gonic/gin#Context.QueryMap), [`func (*Context) GetQueryMap`](https://godoc.org/github.com/gin-gonic/gin#Context.GetQueryMap), [`func (*Context) PostFormMap`](https://godoc.org/github.com/gin-gonic/gin#Context.PostFormMap) and [`func (*Context) GetPostFormMap`](https://godoc.org/github.com/gin-gonic/gin#Context.GetPostFormMap) to support `type map[string]string` as query string or form parameters, see [#1383](https://github.com/gin-gonic/gin/pull/1383) +- [NEW] Add [`func (*Context) AsciiJSON`](https://godoc.org/github.com/gin-gonic/gin#Context.AsciiJSON), see [#1358](https://github.com/gin-gonic/gin/pull/1358) +- [NEW] Add `Pusher()` in [`type ResponseWriter`](https://godoc.org/github.com/gin-gonic/gin#ResponseWriter) for supporting http2 push, see [#1273](https://github.com/gin-gonic/gin/pull/1273) +- [NEW] Add [`func (*Context) DataFromReader`](https://godoc.org/github.com/gin-gonic/gin#Context.DataFromReader) for serving dynamic data, see [#1304](https://github.com/gin-gonic/gin/pull/1304) +- [NEW] Add [`func (*Context) ShouldBindBodyWith`](https://godoc.org/github.com/gin-gonic/gin#Context.ShouldBindBodyWith) allowing to call binding multiple times, see [#1341](https://github.com/gin-gonic/gin/pull/1341) +- [NEW] Support pointers in form binding, see [#1336](https://github.com/gin-gonic/gin/pull/1336) +- [NEW] Add [`func (*Context) JSONP`](https://godoc.org/github.com/gin-gonic/gin#Context.JSONP), see [#1333](https://github.com/gin-gonic/gin/pull/1333) +- [NEW] Support default value in form binding, see [#1138](https://github.com/gin-gonic/gin/pull/1138) +- [NEW] Expose validator engine in [`type StructValidator`](https://godoc.org/github.com/gin-gonic/gin/binding#StructValidator), see [#1277](https://github.com/gin-gonic/gin/pull/1277) +- [NEW] Add [`func (*Context) ShouldBind`](https://godoc.org/github.com/gin-gonic/gin#Context.ShouldBind), [`func (*Context) ShouldBindQuery`](https://godoc.org/github.com/gin-gonic/gin#Context.ShouldBindQuery) and [`func (*Context) ShouldBindJSON`](https://godoc.org/github.com/gin-gonic/gin#Context.ShouldBindJSON), see [#1047](https://github.com/gin-gonic/gin/pull/1047) +- [NEW] Add support for `time.Time` location in form binding, see [#1117](https://github.com/gin-gonic/gin/pull/1117) +- [NEW] Add [`func (*Context) BindQuery`](https://godoc.org/github.com/gin-gonic/gin#Context.BindQuery), see [#1029](https://github.com/gin-gonic/gin/pull/1029) +- [NEW] Make [jsonite](https://github.com/json-iterator/go) optional with build tags, see [#1026](https://github.com/gin-gonic/gin/pull/1026) +- [NEW] Show query string in logger, see [#999](https://github.com/gin-gonic/gin/pull/999) +- [NEW] Add [`func (*Context) SecureJSON`](https://godoc.org/github.com/gin-gonic/gin#Context.SecureJSON), see [#987](https://github.com/gin-gonic/gin/pull/987) and [#993](https://github.com/gin-gonic/gin/pull/993) +- [DEPRECATE] `func (*Context) GetCookie` for [`func (*Context) Cookie`](https://godoc.org/github.com/gin-gonic/gin#Context.Cookie) +- [FIX] Don't display color tags if [`func DisableConsoleColor`](https://godoc.org/github.com/gin-gonic/gin#DisableConsoleColor) called, see [#1072](https://github.com/gin-gonic/gin/pull/1072) +- [FIX] Gin Mode `""` when calling [`func Mode`](https://godoc.org/github.com/gin-gonic/gin#Mode) now returns `const DebugMode`, see [#1250](https://github.com/gin-gonic/gin/pull/1250) +- [FIX] `Flush()` now doesn't overwrite `responseWriter` status code, see [#1460](https://github.com/gin-gonic/gin/pull/1460) + +## Gin 1.2.0 + +- [NEW] Switch from godeps to govendor +- [NEW] Add support for Let's Encrypt via gin-gonic/autotls +- [NEW] Improve README examples and add extra at examples folder +- [NEW] Improved support with App Engine +- [NEW] Add custom template delimiters, see #860 +- [NEW] Add Template Func Maps, see #962 +- [NEW] Add \*context.Handler(), see #928 +- [NEW] Add \*context.GetRawData() +- [NEW] Add \*context.GetHeader() (request) +- [NEW] Add \*context.AbortWithStatusJSON() (JSON content type) +- [NEW] Add \*context.Keys type cast helpers +- [NEW] Add \*context.ShouldBindWith() +- [NEW] Add \*context.MustBindWith() +- [NEW] Add \*engine.SetFuncMap() +- [DEPRECATE] On next release: \*context.BindWith(), see #855 +- [FIX] Refactor render +- [FIX] Reworked tests +- [FIX] logger now supports cygwin +- [FIX] Use X-Forwarded-For before X-Real-Ip +- [FIX] time.Time binding (#904) + +## Gin 1.1.4 + +- [NEW] Support google appengine for IsTerminal func + +## Gin 1.1.3 + +- [FIX] Reverted Logger: skip ANSI color commands + +## Gin 1.1 + +- [NEW] Implement QueryArray and PostArray methods +- [NEW] Refactor GetQuery and GetPostForm +- [NEW] Add contribution guide +- [FIX] Corrected typos in README +- [FIX] Removed additional Iota +- [FIX] Changed imports to gopkg instead of github in README (#733) +- [FIX] Logger: skip ANSI color commands if output is not a tty + +## Gin 1.0rc2 (...) + +- [PERFORMANCE] Fast path for writing Content-Type. +- [PERFORMANCE] Much faster 404 routing +- [PERFORMANCE] Allocation optimizations +- [PERFORMANCE] Faster root tree lookup +- [PERFORMANCE] Zero overhead, String() and JSON() rendering. +- [PERFORMANCE] Faster ClientIP parsing +- [PERFORMANCE] Much faster SSE implementation +- [NEW] Benchmarks suite +- [NEW] Bind validation can be disabled and replaced with custom validators. +- [NEW] More flexible HTML render +- [NEW] Multipart and PostForm bindings +- [NEW] Adds method to return all the registered routes +- [NEW] Context.HandlerName() returns the main handler's name +- [NEW] Adds Error.IsType() helper +- [FIX] Binding multipart form +- [FIX] Integration tests +- [FIX] Crash when binding non struct object in Context. +- [FIX] RunTLS() implementation +- [FIX] Logger() unit tests +- [FIX] Adds SetHTMLTemplate() warning +- [FIX] Context.IsAborted() +- [FIX] More unit tests +- [FIX] JSON, XML, HTML renders accept custom content-types +- [FIX] gin.AbortIndex is unexported +- [FIX] Better approach to avoid directory listing in StaticFS() +- [FIX] Context.ClientIP() always returns the IP with trimmed spaces. +- [FIX] Better warning when running in debug mode. +- [FIX] Google App Engine integration. debugPrint does not use os.Stdout +- [FIX] Fixes integer overflow in error type +- [FIX] Error implements the json.Marshaller interface +- [FIX] MIT license in every file + + +## Gin 1.0rc1 (May 22, 2015) + +- [PERFORMANCE] Zero allocation router +- [PERFORMANCE] Faster JSON, XML and text rendering +- [PERFORMANCE] Custom hand optimized HttpRouter for Gin +- [PERFORMANCE] Misc code optimizations. Inlining, tail call optimizations +- [NEW] Built-in support for golang.org/x/net/context +- [NEW] Any(path, handler). Create a route that matches any path +- [NEW] Refactored rendering pipeline (faster and static typed) +- [NEW] Refactored errors API +- [NEW] IndentedJSON() prints pretty JSON +- [NEW] Added gin.DefaultWriter +- [NEW] UNIX socket support +- [NEW] RouterGroup.BasePath is exposed +- [NEW] JSON validation using go-validate-yourself (very powerful options) +- [NEW] Completed suite of unit tests +- [NEW] HTTP streaming with c.Stream() +- [NEW] StaticFile() creates a router for serving just one file. +- [NEW] StaticFS() has an option to disable directory listing. +- [NEW] StaticFS() for serving static files through virtual filesystems +- [NEW] Server-Sent Events native support +- [NEW] WrapF() and WrapH() helpers for wrapping http.HandlerFunc and http.Handler +- [NEW] Added LoggerWithWriter() middleware +- [NEW] Added RecoveryWithWriter() middleware +- [NEW] Added DefaultPostFormValue() +- [NEW] Added DefaultFormValue() +- [NEW] Added DefaultParamValue() +- [FIX] BasicAuth() when using custom realm +- [FIX] Bug when serving static files in nested routing group +- [FIX] Redirect using built-in http.Redirect() +- [FIX] Logger when printing the requested path +- [FIX] Documentation typos +- [FIX] Context.Engine renamed to Context.engine +- [FIX] Better debugging messages +- [FIX] ErrorLogger +- [FIX] Debug HTTP render +- [FIX] Refactored binding and render modules +- [FIX] Refactored Context initialization +- [FIX] Refactored BasicAuth() +- [FIX] NoMethod/NoRoute handlers +- [FIX] Hijacking http +- [FIX] Better support for Google App Engine (using log instead of fmt) + + +## Gin 0.6 (Mar 9, 2015) + +- [NEW] Support multipart/form-data +- [NEW] NoMethod handler +- [NEW] Validate sub structures +- [NEW] Support for HTTP Realm Auth +- [FIX] Unsigned integers in binding +- [FIX] Improve color logger + + +## Gin 0.5 (Feb 7, 2015) + +- [NEW] Content Negotiation +- [FIX] Solved security bug that allow a client to spoof ip +- [FIX] Fix unexported/ignored fields in binding + + +## Gin 0.4 (Aug 21, 2014) + +- [NEW] Development mode +- [NEW] Unit tests +- [NEW] Add Content.Redirect() +- [FIX] Deferring WriteHeader() +- [FIX] Improved documentation for model binding + + +## Gin 0.3 (Jul 18, 2014) + +- [PERFORMANCE] Normal log and error log are printed in the same call. +- [PERFORMANCE] Improve performance of NoRouter() +- [PERFORMANCE] Improve context's memory locality, reduce CPU cache faults. +- [NEW] Flexible rendering API +- [NEW] Add Context.File() +- [NEW] Add shortcut RunTLS() for http.ListenAndServeTLS +- [FIX] Rename NotFound404() to NoRoute() +- [FIX] Errors in context are purged +- [FIX] Adds HEAD method in Static file serving +- [FIX] Refactors Static() file serving +- [FIX] Using keyed initialization to fix app-engine integration +- [FIX] Can't unmarshal JSON array, #63 +- [FIX] Renaming Context.Req to Context.Request +- [FIX] Check application/x-www-form-urlencoded when parsing form + + +## Gin 0.2b (Jul 08, 2014) +- [PERFORMANCE] Using sync.Pool to allocatio/gc overhead +- [NEW] Travis CI integration +- [NEW] Completely new logger +- [NEW] New API for serving static files. gin.Static() +- [NEW] gin.H() can be serialized into XML +- [NEW] Typed errors. Errors can be typed. Internet/external/custom. +- [NEW] Support for Godeps +- [NEW] Travis/Godocs badges in README +- [NEW] New Bind() and BindWith() methods for parsing request body. +- [NEW] Add Content.Copy() +- [NEW] Add context.LastError() +- [NEW] Add shortcut for OPTIONS HTTP method +- [FIX] Tons of README fixes +- [FIX] Header is written before body +- [FIX] BasicAuth() and changes API a little bit +- [FIX] Recovery() middleware only prints panics +- [FIX] Context.Get() does not panic anymore. Use MustGet() instead. +- [FIX] Multiple http.WriteHeader() in NotFound handlers +- [FIX] Engine.Run() panics if http server can't be set up +- [FIX] Crash when route path doesn't start with '/' +- [FIX] Do not update header when status code is negative +- [FIX] Setting response headers before calling WriteHeader in context.String() +- [FIX] Add MIT license +- [FIX] Changes behaviour of ErrorLogger() and Logger() diff --git a/vendor/github.com/gin-gonic/gin/CODE_OF_CONDUCT.md b/vendor/github.com/gin-gonic/gin/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..4ea14f3 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/CODE_OF_CONDUCT.md @@ -0,0 +1,46 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at teamgingonic@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff --git a/vendor/github.com/gin-gonic/gin/CONTRIBUTING.md b/vendor/github.com/gin-gonic/gin/CONTRIBUTING.md new file mode 100644 index 0000000..d1c723c --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/CONTRIBUTING.md @@ -0,0 +1,13 @@ +## Contributing + +- With issues: + - Use the search tool before opening a new issue. + - Please provide source code and commit sha if you found a bug. + - Review existing issues and provide feedback or react to them. + +- With pull requests: + - Open your pull request against `master` + - Your pull request should have no more than two commits, if not you should squash them. + - It should pass all tests in the available continuous integration systems such as GitHub Actions. + - You should add/modify tests to cover your proposed code changes. + - If your pull request contains a new feature, please document it on the README. diff --git a/vendor/github.com/gin-gonic/gin/LICENSE b/vendor/github.com/gin-gonic/gin/LICENSE new file mode 100644 index 0000000..1ff7f37 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Manuel Martínez-Almeida + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/gin-gonic/gin/Makefile b/vendor/github.com/gin-gonic/gin/Makefile new file mode 100644 index 0000000..5d55b44 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/Makefile @@ -0,0 +1,77 @@ +GO ?= go +GOFMT ?= gofmt "-s" +GO_VERSION=$(shell $(GO) version | cut -c 14- | cut -d' ' -f1 | cut -d'.' -f2) +PACKAGES ?= $(shell $(GO) list ./...) +VETPACKAGES ?= $(shell $(GO) list ./... | grep -v /examples/) +GOFILES := $(shell find . -name "*.go") +TESTFOLDER := $(shell $(GO) list ./... | grep -E 'gin$$|binding$$|render$$' | grep -v examples) +TESTTAGS ?= "" + +.PHONY: test +test: + echo "mode: count" > coverage.out + for d in $(TESTFOLDER); do \ + $(GO) test -tags $(TESTTAGS) -v -covermode=count -coverprofile=profile.out $$d > tmp.out; \ + cat tmp.out; \ + if grep -q "^--- FAIL" tmp.out; then \ + rm tmp.out; \ + exit 1; \ + elif grep -q "build failed" tmp.out; then \ + rm tmp.out; \ + exit 1; \ + elif grep -q "setup failed" tmp.out; then \ + rm tmp.out; \ + exit 1; \ + fi; \ + if [ -f profile.out ]; then \ + cat profile.out | grep -v "mode:" >> coverage.out; \ + rm profile.out; \ + fi; \ + done + +.PHONY: fmt +fmt: + $(GOFMT) -w $(GOFILES) + +.PHONY: fmt-check +fmt-check: + @diff=$$($(GOFMT) -d $(GOFILES)); \ + if [ -n "$$diff" ]; then \ + echo "Please run 'make fmt' and commit the result:"; \ + echo "$${diff}"; \ + exit 1; \ + fi; + +vet: + $(GO) vet $(VETPACKAGES) + +.PHONY: lint +lint: + @hash golint > /dev/null 2>&1; if [ $$? -ne 0 ]; then \ + $(GO) get -u golang.org/x/lint/golint; \ + fi + for PKG in $(PACKAGES); do golint -set_exit_status $$PKG || exit 1; done; + +.PHONY: misspell-check +misspell-check: + @hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \ + $(GO) get -u github.com/client9/misspell/cmd/misspell; \ + fi + misspell -error $(GOFILES) + +.PHONY: misspell +misspell: + @hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \ + $(GO) get -u github.com/client9/misspell/cmd/misspell; \ + fi + misspell -w $(GOFILES) + +.PHONY: tools +tools: + @if [ $(GO_VERSION) -gt 15 ]; then \ + $(GO) install golang.org/x/lint/golint@latest; \ + $(GO) install github.com/client9/misspell/cmd/misspell@latest; \ + elif [ $(GO_VERSION) -lt 16 ]; then \ + $(GO) install golang.org/x/lint/golint; \ + $(GO) install github.com/client9/misspell/cmd/misspell; \ + fi diff --git a/vendor/github.com/gin-gonic/gin/README.md b/vendor/github.com/gin-gonic/gin/README.md new file mode 100644 index 0000000..5cc8321 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/README.md @@ -0,0 +1,2348 @@ +# Gin Web Framework + + + +[![Build Status](https://github.com/gin-gonic/gin/workflows/Run%20Tests/badge.svg?branch=master)](https://github.com/gin-gonic/gin/actions?query=branch%3Amaster) +[![codecov](https://codecov.io/gh/gin-gonic/gin/branch/master/graph/badge.svg)](https://codecov.io/gh/gin-gonic/gin) +[![Go Report Card](https://goreportcard.com/badge/github.com/gin-gonic/gin)](https://goreportcard.com/report/github.com/gin-gonic/gin) +[![GoDoc](https://pkg.go.dev/badge/github.com/gin-gonic/gin?status.svg)](https://pkg.go.dev/github.com/gin-gonic/gin?tab=doc) +[![Join the chat at https://gitter.im/gin-gonic/gin](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/gin-gonic/gin?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![Sourcegraph](https://sourcegraph.com/github.com/gin-gonic/gin/-/badge.svg)](https://sourcegraph.com/github.com/gin-gonic/gin?badge) +[![Open Source Helpers](https://www.codetriage.com/gin-gonic/gin/badges/users.svg)](https://www.codetriage.com/gin-gonic/gin) +[![Release](https://img.shields.io/github/release/gin-gonic/gin.svg?style=flat-square)](https://github.com/gin-gonic/gin/releases) +[![TODOs](https://badgen.net/https/api.tickgit.com/badgen/github.com/gin-gonic/gin)](https://www.tickgit.com/browse?repo=github.com/gin-gonic/gin) + +Gin is a web framework written in Go (Golang). It features a martini-like API with performance that is up to 40 times faster thanks to [httprouter](https://github.com/julienschmidt/httprouter). If you need performance and good productivity, you will love Gin. + + +## Contents + +- [Gin Web Framework](#gin-web-framework) + - [Contents](#contents) + - [Installation](#installation) + - [Quick start](#quick-start) + - [Benchmarks](#benchmarks) + - [Gin v1. stable](#gin-v1-stable) + - [Build with jsoniter/go-json](#build-with-json-replacement) + - [Build without `MsgPack` rendering feature](#build-without-msgpack-rendering-feature) + - [API Examples](#api-examples) + - [Using GET, POST, PUT, PATCH, DELETE and OPTIONS](#using-get-post-put-patch-delete-and-options) + - [Parameters in path](#parameters-in-path) + - [Querystring parameters](#querystring-parameters) + - [Multipart/Urlencoded Form](#multiparturlencoded-form) + - [Another example: query + post form](#another-example-query--post-form) + - [Map as querystring or postform parameters](#map-as-querystring-or-postform-parameters) + - [Upload files](#upload-files) + - [Single file](#single-file) + - [Multiple files](#multiple-files) + - [Grouping routes](#grouping-routes) + - [Blank Gin without middleware by default](#blank-gin-without-middleware-by-default) + - [Using middleware](#using-middleware) + - [How to write log file](#how-to-write-log-file) + - [Custom Log Format](#custom-log-format) + - [Controlling Log output coloring](#controlling-log-output-coloring) + - [Model binding and validation](#model-binding-and-validation) + - [Custom Validators](#custom-validators) + - [Only Bind Query String](#only-bind-query-string) + - [Bind Query String or Post Data](#bind-query-string-or-post-data) + - [Bind Uri](#bind-uri) + - [Bind Header](#bind-header) + - [Bind HTML checkboxes](#bind-html-checkboxes) + - [Multipart/Urlencoded binding](#multiparturlencoded-binding) + - [XML, JSON, YAML and ProtoBuf rendering](#xml-json-yaml-and-protobuf-rendering) + - [SecureJSON](#securejson) + - [JSONP](#jsonp) + - [AsciiJSON](#asciijson) + - [PureJSON](#purejson) + - [Serving static files](#serving-static-files) + - [Serving data from file](#serving-data-from-file) + - [Serving data from reader](#serving-data-from-reader) + - [HTML rendering](#html-rendering) + - [Custom Template renderer](#custom-template-renderer) + - [Custom Delimiters](#custom-delimiters) + - [Custom Template Funcs](#custom-template-funcs) + - [Multitemplate](#multitemplate) + - [Redirects](#redirects) + - [Custom Middleware](#custom-middleware) + - [Using BasicAuth() middleware](#using-basicauth-middleware) + - [Goroutines inside a middleware](#goroutines-inside-a-middleware) + - [Custom HTTP configuration](#custom-http-configuration) + - [Support Let's Encrypt](#support-lets-encrypt) + - [Run multiple service using Gin](#run-multiple-service-using-gin) + - [Graceful shutdown or restart](#graceful-shutdown-or-restart) + - [Third-party packages](#third-party-packages) + - [Manually](#manually) + - [Build a single binary with templates](#build-a-single-binary-with-templates) + - [Bind form-data request with custom struct](#bind-form-data-request-with-custom-struct) + - [Try to bind body into different structs](#try-to-bind-body-into-different-structs) + - [http2 server push](#http2-server-push) + - [Define format for the log of routes](#define-format-for-the-log-of-routes) + - [Set and get a cookie](#set-and-get-a-cookie) + - [Don't trust all proxies](#dont-trust-all-proxies) + - [Testing](#testing) + - [Users](#users) + +## Installation + +To install Gin package, you need to install Go and set your Go workspace first. + +1. You first need [Go](https://golang.org/) installed (**version 1.14+ is required**), then you can use the below Go command to install Gin. + +```sh +$ go get -u github.com/gin-gonic/gin +``` + +2. Import it in your code: + +```go +import "github.com/gin-gonic/gin" +``` + +3. (Optional) Import `net/http`. This is required for example if using constants such as `http.StatusOK`. + +```go +import "net/http" +``` + +## Quick start + +```sh +# assume the following codes in example.go file +$ cat example.go +``` + +```go +package main + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +func main() { + r := gin.Default() + r.GET("/ping", func(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{ + "message": "pong", + }) + }) + r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080") +} +``` + +``` +# run example.go and visit 0.0.0.0:8080/ping (for windows "localhost:8080/ping") on browser +$ go run example.go +``` + +## Benchmarks + +Gin uses a custom version of [HttpRouter](https://github.com/julienschmidt/httprouter) + +[See all benchmarks](/BENCHMARKS.md) + +| Benchmark name | (1) | (2) | (3) | (4) | +| ------------------------------ | ---------:| ---------------:| ------------:| ---------------:| +| BenchmarkGin_GithubAll | **43550** | **27364 ns/op** | **0 B/op** | **0 allocs/op** | +| BenchmarkAce_GithubAll | 40543 | 29670 ns/op | 0 B/op | 0 allocs/op | +| BenchmarkAero_GithubAll | 57632 | 20648 ns/op | 0 B/op | 0 allocs/op | +| BenchmarkBear_GithubAll | 9234 | 216179 ns/op | 86448 B/op | 943 allocs/op | +| BenchmarkBeego_GithubAll | 7407 | 243496 ns/op | 71456 B/op | 609 allocs/op | +| BenchmarkBone_GithubAll | 420 | 2922835 ns/op | 720160 B/op | 8620 allocs/op | +| BenchmarkChi_GithubAll | 7620 | 238331 ns/op | 87696 B/op | 609 allocs/op | +| BenchmarkDenco_GithubAll | 18355 | 64494 ns/op | 20224 B/op | 167 allocs/op | +| BenchmarkEcho_GithubAll | 31251 | 38479 ns/op | 0 B/op | 0 allocs/op | +| BenchmarkGocraftWeb_GithubAll | 4117 | 300062 ns/op | 131656 B/op | 1686 allocs/op | +| BenchmarkGoji_GithubAll | 3274 | 416158 ns/op | 56112 B/op | 334 allocs/op | +| BenchmarkGojiv2_GithubAll | 1402 | 870518 ns/op | 352720 B/op | 4321 allocs/op | +| BenchmarkGoJsonRest_GithubAll | 2976 | 401507 ns/op | 134371 B/op | 2737 allocs/op | +| BenchmarkGoRestful_GithubAll | 410 | 2913158 ns/op | 910144 B/op | 2938 allocs/op | +| BenchmarkGorillaMux_GithubAll | 346 | 3384987 ns/op | 251650 B/op | 1994 allocs/op | +| BenchmarkGowwwRouter_GithubAll | 10000 | 143025 ns/op | 72144 B/op | 501 allocs/op | +| BenchmarkHttpRouter_GithubAll | 55938 | 21360 ns/op | 0 B/op | 0 allocs/op | +| BenchmarkHttpTreeMux_GithubAll | 10000 | 153944 ns/op | 65856 B/op | 671 allocs/op | +| BenchmarkKocha_GithubAll | 10000 | 106315 ns/op | 23304 B/op | 843 allocs/op | +| BenchmarkLARS_GithubAll | 47779 | 25084 ns/op | 0 B/op | 0 allocs/op | +| BenchmarkMacaron_GithubAll | 3266 | 371907 ns/op | 149409 B/op | 1624 allocs/op | +| BenchmarkMartini_GithubAll | 331 | 3444706 ns/op | 226551 B/op | 2325 allocs/op | +| BenchmarkPat_GithubAll | 273 | 4381818 ns/op | 1483152 B/op | 26963 allocs/op | +| BenchmarkPossum_GithubAll | 10000 | 164367 ns/op | 84448 B/op | 609 allocs/op | +| BenchmarkR2router_GithubAll | 10000 | 160220 ns/op | 77328 B/op | 979 allocs/op | +| BenchmarkRivet_GithubAll | 14625 | 82453 ns/op | 16272 B/op | 167 allocs/op | +| BenchmarkTango_GithubAll | 6255 | 279611 ns/op | 63826 B/op | 1618 allocs/op | +| BenchmarkTigerTonic_GithubAll | 2008 | 687874 ns/op | 193856 B/op | 4474 allocs/op | +| BenchmarkTraffic_GithubAll | 355 | 3478508 ns/op | 820744 B/op | 14114 allocs/op | +| BenchmarkVulcan_GithubAll | 6885 | 193333 ns/op | 19894 B/op | 609 allocs/op | + +- (1): Total Repetitions achieved in constant time, higher means more confident result +- (2): Single Repetition Duration (ns/op), lower is better +- (3): Heap Memory (B/op), lower is better +- (4): Average Allocations per Repetition (allocs/op), lower is better + +## Gin v1. stable + +- [x] Zero allocation router. +- [x] Still the fastest http router and framework. From routing to writing. +- [x] Complete suite of unit tests. +- [x] Battle tested. +- [x] API frozen, new releases will not break your code. + +## Build with json replacement + +Gin uses `encoding/json` as default json package but you can change it by build from other tags. + +[jsoniter](https://github.com/json-iterator/go) +```sh +$ go build -tags=jsoniter . +``` +[go-json](https://github.com/goccy/go-json) +```sh +$ go build -tags=go_json . +``` + +## Build without `MsgPack` rendering feature + +Gin enables `MsgPack` rendering feature by default. But you can disable this feature by specifying `nomsgpack` build tag. + +```sh +$ go build -tags=nomsgpack . +``` + +This is useful to reduce the binary size of executable files. See the [detail information](https://github.com/gin-gonic/gin/pull/1852). + +## API Examples + +You can find a number of ready-to-run examples at [Gin examples repository](https://github.com/gin-gonic/examples). + +### Using GET, POST, PUT, PATCH, DELETE and OPTIONS + +```go +func main() { + // Creates a gin router with default middleware: + // logger and recovery (crash-free) middleware + router := gin.Default() + + router.GET("/someGet", getting) + router.POST("/somePost", posting) + router.PUT("/somePut", putting) + router.DELETE("/someDelete", deleting) + router.PATCH("/somePatch", patching) + router.HEAD("/someHead", head) + router.OPTIONS("/someOptions", options) + + // By default it serves on :8080 unless a + // PORT environment variable was defined. + router.Run() + // router.Run(":3000") for a hard coded port +} +``` + +### Parameters in path + +```go +func main() { + router := gin.Default() + + // This handler will match /user/john but will not match /user/ or /user + router.GET("/user/:name", func(c *gin.Context) { + name := c.Param("name") + c.String(http.StatusOK, "Hello %s", name) + }) + + // However, this one will match /user/john/ and also /user/john/send + // If no other routers match /user/john, it will redirect to /user/john/ + router.GET("/user/:name/*action", func(c *gin.Context) { + name := c.Param("name") + action := c.Param("action") + message := name + " is " + action + c.String(http.StatusOK, message) + }) + + // For each matched request Context will hold the route definition + router.POST("/user/:name/*action", func(c *gin.Context) { + b := c.FullPath() == "/user/:name/*action" // true + c.String(http.StatusOK, "%t", b) + }) + + // This handler will add a new router for /user/groups. + // Exact routes are resolved before param routes, regardless of the order they were defined. + // Routes starting with /user/groups are never interpreted as /user/:name/... routes + router.GET("/user/groups", func(c *gin.Context) { + c.String(http.StatusOK, "The available groups are [...]") + }) + + router.Run(":8080") +} +``` + +### Querystring parameters + +```go +func main() { + router := gin.Default() + + // Query string parameters are parsed using the existing underlying request object. + // The request responds to a url matching: /welcome?firstname=Jane&lastname=Doe + router.GET("/welcome", func(c *gin.Context) { + firstname := c.DefaultQuery("firstname", "Guest") + lastname := c.Query("lastname") // shortcut for c.Request.URL.Query().Get("lastname") + + c.String(http.StatusOK, "Hello %s %s", firstname, lastname) + }) + router.Run(":8080") +} +``` + +### Multipart/Urlencoded Form + +```go +func main() { + router := gin.Default() + + router.POST("/form_post", func(c *gin.Context) { + message := c.PostForm("message") + nick := c.DefaultPostForm("nick", "anonymous") + + c.JSON(http.StatusOK, gin.H{ + "status": "posted", + "message": message, + "nick": nick, + }) + }) + router.Run(":8080") +} +``` + +### Another example: query + post form + +``` +POST /post?id=1234&page=1 HTTP/1.1 +Content-Type: application/x-www-form-urlencoded + +name=manu&message=this_is_great +``` + +```go +func main() { + router := gin.Default() + + router.POST("/post", func(c *gin.Context) { + + id := c.Query("id") + page := c.DefaultQuery("page", "0") + name := c.PostForm("name") + message := c.PostForm("message") + + fmt.Printf("id: %s; page: %s; name: %s; message: %s", id, page, name, message) + }) + router.Run(":8080") +} +``` + +``` +id: 1234; page: 1; name: manu; message: this_is_great +``` + +### Map as querystring or postform parameters + +``` +POST /post?ids[a]=1234&ids[b]=hello HTTP/1.1 +Content-Type: application/x-www-form-urlencoded + +names[first]=thinkerou&names[second]=tianou +``` + +```go +func main() { + router := gin.Default() + + router.POST("/post", func(c *gin.Context) { + + ids := c.QueryMap("ids") + names := c.PostFormMap("names") + + fmt.Printf("ids: %v; names: %v", ids, names) + }) + router.Run(":8080") +} +``` + +``` +ids: map[b:hello a:1234]; names: map[second:tianou first:thinkerou] +``` + +### Upload files + +#### Single file + +References issue [#774](https://github.com/gin-gonic/gin/issues/774) and detail [example code](https://github.com/gin-gonic/examples/tree/master/upload-file/single). + +`file.Filename` **SHOULD NOT** be trusted. See [`Content-Disposition` on MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#Directives) and [#1693](https://github.com/gin-gonic/gin/issues/1693) + +> The filename is always optional and must not be used blindly by the application: path information should be stripped, and conversion to the server file system rules should be done. + +```go +func main() { + router := gin.Default() + // Set a lower memory limit for multipart forms (default is 32 MiB) + router.MaxMultipartMemory = 8 << 20 // 8 MiB + router.POST("/upload", func(c *gin.Context) { + // Single file + file, _ := c.FormFile("file") + log.Println(file.Filename) + + // Upload the file to specific dst. + c.SaveUploadedFile(file, dst) + + c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename)) + }) + router.Run(":8080") +} +``` + +How to `curl`: + +```bash +curl -X POST http://localhost:8080/upload \ + -F "file=@/Users/appleboy/test.zip" \ + -H "Content-Type: multipart/form-data" +``` + +#### Multiple files + +See the detail [example code](https://github.com/gin-gonic/examples/tree/master/upload-file/multiple). + +```go +func main() { + router := gin.Default() + // Set a lower memory limit for multipart forms (default is 32 MiB) + router.MaxMultipartMemory = 8 << 20 // 8 MiB + router.POST("/upload", func(c *gin.Context) { + // Multipart form + form, _ := c.MultipartForm() + files := form.File["upload[]"] + + for _, file := range files { + log.Println(file.Filename) + + // Upload the file to specific dst. + c.SaveUploadedFile(file, dst) + } + c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files))) + }) + router.Run(":8080") +} +``` + +How to `curl`: + +```bash +curl -X POST http://localhost:8080/upload \ + -F "upload[]=@/Users/appleboy/test1.zip" \ + -F "upload[]=@/Users/appleboy/test2.zip" \ + -H "Content-Type: multipart/form-data" +``` + +### Grouping routes + +```go +func main() { + router := gin.Default() + + // Simple group: v1 + v1 := router.Group("/v1") + { + v1.POST("/login", loginEndpoint) + v1.POST("/submit", submitEndpoint) + v1.POST("/read", readEndpoint) + } + + // Simple group: v2 + v2 := router.Group("/v2") + { + v2.POST("/login", loginEndpoint) + v2.POST("/submit", submitEndpoint) + v2.POST("/read", readEndpoint) + } + + router.Run(":8080") +} +``` + +### Blank Gin without middleware by default + +Use + +```go +r := gin.New() +``` + +instead of + +```go +// Default With the Logger and Recovery middleware already attached +r := gin.Default() +``` + + +### Using middleware +```go +func main() { + // Creates a router without any middleware by default + r := gin.New() + + // Global middleware + // Logger middleware will write the logs to gin.DefaultWriter even if you set with GIN_MODE=release. + // By default gin.DefaultWriter = os.Stdout + r.Use(gin.Logger()) + + // Recovery middleware recovers from any panics and writes a 500 if there was one. + r.Use(gin.Recovery()) + + // Per route middleware, you can add as many as you desire. + r.GET("/benchmark", MyBenchLogger(), benchEndpoint) + + // Authorization group + // authorized := r.Group("/", AuthRequired()) + // exactly the same as: + authorized := r.Group("/") + // per group middleware! in this case we use the custom created + // AuthRequired() middleware just in the "authorized" group. + authorized.Use(AuthRequired()) + { + authorized.POST("/login", loginEndpoint) + authorized.POST("/submit", submitEndpoint) + authorized.POST("/read", readEndpoint) + + // nested group + testing := authorized.Group("testing") + // visit 0.0.0.0:8080/testing/analytics + testing.GET("/analytics", analyticsEndpoint) + } + + // Listen and serve on 0.0.0.0:8080 + r.Run(":8080") +} +``` + +### Custom Recovery behavior +```go +func main() { + // Creates a router without any middleware by default + r := gin.New() + + // Global middleware + // Logger middleware will write the logs to gin.DefaultWriter even if you set with GIN_MODE=release. + // By default gin.DefaultWriter = os.Stdout + r.Use(gin.Logger()) + + // Recovery middleware recovers from any panics and writes a 500 if there was one. + r.Use(gin.CustomRecovery(func(c *gin.Context, recovered interface{}) { + if err, ok := recovered.(string); ok { + c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err)) + } + c.AbortWithStatus(http.StatusInternalServerError) + })) + + r.GET("/panic", func(c *gin.Context) { + // panic with a string -- the custom middleware could save this to a database or report it to the user + panic("foo") + }) + + r.GET("/", func(c *gin.Context) { + c.String(http.StatusOK, "ohai") + }) + + // Listen and serve on 0.0.0.0:8080 + r.Run(":8080") +} +``` + +### How to write log file +```go +func main() { + // Disable Console Color, you don't need console color when writing the logs to file. + gin.DisableConsoleColor() + + // Logging to a file. + f, _ := os.Create("gin.log") + gin.DefaultWriter = io.MultiWriter(f) + + // Use the following code if you need to write the logs to file and console at the same time. + // gin.DefaultWriter = io.MultiWriter(f, os.Stdout) + + router := gin.Default() + router.GET("/ping", func(c *gin.Context) { + c.String(http.StatusOK, "pong") + }) + +    router.Run(":8080") +} +``` + +### Custom Log Format +```go +func main() { + router := gin.New() + + // LoggerWithFormatter middleware will write the logs to gin.DefaultWriter + // By default gin.DefaultWriter = os.Stdout + router.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string { + + // your custom format + return fmt.Sprintf("%s - [%s] \"%s %s %s %d %s \"%s\" %s\"\n", + param.ClientIP, + param.TimeStamp.Format(time.RFC1123), + param.Method, + param.Path, + param.Request.Proto, + param.StatusCode, + param.Latency, + param.Request.UserAgent(), + param.ErrorMessage, + ) + })) + router.Use(gin.Recovery()) + + router.GET("/ping", func(c *gin.Context) { + c.String(http.StatusOK, "pong") + }) + + router.Run(":8080") +} +``` + +**Sample Output** +``` +::1 - [Fri, 07 Dec 2018 17:04:38 JST] "GET /ping HTTP/1.1 200 122.767µs "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36" " +``` + +### Controlling Log output coloring + +By default, logs output on console should be colorized depending on the detected TTY. + +Never colorize logs: + +```go +func main() { + // Disable log's color + gin.DisableConsoleColor() + + // Creates a gin router with default middleware: + // logger and recovery (crash-free) middleware + router := gin.Default() + + router.GET("/ping", func(c *gin.Context) { + c.String(http.StatusOK, "pong") + }) + + router.Run(":8080") +} +``` + +Always colorize logs: + +```go +func main() { + // Force log's color + gin.ForceConsoleColor() + + // Creates a gin router with default middleware: + // logger and recovery (crash-free) middleware + router := gin.Default() + + router.GET("/ping", func(c *gin.Context) { + c.String(http.StatusOK, "pong") + }) + + router.Run(":8080") +} +``` + +### Model binding and validation + +To bind a request body into a type, use model binding. We currently support binding of JSON, XML, YAML, TOML and standard form values (foo=bar&boo=baz). + +Gin uses [**go-playground/validator/v10**](https://github.com/go-playground/validator) for validation. Check the full docs on tags usage [here](https://godoc.org/github.com/go-playground/validator#hdr-Baked_In_Validators_and_Tags). + +Note that you need to set the corresponding binding tag on all fields you want to bind. For example, when binding from JSON, set `json:"fieldname"`. + +Also, Gin provides two sets of methods for binding: +- **Type** - Must bind + - **Methods** - `Bind`, `BindJSON`, `BindXML`, `BindQuery`, `BindYAML`, `BindHeader`, `BindTOML` + - **Behavior** - These methods use `MustBindWith` under the hood. If there is a binding error, the request is aborted with `c.AbortWithError(400, err).SetType(ErrorTypeBind)`. This sets the response status code to 400 and the `Content-Type` header is set to `text/plain; charset=utf-8`. Note that if you try to set the response code after this, it will result in a warning `[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422`. If you wish to have greater control over the behavior, consider using the `ShouldBind` equivalent method. +- **Type** - Should bind + - **Methods** - `ShouldBind`, `ShouldBindJSON`, `ShouldBindXML`, `ShouldBindQuery`, `ShouldBindYAML`, `ShouldBindHeader`, `ShouldBindTOML`, + - **Behavior** - These methods use `ShouldBindWith` under the hood. If there is a binding error, the error is returned and it is the developer's responsibility to handle the request and error appropriately. + +When using the Bind-method, Gin tries to infer the binder depending on the Content-Type header. If you are sure what you are binding, you can use `MustBindWith` or `ShouldBindWith`. + +You can also specify that specific fields are required. If a field is decorated with `binding:"required"` and has a empty value when binding, an error will be returned. + +```go +// Binding from JSON +type Login struct { + User string `form:"user" json:"user" xml:"user" binding:"required"` + Password string `form:"password" json:"password" xml:"password" binding:"required"` +} + +func main() { + router := gin.Default() + + // Example for binding JSON ({"user": "manu", "password": "123"}) + router.POST("/loginJSON", func(c *gin.Context) { + var json Login + if err := c.ShouldBindJSON(&json); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + + if json.User != "manu" || json.Password != "123" { + c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"}) + return + } + + c.JSON(http.StatusOK, gin.H{"status": "you are logged in"}) + }) + + // Example for binding XML ( + // + // + // manu + // 123 + // ) + router.POST("/loginXML", func(c *gin.Context) { + var xml Login + if err := c.ShouldBindXML(&xml); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + + if xml.User != "manu" || xml.Password != "123" { + c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"}) + return + } + + c.JSON(http.StatusOK, gin.H{"status": "you are logged in"}) + }) + + // Example for binding a HTML form (user=manu&password=123) + router.POST("/loginForm", func(c *gin.Context) { + var form Login + // This will infer what binder to use depending on the content-type header. + if err := c.ShouldBind(&form); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + + if form.User != "manu" || form.Password != "123" { + c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"}) + return + } + + c.JSON(http.StatusOK, gin.H{"status": "you are logged in"}) + }) + + // Listen and serve on 0.0.0.0:8080 + router.Run(":8080") +} +``` + +**Sample request** +```shell +$ curl -v -X POST \ + http://localhost:8080/loginJSON \ + -H 'content-type: application/json' \ + -d '{ "user": "manu" }' +> POST /loginJSON HTTP/1.1 +> Host: localhost:8080 +> User-Agent: curl/7.51.0 +> Accept: */* +> content-type: application/json +> Content-Length: 18 +> +* upload completely sent off: 18 out of 18 bytes +< HTTP/1.1 400 Bad Request +< Content-Type: application/json; charset=utf-8 +< Date: Fri, 04 Aug 2017 03:51:31 GMT +< Content-Length: 100 +< +{"error":"Key: 'Login.Password' Error:Field validation for 'Password' failed on the 'required' tag"} +``` + +**Skip validate** + +When running the above example using the above the `curl` command, it returns error. Because the example use `binding:"required"` for `Password`. If use `binding:"-"` for `Password`, then it will not return error when running the above example again. + +### Custom Validators + +It is also possible to register custom validators. See the [example code](https://github.com/gin-gonic/examples/tree/master/custom-validation/server.go). + +```go +package main + +import ( + "net/http" + "time" + + "github.com/gin-gonic/gin" + "github.com/gin-gonic/gin/binding" + "github.com/go-playground/validator/v10" +) + +// Booking contains binded and validated data. +type Booking struct { + CheckIn time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"` + CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckIn" time_format:"2006-01-02"` +} + +var bookableDate validator.Func = func(fl validator.FieldLevel) bool { + date, ok := fl.Field().Interface().(time.Time) + if ok { + today := time.Now() + if today.After(date) { + return false + } + } + return true +} + +func main() { + route := gin.Default() + + if v, ok := binding.Validator.Engine().(*validator.Validate); ok { + v.RegisterValidation("bookabledate", bookableDate) + } + + route.GET("/bookable", getBookable) + route.Run(":8085") +} + +func getBookable(c *gin.Context) { + var b Booking + if err := c.ShouldBindWith(&b, binding.Query); err == nil { + c.JSON(http.StatusOK, gin.H{"message": "Booking dates are valid!"}) + } else { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + } +} +``` + +```console +$ curl "localhost:8085/bookable?check_in=2030-04-16&check_out=2030-04-17" +{"message":"Booking dates are valid!"} + +$ curl "localhost:8085/bookable?check_in=2030-03-10&check_out=2030-03-09" +{"error":"Key: 'Booking.CheckOut' Error:Field validation for 'CheckOut' failed on the 'gtfield' tag"} + +$ curl "localhost:8085/bookable?check_in=2000-03-09&check_out=2000-03-10" +{"error":"Key: 'Booking.CheckIn' Error:Field validation for 'CheckIn' failed on the 'bookabledate' tag"}% +``` + +[Struct level validations](https://github.com/go-playground/validator/releases/tag/v8.7) can also be registered this way. +See the [struct-lvl-validation example](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations) to learn more. + +### Only Bind Query String + +`ShouldBindQuery` function only binds the query params and not the post data. See the [detail information](https://github.com/gin-gonic/gin/issues/742#issuecomment-315953017). + +```go +package main + +import ( + "log" + "net/http" + + "github.com/gin-gonic/gin" +) + +type Person struct { + Name string `form:"name"` + Address string `form:"address"` +} + +func main() { + route := gin.Default() + route.Any("/testing", startPage) + route.Run(":8085") +} + +func startPage(c *gin.Context) { + var person Person + if c.ShouldBindQuery(&person) == nil { + log.Println("====== Only Bind By Query String ======") + log.Println(person.Name) + log.Println(person.Address) + } + c.String(http.StatusOK, "Success") +} + +``` + +### Bind Query String or Post Data + +See the [detail information](https://github.com/gin-gonic/gin/issues/742#issuecomment-264681292). + +```go +package main + +import ( + "log" + "net/http" + "time" + + "github.com/gin-gonic/gin" +) + +type Person struct { + Name string `form:"name"` + Address string `form:"address"` + Birthday time.Time `form:"birthday" time_format:"2006-01-02" time_utc:"1"` + CreateTime time.Time `form:"createTime" time_format:"unixNano"` + UnixTime time.Time `form:"unixTime" time_format:"unix"` +} + +func main() { + route := gin.Default() + route.GET("/testing", startPage) + route.Run(":8085") +} + +func startPage(c *gin.Context) { + var person Person + // If `GET`, only `Form` binding engine (`query`) used. + // If `POST`, first checks the `content-type` for `JSON` or `XML`, then uses `Form` (`form-data`). + // See more at https://github.com/gin-gonic/gin/blob/master/binding/binding.go#L88 + if c.ShouldBind(&person) == nil { + log.Println(person.Name) + log.Println(person.Address) + log.Println(person.Birthday) + log.Println(person.CreateTime) + log.Println(person.UnixTime) + } + + c.String(http.StatusOK, "Success") +} +``` + +Test it with: +```sh +$ curl -X GET "localhost:8085/testing?name=appleboy&address=xyz&birthday=1992-03-15&createTime=1562400033000000123&unixTime=1562400033" +``` + +### Bind Uri + +See the [detail information](https://github.com/gin-gonic/gin/issues/846). + +```go +package main + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +type Person struct { + ID string `uri:"id" binding:"required,uuid"` + Name string `uri:"name" binding:"required"` +} + +func main() { + route := gin.Default() + route.GET("/:name/:id", func(c *gin.Context) { + var person Person + if err := c.ShouldBindUri(&person); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()}) + return + } + c.JSON(http.StatusOK, gin.H{"name": person.Name, "uuid": person.ID}) + }) + route.Run(":8088") +} +``` + +Test it with: +```sh +$ curl -v localhost:8088/thinkerou/987fbc97-4bed-5078-9f07-9141ba07c9f3 +$ curl -v localhost:8088/thinkerou/not-uuid +``` + +### Bind Header + +```go +package main + +import ( + "fmt" + "net/http" + + "github.com/gin-gonic/gin" +) + +type testHeader struct { + Rate int `header:"Rate"` + Domain string `header:"Domain"` +} + +func main() { + r := gin.Default() + r.GET("/", func(c *gin.Context) { + h := testHeader{} + + if err := c.ShouldBindHeader(&h); err != nil { + c.JSON(http.StatusOK, err) + } + + fmt.Printf("%#v\n", h) + c.JSON(http.StatusOK, gin.H{"Rate": h.Rate, "Domain": h.Domain}) + }) + + r.Run() + +// client +// curl -H "rate:300" -H "domain:music" 127.0.0.1:8080/ +// output +// {"Domain":"music","Rate":300} +} +``` + +### Bind HTML checkboxes + +See the [detail information](https://github.com/gin-gonic/gin/issues/129#issuecomment-124260092) + +main.go + +```go +... + +type myForm struct { + Colors []string `form:"colors[]"` +} + +... + +func formHandler(c *gin.Context) { + var fakeForm myForm + c.ShouldBind(&fakeForm) + c.JSON(http.StatusOK, gin.H{"color": fakeForm.Colors}) +} + +... + +``` + +form.html + +```html +
+

Check some colors

+ + + + + + + +
+``` + +result: + +``` +{"color":["red","green","blue"]} +``` + +### Multipart/Urlencoded binding + +```go +type ProfileForm struct { + Name string `form:"name" binding:"required"` + Avatar *multipart.FileHeader `form:"avatar" binding:"required"` + + // or for multiple files + // Avatars []*multipart.FileHeader `form:"avatar" binding:"required"` +} + +func main() { + router := gin.Default() + router.POST("/profile", func(c *gin.Context) { + // you can bind multipart form with explicit binding declaration: + // c.ShouldBindWith(&form, binding.Form) + // or you can simply use autobinding with ShouldBind method: + var form ProfileForm + // in this case proper binding will be automatically selected + if err := c.ShouldBind(&form); err != nil { + c.String(http.StatusBadRequest, "bad request") + return + } + + err := c.SaveUploadedFile(form.Avatar, form.Avatar.Filename) + if err != nil { + c.String(http.StatusInternalServerError, "unknown error") + return + } + + // db.Save(&form) + + c.String(http.StatusOK, "ok") + }) + router.Run(":8080") +} +``` + +Test it with: +```sh +$ curl -X POST -v --form name=user --form "avatar=@./avatar.png" http://localhost:8080/profile +``` + +### XML, JSON, YAML and ProtoBuf rendering + +```go +func main() { + r := gin.Default() + + // gin.H is a shortcut for map[string]interface{} + r.GET("/someJSON", func(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK}) + }) + + r.GET("/moreJSON", func(c *gin.Context) { + // You also can use a struct + var msg struct { + Name string `json:"user"` + Message string + Number int + } + msg.Name = "Lena" + msg.Message = "hey" + msg.Number = 123 + // Note that msg.Name becomes "user" in the JSON + // Will output : {"user": "Lena", "Message": "hey", "Number": 123} + c.JSON(http.StatusOK, msg) + }) + + r.GET("/someXML", func(c *gin.Context) { + c.XML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK}) + }) + + r.GET("/someYAML", func(c *gin.Context) { + c.YAML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK}) + }) + + r.GET("/someProtoBuf", func(c *gin.Context) { + reps := []int64{int64(1), int64(2)} + label := "test" + // The specific definition of protobuf is written in the testdata/protoexample file. + data := &protoexample.Test{ + Label: &label, + Reps: reps, + } + // Note that data becomes binary data in the response + // Will output protoexample.Test protobuf serialized data + c.ProtoBuf(http.StatusOK, data) + }) + + // Listen and serve on 0.0.0.0:8080 + r.Run(":8080") +} +``` + +#### SecureJSON + +Using SecureJSON to prevent json hijacking. Default prepends `"while(1),"` to response body if the given struct is array values. + +```go +func main() { + r := gin.Default() + + // You can also use your own secure json prefix + // r.SecureJsonPrefix(")]}',\n") + + r.GET("/someJSON", func(c *gin.Context) { + names := []string{"lena", "austin", "foo"} + + // Will output : while(1);["lena","austin","foo"] + c.SecureJSON(http.StatusOK, names) + }) + + // Listen and serve on 0.0.0.0:8080 + r.Run(":8080") +} +``` +#### JSONP + +Using JSONP to request data from a server in a different domain. Add callback to response body if the query parameter callback exists. + +```go +func main() { + r := gin.Default() + + r.GET("/JSONP", func(c *gin.Context) { + data := gin.H{ + "foo": "bar", + } + + //callback is x + // Will output : x({\"foo\":\"bar\"}) + c.JSONP(http.StatusOK, data) + }) + + // Listen and serve on 0.0.0.0:8080 + r.Run(":8080") + + // client + // curl http://127.0.0.1:8080/JSONP?callback=x +} +``` + +#### AsciiJSON + +Using AsciiJSON to Generates ASCII-only JSON with escaped non-ASCII characters. + +```go +func main() { + r := gin.Default() + + r.GET("/someJSON", func(c *gin.Context) { + data := gin.H{ + "lang": "GO语言", + "tag": "
", + } + + // will output : {"lang":"GO\u8bed\u8a00","tag":"\u003cbr\u003e"} + c.AsciiJSON(http.StatusOK, data) + }) + + // Listen and serve on 0.0.0.0:8080 + r.Run(":8080") +} +``` + +#### PureJSON + +Normally, JSON replaces special HTML characters with their unicode entities, e.g. `<` becomes `\u003c`. If you want to encode such characters literally, you can use PureJSON instead. +This feature is unavailable in Go 1.6 and lower. + +```go +func main() { + r := gin.Default() + + // Serves unicode entities + r.GET("/json", func(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{ + "html": "Hello, world!", + }) + }) + + // Serves literal characters + r.GET("/purejson", func(c *gin.Context) { + c.PureJSON(http.StatusOK, gin.H{ + "html": "Hello, world!", + }) + }) + + // listen and serve on 0.0.0.0:8080 + r.Run(":8080") +} +``` + +### Serving static files + +```go +func main() { + router := gin.Default() + router.Static("/assets", "./assets") + router.StaticFS("/more_static", http.Dir("my_file_system")) + router.StaticFile("/favicon.ico", "./resources/favicon.ico") + router.StaticFileFS("/more_favicon.ico", "more_favicon.ico", http.Dir("my_file_system")) + + // Listen and serve on 0.0.0.0:8080 + router.Run(":8080") +} +``` + +### Serving data from file + +```go +func main() { + router := gin.Default() + + router.GET("/local/file", func(c *gin.Context) { + c.File("local/file.go") + }) + + var fs http.FileSystem = // ... + router.GET("/fs/file", func(c *gin.Context) { + c.FileFromFS("fs/file.go", fs) + }) +} + +``` + +### Serving data from reader + +```go +func main() { + router := gin.Default() + router.GET("/someDataFromReader", func(c *gin.Context) { + response, err := http.Get("https://raw.githubusercontent.com/gin-gonic/logo/master/color.png") + if err != nil || response.StatusCode != http.StatusOK { + c.Status(http.StatusServiceUnavailable) + return + } + + reader := response.Body + defer reader.Close() + contentLength := response.ContentLength + contentType := response.Header.Get("Content-Type") + + extraHeaders := map[string]string{ + "Content-Disposition": `attachment; filename="gopher.png"`, + } + + c.DataFromReader(http.StatusOK, contentLength, contentType, reader, extraHeaders) + }) + router.Run(":8080") +} +``` + +### HTML rendering + +Using LoadHTMLGlob() or LoadHTMLFiles() + +```go +func main() { + router := gin.Default() + router.LoadHTMLGlob("templates/*") + //router.LoadHTMLFiles("templates/template1.html", "templates/template2.html") + router.GET("/index", func(c *gin.Context) { + c.HTML(http.StatusOK, "index.tmpl", gin.H{ + "title": "Main website", + }) + }) + router.Run(":8080") +} +``` + +templates/index.tmpl + +```html + +

+ {{ .title }} +

+ +``` + +Using templates with same name in different directories + +```go +func main() { + router := gin.Default() + router.LoadHTMLGlob("templates/**/*") + router.GET("/posts/index", func(c *gin.Context) { + c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{ + "title": "Posts", + }) + }) + router.GET("/users/index", func(c *gin.Context) { + c.HTML(http.StatusOK, "users/index.tmpl", gin.H{ + "title": "Users", + }) + }) + router.Run(":8080") +} +``` + +templates/posts/index.tmpl + +```html +{{ define "posts/index.tmpl" }} +

+ {{ .title }} +

+

Using posts/index.tmpl

+ +{{ end }} +``` + +templates/users/index.tmpl + +```html +{{ define "users/index.tmpl" }} +

+ {{ .title }} +

+

Using users/index.tmpl

+ +{{ end }} +``` + +#### Custom Template renderer + +You can also use your own html template render + +```go +import "html/template" + +func main() { + router := gin.Default() + html := template.Must(template.ParseFiles("file1", "file2")) + router.SetHTMLTemplate(html) + router.Run(":8080") +} +``` + +#### Custom Delimiters + +You may use custom delims + +```go + r := gin.Default() + r.Delims("{[{", "}]}") + r.LoadHTMLGlob("/path/to/templates") +``` + +#### Custom Template Funcs + +See the detail [example code](https://github.com/gin-gonic/examples/tree/master/template). + +main.go + +```go +import ( + "fmt" + "html/template" + "net/http" + "time" + + "github.com/gin-gonic/gin" +) + +func formatAsDate(t time.Time) string { + year, month, day := t.Date() + return fmt.Sprintf("%d/%02d/%02d", year, month, day) +} + +func main() { + router := gin.Default() + router.Delims("{[{", "}]}") + router.SetFuncMap(template.FuncMap{ + "formatAsDate": formatAsDate, + }) + router.LoadHTMLFiles("./testdata/template/raw.tmpl") + + router.GET("/raw", func(c *gin.Context) { + c.HTML(http.StatusOK, "raw.tmpl", gin.H{ + "now": time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC), + }) + }) + + router.Run(":8080") +} + +``` + +raw.tmpl + +```html +Date: {[{.now | formatAsDate}]} +``` + +Result: +``` +Date: 2017/07/01 +``` + +### Multitemplate + +Gin allow by default use only one html.Template. Check [a multitemplate render](https://github.com/gin-contrib/multitemplate) for using features like go 1.6 `block template`. + +### Redirects + +Issuing a HTTP redirect is easy. Both internal and external locations are supported. + +```go +r.GET("/test", func(c *gin.Context) { + c.Redirect(http.StatusMovedPermanently, "http://www.google.com/") +}) +``` + +Issuing a HTTP redirect from POST. Refer to issue: [#444](https://github.com/gin-gonic/gin/issues/444) +```go +r.POST("/test", func(c *gin.Context) { + c.Redirect(http.StatusFound, "/foo") +}) +``` + +Issuing a Router redirect, use `HandleContext` like below. + +``` go +r.GET("/test", func(c *gin.Context) { + c.Request.URL.Path = "/test2" + r.HandleContext(c) +}) +r.GET("/test2", func(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{"hello": "world"}) +}) +``` + + +### Custom Middleware + +```go +func Logger() gin.HandlerFunc { + return func(c *gin.Context) { + t := time.Now() + + // Set example variable + c.Set("example", "12345") + + // before request + + c.Next() + + // after request + latency := time.Since(t) + log.Print(latency) + + // access the status we are sending + status := c.Writer.Status() + log.Println(status) + } +} + +func main() { + r := gin.New() + r.Use(Logger()) + + r.GET("/test", func(c *gin.Context) { + example := c.MustGet("example").(string) + + // it would print: "12345" + log.Println(example) + }) + + // Listen and serve on 0.0.0.0:8080 + r.Run(":8080") +} +``` + +### Using BasicAuth() middleware + +```go +// simulate some private data +var secrets = gin.H{ + "foo": gin.H{"email": "foo@bar.com", "phone": "123433"}, + "austin": gin.H{"email": "austin@example.com", "phone": "666"}, + "lena": gin.H{"email": "lena@guapa.com", "phone": "523443"}, +} + +func main() { + r := gin.Default() + + // Group using gin.BasicAuth() middleware + // gin.Accounts is a shortcut for map[string]string + authorized := r.Group("/admin", gin.BasicAuth(gin.Accounts{ + "foo": "bar", + "austin": "1234", + "lena": "hello2", + "manu": "4321", + })) + + // /admin/secrets endpoint + // hit "localhost:8080/admin/secrets + authorized.GET("/secrets", func(c *gin.Context) { + // get user, it was set by the BasicAuth middleware + user := c.MustGet(gin.AuthUserKey).(string) + if secret, ok := secrets[user]; ok { + c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret}) + } else { + c.JSON(http.StatusOK, gin.H{"user": user, "secret": "NO SECRET :("}) + } + }) + + // Listen and serve on 0.0.0.0:8080 + r.Run(":8080") +} +``` + +### Goroutines inside a middleware + +When starting new Goroutines inside a middleware or handler, you **SHOULD NOT** use the original context inside it, you have to use a read-only copy. + +```go +func main() { + r := gin.Default() + + r.GET("/long_async", func(c *gin.Context) { + // create copy to be used inside the goroutine + cCp := c.Copy() + go func() { + // simulate a long task with time.Sleep(). 5 seconds + time.Sleep(5 * time.Second) + + // note that you are using the copied context "cCp", IMPORTANT + log.Println("Done! in path " + cCp.Request.URL.Path) + }() + }) + + r.GET("/long_sync", func(c *gin.Context) { + // simulate a long task with time.Sleep(). 5 seconds + time.Sleep(5 * time.Second) + + // since we are NOT using a goroutine, we do not have to copy the context + log.Println("Done! in path " + c.Request.URL.Path) + }) + + // Listen and serve on 0.0.0.0:8080 + r.Run(":8080") +} +``` + +### Custom HTTP configuration + +Use `http.ListenAndServe()` directly, like this: + +```go +func main() { + router := gin.Default() + http.ListenAndServe(":8080", router) +} +``` +or + +```go +func main() { + router := gin.Default() + + s := &http.Server{ + Addr: ":8080", + Handler: router, + ReadTimeout: 10 * time.Second, + WriteTimeout: 10 * time.Second, + MaxHeaderBytes: 1 << 20, + } + s.ListenAndServe() +} +``` + +### Support Let's Encrypt + +example for 1-line LetsEncrypt HTTPS servers. + +```go +package main + +import ( + "log" + "net/http" + + "github.com/gin-gonic/autotls" + "github.com/gin-gonic/gin" +) + +func main() { + r := gin.Default() + + // Ping handler + r.GET("/ping", func(c *gin.Context) { + c.String(http.StatusOK, "pong") + }) + + log.Fatal(autotls.Run(r, "example1.com", "example2.com")) +} +``` + +example for custom autocert manager. + +```go +package main + +import ( + "log" + "net/http" + + "github.com/gin-gonic/autotls" + "github.com/gin-gonic/gin" + "golang.org/x/crypto/acme/autocert" +) + +func main() { + r := gin.Default() + + // Ping handler + r.GET("/ping", func(c *gin.Context) { + c.String(http.StatusOK, "pong") + }) + + m := autocert.Manager{ + Prompt: autocert.AcceptTOS, + HostPolicy: autocert.HostWhitelist("example1.com", "example2.com"), + Cache: autocert.DirCache("/var/www/.cache"), + } + + log.Fatal(autotls.RunWithManager(r, &m)) +} +``` + +### Run multiple service using Gin + +See the [question](https://github.com/gin-gonic/gin/issues/346) and try the following example: + +```go +package main + +import ( + "log" + "net/http" + "time" + + "github.com/gin-gonic/gin" + "golang.org/x/sync/errgroup" +) + +var ( + g errgroup.Group +) + +func router01() http.Handler { + e := gin.New() + e.Use(gin.Recovery()) + e.GET("/", func(c *gin.Context) { + c.JSON( + http.StatusOK, + gin.H{ + "code": http.StatusOK, + "error": "Welcome server 01", + }, + ) + }) + + return e +} + +func router02() http.Handler { + e := gin.New() + e.Use(gin.Recovery()) + e.GET("/", func(c *gin.Context) { + c.JSON( + http.StatusOK, + gin.H{ + "code": http.StatusOK, + "error": "Welcome server 02", + }, + ) + }) + + return e +} + +func main() { + server01 := &http.Server{ + Addr: ":8080", + Handler: router01(), + ReadTimeout: 5 * time.Second, + WriteTimeout: 10 * time.Second, + } + + server02 := &http.Server{ + Addr: ":8081", + Handler: router02(), + ReadTimeout: 5 * time.Second, + WriteTimeout: 10 * time.Second, + } + + g.Go(func() error { + err := server01.ListenAndServe() + if err != nil && err != http.ErrServerClosed { + log.Fatal(err) + } + return err + }) + + g.Go(func() error { + err := server02.ListenAndServe() + if err != nil && err != http.ErrServerClosed { + log.Fatal(err) + } + return err + }) + + if err := g.Wait(); err != nil { + log.Fatal(err) + } +} +``` + +### Graceful shutdown or restart + +There are a few approaches you can use to perform a graceful shutdown or restart. You can make use of third-party packages specifically built for that, or you can manually do the same with the functions and methods from the built-in packages. + +#### Third-party packages + +We can use [fvbock/endless](https://github.com/fvbock/endless) to replace the default `ListenAndServe`. Refer to issue [#296](https://github.com/gin-gonic/gin/issues/296) for more details. + +```go +router := gin.Default() +router.GET("/", handler) +// [...] +endless.ListenAndServe(":4242", router) +``` + +Alternatives: + +* [manners](https://github.com/braintree/manners): A polite Go HTTP server that shuts down gracefully. +* [graceful](https://github.com/tylerb/graceful): Graceful is a Go package enabling graceful shutdown of an http.Handler server. +* [grace](https://github.com/facebookgo/grace): Graceful restart & zero downtime deploy for Go servers. + +#### Manually + +In case you are using Go 1.8 or a later version, you may not need to use those libraries. Consider using `http.Server`'s built-in [Shutdown()](https://golang.org/pkg/net/http/#Server.Shutdown) method for graceful shutdowns. The example below describes its usage, and we've got more examples using gin [here](https://github.com/gin-gonic/examples/tree/master/graceful-shutdown). + +```go +// +build go1.8 + +package main + +import ( + "context" + "log" + "net/http" + "os" + "os/signal" + "syscall" + "time" + + "github.com/gin-gonic/gin" +) + +func main() { + router := gin.Default() + router.GET("/", func(c *gin.Context) { + time.Sleep(5 * time.Second) + c.String(http.StatusOK, "Welcome Gin Server") + }) + + srv := &http.Server{ + Addr: ":8080", + Handler: router, + } + + // Initializing the server in a goroutine so that + // it won't block the graceful shutdown handling below + go func() { + if err := srv.ListenAndServe(); err != nil && errors.Is(err, http.ErrServerClosed) { + log.Printf("listen: %s\n", err) + } + }() + + // Wait for interrupt signal to gracefully shutdown the server with + // a timeout of 5 seconds. + quit := make(chan os.Signal) + // kill (no param) default send syscall.SIGTERM + // kill -2 is syscall.SIGINT + // kill -9 is syscall.SIGKILL but can't be caught, so don't need to add it + signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) + <-quit + log.Println("Shutting down server...") + + // The context is used to inform the server it has 5 seconds to finish + // the request it is currently handling + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + if err := srv.Shutdown(ctx); err != nil { + log.Fatal("Server forced to shutdown:", err) + } + + log.Println("Server exiting") +} +``` + +### Build a single binary with templates + +You can build a server into a single binary containing templates by using [go-assets][]. + +[go-assets]: https://github.com/jessevdk/go-assets + +```go +func main() { + r := gin.New() + + t, err := loadTemplate() + if err != nil { + panic(err) + } + r.SetHTMLTemplate(t) + + r.GET("/", func(c *gin.Context) { + c.HTML(http.StatusOK, "/html/index.tmpl",nil) + }) + r.Run(":8080") +} + +// loadTemplate loads templates embedded by go-assets-builder +func loadTemplate() (*template.Template, error) { + t := template.New("") + for name, file := range Assets.Files { + defer file.Close() + if file.IsDir() || !strings.HasSuffix(name, ".tmpl") { + continue + } + h, err := ioutil.ReadAll(file) + if err != nil { + return nil, err + } + t, err = t.New(name).Parse(string(h)) + if err != nil { + return nil, err + } + } + return t, nil +} +``` + +See a complete example in the `https://github.com/gin-gonic/examples/tree/master/assets-in-binary` directory. + +### Bind form-data request with custom struct + +The follow example using custom struct: + +```go +type StructA struct { + FieldA string `form:"field_a"` +} + +type StructB struct { + NestedStruct StructA + FieldB string `form:"field_b"` +} + +type StructC struct { + NestedStructPointer *StructA + FieldC string `form:"field_c"` +} + +type StructD struct { + NestedAnonyStruct struct { + FieldX string `form:"field_x"` + } + FieldD string `form:"field_d"` +} + +func GetDataB(c *gin.Context) { + var b StructB + c.Bind(&b) + c.JSON(http.StatusOK, gin.H{ + "a": b.NestedStruct, + "b": b.FieldB, + }) +} + +func GetDataC(c *gin.Context) { + var b StructC + c.Bind(&b) + c.JSON(http.StatusOK, gin.H{ + "a": b.NestedStructPointer, + "c": b.FieldC, + }) +} + +func GetDataD(c *gin.Context) { + var b StructD + c.Bind(&b) + c.JSON(http.StatusOK, gin.H{ + "x": b.NestedAnonyStruct, + "d": b.FieldD, + }) +} + +func main() { + r := gin.Default() + r.GET("/getb", GetDataB) + r.GET("/getc", GetDataC) + r.GET("/getd", GetDataD) + + r.Run() +} +``` + +Using the command `curl` command result: + +``` +$ curl "http://localhost:8080/getb?field_a=hello&field_b=world" +{"a":{"FieldA":"hello"},"b":"world"} +$ curl "http://localhost:8080/getc?field_a=hello&field_c=world" +{"a":{"FieldA":"hello"},"c":"world"} +$ curl "http://localhost:8080/getd?field_x=hello&field_d=world" +{"d":"world","x":{"FieldX":"hello"}} +``` + +### Try to bind body into different structs + +The normal methods for binding request body consumes `c.Request.Body` and they +cannot be called multiple times. + +```go +type formA struct { + Foo string `json:"foo" xml:"foo" binding:"required"` +} + +type formB struct { + Bar string `json:"bar" xml:"bar" binding:"required"` +} + +func SomeHandler(c *gin.Context) { + objA := formA{} + objB := formB{} + // This c.ShouldBind consumes c.Request.Body and it cannot be reused. + if errA := c.ShouldBind(&objA); errA == nil { + c.String(http.StatusOK, `the body should be formA`) + // Always an error is occurred by this because c.Request.Body is EOF now. + } else if errB := c.ShouldBind(&objB); errB == nil { + c.String(http.StatusOK, `the body should be formB`) + } else { + ... + } +} +``` + +For this, you can use `c.ShouldBindBodyWith`. + +```go +func SomeHandler(c *gin.Context) { + objA := formA{} + objB := formB{} + // This reads c.Request.Body and stores the result into the context. + if errA := c.ShouldBindBodyWith(&objA, binding.Form); errA == nil { + c.String(http.StatusOK, `the body should be formA`) + // At this time, it reuses body stored in the context. + } else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil { + c.String(http.StatusOK, `the body should be formB JSON`) + // And it can accepts other formats + } else if errB2 := c.ShouldBindBodyWith(&objB, binding.XML); errB2 == nil { + c.String(http.StatusOK, `the body should be formB XML`) + } else { + ... + } +} +``` + +* `c.ShouldBindBodyWith` stores body into the context before binding. This has +a slight impact to performance, so you should not use this method if you are +enough to call binding at once. +* This feature is only needed for some formats -- `JSON`, `XML`, `MsgPack`, +`ProtoBuf`. For other formats, `Query`, `Form`, `FormPost`, `FormMultipart`, +can be called by `c.ShouldBind()` multiple times without any damage to +performance (See [#1341](https://github.com/gin-gonic/gin/pull/1341)). + +### Bind form-data request with custom struct and custom tag + +```go +const ( + customerTag = "url" + defaultMemory = 32 << 20 +) + +type customerBinding struct {} + +func (customerBinding) Name() string { + return "form" +} + +func (customerBinding) Bind(req *http.Request, obj interface{}) error { + if err := req.ParseForm(); err != nil { + return err + } + if err := req.ParseMultipartForm(defaultMemory); err != nil { + if err != http.ErrNotMultipart { + return err + } + } + if err := binding.MapFormWithTag(obj, req.Form, customerTag); err != nil { + return err + } + return validate(obj) +} + +func validate(obj interface{}) error { + if binding.Validator == nil { + return nil + } + return binding.Validator.ValidateStruct(obj) +} + +// Now we can do this!!! +// FormA is a external type that we can't modify it's tag +type FormA struct { + FieldA string `url:"field_a"` +} + +func ListHandler(s *Service) func(ctx *gin.Context) { + return func(ctx *gin.Context) { + var urlBinding = customerBinding{} + var opt FormA + err := ctx.MustBindWith(&opt, urlBinding) + if err != nil { + ... + } + ... + } +} +``` + +### http2 server push + +http.Pusher is supported only **go1.8+**. See the [golang blog](https://blog.golang.org/h2push) for detail information. + +```go +package main + +import ( + "html/template" + "log" + "net/http" + + "github.com/gin-gonic/gin" +) + +var html = template.Must(template.New("https").Parse(` + + + Https Test + + + +

Welcome, Ginner!

+ + +`)) + +func main() { + r := gin.Default() + r.Static("/assets", "./assets") + r.SetHTMLTemplate(html) + + r.GET("/", func(c *gin.Context) { + if pusher := c.Writer.Pusher(); pusher != nil { + // use pusher.Push() to do server push + if err := pusher.Push("/assets/app.js", nil); err != nil { + log.Printf("Failed to push: %v", err) + } + } + c.HTML(http.StatusOK, "https", gin.H{ + "status": "success", + }) + }) + + // Listen and Server in https://127.0.0.1:8080 + r.RunTLS(":8080", "./testdata/server.pem", "./testdata/server.key") +} +``` + +### Define format for the log of routes + +The default log of routes is: +``` +[GIN-debug] POST /foo --> main.main.func1 (3 handlers) +[GIN-debug] GET /bar --> main.main.func2 (3 handlers) +[GIN-debug] GET /status --> main.main.func3 (3 handlers) +``` + +If you want to log this information in given format (e.g. JSON, key values or something else), then you can define this format with `gin.DebugPrintRouteFunc`. +In the example below, we log all routes with standard log package but you can use another log tools that suits of your needs. +```go +import ( + "log" + "net/http" + + "github.com/gin-gonic/gin" +) + +func main() { + r := gin.Default() + gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) { + log.Printf("endpoint %v %v %v %v\n", httpMethod, absolutePath, handlerName, nuHandlers) + } + + r.POST("/foo", func(c *gin.Context) { + c.JSON(http.StatusOK, "foo") + }) + + r.GET("/bar", func(c *gin.Context) { + c.JSON(http.StatusOK, "bar") + }) + + r.GET("/status", func(c *gin.Context) { + c.JSON(http.StatusOK, "ok") + }) + + // Listen and Server in http://0.0.0.0:8080 + r.Run() +} +``` + +### Set and get a cookie + +```go +import ( + "fmt" + + "github.com/gin-gonic/gin" +) + +func main() { + + router := gin.Default() + + router.GET("/cookie", func(c *gin.Context) { + + cookie, err := c.Cookie("gin_cookie") + + if err != nil { + cookie = "NotSet" + c.SetCookie("gin_cookie", "test", 3600, "/", "localhost", false, true) + } + + fmt.Printf("Cookie value: %s \n", cookie) + }) + + router.Run() +} +``` + +## Don't trust all proxies + +Gin lets you specify which headers to hold the real client IP (if any), +as well as specifying which proxies (or direct clients) you trust to +specify one of these headers. + +Use function `SetTrustedProxies()` on your `gin.Engine` to specify network addresses +or network CIDRs from where clients which their request headers related to client +IP can be trusted. They can be IPv4 addresses, IPv4 CIDRs, IPv6 addresses or +IPv6 CIDRs. + +**Attention:** Gin trust all proxies by default if you don't specify a trusted +proxy using the function above, **this is NOT safe**. At the same time, if you don't +use any proxy, you can disable this feature by using `Engine.SetTrustedProxies(nil)`, +then `Context.ClientIP()` will return the remote address directly to avoid some +unnecessary computation. + +```go +import ( + "fmt" + + "github.com/gin-gonic/gin" +) + +func main() { + + router := gin.Default() + router.SetTrustedProxies([]string{"192.168.1.2"}) + + router.GET("/", func(c *gin.Context) { + // If the client is 192.168.1.2, use the X-Forwarded-For + // header to deduce the original client IP from the trust- + // worthy parts of that header. + // Otherwise, simply return the direct client IP + fmt.Printf("ClientIP: %s\n", c.ClientIP()) + }) + router.Run() +} +``` + +**Notice:** If you are using a CDN service, you can set the `Engine.TrustedPlatform` +to skip TrustedProxies check, it has a higher priority than TrustedProxies. +Look at the example below: +```go +import ( + "fmt" + + "github.com/gin-gonic/gin" +) + +func main() { + + router := gin.Default() + // Use predefined header gin.PlatformXXX + router.TrustedPlatform = gin.PlatformGoogleAppEngine + // Or set your own trusted request header for another trusted proxy service + // Don't set it to any suspect request header, it's unsafe + router.TrustedPlatform = "X-CDN-IP" + + router.GET("/", func(c *gin.Context) { + // If you set TrustedPlatform, ClientIP() will resolve the + // corresponding header and return IP directly + fmt.Printf("ClientIP: %s\n", c.ClientIP()) + }) + router.Run() +} +``` + +## Testing + +The `net/http/httptest` package is preferable way for HTTP testing. + +```go +package main + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +func setupRouter() *gin.Engine { + r := gin.Default() + r.GET("/ping", func(c *gin.Context) { + c.String(http.StatusOK, "pong") + }) + return r +} + +func main() { + r := setupRouter() + r.Run(":8080") +} +``` + +Test for code example above: + +```go +package main + +import ( + "net/http" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestPingRoute(t *testing.T) { + router := setupRouter() + + w := httptest.NewRecorder() + req, _ := http.NewRequest(http.MethodGet, "/ping", nil) + router.ServeHTTP(w, req) + + assert.Equal(t, http.StatusOK, w.Code) + assert.Equal(t, "pong", w.Body.String()) +} +``` + +## Users + +Awesome project lists using [Gin](https://github.com/gin-gonic/gin) web framework. + +* [gorush](https://github.com/appleboy/gorush): A push notification server written in Go. +* [fnproject](https://github.com/fnproject/fn): The container native, cloud agnostic serverless platform. +* [photoprism](https://github.com/photoprism/photoprism): Personal photo management powered by Go and Google TensorFlow. +* [krakend](https://github.com/devopsfaith/krakend): Ultra performant API Gateway with middlewares. +* [picfit](https://github.com/thoas/picfit): An image resizing server written in Go. +* [brigade](https://github.com/brigadecore/brigade): Event-based Scripting for Kubernetes. +* [dkron](https://github.com/distribworks/dkron): Distributed, fault tolerant job scheduling system. + diff --git a/vendor/github.com/gin-gonic/gin/any.go b/vendor/github.com/gin-gonic/gin/any.go new file mode 100644 index 0000000..42b1ea4 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/any.go @@ -0,0 +1,10 @@ +// Copyright 2022 Gin Core Team. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +//go:build !go1.18 +// +build !go1.18 + +package gin + +type any = interface{} diff --git a/vendor/github.com/gin-gonic/gin/auth.go b/vendor/github.com/gin-gonic/gin/auth.go new file mode 100644 index 0000000..2503c51 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/auth.go @@ -0,0 +1,91 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package gin + +import ( + "crypto/subtle" + "encoding/base64" + "net/http" + "strconv" + + "github.com/gin-gonic/gin/internal/bytesconv" +) + +// AuthUserKey is the cookie name for user credential in basic auth. +const AuthUserKey = "user" + +// Accounts defines a key/value for user/pass list of authorized logins. +type Accounts map[string]string + +type authPair struct { + value string + user string +} + +type authPairs []authPair + +func (a authPairs) searchCredential(authValue string) (string, bool) { + if authValue == "" { + return "", false + } + for _, pair := range a { + if subtle.ConstantTimeCompare(bytesconv.StringToBytes(pair.value), bytesconv.StringToBytes(authValue)) == 1 { + return pair.user, true + } + } + return "", false +} + +// BasicAuthForRealm returns a Basic HTTP Authorization middleware. It takes as arguments a map[string]string where +// the key is the user name and the value is the password, as well as the name of the Realm. +// If the realm is empty, "Authorization Required" will be used by default. +// (see http://tools.ietf.org/html/rfc2617#section-1.2) +func BasicAuthForRealm(accounts Accounts, realm string) HandlerFunc { + if realm == "" { + realm = "Authorization Required" + } + realm = "Basic realm=" + strconv.Quote(realm) + pairs := processAccounts(accounts) + return func(c *Context) { + // Search user in the slice of allowed credentials + user, found := pairs.searchCredential(c.requestHeader("Authorization")) + if !found { + // Credentials doesn't match, we return 401 and abort handlers chain. + c.Header("WWW-Authenticate", realm) + c.AbortWithStatus(http.StatusUnauthorized) + return + } + + // The user credentials was found, set user's id to key AuthUserKey in this context, the user's id can be read later using + // c.MustGet(gin.AuthUserKey). + c.Set(AuthUserKey, user) + } +} + +// BasicAuth returns a Basic HTTP Authorization middleware. It takes as argument a map[string]string where +// the key is the user name and the value is the password. +func BasicAuth(accounts Accounts) HandlerFunc { + return BasicAuthForRealm(accounts, "") +} + +func processAccounts(accounts Accounts) authPairs { + length := len(accounts) + assert1(length > 0, "Empty list of authorized credentials") + pairs := make(authPairs, 0, length) + for user, password := range accounts { + assert1(user != "", "User can not be empty") + value := authorizationHeader(user, password) + pairs = append(pairs, authPair{ + value: value, + user: user, + }) + } + return pairs +} + +func authorizationHeader(user, password string) string { + base := user + ":" + password + return "Basic " + base64.StdEncoding.EncodeToString(bytesconv.StringToBytes(base)) +} diff --git a/vendor/github.com/gin-gonic/gin/binding/any.go b/vendor/github.com/gin-gonic/gin/binding/any.go new file mode 100644 index 0000000..d8251a7 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/binding/any.go @@ -0,0 +1,10 @@ +// Copyright 2022 Gin Core Team. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +//go:build !go1.18 +// +build !go1.18 + +package binding + +type any = interface{} diff --git a/vendor/github.com/gin-gonic/gin/binding/binding.go b/vendor/github.com/gin-gonic/gin/binding/binding.go new file mode 100644 index 0000000..a58924e --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/binding/binding.go @@ -0,0 +1,122 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +//go:build !nomsgpack +// +build !nomsgpack + +package binding + +import "net/http" + +// Content-Type MIME of the most common data formats. +const ( + MIMEJSON = "application/json" + MIMEHTML = "text/html" + MIMEXML = "application/xml" + MIMEXML2 = "text/xml" + MIMEPlain = "text/plain" + MIMEPOSTForm = "application/x-www-form-urlencoded" + MIMEMultipartPOSTForm = "multipart/form-data" + MIMEPROTOBUF = "application/x-protobuf" + MIMEMSGPACK = "application/x-msgpack" + MIMEMSGPACK2 = "application/msgpack" + MIMEYAML = "application/x-yaml" + MIMETOML = "application/toml" +) + +// Binding describes the interface which needs to be implemented for binding the +// data present in the request such as JSON request body, query parameters or +// the form POST. +type Binding interface { + Name() string + Bind(*http.Request, any) error +} + +// BindingBody adds BindBody method to Binding. BindBody is similar with Bind, +// but it reads the body from supplied bytes instead of req.Body. +type BindingBody interface { + Binding + BindBody([]byte, any) error +} + +// BindingUri adds BindUri method to Binding. BindUri is similar with Bind, +// but it reads the Params. +type BindingUri interface { + Name() string + BindUri(map[string][]string, any) error +} + +// StructValidator is the minimal interface which needs to be implemented in +// order for it to be used as the validator engine for ensuring the correctness +// of the request. Gin provides a default implementation for this using +// https://github.com/go-playground/validator/tree/v10.6.1. +type StructValidator interface { + // ValidateStruct can receive any kind of type and it should never panic, even if the configuration is not right. + // If the received type is a slice|array, the validation should be performed travel on every element. + // If the received type is not a struct or slice|array, any validation should be skipped and nil must be returned. + // If the received type is a struct or pointer to a struct, the validation should be performed. + // If the struct is not valid or the validation itself fails, a descriptive error should be returned. + // Otherwise nil must be returned. + ValidateStruct(any) error + + // Engine returns the underlying validator engine which powers the + // StructValidator implementation. + Engine() any +} + +// Validator is the default validator which implements the StructValidator +// interface. It uses https://github.com/go-playground/validator/tree/v10.6.1 +// under the hood. +var Validator StructValidator = &defaultValidator{} + +// These implement the Binding interface and can be used to bind the data +// present in the request to struct instances. +var ( + JSON = jsonBinding{} + XML = xmlBinding{} + Form = formBinding{} + Query = queryBinding{} + FormPost = formPostBinding{} + FormMultipart = formMultipartBinding{} + ProtoBuf = protobufBinding{} + MsgPack = msgpackBinding{} + YAML = yamlBinding{} + Uri = uriBinding{} + Header = headerBinding{} + TOML = tomlBinding{} +) + +// Default returns the appropriate Binding instance based on the HTTP method +// and the content type. +func Default(method, contentType string) Binding { + if method == http.MethodGet { + return Form + } + + switch contentType { + case MIMEJSON: + return JSON + case MIMEXML, MIMEXML2: + return XML + case MIMEPROTOBUF: + return ProtoBuf + case MIMEMSGPACK, MIMEMSGPACK2: + return MsgPack + case MIMEYAML: + return YAML + case MIMETOML: + return TOML + case MIMEMultipartPOSTForm: + return FormMultipart + default: // case MIMEPOSTForm: + return Form + } +} + +func validate(obj any) error { + if Validator == nil { + return nil + } + return Validator.ValidateStruct(obj) +} diff --git a/vendor/github.com/gin-gonic/gin/binding/binding_nomsgpack.go b/vendor/github.com/gin-gonic/gin/binding/binding_nomsgpack.go new file mode 100644 index 0000000..7f6a904 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/binding/binding_nomsgpack.go @@ -0,0 +1,116 @@ +// Copyright 2020 Gin Core Team. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +//go:build nomsgpack +// +build nomsgpack + +package binding + +import "net/http" + +// Content-Type MIME of the most common data formats. +const ( + MIMEJSON = "application/json" + MIMEHTML = "text/html" + MIMEXML = "application/xml" + MIMEXML2 = "text/xml" + MIMEPlain = "text/plain" + MIMEPOSTForm = "application/x-www-form-urlencoded" + MIMEMultipartPOSTForm = "multipart/form-data" + MIMEPROTOBUF = "application/x-protobuf" + MIMEYAML = "application/x-yaml" + MIMETOML = "application/toml" +) + +// Binding describes the interface which needs to be implemented for binding the +// data present in the request such as JSON request body, query parameters or +// the form POST. +type Binding interface { + Name() string + Bind(*http.Request, any) error +} + +// BindingBody adds BindBody method to Binding. BindBody is similar with Bind, +// but it reads the body from supplied bytes instead of req.Body. +type BindingBody interface { + Binding + BindBody([]byte, any) error +} + +// BindingUri adds BindUri method to Binding. BindUri is similar with Bind, +// but it reads the Params. +type BindingUri interface { + Name() string + BindUri(map[string][]string, any) error +} + +// StructValidator is the minimal interface which needs to be implemented in +// order for it to be used as the validator engine for ensuring the correctness +// of the request. Gin provides a default implementation for this using +// https://github.com/go-playground/validator/tree/v10.6.1. +type StructValidator interface { + // ValidateStruct can receive any kind of type and it should never panic, even if the configuration is not right. + // If the received type is not a struct, any validation should be skipped and nil must be returned. + // If the received type is a struct or pointer to a struct, the validation should be performed. + // If the struct is not valid or the validation itself fails, a descriptive error should be returned. + // Otherwise nil must be returned. + ValidateStruct(any) error + + // Engine returns the underlying validator engine which powers the + // StructValidator implementation. + Engine() any +} + +// Validator is the default validator which implements the StructValidator +// interface. It uses https://github.com/go-playground/validator/tree/v10.6.1 +// under the hood. +var Validator StructValidator = &defaultValidator{} + +// These implement the Binding interface and can be used to bind the data +// present in the request to struct instances. +var ( + JSON = jsonBinding{} + XML = xmlBinding{} + Form = formBinding{} + Query = queryBinding{} + FormPost = formPostBinding{} + FormMultipart = formMultipartBinding{} + ProtoBuf = protobufBinding{} + YAML = yamlBinding{} + Uri = uriBinding{} + Header = headerBinding{} + TOML = tomlBinding{} +) + +// Default returns the appropriate Binding instance based on the HTTP method +// and the content type. +func Default(method, contentType string) Binding { + if method == "GET" { + return Form + } + + switch contentType { + case MIMEJSON: + return JSON + case MIMEXML, MIMEXML2: + return XML + case MIMEPROTOBUF: + return ProtoBuf + case MIMEYAML: + return YAML + case MIMEMultipartPOSTForm: + return FormMultipart + case MIMETOML: + return TOML + default: // case MIMEPOSTForm: + return Form + } +} + +func validate(obj any) error { + if Validator == nil { + return nil + } + return Validator.ValidateStruct(obj) +} diff --git a/vendor/github.com/gin-gonic/gin/binding/default_validator.go b/vendor/github.com/gin-gonic/gin/binding/default_validator.go new file mode 100644 index 0000000..c03afe7 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/binding/default_validator.go @@ -0,0 +1,97 @@ +// Copyright 2017 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package binding + +import ( + "fmt" + "reflect" + "strings" + "sync" + + "github.com/go-playground/validator/v10" +) + +type defaultValidator struct { + once sync.Once + validate *validator.Validate +} + +type SliceValidationError []error + +// Error concatenates all error elements in SliceValidationError into a single string separated by \n. +func (err SliceValidationError) Error() string { + n := len(err) + switch n { + case 0: + return "" + default: + var b strings.Builder + if err[0] != nil { + fmt.Fprintf(&b, "[%d]: %s", 0, err[0].Error()) + } + if n > 1 { + for i := 1; i < n; i++ { + if err[i] != nil { + b.WriteString("\n") + fmt.Fprintf(&b, "[%d]: %s", i, err[i].Error()) + } + } + } + return b.String() + } +} + +var _ StructValidator = &defaultValidator{} + +// ValidateStruct receives any kind of type, but only performed struct or pointer to struct type. +func (v *defaultValidator) ValidateStruct(obj any) error { + if obj == nil { + return nil + } + + value := reflect.ValueOf(obj) + switch value.Kind() { + case reflect.Ptr: + return v.ValidateStruct(value.Elem().Interface()) + case reflect.Struct: + return v.validateStruct(obj) + case reflect.Slice, reflect.Array: + count := value.Len() + validateRet := make(SliceValidationError, 0) + for i := 0; i < count; i++ { + if err := v.ValidateStruct(value.Index(i).Interface()); err != nil { + validateRet = append(validateRet, err) + } + } + if len(validateRet) == 0 { + return nil + } + return validateRet + default: + return nil + } +} + +// validateStruct receives struct type +func (v *defaultValidator) validateStruct(obj any) error { + v.lazyinit() + return v.validate.Struct(obj) +} + +// Engine returns the underlying validator engine which powers the default +// Validator instance. This is useful if you want to register custom validations +// or struct level validations. See validator GoDoc for more info - +// https://pkg.go.dev/github.com/go-playground/validator/v10 +func (v *defaultValidator) Engine() any { + v.lazyinit() + return v.validate +} + +func (v *defaultValidator) lazyinit() { + v.once.Do(func() { + v.validate = validator.New() + v.validate.SetTagName("binding") + }) +} diff --git a/vendor/github.com/gin-gonic/gin/binding/form.go b/vendor/github.com/gin-gonic/gin/binding/form.go new file mode 100644 index 0000000..b17352b --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/binding/form.go @@ -0,0 +1,62 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package binding + +import ( + "errors" + "net/http" +) + +const defaultMemory = 32 << 20 + +type formBinding struct{} +type formPostBinding struct{} +type formMultipartBinding struct{} + +func (formBinding) Name() string { + return "form" +} + +func (formBinding) Bind(req *http.Request, obj any) error { + if err := req.ParseForm(); err != nil { + return err + } + if err := req.ParseMultipartForm(defaultMemory); err != nil && !errors.Is(err, http.ErrNotMultipart) { + return err + } + if err := mapForm(obj, req.Form); err != nil { + return err + } + return validate(obj) +} + +func (formPostBinding) Name() string { + return "form-urlencoded" +} + +func (formPostBinding) Bind(req *http.Request, obj any) error { + if err := req.ParseForm(); err != nil { + return err + } + if err := mapForm(obj, req.PostForm); err != nil { + return err + } + return validate(obj) +} + +func (formMultipartBinding) Name() string { + return "multipart/form-data" +} + +func (formMultipartBinding) Bind(req *http.Request, obj any) error { + if err := req.ParseMultipartForm(defaultMemory); err != nil { + return err + } + if err := mappingByPtr(obj, (*multipartRequest)(req), "form"); err != nil { + return err + } + + return validate(obj) +} diff --git a/vendor/github.com/gin-gonic/gin/binding/form_mapping.go b/vendor/github.com/gin-gonic/gin/binding/form_mapping.go new file mode 100644 index 0000000..98cebfe --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/binding/form_mapping.go @@ -0,0 +1,403 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package binding + +import ( + "errors" + "fmt" + "reflect" + "strconv" + "strings" + "time" + + "github.com/gin-gonic/gin/internal/bytesconv" + "github.com/gin-gonic/gin/internal/json" +) + +var ( + errUnknownType = errors.New("unknown type") + + // ErrConvertMapStringSlice can not covert to map[string][]string + ErrConvertMapStringSlice = errors.New("can not convert to map slices of strings") + + // ErrConvertToMapString can not convert to map[string]string + ErrConvertToMapString = errors.New("can not convert to map of strings") +) + +func mapURI(ptr any, m map[string][]string) error { + return mapFormByTag(ptr, m, "uri") +} + +func mapForm(ptr any, form map[string][]string) error { + return mapFormByTag(ptr, form, "form") +} + +func MapFormWithTag(ptr any, form map[string][]string, tag string) error { + return mapFormByTag(ptr, form, tag) +} + +var emptyField = reflect.StructField{} + +func mapFormByTag(ptr any, form map[string][]string, tag string) error { + // Check if ptr is a map + ptrVal := reflect.ValueOf(ptr) + var pointed any + if ptrVal.Kind() == reflect.Ptr { + ptrVal = ptrVal.Elem() + pointed = ptrVal.Interface() + } + if ptrVal.Kind() == reflect.Map && + ptrVal.Type().Key().Kind() == reflect.String { + if pointed != nil { + ptr = pointed + } + return setFormMap(ptr, form) + } + + return mappingByPtr(ptr, formSource(form), tag) +} + +// setter tries to set value on a walking by fields of a struct +type setter interface { + TrySet(value reflect.Value, field reflect.StructField, key string, opt setOptions) (isSet bool, err error) +} + +type formSource map[string][]string + +var _ setter = formSource(nil) + +// TrySet tries to set a value by request's form source (like map[string][]string) +func (form formSource) TrySet(value reflect.Value, field reflect.StructField, tagValue string, opt setOptions) (isSet bool, err error) { + return setByForm(value, field, form, tagValue, opt) +} + +func mappingByPtr(ptr any, setter setter, tag string) error { + _, err := mapping(reflect.ValueOf(ptr), emptyField, setter, tag) + return err +} + +func mapping(value reflect.Value, field reflect.StructField, setter setter, tag string) (bool, error) { + if field.Tag.Get(tag) == "-" { // just ignoring this field + return false, nil + } + + vKind := value.Kind() + + if vKind == reflect.Ptr { + var isNew bool + vPtr := value + if value.IsNil() { + isNew = true + vPtr = reflect.New(value.Type().Elem()) + } + isSet, err := mapping(vPtr.Elem(), field, setter, tag) + if err != nil { + return false, err + } + if isNew && isSet { + value.Set(vPtr) + } + return isSet, nil + } + + if vKind != reflect.Struct || !field.Anonymous { + ok, err := tryToSetValue(value, field, setter, tag) + if err != nil { + return false, err + } + if ok { + return true, nil + } + } + + if vKind == reflect.Struct { + tValue := value.Type() + + var isSet bool + for i := 0; i < value.NumField(); i++ { + sf := tValue.Field(i) + if sf.PkgPath != "" && !sf.Anonymous { // unexported + continue + } + ok, err := mapping(value.Field(i), sf, setter, tag) + if err != nil { + return false, err + } + isSet = isSet || ok + } + return isSet, nil + } + return false, nil +} + +type setOptions struct { + isDefaultExists bool + defaultValue string +} + +func tryToSetValue(value reflect.Value, field reflect.StructField, setter setter, tag string) (bool, error) { + var tagValue string + var setOpt setOptions + + tagValue = field.Tag.Get(tag) + tagValue, opts := head(tagValue, ",") + + if tagValue == "" { // default value is FieldName + tagValue = field.Name + } + if tagValue == "" { // when field is "emptyField" variable + return false, nil + } + + var opt string + for len(opts) > 0 { + opt, opts = head(opts, ",") + + if k, v := head(opt, "="); k == "default" { + setOpt.isDefaultExists = true + setOpt.defaultValue = v + } + } + + return setter.TrySet(value, field, tagValue, setOpt) +} + +func setByForm(value reflect.Value, field reflect.StructField, form map[string][]string, tagValue string, opt setOptions) (isSet bool, err error) { + vs, ok := form[tagValue] + if !ok && !opt.isDefaultExists { + return false, nil + } + + switch value.Kind() { + case reflect.Slice: + if !ok { + vs = []string{opt.defaultValue} + } + return true, setSlice(vs, value, field) + case reflect.Array: + if !ok { + vs = []string{opt.defaultValue} + } + if len(vs) != value.Len() { + return false, fmt.Errorf("%q is not valid value for %s", vs, value.Type().String()) + } + return true, setArray(vs, value, field) + default: + var val string + if !ok { + val = opt.defaultValue + } + + if len(vs) > 0 { + val = vs[0] + } + return true, setWithProperType(val, value, field) + } +} + +func setWithProperType(val string, value reflect.Value, field reflect.StructField) error { + switch value.Kind() { + case reflect.Int: + return setIntField(val, 0, value) + case reflect.Int8: + return setIntField(val, 8, value) + case reflect.Int16: + return setIntField(val, 16, value) + case reflect.Int32: + return setIntField(val, 32, value) + case reflect.Int64: + switch value.Interface().(type) { + case time.Duration: + return setTimeDuration(val, value) + } + return setIntField(val, 64, value) + case reflect.Uint: + return setUintField(val, 0, value) + case reflect.Uint8: + return setUintField(val, 8, value) + case reflect.Uint16: + return setUintField(val, 16, value) + case reflect.Uint32: + return setUintField(val, 32, value) + case reflect.Uint64: + return setUintField(val, 64, value) + case reflect.Bool: + return setBoolField(val, value) + case reflect.Float32: + return setFloatField(val, 32, value) + case reflect.Float64: + return setFloatField(val, 64, value) + case reflect.String: + value.SetString(val) + case reflect.Struct: + switch value.Interface().(type) { + case time.Time: + return setTimeField(val, field, value) + } + return json.Unmarshal(bytesconv.StringToBytes(val), value.Addr().Interface()) + case reflect.Map: + return json.Unmarshal(bytesconv.StringToBytes(val), value.Addr().Interface()) + default: + return errUnknownType + } + return nil +} + +func setIntField(val string, bitSize int, field reflect.Value) error { + if val == "" { + val = "0" + } + intVal, err := strconv.ParseInt(val, 10, bitSize) + if err == nil { + field.SetInt(intVal) + } + return err +} + +func setUintField(val string, bitSize int, field reflect.Value) error { + if val == "" { + val = "0" + } + uintVal, err := strconv.ParseUint(val, 10, bitSize) + if err == nil { + field.SetUint(uintVal) + } + return err +} + +func setBoolField(val string, field reflect.Value) error { + if val == "" { + val = "false" + } + boolVal, err := strconv.ParseBool(val) + if err == nil { + field.SetBool(boolVal) + } + return err +} + +func setFloatField(val string, bitSize int, field reflect.Value) error { + if val == "" { + val = "0.0" + } + floatVal, err := strconv.ParseFloat(val, bitSize) + if err == nil { + field.SetFloat(floatVal) + } + return err +} + +func setTimeField(val string, structField reflect.StructField, value reflect.Value) error { + timeFormat := structField.Tag.Get("time_format") + if timeFormat == "" { + timeFormat = time.RFC3339 + } + + switch tf := strings.ToLower(timeFormat); tf { + case "unix", "unixnano": + tv, err := strconv.ParseInt(val, 10, 64) + if err != nil { + return err + } + + d := time.Duration(1) + if tf == "unixnano" { + d = time.Second + } + + t := time.Unix(tv/int64(d), tv%int64(d)) + value.Set(reflect.ValueOf(t)) + return nil + } + + if val == "" { + value.Set(reflect.ValueOf(time.Time{})) + return nil + } + + l := time.Local + if isUTC, _ := strconv.ParseBool(structField.Tag.Get("time_utc")); isUTC { + l = time.UTC + } + + if locTag := structField.Tag.Get("time_location"); locTag != "" { + loc, err := time.LoadLocation(locTag) + if err != nil { + return err + } + l = loc + } + + t, err := time.ParseInLocation(timeFormat, val, l) + if err != nil { + return err + } + + value.Set(reflect.ValueOf(t)) + return nil +} + +func setArray(vals []string, value reflect.Value, field reflect.StructField) error { + for i, s := range vals { + err := setWithProperType(s, value.Index(i), field) + if err != nil { + return err + } + } + return nil +} + +func setSlice(vals []string, value reflect.Value, field reflect.StructField) error { + slice := reflect.MakeSlice(value.Type(), len(vals), len(vals)) + err := setArray(vals, slice, field) + if err != nil { + return err + } + value.Set(slice) + return nil +} + +func setTimeDuration(val string, value reflect.Value) error { + d, err := time.ParseDuration(val) + if err != nil { + return err + } + value.Set(reflect.ValueOf(d)) + return nil +} + +func head(str, sep string) (head string, tail string) { + idx := strings.Index(str, sep) + if idx < 0 { + return str, "" + } + return str[:idx], str[idx+len(sep):] +} + +func setFormMap(ptr any, form map[string][]string) error { + el := reflect.TypeOf(ptr).Elem() + + if el.Kind() == reflect.Slice { + ptrMap, ok := ptr.(map[string][]string) + if !ok { + return ErrConvertMapStringSlice + } + for k, v := range form { + ptrMap[k] = v + } + + return nil + } + + ptrMap, ok := ptr.(map[string]string) + if !ok { + return ErrConvertToMapString + } + for k, v := range form { + ptrMap[k] = v[len(v)-1] // pick last + } + + return nil +} diff --git a/vendor/github.com/gin-gonic/gin/binding/header.go b/vendor/github.com/gin-gonic/gin/binding/header.go new file mode 100644 index 0000000..03bc78d --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/binding/header.go @@ -0,0 +1,38 @@ +// Copyright 2022 Gin Core Team. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package binding + +import ( + "net/http" + "net/textproto" + "reflect" +) + +type headerBinding struct{} + +func (headerBinding) Name() string { + return "header" +} + +func (headerBinding) Bind(req *http.Request, obj any) error { + + if err := mapHeader(obj, req.Header); err != nil { + return err + } + + return validate(obj) +} + +func mapHeader(ptr any, h map[string][]string) error { + return mappingByPtr(ptr, headerSource(h), "header") +} + +type headerSource map[string][]string + +var _ setter = headerSource(nil) + +func (hs headerSource) TrySet(value reflect.Value, field reflect.StructField, tagValue string, opt setOptions) (bool, error) { + return setByForm(value, field, hs, textproto.CanonicalMIMEHeaderKey(tagValue), opt) +} diff --git a/vendor/github.com/gin-gonic/gin/binding/json.go b/vendor/github.com/gin-gonic/gin/binding/json.go new file mode 100644 index 0000000..36eb27a --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/binding/json.go @@ -0,0 +1,56 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package binding + +import ( + "bytes" + "errors" + "io" + "net/http" + + "github.com/gin-gonic/gin/internal/json" +) + +// EnableDecoderUseNumber is used to call the UseNumber method on the JSON +// Decoder instance. UseNumber causes the Decoder to unmarshal a number into an +// interface{} as a Number instead of as a float64. +var EnableDecoderUseNumber = false + +// EnableDecoderDisallowUnknownFields is used to call the DisallowUnknownFields method +// on the JSON Decoder instance. DisallowUnknownFields causes the Decoder to +// return an error when the destination is a struct and the input contains object +// keys which do not match any non-ignored, exported fields in the destination. +var EnableDecoderDisallowUnknownFields = false + +type jsonBinding struct{} + +func (jsonBinding) Name() string { + return "json" +} + +func (jsonBinding) Bind(req *http.Request, obj any) error { + if req == nil || req.Body == nil { + return errors.New("invalid request") + } + return decodeJSON(req.Body, obj) +} + +func (jsonBinding) BindBody(body []byte, obj any) error { + return decodeJSON(bytes.NewReader(body), obj) +} + +func decodeJSON(r io.Reader, obj any) error { + decoder := json.NewDecoder(r) + if EnableDecoderUseNumber { + decoder.UseNumber() + } + if EnableDecoderDisallowUnknownFields { + decoder.DisallowUnknownFields() + } + if err := decoder.Decode(obj); err != nil { + return err + } + return validate(obj) +} diff --git a/vendor/github.com/gin-gonic/gin/binding/msgpack.go b/vendor/github.com/gin-gonic/gin/binding/msgpack.go new file mode 100644 index 0000000..d1f035e --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/binding/msgpack.go @@ -0,0 +1,38 @@ +// Copyright 2017 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +//go:build !nomsgpack +// +build !nomsgpack + +package binding + +import ( + "bytes" + "io" + "net/http" + + "github.com/ugorji/go/codec" +) + +type msgpackBinding struct{} + +func (msgpackBinding) Name() string { + return "msgpack" +} + +func (msgpackBinding) Bind(req *http.Request, obj any) error { + return decodeMsgPack(req.Body, obj) +} + +func (msgpackBinding) BindBody(body []byte, obj any) error { + return decodeMsgPack(bytes.NewReader(body), obj) +} + +func decodeMsgPack(r io.Reader, obj any) error { + cdc := new(codec.MsgpackHandle) + if err := codec.NewDecoder(r, cdc).Decode(&obj); err != nil { + return err + } + return validate(obj) +} diff --git a/vendor/github.com/gin-gonic/gin/binding/multipart_form_mapping.go b/vendor/github.com/gin-gonic/gin/binding/multipart_form_mapping.go new file mode 100644 index 0000000..4ebe832 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/binding/multipart_form_mapping.go @@ -0,0 +1,74 @@ +// Copyright 2019 Gin Core Team. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package binding + +import ( + "errors" + "mime/multipart" + "net/http" + "reflect" +) + +type multipartRequest http.Request + +var _ setter = (*multipartRequest)(nil) + +var ( + // ErrMultiFileHeader multipart.FileHeader invalid + ErrMultiFileHeader = errors.New("unsupported field type for multipart.FileHeader") + + // ErrMultiFileHeaderLenInvalid array for []*multipart.FileHeader len invalid + ErrMultiFileHeaderLenInvalid = errors.New("unsupported len of array for []*multipart.FileHeader") +) + +// TrySet tries to set a value by the multipart request with the binding a form file +func (r *multipartRequest) TrySet(value reflect.Value, field reflect.StructField, key string, opt setOptions) (bool, error) { + if files := r.MultipartForm.File[key]; len(files) != 0 { + return setByMultipartFormFile(value, field, files) + } + + return setByForm(value, field, r.MultipartForm.Value, key, opt) +} + +func setByMultipartFormFile(value reflect.Value, field reflect.StructField, files []*multipart.FileHeader) (isSet bool, err error) { + switch value.Kind() { + case reflect.Ptr: + switch value.Interface().(type) { + case *multipart.FileHeader: + value.Set(reflect.ValueOf(files[0])) + return true, nil + } + case reflect.Struct: + switch value.Interface().(type) { + case multipart.FileHeader: + value.Set(reflect.ValueOf(*files[0])) + return true, nil + } + case reflect.Slice: + slice := reflect.MakeSlice(value.Type(), len(files), len(files)) + isSet, err = setArrayOfMultipartFormFiles(slice, field, files) + if err != nil || !isSet { + return isSet, err + } + value.Set(slice) + return true, nil + case reflect.Array: + return setArrayOfMultipartFormFiles(value, field, files) + } + return false, ErrMultiFileHeader +} + +func setArrayOfMultipartFormFiles(value reflect.Value, field reflect.StructField, files []*multipart.FileHeader) (isSet bool, err error) { + if value.Len() != len(files) { + return false, ErrMultiFileHeaderLenInvalid + } + for i := range files { + set, err := setByMultipartFormFile(value.Index(i), field, files[i:i+1]) + if err != nil || !set { + return set, err + } + } + return true, nil +} diff --git a/vendor/github.com/gin-gonic/gin/binding/protobuf.go b/vendor/github.com/gin-gonic/gin/binding/protobuf.go new file mode 100644 index 0000000..44f2fdb --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/binding/protobuf.go @@ -0,0 +1,41 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package binding + +import ( + "errors" + "io/ioutil" + "net/http" + + "google.golang.org/protobuf/proto" +) + +type protobufBinding struct{} + +func (protobufBinding) Name() string { + return "protobuf" +} + +func (b protobufBinding) Bind(req *http.Request, obj any) error { + buf, err := ioutil.ReadAll(req.Body) + if err != nil { + return err + } + return b.BindBody(buf, obj) +} + +func (protobufBinding) BindBody(body []byte, obj any) error { + msg, ok := obj.(proto.Message) + if !ok { + return errors.New("obj is not ProtoMessage") + } + if err := proto.Unmarshal(body, msg); err != nil { + return err + } + // Here it's same to return validate(obj), but util now we can't add + // `binding:""` to the struct which automatically generate by gen-proto + return nil + // return validate(obj) +} diff --git a/vendor/github.com/gin-gonic/gin/binding/query.go b/vendor/github.com/gin-gonic/gin/binding/query.go new file mode 100644 index 0000000..c958b88 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/binding/query.go @@ -0,0 +1,21 @@ +// Copyright 2017 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package binding + +import "net/http" + +type queryBinding struct{} + +func (queryBinding) Name() string { + return "query" +} + +func (queryBinding) Bind(req *http.Request, obj any) error { + values := req.URL.Query() + if err := mapForm(obj, values); err != nil { + return err + } + return validate(obj) +} diff --git a/vendor/github.com/gin-gonic/gin/binding/toml.go b/vendor/github.com/gin-gonic/gin/binding/toml.go new file mode 100644 index 0000000..a6b8a90 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/binding/toml.go @@ -0,0 +1,35 @@ +// Copyright 2022 Gin Core Team. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package binding + +import ( + "bytes" + "io" + "net/http" + + "github.com/pelletier/go-toml/v2" +) + +type tomlBinding struct{} + +func (tomlBinding) Name() string { + return "toml" +} + +func decodeToml(r io.Reader, obj any) error { + decoder := toml.NewDecoder(r) + if err := decoder.Decode(obj); err != nil { + return err + } + return decoder.Decode(obj) +} + +func (tomlBinding) Bind(req *http.Request, obj any) error { + return decodeToml(req.Body, obj) +} + +func (tomlBinding) BindBody(body []byte, obj any) error { + return decodeToml(bytes.NewReader(body), obj) +} diff --git a/vendor/github.com/gin-gonic/gin/binding/uri.go b/vendor/github.com/gin-gonic/gin/binding/uri.go new file mode 100644 index 0000000..2915106 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/binding/uri.go @@ -0,0 +1,18 @@ +// Copyright 2018 Gin Core Team. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package binding + +type uriBinding struct{} + +func (uriBinding) Name() string { + return "uri" +} + +func (uriBinding) BindUri(m map[string][]string, obj any) error { + if err := mapURI(obj, m); err != nil { + return err + } + return validate(obj) +} diff --git a/vendor/github.com/gin-gonic/gin/binding/xml.go b/vendor/github.com/gin-gonic/gin/binding/xml.go new file mode 100644 index 0000000..a70f4ad --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/binding/xml.go @@ -0,0 +1,33 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package binding + +import ( + "bytes" + "encoding/xml" + "io" + "net/http" +) + +type xmlBinding struct{} + +func (xmlBinding) Name() string { + return "xml" +} + +func (xmlBinding) Bind(req *http.Request, obj any) error { + return decodeXML(req.Body, obj) +} + +func (xmlBinding) BindBody(body []byte, obj any) error { + return decodeXML(bytes.NewReader(body), obj) +} +func decodeXML(r io.Reader, obj any) error { + decoder := xml.NewDecoder(r) + if err := decoder.Decode(obj); err != nil { + return err + } + return validate(obj) +} diff --git a/vendor/github.com/gin-gonic/gin/binding/yaml.go b/vendor/github.com/gin-gonic/gin/binding/yaml.go new file mode 100644 index 0000000..b0d36a3 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/binding/yaml.go @@ -0,0 +1,35 @@ +// Copyright 2018 Gin Core Team. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package binding + +import ( + "bytes" + "io" + "net/http" + + "gopkg.in/yaml.v2" +) + +type yamlBinding struct{} + +func (yamlBinding) Name() string { + return "yaml" +} + +func (yamlBinding) Bind(req *http.Request, obj any) error { + return decodeYAML(req.Body, obj) +} + +func (yamlBinding) BindBody(body []byte, obj any) error { + return decodeYAML(bytes.NewReader(body), obj) +} + +func decodeYAML(r io.Reader, obj any) error { + decoder := yaml.NewDecoder(r) + if err := decoder.Decode(obj); err != nil { + return err + } + return validate(obj) +} diff --git a/vendor/github.com/gin-gonic/gin/codecov.yml b/vendor/github.com/gin-gonic/gin/codecov.yml new file mode 100644 index 0000000..c9c9a52 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/codecov.yml @@ -0,0 +1,5 @@ +coverage: + notify: + gitter: + default: + url: https://webhooks.gitter.im/e/d90dcdeeab2f1e357165 diff --git a/vendor/github.com/gin-gonic/gin/context.go b/vendor/github.com/gin-gonic/gin/context.go new file mode 100644 index 0000000..b1ad95e --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/context.go @@ -0,0 +1,1202 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package gin + +import ( + "errors" + "io" + "io/ioutil" + "log" + "math" + "mime/multipart" + "net" + "net/http" + "net/url" + "os" + "strings" + "sync" + "time" + + "github.com/gin-contrib/sse" + "github.com/gin-gonic/gin/binding" + "github.com/gin-gonic/gin/render" +) + +// Content-Type MIME of the most common data formats. +const ( + MIMEJSON = binding.MIMEJSON + MIMEHTML = binding.MIMEHTML + MIMEXML = binding.MIMEXML + MIMEXML2 = binding.MIMEXML2 + MIMEPlain = binding.MIMEPlain + MIMEPOSTForm = binding.MIMEPOSTForm + MIMEMultipartPOSTForm = binding.MIMEMultipartPOSTForm + MIMEYAML = binding.MIMEYAML + MIMETOML = binding.MIMETOML +) + +// BodyBytesKey indicates a default body bytes key. +const BodyBytesKey = "_gin-gonic/gin/bodybyteskey" + +// ContextKey is the key that a Context returns itself for. +const ContextKey = "_gin-gonic/gin/contextkey" + +// abortIndex represents a typical value used in abort functions. +const abortIndex int8 = math.MaxInt8 >> 1 + +// Context is the most important part of gin. It allows us to pass variables between middleware, +// manage the flow, validate the JSON of a request and render a JSON response for example. +type Context struct { + writermem responseWriter + Request *http.Request + Writer ResponseWriter + + Params Params + handlers HandlersChain + index int8 + fullPath string + + engine *Engine + params *Params + skippedNodes *[]skippedNode + + // This mutex protects Keys map. + mu sync.RWMutex + + // Keys is a key/value pair exclusively for the context of each request. + Keys map[string]any + + // Errors is a list of errors attached to all the handlers/middlewares who used this context. + Errors errorMsgs + + // Accepted defines a list of manually accepted formats for content negotiation. + Accepted []string + + // queryCache caches the query result from c.Request.URL.Query(). + queryCache url.Values + + // formCache caches c.Request.PostForm, which contains the parsed form data from POST, PATCH, + // or PUT body parameters. + formCache url.Values + + // SameSite allows a server to define a cookie attribute making it impossible for + // the browser to send this cookie along with cross-site requests. + sameSite http.SameSite +} + +/************************************/ +/********** CONTEXT CREATION ********/ +/************************************/ + +func (c *Context) reset() { + c.Writer = &c.writermem + c.Params = c.Params[:0] + c.handlers = nil + c.index = -1 + + c.fullPath = "" + c.Keys = nil + c.Errors = c.Errors[:0] + c.Accepted = nil + c.queryCache = nil + c.formCache = nil + c.sameSite = 0 + *c.params = (*c.params)[:0] + *c.skippedNodes = (*c.skippedNodes)[:0] +} + +// Copy returns a copy of the current context that can be safely used outside the request's scope. +// This has to be used when the context has to be passed to a goroutine. +func (c *Context) Copy() *Context { + cp := Context{ + writermem: c.writermem, + Request: c.Request, + Params: c.Params, + engine: c.engine, + } + cp.writermem.ResponseWriter = nil + cp.Writer = &cp.writermem + cp.index = abortIndex + cp.handlers = nil + cp.Keys = map[string]any{} + for k, v := range c.Keys { + cp.Keys[k] = v + } + paramCopy := make([]Param, len(cp.Params)) + copy(paramCopy, cp.Params) + cp.Params = paramCopy + return &cp +} + +// HandlerName returns the main handler's name. For example if the handler is "handleGetUsers()", +// this function will return "main.handleGetUsers". +func (c *Context) HandlerName() string { + return nameOfFunction(c.handlers.Last()) +} + +// HandlerNames returns a list of all registered handlers for this context in descending order, +// following the semantics of HandlerName() +func (c *Context) HandlerNames() []string { + hn := make([]string, 0, len(c.handlers)) + for _, val := range c.handlers { + hn = append(hn, nameOfFunction(val)) + } + return hn +} + +// Handler returns the main handler. +func (c *Context) Handler() HandlerFunc { + return c.handlers.Last() +} + +// FullPath returns a matched route full path. For not found routes +// returns an empty string. +// router.GET("/user/:id", func(c *gin.Context) { +// c.FullPath() == "/user/:id" // true +// }) +func (c *Context) FullPath() string { + return c.fullPath +} + +/************************************/ +/*********** FLOW CONTROL ***********/ +/************************************/ + +// Next should be used only inside middleware. +// It executes the pending handlers in the chain inside the calling handler. +// See example in GitHub. +func (c *Context) Next() { + c.index++ + for c.index < int8(len(c.handlers)) { + c.handlers[c.index](c) + c.index++ + } +} + +// IsAborted returns true if the current context was aborted. +func (c *Context) IsAborted() bool { + return c.index >= abortIndex +} + +// Abort prevents pending handlers from being called. Note that this will not stop the current handler. +// Let's say you have an authorization middleware that validates that the current request is authorized. +// If the authorization fails (ex: the password does not match), call Abort to ensure the remaining handlers +// for this request are not called. +func (c *Context) Abort() { + c.index = abortIndex +} + +// AbortWithStatus calls `Abort()` and writes the headers with the specified status code. +// For example, a failed attempt to authenticate a request could use: context.AbortWithStatus(401). +func (c *Context) AbortWithStatus(code int) { + c.Status(code) + c.Writer.WriteHeaderNow() + c.Abort() +} + +// AbortWithStatusJSON calls `Abort()` and then `JSON` internally. +// This method stops the chain, writes the status code and return a JSON body. +// It also sets the Content-Type as "application/json". +func (c *Context) AbortWithStatusJSON(code int, jsonObj any) { + c.Abort() + c.JSON(code, jsonObj) +} + +// AbortWithError calls `AbortWithStatus()` and `Error()` internally. +// This method stops the chain, writes the status code and pushes the specified error to `c.Errors`. +// See Context.Error() for more details. +func (c *Context) AbortWithError(code int, err error) *Error { + c.AbortWithStatus(code) + return c.Error(err) +} + +/************************************/ +/********* ERROR MANAGEMENT *********/ +/************************************/ + +// Error attaches an error to the current context. The error is pushed to a list of errors. +// It's a good idea to call Error for each error that occurred during the resolution of a request. +// A middleware can be used to collect all the errors and push them to a database together, +// print a log, or append it in the HTTP response. +// Error will panic if err is nil. +func (c *Context) Error(err error) *Error { + if err == nil { + panic("err is nil") + } + + var parsedError *Error + ok := errors.As(err, &parsedError) + if !ok { + parsedError = &Error{ + Err: err, + Type: ErrorTypePrivate, + } + } + + c.Errors = append(c.Errors, parsedError) + return parsedError +} + +/************************************/ +/******** METADATA MANAGEMENT********/ +/************************************/ + +// Set is used to store a new key/value pair exclusively for this context. +// It also lazy initializes c.Keys if it was not used previously. +func (c *Context) Set(key string, value any) { + c.mu.Lock() + if c.Keys == nil { + c.Keys = make(map[string]any) + } + + c.Keys[key] = value + c.mu.Unlock() +} + +// Get returns the value for the given key, ie: (value, true). +// If the value does not exist it returns (nil, false) +func (c *Context) Get(key string) (value any, exists bool) { + c.mu.RLock() + value, exists = c.Keys[key] + c.mu.RUnlock() + return +} + +// MustGet returns the value for the given key if it exists, otherwise it panics. +func (c *Context) MustGet(key string) any { + if value, exists := c.Get(key); exists { + return value + } + panic("Key \"" + key + "\" does not exist") +} + +// GetString returns the value associated with the key as a string. +func (c *Context) GetString(key string) (s string) { + if val, ok := c.Get(key); ok && val != nil { + s, _ = val.(string) + } + return +} + +// GetBool returns the value associated with the key as a boolean. +func (c *Context) GetBool(key string) (b bool) { + if val, ok := c.Get(key); ok && val != nil { + b, _ = val.(bool) + } + return +} + +// GetInt returns the value associated with the key as an integer. +func (c *Context) GetInt(key string) (i int) { + if val, ok := c.Get(key); ok && val != nil { + i, _ = val.(int) + } + return +} + +// GetInt64 returns the value associated with the key as an integer. +func (c *Context) GetInt64(key string) (i64 int64) { + if val, ok := c.Get(key); ok && val != nil { + i64, _ = val.(int64) + } + return +} + +// GetUint returns the value associated with the key as an unsigned integer. +func (c *Context) GetUint(key string) (ui uint) { + if val, ok := c.Get(key); ok && val != nil { + ui, _ = val.(uint) + } + return +} + +// GetUint64 returns the value associated with the key as an unsigned integer. +func (c *Context) GetUint64(key string) (ui64 uint64) { + if val, ok := c.Get(key); ok && val != nil { + ui64, _ = val.(uint64) + } + return +} + +// GetFloat64 returns the value associated with the key as a float64. +func (c *Context) GetFloat64(key string) (f64 float64) { + if val, ok := c.Get(key); ok && val != nil { + f64, _ = val.(float64) + } + return +} + +// GetTime returns the value associated with the key as time. +func (c *Context) GetTime(key string) (t time.Time) { + if val, ok := c.Get(key); ok && val != nil { + t, _ = val.(time.Time) + } + return +} + +// GetDuration returns the value associated with the key as a duration. +func (c *Context) GetDuration(key string) (d time.Duration) { + if val, ok := c.Get(key); ok && val != nil { + d, _ = val.(time.Duration) + } + return +} + +// GetStringSlice returns the value associated with the key as a slice of strings. +func (c *Context) GetStringSlice(key string) (ss []string) { + if val, ok := c.Get(key); ok && val != nil { + ss, _ = val.([]string) + } + return +} + +// GetStringMap returns the value associated with the key as a map of interfaces. +func (c *Context) GetStringMap(key string) (sm map[string]any) { + if val, ok := c.Get(key); ok && val != nil { + sm, _ = val.(map[string]any) + } + return +} + +// GetStringMapString returns the value associated with the key as a map of strings. +func (c *Context) GetStringMapString(key string) (sms map[string]string) { + if val, ok := c.Get(key); ok && val != nil { + sms, _ = val.(map[string]string) + } + return +} + +// GetStringMapStringSlice returns the value associated with the key as a map to a slice of strings. +func (c *Context) GetStringMapStringSlice(key string) (smss map[string][]string) { + if val, ok := c.Get(key); ok && val != nil { + smss, _ = val.(map[string][]string) + } + return +} + +/************************************/ +/************ INPUT DATA ************/ +/************************************/ + +// Param returns the value of the URL param. +// It is a shortcut for c.Params.ByName(key) +// router.GET("/user/:id", func(c *gin.Context) { +// // a GET request to /user/john +// id := c.Param("id") // id == "john" +// }) +func (c *Context) Param(key string) string { + return c.Params.ByName(key) +} + +// AddParam adds param to context and +// replaces path param key with given value for e2e testing purposes +// Example Route: "/user/:id" +// AddParam("id", 1) +// Result: "/user/1" +func (c *Context) AddParam(key, value string) { + c.Params = append(c.Params, Param{Key: key, Value: value}) +} + +// Query returns the keyed url query value if it exists, +// otherwise it returns an empty string `("")`. +// It is shortcut for `c.Request.URL.Query().Get(key)` +// GET /path?id=1234&name=Manu&value= +// c.Query("id") == "1234" +// c.Query("name") == "Manu" +// c.Query("value") == "" +// c.Query("wtf") == "" +func (c *Context) Query(key string) (value string) { + value, _ = c.GetQuery(key) + return +} + +// DefaultQuery returns the keyed url query value if it exists, +// otherwise it returns the specified defaultValue string. +// See: Query() and GetQuery() for further information. +// GET /?name=Manu&lastname= +// c.DefaultQuery("name", "unknown") == "Manu" +// c.DefaultQuery("id", "none") == "none" +// c.DefaultQuery("lastname", "none") == "" +func (c *Context) DefaultQuery(key, defaultValue string) string { + if value, ok := c.GetQuery(key); ok { + return value + } + return defaultValue +} + +// GetQuery is like Query(), it returns the keyed url query value +// if it exists `(value, true)` (even when the value is an empty string), +// otherwise it returns `("", false)`. +// It is shortcut for `c.Request.URL.Query().Get(key)` +// GET /?name=Manu&lastname= +// ("Manu", true) == c.GetQuery("name") +// ("", false) == c.GetQuery("id") +// ("", true) == c.GetQuery("lastname") +func (c *Context) GetQuery(key string) (string, bool) { + if values, ok := c.GetQueryArray(key); ok { + return values[0], ok + } + return "", false +} + +// QueryArray returns a slice of strings for a given query key. +// The length of the slice depends on the number of params with the given key. +func (c *Context) QueryArray(key string) (values []string) { + values, _ = c.GetQueryArray(key) + return +} + +func (c *Context) initQueryCache() { + if c.queryCache == nil { + if c.Request != nil { + c.queryCache = c.Request.URL.Query() + } else { + c.queryCache = url.Values{} + } + } +} + +// GetQueryArray returns a slice of strings for a given query key, plus +// a boolean value whether at least one value exists for the given key. +func (c *Context) GetQueryArray(key string) (values []string, ok bool) { + c.initQueryCache() + values, ok = c.queryCache[key] + return +} + +// QueryMap returns a map for a given query key. +func (c *Context) QueryMap(key string) (dicts map[string]string) { + dicts, _ = c.GetQueryMap(key) + return +} + +// GetQueryMap returns a map for a given query key, plus a boolean value +// whether at least one value exists for the given key. +func (c *Context) GetQueryMap(key string) (map[string]string, bool) { + c.initQueryCache() + return c.get(c.queryCache, key) +} + +// PostForm returns the specified key from a POST urlencoded form or multipart form +// when it exists, otherwise it returns an empty string `("")`. +func (c *Context) PostForm(key string) (value string) { + value, _ = c.GetPostForm(key) + return +} + +// DefaultPostForm returns the specified key from a POST urlencoded form or multipart form +// when it exists, otherwise it returns the specified defaultValue string. +// See: PostForm() and GetPostForm() for further information. +func (c *Context) DefaultPostForm(key, defaultValue string) string { + if value, ok := c.GetPostForm(key); ok { + return value + } + return defaultValue +} + +// GetPostForm is like PostForm(key). It returns the specified key from a POST urlencoded +// form or multipart form when it exists `(value, true)` (even when the value is an empty string), +// otherwise it returns ("", false). +// For example, during a PATCH request to update the user's email: +// email=mail@example.com --> ("mail@example.com", true) := GetPostForm("email") // set email to "mail@example.com" +// email= --> ("", true) := GetPostForm("email") // set email to "" +// --> ("", false) := GetPostForm("email") // do nothing with email +func (c *Context) GetPostForm(key string) (string, bool) { + if values, ok := c.GetPostFormArray(key); ok { + return values[0], ok + } + return "", false +} + +// PostFormArray returns a slice of strings for a given form key. +// The length of the slice depends on the number of params with the given key. +func (c *Context) PostFormArray(key string) (values []string) { + values, _ = c.GetPostFormArray(key) + return +} + +func (c *Context) initFormCache() { + if c.formCache == nil { + c.formCache = make(url.Values) + req := c.Request + if err := req.ParseMultipartForm(c.engine.MaxMultipartMemory); err != nil { + if !errors.Is(err, http.ErrNotMultipart) { + debugPrint("error on parse multipart form array: %v", err) + } + } + c.formCache = req.PostForm + } +} + +// GetPostFormArray returns a slice of strings for a given form key, plus +// a boolean value whether at least one value exists for the given key. +func (c *Context) GetPostFormArray(key string) (values []string, ok bool) { + c.initFormCache() + values, ok = c.formCache[key] + return +} + +// PostFormMap returns a map for a given form key. +func (c *Context) PostFormMap(key string) (dicts map[string]string) { + dicts, _ = c.GetPostFormMap(key) + return +} + +// GetPostFormMap returns a map for a given form key, plus a boolean value +// whether at least one value exists for the given key. +func (c *Context) GetPostFormMap(key string) (map[string]string, bool) { + c.initFormCache() + return c.get(c.formCache, key) +} + +// get is an internal method and returns a map which satisfy conditions. +func (c *Context) get(m map[string][]string, key string) (map[string]string, bool) { + dicts := make(map[string]string) + exist := false + for k, v := range m { + if i := strings.IndexByte(k, '['); i >= 1 && k[0:i] == key { + if j := strings.IndexByte(k[i+1:], ']'); j >= 1 { + exist = true + dicts[k[i+1:][:j]] = v[0] + } + } + } + return dicts, exist +} + +// FormFile returns the first file for the provided form key. +func (c *Context) FormFile(name string) (*multipart.FileHeader, error) { + if c.Request.MultipartForm == nil { + if err := c.Request.ParseMultipartForm(c.engine.MaxMultipartMemory); err != nil { + return nil, err + } + } + f, fh, err := c.Request.FormFile(name) + if err != nil { + return nil, err + } + f.Close() + return fh, err +} + +// MultipartForm is the parsed multipart form, including file uploads. +func (c *Context) MultipartForm() (*multipart.Form, error) { + err := c.Request.ParseMultipartForm(c.engine.MaxMultipartMemory) + return c.Request.MultipartForm, err +} + +// SaveUploadedFile uploads the form file to specific dst. +func (c *Context) SaveUploadedFile(file *multipart.FileHeader, dst string) error { + src, err := file.Open() + if err != nil { + return err + } + defer src.Close() + + out, err := os.Create(dst) + if err != nil { + return err + } + defer out.Close() + + _, err = io.Copy(out, src) + return err +} + +// Bind checks the Method and Content-Type to select a binding engine automatically, +// Depending on the "Content-Type" header different bindings are used, for example: +// "application/json" --> JSON binding +// "application/xml" --> XML binding +// It parses the request's body as JSON if Content-Type == "application/json" using JSON or XML as a JSON input. +// It decodes the json payload into the struct specified as a pointer. +// It writes a 400 error and sets Content-Type header "text/plain" in the response if input is not valid. +func (c *Context) Bind(obj any) error { + b := binding.Default(c.Request.Method, c.ContentType()) + return c.MustBindWith(obj, b) +} + +// BindJSON is a shortcut for c.MustBindWith(obj, binding.JSON). +func (c *Context) BindJSON(obj any) error { + return c.MustBindWith(obj, binding.JSON) +} + +// BindXML is a shortcut for c.MustBindWith(obj, binding.BindXML). +func (c *Context) BindXML(obj any) error { + return c.MustBindWith(obj, binding.XML) +} + +// BindQuery is a shortcut for c.MustBindWith(obj, binding.Query). +func (c *Context) BindQuery(obj any) error { + return c.MustBindWith(obj, binding.Query) +} + +// BindYAML is a shortcut for c.MustBindWith(obj, binding.YAML). +func (c *Context) BindYAML(obj any) error { + return c.MustBindWith(obj, binding.YAML) +} + +// BindTOML is a shortcut for c.MustBindWith(obj, binding.TOML). +func (c *Context) BindTOML(obj interface{}) error { + return c.MustBindWith(obj, binding.TOML) +} + +// BindHeader is a shortcut for c.MustBindWith(obj, binding.Header). +func (c *Context) BindHeader(obj any) error { + return c.MustBindWith(obj, binding.Header) +} + +// BindUri binds the passed struct pointer using binding.Uri. +// It will abort the request with HTTP 400 if any error occurs. +func (c *Context) BindUri(obj any) error { + if err := c.ShouldBindUri(obj); err != nil { + c.AbortWithError(http.StatusBadRequest, err).SetType(ErrorTypeBind) // nolint: errcheck + return err + } + return nil +} + +// MustBindWith binds the passed struct pointer using the specified binding engine. +// It will abort the request with HTTP 400 if any error occurs. +// See the binding package. +func (c *Context) MustBindWith(obj any, b binding.Binding) error { + if err := c.ShouldBindWith(obj, b); err != nil { + c.AbortWithError(http.StatusBadRequest, err).SetType(ErrorTypeBind) // nolint: errcheck + return err + } + return nil +} + +// ShouldBind checks the Method and Content-Type to select a binding engine automatically, +// Depending on the "Content-Type" header different bindings are used, for example: +// "application/json" --> JSON binding +// "application/xml" --> XML binding +// It parses the request's body as JSON if Content-Type == "application/json" using JSON or XML as a JSON input. +// It decodes the json payload into the struct specified as a pointer. +// Like c.Bind() but this method does not set the response status code to 400 or abort if input is not valid. +func (c *Context) ShouldBind(obj any) error { + b := binding.Default(c.Request.Method, c.ContentType()) + return c.ShouldBindWith(obj, b) +} + +// ShouldBindJSON is a shortcut for c.ShouldBindWith(obj, binding.JSON). +func (c *Context) ShouldBindJSON(obj any) error { + return c.ShouldBindWith(obj, binding.JSON) +} + +// ShouldBindXML is a shortcut for c.ShouldBindWith(obj, binding.XML). +func (c *Context) ShouldBindXML(obj any) error { + return c.ShouldBindWith(obj, binding.XML) +} + +// ShouldBindQuery is a shortcut for c.ShouldBindWith(obj, binding.Query). +func (c *Context) ShouldBindQuery(obj any) error { + return c.ShouldBindWith(obj, binding.Query) +} + +// ShouldBindYAML is a shortcut for c.ShouldBindWith(obj, binding.YAML). +func (c *Context) ShouldBindYAML(obj any) error { + return c.ShouldBindWith(obj, binding.YAML) +} + +// ShouldBindTOML is a shortcut for c.ShouldBindWith(obj, binding.TOML). +func (c *Context) ShouldBindTOML(obj interface{}) error { + return c.ShouldBindWith(obj, binding.TOML) +} + +// ShouldBindHeader is a shortcut for c.ShouldBindWith(obj, binding.Header). +func (c *Context) ShouldBindHeader(obj any) error { + return c.ShouldBindWith(obj, binding.Header) +} + +// ShouldBindUri binds the passed struct pointer using the specified binding engine. +func (c *Context) ShouldBindUri(obj any) error { + m := make(map[string][]string) + for _, v := range c.Params { + m[v.Key] = []string{v.Value} + } + return binding.Uri.BindUri(m, obj) +} + +// ShouldBindWith binds the passed struct pointer using the specified binding engine. +// See the binding package. +func (c *Context) ShouldBindWith(obj any, b binding.Binding) error { + return b.Bind(c.Request, obj) +} + +// ShouldBindBodyWith is similar with ShouldBindWith, but it stores the request +// body into the context, and reuse when it is called again. +// +// NOTE: This method reads the body before binding. So you should use +// ShouldBindWith for better performance if you need to call only once. +func (c *Context) ShouldBindBodyWith(obj any, bb binding.BindingBody) (err error) { + var body []byte + if cb, ok := c.Get(BodyBytesKey); ok { + if cbb, ok := cb.([]byte); ok { + body = cbb + } + } + if body == nil { + body, err = ioutil.ReadAll(c.Request.Body) + if err != nil { + return err + } + c.Set(BodyBytesKey, body) + } + return bb.BindBody(body, obj) +} + +// ClientIP implements one best effort algorithm to return the real client IP. +// It called c.RemoteIP() under the hood, to check if the remote IP is a trusted proxy or not. +// If it is it will then try to parse the headers defined in Engine.RemoteIPHeaders (defaulting to [X-Forwarded-For, X-Real-Ip]). +// If the headers are not syntactically valid OR the remote IP does not correspond to a trusted proxy, +// the remote IP (coming from Request.RemoteAddr) is returned. +func (c *Context) ClientIP() string { + // Check if we're running on a trusted platform, continue running backwards if error + if c.engine.TrustedPlatform != "" { + // Developers can define their own header of Trusted Platform or use predefined constants + if addr := c.requestHeader(c.engine.TrustedPlatform); addr != "" { + return addr + } + } + + // Legacy "AppEngine" flag + if c.engine.AppEngine { + log.Println(`The AppEngine flag is going to be deprecated. Please check issues #2723 and #2739 and use 'TrustedPlatform: gin.PlatformGoogleAppEngine' instead.`) + if addr := c.requestHeader("X-Appengine-Remote-Addr"); addr != "" { + return addr + } + } + + // It also checks if the remoteIP is a trusted proxy or not. + // In order to perform this validation, it will see if the IP is contained within at least one of the CIDR blocks + // defined by Engine.SetTrustedProxies() + remoteIP := net.ParseIP(c.RemoteIP()) + if remoteIP == nil { + return "" + } + trusted := c.engine.isTrustedProxy(remoteIP) + + if trusted && c.engine.ForwardedByClientIP && c.engine.RemoteIPHeaders != nil { + for _, headerName := range c.engine.RemoteIPHeaders { + ip, valid := c.engine.validateHeader(c.requestHeader(headerName)) + if valid { + return ip + } + } + } + return remoteIP.String() +} + +// RemoteIP parses the IP from Request.RemoteAddr, normalizes and returns the IP (without the port). +func (c *Context) RemoteIP() string { + ip, _, err := net.SplitHostPort(strings.TrimSpace(c.Request.RemoteAddr)) + if err != nil { + return "" + } + return ip +} + +// ContentType returns the Content-Type header of the request. +func (c *Context) ContentType() string { + return filterFlags(c.requestHeader("Content-Type")) +} + +// IsWebsocket returns true if the request headers indicate that a websocket +// handshake is being initiated by the client. +func (c *Context) IsWebsocket() bool { + if strings.Contains(strings.ToLower(c.requestHeader("Connection")), "upgrade") && + strings.EqualFold(c.requestHeader("Upgrade"), "websocket") { + return true + } + return false +} + +func (c *Context) requestHeader(key string) string { + return c.Request.Header.Get(key) +} + +/************************************/ +/******** RESPONSE RENDERING ********/ +/************************************/ + +// bodyAllowedForStatus is a copy of http.bodyAllowedForStatus non-exported function. +func bodyAllowedForStatus(status int) bool { + switch { + case status >= 100 && status <= 199: + return false + case status == http.StatusNoContent: + return false + case status == http.StatusNotModified: + return false + } + return true +} + +// Status sets the HTTP response code. +func (c *Context) Status(code int) { + c.Writer.WriteHeader(code) +} + +// Header is an intelligent shortcut for c.Writer.Header().Set(key, value). +// It writes a header in the response. +// If value == "", this method removes the header `c.Writer.Header().Del(key)` +func (c *Context) Header(key, value string) { + if value == "" { + c.Writer.Header().Del(key) + return + } + c.Writer.Header().Set(key, value) +} + +// GetHeader returns value from request headers. +func (c *Context) GetHeader(key string) string { + return c.requestHeader(key) +} + +// GetRawData returns stream data. +func (c *Context) GetRawData() ([]byte, error) { + return ioutil.ReadAll(c.Request.Body) +} + +// SetSameSite with cookie +func (c *Context) SetSameSite(samesite http.SameSite) { + c.sameSite = samesite +} + +// SetCookie adds a Set-Cookie header to the ResponseWriter's headers. +// The provided cookie must have a valid Name. Invalid cookies may be +// silently dropped. +func (c *Context) SetCookie(name, value string, maxAge int, path, domain string, secure, httpOnly bool) { + if path == "" { + path = "/" + } + http.SetCookie(c.Writer, &http.Cookie{ + Name: name, + Value: url.QueryEscape(value), + MaxAge: maxAge, + Path: path, + Domain: domain, + SameSite: c.sameSite, + Secure: secure, + HttpOnly: httpOnly, + }) +} + +// Cookie returns the named cookie provided in the request or +// ErrNoCookie if not found. And return the named cookie is unescaped. +// If multiple cookies match the given name, only one cookie will +// be returned. +func (c *Context) Cookie(name string) (string, error) { + cookie, err := c.Request.Cookie(name) + if err != nil { + return "", err + } + val, _ := url.QueryUnescape(cookie.Value) + return val, nil +} + +// Render writes the response headers and calls render.Render to render data. +func (c *Context) Render(code int, r render.Render) { + c.Status(code) + + if !bodyAllowedForStatus(code) { + r.WriteContentType(c.Writer) + c.Writer.WriteHeaderNow() + return + } + + if err := r.Render(c.Writer); err != nil { + panic(err) + } +} + +// HTML renders the HTTP template specified by its file name. +// It also updates the HTTP code and sets the Content-Type as "text/html". +// See http://golang.org/doc/articles/wiki/ +func (c *Context) HTML(code int, name string, obj any) { + instance := c.engine.HTMLRender.Instance(name, obj) + c.Render(code, instance) +} + +// IndentedJSON serializes the given struct as pretty JSON (indented + endlines) into the response body. +// It also sets the Content-Type as "application/json". +// WARNING: we recommend using this only for development purposes since printing pretty JSON is +// more CPU and bandwidth consuming. Use Context.JSON() instead. +func (c *Context) IndentedJSON(code int, obj any) { + c.Render(code, render.IndentedJSON{Data: obj}) +} + +// SecureJSON serializes the given struct as Secure JSON into the response body. +// Default prepends "while(1)," to response body if the given struct is array values. +// It also sets the Content-Type as "application/json". +func (c *Context) SecureJSON(code int, obj any) { + c.Render(code, render.SecureJSON{Prefix: c.engine.secureJSONPrefix, Data: obj}) +} + +// JSONP serializes the given struct as JSON into the response body. +// It adds padding to response body to request data from a server residing in a different domain than the client. +// It also sets the Content-Type as "application/javascript". +func (c *Context) JSONP(code int, obj any) { + callback := c.DefaultQuery("callback", "") + if callback == "" { + c.Render(code, render.JSON{Data: obj}) + return + } + c.Render(code, render.JsonpJSON{Callback: callback, Data: obj}) +} + +// JSON serializes the given struct as JSON into the response body. +// It also sets the Content-Type as "application/json". +func (c *Context) JSON(code int, obj any) { + c.Render(code, render.JSON{Data: obj}) +} + +// AsciiJSON serializes the given struct as JSON into the response body with unicode to ASCII string. +// It also sets the Content-Type as "application/json". +func (c *Context) AsciiJSON(code int, obj any) { + c.Render(code, render.AsciiJSON{Data: obj}) +} + +// PureJSON serializes the given struct as JSON into the response body. +// PureJSON, unlike JSON, does not replace special html characters with their unicode entities. +func (c *Context) PureJSON(code int, obj any) { + c.Render(code, render.PureJSON{Data: obj}) +} + +// XML serializes the given struct as XML into the response body. +// It also sets the Content-Type as "application/xml". +func (c *Context) XML(code int, obj any) { + c.Render(code, render.XML{Data: obj}) +} + +// YAML serializes the given struct as YAML into the response body. +func (c *Context) YAML(code int, obj any) { + c.Render(code, render.YAML{Data: obj}) +} + +// TOML serializes the given struct as TOML into the response body. +func (c *Context) TOML(code int, obj interface{}) { + c.Render(code, render.TOML{Data: obj}) +} + +// ProtoBuf serializes the given struct as ProtoBuf into the response body. +func (c *Context) ProtoBuf(code int, obj any) { + c.Render(code, render.ProtoBuf{Data: obj}) +} + +// String writes the given string into the response body. +func (c *Context) String(code int, format string, values ...any) { + c.Render(code, render.String{Format: format, Data: values}) +} + +// Redirect returns an HTTP redirect to the specific location. +func (c *Context) Redirect(code int, location string) { + c.Render(-1, render.Redirect{ + Code: code, + Location: location, + Request: c.Request, + }) +} + +// Data writes some data into the body stream and updates the HTTP code. +func (c *Context) Data(code int, contentType string, data []byte) { + c.Render(code, render.Data{ + ContentType: contentType, + Data: data, + }) +} + +// DataFromReader writes the specified reader into the body stream and updates the HTTP code. +func (c *Context) DataFromReader(code int, contentLength int64, contentType string, reader io.Reader, extraHeaders map[string]string) { + c.Render(code, render.Reader{ + Headers: extraHeaders, + ContentType: contentType, + ContentLength: contentLength, + Reader: reader, + }) +} + +// File writes the specified file into the body stream in an efficient way. +func (c *Context) File(filepath string) { + http.ServeFile(c.Writer, c.Request, filepath) +} + +// FileFromFS writes the specified file from http.FileSystem into the body stream in an efficient way. +func (c *Context) FileFromFS(filepath string, fs http.FileSystem) { + defer func(old string) { + c.Request.URL.Path = old + }(c.Request.URL.Path) + + c.Request.URL.Path = filepath + + http.FileServer(fs).ServeHTTP(c.Writer, c.Request) +} + +// FileAttachment writes the specified file into the body stream in an efficient way +// On the client side, the file will typically be downloaded with the given filename +func (c *Context) FileAttachment(filepath, filename string) { + if isASCII(filename) { + c.Writer.Header().Set("Content-Disposition", `attachment; filename="`+filename+`"`) + } else { + c.Writer.Header().Set("Content-Disposition", `attachment; filename*=UTF-8''`+url.QueryEscape(filename)) + } + http.ServeFile(c.Writer, c.Request, filepath) +} + +// SSEvent writes a Server-Sent Event into the body stream. +func (c *Context) SSEvent(name string, message any) { + c.Render(-1, sse.Event{ + Event: name, + Data: message, + }) +} + +// Stream sends a streaming response and returns a boolean +// indicates "Is client disconnected in middle of stream" +func (c *Context) Stream(step func(w io.Writer) bool) bool { + w := c.Writer + clientGone := w.CloseNotify() + for { + select { + case <-clientGone: + return true + default: + keepOpen := step(w) + w.Flush() + if !keepOpen { + return false + } + } + } +} + +/************************************/ +/******** CONTENT NEGOTIATION *******/ +/************************************/ + +// Negotiate contains all negotiations data. +type Negotiate struct { + Offered []string + HTMLName string + HTMLData any + JSONData any + XMLData any + YAMLData any + Data any + TOMLData any +} + +// Negotiate calls different Render according to acceptable Accept format. +func (c *Context) Negotiate(code int, config Negotiate) { + switch c.NegotiateFormat(config.Offered...) { + case binding.MIMEJSON: + data := chooseData(config.JSONData, config.Data) + c.JSON(code, data) + + case binding.MIMEHTML: + data := chooseData(config.HTMLData, config.Data) + c.HTML(code, config.HTMLName, data) + + case binding.MIMEXML: + data := chooseData(config.XMLData, config.Data) + c.XML(code, data) + + case binding.MIMEYAML: + data := chooseData(config.YAMLData, config.Data) + c.YAML(code, data) + + case binding.MIMETOML: + data := chooseData(config.TOMLData, config.Data) + c.TOML(code, data) + + default: + c.AbortWithError(http.StatusNotAcceptable, errors.New("the accepted formats are not offered by the server")) // nolint: errcheck + } +} + +// NegotiateFormat returns an acceptable Accept format. +func (c *Context) NegotiateFormat(offered ...string) string { + assert1(len(offered) > 0, "you must provide at least one offer") + + if c.Accepted == nil { + c.Accepted = parseAccept(c.requestHeader("Accept")) + } + if len(c.Accepted) == 0 { + return offered[0] + } + for _, accepted := range c.Accepted { + for _, offer := range offered { + // According to RFC 2616 and RFC 2396, non-ASCII characters are not allowed in headers, + // therefore we can just iterate over the string without casting it into []rune + i := 0 + for ; i < len(accepted); i++ { + if accepted[i] == '*' || offer[i] == '*' { + return offer + } + if accepted[i] != offer[i] { + break + } + } + if i == len(accepted) { + return offer + } + } + } + return "" +} + +// SetAccepted sets Accept header data. +func (c *Context) SetAccepted(formats ...string) { + c.Accepted = formats +} + +/************************************/ +/***** GOLANG.ORG/X/NET/CONTEXT *****/ +/************************************/ + +// Deadline returns that there is no deadline (ok==false) when c.Request has no Context. +func (c *Context) Deadline() (deadline time.Time, ok bool) { + if !c.engine.ContextWithFallback || c.Request == nil || c.Request.Context() == nil { + return + } + return c.Request.Context().Deadline() +} + +// Done returns nil (chan which will wait forever) when c.Request has no Context. +func (c *Context) Done() <-chan struct{} { + if !c.engine.ContextWithFallback || c.Request == nil || c.Request.Context() == nil { + return nil + } + return c.Request.Context().Done() +} + +// Err returns nil when c.Request has no Context. +func (c *Context) Err() error { + if !c.engine.ContextWithFallback || c.Request == nil || c.Request.Context() == nil { + return nil + } + return c.Request.Context().Err() +} + +// Value returns the value associated with this context for key, or nil +// if no value is associated with key. Successive calls to Value with +// the same key returns the same result. +func (c *Context) Value(key any) any { + if key == 0 { + return c.Request + } + if key == ContextKey { + return c + } + if keyAsString, ok := key.(string); ok { + if val, exists := c.Get(keyAsString); exists { + return val + } + } + if !c.engine.ContextWithFallback || c.Request == nil || c.Request.Context() == nil { + return nil + } + return c.Request.Context().Value(key) +} diff --git a/vendor/github.com/gin-gonic/gin/context_appengine.go b/vendor/github.com/gin-gonic/gin/context_appengine.go new file mode 100644 index 0000000..931313f --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/context_appengine.go @@ -0,0 +1,12 @@ +// Copyright 2017 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +//go:build appengine +// +build appengine + +package gin + +func init() { + defaultPlatform = PlatformGoogleAppEngine +} diff --git a/vendor/github.com/gin-gonic/gin/debug.go b/vendor/github.com/gin-gonic/gin/debug.go new file mode 100644 index 0000000..25fd7c8 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/debug.go @@ -0,0 +1,101 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package gin + +import ( + "fmt" + "html/template" + "runtime" + "strconv" + "strings" +) + +const ginSupportMinGoVer = 14 + +// IsDebugging returns true if the framework is running in debug mode. +// Use SetMode(gin.ReleaseMode) to disable debug mode. +func IsDebugging() bool { + return ginMode == debugCode +} + +// DebugPrintRouteFunc indicates debug log output format. +var DebugPrintRouteFunc func(httpMethod, absolutePath, handlerName string, nuHandlers int) + +func debugPrintRoute(httpMethod, absolutePath string, handlers HandlersChain) { + if IsDebugging() { + nuHandlers := len(handlers) + handlerName := nameOfFunction(handlers.Last()) + if DebugPrintRouteFunc == nil { + debugPrint("%-6s %-25s --> %s (%d handlers)\n", httpMethod, absolutePath, handlerName, nuHandlers) + } else { + DebugPrintRouteFunc(httpMethod, absolutePath, handlerName, nuHandlers) + } + } +} + +func debugPrintLoadTemplate(tmpl *template.Template) { + if IsDebugging() { + var buf strings.Builder + for _, tmpl := range tmpl.Templates() { + buf.WriteString("\t- ") + buf.WriteString(tmpl.Name()) + buf.WriteString("\n") + } + debugPrint("Loaded HTML Templates (%d): \n%s\n", len(tmpl.Templates()), buf.String()) + } +} + +func debugPrint(format string, values ...any) { + if IsDebugging() { + if !strings.HasSuffix(format, "\n") { + format += "\n" + } + fmt.Fprintf(DefaultWriter, "[GIN-debug] "+format, values...) + } +} + +func getMinVer(v string) (uint64, error) { + first := strings.IndexByte(v, '.') + last := strings.LastIndexByte(v, '.') + if first == last { + return strconv.ParseUint(v[first+1:], 10, 64) + } + return strconv.ParseUint(v[first+1:last], 10, 64) +} + +func debugPrintWARNINGDefault() { + if v, e := getMinVer(runtime.Version()); e == nil && v <= ginSupportMinGoVer { + debugPrint(`[WARNING] Now Gin requires Go 1.14+. + +`) + } + debugPrint(`[WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached. + +`) +} + +func debugPrintWARNINGNew() { + debugPrint(`[WARNING] Running in "debug" mode. Switch to "release" mode in production. + - using env: export GIN_MODE=release + - using code: gin.SetMode(gin.ReleaseMode) + +`) +} + +func debugPrintWARNINGSetHTMLTemplate() { + debugPrint(`[WARNING] Since SetHTMLTemplate() is NOT thread-safe. It should only be called +at initialization. ie. before any route is registered or the router is listening in a socket: + + router := gin.Default() + router.SetHTMLTemplate(template) // << good place + +`) +} + +func debugPrintError(err error) { + if err != nil && IsDebugging() { + fmt.Fprintf(DefaultErrorWriter, "[GIN-debug] [ERROR] %v\n", err) + } +} diff --git a/vendor/github.com/gin-gonic/gin/deprecated.go b/vendor/github.com/gin-gonic/gin/deprecated.go new file mode 100644 index 0000000..fdad855 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/deprecated.go @@ -0,0 +1,21 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package gin + +import ( + "log" + + "github.com/gin-gonic/gin/binding" +) + +// BindWith binds the passed struct pointer using the specified binding engine. +// See the binding package. +func (c *Context) BindWith(obj any, b binding.Binding) error { + log.Println(`BindWith(\"interface{}, binding.Binding\") error is going to + be deprecated, please check issue #662 and either use MustBindWith() if you + want HTTP 400 to be automatically returned if any error occur, or use + ShouldBindWith() if you need to manage the error.`) + return c.MustBindWith(obj, b) +} diff --git a/vendor/github.com/gin-gonic/gin/doc.go b/vendor/github.com/gin-gonic/gin/doc.go new file mode 100644 index 0000000..1bd0386 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/doc.go @@ -0,0 +1,6 @@ +/* +Package gin implements a HTTP web framework called gin. + +See https://gin-gonic.com/ for more information about gin. +*/ +package gin // import "github.com/gin-gonic/gin" diff --git a/vendor/github.com/gin-gonic/gin/errors.go b/vendor/github.com/gin-gonic/gin/errors.go new file mode 100644 index 0000000..2853ce8 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/errors.go @@ -0,0 +1,174 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package gin + +import ( + "fmt" + "reflect" + "strings" + + "github.com/gin-gonic/gin/internal/json" +) + +// ErrorType is an unsigned 64-bit error code as defined in the gin spec. +type ErrorType uint64 + +const ( + // ErrorTypeBind is used when Context.Bind() fails. + ErrorTypeBind ErrorType = 1 << 63 + // ErrorTypeRender is used when Context.Render() fails. + ErrorTypeRender ErrorType = 1 << 62 + // ErrorTypePrivate indicates a private error. + ErrorTypePrivate ErrorType = 1 << 0 + // ErrorTypePublic indicates a public error. + ErrorTypePublic ErrorType = 1 << 1 + // ErrorTypeAny indicates any other error. + ErrorTypeAny ErrorType = 1<<64 - 1 + // ErrorTypeNu indicates any other error. + ErrorTypeNu = 2 +) + +// Error represents a error's specification. +type Error struct { + Err error + Type ErrorType + Meta any +} + +type errorMsgs []*Error + +var _ error = &Error{} + +// SetType sets the error's type. +func (msg *Error) SetType(flags ErrorType) *Error { + msg.Type = flags + return msg +} + +// SetMeta sets the error's meta data. +func (msg *Error) SetMeta(data any) *Error { + msg.Meta = data + return msg +} + +// JSON creates a properly formatted JSON +func (msg *Error) JSON() any { + jsonData := H{} + if msg.Meta != nil { + value := reflect.ValueOf(msg.Meta) + switch value.Kind() { + case reflect.Struct: + return msg.Meta + case reflect.Map: + for _, key := range value.MapKeys() { + jsonData[key.String()] = value.MapIndex(key).Interface() + } + default: + jsonData["meta"] = msg.Meta + } + } + if _, ok := jsonData["error"]; !ok { + jsonData["error"] = msg.Error() + } + return jsonData +} + +// MarshalJSON implements the json.Marshaller interface. +func (msg *Error) MarshalJSON() ([]byte, error) { + return json.Marshal(msg.JSON()) +} + +// Error implements the error interface. +func (msg Error) Error() string { + return msg.Err.Error() +} + +// IsType judges one error. +func (msg *Error) IsType(flags ErrorType) bool { + return (msg.Type & flags) > 0 +} + +// Unwrap returns the wrapped error, to allow interoperability with errors.Is(), errors.As() and errors.Unwrap() +func (msg *Error) Unwrap() error { + return msg.Err +} + +// ByType returns a readonly copy filtered the byte. +// ie ByType(gin.ErrorTypePublic) returns a slice of errors with type=ErrorTypePublic. +func (a errorMsgs) ByType(typ ErrorType) errorMsgs { + if len(a) == 0 { + return nil + } + if typ == ErrorTypeAny { + return a + } + var result errorMsgs + for _, msg := range a { + if msg.IsType(typ) { + result = append(result, msg) + } + } + return result +} + +// Last returns the last error in the slice. It returns nil if the array is empty. +// Shortcut for errors[len(errors)-1]. +func (a errorMsgs) Last() *Error { + if length := len(a); length > 0 { + return a[length-1] + } + return nil +} + +// Errors returns an array with all the error messages. +// Example: +// c.Error(errors.New("first")) +// c.Error(errors.New("second")) +// c.Error(errors.New("third")) +// c.Errors.Errors() // == []string{"first", "second", "third"} +func (a errorMsgs) Errors() []string { + if len(a) == 0 { + return nil + } + errorStrings := make([]string, len(a)) + for i, err := range a { + errorStrings[i] = err.Error() + } + return errorStrings +} + +func (a errorMsgs) JSON() any { + switch length := len(a); length { + case 0: + return nil + case 1: + return a.Last().JSON() + default: + jsonData := make([]any, length) + for i, err := range a { + jsonData[i] = err.JSON() + } + return jsonData + } +} + +// MarshalJSON implements the json.Marshaller interface. +func (a errorMsgs) MarshalJSON() ([]byte, error) { + return json.Marshal(a.JSON()) +} + +func (a errorMsgs) String() string { + if len(a) == 0 { + return "" + } + var buffer strings.Builder + for i, msg := range a { + fmt.Fprintf(&buffer, "Error #%02d: %s\n", i+1, msg.Err) + if msg.Meta != nil { + fmt.Fprintf(&buffer, " Meta: %v\n", msg.Meta) + } + } + return buffer.String() +} diff --git a/vendor/github.com/gin-gonic/gin/fs.go b/vendor/github.com/gin-gonic/gin/fs.go new file mode 100644 index 0000000..6427473 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/fs.go @@ -0,0 +1,45 @@ +// Copyright 2017 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package gin + +import ( + "net/http" + "os" +) + +type onlyFilesFS struct { + fs http.FileSystem +} + +type neuteredReaddirFile struct { + http.File +} + +// Dir returns a http.FileSystem that can be used by http.FileServer(). It is used internally +// in router.Static(). +// if listDirectory == true, then it works the same as http.Dir() otherwise it returns +// a filesystem that prevents http.FileServer() to list the directory files. +func Dir(root string, listDirectory bool) http.FileSystem { + fs := http.Dir(root) + if listDirectory { + return fs + } + return &onlyFilesFS{fs} +} + +// Open conforms to http.Filesystem. +func (fs onlyFilesFS) Open(name string) (http.File, error) { + f, err := fs.fs.Open(name) + if err != nil { + return nil, err + } + return neuteredReaddirFile{f}, nil +} + +// Readdir overrides the http.File default implementation. +func (f neuteredReaddirFile) Readdir(count int) ([]os.FileInfo, error) { + // this disables directory listing + return nil, nil +} diff --git a/vendor/github.com/gin-gonic/gin/gin.go b/vendor/github.com/gin-gonic/gin/gin.go new file mode 100644 index 0000000..f932429 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/gin.go @@ -0,0 +1,704 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package gin + +import ( + "fmt" + "html/template" + "net" + "net/http" + "os" + "path" + "strings" + "sync" + + "github.com/gin-gonic/gin/internal/bytesconv" + "github.com/gin-gonic/gin/render" + "golang.org/x/net/http2" + "golang.org/x/net/http2/h2c" +) + +const defaultMultipartMemory = 32 << 20 // 32 MB + +var ( + default404Body = []byte("404 page not found") + default405Body = []byte("405 method not allowed") +) + +var defaultPlatform string + +var defaultTrustedCIDRs = []*net.IPNet{ + { // 0.0.0.0/0 (IPv4) + IP: net.IP{0x0, 0x0, 0x0, 0x0}, + Mask: net.IPMask{0x0, 0x0, 0x0, 0x0}, + }, + { // ::/0 (IPv6) + IP: net.IP{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, + Mask: net.IPMask{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, + }, +} + +// HandlerFunc defines the handler used by gin middleware as return value. +type HandlerFunc func(*Context) + +// HandlersChain defines a HandlerFunc slice. +type HandlersChain []HandlerFunc + +// Last returns the last handler in the chain. i.e. the last handler is the main one. +func (c HandlersChain) Last() HandlerFunc { + if length := len(c); length > 0 { + return c[length-1] + } + return nil +} + +// RouteInfo represents a request route's specification which contains method and path and its handler. +type RouteInfo struct { + Method string + Path string + Handler string + HandlerFunc HandlerFunc +} + +// RoutesInfo defines a RouteInfo slice. +type RoutesInfo []RouteInfo + +// Trusted platforms +const ( + // PlatformGoogleAppEngine when running on Google App Engine. Trust X-Appengine-Remote-Addr + // for determining the client's IP + PlatformGoogleAppEngine = "X-Appengine-Remote-Addr" + // PlatformCloudflare when using Cloudflare's CDN. Trust CF-Connecting-IP for determining + // the client's IP + PlatformCloudflare = "CF-Connecting-IP" +) + +// Engine is the framework's instance, it contains the muxer, middleware and configuration settings. +// Create an instance of Engine, by using New() or Default() +type Engine struct { + RouterGroup + + // RedirectTrailingSlash enables automatic redirection if the current route can't be matched but a + // handler for the path with (without) the trailing slash exists. + // For example if /foo/ is requested but a route only exists for /foo, the + // client is redirected to /foo with http status code 301 for GET requests + // and 307 for all other request methods. + RedirectTrailingSlash bool + + // RedirectFixedPath if enabled, the router tries to fix the current request path, if no + // handle is registered for it. + // First superfluous path elements like ../ or // are removed. + // Afterwards the router does a case-insensitive lookup of the cleaned path. + // If a handle can be found for this route, the router makes a redirection + // to the corrected path with status code 301 for GET requests and 307 for + // all other request methods. + // For example /FOO and /..//Foo could be redirected to /foo. + // RedirectTrailingSlash is independent of this option. + RedirectFixedPath bool + + // HandleMethodNotAllowed if enabled, the router checks if another method is allowed for the + // current route, if the current request can not be routed. + // If this is the case, the request is answered with 'Method Not Allowed' + // and HTTP status code 405. + // If no other Method is allowed, the request is delegated to the NotFound + // handler. + HandleMethodNotAllowed bool + + // ForwardedByClientIP if enabled, client IP will be parsed from the request's headers that + // match those stored at `(*gin.Engine).RemoteIPHeaders`. If no IP was + // fetched, it falls back to the IP obtained from + // `(*gin.Context).Request.RemoteAddr`. + ForwardedByClientIP bool + + // AppEngine was deprecated. + // Deprecated: USE `TrustedPlatform` WITH VALUE `gin.PlatformGoogleAppEngine` INSTEAD + // #726 #755 If enabled, it will trust some headers starting with + // 'X-AppEngine...' for better integration with that PaaS. + AppEngine bool + + // UseRawPath if enabled, the url.RawPath will be used to find parameters. + UseRawPath bool + + // UnescapePathValues if true, the path value will be unescaped. + // If UseRawPath is false (by default), the UnescapePathValues effectively is true, + // as url.Path gonna be used, which is already unescaped. + UnescapePathValues bool + + // RemoveExtraSlash a parameter can be parsed from the URL even with extra slashes. + // See the PR #1817 and issue #1644 + RemoveExtraSlash bool + + // RemoteIPHeaders list of headers used to obtain the client IP when + // `(*gin.Engine).ForwardedByClientIP` is `true` and + // `(*gin.Context).Request.RemoteAddr` is matched by at least one of the + // network origins of list defined by `(*gin.Engine).SetTrustedProxies()`. + RemoteIPHeaders []string + + // TrustedPlatform if set to a constant of value gin.Platform*, trusts the headers set by + // that platform, for example to determine the client IP + TrustedPlatform string + + // MaxMultipartMemory value of 'maxMemory' param that is given to http.Request's ParseMultipartForm + // method call. + MaxMultipartMemory int64 + + // UseH2C enable h2c support. + UseH2C bool + + // ContextWithFallback enable fallback Context.Deadline(), Context.Done(), Context.Err() and Context.Value() when Context.Request.Context() is not nil. + ContextWithFallback bool + + delims render.Delims + secureJSONPrefix string + HTMLRender render.HTMLRender + FuncMap template.FuncMap + allNoRoute HandlersChain + allNoMethod HandlersChain + noRoute HandlersChain + noMethod HandlersChain + pool sync.Pool + trees methodTrees + maxParams uint16 + maxSections uint16 + trustedProxies []string + trustedCIDRs []*net.IPNet +} + +var _ IRouter = &Engine{} + +// New returns a new blank Engine instance without any middleware attached. +// By default, the configuration is: +// - RedirectTrailingSlash: true +// - RedirectFixedPath: false +// - HandleMethodNotAllowed: false +// - ForwardedByClientIP: true +// - UseRawPath: false +// - UnescapePathValues: true +func New() *Engine { + debugPrintWARNINGNew() + engine := &Engine{ + RouterGroup: RouterGroup{ + Handlers: nil, + basePath: "/", + root: true, + }, + FuncMap: template.FuncMap{}, + RedirectTrailingSlash: true, + RedirectFixedPath: false, + HandleMethodNotAllowed: false, + ForwardedByClientIP: true, + RemoteIPHeaders: []string{"X-Forwarded-For", "X-Real-IP"}, + TrustedPlatform: defaultPlatform, + UseRawPath: false, + RemoveExtraSlash: false, + UnescapePathValues: true, + MaxMultipartMemory: defaultMultipartMemory, + trees: make(methodTrees, 0, 9), + delims: render.Delims{Left: "{{", Right: "}}"}, + secureJSONPrefix: "while(1);", + trustedProxies: []string{"0.0.0.0/0", "::/0"}, + trustedCIDRs: defaultTrustedCIDRs, + } + engine.RouterGroup.engine = engine + engine.pool.New = func() any { + return engine.allocateContext() + } + return engine +} + +// Default returns an Engine instance with the Logger and Recovery middleware already attached. +func Default() *Engine { + debugPrintWARNINGDefault() + engine := New() + engine.Use(Logger(), Recovery()) + return engine +} + +func (engine *Engine) Handler() http.Handler { + if !engine.UseH2C { + return engine + } + + h2s := &http2.Server{} + return h2c.NewHandler(engine, h2s) +} + +func (engine *Engine) allocateContext() *Context { + v := make(Params, 0, engine.maxParams) + skippedNodes := make([]skippedNode, 0, engine.maxSections) + return &Context{engine: engine, params: &v, skippedNodes: &skippedNodes} +} + +// Delims sets template left and right delims and returns an Engine instance. +func (engine *Engine) Delims(left, right string) *Engine { + engine.delims = render.Delims{Left: left, Right: right} + return engine +} + +// SecureJsonPrefix sets the secureJSONPrefix used in Context.SecureJSON. +func (engine *Engine) SecureJsonPrefix(prefix string) *Engine { + engine.secureJSONPrefix = prefix + return engine +} + +// LoadHTMLGlob loads HTML files identified by glob pattern +// and associates the result with HTML renderer. +func (engine *Engine) LoadHTMLGlob(pattern string) { + left := engine.delims.Left + right := engine.delims.Right + templ := template.Must(template.New("").Delims(left, right).Funcs(engine.FuncMap).ParseGlob(pattern)) + + if IsDebugging() { + debugPrintLoadTemplate(templ) + engine.HTMLRender = render.HTMLDebug{Glob: pattern, FuncMap: engine.FuncMap, Delims: engine.delims} + return + } + + engine.SetHTMLTemplate(templ) +} + +// LoadHTMLFiles loads a slice of HTML files +// and associates the result with HTML renderer. +func (engine *Engine) LoadHTMLFiles(files ...string) { + if IsDebugging() { + engine.HTMLRender = render.HTMLDebug{Files: files, FuncMap: engine.FuncMap, Delims: engine.delims} + return + } + + templ := template.Must(template.New("").Delims(engine.delims.Left, engine.delims.Right).Funcs(engine.FuncMap).ParseFiles(files...)) + engine.SetHTMLTemplate(templ) +} + +// SetHTMLTemplate associate a template with HTML renderer. +func (engine *Engine) SetHTMLTemplate(templ *template.Template) { + if len(engine.trees) > 0 { + debugPrintWARNINGSetHTMLTemplate() + } + + engine.HTMLRender = render.HTMLProduction{Template: templ.Funcs(engine.FuncMap)} +} + +// SetFuncMap sets the FuncMap used for template.FuncMap. +func (engine *Engine) SetFuncMap(funcMap template.FuncMap) { + engine.FuncMap = funcMap +} + +// NoRoute adds handlers for NoRoute. It returns a 404 code by default. +func (engine *Engine) NoRoute(handlers ...HandlerFunc) { + engine.noRoute = handlers + engine.rebuild404Handlers() +} + +// NoMethod sets the handlers called when Engine.HandleMethodNotAllowed = true. +func (engine *Engine) NoMethod(handlers ...HandlerFunc) { + engine.noMethod = handlers + engine.rebuild405Handlers() +} + +// Use attaches a global middleware to the router. i.e. the middleware attached through Use() will be +// included in the handlers chain for every single request. Even 404, 405, static files... +// For example, this is the right place for a logger or error management middleware. +func (engine *Engine) Use(middleware ...HandlerFunc) IRoutes { + engine.RouterGroup.Use(middleware...) + engine.rebuild404Handlers() + engine.rebuild405Handlers() + return engine +} + +func (engine *Engine) rebuild404Handlers() { + engine.allNoRoute = engine.combineHandlers(engine.noRoute) +} + +func (engine *Engine) rebuild405Handlers() { + engine.allNoMethod = engine.combineHandlers(engine.noMethod) +} + +func (engine *Engine) addRoute(method, path string, handlers HandlersChain) { + assert1(path[0] == '/', "path must begin with '/'") + assert1(method != "", "HTTP method can not be empty") + assert1(len(handlers) > 0, "there must be at least one handler") + + debugPrintRoute(method, path, handlers) + + root := engine.trees.get(method) + if root == nil { + root = new(node) + root.fullPath = "/" + engine.trees = append(engine.trees, methodTree{method: method, root: root}) + } + root.addRoute(path, handlers) + + // Update maxParams + if paramsCount := countParams(path); paramsCount > engine.maxParams { + engine.maxParams = paramsCount + } + + if sectionsCount := countSections(path); sectionsCount > engine.maxSections { + engine.maxSections = sectionsCount + } +} + +// Routes returns a slice of registered routes, including some useful information, such as: +// the http method, path and the handler name. +func (engine *Engine) Routes() (routes RoutesInfo) { + for _, tree := range engine.trees { + routes = iterate("", tree.method, routes, tree.root) + } + return routes +} + +func iterate(path, method string, routes RoutesInfo, root *node) RoutesInfo { + path += root.path + if len(root.handlers) > 0 { + handlerFunc := root.handlers.Last() + routes = append(routes, RouteInfo{ + Method: method, + Path: path, + Handler: nameOfFunction(handlerFunc), + HandlerFunc: handlerFunc, + }) + } + for _, child := range root.children { + routes = iterate(path, method, routes, child) + } + return routes +} + +// Run attaches the router to a http.Server and starts listening and serving HTTP requests. +// It is a shortcut for http.ListenAndServe(addr, router) +// Note: this method will block the calling goroutine indefinitely unless an error happens. +func (engine *Engine) Run(addr ...string) (err error) { + defer func() { debugPrintError(err) }() + + if engine.isUnsafeTrustedProxies() { + debugPrint("[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.\n" + + "Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.") + } + + address := resolveAddress(addr) + debugPrint("Listening and serving HTTP on %s\n", address) + err = http.ListenAndServe(address, engine.Handler()) + return +} + +func (engine *Engine) prepareTrustedCIDRs() ([]*net.IPNet, error) { + if engine.trustedProxies == nil { + return nil, nil + } + + cidr := make([]*net.IPNet, 0, len(engine.trustedProxies)) + for _, trustedProxy := range engine.trustedProxies { + if !strings.Contains(trustedProxy, "/") { + ip := parseIP(trustedProxy) + if ip == nil { + return cidr, &net.ParseError{Type: "IP address", Text: trustedProxy} + } + + switch len(ip) { + case net.IPv4len: + trustedProxy += "/32" + case net.IPv6len: + trustedProxy += "/128" + } + } + _, cidrNet, err := net.ParseCIDR(trustedProxy) + if err != nil { + return cidr, err + } + cidr = append(cidr, cidrNet) + } + return cidr, nil +} + +// SetTrustedProxies set a list of network origins (IPv4 addresses, +// IPv4 CIDRs, IPv6 addresses or IPv6 CIDRs) from which to trust +// request's headers that contain alternative client IP when +// `(*gin.Engine).ForwardedByClientIP` is `true`. `TrustedProxies` +// feature is enabled by default, and it also trusts all proxies +// by default. If you want to disable this feature, use +// Engine.SetTrustedProxies(nil), then Context.ClientIP() will +// return the remote address directly. +func (engine *Engine) SetTrustedProxies(trustedProxies []string) error { + engine.trustedProxies = trustedProxies + return engine.parseTrustedProxies() +} + +// isUnsafeTrustedProxies checks if Engine.trustedCIDRs contains all IPs, it's not safe if it has (returns true) +func (engine *Engine) isUnsafeTrustedProxies() bool { + return engine.isTrustedProxy(net.ParseIP("0.0.0.0")) || engine.isTrustedProxy(net.ParseIP("::")) +} + +// parseTrustedProxies parse Engine.trustedProxies to Engine.trustedCIDRs +func (engine *Engine) parseTrustedProxies() error { + trustedCIDRs, err := engine.prepareTrustedCIDRs() + engine.trustedCIDRs = trustedCIDRs + return err +} + +// isTrustedProxy will check whether the IP address is included in the trusted list according to Engine.trustedCIDRs +func (engine *Engine) isTrustedProxy(ip net.IP) bool { + if engine.trustedCIDRs == nil { + return false + } + for _, cidr := range engine.trustedCIDRs { + if cidr.Contains(ip) { + return true + } + } + return false +} + +// validateHeader will parse X-Forwarded-For header and return the trusted client IP address +func (engine *Engine) validateHeader(header string) (clientIP string, valid bool) { + if header == "" { + return "", false + } + items := strings.Split(header, ",") + for i := len(items) - 1; i >= 0; i-- { + ipStr := strings.TrimSpace(items[i]) + ip := net.ParseIP(ipStr) + if ip == nil { + break + } + + // X-Forwarded-For is appended by proxy + // Check IPs in reverse order and stop when find untrusted proxy + if (i == 0) || (!engine.isTrustedProxy(ip)) { + return ipStr, true + } + } + return "", false +} + +// parseIP parse a string representation of an IP and returns a net.IP with the +// minimum byte representation or nil if input is invalid. +func parseIP(ip string) net.IP { + parsedIP := net.ParseIP(ip) + + if ipv4 := parsedIP.To4(); ipv4 != nil { + // return ip in a 4-byte representation + return ipv4 + } + + // return ip in a 16-byte representation or nil + return parsedIP +} + +// RunTLS attaches the router to a http.Server and starts listening and serving HTTPS (secure) requests. +// It is a shortcut for http.ListenAndServeTLS(addr, certFile, keyFile, router) +// Note: this method will block the calling goroutine indefinitely unless an error happens. +func (engine *Engine) RunTLS(addr, certFile, keyFile string) (err error) { + debugPrint("Listening and serving HTTPS on %s\n", addr) + defer func() { debugPrintError(err) }() + + if engine.isUnsafeTrustedProxies() { + debugPrint("[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.\n" + + "Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.") + } + + err = http.ListenAndServeTLS(addr, certFile, keyFile, engine.Handler()) + return +} + +// RunUnix attaches the router to a http.Server and starts listening and serving HTTP requests +// through the specified unix socket (i.e. a file). +// Note: this method will block the calling goroutine indefinitely unless an error happens. +func (engine *Engine) RunUnix(file string) (err error) { + debugPrint("Listening and serving HTTP on unix:/%s", file) + defer func() { debugPrintError(err) }() + + if engine.isUnsafeTrustedProxies() { + debugPrint("[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.\n" + + "Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.") + } + + listener, err := net.Listen("unix", file) + if err != nil { + return + } + defer listener.Close() + defer os.Remove(file) + + err = http.Serve(listener, engine.Handler()) + return +} + +// RunFd attaches the router to a http.Server and starts listening and serving HTTP requests +// through the specified file descriptor. +// Note: this method will block the calling goroutine indefinitely unless an error happens. +func (engine *Engine) RunFd(fd int) (err error) { + debugPrint("Listening and serving HTTP on fd@%d", fd) + defer func() { debugPrintError(err) }() + + if engine.isUnsafeTrustedProxies() { + debugPrint("[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.\n" + + "Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.") + } + + f := os.NewFile(uintptr(fd), fmt.Sprintf("fd@%d", fd)) + listener, err := net.FileListener(f) + if err != nil { + return + } + defer listener.Close() + err = engine.RunListener(listener) + return +} + +// RunListener attaches the router to a http.Server and starts listening and serving HTTP requests +// through the specified net.Listener +func (engine *Engine) RunListener(listener net.Listener) (err error) { + debugPrint("Listening and serving HTTP on listener what's bind with address@%s", listener.Addr()) + defer func() { debugPrintError(err) }() + + if engine.isUnsafeTrustedProxies() { + debugPrint("[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.\n" + + "Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.") + } + + err = http.Serve(listener, engine.Handler()) + return +} + +// ServeHTTP conforms to the http.Handler interface. +func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) { + c := engine.pool.Get().(*Context) + c.writermem.reset(w) + c.Request = req + c.reset() + + engine.handleHTTPRequest(c) + + engine.pool.Put(c) +} + +// HandleContext re-enters a context that has been rewritten. +// This can be done by setting c.Request.URL.Path to your new target. +// Disclaimer: You can loop yourself to deal with this, use wisely. +func (engine *Engine) HandleContext(c *Context) { + oldIndexValue := c.index + c.reset() + engine.handleHTTPRequest(c) + + c.index = oldIndexValue +} + +func (engine *Engine) handleHTTPRequest(c *Context) { + httpMethod := c.Request.Method + rPath := c.Request.URL.Path + unescape := false + if engine.UseRawPath && len(c.Request.URL.RawPath) > 0 { + rPath = c.Request.URL.RawPath + unescape = engine.UnescapePathValues + } + + if engine.RemoveExtraSlash { + rPath = cleanPath(rPath) + } + + // Find root of the tree for the given HTTP method + t := engine.trees + for i, tl := 0, len(t); i < tl; i++ { + if t[i].method != httpMethod { + continue + } + root := t[i].root + // Find route in tree + value := root.getValue(rPath, c.params, c.skippedNodes, unescape) + if value.params != nil { + c.Params = *value.params + } + if value.handlers != nil { + c.handlers = value.handlers + c.fullPath = value.fullPath + c.Next() + c.writermem.WriteHeaderNow() + return + } + if httpMethod != http.MethodConnect && rPath != "/" { + if value.tsr && engine.RedirectTrailingSlash { + redirectTrailingSlash(c) + return + } + if engine.RedirectFixedPath && redirectFixedPath(c, root, engine.RedirectFixedPath) { + return + } + } + break + } + + if engine.HandleMethodNotAllowed { + for _, tree := range engine.trees { + if tree.method == httpMethod { + continue + } + if value := tree.root.getValue(rPath, nil, c.skippedNodes, unescape); value.handlers != nil { + c.handlers = engine.allNoMethod + serveError(c, http.StatusMethodNotAllowed, default405Body) + return + } + } + } + c.handlers = engine.allNoRoute + serveError(c, http.StatusNotFound, default404Body) +} + +var mimePlain = []string{MIMEPlain} + +func serveError(c *Context, code int, defaultMessage []byte) { + c.writermem.status = code + c.Next() + if c.writermem.Written() { + return + } + if c.writermem.Status() == code { + c.writermem.Header()["Content-Type"] = mimePlain + _, err := c.Writer.Write(defaultMessage) + if err != nil { + debugPrint("cannot write message to writer during serve error: %v", err) + } + return + } + c.writermem.WriteHeaderNow() +} + +func redirectTrailingSlash(c *Context) { + req := c.Request + p := req.URL.Path + if prefix := path.Clean(c.Request.Header.Get("X-Forwarded-Prefix")); prefix != "." { + p = prefix + "/" + req.URL.Path + } + req.URL.Path = p + "/" + if length := len(p); length > 1 && p[length-1] == '/' { + req.URL.Path = p[:length-1] + } + redirectRequest(c) +} + +func redirectFixedPath(c *Context, root *node, trailingSlash bool) bool { + req := c.Request + rPath := req.URL.Path + + if fixedPath, ok := root.findCaseInsensitivePath(cleanPath(rPath), trailingSlash); ok { + req.URL.Path = bytesconv.BytesToString(fixedPath) + redirectRequest(c) + return true + } + return false +} + +func redirectRequest(c *Context) { + req := c.Request + rPath := req.URL.Path + rURL := req.URL.String() + + code := http.StatusMovedPermanently // Permanent redirect, request with GET method + if req.Method != http.MethodGet { + code = http.StatusTemporaryRedirect + } + debugPrint("redirecting request %d: %s --> %s", code, rPath, rURL) + http.Redirect(c.Writer, req, rURL, code) + c.writermem.WriteHeaderNow() +} diff --git a/vendor/github.com/gin-gonic/gin/go.mod b/vendor/github.com/gin-gonic/gin/go.mod new file mode 100644 index 0000000..6cdde34 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/go.mod @@ -0,0 +1,31 @@ +module github.com/gin-gonic/gin + +go 1.18 + +require ( + github.com/gin-contrib/sse v0.1.0 + github.com/go-playground/validator/v10 v10.10.0 + github.com/goccy/go-json v0.9.7 + github.com/json-iterator/go v1.1.12 + github.com/mattn/go-isatty v0.0.14 + github.com/pelletier/go-toml/v2 v2.0.1 + github.com/stretchr/testify v1.7.1 + github.com/ugorji/go/codec v1.2.7 + golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 + google.golang.org/protobuf v1.28.0 + gopkg.in/yaml.v2 v2.4.0 +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/go-playground/locales v0.14.0 // indirect + github.com/go-playground/universal-translator v0.18.0 // indirect + github.com/leodido/go-urn v1.2.1 // indirect + github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect + golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 // indirect + golang.org/x/text v0.3.6 // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect +) diff --git a/vendor/github.com/gin-gonic/gin/go.sum b/vendor/github.com/gin-gonic/gin/go.sum new file mode 100644 index 0000000..d06b810 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/go.sum @@ -0,0 +1,84 @@ +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= +github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= +github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= +github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= +github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0= +github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= +github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM= +github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= +github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU= +github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= +github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= +github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= +github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 h1:siQdpVirKtzPhKl3lZWozZraCFObP8S1v6PRp0bLrtU= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/vendor/github.com/gin-gonic/gin/internal/bytesconv/bytesconv.go b/vendor/github.com/gin-gonic/gin/internal/bytesconv/bytesconv.go new file mode 100644 index 0000000..86e4c4d --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/internal/bytesconv/bytesconv.go @@ -0,0 +1,24 @@ +// Copyright 2020 Gin Core Team. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package bytesconv + +import ( + "unsafe" +) + +// StringToBytes converts string to byte slice without a memory allocation. +func StringToBytes(s string) []byte { + return *(*[]byte)(unsafe.Pointer( + &struct { + string + Cap int + }{s, len(s)}, + )) +} + +// BytesToString converts byte slice to string without a memory allocation. +func BytesToString(b []byte) string { + return *(*string)(unsafe.Pointer(&b)) +} diff --git a/vendor/github.com/gin-gonic/gin/internal/json/go_json.go b/vendor/github.com/gin-gonic/gin/internal/json/go_json.go new file mode 100644 index 0000000..23f7172 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/internal/json/go_json.go @@ -0,0 +1,23 @@ +// Copyright 2017 Bo-Yi Wu. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +//go:build go_json +// +build go_json + +package json + +import json "github.com/goccy/go-json" + +var ( + // Marshal is exported by gin/json package. + Marshal = json.Marshal + // Unmarshal is exported by gin/json package. + Unmarshal = json.Unmarshal + // MarshalIndent is exported by gin/json package. + MarshalIndent = json.MarshalIndent + // NewDecoder is exported by gin/json package. + NewDecoder = json.NewDecoder + // NewEncoder is exported by gin/json package. + NewEncoder = json.NewEncoder +) diff --git a/vendor/github.com/gin-gonic/gin/internal/json/json.go b/vendor/github.com/gin-gonic/gin/internal/json/json.go new file mode 100644 index 0000000..a26d7db --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/internal/json/json.go @@ -0,0 +1,23 @@ +// Copyright 2017 Bo-Yi Wu. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +//go:build !jsoniter && !go_json +// +build !jsoniter,!go_json + +package json + +import "encoding/json" + +var ( + // Marshal is exported by gin/json package. + Marshal = json.Marshal + // Unmarshal is exported by gin/json package. + Unmarshal = json.Unmarshal + // MarshalIndent is exported by gin/json package. + MarshalIndent = json.MarshalIndent + // NewDecoder is exported by gin/json package. + NewDecoder = json.NewDecoder + // NewEncoder is exported by gin/json package. + NewEncoder = json.NewEncoder +) diff --git a/vendor/github.com/gin-gonic/gin/internal/json/jsoniter.go b/vendor/github.com/gin-gonic/gin/internal/json/jsoniter.go new file mode 100644 index 0000000..853b1a9 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/internal/json/jsoniter.go @@ -0,0 +1,24 @@ +// Copyright 2017 Bo-Yi Wu. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +//go:build jsoniter +// +build jsoniter + +package json + +import jsoniter "github.com/json-iterator/go" + +var ( + json = jsoniter.ConfigCompatibleWithStandardLibrary + // Marshal is exported by gin/json package. + Marshal = json.Marshal + // Unmarshal is exported by gin/json package. + Unmarshal = json.Unmarshal + // MarshalIndent is exported by gin/json package. + MarshalIndent = json.MarshalIndent + // NewDecoder is exported by gin/json package. + NewDecoder = json.NewDecoder + // NewEncoder is exported by gin/json package. + NewEncoder = json.NewEncoder +) diff --git a/vendor/github.com/gin-gonic/gin/logger.go b/vendor/github.com/gin-gonic/gin/logger.go new file mode 100644 index 0000000..cd1e7fa --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/logger.go @@ -0,0 +1,270 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package gin + +import ( + "fmt" + "io" + "net/http" + "os" + "time" + + "github.com/mattn/go-isatty" +) + +type consoleColorModeValue int + +const ( + autoColor consoleColorModeValue = iota + disableColor + forceColor +) + +const ( + green = "\033[97;42m" + white = "\033[90;47m" + yellow = "\033[90;43m" + red = "\033[97;41m" + blue = "\033[97;44m" + magenta = "\033[97;45m" + cyan = "\033[97;46m" + reset = "\033[0m" +) + +var consoleColorMode = autoColor + +// LoggerConfig defines the config for Logger middleware. +type LoggerConfig struct { + // Optional. Default value is gin.defaultLogFormatter + Formatter LogFormatter + + // Output is a writer where logs are written. + // Optional. Default value is gin.DefaultWriter. + Output io.Writer + + // SkipPaths is an url path array which logs are not written. + // Optional. + SkipPaths []string +} + +// LogFormatter gives the signature of the formatter function passed to LoggerWithFormatter +type LogFormatter func(params LogFormatterParams) string + +// LogFormatterParams is the structure any formatter will be handed when time to log comes +type LogFormatterParams struct { + Request *http.Request + + // TimeStamp shows the time after the server returns a response. + TimeStamp time.Time + // StatusCode is HTTP response code. + StatusCode int + // Latency is how much time the server cost to process a certain request. + Latency time.Duration + // ClientIP equals Context's ClientIP method. + ClientIP string + // Method is the HTTP method given to the request. + Method string + // Path is a path the client requests. + Path string + // ErrorMessage is set if error has occurred in processing the request. + ErrorMessage string + // isTerm shows whether gin's output descriptor refers to a terminal. + isTerm bool + // BodySize is the size of the Response Body + BodySize int + // Keys are the keys set on the request's context. + Keys map[string]any +} + +// StatusCodeColor is the ANSI color for appropriately logging http status code to a terminal. +func (p *LogFormatterParams) StatusCodeColor() string { + code := p.StatusCode + + switch { + case code >= http.StatusOK && code < http.StatusMultipleChoices: + return green + case code >= http.StatusMultipleChoices && code < http.StatusBadRequest: + return white + case code >= http.StatusBadRequest && code < http.StatusInternalServerError: + return yellow + default: + return red + } +} + +// MethodColor is the ANSI color for appropriately logging http method to a terminal. +func (p *LogFormatterParams) MethodColor() string { + method := p.Method + + switch method { + case http.MethodGet: + return blue + case http.MethodPost: + return cyan + case http.MethodPut: + return yellow + case http.MethodDelete: + return red + case http.MethodPatch: + return green + case http.MethodHead: + return magenta + case http.MethodOptions: + return white + default: + return reset + } +} + +// ResetColor resets all escape attributes. +func (p *LogFormatterParams) ResetColor() string { + return reset +} + +// IsOutputColor indicates whether can colors be outputted to the log. +func (p *LogFormatterParams) IsOutputColor() bool { + return consoleColorMode == forceColor || (consoleColorMode == autoColor && p.isTerm) +} + +// defaultLogFormatter is the default log format function Logger middleware uses. +var defaultLogFormatter = func(param LogFormatterParams) string { + var statusColor, methodColor, resetColor string + if param.IsOutputColor() { + statusColor = param.StatusCodeColor() + methodColor = param.MethodColor() + resetColor = param.ResetColor() + } + + if param.Latency > time.Minute { + param.Latency = param.Latency.Truncate(time.Second) + } + return fmt.Sprintf("[GIN] %v |%s %3d %s| %13v | %15s |%s %-7s %s %#v\n%s", + param.TimeStamp.Format("2006/01/02 - 15:04:05"), + statusColor, param.StatusCode, resetColor, + param.Latency, + param.ClientIP, + methodColor, param.Method, resetColor, + param.Path, + param.ErrorMessage, + ) +} + +// DisableConsoleColor disables color output in the console. +func DisableConsoleColor() { + consoleColorMode = disableColor +} + +// ForceConsoleColor force color output in the console. +func ForceConsoleColor() { + consoleColorMode = forceColor +} + +// ErrorLogger returns a HandlerFunc for any error type. +func ErrorLogger() HandlerFunc { + return ErrorLoggerT(ErrorTypeAny) +} + +// ErrorLoggerT returns a HandlerFunc for a given error type. +func ErrorLoggerT(typ ErrorType) HandlerFunc { + return func(c *Context) { + c.Next() + errors := c.Errors.ByType(typ) + if len(errors) > 0 { + c.JSON(-1, errors) + } + } +} + +// Logger instances a Logger middleware that will write the logs to gin.DefaultWriter. +// By default, gin.DefaultWriter = os.Stdout. +func Logger() HandlerFunc { + return LoggerWithConfig(LoggerConfig{}) +} + +// LoggerWithFormatter instance a Logger middleware with the specified log format function. +func LoggerWithFormatter(f LogFormatter) HandlerFunc { + return LoggerWithConfig(LoggerConfig{ + Formatter: f, + }) +} + +// LoggerWithWriter instance a Logger middleware with the specified writer buffer. +// Example: os.Stdout, a file opened in write mode, a socket... +func LoggerWithWriter(out io.Writer, notlogged ...string) HandlerFunc { + return LoggerWithConfig(LoggerConfig{ + Output: out, + SkipPaths: notlogged, + }) +} + +// LoggerWithConfig instance a Logger middleware with config. +func LoggerWithConfig(conf LoggerConfig) HandlerFunc { + formatter := conf.Formatter + if formatter == nil { + formatter = defaultLogFormatter + } + + out := conf.Output + if out == nil { + out = DefaultWriter + } + + notlogged := conf.SkipPaths + + isTerm := true + + if w, ok := out.(*os.File); !ok || os.Getenv("TERM") == "dumb" || + (!isatty.IsTerminal(w.Fd()) && !isatty.IsCygwinTerminal(w.Fd())) { + isTerm = false + } + + var skip map[string]struct{} + + if length := len(notlogged); length > 0 { + skip = make(map[string]struct{}, length) + + for _, path := range notlogged { + skip[path] = struct{}{} + } + } + + return func(c *Context) { + // Start timer + start := time.Now() + path := c.Request.URL.Path + raw := c.Request.URL.RawQuery + + // Process request + c.Next() + + // Log only when path is not being skipped + if _, ok := skip[path]; !ok { + param := LogFormatterParams{ + Request: c.Request, + isTerm: isTerm, + Keys: c.Keys, + } + + // Stop timer + param.TimeStamp = time.Now() + param.Latency = param.TimeStamp.Sub(start) + + param.ClientIP = c.ClientIP() + param.Method = c.Request.Method + param.StatusCode = c.Writer.Status() + param.ErrorMessage = c.Errors.ByType(ErrorTypePrivate).String() + + param.BodySize = c.Writer.Size() + + if raw != "" { + path = path + "?" + raw + } + + param.Path = path + + fmt.Fprint(out, formatter(param)) + } + } +} diff --git a/vendor/github.com/gin-gonic/gin/mode.go b/vendor/github.com/gin-gonic/gin/mode.go new file mode 100644 index 0000000..545fdaa --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/mode.go @@ -0,0 +1,99 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package gin + +import ( + "flag" + "io" + "os" + + "github.com/gin-gonic/gin/binding" +) + +// EnvGinMode indicates environment name for gin mode. +const EnvGinMode = "GIN_MODE" + +const ( + // DebugMode indicates gin mode is debug. + DebugMode = "debug" + // ReleaseMode indicates gin mode is release. + ReleaseMode = "release" + // TestMode indicates gin mode is test. + TestMode = "test" +) + +const ( + debugCode = iota + releaseCode + testCode +) + +// DefaultWriter is the default io.Writer used by Gin for debug output and +// middleware output like Logger() or Recovery(). +// Note that both Logger and Recovery provides custom ways to configure their +// output io.Writer. +// To support coloring in Windows use: +// import "github.com/mattn/go-colorable" +// gin.DefaultWriter = colorable.NewColorableStdout() +var DefaultWriter io.Writer = os.Stdout + +// DefaultErrorWriter is the default io.Writer used by Gin to debug errors +var DefaultErrorWriter io.Writer = os.Stderr + +var ( + ginMode = debugCode + modeName = DebugMode +) + +func init() { + mode := os.Getenv(EnvGinMode) + SetMode(mode) +} + +// SetMode sets gin mode according to input string. +func SetMode(value string) { + if value == "" { + if flag.Lookup("test.v") != nil { + value = TestMode + } else { + value = DebugMode + } + } + + switch value { + case DebugMode: + ginMode = debugCode + case ReleaseMode: + ginMode = releaseCode + case TestMode: + ginMode = testCode + default: + panic("gin mode unknown: " + value + " (available mode: debug release test)") + } + + modeName = value +} + +// DisableBindValidation closes the default validator. +func DisableBindValidation() { + binding.Validator = nil +} + +// EnableJsonDecoderUseNumber sets true for binding.EnableDecoderUseNumber to +// call the UseNumber method on the JSON Decoder instance. +func EnableJsonDecoderUseNumber() { + binding.EnableDecoderUseNumber = true +} + +// EnableJsonDecoderDisallowUnknownFields sets true for binding.EnableDecoderDisallowUnknownFields to +// call the DisallowUnknownFields method on the JSON Decoder instance. +func EnableJsonDecoderDisallowUnknownFields() { + binding.EnableDecoderDisallowUnknownFields = true +} + +// Mode returns current gin mode. +func Mode() string { + return modeName +} diff --git a/vendor/github.com/gin-gonic/gin/path.go b/vendor/github.com/gin-gonic/gin/path.go new file mode 100644 index 0000000..d42d6b9 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/path.go @@ -0,0 +1,150 @@ +// Copyright 2013 Julien Schmidt. All rights reserved. +// Based on the path package, Copyright 2009 The Go Authors. +// Use of this source code is governed by a BSD-style license that can be found +// at https://github.com/julienschmidt/httprouter/blob/master/LICENSE. + +package gin + +// cleanPath is the URL version of path.Clean, it returns a canonical URL path +// for p, eliminating . and .. elements. +// +// The following rules are applied iteratively until no further processing can +// be done: +// 1. Replace multiple slashes with a single slash. +// 2. Eliminate each . path name element (the current directory). +// 3. Eliminate each inner .. path name element (the parent directory) +// along with the non-.. element that precedes it. +// 4. Eliminate .. elements that begin a rooted path: +// that is, replace "/.." by "/" at the beginning of a path. +// +// If the result of this process is an empty string, "/" is returned. +func cleanPath(p string) string { + const stackBufSize = 128 + // Turn empty string into "/" + if p == "" { + return "/" + } + + // Reasonably sized buffer on stack to avoid allocations in the common case. + // If a larger buffer is required, it gets allocated dynamically. + buf := make([]byte, 0, stackBufSize) + + n := len(p) + + // Invariants: + // reading from path; r is index of next byte to process. + // writing to buf; w is index of next byte to write. + + // path must start with '/' + r := 1 + w := 1 + + if p[0] != '/' { + r = 0 + + if n+1 > stackBufSize { + buf = make([]byte, n+1) + } else { + buf = buf[:n+1] + } + buf[0] = '/' + } + + trailing := n > 1 && p[n-1] == '/' + + // A bit more clunky without a 'lazybuf' like the path package, but the loop + // gets completely inlined (bufApp calls). + // loop has no expensive function calls (except 1x make) // So in contrast to the path package this loop has no expensive function + // calls (except make, if needed). + + for r < n { + switch { + case p[r] == '/': + // empty path element, trailing slash is added after the end + r++ + + case p[r] == '.' && r+1 == n: + trailing = true + r++ + + case p[r] == '.' && p[r+1] == '/': + // . element + r += 2 + + case p[r] == '.' && p[r+1] == '.' && (r+2 == n || p[r+2] == '/'): + // .. element: remove to last / + r += 3 + + if w > 1 { + // can backtrack + w-- + + if len(buf) == 0 { + for w > 1 && p[w] != '/' { + w-- + } + } else { + for w > 1 && buf[w] != '/' { + w-- + } + } + } + + default: + // Real path element. + // Add slash if needed + if w > 1 { + bufApp(&buf, p, w, '/') + w++ + } + + // Copy element + for r < n && p[r] != '/' { + bufApp(&buf, p, w, p[r]) + w++ + r++ + } + } + } + + // Re-append trailing slash + if trailing && w > 1 { + bufApp(&buf, p, w, '/') + w++ + } + + // If the original string was not modified (or only shortened at the end), + // return the respective substring of the original string. + // Otherwise return a new string from the buffer. + if len(buf) == 0 { + return p[:w] + } + return string(buf[:w]) +} + +// Internal helper to lazily create a buffer if necessary. +// Calls to this function get inlined. +func bufApp(buf *[]byte, s string, w int, c byte) { + b := *buf + if len(b) == 0 { + // No modification of the original string so far. + // If the next character is the same as in the original string, we do + // not yet have to allocate a buffer. + if s[w] == c { + return + } + + // Otherwise use either the stack buffer, if it is large enough, or + // allocate a new buffer on the heap, and copy all previous characters. + length := len(s) + if length > cap(b) { + *buf = make([]byte, length) + } else { + *buf = (*buf)[:length] + } + b = *buf + + copy(b, s[:w]) + } + b[w] = c +} diff --git a/vendor/github.com/gin-gonic/gin/recovery.go b/vendor/github.com/gin-gonic/gin/recovery.go new file mode 100644 index 0000000..abb6451 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/recovery.go @@ -0,0 +1,173 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package gin + +import ( + "bytes" + "errors" + "fmt" + "io" + "io/ioutil" + "log" + "net" + "net/http" + "net/http/httputil" + "os" + "runtime" + "strings" + "time" +) + +var ( + dunno = []byte("???") + centerDot = []byte("·") + dot = []byte(".") + slash = []byte("/") +) + +// RecoveryFunc defines the function passable to CustomRecovery. +type RecoveryFunc func(c *Context, err any) + +// Recovery returns a middleware that recovers from any panics and writes a 500 if there was one. +func Recovery() HandlerFunc { + return RecoveryWithWriter(DefaultErrorWriter) +} + +// CustomRecovery returns a middleware that recovers from any panics and calls the provided handle func to handle it. +func CustomRecovery(handle RecoveryFunc) HandlerFunc { + return RecoveryWithWriter(DefaultErrorWriter, handle) +} + +// RecoveryWithWriter returns a middleware for a given writer that recovers from any panics and writes a 500 if there was one. +func RecoveryWithWriter(out io.Writer, recovery ...RecoveryFunc) HandlerFunc { + if len(recovery) > 0 { + return CustomRecoveryWithWriter(out, recovery[0]) + } + return CustomRecoveryWithWriter(out, defaultHandleRecovery) +} + +// CustomRecoveryWithWriter returns a middleware for a given writer that recovers from any panics and calls the provided handle func to handle it. +func CustomRecoveryWithWriter(out io.Writer, handle RecoveryFunc) HandlerFunc { + var logger *log.Logger + if out != nil { + logger = log.New(out, "\n\n\x1b[31m", log.LstdFlags) + } + return func(c *Context) { + defer func() { + if err := recover(); err != nil { + // Check for a broken connection, as it is not really a + // condition that warrants a panic stack trace. + var brokenPipe bool + if ne, ok := err.(*net.OpError); ok { + var se *os.SyscallError + if errors.As(ne, &se) { + if strings.Contains(strings.ToLower(se.Error()), "broken pipe") || strings.Contains(strings.ToLower(se.Error()), "connection reset by peer") { + brokenPipe = true + } + } + } + if logger != nil { + stack := stack(3) + httpRequest, _ := httputil.DumpRequest(c.Request, false) + headers := strings.Split(string(httpRequest), "\r\n") + for idx, header := range headers { + current := strings.Split(header, ":") + if current[0] == "Authorization" { + headers[idx] = current[0] + ": *" + } + } + headersToStr := strings.Join(headers, "\r\n") + if brokenPipe { + logger.Printf("%s\n%s%s", err, headersToStr, reset) + } else if IsDebugging() { + logger.Printf("[Recovery] %s panic recovered:\n%s\n%s\n%s%s", + timeFormat(time.Now()), headersToStr, err, stack, reset) + } else { + logger.Printf("[Recovery] %s panic recovered:\n%s\n%s%s", + timeFormat(time.Now()), err, stack, reset) + } + } + if brokenPipe { + // If the connection is dead, we can't write a status to it. + c.Error(err.(error)) // nolint: errcheck + c.Abort() + } else { + handle(c, err) + } + } + }() + c.Next() + } +} + +func defaultHandleRecovery(c *Context, err any) { + c.AbortWithStatus(http.StatusInternalServerError) +} + +// stack returns a nicely formatted stack frame, skipping skip frames. +func stack(skip int) []byte { + buf := new(bytes.Buffer) // the returned data + // As we loop, we open files and read them. These variables record the currently + // loaded file. + var lines [][]byte + var lastFile string + for i := skip; ; i++ { // Skip the expected number of frames + pc, file, line, ok := runtime.Caller(i) + if !ok { + break + } + // Print this much at least. If we can't find the source, it won't show. + fmt.Fprintf(buf, "%s:%d (0x%x)\n", file, line, pc) + if file != lastFile { + data, err := ioutil.ReadFile(file) + if err != nil { + continue + } + lines = bytes.Split(data, []byte{'\n'}) + lastFile = file + } + fmt.Fprintf(buf, "\t%s: %s\n", function(pc), source(lines, line)) + } + return buf.Bytes() +} + +// source returns a space-trimmed slice of the n'th line. +func source(lines [][]byte, n int) []byte { + n-- // in stack trace, lines are 1-indexed but our array is 0-indexed + if n < 0 || n >= len(lines) { + return dunno + } + return bytes.TrimSpace(lines[n]) +} + +// function returns, if possible, the name of the function containing the PC. +func function(pc uintptr) []byte { + fn := runtime.FuncForPC(pc) + if fn == nil { + return dunno + } + name := []byte(fn.Name()) + // The name includes the path name to the package, which is unnecessary + // since the file name is already included. Plus, it has center dots. + // That is, we see + // runtime/debug.*T·ptrmethod + // and want + // *T.ptrmethod + // Also the package path might contain dot (e.g. code.google.com/...), + // so first eliminate the path prefix + if lastSlash := bytes.LastIndex(name, slash); lastSlash >= 0 { + name = name[lastSlash+1:] + } + if period := bytes.Index(name, dot); period >= 0 { + name = name[period+1:] + } + name = bytes.Replace(name, centerDot, dot, -1) + return name +} + +// timeFormat returns a customized time string for logger. +func timeFormat(t time.Time) string { + return t.Format("2006/01/02 - 15:04:05") +} diff --git a/vendor/github.com/gin-gonic/gin/render/any.go b/vendor/github.com/gin-gonic/gin/render/any.go new file mode 100644 index 0000000..b19ad45 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/render/any.go @@ -0,0 +1,10 @@ +// Copyright 2021 Gin Core Team. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +//go:build !go1.18 +// +build !go1.18 + +package render + +type any = interface{} diff --git a/vendor/github.com/gin-gonic/gin/render/data.go b/vendor/github.com/gin-gonic/gin/render/data.go new file mode 100644 index 0000000..a653ea3 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/render/data.go @@ -0,0 +1,25 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package render + +import "net/http" + +// Data contains ContentType and bytes data. +type Data struct { + ContentType string + Data []byte +} + +// Render (Data) writes data with custom ContentType. +func (r Data) Render(w http.ResponseWriter) (err error) { + r.WriteContentType(w) + _, err = w.Write(r.Data) + return +} + +// WriteContentType (Data) writes custom ContentType. +func (r Data) WriteContentType(w http.ResponseWriter) { + writeContentType(w, []string{r.ContentType}) +} diff --git a/vendor/github.com/gin-gonic/gin/render/html.go b/vendor/github.com/gin-gonic/gin/render/html.go new file mode 100644 index 0000000..c308408 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/render/html.go @@ -0,0 +1,92 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package render + +import ( + "html/template" + "net/http" +) + +// Delims represents a set of Left and Right delimiters for HTML template rendering. +type Delims struct { + // Left delimiter, defaults to {{. + Left string + // Right delimiter, defaults to }}. + Right string +} + +// HTMLRender interface is to be implemented by HTMLProduction and HTMLDebug. +type HTMLRender interface { + // Instance returns an HTML instance. + Instance(string, any) Render +} + +// HTMLProduction contains template reference and its delims. +type HTMLProduction struct { + Template *template.Template + Delims Delims +} + +// HTMLDebug contains template delims and pattern and function with file list. +type HTMLDebug struct { + Files []string + Glob string + Delims Delims + FuncMap template.FuncMap +} + +// HTML contains template reference and its name with given interface object. +type HTML struct { + Template *template.Template + Name string + Data any +} + +var htmlContentType = []string{"text/html; charset=utf-8"} + +// Instance (HTMLProduction) returns an HTML instance which it realizes Render interface. +func (r HTMLProduction) Instance(name string, data any) Render { + return HTML{ + Template: r.Template, + Name: name, + Data: data, + } +} + +// Instance (HTMLDebug) returns an HTML instance which it realizes Render interface. +func (r HTMLDebug) Instance(name string, data any) Render { + return HTML{ + Template: r.loadTemplate(), + Name: name, + Data: data, + } +} +func (r HTMLDebug) loadTemplate() *template.Template { + if r.FuncMap == nil { + r.FuncMap = template.FuncMap{} + } + if len(r.Files) > 0 { + return template.Must(template.New("").Delims(r.Delims.Left, r.Delims.Right).Funcs(r.FuncMap).ParseFiles(r.Files...)) + } + if r.Glob != "" { + return template.Must(template.New("").Delims(r.Delims.Left, r.Delims.Right).Funcs(r.FuncMap).ParseGlob(r.Glob)) + } + panic("the HTML debug render was created without files or glob pattern") +} + +// Render (HTML) executes template and writes its result with custom ContentType for response. +func (r HTML) Render(w http.ResponseWriter) error { + r.WriteContentType(w) + + if r.Name == "" { + return r.Template.Execute(w, r.Data) + } + return r.Template.ExecuteTemplate(w, r.Name, r.Data) +} + +// WriteContentType (HTML) writes HTML ContentType. +func (r HTML) WriteContentType(w http.ResponseWriter) { + writeContentType(w, htmlContentType) +} diff --git a/vendor/github.com/gin-gonic/gin/render/json.go b/vendor/github.com/gin-gonic/gin/render/json.go new file mode 100644 index 0000000..af678e8 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/render/json.go @@ -0,0 +1,193 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package render + +import ( + "bytes" + "fmt" + "html/template" + "net/http" + + "github.com/gin-gonic/gin/internal/bytesconv" + "github.com/gin-gonic/gin/internal/json" +) + +// JSON contains the given interface object. +type JSON struct { + Data any +} + +// IndentedJSON contains the given interface object. +type IndentedJSON struct { + Data any +} + +// SecureJSON contains the given interface object and its prefix. +type SecureJSON struct { + Prefix string + Data any +} + +// JsonpJSON contains the given interface object its callback. +type JsonpJSON struct { + Callback string + Data any +} + +// AsciiJSON contains the given interface object. +type AsciiJSON struct { + Data any +} + +// PureJSON contains the given interface object. +type PureJSON struct { + Data any +} + +var ( + jsonContentType = []string{"application/json; charset=utf-8"} + jsonpContentType = []string{"application/javascript; charset=utf-8"} + jsonASCIIContentType = []string{"application/json"} +) + +// Render (JSON) writes data with custom ContentType. +func (r JSON) Render(w http.ResponseWriter) (err error) { + if err = WriteJSON(w, r.Data); err != nil { + panic(err) + } + return +} + +// WriteContentType (JSON) writes JSON ContentType. +func (r JSON) WriteContentType(w http.ResponseWriter) { + writeContentType(w, jsonContentType) +} + +// WriteJSON marshals the given interface object and writes it with custom ContentType. +func WriteJSON(w http.ResponseWriter, obj any) error { + writeContentType(w, jsonContentType) + jsonBytes, err := json.Marshal(obj) + if err != nil { + return err + } + _, err = w.Write(jsonBytes) + return err +} + +// Render (IndentedJSON) marshals the given interface object and writes it with custom ContentType. +func (r IndentedJSON) Render(w http.ResponseWriter) error { + r.WriteContentType(w) + jsonBytes, err := json.MarshalIndent(r.Data, "", " ") + if err != nil { + return err + } + _, err = w.Write(jsonBytes) + return err +} + +// WriteContentType (IndentedJSON) writes JSON ContentType. +func (r IndentedJSON) WriteContentType(w http.ResponseWriter) { + writeContentType(w, jsonContentType) +} + +// Render (SecureJSON) marshals the given interface object and writes it with custom ContentType. +func (r SecureJSON) Render(w http.ResponseWriter) error { + r.WriteContentType(w) + jsonBytes, err := json.Marshal(r.Data) + if err != nil { + return err + } + // if the jsonBytes is array values + if bytes.HasPrefix(jsonBytes, bytesconv.StringToBytes("[")) && bytes.HasSuffix(jsonBytes, + bytesconv.StringToBytes("]")) { + if _, err = w.Write(bytesconv.StringToBytes(r.Prefix)); err != nil { + return err + } + } + _, err = w.Write(jsonBytes) + return err +} + +// WriteContentType (SecureJSON) writes JSON ContentType. +func (r SecureJSON) WriteContentType(w http.ResponseWriter) { + writeContentType(w, jsonContentType) +} + +// Render (JsonpJSON) marshals the given interface object and writes it and its callback with custom ContentType. +func (r JsonpJSON) Render(w http.ResponseWriter) (err error) { + r.WriteContentType(w) + ret, err := json.Marshal(r.Data) + if err != nil { + return err + } + + if r.Callback == "" { + _, err = w.Write(ret) + return err + } + + callback := template.JSEscapeString(r.Callback) + if _, err = w.Write(bytesconv.StringToBytes(callback)); err != nil { + return err + } + + if _, err = w.Write(bytesconv.StringToBytes("(")); err != nil { + return err + } + + if _, err = w.Write(ret); err != nil { + return err + } + + if _, err = w.Write(bytesconv.StringToBytes(");")); err != nil { + return err + } + + return nil +} + +// WriteContentType (JsonpJSON) writes Javascript ContentType. +func (r JsonpJSON) WriteContentType(w http.ResponseWriter) { + writeContentType(w, jsonpContentType) +} + +// Render (AsciiJSON) marshals the given interface object and writes it with custom ContentType. +func (r AsciiJSON) Render(w http.ResponseWriter) (err error) { + r.WriteContentType(w) + ret, err := json.Marshal(r.Data) + if err != nil { + return err + } + + var buffer bytes.Buffer + for _, r := range bytesconv.BytesToString(ret) { + cvt := string(r) + if r >= 128 { + cvt = fmt.Sprintf("\\u%04x", int64(r)) + } + buffer.WriteString(cvt) + } + + _, err = w.Write(buffer.Bytes()) + return err +} + +// WriteContentType (AsciiJSON) writes JSON ContentType. +func (r AsciiJSON) WriteContentType(w http.ResponseWriter) { + writeContentType(w, jsonASCIIContentType) +} + +// Render (PureJSON) writes custom ContentType and encodes the given interface object. +func (r PureJSON) Render(w http.ResponseWriter) error { + r.WriteContentType(w) + encoder := json.NewEncoder(w) + encoder.SetEscapeHTML(false) + return encoder.Encode(r.Data) +} + +// WriteContentType (PureJSON) writes custom ContentType. +func (r PureJSON) WriteContentType(w http.ResponseWriter) { + writeContentType(w, jsonContentType) +} diff --git a/vendor/github.com/gin-gonic/gin/render/msgpack.go b/vendor/github.com/gin-gonic/gin/render/msgpack.go new file mode 100644 index 0000000..e0f30f7 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/render/msgpack.go @@ -0,0 +1,44 @@ +// Copyright 2017 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +//go:build !nomsgpack +// +build !nomsgpack + +package render + +import ( + "net/http" + + "github.com/ugorji/go/codec" +) + +// Check interface implemented here to support go build tag nomsgpack. +// See: https://github.com/gin-gonic/gin/pull/1852/ +var ( + _ Render = MsgPack{} +) + +// MsgPack contains the given interface object. +type MsgPack struct { + Data any +} + +var msgpackContentType = []string{"application/msgpack; charset=utf-8"} + +// WriteContentType (MsgPack) writes MsgPack ContentType. +func (r MsgPack) WriteContentType(w http.ResponseWriter) { + writeContentType(w, msgpackContentType) +} + +// Render (MsgPack) encodes the given interface object and writes data with custom ContentType. +func (r MsgPack) Render(w http.ResponseWriter) error { + return WriteMsgPack(w, r.Data) +} + +// WriteMsgPack writes MsgPack ContentType and encodes the given interface object. +func WriteMsgPack(w http.ResponseWriter, obj any) error { + writeContentType(w, msgpackContentType) + var mh codec.MsgpackHandle + return codec.NewEncoder(w, &mh).Encode(obj) +} diff --git a/vendor/github.com/gin-gonic/gin/render/protobuf.go b/vendor/github.com/gin-gonic/gin/render/protobuf.go new file mode 100644 index 0000000..9331c40 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/render/protobuf.go @@ -0,0 +1,36 @@ +// Copyright 2018 Gin Core Team. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package render + +import ( + "net/http" + + "google.golang.org/protobuf/proto" +) + +// ProtoBuf contains the given interface object. +type ProtoBuf struct { + Data any +} + +var protobufContentType = []string{"application/x-protobuf"} + +// Render (ProtoBuf) marshals the given interface object and writes data with custom ContentType. +func (r ProtoBuf) Render(w http.ResponseWriter) error { + r.WriteContentType(w) + + bytes, err := proto.Marshal(r.Data.(proto.Message)) + if err != nil { + return err + } + + _, err = w.Write(bytes) + return err +} + +// WriteContentType (ProtoBuf) writes ProtoBuf ContentType. +func (r ProtoBuf) WriteContentType(w http.ResponseWriter) { + writeContentType(w, protobufContentType) +} diff --git a/vendor/github.com/gin-gonic/gin/render/reader.go b/vendor/github.com/gin-gonic/gin/render/reader.go new file mode 100644 index 0000000..5752d8d --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/render/reader.go @@ -0,0 +1,48 @@ +// Copyright 2018 Gin Core Team. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package render + +import ( + "io" + "net/http" + "strconv" +) + +// Reader contains the IO reader and its length, and custom ContentType and other headers. +type Reader struct { + ContentType string + ContentLength int64 + Reader io.Reader + Headers map[string]string +} + +// Render (Reader) writes data with custom ContentType and headers. +func (r Reader) Render(w http.ResponseWriter) (err error) { + r.WriteContentType(w) + if r.ContentLength >= 0 { + if r.Headers == nil { + r.Headers = map[string]string{} + } + r.Headers["Content-Length"] = strconv.FormatInt(r.ContentLength, 10) + } + r.writeHeaders(w, r.Headers) + _, err = io.Copy(w, r.Reader) + return +} + +// WriteContentType (Reader) writes custom ContentType. +func (r Reader) WriteContentType(w http.ResponseWriter) { + writeContentType(w, []string{r.ContentType}) +} + +// writeHeaders writes custom Header. +func (r Reader) writeHeaders(w http.ResponseWriter, headers map[string]string) { + header := w.Header() + for k, v := range headers { + if header.Get(k) == "" { + header.Set(k, v) + } + } +} diff --git a/vendor/github.com/gin-gonic/gin/render/redirect.go b/vendor/github.com/gin-gonic/gin/render/redirect.go new file mode 100644 index 0000000..70e3a47 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/render/redirect.go @@ -0,0 +1,29 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package render + +import ( + "fmt" + "net/http" +) + +// Redirect contains the http request reference and redirects status code and location. +type Redirect struct { + Code int + Request *http.Request + Location string +} + +// Render (Redirect) redirects the http request to new location and writes redirect response. +func (r Redirect) Render(w http.ResponseWriter) error { + if (r.Code < http.StatusMultipleChoices || r.Code > http.StatusPermanentRedirect) && r.Code != http.StatusCreated { + panic(fmt.Sprintf("Cannot redirect with status code %d", r.Code)) + } + http.Redirect(w, r.Request, r.Location, r.Code) + return nil +} + +// WriteContentType (Redirect) don't write any ContentType. +func (r Redirect) WriteContentType(http.ResponseWriter) {} diff --git a/vendor/github.com/gin-gonic/gin/render/render.go b/vendor/github.com/gin-gonic/gin/render/render.go new file mode 100644 index 0000000..7955000 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/render/render.go @@ -0,0 +1,41 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package render + +import "net/http" + +// Render interface is to be implemented by JSON, XML, HTML, YAML and so on. +type Render interface { + // Render writes data with custom ContentType. + Render(http.ResponseWriter) error + // WriteContentType writes custom ContentType. + WriteContentType(w http.ResponseWriter) +} + +var ( + _ Render = JSON{} + _ Render = IndentedJSON{} + _ Render = SecureJSON{} + _ Render = JsonpJSON{} + _ Render = XML{} + _ Render = String{} + _ Render = Redirect{} + _ Render = Data{} + _ Render = HTML{} + _ HTMLRender = HTMLDebug{} + _ HTMLRender = HTMLProduction{} + _ Render = YAML{} + _ Render = Reader{} + _ Render = AsciiJSON{} + _ Render = ProtoBuf{} + _ Render = TOML{} +) + +func writeContentType(w http.ResponseWriter, value []string) { + header := w.Header() + if val := header["Content-Type"]; len(val) == 0 { + header["Content-Type"] = value + } +} diff --git a/vendor/github.com/gin-gonic/gin/render/text.go b/vendor/github.com/gin-gonic/gin/render/text.go new file mode 100644 index 0000000..77eafdf --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/render/text.go @@ -0,0 +1,41 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package render + +import ( + "fmt" + "net/http" + + "github.com/gin-gonic/gin/internal/bytesconv" +) + +// String contains the given interface object slice and its format. +type String struct { + Format string + Data []any +} + +var plainContentType = []string{"text/plain; charset=utf-8"} + +// Render (String) writes data with custom ContentType. +func (r String) Render(w http.ResponseWriter) error { + return WriteString(w, r.Format, r.Data) +} + +// WriteContentType (String) writes Plain ContentType. +func (r String) WriteContentType(w http.ResponseWriter) { + writeContentType(w, plainContentType) +} + +// WriteString writes data according to its format and write custom ContentType. +func WriteString(w http.ResponseWriter, format string, data []any) (err error) { + writeContentType(w, plainContentType) + if len(data) > 0 { + _, err = fmt.Fprintf(w, format, data...) + return + } + _, err = w.Write(bytesconv.StringToBytes(format)) + return +} diff --git a/vendor/github.com/gin-gonic/gin/render/toml.go b/vendor/github.com/gin-gonic/gin/render/toml.go new file mode 100644 index 0000000..40f044c --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/render/toml.go @@ -0,0 +1,36 @@ +// Copyright 2022 Gin Core Team. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package render + +import ( + "net/http" + + "github.com/pelletier/go-toml/v2" +) + +// TOML contains the given interface object. +type TOML struct { + Data any +} + +var TOMLContentType = []string{"application/toml; charset=utf-8"} + +// Render (TOML) marshals the given interface object and writes data with custom ContentType. +func (r TOML) Render(w http.ResponseWriter) error { + r.WriteContentType(w) + + bytes, err := toml.Marshal(r.Data) + if err != nil { + return err + } + + _, err = w.Write(bytes) + return err +} + +// WriteContentType (TOML) writes TOML ContentType for response. +func (r TOML) WriteContentType(w http.ResponseWriter) { + writeContentType(w, TOMLContentType) +} diff --git a/vendor/github.com/gin-gonic/gin/render/xml.go b/vendor/github.com/gin-gonic/gin/render/xml.go new file mode 100644 index 0000000..6af8901 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/render/xml.go @@ -0,0 +1,28 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package render + +import ( + "encoding/xml" + "net/http" +) + +// XML contains the given interface object. +type XML struct { + Data any +} + +var xmlContentType = []string{"application/xml; charset=utf-8"} + +// Render (XML) encodes the given interface object and writes data with custom ContentType. +func (r XML) Render(w http.ResponseWriter) error { + r.WriteContentType(w) + return xml.NewEncoder(w).Encode(r.Data) +} + +// WriteContentType (XML) writes XML ContentType for response. +func (r XML) WriteContentType(w http.ResponseWriter) { + writeContentType(w, xmlContentType) +} diff --git a/vendor/github.com/gin-gonic/gin/render/yaml.go b/vendor/github.com/gin-gonic/gin/render/yaml.go new file mode 100644 index 0000000..4f0ac01 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/render/yaml.go @@ -0,0 +1,36 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package render + +import ( + "net/http" + + "gopkg.in/yaml.v2" +) + +// YAML contains the given interface object. +type YAML struct { + Data any +} + +var yamlContentType = []string{"application/x-yaml; charset=utf-8"} + +// Render (YAML) marshals the given interface object and writes data with custom ContentType. +func (r YAML) Render(w http.ResponseWriter) error { + r.WriteContentType(w) + + bytes, err := yaml.Marshal(r.Data) + if err != nil { + return err + } + + _, err = w.Write(bytes) + return err +} + +// WriteContentType (YAML) writes YAML ContentType for response. +func (r YAML) WriteContentType(w http.ResponseWriter) { + writeContentType(w, yamlContentType) +} diff --git a/vendor/github.com/gin-gonic/gin/response_writer.go b/vendor/github.com/gin-gonic/gin/response_writer.go new file mode 100644 index 0000000..77c7ed8 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/response_writer.go @@ -0,0 +1,126 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package gin + +import ( + "bufio" + "io" + "net" + "net/http" +) + +const ( + noWritten = -1 + defaultStatus = http.StatusOK +) + +// ResponseWriter ... +type ResponseWriter interface { + http.ResponseWriter + http.Hijacker + http.Flusher + http.CloseNotifier + + // Status returns the HTTP response status code of the current request. + Status() int + + // Size returns the number of bytes already written into the response http body. + // See Written() + Size() int + + // WriteString writes the string into the response body. + WriteString(string) (int, error) + + // Written returns true if the response body was already written. + Written() bool + + // WriteHeaderNow forces to write the http header (status code + headers). + WriteHeaderNow() + + // Pusher get the http.Pusher for server push + Pusher() http.Pusher +} + +type responseWriter struct { + http.ResponseWriter + size int + status int +} + +var _ ResponseWriter = &responseWriter{} + +func (w *responseWriter) reset(writer http.ResponseWriter) { + w.ResponseWriter = writer + w.size = noWritten + w.status = defaultStatus +} + +func (w *responseWriter) WriteHeader(code int) { + if code > 0 && w.status != code { + if w.Written() { + debugPrint("[WARNING] Headers were already written. Wanted to override status code %d with %d", w.status, code) + } + w.status = code + } +} + +func (w *responseWriter) WriteHeaderNow() { + if !w.Written() { + w.size = 0 + w.ResponseWriter.WriteHeader(w.status) + } +} + +func (w *responseWriter) Write(data []byte) (n int, err error) { + w.WriteHeaderNow() + n, err = w.ResponseWriter.Write(data) + w.size += n + return +} + +func (w *responseWriter) WriteString(s string) (n int, err error) { + w.WriteHeaderNow() + n, err = io.WriteString(w.ResponseWriter, s) + w.size += n + return +} + +func (w *responseWriter) Status() int { + return w.status +} + +func (w *responseWriter) Size() int { + return w.size +} + +func (w *responseWriter) Written() bool { + return w.size != noWritten +} + +// Hijack implements the http.Hijacker interface. +func (w *responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { + if w.size < 0 { + w.size = 0 + } + return w.ResponseWriter.(http.Hijacker).Hijack() +} + +// CloseNotify implements the http.CloseNotifier interface. +func (w *responseWriter) CloseNotify() <-chan bool { + return w.ResponseWriter.(http.CloseNotifier).CloseNotify() +} + +// Flush implements the http.Flusher interface. +func (w *responseWriter) Flush() { + w.WriteHeaderNow() + w.ResponseWriter.(http.Flusher).Flush() +} + +func (w *responseWriter) Pusher() (pusher http.Pusher) { + if pusher, ok := w.ResponseWriter.(http.Pusher); ok { + return pusher + } + return nil +} diff --git a/vendor/github.com/gin-gonic/gin/routergroup.go b/vendor/github.com/gin-gonic/gin/routergroup.go new file mode 100644 index 0000000..3c082d9 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/routergroup.go @@ -0,0 +1,248 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package gin + +import ( + "net/http" + "path" + "regexp" + "strings" +) + +var ( + // regEnLetter matches english letters for http method name + regEnLetter = regexp.MustCompile("^[A-Z]+$") + + // anyMethods for RouterGroup Any method + anyMethods = []string{ + http.MethodGet, http.MethodPost, http.MethodPut, http.MethodPatch, + http.MethodHead, http.MethodOptions, http.MethodDelete, http.MethodConnect, + http.MethodTrace, + } +) + +// IRouter defines all router handle interface includes single and group router. +type IRouter interface { + IRoutes + Group(string, ...HandlerFunc) *RouterGroup +} + +// IRoutes defines all router handle interface. +type IRoutes interface { + Use(...HandlerFunc) IRoutes + + Handle(string, string, ...HandlerFunc) IRoutes + Any(string, ...HandlerFunc) IRoutes + GET(string, ...HandlerFunc) IRoutes + POST(string, ...HandlerFunc) IRoutes + DELETE(string, ...HandlerFunc) IRoutes + PATCH(string, ...HandlerFunc) IRoutes + PUT(string, ...HandlerFunc) IRoutes + OPTIONS(string, ...HandlerFunc) IRoutes + HEAD(string, ...HandlerFunc) IRoutes + + StaticFile(string, string) IRoutes + StaticFileFS(string, string, http.FileSystem) IRoutes + Static(string, string) IRoutes + StaticFS(string, http.FileSystem) IRoutes +} + +// RouterGroup is used internally to configure router, a RouterGroup is associated with +// a prefix and an array of handlers (middleware). +type RouterGroup struct { + Handlers HandlersChain + basePath string + engine *Engine + root bool +} + +var _ IRouter = &RouterGroup{} + +// Use adds middleware to the group, see example code in GitHub. +func (group *RouterGroup) Use(middleware ...HandlerFunc) IRoutes { + group.Handlers = append(group.Handlers, middleware...) + return group.returnObj() +} + +// Group creates a new router group. You should add all the routes that have common middlewares or the same path prefix. +// For example, all the routes that use a common middleware for authorization could be grouped. +func (group *RouterGroup) Group(relativePath string, handlers ...HandlerFunc) *RouterGroup { + return &RouterGroup{ + Handlers: group.combineHandlers(handlers), + basePath: group.calculateAbsolutePath(relativePath), + engine: group.engine, + } +} + +// BasePath returns the base path of router group. +// For example, if v := router.Group("/rest/n/v1/api"), v.BasePath() is "/rest/n/v1/api". +func (group *RouterGroup) BasePath() string { + return group.basePath +} + +func (group *RouterGroup) handle(httpMethod, relativePath string, handlers HandlersChain) IRoutes { + absolutePath := group.calculateAbsolutePath(relativePath) + handlers = group.combineHandlers(handlers) + group.engine.addRoute(httpMethod, absolutePath, handlers) + return group.returnObj() +} + +// Handle registers a new request handle and middleware with the given path and method. +// The last handler should be the real handler, the other ones should be middleware that can and should be shared among different routes. +// See the example code in GitHub. +// +// For GET, POST, PUT, PATCH and DELETE requests the respective shortcut +// functions can be used. +// +// This function is intended for bulk loading and to allow the usage of less +// frequently used, non-standardized or custom methods (e.g. for internal +// communication with a proxy). +func (group *RouterGroup) Handle(httpMethod, relativePath string, handlers ...HandlerFunc) IRoutes { + if matched := regEnLetter.MatchString(httpMethod); !matched { + panic("http method " + httpMethod + " is not valid") + } + return group.handle(httpMethod, relativePath, handlers) +} + +// POST is a shortcut for router.Handle("POST", path, handle). +func (group *RouterGroup) POST(relativePath string, handlers ...HandlerFunc) IRoutes { + return group.handle(http.MethodPost, relativePath, handlers) +} + +// GET is a shortcut for router.Handle("GET", path, handle). +func (group *RouterGroup) GET(relativePath string, handlers ...HandlerFunc) IRoutes { + return group.handle(http.MethodGet, relativePath, handlers) +} + +// DELETE is a shortcut for router.Handle("DELETE", path, handle). +func (group *RouterGroup) DELETE(relativePath string, handlers ...HandlerFunc) IRoutes { + return group.handle(http.MethodDelete, relativePath, handlers) +} + +// PATCH is a shortcut for router.Handle("PATCH", path, handle). +func (group *RouterGroup) PATCH(relativePath string, handlers ...HandlerFunc) IRoutes { + return group.handle(http.MethodPatch, relativePath, handlers) +} + +// PUT is a shortcut for router.Handle("PUT", path, handle). +func (group *RouterGroup) PUT(relativePath string, handlers ...HandlerFunc) IRoutes { + return group.handle(http.MethodPut, relativePath, handlers) +} + +// OPTIONS is a shortcut for router.Handle("OPTIONS", path, handle). +func (group *RouterGroup) OPTIONS(relativePath string, handlers ...HandlerFunc) IRoutes { + return group.handle(http.MethodOptions, relativePath, handlers) +} + +// HEAD is a shortcut for router.Handle("HEAD", path, handle). +func (group *RouterGroup) HEAD(relativePath string, handlers ...HandlerFunc) IRoutes { + return group.handle(http.MethodHead, relativePath, handlers) +} + +// Any registers a route that matches all the HTTP methods. +// GET, POST, PUT, PATCH, HEAD, OPTIONS, DELETE, CONNECT, TRACE. +func (group *RouterGroup) Any(relativePath string, handlers ...HandlerFunc) IRoutes { + for _, method := range anyMethods { + group.handle(method, relativePath, handlers) + } + + return group.returnObj() +} + +// StaticFile registers a single route in order to serve a single file of the local filesystem. +// router.StaticFile("favicon.ico", "./resources/favicon.ico") +func (group *RouterGroup) StaticFile(relativePath, filepath string) IRoutes { + return group.staticFileHandler(relativePath, func(c *Context) { + c.File(filepath) + }) +} + +// StaticFileFS works just like `StaticFile` but a custom `http.FileSystem` can be used instead.. +// router.StaticFileFS("favicon.ico", "./resources/favicon.ico", Dir{".", false}) +// Gin by default user: gin.Dir() +func (group *RouterGroup) StaticFileFS(relativePath, filepath string, fs http.FileSystem) IRoutes { + return group.staticFileHandler(relativePath, func(c *Context) { + c.FileFromFS(filepath, fs) + }) +} + +func (group *RouterGroup) staticFileHandler(relativePath string, handler HandlerFunc) IRoutes { + if strings.Contains(relativePath, ":") || strings.Contains(relativePath, "*") { + panic("URL parameters can not be used when serving a static file") + } + group.GET(relativePath, handler) + group.HEAD(relativePath, handler) + return group.returnObj() +} + +// Static serves files from the given file system root. +// Internally a http.FileServer is used, therefore http.NotFound is used instead +// of the Router's NotFound handler. +// To use the operating system's file system implementation, +// use : +// router.Static("/static", "/var/www") +func (group *RouterGroup) Static(relativePath, root string) IRoutes { + return group.StaticFS(relativePath, Dir(root, false)) +} + +// StaticFS works just like `Static()` but a custom `http.FileSystem` can be used instead. +// Gin by default user: gin.Dir() +func (group *RouterGroup) StaticFS(relativePath string, fs http.FileSystem) IRoutes { + if strings.Contains(relativePath, ":") || strings.Contains(relativePath, "*") { + panic("URL parameters can not be used when serving a static folder") + } + handler := group.createStaticHandler(relativePath, fs) + urlPattern := path.Join(relativePath, "/*filepath") + + // Register GET and HEAD handlers + group.GET(urlPattern, handler) + group.HEAD(urlPattern, handler) + return group.returnObj() +} + +func (group *RouterGroup) createStaticHandler(relativePath string, fs http.FileSystem) HandlerFunc { + absolutePath := group.calculateAbsolutePath(relativePath) + fileServer := http.StripPrefix(absolutePath, http.FileServer(fs)) + + return func(c *Context) { + if _, noListing := fs.(*onlyFilesFS); noListing { + c.Writer.WriteHeader(http.StatusNotFound) + } + + file := c.Param("filepath") + // Check if file exists and/or if we have permission to access it + f, err := fs.Open(file) + if err != nil { + c.Writer.WriteHeader(http.StatusNotFound) + c.handlers = group.engine.noRoute + // Reset index + c.index = -1 + return + } + f.Close() + + fileServer.ServeHTTP(c.Writer, c.Request) + } +} + +func (group *RouterGroup) combineHandlers(handlers HandlersChain) HandlersChain { + finalSize := len(group.Handlers) + len(handlers) + assert1(finalSize < int(abortIndex), "too many handlers") + mergedHandlers := make(HandlersChain, finalSize) + copy(mergedHandlers, group.Handlers) + copy(mergedHandlers[len(group.Handlers):], handlers) + return mergedHandlers +} + +func (group *RouterGroup) calculateAbsolutePath(relativePath string) string { + return joinPaths(group.basePath, relativePath) +} + +func (group *RouterGroup) returnObj() IRoutes { + if group.root { + return group.engine + } + return group +} diff --git a/vendor/github.com/gin-gonic/gin/test_helpers.go b/vendor/github.com/gin-gonic/gin/test_helpers.go new file mode 100644 index 0000000..b3be93b --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/test_helpers.go @@ -0,0 +1,16 @@ +// Copyright 2017 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package gin + +import "net/http" + +// CreateTestContext returns a fresh engine and context for testing purposes +func CreateTestContext(w http.ResponseWriter) (c *Context, r *Engine) { + r = New() + c = r.allocateContext() + c.reset() + c.writermem.reset(w) + return +} diff --git a/vendor/github.com/gin-gonic/gin/tree.go b/vendor/github.com/gin-gonic/gin/tree.go new file mode 100644 index 0000000..88100ee --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/tree.go @@ -0,0 +1,871 @@ +// Copyright 2013 Julien Schmidt. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be found +// at https://github.com/julienschmidt/httprouter/blob/master/LICENSE + +package gin + +import ( + "bytes" + "net/url" + "strings" + "unicode" + "unicode/utf8" + + "github.com/gin-gonic/gin/internal/bytesconv" +) + +var ( + strColon = []byte(":") + strStar = []byte("*") + strSlash = []byte("/") +) + +// Param is a single URL parameter, consisting of a key and a value. +type Param struct { + Key string + Value string +} + +// Params is a Param-slice, as returned by the router. +// The slice is ordered, the first URL parameter is also the first slice value. +// It is therefore safe to read values by the index. +type Params []Param + +// Get returns the value of the first Param which key matches the given name and a boolean true. +// If no matching Param is found, an empty string is returned and a boolean false . +func (ps Params) Get(name string) (string, bool) { + for _, entry := range ps { + if entry.Key == name { + return entry.Value, true + } + } + return "", false +} + +// ByName returns the value of the first Param which key matches the given name. +// If no matching Param is found, an empty string is returned. +func (ps Params) ByName(name string) (va string) { + va, _ = ps.Get(name) + return +} + +type methodTree struct { + method string + root *node +} + +type methodTrees []methodTree + +func (trees methodTrees) get(method string) *node { + for _, tree := range trees { + if tree.method == method { + return tree.root + } + } + return nil +} + +func min(a, b int) int { + if a <= b { + return a + } + return b +} + +func longestCommonPrefix(a, b string) int { + i := 0 + max := min(len(a), len(b)) + for i < max && a[i] == b[i] { + i++ + } + return i +} + +// addChild will add a child node, keeping wildcardChild at the end +func (n *node) addChild(child *node) { + if n.wildChild && len(n.children) > 0 { + wildcardChild := n.children[len(n.children)-1] + n.children = append(n.children[:len(n.children)-1], child, wildcardChild) + } else { + n.children = append(n.children, child) + } +} + +func countParams(path string) uint16 { + var n uint16 + s := bytesconv.StringToBytes(path) + n += uint16(bytes.Count(s, strColon)) + n += uint16(bytes.Count(s, strStar)) + return n +} + +func countSections(path string) uint16 { + s := bytesconv.StringToBytes(path) + return uint16(bytes.Count(s, strSlash)) +} + +type nodeType uint8 + +const ( + root nodeType = iota + 1 + param + catchAll +) + +type node struct { + path string + indices string + wildChild bool + nType nodeType + priority uint32 + children []*node // child nodes, at most 1 :param style node at the end of the array + handlers HandlersChain + fullPath string +} + +// Increments priority of the given child and reorders if necessary +func (n *node) incrementChildPrio(pos int) int { + cs := n.children + cs[pos].priority++ + prio := cs[pos].priority + + // Adjust position (move to front) + newPos := pos + for ; newPos > 0 && cs[newPos-1].priority < prio; newPos-- { + // Swap node positions + cs[newPos-1], cs[newPos] = cs[newPos], cs[newPos-1] + } + + // Build new index char string + if newPos != pos { + n.indices = n.indices[:newPos] + // Unchanged prefix, might be empty + n.indices[pos:pos+1] + // The index char we move + n.indices[newPos:pos] + n.indices[pos+1:] // Rest without char at 'pos' + } + + return newPos +} + +// addRoute adds a node with the given handle to the path. +// Not concurrency-safe! +func (n *node) addRoute(path string, handlers HandlersChain) { + fullPath := path + n.priority++ + + // Empty tree + if len(n.path) == 0 && len(n.children) == 0 { + n.insertChild(path, fullPath, handlers) + n.nType = root + return + } + + parentFullPathIndex := 0 + +walk: + for { + // Find the longest common prefix. + // This also implies that the common prefix contains no ':' or '*' + // since the existing key can't contain those chars. + i := longestCommonPrefix(path, n.path) + + // Split edge + if i < len(n.path) { + child := node{ + path: n.path[i:], + wildChild: n.wildChild, + indices: n.indices, + children: n.children, + handlers: n.handlers, + priority: n.priority - 1, + fullPath: n.fullPath, + } + + n.children = []*node{&child} + // []byte for proper unicode char conversion, see #65 + n.indices = bytesconv.BytesToString([]byte{n.path[i]}) + n.path = path[:i] + n.handlers = nil + n.wildChild = false + n.fullPath = fullPath[:parentFullPathIndex+i] + } + + // Make new node a child of this node + if i < len(path) { + path = path[i:] + c := path[0] + + // '/' after param + if n.nType == param && c == '/' && len(n.children) == 1 { + parentFullPathIndex += len(n.path) + n = n.children[0] + n.priority++ + continue walk + } + + // Check if a child with the next path byte exists + for i, max := 0, len(n.indices); i < max; i++ { + if c == n.indices[i] { + parentFullPathIndex += len(n.path) + i = n.incrementChildPrio(i) + n = n.children[i] + continue walk + } + } + + // Otherwise insert it + if c != ':' && c != '*' && n.nType != catchAll { + // []byte for proper unicode char conversion, see #65 + n.indices += bytesconv.BytesToString([]byte{c}) + child := &node{ + fullPath: fullPath, + } + n.addChild(child) + n.incrementChildPrio(len(n.indices) - 1) + n = child + } else if n.wildChild { + // inserting a wildcard node, need to check if it conflicts with the existing wildcard + n = n.children[len(n.children)-1] + n.priority++ + + // Check if the wildcard matches + if len(path) >= len(n.path) && n.path == path[:len(n.path)] && + // Adding a child to a catchAll is not possible + n.nType != catchAll && + // Check for longer wildcard, e.g. :name and :names + (len(n.path) >= len(path) || path[len(n.path)] == '/') { + continue walk + } + + // Wildcard conflict + pathSeg := path + if n.nType != catchAll { + pathSeg = strings.SplitN(pathSeg, "/", 2)[0] + } + prefix := fullPath[:strings.Index(fullPath, pathSeg)] + n.path + panic("'" + pathSeg + + "' in new path '" + fullPath + + "' conflicts with existing wildcard '" + n.path + + "' in existing prefix '" + prefix + + "'") + } + + n.insertChild(path, fullPath, handlers) + return + } + + // Otherwise add handle to current node + if n.handlers != nil { + panic("handlers are already registered for path '" + fullPath + "'") + } + n.handlers = handlers + n.fullPath = fullPath + return + } +} + +// Search for a wildcard segment and check the name for invalid characters. +// Returns -1 as index, if no wildcard was found. +func findWildcard(path string) (wildcard string, i int, valid bool) { + // Find start + for start, c := range []byte(path) { + // A wildcard starts with ':' (param) or '*' (catch-all) + if c != ':' && c != '*' { + continue + } + + // Find end and check for invalid characters + valid = true + for end, c := range []byte(path[start+1:]) { + switch c { + case '/': + return path[start : start+1+end], start, valid + case ':', '*': + valid = false + } + } + return path[start:], start, valid + } + return "", -1, false +} + +func (n *node) insertChild(path string, fullPath string, handlers HandlersChain) { + for { + // Find prefix until first wildcard + wildcard, i, valid := findWildcard(path) + if i < 0 { // No wildcard found + break + } + + // The wildcard name must only contain one ':' or '*' character + if !valid { + panic("only one wildcard per path segment is allowed, has: '" + + wildcard + "' in path '" + fullPath + "'") + } + + // check if the wildcard has a name + if len(wildcard) < 2 { + panic("wildcards must be named with a non-empty name in path '" + fullPath + "'") + } + + if wildcard[0] == ':' { // param + if i > 0 { + // Insert prefix before the current wildcard + n.path = path[:i] + path = path[i:] + } + + child := &node{ + nType: param, + path: wildcard, + fullPath: fullPath, + } + n.addChild(child) + n.wildChild = true + n = child + n.priority++ + + // if the path doesn't end with the wildcard, then there + // will be another subpath starting with '/' + if len(wildcard) < len(path) { + path = path[len(wildcard):] + + child := &node{ + priority: 1, + fullPath: fullPath, + } + n.addChild(child) + n = child + continue + } + + // Otherwise we're done. Insert the handle in the new leaf + n.handlers = handlers + return + } + + // catchAll + if i+len(wildcard) != len(path) { + panic("catch-all routes are only allowed at the end of the path in path '" + fullPath + "'") + } + + if len(n.path) > 0 && n.path[len(n.path)-1] == '/' { + pathSeg := strings.SplitN(n.children[0].path, "/", 2)[0] + panic("catch-all wildcard '" + path + + "' in new path '" + fullPath + + "' conflicts with existing path segment '" + pathSeg + + "' in existing prefix '" + n.path + pathSeg + + "'") + } + + // currently fixed width 1 for '/' + i-- + if path[i] != '/' { + panic("no / before catch-all in path '" + fullPath + "'") + } + + n.path = path[:i] + + // First node: catchAll node with empty path + child := &node{ + wildChild: true, + nType: catchAll, + fullPath: fullPath, + } + + n.addChild(child) + n.indices = string('/') + n = child + n.priority++ + + // second node: node holding the variable + child = &node{ + path: path[i:], + nType: catchAll, + handlers: handlers, + priority: 1, + fullPath: fullPath, + } + n.children = []*node{child} + + return + } + + // If no wildcard was found, simply insert the path and handle + n.path = path + n.handlers = handlers + n.fullPath = fullPath +} + +// nodeValue holds return values of (*Node).getValue method +type nodeValue struct { + handlers HandlersChain + params *Params + tsr bool + fullPath string +} + +type skippedNode struct { + path string + node *node + paramsCount int16 +} + +// Returns the handle registered with the given path (key). The values of +// wildcards are saved to a map. +// If no handle can be found, a TSR (trailing slash redirect) recommendation is +// made if a handle exists with an extra (without the) trailing slash for the +// given path. +func (n *node) getValue(path string, params *Params, skippedNodes *[]skippedNode, unescape bool) (value nodeValue) { + var globalParamsCount int16 + +walk: // Outer loop for walking the tree + for { + prefix := n.path + if len(path) > len(prefix) { + if path[:len(prefix)] == prefix { + path = path[len(prefix):] + + // Try all the non-wildcard children first by matching the indices + idxc := path[0] + for i, c := range []byte(n.indices) { + if c == idxc { + // strings.HasPrefix(n.children[len(n.children)-1].path, ":") == n.wildChild + if n.wildChild { + index := len(*skippedNodes) + *skippedNodes = (*skippedNodes)[:index+1] + (*skippedNodes)[index] = skippedNode{ + path: prefix + path, + node: &node{ + path: n.path, + wildChild: n.wildChild, + nType: n.nType, + priority: n.priority, + children: n.children, + handlers: n.handlers, + fullPath: n.fullPath, + }, + paramsCount: globalParamsCount, + } + } + + n = n.children[i] + continue walk + } + } + + if !n.wildChild { + // If the path at the end of the loop is not equal to '/' and the current node has no child nodes + // the current node needs to roll back to last vaild skippedNode + if path != "/" { + for l := len(*skippedNodes); l > 0; { + skippedNode := (*skippedNodes)[l-1] + *skippedNodes = (*skippedNodes)[:l-1] + if strings.HasSuffix(skippedNode.path, path) { + path = skippedNode.path + n = skippedNode.node + if value.params != nil { + *value.params = (*value.params)[:skippedNode.paramsCount] + } + globalParamsCount = skippedNode.paramsCount + continue walk + } + } + } + + // Nothing found. + // We can recommend to redirect to the same URL without a + // trailing slash if a leaf exists for that path. + value.tsr = path == "/" && n.handlers != nil + return + } + + // Handle wildcard child, which is always at the end of the array + n = n.children[len(n.children)-1] + globalParamsCount++ + + switch n.nType { + case param: + // fix truncate the parameter + // tree_test.go line: 204 + + // Find param end (either '/' or path end) + end := 0 + for end < len(path) && path[end] != '/' { + end++ + } + + // Save param value + if params != nil && cap(*params) > 0 { + if value.params == nil { + value.params = params + } + // Expand slice within preallocated capacity + i := len(*value.params) + *value.params = (*value.params)[:i+1] + val := path[:end] + if unescape { + if v, err := url.QueryUnescape(val); err == nil { + val = v + } + } + (*value.params)[i] = Param{ + Key: n.path[1:], + Value: val, + } + } + + // we need to go deeper! + if end < len(path) { + if len(n.children) > 0 { + path = path[end:] + n = n.children[0] + continue walk + } + + // ... but we can't + value.tsr = len(path) == end+1 + return + } + + if value.handlers = n.handlers; value.handlers != nil { + value.fullPath = n.fullPath + return + } + if len(n.children) == 1 { + // No handle found. Check if a handle for this path + a + // trailing slash exists for TSR recommendation + n = n.children[0] + value.tsr = (n.path == "/" && n.handlers != nil) || (n.path == "" && n.indices == "/") + } + return + + case catchAll: + // Save param value + if params != nil { + if value.params == nil { + value.params = params + } + // Expand slice within preallocated capacity + i := len(*value.params) + *value.params = (*value.params)[:i+1] + val := path + if unescape { + if v, err := url.QueryUnescape(path); err == nil { + val = v + } + } + (*value.params)[i] = Param{ + Key: n.path[2:], + Value: val, + } + } + + value.handlers = n.handlers + value.fullPath = n.fullPath + return + + default: + panic("invalid node type") + } + } + } + + if path == prefix { + // If the current path does not equal '/' and the node does not have a registered handle and the most recently matched node has a child node + // the current node needs to roll back to last vaild skippedNode + if n.handlers == nil && path != "/" { + for l := len(*skippedNodes); l > 0; { + skippedNode := (*skippedNodes)[l-1] + *skippedNodes = (*skippedNodes)[:l-1] + if strings.HasSuffix(skippedNode.path, path) { + path = skippedNode.path + n = skippedNode.node + if value.params != nil { + *value.params = (*value.params)[:skippedNode.paramsCount] + } + globalParamsCount = skippedNode.paramsCount + continue walk + } + } + // n = latestNode.children[len(latestNode.children)-1] + } + // We should have reached the node containing the handle. + // Check if this node has a handle registered. + if value.handlers = n.handlers; value.handlers != nil { + value.fullPath = n.fullPath + return + } + + // If there is no handle for this route, but this route has a + // wildcard child, there must be a handle for this path with an + // additional trailing slash + if path == "/" && n.wildChild && n.nType != root { + value.tsr = true + return + } + + // No handle found. Check if a handle for this path + a + // trailing slash exists for trailing slash recommendation + for i, c := range []byte(n.indices) { + if c == '/' { + n = n.children[i] + value.tsr = (len(n.path) == 1 && n.handlers != nil) || + (n.nType == catchAll && n.children[0].handlers != nil) + return + } + } + + return + } + + // Nothing found. We can recommend to redirect to the same URL with an + // extra trailing slash if a leaf exists for that path + value.tsr = path == "/" || + (len(prefix) == len(path)+1 && prefix[len(path)] == '/' && + path == prefix[:len(prefix)-1] && n.handlers != nil) + + // roll back to last valid skippedNode + if !value.tsr && path != "/" { + for l := len(*skippedNodes); l > 0; { + skippedNode := (*skippedNodes)[l-1] + *skippedNodes = (*skippedNodes)[:l-1] + if strings.HasSuffix(skippedNode.path, path) { + path = skippedNode.path + n = skippedNode.node + if value.params != nil { + *value.params = (*value.params)[:skippedNode.paramsCount] + } + globalParamsCount = skippedNode.paramsCount + continue walk + } + } + } + + return + } +} + +// Makes a case-insensitive lookup of the given path and tries to find a handler. +// It can optionally also fix trailing slashes. +// It returns the case-corrected path and a bool indicating whether the lookup +// was successful. +func (n *node) findCaseInsensitivePath(path string, fixTrailingSlash bool) ([]byte, bool) { + const stackBufSize = 128 + + // Use a static sized buffer on the stack in the common case. + // If the path is too long, allocate a buffer on the heap instead. + buf := make([]byte, 0, stackBufSize) + if length := len(path) + 1; length > stackBufSize { + buf = make([]byte, 0, length) + } + + ciPath := n.findCaseInsensitivePathRec( + path, + buf, // Preallocate enough memory for new path + [4]byte{}, // Empty rune buffer + fixTrailingSlash, + ) + + return ciPath, ciPath != nil +} + +// Shift bytes in array by n bytes left +func shiftNRuneBytes(rb [4]byte, n int) [4]byte { + switch n { + case 0: + return rb + case 1: + return [4]byte{rb[1], rb[2], rb[3], 0} + case 2: + return [4]byte{rb[2], rb[3]} + case 3: + return [4]byte{rb[3]} + default: + return [4]byte{} + } +} + +// Recursive case-insensitive lookup function used by n.findCaseInsensitivePath +func (n *node) findCaseInsensitivePathRec(path string, ciPath []byte, rb [4]byte, fixTrailingSlash bool) []byte { + npLen := len(n.path) + +walk: // Outer loop for walking the tree + for len(path) >= npLen && (npLen == 0 || strings.EqualFold(path[1:npLen], n.path[1:])) { + // Add common prefix to result + oldPath := path + path = path[npLen:] + ciPath = append(ciPath, n.path...) + + if len(path) == 0 { + // We should have reached the node containing the handle. + // Check if this node has a handle registered. + if n.handlers != nil { + return ciPath + } + + // No handle found. + // Try to fix the path by adding a trailing slash + if fixTrailingSlash { + for i, c := range []byte(n.indices) { + if c == '/' { + n = n.children[i] + if (len(n.path) == 1 && n.handlers != nil) || + (n.nType == catchAll && n.children[0].handlers != nil) { + return append(ciPath, '/') + } + return nil + } + } + } + return nil + } + + // If this node does not have a wildcard (param or catchAll) child, + // we can just look up the next child node and continue to walk down + // the tree + if !n.wildChild { + // Skip rune bytes already processed + rb = shiftNRuneBytes(rb, npLen) + + if rb[0] != 0 { + // Old rune not finished + idxc := rb[0] + for i, c := range []byte(n.indices) { + if c == idxc { + // continue with child node + n = n.children[i] + npLen = len(n.path) + continue walk + } + } + } else { + // Process a new rune + var rv rune + + // Find rune start. + // Runes are up to 4 byte long, + // -4 would definitely be another rune. + var off int + for max := min(npLen, 3); off < max; off++ { + if i := npLen - off; utf8.RuneStart(oldPath[i]) { + // read rune from cached path + rv, _ = utf8.DecodeRuneInString(oldPath[i:]) + break + } + } + + // Calculate lowercase bytes of current rune + lo := unicode.ToLower(rv) + utf8.EncodeRune(rb[:], lo) + + // Skip already processed bytes + rb = shiftNRuneBytes(rb, off) + + idxc := rb[0] + for i, c := range []byte(n.indices) { + // Lowercase matches + if c == idxc { + // must use a recursive approach since both the + // uppercase byte and the lowercase byte might exist + // as an index + if out := n.children[i].findCaseInsensitivePathRec( + path, ciPath, rb, fixTrailingSlash, + ); out != nil { + return out + } + break + } + } + + // If we found no match, the same for the uppercase rune, + // if it differs + if up := unicode.ToUpper(rv); up != lo { + utf8.EncodeRune(rb[:], up) + rb = shiftNRuneBytes(rb, off) + + idxc := rb[0] + for i, c := range []byte(n.indices) { + // Uppercase matches + if c == idxc { + // Continue with child node + n = n.children[i] + npLen = len(n.path) + continue walk + } + } + } + } + + // Nothing found. We can recommend to redirect to the same URL + // without a trailing slash if a leaf exists for that path + if fixTrailingSlash && path == "/" && n.handlers != nil { + return ciPath + } + return nil + } + + n = n.children[0] + switch n.nType { + case param: + // Find param end (either '/' or path end) + end := 0 + for end < len(path) && path[end] != '/' { + end++ + } + + // Add param value to case insensitive path + ciPath = append(ciPath, path[:end]...) + + // We need to go deeper! + if end < len(path) { + if len(n.children) > 0 { + // Continue with child node + n = n.children[0] + npLen = len(n.path) + path = path[end:] + continue + } + + // ... but we can't + if fixTrailingSlash && len(path) == end+1 { + return ciPath + } + return nil + } + + if n.handlers != nil { + return ciPath + } + + if fixTrailingSlash && len(n.children) == 1 { + // No handle found. Check if a handle for this path + a + // trailing slash exists + n = n.children[0] + if n.path == "/" && n.handlers != nil { + return append(ciPath, '/') + } + } + + return nil + + case catchAll: + return append(ciPath, path...) + + default: + panic("invalid node type") + } + } + + // Nothing found. + // Try to fix the path by adding / removing a trailing slash + if fixTrailingSlash { + if path == "/" { + return ciPath + } + if len(path)+1 == npLen && n.path[len(path)] == '/' && + strings.EqualFold(path[1:], n.path[1:len(path)]) && n.handlers != nil { + return append(ciPath, n.path...) + } + } + return nil +} diff --git a/vendor/github.com/gin-gonic/gin/utils.go b/vendor/github.com/gin-gonic/gin/utils.go new file mode 100644 index 0000000..4021a2a --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/utils.go @@ -0,0 +1,164 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package gin + +import ( + "encoding/xml" + "net/http" + "os" + "path" + "reflect" + "runtime" + "strings" + "unicode" +) + +// BindKey indicates a default bind key. +const BindKey = "_gin-gonic/gin/bindkey" + +// Bind is a helper function for given interface object and returns a Gin middleware. +func Bind(val any) HandlerFunc { + value := reflect.ValueOf(val) + if value.Kind() == reflect.Ptr { + panic(`Bind struct can not be a pointer. Example: + Use: gin.Bind(Struct{}) instead of gin.Bind(&Struct{}) +`) + } + typ := value.Type() + + return func(c *Context) { + obj := reflect.New(typ).Interface() + if c.Bind(obj) == nil { + c.Set(BindKey, obj) + } + } +} + +// WrapF is a helper function for wrapping http.HandlerFunc and returns a Gin middleware. +func WrapF(f http.HandlerFunc) HandlerFunc { + return func(c *Context) { + f(c.Writer, c.Request) + } +} + +// WrapH is a helper function for wrapping http.Handler and returns a Gin middleware. +func WrapH(h http.Handler) HandlerFunc { + return func(c *Context) { + h.ServeHTTP(c.Writer, c.Request) + } +} + +// H is a shortcut for map[string]interface{} +type H map[string]any + +// MarshalXML allows type H to be used with xml.Marshal. +func (h H) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + start.Name = xml.Name{ + Space: "", + Local: "map", + } + if err := e.EncodeToken(start); err != nil { + return err + } + for key, value := range h { + elem := xml.StartElement{ + Name: xml.Name{Space: "", Local: key}, + Attr: []xml.Attr{}, + } + if err := e.EncodeElement(value, elem); err != nil { + return err + } + } + + return e.EncodeToken(xml.EndElement{Name: start.Name}) +} + +func assert1(guard bool, text string) { + if !guard { + panic(text) + } +} + +func filterFlags(content string) string { + for i, char := range content { + if char == ' ' || char == ';' { + return content[:i] + } + } + return content +} + +func chooseData(custom, wildcard any) any { + if custom != nil { + return custom + } + if wildcard != nil { + return wildcard + } + panic("negotiation config is invalid") +} + +func parseAccept(acceptHeader string) []string { + parts := strings.Split(acceptHeader, ",") + out := make([]string, 0, len(parts)) + for _, part := range parts { + if i := strings.IndexByte(part, ';'); i > 0 { + part = part[:i] + } + if part = strings.TrimSpace(part); part != "" { + out = append(out, part) + } + } + return out +} + +func lastChar(str string) uint8 { + if str == "" { + panic("The length of the string can't be 0") + } + return str[len(str)-1] +} + +func nameOfFunction(f any) string { + return runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name() +} + +func joinPaths(absolutePath, relativePath string) string { + if relativePath == "" { + return absolutePath + } + + finalPath := path.Join(absolutePath, relativePath) + if lastChar(relativePath) == '/' && lastChar(finalPath) != '/' { + return finalPath + "/" + } + return finalPath +} + +func resolveAddress(addr []string) string { + switch len(addr) { + case 0: + if port := os.Getenv("PORT"); port != "" { + debugPrint("Environment variable PORT=\"%s\"", port) + return ":" + port + } + debugPrint("Environment variable PORT is undefined. Using port :8080 by default") + return ":8080" + case 1: + return addr[0] + default: + panic("too many parameters") + } +} + +// https://stackoverflow.com/questions/53069040/checking-a-string-contains-only-ascii-characters +func isASCII(s string) bool { + for i := 0; i < len(s); i++ { + if s[i] > unicode.MaxASCII { + return false + } + } + return true +} diff --git a/vendor/github.com/gin-gonic/gin/version.go b/vendor/github.com/gin-gonic/gin/version.go new file mode 100644 index 0000000..632ca7d --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/version.go @@ -0,0 +1,8 @@ +// Copyright 2018 Gin Core Team. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package gin + +// Version is the current gin framework's version. +const Version = "v1.8.1" diff --git a/vendor/github.com/go-chi/chi/.gitignore b/vendor/github.com/go-chi/chi/.gitignore new file mode 100644 index 0000000..ba22c99 --- /dev/null +++ b/vendor/github.com/go-chi/chi/.gitignore @@ -0,0 +1,3 @@ +.idea +*.sw? +.vscode diff --git a/vendor/github.com/go-chi/chi/CHANGELOG.md b/vendor/github.com/go-chi/chi/CHANGELOG.md new file mode 100644 index 0000000..7dd0791 --- /dev/null +++ b/vendor/github.com/go-chi/chi/CHANGELOG.md @@ -0,0 +1,269 @@ +# Changelog + +## v1.5.4 (2021-02-27) + +- Undo prior retraction in v1.5.3 as we prepare for v5.0.0 release +- History of changes: see https://github.com/go-chi/chi/compare/v1.5.3...v1.5.4 + + +## v1.5.3 (2021-02-21) + +- Update go.mod to go 1.16 with new retract directive marking all versions without prior go.mod support +- History of changes: see https://github.com/go-chi/chi/compare/v1.5.2...v1.5.3 + + +## v1.5.2 (2021-02-10) + +- Reverting allocation optimization as a precaution as go test -race fails. +- Minor improvements, see history below +- History of changes: see https://github.com/go-chi/chi/compare/v1.5.1...v1.5.2 + + +## v1.5.1 (2020-12-06) + +- Performance improvement: removing 1 allocation by foregoing context.WithValue, thank you @bouk for + your contribution (https://github.com/go-chi/chi/pull/555). Note: new benchmarks posted in README. +- `middleware.CleanPath`: new middleware that clean's request path of double slashes +- deprecate & remove `chi.ServerBaseContext` in favour of stdlib `http.Server#BaseContext` +- plus other tiny improvements, see full commit history below +- History of changes: see https://github.com/go-chi/chi/compare/v4.1.2...v1.5.1 + + +## v1.5.0 (2020-11-12) - now with go.mod support + +`chi` dates back to 2016 with it's original implementation as one of the first routers to adopt the newly introduced +context.Context api to the stdlib -- set out to design a router that is faster, more modular and simpler than anything +else out there -- while not introducing any custom handler types or dependencies. Today, `chi` still has zero dependencies, +and in many ways is future proofed from changes, given it's minimal nature. Between versions, chi's iterations have been very +incremental, with the architecture and api being the same today as it was originally designed in 2016. For this reason it +makes chi a pretty easy project to maintain, as well thanks to the many amazing community contributions over the years +to who all help make chi better (total of 86 contributors to date -- thanks all!). + +Chi has been an labour of love, art and engineering, with the goals to offer beautiful ergonomics, flexibility, performance +and simplicity when building HTTP services with Go. I've strived to keep the router very minimal in surface area / code size, +and always improving the code wherever possible -- and as of today the `chi` package is just 1082 lines of code (not counting +middlewares, which are all optional). As well, I don't have the exact metrics, but from my analysis and email exchanges from +companies and developers, chi is used by thousands of projects around the world -- thank you all as there is no better form of +joy for me than to have art I had started be helpful and enjoyed by others. And of course I use chi in all of my own projects too :) + +For me, the asthetics of chi's code and usage are very important. With the introduction of Go's module support +(which I'm a big fan of), chi's past versioning scheme choice to v2, v3 and v4 would mean I'd require the import path +of "github.com/go-chi/chi/v4", leading to the lengthy discussion at https://github.com/go-chi/chi/issues/462. +Haha, to some, you may be scratching your head why I've spent > 1 year stalling to adopt "/vXX" convention in the import +path -- which isn't horrible in general -- but for chi, I'm unable to accept it as I strive for perfection in it's API design, +aesthetics and simplicity. It just doesn't feel good to me given chi's simple nature -- I do not foresee a "v5" or "v6", +and upgrading between versions in the future will also be just incremental. + +I do understand versioning is a part of the API design as well, which is why the solution for a while has been to "do nothing", +as Go supports both old and new import paths with/out go.mod. However, now that Go module support has had time to iron out kinks and +is adopted everywhere, it's time for chi to get with the times. Luckily, I've discovered a path forward that will make me happy, +while also not breaking anyone's app who adopted a prior versioning from tags in v2/v3/v4. I've made an experimental release of +v1.5.0 with go.mod silently, and tested it with new and old projects, to ensure the developer experience is preserved, and it's +largely unnoticed. Fortunately, Go's toolchain will check the tags of a repo and consider the "latest" tag the one with go.mod. +However, you can still request a specific older tag such as v4.1.2, and everything will "just work". But new users can just +`go get github.com/go-chi/chi` or `go get github.com/go-chi/chi@latest` and they will get the latest version which contains +go.mod support, which is v1.5.0+. `chi` will not change very much over the years, just like it hasn't changed much from 4 years ago. +Therefore, we will stay on v1.x from here on, starting from v1.5.0. Any breaking changes will bump a "minor" release and +backwards-compatible improvements/fixes will bump a "tiny" release. + +For existing projects who want to upgrade to the latest go.mod version, run: `go get -u github.com/go-chi/chi@v1.5.0`, +which will get you on the go.mod version line (as Go's mod cache may still remember v4.x). Brand new systems can run +`go get -u github.com/go-chi/chi` or `go get -u github.com/go-chi/chi@latest` to install chi, which will install v1.5.0+ +built with go.mod support. + +My apologies to the developers who will disagree with the decisions above, but, hope you'll try it and see it's a very +minor request which is backwards compatible and won't break your existing installations. + +Cheers all, happy coding! + + +--- + + +## v4.1.2 (2020-06-02) + +- fix that handles MethodNotAllowed with path variables, thank you @caseyhadden for your contribution +- fix to replace nested wildcards correctly in RoutePattern, thank you @@unmultimedio for your contribution +- History of changes: see https://github.com/go-chi/chi/compare/v4.1.1...v4.1.2 + + +## v4.1.1 (2020-04-16) + +- fix for issue https://github.com/go-chi/chi/issues/411 which allows for overlapping regexp + route to the correct handler through a recursive tree search, thanks to @Jahaja for the PR/fix! +- new middleware.RouteHeaders as a simple router for request headers with wildcard support +- History of changes: see https://github.com/go-chi/chi/compare/v4.1.0...v4.1.1 + + +## v4.1.0 (2020-04-1) + +- middleware.LogEntry: Write method on interface now passes the response header + and an extra interface type useful for custom logger implementations. +- middleware.WrapResponseWriter: minor fix +- middleware.Recoverer: a bit prettier +- History of changes: see https://github.com/go-chi/chi/compare/v4.0.4...v4.1.0 + +## v4.0.4 (2020-03-24) + +- middleware.Recoverer: new pretty stack trace printing (https://github.com/go-chi/chi/pull/496) +- a few minor improvements and fixes +- History of changes: see https://github.com/go-chi/chi/compare/v4.0.3...v4.0.4 + + +## v4.0.3 (2020-01-09) + +- core: fix regexp routing to include default value when param is not matched +- middleware: rewrite of middleware.Compress +- middleware: suppress http.ErrAbortHandler in middleware.Recoverer +- History of changes: see https://github.com/go-chi/chi/compare/v4.0.2...v4.0.3 + + +## v4.0.2 (2019-02-26) + +- Minor fixes +- History of changes: see https://github.com/go-chi/chi/compare/v4.0.1...v4.0.2 + + +## v4.0.1 (2019-01-21) + +- Fixes issue with compress middleware: #382 #385 +- History of changes: see https://github.com/go-chi/chi/compare/v4.0.0...v4.0.1 + + +## v4.0.0 (2019-01-10) + +- chi v4 requires Go 1.10.3+ (or Go 1.9.7+) - we have deprecated support for Go 1.7 and 1.8 +- router: respond with 404 on router with no routes (#362) +- router: additional check to ensure wildcard is at the end of a url pattern (#333) +- middleware: deprecate use of http.CloseNotifier (#347) +- middleware: fix RedirectSlashes to include query params on redirect (#334) +- History of changes: see https://github.com/go-chi/chi/compare/v3.3.4...v4.0.0 + + +## v3.3.4 (2019-01-07) + +- Minor middleware improvements. No changes to core library/router. Moving v3 into its +- own branch as a version of chi for Go 1.7, 1.8, 1.9, 1.10, 1.11 +- History of changes: see https://github.com/go-chi/chi/compare/v3.3.3...v3.3.4 + + +## v3.3.3 (2018-08-27) + +- Minor release +- See https://github.com/go-chi/chi/compare/v3.3.2...v3.3.3 + + +## v3.3.2 (2017-12-22) + +- Support to route trailing slashes on mounted sub-routers (#281) +- middleware: new `ContentCharset` to check matching charsets. Thank you + @csucu for your community contribution! + + +## v3.3.1 (2017-11-20) + +- middleware: new `AllowContentType` handler for explicit whitelist of accepted request Content-Types +- middleware: new `SetHeader` handler for short-hand middleware to set a response header key/value +- Minor bug fixes + + +## v3.3.0 (2017-10-10) + +- New chi.RegisterMethod(method) to add support for custom HTTP methods, see _examples/custom-method for usage +- Deprecated LINK and UNLINK methods from the default list, please use `chi.RegisterMethod("LINK")` and `chi.RegisterMethod("UNLINK")` in an `init()` function + + +## v3.2.1 (2017-08-31) + +- Add new `Match(rctx *Context, method, path string) bool` method to `Routes` interface + and `Mux`. Match searches the mux's routing tree for a handler that matches the method/path +- Add new `RouteMethod` to `*Context` +- Add new `Routes` pointer to `*Context` +- Add new `middleware.GetHead` to route missing HEAD requests to GET handler +- Updated benchmarks (see README) + + +## v3.1.5 (2017-08-02) + +- Setup golint and go vet for the project +- As per golint, we've redefined `func ServerBaseContext(h http.Handler, baseCtx context.Context) http.Handler` + to `func ServerBaseContext(baseCtx context.Context, h http.Handler) http.Handler` + + +## v3.1.0 (2017-07-10) + +- Fix a few minor issues after v3 release +- Move `docgen` sub-pkg to https://github.com/go-chi/docgen +- Move `render` sub-pkg to https://github.com/go-chi/render +- Add new `URLFormat` handler to chi/middleware sub-pkg to make working with url mime + suffixes easier, ie. parsing `/articles/1.json` and `/articles/1.xml`. See comments in + https://github.com/go-chi/chi/blob/master/middleware/url_format.go for example usage. + + +## v3.0.0 (2017-06-21) + +- Major update to chi library with many exciting updates, but also some *breaking changes* +- URL parameter syntax changed from `/:id` to `/{id}` for even more flexible routing, such as + `/articles/{month}-{day}-{year}-{slug}`, `/articles/{id}`, and `/articles/{id}.{ext}` on the + same router +- Support for regexp for routing patterns, in the form of `/{paramKey:regExp}` for example: + `r.Get("/articles/{name:[a-z]+}", h)` and `chi.URLParam(r, "name")` +- Add `Method` and `MethodFunc` to `chi.Router` to allow routing definitions such as + `r.Method("GET", "/", h)` which provides a cleaner interface for custom handlers like + in `_examples/custom-handler` +- Deprecating `mux#FileServer` helper function. Instead, we encourage users to create their + own using file handler with the stdlib, see `_examples/fileserver` for an example +- Add support for LINK/UNLINK http methods via `r.Method()` and `r.MethodFunc()` +- Moved the chi project to its own organization, to allow chi-related community packages to + be easily discovered and supported, at: https://github.com/go-chi +- *NOTE:* please update your import paths to `"github.com/go-chi/chi"` +- *NOTE:* chi v2 is still available at https://github.com/go-chi/chi/tree/v2 + + +## v2.1.0 (2017-03-30) + +- Minor improvements and update to the chi core library +- Introduced a brand new `chi/render` sub-package to complete the story of building + APIs to offer a pattern for managing well-defined request / response payloads. Please + check out the updated `_examples/rest` example for how it works. +- Added `MethodNotAllowed(h http.HandlerFunc)` to chi.Router interface + + +## v2.0.0 (2017-01-06) + +- After many months of v2 being in an RC state with many companies and users running it in + production, the inclusion of some improvements to the middlewares, we are very pleased to + announce v2.0.0 of chi. + + +## v2.0.0-rc1 (2016-07-26) + +- Huge update! chi v2 is a large refactor targetting Go 1.7+. As of Go 1.7, the popular + community `"net/context"` package has been included in the standard library as `"context"` and + utilized by `"net/http"` and `http.Request` to managing deadlines, cancelation signals and other + request-scoped values. We're very excited about the new context addition and are proud to + introduce chi v2, a minimal and powerful routing package for building large HTTP services, + with zero external dependencies. Chi focuses on idiomatic design and encourages the use of + stdlib HTTP handlers and middlwares. +- chi v2 deprecates its `chi.Handler` interface and requires `http.Handler` or `http.HandlerFunc` +- chi v2 stores URL routing parameters and patterns in the standard request context: `r.Context()` +- chi v2 lower-level routing context is accessible by `chi.RouteContext(r.Context()) *chi.Context`, + which provides direct access to URL routing parameters, the routing path and the matching + routing patterns. +- Users upgrading from chi v1 to v2, need to: + 1. Update the old chi.Handler signature, `func(ctx context.Context, w http.ResponseWriter, r *http.Request)` to + the standard http.Handler: `func(w http.ResponseWriter, r *http.Request)` + 2. Use `chi.URLParam(r *http.Request, paramKey string) string` + or `URLParamFromCtx(ctx context.Context, paramKey string) string` to access a url parameter value + + +## v1.0.0 (2016-07-01) + +- Released chi v1 stable https://github.com/go-chi/chi/tree/v1.0.0 for Go 1.6 and older. + + +## v0.9.0 (2016-03-31) + +- Reuse context objects via sync.Pool for zero-allocation routing [#33](https://github.com/go-chi/chi/pull/33) +- BREAKING NOTE: due to subtle API changes, previously `chi.URLParams(ctx)["id"]` used to access url parameters + has changed to: `chi.URLParam(ctx, "id")` diff --git a/vendor/github.com/go-chi/chi/CONTRIBUTING.md b/vendor/github.com/go-chi/chi/CONTRIBUTING.md new file mode 100644 index 0000000..c0ac2df --- /dev/null +++ b/vendor/github.com/go-chi/chi/CONTRIBUTING.md @@ -0,0 +1,31 @@ +# Contributing + +## Prerequisites + +1. [Install Go][go-install]. +2. Download the sources and switch the working directory: + + ```bash + go get -u -d github.com/go-chi/chi + cd $GOPATH/src/github.com/go-chi/chi + ``` + +## Submitting a Pull Request + +A typical workflow is: + +1. [Fork the repository.][fork] [This tip maybe also helpful.][go-fork-tip] +2. [Create a topic branch.][branch] +3. Add tests for your change. +4. Run `go test`. If your tests pass, return to the step 3. +5. Implement the change and ensure the steps from the previous step pass. +6. Run `goimports -w .`, to ensure the new code conforms to Go formatting guideline. +7. [Add, commit and push your changes.][git-help] +8. [Submit a pull request.][pull-req] + +[go-install]: https://golang.org/doc/install +[go-fork-tip]: http://blog.campoy.cat/2014/03/github-and-go-forking-pull-requests-and.html +[fork]: https://help.github.com/articles/fork-a-repo +[branch]: http://learn.github.com/p/branching.html +[git-help]: https://guides.github.com +[pull-req]: https://help.github.com/articles/using-pull-requests diff --git a/vendor/github.com/go-chi/chi/LICENSE b/vendor/github.com/go-chi/chi/LICENSE new file mode 100644 index 0000000..d99f02f --- /dev/null +++ b/vendor/github.com/go-chi/chi/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2015-present Peter Kieltyka (https://github.com/pkieltyka), Google Inc. + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/go-chi/chi/Makefile b/vendor/github.com/go-chi/chi/Makefile new file mode 100644 index 0000000..b96c92d --- /dev/null +++ b/vendor/github.com/go-chi/chi/Makefile @@ -0,0 +1,14 @@ +all: + @echo "**********************************************************" + @echo "** chi build tool **" + @echo "**********************************************************" + + +test: + go clean -testcache && $(MAKE) test-router && $(MAKE) test-middleware + +test-router: + go test -race -v . + +test-middleware: + go test -race -v ./middleware diff --git a/vendor/github.com/go-chi/chi/README.md b/vendor/github.com/go-chi/chi/README.md new file mode 100644 index 0000000..1b96d36 --- /dev/null +++ b/vendor/github.com/go-chi/chi/README.md @@ -0,0 +1,511 @@ +# chi + + +[![GoDoc Widget]][GoDoc] [![Travis Widget]][Travis] + +`chi` is a lightweight, idiomatic and composable router for building Go HTTP services. It's +especially good at helping you write large REST API services that are kept maintainable as your +project grows and changes. `chi` is built on the new `context` package introduced in Go 1.7 to +handle signaling, cancelation and request-scoped values across a handler chain. + +The focus of the project has been to seek out an elegant and comfortable design for writing +REST API servers, written during the development of the Pressly API service that powers our +public API service, which in turn powers all of our client-side applications. + +The key considerations of chi's design are: project structure, maintainability, standard http +handlers (stdlib-only), developer productivity, and deconstructing a large system into many small +parts. The core router `github.com/go-chi/chi` is quite small (less than 1000 LOC), but we've also +included some useful/optional subpackages: [middleware](/middleware), [render](https://github.com/go-chi/render) +and [docgen](https://github.com/go-chi/docgen). We hope you enjoy it too! + +## Install + +`go get -u github.com/go-chi/chi` + + +## Features + +* **Lightweight** - cloc'd in ~1000 LOC for the chi router +* **Fast** - yes, see [benchmarks](#benchmarks) +* **100% compatible with net/http** - use any http or middleware pkg in the ecosystem that is also compatible with `net/http` +* **Designed for modular/composable APIs** - middlewares, inline middlewares, route groups and sub-router mounting +* **Context control** - built on new `context` package, providing value chaining, cancellations and timeouts +* **Robust** - in production at Pressly, CloudFlare, Heroku, 99Designs, and many others (see [discussion](https://github.com/go-chi/chi/issues/91)) +* **Doc generation** - `docgen` auto-generates routing documentation from your source to JSON or Markdown +* **Go.mod support** - v1.x of chi (starting from v1.5.0), now has go.mod support (see [CHANGELOG](https://github.com/go-chi/chi/blob/master/CHANGELOG.md#v150-2020-11-12---now-with-gomod-support)) +* **No external dependencies** - plain ol' Go stdlib + net/http + + +## Examples + +See [_examples/](https://github.com/go-chi/chi/blob/master/_examples/) for a variety of examples. + + +**As easy as:** + +```go +package main + +import ( + "net/http" + + "github.com/go-chi/chi" + "github.com/go-chi/chi/middleware" +) + +func main() { + r := chi.NewRouter() + r.Use(middleware.Logger) + r.Get("/", func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("welcome")) + }) + http.ListenAndServe(":3000", r) +} +``` + +**REST Preview:** + +Here is a little preview of how routing looks like with chi. Also take a look at the generated routing docs +in JSON ([routes.json](https://github.com/go-chi/chi/blob/master/_examples/rest/routes.json)) and in +Markdown ([routes.md](https://github.com/go-chi/chi/blob/master/_examples/rest/routes.md)). + +I highly recommend reading the source of the [examples](https://github.com/go-chi/chi/blob/master/_examples/) listed +above, they will show you all the features of chi and serve as a good form of documentation. + +```go +import ( + //... + "context" + "github.com/go-chi/chi" + "github.com/go-chi/chi/middleware" +) + +func main() { + r := chi.NewRouter() + + // A good base middleware stack + r.Use(middleware.RequestID) + r.Use(middleware.RealIP) + r.Use(middleware.Logger) + r.Use(middleware.Recoverer) + + // Set a timeout value on the request context (ctx), that will signal + // through ctx.Done() that the request has timed out and further + // processing should be stopped. + r.Use(middleware.Timeout(60 * time.Second)) + + r.Get("/", func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("hi")) + }) + + // RESTy routes for "articles" resource + r.Route("/articles", func(r chi.Router) { + r.With(paginate).Get("/", listArticles) // GET /articles + r.With(paginate).Get("/{month}-{day}-{year}", listArticlesByDate) // GET /articles/01-16-2017 + + r.Post("/", createArticle) // POST /articles + r.Get("/search", searchArticles) // GET /articles/search + + // Regexp url parameters: + r.Get("/{articleSlug:[a-z-]+}", getArticleBySlug) // GET /articles/home-is-toronto + + // Subrouters: + r.Route("/{articleID}", func(r chi.Router) { + r.Use(ArticleCtx) + r.Get("/", getArticle) // GET /articles/123 + r.Put("/", updateArticle) // PUT /articles/123 + r.Delete("/", deleteArticle) // DELETE /articles/123 + }) + }) + + // Mount the admin sub-router + r.Mount("/admin", adminRouter()) + + http.ListenAndServe(":3333", r) +} + +func ArticleCtx(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + articleID := chi.URLParam(r, "articleID") + article, err := dbGetArticle(articleID) + if err != nil { + http.Error(w, http.StatusText(404), 404) + return + } + ctx := context.WithValue(r.Context(), "article", article) + next.ServeHTTP(w, r.WithContext(ctx)) + }) +} + +func getArticle(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + article, ok := ctx.Value("article").(*Article) + if !ok { + http.Error(w, http.StatusText(422), 422) + return + } + w.Write([]byte(fmt.Sprintf("title:%s", article.Title))) +} + +// A completely separate router for administrator routes +func adminRouter() http.Handler { + r := chi.NewRouter() + r.Use(AdminOnly) + r.Get("/", adminIndex) + r.Get("/accounts", adminListAccounts) + return r +} + +func AdminOnly(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + perm, ok := ctx.Value("acl.permission").(YourPermissionType) + if !ok || !perm.IsAdmin() { + http.Error(w, http.StatusText(403), 403) + return + } + next.ServeHTTP(w, r) + }) +} +``` + + +## Router interface + +chi's router is based on a kind of [Patricia Radix trie](https://en.wikipedia.org/wiki/Radix_tree). +The router is fully compatible with `net/http`. + +Built on top of the tree is the `Router` interface: + +```go +// Router consisting of the core routing methods used by chi's Mux, +// using only the standard net/http. +type Router interface { + http.Handler + Routes + + // Use appends one or more middlewares onto the Router stack. + Use(middlewares ...func(http.Handler) http.Handler) + + // With adds inline middlewares for an endpoint handler. + With(middlewares ...func(http.Handler) http.Handler) Router + + // Group adds a new inline-Router along the current routing + // path, with a fresh middleware stack for the inline-Router. + Group(fn func(r Router)) Router + + // Route mounts a sub-Router along a `pattern`` string. + Route(pattern string, fn func(r Router)) Router + + // Mount attaches another http.Handler along ./pattern/* + Mount(pattern string, h http.Handler) + + // Handle and HandleFunc adds routes for `pattern` that matches + // all HTTP methods. + Handle(pattern string, h http.Handler) + HandleFunc(pattern string, h http.HandlerFunc) + + // Method and MethodFunc adds routes for `pattern` that matches + // the `method` HTTP method. + Method(method, pattern string, h http.Handler) + MethodFunc(method, pattern string, h http.HandlerFunc) + + // HTTP-method routing along `pattern` + Connect(pattern string, h http.HandlerFunc) + Delete(pattern string, h http.HandlerFunc) + Get(pattern string, h http.HandlerFunc) + Head(pattern string, h http.HandlerFunc) + Options(pattern string, h http.HandlerFunc) + Patch(pattern string, h http.HandlerFunc) + Post(pattern string, h http.HandlerFunc) + Put(pattern string, h http.HandlerFunc) + Trace(pattern string, h http.HandlerFunc) + + // NotFound defines a handler to respond whenever a route could + // not be found. + NotFound(h http.HandlerFunc) + + // MethodNotAllowed defines a handler to respond whenever a method is + // not allowed. + MethodNotAllowed(h http.HandlerFunc) +} + +// Routes interface adds two methods for router traversal, which is also +// used by the github.com/go-chi/docgen package to generate documentation for Routers. +type Routes interface { + // Routes returns the routing tree in an easily traversable structure. + Routes() []Route + + // Middlewares returns the list of middlewares in use by the router. + Middlewares() Middlewares + + // Match searches the routing tree for a handler that matches + // the method/path - similar to routing a http request, but without + // executing the handler thereafter. + Match(rctx *Context, method, path string) bool +} +``` + +Each routing method accepts a URL `pattern` and chain of `handlers`. The URL pattern +supports named params (ie. `/users/{userID}`) and wildcards (ie. `/admin/*`). URL parameters +can be fetched at runtime by calling `chi.URLParam(r, "userID")` for named parameters +and `chi.URLParam(r, "*")` for a wildcard parameter. + + +### Middleware handlers + +chi's middlewares are just stdlib net/http middleware handlers. There is nothing special +about them, which means the router and all the tooling is designed to be compatible and +friendly with any middleware in the community. This offers much better extensibility and reuse +of packages and is at the heart of chi's purpose. + +Here is an example of a standard net/http middleware where we assign a context key `"user"` +the value of `"123"`. This middleware sets a hypothetical user identifier on the request +context and calls the next handler in the chain. + +```go +// HTTP middleware setting a value on the request context +func MyMiddleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // create new context from `r` request context, and assign key `"user"` + // to value of `"123"` + ctx := context.WithValue(r.Context(), "user", "123") + + // call the next handler in the chain, passing the response writer and + // the updated request object with the new context value. + // + // note: context.Context values are nested, so any previously set + // values will be accessible as well, and the new `"user"` key + // will be accessible from this point forward. + next.ServeHTTP(w, r.WithContext(ctx)) + }) +} +``` + + +### Request handlers + +chi uses standard net/http request handlers. This little snippet is an example of a http.Handler +func that reads a user identifier from the request context - hypothetically, identifying +the user sending an authenticated request, validated+set by a previous middleware handler. + +```go +// HTTP handler accessing data from the request context. +func MyRequestHandler(w http.ResponseWriter, r *http.Request) { + // here we read from the request context and fetch out `"user"` key set in + // the MyMiddleware example above. + user := r.Context().Value("user").(string) + + // respond to the client + w.Write([]byte(fmt.Sprintf("hi %s", user))) +} +``` + + +### URL parameters + +chi's router parses and stores URL parameters right onto the request context. Here is +an example of how to access URL params in your net/http handlers. And of course, middlewares +are able to access the same information. + +```go +// HTTP handler accessing the url routing parameters. +func MyRequestHandler(w http.ResponseWriter, r *http.Request) { + // fetch the url parameter `"userID"` from the request of a matching + // routing pattern. An example routing pattern could be: /users/{userID} + userID := chi.URLParam(r, "userID") + + // fetch `"key"` from the request context + ctx := r.Context() + key := ctx.Value("key").(string) + + // respond to the client + w.Write([]byte(fmt.Sprintf("hi %v, %v", userID, key))) +} +``` + + +## Middlewares + +chi comes equipped with an optional `middleware` package, providing a suite of standard +`net/http` middlewares. Please note, any middleware in the ecosystem that is also compatible +with `net/http` can be used with chi's mux. + +### Core middlewares + +---------------------------------------------------------------------------------------------------- +| chi/middleware Handler | description | +| :--------------------- | :---------------------------------------------------------------------- | +| [AllowContentEncoding] | Enforces a whitelist of request Content-Encoding headers | +| [AllowContentType] | Explicit whitelist of accepted request Content-Types | +| [BasicAuth] | Basic HTTP authentication | +| [Compress] | Gzip compression for clients that accept compressed responses | +| [ContentCharset] | Ensure charset for Content-Type request headers | +| [CleanPath] | Clean double slashes from request path | +| [GetHead] | Automatically route undefined HEAD requests to GET handlers | +| [Heartbeat] | Monitoring endpoint to check the servers pulse | +| [Logger] | Logs the start and end of each request with the elapsed processing time | +| [NoCache] | Sets response headers to prevent clients from caching | +| [Profiler] | Easily attach net/http/pprof to your routers | +| [RealIP] | Sets a http.Request's RemoteAddr to either X-Forwarded-For or X-Real-IP | +| [Recoverer] | Gracefully absorb panics and prints the stack trace | +| [RequestID] | Injects a request ID into the context of each request | +| [RedirectSlashes] | Redirect slashes on routing paths | +| [RouteHeaders] | Route handling for request headers | +| [SetHeader] | Short-hand middleware to set a response header key/value | +| [StripSlashes] | Strip slashes on routing paths | +| [Throttle] | Puts a ceiling on the number of concurrent requests | +| [Timeout] | Signals to the request context when the timeout deadline is reached | +| [URLFormat] | Parse extension from url and put it on request context | +| [WithValue] | Short-hand middleware to set a key/value on the request context | +---------------------------------------------------------------------------------------------------- + +[AllowContentEncoding]: https://pkg.go.dev/github.com/go-chi/chi/middleware#AllowContentEncoding +[AllowContentType]: https://pkg.go.dev/github.com/go-chi/chi/middleware#AllowContentType +[BasicAuth]: https://pkg.go.dev/github.com/go-chi/chi/middleware#BasicAuth +[Compress]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Compress +[ContentCharset]: https://pkg.go.dev/github.com/go-chi/chi/middleware#ContentCharset +[CleanPath]: https://pkg.go.dev/github.com/go-chi/chi/middleware#CleanPath +[GetHead]: https://pkg.go.dev/github.com/go-chi/chi/middleware#GetHead +[GetReqID]: https://pkg.go.dev/github.com/go-chi/chi/middleware#GetReqID +[Heartbeat]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Heartbeat +[Logger]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Logger +[NoCache]: https://pkg.go.dev/github.com/go-chi/chi/middleware#NoCache +[Profiler]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Profiler +[RealIP]: https://pkg.go.dev/github.com/go-chi/chi/middleware#RealIP +[Recoverer]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Recoverer +[RedirectSlashes]: https://pkg.go.dev/github.com/go-chi/chi/middleware#RedirectSlashes +[RequestLogger]: https://pkg.go.dev/github.com/go-chi/chi/middleware#RequestLogger +[RequestID]: https://pkg.go.dev/github.com/go-chi/chi/middleware#RequestID +[RouteHeaders]: https://pkg.go.dev/github.com/go-chi/chi/middleware#RouteHeaders +[SetHeader]: https://pkg.go.dev/github.com/go-chi/chi/middleware#SetHeader +[StripSlashes]: https://pkg.go.dev/github.com/go-chi/chi/middleware#StripSlashes +[Throttle]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Throttle +[ThrottleBacklog]: https://pkg.go.dev/github.com/go-chi/chi/middleware#ThrottleBacklog +[ThrottleWithOpts]: https://pkg.go.dev/github.com/go-chi/chi/middleware#ThrottleWithOpts +[Timeout]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Timeout +[URLFormat]: https://pkg.go.dev/github.com/go-chi/chi/middleware#URLFormat +[WithLogEntry]: https://pkg.go.dev/github.com/go-chi/chi/middleware#WithLogEntry +[WithValue]: https://pkg.go.dev/github.com/go-chi/chi/middleware#WithValue +[Compressor]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Compressor +[DefaultLogFormatter]: https://pkg.go.dev/github.com/go-chi/chi/middleware#DefaultLogFormatter +[EncoderFunc]: https://pkg.go.dev/github.com/go-chi/chi/middleware#EncoderFunc +[HeaderRoute]: https://pkg.go.dev/github.com/go-chi/chi/middleware#HeaderRoute +[HeaderRouter]: https://pkg.go.dev/github.com/go-chi/chi/middleware#HeaderRouter +[LogEntry]: https://pkg.go.dev/github.com/go-chi/chi/middleware#LogEntry +[LogFormatter]: https://pkg.go.dev/github.com/go-chi/chi/middleware#LogFormatter +[LoggerInterface]: https://pkg.go.dev/github.com/go-chi/chi/middleware#LoggerInterface +[ThrottleOpts]: https://pkg.go.dev/github.com/go-chi/chi/middleware#ThrottleOpts +[WrapResponseWriter]: https://pkg.go.dev/github.com/go-chi/chi/middleware#WrapResponseWriter + +### Extra middlewares & packages + +Please see https://github.com/go-chi for additional packages. + +-------------------------------------------------------------------------------------------------------------------- +| package | description | +|:---------------------------------------------------|:------------------------------------------------------------- +| [cors](https://github.com/go-chi/cors) | Cross-origin resource sharing (CORS) | +| [docgen](https://github.com/go-chi/docgen) | Print chi.Router routes at runtime | +| [jwtauth](https://github.com/go-chi/jwtauth) | JWT authentication | +| [hostrouter](https://github.com/go-chi/hostrouter) | Domain/host based request routing | +| [httplog](https://github.com/go-chi/httplog) | Small but powerful structured HTTP request logging | +| [httprate](https://github.com/go-chi/httprate) | HTTP request rate limiter | +| [httptracer](https://github.com/go-chi/httptracer) | HTTP request performance tracing library | +| [httpvcr](https://github.com/go-chi/httpvcr) | Write deterministic tests for external sources | +| [stampede](https://github.com/go-chi/stampede) | HTTP request coalescer | +-------------------------------------------------------------------------------------------------------------------- + + +## context? + +`context` is a tiny pkg that provides simple interface to signal context across call stacks +and goroutines. It was originally written by [Sameer Ajmani](https://github.com/Sajmani) +and is available in stdlib since go1.7. + +Learn more at https://blog.golang.org/context + +and.. +* Docs: https://golang.org/pkg/context +* Source: https://github.com/golang/go/tree/master/src/context + + +## Benchmarks + +The benchmark suite: https://github.com/pkieltyka/go-http-routing-benchmark + +Results as of Nov 29, 2020 with Go 1.15.5 on Linux AMD 3950x + +```shell +BenchmarkChi_Param 3075895 384 ns/op 400 B/op 2 allocs/op +BenchmarkChi_Param5 2116603 566 ns/op 400 B/op 2 allocs/op +BenchmarkChi_Param20 964117 1227 ns/op 400 B/op 2 allocs/op +BenchmarkChi_ParamWrite 2863413 420 ns/op 400 B/op 2 allocs/op +BenchmarkChi_GithubStatic 3045488 395 ns/op 400 B/op 2 allocs/op +BenchmarkChi_GithubParam 2204115 540 ns/op 400 B/op 2 allocs/op +BenchmarkChi_GithubAll 10000 113811 ns/op 81203 B/op 406 allocs/op +BenchmarkChi_GPlusStatic 3337485 359 ns/op 400 B/op 2 allocs/op +BenchmarkChi_GPlusParam 2825853 423 ns/op 400 B/op 2 allocs/op +BenchmarkChi_GPlus2Params 2471697 483 ns/op 400 B/op 2 allocs/op +BenchmarkChi_GPlusAll 194220 5950 ns/op 5200 B/op 26 allocs/op +BenchmarkChi_ParseStatic 3365324 356 ns/op 400 B/op 2 allocs/op +BenchmarkChi_ParseParam 2976614 404 ns/op 400 B/op 2 allocs/op +BenchmarkChi_Parse2Params 2638084 439 ns/op 400 B/op 2 allocs/op +BenchmarkChi_ParseAll 109567 11295 ns/op 10400 B/op 52 allocs/op +BenchmarkChi_StaticAll 16846 71308 ns/op 62802 B/op 314 allocs/op +``` + +Comparison with other routers: https://gist.github.com/pkieltyka/123032f12052520aaccab752bd3e78cc + +NOTE: the allocs in the benchmark above are from the calls to http.Request's +`WithContext(context.Context)` method that clones the http.Request, sets the `Context()` +on the duplicated (alloc'd) request and returns it the new request object. This is just +how setting context on a request in Go works. + + +## Go module support & note on chi's versioning + +* Go.mod support means we reset our versioning starting from v1.5 (see [CHANGELOG](https://github.com/go-chi/chi/blob/master/CHANGELOG.md#v150-2020-11-12---now-with-gomod-support)) +* All older tags are preserved, are backwards-compatible and will "just work" as they +* Brand new systems can run `go get -u github.com/go-chi/chi` as normal, or `go get -u github.com/go-chi/chi@latest` +to install chi, which will install v1.x+ built with go.mod support, starting from v1.5.0. +* For existing projects who want to upgrade to the latest go.mod version, run: `go get -u github.com/go-chi/chi@v1.5.0`, +which will get you on the go.mod version line (as Go's mod cache may still remember v4.x). +* Any breaking changes will bump a "minor" release and backwards-compatible improvements/fixes will bump a "tiny" release. + + +## Credits + +* Carl Jackson for https://github.com/zenazn/goji + * Parts of chi's thinking comes from goji, and chi's middleware package + sources from goji. +* Armon Dadgar for https://github.com/armon/go-radix +* Contributions: [@VojtechVitek](https://github.com/VojtechVitek) + +We'll be more than happy to see [your contributions](./CONTRIBUTING.md)! + + +## Beyond REST + +chi is just a http router that lets you decompose request handling into many smaller layers. +Many companies use chi to write REST services for their public APIs. But, REST is just a convention +for managing state via HTTP, and there's a lot of other pieces required to write a complete client-server +system or network of microservices. + +Looking beyond REST, I also recommend some newer works in the field: +* [webrpc](https://github.com/webrpc/webrpc) - Web-focused RPC client+server framework with code-gen +* [gRPC](https://github.com/grpc/grpc-go) - Google's RPC framework via protobufs +* [graphql](https://github.com/99designs/gqlgen) - Declarative query language +* [NATS](https://nats.io) - lightweight pub-sub + + +## License + +Copyright (c) 2015-present [Peter Kieltyka](https://github.com/pkieltyka) + +Licensed under [MIT License](./LICENSE) + +[GoDoc]: https://pkg.go.dev/github.com/go-chi/chi?tab=versions +[GoDoc Widget]: https://godoc.org/github.com/go-chi/chi?status.svg +[Travis]: https://travis-ci.org/go-chi/chi +[Travis Widget]: https://travis-ci.org/go-chi/chi.svg?branch=master diff --git a/vendor/github.com/go-chi/chi/chain.go b/vendor/github.com/go-chi/chi/chain.go new file mode 100644 index 0000000..88e6846 --- /dev/null +++ b/vendor/github.com/go-chi/chi/chain.go @@ -0,0 +1,49 @@ +package chi + +import "net/http" + +// Chain returns a Middlewares type from a slice of middleware handlers. +func Chain(middlewares ...func(http.Handler) http.Handler) Middlewares { + return Middlewares(middlewares) +} + +// Handler builds and returns a http.Handler from the chain of middlewares, +// with `h http.Handler` as the final handler. +func (mws Middlewares) Handler(h http.Handler) http.Handler { + return &ChainHandler{mws, h, chain(mws, h)} +} + +// HandlerFunc builds and returns a http.Handler from the chain of middlewares, +// with `h http.Handler` as the final handler. +func (mws Middlewares) HandlerFunc(h http.HandlerFunc) http.Handler { + return &ChainHandler{mws, h, chain(mws, h)} +} + +// ChainHandler is a http.Handler with support for handler composition and +// execution. +type ChainHandler struct { + Middlewares Middlewares + Endpoint http.Handler + chain http.Handler +} + +func (c *ChainHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + c.chain.ServeHTTP(w, r) +} + +// chain builds a http.Handler composed of an inline middleware stack and endpoint +// handler in the order they are passed. +func chain(middlewares []func(http.Handler) http.Handler, endpoint http.Handler) http.Handler { + // Return ahead of time if there aren't any middlewares for the chain + if len(middlewares) == 0 { + return endpoint + } + + // Wrap the end handler with the middleware chain + h := middlewares[len(middlewares)-1](endpoint) + for i := len(middlewares) - 2; i >= 0; i-- { + h = middlewares[i](h) + } + + return h +} diff --git a/vendor/github.com/go-chi/chi/chi.go b/vendor/github.com/go-chi/chi/chi.go new file mode 100644 index 0000000..b7063dc --- /dev/null +++ b/vendor/github.com/go-chi/chi/chi.go @@ -0,0 +1,134 @@ +// +// Package chi is a small, idiomatic and composable router for building HTTP services. +// +// chi requires Go 1.10 or newer. +// +// Example: +// package main +// +// import ( +// "net/http" +// +// "github.com/go-chi/chi" +// "github.com/go-chi/chi/middleware" +// ) +// +// func main() { +// r := chi.NewRouter() +// r.Use(middleware.Logger) +// r.Use(middleware.Recoverer) +// +// r.Get("/", func(w http.ResponseWriter, r *http.Request) { +// w.Write([]byte("root.")) +// }) +// +// http.ListenAndServe(":3333", r) +// } +// +// See github.com/go-chi/chi/_examples/ for more in-depth examples. +// +// URL patterns allow for easy matching of path components in HTTP +// requests. The matching components can then be accessed using +// chi.URLParam(). All patterns must begin with a slash. +// +// A simple named placeholder {name} matches any sequence of characters +// up to the next / or the end of the URL. Trailing slashes on paths must +// be handled explicitly. +// +// A placeholder with a name followed by a colon allows a regular +// expression match, for example {number:\\d+}. The regular expression +// syntax is Go's normal regexp RE2 syntax, except that regular expressions +// including { or } are not supported, and / will never be +// matched. An anonymous regexp pattern is allowed, using an empty string +// before the colon in the placeholder, such as {:\\d+} +// +// The special placeholder of asterisk matches the rest of the requested +// URL. Any trailing characters in the pattern are ignored. This is the only +// placeholder which will match / characters. +// +// Examples: +// "/user/{name}" matches "/user/jsmith" but not "/user/jsmith/info" or "/user/jsmith/" +// "/user/{name}/info" matches "/user/jsmith/info" +// "/page/*" matches "/page/intro/latest" +// "/page/*/index" also matches "/page/intro/latest" +// "/date/{yyyy:\\d\\d\\d\\d}/{mm:\\d\\d}/{dd:\\d\\d}" matches "/date/2017/04/01" +// +package chi + +import "net/http" + +// NewRouter returns a new Mux object that implements the Router interface. +func NewRouter() *Mux { + return NewMux() +} + +// Router consisting of the core routing methods used by chi's Mux, +// using only the standard net/http. +type Router interface { + http.Handler + Routes + + // Use appends one or more middlewares onto the Router stack. + Use(middlewares ...func(http.Handler) http.Handler) + + // With adds inline middlewares for an endpoint handler. + With(middlewares ...func(http.Handler) http.Handler) Router + + // Group adds a new inline-Router along the current routing + // path, with a fresh middleware stack for the inline-Router. + Group(fn func(r Router)) Router + + // Route mounts a sub-Router along a `pattern`` string. + Route(pattern string, fn func(r Router)) Router + + // Mount attaches another http.Handler along ./pattern/* + Mount(pattern string, h http.Handler) + + // Handle and HandleFunc adds routes for `pattern` that matches + // all HTTP methods. + Handle(pattern string, h http.Handler) + HandleFunc(pattern string, h http.HandlerFunc) + + // Method and MethodFunc adds routes for `pattern` that matches + // the `method` HTTP method. + Method(method, pattern string, h http.Handler) + MethodFunc(method, pattern string, h http.HandlerFunc) + + // HTTP-method routing along `pattern` + Connect(pattern string, h http.HandlerFunc) + Delete(pattern string, h http.HandlerFunc) + Get(pattern string, h http.HandlerFunc) + Head(pattern string, h http.HandlerFunc) + Options(pattern string, h http.HandlerFunc) + Patch(pattern string, h http.HandlerFunc) + Post(pattern string, h http.HandlerFunc) + Put(pattern string, h http.HandlerFunc) + Trace(pattern string, h http.HandlerFunc) + + // NotFound defines a handler to respond whenever a route could + // not be found. + NotFound(h http.HandlerFunc) + + // MethodNotAllowed defines a handler to respond whenever a method is + // not allowed. + MethodNotAllowed(h http.HandlerFunc) +} + +// Routes interface adds two methods for router traversal, which is also +// used by the `docgen` subpackage to generation documentation for Routers. +type Routes interface { + // Routes returns the routing tree in an easily traversable structure. + Routes() []Route + + // Middlewares returns the list of middlewares in use by the router. + Middlewares() Middlewares + + // Match searches the routing tree for a handler that matches + // the method/path - similar to routing a http request, but without + // executing the handler thereafter. + Match(rctx *Context, method, path string) bool +} + +// Middlewares type is a slice of standard middleware handlers with methods +// to compose middleware chains and http.Handler's. +type Middlewares []func(http.Handler) http.Handler diff --git a/vendor/github.com/go-chi/chi/context.go b/vendor/github.com/go-chi/chi/context.go new file mode 100644 index 0000000..8c97f21 --- /dev/null +++ b/vendor/github.com/go-chi/chi/context.go @@ -0,0 +1,157 @@ +package chi + +import ( + "context" + "net/http" + "strings" +) + +// URLParam returns the url parameter from a http.Request object. +func URLParam(r *http.Request, key string) string { + if rctx := RouteContext(r.Context()); rctx != nil { + return rctx.URLParam(key) + } + return "" +} + +// URLParamFromCtx returns the url parameter from a http.Request Context. +func URLParamFromCtx(ctx context.Context, key string) string { + if rctx := RouteContext(ctx); rctx != nil { + return rctx.URLParam(key) + } + return "" +} + +// RouteContext returns chi's routing Context object from a +// http.Request Context. +func RouteContext(ctx context.Context) *Context { + val, _ := ctx.Value(RouteCtxKey).(*Context) + return val +} + +// NewRouteContext returns a new routing Context object. +func NewRouteContext() *Context { + return &Context{} +} + +var ( + // RouteCtxKey is the context.Context key to store the request context. + RouteCtxKey = &contextKey{"RouteContext"} +) + +// Context is the default routing context set on the root node of a +// request context to track route patterns, URL parameters and +// an optional routing path. +type Context struct { + Routes Routes + + // Routing path/method override used during the route search. + // See Mux#routeHTTP method. + RoutePath string + RouteMethod string + + // Routing pattern stack throughout the lifecycle of the request, + // across all connected routers. It is a record of all matching + // patterns across a stack of sub-routers. + RoutePatterns []string + + // URLParams are the stack of routeParams captured during the + // routing lifecycle across a stack of sub-routers. + URLParams RouteParams + + // The endpoint routing pattern that matched the request URI path + // or `RoutePath` of the current sub-router. This value will update + // during the lifecycle of a request passing through a stack of + // sub-routers. + routePattern string + + // Route parameters matched for the current sub-router. It is + // intentionally unexported so it cant be tampered. + routeParams RouteParams + + // methodNotAllowed hint + methodNotAllowed bool + + // parentCtx is the parent of this one, for using Context as a + // context.Context directly. This is an optimization that saves + // 1 allocation. + parentCtx context.Context +} + +// Reset a routing context to its initial state. +func (x *Context) Reset() { + x.Routes = nil + x.RoutePath = "" + x.RouteMethod = "" + x.RoutePatterns = x.RoutePatterns[:0] + x.URLParams.Keys = x.URLParams.Keys[:0] + x.URLParams.Values = x.URLParams.Values[:0] + + x.routePattern = "" + x.routeParams.Keys = x.routeParams.Keys[:0] + x.routeParams.Values = x.routeParams.Values[:0] + x.methodNotAllowed = false + x.parentCtx = nil +} + +// URLParam returns the corresponding URL parameter value from the request +// routing context. +func (x *Context) URLParam(key string) string { + for k := len(x.URLParams.Keys) - 1; k >= 0; k-- { + if x.URLParams.Keys[k] == key { + return x.URLParams.Values[k] + } + } + return "" +} + +// RoutePattern builds the routing pattern string for the particular +// request, at the particular point during routing. This means, the value +// will change throughout the execution of a request in a router. That is +// why its advised to only use this value after calling the next handler. +// +// For example, +// +// func Instrument(next http.Handler) http.Handler { +// return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { +// next.ServeHTTP(w, r) +// routePattern := chi.RouteContext(r.Context()).RoutePattern() +// measure(w, r, routePattern) +// }) +// } +func (x *Context) RoutePattern() string { + routePattern := strings.Join(x.RoutePatterns, "") + return replaceWildcards(routePattern) +} + +// replaceWildcards takes a route pattern and recursively replaces all +// occurrences of "/*/" to "/". +func replaceWildcards(p string) string { + if strings.Contains(p, "/*/") { + return replaceWildcards(strings.Replace(p, "/*/", "/", -1)) + } + + return p +} + +// RouteParams is a structure to track URL routing parameters efficiently. +type RouteParams struct { + Keys, Values []string +} + +// Add will append a URL parameter to the end of the route param +func (s *RouteParams) Add(key, value string) { + s.Keys = append(s.Keys, key) + s.Values = append(s.Values, value) +} + +// contextKey is a value for use with context.WithValue. It's used as +// a pointer so it fits in an interface{} without allocation. This technique +// for defining context keys was copied from Go 1.7's new use of context in net/http. +type contextKey struct { + name string +} + +func (k *contextKey) String() string { + return "chi context value " + k.name +} diff --git a/vendor/github.com/go-chi/chi/go.mod b/vendor/github.com/go-chi/chi/go.mod new file mode 100644 index 0000000..769b901 --- /dev/null +++ b/vendor/github.com/go-chi/chi/go.mod @@ -0,0 +1,3 @@ +module github.com/go-chi/chi + +go 1.16 diff --git a/vendor/github.com/go-chi/chi/mux.go b/vendor/github.com/go-chi/chi/mux.go new file mode 100644 index 0000000..146643b --- /dev/null +++ b/vendor/github.com/go-chi/chi/mux.go @@ -0,0 +1,479 @@ +package chi + +import ( + "context" + "fmt" + "net/http" + "strings" + "sync" +) + +var _ Router = &Mux{} + +// Mux is a simple HTTP route multiplexer that parses a request path, +// records any URL params, and executes an end handler. It implements +// the http.Handler interface and is friendly with the standard library. +// +// Mux is designed to be fast, minimal and offer a powerful API for building +// modular and composable HTTP services with a large set of handlers. It's +// particularly useful for writing large REST API services that break a handler +// into many smaller parts composed of middlewares and end handlers. +type Mux struct { + // The radix trie router + tree *node + + // The middleware stack + middlewares []func(http.Handler) http.Handler + + // Controls the behaviour of middleware chain generation when a mux + // is registered as an inline group inside another mux. + inline bool + parent *Mux + + // The computed mux handler made of the chained middleware stack and + // the tree router + handler http.Handler + + // Routing context pool + pool *sync.Pool + + // Custom route not found handler + notFoundHandler http.HandlerFunc + + // Custom method not allowed handler + methodNotAllowedHandler http.HandlerFunc +} + +// NewMux returns a newly initialized Mux object that implements the Router +// interface. +func NewMux() *Mux { + mux := &Mux{tree: &node{}, pool: &sync.Pool{}} + mux.pool.New = func() interface{} { + return NewRouteContext() + } + return mux +} + +// ServeHTTP is the single method of the http.Handler interface that makes +// Mux interoperable with the standard library. It uses a sync.Pool to get and +// reuse routing contexts for each request. +func (mx *Mux) ServeHTTP(w http.ResponseWriter, r *http.Request) { + // Ensure the mux has some routes defined on the mux + if mx.handler == nil { + mx.NotFoundHandler().ServeHTTP(w, r) + return + } + + // Check if a routing context already exists from a parent router. + rctx, _ := r.Context().Value(RouteCtxKey).(*Context) + if rctx != nil { + mx.handler.ServeHTTP(w, r) + return + } + + // Fetch a RouteContext object from the sync pool, and call the computed + // mx.handler that is comprised of mx.middlewares + mx.routeHTTP. + // Once the request is finished, reset the routing context and put it back + // into the pool for reuse from another request. + rctx = mx.pool.Get().(*Context) + rctx.Reset() + rctx.Routes = mx + rctx.parentCtx = r.Context() + + // NOTE: r.WithContext() causes 2 allocations and context.WithValue() causes 1 allocation + r = r.WithContext(context.WithValue(r.Context(), RouteCtxKey, rctx)) + + // Serve the request and once its done, put the request context back in the sync pool + mx.handler.ServeHTTP(w, r) + mx.pool.Put(rctx) +} + +// Use appends a middleware handler to the Mux middleware stack. +// +// The middleware stack for any Mux will execute before searching for a matching +// route to a specific handler, which provides opportunity to respond early, +// change the course of the request execution, or set request-scoped values for +// the next http.Handler. +func (mx *Mux) Use(middlewares ...func(http.Handler) http.Handler) { + if mx.handler != nil { + panic("chi: all middlewares must be defined before routes on a mux") + } + mx.middlewares = append(mx.middlewares, middlewares...) +} + +// Handle adds the route `pattern` that matches any http method to +// execute the `handler` http.Handler. +func (mx *Mux) Handle(pattern string, handler http.Handler) { + mx.handle(mALL, pattern, handler) +} + +// HandleFunc adds the route `pattern` that matches any http method to +// execute the `handlerFn` http.HandlerFunc. +func (mx *Mux) HandleFunc(pattern string, handlerFn http.HandlerFunc) { + mx.handle(mALL, pattern, handlerFn) +} + +// Method adds the route `pattern` that matches `method` http method to +// execute the `handler` http.Handler. +func (mx *Mux) Method(method, pattern string, handler http.Handler) { + m, ok := methodMap[strings.ToUpper(method)] + if !ok { + panic(fmt.Sprintf("chi: '%s' http method is not supported.", method)) + } + mx.handle(m, pattern, handler) +} + +// MethodFunc adds the route `pattern` that matches `method` http method to +// execute the `handlerFn` http.HandlerFunc. +func (mx *Mux) MethodFunc(method, pattern string, handlerFn http.HandlerFunc) { + mx.Method(method, pattern, handlerFn) +} + +// Connect adds the route `pattern` that matches a CONNECT http method to +// execute the `handlerFn` http.HandlerFunc. +func (mx *Mux) Connect(pattern string, handlerFn http.HandlerFunc) { + mx.handle(mCONNECT, pattern, handlerFn) +} + +// Delete adds the route `pattern` that matches a DELETE http method to +// execute the `handlerFn` http.HandlerFunc. +func (mx *Mux) Delete(pattern string, handlerFn http.HandlerFunc) { + mx.handle(mDELETE, pattern, handlerFn) +} + +// Get adds the route `pattern` that matches a GET http method to +// execute the `handlerFn` http.HandlerFunc. +func (mx *Mux) Get(pattern string, handlerFn http.HandlerFunc) { + mx.handle(mGET, pattern, handlerFn) +} + +// Head adds the route `pattern` that matches a HEAD http method to +// execute the `handlerFn` http.HandlerFunc. +func (mx *Mux) Head(pattern string, handlerFn http.HandlerFunc) { + mx.handle(mHEAD, pattern, handlerFn) +} + +// Options adds the route `pattern` that matches a OPTIONS http method to +// execute the `handlerFn` http.HandlerFunc. +func (mx *Mux) Options(pattern string, handlerFn http.HandlerFunc) { + mx.handle(mOPTIONS, pattern, handlerFn) +} + +// Patch adds the route `pattern` that matches a PATCH http method to +// execute the `handlerFn` http.HandlerFunc. +func (mx *Mux) Patch(pattern string, handlerFn http.HandlerFunc) { + mx.handle(mPATCH, pattern, handlerFn) +} + +// Post adds the route `pattern` that matches a POST http method to +// execute the `handlerFn` http.HandlerFunc. +func (mx *Mux) Post(pattern string, handlerFn http.HandlerFunc) { + mx.handle(mPOST, pattern, handlerFn) +} + +// Put adds the route `pattern` that matches a PUT http method to +// execute the `handlerFn` http.HandlerFunc. +func (mx *Mux) Put(pattern string, handlerFn http.HandlerFunc) { + mx.handle(mPUT, pattern, handlerFn) +} + +// Trace adds the route `pattern` that matches a TRACE http method to +// execute the `handlerFn` http.HandlerFunc. +func (mx *Mux) Trace(pattern string, handlerFn http.HandlerFunc) { + mx.handle(mTRACE, pattern, handlerFn) +} + +// NotFound sets a custom http.HandlerFunc for routing paths that could +// not be found. The default 404 handler is `http.NotFound`. +func (mx *Mux) NotFound(handlerFn http.HandlerFunc) { + // Build NotFound handler chain + m := mx + h := Chain(mx.middlewares...).HandlerFunc(handlerFn).ServeHTTP + if mx.inline && mx.parent != nil { + m = mx.parent + } + + // Update the notFoundHandler from this point forward + m.notFoundHandler = h + m.updateSubRoutes(func(subMux *Mux) { + if subMux.notFoundHandler == nil { + subMux.NotFound(h) + } + }) +} + +// MethodNotAllowed sets a custom http.HandlerFunc for routing paths where the +// method is unresolved. The default handler returns a 405 with an empty body. +func (mx *Mux) MethodNotAllowed(handlerFn http.HandlerFunc) { + // Build MethodNotAllowed handler chain + m := mx + h := Chain(mx.middlewares...).HandlerFunc(handlerFn).ServeHTTP + if mx.inline && mx.parent != nil { + m = mx.parent + } + + // Update the methodNotAllowedHandler from this point forward + m.methodNotAllowedHandler = h + m.updateSubRoutes(func(subMux *Mux) { + if subMux.methodNotAllowedHandler == nil { + subMux.MethodNotAllowed(h) + } + }) +} + +// With adds inline middlewares for an endpoint handler. +func (mx *Mux) With(middlewares ...func(http.Handler) http.Handler) Router { + // Similarly as in handle(), we must build the mux handler once additional + // middleware registration isn't allowed for this stack, like now. + if !mx.inline && mx.handler == nil { + mx.updateRouteHandler() + } + + // Copy middlewares from parent inline muxs + var mws Middlewares + if mx.inline { + mws = make(Middlewares, len(mx.middlewares)) + copy(mws, mx.middlewares) + } + mws = append(mws, middlewares...) + + im := &Mux{ + pool: mx.pool, inline: true, parent: mx, tree: mx.tree, middlewares: mws, + notFoundHandler: mx.notFoundHandler, methodNotAllowedHandler: mx.methodNotAllowedHandler, + } + + return im +} + +// Group creates a new inline-Mux with a fresh middleware stack. It's useful +// for a group of handlers along the same routing path that use an additional +// set of middlewares. See _examples/. +func (mx *Mux) Group(fn func(r Router)) Router { + im := mx.With().(*Mux) + if fn != nil { + fn(im) + } + return im +} + +// Route creates a new Mux with a fresh middleware stack and mounts it +// along the `pattern` as a subrouter. Effectively, this is a short-hand +// call to Mount. See _examples/. +func (mx *Mux) Route(pattern string, fn func(r Router)) Router { + if fn == nil { + panic(fmt.Sprintf("chi: attempting to Route() a nil subrouter on '%s'", pattern)) + } + subRouter := NewRouter() + fn(subRouter) + mx.Mount(pattern, subRouter) + return subRouter +} + +// Mount attaches another http.Handler or chi Router as a subrouter along a routing +// path. It's very useful to split up a large API as many independent routers and +// compose them as a single service using Mount. See _examples/. +// +// Note that Mount() simply sets a wildcard along the `pattern` that will continue +// routing at the `handler`, which in most cases is another chi.Router. As a result, +// if you define two Mount() routes on the exact same pattern the mount will panic. +func (mx *Mux) Mount(pattern string, handler http.Handler) { + if handler == nil { + panic(fmt.Sprintf("chi: attempting to Mount() a nil handler on '%s'", pattern)) + } + + // Provide runtime safety for ensuring a pattern isn't mounted on an existing + // routing pattern. + if mx.tree.findPattern(pattern+"*") || mx.tree.findPattern(pattern+"/*") { + panic(fmt.Sprintf("chi: attempting to Mount() a handler on an existing path, '%s'", pattern)) + } + + // Assign sub-Router's with the parent not found & method not allowed handler if not specified. + subr, ok := handler.(*Mux) + if ok && subr.notFoundHandler == nil && mx.notFoundHandler != nil { + subr.NotFound(mx.notFoundHandler) + } + if ok && subr.methodNotAllowedHandler == nil && mx.methodNotAllowedHandler != nil { + subr.MethodNotAllowed(mx.methodNotAllowedHandler) + } + + mountHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + rctx := RouteContext(r.Context()) + + // shift the url path past the previous subrouter + rctx.RoutePath = mx.nextRoutePath(rctx) + + // reset the wildcard URLParam which connects the subrouter + n := len(rctx.URLParams.Keys) - 1 + if n >= 0 && rctx.URLParams.Keys[n] == "*" && len(rctx.URLParams.Values) > n { + rctx.URLParams.Values[n] = "" + } + + handler.ServeHTTP(w, r) + }) + + if pattern == "" || pattern[len(pattern)-1] != '/' { + mx.handle(mALL|mSTUB, pattern, mountHandler) + mx.handle(mALL|mSTUB, pattern+"/", mountHandler) + pattern += "/" + } + + method := mALL + subroutes, _ := handler.(Routes) + if subroutes != nil { + method |= mSTUB + } + n := mx.handle(method, pattern+"*", mountHandler) + + if subroutes != nil { + n.subroutes = subroutes + } +} + +// Routes returns a slice of routing information from the tree, +// useful for traversing available routes of a router. +func (mx *Mux) Routes() []Route { + return mx.tree.routes() +} + +// Middlewares returns a slice of middleware handler functions. +func (mx *Mux) Middlewares() Middlewares { + return mx.middlewares +} + +// Match searches the routing tree for a handler that matches the method/path. +// It's similar to routing a http request, but without executing the handler +// thereafter. +// +// Note: the *Context state is updated during execution, so manage +// the state carefully or make a NewRouteContext(). +func (mx *Mux) Match(rctx *Context, method, path string) bool { + m, ok := methodMap[method] + if !ok { + return false + } + + node, _, h := mx.tree.FindRoute(rctx, m, path) + + if node != nil && node.subroutes != nil { + rctx.RoutePath = mx.nextRoutePath(rctx) + return node.subroutes.Match(rctx, method, rctx.RoutePath) + } + + return h != nil +} + +// NotFoundHandler returns the default Mux 404 responder whenever a route +// cannot be found. +func (mx *Mux) NotFoundHandler() http.HandlerFunc { + if mx.notFoundHandler != nil { + return mx.notFoundHandler + } + return http.NotFound +} + +// MethodNotAllowedHandler returns the default Mux 405 responder whenever +// a method cannot be resolved for a route. +func (mx *Mux) MethodNotAllowedHandler() http.HandlerFunc { + if mx.methodNotAllowedHandler != nil { + return mx.methodNotAllowedHandler + } + return methodNotAllowedHandler +} + +// handle registers a http.Handler in the routing tree for a particular http method +// and routing pattern. +func (mx *Mux) handle(method methodTyp, pattern string, handler http.Handler) *node { + if len(pattern) == 0 || pattern[0] != '/' { + panic(fmt.Sprintf("chi: routing pattern must begin with '/' in '%s'", pattern)) + } + + // Build the computed routing handler for this routing pattern. + if !mx.inline && mx.handler == nil { + mx.updateRouteHandler() + } + + // Build endpoint handler with inline middlewares for the route + var h http.Handler + if mx.inline { + mx.handler = http.HandlerFunc(mx.routeHTTP) + h = Chain(mx.middlewares...).Handler(handler) + } else { + h = handler + } + + // Add the endpoint to the tree and return the node + return mx.tree.InsertRoute(method, pattern, h) +} + +// routeHTTP routes a http.Request through the Mux routing tree to serve +// the matching handler for a particular http method. +func (mx *Mux) routeHTTP(w http.ResponseWriter, r *http.Request) { + // Grab the route context object + rctx := r.Context().Value(RouteCtxKey).(*Context) + + // The request routing path + routePath := rctx.RoutePath + if routePath == "" { + if r.URL.RawPath != "" { + routePath = r.URL.RawPath + } else { + routePath = r.URL.Path + } + } + + // Check if method is supported by chi + if rctx.RouteMethod == "" { + rctx.RouteMethod = r.Method + } + method, ok := methodMap[rctx.RouteMethod] + if !ok { + mx.MethodNotAllowedHandler().ServeHTTP(w, r) + return + } + + // Find the route + if _, _, h := mx.tree.FindRoute(rctx, method, routePath); h != nil { + h.ServeHTTP(w, r) + return + } + if rctx.methodNotAllowed { + mx.MethodNotAllowedHandler().ServeHTTP(w, r) + } else { + mx.NotFoundHandler().ServeHTTP(w, r) + } +} + +func (mx *Mux) nextRoutePath(rctx *Context) string { + routePath := "/" + nx := len(rctx.routeParams.Keys) - 1 // index of last param in list + if nx >= 0 && rctx.routeParams.Keys[nx] == "*" && len(rctx.routeParams.Values) > nx { + routePath = "/" + rctx.routeParams.Values[nx] + } + return routePath +} + +// Recursively update data on child routers. +func (mx *Mux) updateSubRoutes(fn func(subMux *Mux)) { + for _, r := range mx.tree.routes() { + subMux, ok := r.SubRoutes.(*Mux) + if !ok { + continue + } + fn(subMux) + } +} + +// updateRouteHandler builds the single mux handler that is a chain of the middleware +// stack, as defined by calls to Use(), and the tree router (Mux) itself. After this +// point, no other middlewares can be registered on this Mux's stack. But you can still +// compose additional middlewares via Group()'s or using a chained middleware handler. +func (mx *Mux) updateRouteHandler() { + mx.handler = chain(mx.middlewares, http.HandlerFunc(mx.routeHTTP)) +} + +// methodNotAllowedHandler is a helper function to respond with a 405, +// method not allowed. +func methodNotAllowedHandler(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(405) + w.Write(nil) +} diff --git a/vendor/github.com/go-chi/chi/tree.go b/vendor/github.com/go-chi/chi/tree.go new file mode 100644 index 0000000..8057c52 --- /dev/null +++ b/vendor/github.com/go-chi/chi/tree.go @@ -0,0 +1,866 @@ +package chi + +// Radix tree implementation below is a based on the original work by +// Armon Dadgar in https://github.com/armon/go-radix/blob/master/radix.go +// (MIT licensed). It's been heavily modified for use as a HTTP routing tree. + +import ( + "fmt" + "net/http" + "regexp" + "sort" + "strconv" + "strings" +) + +type methodTyp int + +const ( + mSTUB methodTyp = 1 << iota + mCONNECT + mDELETE + mGET + mHEAD + mOPTIONS + mPATCH + mPOST + mPUT + mTRACE +) + +var mALL = mCONNECT | mDELETE | mGET | mHEAD | + mOPTIONS | mPATCH | mPOST | mPUT | mTRACE + +var methodMap = map[string]methodTyp{ + http.MethodConnect: mCONNECT, + http.MethodDelete: mDELETE, + http.MethodGet: mGET, + http.MethodHead: mHEAD, + http.MethodOptions: mOPTIONS, + http.MethodPatch: mPATCH, + http.MethodPost: mPOST, + http.MethodPut: mPUT, + http.MethodTrace: mTRACE, +} + +// RegisterMethod adds support for custom HTTP method handlers, available +// via Router#Method and Router#MethodFunc +func RegisterMethod(method string) { + if method == "" { + return + } + method = strings.ToUpper(method) + if _, ok := methodMap[method]; ok { + return + } + n := len(methodMap) + if n > strconv.IntSize-2 { + panic(fmt.Sprintf("chi: max number of methods reached (%d)", strconv.IntSize)) + } + mt := methodTyp(2 << n) + methodMap[method] = mt + mALL |= mt +} + +type nodeTyp uint8 + +const ( + ntStatic nodeTyp = iota // /home + ntRegexp // /{id:[0-9]+} + ntParam // /{user} + ntCatchAll // /api/v1/* +) + +type node struct { + // node type: static, regexp, param, catchAll + typ nodeTyp + + // first byte of the prefix + label byte + + // first byte of the child prefix + tail byte + + // prefix is the common prefix we ignore + prefix string + + // regexp matcher for regexp nodes + rex *regexp.Regexp + + // HTTP handler endpoints on the leaf node + endpoints endpoints + + // subroutes on the leaf node + subroutes Routes + + // child nodes should be stored in-order for iteration, + // in groups of the node type. + children [ntCatchAll + 1]nodes +} + +// endpoints is a mapping of http method constants to handlers +// for a given route. +type endpoints map[methodTyp]*endpoint + +type endpoint struct { + // endpoint handler + handler http.Handler + + // pattern is the routing pattern for handler nodes + pattern string + + // parameter keys recorded on handler nodes + paramKeys []string +} + +func (s endpoints) Value(method methodTyp) *endpoint { + mh, ok := s[method] + if !ok { + mh = &endpoint{} + s[method] = mh + } + return mh +} + +func (n *node) InsertRoute(method methodTyp, pattern string, handler http.Handler) *node { + var parent *node + search := pattern + + for { + // Handle key exhaustion + if len(search) == 0 { + // Insert or update the node's leaf handler + n.setEndpoint(method, handler, pattern) + return n + } + + // We're going to be searching for a wild node next, + // in this case, we need to get the tail + var label = search[0] + var segTail byte + var segEndIdx int + var segTyp nodeTyp + var segRexpat string + if label == '{' || label == '*' { + segTyp, _, segRexpat, segTail, _, segEndIdx = patNextSegment(search) + } + + var prefix string + if segTyp == ntRegexp { + prefix = segRexpat + } + + // Look for the edge to attach to + parent = n + n = n.getEdge(segTyp, label, segTail, prefix) + + // No edge, create one + if n == nil { + child := &node{label: label, tail: segTail, prefix: search} + hn := parent.addChild(child, search) + hn.setEndpoint(method, handler, pattern) + + return hn + } + + // Found an edge to match the pattern + + if n.typ > ntStatic { + // We found a param node, trim the param from the search path and continue. + // This param/wild pattern segment would already be on the tree from a previous + // call to addChild when creating a new node. + search = search[segEndIdx:] + continue + } + + // Static nodes fall below here. + // Determine longest prefix of the search key on match. + commonPrefix := longestPrefix(search, n.prefix) + if commonPrefix == len(n.prefix) { + // the common prefix is as long as the current node's prefix we're attempting to insert. + // keep the search going. + search = search[commonPrefix:] + continue + } + + // Split the node + child := &node{ + typ: ntStatic, + prefix: search[:commonPrefix], + } + parent.replaceChild(search[0], segTail, child) + + // Restore the existing node + n.label = n.prefix[commonPrefix] + n.prefix = n.prefix[commonPrefix:] + child.addChild(n, n.prefix) + + // If the new key is a subset, set the method/handler on this node and finish. + search = search[commonPrefix:] + if len(search) == 0 { + child.setEndpoint(method, handler, pattern) + return child + } + + // Create a new edge for the node + subchild := &node{ + typ: ntStatic, + label: search[0], + prefix: search, + } + hn := child.addChild(subchild, search) + hn.setEndpoint(method, handler, pattern) + return hn + } +} + +// addChild appends the new `child` node to the tree using the `pattern` as the trie key. +// For a URL router like chi's, we split the static, param, regexp and wildcard segments +// into different nodes. In addition, addChild will recursively call itself until every +// pattern segment is added to the url pattern tree as individual nodes, depending on type. +func (n *node) addChild(child *node, prefix string) *node { + search := prefix + + // handler leaf node added to the tree is the child. + // this may be overridden later down the flow + hn := child + + // Parse next segment + segTyp, _, segRexpat, segTail, segStartIdx, segEndIdx := patNextSegment(search) + + // Add child depending on next up segment + switch segTyp { + + case ntStatic: + // Search prefix is all static (that is, has no params in path) + // noop + + default: + // Search prefix contains a param, regexp or wildcard + + if segTyp == ntRegexp { + rex, err := regexp.Compile(segRexpat) + if err != nil { + panic(fmt.Sprintf("chi: invalid regexp pattern '%s' in route param", segRexpat)) + } + child.prefix = segRexpat + child.rex = rex + } + + if segStartIdx == 0 { + // Route starts with a param + child.typ = segTyp + + if segTyp == ntCatchAll { + segStartIdx = -1 + } else { + segStartIdx = segEndIdx + } + if segStartIdx < 0 { + segStartIdx = len(search) + } + child.tail = segTail // for params, we set the tail + + if segStartIdx != len(search) { + // add static edge for the remaining part, split the end. + // its not possible to have adjacent param nodes, so its certainly + // going to be a static node next. + + search = search[segStartIdx:] // advance search position + + nn := &node{ + typ: ntStatic, + label: search[0], + prefix: search, + } + hn = child.addChild(nn, search) + } + + } else if segStartIdx > 0 { + // Route has some param + + // starts with a static segment + child.typ = ntStatic + child.prefix = search[:segStartIdx] + child.rex = nil + + // add the param edge node + search = search[segStartIdx:] + + nn := &node{ + typ: segTyp, + label: search[0], + tail: segTail, + } + hn = child.addChild(nn, search) + + } + } + + n.children[child.typ] = append(n.children[child.typ], child) + n.children[child.typ].Sort() + return hn +} + +func (n *node) replaceChild(label, tail byte, child *node) { + for i := 0; i < len(n.children[child.typ]); i++ { + if n.children[child.typ][i].label == label && n.children[child.typ][i].tail == tail { + n.children[child.typ][i] = child + n.children[child.typ][i].label = label + n.children[child.typ][i].tail = tail + return + } + } + panic("chi: replacing missing child") +} + +func (n *node) getEdge(ntyp nodeTyp, label, tail byte, prefix string) *node { + nds := n.children[ntyp] + for i := 0; i < len(nds); i++ { + if nds[i].label == label && nds[i].tail == tail { + if ntyp == ntRegexp && nds[i].prefix != prefix { + continue + } + return nds[i] + } + } + return nil +} + +func (n *node) setEndpoint(method methodTyp, handler http.Handler, pattern string) { + // Set the handler for the method type on the node + if n.endpoints == nil { + n.endpoints = make(endpoints) + } + + paramKeys := patParamKeys(pattern) + + if method&mSTUB == mSTUB { + n.endpoints.Value(mSTUB).handler = handler + } + if method&mALL == mALL { + h := n.endpoints.Value(mALL) + h.handler = handler + h.pattern = pattern + h.paramKeys = paramKeys + for _, m := range methodMap { + h := n.endpoints.Value(m) + h.handler = handler + h.pattern = pattern + h.paramKeys = paramKeys + } + } else { + h := n.endpoints.Value(method) + h.handler = handler + h.pattern = pattern + h.paramKeys = paramKeys + } +} + +func (n *node) FindRoute(rctx *Context, method methodTyp, path string) (*node, endpoints, http.Handler) { + // Reset the context routing pattern and params + rctx.routePattern = "" + rctx.routeParams.Keys = rctx.routeParams.Keys[:0] + rctx.routeParams.Values = rctx.routeParams.Values[:0] + + // Find the routing handlers for the path + rn := n.findRoute(rctx, method, path) + if rn == nil { + return nil, nil, nil + } + + // Record the routing params in the request lifecycle + rctx.URLParams.Keys = append(rctx.URLParams.Keys, rctx.routeParams.Keys...) + rctx.URLParams.Values = append(rctx.URLParams.Values, rctx.routeParams.Values...) + + // Record the routing pattern in the request lifecycle + if rn.endpoints[method].pattern != "" { + rctx.routePattern = rn.endpoints[method].pattern + rctx.RoutePatterns = append(rctx.RoutePatterns, rctx.routePattern) + } + + return rn, rn.endpoints, rn.endpoints[method].handler +} + +// Recursive edge traversal by checking all nodeTyp groups along the way. +// It's like searching through a multi-dimensional radix trie. +func (n *node) findRoute(rctx *Context, method methodTyp, path string) *node { + nn := n + search := path + + for t, nds := range nn.children { + ntyp := nodeTyp(t) + if len(nds) == 0 { + continue + } + + var xn *node + xsearch := search + + var label byte + if search != "" { + label = search[0] + } + + switch ntyp { + case ntStatic: + xn = nds.findEdge(label) + if xn == nil || !strings.HasPrefix(xsearch, xn.prefix) { + continue + } + xsearch = xsearch[len(xn.prefix):] + + case ntParam, ntRegexp: + // short-circuit and return no matching route for empty param values + if xsearch == "" { + continue + } + + // serially loop through each node grouped by the tail delimiter + for idx := 0; idx < len(nds); idx++ { + xn = nds[idx] + + // label for param nodes is the delimiter byte + p := strings.IndexByte(xsearch, xn.tail) + + if p < 0 { + if xn.tail == '/' { + p = len(xsearch) + } else { + continue + } + } else if ntyp == ntRegexp && p == 0 { + continue + } + + if ntyp == ntRegexp && xn.rex != nil { + if !xn.rex.MatchString(xsearch[:p]) { + continue + } + } else if strings.IndexByte(xsearch[:p], '/') != -1 { + // avoid a match across path segments + continue + } + + prevlen := len(rctx.routeParams.Values) + rctx.routeParams.Values = append(rctx.routeParams.Values, xsearch[:p]) + xsearch = xsearch[p:] + + if len(xsearch) == 0 { + if xn.isLeaf() { + h := xn.endpoints[method] + if h != nil && h.handler != nil { + rctx.routeParams.Keys = append(rctx.routeParams.Keys, h.paramKeys...) + return xn + } + + // flag that the routing context found a route, but not a corresponding + // supported method + rctx.methodNotAllowed = true + } + } + + // recursively find the next node on this branch + fin := xn.findRoute(rctx, method, xsearch) + if fin != nil { + return fin + } + + // not found on this branch, reset vars + rctx.routeParams.Values = rctx.routeParams.Values[:prevlen] + xsearch = search + } + + rctx.routeParams.Values = append(rctx.routeParams.Values, "") + + default: + // catch-all nodes + rctx.routeParams.Values = append(rctx.routeParams.Values, search) + xn = nds[0] + xsearch = "" + } + + if xn == nil { + continue + } + + // did we find it yet? + if len(xsearch) == 0 { + if xn.isLeaf() { + h := xn.endpoints[method] + if h != nil && h.handler != nil { + rctx.routeParams.Keys = append(rctx.routeParams.Keys, h.paramKeys...) + return xn + } + + // flag that the routing context found a route, but not a corresponding + // supported method + rctx.methodNotAllowed = true + } + } + + // recursively find the next node.. + fin := xn.findRoute(rctx, method, xsearch) + if fin != nil { + return fin + } + + // Did not find final handler, let's remove the param here if it was set + if xn.typ > ntStatic { + if len(rctx.routeParams.Values) > 0 { + rctx.routeParams.Values = rctx.routeParams.Values[:len(rctx.routeParams.Values)-1] + } + } + + } + + return nil +} + +func (n *node) findEdge(ntyp nodeTyp, label byte) *node { + nds := n.children[ntyp] + num := len(nds) + idx := 0 + + switch ntyp { + case ntStatic, ntParam, ntRegexp: + i, j := 0, num-1 + for i <= j { + idx = i + (j-i)/2 + if label > nds[idx].label { + i = idx + 1 + } else if label < nds[idx].label { + j = idx - 1 + } else { + i = num // breaks cond + } + } + if nds[idx].label != label { + return nil + } + return nds[idx] + + default: // catch all + return nds[idx] + } +} + +func (n *node) isLeaf() bool { + return n.endpoints != nil +} + +func (n *node) findPattern(pattern string) bool { + nn := n + for _, nds := range nn.children { + if len(nds) == 0 { + continue + } + + n = nn.findEdge(nds[0].typ, pattern[0]) + if n == nil { + continue + } + + var idx int + var xpattern string + + switch n.typ { + case ntStatic: + idx = longestPrefix(pattern, n.prefix) + if idx < len(n.prefix) { + continue + } + + case ntParam, ntRegexp: + idx = strings.IndexByte(pattern, '}') + 1 + + case ntCatchAll: + idx = longestPrefix(pattern, "*") + + default: + panic("chi: unknown node type") + } + + xpattern = pattern[idx:] + if len(xpattern) == 0 { + return true + } + + return n.findPattern(xpattern) + } + return false +} + +func (n *node) routes() []Route { + rts := []Route{} + + n.walk(func(eps endpoints, subroutes Routes) bool { + if eps[mSTUB] != nil && eps[mSTUB].handler != nil && subroutes == nil { + return false + } + + // Group methodHandlers by unique patterns + pats := make(map[string]endpoints) + + for mt, h := range eps { + if h.pattern == "" { + continue + } + p, ok := pats[h.pattern] + if !ok { + p = endpoints{} + pats[h.pattern] = p + } + p[mt] = h + } + + for p, mh := range pats { + hs := make(map[string]http.Handler) + if mh[mALL] != nil && mh[mALL].handler != nil { + hs["*"] = mh[mALL].handler + } + + for mt, h := range mh { + if h.handler == nil { + continue + } + m := methodTypString(mt) + if m == "" { + continue + } + hs[m] = h.handler + } + + rt := Route{p, hs, subroutes} + rts = append(rts, rt) + } + + return false + }) + + return rts +} + +func (n *node) walk(fn func(eps endpoints, subroutes Routes) bool) bool { + // Visit the leaf values if any + if (n.endpoints != nil || n.subroutes != nil) && fn(n.endpoints, n.subroutes) { + return true + } + + // Recurse on the children + for _, ns := range n.children { + for _, cn := range ns { + if cn.walk(fn) { + return true + } + } + } + return false +} + +// patNextSegment returns the next segment details from a pattern: +// node type, param key, regexp string, param tail byte, param starting index, param ending index +func patNextSegment(pattern string) (nodeTyp, string, string, byte, int, int) { + ps := strings.Index(pattern, "{") + ws := strings.Index(pattern, "*") + + if ps < 0 && ws < 0 { + return ntStatic, "", "", 0, 0, len(pattern) // we return the entire thing + } + + // Sanity check + if ps >= 0 && ws >= 0 && ws < ps { + panic("chi: wildcard '*' must be the last pattern in a route, otherwise use a '{param}'") + } + + var tail byte = '/' // Default endpoint tail to / byte + + if ps >= 0 { + // Param/Regexp pattern is next + nt := ntParam + + // Read to closing } taking into account opens and closes in curl count (cc) + cc := 0 + pe := ps + for i, c := range pattern[ps:] { + if c == '{' { + cc++ + } else if c == '}' { + cc-- + if cc == 0 { + pe = ps + i + break + } + } + } + if pe == ps { + panic("chi: route param closing delimiter '}' is missing") + } + + key := pattern[ps+1 : pe] + pe++ // set end to next position + + if pe < len(pattern) { + tail = pattern[pe] + } + + var rexpat string + if idx := strings.Index(key, ":"); idx >= 0 { + nt = ntRegexp + rexpat = key[idx+1:] + key = key[:idx] + } + + if len(rexpat) > 0 { + if rexpat[0] != '^' { + rexpat = "^" + rexpat + } + if rexpat[len(rexpat)-1] != '$' { + rexpat += "$" + } + } + + return nt, key, rexpat, tail, ps, pe + } + + // Wildcard pattern as finale + if ws < len(pattern)-1 { + panic("chi: wildcard '*' must be the last value in a route. trim trailing text or use a '{param}' instead") + } + return ntCatchAll, "*", "", 0, ws, len(pattern) +} + +func patParamKeys(pattern string) []string { + pat := pattern + paramKeys := []string{} + for { + ptyp, paramKey, _, _, _, e := patNextSegment(pat) + if ptyp == ntStatic { + return paramKeys + } + for i := 0; i < len(paramKeys); i++ { + if paramKeys[i] == paramKey { + panic(fmt.Sprintf("chi: routing pattern '%s' contains duplicate param key, '%s'", pattern, paramKey)) + } + } + paramKeys = append(paramKeys, paramKey) + pat = pat[e:] + } +} + +// longestPrefix finds the length of the shared prefix +// of two strings +func longestPrefix(k1, k2 string) int { + max := len(k1) + if l := len(k2); l < max { + max = l + } + var i int + for i = 0; i < max; i++ { + if k1[i] != k2[i] { + break + } + } + return i +} + +func methodTypString(method methodTyp) string { + for s, t := range methodMap { + if method == t { + return s + } + } + return "" +} + +type nodes []*node + +// Sort the list of nodes by label +func (ns nodes) Sort() { sort.Sort(ns); ns.tailSort() } +func (ns nodes) Len() int { return len(ns) } +func (ns nodes) Swap(i, j int) { ns[i], ns[j] = ns[j], ns[i] } +func (ns nodes) Less(i, j int) bool { return ns[i].label < ns[j].label } + +// tailSort pushes nodes with '/' as the tail to the end of the list for param nodes. +// The list order determines the traversal order. +func (ns nodes) tailSort() { + for i := len(ns) - 1; i >= 0; i-- { + if ns[i].typ > ntStatic && ns[i].tail == '/' { + ns.Swap(i, len(ns)-1) + return + } + } +} + +func (ns nodes) findEdge(label byte) *node { + num := len(ns) + idx := 0 + i, j := 0, num-1 + for i <= j { + idx = i + (j-i)/2 + if label > ns[idx].label { + i = idx + 1 + } else if label < ns[idx].label { + j = idx - 1 + } else { + i = num // breaks cond + } + } + if ns[idx].label != label { + return nil + } + return ns[idx] +} + +// Route describes the details of a routing handler. +// Handlers map key is an HTTP method +type Route struct { + Pattern string + Handlers map[string]http.Handler + SubRoutes Routes +} + +// WalkFunc is the type of the function called for each method and route visited by Walk. +type WalkFunc func(method string, route string, handler http.Handler, middlewares ...func(http.Handler) http.Handler) error + +// Walk walks any router tree that implements Routes interface. +func Walk(r Routes, walkFn WalkFunc) error { + return walk(r, walkFn, "") +} + +func walk(r Routes, walkFn WalkFunc, parentRoute string, parentMw ...func(http.Handler) http.Handler) error { + for _, route := range r.Routes() { + mws := make([]func(http.Handler) http.Handler, len(parentMw)) + copy(mws, parentMw) + mws = append(mws, r.Middlewares()...) + + if route.SubRoutes != nil { + if err := walk(route.SubRoutes, walkFn, parentRoute+route.Pattern, mws...); err != nil { + return err + } + continue + } + + for method, handler := range route.Handlers { + if method == "*" { + // Ignore a "catchAll" method, since we pass down all the specific methods for each route. + continue + } + + fullRoute := parentRoute + route.Pattern + fullRoute = strings.Replace(fullRoute, "/*/", "/", -1) + + if chain, ok := handler.(*ChainHandler); ok { + if err := walkFn(method, fullRoute, chain.Endpoint, append(mws, chain.Middlewares...)...); err != nil { + return err + } + } else { + if err := walkFn(method, fullRoute, handler, mws...); err != nil { + return err + } + } + } + } + + return nil +} diff --git a/vendor/github.com/go-chi/cors/LICENSE b/vendor/github.com/go-chi/cors/LICENSE new file mode 100644 index 0000000..aee6182 --- /dev/null +++ b/vendor/github.com/go-chi/cors/LICENSE @@ -0,0 +1,21 @@ +Copyright (c) 2014 Olivier Poitrey +Copyright (c) 2016-Present https://github.com/go-chi authors + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/go-chi/cors/README.md b/vendor/github.com/go-chi/cors/README.md new file mode 100644 index 0000000..b41686b --- /dev/null +++ b/vendor/github.com/go-chi/cors/README.md @@ -0,0 +1,39 @@ +# CORS net/http middleware + +[go-chi/cors](https://github.com/go-chi/cors) is a fork of [github.com/rs/cors](https://github.com/rs/cors) that +provides a `net/http` compatible middleware for performing preflight CORS checks on the server side. These headers +are required for using the browser native [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API). + +This middleware is designed to be used as a top-level middleware on the [chi](https://github.com/go-chi/chi) router. +Applying with within a `r.Group()` or using `With()` will not work without routes matching `OPTIONS` added. + +## Usage + +```go +func main() { + r := chi.NewRouter() + + // Basic CORS + // for more ideas, see: https://developer.github.com/v3/#cross-origin-resource-sharing + r.Use(cors.Handler(cors.Options{ + // AllowedOrigins: []string{"https://foo.com"}, // Use this to allow specific origin hosts + AllowedOrigins: []string{"https://*", "http://*"}, + // AllowOriginFunc: func(r *http.Request, origin string) bool { return true }, + AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"}, + AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token"}, + ExposedHeaders: []string{"Link"}, + AllowCredentials: false, + MaxAge: 300, // Maximum value not ignored by any of major browsers + })) + + r.Get("/", func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("welcome")) + }) + + http.ListenAndServe(":3000", r) +} +``` + +## Credits + +All credit for the original work of this middleware goes out to [github.com/rs](github.com/rs). diff --git a/vendor/github.com/go-chi/cors/cors.go b/vendor/github.com/go-chi/cors/cors.go new file mode 100644 index 0000000..8df8163 --- /dev/null +++ b/vendor/github.com/go-chi/cors/cors.go @@ -0,0 +1,400 @@ +// cors package is net/http handler to handle CORS related requests +// as defined by http://www.w3.org/TR/cors/ +// +// You can configure it by passing an option struct to cors.New: +// +// c := cors.New(cors.Options{ +// AllowedOrigins: []string{"foo.com"}, +// AllowedMethods: []string{"GET", "POST", "DELETE"}, +// AllowCredentials: true, +// }) +// +// Then insert the handler in the chain: +// +// handler = c.Handler(handler) +// +// See Options documentation for more options. +// +// The resulting handler is a standard net/http handler. +package cors + +import ( + "log" + "net/http" + "os" + "strconv" + "strings" +) + +// Options is a configuration container to setup the CORS middleware. +type Options struct { + // AllowedOrigins is a list of origins a cross-domain request can be executed from. + // If the special "*" value is present in the list, all origins will be allowed. + // An origin may contain a wildcard (*) to replace 0 or more characters + // (i.e.: http://*.domain.com). Usage of wildcards implies a small performance penalty. + // Only one wildcard can be used per origin. + // Default value is ["*"] + AllowedOrigins []string + + // AllowOriginFunc is a custom function to validate the origin. It takes the origin + // as argument and returns true if allowed or false otherwise. If this option is + // set, the content of AllowedOrigins is ignored. + AllowOriginFunc func(r *http.Request, origin string) bool + + // AllowedMethods is a list of methods the client is allowed to use with + // cross-domain requests. Default value is simple methods (HEAD, GET and POST). + AllowedMethods []string + + // AllowedHeaders is list of non simple headers the client is allowed to use with + // cross-domain requests. + // If the special "*" value is present in the list, all headers will be allowed. + // Default value is [] but "Origin" is always appended to the list. + AllowedHeaders []string + + // ExposedHeaders indicates which headers are safe to expose to the API of a CORS + // API specification + ExposedHeaders []string + + // AllowCredentials indicates whether the request can include user credentials like + // cookies, HTTP authentication or client side SSL certificates. + AllowCredentials bool + + // MaxAge indicates how long (in seconds) the results of a preflight request + // can be cached + MaxAge int + + // OptionsPassthrough instructs preflight to let other potential next handlers to + // process the OPTIONS method. Turn this on if your application handles OPTIONS. + OptionsPassthrough bool + + // Debugging flag adds additional output to debug server side CORS issues + Debug bool +} + +// Logger generic interface for logger +type Logger interface { + Printf(string, ...interface{}) +} + +// Cors http handler +type Cors struct { + // Debug logger + Log Logger + + // Normalized list of plain allowed origins + allowedOrigins []string + + // List of allowed origins containing wildcards + allowedWOrigins []wildcard + + // Optional origin validator function + allowOriginFunc func(r *http.Request, origin string) bool + + // Normalized list of allowed headers + allowedHeaders []string + + // Normalized list of allowed methods + allowedMethods []string + + // Normalized list of exposed headers + exposedHeaders []string + maxAge int + + // Set to true when allowed origins contains a "*" + allowedOriginsAll bool + + // Set to true when allowed headers contains a "*" + allowedHeadersAll bool + + allowCredentials bool + optionPassthrough bool +} + +// New creates a new Cors handler with the provided options. +func New(options Options) *Cors { + c := &Cors{ + exposedHeaders: convert(options.ExposedHeaders, http.CanonicalHeaderKey), + allowOriginFunc: options.AllowOriginFunc, + allowCredentials: options.AllowCredentials, + maxAge: options.MaxAge, + optionPassthrough: options.OptionsPassthrough, + } + if options.Debug && c.Log == nil { + c.Log = log.New(os.Stdout, "[cors] ", log.LstdFlags) + } + + // Normalize options + // Note: for origins and methods matching, the spec requires a case-sensitive matching. + // As it may error prone, we chose to ignore the spec here. + + // Allowed Origins + if len(options.AllowedOrigins) == 0 { + if options.AllowOriginFunc == nil { + // Default is all origins + c.allowedOriginsAll = true + } + } else { + c.allowedOrigins = []string{} + c.allowedWOrigins = []wildcard{} + for _, origin := range options.AllowedOrigins { + // Normalize + origin = strings.ToLower(origin) + if origin == "*" { + // If "*" is present in the list, turn the whole list into a match all + c.allowedOriginsAll = true + c.allowedOrigins = nil + c.allowedWOrigins = nil + break + } else if i := strings.IndexByte(origin, '*'); i >= 0 { + // Split the origin in two: start and end string without the * + w := wildcard{origin[0:i], origin[i+1:]} + c.allowedWOrigins = append(c.allowedWOrigins, w) + } else { + c.allowedOrigins = append(c.allowedOrigins, origin) + } + } + } + + // Allowed Headers + if len(options.AllowedHeaders) == 0 { + // Use sensible defaults + c.allowedHeaders = []string{"Origin", "Accept", "Content-Type"} + } else { + // Origin is always appended as some browsers will always request for this header at preflight + c.allowedHeaders = convert(append(options.AllowedHeaders, "Origin"), http.CanonicalHeaderKey) + for _, h := range options.AllowedHeaders { + if h == "*" { + c.allowedHeadersAll = true + c.allowedHeaders = nil + break + } + } + } + + // Allowed Methods + if len(options.AllowedMethods) == 0 { + // Default is spec's "simple" methods + c.allowedMethods = []string{http.MethodGet, http.MethodPost, http.MethodHead} + } else { + c.allowedMethods = convert(options.AllowedMethods, strings.ToUpper) + } + + return c +} + +// Handler creates a new Cors handler with passed options. +func Handler(options Options) func(next http.Handler) http.Handler { + c := New(options) + return c.Handler +} + +// AllowAll create a new Cors handler with permissive configuration allowing all +// origins with all standard methods with any header and credentials. +func AllowAll() *Cors { + return New(Options{ + AllowedOrigins: []string{"*"}, + AllowedMethods: []string{ + http.MethodHead, + http.MethodGet, + http.MethodPost, + http.MethodPut, + http.MethodPatch, + http.MethodDelete, + }, + AllowedHeaders: []string{"*"}, + AllowCredentials: false, + }) +} + +// Handler apply the CORS specification on the request, and add relevant CORS headers +// as necessary. +func (c *Cors) Handler(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method == http.MethodOptions && r.Header.Get("Access-Control-Request-Method") != "" { + c.logf("Handler: Preflight request") + c.handlePreflight(w, r) + // Preflight requests are standalone and should stop the chain as some other + // middleware may not handle OPTIONS requests correctly. One typical example + // is authentication middleware ; OPTIONS requests won't carry authentication + // headers (see #1) + if c.optionPassthrough { + next.ServeHTTP(w, r) + } else { + w.WriteHeader(http.StatusOK) + } + } else { + c.logf("Handler: Actual request") + c.handleActualRequest(w, r) + next.ServeHTTP(w, r) + } + }) +} + +// handlePreflight handles pre-flight CORS requests +func (c *Cors) handlePreflight(w http.ResponseWriter, r *http.Request) { + headers := w.Header() + origin := r.Header.Get("Origin") + + if r.Method != http.MethodOptions { + c.logf("Preflight aborted: %s!=OPTIONS", r.Method) + return + } + // Always set Vary headers + // see https://github.com/rs/cors/issues/10, + // https://github.com/rs/cors/commit/dbdca4d95feaa7511a46e6f1efb3b3aa505bc43f#commitcomment-12352001 + headers.Add("Vary", "Origin") + headers.Add("Vary", "Access-Control-Request-Method") + headers.Add("Vary", "Access-Control-Request-Headers") + + if origin == "" { + c.logf("Preflight aborted: empty origin") + return + } + if !c.isOriginAllowed(r, origin) { + c.logf("Preflight aborted: origin '%s' not allowed", origin) + return + } + + reqMethod := r.Header.Get("Access-Control-Request-Method") + if !c.isMethodAllowed(reqMethod) { + c.logf("Preflight aborted: method '%s' not allowed", reqMethod) + return + } + reqHeaders := parseHeaderList(r.Header.Get("Access-Control-Request-Headers")) + if !c.areHeadersAllowed(reqHeaders) { + c.logf("Preflight aborted: headers '%v' not allowed", reqHeaders) + return + } + if c.allowedOriginsAll { + headers.Set("Access-Control-Allow-Origin", "*") + } else { + headers.Set("Access-Control-Allow-Origin", origin) + } + // Spec says: Since the list of methods can be unbounded, simply returning the method indicated + // by Access-Control-Request-Method (if supported) can be enough + headers.Set("Access-Control-Allow-Methods", strings.ToUpper(reqMethod)) + if len(reqHeaders) > 0 { + + // Spec says: Since the list of headers can be unbounded, simply returning supported headers + // from Access-Control-Request-Headers can be enough + headers.Set("Access-Control-Allow-Headers", strings.Join(reqHeaders, ", ")) + } + if c.allowCredentials { + headers.Set("Access-Control-Allow-Credentials", "true") + } + if c.maxAge > 0 { + headers.Set("Access-Control-Max-Age", strconv.Itoa(c.maxAge)) + } + c.logf("Preflight response headers: %v", headers) +} + +// handleActualRequest handles simple cross-origin requests, actual request or redirects +func (c *Cors) handleActualRequest(w http.ResponseWriter, r *http.Request) { + headers := w.Header() + origin := r.Header.Get("Origin") + + // Always set Vary, see https://github.com/rs/cors/issues/10 + headers.Add("Vary", "Origin") + if origin == "" { + c.logf("Actual request no headers added: missing origin") + return + } + if !c.isOriginAllowed(r, origin) { + c.logf("Actual request no headers added: origin '%s' not allowed", origin) + return + } + + // Note that spec does define a way to specifically disallow a simple method like GET or + // POST. Access-Control-Allow-Methods is only used for pre-flight requests and the + // spec doesn't instruct to check the allowed methods for simple cross-origin requests. + // We think it's a nice feature to be able to have control on those methods though. + if !c.isMethodAllowed(r.Method) { + c.logf("Actual request no headers added: method '%s' not allowed", r.Method) + + return + } + if c.allowedOriginsAll { + headers.Set("Access-Control-Allow-Origin", "*") + } else { + headers.Set("Access-Control-Allow-Origin", origin) + } + if len(c.exposedHeaders) > 0 { + headers.Set("Access-Control-Expose-Headers", strings.Join(c.exposedHeaders, ", ")) + } + if c.allowCredentials { + headers.Set("Access-Control-Allow-Credentials", "true") + } + c.logf("Actual response added headers: %v", headers) +} + +// convenience method. checks if a logger is set. +func (c *Cors) logf(format string, a ...interface{}) { + if c.Log != nil { + c.Log.Printf(format, a...) + } +} + +// isOriginAllowed checks if a given origin is allowed to perform cross-domain requests +// on the endpoint +func (c *Cors) isOriginAllowed(r *http.Request, origin string) bool { + if c.allowOriginFunc != nil { + return c.allowOriginFunc(r, origin) + } + if c.allowedOriginsAll { + return true + } + origin = strings.ToLower(origin) + for _, o := range c.allowedOrigins { + if o == origin { + return true + } + } + for _, w := range c.allowedWOrigins { + if w.match(origin) { + return true + } + } + return false +} + +// isMethodAllowed checks if a given method can be used as part of a cross-domain request +// on the endpoint +func (c *Cors) isMethodAllowed(method string) bool { + if len(c.allowedMethods) == 0 { + // If no method allowed, always return false, even for preflight request + return false + } + method = strings.ToUpper(method) + if method == http.MethodOptions { + // Always allow preflight requests + return true + } + for _, m := range c.allowedMethods { + if m == method { + return true + } + } + return false +} + +// areHeadersAllowed checks if a given list of headers are allowed to used within +// a cross-domain request. +func (c *Cors) areHeadersAllowed(requestedHeaders []string) bool { + if c.allowedHeadersAll || len(requestedHeaders) == 0 { + return true + } + for _, header := range requestedHeaders { + header = http.CanonicalHeaderKey(header) + found := false + for _, h := range c.allowedHeaders { + if h == header { + found = true + break + } + } + if !found { + return false + } + } + return true +} diff --git a/vendor/github.com/go-chi/cors/go.mod b/vendor/github.com/go-chi/cors/go.mod new file mode 100644 index 0000000..26ddfc1 --- /dev/null +++ b/vendor/github.com/go-chi/cors/go.mod @@ -0,0 +1,3 @@ +module github.com/go-chi/cors + +go 1.14 diff --git a/vendor/github.com/go-chi/cors/utils.go b/vendor/github.com/go-chi/cors/utils.go new file mode 100644 index 0000000..cd24831 --- /dev/null +++ b/vendor/github.com/go-chi/cors/utils.go @@ -0,0 +1,70 @@ +package cors + +import "strings" + +const toLower = 'a' - 'A' + +type converter func(string) string + +type wildcard struct { + prefix string + suffix string +} + +func (w wildcard) match(s string) bool { + return len(s) >= len(w.prefix+w.suffix) && strings.HasPrefix(s, w.prefix) && strings.HasSuffix(s, w.suffix) +} + +// convert converts a list of string using the passed converter function +func convert(s []string, c converter) []string { + out := []string{} + for _, i := range s { + out = append(out, c(i)) + } + return out +} + +// parseHeaderList tokenize + normalize a string containing a list of headers +func parseHeaderList(headerList string) []string { + l := len(headerList) + h := make([]byte, 0, l) + upper := true + // Estimate the number headers in order to allocate the right splice size + t := 0 + for i := 0; i < l; i++ { + if headerList[i] == ',' { + t++ + } + } + headers := make([]string, 0, t) + for i := 0; i < l; i++ { + b := headerList[i] + if b >= 'a' && b <= 'z' { + if upper { + h = append(h, b-toLower) + } else { + h = append(h, b) + } + } else if b >= 'A' && b <= 'Z' { + if !upper { + h = append(h, b+toLower) + } else { + h = append(h, b) + } + } else if b == '-' || (b >= '0' && b <= '9') { + h = append(h, b) + } + + if b == ' ' || b == ',' || i == l-1 { + if len(h) > 0 { + // Flush the found header + headers = append(headers, string(h)) + h = h[:0] + upper = true + } + } else { + upper = b == '-' + } + } + return headers +} diff --git a/vendor/github.com/go-chi/render/.travis.yml b/vendor/github.com/go-chi/render/.travis.yml new file mode 100644 index 0000000..a026204 --- /dev/null +++ b/vendor/github.com/go-chi/render/.travis.yml @@ -0,0 +1,15 @@ +language: go + +go: + - 1.7.x + - 1.8.x + - tip + +install: + - go get -u golang.org/x/tools/cmd/goimports + +script: + - go get -d -t ./... + - go test ./... + - > + goimports -d -e ./ | grep '.*' && { echo; echo "Aborting due to non-empty goimports output."; exit 1; } || : diff --git a/vendor/github.com/go-chi/render/LICENSE b/vendor/github.com/go-chi/render/LICENSE new file mode 100644 index 0000000..4344db7 --- /dev/null +++ b/vendor/github.com/go-chi/render/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2016-Present https://github.com/go-chi authors + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/go-chi/render/README.md b/vendor/github.com/go-chi/render/README.md new file mode 100644 index 0000000..068e0bf --- /dev/null +++ b/vendor/github.com/go-chi/render/README.md @@ -0,0 +1,24 @@ +# render + +The `render` package helps manage HTTP request / response payloads. + +Every well-designed, robust and maintainable Web Service / REST API also needs +well-*defined* request and response payloads. Together with the endpoint handlers, +the request and response payloads make up the contract between your server and the +clients calling on it. + +Typically in a REST API application, you will have your data models (objects/structs) +that hold lower-level runtime application state, and at times you need to assemble, +decorate, hide or transform the representation before responding to a client. That +server output (response payload) structure, is also likely the input structure to +another handler on the server. + +This is where `render` comes in - offering a few simple helpers and interfaces to +provide a simple pattern for managing payload encoding and decoding. + +We've also combined it with some helpers for responding to content types and parsing +request bodies. Please have a look at the [rest](https://github.com/go-chi/chi/blob/master/_examples/rest/main.go) +example which uses the latest chi/render sub-pkg. + +All feedback is welcome, thank you! + diff --git a/vendor/github.com/go-chi/render/content_type.go b/vendor/github.com/go-chi/render/content_type.go new file mode 100644 index 0000000..f2bbb42 --- /dev/null +++ b/vendor/github.com/go-chi/render/content_type.go @@ -0,0 +1,84 @@ +package render + +import ( + "context" + "net/http" + "strings" +) + +var ( + ContentTypeCtxKey = &contextKey{"ContentType"} +) + +// ContentType is an enumeration of common HTTP content types. +type ContentType int + +// ContentTypes handled by this package. +const ( + ContentTypeUnknown = iota + ContentTypePlainText + ContentTypeHTML + ContentTypeJSON + ContentTypeXML + ContentTypeForm + ContentTypeEventStream +) + +func GetContentType(s string) ContentType { + s = strings.TrimSpace(strings.Split(s, ";")[0]) + switch s { + case "text/plain": + return ContentTypePlainText + case "text/html", "application/xhtml+xml": + return ContentTypeHTML + case "application/json", "text/javascript": + return ContentTypeJSON + case "text/xml", "application/xml": + return ContentTypeXML + case "application/x-www-form-urlencoded": + return ContentTypeForm + case "text/event-stream": + return ContentTypeEventStream + default: + return ContentTypeUnknown + } +} + +// SetContentType is a middleware that forces response Content-Type. +func SetContentType(contentType ContentType) func(next http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + fn := func(w http.ResponseWriter, r *http.Request) { + r = r.WithContext(context.WithValue(r.Context(), ContentTypeCtxKey, contentType)) + next.ServeHTTP(w, r) + } + return http.HandlerFunc(fn) + } +} + +// GetRequestContentType is a helper function that returns ContentType based on +// context or request headers. +func GetRequestContentType(r *http.Request) ContentType { + if contentType, ok := r.Context().Value(ContentTypeCtxKey).(ContentType); ok { + return contentType + } + return GetContentType(r.Header.Get("Content-Type")) +} + +func GetAcceptedContentType(r *http.Request) ContentType { + if contentType, ok := r.Context().Value(ContentTypeCtxKey).(ContentType); ok { + return contentType + } + + var contentType ContentType + + // Parse request Accept header. + fields := strings.Split(r.Header.Get("Accept"), ",") + if len(fields) > 0 { + contentType = GetContentType(strings.TrimSpace(fields[0])) + } + + if contentType == ContentTypeUnknown { + contentType = ContentTypePlainText + } + return contentType +} diff --git a/vendor/github.com/go-chi/render/decoder.go b/vendor/github.com/go-chi/render/decoder.go new file mode 100644 index 0000000..849c56b --- /dev/null +++ b/vendor/github.com/go-chi/render/decoder.go @@ -0,0 +1,44 @@ +package render + +import ( + "encoding/json" + "encoding/xml" + "errors" + "io" + "io/ioutil" + "net/http" +) + +// Decode is a package-level variable set to our default Decoder. We do this +// because it allows you to set render.Decode to another function with the +// same function signature, while also utilizing the render.Decoder() function +// itself. Effectively, allowing you to easily add your own logic to the package +// defaults. For example, maybe you want to impose a limit on the number of +// bytes allowed to be read from the request body. +var Decode = DefaultDecoder + +func DefaultDecoder(r *http.Request, v interface{}) error { + var err error + + switch GetRequestContentType(r) { + case ContentTypeJSON: + err = DecodeJSON(r.Body, v) + case ContentTypeXML: + err = DecodeXML(r.Body, v) + // case ContentTypeForm: // TODO + default: + err = errors.New("render: unable to automatically decode the request content type") + } + + return err +} + +func DecodeJSON(r io.Reader, v interface{}) error { + defer io.Copy(ioutil.Discard, r) + return json.NewDecoder(r).Decode(v) +} + +func DecodeXML(r io.Reader, v interface{}) error { + defer io.Copy(ioutil.Discard, r) + return xml.NewDecoder(r).Decode(v) +} diff --git a/vendor/github.com/go-chi/render/render.go b/vendor/github.com/go-chi/render/render.go new file mode 100644 index 0000000..75a90e2 --- /dev/null +++ b/vendor/github.com/go-chi/render/render.go @@ -0,0 +1,143 @@ +package render + +import ( + "net/http" + "reflect" +) + +// Renderer interface for managing response payloads. +type Renderer interface { + Render(w http.ResponseWriter, r *http.Request) error +} + +// Binder interface for managing request payloads. +type Binder interface { + Bind(r *http.Request) error +} + +// Bind decodes a request body and executes the Binder method of the +// payload structure. +func Bind(r *http.Request, v Binder) error { + if err := Decode(r, v); err != nil { + return err + } + return binder(r, v) +} + +// Render renders a single payload and respond to the client request. +func Render(w http.ResponseWriter, r *http.Request, v Renderer) error { + if err := renderer(w, r, v); err != nil { + return err + } + Respond(w, r, v) + return nil +} + +// RenderList renders a slice of payloads and responds to the client request. +func RenderList(w http.ResponseWriter, r *http.Request, l []Renderer) error { + for _, v := range l { + if err := renderer(w, r, v); err != nil { + return err + } + } + Respond(w, r, l) + return nil +} + +func isNil(f reflect.Value) bool { + switch f.Kind() { + case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: + return f.IsNil() + default: + return false + } +} + +// Executed top-down +func renderer(w http.ResponseWriter, r *http.Request, v Renderer) error { + rv := reflect.ValueOf(v) + if rv.Kind() == reflect.Ptr { + rv = rv.Elem() + } + + // We call it top-down. + if err := v.Render(w, r); err != nil { + return err + } + + // We're done if the Renderer isn't a struct object + if rv.Kind() != reflect.Struct { + return nil + } + + // For structs, we call Render on each field that implements Renderer + for i := 0; i < rv.NumField(); i++ { + f := rv.Field(i) + if f.Type().Implements(rendererType) { + + if isNil(f) { + continue + } + + fv := f.Interface().(Renderer) + if err := renderer(w, r, fv); err != nil { + return err + } + + } + } + + return nil +} + +// Executed bottom-up +func binder(r *http.Request, v Binder) error { + rv := reflect.ValueOf(v) + if rv.Kind() == reflect.Ptr { + rv = rv.Elem() + } + + // Call Binder on non-struct types right away + if rv.Kind() != reflect.Struct { + return v.Bind(r) + } + + // For structs, we call Bind on each field that implements Binder + for i := 0; i < rv.NumField(); i++ { + f := rv.Field(i) + if f.Type().Implements(binderType) { + + if isNil(f) { + continue + } + + fv := f.Interface().(Binder) + if err := binder(r, fv); err != nil { + return err + } + } + } + + // We call it bottom-up + if err := v.Bind(r); err != nil { + return err + } + + return nil +} + +var ( + rendererType = reflect.TypeOf(new(Renderer)).Elem() + binderType = reflect.TypeOf(new(Binder)).Elem() +) + +// contextKey is a value for use with context.WithValue. It's used as +// a pointer so it fits in an interface{} without allocation. This technique +// for defining context keys was copied from Go 1.7's new use of context in net/http. +type contextKey struct { + name string +} + +func (k *contextKey) String() string { + return "chi render context value " + k.name +} diff --git a/vendor/github.com/go-chi/render/responder.go b/vendor/github.com/go-chi/render/responder.go new file mode 100644 index 0000000..9365350 --- /dev/null +++ b/vendor/github.com/go-chi/render/responder.go @@ -0,0 +1,234 @@ +package render + +import ( + "bytes" + "context" + "encoding/json" + "encoding/xml" + "fmt" + "net/http" + "reflect" +) + +// M is a convenience alias for quickly building a map structure that is going +// out to a responder. Just a short-hand. +type M map[string]interface{} + +// Respond is a package-level variable set to our default Responder. We do this +// because it allows you to set render.Respond to another function with the +// same function signature, while also utilizing the render.Responder() function +// itself. Effectively, allowing you to easily add your own logic to the package +// defaults. For example, maybe you want to test if v is an error and respond +// differently, or log something before you respond. +var Respond = DefaultResponder + +// StatusCtxKey is a context key to record a future HTTP response status code. +var StatusCtxKey = &contextKey{"Status"} + +// Status sets a HTTP response status code hint into request context at any point +// during the request life-cycle. Before the Responder sends its response header +// it will check the StatusCtxKey +func Status(r *http.Request, status int) { + *r = *r.WithContext(context.WithValue(r.Context(), StatusCtxKey, status)) +} + +// Respond handles streaming JSON and XML responses, automatically setting the +// Content-Type based on request headers. It will default to a JSON response. +func DefaultResponder(w http.ResponseWriter, r *http.Request, v interface{}) { + if v != nil { + switch reflect.TypeOf(v).Kind() { + case reflect.Chan: + switch GetAcceptedContentType(r) { + case ContentTypeEventStream: + channelEventStream(w, r, v) + return + default: + v = channelIntoSlice(w, r, v) + } + } + } + + // Format response based on request Accept header. + switch GetAcceptedContentType(r) { + case ContentTypeJSON: + JSON(w, r, v) + case ContentTypeXML: + XML(w, r, v) + default: + JSON(w, r, v) + } +} + +// PlainText writes a string to the response, setting the Content-Type as +// text/plain. +func PlainText(w http.ResponseWriter, r *http.Request, v string) { + w.Header().Set("Content-Type", "text/plain; charset=utf-8") + if status, ok := r.Context().Value(StatusCtxKey).(int); ok { + w.WriteHeader(status) + } + w.Write([]byte(v)) +} + +// Data writes raw bytes to the response, setting the Content-Type as +// application/octet-stream. +func Data(w http.ResponseWriter, r *http.Request, v []byte) { + w.Header().Set("Content-Type", "application/octet-stream") + if status, ok := r.Context().Value(StatusCtxKey).(int); ok { + w.WriteHeader(status) + } + w.Write(v) +} + +// HTML writes a string to the response, setting the Content-Type as text/html. +func HTML(w http.ResponseWriter, r *http.Request, v string) { + w.Header().Set("Content-Type", "text/html; charset=utf-8") + if status, ok := r.Context().Value(StatusCtxKey).(int); ok { + w.WriteHeader(status) + } + w.Write([]byte(v)) +} + +// JSON marshals 'v' to JSON, automatically escaping HTML and setting the +// Content-Type as application/json. +func JSON(w http.ResponseWriter, r *http.Request, v interface{}) { + buf := &bytes.Buffer{} + enc := json.NewEncoder(buf) + enc.SetEscapeHTML(true) + if err := enc.Encode(v); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + w.Header().Set("Content-Type", "application/json; charset=utf-8") + if status, ok := r.Context().Value(StatusCtxKey).(int); ok { + w.WriteHeader(status) + } + w.Write(buf.Bytes()) +} + +// XML marshals 'v' to JSON, setting the Content-Type as application/xml. It +// will automatically prepend a generic XML header (see encoding/xml.Header) if +// one is not found in the first 100 bytes of 'v'. +func XML(w http.ResponseWriter, r *http.Request, v interface{}) { + b, err := xml.Marshal(v) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + w.Header().Set("Content-Type", "application/xml; charset=utf-8") + if status, ok := r.Context().Value(StatusCtxKey).(int); ok { + w.WriteHeader(status) + } + + // Try to find 100 { + findHeaderUntil = 100 + } + if !bytes.Contains(b[:findHeaderUntil], []byte("![Project status](https://img.shields.io/badge/version-0.14.0-green.svg) +[![Build Status](https://travis-ci.org/go-playground/locales.svg?branch=master)](https://travis-ci.org/go-playground/locales) +[![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/locales)](https://goreportcard.com/report/github.com/go-playground/locales) +[![GoDoc](https://godoc.org/github.com/go-playground/locales?status.svg)](https://godoc.org/github.com/go-playground/locales) +![License](https://img.shields.io/dub/l/vibe-d.svg) +[![Gitter](https://badges.gitter.im/go-playground/locales.svg)](https://gitter.im/go-playground/locales?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) + +Locales is a set of locales generated from the [Unicode CLDR Project](http://cldr.unicode.org/) which can be used independently or within +an i18n package; these were built for use with, but not exclusive to, [Universal Translator](https://github.com/go-playground/universal-translator). + +Features +-------- +- [x] Rules generated from the latest [CLDR](http://cldr.unicode.org/index/downloads) data, v36.0.1 +- [x] Contains Cardinal, Ordinal and Range Plural Rules +- [x] Contains Month, Weekday and Timezone translations built in +- [x] Contains Date & Time formatting functions +- [x] Contains Number, Currency, Accounting and Percent formatting functions +- [x] Supports the "Gregorian" calendar only ( my time isn't unlimited, had to draw the line somewhere ) + +Full Tests +-------------------- +I could sure use your help adding tests for every locale, it is a huge undertaking and I just don't have the free time to do it all at the moment; +any help would be **greatly appreciated!!!!** please see [issue](https://github.com/go-playground/locales/issues/1) for details. + +Installation +----------- + +Use go get + +```shell +go get github.com/go-playground/locales +``` + +NOTES +-------- +You'll notice most return types are []byte, this is because most of the time the results will be concatenated with a larger body +of text and can avoid some allocations if already appending to a byte array, otherwise just cast as string. + +Usage +------- +```go +package main + +import ( + "fmt" + "time" + + "github.com/go-playground/locales/currency" + "github.com/go-playground/locales/en_CA" +) + +func main() { + + loc, _ := time.LoadLocation("America/Toronto") + datetime := time.Date(2016, 02, 03, 9, 0, 1, 0, loc) + + l := en_CA.New() + + // Dates + fmt.Println(l.FmtDateFull(datetime)) + fmt.Println(l.FmtDateLong(datetime)) + fmt.Println(l.FmtDateMedium(datetime)) + fmt.Println(l.FmtDateShort(datetime)) + + // Times + fmt.Println(l.FmtTimeFull(datetime)) + fmt.Println(l.FmtTimeLong(datetime)) + fmt.Println(l.FmtTimeMedium(datetime)) + fmt.Println(l.FmtTimeShort(datetime)) + + // Months Wide + fmt.Println(l.MonthWide(time.January)) + fmt.Println(l.MonthWide(time.February)) + fmt.Println(l.MonthWide(time.March)) + // ... + + // Months Abbreviated + fmt.Println(l.MonthAbbreviated(time.January)) + fmt.Println(l.MonthAbbreviated(time.February)) + fmt.Println(l.MonthAbbreviated(time.March)) + // ... + + // Months Narrow + fmt.Println(l.MonthNarrow(time.January)) + fmt.Println(l.MonthNarrow(time.February)) + fmt.Println(l.MonthNarrow(time.March)) + // ... + + // Weekdays Wide + fmt.Println(l.WeekdayWide(time.Sunday)) + fmt.Println(l.WeekdayWide(time.Monday)) + fmt.Println(l.WeekdayWide(time.Tuesday)) + // ... + + // Weekdays Abbreviated + fmt.Println(l.WeekdayAbbreviated(time.Sunday)) + fmt.Println(l.WeekdayAbbreviated(time.Monday)) + fmt.Println(l.WeekdayAbbreviated(time.Tuesday)) + // ... + + // Weekdays Short + fmt.Println(l.WeekdayShort(time.Sunday)) + fmt.Println(l.WeekdayShort(time.Monday)) + fmt.Println(l.WeekdayShort(time.Tuesday)) + // ... + + // Weekdays Narrow + fmt.Println(l.WeekdayNarrow(time.Sunday)) + fmt.Println(l.WeekdayNarrow(time.Monday)) + fmt.Println(l.WeekdayNarrow(time.Tuesday)) + // ... + + var f64 float64 + + f64 = -10356.4523 + + // Number + fmt.Println(l.FmtNumber(f64, 2)) + + // Currency + fmt.Println(l.FmtCurrency(f64, 2, currency.CAD)) + fmt.Println(l.FmtCurrency(f64, 2, currency.USD)) + + // Accounting + fmt.Println(l.FmtAccounting(f64, 2, currency.CAD)) + fmt.Println(l.FmtAccounting(f64, 2, currency.USD)) + + f64 = 78.12 + + // Percent + fmt.Println(l.FmtPercent(f64, 0)) + + // Plural Rules for locale, so you know what rules you must cover + fmt.Println(l.PluralsCardinal()) + fmt.Println(l.PluralsOrdinal()) + + // Cardinal Plural Rules + fmt.Println(l.CardinalPluralRule(1, 0)) + fmt.Println(l.CardinalPluralRule(1.0, 0)) + fmt.Println(l.CardinalPluralRule(1.0, 1)) + fmt.Println(l.CardinalPluralRule(3, 0)) + + // Ordinal Plural Rules + fmt.Println(l.OrdinalPluralRule(21, 0)) // 21st + fmt.Println(l.OrdinalPluralRule(22, 0)) // 22nd + fmt.Println(l.OrdinalPluralRule(33, 0)) // 33rd + fmt.Println(l.OrdinalPluralRule(34, 0)) // 34th + + // Range Plural Rules + fmt.Println(l.RangePluralRule(1, 0, 1, 0)) // 1-1 + fmt.Println(l.RangePluralRule(1, 0, 2, 0)) // 1-2 + fmt.Println(l.RangePluralRule(5, 0, 8, 0)) // 5-8 +} +``` + +NOTES: +------- +These rules were generated from the [Unicode CLDR Project](http://cldr.unicode.org/), if you encounter any issues +I strongly encourage contributing to the CLDR project to get the locale information corrected and the next time +these locales are regenerated the fix will come with. + +I do however realize that time constraints are often important and so there are two options: + +1. Create your own locale, copy, paste and modify, and ensure it complies with the `Translator` interface. +2. Add an exception in the locale generation code directly and once regenerated, fix will be in place. + +Please to not make fixes inside the locale files, they WILL get overwritten when the locales are regenerated. + +License +------ +Distributed under MIT License, please see license file in code for more details. diff --git a/vendor/github.com/go-playground/locales/currency/currency.go b/vendor/github.com/go-playground/locales/currency/currency.go new file mode 100644 index 0000000..b5a95fb --- /dev/null +++ b/vendor/github.com/go-playground/locales/currency/currency.go @@ -0,0 +1,311 @@ +package currency + +// Type is the currency type associated with the locales currency enum +type Type int + +// locale currencies +const ( + ADP Type = iota + AED + AFA + AFN + ALK + ALL + AMD + ANG + AOA + AOK + AON + AOR + ARA + ARL + ARM + ARP + ARS + ATS + AUD + AWG + AZM + AZN + BAD + BAM + BAN + BBD + BDT + BEC + BEF + BEL + BGL + BGM + BGN + BGO + BHD + BIF + BMD + BND + BOB + BOL + BOP + BOV + BRB + BRC + BRE + BRL + BRN + BRR + BRZ + BSD + BTN + BUK + BWP + BYB + BYN + BYR + BZD + CAD + CDF + CHE + CHF + CHW + CLE + CLF + CLP + CNH + CNX + CNY + COP + COU + CRC + CSD + CSK + CUC + CUP + CVE + CYP + CZK + DDM + DEM + DJF + DKK + DOP + DZD + ECS + ECV + EEK + EGP + ERN + ESA + ESB + ESP + ETB + EUR + FIM + FJD + FKP + FRF + GBP + GEK + GEL + GHC + GHS + GIP + GMD + GNF + GNS + GQE + GRD + GTQ + GWE + GWP + GYD + HKD + HNL + HRD + HRK + HTG + HUF + IDR + IEP + ILP + ILR + ILS + INR + IQD + IRR + ISJ + ISK + ITL + JMD + JOD + JPY + KES + KGS + KHR + KMF + KPW + KRH + KRO + KRW + KWD + KYD + KZT + LAK + LBP + LKR + LRD + LSL + LTL + LTT + LUC + LUF + LUL + LVL + LVR + LYD + MAD + MAF + MCF + MDC + MDL + MGA + MGF + MKD + MKN + MLF + MMK + MNT + MOP + MRO + MRU + MTL + MTP + MUR + MVP + MVR + MWK + MXN + MXP + MXV + MYR + MZE + MZM + MZN + NAD + NGN + NIC + NIO + NLG + NOK + NPR + NZD + OMR + PAB + PEI + PEN + PES + PGK + PHP + PKR + PLN + PLZ + PTE + PYG + QAR + RHD + ROL + RON + RSD + RUB + RUR + RWF + SAR + SBD + SCR + SDD + SDG + SDP + SEK + SGD + SHP + SIT + SKK + SLL + SOS + SRD + SRG + SSP + STD + STN + SUR + SVC + SYP + SZL + THB + TJR + TJS + TMM + TMT + TND + TOP + TPE + TRL + TRY + TTD + TWD + TZS + UAH + UAK + UGS + UGX + USD + USN + USS + UYI + UYP + UYU + UYW + UZS + VEB + VEF + VES + VND + VNN + VUV + WST + XAF + XAG + XAU + XBA + XBB + XBC + XBD + XCD + XDR + XEU + XFO + XFU + XOF + XPD + XPF + XPT + XRE + XSU + XTS + XUA + XXX + YDD + YER + YUD + YUM + YUN + YUR + ZAL + ZAR + ZMK + ZMW + ZRN + ZRZ + ZWD + ZWL + ZWR +) diff --git a/vendor/github.com/go-playground/locales/go.mod b/vendor/github.com/go-playground/locales/go.mod new file mode 100644 index 0000000..41b8dc1 --- /dev/null +++ b/vendor/github.com/go-playground/locales/go.mod @@ -0,0 +1,5 @@ +module github.com/go-playground/locales + +go 1.13 + +require golang.org/x/text v0.3.6 diff --git a/vendor/github.com/go-playground/locales/go.sum b/vendor/github.com/go-playground/locales/go.sum new file mode 100644 index 0000000..3c12b4f --- /dev/null +++ b/vendor/github.com/go-playground/locales/go.sum @@ -0,0 +1,3 @@ +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/vendor/github.com/go-playground/locales/logo.png b/vendor/github.com/go-playground/locales/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..3038276e6873076ecd542099e95b25037b1c0c34 GIT binary patch literal 37360 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 z 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 literal 0 HcmV?d00001 diff --git a/vendor/github.com/go-playground/locales/rules.go b/vendor/github.com/go-playground/locales/rules.go new file mode 100644 index 0000000..9202900 --- /dev/null +++ b/vendor/github.com/go-playground/locales/rules.go @@ -0,0 +1,293 @@ +package locales + +import ( + "strconv" + "time" + + "github.com/go-playground/locales/currency" +) + +// // ErrBadNumberValue is returned when the number passed for +// // plural rule determination cannot be parsed +// type ErrBadNumberValue struct { +// NumberValue string +// InnerError error +// } + +// // Error returns ErrBadNumberValue error string +// func (e *ErrBadNumberValue) Error() string { +// return fmt.Sprintf("Invalid Number Value '%s' %s", e.NumberValue, e.InnerError) +// } + +// var _ error = new(ErrBadNumberValue) + +// PluralRule denotes the type of plural rules +type PluralRule int + +// PluralRule's +const ( + PluralRuleUnknown PluralRule = iota + PluralRuleZero // zero + PluralRuleOne // one - singular + PluralRuleTwo // two - dual + PluralRuleFew // few - paucal + PluralRuleMany // many - also used for fractions if they have a separate class + PluralRuleOther // other - required—general plural form—also used if the language only has a single form +) + +const ( + pluralsString = "UnknownZeroOneTwoFewManyOther" +) + +// Translator encapsulates an instance of a locale +// NOTE: some values are returned as a []byte just in case the caller +// wishes to add more and can help avoid allocations; otherwise just cast as string +type Translator interface { + + // The following Functions are for overriding, debugging or developing + // with a Translator Locale + + // Locale returns the string value of the translator + Locale() string + + // returns an array of cardinal plural rules associated + // with this translator + PluralsCardinal() []PluralRule + + // returns an array of ordinal plural rules associated + // with this translator + PluralsOrdinal() []PluralRule + + // returns an array of range plural rules associated + // with this translator + PluralsRange() []PluralRule + + // returns the cardinal PluralRule given 'num' and digits/precision of 'v' for locale + CardinalPluralRule(num float64, v uint64) PluralRule + + // returns the ordinal PluralRule given 'num' and digits/precision of 'v' for locale + OrdinalPluralRule(num float64, v uint64) PluralRule + + // returns the ordinal PluralRule given 'num1', 'num2' and digits/precision of 'v1' and 'v2' for locale + RangePluralRule(num1 float64, v1 uint64, num2 float64, v2 uint64) PluralRule + + // returns the locales abbreviated month given the 'month' provided + MonthAbbreviated(month time.Month) string + + // returns the locales abbreviated months + MonthsAbbreviated() []string + + // returns the locales narrow month given the 'month' provided + MonthNarrow(month time.Month) string + + // returns the locales narrow months + MonthsNarrow() []string + + // returns the locales wide month given the 'month' provided + MonthWide(month time.Month) string + + // returns the locales wide months + MonthsWide() []string + + // returns the locales abbreviated weekday given the 'weekday' provided + WeekdayAbbreviated(weekday time.Weekday) string + + // returns the locales abbreviated weekdays + WeekdaysAbbreviated() []string + + // returns the locales narrow weekday given the 'weekday' provided + WeekdayNarrow(weekday time.Weekday) string + + // WeekdaysNarrowreturns the locales narrow weekdays + WeekdaysNarrow() []string + + // returns the locales short weekday given the 'weekday' provided + WeekdayShort(weekday time.Weekday) string + + // returns the locales short weekdays + WeekdaysShort() []string + + // returns the locales wide weekday given the 'weekday' provided + WeekdayWide(weekday time.Weekday) string + + // returns the locales wide weekdays + WeekdaysWide() []string + + // The following Functions are common Formatting functionsfor the Translator's Locale + + // returns 'num' with digits/precision of 'v' for locale and handles both Whole and Real numbers based on 'v' + FmtNumber(num float64, v uint64) string + + // returns 'num' with digits/precision of 'v' for locale and handles both Whole and Real numbers based on 'v' + // NOTE: 'num' passed into FmtPercent is assumed to be in percent already + FmtPercent(num float64, v uint64) string + + // returns the currency representation of 'num' with digits/precision of 'v' for locale + FmtCurrency(num float64, v uint64, currency currency.Type) string + + // returns the currency representation of 'num' with digits/precision of 'v' for locale + // in accounting notation. + FmtAccounting(num float64, v uint64, currency currency.Type) string + + // returns the short date representation of 't' for locale + FmtDateShort(t time.Time) string + + // returns the medium date representation of 't' for locale + FmtDateMedium(t time.Time) string + + // returns the long date representation of 't' for locale + FmtDateLong(t time.Time) string + + // returns the full date representation of 't' for locale + FmtDateFull(t time.Time) string + + // returns the short time representation of 't' for locale + FmtTimeShort(t time.Time) string + + // returns the medium time representation of 't' for locale + FmtTimeMedium(t time.Time) string + + // returns the long time representation of 't' for locale + FmtTimeLong(t time.Time) string + + // returns the full time representation of 't' for locale + FmtTimeFull(t time.Time) string +} + +// String returns the string value of PluralRule +func (p PluralRule) String() string { + + switch p { + case PluralRuleZero: + return pluralsString[7:11] + case PluralRuleOne: + return pluralsString[11:14] + case PluralRuleTwo: + return pluralsString[14:17] + case PluralRuleFew: + return pluralsString[17:20] + case PluralRuleMany: + return pluralsString[20:24] + case PluralRuleOther: + return pluralsString[24:] + default: + return pluralsString[:7] + } +} + +// +// Precision Notes: +// +// must specify a precision >= 0, and here is why https://play.golang.org/p/LyL90U0Vyh +// +// v := float64(3.141) +// i := float64(int64(v)) +// +// fmt.Println(v - i) +// +// or +// +// s := strconv.FormatFloat(v-i, 'f', -1, 64) +// fmt.Println(s) +// +// these will not print what you'd expect: 0.14100000000000001 +// and so this library requires a precision to be specified, or +// inaccurate plural rules could be applied. +// +// +// +// n - absolute value of the source number (integer and decimals). +// i - integer digits of n. +// v - number of visible fraction digits in n, with trailing zeros. +// w - number of visible fraction digits in n, without trailing zeros. +// f - visible fractional digits in n, with trailing zeros. +// t - visible fractional digits in n, without trailing zeros. +// +// +// Func(num float64, v uint64) // v = digits/precision and prevents -1 as a special case as this can lead to very unexpected behaviour, see precision note's above. +// +// n := math.Abs(num) +// i := int64(n) +// v := v +// +// +// w := strconv.FormatFloat(num-float64(i), 'f', int(v), 64) // then parse backwards on string until no more zero's.... +// f := strconv.FormatFloat(n, 'f', int(v), 64) // then turn everything after decimal into an int64 +// t := strconv.FormatFloat(n, 'f', int(v), 64) // then parse backwards on string until no more zero's.... +// +// +// +// General Inclusion Rules +// - v will always be available inherently +// - all require n +// - w requires i +// + +// W returns the number of visible fraction digits in N, without trailing zeros. +func W(n float64, v uint64) (w int64) { + + s := strconv.FormatFloat(n-float64(int64(n)), 'f', int(v), 64) + + // with either be '0' or '0.xxxx', so if 1 then w will be zero + // otherwise need to parse + if len(s) != 1 { + + s = s[2:] + end := len(s) + 1 + + for i := end; i >= 0; i-- { + if s[i] != '0' { + end = i + 1 + break + } + } + + w = int64(len(s[:end])) + } + + return +} + +// F returns the visible fractional digits in N, with trailing zeros. +func F(n float64, v uint64) (f int64) { + + s := strconv.FormatFloat(n-float64(int64(n)), 'f', int(v), 64) + + // with either be '0' or '0.xxxx', so if 1 then f will be zero + // otherwise need to parse + if len(s) != 1 { + + // ignoring error, because it can't fail as we generated + // the string internally from a real number + f, _ = strconv.ParseInt(s[2:], 10, 64) + } + + return +} + +// T returns the visible fractional digits in N, without trailing zeros. +func T(n float64, v uint64) (t int64) { + + s := strconv.FormatFloat(n-float64(int64(n)), 'f', int(v), 64) + + // with either be '0' or '0.xxxx', so if 1 then t will be zero + // otherwise need to parse + if len(s) != 1 { + + s = s[2:] + end := len(s) + 1 + + for i := end; i >= 0; i-- { + if s[i] != '0' { + end = i + 1 + break + } + } + + // ignoring error, because it can't fail as we generated + // the string internally from a real number + t, _ = strconv.ParseInt(s[:end], 10, 64) + } + + return +} diff --git a/vendor/github.com/go-playground/universal-translator/.gitignore b/vendor/github.com/go-playground/universal-translator/.gitignore new file mode 100644 index 0000000..bc4e07f --- /dev/null +++ b/vendor/github.com/go-playground/universal-translator/.gitignore @@ -0,0 +1,25 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof +*.coverprofile \ No newline at end of file diff --git a/vendor/github.com/go-playground/universal-translator/.travis.yml b/vendor/github.com/go-playground/universal-translator/.travis.yml new file mode 100644 index 0000000..39b8b92 --- /dev/null +++ b/vendor/github.com/go-playground/universal-translator/.travis.yml @@ -0,0 +1,27 @@ +language: go +go: + - 1.13.4 + - tip +matrix: + allow_failures: + - go: tip + +notifications: + email: + recipients: dean.karn@gmail.com + on_success: change + on_failure: always + +before_install: + - go install github.com/mattn/goveralls + +# Only clone the most recent commit. +git: + depth: 1 + +script: + - go test -v -race -covermode=atomic -coverprofile=coverage.coverprofile ./... + +after_success: | + [ $TRAVIS_GO_VERSION = 1.13.4 ] && + goveralls -coverprofile=coverage.coverprofile -service travis-ci -repotoken $COVERALLS_TOKEN \ No newline at end of file diff --git a/vendor/github.com/go-playground/universal-translator/LICENSE b/vendor/github.com/go-playground/universal-translator/LICENSE new file mode 100644 index 0000000..8d8aba1 --- /dev/null +++ b/vendor/github.com/go-playground/universal-translator/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Go Playground + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/go-playground/universal-translator/Makefile b/vendor/github.com/go-playground/universal-translator/Makefile new file mode 100644 index 0000000..ec3455b --- /dev/null +++ b/vendor/github.com/go-playground/universal-translator/Makefile @@ -0,0 +1,18 @@ +GOCMD=GO111MODULE=on go + +linters-install: + @golangci-lint --version >/dev/null 2>&1 || { \ + echo "installing linting tools..."; \ + curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s v1.41.1; \ + } + +lint: linters-install + golangci-lint run + +test: + $(GOCMD) test -cover -race ./... + +bench: + $(GOCMD) test -bench=. -benchmem ./... + +.PHONY: test lint linters-install \ No newline at end of file diff --git a/vendor/github.com/go-playground/universal-translator/README.md b/vendor/github.com/go-playground/universal-translator/README.md new file mode 100644 index 0000000..46dec6d --- /dev/null +++ b/vendor/github.com/go-playground/universal-translator/README.md @@ -0,0 +1,89 @@ +## universal-translator +![Project status](https://img.shields.io/badge/version-0.18.0-green.svg) +[![Build Status](https://travis-ci.org/go-playground/universal-translator.svg?branch=master)](https://travis-ci.org/go-playground/universal-translator) +[![Coverage Status](https://coveralls.io/repos/github/go-playground/universal-translator/badge.svg)](https://coveralls.io/github/go-playground/universal-translator) +[![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/universal-translator)](https://goreportcard.com/report/github.com/go-playground/universal-translator) +[![GoDoc](https://godoc.org/github.com/go-playground/universal-translator?status.svg)](https://godoc.org/github.com/go-playground/universal-translator) +![License](https://img.shields.io/dub/l/vibe-d.svg) +[![Gitter](https://badges.gitter.im/go-playground/universal-translator.svg)](https://gitter.im/go-playground/universal-translator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) + +Universal Translator is an i18n Translator for Go/Golang using CLDR data + pluralization rules + +Why another i18n library? +-------------------------- +Because none of the plural rules seem to be correct out there, including the previous implementation of this package, +so I took it upon myself to create [locales](https://github.com/go-playground/locales) for everyone to use; this package +is a thin wrapper around [locales](https://github.com/go-playground/locales) in order to store and translate text for +use in your applications. + +Features +-------- +- [x] Rules generated from the [CLDR](http://cldr.unicode.org/index/downloads) data, v36.0.1 +- [x] Contains Cardinal, Ordinal and Range Plural Rules +- [x] Contains Month, Weekday and Timezone translations built in +- [x] Contains Date & Time formatting functions +- [x] Contains Number, Currency, Accounting and Percent formatting functions +- [x] Supports the "Gregorian" calendar only ( my time isn't unlimited, had to draw the line somewhere ) +- [x] Support loading translations from files +- [x] Exporting translations to file(s), mainly for getting them professionally translated +- [ ] Code Generation for translation files -> Go code.. i.e. after it has been professionally translated +- [ ] Tests for all languages, I need help with this, please see [here](https://github.com/go-playground/locales/issues/1) + +Installation +----------- + +Use go get + +```shell +go get github.com/go-playground/universal-translator +``` + +Usage & Documentation +------- + +Please see https://godoc.org/github.com/go-playground/universal-translator for usage docs + +##### Examples: + +- [Basic](https://github.com/go-playground/universal-translator/tree/master/_examples/basic) +- [Full - no files](https://github.com/go-playground/universal-translator/tree/master/_examples/full-no-files) +- [Full - with files](https://github.com/go-playground/universal-translator/tree/master/_examples/full-with-files) + +File formatting +-------------- +All types, Plain substitution, Cardinal, Ordinal and Range translations can all be contained within the same file(s); +they are only separated for easy viewing. + +##### Examples: + +- [Formats](https://github.com/go-playground/universal-translator/tree/master/_examples/file-formats) + +##### Basic Makeup +NOTE: not all fields are needed for all translation types, see [examples](https://github.com/go-playground/universal-translator/tree/master/_examples/file-formats) +```json +{ + "locale": "en", + "key": "days-left", + "trans": "You have {0} day left.", + "type": "Cardinal", + "rule": "One", + "override": false +} +``` +|Field|Description| +|---|---| +|locale|The locale for which the translation is for.| +|key|The translation key that will be used to store and lookup each translation; normally it is a string or integer.| +|trans|The actual translation text.| +|type|The type of translation Cardinal, Ordinal, Range or "" for a plain substitution(not required to be defined if plain used)| +|rule|The plural rule for which the translation is for eg. One, Two, Few, Many or Other.(not required to be defined if plain used)| +|override|If you wish to override an existing translation that has already been registered, set this to 'true'. 99% of the time there is no need to define it.| + +Help With Tests +--------------- +To anyone interesting in helping or contributing, I sure could use some help creating tests for each language. +Please see issue [here](https://github.com/go-playground/locales/issues/1) for details. + +License +------ +Distributed under MIT License, please see license file in code for more details. diff --git a/vendor/github.com/go-playground/universal-translator/errors.go b/vendor/github.com/go-playground/universal-translator/errors.go new file mode 100644 index 0000000..38b163b --- /dev/null +++ b/vendor/github.com/go-playground/universal-translator/errors.go @@ -0,0 +1,148 @@ +package ut + +import ( + "errors" + "fmt" + + "github.com/go-playground/locales" +) + +var ( + // ErrUnknowTranslation indicates the translation could not be found + ErrUnknowTranslation = errors.New("Unknown Translation") +) + +var _ error = new(ErrConflictingTranslation) +var _ error = new(ErrRangeTranslation) +var _ error = new(ErrOrdinalTranslation) +var _ error = new(ErrCardinalTranslation) +var _ error = new(ErrMissingPluralTranslation) +var _ error = new(ErrExistingTranslator) + +// ErrExistingTranslator is the error representing a conflicting translator +type ErrExistingTranslator struct { + locale string +} + +// Error returns ErrExistingTranslator's internal error text +func (e *ErrExistingTranslator) Error() string { + return fmt.Sprintf("error: conflicting translator for locale '%s'", e.locale) +} + +// ErrConflictingTranslation is the error representing a conflicting translation +type ErrConflictingTranslation struct { + locale string + key interface{} + rule locales.PluralRule + text string +} + +// Error returns ErrConflictingTranslation's internal error text +func (e *ErrConflictingTranslation) Error() string { + + if _, ok := e.key.(string); !ok { + return fmt.Sprintf("error: conflicting key '%#v' rule '%s' with text '%s' for locale '%s', value being ignored", e.key, e.rule, e.text, e.locale) + } + + return fmt.Sprintf("error: conflicting key '%s' rule '%s' with text '%s' for locale '%s', value being ignored", e.key, e.rule, e.text, e.locale) +} + +// ErrRangeTranslation is the error representing a range translation error +type ErrRangeTranslation struct { + text string +} + +// Error returns ErrRangeTranslation's internal error text +func (e *ErrRangeTranslation) Error() string { + return e.text +} + +// ErrOrdinalTranslation is the error representing an ordinal translation error +type ErrOrdinalTranslation struct { + text string +} + +// Error returns ErrOrdinalTranslation's internal error text +func (e *ErrOrdinalTranslation) Error() string { + return e.text +} + +// ErrCardinalTranslation is the error representing a cardinal translation error +type ErrCardinalTranslation struct { + text string +} + +// Error returns ErrCardinalTranslation's internal error text +func (e *ErrCardinalTranslation) Error() string { + return e.text +} + +// ErrMissingPluralTranslation is the error signifying a missing translation given +// the locales plural rules. +type ErrMissingPluralTranslation struct { + locale string + key interface{} + rule locales.PluralRule + translationType string +} + +// Error returns ErrMissingPluralTranslation's internal error text +func (e *ErrMissingPluralTranslation) Error() string { + + if _, ok := e.key.(string); !ok { + return fmt.Sprintf("error: missing '%s' plural rule '%s' for translation with key '%#v' and locale '%s'", e.translationType, e.rule, e.key, e.locale) + } + + return fmt.Sprintf("error: missing '%s' plural rule '%s' for translation with key '%s' and locale '%s'", e.translationType, e.rule, e.key, e.locale) +} + +// ErrMissingBracket is the error representing a missing bracket in a translation +// eg. This is a {0 <-- missing ending '}' +type ErrMissingBracket struct { + locale string + key interface{} + text string +} + +// Error returns ErrMissingBracket error message +func (e *ErrMissingBracket) Error() string { + return fmt.Sprintf("error: missing bracket '{}', in translation. locale: '%s' key: '%v' text: '%s'", e.locale, e.key, e.text) +} + +// ErrBadParamSyntax is the error representing a bad parameter definition in a translation +// eg. This is a {must-be-int} +type ErrBadParamSyntax struct { + locale string + param string + key interface{} + text string +} + +// Error returns ErrBadParamSyntax error message +func (e *ErrBadParamSyntax) Error() string { + return fmt.Sprintf("error: bad parameter syntax, missing parameter '%s' in translation. locale: '%s' key: '%v' text: '%s'", e.param, e.locale, e.key, e.text) +} + +// import/export errors + +// ErrMissingLocale is the error representing an expected locale that could +// not be found aka locale not registered with the UniversalTranslator Instance +type ErrMissingLocale struct { + locale string +} + +// Error returns ErrMissingLocale's internal error text +func (e *ErrMissingLocale) Error() string { + return fmt.Sprintf("error: locale '%s' not registered.", e.locale) +} + +// ErrBadPluralDefinition is the error representing an incorrect plural definition +// usually found within translations defined within files during the import process. +type ErrBadPluralDefinition struct { + tl translation +} + +// Error returns ErrBadPluralDefinition's internal error text +func (e *ErrBadPluralDefinition) Error() string { + return fmt.Sprintf("error: bad plural definition '%#v'", e.tl) +} diff --git a/vendor/github.com/go-playground/universal-translator/go.mod b/vendor/github.com/go-playground/universal-translator/go.mod new file mode 100644 index 0000000..9d08600 --- /dev/null +++ b/vendor/github.com/go-playground/universal-translator/go.mod @@ -0,0 +1,5 @@ +module github.com/go-playground/universal-translator + +go 1.13 + +require github.com/go-playground/locales v0.14.0 diff --git a/vendor/github.com/go-playground/universal-translator/go.sum b/vendor/github.com/go-playground/universal-translator/go.sum new file mode 100644 index 0000000..20667ea --- /dev/null +++ b/vendor/github.com/go-playground/universal-translator/go.sum @@ -0,0 +1,7 @@ +github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= +github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/vendor/github.com/go-playground/universal-translator/import_export.go b/vendor/github.com/go-playground/universal-translator/import_export.go new file mode 100644 index 0000000..1216f19 --- /dev/null +++ b/vendor/github.com/go-playground/universal-translator/import_export.go @@ -0,0 +1,276 @@ +package ut + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "os" + "path/filepath" + + "io" + + "github.com/go-playground/locales" +) + +type translation struct { + Locale string `json:"locale"` + Key interface{} `json:"key"` // either string or integer + Translation string `json:"trans"` + PluralType string `json:"type,omitempty"` + PluralRule string `json:"rule,omitempty"` + OverrideExisting bool `json:"override,omitempty"` +} + +const ( + cardinalType = "Cardinal" + ordinalType = "Ordinal" + rangeType = "Range" +) + +// ImportExportFormat is the format of the file import or export +type ImportExportFormat uint8 + +// supported Export Formats +const ( + FormatJSON ImportExportFormat = iota +) + +// Export writes the translations out to a file on disk. +// +// NOTE: this currently only works with string or int translations keys. +func (t *UniversalTranslator) Export(format ImportExportFormat, dirname string) error { + + _, err := os.Stat(dirname) + fmt.Println(dirname, err, os.IsNotExist(err)) + if err != nil { + + if !os.IsNotExist(err) { + return err + } + + if err = os.MkdirAll(dirname, 0744); err != nil { + return err + } + } + + // build up translations + var trans []translation + var b []byte + var ext string + + for _, locale := range t.translators { + + for k, v := range locale.(*translator).translations { + trans = append(trans, translation{ + Locale: locale.Locale(), + Key: k, + Translation: v.text, + }) + } + + for k, pluralTrans := range locale.(*translator).cardinalTanslations { + + for i, plural := range pluralTrans { + + // leave enough for all plural rules + // but not all are set for all languages. + if plural == nil { + continue + } + + trans = append(trans, translation{ + Locale: locale.Locale(), + Key: k.(string), + Translation: plural.text, + PluralType: cardinalType, + PluralRule: locales.PluralRule(i).String(), + }) + } + } + + for k, pluralTrans := range locale.(*translator).ordinalTanslations { + + for i, plural := range pluralTrans { + + // leave enough for all plural rules + // but not all are set for all languages. + if plural == nil { + continue + } + + trans = append(trans, translation{ + Locale: locale.Locale(), + Key: k.(string), + Translation: plural.text, + PluralType: ordinalType, + PluralRule: locales.PluralRule(i).String(), + }) + } + } + + for k, pluralTrans := range locale.(*translator).rangeTanslations { + + for i, plural := range pluralTrans { + + // leave enough for all plural rules + // but not all are set for all languages. + if plural == nil { + continue + } + + trans = append(trans, translation{ + Locale: locale.Locale(), + Key: k.(string), + Translation: plural.text, + PluralType: rangeType, + PluralRule: locales.PluralRule(i).String(), + }) + } + } + + switch format { + case FormatJSON: + b, err = json.MarshalIndent(trans, "", " ") + ext = ".json" + } + + if err != nil { + return err + } + + err = ioutil.WriteFile(filepath.Join(dirname, fmt.Sprintf("%s%s", locale.Locale(), ext)), b, 0644) + if err != nil { + return err + } + + trans = trans[0:0] + } + + return nil +} + +// Import reads the translations out of a file or directory on disk. +// +// NOTE: this currently only works with string or int translations keys. +func (t *UniversalTranslator) Import(format ImportExportFormat, dirnameOrFilename string) error { + + fi, err := os.Stat(dirnameOrFilename) + if err != nil { + return err + } + + processFn := func(filename string) error { + + f, err := os.Open(filename) + if err != nil { + return err + } + defer f.Close() + + return t.ImportByReader(format, f) + } + + if !fi.IsDir() { + return processFn(dirnameOrFilename) + } + + // recursively go through directory + walker := func(path string, info os.FileInfo, err error) error { + + if info.IsDir() { + return nil + } + + switch format { + case FormatJSON: + // skip non JSON files + if filepath.Ext(info.Name()) != ".json" { + return nil + } + } + + return processFn(path) + } + + return filepath.Walk(dirnameOrFilename, walker) +} + +// ImportByReader imports the the translations found within the contents read from the supplied reader. +// +// NOTE: generally used when assets have been embedded into the binary and are already in memory. +func (t *UniversalTranslator) ImportByReader(format ImportExportFormat, reader io.Reader) error { + + b, err := ioutil.ReadAll(reader) + if err != nil { + return err + } + + var trans []translation + + switch format { + case FormatJSON: + err = json.Unmarshal(b, &trans) + } + + if err != nil { + return err + } + + for _, tl := range trans { + + locale, found := t.FindTranslator(tl.Locale) + if !found { + return &ErrMissingLocale{locale: tl.Locale} + } + + pr := stringToPR(tl.PluralRule) + + if pr == locales.PluralRuleUnknown { + + err = locale.Add(tl.Key, tl.Translation, tl.OverrideExisting) + if err != nil { + return err + } + + continue + } + + switch tl.PluralType { + case cardinalType: + err = locale.AddCardinal(tl.Key, tl.Translation, pr, tl.OverrideExisting) + case ordinalType: + err = locale.AddOrdinal(tl.Key, tl.Translation, pr, tl.OverrideExisting) + case rangeType: + err = locale.AddRange(tl.Key, tl.Translation, pr, tl.OverrideExisting) + default: + return &ErrBadPluralDefinition{tl: tl} + } + + if err != nil { + return err + } + } + + return nil +} + +func stringToPR(s string) locales.PluralRule { + + switch s { + case "Zero": + return locales.PluralRuleZero + case "One": + return locales.PluralRuleOne + case "Two": + return locales.PluralRuleTwo + case "Few": + return locales.PluralRuleFew + case "Many": + return locales.PluralRuleMany + case "Other": + return locales.PluralRuleOther + default: + return locales.PluralRuleUnknown + } + +} diff --git a/vendor/github.com/go-playground/universal-translator/logo.png b/vendor/github.com/go-playground/universal-translator/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..a37aa8c0cd0f6e1b98e0be3eb2531ebc6ac6717b GIT binary patch literal 16598 zcmV(yK*U_<=i=1Q$^7;0v#+eDrK0%p z>%6(N%f`XBv#;pk-N3xJlaY`9`tZ@r#>d0H&B?^Dtf>F`_3`TEoSK)csHK;dl)1LD z{xUb9o}0zMyZALSjf{%1BqI0!{{5jc`1SO`zPq8KpwB5MBz`@`DJHxnB>jUjr=XpP zhJ*ceGX0V>qah&tt}xmxDK3XPA9F;SA|8N$duRs?{%JJ*T{HG>5AcL8I*&O1Ju^KN z1^!Yp@h&apFDzno38}29au*Y6VF#%(B=Pd^`t{{04g#CPRH8PEL>89OH1Y4=wM`?Y+cnsCD|dZGb#-yb zPbYsY6v#U#TTlf1)HKmxCR88|TWkfi;WgJmEa>U!iH1CPzc%zlFUrZIxOpL50SAW2 zHrkRe-Bv8!+}rP-U23*Bp`mB-jzz%dHuKoF($TRq)t%&MEAPFIet}u?$D-;-NTfd? zqGBFudL7@{$H>RCmXS~SDk-e2cr(q3b}2D4;I^fdk8wf@!NHcex`pmIGxX}ykX2Zk zP#l(MXu)GF(Pvk zb5n$3uu@QfLrR3XE#bH{zmF;My}ImfZ|eE@n0GU+i65iC#kVv_JUkHP6q^ z=b4$1KRnawHnN9;XOVD+dTcU@PWtQI+{V7)vVb@}2{~W|d768ob{*KawLyATCMyBY zhk?3y?SQh*YZ(!U#KDNg9qaM-(p?CZPE$X(8z(y`Rk002FaNkl8uC7fajE|-h>jHG2b9lbevz(KOfu`z+X2)PND2t1w1WGFmB z;BZ@Tf}w8eW!d6lVUNJlhe<3w@VLAr5!hqYo=(frj?qrXhNe@r$z?o#)_BC$c#6Tn zw%ibJSrePzu1EE-o7FRWE@Bmr=0#t-W8=a(6GTqoYvcqTWN@=@*0!nMye8HIu2(T+Ak@9J5Z~>D99iw*`m8V%yP8G^_lKA3_-39D4+I+C1zz z%PxAIjtxqC6rEeEoK;TYRK5moFT3e)S;c473ltAKvc{hCWlVc;gKFP7(_^pP+TQSQ zjTnnuLBc{Sdb7KSnYy{T8Mi%*-`7X=bnva_VNVf!d<1rL=-JH6uuGF1?^y5f9AB6q zotFt+&fvKN9wTt?2px9TxG)4b)AV}%MO>l#`PSCbhc8CH z(ahGS3jt5QrHGrvLqpybTd3aT!_Ma3C?0!8iS}-@N4$|3Vjk~Odfkur_B2j4Q=ai9 zwCdFE-MgodJ$v@--@hOJdcD5T)wQs^+~2>veB#83lSsEgpFKBQ8LAYfrz?!j@VGrK zfD?mhnuhu zc6A*>`uqE-yqo0c(WA$Y&khU>p!`akr_C16;qx9(K3}Q48GMs(2|#W(U+C>U+gs?p z^6}jBk0WP#6@}XUG1|MFxifa;Gu`Gf@{^8r3D0vJ&-0ExB2Qql!KaO@u%q%RuxCa- z=nDq{@3OWa?o`}pF?bNzz;Q^nz?4c2d1Yzhk<6eIWaeu#=B8Cm810v^Rke)+e)?h zH``r9!+0zn64TyHj(U9NCw8Ir?OU83bm-%VH;0Wb>dWQso<4o4T$akBA7WgT3iz&_ zN#||w+mrl%lwSPt^Vg61UR6`~YFWHi_l{!JcULueSU zuU#7-U!wAd^F!yiGqsgYce}fpeBa&ns10GwH=8Hj)>BVDk~}BH;~@vhCnx{=D_1_h z9(z4@+Q`0r`z}a*NhgoKotri}dCcg8TMu47d)M~vT^slBr56_$zkgrMPE@N|O(WZ! zsLQ%0YpP1+LKrd6^35*)GUSB5)MzwrJS8#U4D>#RSz-pt?c=lJXO zeSaQ*)aC{sacalkE(o<+>1c~WPfGnKtu-k`2YJOl(N%r)u4fVPB7smYkR!~c!2?5` z13>TVn~)3sx0VVE3qQ8?KZ&MxkE4I%0~`Az9FB(`>c8OVKkXPppkEAHPbYRdx2|$6 zf*j~H;Ex?orIrKyj}eYAQ%S`h#fdpw@Cz<58T?>}2zx?ZT|%y(T{~Xpi=gkZTF;#e z3F=$F{`}PNFa>wR$HyM5Ztd#os_vSakjh6}Iy<|C2zX8|>ielr&R9gEe{Fo0|8gK| zkY8VlfcpEtiRi!U(S93Z-L~--2kINT8Vb8(?fP;$%dGar++*t=TX-4CqacXL~rY1d|=Z=r( zT@Q{j(+PIADfOvY)=!t^b(wRg^=0R7n8aR zGu)okchJ@@r~V1+Ujz8JBY#ZBac;u{>vE*5fRzYXDa*3>N)mKP)O|L;_+)+@W$#W_ z1HCSw0BPQbdWUK^n3k3~2){GaaiQou{J~fvivE1qGekZm14C^s_>uYe_~`Zew$6dh z&dz2jY$hilM;G9l1sq4)7Rn-P`H|OEqLr&S14g)DnOR!8zA!U0bMNinM7RaVpGDl; zY-jGh@Wtt|F$}V_tG&EfzS=j}cU7%lLF4S~p35Z7OJBR(*!bOV-xB?PmY6P)N+eR& zm~-CP8no)@pwxKED3P8YEr^+%?8q=F+vn#4EnG5nUJd7iSCx$h8STYo>M5XqKb%>U znOOtZDR(?fN4Uox1Ub*XkD$wZHf)e>(EIqv@I>f+HsGnMd7^oAVqjvh1vQ|K6RZ%6 zS(agDR(SBQc^!rdmzN8vK88rJqp)LqgEnqF@z805HGQJ@1$%=?VI znx@@zXBFMuwRP&sqPpVZvLw6xjS9oC{Zv}oug2jiu%}ZIcF@Ph^RCBI+pC^=W&^+h zj2nbIz;VS1L`O&K^(`$vP;`|5u!wLu!{jbqrQrBbaLVo`2m4qAM6qoVHq>>S?SyR` z*c}LXS5Tn6g}o`iI4?0VQ5zK%Rio1xlm=zWuo0G1 z^py0Jec*;-d4*BepMTH?oH9ZSY$|#H{6GG`^dbW~(Tbd;`3i5jm;5kK&YSMhLvC&3 zHVlp9eiusn*^WX_1XErv-9)w42ysdA?Q+H zW2CX6=ZBNdm?l$Xli3vMR5s}}x+#0!T+v)!UV9=H(9Y8J_>rsU{BkbR#TC3Ak&M^yN+acyB-!s$e-Ut;vL8ySlm4a z;eC8dRw94`tf=X%Uv6%$8=aRI9J<1TIMbMW6^gFu(4jHQl%}SF=r%{bpn^hWvR;$u# z?d{>=gnV=2*2E~n{(eP81u1Vp-=CRI+4rUIi{BUTb=|}MLKVTK$?cJhCIQZa#yajY zS(}2N?bT>;%*x8uf2KJB_nPh{ry9GsF6g#rFPyoz{6b}Ux%JHA;^J%)xNpWt!c`tW z{u(CNPsL)vuD!{O6hY2%>I8qZSX5O>PtGWEy~`Lmb<%8B>Xe$#4z(JbN}bN!q|z#P z103ko^(ZQx!H{Jz7!K^;PuL-zok!n77@PpuN3`=QIJaXNJwN>xw8No`D|!K~UHql+Qv5HWo# zB}cT^)aaC12QmqJ`hK3=ZTlv`6W5{ViSOGfIrW*|Np9;)2Kq```l9tRy)3$O^iF?{ zPUxJ75m{!I-KK-QaAxVc*K(Nd4R;SXqMht4{NEVX+)5Xg*@A@Hq<~LB?(fg+E!|uH zU3PZ%u1f#x_XH9a#ZAHrAeO}~uDGbkZnqajX~LVrJ32BtOdr;k&6(!Li-vb=RcYZo z`qr(9iCZ7x(X%SDkm@`-$X^FI#FKA=?VA8jd`GrF3{<|9@ts|UOIx>`TRl)x)i(4! zVqK1178248PoY+zy&b-K_%Oy7g$1LI+PVzSss7D$wDbGdl?MTRO~_3yx};tzTQz$r zSe*>=WM;>E0%_2DZ|vGpUk`K^A_F2WgkGGN_tjVSqN1X_;l#xEe>Y_`nRX?JRuvab z&g~`&C+yn9tq{;bzH_ItrY6OpN)iIAqhPS4RrcG0}H-ItzJ63yu82&@oOwU+_mf1X}n+g2RO*VZncK44<-BB z+G+Yq=F+7-dwvP<@5T-$&i;rIO9hgIw?BI0!*bRmde8z!{OebMCn_45k1IEu%%;5w zZ2pLs8`5bugFNbyN1`6vx%0719fnqA*1>c_p8opl;C9=-g_85G(`0|)akx&hT0i8E z*A@6EL~^dPMBnD8U_geo*8BDX#{gcTd}-NoZ9(W=)2}TPcDLmocn>*d*J+ov2jn5X zXFPA=Qd371{#Zkjvdg7$5|ZN*kx0rQ<9P{LJPXA|<1mAld=H zeF6pxh+y>)4x?&9&JdUXE;854k?u3tb-luOx$vDg{YKA04)&K8U7-bQ)+Wt*$g!p+ zd>R)h=2(eXDrI1_slN=}1S%ohp zYxPt}n<|U+ZLLX3DU^`n%%gKDue)jSGZ|@jXG+Vz=eq5l&YUz)X3nM`O}_;8bW6G= z_o!T>E7p}a=o+%+4G~%088Lh6<#L=(cY(ZrFR_KH+jR%FgZ+7u*Ku0ym53ZDlD%;M zDK00U$79jCFr3=+e>+Zd8Kbx^y8rpdw;+ePi0(rEcF{vXXUH9M*J=IbOtmtzv9U2p zZ8n=LDb51T5%B!EI7_u9F0HyYe&&bWyDz1GlxsT+qsKmW{8-WTmSZB|aUiV( zp-$K&$n7N5VfYthn(2a0mpq8WDj|Q##oe9cXkS151>`UX`LAYm5)73sDbrS_7t)At z*5MiTSA0^HksSw%*X)LU1ay357LSh~J$h6Zm8R3Ap?k~D-LOHIy{AFm-Px^**;QYa zRWHuV0((CzdpO8}4s*y3Xwud&^^FK$SLZ;dLr&F+Ft25_rg2cGMHE*=P(hwTxPLCH!Q#wALd+)uu>YY1x z@80P^ABRO1AI(Ks%hl*K+3~t~e6n@AtgJn{^)dCj`q*8&RP*TJAcw=-+1WIg>Og-! zi0R>uof>t-y6A!jjiN=dZvEf4lN?@2@VXN~XWf0N=0ImPpPrm-n>8vX&)n@Ol2R#B znbf1LwNQFh?-AAi|L(|>>jb9nKL5a# z9Oin*V%Hps8x@|4J7>=Pz-uLu-d02$AM6y*6+OQCyoDT5;^I)icc$llc4<5}_oyZ} z9q6GAFnMu9vAj6DbA5(iJ=DU~vNpz>?Ab;zfJ01KKV`b&+4+RMK#-yA2MrCG_ zjasUD`OG&}adz8*Hiir*E=5IYiqq0M(?ZkbGuepsVqLeqJEOB(2kKohauw41-dFoo zTMPU9LH@!E;jl%)zA-iRc}Di9+Jk~xPK8|TB|^jN?%g<&O~C;*1>ZTr|1HqT^~&AZ zt2|$RWm0odWs$lF-$Id8uw<=`?m#1}vaQK}T3tBj~iK{rDR^4%a1L}Fip6pKf zo^E+P(CcIO@2Z!pRH`=%LEgUw>`rv2>e~rA)5v2sH_8=VnBt-*_gW4*wPuqbAjy{F zg8t9slNhyMMJprJo3Y9#Q_FY~k2ZAkutg4!9=0@%*iP77rNsdba<2F7igPm&jID>o z#Kgo_Rqc*a9xqlw4X(wq?9avVNq zlfWb>_yT3k)!mnn1Ko?Cg6jldkn@@v0Zpnql3mf#LUJI^Vez+xlB;b|b15a~Lmi@X zJWG2YK1tUT^v0&MU$F+&){6@@u6Tr zjdB19{%^XtMFoAbLxMTGeca3`Dl2Pk)9Z^WWs<-7woPeKX~Znm6;#ut=)i4DZGI`h zOUtV7N~y{@4xQgO_dr`{X@zvA z9J2{nIpTZ?Ix9NJfxgt`Nv!vrR&C#Sx@&moL?lHYuRFE;i^icGLGYMgK=2as!*F+y zzYB7^=2C^ii(DQ062r07cvB{%yjs=fMwz`zF6@(vkk(-#is~cOIV0CsxT=)reLM7O z{`m-UPzCo=aF7%BcH;2FTvT^-HCu;GT{Si0(*uFSLtPj@?fr^guIS!|F@Y(-mgIM0 zaW8WisqhzQofDQsa1z#?_ca*OC3#HY)*TC(}?XH@?&Z-WxtL~JYjrGCdlLMQysqz8SfFa-G>$_VQx`Nh36<)yN?DnC)#7fB z!>_%4IZIsJ+?=ICB0tL7{@(1QvYaHs45Uw{tXPiEHi zq;9v>)C6A~O&ks3E?4zOPYwjEGlgLhcHN7M-5uy4zvVcsRg7q(#oprRXf3(HQ)IUJ z(u5qhYprT2kK(wXIgT4Cestix!M$rbb2e+FyM>a9riL|Pi${b zWYL!fd*tdHml<@G>e3Yo=eHL4-U>46j7L+xp|&jsyRdcav_GR z?TLwOu)`KNH6uRBVLeKlQl-)kmWV=@sXCVuBE7nXm4b>5UH&(vkkqhs7x<)`RO!=hk@B#+>Rab5%2HV z@qUDT;C_V5J-1;)dF|B@?)S7eM0aW)%WxBPyXuLse{y(u{0LS@BmIVYYLo{hWD2@W zboZVy!GJQ!6dA~Det&WKgV$KiKP2R^X|e|>@v@5htOl`G9KBCW0iDKWi+vohILtX5 z^p*J^*^es_9A7ZZoR6G~M`F*2FVBc^fIH)yC5P$^JM5o4eyi0V`;&p#WgX~oN6;>J z0et0m>jc5dfw0Ihzd--h$)=yy!QEN%TWxJW>+df)pr5|OSDf3oFFG2ZXzc}>q&b_B zMpg&^BI6+advZH0JMHW&ICIl5U)0LyHUE0eet<6}U*hm=L-*YCgZ@xG46Ceyo+d7D zd3%z`xob`i3j~46u;DJPA=%%@|0kPmUi4qEJc4B@?^XHJXFAqO`V1r1zKLtsR*;NE zNzF#Pd#CU{q(+zR9chQO!m{&Hv4xPQX#j3VXTf1#kFu$KhQ1i<)SPUJuM zj6L-LfC+56y*~W^lm#th`;^yuyU3>Y=Bs#gX zxN*THx|cicONSWMm{YK(W-A(|v90N^r041!rU`A>rg4C?uVnZw%yymDml4p z^m^gTU=MovKC&c}*us#r9&ZPCq7Nqfe2aR-pda$Z&s?U*NA?7pOv(Y%6~k)7gUQK0 zPXzxS#^$&-EO5FRvD@!aGJV(U+5=erBbz^6`zYjanHk5nd2`k^-vU{R(Sp&GUG>oM zZ5lf{)4a0iGhRQkVSen#&u&g#tE(%ltE+q2en+0jqO)y0J_P+)(#k#;`K>=vJhLjj zDUys|mm@j;KfzeA0IK^LwAwBofAX$JdD#!-1bxj)vM1(_E%vq6zP{+w){!n8mrh3; zP?>3?t*o`RwXLm94=ZA`CPfMH&zg&g9c98Cs=H{;pvT01{ONu+!|ngfTKN5O>D1Ks z9zV8_B>{)%4%Nf)K|f~~9kP!c9En^VwmOiYuRDl&ySn`A%x**wgO0!UE)4c?Ms(|g2CMy12+&Pq_u%a! ziOWhQZw%-Gfyx`CR6=wgpC=AI^yt$zfZw|H0Q}u;1(u~|^$B3tVn=nvYQ4ed2zgxS zE>vK*U!tfik_qSiodN)Tp2_W+;!qadsW~ZX1U+VRZAlf|$MhE>%)cUcmcFa5x76XP zJduPuW)*eUUzl&>!y);g^^r$>h9i^xfsWT$ICA<@{~MmBOC;O{I_0brprKJlb|J+N zgZ&Vmu|4|e&9I`IX0;XsGxg9iuu zuqIF5#P}!U6;uFJ7mT4u{r~d{{YO5J)tr*#)Qq8zwfTvo#i?CPtTX5!huvS|)--)a zw#q}{A!(XCZ|$>Mts^5NR&tLlRg*lYuGAyZt6S$YJjeGH{cYSNYBb}WgdFH;5svdY zJ~6}?^eSp<6xf?_U?H9R$5?|PZITxa^q>|(e$2hsyTr=+`}M~s1`m^+} zk2rdWpck2C5|LhA$x9JQGc#F_$6+?9IdeQ+jvIysW^EuLAuqlmuUj6mzB@0AxVyL$ z4qu-aJCQT;`sS@0+g~r-xOdA*nUt*3k`V|&2YJh}RphC_r-R6Ig#F?g!ysM&;#ElG zL7#6|M+Tbw0&44d(q-Q%l06rGzZ+>}TLX6*pw|{x?0MNM(^eHS2w6q_?+H`NP_lgzP>mx6aB=_u_k3P+) z?qe7vNjYG^WP0@gS$Q~#=Lw3FI z^kQ#lUte#p+rA4F$6!E4qNPdBj>arwkE;qgrLh@`!#X>ea{d=7=N{8m702;%aa^D< zV6csc@^TEk>mZD>DT%9=&`nn;gh)mlB7!rdB9AJME`b_S!eiwj ztdeHfL{c_bjmTcch>`u}|Hkh*x3{+)Iw$_<;Qj;ar@!axl#^7s(}uH{Y;^fAa2w@GE+?S3Ep z{Oz~%^F4tvUh2BKPS&D;Oly$Rx%c=!JlS~bVug~%%PXR^tFgEVUFh02#JbG1Hj4fs zK|iWiefYX6=Vd3lDs^3Z}T+Ya;&Ni@f!YgQA1J`fWyK%5;X(4!FEX-yLqx}StO zvq`UuOHP2T0^S!C>=UXTiWi?HgPSd*;fB$KaJ9bkRLETcolYqut+(&mx3K>6{O>(6 z(xBB&wIz3z1iCvgYY78VLd(Bg2Z+2ir8OlLRQf6^D$l010h^$|1oUdv`+2I5dGy!v zw0Uo7b($(eu6+&YXc+P65lgLzaR@ILFc;IX>f_gL+Az^7-f8e=hu$F%q3A7}estPl zClWei9YrA0N6X`Y}!prk%Okx6*BdR;WvleVA97X%R&DC&^KGs4G%(E9BPQ3WVdbTMFDE;wHAn3hB92y`<(J4RpFY&niX{j{c{56Ajx2`3ml z3fQ;c>p4Jo)B2IDr>0~gI!SKW&s+)ExP68iybs8Cn>KJ{GmNBl7`%LMaDv`qk|)q8 zHxsyH^j%19*lhfyv{Tm^M^|oc=wK(aO{nJfg)QB^NrbM+Cg#s=d3U|a7w%$7!w0WjnU;tsxcgfeU z!?dyx7KV9G__}WK*;7dg`FeRQjqo#4cN+G;pa+uVW{6GJVKT>Y@9r}s&UvEy?;{8Q z&z$ienRm*$b0Z@-4u%F5>Am6&pQ(Y?1u=tp?;Tih9fz8ispN9RXD5#@M; zUofRC52d6oL`9K%EKJWmrz2O^$de5Sa+{ki%nln=5G-1gS{}57_x38x_&7y$jFZ## zx)WV0t*op2e!iCY`o#BDyx=f6mT!;;VjCm~uFlJ6-XzA55Fs*gIpRz!<4JhY;1C}BLr<47kbpwp6LEtidvj$ud5s%uc(|KfsBujHs zu&DiuCeolf92|`Gx_Pw4UJ1D9V@qY-!+W&I#AW{29FwE2=PFt>@h#h zt83>+6l!>Rt$O|(1e@nSZo3i;tX{b|f1ug3=c{HsbI`g!Gpgm$tGA*1!O`1o2iI&x ze~V5d{Gu)+_2JOdQD)kZ&6#$XrqM%POeS3#xfef}x)b&Uawo^A)iBnHv>qa$3)#(Y zR|nLNF`uH5`Pw=Zv9=FJftcKx8M3trvP+}!MTCi;sSA~5@A^0wGD`#u@a zPY`s4>LQPxrPgNUXj3-qyEOLw<+i9bTa1v~Ku*z7&4C=f5?|kSQ)=pZSd@+)E_k?i zT4z2LVvRNH_2KEyau{9QA$#!gq;zw5EY|%xY(Y?Tu#1U(cRSU3Gql}Tr)Y!D;p>R+ zw(%-nUWEudt==&Ci0tMwJzX_LXTGT6u(Dv*>;aNd?bVmxQmIcUh_B~$Q*>zk{BFCy z%pTQYi!|7RM07$f6{4IEt}wZ~n3}pV7`B(#d)`p&b9#qEXHK?S^3&g(9w0+5GT9D{ zo{2i14x5j6bdF8;-V3=)J5(Y%&2B&sX#e?~Q^vo)NsRsGcy@L+4^NhF5{B*of!({N zr1aDBlG4(W&u9R;Zx5Bg*H2tkDNxI_=3$*$U6)m$%_z_Y_}WHCZGMPxqc+5MF~Ead zK!>mIj*LSIZ(1DGV+O=DsDIvc4_o5X4y&biF6F@NB*$Env3I157c78za&+`6tm$S$ ze7FT2*N~7?+Y>w32|7|a0vn=R8TE4rzCm92=1_5cNsWYotuwTg^)7#}SqeWW=VL&W z&F(X5U%YriMdV_JR;AL`W#y~TvkAJeX|ru=?%Td#qwm~S^`r3rdWmkw(A_ZEroDXB-mrlx2GAF?s==(t${^?w zUiWO9p;$Nv7+M5$C|z)MitbC$BcpUVD^JsFOHju4S{?LWD!ggyMk3}wPEN{}u3wi8 zkUd1N|8nb6fB#&6Z@)!7hCdi0E?dJqLVU;gxrsU|WE*0l z%F)~gbllSvYF?;4p6^DdPo+Iefy}C|^Ia#!LicZx|=kx;>#>W*m5$35-OP}~2($)sWSM+5L zV}#I2OF4kVH+~tA(W`!DFJ@7pL)Lh~OgZ6=68MPisZB)3;w5VTVLA2y%=mIR^!oVN za9o=7%<|Go>#b`m-M`^#21YutbVv5&T}nwX)w)%$9r>>m^wyho>i54Tc5$@-0|-^qv5389|oe03Z9LVZLDo@$A6KChyh0HFb zH|ekA^*^-Xq<(=~-FL`Hb?zd+to(?BY9G`5mrZ$+6K9vnVpwKiz>6mbx@hn2sV$OM zx`58#I~W^2XUVr*-@~%AlU^LLIT;BlEKM=)I%iqUKdFR$1L*kb*CV^R%J|T279Vra znbN;OkGa_B0*5r+_(=H?N}9)@vyFLnOlern>=agSth1P*!@GE9=pzJ1!2Y8(j?VDtI3JWOqCdKV*>@q}he~y2-0s-K{cKKo9a*x=?b8&f7b>u^^`# z%sPvuKfgeogGi~_NSvZWKRhb=lQR0m(e&}y`hKv*ItTLp1ie~L)Q%>VE6@SmrS>9S zop8E9eaLtW=m4kEnA=l$nS}C3RVZb_Q zLr^-sTY=1-lhBT_YrJoOi%O^Huy^;Q?o>K=1xUtEJY7?Lw5zbeUY7t>e@cVp)&9rjhRZL@fiLU zrln!fK{?De4Re>ji@tQZr)STlo*U5|+k?w_7{SVxy8+FklYbz`r^BqH6dUm7(J8rS zCC8(KT(EbX@d`PmvtZT@qCVohi>Ld*B$kaXduBN)RY5fS4+&j-@}B`Z#sT6_jg1|5 zQ#-m;e1nd%<0_h=PNX#j&POZG76Kd8g+`pxtWE^ zON@Zd>}y5+D#o}g10)b5_$AIpgIp6BNR=*F+*~lm}B~8kn%Sz?&C8hFo&_{(Bb_!y|k|xpJD$#tM6v`FKZc zQ~INxPFy{1I_G(iQ*?DcnQ5hw1GXa-K4flvSxOT1azhW<|(3Ixh;XVH5*TL2eCp0E53{WhKEG`gQ5;{d6>n1~Y%ma5 ze%K}aNC~DK+Vp_bAjJX&l~pX!HM@JUkSiCE6(PF9szj`{VmUYnXKNuyYDA-?mnbI= zsh~ZyRfU{fDpf5|C4zE^Q2q(TcV>4o9$LVOR9;-yQ7`@Y`{vD?H?#AWj`#f-Tvb8Q zUxWKlaGD_9;s-W;cL!JpYxaX9{H|njNAxrP{08)3)lS)azB%(9Qkr}U?AFTRqbo-b zTZUFDhsq_bTvp4Lx;{EpLvo`M^rK}B=xpIG%i}ZL;Rk1KDR4;S-xqIb96ccCbGjfp zVqD)Z!Ce(JzK^vBkLS;AqgJx}6XJ(3+PUn0kpH{vllyxveEH@X`^Y5bH zJ^uSU3>{aL@axuK2%L&cu2tNv0bO7hWcOYE(F<#j|L_L}`pfU;&!0?zdu64RR?CK= zOP65uu<`3BHspiAXcZJDAca~fGrg@ zXaUNypPzhv!T|cGVXbP_jO{5Sw?W=(En_)N(2?B$eXCq1IZZ<^LUX_)o>TO(4;^ez zlZuqxP(hyLE{ivC?6?#-Q@L5-8-bNImmP%IEA*pTR~CjEX8 z>A)_?&e&qn8IoWk7-CsWpnHEm4E)p9JqzF|z|j9S{59x_T{BPGjLSp#~jHQiDq zsGg;YW;(C;L2N8*xG7Ur(2`b z8bu!(CFsatG1p-T$UZs|9U086-xhmRX~Aq@w%2m8^k#3-ZFF_ndLtHP`GtGq!0v zF(NuA?-t2{4)Wg*ku4V(*eCs~(j&iZ!r?(axGLfd-NZEC>G{!N$R4mC5ZNI+Vej5I zn}=C>ihe7XZ|1j>Eu(4}O4({!B`sA-!_$vinp{q`q;;za^stn1OfTsG&iSKXRNxrc%gd^^9xB5b@^qq~|8u$i?VRV;s)e zf3rCiOXGobOKn<)Va2d;l?Zwhi&p#<);vsZwwX=Nn-#}|`{(8h+MJ%4vvZD?gEOtE0_g@+bTz-JE3tKTXm%mBT z^LK7yBdUL~7w|#fgS3hXN=v3Unl-gnBF?@MADXTjHBuFI^^8Owlkn`cr-xk~GHVT6 z#mn>-^h(q-l*t_jANT-SAV8EK@>Q9n2(Ueq}&dkrOkQyCnK;ggPO| z!yt^^*Ig{wK!&^Lanorve**{f19reCeD?G>rPnliRX8yXIZHf5&~vKoNYWQ(*fz-* z;M!rwjoWTUpPSd?b=&sliR6qt&>W%*1D%m$NS>BNOZ>WuaL+ZDw=a%ugIoqxhoO$i zPT7Ip&JOh1>l3g~w^?jVcxVAZ8$PIk`gn^Ic*!H^URYH!r*tQ3yJ=+Z`dpMqp7Gq=oE`nlZHw)q z<}8`Pyv9Ty7BW^A+L-Fd;#SWMUWE3$YX$SzC9eC9%Tsndasz)S=<92=XoJ-|7oJLw z{ubjnFh|C`N(Vmp@h9Zzu?)~L%jvq8Fy|4~qlIEtuefH^p6h8iEpuL&)dX@RGsN9F z`N);~?C60q#6BxMSIPP{#5UbJp5PceOX}Lf{8tqHgB#sJ!AgJ^y4)AOy<2b!$cE8t%=oOIDMpsA~@74TSHqZwM`NJLD9VqXm`O76C)V;u~ zRZEY*_`}3`kgxeg8yII7;h9nLG|;s=vi7XrsO$6fLN-&V7xe|#?6KXt9?95quH7GD z)A{Y2ocy^Uxcj0H_yc`-JoMifd%DEn8K5(EA=JU=ucIf&ylJtPPZ13ae}EbQrV zV26r&v4U421KtMG8GFGj7VWNxQ_yGk`{d-P)Sm!n`72G`LEb*lp9=jK8G`zrYrqR+?Y^hyzW7cvbqA4f-Sr5ueUzLvaeN$c zN4~mq=gtS4q#5s%SFUt3c+fwz)XZ9+$XWABkh2YCQFBE14o3Rk8(kf|4|{N)uJ1bFF9hp%-l;Rvb+;eJ;5k1mnn*vn zRR5`tmENP7u0(G#8I97WR;;HNeh)bt=Pb5U&1rCd;(_ZHiyEwno#Y`YP z=)oSiJ!{S?@Z$sdh<6zNiBL0eLe3l2ve3@Qxsb|0^hxP~+r$6B&T?ARtbF0Q@`N77 z;R&Z;nSQP}xQPjUTE$82e&nx658Oi1fxoe{+C1BsAngAEz5qf00MAd3Cq<=4x Z{{;$xH 0 && tarr[rule] != nil && !override { + return &ErrConflictingTranslation{locale: t.Locale(), key: key, rule: rule, text: text} + } + + } else { + tarr = make([]*transText, 7) + t.cardinalTanslations[key] = tarr + } + + trans := &transText{ + text: text, + indexes: make([]int, 2), + } + + tarr[rule] = trans + + idx := strings.Index(text, paramZero) + if idx == -1 { + tarr[rule] = nil + return &ErrCardinalTranslation{text: fmt.Sprintf("error: parameter '%s' not found, may want to use 'Add' instead of 'AddCardinal'. locale: '%s' key: '%v' text: '%s'", paramZero, t.Locale(), key, text)} + } + + trans.indexes[0] = idx + trans.indexes[1] = idx + len(paramZero) + + return nil +} + +// AddOrdinal adds an ordinal plural translation for a particular language/locale +// {0} is the only replacement type accepted and only one variable is accepted as +// multiple cannot be used for a plural rule determination, unless it is a range; +// see AddRange below. +// eg. in locale 'en' one: '{0}st day of spring' other: '{0}nd day of spring' - 1st, 2nd, 3rd... +func (t *translator) AddOrdinal(key interface{}, text string, rule locales.PluralRule, override bool) error { + + var verified bool + + // verify plural rule exists for locale + for _, pr := range t.PluralsOrdinal() { + if pr == rule { + verified = true + break + } + } + + if !verified { + return &ErrOrdinalTranslation{text: fmt.Sprintf("error: ordinal plural rule '%s' does not exist for locale '%s' key: '%v' text: '%s'", rule, t.Locale(), key, text)} + } + + tarr, ok := t.ordinalTanslations[key] + if ok { + // verify not adding a conflicting record + if len(tarr) > 0 && tarr[rule] != nil && !override { + return &ErrConflictingTranslation{locale: t.Locale(), key: key, rule: rule, text: text} + } + + } else { + tarr = make([]*transText, 7) + t.ordinalTanslations[key] = tarr + } + + trans := &transText{ + text: text, + indexes: make([]int, 2), + } + + tarr[rule] = trans + + idx := strings.Index(text, paramZero) + if idx == -1 { + tarr[rule] = nil + return &ErrOrdinalTranslation{text: fmt.Sprintf("error: parameter '%s' not found, may want to use 'Add' instead of 'AddOrdinal'. locale: '%s' key: '%v' text: '%s'", paramZero, t.Locale(), key, text)} + } + + trans.indexes[0] = idx + trans.indexes[1] = idx + len(paramZero) + + return nil +} + +// AddRange adds a range plural translation for a particular language/locale +// {0} and {1} are the only replacement types accepted and only these are accepted. +// eg. in locale 'nl' one: '{0}-{1} day left' other: '{0}-{1} days left' +func (t *translator) AddRange(key interface{}, text string, rule locales.PluralRule, override bool) error { + + var verified bool + + // verify plural rule exists for locale + for _, pr := range t.PluralsRange() { + if pr == rule { + verified = true + break + } + } + + if !verified { + return &ErrRangeTranslation{text: fmt.Sprintf("error: range plural rule '%s' does not exist for locale '%s' key: '%v' text: '%s'", rule, t.Locale(), key, text)} + } + + tarr, ok := t.rangeTanslations[key] + if ok { + // verify not adding a conflicting record + if len(tarr) > 0 && tarr[rule] != nil && !override { + return &ErrConflictingTranslation{locale: t.Locale(), key: key, rule: rule, text: text} + } + + } else { + tarr = make([]*transText, 7) + t.rangeTanslations[key] = tarr + } + + trans := &transText{ + text: text, + indexes: make([]int, 4), + } + + tarr[rule] = trans + + idx := strings.Index(text, paramZero) + if idx == -1 { + tarr[rule] = nil + return &ErrRangeTranslation{text: fmt.Sprintf("error: parameter '%s' not found, are you sure you're adding a Range Translation? locale: '%s' key: '%v' text: '%s'", paramZero, t.Locale(), key, text)} + } + + trans.indexes[0] = idx + trans.indexes[1] = idx + len(paramZero) + + idx = strings.Index(text, paramOne) + if idx == -1 { + tarr[rule] = nil + return &ErrRangeTranslation{text: fmt.Sprintf("error: parameter '%s' not found, a Range Translation requires two parameters. locale: '%s' key: '%v' text: '%s'", paramOne, t.Locale(), key, text)} + } + + trans.indexes[2] = idx + trans.indexes[3] = idx + len(paramOne) + + return nil +} + +// T creates the translation for the locale given the 'key' and params passed in +func (t *translator) T(key interface{}, params ...string) (string, error) { + + trans, ok := t.translations[key] + if !ok { + return unknownTranslation, ErrUnknowTranslation + } + + b := make([]byte, 0, 64) + + var start, end, count int + + for i := 0; i < len(trans.indexes); i++ { + end = trans.indexes[i] + b = append(b, trans.text[start:end]...) + b = append(b, params[count]...) + i++ + start = trans.indexes[i] + count++ + } + + b = append(b, trans.text[start:]...) + + return string(b), nil +} + +// C creates the cardinal translation for the locale given the 'key', 'num' and 'digit' arguments and param passed in +func (t *translator) C(key interface{}, num float64, digits uint64, param string) (string, error) { + + tarr, ok := t.cardinalTanslations[key] + if !ok { + return unknownTranslation, ErrUnknowTranslation + } + + rule := t.CardinalPluralRule(num, digits) + + trans := tarr[rule] + + b := make([]byte, 0, 64) + b = append(b, trans.text[:trans.indexes[0]]...) + b = append(b, param...) + b = append(b, trans.text[trans.indexes[1]:]...) + + return string(b), nil +} + +// O creates the ordinal translation for the locale given the 'key', 'num' and 'digit' arguments and param passed in +func (t *translator) O(key interface{}, num float64, digits uint64, param string) (string, error) { + + tarr, ok := t.ordinalTanslations[key] + if !ok { + return unknownTranslation, ErrUnknowTranslation + } + + rule := t.OrdinalPluralRule(num, digits) + + trans := tarr[rule] + + b := make([]byte, 0, 64) + b = append(b, trans.text[:trans.indexes[0]]...) + b = append(b, param...) + b = append(b, trans.text[trans.indexes[1]:]...) + + return string(b), nil +} + +// R creates the range translation for the locale given the 'key', 'num1', 'digit1', 'num2' and 'digit2' arguments +// and 'param1' and 'param2' passed in +func (t *translator) R(key interface{}, num1 float64, digits1 uint64, num2 float64, digits2 uint64, param1, param2 string) (string, error) { + + tarr, ok := t.rangeTanslations[key] + if !ok { + return unknownTranslation, ErrUnknowTranslation + } + + rule := t.RangePluralRule(num1, digits1, num2, digits2) + + trans := tarr[rule] + + b := make([]byte, 0, 64) + b = append(b, trans.text[:trans.indexes[0]]...) + b = append(b, param1...) + b = append(b, trans.text[trans.indexes[1]:trans.indexes[2]]...) + b = append(b, param2...) + b = append(b, trans.text[trans.indexes[3]:]...) + + return string(b), nil +} + +// VerifyTranslations checks to ensures that no plural rules have been +// missed within the translations. +func (t *translator) VerifyTranslations() error { + + for k, v := range t.cardinalTanslations { + + for _, rule := range t.PluralsCardinal() { + + if v[rule] == nil { + return &ErrMissingPluralTranslation{locale: t.Locale(), translationType: "plural", rule: rule, key: k} + } + } + } + + for k, v := range t.ordinalTanslations { + + for _, rule := range t.PluralsOrdinal() { + + if v[rule] == nil { + return &ErrMissingPluralTranslation{locale: t.Locale(), translationType: "ordinal", rule: rule, key: k} + } + } + } + + for k, v := range t.rangeTanslations { + + for _, rule := range t.PluralsRange() { + + if v[rule] == nil { + return &ErrMissingPluralTranslation{locale: t.Locale(), translationType: "range", rule: rule, key: k} + } + } + } + + return nil +} diff --git a/vendor/github.com/go-playground/universal-translator/universal_translator.go b/vendor/github.com/go-playground/universal-translator/universal_translator.go new file mode 100644 index 0000000..dbf707f --- /dev/null +++ b/vendor/github.com/go-playground/universal-translator/universal_translator.go @@ -0,0 +1,113 @@ +package ut + +import ( + "strings" + + "github.com/go-playground/locales" +) + +// UniversalTranslator holds all locale & translation data +type UniversalTranslator struct { + translators map[string]Translator + fallback Translator +} + +// New returns a new UniversalTranslator instance set with +// the fallback locale and locales it should support +func New(fallback locales.Translator, supportedLocales ...locales.Translator) *UniversalTranslator { + + t := &UniversalTranslator{ + translators: make(map[string]Translator), + } + + for _, v := range supportedLocales { + + trans := newTranslator(v) + t.translators[strings.ToLower(trans.Locale())] = trans + + if fallback.Locale() == v.Locale() { + t.fallback = trans + } + } + + if t.fallback == nil && fallback != nil { + t.fallback = newTranslator(fallback) + } + + return t +} + +// FindTranslator trys to find a Translator based on an array of locales +// and returns the first one it can find, otherwise returns the +// fallback translator. +func (t *UniversalTranslator) FindTranslator(locales ...string) (trans Translator, found bool) { + + for _, locale := range locales { + + if trans, found = t.translators[strings.ToLower(locale)]; found { + return + } + } + + return t.fallback, false +} + +// GetTranslator returns the specified translator for the given locale, +// or fallback if not found +func (t *UniversalTranslator) GetTranslator(locale string) (trans Translator, found bool) { + + if trans, found = t.translators[strings.ToLower(locale)]; found { + return + } + + return t.fallback, false +} + +// GetFallback returns the fallback locale +func (t *UniversalTranslator) GetFallback() Translator { + return t.fallback +} + +// AddTranslator adds the supplied translator, if it already exists the override param +// will be checked and if false an error will be returned, otherwise the translator will be +// overridden; if the fallback matches the supplied translator it will be overridden as well +// NOTE: this is normally only used when translator is embedded within a library +func (t *UniversalTranslator) AddTranslator(translator locales.Translator, override bool) error { + + lc := strings.ToLower(translator.Locale()) + _, ok := t.translators[lc] + if ok && !override { + return &ErrExistingTranslator{locale: translator.Locale()} + } + + trans := newTranslator(translator) + + if t.fallback.Locale() == translator.Locale() { + + // because it's optional to have a fallback, I don't impose that limitation + // don't know why you wouldn't but... + if !override { + return &ErrExistingTranslator{locale: translator.Locale()} + } + + t.fallback = trans + } + + t.translators[lc] = trans + + return nil +} + +// VerifyTranslations runs through all locales and identifies any issues +// eg. missing plural rules for a locale +func (t *UniversalTranslator) VerifyTranslations() (err error) { + + for _, trans := range t.translators { + err = trans.VerifyTranslations() + if err != nil { + return + } + } + + return +} diff --git a/vendor/github.com/go-playground/validator/v10/.gitignore b/vendor/github.com/go-playground/validator/v10/.gitignore new file mode 100644 index 0000000..6e43fac --- /dev/null +++ b/vendor/github.com/go-playground/validator/v10/.gitignore @@ -0,0 +1,30 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test +bin + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof +*.test +*.out +*.txt +cover.html +README.html diff --git a/vendor/github.com/go-playground/validator/v10/LICENSE b/vendor/github.com/go-playground/validator/v10/LICENSE new file mode 100644 index 0000000..6a2ae9a --- /dev/null +++ b/vendor/github.com/go-playground/validator/v10/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Dean Karn + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/vendor/github.com/go-playground/validator/v10/MAINTAINERS.md b/vendor/github.com/go-playground/validator/v10/MAINTAINERS.md new file mode 100644 index 0000000..b809c4c --- /dev/null +++ b/vendor/github.com/go-playground/validator/v10/MAINTAINERS.md @@ -0,0 +1,16 @@ +## Maintainers Guide + +### Semantic Versioning +Semantic versioning as defined [here](https://semver.org) must be strictly adhered to. + +### External Dependencies +Any new external dependencies MUST: +- Have a compatible LICENSE present. +- Be actively maintained. +- Be approved by @go-playground/admins + +### PR Merge Requirements +- Up-to-date branch. +- Passing tests and linting. +- CODEOWNERS approval. +- Tests that cover both the Happy and Unhappy paths. \ No newline at end of file diff --git a/vendor/github.com/go-playground/validator/v10/Makefile b/vendor/github.com/go-playground/validator/v10/Makefile new file mode 100644 index 0000000..ec3455b --- /dev/null +++ b/vendor/github.com/go-playground/validator/v10/Makefile @@ -0,0 +1,18 @@ +GOCMD=GO111MODULE=on go + +linters-install: + @golangci-lint --version >/dev/null 2>&1 || { \ + echo "installing linting tools..."; \ + curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s v1.41.1; \ + } + +lint: linters-install + golangci-lint run + +test: + $(GOCMD) test -cover -race ./... + +bench: + $(GOCMD) test -bench=. -benchmem ./... + +.PHONY: test lint linters-install \ No newline at end of file diff --git a/vendor/github.com/go-playground/validator/v10/README.md b/vendor/github.com/go-playground/validator/v10/README.md new file mode 100644 index 0000000..6712e95 --- /dev/null +++ b/vendor/github.com/go-playground/validator/v10/README.md @@ -0,0 +1,325 @@ +Package validator +================= +[![Join the chat at https://gitter.im/go-playground/validator](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/go-playground/validator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +![Project status](https://img.shields.io/badge/version-10.10.1-green.svg) +[![Build Status](https://travis-ci.org/go-playground/validator.svg?branch=master)](https://travis-ci.org/go-playground/validator) +[![Coverage Status](https://coveralls.io/repos/go-playground/validator/badge.svg?branch=master&service=github)](https://coveralls.io/github/go-playground/validator?branch=master) +[![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/validator)](https://goreportcard.com/report/github.com/go-playground/validator) +[![GoDoc](https://godoc.org/github.com/go-playground/validator?status.svg)](https://pkg.go.dev/github.com/go-playground/validator/v10) +![License](https://img.shields.io/dub/l/vibe-d.svg) + +Package validator implements value validations for structs and individual fields based on tags. + +It has the following **unique** features: + +- Cross Field and Cross Struct validations by using validation tags or custom validators. +- Slice, Array and Map diving, which allows any or all levels of a multidimensional field to be validated. +- Ability to dive into both map keys and values for validation +- Handles type interface by determining it's underlying type prior to validation. +- Handles custom field types such as sql driver Valuer see [Valuer](https://golang.org/src/database/sql/driver/types.go?s=1210:1293#L29) +- Alias validation tags, which allows for mapping of several validations to a single tag for easier defining of validations on structs +- Extraction of custom defined Field Name e.g. can specify to extract the JSON name while validating and have it available in the resulting FieldError +- Customizable i18n aware error messages. +- Default validator for the [gin](https://github.com/gin-gonic/gin) web framework; upgrading from v8 to v9 in gin see [here](https://github.com/go-playground/validator/tree/master/_examples/gin-upgrading-overriding) + +Installation +------------ + +Use go get. + + go get github.com/go-playground/validator/v10 + +Then import the validator package into your own code. + + import "github.com/go-playground/validator/v10" + +Error Return Value +------- + +Validation functions return type error + +They return type error to avoid the issue discussed in the following, where err is always != nil: + +* http://stackoverflow.com/a/29138676/3158232 +* https://github.com/go-playground/validator/issues/134 + +Validator returns only InvalidValidationError for bad validation input, nil or ValidationErrors as type error; so, in your code all you need to do is check if the error returned is not nil, and if it's not check if error is InvalidValidationError ( if necessary, most of the time it isn't ) type cast it to type ValidationErrors like so: + +```go +err := validate.Struct(mystruct) +validationErrors := err.(validator.ValidationErrors) + ``` + +Usage and documentation +------ + +Please see https://pkg.go.dev/github.com/go-playground/validator/v10 for detailed usage docs. + +##### Examples: + +- [Simple](https://github.com/go-playground/validator/blob/master/_examples/simple/main.go) +- [Custom Field Types](https://github.com/go-playground/validator/blob/master/_examples/custom/main.go) +- [Struct Level](https://github.com/go-playground/validator/blob/master/_examples/struct-level/main.go) +- [Translations & Custom Errors](https://github.com/go-playground/validator/blob/master/_examples/translations/main.go) +- [Gin upgrade and/or override validator](https://github.com/go-playground/validator/tree/v9/_examples/gin-upgrading-overriding) +- [wash - an example application putting it all together](https://github.com/bluesuncorp/wash) + +Baked-in Validations +------ + +### Fields: + +| Tag | Description | +| - | - | +| eqcsfield | Field Equals Another Field (relative)| +| eqfield | Field Equals Another Field | +| fieldcontains | NOT DOCUMENTED IN doc.go | +| fieldexcludes | NOT DOCUMENTED IN doc.go | +| gtcsfield | Field Greater Than Another Relative Field | +| gtecsfield | Field Greater Than or Equal To Another Relative Field | +| gtefield | Field Greater Than or Equal To Another Field | +| gtfield | Field Greater Than Another Field | +| ltcsfield | Less Than Another Relative Field | +| ltecsfield | Less Than or Equal To Another Relative Field | +| ltefield | Less Than or Equal To Another Field | +| ltfield | Less Than Another Field | +| necsfield | Field Does Not Equal Another Field (relative) | +| nefield | Field Does Not Equal Another Field | + +### Network: + +| Tag | Description | +| - | - | +| cidr | Classless Inter-Domain Routing CIDR | +| cidrv4 | Classless Inter-Domain Routing CIDRv4 | +| cidrv6 | Classless Inter-Domain Routing CIDRv6 | +| datauri | Data URL | +| fqdn | Full Qualified Domain Name (FQDN) | +| hostname | Hostname RFC 952 | +| hostname_port | HostPort | +| hostname_rfc1123 | Hostname RFC 1123 | +| ip | Internet Protocol Address IP | +| ip4_addr | Internet Protocol Address IPv4 | +| ip6_addr | Internet Protocol Address IPv6 | +| ip_addr | Internet Protocol Address IP | +| ipv4 | Internet Protocol Address IPv4 | +| ipv6 | Internet Protocol Address IPv6 | +| mac | Media Access Control Address MAC | +| tcp4_addr | Transmission Control Protocol Address TCPv4 | +| tcp6_addr | Transmission Control Protocol Address TCPv6 | +| tcp_addr | Transmission Control Protocol Address TCP | +| udp4_addr | User Datagram Protocol Address UDPv4 | +| udp6_addr | User Datagram Protocol Address UDPv6 | +| udp_addr | User Datagram Protocol Address UDP | +| unix_addr | Unix domain socket end point Address | +| uri | URI String | +| url | URL String | +| url_encoded | URL Encoded | +| urn_rfc2141 | Urn RFC 2141 String | + +### Strings: + +| Tag | Description | +| - | - | +| alpha | Alpha Only | +| alphanum | Alphanumeric | +| alphanumunicode | Alphanumeric Unicode | +| alphaunicode | Alpha Unicode | +| ascii | ASCII | +| boolean | Boolean | +| contains | Contains | +| containsany | Contains Any | +| containsrune | Contains Rune | +| endsnotwith | Ends With | +| endswith | Ends With | +| excludes | Excludes | +| excludesall | Excludes All | +| excludesrune | Excludes Rune | +| lowercase | Lowercase | +| multibyte | Multi-Byte Characters | +| number | NOT DOCUMENTED IN doc.go | +| numeric | Numeric | +| printascii | Printable ASCII | +| startsnotwith | Starts Not With | +| startswith | Starts With | +| uppercase | Uppercase | + +### Format: +| Tag | Description | +| - | - | +| base64 | Base64 String | +| base64url | Base64URL String | +| bic | Business Identifier Code (ISO 9362) | +| bcp47_language_tag | Language tag (BCP 47) | +| btc_addr | Bitcoin Address | +| btc_addr_bech32 | Bitcoin Bech32 Address (segwit) | +| datetime | Datetime | +| e164 | e164 formatted phone number | +| email | E-mail String +| eth_addr | Ethereum Address | +| hexadecimal | Hexadecimal String | +| hexcolor | Hexcolor String | +| hsl | HSL String | +| hsla | HSLA String | +| html | HTML Tags | +| html_encoded | HTML Encoded | +| isbn | International Standard Book Number | +| isbn10 | International Standard Book Number 10 | +| isbn13 | International Standard Book Number 13 | +| iso3166_1_alpha2 | Two-letter country code (ISO 3166-1 alpha-2) | +| iso3166_1_alpha3 | Three-letter country code (ISO 3166-1 alpha-3) | +| iso3166_1_alpha_numeric | Numeric country code (ISO 3166-1 numeric) | +| iso3166_2 | Country subdivision code (ISO 3166-2) | +| iso4217 | Currency code (ISO 4217) | +| json | JSON | +| jwt | JSON Web Token (JWT) | +| latitude | Latitude | +| longitude | Longitude | +| postcode_iso3166_alpha2 | Postcode | +| postcode_iso3166_alpha2_field | Postcode | +| rgb | RGB String | +| rgba | RGBA String | +| ssn | Social Security Number SSN | +| timezone | Timezone | +| uuid | Universally Unique Identifier UUID | +| uuid3 | Universally Unique Identifier UUID v3 | +| uuid3_rfc4122 | Universally Unique Identifier UUID v3 RFC4122 | +| uuid4 | Universally Unique Identifier UUID v4 | +| uuid4_rfc4122 | Universally Unique Identifier UUID v4 RFC4122 | +| uuid5 | Universally Unique Identifier UUID v5 | +| uuid5_rfc4122 | Universally Unique Identifier UUID v5 RFC4122 | +| uuid_rfc4122 | Universally Unique Identifier UUID RFC4122 | +| semver | Semantic Versioning 2.0.0 | +| ulid | Universally Unique Lexicographically Sortable Identifier ULID | + +### Comparisons: +| Tag | Description | +| - | - | +| eq | Equals | +| gt | Greater than| +| gte | Greater than or equal | +| lt | Less Than | +| lte | Less Than or Equal | +| ne | Not Equal | + +### Other: +| Tag | Description | +| - | - | +| dir | Directory | +| file | File path | +| isdefault | Is Default | +| len | Length | +| max | Maximum | +| min | Minimum | +| oneof | One Of | +| required | Required | +| required_if | Required If | +| required_unless | Required Unless | +| required_with | Required With | +| required_with_all | Required With All | +| required_without | Required Without | +| required_without_all | Required Without All | +| excluded_with | Excluded With | +| excluded_with_all | Excluded With All | +| excluded_without | Excluded Without | +| excluded_without_all | Excluded Without All | +| unique | Unique | + +#### Aliases: +| Tag | Description | +| - | - | +| iscolor | hexcolor\|rgb\|rgba\|hsl\|hsla | +| country_code | iso3166_1_alpha2\|iso3166_1_alpha3\|iso3166_1_alpha_numeric | + +Benchmarks +------ +###### Run on MacBook Pro (15-inch, 2017) go version go1.10.2 darwin/amd64 +```go +goos: darwin +goarch: amd64 +pkg: github.com/go-playground/validator +BenchmarkFieldSuccess-8 20000000 83.6 ns/op 0 B/op 0 allocs/op +BenchmarkFieldSuccessParallel-8 50000000 26.8 ns/op 0 B/op 0 allocs/op +BenchmarkFieldFailure-8 5000000 291 ns/op 208 B/op 4 allocs/op +BenchmarkFieldFailureParallel-8 20000000 107 ns/op 208 B/op 4 allocs/op +BenchmarkFieldArrayDiveSuccess-8 2000000 623 ns/op 201 B/op 11 allocs/op +BenchmarkFieldArrayDiveSuccessParallel-8 10000000 237 ns/op 201 B/op 11 allocs/op +BenchmarkFieldArrayDiveFailure-8 2000000 859 ns/op 412 B/op 16 allocs/op +BenchmarkFieldArrayDiveFailureParallel-8 5000000 335 ns/op 413 B/op 16 allocs/op +BenchmarkFieldMapDiveSuccess-8 1000000 1292 ns/op 432 B/op 18 allocs/op +BenchmarkFieldMapDiveSuccessParallel-8 3000000 467 ns/op 432 B/op 18 allocs/op +BenchmarkFieldMapDiveFailure-8 1000000 1082 ns/op 512 B/op 16 allocs/op +BenchmarkFieldMapDiveFailureParallel-8 5000000 425 ns/op 512 B/op 16 allocs/op +BenchmarkFieldMapDiveWithKeysSuccess-8 1000000 1539 ns/op 480 B/op 21 allocs/op +BenchmarkFieldMapDiveWithKeysSuccessParallel-8 3000000 613 ns/op 480 B/op 21 allocs/op +BenchmarkFieldMapDiveWithKeysFailure-8 1000000 1413 ns/op 721 B/op 21 allocs/op +BenchmarkFieldMapDiveWithKeysFailureParallel-8 3000000 575 ns/op 721 B/op 21 allocs/op +BenchmarkFieldCustomTypeSuccess-8 10000000 216 ns/op 32 B/op 2 allocs/op +BenchmarkFieldCustomTypeSuccessParallel-8 20000000 82.2 ns/op 32 B/op 2 allocs/op +BenchmarkFieldCustomTypeFailure-8 5000000 274 ns/op 208 B/op 4 allocs/op +BenchmarkFieldCustomTypeFailureParallel-8 20000000 116 ns/op 208 B/op 4 allocs/op +BenchmarkFieldOrTagSuccess-8 2000000 740 ns/op 16 B/op 1 allocs/op +BenchmarkFieldOrTagSuccessParallel-8 3000000 474 ns/op 16 B/op 1 allocs/op +BenchmarkFieldOrTagFailure-8 3000000 471 ns/op 224 B/op 5 allocs/op +BenchmarkFieldOrTagFailureParallel-8 3000000 414 ns/op 224 B/op 5 allocs/op +BenchmarkStructLevelValidationSuccess-8 10000000 213 ns/op 32 B/op 2 allocs/op +BenchmarkStructLevelValidationSuccessParallel-8 20000000 91.8 ns/op 32 B/op 2 allocs/op +BenchmarkStructLevelValidationFailure-8 3000000 473 ns/op 304 B/op 8 allocs/op +BenchmarkStructLevelValidationFailureParallel-8 10000000 234 ns/op 304 B/op 8 allocs/op +BenchmarkStructSimpleCustomTypeSuccess-8 5000000 385 ns/op 32 B/op 2 allocs/op +BenchmarkStructSimpleCustomTypeSuccessParallel-8 10000000 161 ns/op 32 B/op 2 allocs/op +BenchmarkStructSimpleCustomTypeFailure-8 2000000 640 ns/op 424 B/op 9 allocs/op +BenchmarkStructSimpleCustomTypeFailureParallel-8 5000000 318 ns/op 440 B/op 10 allocs/op +BenchmarkStructFilteredSuccess-8 2000000 597 ns/op 288 B/op 9 allocs/op +BenchmarkStructFilteredSuccessParallel-8 10000000 266 ns/op 288 B/op 9 allocs/op +BenchmarkStructFilteredFailure-8 3000000 454 ns/op 256 B/op 7 allocs/op +BenchmarkStructFilteredFailureParallel-8 10000000 214 ns/op 256 B/op 7 allocs/op +BenchmarkStructPartialSuccess-8 3000000 502 ns/op 256 B/op 6 allocs/op +BenchmarkStructPartialSuccessParallel-8 10000000 225 ns/op 256 B/op 6 allocs/op +BenchmarkStructPartialFailure-8 2000000 702 ns/op 480 B/op 11 allocs/op +BenchmarkStructPartialFailureParallel-8 5000000 329 ns/op 480 B/op 11 allocs/op +BenchmarkStructExceptSuccess-8 2000000 793 ns/op 496 B/op 12 allocs/op +BenchmarkStructExceptSuccessParallel-8 10000000 193 ns/op 240 B/op 5 allocs/op +BenchmarkStructExceptFailure-8 2000000 639 ns/op 464 B/op 10 allocs/op +BenchmarkStructExceptFailureParallel-8 5000000 300 ns/op 464 B/op 10 allocs/op +BenchmarkStructSimpleCrossFieldSuccess-8 3000000 417 ns/op 72 B/op 3 allocs/op +BenchmarkStructSimpleCrossFieldSuccessParallel-8 10000000 163 ns/op 72 B/op 3 allocs/op +BenchmarkStructSimpleCrossFieldFailure-8 2000000 645 ns/op 304 B/op 8 allocs/op +BenchmarkStructSimpleCrossFieldFailureParallel-8 5000000 285 ns/op 304 B/op 8 allocs/op +BenchmarkStructSimpleCrossStructCrossFieldSuccess-8 3000000 588 ns/op 80 B/op 4 allocs/op +BenchmarkStructSimpleCrossStructCrossFieldSuccessParallel-8 10000000 221 ns/op 80 B/op 4 allocs/op +BenchmarkStructSimpleCrossStructCrossFieldFailure-8 2000000 868 ns/op 320 B/op 9 allocs/op +BenchmarkStructSimpleCrossStructCrossFieldFailureParallel-8 5000000 337 ns/op 320 B/op 9 allocs/op +BenchmarkStructSimpleSuccess-8 5000000 260 ns/op 0 B/op 0 allocs/op +BenchmarkStructSimpleSuccessParallel-8 20000000 90.6 ns/op 0 B/op 0 allocs/op +BenchmarkStructSimpleFailure-8 2000000 619 ns/op 424 B/op 9 allocs/op +BenchmarkStructSimpleFailureParallel-8 5000000 296 ns/op 424 B/op 9 allocs/op +BenchmarkStructComplexSuccess-8 1000000 1454 ns/op 128 B/op 8 allocs/op +BenchmarkStructComplexSuccessParallel-8 3000000 579 ns/op 128 B/op 8 allocs/op +BenchmarkStructComplexFailure-8 300000 4140 ns/op 3041 B/op 53 allocs/op +BenchmarkStructComplexFailureParallel-8 1000000 2127 ns/op 3041 B/op 53 allocs/op +BenchmarkOneof-8 10000000 140 ns/op 0 B/op 0 allocs/op +BenchmarkOneofParallel-8 20000000 70.1 ns/op 0 B/op 0 allocs/op +``` + +Complementary Software +---------------------- + +Here is a list of software that complements using this library either pre or post validation. + +* [form](https://github.com/go-playground/form) - Decodes url.Values into Go value(s) and Encodes Go value(s) into url.Values. Dual Array and Full map support. +* [mold](https://github.com/go-playground/mold) - A general library to help modify or set data within data structures and other objects + +How to Contribute +------ + +Make a pull request... + +License +------- +Distributed under MIT License, please see license file within the code for more details. + +Maintainers +----------- +This project has grown large enough that more than one person is required to properly support the community. +If you are interested in becoming a maintainer please reach out to me https://github.com/deankarn diff --git a/vendor/github.com/go-playground/validator/v10/baked_in.go b/vendor/github.com/go-playground/validator/v10/baked_in.go new file mode 100644 index 0000000..7868b66 --- /dev/null +++ b/vendor/github.com/go-playground/validator/v10/baked_in.go @@ -0,0 +1,2438 @@ +package validator + +import ( + "bytes" + "context" + "crypto/sha256" + "encoding/hex" + "encoding/json" + "fmt" + "net" + "net/url" + "os" + "reflect" + "strconv" + "strings" + "sync" + "time" + "unicode/utf8" + + "golang.org/x/crypto/sha3" + "golang.org/x/text/language" + + urn "github.com/leodido/go-urn" +) + +// Func accepts a FieldLevel interface for all validation needs. The return +// value should be true when validation succeeds. +type Func func(fl FieldLevel) bool + +// FuncCtx accepts a context.Context and FieldLevel interface for all +// validation needs. The return value should be true when validation succeeds. +type FuncCtx func(ctx context.Context, fl FieldLevel) bool + +// wrapFunc wraps noramal Func makes it compatible with FuncCtx +func wrapFunc(fn Func) FuncCtx { + if fn == nil { + return nil // be sure not to wrap a bad function. + } + return func(ctx context.Context, fl FieldLevel) bool { + return fn(fl) + } +} + +var ( + restrictedTags = map[string]struct{}{ + diveTag: {}, + keysTag: {}, + endKeysTag: {}, + structOnlyTag: {}, + omitempty: {}, + skipValidationTag: {}, + utf8HexComma: {}, + utf8Pipe: {}, + noStructLevelTag: {}, + requiredTag: {}, + isdefault: {}, + } + + // bakedInAliases is a default mapping of a single validation tag that + // defines a common or complex set of validation(s) to simplify + // adding validation to structs. + bakedInAliases = map[string]string{ + "iscolor": "hexcolor|rgb|rgba|hsl|hsla", + "country_code": "iso3166_1_alpha2|iso3166_1_alpha3|iso3166_1_alpha_numeric", + } + + // bakedInValidators is the default map of ValidationFunc + // you can add, remove or even replace items to suite your needs, + // or even disregard and use your own map if so desired. + bakedInValidators = map[string]Func{ + "required": hasValue, + "required_if": requiredIf, + "required_unless": requiredUnless, + "required_with": requiredWith, + "required_with_all": requiredWithAll, + "required_without": requiredWithout, + "required_without_all": requiredWithoutAll, + "excluded_with": excludedWith, + "excluded_with_all": excludedWithAll, + "excluded_without": excludedWithout, + "excluded_without_all": excludedWithoutAll, + "isdefault": isDefault, + "len": hasLengthOf, + "min": hasMinOf, + "max": hasMaxOf, + "eq": isEq, + "ne": isNe, + "lt": isLt, + "lte": isLte, + "gt": isGt, + "gte": isGte, + "eqfield": isEqField, + "eqcsfield": isEqCrossStructField, + "necsfield": isNeCrossStructField, + "gtcsfield": isGtCrossStructField, + "gtecsfield": isGteCrossStructField, + "ltcsfield": isLtCrossStructField, + "ltecsfield": isLteCrossStructField, + "nefield": isNeField, + "gtefield": isGteField, + "gtfield": isGtField, + "ltefield": isLteField, + "ltfield": isLtField, + "fieldcontains": fieldContains, + "fieldexcludes": fieldExcludes, + "alpha": isAlpha, + "alphanum": isAlphanum, + "alphaunicode": isAlphaUnicode, + "alphanumunicode": isAlphanumUnicode, + "boolean": isBoolean, + "numeric": isNumeric, + "number": isNumber, + "hexadecimal": isHexadecimal, + "hexcolor": isHEXColor, + "rgb": isRGB, + "rgba": isRGBA, + "hsl": isHSL, + "hsla": isHSLA, + "e164": isE164, + "email": isEmail, + "url": isURL, + "uri": isURI, + "urn_rfc2141": isUrnRFC2141, // RFC 2141 + "file": isFile, + "base64": isBase64, + "base64url": isBase64URL, + "contains": contains, + "containsany": containsAny, + "containsrune": containsRune, + "excludes": excludes, + "excludesall": excludesAll, + "excludesrune": excludesRune, + "startswith": startsWith, + "endswith": endsWith, + "startsnotwith": startsNotWith, + "endsnotwith": endsNotWith, + "isbn": isISBN, + "isbn10": isISBN10, + "isbn13": isISBN13, + "eth_addr": isEthereumAddress, + "btc_addr": isBitcoinAddress, + "btc_addr_bech32": isBitcoinBech32Address, + "uuid": isUUID, + "uuid3": isUUID3, + "uuid4": isUUID4, + "uuid5": isUUID5, + "uuid_rfc4122": isUUIDRFC4122, + "uuid3_rfc4122": isUUID3RFC4122, + "uuid4_rfc4122": isUUID4RFC4122, + "uuid5_rfc4122": isUUID5RFC4122, + "ulid": isULID, + "ascii": isASCII, + "printascii": isPrintableASCII, + "multibyte": hasMultiByteCharacter, + "datauri": isDataURI, + "latitude": isLatitude, + "longitude": isLongitude, + "ssn": isSSN, + "ipv4": isIPv4, + "ipv6": isIPv6, + "ip": isIP, + "cidrv4": isCIDRv4, + "cidrv6": isCIDRv6, + "cidr": isCIDR, + "tcp4_addr": isTCP4AddrResolvable, + "tcp6_addr": isTCP6AddrResolvable, + "tcp_addr": isTCPAddrResolvable, + "udp4_addr": isUDP4AddrResolvable, + "udp6_addr": isUDP6AddrResolvable, + "udp_addr": isUDPAddrResolvable, + "ip4_addr": isIP4AddrResolvable, + "ip6_addr": isIP6AddrResolvable, + "ip_addr": isIPAddrResolvable, + "unix_addr": isUnixAddrResolvable, + "mac": isMAC, + "hostname": isHostnameRFC952, // RFC 952 + "hostname_rfc1123": isHostnameRFC1123, // RFC 1123 + "fqdn": isFQDN, + "unique": isUnique, + "oneof": isOneOf, + "html": isHTML, + "html_encoded": isHTMLEncoded, + "url_encoded": isURLEncoded, + "dir": isDir, + "json": isJSON, + "jwt": isJWT, + "hostname_port": isHostnamePort, + "lowercase": isLowercase, + "uppercase": isUppercase, + "datetime": isDatetime, + "timezone": isTimeZone, + "iso3166_1_alpha2": isIso3166Alpha2, + "iso3166_1_alpha3": isIso3166Alpha3, + "iso3166_1_alpha_numeric": isIso3166AlphaNumeric, + "iso3166_2": isIso31662, + "iso4217": isIso4217, + "iso4217_numeric": isIso4217Numeric, + "bcp47_language_tag": isBCP47LanguageTag, + "postcode_iso3166_alpha2": isPostcodeByIso3166Alpha2, + "postcode_iso3166_alpha2_field": isPostcodeByIso3166Alpha2Field, + "bic": isIsoBicFormat, + "semver": isSemverFormat, + "dns_rfc1035_label": isDnsRFC1035LabelFormat, + } +) + +var oneofValsCache = map[string][]string{} +var oneofValsCacheRWLock = sync.RWMutex{} + +func parseOneOfParam2(s string) []string { + oneofValsCacheRWLock.RLock() + vals, ok := oneofValsCache[s] + oneofValsCacheRWLock.RUnlock() + if !ok { + oneofValsCacheRWLock.Lock() + vals = splitParamsRegex.FindAllString(s, -1) + for i := 0; i < len(vals); i++ { + vals[i] = strings.Replace(vals[i], "'", "", -1) + } + oneofValsCache[s] = vals + oneofValsCacheRWLock.Unlock() + } + return vals +} + +func isURLEncoded(fl FieldLevel) bool { + return uRLEncodedRegex.MatchString(fl.Field().String()) +} + +func isHTMLEncoded(fl FieldLevel) bool { + return hTMLEncodedRegex.MatchString(fl.Field().String()) +} + +func isHTML(fl FieldLevel) bool { + return hTMLRegex.MatchString(fl.Field().String()) +} + +func isOneOf(fl FieldLevel) bool { + vals := parseOneOfParam2(fl.Param()) + + field := fl.Field() + + var v string + switch field.Kind() { + case reflect.String: + v = field.String() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + v = strconv.FormatInt(field.Int(), 10) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + v = strconv.FormatUint(field.Uint(), 10) + default: + panic(fmt.Sprintf("Bad field type %T", field.Interface())) + } + for i := 0; i < len(vals); i++ { + if vals[i] == v { + return true + } + } + return false +} + +// isUnique is the validation function for validating if each array|slice|map value is unique +func isUnique(fl FieldLevel) bool { + + field := fl.Field() + param := fl.Param() + v := reflect.ValueOf(struct{}{}) + + switch field.Kind() { + case reflect.Slice, reflect.Array: + elem := field.Type().Elem() + if elem.Kind() == reflect.Ptr { + elem = elem.Elem() + } + + if param == "" { + m := reflect.MakeMap(reflect.MapOf(elem, v.Type())) + + for i := 0; i < field.Len(); i++ { + m.SetMapIndex(reflect.Indirect(field.Index(i)), v) + } + return field.Len() == m.Len() + } + + sf, ok := elem.FieldByName(param) + if !ok { + panic(fmt.Sprintf("Bad field name %s", param)) + } + + sfTyp := sf.Type + if sfTyp.Kind() == reflect.Ptr { + sfTyp = sfTyp.Elem() + } + + m := reflect.MakeMap(reflect.MapOf(sfTyp, v.Type())) + for i := 0; i < field.Len(); i++ { + m.SetMapIndex(reflect.Indirect(reflect.Indirect(field.Index(i)).FieldByName(param)), v) + } + return field.Len() == m.Len() + case reflect.Map: + m := reflect.MakeMap(reflect.MapOf(field.Type().Elem(), v.Type())) + + for _, k := range field.MapKeys() { + m.SetMapIndex(field.MapIndex(k), v) + } + return field.Len() == m.Len() + default: + panic(fmt.Sprintf("Bad field type %T", field.Interface())) + } +} + +// isMAC is the validation function for validating if the field's value is a valid MAC address. +func isMAC(fl FieldLevel) bool { + + _, err := net.ParseMAC(fl.Field().String()) + + return err == nil +} + +// isCIDRv4 is the validation function for validating if the field's value is a valid v4 CIDR address. +func isCIDRv4(fl FieldLevel) bool { + + ip, _, err := net.ParseCIDR(fl.Field().String()) + + return err == nil && ip.To4() != nil +} + +// isCIDRv6 is the validation function for validating if the field's value is a valid v6 CIDR address. +func isCIDRv6(fl FieldLevel) bool { + + ip, _, err := net.ParseCIDR(fl.Field().String()) + + return err == nil && ip.To4() == nil +} + +// isCIDR is the validation function for validating if the field's value is a valid v4 or v6 CIDR address. +func isCIDR(fl FieldLevel) bool { + + _, _, err := net.ParseCIDR(fl.Field().String()) + + return err == nil +} + +// isIPv4 is the validation function for validating if a value is a valid v4 IP address. +func isIPv4(fl FieldLevel) bool { + + ip := net.ParseIP(fl.Field().String()) + + return ip != nil && ip.To4() != nil +} + +// isIPv6 is the validation function for validating if the field's value is a valid v6 IP address. +func isIPv6(fl FieldLevel) bool { + + ip := net.ParseIP(fl.Field().String()) + + return ip != nil && ip.To4() == nil +} + +// isIP is the validation function for validating if the field's value is a valid v4 or v6 IP address. +func isIP(fl FieldLevel) bool { + + ip := net.ParseIP(fl.Field().String()) + + return ip != nil +} + +// isSSN is the validation function for validating if the field's value is a valid SSN. +func isSSN(fl FieldLevel) bool { + + field := fl.Field() + + if field.Len() != 11 { + return false + } + + return sSNRegex.MatchString(field.String()) +} + +// isLongitude is the validation function for validating if the field's value is a valid longitude coordinate. +func isLongitude(fl FieldLevel) bool { + field := fl.Field() + + var v string + switch field.Kind() { + case reflect.String: + v = field.String() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + v = strconv.FormatInt(field.Int(), 10) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + v = strconv.FormatUint(field.Uint(), 10) + case reflect.Float32: + v = strconv.FormatFloat(field.Float(), 'f', -1, 32) + case reflect.Float64: + v = strconv.FormatFloat(field.Float(), 'f', -1, 64) + default: + panic(fmt.Sprintf("Bad field type %T", field.Interface())) + } + + return longitudeRegex.MatchString(v) +} + +// isLatitude is the validation function for validating if the field's value is a valid latitude coordinate. +func isLatitude(fl FieldLevel) bool { + field := fl.Field() + + var v string + switch field.Kind() { + case reflect.String: + v = field.String() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + v = strconv.FormatInt(field.Int(), 10) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + v = strconv.FormatUint(field.Uint(), 10) + case reflect.Float32: + v = strconv.FormatFloat(field.Float(), 'f', -1, 32) + case reflect.Float64: + v = strconv.FormatFloat(field.Float(), 'f', -1, 64) + default: + panic(fmt.Sprintf("Bad field type %T", field.Interface())) + } + + return latitudeRegex.MatchString(v) +} + +// isDataURI is the validation function for validating if the field's value is a valid data URI. +func isDataURI(fl FieldLevel) bool { + + uri := strings.SplitN(fl.Field().String(), ",", 2) + + if len(uri) != 2 { + return false + } + + if !dataURIRegex.MatchString(uri[0]) { + return false + } + + return base64Regex.MatchString(uri[1]) +} + +// hasMultiByteCharacter is the validation function for validating if the field's value has a multi byte character. +func hasMultiByteCharacter(fl FieldLevel) bool { + + field := fl.Field() + + if field.Len() == 0 { + return true + } + + return multibyteRegex.MatchString(field.String()) +} + +// isPrintableASCII is the validation function for validating if the field's value is a valid printable ASCII character. +func isPrintableASCII(fl FieldLevel) bool { + return printableASCIIRegex.MatchString(fl.Field().String()) +} + +// isASCII is the validation function for validating if the field's value is a valid ASCII character. +func isASCII(fl FieldLevel) bool { + return aSCIIRegex.MatchString(fl.Field().String()) +} + +// isUUID5 is the validation function for validating if the field's value is a valid v5 UUID. +func isUUID5(fl FieldLevel) bool { + return uUID5Regex.MatchString(fl.Field().String()) +} + +// isUUID4 is the validation function for validating if the field's value is a valid v4 UUID. +func isUUID4(fl FieldLevel) bool { + return uUID4Regex.MatchString(fl.Field().String()) +} + +// isUUID3 is the validation function for validating if the field's value is a valid v3 UUID. +func isUUID3(fl FieldLevel) bool { + return uUID3Regex.MatchString(fl.Field().String()) +} + +// isUUID is the validation function for validating if the field's value is a valid UUID of any version. +func isUUID(fl FieldLevel) bool { + return uUIDRegex.MatchString(fl.Field().String()) +} + +// isUUID5RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v5 UUID. +func isUUID5RFC4122(fl FieldLevel) bool { + return uUID5RFC4122Regex.MatchString(fl.Field().String()) +} + +// isUUID4RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v4 UUID. +func isUUID4RFC4122(fl FieldLevel) bool { + return uUID4RFC4122Regex.MatchString(fl.Field().String()) +} + +// isUUID3RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v3 UUID. +func isUUID3RFC4122(fl FieldLevel) bool { + return uUID3RFC4122Regex.MatchString(fl.Field().String()) +} + +// isUUIDRFC4122 is the validation function for validating if the field's value is a valid RFC4122 UUID of any version. +func isUUIDRFC4122(fl FieldLevel) bool { + return uUIDRFC4122Regex.MatchString(fl.Field().String()) +} + +// isULID is the validation function for validating if the field's value is a valid ULID. +func isULID(fl FieldLevel) bool { + return uLIDRegex.MatchString(fl.Field().String()) +} + +// isISBN is the validation function for validating if the field's value is a valid v10 or v13 ISBN. +func isISBN(fl FieldLevel) bool { + return isISBN10(fl) || isISBN13(fl) +} + +// isISBN13 is the validation function for validating if the field's value is a valid v13 ISBN. +func isISBN13(fl FieldLevel) bool { + + s := strings.Replace(strings.Replace(fl.Field().String(), "-", "", 4), " ", "", 4) + + if !iSBN13Regex.MatchString(s) { + return false + } + + var checksum int32 + var i int32 + + factor := []int32{1, 3} + + for i = 0; i < 12; i++ { + checksum += factor[i%2] * int32(s[i]-'0') + } + + return (int32(s[12]-'0'))-((10-(checksum%10))%10) == 0 +} + +// isISBN10 is the validation function for validating if the field's value is a valid v10 ISBN. +func isISBN10(fl FieldLevel) bool { + + s := strings.Replace(strings.Replace(fl.Field().String(), "-", "", 3), " ", "", 3) + + if !iSBN10Regex.MatchString(s) { + return false + } + + var checksum int32 + var i int32 + + for i = 0; i < 9; i++ { + checksum += (i + 1) * int32(s[i]-'0') + } + + if s[9] == 'X' { + checksum += 10 * 10 + } else { + checksum += 10 * int32(s[9]-'0') + } + + return checksum%11 == 0 +} + +// isEthereumAddress is the validation function for validating if the field's value is a valid Ethereum address. +func isEthereumAddress(fl FieldLevel) bool { + address := fl.Field().String() + + if !ethAddressRegex.MatchString(address) { + return false + } + + if ethAddressRegexUpper.MatchString(address) || ethAddressRegexLower.MatchString(address) { + return true + } + + // Checksum validation. Reference: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md + address = address[2:] // Skip "0x" prefix. + h := sha3.NewLegacyKeccak256() + // hash.Hash's io.Writer implementation says it never returns an error. https://golang.org/pkg/hash/#Hash + _, _ = h.Write([]byte(strings.ToLower(address))) + hash := hex.EncodeToString(h.Sum(nil)) + + for i := 0; i < len(address); i++ { + if address[i] <= '9' { // Skip 0-9 digits: they don't have upper/lower-case. + continue + } + if hash[i] > '7' && address[i] >= 'a' || hash[i] <= '7' && address[i] <= 'F' { + return false + } + } + + return true +} + +// isBitcoinAddress is the validation function for validating if the field's value is a valid btc address +func isBitcoinAddress(fl FieldLevel) bool { + address := fl.Field().String() + + if !btcAddressRegex.MatchString(address) { + return false + } + + alphabet := []byte("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") + + decode := [25]byte{} + + for _, n := range []byte(address) { + d := bytes.IndexByte(alphabet, n) + + for i := 24; i >= 0; i-- { + d += 58 * int(decode[i]) + decode[i] = byte(d % 256) + d /= 256 + } + } + + h := sha256.New() + _, _ = h.Write(decode[:21]) + d := h.Sum([]byte{}) + h = sha256.New() + _, _ = h.Write(d) + + validchecksum := [4]byte{} + computedchecksum := [4]byte{} + + copy(computedchecksum[:], h.Sum(d[:0])) + copy(validchecksum[:], decode[21:]) + + return validchecksum == computedchecksum +} + +// isBitcoinBech32Address is the validation function for validating if the field's value is a valid bech32 btc address +func isBitcoinBech32Address(fl FieldLevel) bool { + address := fl.Field().String() + + if !btcLowerAddressRegexBech32.MatchString(address) && !btcUpperAddressRegexBech32.MatchString(address) { + return false + } + + am := len(address) % 8 + + if am == 0 || am == 3 || am == 5 { + return false + } + + address = strings.ToLower(address) + + alphabet := "qpzry9x8gf2tvdw0s3jn54khce6mua7l" + + hr := []int{3, 3, 0, 2, 3} // the human readable part will always be bc + addr := address[3:] + dp := make([]int, 0, len(addr)) + + for _, c := range addr { + dp = append(dp, strings.IndexRune(alphabet, c)) + } + + ver := dp[0] + + if ver < 0 || ver > 16 { + return false + } + + if ver == 0 { + if len(address) != 42 && len(address) != 62 { + return false + } + } + + values := append(hr, dp...) + + GEN := []int{0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3} + + p := 1 + + for _, v := range values { + b := p >> 25 + p = (p&0x1ffffff)<<5 ^ v + + for i := 0; i < 5; i++ { + if (b>>uint(i))&1 == 1 { + p ^= GEN[i] + } + } + } + + if p != 1 { + return false + } + + b := uint(0) + acc := 0 + mv := (1 << 5) - 1 + var sw []int + + for _, v := range dp[1 : len(dp)-6] { + acc = (acc << 5) | v + b += 5 + for b >= 8 { + b -= 8 + sw = append(sw, (acc>>b)&mv) + } + } + + if len(sw) < 2 || len(sw) > 40 { + return false + } + + return true +} + +// excludesRune is the validation function for validating that the field's value does not contain the rune specified within the param. +func excludesRune(fl FieldLevel) bool { + return !containsRune(fl) +} + +// excludesAll is the validation function for validating that the field's value does not contain any of the characters specified within the param. +func excludesAll(fl FieldLevel) bool { + return !containsAny(fl) +} + +// excludes is the validation function for validating that the field's value does not contain the text specified within the param. +func excludes(fl FieldLevel) bool { + return !contains(fl) +} + +// containsRune is the validation function for validating that the field's value contains the rune specified within the param. +func containsRune(fl FieldLevel) bool { + + r, _ := utf8.DecodeRuneInString(fl.Param()) + + return strings.ContainsRune(fl.Field().String(), r) +} + +// containsAny is the validation function for validating that the field's value contains any of the characters specified within the param. +func containsAny(fl FieldLevel) bool { + return strings.ContainsAny(fl.Field().String(), fl.Param()) +} + +// contains is the validation function for validating that the field's value contains the text specified within the param. +func contains(fl FieldLevel) bool { + return strings.Contains(fl.Field().String(), fl.Param()) +} + +// startsWith is the validation function for validating that the field's value starts with the text specified within the param. +func startsWith(fl FieldLevel) bool { + return strings.HasPrefix(fl.Field().String(), fl.Param()) +} + +// endsWith is the validation function for validating that the field's value ends with the text specified within the param. +func endsWith(fl FieldLevel) bool { + return strings.HasSuffix(fl.Field().String(), fl.Param()) +} + +// startsNotWith is the validation function for validating that the field's value does not start with the text specified within the param. +func startsNotWith(fl FieldLevel) bool { + return !startsWith(fl) +} + +// endsNotWith is the validation function for validating that the field's value does not end with the text specified within the param. +func endsNotWith(fl FieldLevel) bool { + return !endsWith(fl) +} + +// fieldContains is the validation function for validating if the current field's value contains the field specified by the param's value. +func fieldContains(fl FieldLevel) bool { + field := fl.Field() + + currentField, _, ok := fl.GetStructFieldOK() + + if !ok { + return false + } + + return strings.Contains(field.String(), currentField.String()) +} + +// fieldExcludes is the validation function for validating if the current field's value excludes the field specified by the param's value. +func fieldExcludes(fl FieldLevel) bool { + field := fl.Field() + + currentField, _, ok := fl.GetStructFieldOK() + if !ok { + return true + } + + return !strings.Contains(field.String(), currentField.String()) +} + +// isNeField is the validation function for validating if the current field's value is not equal to the field specified by the param's value. +func isNeField(fl FieldLevel) bool { + + field := fl.Field() + kind := field.Kind() + + currentField, currentKind, ok := fl.GetStructFieldOK() + + if !ok || currentKind != kind { + return true + } + + switch kind { + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return field.Int() != currentField.Int() + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return field.Uint() != currentField.Uint() + + case reflect.Float32, reflect.Float64: + return field.Float() != currentField.Float() + + case reflect.Slice, reflect.Map, reflect.Array: + return int64(field.Len()) != int64(currentField.Len()) + + case reflect.Bool: + return field.Bool() != currentField.Bool() + + case reflect.Struct: + + fieldType := field.Type() + + // Not Same underlying type i.e. struct and time + if fieldType != currentField.Type() { + return true + } + + if fieldType == timeType { + + t := currentField.Interface().(time.Time) + fieldTime := field.Interface().(time.Time) + + return !fieldTime.Equal(t) + } + + } + + // default reflect.String: + return field.String() != currentField.String() +} + +// isNe is the validation function for validating that the field's value does not equal the provided param value. +func isNe(fl FieldLevel) bool { + return !isEq(fl) +} + +// isLteCrossStructField is the validation function for validating if the current field's value is less than or equal to the field, within a separate struct, specified by the param's value. +func isLteCrossStructField(fl FieldLevel) bool { + + field := fl.Field() + kind := field.Kind() + + topField, topKind, ok := fl.GetStructFieldOK() + if !ok || topKind != kind { + return false + } + + switch kind { + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return field.Int() <= topField.Int() + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return field.Uint() <= topField.Uint() + + case reflect.Float32, reflect.Float64: + return field.Float() <= topField.Float() + + case reflect.Slice, reflect.Map, reflect.Array: + return int64(field.Len()) <= int64(topField.Len()) + + case reflect.Struct: + + fieldType := field.Type() + + // Not Same underlying type i.e. struct and time + if fieldType != topField.Type() { + return false + } + + if fieldType == timeType { + + fieldTime := field.Interface().(time.Time) + topTime := topField.Interface().(time.Time) + + return fieldTime.Before(topTime) || fieldTime.Equal(topTime) + } + } + + // default reflect.String: + return field.String() <= topField.String() +} + +// isLtCrossStructField is the validation function for validating if the current field's value is less than the field, within a separate struct, specified by the param's value. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func isLtCrossStructField(fl FieldLevel) bool { + + field := fl.Field() + kind := field.Kind() + + topField, topKind, ok := fl.GetStructFieldOK() + if !ok || topKind != kind { + return false + } + + switch kind { + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return field.Int() < topField.Int() + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return field.Uint() < topField.Uint() + + case reflect.Float32, reflect.Float64: + return field.Float() < topField.Float() + + case reflect.Slice, reflect.Map, reflect.Array: + return int64(field.Len()) < int64(topField.Len()) + + case reflect.Struct: + + fieldType := field.Type() + + // Not Same underlying type i.e. struct and time + if fieldType != topField.Type() { + return false + } + + if fieldType == timeType { + + fieldTime := field.Interface().(time.Time) + topTime := topField.Interface().(time.Time) + + return fieldTime.Before(topTime) + } + } + + // default reflect.String: + return field.String() < topField.String() +} + +// isGteCrossStructField is the validation function for validating if the current field's value is greater than or equal to the field, within a separate struct, specified by the param's value. +func isGteCrossStructField(fl FieldLevel) bool { + + field := fl.Field() + kind := field.Kind() + + topField, topKind, ok := fl.GetStructFieldOK() + if !ok || topKind != kind { + return false + } + + switch kind { + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return field.Int() >= topField.Int() + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return field.Uint() >= topField.Uint() + + case reflect.Float32, reflect.Float64: + return field.Float() >= topField.Float() + + case reflect.Slice, reflect.Map, reflect.Array: + return int64(field.Len()) >= int64(topField.Len()) + + case reflect.Struct: + + fieldType := field.Type() + + // Not Same underlying type i.e. struct and time + if fieldType != topField.Type() { + return false + } + + if fieldType == timeType { + + fieldTime := field.Interface().(time.Time) + topTime := topField.Interface().(time.Time) + + return fieldTime.After(topTime) || fieldTime.Equal(topTime) + } + } + + // default reflect.String: + return field.String() >= topField.String() +} + +// isGtCrossStructField is the validation function for validating if the current field's value is greater than the field, within a separate struct, specified by the param's value. +func isGtCrossStructField(fl FieldLevel) bool { + + field := fl.Field() + kind := field.Kind() + + topField, topKind, ok := fl.GetStructFieldOK() + if !ok || topKind != kind { + return false + } + + switch kind { + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return field.Int() > topField.Int() + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return field.Uint() > topField.Uint() + + case reflect.Float32, reflect.Float64: + return field.Float() > topField.Float() + + case reflect.Slice, reflect.Map, reflect.Array: + return int64(field.Len()) > int64(topField.Len()) + + case reflect.Struct: + + fieldType := field.Type() + + // Not Same underlying type i.e. struct and time + if fieldType != topField.Type() { + return false + } + + if fieldType == timeType { + + fieldTime := field.Interface().(time.Time) + topTime := topField.Interface().(time.Time) + + return fieldTime.After(topTime) + } + } + + // default reflect.String: + return field.String() > topField.String() +} + +// isNeCrossStructField is the validation function for validating that the current field's value is not equal to the field, within a separate struct, specified by the param's value. +func isNeCrossStructField(fl FieldLevel) bool { + + field := fl.Field() + kind := field.Kind() + + topField, currentKind, ok := fl.GetStructFieldOK() + if !ok || currentKind != kind { + return true + } + + switch kind { + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return topField.Int() != field.Int() + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return topField.Uint() != field.Uint() + + case reflect.Float32, reflect.Float64: + return topField.Float() != field.Float() + + case reflect.Slice, reflect.Map, reflect.Array: + return int64(topField.Len()) != int64(field.Len()) + + case reflect.Bool: + return topField.Bool() != field.Bool() + + case reflect.Struct: + + fieldType := field.Type() + + // Not Same underlying type i.e. struct and time + if fieldType != topField.Type() { + return true + } + + if fieldType == timeType { + + t := field.Interface().(time.Time) + fieldTime := topField.Interface().(time.Time) + + return !fieldTime.Equal(t) + } + } + + // default reflect.String: + return topField.String() != field.String() +} + +// isEqCrossStructField is the validation function for validating that the current field's value is equal to the field, within a separate struct, specified by the param's value. +func isEqCrossStructField(fl FieldLevel) bool { + + field := fl.Field() + kind := field.Kind() + + topField, topKind, ok := fl.GetStructFieldOK() + if !ok || topKind != kind { + return false + } + + switch kind { + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return topField.Int() == field.Int() + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return topField.Uint() == field.Uint() + + case reflect.Float32, reflect.Float64: + return topField.Float() == field.Float() + + case reflect.Slice, reflect.Map, reflect.Array: + return int64(topField.Len()) == int64(field.Len()) + + case reflect.Bool: + return topField.Bool() == field.Bool() + + case reflect.Struct: + + fieldType := field.Type() + + // Not Same underlying type i.e. struct and time + if fieldType != topField.Type() { + return false + } + + if fieldType == timeType { + + t := field.Interface().(time.Time) + fieldTime := topField.Interface().(time.Time) + + return fieldTime.Equal(t) + } + } + + // default reflect.String: + return topField.String() == field.String() +} + +// isEqField is the validation function for validating if the current field's value is equal to the field specified by the param's value. +func isEqField(fl FieldLevel) bool { + + field := fl.Field() + kind := field.Kind() + + currentField, currentKind, ok := fl.GetStructFieldOK() + if !ok || currentKind != kind { + return false + } + + switch kind { + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return field.Int() == currentField.Int() + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return field.Uint() == currentField.Uint() + + case reflect.Float32, reflect.Float64: + return field.Float() == currentField.Float() + + case reflect.Slice, reflect.Map, reflect.Array: + return int64(field.Len()) == int64(currentField.Len()) + + case reflect.Bool: + return field.Bool() == currentField.Bool() + + case reflect.Struct: + + fieldType := field.Type() + + // Not Same underlying type i.e. struct and time + if fieldType != currentField.Type() { + return false + } + + if fieldType == timeType { + + t := currentField.Interface().(time.Time) + fieldTime := field.Interface().(time.Time) + + return fieldTime.Equal(t) + } + + } + + // default reflect.String: + return field.String() == currentField.String() +} + +// isEq is the validation function for validating if the current field's value is equal to the param's value. +func isEq(fl FieldLevel) bool { + + field := fl.Field() + param := fl.Param() + + switch field.Kind() { + + case reflect.String: + return field.String() == param + + case reflect.Slice, reflect.Map, reflect.Array: + p := asInt(param) + + return int64(field.Len()) == p + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + p := asIntFromType(field.Type(), param) + + return field.Int() == p + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + p := asUint(param) + + return field.Uint() == p + + case reflect.Float32, reflect.Float64: + p := asFloat(param) + + return field.Float() == p + + case reflect.Bool: + p := asBool(param) + + return field.Bool() == p + } + + panic(fmt.Sprintf("Bad field type %T", field.Interface())) +} + +// isPostcodeByIso3166Alpha2 validates by value which is country code in iso 3166 alpha 2 +// example: `postcode_iso3166_alpha2=US` +func isPostcodeByIso3166Alpha2(fl FieldLevel) bool { + field := fl.Field() + param := fl.Param() + + reg, found := postCodeRegexDict[param] + if !found { + return false + } + + return reg.MatchString(field.String()) +} + +// isPostcodeByIso3166Alpha2 validates by field which represents for a value of country code in iso 3166 alpha 2 +// example: `postcode_iso3166_alpha2_field=CountryCode` +func isPostcodeByIso3166Alpha2Field(fl FieldLevel) bool { + field := fl.Field() + params := parseOneOfParam2(fl.Param()) + + if len(params) != 1 { + return false + } + + currentField, kind, _, found := fl.GetStructFieldOKAdvanced2(fl.Parent(), params[0]) + if !found { + return false + } + + if kind != reflect.String { + panic(fmt.Sprintf("Bad field type %T", currentField.Interface())) + } + + reg, found := postCodeRegexDict[currentField.String()] + if !found { + return false + } + + return reg.MatchString(field.String()) +} + +// isBase64 is the validation function for validating if the current field's value is a valid base 64. +func isBase64(fl FieldLevel) bool { + return base64Regex.MatchString(fl.Field().String()) +} + +// isBase64URL is the validation function for validating if the current field's value is a valid base64 URL safe string. +func isBase64URL(fl FieldLevel) bool { + return base64URLRegex.MatchString(fl.Field().String()) +} + +// isURI is the validation function for validating if the current field's value is a valid URI. +func isURI(fl FieldLevel) bool { + + field := fl.Field() + + switch field.Kind() { + + case reflect.String: + + s := field.String() + + // checks needed as of Go 1.6 because of change https://github.com/golang/go/commit/617c93ce740c3c3cc28cdd1a0d712be183d0b328#diff-6c2d018290e298803c0c9419d8739885L195 + // emulate browser and strip the '#' suffix prior to validation. see issue-#237 + if i := strings.Index(s, "#"); i > -1 { + s = s[:i] + } + + if len(s) == 0 { + return false + } + + _, err := url.ParseRequestURI(s) + + return err == nil + } + + panic(fmt.Sprintf("Bad field type %T", field.Interface())) +} + +// isURL is the validation function for validating if the current field's value is a valid URL. +func isURL(fl FieldLevel) bool { + + field := fl.Field() + + switch field.Kind() { + + case reflect.String: + + var i int + s := field.String() + + // checks needed as of Go 1.6 because of change https://github.com/golang/go/commit/617c93ce740c3c3cc28cdd1a0d712be183d0b328#diff-6c2d018290e298803c0c9419d8739885L195 + // emulate browser and strip the '#' suffix prior to validation. see issue-#237 + if i = strings.Index(s, "#"); i > -1 { + s = s[:i] + } + + if len(s) == 0 { + return false + } + + url, err := url.ParseRequestURI(s) + + if err != nil || url.Scheme == "" { + return false + } + + return true + } + + panic(fmt.Sprintf("Bad field type %T", field.Interface())) +} + +// isUrnRFC2141 is the validation function for validating if the current field's value is a valid URN as per RFC 2141. +func isUrnRFC2141(fl FieldLevel) bool { + field := fl.Field() + + switch field.Kind() { + + case reflect.String: + + str := field.String() + + _, match := urn.Parse([]byte(str)) + + return match + } + + panic(fmt.Sprintf("Bad field type %T", field.Interface())) +} + +// isFile is the validation function for validating if the current field's value is a valid file path. +func isFile(fl FieldLevel) bool { + field := fl.Field() + + switch field.Kind() { + case reflect.String: + fileInfo, err := os.Stat(field.String()) + if err != nil { + return false + } + + return !fileInfo.IsDir() + } + + panic(fmt.Sprintf("Bad field type %T", field.Interface())) +} + +// isE164 is the validation function for validating if the current field's value is a valid e.164 formatted phone number. +func isE164(fl FieldLevel) bool { + return e164Regex.MatchString(fl.Field().String()) +} + +// isEmail is the validation function for validating if the current field's value is a valid email address. +func isEmail(fl FieldLevel) bool { + return emailRegex.MatchString(fl.Field().String()) +} + +// isHSLA is the validation function for validating if the current field's value is a valid HSLA color. +func isHSLA(fl FieldLevel) bool { + return hslaRegex.MatchString(fl.Field().String()) +} + +// isHSL is the validation function for validating if the current field's value is a valid HSL color. +func isHSL(fl FieldLevel) bool { + return hslRegex.MatchString(fl.Field().String()) +} + +// isRGBA is the validation function for validating if the current field's value is a valid RGBA color. +func isRGBA(fl FieldLevel) bool { + return rgbaRegex.MatchString(fl.Field().String()) +} + +// isRGB is the validation function for validating if the current field's value is a valid RGB color. +func isRGB(fl FieldLevel) bool { + return rgbRegex.MatchString(fl.Field().String()) +} + +// isHEXColor is the validation function for validating if the current field's value is a valid HEX color. +func isHEXColor(fl FieldLevel) bool { + return hexColorRegex.MatchString(fl.Field().String()) +} + +// isHexadecimal is the validation function for validating if the current field's value is a valid hexadecimal. +func isHexadecimal(fl FieldLevel) bool { + return hexadecimalRegex.MatchString(fl.Field().String()) +} + +// isNumber is the validation function for validating if the current field's value is a valid number. +func isNumber(fl FieldLevel) bool { + switch fl.Field().Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.Float32, reflect.Float64: + return true + default: + return numberRegex.MatchString(fl.Field().String()) + } +} + +// isNumeric is the validation function for validating if the current field's value is a valid numeric value. +func isNumeric(fl FieldLevel) bool { + switch fl.Field().Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.Float32, reflect.Float64: + return true + default: + return numericRegex.MatchString(fl.Field().String()) + } +} + +// isAlphanum is the validation function for validating if the current field's value is a valid alphanumeric value. +func isAlphanum(fl FieldLevel) bool { + return alphaNumericRegex.MatchString(fl.Field().String()) +} + +// isAlpha is the validation function for validating if the current field's value is a valid alpha value. +func isAlpha(fl FieldLevel) bool { + return alphaRegex.MatchString(fl.Field().String()) +} + +// isAlphanumUnicode is the validation function for validating if the current field's value is a valid alphanumeric unicode value. +func isAlphanumUnicode(fl FieldLevel) bool { + return alphaUnicodeNumericRegex.MatchString(fl.Field().String()) +} + +// isAlphaUnicode is the validation function for validating if the current field's value is a valid alpha unicode value. +func isAlphaUnicode(fl FieldLevel) bool { + return alphaUnicodeRegex.MatchString(fl.Field().String()) +} + +// isBoolean is the validation function for validating if the current field's value can be safely converted to a boolean. +func isBoolean(fl FieldLevel) bool { + _, err := strconv.ParseBool(fl.Field().String()) + return err == nil +} + +// isDefault is the opposite of required aka hasValue +func isDefault(fl FieldLevel) bool { + return !hasValue(fl) +} + +// hasValue is the validation function for validating if the current field's value is not the default static value. +func hasValue(fl FieldLevel) bool { + field := fl.Field() + switch field.Kind() { + case reflect.Slice, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func: + return !field.IsNil() + default: + if fl.(*validate).fldIsPointer && field.Interface() != nil { + return true + } + return field.IsValid() && field.Interface() != reflect.Zero(field.Type()).Interface() + } +} + +// requireCheckField is a func for check field kind +func requireCheckFieldKind(fl FieldLevel, param string, defaultNotFoundValue bool) bool { + field := fl.Field() + kind := field.Kind() + var nullable, found bool + if len(param) > 0 { + field, kind, nullable, found = fl.GetStructFieldOKAdvanced2(fl.Parent(), param) + if !found { + return defaultNotFoundValue + } + } + switch kind { + case reflect.Invalid: + return defaultNotFoundValue + case reflect.Slice, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func: + return field.IsNil() + default: + if nullable && field.Interface() != nil { + return false + } + return field.IsValid() && field.Interface() == reflect.Zero(field.Type()).Interface() + } +} + +// requireCheckFieldValue is a func for check field value +func requireCheckFieldValue(fl FieldLevel, param string, value string, defaultNotFoundValue bool) bool { + field, kind, _, found := fl.GetStructFieldOKAdvanced2(fl.Parent(), param) + if !found { + return defaultNotFoundValue + } + + switch kind { + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return field.Int() == asInt(value) + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return field.Uint() == asUint(value) + + case reflect.Float32, reflect.Float64: + return field.Float() == asFloat(value) + + case reflect.Slice, reflect.Map, reflect.Array: + return int64(field.Len()) == asInt(value) + + case reflect.Bool: + return field.Bool() == asBool(value) + } + + // default reflect.String: + return field.String() == value +} + +// requiredIf is the validation function +// The field under validation must be present and not empty only if all the other specified fields are equal to the value following with the specified field. +func requiredIf(fl FieldLevel) bool { + params := parseOneOfParam2(fl.Param()) + if len(params)%2 != 0 { + panic(fmt.Sprintf("Bad param number for required_if %s", fl.FieldName())) + } + for i := 0; i < len(params); i += 2 { + if !requireCheckFieldValue(fl, params[i], params[i+1], false) { + return true + } + } + return hasValue(fl) +} + +// requiredUnless is the validation function +// The field under validation must be present and not empty only unless all the other specified fields are equal to the value following with the specified field. +func requiredUnless(fl FieldLevel) bool { + params := parseOneOfParam2(fl.Param()) + if len(params)%2 != 0 { + panic(fmt.Sprintf("Bad param number for required_unless %s", fl.FieldName())) + } + + for i := 0; i < len(params); i += 2 { + if requireCheckFieldValue(fl, params[i], params[i+1], false) { + return true + } + } + return hasValue(fl) +} + +// excludedWith is the validation function +// The field under validation must not be present or is empty if any of the other specified fields are present. +func excludedWith(fl FieldLevel) bool { + params := parseOneOfParam2(fl.Param()) + for _, param := range params { + if !requireCheckFieldKind(fl, param, true) { + return !hasValue(fl) + } + } + return true +} + +// requiredWith is the validation function +// The field under validation must be present and not empty only if any of the other specified fields are present. +func requiredWith(fl FieldLevel) bool { + params := parseOneOfParam2(fl.Param()) + for _, param := range params { + if !requireCheckFieldKind(fl, param, true) { + return hasValue(fl) + } + } + return true +} + +// excludedWithAll is the validation function +// The field under validation must not be present or is empty if all of the other specified fields are present. +func excludedWithAll(fl FieldLevel) bool { + params := parseOneOfParam2(fl.Param()) + for _, param := range params { + if requireCheckFieldKind(fl, param, true) { + return true + } + } + return !hasValue(fl) +} + +// requiredWithAll is the validation function +// The field under validation must be present and not empty only if all of the other specified fields are present. +func requiredWithAll(fl FieldLevel) bool { + params := parseOneOfParam2(fl.Param()) + for _, param := range params { + if requireCheckFieldKind(fl, param, true) { + return true + } + } + return hasValue(fl) +} + +// excludedWithout is the validation function +// The field under validation must not be present or is empty when any of the other specified fields are not present. +func excludedWithout(fl FieldLevel) bool { + if requireCheckFieldKind(fl, strings.TrimSpace(fl.Param()), true) { + return !hasValue(fl) + } + return true +} + +// requiredWithout is the validation function +// The field under validation must be present and not empty only when any of the other specified fields are not present. +func requiredWithout(fl FieldLevel) bool { + if requireCheckFieldKind(fl, strings.TrimSpace(fl.Param()), true) { + return hasValue(fl) + } + return true +} + +// excludedWithoutAll is the validation function +// The field under validation must not be present or is empty when all of the other specified fields are not present. +func excludedWithoutAll(fl FieldLevel) bool { + params := parseOneOfParam2(fl.Param()) + for _, param := range params { + if !requireCheckFieldKind(fl, param, true) { + return true + } + } + return !hasValue(fl) +} + +// requiredWithoutAll is the validation function +// The field under validation must be present and not empty only when all of the other specified fields are not present. +func requiredWithoutAll(fl FieldLevel) bool { + params := parseOneOfParam2(fl.Param()) + for _, param := range params { + if !requireCheckFieldKind(fl, param, true) { + return true + } + } + return hasValue(fl) +} + +// isGteField is the validation function for validating if the current field's value is greater than or equal to the field specified by the param's value. +func isGteField(fl FieldLevel) bool { + + field := fl.Field() + kind := field.Kind() + + currentField, currentKind, ok := fl.GetStructFieldOK() + if !ok || currentKind != kind { + return false + } + + switch kind { + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + + return field.Int() >= currentField.Int() + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + + return field.Uint() >= currentField.Uint() + + case reflect.Float32, reflect.Float64: + + return field.Float() >= currentField.Float() + + case reflect.Struct: + + fieldType := field.Type() + + // Not Same underlying type i.e. struct and time + if fieldType != currentField.Type() { + return false + } + + if fieldType == timeType { + + t := currentField.Interface().(time.Time) + fieldTime := field.Interface().(time.Time) + + return fieldTime.After(t) || fieldTime.Equal(t) + } + } + + // default reflect.String + return len(field.String()) >= len(currentField.String()) +} + +// isGtField is the validation function for validating if the current field's value is greater than the field specified by the param's value. +func isGtField(fl FieldLevel) bool { + + field := fl.Field() + kind := field.Kind() + + currentField, currentKind, ok := fl.GetStructFieldOK() + if !ok || currentKind != kind { + return false + } + + switch kind { + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + + return field.Int() > currentField.Int() + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + + return field.Uint() > currentField.Uint() + + case reflect.Float32, reflect.Float64: + + return field.Float() > currentField.Float() + + case reflect.Struct: + + fieldType := field.Type() + + // Not Same underlying type i.e. struct and time + if fieldType != currentField.Type() { + return false + } + + if fieldType == timeType { + + t := currentField.Interface().(time.Time) + fieldTime := field.Interface().(time.Time) + + return fieldTime.After(t) + } + } + + // default reflect.String + return len(field.String()) > len(currentField.String()) +} + +// isGte is the validation function for validating if the current field's value is greater than or equal to the param's value. +func isGte(fl FieldLevel) bool { + + field := fl.Field() + param := fl.Param() + + switch field.Kind() { + + case reflect.String: + p := asInt(param) + + return int64(utf8.RuneCountInString(field.String())) >= p + + case reflect.Slice, reflect.Map, reflect.Array: + p := asInt(param) + + return int64(field.Len()) >= p + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + p := asIntFromType(field.Type(), param) + + return field.Int() >= p + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + p := asUint(param) + + return field.Uint() >= p + + case reflect.Float32, reflect.Float64: + p := asFloat(param) + + return field.Float() >= p + + case reflect.Struct: + + if field.Type() == timeType { + + now := time.Now().UTC() + t := field.Interface().(time.Time) + + return t.After(now) || t.Equal(now) + } + } + + panic(fmt.Sprintf("Bad field type %T", field.Interface())) +} + +// isGt is the validation function for validating if the current field's value is greater than the param's value. +func isGt(fl FieldLevel) bool { + + field := fl.Field() + param := fl.Param() + + switch field.Kind() { + + case reflect.String: + p := asInt(param) + + return int64(utf8.RuneCountInString(field.String())) > p + + case reflect.Slice, reflect.Map, reflect.Array: + p := asInt(param) + + return int64(field.Len()) > p + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + p := asIntFromType(field.Type(), param) + + return field.Int() > p + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + p := asUint(param) + + return field.Uint() > p + + case reflect.Float32, reflect.Float64: + p := asFloat(param) + + return field.Float() > p + case reflect.Struct: + + if field.Type() == timeType { + + return field.Interface().(time.Time).After(time.Now().UTC()) + } + } + + panic(fmt.Sprintf("Bad field type %T", field.Interface())) +} + +// hasLengthOf is the validation function for validating if the current field's value is equal to the param's value. +func hasLengthOf(fl FieldLevel) bool { + + field := fl.Field() + param := fl.Param() + + switch field.Kind() { + + case reflect.String: + p := asInt(param) + + return int64(utf8.RuneCountInString(field.String())) == p + + case reflect.Slice, reflect.Map, reflect.Array: + p := asInt(param) + + return int64(field.Len()) == p + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + p := asIntFromType(field.Type(), param) + + return field.Int() == p + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + p := asUint(param) + + return field.Uint() == p + + case reflect.Float32, reflect.Float64: + p := asFloat(param) + + return field.Float() == p + } + + panic(fmt.Sprintf("Bad field type %T", field.Interface())) +} + +// hasMinOf is the validation function for validating if the current field's value is greater than or equal to the param's value. +func hasMinOf(fl FieldLevel) bool { + return isGte(fl) +} + +// isLteField is the validation function for validating if the current field's value is less than or equal to the field specified by the param's value. +func isLteField(fl FieldLevel) bool { + + field := fl.Field() + kind := field.Kind() + + currentField, currentKind, ok := fl.GetStructFieldOK() + if !ok || currentKind != kind { + return false + } + + switch kind { + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + + return field.Int() <= currentField.Int() + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + + return field.Uint() <= currentField.Uint() + + case reflect.Float32, reflect.Float64: + + return field.Float() <= currentField.Float() + + case reflect.Struct: + + fieldType := field.Type() + + // Not Same underlying type i.e. struct and time + if fieldType != currentField.Type() { + return false + } + + if fieldType == timeType { + + t := currentField.Interface().(time.Time) + fieldTime := field.Interface().(time.Time) + + return fieldTime.Before(t) || fieldTime.Equal(t) + } + } + + // default reflect.String + return len(field.String()) <= len(currentField.String()) +} + +// isLtField is the validation function for validating if the current field's value is less than the field specified by the param's value. +func isLtField(fl FieldLevel) bool { + + field := fl.Field() + kind := field.Kind() + + currentField, currentKind, ok := fl.GetStructFieldOK() + if !ok || currentKind != kind { + return false + } + + switch kind { + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + + return field.Int() < currentField.Int() + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + + return field.Uint() < currentField.Uint() + + case reflect.Float32, reflect.Float64: + + return field.Float() < currentField.Float() + + case reflect.Struct: + + fieldType := field.Type() + + // Not Same underlying type i.e. struct and time + if fieldType != currentField.Type() { + return false + } + + if fieldType == timeType { + + t := currentField.Interface().(time.Time) + fieldTime := field.Interface().(time.Time) + + return fieldTime.Before(t) + } + } + + // default reflect.String + return len(field.String()) < len(currentField.String()) +} + +// isLte is the validation function for validating if the current field's value is less than or equal to the param's value. +func isLte(fl FieldLevel) bool { + + field := fl.Field() + param := fl.Param() + + switch field.Kind() { + + case reflect.String: + p := asInt(param) + + return int64(utf8.RuneCountInString(field.String())) <= p + + case reflect.Slice, reflect.Map, reflect.Array: + p := asInt(param) + + return int64(field.Len()) <= p + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + p := asIntFromType(field.Type(), param) + + return field.Int() <= p + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + p := asUint(param) + + return field.Uint() <= p + + case reflect.Float32, reflect.Float64: + p := asFloat(param) + + return field.Float() <= p + + case reflect.Struct: + + if field.Type() == timeType { + + now := time.Now().UTC() + t := field.Interface().(time.Time) + + return t.Before(now) || t.Equal(now) + } + } + + panic(fmt.Sprintf("Bad field type %T", field.Interface())) +} + +// isLt is the validation function for validating if the current field's value is less than the param's value. +func isLt(fl FieldLevel) bool { + + field := fl.Field() + param := fl.Param() + + switch field.Kind() { + + case reflect.String: + p := asInt(param) + + return int64(utf8.RuneCountInString(field.String())) < p + + case reflect.Slice, reflect.Map, reflect.Array: + p := asInt(param) + + return int64(field.Len()) < p + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + p := asIntFromType(field.Type(), param) + + return field.Int() < p + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + p := asUint(param) + + return field.Uint() < p + + case reflect.Float32, reflect.Float64: + p := asFloat(param) + + return field.Float() < p + + case reflect.Struct: + + if field.Type() == timeType { + + return field.Interface().(time.Time).Before(time.Now().UTC()) + } + } + + panic(fmt.Sprintf("Bad field type %T", field.Interface())) +} + +// hasMaxOf is the validation function for validating if the current field's value is less than or equal to the param's value. +func hasMaxOf(fl FieldLevel) bool { + return isLte(fl) +} + +// isTCP4AddrResolvable is the validation function for validating if the field's value is a resolvable tcp4 address. +func isTCP4AddrResolvable(fl FieldLevel) bool { + + if !isIP4Addr(fl) { + return false + } + + _, err := net.ResolveTCPAddr("tcp4", fl.Field().String()) + return err == nil +} + +// isTCP6AddrResolvable is the validation function for validating if the field's value is a resolvable tcp6 address. +func isTCP6AddrResolvable(fl FieldLevel) bool { + + if !isIP6Addr(fl) { + return false + } + + _, err := net.ResolveTCPAddr("tcp6", fl.Field().String()) + + return err == nil +} + +// isTCPAddrResolvable is the validation function for validating if the field's value is a resolvable tcp address. +func isTCPAddrResolvable(fl FieldLevel) bool { + + if !isIP4Addr(fl) && !isIP6Addr(fl) { + return false + } + + _, err := net.ResolveTCPAddr("tcp", fl.Field().String()) + + return err == nil +} + +// isUDP4AddrResolvable is the validation function for validating if the field's value is a resolvable udp4 address. +func isUDP4AddrResolvable(fl FieldLevel) bool { + + if !isIP4Addr(fl) { + return false + } + + _, err := net.ResolveUDPAddr("udp4", fl.Field().String()) + + return err == nil +} + +// isUDP6AddrResolvable is the validation function for validating if the field's value is a resolvable udp6 address. +func isUDP6AddrResolvable(fl FieldLevel) bool { + + if !isIP6Addr(fl) { + return false + } + + _, err := net.ResolveUDPAddr("udp6", fl.Field().String()) + + return err == nil +} + +// isUDPAddrResolvable is the validation function for validating if the field's value is a resolvable udp address. +func isUDPAddrResolvable(fl FieldLevel) bool { + + if !isIP4Addr(fl) && !isIP6Addr(fl) { + return false + } + + _, err := net.ResolveUDPAddr("udp", fl.Field().String()) + + return err == nil +} + +// isIP4AddrResolvable is the validation function for validating if the field's value is a resolvable ip4 address. +func isIP4AddrResolvable(fl FieldLevel) bool { + + if !isIPv4(fl) { + return false + } + + _, err := net.ResolveIPAddr("ip4", fl.Field().String()) + + return err == nil +} + +// isIP6AddrResolvable is the validation function for validating if the field's value is a resolvable ip6 address. +func isIP6AddrResolvable(fl FieldLevel) bool { + + if !isIPv6(fl) { + return false + } + + _, err := net.ResolveIPAddr("ip6", fl.Field().String()) + + return err == nil +} + +// isIPAddrResolvable is the validation function for validating if the field's value is a resolvable ip address. +func isIPAddrResolvable(fl FieldLevel) bool { + + if !isIP(fl) { + return false + } + + _, err := net.ResolveIPAddr("ip", fl.Field().String()) + + return err == nil +} + +// isUnixAddrResolvable is the validation function for validating if the field's value is a resolvable unix address. +func isUnixAddrResolvable(fl FieldLevel) bool { + + _, err := net.ResolveUnixAddr("unix", fl.Field().String()) + + return err == nil +} + +func isIP4Addr(fl FieldLevel) bool { + + val := fl.Field().String() + + if idx := strings.LastIndex(val, ":"); idx != -1 { + val = val[0:idx] + } + + ip := net.ParseIP(val) + + return ip != nil && ip.To4() != nil +} + +func isIP6Addr(fl FieldLevel) bool { + + val := fl.Field().String() + + if idx := strings.LastIndex(val, ":"); idx != -1 { + if idx != 0 && val[idx-1:idx] == "]" { + val = val[1 : idx-1] + } + } + + ip := net.ParseIP(val) + + return ip != nil && ip.To4() == nil +} + +func isHostnameRFC952(fl FieldLevel) bool { + return hostnameRegexRFC952.MatchString(fl.Field().String()) +} + +func isHostnameRFC1123(fl FieldLevel) bool { + return hostnameRegexRFC1123.MatchString(fl.Field().String()) +} + +func isFQDN(fl FieldLevel) bool { + val := fl.Field().String() + + if val == "" { + return false + } + + return fqdnRegexRFC1123.MatchString(val) +} + +// isDir is the validation function for validating if the current field's value is a valid directory. +func isDir(fl FieldLevel) bool { + field := fl.Field() + + if field.Kind() == reflect.String { + fileInfo, err := os.Stat(field.String()) + if err != nil { + return false + } + + return fileInfo.IsDir() + } + + panic(fmt.Sprintf("Bad field type %T", field.Interface())) +} + +// isJSON is the validation function for validating if the current field's value is a valid json string. +func isJSON(fl FieldLevel) bool { + field := fl.Field() + + if field.Kind() == reflect.String { + val := field.String() + return json.Valid([]byte(val)) + } + + panic(fmt.Sprintf("Bad field type %T", field.Interface())) +} + +// isJWT is the validation function for validating if the current field's value is a valid JWT string. +func isJWT(fl FieldLevel) bool { + return jWTRegex.MatchString(fl.Field().String()) +} + +// isHostnamePort validates a : combination for fields typically used for socket address. +func isHostnamePort(fl FieldLevel) bool { + val := fl.Field().String() + host, port, err := net.SplitHostPort(val) + if err != nil { + return false + } + // Port must be a iny <= 65535. + if portNum, err := strconv.ParseInt(port, 10, 32); err != nil || portNum > 65535 || portNum < 1 { + return false + } + + // If host is specified, it should match a DNS name + if host != "" { + return hostnameRegexRFC1123.MatchString(host) + } + return true +} + +// isLowercase is the validation function for validating if the current field's value is a lowercase string. +func isLowercase(fl FieldLevel) bool { + field := fl.Field() + + if field.Kind() == reflect.String { + if field.String() == "" { + return false + } + return field.String() == strings.ToLower(field.String()) + } + + panic(fmt.Sprintf("Bad field type %T", field.Interface())) +} + +// isUppercase is the validation function for validating if the current field's value is an uppercase string. +func isUppercase(fl FieldLevel) bool { + field := fl.Field() + + if field.Kind() == reflect.String { + if field.String() == "" { + return false + } + return field.String() == strings.ToUpper(field.String()) + } + + panic(fmt.Sprintf("Bad field type %T", field.Interface())) +} + +// isDatetime is the validation function for validating if the current field's value is a valid datetime string. +func isDatetime(fl FieldLevel) bool { + field := fl.Field() + param := fl.Param() + + if field.Kind() == reflect.String { + _, err := time.Parse(param, field.String()) + + return err == nil + } + + panic(fmt.Sprintf("Bad field type %T", field.Interface())) +} + +// isTimeZone is the validation function for validating if the current field's value is a valid time zone string. +func isTimeZone(fl FieldLevel) bool { + field := fl.Field() + + if field.Kind() == reflect.String { + // empty value is converted to UTC by time.LoadLocation but disallow it as it is not a valid time zone name + if field.String() == "" { + return false + } + + // Local value is converted to the current system time zone by time.LoadLocation but disallow it as it is not a valid time zone name + if strings.ToLower(field.String()) == "local" { + return false + } + + _, err := time.LoadLocation(field.String()) + return err == nil + } + + panic(fmt.Sprintf("Bad field type %T", field.Interface())) +} + +// isIso3166Alpha2 is the validation function for validating if the current field's value is a valid iso3166-1 alpha-2 country code. +func isIso3166Alpha2(fl FieldLevel) bool { + val := fl.Field().String() + return iso3166_1_alpha2[val] +} + +// isIso3166Alpha2 is the validation function for validating if the current field's value is a valid iso3166-1 alpha-3 country code. +func isIso3166Alpha3(fl FieldLevel) bool { + val := fl.Field().String() + return iso3166_1_alpha3[val] +} + +// isIso3166Alpha2 is the validation function for validating if the current field's value is a valid iso3166-1 alpha-numeric country code. +func isIso3166AlphaNumeric(fl FieldLevel) bool { + field := fl.Field() + + var code int + switch field.Kind() { + case reflect.String: + i, err := strconv.Atoi(field.String()) + if err != nil { + return false + } + code = i % 1000 + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + code = int(field.Int() % 1000) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + code = int(field.Uint() % 1000) + default: + panic(fmt.Sprintf("Bad field type %T", field.Interface())) + } + return iso3166_1_alpha_numeric[code] +} + +// isIso31662 is the validation function for validating if the current field's value is a valid iso3166-2 code. +func isIso31662(fl FieldLevel) bool { + val := fl.Field().String() + return iso3166_2[val] +} + +// isIso4217 is the validation function for validating if the current field's value is a valid iso4217 currency code. +func isIso4217(fl FieldLevel) bool { + val := fl.Field().String() + return iso4217[val] +} + +// isIso4217Numeric is the validation function for validating if the current field's value is a valid iso4217 numeric currency code. +func isIso4217Numeric(fl FieldLevel) bool { + field := fl.Field() + + var code int + switch field.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + code = int(field.Int()) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + code = int(field.Uint()) + default: + panic(fmt.Sprintf("Bad field type %T", field.Interface())) + } + return iso4217_numeric[code] +} + +// isBCP47LanguageTag is the validation function for validating if the current field's value is a valid BCP 47 language tag, as parsed by language.Parse +func isBCP47LanguageTag(fl FieldLevel) bool { + field := fl.Field() + + if field.Kind() == reflect.String { + _, err := language.Parse(field.String()) + return err == nil + } + + panic(fmt.Sprintf("Bad field type %T", field.Interface())) +} + +// isIsoBicFormat is the validation function for validating if the current field's value is a valid Business Identifier Code (SWIFT code), defined in ISO 9362 +func isIsoBicFormat(fl FieldLevel) bool { + bicString := fl.Field().String() + + return bicRegex.MatchString(bicString) +} + +// isSemverFormat is the validation function for validating if the current field's value is a valid semver version, defined in Semantic Versioning 2.0.0 +func isSemverFormat(fl FieldLevel) bool { + semverString := fl.Field().String() + + return semverRegex.MatchString(semverString) +} + +// isDnsRFC1035LabelFormat is the validation function +// for validating if the current field's value is +// a valid dns RFC 1035 label, defined in RFC 1035. +func isDnsRFC1035LabelFormat(fl FieldLevel) bool { + val := fl.Field().String() + return dnsRegexRFC1035Label.MatchString(val) +} diff --git a/vendor/github.com/go-playground/validator/v10/cache.go b/vendor/github.com/go-playground/validator/v10/cache.go new file mode 100644 index 0000000..0d18d6e --- /dev/null +++ b/vendor/github.com/go-playground/validator/v10/cache.go @@ -0,0 +1,322 @@ +package validator + +import ( + "fmt" + "reflect" + "strings" + "sync" + "sync/atomic" +) + +type tagType uint8 + +const ( + typeDefault tagType = iota + typeOmitEmpty + typeIsDefault + typeNoStructLevel + typeStructOnly + typeDive + typeOr + typeKeys + typeEndKeys +) + +const ( + invalidValidation = "Invalid validation tag on field '%s'" + undefinedValidation = "Undefined validation function '%s' on field '%s'" + keysTagNotDefined = "'" + endKeysTag + "' tag encountered without a corresponding '" + keysTag + "' tag" +) + +type structCache struct { + lock sync.Mutex + m atomic.Value // map[reflect.Type]*cStruct +} + +func (sc *structCache) Get(key reflect.Type) (c *cStruct, found bool) { + c, found = sc.m.Load().(map[reflect.Type]*cStruct)[key] + return +} + +func (sc *structCache) Set(key reflect.Type, value *cStruct) { + m := sc.m.Load().(map[reflect.Type]*cStruct) + nm := make(map[reflect.Type]*cStruct, len(m)+1) + for k, v := range m { + nm[k] = v + } + nm[key] = value + sc.m.Store(nm) +} + +type tagCache struct { + lock sync.Mutex + m atomic.Value // map[string]*cTag +} + +func (tc *tagCache) Get(key string) (c *cTag, found bool) { + c, found = tc.m.Load().(map[string]*cTag)[key] + return +} + +func (tc *tagCache) Set(key string, value *cTag) { + m := tc.m.Load().(map[string]*cTag) + nm := make(map[string]*cTag, len(m)+1) + for k, v := range m { + nm[k] = v + } + nm[key] = value + tc.m.Store(nm) +} + +type cStruct struct { + name string + fields []*cField + fn StructLevelFuncCtx +} + +type cField struct { + idx int + name string + altName string + namesEqual bool + cTags *cTag +} + +type cTag struct { + tag string + aliasTag string + actualAliasTag string + param string + keys *cTag // only populated when using tag's 'keys' and 'endkeys' for map key validation + next *cTag + fn FuncCtx + typeof tagType + hasTag bool + hasAlias bool + hasParam bool // true if parameter used eg. eq= where the equal sign has been set + isBlockEnd bool // indicates the current tag represents the last validation in the block + runValidationWhenNil bool +} + +func (v *Validate) extractStructCache(current reflect.Value, sName string) *cStruct { + v.structCache.lock.Lock() + defer v.structCache.lock.Unlock() // leave as defer! because if inner panics, it will never get unlocked otherwise! + + typ := current.Type() + + // could have been multiple trying to access, but once first is done this ensures struct + // isn't parsed again. + cs, ok := v.structCache.Get(typ) + if ok { + return cs + } + + cs = &cStruct{name: sName, fields: make([]*cField, 0), fn: v.structLevelFuncs[typ]} + + numFields := current.NumField() + + var ctag *cTag + var fld reflect.StructField + var tag string + var customName string + + for i := 0; i < numFields; i++ { + + fld = typ.Field(i) + + if !fld.Anonymous && len(fld.PkgPath) > 0 { + continue + } + + tag = fld.Tag.Get(v.tagName) + + if tag == skipValidationTag { + continue + } + + customName = fld.Name + + if v.hasTagNameFunc { + name := v.tagNameFunc(fld) + if len(name) > 0 { + customName = name + } + } + + // NOTE: cannot use shared tag cache, because tags may be equal, but things like alias may be different + // and so only struct level caching can be used instead of combined with Field tag caching + + if len(tag) > 0 { + ctag, _ = v.parseFieldTagsRecursive(tag, fld.Name, "", false) + } else { + // even if field doesn't have validations need cTag for traversing to potential inner/nested + // elements of the field. + ctag = new(cTag) + } + + cs.fields = append(cs.fields, &cField{ + idx: i, + name: fld.Name, + altName: customName, + cTags: ctag, + namesEqual: fld.Name == customName, + }) + } + v.structCache.Set(typ, cs) + return cs +} + +func (v *Validate) parseFieldTagsRecursive(tag string, fieldName string, alias string, hasAlias bool) (firstCtag *cTag, current *cTag) { + var t string + noAlias := len(alias) == 0 + tags := strings.Split(tag, tagSeparator) + + for i := 0; i < len(tags); i++ { + t = tags[i] + if noAlias { + alias = t + } + + // check map for alias and process new tags, otherwise process as usual + if tagsVal, found := v.aliases[t]; found { + if i == 0 { + firstCtag, current = v.parseFieldTagsRecursive(tagsVal, fieldName, t, true) + } else { + next, curr := v.parseFieldTagsRecursive(tagsVal, fieldName, t, true) + current.next, current = next, curr + + } + continue + } + + var prevTag tagType + + if i == 0 { + current = &cTag{aliasTag: alias, hasAlias: hasAlias, hasTag: true, typeof: typeDefault} + firstCtag = current + } else { + prevTag = current.typeof + current.next = &cTag{aliasTag: alias, hasAlias: hasAlias, hasTag: true} + current = current.next + } + + switch t { + case diveTag: + current.typeof = typeDive + continue + + case keysTag: + current.typeof = typeKeys + + if i == 0 || prevTag != typeDive { + panic(fmt.Sprintf("'%s' tag must be immediately preceded by the '%s' tag", keysTag, diveTag)) + } + + current.typeof = typeKeys + + // need to pass along only keys tag + // need to increment i to skip over the keys tags + b := make([]byte, 0, 64) + + i++ + + for ; i < len(tags); i++ { + + b = append(b, tags[i]...) + b = append(b, ',') + + if tags[i] == endKeysTag { + break + } + } + + current.keys, _ = v.parseFieldTagsRecursive(string(b[:len(b)-1]), fieldName, "", false) + continue + + case endKeysTag: + current.typeof = typeEndKeys + + // if there are more in tags then there was no keysTag defined + // and an error should be thrown + if i != len(tags)-1 { + panic(keysTagNotDefined) + } + return + + case omitempty: + current.typeof = typeOmitEmpty + continue + + case structOnlyTag: + current.typeof = typeStructOnly + continue + + case noStructLevelTag: + current.typeof = typeNoStructLevel + continue + + default: + if t == isdefault { + current.typeof = typeIsDefault + } + // if a pipe character is needed within the param you must use the utf8Pipe representation "0x7C" + orVals := strings.Split(t, orSeparator) + + for j := 0; j < len(orVals); j++ { + vals := strings.SplitN(orVals[j], tagKeySeparator, 2) + if noAlias { + alias = vals[0] + current.aliasTag = alias + } else { + current.actualAliasTag = t + } + + if j > 0 { + current.next = &cTag{aliasTag: alias, actualAliasTag: current.actualAliasTag, hasAlias: hasAlias, hasTag: true} + current = current.next + } + current.hasParam = len(vals) > 1 + + current.tag = vals[0] + if len(current.tag) == 0 { + panic(strings.TrimSpace(fmt.Sprintf(invalidValidation, fieldName))) + } + + if wrapper, ok := v.validations[current.tag]; ok { + current.fn = wrapper.fn + current.runValidationWhenNil = wrapper.runValidatinOnNil + } else { + panic(strings.TrimSpace(fmt.Sprintf(undefinedValidation, current.tag, fieldName))) + } + + if len(orVals) > 1 { + current.typeof = typeOr + } + + if len(vals) > 1 { + current.param = strings.Replace(strings.Replace(vals[1], utf8HexComma, ",", -1), utf8Pipe, "|", -1) + } + } + current.isBlockEnd = true + } + } + return +} + +func (v *Validate) fetchCacheTag(tag string) *cTag { + // find cached tag + ctag, found := v.tagCache.Get(tag) + if !found { + v.tagCache.lock.Lock() + defer v.tagCache.lock.Unlock() + + // could have been multiple trying to access, but once first is done this ensures tag + // isn't parsed again. + ctag, found = v.tagCache.Get(tag) + if !found { + ctag, _ = v.parseFieldTagsRecursive(tag, "", "", false) + v.tagCache.Set(tag, ctag) + } + } + return ctag +} diff --git a/vendor/github.com/go-playground/validator/v10/country_codes.go b/vendor/github.com/go-playground/validator/v10/country_codes.go new file mode 100644 index 0000000..0d9eda0 --- /dev/null +++ b/vendor/github.com/go-playground/validator/v10/country_codes.go @@ -0,0 +1,1132 @@ +package validator + +var iso3166_1_alpha2 = map[string]bool{ + // see: https://www.iso.org/iso-3166-country-codes.html + "AF": true, "AX": true, "AL": true, "DZ": true, "AS": true, + "AD": true, "AO": true, "AI": true, "AQ": true, "AG": true, + "AR": true, "AM": true, "AW": true, "AU": true, "AT": true, + "AZ": true, "BS": true, "BH": true, "BD": true, "BB": true, + "BY": true, "BE": true, "BZ": true, "BJ": true, "BM": true, + "BT": true, "BO": true, "BQ": true, "BA": true, "BW": true, + "BV": true, "BR": true, "IO": true, "BN": true, "BG": true, + "BF": true, "BI": true, "KH": true, "CM": true, "CA": true, + "CV": true, "KY": true, "CF": true, "TD": true, "CL": true, + "CN": true, "CX": true, "CC": true, "CO": true, "KM": true, + "CG": true, "CD": true, "CK": true, "CR": true, "CI": true, + "HR": true, "CU": true, "CW": true, "CY": true, "CZ": true, + "DK": true, "DJ": true, "DM": true, "DO": true, "EC": true, + "EG": true, "SV": true, "GQ": true, "ER": true, "EE": true, + "ET": true, "FK": true, "FO": true, "FJ": true, "FI": true, + "FR": true, "GF": true, "PF": true, "TF": true, "GA": true, + "GM": true, "GE": true, "DE": true, "GH": true, "GI": true, + "GR": true, "GL": true, "GD": true, "GP": true, "GU": true, + "GT": true, "GG": true, "GN": true, "GW": true, "GY": true, + "HT": true, "HM": true, "VA": true, "HN": true, "HK": true, + "HU": true, "IS": true, "IN": true, "ID": true, "IR": true, + "IQ": true, "IE": true, "IM": true, "IL": true, "IT": true, + "JM": true, "JP": true, "JE": true, "JO": true, "KZ": true, + "KE": true, "KI": true, "KP": true, "KR": true, "KW": true, + "KG": true, "LA": true, "LV": true, "LB": true, "LS": true, + "LR": true, "LY": true, "LI": true, "LT": true, "LU": true, + "MO": true, "MK": true, "MG": true, "MW": true, "MY": true, + "MV": true, "ML": true, "MT": true, "MH": true, "MQ": true, + "MR": true, "MU": true, "YT": true, "MX": true, "FM": true, + "MD": true, "MC": true, "MN": true, "ME": true, "MS": true, + "MA": true, "MZ": true, "MM": true, "NA": true, "NR": true, + "NP": true, "NL": true, "NC": true, "NZ": true, "NI": true, + "NE": true, "NG": true, "NU": true, "NF": true, "MP": true, + "NO": true, "OM": true, "PK": true, "PW": true, "PS": true, + "PA": true, "PG": true, "PY": true, "PE": true, "PH": true, + "PN": true, "PL": true, "PT": true, "PR": true, "QA": true, + "RE": true, "RO": true, "RU": true, "RW": true, "BL": true, + "SH": true, "KN": true, "LC": true, "MF": true, "PM": true, + "VC": true, "WS": true, "SM": true, "ST": true, "SA": true, + "SN": true, "RS": true, "SC": true, "SL": true, "SG": true, + "SX": true, "SK": true, "SI": true, "SB": true, "SO": true, + "ZA": true, "GS": true, "SS": true, "ES": true, "LK": true, + "SD": true, "SR": true, "SJ": true, "SZ": true, "SE": true, + "CH": true, "SY": true, "TW": true, "TJ": true, "TZ": true, + "TH": true, "TL": true, "TG": true, "TK": true, "TO": true, + "TT": true, "TN": true, "TR": true, "TM": true, "TC": true, + "TV": true, "UG": true, "UA": true, "AE": true, "GB": true, + "US": true, "UM": true, "UY": true, "UZ": true, "VU": true, + "VE": true, "VN": true, "VG": true, "VI": true, "WF": true, + "EH": true, "YE": true, "ZM": true, "ZW": true, +} + +var iso3166_1_alpha3 = map[string]bool{ + // see: https://www.iso.org/iso-3166-country-codes.html + "AFG": true, "ALB": true, "DZA": true, "ASM": true, "AND": true, + "AGO": true, "AIA": true, "ATA": true, "ATG": true, "ARG": true, + "ARM": true, "ABW": true, "AUS": true, "AUT": true, "AZE": true, + "BHS": true, "BHR": true, "BGD": true, "BRB": true, "BLR": true, + "BEL": true, "BLZ": true, "BEN": true, "BMU": true, "BTN": true, + "BOL": true, "BES": true, "BIH": true, "BWA": true, "BVT": true, + "BRA": true, "IOT": true, "BRN": true, "BGR": true, "BFA": true, + "BDI": true, "CPV": true, "KHM": true, "CMR": true, "CAN": true, + "CYM": true, "CAF": true, "TCD": true, "CHL": true, "CHN": true, + "CXR": true, "CCK": true, "COL": true, "COM": true, "COD": true, + "COG": true, "COK": true, "CRI": true, "HRV": true, "CUB": true, + "CUW": true, "CYP": true, "CZE": true, "CIV": true, "DNK": true, + "DJI": true, "DMA": true, "DOM": true, "ECU": true, "EGY": true, + "SLV": true, "GNQ": true, "ERI": true, "EST": true, "SWZ": true, + "ETH": true, "FLK": true, "FRO": true, "FJI": true, "FIN": true, + "FRA": true, "GUF": true, "PYF": true, "ATF": true, "GAB": true, + "GMB": true, "GEO": true, "DEU": true, "GHA": true, "GIB": true, + "GRC": true, "GRL": true, "GRD": true, "GLP": true, "GUM": true, + "GTM": true, "GGY": true, "GIN": true, "GNB": true, "GUY": true, + "HTI": true, "HMD": true, "VAT": true, "HND": true, "HKG": true, + "HUN": true, "ISL": true, "IND": true, "IDN": true, "IRN": true, + "IRQ": true, "IRL": true, "IMN": true, "ISR": true, "ITA": true, + "JAM": true, "JPN": true, "JEY": true, "JOR": true, "KAZ": true, + "KEN": true, "KIR": true, "PRK": true, "KOR": true, "KWT": true, + "KGZ": true, "LAO": true, "LVA": true, "LBN": true, "LSO": true, + "LBR": true, "LBY": true, "LIE": true, "LTU": true, "LUX": true, + "MAC": true, "MDG": true, "MWI": true, "MYS": true, "MDV": true, + "MLI": true, "MLT": true, "MHL": true, "MTQ": true, "MRT": true, + "MUS": true, "MYT": true, "MEX": true, "FSM": true, "MDA": true, + "MCO": true, "MNG": true, "MNE": true, "MSR": true, "MAR": true, + "MOZ": true, "MMR": true, "NAM": true, "NRU": true, "NPL": true, + "NLD": true, "NCL": true, "NZL": true, "NIC": true, "NER": true, + "NGA": true, "NIU": true, "NFK": true, "MKD": true, "MNP": true, + "NOR": true, "OMN": true, "PAK": true, "PLW": true, "PSE": true, + "PAN": true, "PNG": true, "PRY": true, "PER": true, "PHL": true, + "PCN": true, "POL": true, "PRT": true, "PRI": true, "QAT": true, + "ROU": true, "RUS": true, "RWA": true, "REU": true, "BLM": true, + "SHN": true, "KNA": true, "LCA": true, "MAF": true, "SPM": true, + "VCT": true, "WSM": true, "SMR": true, "STP": true, "SAU": true, + "SEN": true, "SRB": true, "SYC": true, "SLE": true, "SGP": true, + "SXM": true, "SVK": true, "SVN": true, "SLB": true, "SOM": true, + "ZAF": true, "SGS": true, "SSD": true, "ESP": true, "LKA": true, + "SDN": true, "SUR": true, "SJM": true, "SWE": true, "CHE": true, + "SYR": true, "TWN": true, "TJK": true, "TZA": true, "THA": true, + "TLS": true, "TGO": true, "TKL": true, "TON": true, "TTO": true, + "TUN": true, "TUR": true, "TKM": true, "TCA": true, "TUV": true, + "UGA": true, "UKR": true, "ARE": true, "GBR": true, "UMI": true, + "USA": true, "URY": true, "UZB": true, "VUT": true, "VEN": true, + "VNM": true, "VGB": true, "VIR": true, "WLF": true, "ESH": true, + "YEM": true, "ZMB": true, "ZWE": true, "ALA": true, +} +var iso3166_1_alpha_numeric = map[int]bool{ + // see: https://www.iso.org/iso-3166-country-codes.html + 4: true, 8: true, 12: true, 16: true, 20: true, + 24: true, 660: true, 10: true, 28: true, 32: true, + 51: true, 533: true, 36: true, 40: true, 31: true, + 44: true, 48: true, 50: true, 52: true, 112: true, + 56: true, 84: true, 204: true, 60: true, 64: true, + 68: true, 535: true, 70: true, 72: true, 74: true, + 76: true, 86: true, 96: true, 100: true, 854: true, + 108: true, 132: true, 116: true, 120: true, 124: true, + 136: true, 140: true, 148: true, 152: true, 156: true, + 162: true, 166: true, 170: true, 174: true, 180: true, + 178: true, 184: true, 188: true, 191: true, 192: true, + 531: true, 196: true, 203: true, 384: true, 208: true, + 262: true, 212: true, 214: true, 218: true, 818: true, + 222: true, 226: true, 232: true, 233: true, 748: true, + 231: true, 238: true, 234: true, 242: true, 246: true, + 250: true, 254: true, 258: true, 260: true, 266: true, + 270: true, 268: true, 276: true, 288: true, 292: true, + 300: true, 304: true, 308: true, 312: true, 316: true, + 320: true, 831: true, 324: true, 624: true, 328: true, + 332: true, 334: true, 336: true, 340: true, 344: true, + 348: true, 352: true, 356: true, 360: true, 364: true, + 368: true, 372: true, 833: true, 376: true, 380: true, + 388: true, 392: true, 832: true, 400: true, 398: true, + 404: true, 296: true, 408: true, 410: true, 414: true, + 417: true, 418: true, 428: true, 422: true, 426: true, + 430: true, 434: true, 438: true, 440: true, 442: true, + 446: true, 450: true, 454: true, 458: true, 462: true, + 466: true, 470: true, 584: true, 474: true, 478: true, + 480: true, 175: true, 484: true, 583: true, 498: true, + 492: true, 496: true, 499: true, 500: true, 504: true, + 508: true, 104: true, 516: true, 520: true, 524: true, + 528: true, 540: true, 554: true, 558: true, 562: true, + 566: true, 570: true, 574: true, 807: true, 580: true, + 578: true, 512: true, 586: true, 585: true, 275: true, + 591: true, 598: true, 600: true, 604: true, 608: true, + 612: true, 616: true, 620: true, 630: true, 634: true, + 642: true, 643: true, 646: true, 638: true, 652: true, + 654: true, 659: true, 662: true, 663: true, 666: true, + 670: true, 882: true, 674: true, 678: true, 682: true, + 686: true, 688: true, 690: true, 694: true, 702: true, + 534: true, 703: true, 705: true, 90: true, 706: true, + 710: true, 239: true, 728: true, 724: true, 144: true, + 729: true, 740: true, 744: true, 752: true, 756: true, + 760: true, 158: true, 762: true, 834: true, 764: true, + 626: true, 768: true, 772: true, 776: true, 780: true, + 788: true, 792: true, 795: true, 796: true, 798: true, + 800: true, 804: true, 784: true, 826: true, 581: true, + 840: true, 858: true, 860: true, 548: true, 862: true, + 704: true, 92: true, 850: true, 876: true, 732: true, + 887: true, 894: true, 716: true, 248: true, +} + +var iso3166_2 = map[string]bool{ + "AD-02" : true, "AD-03" : true, "AD-04" : true, "AD-05" : true, "AD-06" : true, + "AD-07" : true, "AD-08" : true, "AE-AJ" : true, "AE-AZ" : true, "AE-DU" : true, + "AE-FU" : true, "AE-RK" : true, "AE-SH" : true, "AE-UQ" : true, "AF-BAL" : true, + "AF-BAM" : true, "AF-BDG" : true, "AF-BDS" : true, "AF-BGL" : true, "AF-DAY" : true, + "AF-FRA" : true, "AF-FYB" : true, "AF-GHA" : true, "AF-GHO" : true, "AF-HEL" : true, + "AF-HER" : true, "AF-JOW" : true, "AF-KAB" : true, "AF-KAN" : true, "AF-KAP" : true, + "AF-KDZ" : true, "AF-KHO" : true, "AF-KNR" : true, "AF-LAG" : true, "AF-LOG" : true, + "AF-NAN" : true, "AF-NIM" : true, "AF-NUR" : true, "AF-PAN" : true, "AF-PAR" : true, + "AF-PIA" : true, "AF-PKA" : true, "AF-SAM" : true, "AF-SAR" : true, "AF-TAK" : true, + "AF-URU" : true, "AF-WAR" : true, "AF-ZAB" : true, "AG-03" : true, "AG-04" : true, + "AG-05" : true, "AG-06" : true, "AG-07" : true, "AG-08" : true, "AG-10" : true, + "AG-11" : true, "AL-01" : true, "AL-02" : true, "AL-03" : true, "AL-04" : true, + "AL-05" : true, "AL-06" : true, "AL-07" : true, "AL-08" : true, "AL-09" : true, + "AL-10" : true, "AL-11" : true, "AL-12" : true, "AL-BR" : true, "AL-BU" : true, + "AL-DI" : true, "AL-DL" : true, "AL-DR" : true, "AL-DV" : true, "AL-EL" : true, + "AL-ER" : true, "AL-FR" : true, "AL-GJ" : true, "AL-GR" : true, "AL-HA" : true, + "AL-KA" : true, "AL-KB" : true, "AL-KC" : true, "AL-KO" : true, "AL-KR" : true, + "AL-KU" : true, "AL-LB" : true, "AL-LE" : true, "AL-LU" : true, "AL-MK" : true, + "AL-MM" : true, "AL-MR" : true, "AL-MT" : true, "AL-PG" : true, "AL-PQ" : true, + "AL-PR" : true, "AL-PU" : true, "AL-SH" : true, "AL-SK" : true, "AL-SR" : true, + "AL-TE" : true, "AL-TP" : true, "AL-TR" : true, "AL-VL" : true, "AM-AG" : true, + "AM-AR" : true, "AM-AV" : true, "AM-ER" : true, "AM-GR" : true, "AM-KT" : true, + "AM-LO" : true, "AM-SH" : true, "AM-SU" : true, "AM-TV" : true, "AM-VD" : true, + "AO-BGO" : true, "AO-BGU" : true, "AO-BIE" : true, "AO-CAB" : true, "AO-CCU" : true, + "AO-CNN" : true, "AO-CNO" : true, "AO-CUS" : true, "AO-HUA" : true, "AO-HUI" : true, + "AO-LNO" : true, "AO-LSU" : true, "AO-LUA" : true, "AO-MAL" : true, "AO-MOX" : true, + "AO-NAM" : true, "AO-UIG" : true, "AO-ZAI" : true, "AR-A" : true, "AR-B" : true, + "AR-C" : true, "AR-D" : true, "AR-E" : true, "AR-G" : true, "AR-H" : true, + "AR-J" : true, "AR-K" : true, "AR-L" : true, "AR-M" : true, "AR-N" : true, + "AR-P" : true, "AR-Q" : true, "AR-R" : true, "AR-S" : true, "AR-T" : true, + "AR-U" : true, "AR-V" : true, "AR-W" : true, "AR-X" : true, "AR-Y" : true, + "AR-Z" : true, "AT-1" : true, "AT-2" : true, "AT-3" : true, "AT-4" : true, + "AT-5" : true, "AT-6" : true, "AT-7" : true, "AT-8" : true, "AT-9" : true, + "AU-ACT" : true, "AU-NSW" : true, "AU-NT" : true, "AU-QLD" : true, "AU-SA" : true, + "AU-TAS" : true, "AU-VIC" : true, "AU-WA" : true, "AZ-ABS" : true, "AZ-AGA" : true, + "AZ-AGC" : true, "AZ-AGM" : true, "AZ-AGS" : true, "AZ-AGU" : true, "AZ-AST" : true, + "AZ-BA" : true, "AZ-BAB" : true, "AZ-BAL" : true, "AZ-BAR" : true, "AZ-BEY" : true, + "AZ-BIL" : true, "AZ-CAB" : true, "AZ-CAL" : true, "AZ-CUL" : true, "AZ-DAS" : true, + "AZ-FUZ" : true, "AZ-GA" : true, "AZ-GAD" : true, "AZ-GOR" : true, "AZ-GOY" : true, + "AZ-GYG" : true, "AZ-HAC" : true, "AZ-IMI" : true, "AZ-ISM" : true, "AZ-KAL" : true, + "AZ-KAN" : true, "AZ-KUR" : true, "AZ-LA" : true, "AZ-LAC" : true, "AZ-LAN" : true, + "AZ-LER" : true, "AZ-MAS" : true, "AZ-MI" : true, "AZ-NA" : true, "AZ-NEF" : true, + "AZ-NV" : true, "AZ-NX" : true, "AZ-OGU" : true, "AZ-ORD" : true, "AZ-QAB" : true, + "AZ-QAX" : true, "AZ-QAZ" : true, "AZ-QBA" : true, "AZ-QBI" : true, "AZ-QOB" : true, + "AZ-QUS" : true, "AZ-SA" : true, "AZ-SAB" : true, "AZ-SAD" : true, "AZ-SAH" : true, + "AZ-SAK" : true, "AZ-SAL" : true, "AZ-SAR" : true, "AZ-SAT" : true, "AZ-SBN" : true, + "AZ-SIY" : true, "AZ-SKR" : true, "AZ-SM" : true, "AZ-SMI" : true, "AZ-SMX" : true, + "AZ-SR" : true, "AZ-SUS" : true, "AZ-TAR" : true, "AZ-TOV" : true, "AZ-UCA" : true, + "AZ-XA" : true, "AZ-XAC" : true, "AZ-XCI" : true, "AZ-XIZ" : true, "AZ-XVD" : true, + "AZ-YAR" : true, "AZ-YE" : true, "AZ-YEV" : true, "AZ-ZAN" : true, "AZ-ZAQ" : true, + "AZ-ZAR" : true, "BA-01" : true, "BA-02" : true, "BA-03" : true, "BA-04" : true, + "BA-05" : true, "BA-06" : true, "BA-07" : true, "BA-08" : true, "BA-09" : true, + "BA-10" : true, "BA-BIH" : true, "BA-BRC" : true, "BA-SRP" : true, "BB-01" : true, + "BB-02" : true, "BB-03" : true, "BB-04" : true, "BB-05" : true, "BB-06" : true, + "BB-07" : true, "BB-08" : true, "BB-09" : true, "BB-10" : true, "BB-11" : true, + "BD-01" : true, "BD-02" : true, "BD-03" : true, "BD-04" : true, "BD-05" : true, + "BD-06" : true, "BD-07" : true, "BD-08" : true, "BD-09" : true, "BD-10" : true, + "BD-11" : true, "BD-12" : true, "BD-13" : true, "BD-14" : true, "BD-15" : true, + "BD-16" : true, "BD-17" : true, "BD-18" : true, "BD-19" : true, "BD-20" : true, + "BD-21" : true, "BD-22" : true, "BD-23" : true, "BD-24" : true, "BD-25" : true, + "BD-26" : true, "BD-27" : true, "BD-28" : true, "BD-29" : true, "BD-30" : true, + "BD-31" : true, "BD-32" : true, "BD-33" : true, "BD-34" : true, "BD-35" : true, + "BD-36" : true, "BD-37" : true, "BD-38" : true, "BD-39" : true, "BD-40" : true, + "BD-41" : true, "BD-42" : true, "BD-43" : true, "BD-44" : true, "BD-45" : true, + "BD-46" : true, "BD-47" : true, "BD-48" : true, "BD-49" : true, "BD-50" : true, + "BD-51" : true, "BD-52" : true, "BD-53" : true, "BD-54" : true, "BD-55" : true, + "BD-56" : true, "BD-57" : true, "BD-58" : true, "BD-59" : true, "BD-60" : true, + "BD-61" : true, "BD-62" : true, "BD-63" : true, "BD-64" : true, "BD-A" : true, + "BD-B" : true, "BD-C" : true, "BD-D" : true, "BD-E" : true, "BD-F" : true, + "BD-G" : true, "BE-BRU" : true, "BE-VAN" : true, "BE-VBR" : true, "BE-VLG" : true, + "BE-VLI" : true, "BE-VOV" : true, "BE-VWV" : true, "BE-WAL" : true, "BE-WBR" : true, + "BE-WHT" : true, "BE-WLG" : true, "BE-WLX" : true, "BE-WNA" : true, "BF-01" : true, + "BF-02" : true, "BF-03" : true, "BF-04" : true, "BF-05" : true, "BF-06" : true, + "BF-07" : true, "BF-08" : true, "BF-09" : true, "BF-10" : true, "BF-11" : true, + "BF-12" : true, "BF-13" : true, "BF-BAL" : true, "BF-BAM" : true, "BF-BAN" : true, + "BF-BAZ" : true, "BF-BGR" : true, "BF-BLG" : true, "BF-BLK" : true, "BF-COM" : true, + "BF-GAN" : true, "BF-GNA" : true, "BF-GOU" : true, "BF-HOU" : true, "BF-IOB" : true, + "BF-KAD" : true, "BF-KEN" : true, "BF-KMD" : true, "BF-KMP" : true, "BF-KOP" : true, + "BF-KOS" : true, "BF-KOT" : true, "BF-KOW" : true, "BF-LER" : true, "BF-LOR" : true, + "BF-MOU" : true, "BF-NAM" : true, "BF-NAO" : true, "BF-NAY" : true, "BF-NOU" : true, + "BF-OUB" : true, "BF-OUD" : true, "BF-PAS" : true, "BF-PON" : true, "BF-SEN" : true, + "BF-SIS" : true, "BF-SMT" : true, "BF-SNG" : true, "BF-SOM" : true, "BF-SOR" : true, + "BF-TAP" : true, "BF-TUI" : true, "BF-YAG" : true, "BF-YAT" : true, "BF-ZIR" : true, + "BF-ZON" : true, "BF-ZOU" : true, "BG-01" : true, "BG-02" : true, "BG-03" : true, + "BG-04" : true, "BG-05" : true, "BG-06" : true, "BG-07" : true, "BG-08" : true, + "BG-09" : true, "BG-10" : true, "BG-11" : true, "BG-12" : true, "BG-13" : true, + "BG-14" : true, "BG-15" : true, "BG-16" : true, "BG-17" : true, "BG-18" : true, + "BG-19" : true, "BG-20" : true, "BG-21" : true, "BG-22" : true, "BG-23" : true, + "BG-24" : true, "BG-25" : true, "BG-26" : true, "BG-27" : true, "BG-28" : true, + "BH-13" : true, "BH-14" : true, "BH-15" : true, "BH-16" : true, "BH-17" : true, + "BI-BB" : true, "BI-BL" : true, "BI-BM" : true, "BI-BR" : true, "BI-CA" : true, + "BI-CI" : true, "BI-GI" : true, "BI-KI" : true, "BI-KR" : true, "BI-KY" : true, + "BI-MA" : true, "BI-MU" : true, "BI-MW" : true, "BI-NG" : true, "BI-RT" : true, + "BI-RY" : true, "BJ-AK" : true, "BJ-AL" : true, "BJ-AQ" : true, "BJ-BO" : true, + "BJ-CO" : true, "BJ-DO" : true, "BJ-KO" : true, "BJ-LI" : true, "BJ-MO" : true, + "BJ-OU" : true, "BJ-PL" : true, "BJ-ZO" : true, "BN-BE" : true, "BN-BM" : true, + "BN-TE" : true, "BN-TU" : true, "BO-B" : true, "BO-C" : true, "BO-H" : true, + "BO-L" : true, "BO-N" : true, "BO-O" : true, "BO-P" : true, "BO-S" : true, + "BO-T" : true, "BQ-BO" : true, "BQ-SA" : true, "BQ-SE" : true, "BR-AC" : true, + "BR-AL" : true, "BR-AM" : true, "BR-AP" : true, "BR-BA" : true, "BR-CE" : true, + "BR-DF" : true, "BR-ES" : true, "BR-FN" : true, "BR-GO" : true, "BR-MA" : true, + "BR-MG" : true, "BR-MS" : true, "BR-MT" : true, "BR-PA" : true, "BR-PB" : true, + "BR-PE" : true, "BR-PI" : true, "BR-PR" : true, "BR-RJ" : true, "BR-RN" : true, + "BR-RO" : true, "BR-RR" : true, "BR-RS" : true, "BR-SC" : true, "BR-SE" : true, + "BR-SP" : true, "BR-TO" : true, "BS-AK" : true, "BS-BI" : true, "BS-BP" : true, + "BS-BY" : true, "BS-CE" : true, "BS-CI" : true, "BS-CK" : true, "BS-CO" : true, + "BS-CS" : true, "BS-EG" : true, "BS-EX" : true, "BS-FP" : true, "BS-GC" : true, + "BS-HI" : true, "BS-HT" : true, "BS-IN" : true, "BS-LI" : true, "BS-MC" : true, + "BS-MG" : true, "BS-MI" : true, "BS-NE" : true, "BS-NO" : true, "BS-NS" : true, + "BS-RC" : true, "BS-RI" : true, "BS-SA" : true, "BS-SE" : true, "BS-SO" : true, + "BS-SS" : true, "BS-SW" : true, "BS-WG" : true, "BT-11" : true, "BT-12" : true, + "BT-13" : true, "BT-14" : true, "BT-15" : true, "BT-21" : true, "BT-22" : true, + "BT-23" : true, "BT-24" : true, "BT-31" : true, "BT-32" : true, "BT-33" : true, + "BT-34" : true, "BT-41" : true, "BT-42" : true, "BT-43" : true, "BT-44" : true, + "BT-45" : true, "BT-GA" : true, "BT-TY" : true, "BW-CE" : true, "BW-GH" : true, + "BW-KG" : true, "BW-KL" : true, "BW-KW" : true, "BW-NE" : true, "BW-NW" : true, + "BW-SE" : true, "BW-SO" : true, "BY-BR" : true, "BY-HM" : true, "BY-HO" : true, + "BY-HR" : true, "BY-MA" : true, "BY-MI" : true, "BY-VI" : true, "BZ-BZ" : true, + "BZ-CY" : true, "BZ-CZL" : true, "BZ-OW" : true, "BZ-SC" : true, "BZ-TOL" : true, + "CA-AB" : true, "CA-BC" : true, "CA-MB" : true, "CA-NB" : true, "CA-NL" : true, + "CA-NS" : true, "CA-NT" : true, "CA-NU" : true, "CA-ON" : true, "CA-PE" : true, + "CA-QC" : true, "CA-SK" : true, "CA-YT" : true, "CD-BC" : true, "CD-BN" : true, + "CD-EQ" : true, "CD-KA" : true, "CD-KE" : true, "CD-KN" : true, "CD-KW" : true, + "CD-MA" : true, "CD-NK" : true, "CD-OR" : true, "CD-SK" : true, "CF-AC" : true, + "CF-BB" : true, "CF-BGF" : true, "CF-BK" : true, "CF-HK" : true, "CF-HM" : true, + "CF-HS" : true, "CF-KB" : true, "CF-KG" : true, "CF-LB" : true, "CF-MB" : true, + "CF-MP" : true, "CF-NM" : true, "CF-OP" : true, "CF-SE" : true, "CF-UK" : true, + "CF-VK" : true, "CG-11" : true, "CG-12" : true, "CG-13" : true, "CG-14" : true, + "CG-15" : true, "CG-2" : true, "CG-5" : true, "CG-7" : true, "CG-8" : true, + "CG-9" : true, "CG-BZV" : true, "CH-AG" : true, "CH-AI" : true, "CH-AR" : true, + "CH-BE" : true, "CH-BL" : true, "CH-BS" : true, "CH-FR" : true, "CH-GE" : true, + "CH-GL" : true, "CH-GR" : true, "CH-JU" : true, "CH-LU" : true, "CH-NE" : true, + "CH-NW" : true, "CH-OW" : true, "CH-SG" : true, "CH-SH" : true, "CH-SO" : true, + "CH-SZ" : true, "CH-TG" : true, "CH-TI" : true, "CH-UR" : true, "CH-VD" : true, + "CH-VS" : true, "CH-ZG" : true, "CH-ZH" : true, "CI-01" : true, "CI-02" : true, + "CI-03" : true, "CI-04" : true, "CI-05" : true, "CI-06" : true, "CI-07" : true, + "CI-08" : true, "CI-09" : true, "CI-10" : true, "CI-11" : true, "CI-12" : true, + "CI-13" : true, "CI-14" : true, "CI-15" : true, "CI-16" : true, "CI-17" : true, + "CI-18" : true, "CI-19" : true, "CL-AI" : true, "CL-AN" : true, "CL-AP" : true, + "CL-AR" : true, "CL-AT" : true, "CL-BI" : true, "CL-CO" : true, "CL-LI" : true, + "CL-LL" : true, "CL-LR" : true, "CL-MA" : true, "CL-ML" : true, "CL-RM" : true, + "CL-TA" : true, "CL-VS" : true, "CM-AD" : true, "CM-CE" : true, "CM-EN" : true, + "CM-ES" : true, "CM-LT" : true, "CM-NO" : true, "CM-NW" : true, "CM-OU" : true, + "CM-SU" : true, "CM-SW" : true, "CN-11" : true, "CN-12" : true, "CN-13" : true, + "CN-14" : true, "CN-15" : true, "CN-21" : true, "CN-22" : true, "CN-23" : true, + "CN-31" : true, "CN-32" : true, "CN-33" : true, "CN-34" : true, "CN-35" : true, + "CN-36" : true, "CN-37" : true, "CN-41" : true, "CN-42" : true, "CN-43" : true, + "CN-44" : true, "CN-45" : true, "CN-46" : true, "CN-50" : true, "CN-51" : true, + "CN-52" : true, "CN-53" : true, "CN-54" : true, "CN-61" : true, "CN-62" : true, + "CN-63" : true, "CN-64" : true, "CN-65" : true, "CN-71" : true, "CN-91" : true, + "CN-92" : true, "CO-AMA" : true, "CO-ANT" : true, "CO-ARA" : true, "CO-ATL" : true, + "CO-BOL" : true, "CO-BOY" : true, "CO-CAL" : true, "CO-CAQ" : true, "CO-CAS" : true, + "CO-CAU" : true, "CO-CES" : true, "CO-CHO" : true, "CO-COR" : true, "CO-CUN" : true, + "CO-DC" : true, "CO-GUA" : true, "CO-GUV" : true, "CO-HUI" : true, "CO-LAG" : true, + "CO-MAG" : true, "CO-MET" : true, "CO-NAR" : true, "CO-NSA" : true, "CO-PUT" : true, + "CO-QUI" : true, "CO-RIS" : true, "CO-SAN" : true, "CO-SAP" : true, "CO-SUC" : true, + "CO-TOL" : true, "CO-VAC" : true, "CO-VAU" : true, "CO-VID" : true, "CR-A" : true, + "CR-C" : true, "CR-G" : true, "CR-H" : true, "CR-L" : true, "CR-P" : true, + "CR-SJ" : true, "CU-01" : true, "CU-02" : true, "CU-03" : true, "CU-04" : true, + "CU-05" : true, "CU-06" : true, "CU-07" : true, "CU-08" : true, "CU-09" : true, + "CU-10" : true, "CU-11" : true, "CU-12" : true, "CU-13" : true, "CU-14" : true, + "CU-99" : true, "CV-B" : true, "CV-BR" : true, "CV-BV" : true, "CV-CA" : true, + "CV-CF" : true, "CV-CR" : true, "CV-MA" : true, "CV-MO" : true, "CV-PA" : true, + "CV-PN" : true, "CV-PR" : true, "CV-RB" : true, "CV-RG" : true, "CV-RS" : true, + "CV-S" : true, "CV-SD" : true, "CV-SF" : true, "CV-SL" : true, "CV-SM" : true, + "CV-SO" : true, "CV-SS" : true, "CV-SV" : true, "CV-TA" : true, "CV-TS" : true, + "CY-01" : true, "CY-02" : true, "CY-03" : true, "CY-04" : true, "CY-05" : true, + "CY-06" : true, "CZ-10" : true, "CZ-101" : true, "CZ-102" : true, "CZ-103" : true, + "CZ-104" : true, "CZ-105" : true, "CZ-106" : true, "CZ-107" : true, "CZ-108" : true, + "CZ-109" : true, "CZ-110" : true, "CZ-111" : true, "CZ-112" : true, "CZ-113" : true, + "CZ-114" : true, "CZ-115" : true, "CZ-116" : true, "CZ-117" : true, "CZ-118" : true, + "CZ-119" : true, "CZ-120" : true, "CZ-121" : true, "CZ-122" : true, "CZ-20" : true, + "CZ-201" : true, "CZ-202" : true, "CZ-203" : true, "CZ-204" : true, "CZ-205" : true, + "CZ-206" : true, "CZ-207" : true, "CZ-208" : true, "CZ-209" : true, "CZ-20A" : true, + "CZ-20B" : true, "CZ-20C" : true, "CZ-31" : true, "CZ-311" : true, "CZ-312" : true, + "CZ-313" : true, "CZ-314" : true, "CZ-315" : true, "CZ-316" : true, "CZ-317" : true, + "CZ-32" : true, "CZ-321" : true, "CZ-322" : true, "CZ-323" : true, "CZ-324" : true, + "CZ-325" : true, "CZ-326" : true, "CZ-327" : true, "CZ-41" : true, "CZ-411" : true, + "CZ-412" : true, "CZ-413" : true, "CZ-42" : true, "CZ-421" : true, "CZ-422" : true, + "CZ-423" : true, "CZ-424" : true, "CZ-425" : true, "CZ-426" : true, "CZ-427" : true, + "CZ-51" : true, "CZ-511" : true, "CZ-512" : true, "CZ-513" : true, "CZ-514" : true, + "CZ-52" : true, "CZ-521" : true, "CZ-522" : true, "CZ-523" : true, "CZ-524" : true, + "CZ-525" : true, "CZ-53" : true, "CZ-531" : true, "CZ-532" : true, "CZ-533" : true, + "CZ-534" : true, "CZ-63" : true, "CZ-631" : true, "CZ-632" : true, "CZ-633" : true, + "CZ-634" : true, "CZ-635" : true, "CZ-64" : true, "CZ-641" : true, "CZ-642" : true, + "CZ-643" : true, "CZ-644" : true, "CZ-645" : true, "CZ-646" : true, "CZ-647" : true, + "CZ-71" : true, "CZ-711" : true, "CZ-712" : true, "CZ-713" : true, "CZ-714" : true, + "CZ-715" : true, "CZ-72" : true, "CZ-721" : true, "CZ-722" : true, "CZ-723" : true, + "CZ-724" : true, "CZ-80" : true, "CZ-801" : true, "CZ-802" : true, "CZ-803" : true, + "CZ-804" : true, "CZ-805" : true, "CZ-806" : true, "DE-BB" : true, "DE-BE" : true, + "DE-BW" : true, "DE-BY" : true, "DE-HB" : true, "DE-HE" : true, "DE-HH" : true, + "DE-MV" : true, "DE-NI" : true, "DE-NW" : true, "DE-RP" : true, "DE-SH" : true, + "DE-SL" : true, "DE-SN" : true, "DE-ST" : true, "DE-TH" : true, "DJ-AR" : true, + "DJ-AS" : true, "DJ-DI" : true, "DJ-DJ" : true, "DJ-OB" : true, "DJ-TA" : true, + "DK-81" : true, "DK-82" : true, "DK-83" : true, "DK-84" : true, "DK-85" : true, + "DM-01" : true, "DM-02" : true, "DM-03" : true, "DM-04" : true, "DM-05" : true, + "DM-06" : true, "DM-07" : true, "DM-08" : true, "DM-09" : true, "DM-10" : true, + "DO-01" : true, "DO-02" : true, "DO-03" : true, "DO-04" : true, "DO-05" : true, + "DO-06" : true, "DO-07" : true, "DO-08" : true, "DO-09" : true, "DO-10" : true, + "DO-11" : true, "DO-12" : true, "DO-13" : true, "DO-14" : true, "DO-15" : true, + "DO-16" : true, "DO-17" : true, "DO-18" : true, "DO-19" : true, "DO-20" : true, + "DO-21" : true, "DO-22" : true, "DO-23" : true, "DO-24" : true, "DO-25" : true, + "DO-26" : true, "DO-27" : true, "DO-28" : true, "DO-29" : true, "DO-30" : true, + "DZ-01" : true, "DZ-02" : true, "DZ-03" : true, "DZ-04" : true, "DZ-05" : true, + "DZ-06" : true, "DZ-07" : true, "DZ-08" : true, "DZ-09" : true, "DZ-10" : true, + "DZ-11" : true, "DZ-12" : true, "DZ-13" : true, "DZ-14" : true, "DZ-15" : true, + "DZ-16" : true, "DZ-17" : true, "DZ-18" : true, "DZ-19" : true, "DZ-20" : true, + "DZ-21" : true, "DZ-22" : true, "DZ-23" : true, "DZ-24" : true, "DZ-25" : true, + "DZ-26" : true, "DZ-27" : true, "DZ-28" : true, "DZ-29" : true, "DZ-30" : true, + "DZ-31" : true, "DZ-32" : true, "DZ-33" : true, "DZ-34" : true, "DZ-35" : true, + "DZ-36" : true, "DZ-37" : true, "DZ-38" : true, "DZ-39" : true, "DZ-40" : true, + "DZ-41" : true, "DZ-42" : true, "DZ-43" : true, "DZ-44" : true, "DZ-45" : true, + "DZ-46" : true, "DZ-47" : true, "DZ-48" : true, "EC-A" : true, "EC-B" : true, + "EC-C" : true, "EC-D" : true, "EC-E" : true, "EC-F" : true, "EC-G" : true, + "EC-H" : true, "EC-I" : true, "EC-L" : true, "EC-M" : true, "EC-N" : true, + "EC-O" : true, "EC-P" : true, "EC-R" : true, "EC-S" : true, "EC-SD" : true, + "EC-SE" : true, "EC-T" : true, "EC-U" : true, "EC-W" : true, "EC-X" : true, + "EC-Y" : true, "EC-Z" : true, "EE-37" : true, "EE-39" : true, "EE-44" : true, + "EE-49" : true, "EE-51" : true, "EE-57" : true, "EE-59" : true, "EE-65" : true, + "EE-67" : true, "EE-70" : true, "EE-74" : true, "EE-78" : true, "EE-82" : true, + "EE-84" : true, "EE-86" : true, "EG-ALX" : true, "EG-ASN" : true, "EG-AST" : true, + "EG-BA" : true, "EG-BH" : true, "EG-BNS" : true, "EG-C" : true, "EG-DK" : true, + "EG-DT" : true, "EG-FYM" : true, "EG-GH" : true, "EG-GZ" : true, "EG-HU" : true, + "EG-IS" : true, "EG-JS" : true, "EG-KB" : true, "EG-KFS" : true, "EG-KN" : true, + "EG-MN" : true, "EG-MNF" : true, "EG-MT" : true, "EG-PTS" : true, "EG-SHG" : true, + "EG-SHR" : true, "EG-SIN" : true, "EG-SU" : true, "EG-SUZ" : true, "EG-WAD" : true, + "ER-AN" : true, "ER-DK" : true, "ER-DU" : true, "ER-GB" : true, "ER-MA" : true, + "ER-SK" : true, "ES-A" : true, "ES-AB" : true, "ES-AL" : true, "ES-AN" : true, + "ES-AR" : true, "ES-AS" : true, "ES-AV" : true, "ES-B" : true, "ES-BA" : true, + "ES-BI" : true, "ES-BU" : true, "ES-C" : true, "ES-CA" : true, "ES-CB" : true, + "ES-CC" : true, "ES-CE" : true, "ES-CL" : true, "ES-CM" : true, "ES-CN" : true, + "ES-CO" : true, "ES-CR" : true, "ES-CS" : true, "ES-CT" : true, "ES-CU" : true, + "ES-EX" : true, "ES-GA" : true, "ES-GC" : true, "ES-GI" : true, "ES-GR" : true, + "ES-GU" : true, "ES-H" : true, "ES-HU" : true, "ES-IB" : true, "ES-J" : true, + "ES-L" : true, "ES-LE" : true, "ES-LO" : true, "ES-LU" : true, "ES-M" : true, + "ES-MA" : true, "ES-MC" : true, "ES-MD" : true, "ES-ML" : true, "ES-MU" : true, + "ES-NA" : true, "ES-NC" : true, "ES-O" : true, "ES-OR" : true, "ES-P" : true, + "ES-PM" : true, "ES-PO" : true, "ES-PV" : true, "ES-RI" : true, "ES-S" : true, + "ES-SA" : true, "ES-SE" : true, "ES-SG" : true, "ES-SO" : true, "ES-SS" : true, + "ES-T" : true, "ES-TE" : true, "ES-TF" : true, "ES-TO" : true, "ES-V" : true, + "ES-VA" : true, "ES-VC" : true, "ES-VI" : true, "ES-Z" : true, "ES-ZA" : true, + "ET-AA" : true, "ET-AF" : true, "ET-AM" : true, "ET-BE" : true, "ET-DD" : true, + "ET-GA" : true, "ET-HA" : true, "ET-OR" : true, "ET-SN" : true, "ET-SO" : true, + "ET-TI" : true, "FI-01" : true, "FI-02" : true, "FI-03" : true, "FI-04" : true, + "FI-05" : true, "FI-06" : true, "FI-07" : true, "FI-08" : true, "FI-09" : true, + "FI-10" : true, "FI-11" : true, "FI-12" : true, "FI-13" : true, "FI-14" : true, + "FI-15" : true, "FI-16" : true, "FI-17" : true, "FI-18" : true, "FI-19" : true, + "FJ-C" : true, "FJ-E" : true, "FJ-N" : true, "FJ-R" : true, "FJ-W" : true, + "FM-KSA" : true, "FM-PNI" : true, "FM-TRK" : true, "FM-YAP" : true, "FR-01" : true, + "FR-02" : true, "FR-03" : true, "FR-04" : true, "FR-05" : true, "FR-06" : true, + "FR-07" : true, "FR-08" : true, "FR-09" : true, "FR-10" : true, "FR-11" : true, + "FR-12" : true, "FR-13" : true, "FR-14" : true, "FR-15" : true, "FR-16" : true, + "FR-17" : true, "FR-18" : true, "FR-19" : true, "FR-21" : true, "FR-22" : true, + "FR-23" : true, "FR-24" : true, "FR-25" : true, "FR-26" : true, "FR-27" : true, + "FR-28" : true, "FR-29" : true, "FR-2A" : true, "FR-2B" : true, "FR-30" : true, + "FR-31" : true, "FR-32" : true, "FR-33" : true, "FR-34" : true, "FR-35" : true, + "FR-36" : true, "FR-37" : true, "FR-38" : true, "FR-39" : true, "FR-40" : true, + "FR-41" : true, "FR-42" : true, "FR-43" : true, "FR-44" : true, "FR-45" : true, + "FR-46" : true, "FR-47" : true, "FR-48" : true, "FR-49" : true, "FR-50" : true, + "FR-51" : true, "FR-52" : true, "FR-53" : true, "FR-54" : true, "FR-55" : true, + "FR-56" : true, "FR-57" : true, "FR-58" : true, "FR-59" : true, "FR-60" : true, + "FR-61" : true, "FR-62" : true, "FR-63" : true, "FR-64" : true, "FR-65" : true, + "FR-66" : true, "FR-67" : true, "FR-68" : true, "FR-69" : true, "FR-70" : true, + "FR-71" : true, "FR-72" : true, "FR-73" : true, "FR-74" : true, "FR-75" : true, + "FR-76" : true, "FR-77" : true, "FR-78" : true, "FR-79" : true, "FR-80" : true, + "FR-81" : true, "FR-82" : true, "FR-83" : true, "FR-84" : true, "FR-85" : true, + "FR-86" : true, "FR-87" : true, "FR-88" : true, "FR-89" : true, "FR-90" : true, + "FR-91" : true, "FR-92" : true, "FR-93" : true, "FR-94" : true, "FR-95" : true, + "FR-ARA" : true, "FR-BFC" : true, "FR-BL" : true, "FR-BRE" : true, "FR-COR" : true, + "FR-CP" : true, "FR-CVL" : true, "FR-GES" : true, "FR-GF" : true, "FR-GP" : true, + "FR-GUA" : true, "FR-HDF" : true, "FR-IDF" : true, "FR-LRE" : true, "FR-MAY" : true, + "FR-MF" : true, "FR-MQ" : true, "FR-NAQ" : true, "FR-NC" : true, "FR-NOR" : true, + "FR-OCC" : true, "FR-PAC" : true, "FR-PDL" : true, "FR-PF" : true, "FR-PM" : true, + "FR-RE" : true, "FR-TF" : true, "FR-WF" : true, "FR-YT" : true, "GA-1" : true, + "GA-2" : true, "GA-3" : true, "GA-4" : true, "GA-5" : true, "GA-6" : true, + "GA-7" : true, "GA-8" : true, "GA-9" : true, "GB-ABC" : true, "GB-ABD" : true, + "GB-ABE" : true, "GB-AGB" : true, "GB-AGY" : true, "GB-AND" : true, "GB-ANN" : true, + "GB-ANS" : true, "GB-BAS" : true, "GB-BBD" : true, "GB-BDF" : true, "GB-BDG" : true, + "GB-BEN" : true, "GB-BEX" : true, "GB-BFS" : true, "GB-BGE" : true, "GB-BGW" : true, + "GB-BIR" : true, "GB-BKM" : true, "GB-BMH" : true, "GB-BNE" : true, "GB-BNH" : true, + "GB-BNS" : true, "GB-BOL" : true, "GB-BPL" : true, "GB-BRC" : true, "GB-BRD" : true, + "GB-BRY" : true, "GB-BST" : true, "GB-BUR" : true, "GB-CAM" : true, "GB-CAY" : true, + "GB-CBF" : true, "GB-CCG" : true, "GB-CGN" : true, "GB-CHE" : true, "GB-CHW" : true, + "GB-CLD" : true, "GB-CLK" : true, "GB-CMA" : true, "GB-CMD" : true, "GB-CMN" : true, + "GB-CON" : true, "GB-COV" : true, "GB-CRF" : true, "GB-CRY" : true, "GB-CWY" : true, + "GB-DAL" : true, "GB-DBY" : true, "GB-DEN" : true, "GB-DER" : true, "GB-DEV" : true, + "GB-DGY" : true, "GB-DNC" : true, "GB-DND" : true, "GB-DOR" : true, "GB-DRS" : true, + "GB-DUD" : true, "GB-DUR" : true, "GB-EAL" : true, "GB-EAW" : true, "GB-EAY" : true, + "GB-EDH" : true, "GB-EDU" : true, "GB-ELN" : true, "GB-ELS" : true, "GB-ENF" : true, + "GB-ENG" : true, "GB-ERW" : true, "GB-ERY" : true, "GB-ESS" : true, "GB-ESX" : true, + "GB-FAL" : true, "GB-FIF" : true, "GB-FLN" : true, "GB-FMO" : true, "GB-GAT" : true, + "GB-GBN" : true, "GB-GLG" : true, "GB-GLS" : true, "GB-GRE" : true, "GB-GWN" : true, + "GB-HAL" : true, "GB-HAM" : true, "GB-HAV" : true, "GB-HCK" : true, "GB-HEF" : true, + "GB-HIL" : true, "GB-HLD" : true, "GB-HMF" : true, "GB-HNS" : true, "GB-HPL" : true, + "GB-HRT" : true, "GB-HRW" : true, "GB-HRY" : true, "GB-IOS" : true, "GB-IOW" : true, + "GB-ISL" : true, "GB-IVC" : true, "GB-KEC" : true, "GB-KEN" : true, "GB-KHL" : true, + "GB-KIR" : true, "GB-KTT" : true, "GB-KWL" : true, "GB-LAN" : true, "GB-LBC" : true, + "GB-LBH" : true, "GB-LCE" : true, "GB-LDS" : true, "GB-LEC" : true, "GB-LEW" : true, + "GB-LIN" : true, "GB-LIV" : true, "GB-LND" : true, "GB-LUT" : true, "GB-MAN" : true, + "GB-MDB" : true, "GB-MDW" : true, "GB-MEA" : true, "GB-MIK" : true, "GD-01" : true, + "GB-MLN" : true, "GB-MON" : true, "GB-MRT" : true, "GB-MRY" : true, "GB-MTY" : true, + "GB-MUL" : true, "GB-NAY" : true, "GB-NBL" : true, "GB-NEL" : true, "GB-NET" : true, + "GB-NFK" : true, "GB-NGM" : true, "GB-NIR" : true, "GB-NLK" : true, "GB-NLN" : true, + "GB-NMD" : true, "GB-NSM" : true, "GB-NTH" : true, "GB-NTL" : true, "GB-NTT" : true, + "GB-NTY" : true, "GB-NWM" : true, "GB-NWP" : true, "GB-NYK" : true, "GB-OLD" : true, + "GB-ORK" : true, "GB-OXF" : true, "GB-PEM" : true, "GB-PKN" : true, "GB-PLY" : true, + "GB-POL" : true, "GB-POR" : true, "GB-POW" : true, "GB-PTE" : true, "GB-RCC" : true, + "GB-RCH" : true, "GB-RCT" : true, "GB-RDB" : true, "GB-RDG" : true, "GB-RFW" : true, + "GB-RIC" : true, "GB-ROT" : true, "GB-RUT" : true, "GB-SAW" : true, "GB-SAY" : true, + "GB-SCB" : true, "GB-SCT" : true, "GB-SFK" : true, "GB-SFT" : true, "GB-SGC" : true, + "GB-SHF" : true, "GB-SHN" : true, "GB-SHR" : true, "GB-SKP" : true, "GB-SLF" : true, + "GB-SLG" : true, "GB-SLK" : true, "GB-SND" : true, "GB-SOL" : true, "GB-SOM" : true, + "GB-SOS" : true, "GB-SRY" : true, "GB-STE" : true, "GB-STG" : true, "GB-STH" : true, + "GB-STN" : true, "GB-STS" : true, "GB-STT" : true, "GB-STY" : true, "GB-SWA" : true, + "GB-SWD" : true, "GB-SWK" : true, "GB-TAM" : true, "GB-TFW" : true, "GB-THR" : true, + "GB-TOB" : true, "GB-TOF" : true, "GB-TRF" : true, "GB-TWH" : true, "GB-UKM" : true, + "GB-VGL" : true, "GB-WAR" : true, "GB-WBK" : true, "GB-WDU" : true, "GB-WFT" : true, + "GB-WGN" : true, "GB-WIL" : true, "GB-WKF" : true, "GB-WLL" : true, "GB-WLN" : true, + "GB-WLS" : true, "GB-WLV" : true, "GB-WND" : true, "GB-WNM" : true, "GB-WOK" : true, + "GB-WOR" : true, "GB-WRL" : true, "GB-WRT" : true, "GB-WRX" : true, "GB-WSM" : true, + "GB-WSX" : true, "GB-YOR" : true, "GB-ZET" : true, "GD-02" : true, "GD-03" : true, + "GD-04" : true, "GD-05" : true, "GD-06" : true, "GD-10" : true, "GE-AB" : true, + "GE-AJ" : true, "GE-GU" : true, "GE-IM" : true, "GE-KA" : true, "GE-KK" : true, + "GE-MM" : true, "GE-RL" : true, "GE-SJ" : true, "GE-SK" : true, "GE-SZ" : true, + "GE-TB" : true, "GH-AA" : true, "GH-AH" : true, "GH-BA" : true, "GH-CP" : true, + "GH-EP" : true, "GH-NP" : true, "GH-TV" : true, "GH-UE" : true, "GH-UW" : true, + "GH-WP" : true, "GL-KU" : true, "GL-QA" : true, "GL-QE" : true, "GL-SM" : true, + "GM-B" : true, "GM-L" : true, "GM-M" : true, "GM-N" : true, "GM-U" : true, + "GM-W" : true, "GN-B" : true, "GN-BE" : true, "GN-BF" : true, "GN-BK" : true, + "GN-C" : true, "GN-CO" : true, "GN-D" : true, "GN-DB" : true, "GN-DI" : true, + "GN-DL" : true, "GN-DU" : true, "GN-F" : true, "GN-FA" : true, "GN-FO" : true, + "GN-FR" : true, "GN-GA" : true, "GN-GU" : true, "GN-K" : true, "GN-KA" : true, + "GN-KB" : true, "GN-KD" : true, "GN-KE" : true, "GN-KN" : true, "GN-KO" : true, + "GN-KS" : true, "GN-L" : true, "GN-LA" : true, "GN-LE" : true, "GN-LO" : true, + "GN-M" : true, "GN-MC" : true, "GN-MD" : true, "GN-ML" : true, "GN-MM" : true, + "GN-N" : true, "GN-NZ" : true, "GN-PI" : true, "GN-SI" : true, "GN-TE" : true, + "GN-TO" : true, "GN-YO" : true, "GQ-AN" : true, "GQ-BN" : true, "GQ-BS" : true, + "GQ-C" : true, "GQ-CS" : true, "GQ-I" : true, "GQ-KN" : true, "GQ-LI" : true, + "GQ-WN" : true, "GR-01" : true, "GR-03" : true, "GR-04" : true, "GR-05" : true, + "GR-06" : true, "GR-07" : true, "GR-11" : true, "GR-12" : true, "GR-13" : true, + "GR-14" : true, "GR-15" : true, "GR-16" : true, "GR-17" : true, "GR-21" : true, + "GR-22" : true, "GR-23" : true, "GR-24" : true, "GR-31" : true, "GR-32" : true, + "GR-33" : true, "GR-34" : true, "GR-41" : true, "GR-42" : true, "GR-43" : true, + "GR-44" : true, "GR-51" : true, "GR-52" : true, "GR-53" : true, "GR-54" : true, + "GR-55" : true, "GR-56" : true, "GR-57" : true, "GR-58" : true, "GR-59" : true, + "GR-61" : true, "GR-62" : true, "GR-63" : true, "GR-64" : true, "GR-69" : true, + "GR-71" : true, "GR-72" : true, "GR-73" : true, "GR-81" : true, "GR-82" : true, + "GR-83" : true, "GR-84" : true, "GR-85" : true, "GR-91" : true, "GR-92" : true, + "GR-93" : true, "GR-94" : true, "GR-A" : true, "GR-A1" : true, "GR-B" : true, + "GR-C" : true, "GR-D" : true, "GR-E" : true, "GR-F" : true, "GR-G" : true, + "GR-H" : true, "GR-I" : true, "GR-J" : true, "GR-K" : true, "GR-L" : true, + "GR-M" : true, "GT-AV" : true, "GT-BV" : true, "GT-CM" : true, "GT-CQ" : true, + "GT-ES" : true, "GT-GU" : true, "GT-HU" : true, "GT-IZ" : true, "GT-JA" : true, + "GT-JU" : true, "GT-PE" : true, "GT-PR" : true, "GT-QC" : true, "GT-QZ" : true, + "GT-RE" : true, "GT-SA" : true, "GT-SM" : true, "GT-SO" : true, "GT-SR" : true, + "GT-SU" : true, "GT-TO" : true, "GT-ZA" : true, "GW-BA" : true, "GW-BL" : true, + "GW-BM" : true, "GW-BS" : true, "GW-CA" : true, "GW-GA" : true, "GW-L" : true, + "GW-N" : true, "GW-OI" : true, "GW-QU" : true, "GW-S" : true, "GW-TO" : true, + "GY-BA" : true, "GY-CU" : true, "GY-DE" : true, "GY-EB" : true, "GY-ES" : true, + "GY-MA" : true, "GY-PM" : true, "GY-PT" : true, "GY-UD" : true, "GY-UT" : true, + "HN-AT" : true, "HN-CH" : true, "HN-CL" : true, "HN-CM" : true, "HN-CP" : true, + "HN-CR" : true, "HN-EP" : true, "HN-FM" : true, "HN-GD" : true, "HN-IB" : true, + "HN-IN" : true, "HN-LE" : true, "HN-LP" : true, "HN-OC" : true, "HN-OL" : true, + "HN-SB" : true, "HN-VA" : true, "HN-YO" : true, "HR-01" : true, "HR-02" : true, + "HR-03" : true, "HR-04" : true, "HR-05" : true, "HR-06" : true, "HR-07" : true, + "HR-08" : true, "HR-09" : true, "HR-10" : true, "HR-11" : true, "HR-12" : true, + "HR-13" : true, "HR-14" : true, "HR-15" : true, "HR-16" : true, "HR-17" : true, + "HR-18" : true, "HR-19" : true, "HR-20" : true, "HR-21" : true, "HT-AR" : true, + "HT-CE" : true, "HT-GA" : true, "HT-ND" : true, "HT-NE" : true, "HT-NO" : true, + "HT-OU" : true, "HT-SD" : true, "HT-SE" : true, "HU-BA" : true, "HU-BC" : true, + "HU-BE" : true, "HU-BK" : true, "HU-BU" : true, "HU-BZ" : true, "HU-CS" : true, + "HU-DE" : true, "HU-DU" : true, "HU-EG" : true, "HU-ER" : true, "HU-FE" : true, + "HU-GS" : true, "HU-GY" : true, "HU-HB" : true, "HU-HE" : true, "HU-HV" : true, + "HU-JN" : true, "HU-KE" : true, "HU-KM" : true, "HU-KV" : true, "HU-MI" : true, + "HU-NK" : true, "HU-NO" : true, "HU-NY" : true, "HU-PE" : true, "HU-PS" : true, + "HU-SD" : true, "HU-SF" : true, "HU-SH" : true, "HU-SK" : true, "HU-SN" : true, + "HU-SO" : true, "HU-SS" : true, "HU-ST" : true, "HU-SZ" : true, "HU-TB" : true, + "HU-TO" : true, "HU-VA" : true, "HU-VE" : true, "HU-VM" : true, "HU-ZA" : true, + "HU-ZE" : true, "ID-AC" : true, "ID-BA" : true, "ID-BB" : true, "ID-BE" : true, + "ID-BT" : true, "ID-GO" : true, "ID-IJ" : true, "ID-JA" : true, "ID-JB" : true, + "ID-JI" : true, "ID-JK" : true, "ID-JT" : true, "ID-JW" : true, "ID-KA" : true, + "ID-KB" : true, "ID-KI" : true, "ID-KR" : true, "ID-KS" : true, "ID-KT" : true, + "ID-LA" : true, "ID-MA" : true, "ID-ML" : true, "ID-MU" : true, "ID-NB" : true, + "ID-NT" : true, "ID-NU" : true, "ID-PA" : true, "ID-PB" : true, "ID-RI" : true, + "ID-SA" : true, "ID-SB" : true, "ID-SG" : true, "ID-SL" : true, "ID-SM" : true, + "ID-SN" : true, "ID-SR" : true, "ID-SS" : true, "ID-ST" : true, "ID-SU" : true, + "ID-YO" : true, "IE-C" : true, "IE-CE" : true, "IE-CN" : true, "IE-CO" : true, + "IE-CW" : true, "IE-D" : true, "IE-DL" : true, "IE-G" : true, "IE-KE" : true, + "IE-KK" : true, "IE-KY" : true, "IE-L" : true, "IE-LD" : true, "IE-LH" : true, + "IE-LK" : true, "IE-LM" : true, "IE-LS" : true, "IE-M" : true, "IE-MH" : true, + "IE-MN" : true, "IE-MO" : true, "IE-OY" : true, "IE-RN" : true, "IE-SO" : true, + "IE-TA" : true, "IE-U" : true, "IE-WD" : true, "IE-WH" : true, "IE-WW" : true, + "IE-WX" : true, "IL-D" : true, "IL-HA" : true, "IL-JM" : true, "IL-M" : true, + "IL-TA" : true, "IL-Z" : true, "IN-AN" : true, "IN-AP" : true, "IN-AR" : true, + "IN-AS" : true, "IN-BR" : true, "IN-CH" : true, "IN-CT" : true, "IN-DD" : true, + "IN-DL" : true, "IN-DN" : true, "IN-GA" : true, "IN-GJ" : true, "IN-HP" : true, + "IN-HR" : true, "IN-JH" : true, "IN-JK" : true, "IN-KA" : true, "IN-KL" : true, + "IN-LD" : true, "IN-MH" : true, "IN-ML" : true, "IN-MN" : true, "IN-MP" : true, + "IN-MZ" : true, "IN-NL" : true, "IN-OR" : true, "IN-PB" : true, "IN-PY" : true, + "IN-RJ" : true, "IN-SK" : true, "IN-TN" : true, "IN-TR" : true, "IN-UP" : true, + "IN-UT" : true, "IN-WB" : true, "IQ-AN" : true, "IQ-AR" : true, "IQ-BA" : true, + "IQ-BB" : true, "IQ-BG" : true, "IQ-DA" : true, "IQ-DI" : true, "IQ-DQ" : true, + "IQ-KA" : true, "IQ-MA" : true, "IQ-MU" : true, "IQ-NA" : true, "IQ-NI" : true, + "IQ-QA" : true, "IQ-SD" : true, "IQ-SW" : true, "IQ-TS" : true, "IQ-WA" : true, + "IR-01" : true, "IR-02" : true, "IR-03" : true, "IR-04" : true, "IR-05" : true, + "IR-06" : true, "IR-07" : true, "IR-08" : true, "IR-10" : true, "IR-11" : true, + "IR-12" : true, "IR-13" : true, "IR-14" : true, "IR-15" : true, "IR-16" : true, + "IR-17" : true, "IR-18" : true, "IR-19" : true, "IR-20" : true, "IR-21" : true, + "IR-22" : true, "IR-23" : true, "IR-24" : true, "IR-25" : true, "IR-26" : true, + "IR-27" : true, "IR-28" : true, "IR-29" : true, "IR-30" : true, "IR-31" : true, + "IS-0" : true, "IS-1" : true, "IS-2" : true, "IS-3" : true, "IS-4" : true, + "IS-5" : true, "IS-6" : true, "IS-7" : true, "IS-8" : true, "IT-21" : true, + "IT-23" : true, "IT-25" : true, "IT-32" : true, "IT-34" : true, "IT-36" : true, + "IT-42" : true, "IT-45" : true, "IT-52" : true, "IT-55" : true, "IT-57" : true, + "IT-62" : true, "IT-65" : true, "IT-67" : true, "IT-72" : true, "IT-75" : true, + "IT-77" : true, "IT-78" : true, "IT-82" : true, "IT-88" : true, "IT-AG" : true, + "IT-AL" : true, "IT-AN" : true, "IT-AO" : true, "IT-AP" : true, "IT-AQ" : true, + "IT-AR" : true, "IT-AT" : true, "IT-AV" : true, "IT-BA" : true, "IT-BG" : true, + "IT-BI" : true, "IT-BL" : true, "IT-BN" : true, "IT-BO" : true, "IT-BR" : true, + "IT-BS" : true, "IT-BT" : true, "IT-BZ" : true, "IT-CA" : true, "IT-CB" : true, + "IT-CE" : true, "IT-CH" : true, "IT-CI" : true, "IT-CL" : true, "IT-CN" : true, + "IT-CO" : true, "IT-CR" : true, "IT-CS" : true, "IT-CT" : true, "IT-CZ" : true, + "IT-EN" : true, "IT-FC" : true, "IT-FE" : true, "IT-FG" : true, "IT-FI" : true, + "IT-FM" : true, "IT-FR" : true, "IT-GE" : true, "IT-GO" : true, "IT-GR" : true, + "IT-IM" : true, "IT-IS" : true, "IT-KR" : true, "IT-LC" : true, "IT-LE" : true, + "IT-LI" : true, "IT-LO" : true, "IT-LT" : true, "IT-LU" : true, "IT-MB" : true, + "IT-MC" : true, "IT-ME" : true, "IT-MI" : true, "IT-MN" : true, "IT-MO" : true, + "IT-MS" : true, "IT-MT" : true, "IT-NA" : true, "IT-NO" : true, "IT-NU" : true, + "IT-OG" : true, "IT-OR" : true, "IT-OT" : true, "IT-PA" : true, "IT-PC" : true, + "IT-PD" : true, "IT-PE" : true, "IT-PG" : true, "IT-PI" : true, "IT-PN" : true, + "IT-PO" : true, "IT-PR" : true, "IT-PT" : true, "IT-PU" : true, "IT-PV" : true, + "IT-PZ" : true, "IT-RA" : true, "IT-RC" : true, "IT-RE" : true, "IT-RG" : true, + "IT-RI" : true, "IT-RM" : true, "IT-RN" : true, "IT-RO" : true, "IT-SA" : true, + "IT-SI" : true, "IT-SO" : true, "IT-SP" : true, "IT-SR" : true, "IT-SS" : true, + "IT-SV" : true, "IT-TA" : true, "IT-TE" : true, "IT-TN" : true, "IT-TO" : true, + "IT-TP" : true, "IT-TR" : true, "IT-TS" : true, "IT-TV" : true, "IT-UD" : true, + "IT-VA" : true, "IT-VB" : true, "IT-VC" : true, "IT-VE" : true, "IT-VI" : true, + "IT-VR" : true, "IT-VS" : true, "IT-VT" : true, "IT-VV" : true, "JM-01" : true, + "JM-02" : true, "JM-03" : true, "JM-04" : true, "JM-05" : true, "JM-06" : true, + "JM-07" : true, "JM-08" : true, "JM-09" : true, "JM-10" : true, "JM-11" : true, + "JM-12" : true, "JM-13" : true, "JM-14" : true, "JO-AJ" : true, "JO-AM" : true, + "JO-AQ" : true, "JO-AT" : true, "JO-AZ" : true, "JO-BA" : true, "JO-IR" : true, + "JO-JA" : true, "JO-KA" : true, "JO-MA" : true, "JO-MD" : true, "JO-MN" : true, + "JP-01" : true, "JP-02" : true, "JP-03" : true, "JP-04" : true, "JP-05" : true, + "JP-06" : true, "JP-07" : true, "JP-08" : true, "JP-09" : true, "JP-10" : true, + "JP-11" : true, "JP-12" : true, "JP-13" : true, "JP-14" : true, "JP-15" : true, + "JP-16" : true, "JP-17" : true, "JP-18" : true, "JP-19" : true, "JP-20" : true, + "JP-21" : true, "JP-22" : true, "JP-23" : true, "JP-24" : true, "JP-25" : true, + "JP-26" : true, "JP-27" : true, "JP-28" : true, "JP-29" : true, "JP-30" : true, + "JP-31" : true, "JP-32" : true, "JP-33" : true, "JP-34" : true, "JP-35" : true, + "JP-36" : true, "JP-37" : true, "JP-38" : true, "JP-39" : true, "JP-40" : true, + "JP-41" : true, "JP-42" : true, "JP-43" : true, "JP-44" : true, "JP-45" : true, + "JP-46" : true, "JP-47" : true, "KE-110" : true, "KE-200" : true, "KE-300" : true, + "KE-400" : true, "KE-500" : true, "KE-700" : true, "KE-800" : true, "KG-B" : true, + "KG-C" : true, "KG-GB" : true, "KG-J" : true, "KG-N" : true, "KG-O" : true, + "KG-T" : true, "KG-Y" : true, "KH-1" : true, "KH-10" : true, "KH-11" : true, + "KH-12" : true, "KH-13" : true, "KH-14" : true, "KH-15" : true, "KH-16" : true, + "KH-17" : true, "KH-18" : true, "KH-19" : true, "KH-2" : true, "KH-20" : true, + "KH-21" : true, "KH-22" : true, "KH-23" : true, "KH-24" : true, "KH-3" : true, + "KH-4" : true, "KH-5" : true, "KH-6" : true, "KH-7" : true, "KH-8" : true, + "KH-9" : true, "KI-G" : true, "KI-L" : true, "KI-P" : true, "KM-A" : true, + "KM-G" : true, "KM-M" : true, "KN-01" : true, "KN-02" : true, "KN-03" : true, + "KN-04" : true, "KN-05" : true, "KN-06" : true, "KN-07" : true, "KN-08" : true, + "KN-09" : true, "KN-10" : true, "KN-11" : true, "KN-12" : true, "KN-13" : true, + "KN-15" : true, "KN-K" : true, "KN-N" : true, "KP-01" : true, "KP-02" : true, + "KP-03" : true, "KP-04" : true, "KP-05" : true, "KP-06" : true, "KP-07" : true, + "KP-08" : true, "KP-09" : true, "KP-10" : true, "KP-13" : true, "KR-11" : true, + "KR-26" : true, "KR-27" : true, "KR-28" : true, "KR-29" : true, "KR-30" : true, + "KR-31" : true, "KR-41" : true, "KR-42" : true, "KR-43" : true, "KR-44" : true, + "KR-45" : true, "KR-46" : true, "KR-47" : true, "KR-48" : true, "KR-49" : true, + "KW-AH" : true, "KW-FA" : true, "KW-HA" : true, "KW-JA" : true, "KW-KU" : true, + "KW-MU" : true, "KZ-AKM" : true, "KZ-AKT" : true, "KZ-ALA" : true, "KZ-ALM" : true, + "KZ-AST" : true, "KZ-ATY" : true, "KZ-KAR" : true, "KZ-KUS" : true, "KZ-KZY" : true, + "KZ-MAN" : true, "KZ-PAV" : true, "KZ-SEV" : true, "KZ-VOS" : true, "KZ-YUZ" : true, + "KZ-ZAP" : true, "KZ-ZHA" : true, "LA-AT" : true, "LA-BK" : true, "LA-BL" : true, + "LA-CH" : true, "LA-HO" : true, "LA-KH" : true, "LA-LM" : true, "LA-LP" : true, + "LA-OU" : true, "LA-PH" : true, "LA-SL" : true, "LA-SV" : true, "LA-VI" : true, + "LA-VT" : true, "LA-XA" : true, "LA-XE" : true, "LA-XI" : true, "LA-XS" : true, + "LB-AK" : true, "LB-AS" : true, "LB-BA" : true, "LB-BH" : true, "LB-BI" : true, + "LB-JA" : true, "LB-JL" : true, "LB-NA" : true, "LI-01" : true, "LI-02" : true, + "LI-03" : true, "LI-04" : true, "LI-05" : true, "LI-06" : true, "LI-07" : true, + "LI-08" : true, "LI-09" : true, "LI-10" : true, "LI-11" : true, "LK-1" : true, + "LK-11" : true, "LK-12" : true, "LK-13" : true, "LK-2" : true, "LK-21" : true, + "LK-22" : true, "LK-23" : true, "LK-3" : true, "LK-31" : true, "LK-32" : true, + "LK-33" : true, "LK-4" : true, "LK-41" : true, "LK-42" : true, "LK-43" : true, + "LK-44" : true, "LK-45" : true, "LK-5" : true, "LK-51" : true, "LK-52" : true, + "LK-53" : true, "LK-6" : true, "LK-61" : true, "LK-62" : true, "LK-7" : true, + "LK-71" : true, "LK-72" : true, "LK-8" : true, "LK-81" : true, "LK-82" : true, + "LK-9" : true, "LK-91" : true, "LK-92" : true, "LR-BG" : true, "LR-BM" : true, + "LR-CM" : true, "LR-GB" : true, "LR-GG" : true, "LR-GK" : true, "LR-LO" : true, + "LR-MG" : true, "LR-MO" : true, "LR-MY" : true, "LR-NI" : true, "LR-RI" : true, + "LR-SI" : true, "LS-A" : true, "LS-B" : true, "LS-C" : true, "LS-D" : true, + "LS-E" : true, "LS-F" : true, "LS-G" : true, "LS-H" : true, "LS-J" : true, + "LS-K" : true, "LT-AL" : true, "LT-KL" : true, "LT-KU" : true, "LT-MR" : true, + "LT-PN" : true, "LT-SA" : true, "LT-TA" : true, "LT-TE" : true, "LT-UT" : true, + "LT-VL" : true, "LU-D" : true, "LU-G" : true, "LU-L" : true, "LV-001" : true, + "LV-002" : true, "LV-003" : true, "LV-004" : true, "LV-005" : true, "LV-006" : true, + "LV-007" : true, "LV-008" : true, "LV-009" : true, "LV-010" : true, "LV-011" : true, + "LV-012" : true, "LV-013" : true, "LV-014" : true, "LV-015" : true, "LV-016" : true, + "LV-017" : true, "LV-018" : true, "LV-019" : true, "LV-020" : true, "LV-021" : true, + "LV-022" : true, "LV-023" : true, "LV-024" : true, "LV-025" : true, "LV-026" : true, + "LV-027" : true, "LV-028" : true, "LV-029" : true, "LV-030" : true, "LV-031" : true, + "LV-032" : true, "LV-033" : true, "LV-034" : true, "LV-035" : true, "LV-036" : true, + "LV-037" : true, "LV-038" : true, "LV-039" : true, "LV-040" : true, "LV-041" : true, + "LV-042" : true, "LV-043" : true, "LV-044" : true, "LV-045" : true, "LV-046" : true, + "LV-047" : true, "LV-048" : true, "LV-049" : true, "LV-050" : true, "LV-051" : true, + "LV-052" : true, "LV-053" : true, "LV-054" : true, "LV-055" : true, "LV-056" : true, + "LV-057" : true, "LV-058" : true, "LV-059" : true, "LV-060" : true, "LV-061" : true, + "LV-062" : true, "LV-063" : true, "LV-064" : true, "LV-065" : true, "LV-066" : true, + "LV-067" : true, "LV-068" : true, "LV-069" : true, "LV-070" : true, "LV-071" : true, + "LV-072" : true, "LV-073" : true, "LV-074" : true, "LV-075" : true, "LV-076" : true, + "LV-077" : true, "LV-078" : true, "LV-079" : true, "LV-080" : true, "LV-081" : true, + "LV-082" : true, "LV-083" : true, "LV-084" : true, "LV-085" : true, "LV-086" : true, + "LV-087" : true, "LV-088" : true, "LV-089" : true, "LV-090" : true, "LV-091" : true, + "LV-092" : true, "LV-093" : true, "LV-094" : true, "LV-095" : true, "LV-096" : true, + "LV-097" : true, "LV-098" : true, "LV-099" : true, "LV-100" : true, "LV-101" : true, + "LV-102" : true, "LV-103" : true, "LV-104" : true, "LV-105" : true, "LV-106" : true, + "LV-107" : true, "LV-108" : true, "LV-109" : true, "LV-110" : true, "LV-DGV" : true, + "LV-JEL" : true, "LV-JKB" : true, "LV-JUR" : true, "LV-LPX" : true, "LV-REZ" : true, + "LV-RIX" : true, "LV-VEN" : true, "LV-VMR" : true, "LY-BA" : true, "LY-BU" : true, + "LY-DR" : true, "LY-GT" : true, "LY-JA" : true, "LY-JB" : true, "LY-JG" : true, + "LY-JI" : true, "LY-JU" : true, "LY-KF" : true, "LY-MB" : true, "LY-MI" : true, + "LY-MJ" : true, "LY-MQ" : true, "LY-NL" : true, "LY-NQ" : true, "LY-SB" : true, + "LY-SR" : true, "LY-TB" : true, "LY-WA" : true, "LY-WD" : true, "LY-WS" : true, + "LY-ZA" : true, "MA-01" : true, "MA-02" : true, "MA-03" : true, "MA-04" : true, + "MA-05" : true, "MA-06" : true, "MA-07" : true, "MA-08" : true, "MA-09" : true, + "MA-10" : true, "MA-11" : true, "MA-12" : true, "MA-13" : true, "MA-14" : true, + "MA-15" : true, "MA-16" : true, "MA-AGD" : true, "MA-AOU" : true, "MA-ASZ" : true, + "MA-AZI" : true, "MA-BEM" : true, "MA-BER" : true, "MA-BES" : true, "MA-BOD" : true, + "MA-BOM" : true, "MA-CAS" : true, "MA-CHE" : true, "MA-CHI" : true, "MA-CHT" : true, + "MA-ERR" : true, "MA-ESI" : true, "MA-ESM" : true, "MA-FAH" : true, "MA-FES" : true, + "MA-FIG" : true, "MA-GUE" : true, "MA-HAJ" : true, "MA-HAO" : true, "MA-HOC" : true, + "MA-IFR" : true, "MA-INE" : true, "MA-JDI" : true, "MA-JRA" : true, "MA-KEN" : true, + "MA-KES" : true, "MA-KHE" : true, "MA-KHN" : true, "MA-KHO" : true, "MA-LAA" : true, + "MA-LAR" : true, "MA-MED" : true, "MA-MEK" : true, "MA-MMD" : true, "MA-MMN" : true, + "MA-MOH" : true, "MA-MOU" : true, "MA-NAD" : true, "MA-NOU" : true, "MA-OUA" : true, + "MA-OUD" : true, "MA-OUJ" : true, "MA-RAB" : true, "MA-SAF" : true, "MA-SAL" : true, + "MA-SEF" : true, "MA-SET" : true, "MA-SIK" : true, "MA-SKH" : true, "MA-SYB" : true, + "MA-TAI" : true, "MA-TAO" : true, "MA-TAR" : true, "MA-TAT" : true, "MA-TAZ" : true, + "MA-TET" : true, "MA-TIZ" : true, "MA-TNG" : true, "MA-TNT" : true, "MA-ZAG" : true, + "MC-CL" : true, "MC-CO" : true, "MC-FO" : true, "MC-GA" : true, "MC-JE" : true, + "MC-LA" : true, "MC-MA" : true, "MC-MC" : true, "MC-MG" : true, "MC-MO" : true, + "MC-MU" : true, "MC-PH" : true, "MC-SD" : true, "MC-SO" : true, "MC-SP" : true, + "MC-SR" : true, "MC-VR" : true, "MD-AN" : true, "MD-BA" : true, "MD-BD" : true, + "MD-BR" : true, "MD-BS" : true, "MD-CA" : true, "MD-CL" : true, "MD-CM" : true, + "MD-CR" : true, "MD-CS" : true, "MD-CT" : true, "MD-CU" : true, "MD-DO" : true, + "MD-DR" : true, "MD-DU" : true, "MD-ED" : true, "MD-FA" : true, "MD-FL" : true, + "MD-GA" : true, "MD-GL" : true, "MD-HI" : true, "MD-IA" : true, "MD-LE" : true, + "MD-NI" : true, "MD-OC" : true, "MD-OR" : true, "MD-RE" : true, "MD-RI" : true, + "MD-SD" : true, "MD-SI" : true, "MD-SN" : true, "MD-SO" : true, "MD-ST" : true, + "MD-SV" : true, "MD-TA" : true, "MD-TE" : true, "MD-UN" : true, "ME-01" : true, + "ME-02" : true, "ME-03" : true, "ME-04" : true, "ME-05" : true, "ME-06" : true, + "ME-07" : true, "ME-08" : true, "ME-09" : true, "ME-10" : true, "ME-11" : true, + "ME-12" : true, "ME-13" : true, "ME-14" : true, "ME-15" : true, "ME-16" : true, + "ME-17" : true, "ME-18" : true, "ME-19" : true, "ME-20" : true, "ME-21" : true, + "MG-A" : true, "MG-D" : true, "MG-F" : true, "MG-M" : true, "MG-T" : true, + "MG-U" : true, "MH-ALK" : true, "MH-ALL" : true, "MH-ARN" : true, "MH-AUR" : true, + "MH-EBO" : true, "MH-ENI" : true, "MH-JAB" : true, "MH-JAL" : true, "MH-KIL" : true, + "MH-KWA" : true, "MH-L" : true, "MH-LAE" : true, "MH-LIB" : true, "MH-LIK" : true, + "MH-MAJ" : true, "MH-MAL" : true, "MH-MEJ" : true, "MH-MIL" : true, "MH-NMK" : true, + "MH-NMU" : true, "MH-RON" : true, "MH-T" : true, "MH-UJA" : true, "MH-UTI" : true, + "MH-WTJ" : true, "MH-WTN" : true, "MK-01" : true, "MK-02" : true, "MK-03" : true, + "MK-04" : true, "MK-05" : true, "MK-06" : true, "MK-07" : true, "MK-08" : true, + "MK-09" : true, "MK-10" : true, "MK-11" : true, "MK-12" : true, "MK-13" : true, + "MK-14" : true, "MK-15" : true, "MK-16" : true, "MK-17" : true, "MK-18" : true, + "MK-19" : true, "MK-20" : true, "MK-21" : true, "MK-22" : true, "MK-23" : true, + "MK-24" : true, "MK-25" : true, "MK-26" : true, "MK-27" : true, "MK-28" : true, + "MK-29" : true, "MK-30" : true, "MK-31" : true, "MK-32" : true, "MK-33" : true, + "MK-34" : true, "MK-35" : true, "MK-36" : true, "MK-37" : true, "MK-38" : true, + "MK-39" : true, "MK-40" : true, "MK-41" : true, "MK-42" : true, "MK-43" : true, + "MK-44" : true, "MK-45" : true, "MK-46" : true, "MK-47" : true, "MK-48" : true, + "MK-49" : true, "MK-50" : true, "MK-51" : true, "MK-52" : true, "MK-53" : true, + "MK-54" : true, "MK-55" : true, "MK-56" : true, "MK-57" : true, "MK-58" : true, + "MK-59" : true, "MK-60" : true, "MK-61" : true, "MK-62" : true, "MK-63" : true, + "MK-64" : true, "MK-65" : true, "MK-66" : true, "MK-67" : true, "MK-68" : true, + "MK-69" : true, "MK-70" : true, "MK-71" : true, "MK-72" : true, "MK-73" : true, + "MK-74" : true, "MK-75" : true, "MK-76" : true, "MK-77" : true, "MK-78" : true, + "MK-79" : true, "MK-80" : true, "MK-81" : true, "MK-82" : true, "MK-83" : true, + "MK-84" : true, "ML-1" : true, "ML-2" : true, "ML-3" : true, "ML-4" : true, + "ML-5" : true, "ML-6" : true, "ML-7" : true, "ML-8" : true, "ML-BK0" : true, + "MM-01" : true, "MM-02" : true, "MM-03" : true, "MM-04" : true, "MM-05" : true, + "MM-06" : true, "MM-07" : true, "MM-11" : true, "MM-12" : true, "MM-13" : true, + "MM-14" : true, "MM-15" : true, "MM-16" : true, "MM-17" : true, "MN-035" : true, + "MN-037" : true, "MN-039" : true, "MN-041" : true, "MN-043" : true, "MN-046" : true, + "MN-047" : true, "MN-049" : true, "MN-051" : true, "MN-053" : true, "MN-055" : true, + "MN-057" : true, "MN-059" : true, "MN-061" : true, "MN-063" : true, "MN-064" : true, + "MN-065" : true, "MN-067" : true, "MN-069" : true, "MN-071" : true, "MN-073" : true, + "MN-1" : true, "MR-01" : true, "MR-02" : true, "MR-03" : true, "MR-04" : true, + "MR-05" : true, "MR-06" : true, "MR-07" : true, "MR-08" : true, "MR-09" : true, + "MR-10" : true, "MR-11" : true, "MR-12" : true, "MR-NKC" : true, "MT-01" : true, + "MT-02" : true, "MT-03" : true, "MT-04" : true, "MT-05" : true, "MT-06" : true, + "MT-07" : true, "MT-08" : true, "MT-09" : true, "MT-10" : true, "MT-11" : true, + "MT-12" : true, "MT-13" : true, "MT-14" : true, "MT-15" : true, "MT-16" : true, + "MT-17" : true, "MT-18" : true, "MT-19" : true, "MT-20" : true, "MT-21" : true, + "MT-22" : true, "MT-23" : true, "MT-24" : true, "MT-25" : true, "MT-26" : true, + "MT-27" : true, "MT-28" : true, "MT-29" : true, "MT-30" : true, "MT-31" : true, + "MT-32" : true, "MT-33" : true, "MT-34" : true, "MT-35" : true, "MT-36" : true, + "MT-37" : true, "MT-38" : true, "MT-39" : true, "MT-40" : true, "MT-41" : true, + "MT-42" : true, "MT-43" : true, "MT-44" : true, "MT-45" : true, "MT-46" : true, + "MT-47" : true, "MT-48" : true, "MT-49" : true, "MT-50" : true, "MT-51" : true, + "MT-52" : true, "MT-53" : true, "MT-54" : true, "MT-55" : true, "MT-56" : true, + "MT-57" : true, "MT-58" : true, "MT-59" : true, "MT-60" : true, "MT-61" : true, + "MT-62" : true, "MT-63" : true, "MT-64" : true, "MT-65" : true, "MT-66" : true, + "MT-67" : true, "MT-68" : true, "MU-AG" : true, "MU-BL" : true, "MU-BR" : true, + "MU-CC" : true, "MU-CU" : true, "MU-FL" : true, "MU-GP" : true, "MU-MO" : true, + "MU-PA" : true, "MU-PL" : true, "MU-PU" : true, "MU-PW" : true, "MU-QB" : true, + "MU-RO" : true, "MU-RP" : true, "MU-SA" : true, "MU-VP" : true, "MV-00" : true, + "MV-01" : true, "MV-02" : true, "MV-03" : true, "MV-04" : true, "MV-05" : true, + "MV-07" : true, "MV-08" : true, "MV-12" : true, "MV-13" : true, "MV-14" : true, + "MV-17" : true, "MV-20" : true, "MV-23" : true, "MV-24" : true, "MV-25" : true, + "MV-26" : true, "MV-27" : true, "MV-28" : true, "MV-29" : true, "MV-CE" : true, + "MV-MLE" : true, "MV-NC" : true, "MV-NO" : true, "MV-SC" : true, "MV-SU" : true, + "MV-UN" : true, "MV-US" : true, "MW-BA" : true, "MW-BL" : true, "MW-C" : true, + "MW-CK" : true, "MW-CR" : true, "MW-CT" : true, "MW-DE" : true, "MW-DO" : true, + "MW-KR" : true, "MW-KS" : true, "MW-LI" : true, "MW-LK" : true, "MW-MC" : true, + "MW-MG" : true, "MW-MH" : true, "MW-MU" : true, "MW-MW" : true, "MW-MZ" : true, + "MW-N" : true, "MW-NB" : true, "MW-NE" : true, "MW-NI" : true, "MW-NK" : true, + "MW-NS" : true, "MW-NU" : true, "MW-PH" : true, "MW-RU" : true, "MW-S" : true, + "MW-SA" : true, "MW-TH" : true, "MW-ZO" : true, "MX-AGU" : true, "MX-BCN" : true, + "MX-BCS" : true, "MX-CAM" : true, "MX-CHH" : true, "MX-CHP" : true, "MX-COA" : true, + "MX-COL" : true, "MX-DIF" : true, "MX-DUR" : true, "MX-GRO" : true, "MX-GUA" : true, + "MX-HID" : true, "MX-JAL" : true, "MX-MEX" : true, "MX-MIC" : true, "MX-MOR" : true, + "MX-NAY" : true, "MX-NLE" : true, "MX-OAX" : true, "MX-PUE" : true, "MX-QUE" : true, + "MX-ROO" : true, "MX-SIN" : true, "MX-SLP" : true, "MX-SON" : true, "MX-TAB" : true, + "MX-TAM" : true, "MX-TLA" : true, "MX-VER" : true, "MX-YUC" : true, "MX-ZAC" : true, + "MY-01" : true, "MY-02" : true, "MY-03" : true, "MY-04" : true, "MY-05" : true, + "MY-06" : true, "MY-07" : true, "MY-08" : true, "MY-09" : true, "MY-10" : true, + "MY-11" : true, "MY-12" : true, "MY-13" : true, "MY-14" : true, "MY-15" : true, + "MY-16" : true, "MZ-A" : true, "MZ-B" : true, "MZ-G" : true, "MZ-I" : true, + "MZ-L" : true, "MZ-MPM" : true, "MZ-N" : true, "MZ-P" : true, "MZ-Q" : true, + "MZ-S" : true, "MZ-T" : true, "NA-CA" : true, "NA-ER" : true, "NA-HA" : true, + "NA-KA" : true, "NA-KH" : true, "NA-KU" : true, "NA-OD" : true, "NA-OH" : true, + "NA-OK" : true, "NA-ON" : true, "NA-OS" : true, "NA-OT" : true, "NA-OW" : true, + "NE-1" : true, "NE-2" : true, "NE-3" : true, "NE-4" : true, "NE-5" : true, + "NE-6" : true, "NE-7" : true, "NE-8" : true, "NG-AB" : true, "NG-AD" : true, + "NG-AK" : true, "NG-AN" : true, "NG-BA" : true, "NG-BE" : true, "NG-BO" : true, + "NG-BY" : true, "NG-CR" : true, "NG-DE" : true, "NG-EB" : true, "NG-ED" : true, + "NG-EK" : true, "NG-EN" : true, "NG-FC" : true, "NG-GO" : true, "NG-IM" : true, + "NG-JI" : true, "NG-KD" : true, "NG-KE" : true, "NG-KN" : true, "NG-KO" : true, + "NG-KT" : true, "NG-KW" : true, "NG-LA" : true, "NG-NA" : true, "NG-NI" : true, + "NG-OG" : true, "NG-ON" : true, "NG-OS" : true, "NG-OY" : true, "NG-PL" : true, + "NG-RI" : true, "NG-SO" : true, "NG-TA" : true, "NG-YO" : true, "NG-ZA" : true, + "NI-AN" : true, "NI-AS" : true, "NI-BO" : true, "NI-CA" : true, "NI-CI" : true, + "NI-CO" : true, "NI-ES" : true, "NI-GR" : true, "NI-JI" : true, "NI-LE" : true, + "NI-MD" : true, "NI-MN" : true, "NI-MS" : true, "NI-MT" : true, "NI-NS" : true, + "NI-RI" : true, "NI-SJ" : true, "NL-AW" : true, "NL-BQ1" : true, "NL-BQ2" : true, + "NL-BQ3" : true, "NL-CW" : true, "NL-DR" : true, "NL-FL" : true, "NL-FR" : true, + "NL-GE" : true, "NL-GR" : true, "NL-LI" : true, "NL-NB" : true, "NL-NH" : true, + "NL-OV" : true, "NL-SX" : true, "NL-UT" : true, "NL-ZE" : true, "NL-ZH" : true, + "NO-01" : true, "NO-02" : true, "NO-03" : true, "NO-04" : true, "NO-05" : true, + "NO-06" : true, "NO-07" : true, "NO-08" : true, "NO-09" : true, "NO-10" : true, + "NO-11" : true, "NO-12" : true, "NO-14" : true, "NO-15" : true, "NO-16" : true, + "NO-17" : true, "NO-18" : true, "NO-19" : true, "NO-20" : true, "NO-21" : true, + "NO-22" : true, "NP-1" : true, "NP-2" : true, "NP-3" : true, "NP-4" : true, + "NP-5" : true, "NP-BA" : true, "NP-BH" : true, "NP-DH" : true, "NP-GA" : true, + "NP-JA" : true, "NP-KA" : true, "NP-KO" : true, "NP-LU" : true, "NP-MA" : true, + "NP-ME" : true, "NP-NA" : true, "NP-RA" : true, "NP-SA" : true, "NP-SE" : true, + "NR-01" : true, "NR-02" : true, "NR-03" : true, "NR-04" : true, "NR-05" : true, + "NR-06" : true, "NR-07" : true, "NR-08" : true, "NR-09" : true, "NR-10" : true, + "NR-11" : true, "NR-12" : true, "NR-13" : true, "NR-14" : true, "NZ-AUK" : true, + "NZ-BOP" : true, "NZ-CAN" : true, "NZ-CIT" : true, "NZ-GIS" : true, "NZ-HKB" : true, + "NZ-MBH" : true, "NZ-MWT" : true, "NZ-N" : true, "NZ-NSN" : true, "NZ-NTL" : true, + "NZ-OTA" : true, "NZ-S" : true, "NZ-STL" : true, "NZ-TAS" : true, "NZ-TKI" : true, + "NZ-WGN" : true, "NZ-WKO" : true, "NZ-WTC" : true, "OM-BA" : true, "OM-BU" : true, + "OM-DA" : true, "OM-MA" : true, "OM-MU" : true, "OM-SH" : true, "OM-WU" : true, + "OM-ZA" : true, "OM-ZU" : true, "PA-1" : true, "PA-2" : true, "PA-3" : true, + "PA-4" : true, "PA-5" : true, "PA-6" : true, "PA-7" : true, "PA-8" : true, + "PA-9" : true, "PA-EM" : true, "PA-KY" : true, "PA-NB" : true, "PE-AMA" : true, + "PE-ANC" : true, "PE-APU" : true, "PE-ARE" : true, "PE-AYA" : true, "PE-CAJ" : true, + "PE-CAL" : true, "PE-CUS" : true, "PE-HUC" : true, "PE-HUV" : true, "PE-ICA" : true, + "PE-JUN" : true, "PE-LAL" : true, "PE-LAM" : true, "PE-LIM" : true, "PE-LMA" : true, + "PE-LOR" : true, "PE-MDD" : true, "PE-MOQ" : true, "PE-PAS" : true, "PE-PIU" : true, + "PE-PUN" : true, "PE-SAM" : true, "PE-TAC" : true, "PE-TUM" : true, "PE-UCA" : true, + "PG-CPK" : true, "PG-CPM" : true, "PG-EBR" : true, "PG-EHG" : true, "PG-EPW" : true, + "PG-ESW" : true, "PG-GPK" : true, "PG-MBA" : true, "PG-MPL" : true, "PG-MPM" : true, + "PG-MRL" : true, "PG-NCD" : true, "PG-NIK" : true, "PG-NPP" : true, "PG-NSB" : true, + "PG-SAN" : true, "PG-SHM" : true, "PG-WBK" : true, "PG-WHM" : true, "PG-WPD" : true, + "PH-00" : true, "PH-01" : true, "PH-02" : true, "PH-03" : true, "PH-05" : true, + "PH-06" : true, "PH-07" : true, "PH-08" : true, "PH-09" : true, "PH-10" : true, + "PH-11" : true, "PH-12" : true, "PH-13" : true, "PH-14" : true, "PH-15" : true, + "PH-40" : true, "PH-41" : true, "PH-ABR" : true, "PH-AGN" : true, "PH-AGS" : true, + "PH-AKL" : true, "PH-ALB" : true, "PH-ANT" : true, "PH-APA" : true, "PH-AUR" : true, + "PH-BAN" : true, "PH-BAS" : true, "PH-BEN" : true, "PH-BIL" : true, "PH-BOH" : true, + "PH-BTG" : true, "PH-BTN" : true, "PH-BUK" : true, "PH-BUL" : true, "PH-CAG" : true, + "PH-CAM" : true, "PH-CAN" : true, "PH-CAP" : true, "PH-CAS" : true, "PH-CAT" : true, + "PH-CAV" : true, "PH-CEB" : true, "PH-COM" : true, "PH-DAO" : true, "PH-DAS" : true, + "PH-DAV" : true, "PH-DIN" : true, "PH-EAS" : true, "PH-GUI" : true, "PH-IFU" : true, + "PH-ILI" : true, "PH-ILN" : true, "PH-ILS" : true, "PH-ISA" : true, "PH-KAL" : true, + "PH-LAG" : true, "PH-LAN" : true, "PH-LAS" : true, "PH-LEY" : true, "PH-LUN" : true, + "PH-MAD" : true, "PH-MAG" : true, "PH-MAS" : true, "PH-MDC" : true, "PH-MDR" : true, + "PH-MOU" : true, "PH-MSC" : true, "PH-MSR" : true, "PH-NCO" : true, "PH-NEC" : true, + "PH-NER" : true, "PH-NSA" : true, "PH-NUE" : true, "PH-NUV" : true, "PH-PAM" : true, + "PH-PAN" : true, "PH-PLW" : true, "PH-QUE" : true, "PH-QUI" : true, "PH-RIZ" : true, + "PH-ROM" : true, "PH-SAR" : true, "PH-SCO" : true, "PH-SIG" : true, "PH-SLE" : true, + "PH-SLU" : true, "PH-SOR" : true, "PH-SUK" : true, "PH-SUN" : true, "PH-SUR" : true, + "PH-TAR" : true, "PH-TAW" : true, "PH-WSA" : true, "PH-ZAN" : true, "PH-ZAS" : true, + "PH-ZMB" : true, "PH-ZSI" : true, "PK-BA" : true, "PK-GB" : true, "PK-IS" : true, + "PK-JK" : true, "PK-KP" : true, "PK-PB" : true, "PK-SD" : true, "PK-TA" : true, + "PL-DS" : true, "PL-KP" : true, "PL-LB" : true, "PL-LD" : true, "PL-LU" : true, + "PL-MA" : true, "PL-MZ" : true, "PL-OP" : true, "PL-PD" : true, "PL-PK" : true, + "PL-PM" : true, "PL-SK" : true, "PL-SL" : true, "PL-WN" : true, "PL-WP" : true, + "PL-ZP" : true, "PS-BTH" : true, "PS-DEB" : true, "PS-GZA" : true, "PS-HBN" : true, + "PS-JEM" : true, "PS-JEN" : true, "PS-JRH" : true, "PS-KYS" : true, "PS-NBS" : true, + "PS-NGZ" : true, "PS-QQA" : true, "PS-RBH" : true, "PS-RFH" : true, "PS-SLT" : true, + "PS-TBS" : true, "PS-TKM" : true, "PT-01" : true, "PT-02" : true, "PT-03" : true, + "PT-04" : true, "PT-05" : true, "PT-06" : true, "PT-07" : true, "PT-08" : true, + "PT-09" : true, "PT-10" : true, "PT-11" : true, "PT-12" : true, "PT-13" : true, + "PT-14" : true, "PT-15" : true, "PT-16" : true, "PT-17" : true, "PT-18" : true, + "PT-20" : true, "PT-30" : true, "PW-002" : true, "PW-004" : true, "PW-010" : true, + "PW-050" : true, "PW-100" : true, "PW-150" : true, "PW-212" : true, "PW-214" : true, + "PW-218" : true, "PW-222" : true, "PW-224" : true, "PW-226" : true, "PW-227" : true, + "PW-228" : true, "PW-350" : true, "PW-370" : true, "PY-1" : true, "PY-10" : true, + "PY-11" : true, "PY-12" : true, "PY-13" : true, "PY-14" : true, "PY-15" : true, + "PY-16" : true, "PY-19" : true, "PY-2" : true, "PY-3" : true, "PY-4" : true, + "PY-5" : true, "PY-6" : true, "PY-7" : true, "PY-8" : true, "PY-9" : true, + "PY-ASU" : true, "QA-DA" : true, "QA-KH" : true, "QA-MS" : true, "QA-RA" : true, + "QA-US" : true, "QA-WA" : true, "QA-ZA" : true, "RO-AB" : true, "RO-AG" : true, + "RO-AR" : true, "RO-B" : true, "RO-BC" : true, "RO-BH" : true, "RO-BN" : true, + "RO-BR" : true, "RO-BT" : true, "RO-BV" : true, "RO-BZ" : true, "RO-CJ" : true, + "RO-CL" : true, "RO-CS" : true, "RO-CT" : true, "RO-CV" : true, "RO-DB" : true, + "RO-DJ" : true, "RO-GJ" : true, "RO-GL" : true, "RO-GR" : true, "RO-HD" : true, + "RO-HR" : true, "RO-IF" : true, "RO-IL" : true, "RO-IS" : true, "RO-MH" : true, + "RO-MM" : true, "RO-MS" : true, "RO-NT" : true, "RO-OT" : true, "RO-PH" : true, + "RO-SB" : true, "RO-SJ" : true, "RO-SM" : true, "RO-SV" : true, "RO-TL" : true, + "RO-TM" : true, "RO-TR" : true, "RO-VL" : true, "RO-VN" : true, "RO-VS" : true, + "RS-00" : true, "RS-01" : true, "RS-02" : true, "RS-03" : true, "RS-04" : true, + "RS-05" : true, "RS-06" : true, "RS-07" : true, "RS-08" : true, "RS-09" : true, + "RS-10" : true, "RS-11" : true, "RS-12" : true, "RS-13" : true, "RS-14" : true, + "RS-15" : true, "RS-16" : true, "RS-17" : true, "RS-18" : true, "RS-19" : true, + "RS-20" : true, "RS-21" : true, "RS-22" : true, "RS-23" : true, "RS-24" : true, + "RS-25" : true, "RS-26" : true, "RS-27" : true, "RS-28" : true, "RS-29" : true, + "RS-KM" : true, "RS-VO" : true, "RU-AD" : true, "RU-AL" : true, "RU-ALT" : true, + "RU-AMU" : true, "RU-ARK" : true, "RU-AST" : true, "RU-BA" : true, "RU-BEL" : true, + "RU-BRY" : true, "RU-BU" : true, "RU-CE" : true, "RU-CHE" : true, "RU-CHU" : true, + "RU-CU" : true, "RU-DA" : true, "RU-IN" : true, "RU-IRK" : true, "RU-IVA" : true, + "RU-KAM" : true, "RU-KB" : true, "RU-KC" : true, "RU-KDA" : true, "RU-KEM" : true, + "RU-KGD" : true, "RU-KGN" : true, "RU-KHA" : true, "RU-KHM" : true, "RU-KIR" : true, + "RU-KK" : true, "RU-KL" : true, "RU-KLU" : true, "RU-KO" : true, "RU-KOS" : true, + "RU-KR" : true, "RU-KRS" : true, "RU-KYA" : true, "RU-LEN" : true, "RU-LIP" : true, + "RU-MAG" : true, "RU-ME" : true, "RU-MO" : true, "RU-MOS" : true, "RU-MOW" : true, + "RU-MUR" : true, "RU-NEN" : true, "RU-NGR" : true, "RU-NIZ" : true, "RU-NVS" : true, + "RU-OMS" : true, "RU-ORE" : true, "RU-ORL" : true, "RU-PER" : true, "RU-PNZ" : true, + "RU-PRI" : true, "RU-PSK" : true, "RU-ROS" : true, "RU-RYA" : true, "RU-SA" : true, + "RU-SAK" : true, "RU-SAM" : true, "RU-SAR" : true, "RU-SE" : true, "RU-SMO" : true, + "RU-SPE" : true, "RU-STA" : true, "RU-SVE" : true, "RU-TA" : true, "RU-TAM" : true, + "RU-TOM" : true, "RU-TUL" : true, "RU-TVE" : true, "RU-TY" : true, "RU-TYU" : true, + "RU-UD" : true, "RU-ULY" : true, "RU-VGG" : true, "RU-VLA" : true, "RU-VLG" : true, + "RU-VOR" : true, "RU-YAN" : true, "RU-YAR" : true, "RU-YEV" : true, "RU-ZAB" : true, + "RW-01" : true, "RW-02" : true, "RW-03" : true, "RW-04" : true, "RW-05" : true, + "SA-01" : true, "SA-02" : true, "SA-03" : true, "SA-04" : true, "SA-05" : true, + "SA-06" : true, "SA-07" : true, "SA-08" : true, "SA-09" : true, "SA-10" : true, + "SA-11" : true, "SA-12" : true, "SA-14" : true, "SB-CE" : true, "SB-CH" : true, + "SB-CT" : true, "SB-GU" : true, "SB-IS" : true, "SB-MK" : true, "SB-ML" : true, + "SB-RB" : true, "SB-TE" : true, "SB-WE" : true, "SC-01" : true, "SC-02" : true, + "SC-03" : true, "SC-04" : true, "SC-05" : true, "SC-06" : true, "SC-07" : true, + "SC-08" : true, "SC-09" : true, "SC-10" : true, "SC-11" : true, "SC-12" : true, + "SC-13" : true, "SC-14" : true, "SC-15" : true, "SC-16" : true, "SC-17" : true, + "SC-18" : true, "SC-19" : true, "SC-20" : true, "SC-21" : true, "SC-22" : true, + "SC-23" : true, "SC-24" : true, "SC-25" : true, "SD-DC" : true, "SD-DE" : true, + "SD-DN" : true, "SD-DS" : true, "SD-DW" : true, "SD-GD" : true, "SD-GZ" : true, + "SD-KA" : true, "SD-KH" : true, "SD-KN" : true, "SD-KS" : true, "SD-NB" : true, + "SD-NO" : true, "SD-NR" : true, "SD-NW" : true, "SD-RS" : true, "SD-SI" : true, + "SE-AB" : true, "SE-AC" : true, "SE-BD" : true, "SE-C" : true, "SE-D" : true, + "SE-E" : true, "SE-F" : true, "SE-G" : true, "SE-H" : true, "SE-I" : true, + "SE-K" : true, "SE-M" : true, "SE-N" : true, "SE-O" : true, "SE-S" : true, + "SE-T" : true, "SE-U" : true, "SE-W" : true, "SE-X" : true, "SE-Y" : true, + "SE-Z" : true, "SG-01" : true, "SG-02" : true, "SG-03" : true, "SG-04" : true, + "SG-05" : true, "SH-AC" : true, "SH-HL" : true, "SH-TA" : true, "SI-001" : true, + "SI-002" : true, "SI-003" : true, "SI-004" : true, "SI-005" : true, "SI-006" : true, + "SI-007" : true, "SI-008" : true, "SI-009" : true, "SI-010" : true, "SI-011" : true, + "SI-012" : true, "SI-013" : true, "SI-014" : true, "SI-015" : true, "SI-016" : true, + "SI-017" : true, "SI-018" : true, "SI-019" : true, "SI-020" : true, "SI-021" : true, + "SI-022" : true, "SI-023" : true, "SI-024" : true, "SI-025" : true, "SI-026" : true, + "SI-027" : true, "SI-028" : true, "SI-029" : true, "SI-030" : true, "SI-031" : true, + "SI-032" : true, "SI-033" : true, "SI-034" : true, "SI-035" : true, "SI-036" : true, + "SI-037" : true, "SI-038" : true, "SI-039" : true, "SI-040" : true, "SI-041" : true, + "SI-042" : true, "SI-043" : true, "SI-044" : true, "SI-045" : true, "SI-046" : true, + "SI-047" : true, "SI-048" : true, "SI-049" : true, "SI-050" : true, "SI-051" : true, + "SI-052" : true, "SI-053" : true, "SI-054" : true, "SI-055" : true, "SI-056" : true, + "SI-057" : true, "SI-058" : true, "SI-059" : true, "SI-060" : true, "SI-061" : true, + "SI-062" : true, "SI-063" : true, "SI-064" : true, "SI-065" : true, "SI-066" : true, + "SI-067" : true, "SI-068" : true, "SI-069" : true, "SI-070" : true, "SI-071" : true, + "SI-072" : true, "SI-073" : true, "SI-074" : true, "SI-075" : true, "SI-076" : true, + "SI-077" : true, "SI-078" : true, "SI-079" : true, "SI-080" : true, "SI-081" : true, + "SI-082" : true, "SI-083" : true, "SI-084" : true, "SI-085" : true, "SI-086" : true, + "SI-087" : true, "SI-088" : true, "SI-089" : true, "SI-090" : true, "SI-091" : true, + "SI-092" : true, "SI-093" : true, "SI-094" : true, "SI-095" : true, "SI-096" : true, + "SI-097" : true, "SI-098" : true, "SI-099" : true, "SI-100" : true, "SI-101" : true, + "SI-102" : true, "SI-103" : true, "SI-104" : true, "SI-105" : true, "SI-106" : true, + "SI-107" : true, "SI-108" : true, "SI-109" : true, "SI-110" : true, "SI-111" : true, + "SI-112" : true, "SI-113" : true, "SI-114" : true, "SI-115" : true, "SI-116" : true, + "SI-117" : true, "SI-118" : true, "SI-119" : true, "SI-120" : true, "SI-121" : true, + "SI-122" : true, "SI-123" : true, "SI-124" : true, "SI-125" : true, "SI-126" : true, + "SI-127" : true, "SI-128" : true, "SI-129" : true, "SI-130" : true, "SI-131" : true, + "SI-132" : true, "SI-133" : true, "SI-134" : true, "SI-135" : true, "SI-136" : true, + "SI-137" : true, "SI-138" : true, "SI-139" : true, "SI-140" : true, "SI-141" : true, + "SI-142" : true, "SI-143" : true, "SI-144" : true, "SI-146" : true, "SI-147" : true, + "SI-148" : true, "SI-149" : true, "SI-150" : true, "SI-151" : true, "SI-152" : true, + "SI-153" : true, "SI-154" : true, "SI-155" : true, "SI-156" : true, "SI-157" : true, + "SI-158" : true, "SI-159" : true, "SI-160" : true, "SI-161" : true, "SI-162" : true, + "SI-163" : true, "SI-164" : true, "SI-165" : true, "SI-166" : true, "SI-167" : true, + "SI-168" : true, "SI-169" : true, "SI-170" : true, "SI-171" : true, "SI-172" : true, + "SI-173" : true, "SI-174" : true, "SI-175" : true, "SI-176" : true, "SI-177" : true, + "SI-178" : true, "SI-179" : true, "SI-180" : true, "SI-181" : true, "SI-182" : true, + "SI-183" : true, "SI-184" : true, "SI-185" : true, "SI-186" : true, "SI-187" : true, + "SI-188" : true, "SI-189" : true, "SI-190" : true, "SI-191" : true, "SI-192" : true, + "SI-193" : true, "SI-194" : true, "SI-195" : true, "SI-196" : true, "SI-197" : true, + "SI-198" : true, "SI-199" : true, "SI-200" : true, "SI-201" : true, "SI-202" : true, + "SI-203" : true, "SI-204" : true, "SI-205" : true, "SI-206" : true, "SI-207" : true, + "SI-208" : true, "SI-209" : true, "SI-210" : true, "SI-211" : true, "SK-BC" : true, + "SK-BL" : true, "SK-KI" : true, "SK-NI" : true, "SK-PV" : true, "SK-TA" : true, + "SK-TC" : true, "SK-ZI" : true, "SL-E" : true, "SL-N" : true, "SL-S" : true, + "SL-W" : true, "SM-01" : true, "SM-02" : true, "SM-03" : true, "SM-04" : true, + "SM-05" : true, "SM-06" : true, "SM-07" : true, "SM-08" : true, "SM-09" : true, + "SN-DB" : true, "SN-DK" : true, "SN-FK" : true, "SN-KA" : true, "SN-KD" : true, + "SN-KE" : true, "SN-KL" : true, "SN-LG" : true, "SN-MT" : true, "SN-SE" : true, + "SN-SL" : true, "SN-TC" : true, "SN-TH" : true, "SN-ZG" : true, "SO-AW" : true, + "SO-BK" : true, "SO-BN" : true, "SO-BR" : true, "SO-BY" : true, "SO-GA" : true, + "SO-GE" : true, "SO-HI" : true, "SO-JD" : true, "SO-JH" : true, "SO-MU" : true, + "SO-NU" : true, "SO-SA" : true, "SO-SD" : true, "SO-SH" : true, "SO-SO" : true, + "SO-TO" : true, "SO-WO" : true, "SR-BR" : true, "SR-CM" : true, "SR-CR" : true, + "SR-MA" : true, "SR-NI" : true, "SR-PM" : true, "SR-PR" : true, "SR-SA" : true, + "SR-SI" : true, "SR-WA" : true, "SS-BN" : true, "SS-BW" : true, "SS-EC" : true, + "SS-EE8" : true, "SS-EW" : true, "SS-JG" : true, "SS-LK" : true, "SS-NU" : true, + "SS-UY" : true, "SS-WR" : true, "ST-P" : true, "ST-S" : true, "SV-AH" : true, + "SV-CA" : true, "SV-CH" : true, "SV-CU" : true, "SV-LI" : true, "SV-MO" : true, + "SV-PA" : true, "SV-SA" : true, "SV-SM" : true, "SV-SO" : true, "SV-SS" : true, + "SV-SV" : true, "SV-UN" : true, "SV-US" : true, "SY-DI" : true, "SY-DR" : true, + "SY-DY" : true, "SY-HA" : true, "SY-HI" : true, "SY-HL" : true, "SY-HM" : true, + "SY-ID" : true, "SY-LA" : true, "SY-QU" : true, "SY-RA" : true, "SY-RD" : true, + "SY-SU" : true, "SY-TA" : true, "SZ-HH" : true, "SZ-LU" : true, "SZ-MA" : true, + "SZ-SH" : true, "TD-BA" : true, "TD-BG" : true, "TD-BO" : true, "TD-CB" : true, + "TD-EN" : true, "TD-GR" : true, "TD-HL" : true, "TD-KA" : true, "TD-LC" : true, + "TD-LO" : true, "TD-LR" : true, "TD-MA" : true, "TD-MC" : true, "TD-ME" : true, + "TD-MO" : true, "TD-ND" : true, "TD-OD" : true, "TD-SA" : true, "TD-SI" : true, + "TD-TA" : true, "TD-TI" : true, "TD-WF" : true, "TG-C" : true, "TG-K" : true, + "TG-M" : true, "TG-P" : true, "TG-S" : true, "TH-10" : true, "TH-11" : true, + "TH-12" : true, "TH-13" : true, "TH-14" : true, "TH-15" : true, "TH-16" : true, + "TH-17" : true, "TH-18" : true, "TH-19" : true, "TH-20" : true, "TH-21" : true, + "TH-22" : true, "TH-23" : true, "TH-24" : true, "TH-25" : true, "TH-26" : true, + "TH-27" : true, "TH-30" : true, "TH-31" : true, "TH-32" : true, "TH-33" : true, + "TH-34" : true, "TH-35" : true, "TH-36" : true, "TH-37" : true, "TH-39" : true, + "TH-40" : true, "TH-41" : true, "TH-42" : true, "TH-43" : true, "TH-44" : true, + "TH-45" : true, "TH-46" : true, "TH-47" : true, "TH-48" : true, "TH-49" : true, + "TH-50" : true, "TH-51" : true, "TH-52" : true, "TH-53" : true, "TH-54" : true, + "TH-55" : true, "TH-56" : true, "TH-57" : true, "TH-58" : true, "TH-60" : true, + "TH-61" : true, "TH-62" : true, "TH-63" : true, "TH-64" : true, "TH-65" : true, + "TH-66" : true, "TH-67" : true, "TH-70" : true, "TH-71" : true, "TH-72" : true, + "TH-73" : true, "TH-74" : true, "TH-75" : true, "TH-76" : true, "TH-77" : true, + "TH-80" : true, "TH-81" : true, "TH-82" : true, "TH-83" : true, "TH-84" : true, + "TH-85" : true, "TH-86" : true, "TH-90" : true, "TH-91" : true, "TH-92" : true, + "TH-93" : true, "TH-94" : true, "TH-95" : true, "TH-96" : true, "TH-S" : true, + "TJ-GB" : true, "TJ-KT" : true, "TJ-SU" : true, "TL-AL" : true, "TL-AN" : true, + "TL-BA" : true, "TL-BO" : true, "TL-CO" : true, "TL-DI" : true, "TL-ER" : true, + "TL-LA" : true, "TL-LI" : true, "TL-MF" : true, "TL-MT" : true, "TL-OE" : true, + "TL-VI" : true, "TM-A" : true, "TM-B" : true, "TM-D" : true, "TM-L" : true, + "TM-M" : true, "TM-S" : true, "TN-11" : true, "TN-12" : true, "TN-13" : true, + "TN-14" : true, "TN-21" : true, "TN-22" : true, "TN-23" : true, "TN-31" : true, + "TN-32" : true, "TN-33" : true, "TN-34" : true, "TN-41" : true, "TN-42" : true, + "TN-43" : true, "TN-51" : true, "TN-52" : true, "TN-53" : true, "TN-61" : true, + "TN-71" : true, "TN-72" : true, "TN-73" : true, "TN-81" : true, "TN-82" : true, + "TN-83" : true, "TO-01" : true, "TO-02" : true, "TO-03" : true, "TO-04" : true, + "TO-05" : true, "TR-01" : true, "TR-02" : true, "TR-03" : true, "TR-04" : true, + "TR-05" : true, "TR-06" : true, "TR-07" : true, "TR-08" : true, "TR-09" : true, + "TR-10" : true, "TR-11" : true, "TR-12" : true, "TR-13" : true, "TR-14" : true, + "TR-15" : true, "TR-16" : true, "TR-17" : true, "TR-18" : true, "TR-19" : true, + "TR-20" : true, "TR-21" : true, "TR-22" : true, "TR-23" : true, "TR-24" : true, + "TR-25" : true, "TR-26" : true, "TR-27" : true, "TR-28" : true, "TR-29" : true, + "TR-30" : true, "TR-31" : true, "TR-32" : true, "TR-33" : true, "TR-34" : true, + "TR-35" : true, "TR-36" : true, "TR-37" : true, "TR-38" : true, "TR-39" : true, + "TR-40" : true, "TR-41" : true, "TR-42" : true, "TR-43" : true, "TR-44" : true, + "TR-45" : true, "TR-46" : true, "TR-47" : true, "TR-48" : true, "TR-49" : true, + "TR-50" : true, "TR-51" : true, "TR-52" : true, "TR-53" : true, "TR-54" : true, + "TR-55" : true, "TR-56" : true, "TR-57" : true, "TR-58" : true, "TR-59" : true, + "TR-60" : true, "TR-61" : true, "TR-62" : true, "TR-63" : true, "TR-64" : true, + "TR-65" : true, "TR-66" : true, "TR-67" : true, "TR-68" : true, "TR-69" : true, + "TR-70" : true, "TR-71" : true, "TR-72" : true, "TR-73" : true, "TR-74" : true, + "TR-75" : true, "TR-76" : true, "TR-77" : true, "TR-78" : true, "TR-79" : true, + "TR-80" : true, "TR-81" : true, "TT-ARI" : true, "TT-CHA" : true, "TT-CTT" : true, + "TT-DMN" : true, "TT-ETO" : true, "TT-PED" : true, "TT-POS" : true, "TT-PRT" : true, + "TT-PTF" : true, "TT-RCM" : true, "TT-SFO" : true, "TT-SGE" : true, "TT-SIP" : true, + "TT-SJL" : true, "TT-TUP" : true, "TT-WTO" : true, "TV-FUN" : true, "TV-NIT" : true, + "TV-NKF" : true, "TV-NKL" : true, "TV-NMA" : true, "TV-NMG" : true, "TV-NUI" : true, + "TV-VAI" : true, "TW-CHA" : true, "TW-CYI" : true, "TW-CYQ" : true, "TW-HSQ" : true, + "TW-HSZ" : true, "TW-HUA" : true, "TW-ILA" : true, "TW-KEE" : true, "TW-KHH" : true, + "TW-KHQ" : true, "TW-MIA" : true, "TW-NAN" : true, "TW-PEN" : true, "TW-PIF" : true, + "TW-TAO" : true, "TW-TNN" : true, "TW-TNQ" : true, "TW-TPE" : true, "TW-TPQ" : true, + "TW-TTT" : true, "TW-TXG" : true, "TW-TXQ" : true, "TW-YUN" : true, "TZ-01" : true, + "TZ-02" : true, "TZ-03" : true, "TZ-04" : true, "TZ-05" : true, "TZ-06" : true, + "TZ-07" : true, "TZ-08" : true, "TZ-09" : true, "TZ-10" : true, "TZ-11" : true, + "TZ-12" : true, "TZ-13" : true, "TZ-14" : true, "TZ-15" : true, "TZ-16" : true, + "TZ-17" : true, "TZ-18" : true, "TZ-19" : true, "TZ-20" : true, "TZ-21" : true, + "TZ-22" : true, "TZ-23" : true, "TZ-24" : true, "TZ-25" : true, "TZ-26" : true, + "UA-05" : true, "UA-07" : true, "UA-09" : true, "UA-12" : true, "UA-14" : true, + "UA-18" : true, "UA-21" : true, "UA-23" : true, "UA-26" : true, "UA-30" : true, + "UA-32" : true, "UA-35" : true, "UA-40" : true, "UA-43" : true, "UA-46" : true, + "UA-48" : true, "UA-51" : true, "UA-53" : true, "UA-56" : true, "UA-59" : true, + "UA-61" : true, "UA-63" : true, "UA-65" : true, "UA-68" : true, "UA-71" : true, + "UA-74" : true, "UA-77" : true, "UG-101" : true, "UG-102" : true, "UG-103" : true, + "UG-104" : true, "UG-105" : true, "UG-106" : true, "UG-107" : true, "UG-108" : true, + "UG-109" : true, "UG-110" : true, "UG-111" : true, "UG-112" : true, "UG-113" : true, + "UG-114" : true, "UG-115" : true, "UG-116" : true, "UG-201" : true, "UG-202" : true, + "UG-203" : true, "UG-204" : true, "UG-205" : true, "UG-206" : true, "UG-207" : true, + "UG-208" : true, "UG-209" : true, "UG-210" : true, "UG-211" : true, "UG-212" : true, + "UG-213" : true, "UG-214" : true, "UG-215" : true, "UG-216" : true, "UG-217" : true, + "UG-218" : true, "UG-219" : true, "UG-220" : true, "UG-221" : true, "UG-222" : true, + "UG-223" : true, "UG-224" : true, "UG-301" : true, "UG-302" : true, "UG-303" : true, + "UG-304" : true, "UG-305" : true, "UG-306" : true, "UG-307" : true, "UG-308" : true, + "UG-309" : true, "UG-310" : true, "UG-311" : true, "UG-312" : true, "UG-313" : true, + "UG-314" : true, "UG-315" : true, "UG-316" : true, "UG-317" : true, "UG-318" : true, + "UG-319" : true, "UG-320" : true, "UG-321" : true, "UG-401" : true, "UG-402" : true, + "UG-403" : true, "UG-404" : true, "UG-405" : true, "UG-406" : true, "UG-407" : true, + "UG-408" : true, "UG-409" : true, "UG-410" : true, "UG-411" : true, "UG-412" : true, + "UG-413" : true, "UG-414" : true, "UG-415" : true, "UG-416" : true, "UG-417" : true, + "UG-418" : true, "UG-419" : true, "UG-C" : true, "UG-E" : true, "UG-N" : true, + "UG-W" : true, "UM-67" : true, "UM-71" : true, "UM-76" : true, "UM-79" : true, + "UM-81" : true, "UM-84" : true, "UM-86" : true, "UM-89" : true, "UM-95" : true, + "US-AK" : true, "US-AL" : true, "US-AR" : true, "US-AS" : true, "US-AZ" : true, + "US-CA" : true, "US-CO" : true, "US-CT" : true, "US-DC" : true, "US-DE" : true, + "US-FL" : true, "US-GA" : true, "US-GU" : true, "US-HI" : true, "US-IA" : true, + "US-ID" : true, "US-IL" : true, "US-IN" : true, "US-KS" : true, "US-KY" : true, + "US-LA" : true, "US-MA" : true, "US-MD" : true, "US-ME" : true, "US-MI" : true, + "US-MN" : true, "US-MO" : true, "US-MP" : true, "US-MS" : true, "US-MT" : true, + "US-NC" : true, "US-ND" : true, "US-NE" : true, "US-NH" : true, "US-NJ" : true, + "US-NM" : true, "US-NV" : true, "US-NY" : true, "US-OH" : true, "US-OK" : true, + "US-OR" : true, "US-PA" : true, "US-PR" : true, "US-RI" : true, "US-SC" : true, + "US-SD" : true, "US-TN" : true, "US-TX" : true, "US-UM" : true, "US-UT" : true, + "US-VA" : true, "US-VI" : true, "US-VT" : true, "US-WA" : true, "US-WI" : true, + "US-WV" : true, "US-WY" : true, "UY-AR" : true, "UY-CA" : true, "UY-CL" : true, + "UY-CO" : true, "UY-DU" : true, "UY-FD" : true, "UY-FS" : true, "UY-LA" : true, + "UY-MA" : true, "UY-MO" : true, "UY-PA" : true, "UY-RN" : true, "UY-RO" : true, + "UY-RV" : true, "UY-SA" : true, "UY-SJ" : true, "UY-SO" : true, "UY-TA" : true, + "UY-TT" : true, "UZ-AN" : true, "UZ-BU" : true, "UZ-FA" : true, "UZ-JI" : true, + "UZ-NG" : true, "UZ-NW" : true, "UZ-QA" : true, "UZ-QR" : true, "UZ-SA" : true, + "UZ-SI" : true, "UZ-SU" : true, "UZ-TK" : true, "UZ-TO" : true, "UZ-XO" : true, + "VC-01" : true, "VC-02" : true, "VC-03" : true, "VC-04" : true, "VC-05" : true, + "VC-06" : true, "VE-A" : true, "VE-B" : true, "VE-C" : true, "VE-D" : true, + "VE-E" : true, "VE-F" : true, "VE-G" : true, "VE-H" : true, "VE-I" : true, + "VE-J" : true, "VE-K" : true, "VE-L" : true, "VE-M" : true, "VE-N" : true, + "VE-O" : true, "VE-P" : true, "VE-R" : true, "VE-S" : true, "VE-T" : true, + "VE-U" : true, "VE-V" : true, "VE-W" : true, "VE-X" : true, "VE-Y" : true, + "VE-Z" : true, "VN-01" : true, "VN-02" : true, "VN-03" : true, "VN-04" : true, + "VN-05" : true, "VN-06" : true, "VN-07" : true, "VN-09" : true, "VN-13" : true, + "VN-14" : true, "VN-15" : true, "VN-18" : true, "VN-20" : true, "VN-21" : true, + "VN-22" : true, "VN-23" : true, "VN-24" : true, "VN-25" : true, "VN-26" : true, + "VN-27" : true, "VN-28" : true, "VN-29" : true, "VN-30" : true, "VN-31" : true, + "VN-32" : true, "VN-33" : true, "VN-34" : true, "VN-35" : true, "VN-36" : true, + "VN-37" : true, "VN-39" : true, "VN-40" : true, "VN-41" : true, "VN-43" : true, + "VN-44" : true, "VN-45" : true, "VN-46" : true, "VN-47" : true, "VN-49" : true, + "VN-50" : true, "VN-51" : true, "VN-52" : true, "VN-53" : true, "VN-54" : true, + "VN-55" : true, "VN-56" : true, "VN-57" : true, "VN-58" : true, "VN-59" : true, + "VN-61" : true, "VN-63" : true, "VN-66" : true, "VN-67" : true, "VN-68" : true, + "VN-69" : true, "VN-70" : true, "VN-71" : true, "VN-72" : true, "VN-73" : true, + "VN-CT" : true, "VN-DN" : true, "VN-HN" : true, "VN-HP" : true, "VN-SG" : true, + "VU-MAP" : true, "VU-PAM" : true, "VU-SAM" : true, "VU-SEE" : true, "VU-TAE" : true, + "VU-TOB" : true, "WS-AA" : true, "WS-AL" : true, "WS-AT" : true, "WS-FA" : true, + "WS-GE" : true, "WS-GI" : true, "WS-PA" : true, "WS-SA" : true, "WS-TU" : true, + "WS-VF" : true, "WS-VS" : true, "YE-AB" : true, "YE-AD" : true, "YE-AM" : true, + "YE-BA" : true, "YE-DA" : true, "YE-DH" : true, "YE-HD" : true, "YE-HJ" : true, + "YE-IB" : true, "YE-JA" : true, "YE-LA" : true, "YE-MA" : true, "YE-MR" : true, + "YE-MU" : true, "YE-MW" : true, "YE-RA" : true, "YE-SD" : true, "YE-SH" : true, + "YE-SN" : true, "YE-TA" : true, "ZA-EC" : true, "ZA-FS" : true, "ZA-GP" : true, + "ZA-LP" : true, "ZA-MP" : true, "ZA-NC" : true, "ZA-NW" : true, "ZA-WC" : true, + "ZA-ZN" : true, "ZM-01" : true, "ZM-02" : true, "ZM-03" : true, "ZM-04" : true, + "ZM-05" : true, "ZM-06" : true, "ZM-07" : true, "ZM-08" : true, "ZM-09" : true, + "ZW-BU" : true, "ZW-HA" : true, "ZW-MA" : true, "ZW-MC" : true, "ZW-ME" : true, + "ZW-MI" : true, "ZW-MN" : true, "ZW-MS" : true, "ZW-MV" : true, "ZW-MW" : true, +} diff --git a/vendor/github.com/go-playground/validator/v10/currency_codes.go b/vendor/github.com/go-playground/validator/v10/currency_codes.go new file mode 100644 index 0000000..a5cd9b1 --- /dev/null +++ b/vendor/github.com/go-playground/validator/v10/currency_codes.go @@ -0,0 +1,79 @@ +package validator + +var iso4217 = map[string]bool{ + "AFN": true, "EUR": true, "ALL": true, "DZD": true, "USD": true, + "AOA": true, "XCD": true, "ARS": true, "AMD": true, "AWG": true, + "AUD": true, "AZN": true, "BSD": true, "BHD": true, "BDT": true, + "BBD": true, "BYN": true, "BZD": true, "XOF": true, "BMD": true, + "INR": true, "BTN": true, "BOB": true, "BOV": true, "BAM": true, + "BWP": true, "NOK": true, "BRL": true, "BND": true, "BGN": true, + "BIF": true, "CVE": true, "KHR": true, "XAF": true, "CAD": true, + "KYD": true, "CLP": true, "CLF": true, "CNY": true, "COP": true, + "COU": true, "KMF": true, "CDF": true, "NZD": true, "CRC": true, + "HRK": true, "CUP": true, "CUC": true, "ANG": true, "CZK": true, + "DKK": true, "DJF": true, "DOP": true, "EGP": true, "SVC": true, + "ERN": true, "SZL": true, "ETB": true, "FKP": true, "FJD": true, + "XPF": true, "GMD": true, "GEL": true, "GHS": true, "GIP": true, + "GTQ": true, "GBP": true, "GNF": true, "GYD": true, "HTG": true, + "HNL": true, "HKD": true, "HUF": true, "ISK": true, "IDR": true, + "XDR": true, "IRR": true, "IQD": true, "ILS": true, "JMD": true, + "JPY": true, "JOD": true, "KZT": true, "KES": true, "KPW": true, + "KRW": true, "KWD": true, "KGS": true, "LAK": true, "LBP": true, + "LSL": true, "ZAR": true, "LRD": true, "LYD": true, "CHF": true, + "MOP": true, "MKD": true, "MGA": true, "MWK": true, "MYR": true, + "MVR": true, "MRU": true, "MUR": true, "XUA": true, "MXN": true, + "MXV": true, "MDL": true, "MNT": true, "MAD": true, "MZN": true, + "MMK": true, "NAD": true, "NPR": true, "NIO": true, "NGN": true, + "OMR": true, "PKR": true, "PAB": true, "PGK": true, "PYG": true, + "PEN": true, "PHP": true, "PLN": true, "QAR": true, "RON": true, + "RUB": true, "RWF": true, "SHP": true, "WST": true, "STN": true, + "SAR": true, "RSD": true, "SCR": true, "SLL": true, "SGD": true, + "XSU": true, "SBD": true, "SOS": true, "SSP": true, "LKR": true, + "SDG": true, "SRD": true, "SEK": true, "CHE": true, "CHW": true, + "SYP": true, "TWD": true, "TJS": true, "TZS": true, "THB": true, + "TOP": true, "TTD": true, "TND": true, "TRY": true, "TMT": true, + "UGX": true, "UAH": true, "AED": true, "USN": true, "UYU": true, + "UYI": true, "UYW": true, "UZS": true, "VUV": true, "VES": true, + "VND": true, "YER": true, "ZMW": true, "ZWL": true, "XBA": true, + "XBB": true, "XBC": true, "XBD": true, "XTS": true, "XXX": true, + "XAU": true, "XPD": true, "XPT": true, "XAG": true, +} + +var iso4217_numeric = map[int]bool{ + 8: true, 12: true, 32: true, 36: true, 44: true, + 48: true, 50: true, 51: true, 52: true, 60: true, + 64: true, 68: true, 72: true, 84: true, 90: true, + 96: true, 104: true, 108: true, 116: true, 124: true, + 132: true, 136: true, 144: true, 152: true, 156: true, + 170: true, 174: true, 188: true, 191: true, 192: true, + 203: true, 208: true, 214: true, 222: true, 230: true, + 232: true, 238: true, 242: true, 262: true, 270: true, + 292: true, 320: true, 324: true, 328: true, 332: true, + 340: true, 344: true, 348: true, 352: true, 356: true, + 360: true, 364: true, 368: true, 376: true, 388: true, + 392: true, 398: true, 400: true, 404: true, 408: true, + 410: true, 414: true, 417: true, 418: true, 422: true, + 426: true, 430: true, 434: true, 446: true, 454: true, + 458: true, 462: true, 480: true, 484: true, 496: true, + 498: true, 504: true, 512: true, 516: true, 524: true, + 532: true, 533: true, 548: true, 554: true, 558: true, + 566: true, 578: true, 586: true, 590: true, 598: true, + 600: true, 604: true, 608: true, 634: true, 643: true, + 646: true, 654: true, 682: true, 690: true, 694: true, + 702: true, 704: true, 706: true, 710: true, 728: true, + 748: true, 752: true, 756: true, 760: true, 764: true, + 776: true, 780: true, 784: true, 788: true, 800: true, + 807: true, 818: true, 826: true, 834: true, 840: true, + 858: true, 860: true, 882: true, 886: true, 901: true, + 927: true, 928: true, 929: true, 930: true, 931: true, + 932: true, 933: true, 934: true, 936: true, 938: true, + 940: true, 941: true, 943: true, 944: true, 946: true, + 947: true, 948: true, 949: true, 950: true, 951: true, + 952: true, 953: true, 955: true, 956: true, 957: true, + 958: true, 959: true, 960: true, 961: true, 962: true, + 963: true, 964: true, 965: true, 967: true, 968: true, + 969: true, 970: true, 971: true, 972: true, 973: true, + 975: true, 976: true, 977: true, 978: true, 979: true, + 980: true, 981: true, 984: true, 985: true, 986: true, + 990: true, 994: true, 997: true, 999: true, +} diff --git a/vendor/github.com/go-playground/validator/v10/doc.go b/vendor/github.com/go-playground/validator/v10/doc.go new file mode 100644 index 0000000..b284c37 --- /dev/null +++ b/vendor/github.com/go-playground/validator/v10/doc.go @@ -0,0 +1,1361 @@ +/* +Package validator implements value validations for structs and individual fields +based on tags. + +It can also handle Cross-Field and Cross-Struct validation for nested structs +and has the ability to dive into arrays and maps of any type. + +see more examples https://github.com/go-playground/validator/tree/master/_examples + +Singleton + +Validator is designed to be thread-safe and used as a singleton instance. +It caches information about your struct and validations, +in essence only parsing your validation tags once per struct type. +Using multiple instances neglects the benefit of caching. +The not thread-safe functions are explicitly marked as such in the documentation. + +Validation Functions Return Type error + +Doing things this way is actually the way the standard library does, see the +file.Open method here: + + https://golang.org/pkg/os/#Open. + +The authors return type "error" to avoid the issue discussed in the following, +where err is always != nil: + + http://stackoverflow.com/a/29138676/3158232 + https://github.com/go-playground/validator/issues/134 + +Validator only InvalidValidationError for bad validation input, nil or +ValidationErrors as type error; so, in your code all you need to do is check +if the error returned is not nil, and if it's not check if error is +InvalidValidationError ( if necessary, most of the time it isn't ) type cast +it to type ValidationErrors like so err.(validator.ValidationErrors). + +Custom Validation Functions + +Custom Validation functions can be added. Example: + + // Structure + func customFunc(fl validator.FieldLevel) bool { + + if fl.Field().String() == "invalid" { + return false + } + + return true + } + + validate.RegisterValidation("custom tag name", customFunc) + // NOTES: using the same tag name as an existing function + // will overwrite the existing one + +Cross-Field Validation + +Cross-Field Validation can be done via the following tags: + - eqfield + - nefield + - gtfield + - gtefield + - ltfield + - ltefield + - eqcsfield + - necsfield + - gtcsfield + - gtecsfield + - ltcsfield + - ltecsfield + +If, however, some custom cross-field validation is required, it can be done +using a custom validation. + +Why not just have cross-fields validation tags (i.e. only eqcsfield and not +eqfield)? + +The reason is efficiency. If you want to check a field within the same struct +"eqfield" only has to find the field on the same struct (1 level). But, if we +used "eqcsfield" it could be multiple levels down. Example: + + type Inner struct { + StartDate time.Time + } + + type Outer struct { + InnerStructField *Inner + CreatedAt time.Time `validate:"ltecsfield=InnerStructField.StartDate"` + } + + now := time.Now() + + inner := &Inner{ + StartDate: now, + } + + outer := &Outer{ + InnerStructField: inner, + CreatedAt: now, + } + + errs := validate.Struct(outer) + + // NOTE: when calling validate.Struct(val) topStruct will be the top level struct passed + // into the function + // when calling validate.VarWithValue(val, field, tag) val will be + // whatever you pass, struct, field... + // when calling validate.Field(field, tag) val will be nil + +Multiple Validators + +Multiple validators on a field will process in the order defined. Example: + + type Test struct { + Field `validate:"max=10,min=1"` + } + + // max will be checked then min + +Bad Validator definitions are not handled by the library. Example: + + type Test struct { + Field `validate:"min=10,max=0"` + } + + // this definition of min max will never succeed + +Using Validator Tags + +Baked In Cross-Field validation only compares fields on the same struct. +If Cross-Field + Cross-Struct validation is needed you should implement your +own custom validator. + +Comma (",") is the default separator of validation tags. If you wish to +have a comma included within the parameter (i.e. excludesall=,) you will need to +use the UTF-8 hex representation 0x2C, which is replaced in the code as a comma, +so the above will become excludesall=0x2C. + + type Test struct { + Field `validate:"excludesall=,"` // BAD! Do not include a comma. + Field `validate:"excludesall=0x2C"` // GOOD! Use the UTF-8 hex representation. + } + +Pipe ("|") is the 'or' validation tags deparator. If you wish to +have a pipe included within the parameter i.e. excludesall=| you will need to +use the UTF-8 hex representation 0x7C, which is replaced in the code as a pipe, +so the above will become excludesall=0x7C + + type Test struct { + Field `validate:"excludesall=|"` // BAD! Do not include a a pipe! + Field `validate:"excludesall=0x7C"` // GOOD! Use the UTF-8 hex representation. + } + + +Baked In Validators and Tags + +Here is a list of the current built in validators: + + +Skip Field + +Tells the validation to skip this struct field; this is particularly +handy in ignoring embedded structs from being validated. (Usage: -) + Usage: - + + +Or Operator + +This is the 'or' operator allowing multiple validators to be used and +accepted. (Usage: rgb|rgba) <-- this would allow either rgb or rgba +colors to be accepted. This can also be combined with 'and' for example +( Usage: omitempty,rgb|rgba) + + Usage: | + +StructOnly + +When a field that is a nested struct is encountered, and contains this flag +any validation on the nested struct will be run, but none of the nested +struct fields will be validated. This is useful if inside of your program +you know the struct will be valid, but need to verify it has been assigned. +NOTE: only "required" and "omitempty" can be used on a struct itself. + + Usage: structonly + +NoStructLevel + +Same as structonly tag except that any struct level validations will not run. + + Usage: nostructlevel + +Omit Empty + +Allows conditional validation, for example if a field is not set with +a value (Determined by the "required" validator) then other validation +such as min or max won't run, but if a value is set validation will run. + + Usage: omitempty + +Dive + +This tells the validator to dive into a slice, array or map and validate that +level of the slice, array or map with the validation tags that follow. +Multidimensional nesting is also supported, each level you wish to dive will +require another dive tag. dive has some sub-tags, 'keys' & 'endkeys', please see +the Keys & EndKeys section just below. + + Usage: dive + +Example #1 + + [][]string with validation tag "gt=0,dive,len=1,dive,required" + // gt=0 will be applied to [] + // len=1 will be applied to []string + // required will be applied to string + +Example #2 + + [][]string with validation tag "gt=0,dive,dive,required" + // gt=0 will be applied to [] + // []string will be spared validation + // required will be applied to string + +Keys & EndKeys + +These are to be used together directly after the dive tag and tells the validator +that anything between 'keys' and 'endkeys' applies to the keys of a map and not the +values; think of it like the 'dive' tag, but for map keys instead of values. +Multidimensional nesting is also supported, each level you wish to validate will +require another 'keys' and 'endkeys' tag. These tags are only valid for maps. + + Usage: dive,keys,othertagvalidation(s),endkeys,valuevalidationtags + +Example #1 + + map[string]string with validation tag "gt=0,dive,keys,eg=1|eq=2,endkeys,required" + // gt=0 will be applied to the map itself + // eg=1|eq=2 will be applied to the map keys + // required will be applied to map values + +Example #2 + + map[[2]string]string with validation tag "gt=0,dive,keys,dive,eq=1|eq=2,endkeys,required" + // gt=0 will be applied to the map itself + // eg=1|eq=2 will be applied to each array element in the the map keys + // required will be applied to map values + +Required + +This validates that the value is not the data types default zero value. +For numbers ensures value is not zero. For strings ensures value is +not "". For slices, maps, pointers, interfaces, channels and functions +ensures the value is not nil. + + Usage: required + +Required If + +The field under validation must be present and not empty only if all +the other specified fields are equal to the value following the specified +field. For strings ensures value is not "". For slices, maps, pointers, +interfaces, channels and functions ensures the value is not nil. + + Usage: required_if + +Examples: + + // require the field if the Field1 is equal to the parameter given: + Usage: required_if=Field1 foobar + + // require the field if the Field1 and Field2 is equal to the value respectively: + Usage: required_if=Field1 foo Field2 bar + +Required Unless + +The field under validation must be present and not empty unless all +the other specified fields are equal to the value following the specified +field. For strings ensures value is not "". For slices, maps, pointers, +interfaces, channels and functions ensures the value is not nil. + + Usage: required_unless + +Examples: + + // require the field unless the Field1 is equal to the parameter given: + Usage: required_unless=Field1 foobar + + // require the field unless the Field1 and Field2 is equal to the value respectively: + Usage: required_unless=Field1 foo Field2 bar + +Required With + +The field under validation must be present and not empty only if any +of the other specified fields are present. For strings ensures value is +not "". For slices, maps, pointers, interfaces, channels and functions +ensures the value is not nil. + + Usage: required_with + +Examples: + + // require the field if the Field1 is present: + Usage: required_with=Field1 + + // require the field if the Field1 or Field2 is present: + Usage: required_with=Field1 Field2 + +Required With All + +The field under validation must be present and not empty only if all +of the other specified fields are present. For strings ensures value is +not "". For slices, maps, pointers, interfaces, channels and functions +ensures the value is not nil. + + Usage: required_with_all + +Example: + + // require the field if the Field1 and Field2 is present: + Usage: required_with_all=Field1 Field2 + +Required Without + +The field under validation must be present and not empty only when any +of the other specified fields are not present. For strings ensures value is +not "". For slices, maps, pointers, interfaces, channels and functions +ensures the value is not nil. + + Usage: required_without + +Examples: + + // require the field if the Field1 is not present: + Usage: required_without=Field1 + + // require the field if the Field1 or Field2 is not present: + Usage: required_without=Field1 Field2 + +Required Without All + +The field under validation must be present and not empty only when all +of the other specified fields are not present. For strings ensures value is +not "". For slices, maps, pointers, interfaces, channels and functions +ensures the value is not nil. + + Usage: required_without_all + +Example: + + // require the field if the Field1 and Field2 is not present: + Usage: required_without_all=Field1 Field2 + +Is Default + +This validates that the value is the default value and is almost the +opposite of required. + + Usage: isdefault + +Length + +For numbers, length will ensure that the value is +equal to the parameter given. For strings, it checks that +the string length is exactly that number of characters. For slices, +arrays, and maps, validates the number of items. + +Example #1 + + Usage: len=10 + +Example #2 (time.Duration) + +For time.Duration, len will ensure that the value is equal to the duration given +in the parameter. + + Usage: len=1h30m + +Maximum + +For numbers, max will ensure that the value is +less than or equal to the parameter given. For strings, it checks +that the string length is at most that number of characters. For +slices, arrays, and maps, validates the number of items. + +Example #1 + + Usage: max=10 + +Example #2 (time.Duration) + +For time.Duration, max will ensure that the value is less than or equal to the +duration given in the parameter. + + Usage: max=1h30m + +Minimum + +For numbers, min will ensure that the value is +greater or equal to the parameter given. For strings, it checks that +the string length is at least that number of characters. For slices, +arrays, and maps, validates the number of items. + +Example #1 + + Usage: min=10 + +Example #2 (time.Duration) + +For time.Duration, min will ensure that the value is greater than or equal to +the duration given in the parameter. + + Usage: min=1h30m + +Equals + +For strings & numbers, eq will ensure that the value is +equal to the parameter given. For slices, arrays, and maps, +validates the number of items. + +Example #1 + + Usage: eq=10 + +Example #2 (time.Duration) + +For time.Duration, eq will ensure that the value is equal to the duration given +in the parameter. + + Usage: eq=1h30m + +Not Equal + +For strings & numbers, ne will ensure that the value is not +equal to the parameter given. For slices, arrays, and maps, +validates the number of items. + +Example #1 + + Usage: ne=10 + +Example #2 (time.Duration) + +For time.Duration, ne will ensure that the value is not equal to the duration +given in the parameter. + + Usage: ne=1h30m + +One Of + +For strings, ints, and uints, oneof will ensure that the value +is one of the values in the parameter. The parameter should be +a list of values separated by whitespace. Values may be +strings or numbers. To match strings with spaces in them, include +the target string between single quotes. + + Usage: oneof=red green + oneof='red green' 'blue yellow' + oneof=5 7 9 + +Greater Than + +For numbers, this will ensure that the value is greater than the +parameter given. For strings, it checks that the string length +is greater than that number of characters. For slices, arrays +and maps it validates the number of items. + +Example #1 + + Usage: gt=10 + +Example #2 (time.Time) + +For time.Time ensures the time value is greater than time.Now.UTC(). + + Usage: gt + +Example #3 (time.Duration) + +For time.Duration, gt will ensure that the value is greater than the duration +given in the parameter. + + Usage: gt=1h30m + +Greater Than or Equal + +Same as 'min' above. Kept both to make terminology with 'len' easier. + +Example #1 + + Usage: gte=10 + +Example #2 (time.Time) + +For time.Time ensures the time value is greater than or equal to time.Now.UTC(). + + Usage: gte + +Example #3 (time.Duration) + +For time.Duration, gte will ensure that the value is greater than or equal to +the duration given in the parameter. + + Usage: gte=1h30m + +Less Than + +For numbers, this will ensure that the value is less than the parameter given. +For strings, it checks that the string length is less than that number of +characters. For slices, arrays, and maps it validates the number of items. + +Example #1 + + Usage: lt=10 + +Example #2 (time.Time) + +For time.Time ensures the time value is less than time.Now.UTC(). + + Usage: lt + +Example #3 (time.Duration) + +For time.Duration, lt will ensure that the value is less than the duration given +in the parameter. + + Usage: lt=1h30m + +Less Than or Equal + +Same as 'max' above. Kept both to make terminology with 'len' easier. + +Example #1 + + Usage: lte=10 + +Example #2 (time.Time) + +For time.Time ensures the time value is less than or equal to time.Now.UTC(). + + Usage: lte + +Example #3 (time.Duration) + +For time.Duration, lte will ensure that the value is less than or equal to the +duration given in the parameter. + + Usage: lte=1h30m + +Field Equals Another Field + +This will validate the field value against another fields value either within +a struct or passed in field. + +Example #1: + + // Validation on Password field using: + Usage: eqfield=ConfirmPassword + +Example #2: + + // Validating by field: + validate.VarWithValue(password, confirmpassword, "eqfield") + +Field Equals Another Field (relative) + +This does the same as eqfield except that it validates the field provided relative +to the top level struct. + + Usage: eqcsfield=InnerStructField.Field) + +Field Does Not Equal Another Field + +This will validate the field value against another fields value either within +a struct or passed in field. + +Examples: + + // Confirm two colors are not the same: + // + // Validation on Color field: + Usage: nefield=Color2 + + // Validating by field: + validate.VarWithValue(color1, color2, "nefield") + +Field Does Not Equal Another Field (relative) + +This does the same as nefield except that it validates the field provided +relative to the top level struct. + + Usage: necsfield=InnerStructField.Field + +Field Greater Than Another Field + +Only valid for Numbers, time.Duration and time.Time types, this will validate +the field value against another fields value either within a struct or passed in +field. usage examples are for validation of a Start and End date: + +Example #1: + + // Validation on End field using: + validate.Struct Usage(gtfield=Start) + +Example #2: + + // Validating by field: + validate.VarWithValue(start, end, "gtfield") + +Field Greater Than Another Relative Field + +This does the same as gtfield except that it validates the field provided +relative to the top level struct. + + Usage: gtcsfield=InnerStructField.Field + +Field Greater Than or Equal To Another Field + +Only valid for Numbers, time.Duration and time.Time types, this will validate +the field value against another fields value either within a struct or passed in +field. usage examples are for validation of a Start and End date: + +Example #1: + + // Validation on End field using: + validate.Struct Usage(gtefield=Start) + +Example #2: + + // Validating by field: + validate.VarWithValue(start, end, "gtefield") + +Field Greater Than or Equal To Another Relative Field + +This does the same as gtefield except that it validates the field provided relative +to the top level struct. + + Usage: gtecsfield=InnerStructField.Field + +Less Than Another Field + +Only valid for Numbers, time.Duration and time.Time types, this will validate +the field value against another fields value either within a struct or passed in +field. usage examples are for validation of a Start and End date: + +Example #1: + + // Validation on End field using: + validate.Struct Usage(ltfield=Start) + +Example #2: + + // Validating by field: + validate.VarWithValue(start, end, "ltfield") + +Less Than Another Relative Field + +This does the same as ltfield except that it validates the field provided relative +to the top level struct. + + Usage: ltcsfield=InnerStructField.Field + +Less Than or Equal To Another Field + +Only valid for Numbers, time.Duration and time.Time types, this will validate +the field value against another fields value either within a struct or passed in +field. usage examples are for validation of a Start and End date: + +Example #1: + + // Validation on End field using: + validate.Struct Usage(ltefield=Start) + +Example #2: + + // Validating by field: + validate.VarWithValue(start, end, "ltefield") + +Less Than or Equal To Another Relative Field + +This does the same as ltefield except that it validates the field provided relative +to the top level struct. + + Usage: ltecsfield=InnerStructField.Field + +Field Contains Another Field + +This does the same as contains except for struct fields. It should only be used +with string types. See the behavior of reflect.Value.String() for behavior on +other types. + + Usage: containsfield=InnerStructField.Field + +Field Excludes Another Field + +This does the same as excludes except for struct fields. It should only be used +with string types. See the behavior of reflect.Value.String() for behavior on +other types. + + Usage: excludesfield=InnerStructField.Field + +Unique + +For arrays & slices, unique will ensure that there are no duplicates. +For maps, unique will ensure that there are no duplicate values. +For slices of struct, unique will ensure that there are no duplicate values +in a field of the struct specified via a parameter. + + // For arrays, slices, and maps: + Usage: unique + + // For slices of struct: + Usage: unique=field + +Alpha Only + +This validates that a string value contains ASCII alpha characters only + + Usage: alpha + +Alphanumeric + +This validates that a string value contains ASCII alphanumeric characters only + + Usage: alphanum + +Alpha Unicode + +This validates that a string value contains unicode alpha characters only + + Usage: alphaunicode + +Alphanumeric Unicode + +This validates that a string value contains unicode alphanumeric characters only + + Usage: alphanumunicode + +Boolean + +This validates that a string value can successfully be parsed into a boolean with strconv.ParseBool + + Usage: boolean + +Number + +This validates that a string value contains number values only. +For integers or float it returns true. + + Usage: number + +Numeric + +This validates that a string value contains a basic numeric value. +basic excludes exponents etc... +for integers or float it returns true. + + Usage: numeric + +Hexadecimal String + +This validates that a string value contains a valid hexadecimal. + + Usage: hexadecimal + +Hexcolor String + +This validates that a string value contains a valid hex color including +hashtag (#) + + Usage: hexcolor + +Lowercase String + +This validates that a string value contains only lowercase characters. An empty string is not a valid lowercase string. + + Usage: lowercase + +Uppercase String + +This validates that a string value contains only uppercase characters. An empty string is not a valid uppercase string. + + Usage: uppercase + +RGB String + +This validates that a string value contains a valid rgb color + + Usage: rgb + +RGBA String + +This validates that a string value contains a valid rgba color + + Usage: rgba + +HSL String + +This validates that a string value contains a valid hsl color + + Usage: hsl + +HSLA String + +This validates that a string value contains a valid hsla color + + Usage: hsla + +E.164 Phone Number String + +This validates that a string value contains a valid E.164 Phone number +https://en.wikipedia.org/wiki/E.164 (ex. +1123456789) + + Usage: e164 + +E-mail String + +This validates that a string value contains a valid email +This may not conform to all possibilities of any rfc standard, but neither +does any email provider accept all possibilities. + + Usage: email + +JSON String + +This validates that a string value is valid JSON + + Usage: json + +JWT String + +This validates that a string value is a valid JWT + + Usage: jwt + +File path + +This validates that a string value contains a valid file path and that +the file exists on the machine. +This is done using os.Stat, which is a platform independent function. + + Usage: file + +URL String + +This validates that a string value contains a valid url +This will accept any url the golang request uri accepts but must contain +a schema for example http:// or rtmp:// + + Usage: url + +URI String + +This validates that a string value contains a valid uri +This will accept any uri the golang request uri accepts + + Usage: uri + +Urn RFC 2141 String + +This validataes that a string value contains a valid URN +according to the RFC 2141 spec. + + Usage: urn_rfc2141 + +Base64 String + +This validates that a string value contains a valid base64 value. +Although an empty string is valid base64 this will report an empty string +as an error, if you wish to accept an empty string as valid you can use +this with the omitempty tag. + + Usage: base64 + +Base64URL String + +This validates that a string value contains a valid base64 URL safe value +according the the RFC4648 spec. +Although an empty string is a valid base64 URL safe value, this will report +an empty string as an error, if you wish to accept an empty string as valid +you can use this with the omitempty tag. + + Usage: base64url + +Bitcoin Address + +This validates that a string value contains a valid bitcoin address. +The format of the string is checked to ensure it matches one of the three formats +P2PKH, P2SH and performs checksum validation. + + Usage: btc_addr + +Bitcoin Bech32 Address (segwit) + +This validates that a string value contains a valid bitcoin Bech32 address as defined +by bip-0173 (https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki) +Special thanks to Pieter Wuille for providng reference implementations. + + Usage: btc_addr_bech32 + +Ethereum Address + +This validates that a string value contains a valid ethereum address. +The format of the string is checked to ensure it matches the standard Ethereum address format. + + Usage: eth_addr + +Contains + +This validates that a string value contains the substring value. + + Usage: contains=@ + +Contains Any + +This validates that a string value contains any Unicode code points +in the substring value. + + Usage: containsany=!@#? + +Contains Rune + +This validates that a string value contains the supplied rune value. + + Usage: containsrune=@ + +Excludes + +This validates that a string value does not contain the substring value. + + Usage: excludes=@ + +Excludes All + +This validates that a string value does not contain any Unicode code +points in the substring value. + + Usage: excludesall=!@#? + +Excludes Rune + +This validates that a string value does not contain the supplied rune value. + + Usage: excludesrune=@ + +Starts With + +This validates that a string value starts with the supplied string value + + Usage: startswith=hello + +Ends With + +This validates that a string value ends with the supplied string value + + Usage: endswith=goodbye + +Does Not Start With + +This validates that a string value does not start with the supplied string value + + Usage: startsnotwith=hello + +Does Not End With + +This validates that a string value does not end with the supplied string value + + Usage: endsnotwith=goodbye + +International Standard Book Number + +This validates that a string value contains a valid isbn10 or isbn13 value. + + Usage: isbn + +International Standard Book Number 10 + +This validates that a string value contains a valid isbn10 value. + + Usage: isbn10 + +International Standard Book Number 13 + +This validates that a string value contains a valid isbn13 value. + + Usage: isbn13 + +Universally Unique Identifier UUID + +This validates that a string value contains a valid UUID. Uppercase UUID values will not pass - use `uuid_rfc4122` instead. + + Usage: uuid + +Universally Unique Identifier UUID v3 + +This validates that a string value contains a valid version 3 UUID. Uppercase UUID values will not pass - use `uuid3_rfc4122` instead. + + Usage: uuid3 + +Universally Unique Identifier UUID v4 + +This validates that a string value contains a valid version 4 UUID. Uppercase UUID values will not pass - use `uuid4_rfc4122` instead. + + Usage: uuid4 + +Universally Unique Identifier UUID v5 + +This validates that a string value contains a valid version 5 UUID. Uppercase UUID values will not pass - use `uuid5_rfc4122` instead. + + Usage: uuid5 + +Universally Unique Lexicographically Sortable Identifier ULID + +This validates that a string value contains a valid ULID value. + + Usage: ulid + +ASCII + +This validates that a string value contains only ASCII characters. +NOTE: if the string is blank, this validates as true. + + Usage: ascii + +Printable ASCII + +This validates that a string value contains only printable ASCII characters. +NOTE: if the string is blank, this validates as true. + + Usage: printascii + +Multi-Byte Characters + +This validates that a string value contains one or more multibyte characters. +NOTE: if the string is blank, this validates as true. + + Usage: multibyte + +Data URL + +This validates that a string value contains a valid DataURI. +NOTE: this will also validate that the data portion is valid base64 + + Usage: datauri + +Latitude + +This validates that a string value contains a valid latitude. + + Usage: latitude + +Longitude + +This validates that a string value contains a valid longitude. + + Usage: longitude + +Social Security Number SSN + +This validates that a string value contains a valid U.S. Social Security Number. + + Usage: ssn + +Internet Protocol Address IP + +This validates that a string value contains a valid IP Address. + + Usage: ip + +Internet Protocol Address IPv4 + +This validates that a string value contains a valid v4 IP Address. + + Usage: ipv4 + +Internet Protocol Address IPv6 + +This validates that a string value contains a valid v6 IP Address. + + Usage: ipv6 + +Classless Inter-Domain Routing CIDR + +This validates that a string value contains a valid CIDR Address. + + Usage: cidr + +Classless Inter-Domain Routing CIDRv4 + +This validates that a string value contains a valid v4 CIDR Address. + + Usage: cidrv4 + +Classless Inter-Domain Routing CIDRv6 + +This validates that a string value contains a valid v6 CIDR Address. + + Usage: cidrv6 + +Transmission Control Protocol Address TCP + +This validates that a string value contains a valid resolvable TCP Address. + + Usage: tcp_addr + +Transmission Control Protocol Address TCPv4 + +This validates that a string value contains a valid resolvable v4 TCP Address. + + Usage: tcp4_addr + +Transmission Control Protocol Address TCPv6 + +This validates that a string value contains a valid resolvable v6 TCP Address. + + Usage: tcp6_addr + +User Datagram Protocol Address UDP + +This validates that a string value contains a valid resolvable UDP Address. + + Usage: udp_addr + +User Datagram Protocol Address UDPv4 + +This validates that a string value contains a valid resolvable v4 UDP Address. + + Usage: udp4_addr + +User Datagram Protocol Address UDPv6 + +This validates that a string value contains a valid resolvable v6 UDP Address. + + Usage: udp6_addr + +Internet Protocol Address IP + +This validates that a string value contains a valid resolvable IP Address. + + Usage: ip_addr + +Internet Protocol Address IPv4 + +This validates that a string value contains a valid resolvable v4 IP Address. + + Usage: ip4_addr + +Internet Protocol Address IPv6 + +This validates that a string value contains a valid resolvable v6 IP Address. + + Usage: ip6_addr + +Unix domain socket end point Address + +This validates that a string value contains a valid Unix Address. + + Usage: unix_addr + +Media Access Control Address MAC + +This validates that a string value contains a valid MAC Address. + + Usage: mac + +Note: See Go's ParseMAC for accepted formats and types: + + http://golang.org/src/net/mac.go?s=866:918#L29 + +Hostname RFC 952 + +This validates that a string value is a valid Hostname according to RFC 952 https://tools.ietf.org/html/rfc952 + + Usage: hostname + +Hostname RFC 1123 + +This validates that a string value is a valid Hostname according to RFC 1123 https://tools.ietf.org/html/rfc1123 + + Usage: hostname_rfc1123 or if you want to continue to use 'hostname' in your tags, create an alias. + +Full Qualified Domain Name (FQDN) + +This validates that a string value contains a valid FQDN. + + Usage: fqdn + +HTML Tags + +This validates that a string value appears to be an HTML element tag +including those described at https://developer.mozilla.org/en-US/docs/Web/HTML/Element + + Usage: html + +HTML Encoded + +This validates that a string value is a proper character reference in decimal +or hexadecimal format + + Usage: html_encoded + +URL Encoded + +This validates that a string value is percent-encoded (URL encoded) according +to https://tools.ietf.org/html/rfc3986#section-2.1 + + Usage: url_encoded + +Directory + +This validates that a string value contains a valid directory and that +it exists on the machine. +This is done using os.Stat, which is a platform independent function. + + Usage: dir + +HostPort + +This validates that a string value contains a valid DNS hostname and port that +can be used to valiate fields typically passed to sockets and connections. + + Usage: hostname_port + +Datetime + +This validates that a string value is a valid datetime based on the supplied datetime format. +Supplied format must match the official Go time format layout as documented in https://golang.org/pkg/time/ + + Usage: datetime=2006-01-02 + +Iso3166-1 alpha-2 + +This validates that a string value is a valid country code based on iso3166-1 alpha-2 standard. +see: https://www.iso.org/iso-3166-country-codes.html + + Usage: iso3166_1_alpha2 + +Iso3166-1 alpha-3 + +This validates that a string value is a valid country code based on iso3166-1 alpha-3 standard. +see: https://www.iso.org/iso-3166-country-codes.html + + Usage: iso3166_1_alpha3 + +Iso3166-1 alpha-numeric + +This validates that a string value is a valid country code based on iso3166-1 alpha-numeric standard. +see: https://www.iso.org/iso-3166-country-codes.html + + Usage: iso3166_1_alpha3 + +BCP 47 Language Tag + +This validates that a string value is a valid BCP 47 language tag, as parsed by language.Parse. +More information on https://pkg.go.dev/golang.org/x/text/language + + Usage: bcp47_language_tag + +BIC (SWIFT code) + +This validates that a string value is a valid Business Identifier Code (SWIFT code), defined in ISO 9362. +More information on https://www.iso.org/standard/60390.html + + Usage: bic + +RFC 1035 label + +This validates that a string value is a valid dns RFC 1035 label, defined in RFC 1035. +More information on https://datatracker.ietf.org/doc/html/rfc1035 + + Usage: dns_rfc1035_label + +TimeZone + +This validates that a string value is a valid time zone based on the time zone database present on the system. +Although empty value and Local value are allowed by time.LoadLocation golang function, they are not allowed by this validator. +More information on https://golang.org/pkg/time/#LoadLocation + + Usage: timezone + +Semantic Version + +This validates that a string value is a valid semver version, defined in Semantic Versioning 2.0.0. +More information on https://semver.org/ + + Usage: semver + +Alias Validators and Tags + +NOTE: When returning an error, the tag returned in "FieldError" will be +the alias tag unless the dive tag is part of the alias. Everything after the +dive tag is not reported as the alias tag. Also, the "ActualTag" in the before +case will be the actual tag within the alias that failed. + +Here is a list of the current built in alias tags: + + "iscolor" + alias is "hexcolor|rgb|rgba|hsl|hsla" (Usage: iscolor) + "country_code" + alias is "iso3166_1_alpha2|iso3166_1_alpha3|iso3166_1_alpha_numeric" (Usage: country_code) + +Validator notes: + + regex + a regex validator won't be added because commas and = signs can be part + of a regex which conflict with the validation definitions. Although + workarounds can be made, they take away from using pure regex's. + Furthermore it's quick and dirty but the regex's become harder to + maintain and are not reusable, so it's as much a programming philosophy + as anything. + + In place of this new validator functions should be created; a regex can + be used within the validator function and even be precompiled for better + efficiency within regexes.go. + + And the best reason, you can submit a pull request and we can keep on + adding to the validation library of this package! + +Non standard validators + +A collection of validation rules that are frequently needed but are more +complex than the ones found in the baked in validators. +A non standard validator must be registered manually like you would +with your own custom validation functions. + +Example of registration and use: + + type Test struct { + TestField string `validate:"yourtag"` + } + + t := &Test{ + TestField: "Test" + } + + validate := validator.New() + validate.RegisterValidation("yourtag", validators.NotBlank) + +Here is a list of the current non standard validators: + + NotBlank + This validates that the value is not blank or with length zero. + For strings ensures they do not contain only spaces. For channels, maps, slices and arrays + ensures they don't have zero length. For others, a non empty value is required. + + Usage: notblank + +Panics + +This package panics when bad input is provided, this is by design, bad code like +that should not make it to production. + + type Test struct { + TestField string `validate:"nonexistantfunction=1"` + } + + t := &Test{ + TestField: "Test" + } + + validate.Struct(t) // this will panic +*/ +package validator diff --git a/vendor/github.com/go-playground/validator/v10/errors.go b/vendor/github.com/go-playground/validator/v10/errors.go new file mode 100644 index 0000000..9a1b1ab --- /dev/null +++ b/vendor/github.com/go-playground/validator/v10/errors.go @@ -0,0 +1,275 @@ +package validator + +import ( + "bytes" + "fmt" + "reflect" + "strings" + + ut "github.com/go-playground/universal-translator" +) + +const ( + fieldErrMsg = "Key: '%s' Error:Field validation for '%s' failed on the '%s' tag" +) + +// ValidationErrorsTranslations is the translation return type +type ValidationErrorsTranslations map[string]string + +// InvalidValidationError describes an invalid argument passed to +// `Struct`, `StructExcept`, StructPartial` or `Field` +type InvalidValidationError struct { + Type reflect.Type +} + +// Error returns InvalidValidationError message +func (e *InvalidValidationError) Error() string { + + if e.Type == nil { + return "validator: (nil)" + } + + return "validator: (nil " + e.Type.String() + ")" +} + +// ValidationErrors is an array of FieldError's +// for use in custom error messages post validation. +type ValidationErrors []FieldError + +// Error is intended for use in development + debugging and not intended to be a production error message. +// It allows ValidationErrors to subscribe to the Error interface. +// All information to create an error message specific to your application is contained within +// the FieldError found within the ValidationErrors array +func (ve ValidationErrors) Error() string { + + buff := bytes.NewBufferString("") + + var fe *fieldError + + for i := 0; i < len(ve); i++ { + + fe = ve[i].(*fieldError) + buff.WriteString(fe.Error()) + buff.WriteString("\n") + } + + return strings.TrimSpace(buff.String()) +} + +// Translate translates all of the ValidationErrors +func (ve ValidationErrors) Translate(ut ut.Translator) ValidationErrorsTranslations { + + trans := make(ValidationErrorsTranslations) + + var fe *fieldError + + for i := 0; i < len(ve); i++ { + fe = ve[i].(*fieldError) + + // // in case an Anonymous struct was used, ensure that the key + // // would be 'Username' instead of ".Username" + // if len(fe.ns) > 0 && fe.ns[:1] == "." { + // trans[fe.ns[1:]] = fe.Translate(ut) + // continue + // } + + trans[fe.ns] = fe.Translate(ut) + } + + return trans +} + +// FieldError contains all functions to get error details +type FieldError interface { + + // Tag returns the validation tag that failed. if the + // validation was an alias, this will return the + // alias name and not the underlying tag that failed. + // + // eg. alias "iscolor": "hexcolor|rgb|rgba|hsl|hsla" + // will return "iscolor" + Tag() string + + // ActualTag returns the validation tag that failed, even if an + // alias the actual tag within the alias will be returned. + // If an 'or' validation fails the entire or will be returned. + // + // eg. alias "iscolor": "hexcolor|rgb|rgba|hsl|hsla" + // will return "hexcolor|rgb|rgba|hsl|hsla" + ActualTag() string + + // Namespace returns the namespace for the field error, with the tag + // name taking precedence over the field's actual name. + // + // eg. JSON name "User.fname" + // + // See StructNamespace() for a version that returns actual names. + // + // NOTE: this field can be blank when validating a single primitive field + // using validate.Field(...) as there is no way to extract it's name + Namespace() string + + // StructNamespace returns the namespace for the field error, with the field's + // actual name. + // + // eq. "User.FirstName" see Namespace for comparison + // + // NOTE: this field can be blank when validating a single primitive field + // using validate.Field(...) as there is no way to extract its name + StructNamespace() string + + // Field returns the fields name with the tag name taking precedence over the + // field's actual name. + // + // eq. JSON name "fname" + // see StructField for comparison + Field() string + + // StructField returns the field's actual name from the struct, when able to determine. + // + // eq. "FirstName" + // see Field for comparison + StructField() string + + // Value returns the actual field's value in case needed for creating the error + // message + Value() interface{} + + // Param returns the param value, in string form for comparison; this will also + // help with generating an error message + Param() string + + // Kind returns the Field's reflect Kind + // + // eg. time.Time's kind is a struct + Kind() reflect.Kind + + // Type returns the Field's reflect Type + // + // eg. time.Time's type is time.Time + Type() reflect.Type + + // Translate returns the FieldError's translated error + // from the provided 'ut.Translator' and registered 'TranslationFunc' + // + // NOTE: if no registered translator can be found it returns the same as + // calling fe.Error() + Translate(ut ut.Translator) string + + // Error returns the FieldError's message + Error() string +} + +// compile time interface checks +var _ FieldError = new(fieldError) +var _ error = new(fieldError) + +// fieldError contains a single field's validation error along +// with other properties that may be needed for error message creation +// it complies with the FieldError interface +type fieldError struct { + v *Validate + tag string + actualTag string + ns string + structNs string + fieldLen uint8 + structfieldLen uint8 + value interface{} + param string + kind reflect.Kind + typ reflect.Type +} + +// Tag returns the validation tag that failed. +func (fe *fieldError) Tag() string { + return fe.tag +} + +// ActualTag returns the validation tag that failed, even if an +// alias the actual tag within the alias will be returned. +func (fe *fieldError) ActualTag() string { + return fe.actualTag +} + +// Namespace returns the namespace for the field error, with the tag +// name taking precedence over the field's actual name. +func (fe *fieldError) Namespace() string { + return fe.ns +} + +// StructNamespace returns the namespace for the field error, with the field's +// actual name. +func (fe *fieldError) StructNamespace() string { + return fe.structNs +} + +// Field returns the field's name with the tag name taking precedence over the +// field's actual name. +func (fe *fieldError) Field() string { + + return fe.ns[len(fe.ns)-int(fe.fieldLen):] + // // return fe.field + // fld := fe.ns[len(fe.ns)-int(fe.fieldLen):] + + // log.Println("FLD:", fld) + + // if len(fld) > 0 && fld[:1] == "." { + // return fld[1:] + // } + + // return fld +} + +// StructField returns the field's actual name from the struct, when able to determine. +func (fe *fieldError) StructField() string { + // return fe.structField + return fe.structNs[len(fe.structNs)-int(fe.structfieldLen):] +} + +// Value returns the actual field's value in case needed for creating the error +// message +func (fe *fieldError) Value() interface{} { + return fe.value +} + +// Param returns the param value, in string form for comparison; this will +// also help with generating an error message +func (fe *fieldError) Param() string { + return fe.param +} + +// Kind returns the Field's reflect Kind +func (fe *fieldError) Kind() reflect.Kind { + return fe.kind +} + +// Type returns the Field's reflect Type +func (fe *fieldError) Type() reflect.Type { + return fe.typ +} + +// Error returns the fieldError's error message +func (fe *fieldError) Error() string { + return fmt.Sprintf(fieldErrMsg, fe.ns, fe.Field(), fe.tag) +} + +// Translate returns the FieldError's translated error +// from the provided 'ut.Translator' and registered 'TranslationFunc' +// +// NOTE: if no registered translation can be found, it returns the original +// untranslated error message. +func (fe *fieldError) Translate(ut ut.Translator) string { + + m, ok := fe.v.transTagFunc[ut] + if !ok { + return fe.Error() + } + + fn, ok := m[fe.tag] + if !ok { + return fe.Error() + } + + return fn(ut, fe) +} diff --git a/vendor/github.com/go-playground/validator/v10/field_level.go b/vendor/github.com/go-playground/validator/v10/field_level.go new file mode 100644 index 0000000..ef35826 --- /dev/null +++ b/vendor/github.com/go-playground/validator/v10/field_level.go @@ -0,0 +1,120 @@ +package validator + +import "reflect" + +// FieldLevel contains all the information and helper functions +// to validate a field +type FieldLevel interface { + + // Top returns the top level struct, if any + Top() reflect.Value + + // Parent returns the current fields parent struct, if any or + // the comparison value if called 'VarWithValue' + Parent() reflect.Value + + // Field returns current field for validation + Field() reflect.Value + + // FieldName returns the field's name with the tag + // name taking precedence over the fields actual name. + FieldName() string + + // StructFieldName returns the struct field's name + StructFieldName() string + + // Param returns param for validation against current field + Param() string + + // GetTag returns the current validations tag name + GetTag() string + + // ExtractType gets the actual underlying type of field value. + // It will dive into pointers, customTypes and return you the + // underlying value and it's kind. + ExtractType(field reflect.Value) (value reflect.Value, kind reflect.Kind, nullable bool) + + // GetStructFieldOK traverses the parent struct to retrieve a specific field denoted by the provided namespace + // in the param and returns the field, field kind and whether is was successful in retrieving + // the field at all. + // + // NOTE: when not successful ok will be false, this can happen when a nested struct is nil and so the field + // could not be retrieved because it didn't exist. + // + // Deprecated: Use GetStructFieldOK2() instead which also return if the value is nullable. + GetStructFieldOK() (reflect.Value, reflect.Kind, bool) + + // GetStructFieldOKAdvanced is the same as GetStructFieldOK except that it accepts the parent struct to start looking for + // the field and namespace allowing more extensibility for validators. + // + // Deprecated: Use GetStructFieldOKAdvanced2() instead which also return if the value is nullable. + GetStructFieldOKAdvanced(val reflect.Value, namespace string) (reflect.Value, reflect.Kind, bool) + + // GetStructFieldOK2 traverses the parent struct to retrieve a specific field denoted by the provided namespace + // in the param and returns the field, field kind, if it's a nullable type and whether is was successful in retrieving + // the field at all. + // + // NOTE: when not successful ok will be false, this can happen when a nested struct is nil and so the field + // could not be retrieved because it didn't exist. + GetStructFieldOK2() (reflect.Value, reflect.Kind, bool, bool) + + // GetStructFieldOKAdvanced2 is the same as GetStructFieldOK except that it accepts the parent struct to start looking for + // the field and namespace allowing more extensibility for validators. + GetStructFieldOKAdvanced2(val reflect.Value, namespace string) (reflect.Value, reflect.Kind, bool, bool) +} + +var _ FieldLevel = new(validate) + +// Field returns current field for validation +func (v *validate) Field() reflect.Value { + return v.flField +} + +// FieldName returns the field's name with the tag +// name taking precedence over the fields actual name. +func (v *validate) FieldName() string { + return v.cf.altName +} + +// GetTag returns the current validations tag name +func (v *validate) GetTag() string { + return v.ct.tag +} + +// StructFieldName returns the struct field's name +func (v *validate) StructFieldName() string { + return v.cf.name +} + +// Param returns param for validation against current field +func (v *validate) Param() string { + return v.ct.param +} + +// GetStructFieldOK returns Param returns param for validation against current field +// +// Deprecated: Use GetStructFieldOK2() instead which also return if the value is nullable. +func (v *validate) GetStructFieldOK() (reflect.Value, reflect.Kind, bool) { + current, kind, _, found := v.getStructFieldOKInternal(v.slflParent, v.ct.param) + return current, kind, found +} + +// GetStructFieldOKAdvanced is the same as GetStructFieldOK except that it accepts the parent struct to start looking for +// the field and namespace allowing more extensibility for validators. +// +// Deprecated: Use GetStructFieldOKAdvanced2() instead which also return if the value is nullable. +func (v *validate) GetStructFieldOKAdvanced(val reflect.Value, namespace string) (reflect.Value, reflect.Kind, bool) { + current, kind, _, found := v.GetStructFieldOKAdvanced2(val, namespace) + return current, kind, found +} + +// GetStructFieldOK2 returns Param returns param for validation against current field +func (v *validate) GetStructFieldOK2() (reflect.Value, reflect.Kind, bool, bool) { + return v.getStructFieldOKInternal(v.slflParent, v.ct.param) +} + +// GetStructFieldOKAdvanced2 is the same as GetStructFieldOK except that it accepts the parent struct to start looking for +// the field and namespace allowing more extensibility for validators. +func (v *validate) GetStructFieldOKAdvanced2(val reflect.Value, namespace string) (reflect.Value, reflect.Kind, bool, bool) { + return v.getStructFieldOKInternal(val, namespace) +} diff --git a/vendor/github.com/go-playground/validator/v10/go.mod b/vendor/github.com/go-playground/validator/v10/go.mod new file mode 100644 index 0000000..e281ec0 --- /dev/null +++ b/vendor/github.com/go-playground/validator/v10/go.mod @@ -0,0 +1,19 @@ +module github.com/go-playground/validator/v10 + +go 1.13 + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/go-playground/assert/v2 v2.0.1 + github.com/go-playground/locales v0.14.0 + github.com/go-playground/universal-translator v0.18.0 + github.com/kr/pretty v0.3.0 // indirect + github.com/leodido/go-urn v1.2.1 + github.com/rogpeppe/go-internal v1.8.0 // indirect + github.com/stretchr/testify v1.7.0 // indirect + golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 + golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 // indirect + golang.org/x/text v0.3.7 + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect +) diff --git a/vendor/github.com/go-playground/validator/v10/go.sum b/vendor/github.com/go-playground/validator/v10/go.sum new file mode 100644 index 0000000..a1c43c3 --- /dev/null +++ b/vendor/github.com/go-playground/validator/v10/go.sum @@ -0,0 +1,52 @@ +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= +github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= +github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= +github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= +github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= +github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M= +golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 h1:siQdpVirKtzPhKl3lZWozZraCFObP8S1v6PRp0bLrtU= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/vendor/github.com/go-playground/validator/v10/logo.png b/vendor/github.com/go-playground/validator/v10/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..355000f5247d50e979cf5db5de38188ef4649a34 GIT binary patch literal 13443 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 V^Rh-@K?jDw` + jWTRegexString = "^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$" + splitParamsRegexString = `'[^']*'|\S+` + bicRegexString = `^[A-Za-z]{6}[A-Za-z0-9]{2}([A-Za-z0-9]{3})?$` + semverRegexString = `^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$` // numbered capture groups https://semver.org/ + dnsRegexStringRFC1035Label = "^[a-z]([-a-z0-9]*[a-z0-9]){0,62}$" +) + +var ( + alphaRegex = regexp.MustCompile(alphaRegexString) + alphaNumericRegex = regexp.MustCompile(alphaNumericRegexString) + alphaUnicodeRegex = regexp.MustCompile(alphaUnicodeRegexString) + alphaUnicodeNumericRegex = regexp.MustCompile(alphaUnicodeNumericRegexString) + numericRegex = regexp.MustCompile(numericRegexString) + numberRegex = regexp.MustCompile(numberRegexString) + hexadecimalRegex = regexp.MustCompile(hexadecimalRegexString) + hexColorRegex = regexp.MustCompile(hexColorRegexString) + rgbRegex = regexp.MustCompile(rgbRegexString) + rgbaRegex = regexp.MustCompile(rgbaRegexString) + hslRegex = regexp.MustCompile(hslRegexString) + hslaRegex = regexp.MustCompile(hslaRegexString) + e164Regex = regexp.MustCompile(e164RegexString) + emailRegex = regexp.MustCompile(emailRegexString) + base64Regex = regexp.MustCompile(base64RegexString) + base64URLRegex = regexp.MustCompile(base64URLRegexString) + iSBN10Regex = regexp.MustCompile(iSBN10RegexString) + iSBN13Regex = regexp.MustCompile(iSBN13RegexString) + uUID3Regex = regexp.MustCompile(uUID3RegexString) + uUID4Regex = regexp.MustCompile(uUID4RegexString) + uUID5Regex = regexp.MustCompile(uUID5RegexString) + uUIDRegex = regexp.MustCompile(uUIDRegexString) + uUID3RFC4122Regex = regexp.MustCompile(uUID3RFC4122RegexString) + uUID4RFC4122Regex = regexp.MustCompile(uUID4RFC4122RegexString) + uUID5RFC4122Regex = regexp.MustCompile(uUID5RFC4122RegexString) + uUIDRFC4122Regex = regexp.MustCompile(uUIDRFC4122RegexString) + uLIDRegex = regexp.MustCompile(uLIDRegexString) + aSCIIRegex = regexp.MustCompile(aSCIIRegexString) + printableASCIIRegex = regexp.MustCompile(printableASCIIRegexString) + multibyteRegex = regexp.MustCompile(multibyteRegexString) + dataURIRegex = regexp.MustCompile(dataURIRegexString) + latitudeRegex = regexp.MustCompile(latitudeRegexString) + longitudeRegex = regexp.MustCompile(longitudeRegexString) + sSNRegex = regexp.MustCompile(sSNRegexString) + hostnameRegexRFC952 = regexp.MustCompile(hostnameRegexStringRFC952) + hostnameRegexRFC1123 = regexp.MustCompile(hostnameRegexStringRFC1123) + fqdnRegexRFC1123 = regexp.MustCompile(fqdnRegexStringRFC1123) + btcAddressRegex = regexp.MustCompile(btcAddressRegexString) + btcUpperAddressRegexBech32 = regexp.MustCompile(btcAddressUpperRegexStringBech32) + btcLowerAddressRegexBech32 = regexp.MustCompile(btcAddressLowerRegexStringBech32) + ethAddressRegex = regexp.MustCompile(ethAddressRegexString) + ethAddressRegexUpper = regexp.MustCompile(ethAddressUpperRegexString) + ethAddressRegexLower = regexp.MustCompile(ethAddressLowerRegexString) + uRLEncodedRegex = regexp.MustCompile(uRLEncodedRegexString) + hTMLEncodedRegex = regexp.MustCompile(hTMLEncodedRegexString) + hTMLRegex = regexp.MustCompile(hTMLRegexString) + jWTRegex = regexp.MustCompile(jWTRegexString) + splitParamsRegex = regexp.MustCompile(splitParamsRegexString) + bicRegex = regexp.MustCompile(bicRegexString) + semverRegex = regexp.MustCompile(semverRegexString) + dnsRegexRFC1035Label = regexp.MustCompile(dnsRegexStringRFC1035Label) +) diff --git a/vendor/github.com/go-playground/validator/v10/struct_level.go b/vendor/github.com/go-playground/validator/v10/struct_level.go new file mode 100644 index 0000000..c0d89cf --- /dev/null +++ b/vendor/github.com/go-playground/validator/v10/struct_level.go @@ -0,0 +1,175 @@ +package validator + +import ( + "context" + "reflect" +) + +// StructLevelFunc accepts all values needed for struct level validation +type StructLevelFunc func(sl StructLevel) + +// StructLevelFuncCtx accepts all values needed for struct level validation +// but also allows passing of contextual validation information via context.Context. +type StructLevelFuncCtx func(ctx context.Context, sl StructLevel) + +// wrapStructLevelFunc wraps normal StructLevelFunc makes it compatible with StructLevelFuncCtx +func wrapStructLevelFunc(fn StructLevelFunc) StructLevelFuncCtx { + return func(ctx context.Context, sl StructLevel) { + fn(sl) + } +} + +// StructLevel contains all the information and helper functions +// to validate a struct +type StructLevel interface { + + // Validator returns the main validation object, in case one wants to call validations internally. + // this is so you don't have to use anonymous functions to get access to the validate + // instance. + Validator() *Validate + + // Top returns the top level struct, if any + Top() reflect.Value + + // Parent returns the current fields parent struct, if any + Parent() reflect.Value + + // Current returns the current struct. + Current() reflect.Value + + // ExtractType gets the actual underlying type of field value. + // It will dive into pointers, customTypes and return you the + // underlying value and its kind. + ExtractType(field reflect.Value) (value reflect.Value, kind reflect.Kind, nullable bool) + + // ReportError reports an error just by passing the field and tag information + // + // NOTES: + // + // fieldName and altName get appended to the existing namespace that + // validator is on. e.g. pass 'FirstName' or 'Names[0]' depending + // on the nesting + // + // tag can be an existing validation tag or just something you make up + // and process on the flip side it's up to you. + ReportError(field interface{}, fieldName, structFieldName string, tag, param string) + + // ReportValidationErrors reports an error just by passing ValidationErrors + // + // NOTES: + // + // relativeNamespace and relativeActualNamespace get appended to the + // existing namespace that validator is on. + // e.g. pass 'User.FirstName' or 'Users[0].FirstName' depending + // on the nesting. most of the time they will be blank, unless you validate + // at a level lower the the current field depth + ReportValidationErrors(relativeNamespace, relativeActualNamespace string, errs ValidationErrors) +} + +var _ StructLevel = new(validate) + +// Top returns the top level struct +// +// NOTE: this can be the same as the current struct being validated +// if not is a nested struct. +// +// this is only called when within Struct and Field Level validation and +// should not be relied upon for an acurate value otherwise. +func (v *validate) Top() reflect.Value { + return v.top +} + +// Parent returns the current structs parent +// +// NOTE: this can be the same as the current struct being validated +// if not is a nested struct. +// +// this is only called when within Struct and Field Level validation and +// should not be relied upon for an acurate value otherwise. +func (v *validate) Parent() reflect.Value { + return v.slflParent +} + +// Current returns the current struct. +func (v *validate) Current() reflect.Value { + return v.slCurrent +} + +// Validator returns the main validation object, in case one want to call validations internally. +func (v *validate) Validator() *Validate { + return v.v +} + +// ExtractType gets the actual underlying type of field value. +func (v *validate) ExtractType(field reflect.Value) (reflect.Value, reflect.Kind, bool) { + return v.extractTypeInternal(field, false) +} + +// ReportError reports an error just by passing the field and tag information +func (v *validate) ReportError(field interface{}, fieldName, structFieldName, tag, param string) { + + fv, kind, _ := v.extractTypeInternal(reflect.ValueOf(field), false) + + if len(structFieldName) == 0 { + structFieldName = fieldName + } + + v.str1 = string(append(v.ns, fieldName...)) + + if v.v.hasTagNameFunc || fieldName != structFieldName { + v.str2 = string(append(v.actualNs, structFieldName...)) + } else { + v.str2 = v.str1 + } + + if kind == reflect.Invalid { + + v.errs = append(v.errs, + &fieldError{ + v: v.v, + tag: tag, + actualTag: tag, + ns: v.str1, + structNs: v.str2, + fieldLen: uint8(len(fieldName)), + structfieldLen: uint8(len(structFieldName)), + param: param, + kind: kind, + }, + ) + return + } + + v.errs = append(v.errs, + &fieldError{ + v: v.v, + tag: tag, + actualTag: tag, + ns: v.str1, + structNs: v.str2, + fieldLen: uint8(len(fieldName)), + structfieldLen: uint8(len(structFieldName)), + value: fv.Interface(), + param: param, + kind: kind, + typ: fv.Type(), + }, + ) +} + +// ReportValidationErrors reports ValidationErrors obtained from running validations within the Struct Level validation. +// +// NOTE: this function prepends the current namespace to the relative ones. +func (v *validate) ReportValidationErrors(relativeNamespace, relativeStructNamespace string, errs ValidationErrors) { + + var err *fieldError + + for i := 0; i < len(errs); i++ { + + err = errs[i].(*fieldError) + err.ns = string(append(append(v.ns, relativeNamespace...), err.ns...)) + err.structNs = string(append(append(v.actualNs, relativeStructNamespace...), err.structNs...)) + + v.errs = append(v.errs, err) + } +} diff --git a/vendor/github.com/go-playground/validator/v10/translations.go b/vendor/github.com/go-playground/validator/v10/translations.go new file mode 100644 index 0000000..4d9d75c --- /dev/null +++ b/vendor/github.com/go-playground/validator/v10/translations.go @@ -0,0 +1,11 @@ +package validator + +import ut "github.com/go-playground/universal-translator" + +// TranslationFunc is the function type used to register or override +// custom translations +type TranslationFunc func(ut ut.Translator, fe FieldError) string + +// RegisterTranslationsFunc allows for registering of translations +// for a 'ut.Translator' for use within the 'TranslationFunc' +type RegisterTranslationsFunc func(ut ut.Translator) error diff --git a/vendor/github.com/go-playground/validator/v10/util.go b/vendor/github.com/go-playground/validator/v10/util.go new file mode 100644 index 0000000..56420f4 --- /dev/null +++ b/vendor/github.com/go-playground/validator/v10/util.go @@ -0,0 +1,288 @@ +package validator + +import ( + "reflect" + "strconv" + "strings" + "time" +) + +// extractTypeInternal gets the actual underlying type of field value. +// It will dive into pointers, customTypes and return you the +// underlying value and it's kind. +func (v *validate) extractTypeInternal(current reflect.Value, nullable bool) (reflect.Value, reflect.Kind, bool) { + +BEGIN: + switch current.Kind() { + case reflect.Ptr: + + nullable = true + + if current.IsNil() { + return current, reflect.Ptr, nullable + } + + current = current.Elem() + goto BEGIN + + case reflect.Interface: + + nullable = true + + if current.IsNil() { + return current, reflect.Interface, nullable + } + + current = current.Elem() + goto BEGIN + + case reflect.Invalid: + return current, reflect.Invalid, nullable + + default: + + if v.v.hasCustomFuncs { + + if fn, ok := v.v.customFuncs[current.Type()]; ok { + current = reflect.ValueOf(fn(current)) + goto BEGIN + } + } + + return current, current.Kind(), nullable + } +} + +// getStructFieldOKInternal traverses a struct to retrieve a specific field denoted by the provided namespace and +// returns the field, field kind and whether is was successful in retrieving the field at all. +// +// NOTE: when not successful ok will be false, this can happen when a nested struct is nil and so the field +// could not be retrieved because it didn't exist. +func (v *validate) getStructFieldOKInternal(val reflect.Value, namespace string) (current reflect.Value, kind reflect.Kind, nullable bool, found bool) { + +BEGIN: + current, kind, nullable = v.ExtractType(val) + if kind == reflect.Invalid { + return + } + + if namespace == "" { + found = true + return + } + + switch kind { + + case reflect.Ptr, reflect.Interface: + return + + case reflect.Struct: + + typ := current.Type() + fld := namespace + var ns string + + if typ != timeType { + + idx := strings.Index(namespace, namespaceSeparator) + + if idx != -1 { + fld = namespace[:idx] + ns = namespace[idx+1:] + } else { + ns = "" + } + + bracketIdx := strings.Index(fld, leftBracket) + if bracketIdx != -1 { + fld = fld[:bracketIdx] + + ns = namespace[bracketIdx:] + } + + val = current.FieldByName(fld) + namespace = ns + goto BEGIN + } + + case reflect.Array, reflect.Slice: + idx := strings.Index(namespace, leftBracket) + idx2 := strings.Index(namespace, rightBracket) + + arrIdx, _ := strconv.Atoi(namespace[idx+1 : idx2]) + + if arrIdx >= current.Len() { + return + } + + startIdx := idx2 + 1 + + if startIdx < len(namespace) { + if namespace[startIdx:startIdx+1] == namespaceSeparator { + startIdx++ + } + } + + val = current.Index(arrIdx) + namespace = namespace[startIdx:] + goto BEGIN + + case reflect.Map: + idx := strings.Index(namespace, leftBracket) + 1 + idx2 := strings.Index(namespace, rightBracket) + + endIdx := idx2 + + if endIdx+1 < len(namespace) { + if namespace[endIdx+1:endIdx+2] == namespaceSeparator { + endIdx++ + } + } + + key := namespace[idx:idx2] + + switch current.Type().Key().Kind() { + case reflect.Int: + i, _ := strconv.Atoi(key) + val = current.MapIndex(reflect.ValueOf(i)) + namespace = namespace[endIdx+1:] + + case reflect.Int8: + i, _ := strconv.ParseInt(key, 10, 8) + val = current.MapIndex(reflect.ValueOf(int8(i))) + namespace = namespace[endIdx+1:] + + case reflect.Int16: + i, _ := strconv.ParseInt(key, 10, 16) + val = current.MapIndex(reflect.ValueOf(int16(i))) + namespace = namespace[endIdx+1:] + + case reflect.Int32: + i, _ := strconv.ParseInt(key, 10, 32) + val = current.MapIndex(reflect.ValueOf(int32(i))) + namespace = namespace[endIdx+1:] + + case reflect.Int64: + i, _ := strconv.ParseInt(key, 10, 64) + val = current.MapIndex(reflect.ValueOf(i)) + namespace = namespace[endIdx+1:] + + case reflect.Uint: + i, _ := strconv.ParseUint(key, 10, 0) + val = current.MapIndex(reflect.ValueOf(uint(i))) + namespace = namespace[endIdx+1:] + + case reflect.Uint8: + i, _ := strconv.ParseUint(key, 10, 8) + val = current.MapIndex(reflect.ValueOf(uint8(i))) + namespace = namespace[endIdx+1:] + + case reflect.Uint16: + i, _ := strconv.ParseUint(key, 10, 16) + val = current.MapIndex(reflect.ValueOf(uint16(i))) + namespace = namespace[endIdx+1:] + + case reflect.Uint32: + i, _ := strconv.ParseUint(key, 10, 32) + val = current.MapIndex(reflect.ValueOf(uint32(i))) + namespace = namespace[endIdx+1:] + + case reflect.Uint64: + i, _ := strconv.ParseUint(key, 10, 64) + val = current.MapIndex(reflect.ValueOf(i)) + namespace = namespace[endIdx+1:] + + case reflect.Float32: + f, _ := strconv.ParseFloat(key, 32) + val = current.MapIndex(reflect.ValueOf(float32(f))) + namespace = namespace[endIdx+1:] + + case reflect.Float64: + f, _ := strconv.ParseFloat(key, 64) + val = current.MapIndex(reflect.ValueOf(f)) + namespace = namespace[endIdx+1:] + + case reflect.Bool: + b, _ := strconv.ParseBool(key) + val = current.MapIndex(reflect.ValueOf(b)) + namespace = namespace[endIdx+1:] + + // reflect.Type = string + default: + val = current.MapIndex(reflect.ValueOf(key)) + namespace = namespace[endIdx+1:] + } + + goto BEGIN + } + + // if got here there was more namespace, cannot go any deeper + panic("Invalid field namespace") +} + +// asInt returns the parameter as a int64 +// or panics if it can't convert +func asInt(param string) int64 { + i, err := strconv.ParseInt(param, 0, 64) + panicIf(err) + + return i +} + +// asIntFromTimeDuration parses param as time.Duration and returns it as int64 +// or panics on error. +func asIntFromTimeDuration(param string) int64 { + d, err := time.ParseDuration(param) + if err != nil { + // attempt parsing as an an integer assuming nanosecond precision + return asInt(param) + } + return int64(d) +} + +// asIntFromType calls the proper function to parse param as int64, +// given a field's Type t. +func asIntFromType(t reflect.Type, param string) int64 { + switch t { + case timeDurationType: + return asIntFromTimeDuration(param) + default: + return asInt(param) + } +} + +// asUint returns the parameter as a uint64 +// or panics if it can't convert +func asUint(param string) uint64 { + + i, err := strconv.ParseUint(param, 0, 64) + panicIf(err) + + return i +} + +// asFloat returns the parameter as a float64 +// or panics if it can't convert +func asFloat(param string) float64 { + + i, err := strconv.ParseFloat(param, 64) + panicIf(err) + + return i +} + +// asBool returns the parameter as a bool +// or panics if it can't convert +func asBool(param string) bool { + + i, err := strconv.ParseBool(param) + panicIf(err) + + return i +} + +func panicIf(err error) { + if err != nil { + panic(err.Error()) + } +} diff --git a/vendor/github.com/go-playground/validator/v10/validator.go b/vendor/github.com/go-playground/validator/v10/validator.go new file mode 100644 index 0000000..2a4fad0 --- /dev/null +++ b/vendor/github.com/go-playground/validator/v10/validator.go @@ -0,0 +1,477 @@ +package validator + +import ( + "context" + "fmt" + "reflect" + "strconv" +) + +// per validate construct +type validate struct { + v *Validate + top reflect.Value + ns []byte + actualNs []byte + errs ValidationErrors + includeExclude map[string]struct{} // reset only if StructPartial or StructExcept are called, no need otherwise + ffn FilterFunc + slflParent reflect.Value // StructLevel & FieldLevel + slCurrent reflect.Value // StructLevel & FieldLevel + flField reflect.Value // StructLevel & FieldLevel + cf *cField // StructLevel & FieldLevel + ct *cTag // StructLevel & FieldLevel + misc []byte // misc reusable + str1 string // misc reusable + str2 string // misc reusable + fldIsPointer bool // StructLevel & FieldLevel + isPartial bool + hasExcludes bool +} + +// parent and current will be the same the first run of validateStruct +func (v *validate) validateStruct(ctx context.Context, parent reflect.Value, current reflect.Value, typ reflect.Type, ns []byte, structNs []byte, ct *cTag) { + + cs, ok := v.v.structCache.Get(typ) + if !ok { + cs = v.v.extractStructCache(current, typ.Name()) + } + + if len(ns) == 0 && len(cs.name) != 0 { + + ns = append(ns, cs.name...) + ns = append(ns, '.') + + structNs = append(structNs, cs.name...) + structNs = append(structNs, '.') + } + + // ct is nil on top level struct, and structs as fields that have no tag info + // so if nil or if not nil and the structonly tag isn't present + if ct == nil || ct.typeof != typeStructOnly { + + var f *cField + + for i := 0; i < len(cs.fields); i++ { + + f = cs.fields[i] + + if v.isPartial { + + if v.ffn != nil { + // used with StructFiltered + if v.ffn(append(structNs, f.name...)) { + continue + } + + } else { + // used with StructPartial & StructExcept + _, ok = v.includeExclude[string(append(structNs, f.name...))] + + if (ok && v.hasExcludes) || (!ok && !v.hasExcludes) { + continue + } + } + } + + v.traverseField(ctx, current, current.Field(f.idx), ns, structNs, f, f.cTags) + } + } + + // check if any struct level validations, after all field validations already checked. + // first iteration will have no info about nostructlevel tag, and is checked prior to + // calling the next iteration of validateStruct called from traverseField. + if cs.fn != nil { + + v.slflParent = parent + v.slCurrent = current + v.ns = ns + v.actualNs = structNs + + cs.fn(ctx, v) + } +} + +// traverseField validates any field, be it a struct or single field, ensures it's validity and passes it along to be validated via it's tag options +func (v *validate) traverseField(ctx context.Context, parent reflect.Value, current reflect.Value, ns []byte, structNs []byte, cf *cField, ct *cTag) { + var typ reflect.Type + var kind reflect.Kind + + current, kind, v.fldIsPointer = v.extractTypeInternal(current, false) + + switch kind { + case reflect.Ptr, reflect.Interface, reflect.Invalid: + + if ct == nil { + return + } + + if ct.typeof == typeOmitEmpty || ct.typeof == typeIsDefault { + return + } + + if ct.hasTag { + if kind == reflect.Invalid { + v.str1 = string(append(ns, cf.altName...)) + if v.v.hasTagNameFunc { + v.str2 = string(append(structNs, cf.name...)) + } else { + v.str2 = v.str1 + } + v.errs = append(v.errs, + &fieldError{ + v: v.v, + tag: ct.aliasTag, + actualTag: ct.tag, + ns: v.str1, + structNs: v.str2, + fieldLen: uint8(len(cf.altName)), + structfieldLen: uint8(len(cf.name)), + param: ct.param, + kind: kind, + }, + ) + return + } + + v.str1 = string(append(ns, cf.altName...)) + if v.v.hasTagNameFunc { + v.str2 = string(append(structNs, cf.name...)) + } else { + v.str2 = v.str1 + } + if !ct.runValidationWhenNil { + v.errs = append(v.errs, + &fieldError{ + v: v.v, + tag: ct.aliasTag, + actualTag: ct.tag, + ns: v.str1, + structNs: v.str2, + fieldLen: uint8(len(cf.altName)), + structfieldLen: uint8(len(cf.name)), + value: current.Interface(), + param: ct.param, + kind: kind, + typ: current.Type(), + }, + ) + return + } + } + + case reflect.Struct: + + typ = current.Type() + + if typ != timeType { + + if ct != nil { + + if ct.typeof == typeStructOnly { + goto CONTINUE + } else if ct.typeof == typeIsDefault { + // set Field Level fields + v.slflParent = parent + v.flField = current + v.cf = cf + v.ct = ct + + if !ct.fn(ctx, v) { + v.str1 = string(append(ns, cf.altName...)) + + if v.v.hasTagNameFunc { + v.str2 = string(append(structNs, cf.name...)) + } else { + v.str2 = v.str1 + } + + v.errs = append(v.errs, + &fieldError{ + v: v.v, + tag: ct.aliasTag, + actualTag: ct.tag, + ns: v.str1, + structNs: v.str2, + fieldLen: uint8(len(cf.altName)), + structfieldLen: uint8(len(cf.name)), + value: current.Interface(), + param: ct.param, + kind: kind, + typ: typ, + }, + ) + return + } + } + + ct = ct.next + } + + if ct != nil && ct.typeof == typeNoStructLevel { + return + } + + CONTINUE: + // if len == 0 then validating using 'Var' or 'VarWithValue' + // Var - doesn't make much sense to do it that way, should call 'Struct', but no harm... + // VarWithField - this allows for validating against each field within the struct against a specific value + // pretty handy in certain situations + if len(cf.name) > 0 { + ns = append(append(ns, cf.altName...), '.') + structNs = append(append(structNs, cf.name...), '.') + } + + v.validateStruct(ctx, parent, current, typ, ns, structNs, ct) + return + } + } + + if ct == nil || !ct.hasTag { + return + } + + typ = current.Type() + +OUTER: + for { + if ct == nil { + return + } + + switch ct.typeof { + + case typeOmitEmpty: + + // set Field Level fields + v.slflParent = parent + v.flField = current + v.cf = cf + v.ct = ct + + if !hasValue(v) { + return + } + + ct = ct.next + continue + + case typeEndKeys: + return + + case typeDive: + + ct = ct.next + + // traverse slice or map here + // or panic ;) + switch kind { + case reflect.Slice, reflect.Array: + + var i64 int64 + reusableCF := &cField{} + + for i := 0; i < current.Len(); i++ { + + i64 = int64(i) + + v.misc = append(v.misc[0:0], cf.name...) + v.misc = append(v.misc, '[') + v.misc = strconv.AppendInt(v.misc, i64, 10) + v.misc = append(v.misc, ']') + + reusableCF.name = string(v.misc) + + if cf.namesEqual { + reusableCF.altName = reusableCF.name + } else { + + v.misc = append(v.misc[0:0], cf.altName...) + v.misc = append(v.misc, '[') + v.misc = strconv.AppendInt(v.misc, i64, 10) + v.misc = append(v.misc, ']') + + reusableCF.altName = string(v.misc) + } + v.traverseField(ctx, parent, current.Index(i), ns, structNs, reusableCF, ct) + } + + case reflect.Map: + + var pv string + reusableCF := &cField{} + + for _, key := range current.MapKeys() { + + pv = fmt.Sprintf("%v", key.Interface()) + + v.misc = append(v.misc[0:0], cf.name...) + v.misc = append(v.misc, '[') + v.misc = append(v.misc, pv...) + v.misc = append(v.misc, ']') + + reusableCF.name = string(v.misc) + + if cf.namesEqual { + reusableCF.altName = reusableCF.name + } else { + v.misc = append(v.misc[0:0], cf.altName...) + v.misc = append(v.misc, '[') + v.misc = append(v.misc, pv...) + v.misc = append(v.misc, ']') + + reusableCF.altName = string(v.misc) + } + + if ct != nil && ct.typeof == typeKeys && ct.keys != nil { + v.traverseField(ctx, parent, key, ns, structNs, reusableCF, ct.keys) + // can be nil when just keys being validated + if ct.next != nil { + v.traverseField(ctx, parent, current.MapIndex(key), ns, structNs, reusableCF, ct.next) + } + } else { + v.traverseField(ctx, parent, current.MapIndex(key), ns, structNs, reusableCF, ct) + } + } + + default: + // throw error, if not a slice or map then should not have gotten here + // bad dive tag + panic("dive error! can't dive on a non slice or map") + } + + return + + case typeOr: + + v.misc = v.misc[0:0] + + for { + + // set Field Level fields + v.slflParent = parent + v.flField = current + v.cf = cf + v.ct = ct + + if ct.fn(ctx, v) { + + // drain rest of the 'or' values, then continue or leave + for { + + ct = ct.next + + if ct == nil { + return + } + + if ct.typeof != typeOr { + continue OUTER + } + } + } + + v.misc = append(v.misc, '|') + v.misc = append(v.misc, ct.tag...) + + if ct.hasParam { + v.misc = append(v.misc, '=') + v.misc = append(v.misc, ct.param...) + } + + if ct.isBlockEnd || ct.next == nil { + // if we get here, no valid 'or' value and no more tags + v.str1 = string(append(ns, cf.altName...)) + + if v.v.hasTagNameFunc { + v.str2 = string(append(structNs, cf.name...)) + } else { + v.str2 = v.str1 + } + + if ct.hasAlias { + + v.errs = append(v.errs, + &fieldError{ + v: v.v, + tag: ct.aliasTag, + actualTag: ct.actualAliasTag, + ns: v.str1, + structNs: v.str2, + fieldLen: uint8(len(cf.altName)), + structfieldLen: uint8(len(cf.name)), + value: current.Interface(), + param: ct.param, + kind: kind, + typ: typ, + }, + ) + + } else { + + tVal := string(v.misc)[1:] + + v.errs = append(v.errs, + &fieldError{ + v: v.v, + tag: tVal, + actualTag: tVal, + ns: v.str1, + structNs: v.str2, + fieldLen: uint8(len(cf.altName)), + structfieldLen: uint8(len(cf.name)), + value: current.Interface(), + param: ct.param, + kind: kind, + typ: typ, + }, + ) + } + + return + } + + ct = ct.next + } + + default: + + // set Field Level fields + v.slflParent = parent + v.flField = current + v.cf = cf + v.ct = ct + + if !ct.fn(ctx, v) { + + v.str1 = string(append(ns, cf.altName...)) + + if v.v.hasTagNameFunc { + v.str2 = string(append(structNs, cf.name...)) + } else { + v.str2 = v.str1 + } + + v.errs = append(v.errs, + &fieldError{ + v: v.v, + tag: ct.aliasTag, + actualTag: ct.tag, + ns: v.str1, + structNs: v.str2, + fieldLen: uint8(len(cf.altName)), + structfieldLen: uint8(len(cf.name)), + value: current.Interface(), + param: ct.param, + kind: kind, + typ: typ, + }, + ) + + return + } + ct = ct.next + } + } + +} diff --git a/vendor/github.com/go-playground/validator/v10/validator_instance.go b/vendor/github.com/go-playground/validator/v10/validator_instance.go new file mode 100644 index 0000000..973964f --- /dev/null +++ b/vendor/github.com/go-playground/validator/v10/validator_instance.go @@ -0,0 +1,658 @@ +package validator + +import ( + "context" + "errors" + "fmt" + "reflect" + "strings" + "sync" + "time" + + ut "github.com/go-playground/universal-translator" +) + +const ( + defaultTagName = "validate" + utf8HexComma = "0x2C" + utf8Pipe = "0x7C" + tagSeparator = "," + orSeparator = "|" + tagKeySeparator = "=" + structOnlyTag = "structonly" + noStructLevelTag = "nostructlevel" + omitempty = "omitempty" + isdefault = "isdefault" + requiredWithoutAllTag = "required_without_all" + requiredWithoutTag = "required_without" + requiredWithTag = "required_with" + requiredWithAllTag = "required_with_all" + requiredIfTag = "required_if" + requiredUnlessTag = "required_unless" + excludedWithoutAllTag = "excluded_without_all" + excludedWithoutTag = "excluded_without" + excludedWithTag = "excluded_with" + excludedWithAllTag = "excluded_with_all" + skipValidationTag = "-" + diveTag = "dive" + keysTag = "keys" + endKeysTag = "endkeys" + requiredTag = "required" + namespaceSeparator = "." + leftBracket = "[" + rightBracket = "]" + restrictedTagChars = ".[],|=+()`~!@#$%^&*\\\"/?<>{}" + restrictedAliasErr = "Alias '%s' either contains restricted characters or is the same as a restricted tag needed for normal operation" + restrictedTagErr = "Tag '%s' either contains restricted characters or is the same as a restricted tag needed for normal operation" +) + +var ( + timeDurationType = reflect.TypeOf(time.Duration(0)) + timeType = reflect.TypeOf(time.Time{}) + + defaultCField = &cField{namesEqual: true} +) + +// FilterFunc is the type used to filter fields using +// StructFiltered(...) function. +// returning true results in the field being filtered/skiped from +// validation +type FilterFunc func(ns []byte) bool + +// CustomTypeFunc allows for overriding or adding custom field type handler functions +// field = field value of the type to return a value to be validated +// example Valuer from sql drive see https://golang.org/src/database/sql/driver/types.go?s=1210:1293#L29 +type CustomTypeFunc func(field reflect.Value) interface{} + +// TagNameFunc allows for adding of a custom tag name parser +type TagNameFunc func(field reflect.StructField) string + +type internalValidationFuncWrapper struct { + fn FuncCtx + runValidatinOnNil bool +} + +// Validate contains the validator settings and cache +type Validate struct { + tagName string + pool *sync.Pool + hasCustomFuncs bool + hasTagNameFunc bool + tagNameFunc TagNameFunc + structLevelFuncs map[reflect.Type]StructLevelFuncCtx + customFuncs map[reflect.Type]CustomTypeFunc + aliases map[string]string + validations map[string]internalValidationFuncWrapper + transTagFunc map[ut.Translator]map[string]TranslationFunc // map[]map[]TranslationFunc + tagCache *tagCache + structCache *structCache +} + +// New returns a new instance of 'validate' with sane defaults. +// Validate is designed to be thread-safe and used as a singleton instance. +// It caches information about your struct and validations, +// in essence only parsing your validation tags once per struct type. +// Using multiple instances neglects the benefit of caching. +func New() *Validate { + + tc := new(tagCache) + tc.m.Store(make(map[string]*cTag)) + + sc := new(structCache) + sc.m.Store(make(map[reflect.Type]*cStruct)) + + v := &Validate{ + tagName: defaultTagName, + aliases: make(map[string]string, len(bakedInAliases)), + validations: make(map[string]internalValidationFuncWrapper, len(bakedInValidators)), + tagCache: tc, + structCache: sc, + } + + // must copy alias validators for separate validations to be used in each validator instance + for k, val := range bakedInAliases { + v.RegisterAlias(k, val) + } + + // must copy validators for separate validations to be used in each instance + for k, val := range bakedInValidators { + + switch k { + // these require that even if the value is nil that the validation should run, omitempty still overrides this behaviour + case requiredIfTag, requiredUnlessTag, requiredWithTag, requiredWithAllTag, requiredWithoutTag, requiredWithoutAllTag, + excludedWithTag, excludedWithAllTag, excludedWithoutTag, excludedWithoutAllTag: + _ = v.registerValidation(k, wrapFunc(val), true, true) + default: + // no need to error check here, baked in will always be valid + _ = v.registerValidation(k, wrapFunc(val), true, false) + } + } + + v.pool = &sync.Pool{ + New: func() interface{} { + return &validate{ + v: v, + ns: make([]byte, 0, 64), + actualNs: make([]byte, 0, 64), + misc: make([]byte, 32), + } + }, + } + + return v +} + +// SetTagName allows for changing of the default tag name of 'validate' +func (v *Validate) SetTagName(name string) { + v.tagName = name +} + +// ValidateMapCtx validates a map using a map of validation rules and allows passing of contextual +// validation validation information via context.Context. +func (v Validate) ValidateMapCtx(ctx context.Context, data map[string]interface{}, rules map[string]interface{}) map[string]interface{} { + errs := make(map[string]interface{}) + for field, rule := range rules { + if reflect.ValueOf(rule).Kind() == reflect.Map && reflect.ValueOf(data[field]).Kind() == reflect.Map { + err := v.ValidateMapCtx(ctx, data[field].(map[string]interface{}), rule.(map[string]interface{})) + if len(err) > 0 { + errs[field] = err + } + } else if reflect.ValueOf(rule).Kind() == reflect.Map { + errs[field] = errors.New("The field: '" + field + "' is not a map to dive") + } else { + err := v.VarCtx(ctx, data[field], rule.(string)) + if err != nil { + errs[field] = err + } + } + } + return errs +} + +// ValidateMap validates map data form a map of tags +func (v *Validate) ValidateMap(data map[string]interface{}, rules map[string]interface{}) map[string]interface{} { + return v.ValidateMapCtx(context.Background(), data, rules) +} + +// RegisterTagNameFunc registers a function to get alternate names for StructFields. +// +// eg. to use the names which have been specified for JSON representations of structs, rather than normal Go field names: +// +// validate.RegisterTagNameFunc(func(fld reflect.StructField) string { +// name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0] +// if name == "-" { +// return "" +// } +// return name +// }) +func (v *Validate) RegisterTagNameFunc(fn TagNameFunc) { + v.tagNameFunc = fn + v.hasTagNameFunc = true +} + +// RegisterValidation adds a validation with the given tag +// +// NOTES: +// - if the key already exists, the previous validation function will be replaced. +// - this method is not thread-safe it is intended that these all be registered prior to any validation +func (v *Validate) RegisterValidation(tag string, fn Func, callValidationEvenIfNull ...bool) error { + return v.RegisterValidationCtx(tag, wrapFunc(fn), callValidationEvenIfNull...) +} + +// RegisterValidationCtx does the same as RegisterValidation on accepts a FuncCtx validation +// allowing context.Context validation support. +func (v *Validate) RegisterValidationCtx(tag string, fn FuncCtx, callValidationEvenIfNull ...bool) error { + var nilCheckable bool + if len(callValidationEvenIfNull) > 0 { + nilCheckable = callValidationEvenIfNull[0] + } + return v.registerValidation(tag, fn, false, nilCheckable) +} + +func (v *Validate) registerValidation(tag string, fn FuncCtx, bakedIn bool, nilCheckable bool) error { + if len(tag) == 0 { + return errors.New("function Key cannot be empty") + } + + if fn == nil { + return errors.New("function cannot be empty") + } + + _, ok := restrictedTags[tag] + if !bakedIn && (ok || strings.ContainsAny(tag, restrictedTagChars)) { + panic(fmt.Sprintf(restrictedTagErr, tag)) + } + v.validations[tag] = internalValidationFuncWrapper{fn: fn, runValidatinOnNil: nilCheckable} + return nil +} + +// RegisterAlias registers a mapping of a single validation tag that +// defines a common or complex set of validation(s) to simplify adding validation +// to structs. +// +// NOTE: this function is not thread-safe it is intended that these all be registered prior to any validation +func (v *Validate) RegisterAlias(alias, tags string) { + + _, ok := restrictedTags[alias] + + if ok || strings.ContainsAny(alias, restrictedTagChars) { + panic(fmt.Sprintf(restrictedAliasErr, alias)) + } + + v.aliases[alias] = tags +} + +// RegisterStructValidation registers a StructLevelFunc against a number of types. +// +// NOTE: +// - this method is not thread-safe it is intended that these all be registered prior to any validation +func (v *Validate) RegisterStructValidation(fn StructLevelFunc, types ...interface{}) { + v.RegisterStructValidationCtx(wrapStructLevelFunc(fn), types...) +} + +// RegisterStructValidationCtx registers a StructLevelFuncCtx against a number of types and allows passing +// of contextual validation information via context.Context. +// +// NOTE: +// - this method is not thread-safe it is intended that these all be registered prior to any validation +func (v *Validate) RegisterStructValidationCtx(fn StructLevelFuncCtx, types ...interface{}) { + + if v.structLevelFuncs == nil { + v.structLevelFuncs = make(map[reflect.Type]StructLevelFuncCtx) + } + + for _, t := range types { + tv := reflect.ValueOf(t) + if tv.Kind() == reflect.Ptr { + t = reflect.Indirect(tv).Interface() + } + + v.structLevelFuncs[reflect.TypeOf(t)] = fn + } +} + +// RegisterCustomTypeFunc registers a CustomTypeFunc against a number of types +// +// NOTE: this method is not thread-safe it is intended that these all be registered prior to any validation +func (v *Validate) RegisterCustomTypeFunc(fn CustomTypeFunc, types ...interface{}) { + + if v.customFuncs == nil { + v.customFuncs = make(map[reflect.Type]CustomTypeFunc) + } + + for _, t := range types { + v.customFuncs[reflect.TypeOf(t)] = fn + } + + v.hasCustomFuncs = true +} + +// RegisterTranslation registers translations against the provided tag. +func (v *Validate) RegisterTranslation(tag string, trans ut.Translator, registerFn RegisterTranslationsFunc, translationFn TranslationFunc) (err error) { + + if v.transTagFunc == nil { + v.transTagFunc = make(map[ut.Translator]map[string]TranslationFunc) + } + + if err = registerFn(trans); err != nil { + return + } + + m, ok := v.transTagFunc[trans] + if !ok { + m = make(map[string]TranslationFunc) + v.transTagFunc[trans] = m + } + + m[tag] = translationFn + + return +} + +// Struct validates a structs exposed fields, and automatically validates nested structs, unless otherwise specified. +// +// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise. +// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors. +func (v *Validate) Struct(s interface{}) error { + return v.StructCtx(context.Background(), s) +} + +// StructCtx validates a structs exposed fields, and automatically validates nested structs, unless otherwise specified +// and also allows passing of context.Context for contextual validation information. +// +// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise. +// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors. +func (v *Validate) StructCtx(ctx context.Context, s interface{}) (err error) { + + val := reflect.ValueOf(s) + top := val + + if val.Kind() == reflect.Ptr && !val.IsNil() { + val = val.Elem() + } + + if val.Kind() != reflect.Struct || val.Type() == timeType { + return &InvalidValidationError{Type: reflect.TypeOf(s)} + } + + // good to validate + vd := v.pool.Get().(*validate) + vd.top = top + vd.isPartial = false + // vd.hasExcludes = false // only need to reset in StructPartial and StructExcept + + vd.validateStruct(ctx, top, val, val.Type(), vd.ns[0:0], vd.actualNs[0:0], nil) + + if len(vd.errs) > 0 { + err = vd.errs + vd.errs = nil + } + + v.pool.Put(vd) + + return +} + +// StructFiltered validates a structs exposed fields, that pass the FilterFunc check and automatically validates +// nested structs, unless otherwise specified. +// +// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise. +// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors. +func (v *Validate) StructFiltered(s interface{}, fn FilterFunc) error { + return v.StructFilteredCtx(context.Background(), s, fn) +} + +// StructFilteredCtx validates a structs exposed fields, that pass the FilterFunc check and automatically validates +// nested structs, unless otherwise specified and also allows passing of contextual validation information via +// context.Context +// +// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise. +// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors. +func (v *Validate) StructFilteredCtx(ctx context.Context, s interface{}, fn FilterFunc) (err error) { + val := reflect.ValueOf(s) + top := val + + if val.Kind() == reflect.Ptr && !val.IsNil() { + val = val.Elem() + } + + if val.Kind() != reflect.Struct || val.Type() == timeType { + return &InvalidValidationError{Type: reflect.TypeOf(s)} + } + + // good to validate + vd := v.pool.Get().(*validate) + vd.top = top + vd.isPartial = true + vd.ffn = fn + // vd.hasExcludes = false // only need to reset in StructPartial and StructExcept + + vd.validateStruct(ctx, top, val, val.Type(), vd.ns[0:0], vd.actualNs[0:0], nil) + + if len(vd.errs) > 0 { + err = vd.errs + vd.errs = nil + } + + v.pool.Put(vd) + + return +} + +// StructPartial validates the fields passed in only, ignoring all others. +// Fields may be provided in a namespaced fashion relative to the struct provided +// eg. NestedStruct.Field or NestedArrayField[0].Struct.Name +// +// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise. +// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors. +func (v *Validate) StructPartial(s interface{}, fields ...string) error { + return v.StructPartialCtx(context.Background(), s, fields...) +} + +// StructPartialCtx validates the fields passed in only, ignoring all others and allows passing of contextual +// validation validation information via context.Context +// Fields may be provided in a namespaced fashion relative to the struct provided +// eg. NestedStruct.Field or NestedArrayField[0].Struct.Name +// +// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise. +// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors. +func (v *Validate) StructPartialCtx(ctx context.Context, s interface{}, fields ...string) (err error) { + val := reflect.ValueOf(s) + top := val + + if val.Kind() == reflect.Ptr && !val.IsNil() { + val = val.Elem() + } + + if val.Kind() != reflect.Struct || val.Type() == timeType { + return &InvalidValidationError{Type: reflect.TypeOf(s)} + } + + // good to validate + vd := v.pool.Get().(*validate) + vd.top = top + vd.isPartial = true + vd.ffn = nil + vd.hasExcludes = false + vd.includeExclude = make(map[string]struct{}) + + typ := val.Type() + name := typ.Name() + + for _, k := range fields { + + flds := strings.Split(k, namespaceSeparator) + if len(flds) > 0 { + + vd.misc = append(vd.misc[0:0], name...) + // Don't append empty name for unnamed structs + if len(vd.misc) != 0 { + vd.misc = append(vd.misc, '.') + } + + for _, s := range flds { + + idx := strings.Index(s, leftBracket) + + if idx != -1 { + for idx != -1 { + vd.misc = append(vd.misc, s[:idx]...) + vd.includeExclude[string(vd.misc)] = struct{}{} + + idx2 := strings.Index(s, rightBracket) + idx2++ + vd.misc = append(vd.misc, s[idx:idx2]...) + vd.includeExclude[string(vd.misc)] = struct{}{} + s = s[idx2:] + idx = strings.Index(s, leftBracket) + } + } else { + + vd.misc = append(vd.misc, s...) + vd.includeExclude[string(vd.misc)] = struct{}{} + } + + vd.misc = append(vd.misc, '.') + } + } + } + + vd.validateStruct(ctx, top, val, typ, vd.ns[0:0], vd.actualNs[0:0], nil) + + if len(vd.errs) > 0 { + err = vd.errs + vd.errs = nil + } + + v.pool.Put(vd) + + return +} + +// StructExcept validates all fields except the ones passed in. +// Fields may be provided in a namespaced fashion relative to the struct provided +// i.e. NestedStruct.Field or NestedArrayField[0].Struct.Name +// +// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise. +// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors. +func (v *Validate) StructExcept(s interface{}, fields ...string) error { + return v.StructExceptCtx(context.Background(), s, fields...) +} + +// StructExceptCtx validates all fields except the ones passed in and allows passing of contextual +// validation validation information via context.Context +// Fields may be provided in a namespaced fashion relative to the struct provided +// i.e. NestedStruct.Field or NestedArrayField[0].Struct.Name +// +// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise. +// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors. +func (v *Validate) StructExceptCtx(ctx context.Context, s interface{}, fields ...string) (err error) { + val := reflect.ValueOf(s) + top := val + + if val.Kind() == reflect.Ptr && !val.IsNil() { + val = val.Elem() + } + + if val.Kind() != reflect.Struct || val.Type() == timeType { + return &InvalidValidationError{Type: reflect.TypeOf(s)} + } + + // good to validate + vd := v.pool.Get().(*validate) + vd.top = top + vd.isPartial = true + vd.ffn = nil + vd.hasExcludes = true + vd.includeExclude = make(map[string]struct{}) + + typ := val.Type() + name := typ.Name() + + for _, key := range fields { + + vd.misc = vd.misc[0:0] + + if len(name) > 0 { + vd.misc = append(vd.misc, name...) + vd.misc = append(vd.misc, '.') + } + + vd.misc = append(vd.misc, key...) + vd.includeExclude[string(vd.misc)] = struct{}{} + } + + vd.validateStruct(ctx, top, val, typ, vd.ns[0:0], vd.actualNs[0:0], nil) + + if len(vd.errs) > 0 { + err = vd.errs + vd.errs = nil + } + + v.pool.Put(vd) + + return +} + +// Var validates a single variable using tag style validation. +// eg. +// var i int +// validate.Var(i, "gt=1,lt=10") +// +// WARNING: a struct can be passed for validation eg. time.Time is a struct or +// if you have a custom type and have registered a custom type handler, so must +// allow it; however unforeseen validations will occur if trying to validate a +// struct that is meant to be passed to 'validate.Struct' +// +// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise. +// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors. +// validate Array, Slice and maps fields which may contain more than one error +func (v *Validate) Var(field interface{}, tag string) error { + return v.VarCtx(context.Background(), field, tag) +} + +// VarCtx validates a single variable using tag style validation and allows passing of contextual +// validation validation information via context.Context. +// eg. +// var i int +// validate.Var(i, "gt=1,lt=10") +// +// WARNING: a struct can be passed for validation eg. time.Time is a struct or +// if you have a custom type and have registered a custom type handler, so must +// allow it; however unforeseen validations will occur if trying to validate a +// struct that is meant to be passed to 'validate.Struct' +// +// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise. +// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors. +// validate Array, Slice and maps fields which may contain more than one error +func (v *Validate) VarCtx(ctx context.Context, field interface{}, tag string) (err error) { + if len(tag) == 0 || tag == skipValidationTag { + return nil + } + + ctag := v.fetchCacheTag(tag) + val := reflect.ValueOf(field) + vd := v.pool.Get().(*validate) + vd.top = val + vd.isPartial = false + vd.traverseField(ctx, val, val, vd.ns[0:0], vd.actualNs[0:0], defaultCField, ctag) + + if len(vd.errs) > 0 { + err = vd.errs + vd.errs = nil + } + v.pool.Put(vd) + return +} + +// VarWithValue validates a single variable, against another variable/field's value using tag style validation +// eg. +// s1 := "abcd" +// s2 := "abcd" +// validate.VarWithValue(s1, s2, "eqcsfield") // returns true +// +// WARNING: a struct can be passed for validation eg. time.Time is a struct or +// if you have a custom type and have registered a custom type handler, so must +// allow it; however unforeseen validations will occur if trying to validate a +// struct that is meant to be passed to 'validate.Struct' +// +// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise. +// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors. +// validate Array, Slice and maps fields which may contain more than one error +func (v *Validate) VarWithValue(field interface{}, other interface{}, tag string) error { + return v.VarWithValueCtx(context.Background(), field, other, tag) +} + +// VarWithValueCtx validates a single variable, against another variable/field's value using tag style validation and +// allows passing of contextual validation validation information via context.Context. +// eg. +// s1 := "abcd" +// s2 := "abcd" +// validate.VarWithValue(s1, s2, "eqcsfield") // returns true +// +// WARNING: a struct can be passed for validation eg. time.Time is a struct or +// if you have a custom type and have registered a custom type handler, so must +// allow it; however unforeseen validations will occur if trying to validate a +// struct that is meant to be passed to 'validate.Struct' +// +// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise. +// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors. +// validate Array, Slice and maps fields which may contain more than one error +func (v *Validate) VarWithValueCtx(ctx context.Context, field interface{}, other interface{}, tag string) (err error) { + if len(tag) == 0 || tag == skipValidationTag { + return nil + } + ctag := v.fetchCacheTag(tag) + otherVal := reflect.ValueOf(other) + vd := v.pool.Get().(*validate) + vd.top = otherVal + vd.isPartial = false + vd.traverseField(ctx, otherVal, reflect.ValueOf(field), vd.ns[0:0], vd.actualNs[0:0], defaultCField, ctag) + + if len(vd.errs) > 0 { + err = vd.errs + vd.errs = nil + } + v.pool.Put(vd) + return +} diff --git a/vendor/github.com/go-redis/redis/v8/.gitignore b/vendor/github.com/go-redis/redis/v8/.gitignore new file mode 100644 index 0000000..b975a7b --- /dev/null +++ b/vendor/github.com/go-redis/redis/v8/.gitignore @@ -0,0 +1,3 @@ +*.rdb +testdata/*/ +.idea/ diff --git a/vendor/github.com/go-redis/redis/v8/.golangci.yml b/vendor/github.com/go-redis/redis/v8/.golangci.yml new file mode 100644 index 0000000..de51455 --- /dev/null +++ b/vendor/github.com/go-redis/redis/v8/.golangci.yml @@ -0,0 +1,4 @@ +run: + concurrency: 8 + deadline: 5m + tests: false diff --git a/vendor/github.com/go-redis/redis/v8/.prettierrc.yml b/vendor/github.com/go-redis/redis/v8/.prettierrc.yml new file mode 100644 index 0000000..8b7f044 --- /dev/null +++ b/vendor/github.com/go-redis/redis/v8/.prettierrc.yml @@ -0,0 +1,4 @@ +semi: false +singleQuote: true +proseWrap: always +printWidth: 100 diff --git a/vendor/github.com/go-redis/redis/v8/CHANGELOG.md b/vendor/github.com/go-redis/redis/v8/CHANGELOG.md new file mode 100644 index 0000000..195e519 --- /dev/null +++ b/vendor/github.com/go-redis/redis/v8/CHANGELOG.md @@ -0,0 +1,177 @@ +## [8.11.5](https://github.com/go-redis/redis/compare/v8.11.4...v8.11.5) (2022-03-17) + + +### Bug Fixes + +* add missing Expire methods to Cmdable ([17e3b43](https://github.com/go-redis/redis/commit/17e3b43879d516437ada71cf9c0deac6a382ed9a)) +* add whitespace for avoid unlikely colisions ([7f7c181](https://github.com/go-redis/redis/commit/7f7c1817617cfec909efb13d14ad22ef05a6ad4c)) +* example/otel compile error ([#2028](https://github.com/go-redis/redis/issues/2028)) ([187c07c](https://github.com/go-redis/redis/commit/187c07c41bf68dc3ab280bc3a925e960bbef6475)) +* **extra/redisotel:** set span.kind attribute to client ([065b200](https://github.com/go-redis/redis/commit/065b200070b41e6e949710b4f9e01b50ccc60ab2)) +* format ([96f53a0](https://github.com/go-redis/redis/commit/96f53a0159a28affa94beec1543a62234e7f8b32)) +* invalid type assert in stringArg ([de6c131](https://github.com/go-redis/redis/commit/de6c131865b8263400c8491777b295035f2408e4)) +* rename Golang to Go ([#2030](https://github.com/go-redis/redis/issues/2030)) ([b82a2d9](https://github.com/go-redis/redis/commit/b82a2d9d4d2de7b7cbe8fcd4895be62dbcacacbc)) +* set timeout for WAIT command. Fixes [#1963](https://github.com/go-redis/redis/issues/1963) ([333fee1](https://github.com/go-redis/redis/commit/333fee1a8fd98a2fbff1ab187c1b03246a7eb01f)) +* update some argument counts in pre-allocs ([f6974eb](https://github.com/go-redis/redis/commit/f6974ebb5c40a8adf90d2cacab6dc297f4eba4c2)) + + +### Features + +* Add redis v7's NX, XX, GT, LT expire variants ([e19bbb2](https://github.com/go-redis/redis/commit/e19bbb26e2e395c6e077b48d80d79e99f729a8b8)) +* add support for acl sentinel auth in universal client ([ab0ccc4](https://github.com/go-redis/redis/commit/ab0ccc47413f9b2a6eabc852fed5005a3ee1af6e)) +* add support for COPY command ([#2016](https://github.com/go-redis/redis/issues/2016)) ([730afbc](https://github.com/go-redis/redis/commit/730afbcffb93760e8a36cc06cfe55ab102b693a7)) +* add support for passing extra attributes added to spans ([39faaa1](https://github.com/go-redis/redis/commit/39faaa171523834ba527c9789710c4fde87f5a2e)) +* add support for time.Duration write and scan ([2f1b74e](https://github.com/go-redis/redis/commit/2f1b74e20cdd7719b2aecf0768d3e3ae7c3e781b)) +* **redisotel:** ability to override TracerProvider ([#1998](https://github.com/go-redis/redis/issues/1998)) ([bf8d4aa](https://github.com/go-redis/redis/commit/bf8d4aa60c00366cda2e98c3ddddc8cf68507417)) +* set net.peer.name and net.peer.port in otel example ([69bf454](https://github.com/go-redis/redis/commit/69bf454f706204211cd34835f76b2e8192d3766d)) + + + +## [8.11.4](https://github.com/go-redis/redis/compare/v8.11.3...v8.11.4) (2021-10-04) + + +### Features + +* add acl auth support for sentinels ([f66582f](https://github.com/go-redis/redis/commit/f66582f44f3dc3a4705a5260f982043fde4aa634)) +* add Cmd.{String,Int,Float,Bool}Slice helpers and an example ([5d3d293](https://github.com/go-redis/redis/commit/5d3d293cc9c60b90871e2420602001463708ce24)) +* add SetVal method for each command ([168981d](https://github.com/go-redis/redis/commit/168981da2d84ee9e07d15d3e74d738c162e264c4)) + + + +## v8.11 + +- Remove OpenTelemetry metrics. +- Supports more redis commands and options. + +## v8.10 + +- Removed extra OpenTelemetry spans from go-redis core. Now go-redis instrumentation only adds a + single span with a Redis command (instead of 4 spans). There are multiple reasons behind this + decision: + + - Traces become smaller and less noisy. + - It may be costly to process those 3 extra spans for each query. + - go-redis no longer depends on OpenTelemetry. + + Eventually we hope to replace the information that we no longer collect with OpenTelemetry + Metrics. + +## v8.9 + +- Changed `PubSub.Channel` to only rely on `Ping` result. You can now use `WithChannelSize`, + `WithChannelHealthCheckInterval`, and `WithChannelSendTimeout` to override default settings. + +## v8.8 + +- To make updating easier, extra modules now have the same version as go-redis does. That means that + you need to update your imports: + +``` +github.com/go-redis/redis/extra/redisotel -> github.com/go-redis/redis/extra/redisotel/v8 +github.com/go-redis/redis/extra/rediscensus -> github.com/go-redis/redis/extra/rediscensus/v8 +``` + +## v8.5 + +- [knadh](https://github.com/knadh) contributed long-awaited ability to scan Redis Hash into a + struct: + +```go +err := rdb.HGetAll(ctx, "hash").Scan(&data) + +err := rdb.MGet(ctx, "key1", "key2").Scan(&data) +``` + +- Please check [redismock](https://github.com/go-redis/redismock) by + [monkey92t](https://github.com/monkey92t) if you are looking for mocking Redis Client. + +## v8 + +- All commands require `context.Context` as a first argument, e.g. `rdb.Ping(ctx)`. If you are not + using `context.Context` yet, the simplest option is to define global package variable + `var ctx = context.TODO()` and use it when `ctx` is required. + +- Full support for `context.Context` canceling. + +- Added `redis.NewFailoverClusterClient` that supports routing read-only commands to a slave node. + +- Added `redisext.OpenTemetryHook` that adds + [Redis OpenTelemetry instrumentation](https://redis.uptrace.dev/tracing/). + +- Redis slow log support. + +- Ring uses Rendezvous Hashing by default which provides better distribution. You need to move + existing keys to a new location or keys will be inaccessible / lost. To use old hashing scheme: + +```go +import "github.com/golang/groupcache/consistenthash" + +ring := redis.NewRing(&redis.RingOptions{ + NewConsistentHash: func() { + return consistenthash.New(100, crc32.ChecksumIEEE) + }, +}) +``` + +- `ClusterOptions.MaxRedirects` default value is changed from 8 to 3. +- `Options.MaxRetries` default value is changed from 0 to 3. + +- `Cluster.ForEachNode` is renamed to `ForEachShard` for consistency with `Ring`. + +## v7.3 + +- New option `Options.Username` which causes client to use `AuthACL`. Be aware if your connection + URL contains username. + +## v7.2 + +- Existing `HMSet` is renamed to `HSet` and old deprecated `HMSet` is restored for Redis 3 users. + +## v7.1 + +- Existing `Cmd.String` is renamed to `Cmd.Text`. New `Cmd.String` implements `fmt.Stringer` + interface. + +## v7 + +- _Important_. Tx.Pipeline now returns a non-transactional pipeline. Use Tx.TxPipeline for a + transactional pipeline. +- WrapProcess is replaced with more convenient AddHook that has access to context.Context. +- WithContext now can not be used to create a shallow copy of the client. +- New methods ProcessContext, DoContext, and ExecContext. +- Client respects Context.Deadline when setting net.Conn deadline. +- Client listens on Context.Done while waiting for a connection from the pool and returns an error + when context context is cancelled. +- Add PubSub.ChannelWithSubscriptions that sends `*Subscription` in addition to `*Message` to allow + detecting reconnections. +- `time.Time` is now marshalled in RFC3339 format. `rdb.Get("foo").Time()` helper is added to parse + the time. +- `SetLimiter` is removed and added `Options.Limiter` instead. +- `HMSet` is deprecated as of Redis v4. + +## v6.15 + +- Cluster and Ring pipelines process commands for each node in its own goroutine. + +## 6.14 + +- Added Options.MinIdleConns. +- Added Options.MaxConnAge. +- PoolStats.FreeConns is renamed to PoolStats.IdleConns. +- Add Client.Do to simplify creating custom commands. +- Add Cmd.String, Cmd.Int, Cmd.Int64, Cmd.Uint64, Cmd.Float64, and Cmd.Bool helpers. +- Lower memory usage. + +## v6.13 + +- Ring got new options called `HashReplicas` and `Hash`. It is recommended to set + `HashReplicas = 1000` for better keys distribution between shards. +- Cluster client was optimized to use much less memory when reloading cluster state. +- PubSub.ReceiveMessage is re-worked to not use ReceiveTimeout so it does not lose data when timeout + occurres. In most cases it is recommended to use PubSub.Channel instead. +- Dialer.KeepAlive is set to 5 minutes by default. + +## v6.12 + +- ClusterClient got new option called `ClusterSlots` which allows to build cluster of normal Redis + Servers that don't have cluster mode enabled. See + https://godoc.org/github.com/go-redis/redis#example-NewClusterClient--ManualSetup diff --git a/vendor/github.com/go-redis/redis/v8/LICENSE b/vendor/github.com/go-redis/redis/v8/LICENSE new file mode 100644 index 0000000..298bed9 --- /dev/null +++ b/vendor/github.com/go-redis/redis/v8/LICENSE @@ -0,0 +1,25 @@ +Copyright (c) 2013 The github.com/go-redis/redis Authors. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/go-redis/redis/v8/Makefile b/vendor/github.com/go-redis/redis/v8/Makefile new file mode 100644 index 0000000..a4cfe05 --- /dev/null +++ b/vendor/github.com/go-redis/redis/v8/Makefile @@ -0,0 +1,35 @@ +PACKAGE_DIRS := $(shell find . -mindepth 2 -type f -name 'go.mod' -exec dirname {} \; | sort) + +test: testdeps + go test ./... + go test ./... -short -race + go test ./... -run=NONE -bench=. -benchmem + env GOOS=linux GOARCH=386 go test ./... + go vet + +testdeps: testdata/redis/src/redis-server + +bench: testdeps + go test ./... -test.run=NONE -test.bench=. -test.benchmem + +.PHONY: all test testdeps bench + +testdata/redis: + mkdir -p $@ + wget -qO- https://download.redis.io/releases/redis-6.2.5.tar.gz | tar xvz --strip-components=1 -C $@ + +testdata/redis/src/redis-server: testdata/redis + cd $< && make all + +fmt: + gofmt -w -s ./ + goimports -w -local github.com/go-redis/redis ./ + +go_mod_tidy: + go get -u && go mod tidy + set -e; for dir in $(PACKAGE_DIRS); do \ + echo "go mod tidy in $${dir}"; \ + (cd "$${dir}" && \ + go get -u && \ + go mod tidy); \ + done diff --git a/vendor/github.com/go-redis/redis/v8/README.md b/vendor/github.com/go-redis/redis/v8/README.md new file mode 100644 index 0000000..f3b6a01 --- /dev/null +++ b/vendor/github.com/go-redis/redis/v8/README.md @@ -0,0 +1,175 @@ +# Redis client for Go + +![build workflow](https://github.com/go-redis/redis/actions/workflows/build.yml/badge.svg) +[![PkgGoDev](https://pkg.go.dev/badge/github.com/go-redis/redis/v8)](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc) +[![Documentation](https://img.shields.io/badge/redis-documentation-informational)](https://redis.uptrace.dev/) + +go-redis is brought to you by :star: [**uptrace/uptrace**](https://github.com/uptrace/uptrace). +Uptrace is an open source and blazingly fast **distributed tracing** backend powered by +OpenTelemetry and ClickHouse. Give it a star as well! + +## Resources + +- [Discussions](https://github.com/go-redis/redis/discussions) +- [Documentation](https://redis.uptrace.dev) +- [Reference](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc) +- [Examples](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#pkg-examples) +- [RealWorld example app](https://github.com/uptrace/go-treemux-realworld-example-app) + +Other projects you may like: + +- [Bun](https://bun.uptrace.dev) - fast and simple SQL client for PostgreSQL, MySQL, and SQLite. +- [BunRouter](https://bunrouter.uptrace.dev/) - fast and flexible HTTP router for Go. + +## Ecosystem + +- [Redis Mock](https://github.com/go-redis/redismock) +- [Distributed Locks](https://github.com/bsm/redislock) +- [Redis Cache](https://github.com/go-redis/cache) +- [Rate limiting](https://github.com/go-redis/redis_rate) + +## Features + +- Redis 3 commands except QUIT, MONITOR, and SYNC. +- Automatic connection pooling with + [circuit breaker](https://en.wikipedia.org/wiki/Circuit_breaker_design_pattern) support. +- [Pub/Sub](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#PubSub). +- [Transactions](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-Client-TxPipeline). +- [Pipeline](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-Client.Pipeline) and + [TxPipeline](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-Client.TxPipeline). +- [Scripting](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#Script). +- [Timeouts](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#Options). +- [Redis Sentinel](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#NewFailoverClient). +- [Redis Cluster](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#NewClusterClient). +- [Cluster of Redis Servers](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-NewClusterClient-ManualSetup) + without using cluster mode and Redis Sentinel. +- [Ring](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#NewRing). +- [Instrumentation](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-package-Instrumentation). + +## Installation + +go-redis supports 2 last Go versions and requires a Go version with +[modules](https://github.com/golang/go/wiki/Modules) support. So make sure to initialize a Go +module: + +```shell +go mod init github.com/my/repo +``` + +And then install go-redis/v8 (note _v8_ in the import; omitting it is a popular mistake): + +```shell +go get github.com/go-redis/redis/v8 +``` + +## Quickstart + +```go +import ( + "context" + "github.com/go-redis/redis/v8" + "fmt" +) + +var ctx = context.Background() + +func ExampleClient() { + rdb := redis.NewClient(&redis.Options{ + Addr: "localhost:6379", + Password: "", // no password set + DB: 0, // use default DB + }) + + err := rdb.Set(ctx, "key", "value", 0).Err() + if err != nil { + panic(err) + } + + val, err := rdb.Get(ctx, "key").Result() + if err != nil { + panic(err) + } + fmt.Println("key", val) + + val2, err := rdb.Get(ctx, "key2").Result() + if err == redis.Nil { + fmt.Println("key2 does not exist") + } else if err != nil { + panic(err) + } else { + fmt.Println("key2", val2) + } + // Output: key value + // key2 does not exist +} +``` + +## Look and feel + +Some corner cases: + +```go +// SET key value EX 10 NX +set, err := rdb.SetNX(ctx, "key", "value", 10*time.Second).Result() + +// SET key value keepttl NX +set, err := rdb.SetNX(ctx, "key", "value", redis.KeepTTL).Result() + +// SORT list LIMIT 0 2 ASC +vals, err := rdb.Sort(ctx, "list", &redis.Sort{Offset: 0, Count: 2, Order: "ASC"}).Result() + +// ZRANGEBYSCORE zset -inf +inf WITHSCORES LIMIT 0 2 +vals, err := rdb.ZRangeByScoreWithScores(ctx, "zset", &redis.ZRangeBy{ + Min: "-inf", + Max: "+inf", + Offset: 0, + Count: 2, +}).Result() + +// ZINTERSTORE out 2 zset1 zset2 WEIGHTS 2 3 AGGREGATE SUM +vals, err := rdb.ZInterStore(ctx, "out", &redis.ZStore{ + Keys: []string{"zset1", "zset2"}, + Weights: []int64{2, 3} +}).Result() + +// EVAL "return {KEYS[1],ARGV[1]}" 1 "key" "hello" +vals, err := rdb.Eval(ctx, "return {KEYS[1],ARGV[1]}", []string{"key"}, "hello").Result() + +// custom command +res, err := rdb.Do(ctx, "set", "key", "value").Result() +``` + +## Run the test + +go-redis will start a redis-server and run the test cases. + +The paths of redis-server bin file and redis config file are defined in `main_test.go`: + +``` +var ( + redisServerBin, _ = filepath.Abs(filepath.Join("testdata", "redis", "src", "redis-server")) + redisServerConf, _ = filepath.Abs(filepath.Join("testdata", "redis", "redis.conf")) +) +``` + +For local testing, you can change the variables to refer to your local files, or create a soft link +to the corresponding folder for redis-server and copy the config file to `testdata/redis/`: + +``` +ln -s /usr/bin/redis-server ./go-redis/testdata/redis/src +cp ./go-redis/testdata/redis.conf ./go-redis/testdata/redis/ +``` + +Lastly, run: + +``` +go test +``` + +## Contributors + +Thanks to all the people who already contributed! + + + + diff --git a/vendor/github.com/go-redis/redis/v8/RELEASING.md b/vendor/github.com/go-redis/redis/v8/RELEASING.md new file mode 100644 index 0000000..1115db4 --- /dev/null +++ b/vendor/github.com/go-redis/redis/v8/RELEASING.md @@ -0,0 +1,15 @@ +# Releasing + +1. Run `release.sh` script which updates versions in go.mod files and pushes a new branch to GitHub: + +```shell +TAG=v1.0.0 ./scripts/release.sh +``` + +2. Open a pull request and wait for the build to finish. + +3. Merge the pull request and run `tag.sh` to create tags for packages: + +```shell +TAG=v1.0.0 ./scripts/tag.sh +``` diff --git a/vendor/github.com/go-redis/redis/v8/cluster.go b/vendor/github.com/go-redis/redis/v8/cluster.go new file mode 100644 index 0000000..a54f2f3 --- /dev/null +++ b/vendor/github.com/go-redis/redis/v8/cluster.go @@ -0,0 +1,1750 @@ +package redis + +import ( + "context" + "crypto/tls" + "fmt" + "math" + "net" + "runtime" + "sort" + "sync" + "sync/atomic" + "time" + + "github.com/go-redis/redis/v8/internal" + "github.com/go-redis/redis/v8/internal/hashtag" + "github.com/go-redis/redis/v8/internal/pool" + "github.com/go-redis/redis/v8/internal/proto" + "github.com/go-redis/redis/v8/internal/rand" +) + +var errClusterNoNodes = fmt.Errorf("redis: cluster has no nodes") + +// ClusterOptions are used to configure a cluster client and should be +// passed to NewClusterClient. +type ClusterOptions struct { + // A seed list of host:port addresses of cluster nodes. + Addrs []string + + // NewClient creates a cluster node client with provided name and options. + NewClient func(opt *Options) *Client + + // The maximum number of retries before giving up. Command is retried + // on network errors and MOVED/ASK redirects. + // Default is 3 retries. + MaxRedirects int + + // Enables read-only commands on slave nodes. + ReadOnly bool + // Allows routing read-only commands to the closest master or slave node. + // It automatically enables ReadOnly. + RouteByLatency bool + // Allows routing read-only commands to the random master or slave node. + // It automatically enables ReadOnly. + RouteRandomly bool + + // Optional function that returns cluster slots information. + // It is useful to manually create cluster of standalone Redis servers + // and load-balance read/write operations between master and slaves. + // It can use service like ZooKeeper to maintain configuration information + // and Cluster.ReloadState to manually trigger state reloading. + ClusterSlots func(context.Context) ([]ClusterSlot, error) + + // Following options are copied from Options struct. + + Dialer func(ctx context.Context, network, addr string) (net.Conn, error) + + OnConnect func(ctx context.Context, cn *Conn) error + + Username string + Password string + + MaxRetries int + MinRetryBackoff time.Duration + MaxRetryBackoff time.Duration + + DialTimeout time.Duration + ReadTimeout time.Duration + WriteTimeout time.Duration + + // PoolFIFO uses FIFO mode for each node connection pool GET/PUT (default LIFO). + PoolFIFO bool + + // PoolSize applies per cluster node and not for the whole cluster. + PoolSize int + MinIdleConns int + MaxConnAge time.Duration + PoolTimeout time.Duration + IdleTimeout time.Duration + IdleCheckFrequency time.Duration + + TLSConfig *tls.Config +} + +func (opt *ClusterOptions) init() { + if opt.MaxRedirects == -1 { + opt.MaxRedirects = 0 + } else if opt.MaxRedirects == 0 { + opt.MaxRedirects = 3 + } + + if opt.RouteByLatency || opt.RouteRandomly { + opt.ReadOnly = true + } + + if opt.PoolSize == 0 { + opt.PoolSize = 5 * runtime.GOMAXPROCS(0) + } + + switch opt.ReadTimeout { + case -1: + opt.ReadTimeout = 0 + case 0: + opt.ReadTimeout = 3 * time.Second + } + switch opt.WriteTimeout { + case -1: + opt.WriteTimeout = 0 + case 0: + opt.WriteTimeout = opt.ReadTimeout + } + + if opt.MaxRetries == 0 { + opt.MaxRetries = -1 + } + switch opt.MinRetryBackoff { + case -1: + opt.MinRetryBackoff = 0 + case 0: + opt.MinRetryBackoff = 8 * time.Millisecond + } + switch opt.MaxRetryBackoff { + case -1: + opt.MaxRetryBackoff = 0 + case 0: + opt.MaxRetryBackoff = 512 * time.Millisecond + } + + if opt.NewClient == nil { + opt.NewClient = NewClient + } +} + +func (opt *ClusterOptions) clientOptions() *Options { + const disableIdleCheck = -1 + + return &Options{ + Dialer: opt.Dialer, + OnConnect: opt.OnConnect, + + Username: opt.Username, + Password: opt.Password, + + MaxRetries: opt.MaxRetries, + MinRetryBackoff: opt.MinRetryBackoff, + MaxRetryBackoff: opt.MaxRetryBackoff, + + DialTimeout: opt.DialTimeout, + ReadTimeout: opt.ReadTimeout, + WriteTimeout: opt.WriteTimeout, + + PoolFIFO: opt.PoolFIFO, + PoolSize: opt.PoolSize, + MinIdleConns: opt.MinIdleConns, + MaxConnAge: opt.MaxConnAge, + PoolTimeout: opt.PoolTimeout, + IdleTimeout: opt.IdleTimeout, + IdleCheckFrequency: disableIdleCheck, + + TLSConfig: opt.TLSConfig, + // If ClusterSlots is populated, then we probably have an artificial + // cluster whose nodes are not in clustering mode (otherwise there isn't + // much use for ClusterSlots config). This means we cannot execute the + // READONLY command against that node -- setting readOnly to false in such + // situations in the options below will prevent that from happening. + readOnly: opt.ReadOnly && opt.ClusterSlots == nil, + } +} + +//------------------------------------------------------------------------------ + +type clusterNode struct { + Client *Client + + latency uint32 // atomic + generation uint32 // atomic + failing uint32 // atomic +} + +func newClusterNode(clOpt *ClusterOptions, addr string) *clusterNode { + opt := clOpt.clientOptions() + opt.Addr = addr + node := clusterNode{ + Client: clOpt.NewClient(opt), + } + + node.latency = math.MaxUint32 + if clOpt.RouteByLatency { + go node.updateLatency() + } + + return &node +} + +func (n *clusterNode) String() string { + return n.Client.String() +} + +func (n *clusterNode) Close() error { + return n.Client.Close() +} + +func (n *clusterNode) updateLatency() { + const numProbe = 10 + var dur uint64 + + for i := 0; i < numProbe; i++ { + time.Sleep(time.Duration(10+rand.Intn(10)) * time.Millisecond) + + start := time.Now() + n.Client.Ping(context.TODO()) + dur += uint64(time.Since(start) / time.Microsecond) + } + + latency := float64(dur) / float64(numProbe) + atomic.StoreUint32(&n.latency, uint32(latency+0.5)) +} + +func (n *clusterNode) Latency() time.Duration { + latency := atomic.LoadUint32(&n.latency) + return time.Duration(latency) * time.Microsecond +} + +func (n *clusterNode) MarkAsFailing() { + atomic.StoreUint32(&n.failing, uint32(time.Now().Unix())) +} + +func (n *clusterNode) Failing() bool { + const timeout = 15 // 15 seconds + + failing := atomic.LoadUint32(&n.failing) + if failing == 0 { + return false + } + if time.Now().Unix()-int64(failing) < timeout { + return true + } + atomic.StoreUint32(&n.failing, 0) + return false +} + +func (n *clusterNode) Generation() uint32 { + return atomic.LoadUint32(&n.generation) +} + +func (n *clusterNode) SetGeneration(gen uint32) { + for { + v := atomic.LoadUint32(&n.generation) + if gen < v || atomic.CompareAndSwapUint32(&n.generation, v, gen) { + break + } + } +} + +//------------------------------------------------------------------------------ + +type clusterNodes struct { + opt *ClusterOptions + + mu sync.RWMutex + addrs []string + nodes map[string]*clusterNode + activeAddrs []string + closed bool + + _generation uint32 // atomic +} + +func newClusterNodes(opt *ClusterOptions) *clusterNodes { + return &clusterNodes{ + opt: opt, + + addrs: opt.Addrs, + nodes: make(map[string]*clusterNode), + } +} + +func (c *clusterNodes) Close() error { + c.mu.Lock() + defer c.mu.Unlock() + + if c.closed { + return nil + } + c.closed = true + + var firstErr error + for _, node := range c.nodes { + if err := node.Client.Close(); err != nil && firstErr == nil { + firstErr = err + } + } + + c.nodes = nil + c.activeAddrs = nil + + return firstErr +} + +func (c *clusterNodes) Addrs() ([]string, error) { + var addrs []string + + c.mu.RLock() + closed := c.closed //nolint:ifshort + if !closed { + if len(c.activeAddrs) > 0 { + addrs = c.activeAddrs + } else { + addrs = c.addrs + } + } + c.mu.RUnlock() + + if closed { + return nil, pool.ErrClosed + } + if len(addrs) == 0 { + return nil, errClusterNoNodes + } + return addrs, nil +} + +func (c *clusterNodes) NextGeneration() uint32 { + return atomic.AddUint32(&c._generation, 1) +} + +// GC removes unused nodes. +func (c *clusterNodes) GC(generation uint32) { + //nolint:prealloc + var collected []*clusterNode + + c.mu.Lock() + + c.activeAddrs = c.activeAddrs[:0] + for addr, node := range c.nodes { + if node.Generation() >= generation { + c.activeAddrs = append(c.activeAddrs, addr) + if c.opt.RouteByLatency { + go node.updateLatency() + } + continue + } + + delete(c.nodes, addr) + collected = append(collected, node) + } + + c.mu.Unlock() + + for _, node := range collected { + _ = node.Client.Close() + } +} + +func (c *clusterNodes) GetOrCreate(addr string) (*clusterNode, error) { + node, err := c.get(addr) + if err != nil { + return nil, err + } + if node != nil { + return node, nil + } + + c.mu.Lock() + defer c.mu.Unlock() + + if c.closed { + return nil, pool.ErrClosed + } + + node, ok := c.nodes[addr] + if ok { + return node, nil + } + + node = newClusterNode(c.opt, addr) + + c.addrs = appendIfNotExists(c.addrs, addr) + c.nodes[addr] = node + + return node, nil +} + +func (c *clusterNodes) get(addr string) (*clusterNode, error) { + var node *clusterNode + var err error + c.mu.RLock() + if c.closed { + err = pool.ErrClosed + } else { + node = c.nodes[addr] + } + c.mu.RUnlock() + return node, err +} + +func (c *clusterNodes) All() ([]*clusterNode, error) { + c.mu.RLock() + defer c.mu.RUnlock() + + if c.closed { + return nil, pool.ErrClosed + } + + cp := make([]*clusterNode, 0, len(c.nodes)) + for _, node := range c.nodes { + cp = append(cp, node) + } + return cp, nil +} + +func (c *clusterNodes) Random() (*clusterNode, error) { + addrs, err := c.Addrs() + if err != nil { + return nil, err + } + + n := rand.Intn(len(addrs)) + return c.GetOrCreate(addrs[n]) +} + +//------------------------------------------------------------------------------ + +type clusterSlot struct { + start, end int + nodes []*clusterNode +} + +type clusterSlotSlice []*clusterSlot + +func (p clusterSlotSlice) Len() int { + return len(p) +} + +func (p clusterSlotSlice) Less(i, j int) bool { + return p[i].start < p[j].start +} + +func (p clusterSlotSlice) Swap(i, j int) { + p[i], p[j] = p[j], p[i] +} + +type clusterState struct { + nodes *clusterNodes + Masters []*clusterNode + Slaves []*clusterNode + + slots []*clusterSlot + + generation uint32 + createdAt time.Time +} + +func newClusterState( + nodes *clusterNodes, slots []ClusterSlot, origin string, +) (*clusterState, error) { + c := clusterState{ + nodes: nodes, + + slots: make([]*clusterSlot, 0, len(slots)), + + generation: nodes.NextGeneration(), + createdAt: time.Now(), + } + + originHost, _, _ := net.SplitHostPort(origin) + isLoopbackOrigin := isLoopback(originHost) + + for _, slot := range slots { + var nodes []*clusterNode + for i, slotNode := range slot.Nodes { + addr := slotNode.Addr + if !isLoopbackOrigin { + addr = replaceLoopbackHost(addr, originHost) + } + + node, err := c.nodes.GetOrCreate(addr) + if err != nil { + return nil, err + } + + node.SetGeneration(c.generation) + nodes = append(nodes, node) + + if i == 0 { + c.Masters = appendUniqueNode(c.Masters, node) + } else { + c.Slaves = appendUniqueNode(c.Slaves, node) + } + } + + c.slots = append(c.slots, &clusterSlot{ + start: slot.Start, + end: slot.End, + nodes: nodes, + }) + } + + sort.Sort(clusterSlotSlice(c.slots)) + + time.AfterFunc(time.Minute, func() { + nodes.GC(c.generation) + }) + + return &c, nil +} + +func replaceLoopbackHost(nodeAddr, originHost string) string { + nodeHost, nodePort, err := net.SplitHostPort(nodeAddr) + if err != nil { + return nodeAddr + } + + nodeIP := net.ParseIP(nodeHost) + if nodeIP == nil { + return nodeAddr + } + + if !nodeIP.IsLoopback() { + return nodeAddr + } + + // Use origin host which is not loopback and node port. + return net.JoinHostPort(originHost, nodePort) +} + +func isLoopback(host string) bool { + ip := net.ParseIP(host) + if ip == nil { + return true + } + return ip.IsLoopback() +} + +func (c *clusterState) slotMasterNode(slot int) (*clusterNode, error) { + nodes := c.slotNodes(slot) + if len(nodes) > 0 { + return nodes[0], nil + } + return c.nodes.Random() +} + +func (c *clusterState) slotSlaveNode(slot int) (*clusterNode, error) { + nodes := c.slotNodes(slot) + switch len(nodes) { + case 0: + return c.nodes.Random() + case 1: + return nodes[0], nil + case 2: + if slave := nodes[1]; !slave.Failing() { + return slave, nil + } + return nodes[0], nil + default: + var slave *clusterNode + for i := 0; i < 10; i++ { + n := rand.Intn(len(nodes)-1) + 1 + slave = nodes[n] + if !slave.Failing() { + return slave, nil + } + } + + // All slaves are loading - use master. + return nodes[0], nil + } +} + +func (c *clusterState) slotClosestNode(slot int) (*clusterNode, error) { + nodes := c.slotNodes(slot) + if len(nodes) == 0 { + return c.nodes.Random() + } + + var node *clusterNode + for _, n := range nodes { + if n.Failing() { + continue + } + if node == nil || n.Latency() < node.Latency() { + node = n + } + } + if node != nil { + return node, nil + } + + // If all nodes are failing - return random node + return c.nodes.Random() +} + +func (c *clusterState) slotRandomNode(slot int) (*clusterNode, error) { + nodes := c.slotNodes(slot) + if len(nodes) == 0 { + return c.nodes.Random() + } + if len(nodes) == 1 { + return nodes[0], nil + } + randomNodes := rand.Perm(len(nodes)) + for _, idx := range randomNodes { + if node := nodes[idx]; !node.Failing() { + return node, nil + } + } + return nodes[randomNodes[0]], nil +} + +func (c *clusterState) slotNodes(slot int) []*clusterNode { + i := sort.Search(len(c.slots), func(i int) bool { + return c.slots[i].end >= slot + }) + if i >= len(c.slots) { + return nil + } + x := c.slots[i] + if slot >= x.start && slot <= x.end { + return x.nodes + } + return nil +} + +//------------------------------------------------------------------------------ + +type clusterStateHolder struct { + load func(ctx context.Context) (*clusterState, error) + + state atomic.Value + reloading uint32 // atomic +} + +func newClusterStateHolder(fn func(ctx context.Context) (*clusterState, error)) *clusterStateHolder { + return &clusterStateHolder{ + load: fn, + } +} + +func (c *clusterStateHolder) Reload(ctx context.Context) (*clusterState, error) { + state, err := c.load(ctx) + if err != nil { + return nil, err + } + c.state.Store(state) + return state, nil +} + +func (c *clusterStateHolder) LazyReload() { + if !atomic.CompareAndSwapUint32(&c.reloading, 0, 1) { + return + } + go func() { + defer atomic.StoreUint32(&c.reloading, 0) + + _, err := c.Reload(context.Background()) + if err != nil { + return + } + time.Sleep(200 * time.Millisecond) + }() +} + +func (c *clusterStateHolder) Get(ctx context.Context) (*clusterState, error) { + v := c.state.Load() + if v == nil { + return c.Reload(ctx) + } + + state := v.(*clusterState) + if time.Since(state.createdAt) > 10*time.Second { + c.LazyReload() + } + return state, nil +} + +func (c *clusterStateHolder) ReloadOrGet(ctx context.Context) (*clusterState, error) { + state, err := c.Reload(ctx) + if err == nil { + return state, nil + } + return c.Get(ctx) +} + +//------------------------------------------------------------------------------ + +type clusterClient struct { + opt *ClusterOptions + nodes *clusterNodes + state *clusterStateHolder //nolint:structcheck + cmdsInfoCache *cmdsInfoCache //nolint:structcheck +} + +// ClusterClient is a Redis Cluster client representing a pool of zero +// or more underlying connections. It's safe for concurrent use by +// multiple goroutines. +type ClusterClient struct { + *clusterClient + cmdable + hooks + ctx context.Context +} + +// NewClusterClient returns a Redis Cluster client as described in +// http://redis.io/topics/cluster-spec. +func NewClusterClient(opt *ClusterOptions) *ClusterClient { + opt.init() + + c := &ClusterClient{ + clusterClient: &clusterClient{ + opt: opt, + nodes: newClusterNodes(opt), + }, + ctx: context.Background(), + } + c.state = newClusterStateHolder(c.loadState) + c.cmdsInfoCache = newCmdsInfoCache(c.cmdsInfo) + c.cmdable = c.Process + + if opt.IdleCheckFrequency > 0 { + go c.reaper(opt.IdleCheckFrequency) + } + + return c +} + +func (c *ClusterClient) Context() context.Context { + return c.ctx +} + +func (c *ClusterClient) WithContext(ctx context.Context) *ClusterClient { + if ctx == nil { + panic("nil context") + } + clone := *c + clone.cmdable = clone.Process + clone.hooks.lock() + clone.ctx = ctx + return &clone +} + +// Options returns read-only Options that were used to create the client. +func (c *ClusterClient) Options() *ClusterOptions { + return c.opt +} + +// ReloadState reloads cluster state. If available it calls ClusterSlots func +// to get cluster slots information. +func (c *ClusterClient) ReloadState(ctx context.Context) { + c.state.LazyReload() +} + +// Close closes the cluster client, releasing any open resources. +// +// It is rare to Close a ClusterClient, as the ClusterClient is meant +// to be long-lived and shared between many goroutines. +func (c *ClusterClient) Close() error { + return c.nodes.Close() +} + +// Do creates a Cmd from the args and processes the cmd. +func (c *ClusterClient) Do(ctx context.Context, args ...interface{}) *Cmd { + cmd := NewCmd(ctx, args...) + _ = c.Process(ctx, cmd) + return cmd +} + +func (c *ClusterClient) Process(ctx context.Context, cmd Cmder) error { + return c.hooks.process(ctx, cmd, c.process) +} + +func (c *ClusterClient) process(ctx context.Context, cmd Cmder) error { + cmdInfo := c.cmdInfo(cmd.Name()) + slot := c.cmdSlot(cmd) + + var node *clusterNode + var ask bool + var lastErr error + for attempt := 0; attempt <= c.opt.MaxRedirects; attempt++ { + if attempt > 0 { + if err := internal.Sleep(ctx, c.retryBackoff(attempt)); err != nil { + return err + } + } + + if node == nil { + var err error + node, err = c.cmdNode(ctx, cmdInfo, slot) + if err != nil { + return err + } + } + + if ask { + pipe := node.Client.Pipeline() + _ = pipe.Process(ctx, NewCmd(ctx, "asking")) + _ = pipe.Process(ctx, cmd) + _, lastErr = pipe.Exec(ctx) + _ = pipe.Close() + ask = false + } else { + lastErr = node.Client.Process(ctx, cmd) + } + + // If there is no error - we are done. + if lastErr == nil { + return nil + } + if isReadOnly := isReadOnlyError(lastErr); isReadOnly || lastErr == pool.ErrClosed { + if isReadOnly { + c.state.LazyReload() + } + node = nil + continue + } + + // If slave is loading - pick another node. + if c.opt.ReadOnly && isLoadingError(lastErr) { + node.MarkAsFailing() + node = nil + continue + } + + var moved bool + var addr string + moved, ask, addr = isMovedError(lastErr) + if moved || ask { + c.state.LazyReload() + + var err error + node, err = c.nodes.GetOrCreate(addr) + if err != nil { + return err + } + continue + } + + if shouldRetry(lastErr, cmd.readTimeout() == nil) { + // First retry the same node. + if attempt == 0 { + continue + } + + // Second try another node. + node.MarkAsFailing() + node = nil + continue + } + + return lastErr + } + return lastErr +} + +// ForEachMaster concurrently calls the fn on each master node in the cluster. +// It returns the first error if any. +func (c *ClusterClient) ForEachMaster( + ctx context.Context, + fn func(ctx context.Context, client *Client) error, +) error { + state, err := c.state.ReloadOrGet(ctx) + if err != nil { + return err + } + + var wg sync.WaitGroup + errCh := make(chan error, 1) + + for _, master := range state.Masters { + wg.Add(1) + go func(node *clusterNode) { + defer wg.Done() + err := fn(ctx, node.Client) + if err != nil { + select { + case errCh <- err: + default: + } + } + }(master) + } + + wg.Wait() + + select { + case err := <-errCh: + return err + default: + return nil + } +} + +// ForEachSlave concurrently calls the fn on each slave node in the cluster. +// It returns the first error if any. +func (c *ClusterClient) ForEachSlave( + ctx context.Context, + fn func(ctx context.Context, client *Client) error, +) error { + state, err := c.state.ReloadOrGet(ctx) + if err != nil { + return err + } + + var wg sync.WaitGroup + errCh := make(chan error, 1) + + for _, slave := range state.Slaves { + wg.Add(1) + go func(node *clusterNode) { + defer wg.Done() + err := fn(ctx, node.Client) + if err != nil { + select { + case errCh <- err: + default: + } + } + }(slave) + } + + wg.Wait() + + select { + case err := <-errCh: + return err + default: + return nil + } +} + +// ForEachShard concurrently calls the fn on each known node in the cluster. +// It returns the first error if any. +func (c *ClusterClient) ForEachShard( + ctx context.Context, + fn func(ctx context.Context, client *Client) error, +) error { + state, err := c.state.ReloadOrGet(ctx) + if err != nil { + return err + } + + var wg sync.WaitGroup + errCh := make(chan error, 1) + + worker := func(node *clusterNode) { + defer wg.Done() + err := fn(ctx, node.Client) + if err != nil { + select { + case errCh <- err: + default: + } + } + } + + for _, node := range state.Masters { + wg.Add(1) + go worker(node) + } + for _, node := range state.Slaves { + wg.Add(1) + go worker(node) + } + + wg.Wait() + + select { + case err := <-errCh: + return err + default: + return nil + } +} + +// PoolStats returns accumulated connection pool stats. +func (c *ClusterClient) PoolStats() *PoolStats { + var acc PoolStats + + state, _ := c.state.Get(context.TODO()) + if state == nil { + return &acc + } + + for _, node := range state.Masters { + s := node.Client.connPool.Stats() + acc.Hits += s.Hits + acc.Misses += s.Misses + acc.Timeouts += s.Timeouts + + acc.TotalConns += s.TotalConns + acc.IdleConns += s.IdleConns + acc.StaleConns += s.StaleConns + } + + for _, node := range state.Slaves { + s := node.Client.connPool.Stats() + acc.Hits += s.Hits + acc.Misses += s.Misses + acc.Timeouts += s.Timeouts + + acc.TotalConns += s.TotalConns + acc.IdleConns += s.IdleConns + acc.StaleConns += s.StaleConns + } + + return &acc +} + +func (c *ClusterClient) loadState(ctx context.Context) (*clusterState, error) { + if c.opt.ClusterSlots != nil { + slots, err := c.opt.ClusterSlots(ctx) + if err != nil { + return nil, err + } + return newClusterState(c.nodes, slots, "") + } + + addrs, err := c.nodes.Addrs() + if err != nil { + return nil, err + } + + var firstErr error + + for _, idx := range rand.Perm(len(addrs)) { + addr := addrs[idx] + + node, err := c.nodes.GetOrCreate(addr) + if err != nil { + if firstErr == nil { + firstErr = err + } + continue + } + + slots, err := node.Client.ClusterSlots(ctx).Result() + if err != nil { + if firstErr == nil { + firstErr = err + } + continue + } + + return newClusterState(c.nodes, slots, node.Client.opt.Addr) + } + + /* + * No node is connectable. It's possible that all nodes' IP has changed. + * Clear activeAddrs to let client be able to re-connect using the initial + * setting of the addresses (e.g. [redis-cluster-0:6379, redis-cluster-1:6379]), + * which might have chance to resolve domain name and get updated IP address. + */ + c.nodes.mu.Lock() + c.nodes.activeAddrs = nil + c.nodes.mu.Unlock() + + return nil, firstErr +} + +// reaper closes idle connections to the cluster. +func (c *ClusterClient) reaper(idleCheckFrequency time.Duration) { + ticker := time.NewTicker(idleCheckFrequency) + defer ticker.Stop() + + for range ticker.C { + nodes, err := c.nodes.All() + if err != nil { + break + } + + for _, node := range nodes { + _, err := node.Client.connPool.(*pool.ConnPool).ReapStaleConns() + if err != nil { + internal.Logger.Printf(c.Context(), "ReapStaleConns failed: %s", err) + } + } + } +} + +func (c *ClusterClient) Pipeline() Pipeliner { + pipe := Pipeline{ + ctx: c.ctx, + exec: c.processPipeline, + } + pipe.init() + return &pipe +} + +func (c *ClusterClient) Pipelined(ctx context.Context, fn func(Pipeliner) error) ([]Cmder, error) { + return c.Pipeline().Pipelined(ctx, fn) +} + +func (c *ClusterClient) processPipeline(ctx context.Context, cmds []Cmder) error { + return c.hooks.processPipeline(ctx, cmds, c._processPipeline) +} + +func (c *ClusterClient) _processPipeline(ctx context.Context, cmds []Cmder) error { + cmdsMap := newCmdsMap() + err := c.mapCmdsByNode(ctx, cmdsMap, cmds) + if err != nil { + setCmdsErr(cmds, err) + return err + } + + for attempt := 0; attempt <= c.opt.MaxRedirects; attempt++ { + if attempt > 0 { + if err := internal.Sleep(ctx, c.retryBackoff(attempt)); err != nil { + setCmdsErr(cmds, err) + return err + } + } + + failedCmds := newCmdsMap() + var wg sync.WaitGroup + + for node, cmds := range cmdsMap.m { + wg.Add(1) + go func(node *clusterNode, cmds []Cmder) { + defer wg.Done() + + err := c._processPipelineNode(ctx, node, cmds, failedCmds) + if err == nil { + return + } + if attempt < c.opt.MaxRedirects { + if err := c.mapCmdsByNode(ctx, failedCmds, cmds); err != nil { + setCmdsErr(cmds, err) + } + } else { + setCmdsErr(cmds, err) + } + }(node, cmds) + } + + wg.Wait() + if len(failedCmds.m) == 0 { + break + } + cmdsMap = failedCmds + } + + return cmdsFirstErr(cmds) +} + +func (c *ClusterClient) mapCmdsByNode(ctx context.Context, cmdsMap *cmdsMap, cmds []Cmder) error { + state, err := c.state.Get(ctx) + if err != nil { + return err + } + + if c.opt.ReadOnly && c.cmdsAreReadOnly(cmds) { + for _, cmd := range cmds { + slot := c.cmdSlot(cmd) + node, err := c.slotReadOnlyNode(state, slot) + if err != nil { + return err + } + cmdsMap.Add(node, cmd) + } + return nil + } + + for _, cmd := range cmds { + slot := c.cmdSlot(cmd) + node, err := state.slotMasterNode(slot) + if err != nil { + return err + } + cmdsMap.Add(node, cmd) + } + return nil +} + +func (c *ClusterClient) cmdsAreReadOnly(cmds []Cmder) bool { + for _, cmd := range cmds { + cmdInfo := c.cmdInfo(cmd.Name()) + if cmdInfo == nil || !cmdInfo.ReadOnly { + return false + } + } + return true +} + +func (c *ClusterClient) _processPipelineNode( + ctx context.Context, node *clusterNode, cmds []Cmder, failedCmds *cmdsMap, +) error { + return node.Client.hooks.processPipeline(ctx, cmds, func(ctx context.Context, cmds []Cmder) error { + return node.Client.withConn(ctx, func(ctx context.Context, cn *pool.Conn) error { + err := cn.WithWriter(ctx, c.opt.WriteTimeout, func(wr *proto.Writer) error { + return writeCmds(wr, cmds) + }) + if err != nil { + return err + } + + return cn.WithReader(ctx, c.opt.ReadTimeout, func(rd *proto.Reader) error { + return c.pipelineReadCmds(ctx, node, rd, cmds, failedCmds) + }) + }) + }) +} + +func (c *ClusterClient) pipelineReadCmds( + ctx context.Context, + node *clusterNode, + rd *proto.Reader, + cmds []Cmder, + failedCmds *cmdsMap, +) error { + for _, cmd := range cmds { + err := cmd.readReply(rd) + cmd.SetErr(err) + + if err == nil { + continue + } + + if c.checkMovedErr(ctx, cmd, err, failedCmds) { + continue + } + + if c.opt.ReadOnly && isLoadingError(err) { + node.MarkAsFailing() + return err + } + if isRedisError(err) { + continue + } + return err + } + return nil +} + +func (c *ClusterClient) checkMovedErr( + ctx context.Context, cmd Cmder, err error, failedCmds *cmdsMap, +) bool { + moved, ask, addr := isMovedError(err) + if !moved && !ask { + return false + } + + node, err := c.nodes.GetOrCreate(addr) + if err != nil { + return false + } + + if moved { + c.state.LazyReload() + failedCmds.Add(node, cmd) + return true + } + + if ask { + failedCmds.Add(node, NewCmd(ctx, "asking"), cmd) + return true + } + + panic("not reached") +} + +// TxPipeline acts like Pipeline, but wraps queued commands with MULTI/EXEC. +func (c *ClusterClient) TxPipeline() Pipeliner { + pipe := Pipeline{ + ctx: c.ctx, + exec: c.processTxPipeline, + } + pipe.init() + return &pipe +} + +func (c *ClusterClient) TxPipelined(ctx context.Context, fn func(Pipeliner) error) ([]Cmder, error) { + return c.TxPipeline().Pipelined(ctx, fn) +} + +func (c *ClusterClient) processTxPipeline(ctx context.Context, cmds []Cmder) error { + return c.hooks.processTxPipeline(ctx, cmds, c._processTxPipeline) +} + +func (c *ClusterClient) _processTxPipeline(ctx context.Context, cmds []Cmder) error { + // Trim multi .. exec. + cmds = cmds[1 : len(cmds)-1] + + state, err := c.state.Get(ctx) + if err != nil { + setCmdsErr(cmds, err) + return err + } + + cmdsMap := c.mapCmdsBySlot(cmds) + for slot, cmds := range cmdsMap { + node, err := state.slotMasterNode(slot) + if err != nil { + setCmdsErr(cmds, err) + continue + } + + cmdsMap := map[*clusterNode][]Cmder{node: cmds} + for attempt := 0; attempt <= c.opt.MaxRedirects; attempt++ { + if attempt > 0 { + if err := internal.Sleep(ctx, c.retryBackoff(attempt)); err != nil { + setCmdsErr(cmds, err) + return err + } + } + + failedCmds := newCmdsMap() + var wg sync.WaitGroup + + for node, cmds := range cmdsMap { + wg.Add(1) + go func(node *clusterNode, cmds []Cmder) { + defer wg.Done() + + err := c._processTxPipelineNode(ctx, node, cmds, failedCmds) + if err == nil { + return + } + + if attempt < c.opt.MaxRedirects { + if err := c.mapCmdsByNode(ctx, failedCmds, cmds); err != nil { + setCmdsErr(cmds, err) + } + } else { + setCmdsErr(cmds, err) + } + }(node, cmds) + } + + wg.Wait() + if len(failedCmds.m) == 0 { + break + } + cmdsMap = failedCmds.m + } + } + + return cmdsFirstErr(cmds) +} + +func (c *ClusterClient) mapCmdsBySlot(cmds []Cmder) map[int][]Cmder { + cmdsMap := make(map[int][]Cmder) + for _, cmd := range cmds { + slot := c.cmdSlot(cmd) + cmdsMap[slot] = append(cmdsMap[slot], cmd) + } + return cmdsMap +} + +func (c *ClusterClient) _processTxPipelineNode( + ctx context.Context, node *clusterNode, cmds []Cmder, failedCmds *cmdsMap, +) error { + return node.Client.hooks.processTxPipeline(ctx, cmds, func(ctx context.Context, cmds []Cmder) error { + return node.Client.withConn(ctx, func(ctx context.Context, cn *pool.Conn) error { + err := cn.WithWriter(ctx, c.opt.WriteTimeout, func(wr *proto.Writer) error { + return writeCmds(wr, cmds) + }) + if err != nil { + return err + } + + return cn.WithReader(ctx, c.opt.ReadTimeout, func(rd *proto.Reader) error { + statusCmd := cmds[0].(*StatusCmd) + // Trim multi and exec. + cmds = cmds[1 : len(cmds)-1] + + err := c.txPipelineReadQueued(ctx, rd, statusCmd, cmds, failedCmds) + if err != nil { + moved, ask, addr := isMovedError(err) + if moved || ask { + return c.cmdsMoved(ctx, cmds, moved, ask, addr, failedCmds) + } + return err + } + + return pipelineReadCmds(rd, cmds) + }) + }) + }) +} + +func (c *ClusterClient) txPipelineReadQueued( + ctx context.Context, + rd *proto.Reader, + statusCmd *StatusCmd, + cmds []Cmder, + failedCmds *cmdsMap, +) error { + // Parse queued replies. + if err := statusCmd.readReply(rd); err != nil { + return err + } + + for _, cmd := range cmds { + err := statusCmd.readReply(rd) + if err == nil || c.checkMovedErr(ctx, cmd, err, failedCmds) || isRedisError(err) { + continue + } + return err + } + + // Parse number of replies. + line, err := rd.ReadLine() + if err != nil { + if err == Nil { + err = TxFailedErr + } + return err + } + + switch line[0] { + case proto.ErrorReply: + return proto.ParseErrorReply(line) + case proto.ArrayReply: + // ok + default: + return fmt.Errorf("redis: expected '*', but got line %q", line) + } + + return nil +} + +func (c *ClusterClient) cmdsMoved( + ctx context.Context, cmds []Cmder, + moved, ask bool, + addr string, + failedCmds *cmdsMap, +) error { + node, err := c.nodes.GetOrCreate(addr) + if err != nil { + return err + } + + if moved { + c.state.LazyReload() + for _, cmd := range cmds { + failedCmds.Add(node, cmd) + } + return nil + } + + if ask { + for _, cmd := range cmds { + failedCmds.Add(node, NewCmd(ctx, "asking"), cmd) + } + return nil + } + + return nil +} + +func (c *ClusterClient) Watch(ctx context.Context, fn func(*Tx) error, keys ...string) error { + if len(keys) == 0 { + return fmt.Errorf("redis: Watch requires at least one key") + } + + slot := hashtag.Slot(keys[0]) + for _, key := range keys[1:] { + if hashtag.Slot(key) != slot { + err := fmt.Errorf("redis: Watch requires all keys to be in the same slot") + return err + } + } + + node, err := c.slotMasterNode(ctx, slot) + if err != nil { + return err + } + + for attempt := 0; attempt <= c.opt.MaxRedirects; attempt++ { + if attempt > 0 { + if err := internal.Sleep(ctx, c.retryBackoff(attempt)); err != nil { + return err + } + } + + err = node.Client.Watch(ctx, fn, keys...) + if err == nil { + break + } + + moved, ask, addr := isMovedError(err) + if moved || ask { + node, err = c.nodes.GetOrCreate(addr) + if err != nil { + return err + } + continue + } + + if isReadOnly := isReadOnlyError(err); isReadOnly || err == pool.ErrClosed { + if isReadOnly { + c.state.LazyReload() + } + node, err = c.slotMasterNode(ctx, slot) + if err != nil { + return err + } + continue + } + + if shouldRetry(err, true) { + continue + } + + return err + } + + return err +} + +func (c *ClusterClient) pubSub() *PubSub { + var node *clusterNode + pubsub := &PubSub{ + opt: c.opt.clientOptions(), + + newConn: func(ctx context.Context, channels []string) (*pool.Conn, error) { + if node != nil { + panic("node != nil") + } + + var err error + if len(channels) > 0 { + slot := hashtag.Slot(channels[0]) + node, err = c.slotMasterNode(ctx, slot) + } else { + node, err = c.nodes.Random() + } + if err != nil { + return nil, err + } + + cn, err := node.Client.newConn(context.TODO()) + if err != nil { + node = nil + + return nil, err + } + + return cn, nil + }, + closeConn: func(cn *pool.Conn) error { + err := node.Client.connPool.CloseConn(cn) + node = nil + return err + }, + } + pubsub.init() + + return pubsub +} + +// Subscribe subscribes the client to the specified channels. +// Channels can be omitted to create empty subscription. +func (c *ClusterClient) Subscribe(ctx context.Context, channels ...string) *PubSub { + pubsub := c.pubSub() + if len(channels) > 0 { + _ = pubsub.Subscribe(ctx, channels...) + } + return pubsub +} + +// PSubscribe subscribes the client to the given patterns. +// Patterns can be omitted to create empty subscription. +func (c *ClusterClient) PSubscribe(ctx context.Context, channels ...string) *PubSub { + pubsub := c.pubSub() + if len(channels) > 0 { + _ = pubsub.PSubscribe(ctx, channels...) + } + return pubsub +} + +func (c *ClusterClient) retryBackoff(attempt int) time.Duration { + return internal.RetryBackoff(attempt, c.opt.MinRetryBackoff, c.opt.MaxRetryBackoff) +} + +func (c *ClusterClient) cmdsInfo(ctx context.Context) (map[string]*CommandInfo, error) { + // Try 3 random nodes. + const nodeLimit = 3 + + addrs, err := c.nodes.Addrs() + if err != nil { + return nil, err + } + + var firstErr error + + perm := rand.Perm(len(addrs)) + if len(perm) > nodeLimit { + perm = perm[:nodeLimit] + } + + for _, idx := range perm { + addr := addrs[idx] + + node, err := c.nodes.GetOrCreate(addr) + if err != nil { + if firstErr == nil { + firstErr = err + } + continue + } + + info, err := node.Client.Command(ctx).Result() + if err == nil { + return info, nil + } + if firstErr == nil { + firstErr = err + } + } + + if firstErr == nil { + panic("not reached") + } + return nil, firstErr +} + +func (c *ClusterClient) cmdInfo(name string) *CommandInfo { + cmdsInfo, err := c.cmdsInfoCache.Get(c.ctx) + if err != nil { + return nil + } + + info := cmdsInfo[name] + if info == nil { + internal.Logger.Printf(c.Context(), "info for cmd=%s not found", name) + } + return info +} + +func (c *ClusterClient) cmdSlot(cmd Cmder) int { + args := cmd.Args() + if args[0] == "cluster" && args[1] == "getkeysinslot" { + return args[2].(int) + } + + cmdInfo := c.cmdInfo(cmd.Name()) + return cmdSlot(cmd, cmdFirstKeyPos(cmd, cmdInfo)) +} + +func cmdSlot(cmd Cmder, pos int) int { + if pos == 0 { + return hashtag.RandomSlot() + } + firstKey := cmd.stringArg(pos) + return hashtag.Slot(firstKey) +} + +func (c *ClusterClient) cmdNode( + ctx context.Context, + cmdInfo *CommandInfo, + slot int, +) (*clusterNode, error) { + state, err := c.state.Get(ctx) + if err != nil { + return nil, err + } + + if c.opt.ReadOnly && cmdInfo != nil && cmdInfo.ReadOnly { + return c.slotReadOnlyNode(state, slot) + } + return state.slotMasterNode(slot) +} + +func (c *clusterClient) slotReadOnlyNode(state *clusterState, slot int) (*clusterNode, error) { + if c.opt.RouteByLatency { + return state.slotClosestNode(slot) + } + if c.opt.RouteRandomly { + return state.slotRandomNode(slot) + } + return state.slotSlaveNode(slot) +} + +func (c *ClusterClient) slotMasterNode(ctx context.Context, slot int) (*clusterNode, error) { + state, err := c.state.Get(ctx) + if err != nil { + return nil, err + } + return state.slotMasterNode(slot) +} + +// SlaveForKey gets a client for a replica node to run any command on it. +// This is especially useful if we want to run a particular lua script which has +// only read only commands on the replica. +// This is because other redis commands generally have a flag that points that +// they are read only and automatically run on the replica nodes +// if ClusterOptions.ReadOnly flag is set to true. +func (c *ClusterClient) SlaveForKey(ctx context.Context, key string) (*Client, error) { + state, err := c.state.Get(ctx) + if err != nil { + return nil, err + } + slot := hashtag.Slot(key) + node, err := c.slotReadOnlyNode(state, slot) + if err != nil { + return nil, err + } + return node.Client, err +} + +// MasterForKey return a client to the master node for a particular key. +func (c *ClusterClient) MasterForKey(ctx context.Context, key string) (*Client, error) { + slot := hashtag.Slot(key) + node, err := c.slotMasterNode(ctx, slot) + if err != nil { + return nil, err + } + return node.Client, err +} + +func appendUniqueNode(nodes []*clusterNode, node *clusterNode) []*clusterNode { + for _, n := range nodes { + if n == node { + return nodes + } + } + return append(nodes, node) +} + +func appendIfNotExists(ss []string, es ...string) []string { +loop: + for _, e := range es { + for _, s := range ss { + if s == e { + continue loop + } + } + ss = append(ss, e) + } + return ss +} + +//------------------------------------------------------------------------------ + +type cmdsMap struct { + mu sync.Mutex + m map[*clusterNode][]Cmder +} + +func newCmdsMap() *cmdsMap { + return &cmdsMap{ + m: make(map[*clusterNode][]Cmder), + } +} + +func (m *cmdsMap) Add(node *clusterNode, cmds ...Cmder) { + m.mu.Lock() + m.m[node] = append(m.m[node], cmds...) + m.mu.Unlock() +} diff --git a/vendor/github.com/go-redis/redis/v8/cluster_commands.go b/vendor/github.com/go-redis/redis/v8/cluster_commands.go new file mode 100644 index 0000000..085bce8 --- /dev/null +++ b/vendor/github.com/go-redis/redis/v8/cluster_commands.go @@ -0,0 +1,109 @@ +package redis + +import ( + "context" + "sync" + "sync/atomic" +) + +func (c *ClusterClient) DBSize(ctx context.Context) *IntCmd { + cmd := NewIntCmd(ctx, "dbsize") + _ = c.hooks.process(ctx, cmd, func(ctx context.Context, _ Cmder) error { + var size int64 + err := c.ForEachMaster(ctx, func(ctx context.Context, master *Client) error { + n, err := master.DBSize(ctx).Result() + if err != nil { + return err + } + atomic.AddInt64(&size, n) + return nil + }) + if err != nil { + cmd.SetErr(err) + } else { + cmd.val = size + } + return nil + }) + return cmd +} + +func (c *ClusterClient) ScriptLoad(ctx context.Context, script string) *StringCmd { + cmd := NewStringCmd(ctx, "script", "load", script) + _ = c.hooks.process(ctx, cmd, func(ctx context.Context, _ Cmder) error { + mu := &sync.Mutex{} + err := c.ForEachShard(ctx, func(ctx context.Context, shard *Client) error { + val, err := shard.ScriptLoad(ctx, script).Result() + if err != nil { + return err + } + + mu.Lock() + if cmd.Val() == "" { + cmd.val = val + } + mu.Unlock() + + return nil + }) + if err != nil { + cmd.SetErr(err) + } + return nil + }) + return cmd +} + +func (c *ClusterClient) ScriptFlush(ctx context.Context) *StatusCmd { + cmd := NewStatusCmd(ctx, "script", "flush") + _ = c.hooks.process(ctx, cmd, func(ctx context.Context, _ Cmder) error { + err := c.ForEachShard(ctx, func(ctx context.Context, shard *Client) error { + return shard.ScriptFlush(ctx).Err() + }) + if err != nil { + cmd.SetErr(err) + } + return nil + }) + return cmd +} + +func (c *ClusterClient) ScriptExists(ctx context.Context, hashes ...string) *BoolSliceCmd { + args := make([]interface{}, 2+len(hashes)) + args[0] = "script" + args[1] = "exists" + for i, hash := range hashes { + args[2+i] = hash + } + cmd := NewBoolSliceCmd(ctx, args...) + + result := make([]bool, len(hashes)) + for i := range result { + result[i] = true + } + + _ = c.hooks.process(ctx, cmd, func(ctx context.Context, _ Cmder) error { + mu := &sync.Mutex{} + err := c.ForEachShard(ctx, func(ctx context.Context, shard *Client) error { + val, err := shard.ScriptExists(ctx, hashes...).Result() + if err != nil { + return err + } + + mu.Lock() + for i, v := range val { + result[i] = result[i] && v + } + mu.Unlock() + + return nil + }) + if err != nil { + cmd.SetErr(err) + } else { + cmd.val = result + } + return nil + }) + return cmd +} diff --git a/vendor/github.com/go-redis/redis/v8/command.go b/vendor/github.com/go-redis/redis/v8/command.go new file mode 100644 index 0000000..4bb12a8 --- /dev/null +++ b/vendor/github.com/go-redis/redis/v8/command.go @@ -0,0 +1,3478 @@ +package redis + +import ( + "context" + "fmt" + "net" + "strconv" + "time" + + "github.com/go-redis/redis/v8/internal" + "github.com/go-redis/redis/v8/internal/hscan" + "github.com/go-redis/redis/v8/internal/proto" + "github.com/go-redis/redis/v8/internal/util" +) + +type Cmder interface { + Name() string + FullName() string + Args() []interface{} + String() string + stringArg(int) string + firstKeyPos() int8 + SetFirstKeyPos(int8) + + readTimeout() *time.Duration + readReply(rd *proto.Reader) error + + SetErr(error) + Err() error +} + +func setCmdsErr(cmds []Cmder, e error) { + for _, cmd := range cmds { + if cmd.Err() == nil { + cmd.SetErr(e) + } + } +} + +func cmdsFirstErr(cmds []Cmder) error { + for _, cmd := range cmds { + if err := cmd.Err(); err != nil { + return err + } + } + return nil +} + +func writeCmds(wr *proto.Writer, cmds []Cmder) error { + for _, cmd := range cmds { + if err := writeCmd(wr, cmd); err != nil { + return err + } + } + return nil +} + +func writeCmd(wr *proto.Writer, cmd Cmder) error { + return wr.WriteArgs(cmd.Args()) +} + +func cmdFirstKeyPos(cmd Cmder, info *CommandInfo) int { + if pos := cmd.firstKeyPos(); pos != 0 { + return int(pos) + } + + switch cmd.Name() { + case "eval", "evalsha": + if cmd.stringArg(2) != "0" { + return 3 + } + + return 0 + case "publish": + return 1 + case "memory": + // https://github.com/redis/redis/issues/7493 + if cmd.stringArg(1) == "usage" { + return 2 + } + } + + if info != nil { + return int(info.FirstKeyPos) + } + return 0 +} + +func cmdString(cmd Cmder, val interface{}) string { + b := make([]byte, 0, 64) + + for i, arg := range cmd.Args() { + if i > 0 { + b = append(b, ' ') + } + b = internal.AppendArg(b, arg) + } + + if err := cmd.Err(); err != nil { + b = append(b, ": "...) + b = append(b, err.Error()...) + } else if val != nil { + b = append(b, ": "...) + b = internal.AppendArg(b, val) + } + + return internal.String(b) +} + +//------------------------------------------------------------------------------ + +type baseCmd struct { + ctx context.Context + args []interface{} + err error + keyPos int8 + + _readTimeout *time.Duration +} + +var _ Cmder = (*Cmd)(nil) + +func (cmd *baseCmd) Name() string { + if len(cmd.args) == 0 { + return "" + } + // Cmd name must be lower cased. + return internal.ToLower(cmd.stringArg(0)) +} + +func (cmd *baseCmd) FullName() string { + switch name := cmd.Name(); name { + case "cluster", "command": + if len(cmd.args) == 1 { + return name + } + if s2, ok := cmd.args[1].(string); ok { + return name + " " + s2 + } + return name + default: + return name + } +} + +func (cmd *baseCmd) Args() []interface{} { + return cmd.args +} + +func (cmd *baseCmd) stringArg(pos int) string { + if pos < 0 || pos >= len(cmd.args) { + return "" + } + arg := cmd.args[pos] + switch v := arg.(type) { + case string: + return v + default: + // TODO: consider using appendArg + return fmt.Sprint(v) + } +} + +func (cmd *baseCmd) firstKeyPos() int8 { + return cmd.keyPos +} + +func (cmd *baseCmd) SetFirstKeyPos(keyPos int8) { + cmd.keyPos = keyPos +} + +func (cmd *baseCmd) SetErr(e error) { + cmd.err = e +} + +func (cmd *baseCmd) Err() error { + return cmd.err +} + +func (cmd *baseCmd) readTimeout() *time.Duration { + return cmd._readTimeout +} + +func (cmd *baseCmd) setReadTimeout(d time.Duration) { + cmd._readTimeout = &d +} + +//------------------------------------------------------------------------------ + +type Cmd struct { + baseCmd + + val interface{} +} + +func NewCmd(ctx context.Context, args ...interface{}) *Cmd { + return &Cmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *Cmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *Cmd) SetVal(val interface{}) { + cmd.val = val +} + +func (cmd *Cmd) Val() interface{} { + return cmd.val +} + +func (cmd *Cmd) Result() (interface{}, error) { + return cmd.val, cmd.err +} + +func (cmd *Cmd) Text() (string, error) { + if cmd.err != nil { + return "", cmd.err + } + return toString(cmd.val) +} + +func toString(val interface{}) (string, error) { + switch val := val.(type) { + case string: + return val, nil + default: + err := fmt.Errorf("redis: unexpected type=%T for String", val) + return "", err + } +} + +func (cmd *Cmd) Int() (int, error) { + if cmd.err != nil { + return 0, cmd.err + } + switch val := cmd.val.(type) { + case int64: + return int(val), nil + case string: + return strconv.Atoi(val) + default: + err := fmt.Errorf("redis: unexpected type=%T for Int", val) + return 0, err + } +} + +func (cmd *Cmd) Int64() (int64, error) { + if cmd.err != nil { + return 0, cmd.err + } + return toInt64(cmd.val) +} + +func toInt64(val interface{}) (int64, error) { + switch val := val.(type) { + case int64: + return val, nil + case string: + return strconv.ParseInt(val, 10, 64) + default: + err := fmt.Errorf("redis: unexpected type=%T for Int64", val) + return 0, err + } +} + +func (cmd *Cmd) Uint64() (uint64, error) { + if cmd.err != nil { + return 0, cmd.err + } + return toUint64(cmd.val) +} + +func toUint64(val interface{}) (uint64, error) { + switch val := val.(type) { + case int64: + return uint64(val), nil + case string: + return strconv.ParseUint(val, 10, 64) + default: + err := fmt.Errorf("redis: unexpected type=%T for Uint64", val) + return 0, err + } +} + +func (cmd *Cmd) Float32() (float32, error) { + if cmd.err != nil { + return 0, cmd.err + } + return toFloat32(cmd.val) +} + +func toFloat32(val interface{}) (float32, error) { + switch val := val.(type) { + case int64: + return float32(val), nil + case string: + f, err := strconv.ParseFloat(val, 32) + if err != nil { + return 0, err + } + return float32(f), nil + default: + err := fmt.Errorf("redis: unexpected type=%T for Float32", val) + return 0, err + } +} + +func (cmd *Cmd) Float64() (float64, error) { + if cmd.err != nil { + return 0, cmd.err + } + return toFloat64(cmd.val) +} + +func toFloat64(val interface{}) (float64, error) { + switch val := val.(type) { + case int64: + return float64(val), nil + case string: + return strconv.ParseFloat(val, 64) + default: + err := fmt.Errorf("redis: unexpected type=%T for Float64", val) + return 0, err + } +} + +func (cmd *Cmd) Bool() (bool, error) { + if cmd.err != nil { + return false, cmd.err + } + return toBool(cmd.val) +} + +func toBool(val interface{}) (bool, error) { + switch val := val.(type) { + case int64: + return val != 0, nil + case string: + return strconv.ParseBool(val) + default: + err := fmt.Errorf("redis: unexpected type=%T for Bool", val) + return false, err + } +} + +func (cmd *Cmd) Slice() ([]interface{}, error) { + if cmd.err != nil { + return nil, cmd.err + } + switch val := cmd.val.(type) { + case []interface{}: + return val, nil + default: + return nil, fmt.Errorf("redis: unexpected type=%T for Slice", val) + } +} + +func (cmd *Cmd) StringSlice() ([]string, error) { + slice, err := cmd.Slice() + if err != nil { + return nil, err + } + + ss := make([]string, len(slice)) + for i, iface := range slice { + val, err := toString(iface) + if err != nil { + return nil, err + } + ss[i] = val + } + return ss, nil +} + +func (cmd *Cmd) Int64Slice() ([]int64, error) { + slice, err := cmd.Slice() + if err != nil { + return nil, err + } + + nums := make([]int64, len(slice)) + for i, iface := range slice { + val, err := toInt64(iface) + if err != nil { + return nil, err + } + nums[i] = val + } + return nums, nil +} + +func (cmd *Cmd) Uint64Slice() ([]uint64, error) { + slice, err := cmd.Slice() + if err != nil { + return nil, err + } + + nums := make([]uint64, len(slice)) + for i, iface := range slice { + val, err := toUint64(iface) + if err != nil { + return nil, err + } + nums[i] = val + } + return nums, nil +} + +func (cmd *Cmd) Float32Slice() ([]float32, error) { + slice, err := cmd.Slice() + if err != nil { + return nil, err + } + + floats := make([]float32, len(slice)) + for i, iface := range slice { + val, err := toFloat32(iface) + if err != nil { + return nil, err + } + floats[i] = val + } + return floats, nil +} + +func (cmd *Cmd) Float64Slice() ([]float64, error) { + slice, err := cmd.Slice() + if err != nil { + return nil, err + } + + floats := make([]float64, len(slice)) + for i, iface := range slice { + val, err := toFloat64(iface) + if err != nil { + return nil, err + } + floats[i] = val + } + return floats, nil +} + +func (cmd *Cmd) BoolSlice() ([]bool, error) { + slice, err := cmd.Slice() + if err != nil { + return nil, err + } + + bools := make([]bool, len(slice)) + for i, iface := range slice { + val, err := toBool(iface) + if err != nil { + return nil, err + } + bools[i] = val + } + return bools, nil +} + +func (cmd *Cmd) readReply(rd *proto.Reader) (err error) { + cmd.val, err = rd.ReadReply(sliceParser) + return err +} + +// sliceParser implements proto.MultiBulkParse. +func sliceParser(rd *proto.Reader, n int64) (interface{}, error) { + vals := make([]interface{}, n) + for i := 0; i < len(vals); i++ { + v, err := rd.ReadReply(sliceParser) + if err != nil { + if err == Nil { + vals[i] = nil + continue + } + if err, ok := err.(proto.RedisError); ok { + vals[i] = err + continue + } + return nil, err + } + vals[i] = v + } + return vals, nil +} + +//------------------------------------------------------------------------------ + +type SliceCmd struct { + baseCmd + + val []interface{} +} + +var _ Cmder = (*SliceCmd)(nil) + +func NewSliceCmd(ctx context.Context, args ...interface{}) *SliceCmd { + return &SliceCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *SliceCmd) SetVal(val []interface{}) { + cmd.val = val +} + +func (cmd *SliceCmd) Val() []interface{} { + return cmd.val +} + +func (cmd *SliceCmd) Result() ([]interface{}, error) { + return cmd.val, cmd.err +} + +func (cmd *SliceCmd) String() string { + return cmdString(cmd, cmd.val) +} + +// Scan scans the results from the map into a destination struct. The map keys +// are matched in the Redis struct fields by the `redis:"field"` tag. +func (cmd *SliceCmd) Scan(dst interface{}) error { + if cmd.err != nil { + return cmd.err + } + + // Pass the list of keys and values. + // Skip the first two args for: HMGET key + var args []interface{} + if cmd.args[0] == "hmget" { + args = cmd.args[2:] + } else { + // Otherwise, it's: MGET field field ... + args = cmd.args[1:] + } + + return hscan.Scan(dst, args, cmd.val) +} + +func (cmd *SliceCmd) readReply(rd *proto.Reader) error { + v, err := rd.ReadArrayReply(sliceParser) + if err != nil { + return err + } + cmd.val = v.([]interface{}) + return nil +} + +//------------------------------------------------------------------------------ + +type StatusCmd struct { + baseCmd + + val string +} + +var _ Cmder = (*StatusCmd)(nil) + +func NewStatusCmd(ctx context.Context, args ...interface{}) *StatusCmd { + return &StatusCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *StatusCmd) SetVal(val string) { + cmd.val = val +} + +func (cmd *StatusCmd) Val() string { + return cmd.val +} + +func (cmd *StatusCmd) Result() (string, error) { + return cmd.val, cmd.err +} + +func (cmd *StatusCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *StatusCmd) readReply(rd *proto.Reader) (err error) { + cmd.val, err = rd.ReadString() + return err +} + +//------------------------------------------------------------------------------ + +type IntCmd struct { + baseCmd + + val int64 +} + +var _ Cmder = (*IntCmd)(nil) + +func NewIntCmd(ctx context.Context, args ...interface{}) *IntCmd { + return &IntCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *IntCmd) SetVal(val int64) { + cmd.val = val +} + +func (cmd *IntCmd) Val() int64 { + return cmd.val +} + +func (cmd *IntCmd) Result() (int64, error) { + return cmd.val, cmd.err +} + +func (cmd *IntCmd) Uint64() (uint64, error) { + return uint64(cmd.val), cmd.err +} + +func (cmd *IntCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *IntCmd) readReply(rd *proto.Reader) (err error) { + cmd.val, err = rd.ReadIntReply() + return err +} + +//------------------------------------------------------------------------------ + +type IntSliceCmd struct { + baseCmd + + val []int64 +} + +var _ Cmder = (*IntSliceCmd)(nil) + +func NewIntSliceCmd(ctx context.Context, args ...interface{}) *IntSliceCmd { + return &IntSliceCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *IntSliceCmd) SetVal(val []int64) { + cmd.val = val +} + +func (cmd *IntSliceCmd) Val() []int64 { + return cmd.val +} + +func (cmd *IntSliceCmd) Result() ([]int64, error) { + return cmd.val, cmd.err +} + +func (cmd *IntSliceCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *IntSliceCmd) readReply(rd *proto.Reader) error { + _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { + cmd.val = make([]int64, n) + for i := 0; i < len(cmd.val); i++ { + num, err := rd.ReadIntReply() + if err != nil { + return nil, err + } + cmd.val[i] = num + } + return nil, nil + }) + return err +} + +//------------------------------------------------------------------------------ + +type DurationCmd struct { + baseCmd + + val time.Duration + precision time.Duration +} + +var _ Cmder = (*DurationCmd)(nil) + +func NewDurationCmd(ctx context.Context, precision time.Duration, args ...interface{}) *DurationCmd { + return &DurationCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + precision: precision, + } +} + +func (cmd *DurationCmd) SetVal(val time.Duration) { + cmd.val = val +} + +func (cmd *DurationCmd) Val() time.Duration { + return cmd.val +} + +func (cmd *DurationCmd) Result() (time.Duration, error) { + return cmd.val, cmd.err +} + +func (cmd *DurationCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *DurationCmd) readReply(rd *proto.Reader) error { + n, err := rd.ReadIntReply() + if err != nil { + return err + } + switch n { + // -2 if the key does not exist + // -1 if the key exists but has no associated expire + case -2, -1: + cmd.val = time.Duration(n) + default: + cmd.val = time.Duration(n) * cmd.precision + } + return nil +} + +//------------------------------------------------------------------------------ + +type TimeCmd struct { + baseCmd + + val time.Time +} + +var _ Cmder = (*TimeCmd)(nil) + +func NewTimeCmd(ctx context.Context, args ...interface{}) *TimeCmd { + return &TimeCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *TimeCmd) SetVal(val time.Time) { + cmd.val = val +} + +func (cmd *TimeCmd) Val() time.Time { + return cmd.val +} + +func (cmd *TimeCmd) Result() (time.Time, error) { + return cmd.val, cmd.err +} + +func (cmd *TimeCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *TimeCmd) readReply(rd *proto.Reader) error { + _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { + if n != 2 { + return nil, fmt.Errorf("got %d elements, expected 2", n) + } + + sec, err := rd.ReadInt() + if err != nil { + return nil, err + } + + microsec, err := rd.ReadInt() + if err != nil { + return nil, err + } + + cmd.val = time.Unix(sec, microsec*1000) + return nil, nil + }) + return err +} + +//------------------------------------------------------------------------------ + +type BoolCmd struct { + baseCmd + + val bool +} + +var _ Cmder = (*BoolCmd)(nil) + +func NewBoolCmd(ctx context.Context, args ...interface{}) *BoolCmd { + return &BoolCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *BoolCmd) SetVal(val bool) { + cmd.val = val +} + +func (cmd *BoolCmd) Val() bool { + return cmd.val +} + +func (cmd *BoolCmd) Result() (bool, error) { + return cmd.val, cmd.err +} + +func (cmd *BoolCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *BoolCmd) readReply(rd *proto.Reader) error { + v, err := rd.ReadReply(nil) + // `SET key value NX` returns nil when key already exists. But + // `SETNX key value` returns bool (0/1). So convert nil to bool. + if err == Nil { + cmd.val = false + return nil + } + if err != nil { + return err + } + switch v := v.(type) { + case int64: + cmd.val = v == 1 + return nil + case string: + cmd.val = v == "OK" + return nil + default: + return fmt.Errorf("got %T, wanted int64 or string", v) + } +} + +//------------------------------------------------------------------------------ + +type StringCmd struct { + baseCmd + + val string +} + +var _ Cmder = (*StringCmd)(nil) + +func NewStringCmd(ctx context.Context, args ...interface{}) *StringCmd { + return &StringCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *StringCmd) SetVal(val string) { + cmd.val = val +} + +func (cmd *StringCmd) Val() string { + return cmd.val +} + +func (cmd *StringCmd) Result() (string, error) { + return cmd.Val(), cmd.err +} + +func (cmd *StringCmd) Bytes() ([]byte, error) { + return util.StringToBytes(cmd.val), cmd.err +} + +func (cmd *StringCmd) Bool() (bool, error) { + if cmd.err != nil { + return false, cmd.err + } + return strconv.ParseBool(cmd.val) +} + +func (cmd *StringCmd) Int() (int, error) { + if cmd.err != nil { + return 0, cmd.err + } + return strconv.Atoi(cmd.Val()) +} + +func (cmd *StringCmd) Int64() (int64, error) { + if cmd.err != nil { + return 0, cmd.err + } + return strconv.ParseInt(cmd.Val(), 10, 64) +} + +func (cmd *StringCmd) Uint64() (uint64, error) { + if cmd.err != nil { + return 0, cmd.err + } + return strconv.ParseUint(cmd.Val(), 10, 64) +} + +func (cmd *StringCmd) Float32() (float32, error) { + if cmd.err != nil { + return 0, cmd.err + } + f, err := strconv.ParseFloat(cmd.Val(), 32) + if err != nil { + return 0, err + } + return float32(f), nil +} + +func (cmd *StringCmd) Float64() (float64, error) { + if cmd.err != nil { + return 0, cmd.err + } + return strconv.ParseFloat(cmd.Val(), 64) +} + +func (cmd *StringCmd) Time() (time.Time, error) { + if cmd.err != nil { + return time.Time{}, cmd.err + } + return time.Parse(time.RFC3339Nano, cmd.Val()) +} + +func (cmd *StringCmd) Scan(val interface{}) error { + if cmd.err != nil { + return cmd.err + } + return proto.Scan([]byte(cmd.val), val) +} + +func (cmd *StringCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *StringCmd) readReply(rd *proto.Reader) (err error) { + cmd.val, err = rd.ReadString() + return err +} + +//------------------------------------------------------------------------------ + +type FloatCmd struct { + baseCmd + + val float64 +} + +var _ Cmder = (*FloatCmd)(nil) + +func NewFloatCmd(ctx context.Context, args ...interface{}) *FloatCmd { + return &FloatCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *FloatCmd) SetVal(val float64) { + cmd.val = val +} + +func (cmd *FloatCmd) Val() float64 { + return cmd.val +} + +func (cmd *FloatCmd) Result() (float64, error) { + return cmd.Val(), cmd.Err() +} + +func (cmd *FloatCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *FloatCmd) readReply(rd *proto.Reader) (err error) { + cmd.val, err = rd.ReadFloatReply() + return err +} + +//------------------------------------------------------------------------------ + +type FloatSliceCmd struct { + baseCmd + + val []float64 +} + +var _ Cmder = (*FloatSliceCmd)(nil) + +func NewFloatSliceCmd(ctx context.Context, args ...interface{}) *FloatSliceCmd { + return &FloatSliceCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *FloatSliceCmd) SetVal(val []float64) { + cmd.val = val +} + +func (cmd *FloatSliceCmd) Val() []float64 { + return cmd.val +} + +func (cmd *FloatSliceCmd) Result() ([]float64, error) { + return cmd.val, cmd.err +} + +func (cmd *FloatSliceCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *FloatSliceCmd) readReply(rd *proto.Reader) error { + _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { + cmd.val = make([]float64, n) + for i := 0; i < len(cmd.val); i++ { + switch num, err := rd.ReadFloatReply(); { + case err == Nil: + cmd.val[i] = 0 + case err != nil: + return nil, err + default: + cmd.val[i] = num + } + } + return nil, nil + }) + return err +} + +//------------------------------------------------------------------------------ + +type StringSliceCmd struct { + baseCmd + + val []string +} + +var _ Cmder = (*StringSliceCmd)(nil) + +func NewStringSliceCmd(ctx context.Context, args ...interface{}) *StringSliceCmd { + return &StringSliceCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *StringSliceCmd) SetVal(val []string) { + cmd.val = val +} + +func (cmd *StringSliceCmd) Val() []string { + return cmd.val +} + +func (cmd *StringSliceCmd) Result() ([]string, error) { + return cmd.Val(), cmd.Err() +} + +func (cmd *StringSliceCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *StringSliceCmd) ScanSlice(container interface{}) error { + return proto.ScanSlice(cmd.Val(), container) +} + +func (cmd *StringSliceCmd) readReply(rd *proto.Reader) error { + _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { + cmd.val = make([]string, n) + for i := 0; i < len(cmd.val); i++ { + switch s, err := rd.ReadString(); { + case err == Nil: + cmd.val[i] = "" + case err != nil: + return nil, err + default: + cmd.val[i] = s + } + } + return nil, nil + }) + return err +} + +//------------------------------------------------------------------------------ + +type BoolSliceCmd struct { + baseCmd + + val []bool +} + +var _ Cmder = (*BoolSliceCmd)(nil) + +func NewBoolSliceCmd(ctx context.Context, args ...interface{}) *BoolSliceCmd { + return &BoolSliceCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *BoolSliceCmd) SetVal(val []bool) { + cmd.val = val +} + +func (cmd *BoolSliceCmd) Val() []bool { + return cmd.val +} + +func (cmd *BoolSliceCmd) Result() ([]bool, error) { + return cmd.val, cmd.err +} + +func (cmd *BoolSliceCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *BoolSliceCmd) readReply(rd *proto.Reader) error { + _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { + cmd.val = make([]bool, n) + for i := 0; i < len(cmd.val); i++ { + n, err := rd.ReadIntReply() + if err != nil { + return nil, err + } + cmd.val[i] = n == 1 + } + return nil, nil + }) + return err +} + +//------------------------------------------------------------------------------ + +type StringStringMapCmd struct { + baseCmd + + val map[string]string +} + +var _ Cmder = (*StringStringMapCmd)(nil) + +func NewStringStringMapCmd(ctx context.Context, args ...interface{}) *StringStringMapCmd { + return &StringStringMapCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *StringStringMapCmd) SetVal(val map[string]string) { + cmd.val = val +} + +func (cmd *StringStringMapCmd) Val() map[string]string { + return cmd.val +} + +func (cmd *StringStringMapCmd) Result() (map[string]string, error) { + return cmd.val, cmd.err +} + +func (cmd *StringStringMapCmd) String() string { + return cmdString(cmd, cmd.val) +} + +// Scan scans the results from the map into a destination struct. The map keys +// are matched in the Redis struct fields by the `redis:"field"` tag. +func (cmd *StringStringMapCmd) Scan(dest interface{}) error { + if cmd.err != nil { + return cmd.err + } + + strct, err := hscan.Struct(dest) + if err != nil { + return err + } + + for k, v := range cmd.val { + if err := strct.Scan(k, v); err != nil { + return err + } + } + + return nil +} + +func (cmd *StringStringMapCmd) readReply(rd *proto.Reader) error { + _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { + cmd.val = make(map[string]string, n/2) + for i := int64(0); i < n; i += 2 { + key, err := rd.ReadString() + if err != nil { + return nil, err + } + + value, err := rd.ReadString() + if err != nil { + return nil, err + } + + cmd.val[key] = value + } + return nil, nil + }) + return err +} + +//------------------------------------------------------------------------------ + +type StringIntMapCmd struct { + baseCmd + + val map[string]int64 +} + +var _ Cmder = (*StringIntMapCmd)(nil) + +func NewStringIntMapCmd(ctx context.Context, args ...interface{}) *StringIntMapCmd { + return &StringIntMapCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *StringIntMapCmd) SetVal(val map[string]int64) { + cmd.val = val +} + +func (cmd *StringIntMapCmd) Val() map[string]int64 { + return cmd.val +} + +func (cmd *StringIntMapCmd) Result() (map[string]int64, error) { + return cmd.val, cmd.err +} + +func (cmd *StringIntMapCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *StringIntMapCmd) readReply(rd *proto.Reader) error { + _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { + cmd.val = make(map[string]int64, n/2) + for i := int64(0); i < n; i += 2 { + key, err := rd.ReadString() + if err != nil { + return nil, err + } + + n, err := rd.ReadIntReply() + if err != nil { + return nil, err + } + + cmd.val[key] = n + } + return nil, nil + }) + return err +} + +//------------------------------------------------------------------------------ + +type StringStructMapCmd struct { + baseCmd + + val map[string]struct{} +} + +var _ Cmder = (*StringStructMapCmd)(nil) + +func NewStringStructMapCmd(ctx context.Context, args ...interface{}) *StringStructMapCmd { + return &StringStructMapCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *StringStructMapCmd) SetVal(val map[string]struct{}) { + cmd.val = val +} + +func (cmd *StringStructMapCmd) Val() map[string]struct{} { + return cmd.val +} + +func (cmd *StringStructMapCmd) Result() (map[string]struct{}, error) { + return cmd.val, cmd.err +} + +func (cmd *StringStructMapCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *StringStructMapCmd) readReply(rd *proto.Reader) error { + _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { + cmd.val = make(map[string]struct{}, n) + for i := int64(0); i < n; i++ { + key, err := rd.ReadString() + if err != nil { + return nil, err + } + cmd.val[key] = struct{}{} + } + return nil, nil + }) + return err +} + +//------------------------------------------------------------------------------ + +type XMessage struct { + ID string + Values map[string]interface{} +} + +type XMessageSliceCmd struct { + baseCmd + + val []XMessage +} + +var _ Cmder = (*XMessageSliceCmd)(nil) + +func NewXMessageSliceCmd(ctx context.Context, args ...interface{}) *XMessageSliceCmd { + return &XMessageSliceCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *XMessageSliceCmd) SetVal(val []XMessage) { + cmd.val = val +} + +func (cmd *XMessageSliceCmd) Val() []XMessage { + return cmd.val +} + +func (cmd *XMessageSliceCmd) Result() ([]XMessage, error) { + return cmd.val, cmd.err +} + +func (cmd *XMessageSliceCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *XMessageSliceCmd) readReply(rd *proto.Reader) error { + var err error + cmd.val, err = readXMessageSlice(rd) + return err +} + +func readXMessageSlice(rd *proto.Reader) ([]XMessage, error) { + n, err := rd.ReadArrayLen() + if err != nil { + return nil, err + } + + msgs := make([]XMessage, n) + for i := 0; i < n; i++ { + var err error + msgs[i], err = readXMessage(rd) + if err != nil { + return nil, err + } + } + return msgs, nil +} + +func readXMessage(rd *proto.Reader) (XMessage, error) { + n, err := rd.ReadArrayLen() + if err != nil { + return XMessage{}, err + } + if n != 2 { + return XMessage{}, fmt.Errorf("got %d, wanted 2", n) + } + + id, err := rd.ReadString() + if err != nil { + return XMessage{}, err + } + + var values map[string]interface{} + + v, err := rd.ReadArrayReply(stringInterfaceMapParser) + if err != nil { + if err != proto.Nil { + return XMessage{}, err + } + } else { + values = v.(map[string]interface{}) + } + + return XMessage{ + ID: id, + Values: values, + }, nil +} + +// stringInterfaceMapParser implements proto.MultiBulkParse. +func stringInterfaceMapParser(rd *proto.Reader, n int64) (interface{}, error) { + m := make(map[string]interface{}, n/2) + for i := int64(0); i < n; i += 2 { + key, err := rd.ReadString() + if err != nil { + return nil, err + } + + value, err := rd.ReadString() + if err != nil { + return nil, err + } + + m[key] = value + } + return m, nil +} + +//------------------------------------------------------------------------------ + +type XStream struct { + Stream string + Messages []XMessage +} + +type XStreamSliceCmd struct { + baseCmd + + val []XStream +} + +var _ Cmder = (*XStreamSliceCmd)(nil) + +func NewXStreamSliceCmd(ctx context.Context, args ...interface{}) *XStreamSliceCmd { + return &XStreamSliceCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *XStreamSliceCmd) SetVal(val []XStream) { + cmd.val = val +} + +func (cmd *XStreamSliceCmd) Val() []XStream { + return cmd.val +} + +func (cmd *XStreamSliceCmd) Result() ([]XStream, error) { + return cmd.val, cmd.err +} + +func (cmd *XStreamSliceCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *XStreamSliceCmd) readReply(rd *proto.Reader) error { + _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { + cmd.val = make([]XStream, n) + for i := 0; i < len(cmd.val); i++ { + i := i + _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { + if n != 2 { + return nil, fmt.Errorf("got %d, wanted 2", n) + } + + stream, err := rd.ReadString() + if err != nil { + return nil, err + } + + msgs, err := readXMessageSlice(rd) + if err != nil { + return nil, err + } + + cmd.val[i] = XStream{ + Stream: stream, + Messages: msgs, + } + return nil, nil + }) + if err != nil { + return nil, err + } + } + return nil, nil + }) + return err +} + +//------------------------------------------------------------------------------ + +type XPending struct { + Count int64 + Lower string + Higher string + Consumers map[string]int64 +} + +type XPendingCmd struct { + baseCmd + val *XPending +} + +var _ Cmder = (*XPendingCmd)(nil) + +func NewXPendingCmd(ctx context.Context, args ...interface{}) *XPendingCmd { + return &XPendingCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *XPendingCmd) SetVal(val *XPending) { + cmd.val = val +} + +func (cmd *XPendingCmd) Val() *XPending { + return cmd.val +} + +func (cmd *XPendingCmd) Result() (*XPending, error) { + return cmd.val, cmd.err +} + +func (cmd *XPendingCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *XPendingCmd) readReply(rd *proto.Reader) error { + _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { + if n != 4 { + return nil, fmt.Errorf("got %d, wanted 4", n) + } + + count, err := rd.ReadIntReply() + if err != nil { + return nil, err + } + + lower, err := rd.ReadString() + if err != nil && err != Nil { + return nil, err + } + + higher, err := rd.ReadString() + if err != nil && err != Nil { + return nil, err + } + + cmd.val = &XPending{ + Count: count, + Lower: lower, + Higher: higher, + } + _, err = rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { + for i := int64(0); i < n; i++ { + _, err = rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { + if n != 2 { + return nil, fmt.Errorf("got %d, wanted 2", n) + } + + consumerName, err := rd.ReadString() + if err != nil { + return nil, err + } + + consumerPending, err := rd.ReadInt() + if err != nil { + return nil, err + } + + if cmd.val.Consumers == nil { + cmd.val.Consumers = make(map[string]int64) + } + cmd.val.Consumers[consumerName] = consumerPending + + return nil, nil + }) + if err != nil { + return nil, err + } + } + return nil, nil + }) + if err != nil && err != Nil { + return nil, err + } + + return nil, nil + }) + return err +} + +//------------------------------------------------------------------------------ + +type XPendingExt struct { + ID string + Consumer string + Idle time.Duration + RetryCount int64 +} + +type XPendingExtCmd struct { + baseCmd + val []XPendingExt +} + +var _ Cmder = (*XPendingExtCmd)(nil) + +func NewXPendingExtCmd(ctx context.Context, args ...interface{}) *XPendingExtCmd { + return &XPendingExtCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *XPendingExtCmd) SetVal(val []XPendingExt) { + cmd.val = val +} + +func (cmd *XPendingExtCmd) Val() []XPendingExt { + return cmd.val +} + +func (cmd *XPendingExtCmd) Result() ([]XPendingExt, error) { + return cmd.val, cmd.err +} + +func (cmd *XPendingExtCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *XPendingExtCmd) readReply(rd *proto.Reader) error { + _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { + cmd.val = make([]XPendingExt, 0, n) + for i := int64(0); i < n; i++ { + _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { + if n != 4 { + return nil, fmt.Errorf("got %d, wanted 4", n) + } + + id, err := rd.ReadString() + if err != nil { + return nil, err + } + + consumer, err := rd.ReadString() + if err != nil && err != Nil { + return nil, err + } + + idle, err := rd.ReadIntReply() + if err != nil && err != Nil { + return nil, err + } + + retryCount, err := rd.ReadIntReply() + if err != nil && err != Nil { + return nil, err + } + + cmd.val = append(cmd.val, XPendingExt{ + ID: id, + Consumer: consumer, + Idle: time.Duration(idle) * time.Millisecond, + RetryCount: retryCount, + }) + return nil, nil + }) + if err != nil { + return nil, err + } + } + return nil, nil + }) + return err +} + +//------------------------------------------------------------------------------ + +type XAutoClaimCmd struct { + baseCmd + + start string + val []XMessage +} + +var _ Cmder = (*XAutoClaimCmd)(nil) + +func NewXAutoClaimCmd(ctx context.Context, args ...interface{}) *XAutoClaimCmd { + return &XAutoClaimCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *XAutoClaimCmd) SetVal(val []XMessage, start string) { + cmd.val = val + cmd.start = start +} + +func (cmd *XAutoClaimCmd) Val() (messages []XMessage, start string) { + return cmd.val, cmd.start +} + +func (cmd *XAutoClaimCmd) Result() (messages []XMessage, start string, err error) { + return cmd.val, cmd.start, cmd.err +} + +func (cmd *XAutoClaimCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *XAutoClaimCmd) readReply(rd *proto.Reader) error { + _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { + if n != 2 { + return nil, fmt.Errorf("got %d, wanted 2", n) + } + var err error + + cmd.start, err = rd.ReadString() + if err != nil { + return nil, err + } + + cmd.val, err = readXMessageSlice(rd) + if err != nil { + return nil, err + } + + return nil, nil + }) + return err +} + +//------------------------------------------------------------------------------ + +type XAutoClaimJustIDCmd struct { + baseCmd + + start string + val []string +} + +var _ Cmder = (*XAutoClaimJustIDCmd)(nil) + +func NewXAutoClaimJustIDCmd(ctx context.Context, args ...interface{}) *XAutoClaimJustIDCmd { + return &XAutoClaimJustIDCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *XAutoClaimJustIDCmd) SetVal(val []string, start string) { + cmd.val = val + cmd.start = start +} + +func (cmd *XAutoClaimJustIDCmd) Val() (ids []string, start string) { + return cmd.val, cmd.start +} + +func (cmd *XAutoClaimJustIDCmd) Result() (ids []string, start string, err error) { + return cmd.val, cmd.start, cmd.err +} + +func (cmd *XAutoClaimJustIDCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *XAutoClaimJustIDCmd) readReply(rd *proto.Reader) error { + _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { + if n != 2 { + return nil, fmt.Errorf("got %d, wanted 2", n) + } + var err error + + cmd.start, err = rd.ReadString() + if err != nil { + return nil, err + } + + nn, err := rd.ReadArrayLen() + if err != nil { + return nil, err + } + + cmd.val = make([]string, nn) + for i := 0; i < nn; i++ { + cmd.val[i], err = rd.ReadString() + if err != nil { + return nil, err + } + } + + return nil, nil + }) + return err +} + +//------------------------------------------------------------------------------ + +type XInfoConsumersCmd struct { + baseCmd + val []XInfoConsumer +} + +type XInfoConsumer struct { + Name string + Pending int64 + Idle int64 +} + +var _ Cmder = (*XInfoConsumersCmd)(nil) + +func NewXInfoConsumersCmd(ctx context.Context, stream string, group string) *XInfoConsumersCmd { + return &XInfoConsumersCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: []interface{}{"xinfo", "consumers", stream, group}, + }, + } +} + +func (cmd *XInfoConsumersCmd) SetVal(val []XInfoConsumer) { + cmd.val = val +} + +func (cmd *XInfoConsumersCmd) Val() []XInfoConsumer { + return cmd.val +} + +func (cmd *XInfoConsumersCmd) Result() ([]XInfoConsumer, error) { + return cmd.val, cmd.err +} + +func (cmd *XInfoConsumersCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *XInfoConsumersCmd) readReply(rd *proto.Reader) error { + n, err := rd.ReadArrayLen() + if err != nil { + return err + } + + cmd.val = make([]XInfoConsumer, n) + + for i := 0; i < n; i++ { + cmd.val[i], err = readXConsumerInfo(rd) + if err != nil { + return err + } + } + + return nil +} + +func readXConsumerInfo(rd *proto.Reader) (XInfoConsumer, error) { + var consumer XInfoConsumer + + n, err := rd.ReadArrayLen() + if err != nil { + return consumer, err + } + if n != 6 { + return consumer, fmt.Errorf("redis: got %d elements in XINFO CONSUMERS reply, wanted 6", n) + } + + for i := 0; i < 3; i++ { + key, err := rd.ReadString() + if err != nil { + return consumer, err + } + + val, err := rd.ReadString() + if err != nil { + return consumer, err + } + + switch key { + case "name": + consumer.Name = val + case "pending": + consumer.Pending, err = strconv.ParseInt(val, 0, 64) + if err != nil { + return consumer, err + } + case "idle": + consumer.Idle, err = strconv.ParseInt(val, 0, 64) + if err != nil { + return consumer, err + } + default: + return consumer, fmt.Errorf("redis: unexpected content %s in XINFO CONSUMERS reply", key) + } + } + + return consumer, nil +} + +//------------------------------------------------------------------------------ + +type XInfoGroupsCmd struct { + baseCmd + val []XInfoGroup +} + +type XInfoGroup struct { + Name string + Consumers int64 + Pending int64 + LastDeliveredID string +} + +var _ Cmder = (*XInfoGroupsCmd)(nil) + +func NewXInfoGroupsCmd(ctx context.Context, stream string) *XInfoGroupsCmd { + return &XInfoGroupsCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: []interface{}{"xinfo", "groups", stream}, + }, + } +} + +func (cmd *XInfoGroupsCmd) SetVal(val []XInfoGroup) { + cmd.val = val +} + +func (cmd *XInfoGroupsCmd) Val() []XInfoGroup { + return cmd.val +} + +func (cmd *XInfoGroupsCmd) Result() ([]XInfoGroup, error) { + return cmd.val, cmd.err +} + +func (cmd *XInfoGroupsCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *XInfoGroupsCmd) readReply(rd *proto.Reader) error { + n, err := rd.ReadArrayLen() + if err != nil { + return err + } + + cmd.val = make([]XInfoGroup, n) + + for i := 0; i < n; i++ { + cmd.val[i], err = readXGroupInfo(rd) + if err != nil { + return err + } + } + + return nil +} + +func readXGroupInfo(rd *proto.Reader) (XInfoGroup, error) { + var group XInfoGroup + + n, err := rd.ReadArrayLen() + if err != nil { + return group, err + } + if n != 8 { + return group, fmt.Errorf("redis: got %d elements in XINFO GROUPS reply, wanted 8", n) + } + + for i := 0; i < 4; i++ { + key, err := rd.ReadString() + if err != nil { + return group, err + } + + val, err := rd.ReadString() + if err != nil { + return group, err + } + + switch key { + case "name": + group.Name = val + case "consumers": + group.Consumers, err = strconv.ParseInt(val, 0, 64) + if err != nil { + return group, err + } + case "pending": + group.Pending, err = strconv.ParseInt(val, 0, 64) + if err != nil { + return group, err + } + case "last-delivered-id": + group.LastDeliveredID = val + default: + return group, fmt.Errorf("redis: unexpected content %s in XINFO GROUPS reply", key) + } + } + + return group, nil +} + +//------------------------------------------------------------------------------ + +type XInfoStreamCmd struct { + baseCmd + val *XInfoStream +} + +type XInfoStream struct { + Length int64 + RadixTreeKeys int64 + RadixTreeNodes int64 + Groups int64 + LastGeneratedID string + FirstEntry XMessage + LastEntry XMessage +} + +var _ Cmder = (*XInfoStreamCmd)(nil) + +func NewXInfoStreamCmd(ctx context.Context, stream string) *XInfoStreamCmd { + return &XInfoStreamCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: []interface{}{"xinfo", "stream", stream}, + }, + } +} + +func (cmd *XInfoStreamCmd) SetVal(val *XInfoStream) { + cmd.val = val +} + +func (cmd *XInfoStreamCmd) Val() *XInfoStream { + return cmd.val +} + +func (cmd *XInfoStreamCmd) Result() (*XInfoStream, error) { + return cmd.val, cmd.err +} + +func (cmd *XInfoStreamCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *XInfoStreamCmd) readReply(rd *proto.Reader) error { + v, err := rd.ReadReply(xStreamInfoParser) + if err != nil { + return err + } + cmd.val = v.(*XInfoStream) + return nil +} + +func xStreamInfoParser(rd *proto.Reader, n int64) (interface{}, error) { + if n != 14 { + return nil, fmt.Errorf("redis: got %d elements in XINFO STREAM reply,"+ + "wanted 14", n) + } + var info XInfoStream + for i := 0; i < 7; i++ { + key, err := rd.ReadString() + if err != nil { + return nil, err + } + switch key { + case "length": + info.Length, err = rd.ReadIntReply() + case "radix-tree-keys": + info.RadixTreeKeys, err = rd.ReadIntReply() + case "radix-tree-nodes": + info.RadixTreeNodes, err = rd.ReadIntReply() + case "groups": + info.Groups, err = rd.ReadIntReply() + case "last-generated-id": + info.LastGeneratedID, err = rd.ReadString() + case "first-entry": + info.FirstEntry, err = readXMessage(rd) + if err == Nil { + err = nil + } + case "last-entry": + info.LastEntry, err = readXMessage(rd) + if err == Nil { + err = nil + } + default: + return nil, fmt.Errorf("redis: unexpected content %s "+ + "in XINFO STREAM reply", key) + } + if err != nil { + return nil, err + } + } + return &info, nil +} + +//------------------------------------------------------------------------------ + +type XInfoStreamFullCmd struct { + baseCmd + val *XInfoStreamFull +} + +type XInfoStreamFull struct { + Length int64 + RadixTreeKeys int64 + RadixTreeNodes int64 + LastGeneratedID string + Entries []XMessage + Groups []XInfoStreamGroup +} + +type XInfoStreamGroup struct { + Name string + LastDeliveredID string + PelCount int64 + Pending []XInfoStreamGroupPending + Consumers []XInfoStreamConsumer +} + +type XInfoStreamGroupPending struct { + ID string + Consumer string + DeliveryTime time.Time + DeliveryCount int64 +} + +type XInfoStreamConsumer struct { + Name string + SeenTime time.Time + PelCount int64 + Pending []XInfoStreamConsumerPending +} + +type XInfoStreamConsumerPending struct { + ID string + DeliveryTime time.Time + DeliveryCount int64 +} + +var _ Cmder = (*XInfoStreamFullCmd)(nil) + +func NewXInfoStreamFullCmd(ctx context.Context, args ...interface{}) *XInfoStreamFullCmd { + return &XInfoStreamFullCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *XInfoStreamFullCmd) SetVal(val *XInfoStreamFull) { + cmd.val = val +} + +func (cmd *XInfoStreamFullCmd) Val() *XInfoStreamFull { + return cmd.val +} + +func (cmd *XInfoStreamFullCmd) Result() (*XInfoStreamFull, error) { + return cmd.val, cmd.err +} + +func (cmd *XInfoStreamFullCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *XInfoStreamFullCmd) readReply(rd *proto.Reader) error { + n, err := rd.ReadArrayLen() + if err != nil { + return err + } + if n != 12 { + return fmt.Errorf("redis: got %d elements in XINFO STREAM FULL reply,"+ + "wanted 12", n) + } + + cmd.val = &XInfoStreamFull{} + + for i := 0; i < 6; i++ { + key, err := rd.ReadString() + if err != nil { + return err + } + + switch key { + case "length": + cmd.val.Length, err = rd.ReadIntReply() + case "radix-tree-keys": + cmd.val.RadixTreeKeys, err = rd.ReadIntReply() + case "radix-tree-nodes": + cmd.val.RadixTreeNodes, err = rd.ReadIntReply() + case "last-generated-id": + cmd.val.LastGeneratedID, err = rd.ReadString() + case "entries": + cmd.val.Entries, err = readXMessageSlice(rd) + case "groups": + cmd.val.Groups, err = readStreamGroups(rd) + default: + return fmt.Errorf("redis: unexpected content %s "+ + "in XINFO STREAM reply", key) + } + if err != nil { + return err + } + } + return nil +} + +func readStreamGroups(rd *proto.Reader) ([]XInfoStreamGroup, error) { + n, err := rd.ReadArrayLen() + if err != nil { + return nil, err + } + groups := make([]XInfoStreamGroup, 0, n) + for i := 0; i < n; i++ { + nn, err := rd.ReadArrayLen() + if err != nil { + return nil, err + } + if nn != 10 { + return nil, fmt.Errorf("redis: got %d elements in XINFO STREAM FULL reply,"+ + "wanted 10", nn) + } + + group := XInfoStreamGroup{} + + for f := 0; f < 5; f++ { + key, err := rd.ReadString() + if err != nil { + return nil, err + } + + switch key { + case "name": + group.Name, err = rd.ReadString() + case "last-delivered-id": + group.LastDeliveredID, err = rd.ReadString() + case "pel-count": + group.PelCount, err = rd.ReadIntReply() + case "pending": + group.Pending, err = readXInfoStreamGroupPending(rd) + case "consumers": + group.Consumers, err = readXInfoStreamConsumers(rd) + default: + return nil, fmt.Errorf("redis: unexpected content %s "+ + "in XINFO STREAM reply", key) + } + + if err != nil { + return nil, err + } + } + + groups = append(groups, group) + } + + return groups, nil +} + +func readXInfoStreamGroupPending(rd *proto.Reader) ([]XInfoStreamGroupPending, error) { + n, err := rd.ReadArrayLen() + if err != nil { + return nil, err + } + + pending := make([]XInfoStreamGroupPending, 0, n) + + for i := 0; i < n; i++ { + nn, err := rd.ReadArrayLen() + if err != nil { + return nil, err + } + if nn != 4 { + return nil, fmt.Errorf("redis: got %d elements in XINFO STREAM FULL reply,"+ + "wanted 4", nn) + } + + p := XInfoStreamGroupPending{} + + p.ID, err = rd.ReadString() + if err != nil { + return nil, err + } + + p.Consumer, err = rd.ReadString() + if err != nil { + return nil, err + } + + delivery, err := rd.ReadIntReply() + if err != nil { + return nil, err + } + p.DeliveryTime = time.Unix(delivery/1000, delivery%1000*int64(time.Millisecond)) + + p.DeliveryCount, err = rd.ReadIntReply() + if err != nil { + return nil, err + } + + pending = append(pending, p) + } + + return pending, nil +} + +func readXInfoStreamConsumers(rd *proto.Reader) ([]XInfoStreamConsumer, error) { + n, err := rd.ReadArrayLen() + if err != nil { + return nil, err + } + + consumers := make([]XInfoStreamConsumer, 0, n) + + for i := 0; i < n; i++ { + nn, err := rd.ReadArrayLen() + if err != nil { + return nil, err + } + if nn != 8 { + return nil, fmt.Errorf("redis: got %d elements in XINFO STREAM FULL reply,"+ + "wanted 8", nn) + } + + c := XInfoStreamConsumer{} + + for f := 0; f < 4; f++ { + cKey, err := rd.ReadString() + if err != nil { + return nil, err + } + + switch cKey { + case "name": + c.Name, err = rd.ReadString() + case "seen-time": + seen, err := rd.ReadIntReply() + if err != nil { + return nil, err + } + c.SeenTime = time.Unix(seen/1000, seen%1000*int64(time.Millisecond)) + case "pel-count": + c.PelCount, err = rd.ReadIntReply() + case "pending": + pendingNumber, err := rd.ReadArrayLen() + if err != nil { + return nil, err + } + + c.Pending = make([]XInfoStreamConsumerPending, 0, pendingNumber) + + for pn := 0; pn < pendingNumber; pn++ { + nn, err := rd.ReadArrayLen() + if err != nil { + return nil, err + } + if nn != 3 { + return nil, fmt.Errorf("redis: got %d elements in XINFO STREAM reply,"+ + "wanted 3", nn) + } + + p := XInfoStreamConsumerPending{} + + p.ID, err = rd.ReadString() + if err != nil { + return nil, err + } + + delivery, err := rd.ReadIntReply() + if err != nil { + return nil, err + } + p.DeliveryTime = time.Unix(delivery/1000, delivery%1000*int64(time.Millisecond)) + + p.DeliveryCount, err = rd.ReadIntReply() + if err != nil { + return nil, err + } + + c.Pending = append(c.Pending, p) + } + default: + return nil, fmt.Errorf("redis: unexpected content %s "+ + "in XINFO STREAM reply", cKey) + } + if err != nil { + return nil, err + } + } + consumers = append(consumers, c) + } + + return consumers, nil +} + +//------------------------------------------------------------------------------ + +type ZSliceCmd struct { + baseCmd + + val []Z +} + +var _ Cmder = (*ZSliceCmd)(nil) + +func NewZSliceCmd(ctx context.Context, args ...interface{}) *ZSliceCmd { + return &ZSliceCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *ZSliceCmd) SetVal(val []Z) { + cmd.val = val +} + +func (cmd *ZSliceCmd) Val() []Z { + return cmd.val +} + +func (cmd *ZSliceCmd) Result() ([]Z, error) { + return cmd.val, cmd.err +} + +func (cmd *ZSliceCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *ZSliceCmd) readReply(rd *proto.Reader) error { + _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { + cmd.val = make([]Z, n/2) + for i := 0; i < len(cmd.val); i++ { + member, err := rd.ReadString() + if err != nil { + return nil, err + } + + score, err := rd.ReadFloatReply() + if err != nil { + return nil, err + } + + cmd.val[i] = Z{ + Member: member, + Score: score, + } + } + return nil, nil + }) + return err +} + +//------------------------------------------------------------------------------ + +type ZWithKeyCmd struct { + baseCmd + + val *ZWithKey +} + +var _ Cmder = (*ZWithKeyCmd)(nil) + +func NewZWithKeyCmd(ctx context.Context, args ...interface{}) *ZWithKeyCmd { + return &ZWithKeyCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *ZWithKeyCmd) SetVal(val *ZWithKey) { + cmd.val = val +} + +func (cmd *ZWithKeyCmd) Val() *ZWithKey { + return cmd.val +} + +func (cmd *ZWithKeyCmd) Result() (*ZWithKey, error) { + return cmd.Val(), cmd.Err() +} + +func (cmd *ZWithKeyCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *ZWithKeyCmd) readReply(rd *proto.Reader) error { + _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { + if n != 3 { + return nil, fmt.Errorf("got %d elements, expected 3", n) + } + + cmd.val = &ZWithKey{} + var err error + + cmd.val.Key, err = rd.ReadString() + if err != nil { + return nil, err + } + + cmd.val.Member, err = rd.ReadString() + if err != nil { + return nil, err + } + + cmd.val.Score, err = rd.ReadFloatReply() + if err != nil { + return nil, err + } + + return nil, nil + }) + return err +} + +//------------------------------------------------------------------------------ + +type ScanCmd struct { + baseCmd + + page []string + cursor uint64 + + process cmdable +} + +var _ Cmder = (*ScanCmd)(nil) + +func NewScanCmd(ctx context.Context, process cmdable, args ...interface{}) *ScanCmd { + return &ScanCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + process: process, + } +} + +func (cmd *ScanCmd) SetVal(page []string, cursor uint64) { + cmd.page = page + cmd.cursor = cursor +} + +func (cmd *ScanCmd) Val() (keys []string, cursor uint64) { + return cmd.page, cmd.cursor +} + +func (cmd *ScanCmd) Result() (keys []string, cursor uint64, err error) { + return cmd.page, cmd.cursor, cmd.err +} + +func (cmd *ScanCmd) String() string { + return cmdString(cmd, cmd.page) +} + +func (cmd *ScanCmd) readReply(rd *proto.Reader) (err error) { + cmd.page, cmd.cursor, err = rd.ReadScanReply() + return err +} + +// Iterator creates a new ScanIterator. +func (cmd *ScanCmd) Iterator() *ScanIterator { + return &ScanIterator{ + cmd: cmd, + } +} + +//------------------------------------------------------------------------------ + +type ClusterNode struct { + ID string + Addr string +} + +type ClusterSlot struct { + Start int + End int + Nodes []ClusterNode +} + +type ClusterSlotsCmd struct { + baseCmd + + val []ClusterSlot +} + +var _ Cmder = (*ClusterSlotsCmd)(nil) + +func NewClusterSlotsCmd(ctx context.Context, args ...interface{}) *ClusterSlotsCmd { + return &ClusterSlotsCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *ClusterSlotsCmd) SetVal(val []ClusterSlot) { + cmd.val = val +} + +func (cmd *ClusterSlotsCmd) Val() []ClusterSlot { + return cmd.val +} + +func (cmd *ClusterSlotsCmd) Result() ([]ClusterSlot, error) { + return cmd.Val(), cmd.Err() +} + +func (cmd *ClusterSlotsCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *ClusterSlotsCmd) readReply(rd *proto.Reader) error { + _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { + cmd.val = make([]ClusterSlot, n) + for i := 0; i < len(cmd.val); i++ { + n, err := rd.ReadArrayLen() + if err != nil { + return nil, err + } + if n < 2 { + err := fmt.Errorf("redis: got %d elements in cluster info, expected at least 2", n) + return nil, err + } + + start, err := rd.ReadIntReply() + if err != nil { + return nil, err + } + + end, err := rd.ReadIntReply() + if err != nil { + return nil, err + } + + nodes := make([]ClusterNode, n-2) + for j := 0; j < len(nodes); j++ { + n, err := rd.ReadArrayLen() + if err != nil { + return nil, err + } + if n != 2 && n != 3 { + err := fmt.Errorf("got %d elements in cluster info address, expected 2 or 3", n) + return nil, err + } + + ip, err := rd.ReadString() + if err != nil { + return nil, err + } + + port, err := rd.ReadString() + if err != nil { + return nil, err + } + + nodes[j].Addr = net.JoinHostPort(ip, port) + + if n == 3 { + id, err := rd.ReadString() + if err != nil { + return nil, err + } + nodes[j].ID = id + } + } + + cmd.val[i] = ClusterSlot{ + Start: int(start), + End: int(end), + Nodes: nodes, + } + } + return nil, nil + }) + return err +} + +//------------------------------------------------------------------------------ + +// GeoLocation is used with GeoAdd to add geospatial location. +type GeoLocation struct { + Name string + Longitude, Latitude, Dist float64 + GeoHash int64 +} + +// GeoRadiusQuery is used with GeoRadius to query geospatial index. +type GeoRadiusQuery struct { + Radius float64 + // Can be m, km, ft, or mi. Default is km. + Unit string + WithCoord bool + WithDist bool + WithGeoHash bool + Count int + // Can be ASC or DESC. Default is no sort order. + Sort string + Store string + StoreDist string +} + +type GeoLocationCmd struct { + baseCmd + + q *GeoRadiusQuery + locations []GeoLocation +} + +var _ Cmder = (*GeoLocationCmd)(nil) + +func NewGeoLocationCmd(ctx context.Context, q *GeoRadiusQuery, args ...interface{}) *GeoLocationCmd { + return &GeoLocationCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: geoLocationArgs(q, args...), + }, + q: q, + } +} + +func geoLocationArgs(q *GeoRadiusQuery, args ...interface{}) []interface{} { + args = append(args, q.Radius) + if q.Unit != "" { + args = append(args, q.Unit) + } else { + args = append(args, "km") + } + if q.WithCoord { + args = append(args, "withcoord") + } + if q.WithDist { + args = append(args, "withdist") + } + if q.WithGeoHash { + args = append(args, "withhash") + } + if q.Count > 0 { + args = append(args, "count", q.Count) + } + if q.Sort != "" { + args = append(args, q.Sort) + } + if q.Store != "" { + args = append(args, "store") + args = append(args, q.Store) + } + if q.StoreDist != "" { + args = append(args, "storedist") + args = append(args, q.StoreDist) + } + return args +} + +func (cmd *GeoLocationCmd) SetVal(locations []GeoLocation) { + cmd.locations = locations +} + +func (cmd *GeoLocationCmd) Val() []GeoLocation { + return cmd.locations +} + +func (cmd *GeoLocationCmd) Result() ([]GeoLocation, error) { + return cmd.locations, cmd.err +} + +func (cmd *GeoLocationCmd) String() string { + return cmdString(cmd, cmd.locations) +} + +func (cmd *GeoLocationCmd) readReply(rd *proto.Reader) error { + v, err := rd.ReadArrayReply(newGeoLocationSliceParser(cmd.q)) + if err != nil { + return err + } + cmd.locations = v.([]GeoLocation) + return nil +} + +func newGeoLocationSliceParser(q *GeoRadiusQuery) proto.MultiBulkParse { + return func(rd *proto.Reader, n int64) (interface{}, error) { + locs := make([]GeoLocation, 0, n) + for i := int64(0); i < n; i++ { + v, err := rd.ReadReply(newGeoLocationParser(q)) + if err != nil { + return nil, err + } + switch vv := v.(type) { + case string: + locs = append(locs, GeoLocation{ + Name: vv, + }) + case *GeoLocation: + // TODO: avoid copying + locs = append(locs, *vv) + default: + return nil, fmt.Errorf("got %T, expected string or *GeoLocation", v) + } + } + return locs, nil + } +} + +func newGeoLocationParser(q *GeoRadiusQuery) proto.MultiBulkParse { + return func(rd *proto.Reader, n int64) (interface{}, error) { + var loc GeoLocation + var err error + + loc.Name, err = rd.ReadString() + if err != nil { + return nil, err + } + if q.WithDist { + loc.Dist, err = rd.ReadFloatReply() + if err != nil { + return nil, err + } + } + if q.WithGeoHash { + loc.GeoHash, err = rd.ReadIntReply() + if err != nil { + return nil, err + } + } + if q.WithCoord { + n, err := rd.ReadArrayLen() + if err != nil { + return nil, err + } + if n != 2 { + return nil, fmt.Errorf("got %d coordinates, expected 2", n) + } + + loc.Longitude, err = rd.ReadFloatReply() + if err != nil { + return nil, err + } + loc.Latitude, err = rd.ReadFloatReply() + if err != nil { + return nil, err + } + } + + return &loc, nil + } +} + +//------------------------------------------------------------------------------ + +// GeoSearchQuery is used for GEOSearch/GEOSearchStore command query. +type GeoSearchQuery struct { + Member string + + // Latitude and Longitude when using FromLonLat option. + Longitude float64 + Latitude float64 + + // Distance and unit when using ByRadius option. + // Can use m, km, ft, or mi. Default is km. + Radius float64 + RadiusUnit string + + // Height, width and unit when using ByBox option. + // Can be m, km, ft, or mi. Default is km. + BoxWidth float64 + BoxHeight float64 + BoxUnit string + + // Can be ASC or DESC. Default is no sort order. + Sort string + Count int + CountAny bool +} + +type GeoSearchLocationQuery struct { + GeoSearchQuery + + WithCoord bool + WithDist bool + WithHash bool +} + +type GeoSearchStoreQuery struct { + GeoSearchQuery + + // When using the StoreDist option, the command stores the items in a + // sorted set populated with their distance from the center of the circle or box, + // as a floating-point number, in the same unit specified for that shape. + StoreDist bool +} + +func geoSearchLocationArgs(q *GeoSearchLocationQuery, args []interface{}) []interface{} { + args = geoSearchArgs(&q.GeoSearchQuery, args) + + if q.WithCoord { + args = append(args, "withcoord") + } + if q.WithDist { + args = append(args, "withdist") + } + if q.WithHash { + args = append(args, "withhash") + } + + return args +} + +func geoSearchArgs(q *GeoSearchQuery, args []interface{}) []interface{} { + if q.Member != "" { + args = append(args, "frommember", q.Member) + } else { + args = append(args, "fromlonlat", q.Longitude, q.Latitude) + } + + if q.Radius > 0 { + if q.RadiusUnit == "" { + q.RadiusUnit = "km" + } + args = append(args, "byradius", q.Radius, q.RadiusUnit) + } else { + if q.BoxUnit == "" { + q.BoxUnit = "km" + } + args = append(args, "bybox", q.BoxWidth, q.BoxHeight, q.BoxUnit) + } + + if q.Sort != "" { + args = append(args, q.Sort) + } + + if q.Count > 0 { + args = append(args, "count", q.Count) + if q.CountAny { + args = append(args, "any") + } + } + + return args +} + +type GeoSearchLocationCmd struct { + baseCmd + + opt *GeoSearchLocationQuery + val []GeoLocation +} + +var _ Cmder = (*GeoSearchLocationCmd)(nil) + +func NewGeoSearchLocationCmd( + ctx context.Context, opt *GeoSearchLocationQuery, args ...interface{}, +) *GeoSearchLocationCmd { + return &GeoSearchLocationCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + opt: opt, + } +} + +func (cmd *GeoSearchLocationCmd) SetVal(val []GeoLocation) { + cmd.val = val +} + +func (cmd *GeoSearchLocationCmd) Val() []GeoLocation { + return cmd.val +} + +func (cmd *GeoSearchLocationCmd) Result() ([]GeoLocation, error) { + return cmd.val, cmd.err +} + +func (cmd *GeoSearchLocationCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *GeoSearchLocationCmd) readReply(rd *proto.Reader) error { + n, err := rd.ReadArrayLen() + if err != nil { + return err + } + + cmd.val = make([]GeoLocation, n) + for i := 0; i < n; i++ { + _, err = rd.ReadArrayLen() + if err != nil { + return err + } + + var loc GeoLocation + + loc.Name, err = rd.ReadString() + if err != nil { + return err + } + if cmd.opt.WithDist { + loc.Dist, err = rd.ReadFloatReply() + if err != nil { + return err + } + } + if cmd.opt.WithHash { + loc.GeoHash, err = rd.ReadIntReply() + if err != nil { + return err + } + } + if cmd.opt.WithCoord { + nn, err := rd.ReadArrayLen() + if err != nil { + return err + } + if nn != 2 { + return fmt.Errorf("got %d coordinates, expected 2", nn) + } + + loc.Longitude, err = rd.ReadFloatReply() + if err != nil { + return err + } + loc.Latitude, err = rd.ReadFloatReply() + if err != nil { + return err + } + } + + cmd.val[i] = loc + } + + return nil +} + +//------------------------------------------------------------------------------ + +type GeoPos struct { + Longitude, Latitude float64 +} + +type GeoPosCmd struct { + baseCmd + + val []*GeoPos +} + +var _ Cmder = (*GeoPosCmd)(nil) + +func NewGeoPosCmd(ctx context.Context, args ...interface{}) *GeoPosCmd { + return &GeoPosCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *GeoPosCmd) SetVal(val []*GeoPos) { + cmd.val = val +} + +func (cmd *GeoPosCmd) Val() []*GeoPos { + return cmd.val +} + +func (cmd *GeoPosCmd) Result() ([]*GeoPos, error) { + return cmd.Val(), cmd.Err() +} + +func (cmd *GeoPosCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *GeoPosCmd) readReply(rd *proto.Reader) error { + _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { + cmd.val = make([]*GeoPos, n) + for i := 0; i < len(cmd.val); i++ { + i := i + _, err := rd.ReadReply(func(rd *proto.Reader, n int64) (interface{}, error) { + longitude, err := rd.ReadFloatReply() + if err != nil { + return nil, err + } + + latitude, err := rd.ReadFloatReply() + if err != nil { + return nil, err + } + + cmd.val[i] = &GeoPos{ + Longitude: longitude, + Latitude: latitude, + } + return nil, nil + }) + if err != nil { + if err == Nil { + cmd.val[i] = nil + continue + } + return nil, err + } + } + return nil, nil + }) + return err +} + +//------------------------------------------------------------------------------ + +type CommandInfo struct { + Name string + Arity int8 + Flags []string + ACLFlags []string + FirstKeyPos int8 + LastKeyPos int8 + StepCount int8 + ReadOnly bool +} + +type CommandsInfoCmd struct { + baseCmd + + val map[string]*CommandInfo +} + +var _ Cmder = (*CommandsInfoCmd)(nil) + +func NewCommandsInfoCmd(ctx context.Context, args ...interface{}) *CommandsInfoCmd { + return &CommandsInfoCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *CommandsInfoCmd) SetVal(val map[string]*CommandInfo) { + cmd.val = val +} + +func (cmd *CommandsInfoCmd) Val() map[string]*CommandInfo { + return cmd.val +} + +func (cmd *CommandsInfoCmd) Result() (map[string]*CommandInfo, error) { + return cmd.Val(), cmd.Err() +} + +func (cmd *CommandsInfoCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *CommandsInfoCmd) readReply(rd *proto.Reader) error { + _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { + cmd.val = make(map[string]*CommandInfo, n) + for i := int64(0); i < n; i++ { + v, err := rd.ReadReply(commandInfoParser) + if err != nil { + return nil, err + } + vv := v.(*CommandInfo) + cmd.val[vv.Name] = vv + } + return nil, nil + }) + return err +} + +func commandInfoParser(rd *proto.Reader, n int64) (interface{}, error) { + const numArgRedis5 = 6 + const numArgRedis6 = 7 + + switch n { + case numArgRedis5, numArgRedis6: + // continue + default: + return nil, fmt.Errorf("redis: got %d elements in COMMAND reply, wanted 7", n) + } + + var cmd CommandInfo + var err error + + cmd.Name, err = rd.ReadString() + if err != nil { + return nil, err + } + + arity, err := rd.ReadIntReply() + if err != nil { + return nil, err + } + cmd.Arity = int8(arity) + + _, err = rd.ReadReply(func(rd *proto.Reader, n int64) (interface{}, error) { + cmd.Flags = make([]string, n) + for i := 0; i < len(cmd.Flags); i++ { + switch s, err := rd.ReadString(); { + case err == Nil: + cmd.Flags[i] = "" + case err != nil: + return nil, err + default: + cmd.Flags[i] = s + } + } + return nil, nil + }) + if err != nil { + return nil, err + } + + firstKeyPos, err := rd.ReadIntReply() + if err != nil { + return nil, err + } + cmd.FirstKeyPos = int8(firstKeyPos) + + lastKeyPos, err := rd.ReadIntReply() + if err != nil { + return nil, err + } + cmd.LastKeyPos = int8(lastKeyPos) + + stepCount, err := rd.ReadIntReply() + if err != nil { + return nil, err + } + cmd.StepCount = int8(stepCount) + + for _, flag := range cmd.Flags { + if flag == "readonly" { + cmd.ReadOnly = true + break + } + } + + if n == numArgRedis5 { + return &cmd, nil + } + + _, err = rd.ReadReply(func(rd *proto.Reader, n int64) (interface{}, error) { + cmd.ACLFlags = make([]string, n) + for i := 0; i < len(cmd.ACLFlags); i++ { + switch s, err := rd.ReadString(); { + case err == Nil: + cmd.ACLFlags[i] = "" + case err != nil: + return nil, err + default: + cmd.ACLFlags[i] = s + } + } + return nil, nil + }) + if err != nil { + return nil, err + } + + return &cmd, nil +} + +//------------------------------------------------------------------------------ + +type cmdsInfoCache struct { + fn func(ctx context.Context) (map[string]*CommandInfo, error) + + once internal.Once + cmds map[string]*CommandInfo +} + +func newCmdsInfoCache(fn func(ctx context.Context) (map[string]*CommandInfo, error)) *cmdsInfoCache { + return &cmdsInfoCache{ + fn: fn, + } +} + +func (c *cmdsInfoCache) Get(ctx context.Context) (map[string]*CommandInfo, error) { + err := c.once.Do(func() error { + cmds, err := c.fn(ctx) + if err != nil { + return err + } + + // Extensions have cmd names in upper case. Convert them to lower case. + for k, v := range cmds { + lower := internal.ToLower(k) + if lower != k { + cmds[lower] = v + } + } + + c.cmds = cmds + return nil + }) + return c.cmds, err +} + +//------------------------------------------------------------------------------ + +type SlowLog struct { + ID int64 + Time time.Time + Duration time.Duration + Args []string + // These are also optional fields emitted only by Redis 4.0 or greater: + // https://redis.io/commands/slowlog#output-format + ClientAddr string + ClientName string +} + +type SlowLogCmd struct { + baseCmd + + val []SlowLog +} + +var _ Cmder = (*SlowLogCmd)(nil) + +func NewSlowLogCmd(ctx context.Context, args ...interface{}) *SlowLogCmd { + return &SlowLogCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *SlowLogCmd) SetVal(val []SlowLog) { + cmd.val = val +} + +func (cmd *SlowLogCmd) Val() []SlowLog { + return cmd.val +} + +func (cmd *SlowLogCmd) Result() ([]SlowLog, error) { + return cmd.Val(), cmd.Err() +} + +func (cmd *SlowLogCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *SlowLogCmd) readReply(rd *proto.Reader) error { + _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { + cmd.val = make([]SlowLog, n) + for i := 0; i < len(cmd.val); i++ { + n, err := rd.ReadArrayLen() + if err != nil { + return nil, err + } + if n < 4 { + err := fmt.Errorf("redis: got %d elements in slowlog get, expected at least 4", n) + return nil, err + } + + id, err := rd.ReadIntReply() + if err != nil { + return nil, err + } + + createdAt, err := rd.ReadIntReply() + if err != nil { + return nil, err + } + createdAtTime := time.Unix(createdAt, 0) + + costs, err := rd.ReadIntReply() + if err != nil { + return nil, err + } + costsDuration := time.Duration(costs) * time.Microsecond + + cmdLen, err := rd.ReadArrayLen() + if err != nil { + return nil, err + } + if cmdLen < 1 { + err := fmt.Errorf("redis: got %d elements commands reply in slowlog get, expected at least 1", cmdLen) + return nil, err + } + + cmdString := make([]string, cmdLen) + for i := 0; i < cmdLen; i++ { + cmdString[i], err = rd.ReadString() + if err != nil { + return nil, err + } + } + + var address, name string + for i := 4; i < n; i++ { + str, err := rd.ReadString() + if err != nil { + return nil, err + } + if i == 4 { + address = str + } else if i == 5 { + name = str + } + } + + cmd.val[i] = SlowLog{ + ID: id, + Time: createdAtTime, + Duration: costsDuration, + Args: cmdString, + ClientAddr: address, + ClientName: name, + } + } + return nil, nil + }) + return err +} diff --git a/vendor/github.com/go-redis/redis/v8/commands.go b/vendor/github.com/go-redis/redis/v8/commands.go new file mode 100644 index 0000000..bbfe089 --- /dev/null +++ b/vendor/github.com/go-redis/redis/v8/commands.go @@ -0,0 +1,3475 @@ +package redis + +import ( + "context" + "errors" + "io" + "time" + + "github.com/go-redis/redis/v8/internal" +) + +// KeepTTL is a Redis KEEPTTL option to keep existing TTL, it requires your redis-server version >= 6.0, +// otherwise you will receive an error: (error) ERR syntax error. +// For example: +// +// rdb.Set(ctx, key, value, redis.KeepTTL) +const KeepTTL = -1 + +func usePrecise(dur time.Duration) bool { + return dur < time.Second || dur%time.Second != 0 +} + +func formatMs(ctx context.Context, dur time.Duration) int64 { + if dur > 0 && dur < time.Millisecond { + internal.Logger.Printf( + ctx, + "specified duration is %s, but minimal supported value is %s - truncating to 1ms", + dur, time.Millisecond, + ) + return 1 + } + return int64(dur / time.Millisecond) +} + +func formatSec(ctx context.Context, dur time.Duration) int64 { + if dur > 0 && dur < time.Second { + internal.Logger.Printf( + ctx, + "specified duration is %s, but minimal supported value is %s - truncating to 1s", + dur, time.Second, + ) + return 1 + } + return int64(dur / time.Second) +} + +func appendArgs(dst, src []interface{}) []interface{} { + if len(src) == 1 { + return appendArg(dst, src[0]) + } + + dst = append(dst, src...) + return dst +} + +func appendArg(dst []interface{}, arg interface{}) []interface{} { + switch arg := arg.(type) { + case []string: + for _, s := range arg { + dst = append(dst, s) + } + return dst + case []interface{}: + dst = append(dst, arg...) + return dst + case map[string]interface{}: + for k, v := range arg { + dst = append(dst, k, v) + } + return dst + case map[string]string: + for k, v := range arg { + dst = append(dst, k, v) + } + return dst + default: + return append(dst, arg) + } +} + +type Cmdable interface { + Pipeline() Pipeliner + Pipelined(ctx context.Context, fn func(Pipeliner) error) ([]Cmder, error) + + TxPipelined(ctx context.Context, fn func(Pipeliner) error) ([]Cmder, error) + TxPipeline() Pipeliner + + Command(ctx context.Context) *CommandsInfoCmd + ClientGetName(ctx context.Context) *StringCmd + Echo(ctx context.Context, message interface{}) *StringCmd + Ping(ctx context.Context) *StatusCmd + Quit(ctx context.Context) *StatusCmd + Del(ctx context.Context, keys ...string) *IntCmd + Unlink(ctx context.Context, keys ...string) *IntCmd + Dump(ctx context.Context, key string) *StringCmd + Exists(ctx context.Context, keys ...string) *IntCmd + Expire(ctx context.Context, key string, expiration time.Duration) *BoolCmd + ExpireAt(ctx context.Context, key string, tm time.Time) *BoolCmd + ExpireNX(ctx context.Context, key string, expiration time.Duration) *BoolCmd + ExpireXX(ctx context.Context, key string, expiration time.Duration) *BoolCmd + ExpireGT(ctx context.Context, key string, expiration time.Duration) *BoolCmd + ExpireLT(ctx context.Context, key string, expiration time.Duration) *BoolCmd + Keys(ctx context.Context, pattern string) *StringSliceCmd + Migrate(ctx context.Context, host, port, key string, db int, timeout time.Duration) *StatusCmd + Move(ctx context.Context, key string, db int) *BoolCmd + ObjectRefCount(ctx context.Context, key string) *IntCmd + ObjectEncoding(ctx context.Context, key string) *StringCmd + ObjectIdleTime(ctx context.Context, key string) *DurationCmd + Persist(ctx context.Context, key string) *BoolCmd + PExpire(ctx context.Context, key string, expiration time.Duration) *BoolCmd + PExpireAt(ctx context.Context, key string, tm time.Time) *BoolCmd + PTTL(ctx context.Context, key string) *DurationCmd + RandomKey(ctx context.Context) *StringCmd + Rename(ctx context.Context, key, newkey string) *StatusCmd + RenameNX(ctx context.Context, key, newkey string) *BoolCmd + Restore(ctx context.Context, key string, ttl time.Duration, value string) *StatusCmd + RestoreReplace(ctx context.Context, key string, ttl time.Duration, value string) *StatusCmd + Sort(ctx context.Context, key string, sort *Sort) *StringSliceCmd + SortStore(ctx context.Context, key, store string, sort *Sort) *IntCmd + SortInterfaces(ctx context.Context, key string, sort *Sort) *SliceCmd + Touch(ctx context.Context, keys ...string) *IntCmd + TTL(ctx context.Context, key string) *DurationCmd + Type(ctx context.Context, key string) *StatusCmd + Append(ctx context.Context, key, value string) *IntCmd + Decr(ctx context.Context, key string) *IntCmd + DecrBy(ctx context.Context, key string, decrement int64) *IntCmd + Get(ctx context.Context, key string) *StringCmd + GetRange(ctx context.Context, key string, start, end int64) *StringCmd + GetSet(ctx context.Context, key string, value interface{}) *StringCmd + GetEx(ctx context.Context, key string, expiration time.Duration) *StringCmd + GetDel(ctx context.Context, key string) *StringCmd + Incr(ctx context.Context, key string) *IntCmd + IncrBy(ctx context.Context, key string, value int64) *IntCmd + IncrByFloat(ctx context.Context, key string, value float64) *FloatCmd + MGet(ctx context.Context, keys ...string) *SliceCmd + MSet(ctx context.Context, values ...interface{}) *StatusCmd + MSetNX(ctx context.Context, values ...interface{}) *BoolCmd + Set(ctx context.Context, key string, value interface{}, expiration time.Duration) *StatusCmd + SetArgs(ctx context.Context, key string, value interface{}, a SetArgs) *StatusCmd + // TODO: rename to SetEx + SetEX(ctx context.Context, key string, value interface{}, expiration time.Duration) *StatusCmd + SetNX(ctx context.Context, key string, value interface{}, expiration time.Duration) *BoolCmd + SetXX(ctx context.Context, key string, value interface{}, expiration time.Duration) *BoolCmd + SetRange(ctx context.Context, key string, offset int64, value string) *IntCmd + StrLen(ctx context.Context, key string) *IntCmd + Copy(ctx context.Context, sourceKey string, destKey string, db int, replace bool) *IntCmd + + GetBit(ctx context.Context, key string, offset int64) *IntCmd + SetBit(ctx context.Context, key string, offset int64, value int) *IntCmd + BitCount(ctx context.Context, key string, bitCount *BitCount) *IntCmd + BitOpAnd(ctx context.Context, destKey string, keys ...string) *IntCmd + BitOpOr(ctx context.Context, destKey string, keys ...string) *IntCmd + BitOpXor(ctx context.Context, destKey string, keys ...string) *IntCmd + BitOpNot(ctx context.Context, destKey string, key string) *IntCmd + BitPos(ctx context.Context, key string, bit int64, pos ...int64) *IntCmd + BitField(ctx context.Context, key string, args ...interface{}) *IntSliceCmd + + Scan(ctx context.Context, cursor uint64, match string, count int64) *ScanCmd + ScanType(ctx context.Context, cursor uint64, match string, count int64, keyType string) *ScanCmd + SScan(ctx context.Context, key string, cursor uint64, match string, count int64) *ScanCmd + HScan(ctx context.Context, key string, cursor uint64, match string, count int64) *ScanCmd + ZScan(ctx context.Context, key string, cursor uint64, match string, count int64) *ScanCmd + + HDel(ctx context.Context, key string, fields ...string) *IntCmd + HExists(ctx context.Context, key, field string) *BoolCmd + HGet(ctx context.Context, key, field string) *StringCmd + HGetAll(ctx context.Context, key string) *StringStringMapCmd + HIncrBy(ctx context.Context, key, field string, incr int64) *IntCmd + HIncrByFloat(ctx context.Context, key, field string, incr float64) *FloatCmd + HKeys(ctx context.Context, key string) *StringSliceCmd + HLen(ctx context.Context, key string) *IntCmd + HMGet(ctx context.Context, key string, fields ...string) *SliceCmd + HSet(ctx context.Context, key string, values ...interface{}) *IntCmd + HMSet(ctx context.Context, key string, values ...interface{}) *BoolCmd + HSetNX(ctx context.Context, key, field string, value interface{}) *BoolCmd + HVals(ctx context.Context, key string) *StringSliceCmd + HRandField(ctx context.Context, key string, count int, withValues bool) *StringSliceCmd + + BLPop(ctx context.Context, timeout time.Duration, keys ...string) *StringSliceCmd + BRPop(ctx context.Context, timeout time.Duration, keys ...string) *StringSliceCmd + BRPopLPush(ctx context.Context, source, destination string, timeout time.Duration) *StringCmd + LIndex(ctx context.Context, key string, index int64) *StringCmd + LInsert(ctx context.Context, key, op string, pivot, value interface{}) *IntCmd + LInsertBefore(ctx context.Context, key string, pivot, value interface{}) *IntCmd + LInsertAfter(ctx context.Context, key string, pivot, value interface{}) *IntCmd + LLen(ctx context.Context, key string) *IntCmd + LPop(ctx context.Context, key string) *StringCmd + LPopCount(ctx context.Context, key string, count int) *StringSliceCmd + LPos(ctx context.Context, key string, value string, args LPosArgs) *IntCmd + LPosCount(ctx context.Context, key string, value string, count int64, args LPosArgs) *IntSliceCmd + LPush(ctx context.Context, key string, values ...interface{}) *IntCmd + LPushX(ctx context.Context, key string, values ...interface{}) *IntCmd + LRange(ctx context.Context, key string, start, stop int64) *StringSliceCmd + LRem(ctx context.Context, key string, count int64, value interface{}) *IntCmd + LSet(ctx context.Context, key string, index int64, value interface{}) *StatusCmd + LTrim(ctx context.Context, key string, start, stop int64) *StatusCmd + RPop(ctx context.Context, key string) *StringCmd + RPopCount(ctx context.Context, key string, count int) *StringSliceCmd + RPopLPush(ctx context.Context, source, destination string) *StringCmd + RPush(ctx context.Context, key string, values ...interface{}) *IntCmd + RPushX(ctx context.Context, key string, values ...interface{}) *IntCmd + LMove(ctx context.Context, source, destination, srcpos, destpos string) *StringCmd + BLMove(ctx context.Context, source, destination, srcpos, destpos string, timeout time.Duration) *StringCmd + + SAdd(ctx context.Context, key string, members ...interface{}) *IntCmd + SCard(ctx context.Context, key string) *IntCmd + SDiff(ctx context.Context, keys ...string) *StringSliceCmd + SDiffStore(ctx context.Context, destination string, keys ...string) *IntCmd + SInter(ctx context.Context, keys ...string) *StringSliceCmd + SInterStore(ctx context.Context, destination string, keys ...string) *IntCmd + SIsMember(ctx context.Context, key string, member interface{}) *BoolCmd + SMIsMember(ctx context.Context, key string, members ...interface{}) *BoolSliceCmd + SMembers(ctx context.Context, key string) *StringSliceCmd + SMembersMap(ctx context.Context, key string) *StringStructMapCmd + SMove(ctx context.Context, source, destination string, member interface{}) *BoolCmd + SPop(ctx context.Context, key string) *StringCmd + SPopN(ctx context.Context, key string, count int64) *StringSliceCmd + SRandMember(ctx context.Context, key string) *StringCmd + SRandMemberN(ctx context.Context, key string, count int64) *StringSliceCmd + SRem(ctx context.Context, key string, members ...interface{}) *IntCmd + SUnion(ctx context.Context, keys ...string) *StringSliceCmd + SUnionStore(ctx context.Context, destination string, keys ...string) *IntCmd + + XAdd(ctx context.Context, a *XAddArgs) *StringCmd + XDel(ctx context.Context, stream string, ids ...string) *IntCmd + XLen(ctx context.Context, stream string) *IntCmd + XRange(ctx context.Context, stream, start, stop string) *XMessageSliceCmd + XRangeN(ctx context.Context, stream, start, stop string, count int64) *XMessageSliceCmd + XRevRange(ctx context.Context, stream string, start, stop string) *XMessageSliceCmd + XRevRangeN(ctx context.Context, stream string, start, stop string, count int64) *XMessageSliceCmd + XRead(ctx context.Context, a *XReadArgs) *XStreamSliceCmd + XReadStreams(ctx context.Context, streams ...string) *XStreamSliceCmd + XGroupCreate(ctx context.Context, stream, group, start string) *StatusCmd + XGroupCreateMkStream(ctx context.Context, stream, group, start string) *StatusCmd + XGroupSetID(ctx context.Context, stream, group, start string) *StatusCmd + XGroupDestroy(ctx context.Context, stream, group string) *IntCmd + XGroupCreateConsumer(ctx context.Context, stream, group, consumer string) *IntCmd + XGroupDelConsumer(ctx context.Context, stream, group, consumer string) *IntCmd + XReadGroup(ctx context.Context, a *XReadGroupArgs) *XStreamSliceCmd + XAck(ctx context.Context, stream, group string, ids ...string) *IntCmd + XPending(ctx context.Context, stream, group string) *XPendingCmd + XPendingExt(ctx context.Context, a *XPendingExtArgs) *XPendingExtCmd + XClaim(ctx context.Context, a *XClaimArgs) *XMessageSliceCmd + XClaimJustID(ctx context.Context, a *XClaimArgs) *StringSliceCmd + XAutoClaim(ctx context.Context, a *XAutoClaimArgs) *XAutoClaimCmd + XAutoClaimJustID(ctx context.Context, a *XAutoClaimArgs) *XAutoClaimJustIDCmd + + // TODO: XTrim and XTrimApprox remove in v9. + XTrim(ctx context.Context, key string, maxLen int64) *IntCmd + XTrimApprox(ctx context.Context, key string, maxLen int64) *IntCmd + XTrimMaxLen(ctx context.Context, key string, maxLen int64) *IntCmd + XTrimMaxLenApprox(ctx context.Context, key string, maxLen, limit int64) *IntCmd + XTrimMinID(ctx context.Context, key string, minID string) *IntCmd + XTrimMinIDApprox(ctx context.Context, key string, minID string, limit int64) *IntCmd + XInfoGroups(ctx context.Context, key string) *XInfoGroupsCmd + XInfoStream(ctx context.Context, key string) *XInfoStreamCmd + XInfoStreamFull(ctx context.Context, key string, count int) *XInfoStreamFullCmd + XInfoConsumers(ctx context.Context, key string, group string) *XInfoConsumersCmd + + BZPopMax(ctx context.Context, timeout time.Duration, keys ...string) *ZWithKeyCmd + BZPopMin(ctx context.Context, timeout time.Duration, keys ...string) *ZWithKeyCmd + + // TODO: remove + // ZAddCh + // ZIncr + // ZAddNXCh + // ZAddXXCh + // ZIncrNX + // ZIncrXX + // in v9. + // use ZAddArgs and ZAddArgsIncr. + + ZAdd(ctx context.Context, key string, members ...*Z) *IntCmd + ZAddNX(ctx context.Context, key string, members ...*Z) *IntCmd + ZAddXX(ctx context.Context, key string, members ...*Z) *IntCmd + ZAddCh(ctx context.Context, key string, members ...*Z) *IntCmd + ZAddNXCh(ctx context.Context, key string, members ...*Z) *IntCmd + ZAddXXCh(ctx context.Context, key string, members ...*Z) *IntCmd + ZAddArgs(ctx context.Context, key string, args ZAddArgs) *IntCmd + ZAddArgsIncr(ctx context.Context, key string, args ZAddArgs) *FloatCmd + ZIncr(ctx context.Context, key string, member *Z) *FloatCmd + ZIncrNX(ctx context.Context, key string, member *Z) *FloatCmd + ZIncrXX(ctx context.Context, key string, member *Z) *FloatCmd + ZCard(ctx context.Context, key string) *IntCmd + ZCount(ctx context.Context, key, min, max string) *IntCmd + ZLexCount(ctx context.Context, key, min, max string) *IntCmd + ZIncrBy(ctx context.Context, key string, increment float64, member string) *FloatCmd + ZInter(ctx context.Context, store *ZStore) *StringSliceCmd + ZInterWithScores(ctx context.Context, store *ZStore) *ZSliceCmd + ZInterStore(ctx context.Context, destination string, store *ZStore) *IntCmd + ZMScore(ctx context.Context, key string, members ...string) *FloatSliceCmd + ZPopMax(ctx context.Context, key string, count ...int64) *ZSliceCmd + ZPopMin(ctx context.Context, key string, count ...int64) *ZSliceCmd + ZRange(ctx context.Context, key string, start, stop int64) *StringSliceCmd + ZRangeWithScores(ctx context.Context, key string, start, stop int64) *ZSliceCmd + ZRangeByScore(ctx context.Context, key string, opt *ZRangeBy) *StringSliceCmd + ZRangeByLex(ctx context.Context, key string, opt *ZRangeBy) *StringSliceCmd + ZRangeByScoreWithScores(ctx context.Context, key string, opt *ZRangeBy) *ZSliceCmd + ZRangeArgs(ctx context.Context, z ZRangeArgs) *StringSliceCmd + ZRangeArgsWithScores(ctx context.Context, z ZRangeArgs) *ZSliceCmd + ZRangeStore(ctx context.Context, dst string, z ZRangeArgs) *IntCmd + ZRank(ctx context.Context, key, member string) *IntCmd + ZRem(ctx context.Context, key string, members ...interface{}) *IntCmd + ZRemRangeByRank(ctx context.Context, key string, start, stop int64) *IntCmd + ZRemRangeByScore(ctx context.Context, key, min, max string) *IntCmd + ZRemRangeByLex(ctx context.Context, key, min, max string) *IntCmd + ZRevRange(ctx context.Context, key string, start, stop int64) *StringSliceCmd + ZRevRangeWithScores(ctx context.Context, key string, start, stop int64) *ZSliceCmd + ZRevRangeByScore(ctx context.Context, key string, opt *ZRangeBy) *StringSliceCmd + ZRevRangeByLex(ctx context.Context, key string, opt *ZRangeBy) *StringSliceCmd + ZRevRangeByScoreWithScores(ctx context.Context, key string, opt *ZRangeBy) *ZSliceCmd + ZRevRank(ctx context.Context, key, member string) *IntCmd + ZScore(ctx context.Context, key, member string) *FloatCmd + ZUnionStore(ctx context.Context, dest string, store *ZStore) *IntCmd + ZUnion(ctx context.Context, store ZStore) *StringSliceCmd + ZUnionWithScores(ctx context.Context, store ZStore) *ZSliceCmd + ZRandMember(ctx context.Context, key string, count int, withScores bool) *StringSliceCmd + ZDiff(ctx context.Context, keys ...string) *StringSliceCmd + ZDiffWithScores(ctx context.Context, keys ...string) *ZSliceCmd + ZDiffStore(ctx context.Context, destination string, keys ...string) *IntCmd + + PFAdd(ctx context.Context, key string, els ...interface{}) *IntCmd + PFCount(ctx context.Context, keys ...string) *IntCmd + PFMerge(ctx context.Context, dest string, keys ...string) *StatusCmd + + BgRewriteAOF(ctx context.Context) *StatusCmd + BgSave(ctx context.Context) *StatusCmd + ClientKill(ctx context.Context, ipPort string) *StatusCmd + ClientKillByFilter(ctx context.Context, keys ...string) *IntCmd + ClientList(ctx context.Context) *StringCmd + ClientPause(ctx context.Context, dur time.Duration) *BoolCmd + ClientID(ctx context.Context) *IntCmd + ConfigGet(ctx context.Context, parameter string) *SliceCmd + ConfigResetStat(ctx context.Context) *StatusCmd + ConfigSet(ctx context.Context, parameter, value string) *StatusCmd + ConfigRewrite(ctx context.Context) *StatusCmd + DBSize(ctx context.Context) *IntCmd + FlushAll(ctx context.Context) *StatusCmd + FlushAllAsync(ctx context.Context) *StatusCmd + FlushDB(ctx context.Context) *StatusCmd + FlushDBAsync(ctx context.Context) *StatusCmd + Info(ctx context.Context, section ...string) *StringCmd + LastSave(ctx context.Context) *IntCmd + Save(ctx context.Context) *StatusCmd + Shutdown(ctx context.Context) *StatusCmd + ShutdownSave(ctx context.Context) *StatusCmd + ShutdownNoSave(ctx context.Context) *StatusCmd + SlaveOf(ctx context.Context, host, port string) *StatusCmd + Time(ctx context.Context) *TimeCmd + DebugObject(ctx context.Context, key string) *StringCmd + ReadOnly(ctx context.Context) *StatusCmd + ReadWrite(ctx context.Context) *StatusCmd + MemoryUsage(ctx context.Context, key string, samples ...int) *IntCmd + + Eval(ctx context.Context, script string, keys []string, args ...interface{}) *Cmd + EvalSha(ctx context.Context, sha1 string, keys []string, args ...interface{}) *Cmd + ScriptExists(ctx context.Context, hashes ...string) *BoolSliceCmd + ScriptFlush(ctx context.Context) *StatusCmd + ScriptKill(ctx context.Context) *StatusCmd + ScriptLoad(ctx context.Context, script string) *StringCmd + + Publish(ctx context.Context, channel string, message interface{}) *IntCmd + PubSubChannels(ctx context.Context, pattern string) *StringSliceCmd + PubSubNumSub(ctx context.Context, channels ...string) *StringIntMapCmd + PubSubNumPat(ctx context.Context) *IntCmd + + ClusterSlots(ctx context.Context) *ClusterSlotsCmd + ClusterNodes(ctx context.Context) *StringCmd + ClusterMeet(ctx context.Context, host, port string) *StatusCmd + ClusterForget(ctx context.Context, nodeID string) *StatusCmd + ClusterReplicate(ctx context.Context, nodeID string) *StatusCmd + ClusterResetSoft(ctx context.Context) *StatusCmd + ClusterResetHard(ctx context.Context) *StatusCmd + ClusterInfo(ctx context.Context) *StringCmd + ClusterKeySlot(ctx context.Context, key string) *IntCmd + ClusterGetKeysInSlot(ctx context.Context, slot int, count int) *StringSliceCmd + ClusterCountFailureReports(ctx context.Context, nodeID string) *IntCmd + ClusterCountKeysInSlot(ctx context.Context, slot int) *IntCmd + ClusterDelSlots(ctx context.Context, slots ...int) *StatusCmd + ClusterDelSlotsRange(ctx context.Context, min, max int) *StatusCmd + ClusterSaveConfig(ctx context.Context) *StatusCmd + ClusterSlaves(ctx context.Context, nodeID string) *StringSliceCmd + ClusterFailover(ctx context.Context) *StatusCmd + ClusterAddSlots(ctx context.Context, slots ...int) *StatusCmd + ClusterAddSlotsRange(ctx context.Context, min, max int) *StatusCmd + + GeoAdd(ctx context.Context, key string, geoLocation ...*GeoLocation) *IntCmd + GeoPos(ctx context.Context, key string, members ...string) *GeoPosCmd + GeoRadius(ctx context.Context, key string, longitude, latitude float64, query *GeoRadiusQuery) *GeoLocationCmd + GeoRadiusStore(ctx context.Context, key string, longitude, latitude float64, query *GeoRadiusQuery) *IntCmd + GeoRadiusByMember(ctx context.Context, key, member string, query *GeoRadiusQuery) *GeoLocationCmd + GeoRadiusByMemberStore(ctx context.Context, key, member string, query *GeoRadiusQuery) *IntCmd + GeoSearch(ctx context.Context, key string, q *GeoSearchQuery) *StringSliceCmd + GeoSearchLocation(ctx context.Context, key string, q *GeoSearchLocationQuery) *GeoSearchLocationCmd + GeoSearchStore(ctx context.Context, key, store string, q *GeoSearchStoreQuery) *IntCmd + GeoDist(ctx context.Context, key string, member1, member2, unit string) *FloatCmd + GeoHash(ctx context.Context, key string, members ...string) *StringSliceCmd +} + +type StatefulCmdable interface { + Cmdable + Auth(ctx context.Context, password string) *StatusCmd + AuthACL(ctx context.Context, username, password string) *StatusCmd + Select(ctx context.Context, index int) *StatusCmd + SwapDB(ctx context.Context, index1, index2 int) *StatusCmd + ClientSetName(ctx context.Context, name string) *BoolCmd +} + +var ( + _ Cmdable = (*Client)(nil) + _ Cmdable = (*Tx)(nil) + _ Cmdable = (*Ring)(nil) + _ Cmdable = (*ClusterClient)(nil) +) + +type cmdable func(ctx context.Context, cmd Cmder) error + +type statefulCmdable func(ctx context.Context, cmd Cmder) error + +//------------------------------------------------------------------------------ + +func (c statefulCmdable) Auth(ctx context.Context, password string) *StatusCmd { + cmd := NewStatusCmd(ctx, "auth", password) + _ = c(ctx, cmd) + return cmd +} + +// AuthACL Perform an AUTH command, using the given user and pass. +// Should be used to authenticate the current connection with one of the connections defined in the ACL list +// when connecting to a Redis 6.0 instance, or greater, that is using the Redis ACL system. +func (c statefulCmdable) AuthACL(ctx context.Context, username, password string) *StatusCmd { + cmd := NewStatusCmd(ctx, "auth", username, password) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) Wait(ctx context.Context, numSlaves int, timeout time.Duration) *IntCmd { + cmd := NewIntCmd(ctx, "wait", numSlaves, int(timeout/time.Millisecond)) + cmd.setReadTimeout(timeout) + _ = c(ctx, cmd) + return cmd +} + +func (c statefulCmdable) Select(ctx context.Context, index int) *StatusCmd { + cmd := NewStatusCmd(ctx, "select", index) + _ = c(ctx, cmd) + return cmd +} + +func (c statefulCmdable) SwapDB(ctx context.Context, index1, index2 int) *StatusCmd { + cmd := NewStatusCmd(ctx, "swapdb", index1, index2) + _ = c(ctx, cmd) + return cmd +} + +// ClientSetName assigns a name to the connection. +func (c statefulCmdable) ClientSetName(ctx context.Context, name string) *BoolCmd { + cmd := NewBoolCmd(ctx, "client", "setname", name) + _ = c(ctx, cmd) + return cmd +} + +//------------------------------------------------------------------------------ + +func (c cmdable) Command(ctx context.Context) *CommandsInfoCmd { + cmd := NewCommandsInfoCmd(ctx, "command") + _ = c(ctx, cmd) + return cmd +} + +// ClientGetName returns the name of the connection. +func (c cmdable) ClientGetName(ctx context.Context) *StringCmd { + cmd := NewStringCmd(ctx, "client", "getname") + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) Echo(ctx context.Context, message interface{}) *StringCmd { + cmd := NewStringCmd(ctx, "echo", message) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) Ping(ctx context.Context) *StatusCmd { + cmd := NewStatusCmd(ctx, "ping") + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) Quit(_ context.Context) *StatusCmd { + panic("not implemented") +} + +func (c cmdable) Del(ctx context.Context, keys ...string) *IntCmd { + args := make([]interface{}, 1+len(keys)) + args[0] = "del" + for i, key := range keys { + args[1+i] = key + } + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) Unlink(ctx context.Context, keys ...string) *IntCmd { + args := make([]interface{}, 1+len(keys)) + args[0] = "unlink" + for i, key := range keys { + args[1+i] = key + } + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) Dump(ctx context.Context, key string) *StringCmd { + cmd := NewStringCmd(ctx, "dump", key) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) Exists(ctx context.Context, keys ...string) *IntCmd { + args := make([]interface{}, 1+len(keys)) + args[0] = "exists" + for i, key := range keys { + args[1+i] = key + } + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) Expire(ctx context.Context, key string, expiration time.Duration) *BoolCmd { + return c.expire(ctx, key, expiration, "") +} + +func (c cmdable) ExpireNX(ctx context.Context, key string, expiration time.Duration) *BoolCmd { + return c.expire(ctx, key, expiration, "NX") +} + +func (c cmdable) ExpireXX(ctx context.Context, key string, expiration time.Duration) *BoolCmd { + return c.expire(ctx, key, expiration, "XX") +} + +func (c cmdable) ExpireGT(ctx context.Context, key string, expiration time.Duration) *BoolCmd { + return c.expire(ctx, key, expiration, "GT") +} + +func (c cmdable) ExpireLT(ctx context.Context, key string, expiration time.Duration) *BoolCmd { + return c.expire(ctx, key, expiration, "LT") +} + +func (c cmdable) expire( + ctx context.Context, key string, expiration time.Duration, mode string, +) *BoolCmd { + args := make([]interface{}, 3, 4) + args[0] = "expire" + args[1] = key + args[2] = formatSec(ctx, expiration) + if mode != "" { + args = append(args, mode) + } + + cmd := NewBoolCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ExpireAt(ctx context.Context, key string, tm time.Time) *BoolCmd { + cmd := NewBoolCmd(ctx, "expireat", key, tm.Unix()) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) Keys(ctx context.Context, pattern string) *StringSliceCmd { + cmd := NewStringSliceCmd(ctx, "keys", pattern) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) Migrate(ctx context.Context, host, port, key string, db int, timeout time.Duration) *StatusCmd { + cmd := NewStatusCmd( + ctx, + "migrate", + host, + port, + key, + db, + formatMs(ctx, timeout), + ) + cmd.setReadTimeout(timeout) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) Move(ctx context.Context, key string, db int) *BoolCmd { + cmd := NewBoolCmd(ctx, "move", key, db) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ObjectRefCount(ctx context.Context, key string) *IntCmd { + cmd := NewIntCmd(ctx, "object", "refcount", key) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ObjectEncoding(ctx context.Context, key string) *StringCmd { + cmd := NewStringCmd(ctx, "object", "encoding", key) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ObjectIdleTime(ctx context.Context, key string) *DurationCmd { + cmd := NewDurationCmd(ctx, time.Second, "object", "idletime", key) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) Persist(ctx context.Context, key string) *BoolCmd { + cmd := NewBoolCmd(ctx, "persist", key) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) PExpire(ctx context.Context, key string, expiration time.Duration) *BoolCmd { + cmd := NewBoolCmd(ctx, "pexpire", key, formatMs(ctx, expiration)) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) PExpireAt(ctx context.Context, key string, tm time.Time) *BoolCmd { + cmd := NewBoolCmd( + ctx, + "pexpireat", + key, + tm.UnixNano()/int64(time.Millisecond), + ) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) PTTL(ctx context.Context, key string) *DurationCmd { + cmd := NewDurationCmd(ctx, time.Millisecond, "pttl", key) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) RandomKey(ctx context.Context) *StringCmd { + cmd := NewStringCmd(ctx, "randomkey") + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) Rename(ctx context.Context, key, newkey string) *StatusCmd { + cmd := NewStatusCmd(ctx, "rename", key, newkey) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) RenameNX(ctx context.Context, key, newkey string) *BoolCmd { + cmd := NewBoolCmd(ctx, "renamenx", key, newkey) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) Restore(ctx context.Context, key string, ttl time.Duration, value string) *StatusCmd { + cmd := NewStatusCmd( + ctx, + "restore", + key, + formatMs(ctx, ttl), + value, + ) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) RestoreReplace(ctx context.Context, key string, ttl time.Duration, value string) *StatusCmd { + cmd := NewStatusCmd( + ctx, + "restore", + key, + formatMs(ctx, ttl), + value, + "replace", + ) + _ = c(ctx, cmd) + return cmd +} + +type Sort struct { + By string + Offset, Count int64 + Get []string + Order string + Alpha bool +} + +func (sort *Sort) args(key string) []interface{} { + args := []interface{}{"sort", key} + if sort.By != "" { + args = append(args, "by", sort.By) + } + if sort.Offset != 0 || sort.Count != 0 { + args = append(args, "limit", sort.Offset, sort.Count) + } + for _, get := range sort.Get { + args = append(args, "get", get) + } + if sort.Order != "" { + args = append(args, sort.Order) + } + if sort.Alpha { + args = append(args, "alpha") + } + return args +} + +func (c cmdable) Sort(ctx context.Context, key string, sort *Sort) *StringSliceCmd { + cmd := NewStringSliceCmd(ctx, sort.args(key)...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) SortStore(ctx context.Context, key, store string, sort *Sort) *IntCmd { + args := sort.args(key) + if store != "" { + args = append(args, "store", store) + } + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) SortInterfaces(ctx context.Context, key string, sort *Sort) *SliceCmd { + cmd := NewSliceCmd(ctx, sort.args(key)...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) Touch(ctx context.Context, keys ...string) *IntCmd { + args := make([]interface{}, len(keys)+1) + args[0] = "touch" + for i, key := range keys { + args[i+1] = key + } + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) TTL(ctx context.Context, key string) *DurationCmd { + cmd := NewDurationCmd(ctx, time.Second, "ttl", key) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) Type(ctx context.Context, key string) *StatusCmd { + cmd := NewStatusCmd(ctx, "type", key) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) Append(ctx context.Context, key, value string) *IntCmd { + cmd := NewIntCmd(ctx, "append", key, value) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) Decr(ctx context.Context, key string) *IntCmd { + cmd := NewIntCmd(ctx, "decr", key) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) DecrBy(ctx context.Context, key string, decrement int64) *IntCmd { + cmd := NewIntCmd(ctx, "decrby", key, decrement) + _ = c(ctx, cmd) + return cmd +} + +// Get Redis `GET key` command. It returns redis.Nil error when key does not exist. +func (c cmdable) Get(ctx context.Context, key string) *StringCmd { + cmd := NewStringCmd(ctx, "get", key) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) GetRange(ctx context.Context, key string, start, end int64) *StringCmd { + cmd := NewStringCmd(ctx, "getrange", key, start, end) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) GetSet(ctx context.Context, key string, value interface{}) *StringCmd { + cmd := NewStringCmd(ctx, "getset", key, value) + _ = c(ctx, cmd) + return cmd +} + +// GetEx An expiration of zero removes the TTL associated with the key (i.e. GETEX key persist). +// Requires Redis >= 6.2.0. +func (c cmdable) GetEx(ctx context.Context, key string, expiration time.Duration) *StringCmd { + args := make([]interface{}, 0, 4) + args = append(args, "getex", key) + if expiration > 0 { + if usePrecise(expiration) { + args = append(args, "px", formatMs(ctx, expiration)) + } else { + args = append(args, "ex", formatSec(ctx, expiration)) + } + } else if expiration == 0 { + args = append(args, "persist") + } + + cmd := NewStringCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +// GetDel redis-server version >= 6.2.0. +func (c cmdable) GetDel(ctx context.Context, key string) *StringCmd { + cmd := NewStringCmd(ctx, "getdel", key) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) Incr(ctx context.Context, key string) *IntCmd { + cmd := NewIntCmd(ctx, "incr", key) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) IncrBy(ctx context.Context, key string, value int64) *IntCmd { + cmd := NewIntCmd(ctx, "incrby", key, value) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) IncrByFloat(ctx context.Context, key string, value float64) *FloatCmd { + cmd := NewFloatCmd(ctx, "incrbyfloat", key, value) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) MGet(ctx context.Context, keys ...string) *SliceCmd { + args := make([]interface{}, 1+len(keys)) + args[0] = "mget" + for i, key := range keys { + args[1+i] = key + } + cmd := NewSliceCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +// MSet is like Set but accepts multiple values: +// - MSet("key1", "value1", "key2", "value2") +// - MSet([]string{"key1", "value1", "key2", "value2"}) +// - MSet(map[string]interface{}{"key1": "value1", "key2": "value2"}) +func (c cmdable) MSet(ctx context.Context, values ...interface{}) *StatusCmd { + args := make([]interface{}, 1, 1+len(values)) + args[0] = "mset" + args = appendArgs(args, values) + cmd := NewStatusCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +// MSetNX is like SetNX but accepts multiple values: +// - MSetNX("key1", "value1", "key2", "value2") +// - MSetNX([]string{"key1", "value1", "key2", "value2"}) +// - MSetNX(map[string]interface{}{"key1": "value1", "key2": "value2"}) +func (c cmdable) MSetNX(ctx context.Context, values ...interface{}) *BoolCmd { + args := make([]interface{}, 1, 1+len(values)) + args[0] = "msetnx" + args = appendArgs(args, values) + cmd := NewBoolCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +// Set Redis `SET key value [expiration]` command. +// Use expiration for `SETEX`-like behavior. +// +// Zero expiration means the key has no expiration time. +// KeepTTL is a Redis KEEPTTL option to keep existing TTL, it requires your redis-server version >= 6.0, +// otherwise you will receive an error: (error) ERR syntax error. +func (c cmdable) Set(ctx context.Context, key string, value interface{}, expiration time.Duration) *StatusCmd { + args := make([]interface{}, 3, 5) + args[0] = "set" + args[1] = key + args[2] = value + if expiration > 0 { + if usePrecise(expiration) { + args = append(args, "px", formatMs(ctx, expiration)) + } else { + args = append(args, "ex", formatSec(ctx, expiration)) + } + } else if expiration == KeepTTL { + args = append(args, "keepttl") + } + + cmd := NewStatusCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +// SetArgs provides arguments for the SetArgs function. +type SetArgs struct { + // Mode can be `NX` or `XX` or empty. + Mode string + + // Zero `TTL` or `Expiration` means that the key has no expiration time. + TTL time.Duration + ExpireAt time.Time + + // When Get is true, the command returns the old value stored at key, or nil when key did not exist. + Get bool + + // KeepTTL is a Redis KEEPTTL option to keep existing TTL, it requires your redis-server version >= 6.0, + // otherwise you will receive an error: (error) ERR syntax error. + KeepTTL bool +} + +// SetArgs supports all the options that the SET command supports. +// It is the alternative to the Set function when you want +// to have more control over the options. +func (c cmdable) SetArgs(ctx context.Context, key string, value interface{}, a SetArgs) *StatusCmd { + args := []interface{}{"set", key, value} + + if a.KeepTTL { + args = append(args, "keepttl") + } + + if !a.ExpireAt.IsZero() { + args = append(args, "exat", a.ExpireAt.Unix()) + } + if a.TTL > 0 { + if usePrecise(a.TTL) { + args = append(args, "px", formatMs(ctx, a.TTL)) + } else { + args = append(args, "ex", formatSec(ctx, a.TTL)) + } + } + + if a.Mode != "" { + args = append(args, a.Mode) + } + + if a.Get { + args = append(args, "get") + } + + cmd := NewStatusCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +// SetEX Redis `SETEX key expiration value` command. +func (c cmdable) SetEX(ctx context.Context, key string, value interface{}, expiration time.Duration) *StatusCmd { + cmd := NewStatusCmd(ctx, "setex", key, formatSec(ctx, expiration), value) + _ = c(ctx, cmd) + return cmd +} + +// SetNX Redis `SET key value [expiration] NX` command. +// +// Zero expiration means the key has no expiration time. +// KeepTTL is a Redis KEEPTTL option to keep existing TTL, it requires your redis-server version >= 6.0, +// otherwise you will receive an error: (error) ERR syntax error. +func (c cmdable) SetNX(ctx context.Context, key string, value interface{}, expiration time.Duration) *BoolCmd { + var cmd *BoolCmd + switch expiration { + case 0: + // Use old `SETNX` to support old Redis versions. + cmd = NewBoolCmd(ctx, "setnx", key, value) + case KeepTTL: + cmd = NewBoolCmd(ctx, "set", key, value, "keepttl", "nx") + default: + if usePrecise(expiration) { + cmd = NewBoolCmd(ctx, "set", key, value, "px", formatMs(ctx, expiration), "nx") + } else { + cmd = NewBoolCmd(ctx, "set", key, value, "ex", formatSec(ctx, expiration), "nx") + } + } + + _ = c(ctx, cmd) + return cmd +} + +// SetXX Redis `SET key value [expiration] XX` command. +// +// Zero expiration means the key has no expiration time. +// KeepTTL is a Redis KEEPTTL option to keep existing TTL, it requires your redis-server version >= 6.0, +// otherwise you will receive an error: (error) ERR syntax error. +func (c cmdable) SetXX(ctx context.Context, key string, value interface{}, expiration time.Duration) *BoolCmd { + var cmd *BoolCmd + switch expiration { + case 0: + cmd = NewBoolCmd(ctx, "set", key, value, "xx") + case KeepTTL: + cmd = NewBoolCmd(ctx, "set", key, value, "keepttl", "xx") + default: + if usePrecise(expiration) { + cmd = NewBoolCmd(ctx, "set", key, value, "px", formatMs(ctx, expiration), "xx") + } else { + cmd = NewBoolCmd(ctx, "set", key, value, "ex", formatSec(ctx, expiration), "xx") + } + } + + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) SetRange(ctx context.Context, key string, offset int64, value string) *IntCmd { + cmd := NewIntCmd(ctx, "setrange", key, offset, value) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) StrLen(ctx context.Context, key string) *IntCmd { + cmd := NewIntCmd(ctx, "strlen", key) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) Copy(ctx context.Context, sourceKey, destKey string, db int, replace bool) *IntCmd { + args := []interface{}{"copy", sourceKey, destKey, "DB", db} + if replace { + args = append(args, "REPLACE") + } + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +//------------------------------------------------------------------------------ + +func (c cmdable) GetBit(ctx context.Context, key string, offset int64) *IntCmd { + cmd := NewIntCmd(ctx, "getbit", key, offset) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) SetBit(ctx context.Context, key string, offset int64, value int) *IntCmd { + cmd := NewIntCmd( + ctx, + "setbit", + key, + offset, + value, + ) + _ = c(ctx, cmd) + return cmd +} + +type BitCount struct { + Start, End int64 +} + +func (c cmdable) BitCount(ctx context.Context, key string, bitCount *BitCount) *IntCmd { + args := []interface{}{"bitcount", key} + if bitCount != nil { + args = append( + args, + bitCount.Start, + bitCount.End, + ) + } + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) bitOp(ctx context.Context, op, destKey string, keys ...string) *IntCmd { + args := make([]interface{}, 3+len(keys)) + args[0] = "bitop" + args[1] = op + args[2] = destKey + for i, key := range keys { + args[3+i] = key + } + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) BitOpAnd(ctx context.Context, destKey string, keys ...string) *IntCmd { + return c.bitOp(ctx, "and", destKey, keys...) +} + +func (c cmdable) BitOpOr(ctx context.Context, destKey string, keys ...string) *IntCmd { + return c.bitOp(ctx, "or", destKey, keys...) +} + +func (c cmdable) BitOpXor(ctx context.Context, destKey string, keys ...string) *IntCmd { + return c.bitOp(ctx, "xor", destKey, keys...) +} + +func (c cmdable) BitOpNot(ctx context.Context, destKey string, key string) *IntCmd { + return c.bitOp(ctx, "not", destKey, key) +} + +func (c cmdable) BitPos(ctx context.Context, key string, bit int64, pos ...int64) *IntCmd { + args := make([]interface{}, 3+len(pos)) + args[0] = "bitpos" + args[1] = key + args[2] = bit + switch len(pos) { + case 0: + case 1: + args[3] = pos[0] + case 2: + args[3] = pos[0] + args[4] = pos[1] + default: + panic("too many arguments") + } + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) BitField(ctx context.Context, key string, args ...interface{}) *IntSliceCmd { + a := make([]interface{}, 0, 2+len(args)) + a = append(a, "bitfield") + a = append(a, key) + a = append(a, args...) + cmd := NewIntSliceCmd(ctx, a...) + _ = c(ctx, cmd) + return cmd +} + +//------------------------------------------------------------------------------ + +func (c cmdable) Scan(ctx context.Context, cursor uint64, match string, count int64) *ScanCmd { + args := []interface{}{"scan", cursor} + if match != "" { + args = append(args, "match", match) + } + if count > 0 { + args = append(args, "count", count) + } + cmd := NewScanCmd(ctx, c, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ScanType(ctx context.Context, cursor uint64, match string, count int64, keyType string) *ScanCmd { + args := []interface{}{"scan", cursor} + if match != "" { + args = append(args, "match", match) + } + if count > 0 { + args = append(args, "count", count) + } + if keyType != "" { + args = append(args, "type", keyType) + } + cmd := NewScanCmd(ctx, c, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) SScan(ctx context.Context, key string, cursor uint64, match string, count int64) *ScanCmd { + args := []interface{}{"sscan", key, cursor} + if match != "" { + args = append(args, "match", match) + } + if count > 0 { + args = append(args, "count", count) + } + cmd := NewScanCmd(ctx, c, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) HScan(ctx context.Context, key string, cursor uint64, match string, count int64) *ScanCmd { + args := []interface{}{"hscan", key, cursor} + if match != "" { + args = append(args, "match", match) + } + if count > 0 { + args = append(args, "count", count) + } + cmd := NewScanCmd(ctx, c, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ZScan(ctx context.Context, key string, cursor uint64, match string, count int64) *ScanCmd { + args := []interface{}{"zscan", key, cursor} + if match != "" { + args = append(args, "match", match) + } + if count > 0 { + args = append(args, "count", count) + } + cmd := NewScanCmd(ctx, c, args...) + _ = c(ctx, cmd) + return cmd +} + +//------------------------------------------------------------------------------ + +func (c cmdable) HDel(ctx context.Context, key string, fields ...string) *IntCmd { + args := make([]interface{}, 2+len(fields)) + args[0] = "hdel" + args[1] = key + for i, field := range fields { + args[2+i] = field + } + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) HExists(ctx context.Context, key, field string) *BoolCmd { + cmd := NewBoolCmd(ctx, "hexists", key, field) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) HGet(ctx context.Context, key, field string) *StringCmd { + cmd := NewStringCmd(ctx, "hget", key, field) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) HGetAll(ctx context.Context, key string) *StringStringMapCmd { + cmd := NewStringStringMapCmd(ctx, "hgetall", key) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) HIncrBy(ctx context.Context, key, field string, incr int64) *IntCmd { + cmd := NewIntCmd(ctx, "hincrby", key, field, incr) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) HIncrByFloat(ctx context.Context, key, field string, incr float64) *FloatCmd { + cmd := NewFloatCmd(ctx, "hincrbyfloat", key, field, incr) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) HKeys(ctx context.Context, key string) *StringSliceCmd { + cmd := NewStringSliceCmd(ctx, "hkeys", key) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) HLen(ctx context.Context, key string) *IntCmd { + cmd := NewIntCmd(ctx, "hlen", key) + _ = c(ctx, cmd) + return cmd +} + +// HMGet returns the values for the specified fields in the hash stored at key. +// It returns an interface{} to distinguish between empty string and nil value. +func (c cmdable) HMGet(ctx context.Context, key string, fields ...string) *SliceCmd { + args := make([]interface{}, 2+len(fields)) + args[0] = "hmget" + args[1] = key + for i, field := range fields { + args[2+i] = field + } + cmd := NewSliceCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +// HSet accepts values in following formats: +// - HSet("myhash", "key1", "value1", "key2", "value2") +// - HSet("myhash", []string{"key1", "value1", "key2", "value2"}) +// - HSet("myhash", map[string]interface{}{"key1": "value1", "key2": "value2"}) +// +// Note that it requires Redis v4 for multiple field/value pairs support. +func (c cmdable) HSet(ctx context.Context, key string, values ...interface{}) *IntCmd { + args := make([]interface{}, 2, 2+len(values)) + args[0] = "hset" + args[1] = key + args = appendArgs(args, values) + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +// HMSet is a deprecated version of HSet left for compatibility with Redis 3. +func (c cmdable) HMSet(ctx context.Context, key string, values ...interface{}) *BoolCmd { + args := make([]interface{}, 2, 2+len(values)) + args[0] = "hmset" + args[1] = key + args = appendArgs(args, values) + cmd := NewBoolCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) HSetNX(ctx context.Context, key, field string, value interface{}) *BoolCmd { + cmd := NewBoolCmd(ctx, "hsetnx", key, field, value) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) HVals(ctx context.Context, key string) *StringSliceCmd { + cmd := NewStringSliceCmd(ctx, "hvals", key) + _ = c(ctx, cmd) + return cmd +} + +// HRandField redis-server version >= 6.2.0. +func (c cmdable) HRandField(ctx context.Context, key string, count int, withValues bool) *StringSliceCmd { + args := make([]interface{}, 0, 4) + + // Although count=0 is meaningless, redis accepts count=0. + args = append(args, "hrandfield", key, count) + if withValues { + args = append(args, "withvalues") + } + + cmd := NewStringSliceCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +//------------------------------------------------------------------------------ + +func (c cmdable) BLPop(ctx context.Context, timeout time.Duration, keys ...string) *StringSliceCmd { + args := make([]interface{}, 1+len(keys)+1) + args[0] = "blpop" + for i, key := range keys { + args[1+i] = key + } + args[len(args)-1] = formatSec(ctx, timeout) + cmd := NewStringSliceCmd(ctx, args...) + cmd.setReadTimeout(timeout) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) BRPop(ctx context.Context, timeout time.Duration, keys ...string) *StringSliceCmd { + args := make([]interface{}, 1+len(keys)+1) + args[0] = "brpop" + for i, key := range keys { + args[1+i] = key + } + args[len(keys)+1] = formatSec(ctx, timeout) + cmd := NewStringSliceCmd(ctx, args...) + cmd.setReadTimeout(timeout) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) BRPopLPush(ctx context.Context, source, destination string, timeout time.Duration) *StringCmd { + cmd := NewStringCmd( + ctx, + "brpoplpush", + source, + destination, + formatSec(ctx, timeout), + ) + cmd.setReadTimeout(timeout) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) LIndex(ctx context.Context, key string, index int64) *StringCmd { + cmd := NewStringCmd(ctx, "lindex", key, index) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) LInsert(ctx context.Context, key, op string, pivot, value interface{}) *IntCmd { + cmd := NewIntCmd(ctx, "linsert", key, op, pivot, value) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) LInsertBefore(ctx context.Context, key string, pivot, value interface{}) *IntCmd { + cmd := NewIntCmd(ctx, "linsert", key, "before", pivot, value) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) LInsertAfter(ctx context.Context, key string, pivot, value interface{}) *IntCmd { + cmd := NewIntCmd(ctx, "linsert", key, "after", pivot, value) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) LLen(ctx context.Context, key string) *IntCmd { + cmd := NewIntCmd(ctx, "llen", key) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) LPop(ctx context.Context, key string) *StringCmd { + cmd := NewStringCmd(ctx, "lpop", key) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) LPopCount(ctx context.Context, key string, count int) *StringSliceCmd { + cmd := NewStringSliceCmd(ctx, "lpop", key, count) + _ = c(ctx, cmd) + return cmd +} + +type LPosArgs struct { + Rank, MaxLen int64 +} + +func (c cmdable) LPos(ctx context.Context, key string, value string, a LPosArgs) *IntCmd { + args := []interface{}{"lpos", key, value} + if a.Rank != 0 { + args = append(args, "rank", a.Rank) + } + if a.MaxLen != 0 { + args = append(args, "maxlen", a.MaxLen) + } + + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) LPosCount(ctx context.Context, key string, value string, count int64, a LPosArgs) *IntSliceCmd { + args := []interface{}{"lpos", key, value, "count", count} + if a.Rank != 0 { + args = append(args, "rank", a.Rank) + } + if a.MaxLen != 0 { + args = append(args, "maxlen", a.MaxLen) + } + cmd := NewIntSliceCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) LPush(ctx context.Context, key string, values ...interface{}) *IntCmd { + args := make([]interface{}, 2, 2+len(values)) + args[0] = "lpush" + args[1] = key + args = appendArgs(args, values) + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) LPushX(ctx context.Context, key string, values ...interface{}) *IntCmd { + args := make([]interface{}, 2, 2+len(values)) + args[0] = "lpushx" + args[1] = key + args = appendArgs(args, values) + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) LRange(ctx context.Context, key string, start, stop int64) *StringSliceCmd { + cmd := NewStringSliceCmd( + ctx, + "lrange", + key, + start, + stop, + ) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) LRem(ctx context.Context, key string, count int64, value interface{}) *IntCmd { + cmd := NewIntCmd(ctx, "lrem", key, count, value) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) LSet(ctx context.Context, key string, index int64, value interface{}) *StatusCmd { + cmd := NewStatusCmd(ctx, "lset", key, index, value) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) LTrim(ctx context.Context, key string, start, stop int64) *StatusCmd { + cmd := NewStatusCmd( + ctx, + "ltrim", + key, + start, + stop, + ) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) RPop(ctx context.Context, key string) *StringCmd { + cmd := NewStringCmd(ctx, "rpop", key) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) RPopCount(ctx context.Context, key string, count int) *StringSliceCmd { + cmd := NewStringSliceCmd(ctx, "rpop", key, count) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) RPopLPush(ctx context.Context, source, destination string) *StringCmd { + cmd := NewStringCmd(ctx, "rpoplpush", source, destination) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) RPush(ctx context.Context, key string, values ...interface{}) *IntCmd { + args := make([]interface{}, 2, 2+len(values)) + args[0] = "rpush" + args[1] = key + args = appendArgs(args, values) + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) RPushX(ctx context.Context, key string, values ...interface{}) *IntCmd { + args := make([]interface{}, 2, 2+len(values)) + args[0] = "rpushx" + args[1] = key + args = appendArgs(args, values) + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) LMove(ctx context.Context, source, destination, srcpos, destpos string) *StringCmd { + cmd := NewStringCmd(ctx, "lmove", source, destination, srcpos, destpos) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) BLMove( + ctx context.Context, source, destination, srcpos, destpos string, timeout time.Duration, +) *StringCmd { + cmd := NewStringCmd(ctx, "blmove", source, destination, srcpos, destpos, formatSec(ctx, timeout)) + cmd.setReadTimeout(timeout) + _ = c(ctx, cmd) + return cmd +} + +//------------------------------------------------------------------------------ + +func (c cmdable) SAdd(ctx context.Context, key string, members ...interface{}) *IntCmd { + args := make([]interface{}, 2, 2+len(members)) + args[0] = "sadd" + args[1] = key + args = appendArgs(args, members) + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) SCard(ctx context.Context, key string) *IntCmd { + cmd := NewIntCmd(ctx, "scard", key) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) SDiff(ctx context.Context, keys ...string) *StringSliceCmd { + args := make([]interface{}, 1+len(keys)) + args[0] = "sdiff" + for i, key := range keys { + args[1+i] = key + } + cmd := NewStringSliceCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) SDiffStore(ctx context.Context, destination string, keys ...string) *IntCmd { + args := make([]interface{}, 2+len(keys)) + args[0] = "sdiffstore" + args[1] = destination + for i, key := range keys { + args[2+i] = key + } + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) SInter(ctx context.Context, keys ...string) *StringSliceCmd { + args := make([]interface{}, 1+len(keys)) + args[0] = "sinter" + for i, key := range keys { + args[1+i] = key + } + cmd := NewStringSliceCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) SInterStore(ctx context.Context, destination string, keys ...string) *IntCmd { + args := make([]interface{}, 2+len(keys)) + args[0] = "sinterstore" + args[1] = destination + for i, key := range keys { + args[2+i] = key + } + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) SIsMember(ctx context.Context, key string, member interface{}) *BoolCmd { + cmd := NewBoolCmd(ctx, "sismember", key, member) + _ = c(ctx, cmd) + return cmd +} + +// SMIsMember Redis `SMISMEMBER key member [member ...]` command. +func (c cmdable) SMIsMember(ctx context.Context, key string, members ...interface{}) *BoolSliceCmd { + args := make([]interface{}, 2, 2+len(members)) + args[0] = "smismember" + args[1] = key + args = appendArgs(args, members) + cmd := NewBoolSliceCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +// SMembers Redis `SMEMBERS key` command output as a slice. +func (c cmdable) SMembers(ctx context.Context, key string) *StringSliceCmd { + cmd := NewStringSliceCmd(ctx, "smembers", key) + _ = c(ctx, cmd) + return cmd +} + +// SMembersMap Redis `SMEMBERS key` command output as a map. +func (c cmdable) SMembersMap(ctx context.Context, key string) *StringStructMapCmd { + cmd := NewStringStructMapCmd(ctx, "smembers", key) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) SMove(ctx context.Context, source, destination string, member interface{}) *BoolCmd { + cmd := NewBoolCmd(ctx, "smove", source, destination, member) + _ = c(ctx, cmd) + return cmd +} + +// SPop Redis `SPOP key` command. +func (c cmdable) SPop(ctx context.Context, key string) *StringCmd { + cmd := NewStringCmd(ctx, "spop", key) + _ = c(ctx, cmd) + return cmd +} + +// SPopN Redis `SPOP key count` command. +func (c cmdable) SPopN(ctx context.Context, key string, count int64) *StringSliceCmd { + cmd := NewStringSliceCmd(ctx, "spop", key, count) + _ = c(ctx, cmd) + return cmd +} + +// SRandMember Redis `SRANDMEMBER key` command. +func (c cmdable) SRandMember(ctx context.Context, key string) *StringCmd { + cmd := NewStringCmd(ctx, "srandmember", key) + _ = c(ctx, cmd) + return cmd +} + +// SRandMemberN Redis `SRANDMEMBER key count` command. +func (c cmdable) SRandMemberN(ctx context.Context, key string, count int64) *StringSliceCmd { + cmd := NewStringSliceCmd(ctx, "srandmember", key, count) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) SRem(ctx context.Context, key string, members ...interface{}) *IntCmd { + args := make([]interface{}, 2, 2+len(members)) + args[0] = "srem" + args[1] = key + args = appendArgs(args, members) + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) SUnion(ctx context.Context, keys ...string) *StringSliceCmd { + args := make([]interface{}, 1+len(keys)) + args[0] = "sunion" + for i, key := range keys { + args[1+i] = key + } + cmd := NewStringSliceCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) SUnionStore(ctx context.Context, destination string, keys ...string) *IntCmd { + args := make([]interface{}, 2+len(keys)) + args[0] = "sunionstore" + args[1] = destination + for i, key := range keys { + args[2+i] = key + } + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +//------------------------------------------------------------------------------ + +// XAddArgs accepts values in the following formats: +// - XAddArgs.Values = []interface{}{"key1", "value1", "key2", "value2"} +// - XAddArgs.Values = []string("key1", "value1", "key2", "value2") +// - XAddArgs.Values = map[string]interface{}{"key1": "value1", "key2": "value2"} +// +// Note that map will not preserve the order of key-value pairs. +// MaxLen/MaxLenApprox and MinID are in conflict, only one of them can be used. +type XAddArgs struct { + Stream string + NoMkStream bool + MaxLen int64 // MAXLEN N + + // Deprecated: use MaxLen+Approx, remove in v9. + MaxLenApprox int64 // MAXLEN ~ N + + MinID string + // Approx causes MaxLen and MinID to use "~" matcher (instead of "="). + Approx bool + Limit int64 + ID string + Values interface{} +} + +// XAdd a.Limit has a bug, please confirm it and use it. +// issue: https://github.com/redis/redis/issues/9046 +func (c cmdable) XAdd(ctx context.Context, a *XAddArgs) *StringCmd { + args := make([]interface{}, 0, 11) + args = append(args, "xadd", a.Stream) + if a.NoMkStream { + args = append(args, "nomkstream") + } + switch { + case a.MaxLen > 0: + if a.Approx { + args = append(args, "maxlen", "~", a.MaxLen) + } else { + args = append(args, "maxlen", a.MaxLen) + } + case a.MaxLenApprox > 0: + // TODO remove in v9. + args = append(args, "maxlen", "~", a.MaxLenApprox) + case a.MinID != "": + if a.Approx { + args = append(args, "minid", "~", a.MinID) + } else { + args = append(args, "minid", a.MinID) + } + } + if a.Limit > 0 { + args = append(args, "limit", a.Limit) + } + if a.ID != "" { + args = append(args, a.ID) + } else { + args = append(args, "*") + } + args = appendArg(args, a.Values) + + cmd := NewStringCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) XDel(ctx context.Context, stream string, ids ...string) *IntCmd { + args := []interface{}{"xdel", stream} + for _, id := range ids { + args = append(args, id) + } + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) XLen(ctx context.Context, stream string) *IntCmd { + cmd := NewIntCmd(ctx, "xlen", stream) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) XRange(ctx context.Context, stream, start, stop string) *XMessageSliceCmd { + cmd := NewXMessageSliceCmd(ctx, "xrange", stream, start, stop) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) XRangeN(ctx context.Context, stream, start, stop string, count int64) *XMessageSliceCmd { + cmd := NewXMessageSliceCmd(ctx, "xrange", stream, start, stop, "count", count) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) XRevRange(ctx context.Context, stream, start, stop string) *XMessageSliceCmd { + cmd := NewXMessageSliceCmd(ctx, "xrevrange", stream, start, stop) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) XRevRangeN(ctx context.Context, stream, start, stop string, count int64) *XMessageSliceCmd { + cmd := NewXMessageSliceCmd(ctx, "xrevrange", stream, start, stop, "count", count) + _ = c(ctx, cmd) + return cmd +} + +type XReadArgs struct { + Streams []string // list of streams and ids, e.g. stream1 stream2 id1 id2 + Count int64 + Block time.Duration +} + +func (c cmdable) XRead(ctx context.Context, a *XReadArgs) *XStreamSliceCmd { + args := make([]interface{}, 0, 6+len(a.Streams)) + args = append(args, "xread") + + keyPos := int8(1) + if a.Count > 0 { + args = append(args, "count") + args = append(args, a.Count) + keyPos += 2 + } + if a.Block >= 0 { + args = append(args, "block") + args = append(args, int64(a.Block/time.Millisecond)) + keyPos += 2 + } + args = append(args, "streams") + keyPos++ + for _, s := range a.Streams { + args = append(args, s) + } + + cmd := NewXStreamSliceCmd(ctx, args...) + if a.Block >= 0 { + cmd.setReadTimeout(a.Block) + } + cmd.SetFirstKeyPos(keyPos) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) XReadStreams(ctx context.Context, streams ...string) *XStreamSliceCmd { + return c.XRead(ctx, &XReadArgs{ + Streams: streams, + Block: -1, + }) +} + +func (c cmdable) XGroupCreate(ctx context.Context, stream, group, start string) *StatusCmd { + cmd := NewStatusCmd(ctx, "xgroup", "create", stream, group, start) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) XGroupCreateMkStream(ctx context.Context, stream, group, start string) *StatusCmd { + cmd := NewStatusCmd(ctx, "xgroup", "create", stream, group, start, "mkstream") + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) XGroupSetID(ctx context.Context, stream, group, start string) *StatusCmd { + cmd := NewStatusCmd(ctx, "xgroup", "setid", stream, group, start) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) XGroupDestroy(ctx context.Context, stream, group string) *IntCmd { + cmd := NewIntCmd(ctx, "xgroup", "destroy", stream, group) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) XGroupCreateConsumer(ctx context.Context, stream, group, consumer string) *IntCmd { + cmd := NewIntCmd(ctx, "xgroup", "createconsumer", stream, group, consumer) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) XGroupDelConsumer(ctx context.Context, stream, group, consumer string) *IntCmd { + cmd := NewIntCmd(ctx, "xgroup", "delconsumer", stream, group, consumer) + _ = c(ctx, cmd) + return cmd +} + +type XReadGroupArgs struct { + Group string + Consumer string + Streams []string // list of streams and ids, e.g. stream1 stream2 id1 id2 + Count int64 + Block time.Duration + NoAck bool +} + +func (c cmdable) XReadGroup(ctx context.Context, a *XReadGroupArgs) *XStreamSliceCmd { + args := make([]interface{}, 0, 10+len(a.Streams)) + args = append(args, "xreadgroup", "group", a.Group, a.Consumer) + + keyPos := int8(4) + if a.Count > 0 { + args = append(args, "count", a.Count) + keyPos += 2 + } + if a.Block >= 0 { + args = append(args, "block", int64(a.Block/time.Millisecond)) + keyPos += 2 + } + if a.NoAck { + args = append(args, "noack") + keyPos++ + } + args = append(args, "streams") + keyPos++ + for _, s := range a.Streams { + args = append(args, s) + } + + cmd := NewXStreamSliceCmd(ctx, args...) + if a.Block >= 0 { + cmd.setReadTimeout(a.Block) + } + cmd.SetFirstKeyPos(keyPos) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) XAck(ctx context.Context, stream, group string, ids ...string) *IntCmd { + args := []interface{}{"xack", stream, group} + for _, id := range ids { + args = append(args, id) + } + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) XPending(ctx context.Context, stream, group string) *XPendingCmd { + cmd := NewXPendingCmd(ctx, "xpending", stream, group) + _ = c(ctx, cmd) + return cmd +} + +type XPendingExtArgs struct { + Stream string + Group string + Idle time.Duration + Start string + End string + Count int64 + Consumer string +} + +func (c cmdable) XPendingExt(ctx context.Context, a *XPendingExtArgs) *XPendingExtCmd { + args := make([]interface{}, 0, 9) + args = append(args, "xpending", a.Stream, a.Group) + if a.Idle != 0 { + args = append(args, "idle", formatMs(ctx, a.Idle)) + } + args = append(args, a.Start, a.End, a.Count) + if a.Consumer != "" { + args = append(args, a.Consumer) + } + cmd := NewXPendingExtCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +type XAutoClaimArgs struct { + Stream string + Group string + MinIdle time.Duration + Start string + Count int64 + Consumer string +} + +func (c cmdable) XAutoClaim(ctx context.Context, a *XAutoClaimArgs) *XAutoClaimCmd { + args := xAutoClaimArgs(ctx, a) + cmd := NewXAutoClaimCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) XAutoClaimJustID(ctx context.Context, a *XAutoClaimArgs) *XAutoClaimJustIDCmd { + args := xAutoClaimArgs(ctx, a) + args = append(args, "justid") + cmd := NewXAutoClaimJustIDCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func xAutoClaimArgs(ctx context.Context, a *XAutoClaimArgs) []interface{} { + args := make([]interface{}, 0, 8) + args = append(args, "xautoclaim", a.Stream, a.Group, a.Consumer, formatMs(ctx, a.MinIdle), a.Start) + if a.Count > 0 { + args = append(args, "count", a.Count) + } + return args +} + +type XClaimArgs struct { + Stream string + Group string + Consumer string + MinIdle time.Duration + Messages []string +} + +func (c cmdable) XClaim(ctx context.Context, a *XClaimArgs) *XMessageSliceCmd { + args := xClaimArgs(a) + cmd := NewXMessageSliceCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) XClaimJustID(ctx context.Context, a *XClaimArgs) *StringSliceCmd { + args := xClaimArgs(a) + args = append(args, "justid") + cmd := NewStringSliceCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func xClaimArgs(a *XClaimArgs) []interface{} { + args := make([]interface{}, 0, 5+len(a.Messages)) + args = append(args, + "xclaim", + a.Stream, + a.Group, a.Consumer, + int64(a.MinIdle/time.Millisecond)) + for _, id := range a.Messages { + args = append(args, id) + } + return args +} + +// xTrim If approx is true, add the "~" parameter, otherwise it is the default "=" (redis default). +// example: +// XTRIM key MAXLEN/MINID threshold LIMIT limit. +// XTRIM key MAXLEN/MINID ~ threshold LIMIT limit. +// The redis-server version is lower than 6.2, please set limit to 0. +func (c cmdable) xTrim( + ctx context.Context, key, strategy string, + approx bool, threshold interface{}, limit int64, +) *IntCmd { + args := make([]interface{}, 0, 7) + args = append(args, "xtrim", key, strategy) + if approx { + args = append(args, "~") + } + args = append(args, threshold) + if limit > 0 { + args = append(args, "limit", limit) + } + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +// Deprecated: use XTrimMaxLen, remove in v9. +func (c cmdable) XTrim(ctx context.Context, key string, maxLen int64) *IntCmd { + return c.xTrim(ctx, key, "maxlen", false, maxLen, 0) +} + +// Deprecated: use XTrimMaxLenApprox, remove in v9. +func (c cmdable) XTrimApprox(ctx context.Context, key string, maxLen int64) *IntCmd { + return c.xTrim(ctx, key, "maxlen", true, maxLen, 0) +} + +// XTrimMaxLen No `~` rules are used, `limit` cannot be used. +// cmd: XTRIM key MAXLEN maxLen +func (c cmdable) XTrimMaxLen(ctx context.Context, key string, maxLen int64) *IntCmd { + return c.xTrim(ctx, key, "maxlen", false, maxLen, 0) +} + +// XTrimMaxLenApprox LIMIT has a bug, please confirm it and use it. +// issue: https://github.com/redis/redis/issues/9046 +// cmd: XTRIM key MAXLEN ~ maxLen LIMIT limit +func (c cmdable) XTrimMaxLenApprox(ctx context.Context, key string, maxLen, limit int64) *IntCmd { + return c.xTrim(ctx, key, "maxlen", true, maxLen, limit) +} + +// XTrimMinID No `~` rules are used, `limit` cannot be used. +// cmd: XTRIM key MINID minID +func (c cmdable) XTrimMinID(ctx context.Context, key string, minID string) *IntCmd { + return c.xTrim(ctx, key, "minid", false, minID, 0) +} + +// XTrimMinIDApprox LIMIT has a bug, please confirm it and use it. +// issue: https://github.com/redis/redis/issues/9046 +// cmd: XTRIM key MINID ~ minID LIMIT limit +func (c cmdable) XTrimMinIDApprox(ctx context.Context, key string, minID string, limit int64) *IntCmd { + return c.xTrim(ctx, key, "minid", true, minID, limit) +} + +func (c cmdable) XInfoConsumers(ctx context.Context, key string, group string) *XInfoConsumersCmd { + cmd := NewXInfoConsumersCmd(ctx, key, group) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) XInfoGroups(ctx context.Context, key string) *XInfoGroupsCmd { + cmd := NewXInfoGroupsCmd(ctx, key) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) XInfoStream(ctx context.Context, key string) *XInfoStreamCmd { + cmd := NewXInfoStreamCmd(ctx, key) + _ = c(ctx, cmd) + return cmd +} + +// XInfoStreamFull XINFO STREAM FULL [COUNT count] +// redis-server >= 6.0. +func (c cmdable) XInfoStreamFull(ctx context.Context, key string, count int) *XInfoStreamFullCmd { + args := make([]interface{}, 0, 6) + args = append(args, "xinfo", "stream", key, "full") + if count > 0 { + args = append(args, "count", count) + } + cmd := NewXInfoStreamFullCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +//------------------------------------------------------------------------------ + +// Z represents sorted set member. +type Z struct { + Score float64 + Member interface{} +} + +// ZWithKey represents sorted set member including the name of the key where it was popped. +type ZWithKey struct { + Z + Key string +} + +// ZStore is used as an arg to ZInter/ZInterStore and ZUnion/ZUnionStore. +type ZStore struct { + Keys []string + Weights []float64 + // Can be SUM, MIN or MAX. + Aggregate string +} + +func (z ZStore) len() (n int) { + n = len(z.Keys) + if len(z.Weights) > 0 { + n += 1 + len(z.Weights) + } + if z.Aggregate != "" { + n += 2 + } + return n +} + +func (z ZStore) appendArgs(args []interface{}) []interface{} { + for _, key := range z.Keys { + args = append(args, key) + } + if len(z.Weights) > 0 { + args = append(args, "weights") + for _, weights := range z.Weights { + args = append(args, weights) + } + } + if z.Aggregate != "" { + args = append(args, "aggregate", z.Aggregate) + } + return args +} + +// BZPopMax Redis `BZPOPMAX key [key ...] timeout` command. +func (c cmdable) BZPopMax(ctx context.Context, timeout time.Duration, keys ...string) *ZWithKeyCmd { + args := make([]interface{}, 1+len(keys)+1) + args[0] = "bzpopmax" + for i, key := range keys { + args[1+i] = key + } + args[len(args)-1] = formatSec(ctx, timeout) + cmd := NewZWithKeyCmd(ctx, args...) + cmd.setReadTimeout(timeout) + _ = c(ctx, cmd) + return cmd +} + +// BZPopMin Redis `BZPOPMIN key [key ...] timeout` command. +func (c cmdable) BZPopMin(ctx context.Context, timeout time.Duration, keys ...string) *ZWithKeyCmd { + args := make([]interface{}, 1+len(keys)+1) + args[0] = "bzpopmin" + for i, key := range keys { + args[1+i] = key + } + args[len(args)-1] = formatSec(ctx, timeout) + cmd := NewZWithKeyCmd(ctx, args...) + cmd.setReadTimeout(timeout) + _ = c(ctx, cmd) + return cmd +} + +// ZAddArgs WARN: The GT, LT and NX options are mutually exclusive. +type ZAddArgs struct { + NX bool + XX bool + LT bool + GT bool + Ch bool + Members []Z +} + +func (c cmdable) zAddArgs(key string, args ZAddArgs, incr bool) []interface{} { + a := make([]interface{}, 0, 6+2*len(args.Members)) + a = append(a, "zadd", key) + + // The GT, LT and NX options are mutually exclusive. + if args.NX { + a = append(a, "nx") + } else { + if args.XX { + a = append(a, "xx") + } + if args.GT { + a = append(a, "gt") + } else if args.LT { + a = append(a, "lt") + } + } + if args.Ch { + a = append(a, "ch") + } + if incr { + a = append(a, "incr") + } + for _, m := range args.Members { + a = append(a, m.Score) + a = append(a, m.Member) + } + return a +} + +func (c cmdable) ZAddArgs(ctx context.Context, key string, args ZAddArgs) *IntCmd { + cmd := NewIntCmd(ctx, c.zAddArgs(key, args, false)...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ZAddArgsIncr(ctx context.Context, key string, args ZAddArgs) *FloatCmd { + cmd := NewFloatCmd(ctx, c.zAddArgs(key, args, true)...) + _ = c(ctx, cmd) + return cmd +} + +// TODO: Compatible with v8 api, will be removed in v9. +func (c cmdable) zAdd(ctx context.Context, key string, args ZAddArgs, members ...*Z) *IntCmd { + args.Members = make([]Z, len(members)) + for i, m := range members { + args.Members[i] = *m + } + cmd := NewIntCmd(ctx, c.zAddArgs(key, args, false)...) + _ = c(ctx, cmd) + return cmd +} + +// ZAdd Redis `ZADD key score member [score member ...]` command. +func (c cmdable) ZAdd(ctx context.Context, key string, members ...*Z) *IntCmd { + return c.zAdd(ctx, key, ZAddArgs{}, members...) +} + +// ZAddNX Redis `ZADD key NX score member [score member ...]` command. +func (c cmdable) ZAddNX(ctx context.Context, key string, members ...*Z) *IntCmd { + return c.zAdd(ctx, key, ZAddArgs{ + NX: true, + }, members...) +} + +// ZAddXX Redis `ZADD key XX score member [score member ...]` command. +func (c cmdable) ZAddXX(ctx context.Context, key string, members ...*Z) *IntCmd { + return c.zAdd(ctx, key, ZAddArgs{ + XX: true, + }, members...) +} + +// ZAddCh Redis `ZADD key CH score member [score member ...]` command. +// Deprecated: Use +// client.ZAddArgs(ctx, ZAddArgs{ +// Ch: true, +// Members: []Z, +// }) +// remove in v9. +func (c cmdable) ZAddCh(ctx context.Context, key string, members ...*Z) *IntCmd { + return c.zAdd(ctx, key, ZAddArgs{ + Ch: true, + }, members...) +} + +// ZAddNXCh Redis `ZADD key NX CH score member [score member ...]` command. +// Deprecated: Use +// client.ZAddArgs(ctx, ZAddArgs{ +// NX: true, +// Ch: true, +// Members: []Z, +// }) +// remove in v9. +func (c cmdable) ZAddNXCh(ctx context.Context, key string, members ...*Z) *IntCmd { + return c.zAdd(ctx, key, ZAddArgs{ + NX: true, + Ch: true, + }, members...) +} + +// ZAddXXCh Redis `ZADD key XX CH score member [score member ...]` command. +// Deprecated: Use +// client.ZAddArgs(ctx, ZAddArgs{ +// XX: true, +// Ch: true, +// Members: []Z, +// }) +// remove in v9. +func (c cmdable) ZAddXXCh(ctx context.Context, key string, members ...*Z) *IntCmd { + return c.zAdd(ctx, key, ZAddArgs{ + XX: true, + Ch: true, + }, members...) +} + +// ZIncr Redis `ZADD key INCR score member` command. +// Deprecated: Use +// client.ZAddArgsIncr(ctx, ZAddArgs{ +// Members: []Z, +// }) +// remove in v9. +func (c cmdable) ZIncr(ctx context.Context, key string, member *Z) *FloatCmd { + return c.ZAddArgsIncr(ctx, key, ZAddArgs{ + Members: []Z{*member}, + }) +} + +// ZIncrNX Redis `ZADD key NX INCR score member` command. +// Deprecated: Use +// client.ZAddArgsIncr(ctx, ZAddArgs{ +// NX: true, +// Members: []Z, +// }) +// remove in v9. +func (c cmdable) ZIncrNX(ctx context.Context, key string, member *Z) *FloatCmd { + return c.ZAddArgsIncr(ctx, key, ZAddArgs{ + NX: true, + Members: []Z{*member}, + }) +} + +// ZIncrXX Redis `ZADD key XX INCR score member` command. +// Deprecated: Use +// client.ZAddArgsIncr(ctx, ZAddArgs{ +// XX: true, +// Members: []Z, +// }) +// remove in v9. +func (c cmdable) ZIncrXX(ctx context.Context, key string, member *Z) *FloatCmd { + return c.ZAddArgsIncr(ctx, key, ZAddArgs{ + XX: true, + Members: []Z{*member}, + }) +} + +func (c cmdable) ZCard(ctx context.Context, key string) *IntCmd { + cmd := NewIntCmd(ctx, "zcard", key) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ZCount(ctx context.Context, key, min, max string) *IntCmd { + cmd := NewIntCmd(ctx, "zcount", key, min, max) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ZLexCount(ctx context.Context, key, min, max string) *IntCmd { + cmd := NewIntCmd(ctx, "zlexcount", key, min, max) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ZIncrBy(ctx context.Context, key string, increment float64, member string) *FloatCmd { + cmd := NewFloatCmd(ctx, "zincrby", key, increment, member) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ZInterStore(ctx context.Context, destination string, store *ZStore) *IntCmd { + args := make([]interface{}, 0, 3+store.len()) + args = append(args, "zinterstore", destination, len(store.Keys)) + args = store.appendArgs(args) + cmd := NewIntCmd(ctx, args...) + cmd.SetFirstKeyPos(3) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ZInter(ctx context.Context, store *ZStore) *StringSliceCmd { + args := make([]interface{}, 0, 2+store.len()) + args = append(args, "zinter", len(store.Keys)) + args = store.appendArgs(args) + cmd := NewStringSliceCmd(ctx, args...) + cmd.SetFirstKeyPos(2) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ZInterWithScores(ctx context.Context, store *ZStore) *ZSliceCmd { + args := make([]interface{}, 0, 3+store.len()) + args = append(args, "zinter", len(store.Keys)) + args = store.appendArgs(args) + args = append(args, "withscores") + cmd := NewZSliceCmd(ctx, args...) + cmd.SetFirstKeyPos(2) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ZMScore(ctx context.Context, key string, members ...string) *FloatSliceCmd { + args := make([]interface{}, 2+len(members)) + args[0] = "zmscore" + args[1] = key + for i, member := range members { + args[2+i] = member + } + cmd := NewFloatSliceCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ZPopMax(ctx context.Context, key string, count ...int64) *ZSliceCmd { + args := []interface{}{ + "zpopmax", + key, + } + + switch len(count) { + case 0: + break + case 1: + args = append(args, count[0]) + default: + panic("too many arguments") + } + + cmd := NewZSliceCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ZPopMin(ctx context.Context, key string, count ...int64) *ZSliceCmd { + args := []interface{}{ + "zpopmin", + key, + } + + switch len(count) { + case 0: + break + case 1: + args = append(args, count[0]) + default: + panic("too many arguments") + } + + cmd := NewZSliceCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +// ZRangeArgs is all the options of the ZRange command. +// In version> 6.2.0, you can replace the(cmd): +// ZREVRANGE, +// ZRANGEBYSCORE, +// ZREVRANGEBYSCORE, +// ZRANGEBYLEX, +// ZREVRANGEBYLEX. +// Please pay attention to your redis-server version. +// +// Rev, ByScore, ByLex and Offset+Count options require redis-server 6.2.0 and higher. +type ZRangeArgs struct { + Key string + + // When the ByScore option is provided, the open interval(exclusive) can be set. + // By default, the score intervals specified by and are closed (inclusive). + // It is similar to the deprecated(6.2.0+) ZRangeByScore command. + // For example: + // ZRangeArgs{ + // Key: "example-key", + // Start: "(3", + // Stop: 8, + // ByScore: true, + // } + // cmd: "ZRange example-key (3 8 ByScore" (3 < score <= 8). + // + // For the ByLex option, it is similar to the deprecated(6.2.0+) ZRangeByLex command. + // You can set the and options as follows: + // ZRangeArgs{ + // Key: "example-key", + // Start: "[abc", + // Stop: "(def", + // ByLex: true, + // } + // cmd: "ZRange example-key [abc (def ByLex" + // + // For normal cases (ByScore==false && ByLex==false), and should be set to the index range (int). + // You can read the documentation for more information: https://redis.io/commands/zrange + Start interface{} + Stop interface{} + + // The ByScore and ByLex options are mutually exclusive. + ByScore bool + ByLex bool + + Rev bool + + // limit offset count. + Offset int64 + Count int64 +} + +func (z ZRangeArgs) appendArgs(args []interface{}) []interface{} { + // For Rev+ByScore/ByLex, we need to adjust the position of and . + if z.Rev && (z.ByScore || z.ByLex) { + args = append(args, z.Key, z.Stop, z.Start) + } else { + args = append(args, z.Key, z.Start, z.Stop) + } + + if z.ByScore { + args = append(args, "byscore") + } else if z.ByLex { + args = append(args, "bylex") + } + if z.Rev { + args = append(args, "rev") + } + if z.Offset != 0 || z.Count != 0 { + args = append(args, "limit", z.Offset, z.Count) + } + return args +} + +func (c cmdable) ZRangeArgs(ctx context.Context, z ZRangeArgs) *StringSliceCmd { + args := make([]interface{}, 0, 9) + args = append(args, "zrange") + args = z.appendArgs(args) + cmd := NewStringSliceCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ZRangeArgsWithScores(ctx context.Context, z ZRangeArgs) *ZSliceCmd { + args := make([]interface{}, 0, 10) + args = append(args, "zrange") + args = z.appendArgs(args) + args = append(args, "withscores") + cmd := NewZSliceCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ZRange(ctx context.Context, key string, start, stop int64) *StringSliceCmd { + return c.ZRangeArgs(ctx, ZRangeArgs{ + Key: key, + Start: start, + Stop: stop, + }) +} + +func (c cmdable) ZRangeWithScores(ctx context.Context, key string, start, stop int64) *ZSliceCmd { + return c.ZRangeArgsWithScores(ctx, ZRangeArgs{ + Key: key, + Start: start, + Stop: stop, + }) +} + +type ZRangeBy struct { + Min, Max string + Offset, Count int64 +} + +func (c cmdable) zRangeBy(ctx context.Context, zcmd, key string, opt *ZRangeBy, withScores bool) *StringSliceCmd { + args := []interface{}{zcmd, key, opt.Min, opt.Max} + if withScores { + args = append(args, "withscores") + } + if opt.Offset != 0 || opt.Count != 0 { + args = append( + args, + "limit", + opt.Offset, + opt.Count, + ) + } + cmd := NewStringSliceCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ZRangeByScore(ctx context.Context, key string, opt *ZRangeBy) *StringSliceCmd { + return c.zRangeBy(ctx, "zrangebyscore", key, opt, false) +} + +func (c cmdable) ZRangeByLex(ctx context.Context, key string, opt *ZRangeBy) *StringSliceCmd { + return c.zRangeBy(ctx, "zrangebylex", key, opt, false) +} + +func (c cmdable) ZRangeByScoreWithScores(ctx context.Context, key string, opt *ZRangeBy) *ZSliceCmd { + args := []interface{}{"zrangebyscore", key, opt.Min, opt.Max, "withscores"} + if opt.Offset != 0 || opt.Count != 0 { + args = append( + args, + "limit", + opt.Offset, + opt.Count, + ) + } + cmd := NewZSliceCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ZRangeStore(ctx context.Context, dst string, z ZRangeArgs) *IntCmd { + args := make([]interface{}, 0, 10) + args = append(args, "zrangestore", dst) + args = z.appendArgs(args) + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ZRank(ctx context.Context, key, member string) *IntCmd { + cmd := NewIntCmd(ctx, "zrank", key, member) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ZRem(ctx context.Context, key string, members ...interface{}) *IntCmd { + args := make([]interface{}, 2, 2+len(members)) + args[0] = "zrem" + args[1] = key + args = appendArgs(args, members) + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ZRemRangeByRank(ctx context.Context, key string, start, stop int64) *IntCmd { + cmd := NewIntCmd( + ctx, + "zremrangebyrank", + key, + start, + stop, + ) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ZRemRangeByScore(ctx context.Context, key, min, max string) *IntCmd { + cmd := NewIntCmd(ctx, "zremrangebyscore", key, min, max) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ZRemRangeByLex(ctx context.Context, key, min, max string) *IntCmd { + cmd := NewIntCmd(ctx, "zremrangebylex", key, min, max) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ZRevRange(ctx context.Context, key string, start, stop int64) *StringSliceCmd { + cmd := NewStringSliceCmd(ctx, "zrevrange", key, start, stop) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ZRevRangeWithScores(ctx context.Context, key string, start, stop int64) *ZSliceCmd { + cmd := NewZSliceCmd(ctx, "zrevrange", key, start, stop, "withscores") + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) zRevRangeBy(ctx context.Context, zcmd, key string, opt *ZRangeBy) *StringSliceCmd { + args := []interface{}{zcmd, key, opt.Max, opt.Min} + if opt.Offset != 0 || opt.Count != 0 { + args = append( + args, + "limit", + opt.Offset, + opt.Count, + ) + } + cmd := NewStringSliceCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ZRevRangeByScore(ctx context.Context, key string, opt *ZRangeBy) *StringSliceCmd { + return c.zRevRangeBy(ctx, "zrevrangebyscore", key, opt) +} + +func (c cmdable) ZRevRangeByLex(ctx context.Context, key string, opt *ZRangeBy) *StringSliceCmd { + return c.zRevRangeBy(ctx, "zrevrangebylex", key, opt) +} + +func (c cmdable) ZRevRangeByScoreWithScores(ctx context.Context, key string, opt *ZRangeBy) *ZSliceCmd { + args := []interface{}{"zrevrangebyscore", key, opt.Max, opt.Min, "withscores"} + if opt.Offset != 0 || opt.Count != 0 { + args = append( + args, + "limit", + opt.Offset, + opt.Count, + ) + } + cmd := NewZSliceCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ZRevRank(ctx context.Context, key, member string) *IntCmd { + cmd := NewIntCmd(ctx, "zrevrank", key, member) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ZScore(ctx context.Context, key, member string) *FloatCmd { + cmd := NewFloatCmd(ctx, "zscore", key, member) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ZUnion(ctx context.Context, store ZStore) *StringSliceCmd { + args := make([]interface{}, 0, 2+store.len()) + args = append(args, "zunion", len(store.Keys)) + args = store.appendArgs(args) + cmd := NewStringSliceCmd(ctx, args...) + cmd.SetFirstKeyPos(2) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ZUnionWithScores(ctx context.Context, store ZStore) *ZSliceCmd { + args := make([]interface{}, 0, 3+store.len()) + args = append(args, "zunion", len(store.Keys)) + args = store.appendArgs(args) + args = append(args, "withscores") + cmd := NewZSliceCmd(ctx, args...) + cmd.SetFirstKeyPos(2) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ZUnionStore(ctx context.Context, dest string, store *ZStore) *IntCmd { + args := make([]interface{}, 0, 3+store.len()) + args = append(args, "zunionstore", dest, len(store.Keys)) + args = store.appendArgs(args) + cmd := NewIntCmd(ctx, args...) + cmd.SetFirstKeyPos(3) + _ = c(ctx, cmd) + return cmd +} + +// ZRandMember redis-server version >= 6.2.0. +func (c cmdable) ZRandMember(ctx context.Context, key string, count int, withScores bool) *StringSliceCmd { + args := make([]interface{}, 0, 4) + + // Although count=0 is meaningless, redis accepts count=0. + args = append(args, "zrandmember", key, count) + if withScores { + args = append(args, "withscores") + } + + cmd := NewStringSliceCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +// ZDiff redis-server version >= 6.2.0. +func (c cmdable) ZDiff(ctx context.Context, keys ...string) *StringSliceCmd { + args := make([]interface{}, 2+len(keys)) + args[0] = "zdiff" + args[1] = len(keys) + for i, key := range keys { + args[i+2] = key + } + + cmd := NewStringSliceCmd(ctx, args...) + cmd.SetFirstKeyPos(2) + _ = c(ctx, cmd) + return cmd +} + +// ZDiffWithScores redis-server version >= 6.2.0. +func (c cmdable) ZDiffWithScores(ctx context.Context, keys ...string) *ZSliceCmd { + args := make([]interface{}, 3+len(keys)) + args[0] = "zdiff" + args[1] = len(keys) + for i, key := range keys { + args[i+2] = key + } + args[len(keys)+2] = "withscores" + + cmd := NewZSliceCmd(ctx, args...) + cmd.SetFirstKeyPos(2) + _ = c(ctx, cmd) + return cmd +} + +// ZDiffStore redis-server version >=6.2.0. +func (c cmdable) ZDiffStore(ctx context.Context, destination string, keys ...string) *IntCmd { + args := make([]interface{}, 0, 3+len(keys)) + args = append(args, "zdiffstore", destination, len(keys)) + for _, key := range keys { + args = append(args, key) + } + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +//------------------------------------------------------------------------------ + +func (c cmdable) PFAdd(ctx context.Context, key string, els ...interface{}) *IntCmd { + args := make([]interface{}, 2, 2+len(els)) + args[0] = "pfadd" + args[1] = key + args = appendArgs(args, els) + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) PFCount(ctx context.Context, keys ...string) *IntCmd { + args := make([]interface{}, 1+len(keys)) + args[0] = "pfcount" + for i, key := range keys { + args[1+i] = key + } + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) PFMerge(ctx context.Context, dest string, keys ...string) *StatusCmd { + args := make([]interface{}, 2+len(keys)) + args[0] = "pfmerge" + args[1] = dest + for i, key := range keys { + args[2+i] = key + } + cmd := NewStatusCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +//------------------------------------------------------------------------------ + +func (c cmdable) BgRewriteAOF(ctx context.Context) *StatusCmd { + cmd := NewStatusCmd(ctx, "bgrewriteaof") + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) BgSave(ctx context.Context) *StatusCmd { + cmd := NewStatusCmd(ctx, "bgsave") + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ClientKill(ctx context.Context, ipPort string) *StatusCmd { + cmd := NewStatusCmd(ctx, "client", "kill", ipPort) + _ = c(ctx, cmd) + return cmd +} + +// ClientKillByFilter is new style syntax, while the ClientKill is old +// +// CLIENT KILL