text:
#==============================================================================#
# AppSync.jl
#
# This file is generated from:
# https://github.com/aws/aws-sdk-js/blob/master/apis/appsync-2017-07-25.normal.json
#==============================================================================#

__precompile__()

module AppSync

using AWSCore

"""
    using AWSSDK.AppSync.create_api_key
    create_api_key([::AWSConfig], arguments::Dict)
    create_api_key([::AWSConfig]; apiId=, <keyword arguments>)

    using AWSCore.Services.appsync
    appsync([::AWSConfig], "POST", "/v1/apis/{apiId}/apikeys", arguments::Dict)
    appsync([::AWSConfig], "POST", "/v1/apis/{apiId}/apikeys", apiId=, <keyword arguments>)

# CreateApiKey Operation

Creates a unique key that you can distribute to clients who are executing your API.

# Arguments

## `apiId = ::String` -- *Required*
The ID for your GraphQL API.

## `description = ::String`
A description of the purpose of the API key.

## `expires = ::Int`
The time from creation time after which the API key expires. The date is represented as seconds since the epoch, rounded down to the nearest hour. The default value for this parameter is 7 days from creation time. For more information, see .

# Returns

`CreateApiKeyResponse`

# Exceptions

`BadRequestException`, `NotFoundException`, `LimitExceededException`, `UnauthorizedException`, `LimitExceededException`, `InternalFailureException`, `ApiKeyLimitExceededException` or `ApiKeyValidityOutOfBoundsException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/appsync-2017-07-25/CreateApiKey)
"""
@inline create_api_key(aws::AWSConfig=default_aws_config(); args...) = create_api_key(aws, args)

@inline create_api_key(aws::AWSConfig, args) = AWSCore.Services.appsync(aws, "POST", "/v1/apis/{apiId}/apikeys", args)

@inline create_api_key(args) = create_api_key(default_aws_config(), args)

"""
    using AWSSDK.AppSync.create_data_source
    create_data_source([::AWSConfig], arguments::Dict)
    create_data_source([::AWSConfig]; apiId=, name=, type=, <keyword arguments>)

    using AWSCore.Services.appsync
    appsync([::AWSConfig], "POST", "/v1/apis/{apiId}/datasources", arguments::Dict)
    appsync([::AWSConfig], "POST", "/v1/apis/{apiId}/datasources", apiId=, name=, type=, <keyword arguments>)

# CreateDataSource Operation

Creates a `DataSource` object.

# Arguments

## `apiId = ::String` -- *Required*
The API ID for the GraphQL API for the `DataSource`.

## `name = ::String` -- *Required*
A user-supplied name for the `DataSource`.

## `description = ::String`
A description of the `DataSource`.

## `type = "AWS_LAMBDA", "AMAZON_DYNAMODB", "AMAZON_ELASTICSEARCH", "NONE" or "HTTP"` -- *Required*
The type of the `DataSource`.

## `serviceRoleArn = ::String`
The IAM service role ARN for the data source. The system assumes this role when accessing the data source.

## `dynamodbConfig = [ ... ]`
DynamoDB settings.
```
 dynamodbConfig = [
        "tableName" => <required> ::String,
        "awsRegion" => <required> ::String,
        "useCallerCredentials" =>  ::Bool
    ]
```

## `lambdaConfig = ["lambdaFunctionArn" => <required> ::String]`
AWS Lambda settings.

## `elasticsearchConfig = [ ... ]`
Amazon Elasticsearch settings.
```
 elasticsearchConfig = [
        "endpoint" => <required> ::String,
        "awsRegion" => <required> ::String
    ]
```

## `httpConfig = ["endpoint" =>  ::String]`
Http endpoint settings.

# Returns

`CreateDataSourceResponse`

# Exceptions

`BadRequestException`, `ConcurrentModificationException`, `NotFoundException`, `UnauthorizedException` or `InternalFailureException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/appsync-2017-07-25/CreateDataSource)
"""
@inline create_data_source(aws::AWSConfig=default_aws_config(); args...) = create_data_source(aws, args)

@inline create_data_source(aws::AWSConfig, args) = AWSCore.Services.appsync(aws, "POST", "/v1/apis/{apiId}/datasources", args)

@inline create_data_source(args) = create_data_source(default_aws_config(), args)

"""
    using AWSSDK.AppSync.create_graphql_api
    create_graphql_api([::AWSConfig], arguments::Dict)
    create_graphql_api([::AWSConfig]; name=, authenticationType=, <keyword arguments>)

    using AWSCore.Services.appsync
    appsync([::AWSConfig], "POST", "/v1/apis", arguments::Dict)
    appsync([::AWSConfig], "POST", "/v1/apis", name=, authenticationType=, <keyword arguments>)

# CreateGraphqlApi Operation

Creates a `GraphqlApi` object.

# Arguments

## `name = ::String` -- *Required*
A user-supplied name for the `GraphqlApi`.

## `logConfig = [ ... ]`
The Amazon CloudWatch logs configuration.
```
 logConfig = [
        "fieldLogLevel" => <required> "NONE", "ERROR" or "ALL",
        "cloudWatchLogsRoleArn" => <required> ::String
    ]
```

## `authenticationType = "API_KEY", "AWS_IAM", "AMAZON_COGNITO_USER_POOLS" or "OPENID_CONNECT"` -- *Required*
The authentication type: API key, IAM, or Amazon Cognito User Pools.

## `userPoolConfig = [ ... ]`
The Amazon Cognito User Pool configuration.
```
 userPoolConfig = [
        "userPoolId" => <required> ::String,
        "awsRegion" => <required> ::String,
        "defaultAction" => <required> "ALLOW" or "DENY",
        "appIdClientRegex" =>  ::String
    ]
```

## `openIDConnectConfig = [ ... ]`
The Open Id Connect configuration configuration.
```
 openIDConnectConfig = [
        "issuer" => <required> ::String,
        "clientId" =>  ::String,
        "iatTTL" =>  ::Int,
        "authTTL" =>  ::Int
    ]
```

# Returns

`CreateGraphqlApiResponse`

# Exceptions

`BadRequestException`, `LimitExceededException`, `ConcurrentModificationException`, `UnauthorizedException`, `InternalFailureException` or `ApiLimitExceededException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/appsync-2017-07-25/CreateGraphqlApi)
"""
@inline create_graphql_api(aws::AWSConfig=default_aws_config(); args...) = create_graphql_api(aws, args)

@inline create_graphql_api(aws::AWSConfig, args) = AWSCore.Services.appsync(aws, "POST", "/v1/apis", args)

@inline create_graphql_api(args) = create_graphql_api(default_aws_config(), args)

"""
    using AWSSDK.AppSync.create_resolver
    create_resolver([::AWSConfig], arguments::Dict)
    create_resolver([::AWSConfig]; apiId=, typeName=, fieldName=, dataSourceName=, requestMappingTemplate=, <keyword arguments>)

    using AWSCore.Services.appsync
    appsync([::AWSConfig], "POST", "/v1/apis/{apiId}/types/{typeName}/resolvers", arguments::Dict)
    appsync([::AWSConfig], "POST", "/v1/apis/{apiId}/types/{typeName}/resolvers", apiId=, typeName=, fieldName=, dataSourceName=, requestMappingTemplate=, <keyword arguments>)

# CreateResolver Operation

Creates a `Resolver` object.

A resolver converts incoming requests into a format that a data source can understand and converts the data source's responses into GraphQL.

# Arguments

## `apiId = ::String` -- *Required*
The ID for the GraphQL API for which the resolver is being created.

## `typeName = ::String` -- *Required*
The name of the `Type`.

## `fieldName = ::String` -- *Required*
The name of the field to attach the resolver to.

## `dataSourceName = ::String` -- *Required*
The name of the data source for which the resolver is being created.

## `requestMappingTemplate = ::String` -- *Required*
The mapping template to be used for requests.

A resolver uses a request mapping template to convert a GraphQL expression into a format that a data source can understand. Mapping templates are written in Apache Velocity Template Language (VTL).

## `responseMappingTemplate = ::String`
The mapping template to be used for responses from the data source.

# Returns

`CreateResolverResponse`

# Exceptions

`ConcurrentModificationException`, `NotFoundException`, `UnauthorizedException` or `InternalFailureException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/appsync-2017-07-25/CreateResolver)
"""
@inline create_resolver(aws::AWSConfig=default_aws_config(); args...) = create_resolver(aws, args)

@inline create_resolver(aws::AWSConfig, args) = AWSCore.Services.appsync(aws, "POST", "/v1/apis/{apiId}/types/{typeName}/resolvers", args)

@inline create_resolver(args) = create_resolver(default_aws_config(), args)

"""
    using AWSSDK.AppSync.create_type
    create_type([::AWSConfig], arguments::Dict)
    create_type([::AWSConfig]; apiId=, definition=, format=)

    using AWSCore.Services.appsync
    appsync([::AWSConfig], "POST", "/v1/apis/{apiId}/types", arguments::Dict)
    appsync([::AWSConfig], "POST", "/v1/apis/{apiId}/types", apiId=, definition=, format=)

# CreateType Operation

Creates a `Type` object.

# Arguments

## `apiId = ::String` -- *Required*
The API ID.

## `definition = ::String` -- *Required*
The type definition, in GraphQL Schema Definition Language (SDL) format.

For more information, see the [GraphQL SDL documentation](http://graphql.org/learn/schema/).

## `format = "SDL" or "JSON"` -- *Required*
The type format: SDL or JSON.

# Returns

`CreateTypeResponse`

# Exceptions

`BadRequestException`, `ConcurrentModificationException`, `NotFoundException`, `UnauthorizedException` or `InternalFailureException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/appsync-2017-07-25/CreateType)
"""
@inline create_type(aws::AWSConfig=default_aws_config(); args...) = create_type(aws, args)

@inline create_type(aws::AWSConfig, args) = AWSCore.Services.appsync(aws, "POST", "/v1/apis/{apiId}/types", args)

@inline create_type(args) = create_type(default_aws_config(), args)

"""
    using AWSSDK.AppSync.delete_api_key
    delete_api_key([::AWSConfig], arguments::Dict)
    delete_api_key([::AWSConfig]; apiId=, id=)

    using AWSCore.Services.appsync
    appsync([::AWSConfig], "DELETE", "/v1/apis/{apiId}/apikeys/{id}", arguments::Dict)
    appsync([::AWSConfig], "DELETE", "/v1/apis/{apiId}/apikeys/{id}", apiId=, id=)

# DeleteApiKey Operation

Deletes an API key.

# Arguments

## `apiId = ::String` -- *Required*
The API ID.

## `id = ::String` -- *Required*
The ID for the API key.

# Returns

`DeleteApiKeyResponse`

# Exceptions

`BadRequestException`, `NotFoundException`, `UnauthorizedException` or `InternalFailureException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/appsync-2017-07-25/DeleteApiKey)
"""
@inline delete_api_key(aws::AWSConfig=default_aws_config(); args...) = delete_api_key(aws, args)

@inline delete_api_key(aws::AWSConfig, args) = AWSCore.Services.appsync(aws, "DELETE", "/v1/apis/{apiId}/apikeys/{id}", args)

@inline delete_api_key(args) = delete_api_key(default_aws_config(), args)

"""
    using AWSSDK.AppSync.delete_data_source
    delete_data_source([::AWSConfig], arguments::Dict)
    delete_data_source([::AWSConfig]; apiId=, name=)

    using AWSCore.Services.appsync
    appsync([::AWSConfig], "DELETE", "/v1/apis/{apiId}/datasources/{name}", arguments::Dict)
    appsync([::AWSConfig], "DELETE", "/v1/apis/{apiId}/datasources/{name}", apiId=, name=)

# DeleteDataSource Operation

Deletes a `DataSource` object.

# Arguments

## `apiId = ::String` -- *Required*
The API ID.

## `name = ::String` -- *Required*
The name of the data source.

# Returns

`DeleteDataSourceResponse`

# Exceptions

`BadRequestException`, `ConcurrentModificationException`, `NotFoundException`, `UnauthorizedException` or `InternalFailureException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/appsync-2017-07-25/DeleteDataSource)
"""
@inline delete_data_source(aws::AWSConfig=default_aws_config(); args...) = delete_data_source(aws, args)

@inline delete_data_source(aws::AWSConfig, args) = AWSCore.Services.appsync(aws, "DELETE", "/v1/apis/{apiId}/datasources/{name}", args)

@inline delete_data_source(args) = delete_data_source(default_aws_config(), args)

"""
    using AWSSDK.AppSync.delete_graphql_api
    delete_graphql_api([::AWSConfig], arguments::Dict)
    delete_graphql_api([::AWSConfig]; apiId=)

    using AWSCore.Services.appsync
    appsync([::AWSConfig], "DELETE", "/v1/apis/{apiId}", arguments::Dict)
    appsync([::AWSConfig], "DELETE", "/v1/apis/{apiId}", apiId=)

# DeleteGraphqlApi Operation

Deletes a `GraphqlApi` object.

# Arguments

## `apiId = ::String` -- *Required*
The API ID.

# Returns

`DeleteGraphqlApiResponse`

# Exceptions

`BadRequestException`, `ConcurrentModificationException`, `NotFoundException`, `UnauthorizedException` or `InternalFailureException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/appsync-2017-07-25/DeleteGraphqlApi)
"""
@inline delete_graphql_api(aws::AWSConfig=default_aws_config(); args...) = delete_graphql_api(aws, args)

@inline delete_graphql_api(aws::AWSConfig, args) = AWSCore.Services.appsync(aws, "DELETE", "/v1/apis/{apiId}", args)

@inline delete_graphql_api(args) = delete_graphql_api(default_aws_config(), args)

"""
    using AWSSDK.AppSync.delete_resolver
    delete_resolver([::AWSConfig], arguments::Dict)
    delete_resolver([::AWSConfig]; apiId=, typeName=, fieldName=)

    using AWSCore.Services.appsync
    appsync([::AWSConfig], "DELETE", "/v1/apis/{apiId}/types/{typeName}/resolvers/{fieldName}", arguments::Dict)
    appsync([::AWSConfig], "DELETE", "/v1/apis/{apiId}/types/{typeName}/resolvers/{fieldName}", apiId=, typeName=, fieldName=)

# DeleteResolver Operation

Deletes a `Resolver` object.

# Arguments

## `apiId = ::String` -- *Required*
The API ID.

## `typeName = ::String` -- *Required*
The name of the resolver type.

## `fieldName = ::String` -- *Required*
The resolver field name.

# Returns

`DeleteResolverResponse`

# Exceptions

`ConcurrentModificationException`, `NotFoundException`, `UnauthorizedException` or `InternalFailureException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/appsync-2017-07-25/DeleteResolver)
"""
@inline delete_resolver(aws::AWSConfig=default_aws_config(); args...) = delete_resolver(aws, args)

@inline delete_resolver(aws::AWSConfig, args) = AWSCore.Services.appsync(aws, "DELETE", "/v1/apis/{apiId}/types/{typeName}/resolvers/{fieldName}", args)

@inline delete_resolver(args) = delete_resolver(default_aws_config(), args)

"""
    using AWSSDK.AppSync.delete_type
    delete_type([::AWSConfig], arguments::Dict)
    delete_type([::AWSConfig]; apiId=, typeName=)

    using AWSCore.Services.appsync
    appsync([::AWSConfig], "DELETE", "/v1/apis/{apiId}/types/{typeName}", arguments::Dict)
    appsync([::AWSConfig], "DELETE", "/v1/apis/{apiId}/types/{typeName}", apiId=, typeName=)

# DeleteType Operation

Deletes a `Type` object.

# Arguments

## `apiId = ::String` -- *Required*
The API ID.

## `typeName = ::String` -- *Required*
The type name.

# Returns

`DeleteTypeResponse`

# Exceptions

`BadRequestException`, `ConcurrentModificationException`, `NotFoundException`, `UnauthorizedException` or `InternalFailureException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/appsync-2017-07-25/DeleteType)
"""
@inline delete_type(aws::AWSConfig=default_aws_config(); args...) = delete_type(aws, args)

@inline delete_type(aws::AWSConfig, args) = AWSCore.Services.appsync(aws, "DELETE", "/v1/apis/{apiId}/types/{typeName}", args)

@inline delete_type(args) = delete_type(default_aws_config(), args)

"""
    using AWSSDK.AppSync.get_data_source
    get_data_source([::AWSConfig], arguments::Dict)
    get_data_source([::AWSConfig]; apiId=, name=)

    using AWSCore.Services.appsync
    appsync([::AWSConfig], "GET", "/v1/apis/{apiId}/datasources/{name}", arguments::Dict)
    appsync([::AWSConfig], "GET", "/v1/apis/{apiId}/datasources/{name}", apiId=, name=)

# GetDataSource Operation

Retrieves a `DataSource` object.

# Arguments

## `apiId = ::String` -- *Required*
The API ID.

## `name = ::String` -- *Required*
The name of the data source.

# Returns

`GetDataSourceResponse`

# Exceptions

`BadRequestException`, `ConcurrentModificationException`, `NotFoundException`, `UnauthorizedException` or `InternalFailureException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/appsync-2017-07-25/GetDataSource)
"""
@inline get_data_source(aws::AWSConfig=default_aws_config(); args...) = get_data_source(aws, args)

@inline get_data_source(aws::AWSConfig, args) = AWSCore.Services.appsync(aws, "GET", "/v1/apis/{apiId}/datasources/{name}", args)

@inline get_data_source(args) = get_data_source(default_aws_config(), args)

"""
    using AWSSDK.AppSync.get_graphql_api
    get_graphql_api([::AWSConfig], arguments::Dict)
    get_graphql_api([::AWSConfig]; apiId=)

    using AWSCore.Services.appsync
    appsync([::AWSConfig], "GET", "/v1/apis/{apiId}", arguments::Dict)
    appsync([::AWSConfig], "GET", "/v1/apis/{apiId}", apiId=)

# GetGraphqlApi Operation

Retrieves a `GraphqlApi` object.

# Arguments

## `apiId = ::String` -- *Required*
The API ID for the GraphQL API.

# Returns

`GetGraphqlApiResponse`

# Exceptions

`BadRequestException`, `NotFoundException`, `UnauthorizedException` or `InternalFailureException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/appsync-2017-07-25/GetGraphqlApi)
"""
@inline get_graphql_api(aws::AWSConfig=default_aws_config(); args...) = get_graphql_api(aws, args)

@inline get_graphql_api(aws::AWSConfig, args) = AWSCore.Services.appsync(aws, "GET", "/v1/apis/{apiId}", args)

@inline get_graphql_api(args) = get_graphql_api(default_aws_config(), args)

"""
    using AWSSDK.AppSync.get_introspection_schema
    get_introspection_schema([::AWSConfig], arguments::Dict)
    get_introspection_schema([::AWSConfig]; apiId=, format=)

    using AWSCore.Services.appsync
    appsync([::AWSConfig], "GET", "/v1/apis/{apiId}/schema", arguments::Dict)
    appsync([::AWSConfig], "GET", "/v1/apis/{apiId}/schema", apiId=, format=)

# GetIntrospectionSchema Operation

Retrieves the introspection schema for a GraphQL API.

# Arguments

## `apiId = ::String` -- *Required*
The API ID.

## `format = "SDL" or "JSON"` -- *Required*
The schema format: SDL or JSON.

# Returns

`GetIntrospectionSchemaResponse`

# Exceptions

`GraphQLSchemaException`, `NotFoundException`, `UnauthorizedException` or `InternalFailureException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/appsync-2017-07-25/GetIntrospectionSchema)
"""
@inline get_introspection_schema(aws::AWSConfig=default_aws_config(); args...) = get_introspection_schema(aws, args)

@inline get_introspection_schema(aws::AWSConfig, args) = AWSCore.Services.appsync(aws, "GET", "/v1/apis/{apiId}/schema", args)

@inline get_introspection_schema(args) = get_introspection_schema(default_aws_config(), args)

"""
    using AWSSDK.AppSync.get_resolver
    get_resolver([::AWSConfig], arguments::Dict)
    get_resolver([::AWSConfig]; apiId=, typeName=, fieldName=)

    using AWSCore.Services.appsync
    appsync([::AWSConfig], "GET", "/v1/apis/{apiId}/types/{typeName}/resolvers/{fieldName}", arguments::Dict)
    appsync([::AWSConfig], "GET", "/v1/apis/{apiId}/types/{typeName}/resolvers/{fieldName}", apiId=, typeName=, fieldName=)

# GetResolver Operation

Retrieves a `Resolver` object.

# Arguments

## `apiId = ::String` -- *Required*
The API ID.

## `typeName = ::String` -- *Required*
The resolver type name.

## `fieldName = ::String` -- *Required*
The resolver field name.

# Returns

`GetResolverResponse`

# Exceptions

`ConcurrentModificationException`, `NotFoundException` or `UnauthorizedException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/appsync-2017-07-25/GetResolver)
"""
@inline get_resolver(aws::AWSConfig=default_aws_config(); args...) = get_resolver(aws, args)

@inline get_resolver(aws::AWSConfig, args) = AWSCore.Services.appsync(aws, "GET", "/v1/apis/{apiId}/types/{typeName}/resolvers/{fieldName}", args)

@inline get_resolver(args) = get_resolver(default_aws_config(), args)

"""
    using AWSSDK.AppSync.get_schema_creation_status
    get_schema_creation_status([::AWSConfig], arguments::Dict)
    get_schema_creation_status([::AWSConfig]; apiId=)

    using AWSCore.Services.appsync
    appsync([::AWSConfig], "GET", "/v1/apis/{apiId}/schemacreation", arguments::Dict)
    appsync([::AWSConfig], "GET", "/v1/apis/{apiId}/schemacreation", apiId=)

# GetSchemaCreationStatus Operation

Retrieves the current status of a schema creation operation.

# Arguments

## `apiId = ::String` -- *Required*
The API ID.

# Returns

`GetSchemaCreationStatusResponse`

# Exceptions

`BadRequestException`, `NotFoundException`, `UnauthorizedException` or `InternalFailureException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/appsync-2017-07-25/GetSchemaCreationStatus)
"""
@inline get_schema_creation_status(aws::AWSConfig=default_aws_config(); args...) = get_schema_creation_status(aws, args)

@inline get_schema_creation_status(aws::AWSConfig, args) = AWSCore.Services.appsync(aws, "GET", "/v1/apis/{apiId}/schemacreation", args)

@inline get_schema_creation_status(args) = get_schema_creation_status(default_aws_config(), args)

"""
    using AWSSDK.AppSync.get_type
    get_type([::AWSConfig], arguments::Dict)
    get_type([::AWSConfig]; apiId=, typeName=, format=)

    using AWSCore.Services.appsync
    appsync([::AWSConfig], "GET", "/v1/apis/{apiId}/types/{typeName}", arguments::Dict)
    appsync([::AWSConfig], "GET", "/v1/apis/{apiId}/types/{typeName}", apiId=, typeName=, format=)

# GetType Operation

Retrieves a `Type` object.

# Arguments

## `apiId = ::String` -- *Required*
The API ID.

## `typeName = ::String` -- *Required*
The type name.

## `format = "SDL" or "JSON"` -- *Required*
The type format: SDL or JSON.

# Returns

`GetTypeResponse`

# Exceptions

`BadRequestException`, `ConcurrentModificationException`, `NotFoundException`, `UnauthorizedException` or `InternalFailureException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/appsync-2017-07-25/GetType)
"""
@inline get_type(aws::AWSConfig=default_aws_config(); args...) = get_type(aws, args)

@inline get_type(aws::AWSConfig, args) = AWSCore.Services.appsync(aws, "GET", "/v1/apis/{apiId}/types/{typeName}", args)

@inline get_type(args) = get_type(default_aws_config(), args)

"""
    using AWSSDK.AppSync.list_api_keys
    list_api_keys([::AWSConfig], arguments::Dict)
    list_api_keys([::AWSConfig]; apiId=, <keyword arguments>)

    using AWSCore.Services.appsync
    appsync([::AWSConfig], "GET", "/v1/apis/{apiId}/apikeys", arguments::Dict)
    appsync([::AWSConfig], "GET", "/v1/apis/{apiId}/apikeys", apiId=, <keyword arguments>)

# ListApiKeys Operation

Lists the API keys for a given API.

**Note**
> API keys are deleted automatically sometime after they expire. However, they may still be included in the response until they have actually been deleted. You can safely call `DeleteApiKey` to manually delete a key before it's automatically deleted.

# Arguments

## `apiId = ::String` -- *Required*
The API ID.

## `nextToken = ::String`
An identifier that was returned from the previous call to this operation, which can be used to return the next set of items in the list.

## `maxResults = ::Int`
The maximum number of results you want the request to return.

# Returns

`ListApiKeysResponse`

# Exceptions

`BadRequestException`, `NotFoundException`, `UnauthorizedException` or `InternalFailureException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/appsync-2017-07-25/ListApiKeys)
"""
@inline list_api_keys(aws::AWSConfig=default_aws_config(); args...) = list_api_keys(aws, args)

@inline list_api_keys(aws::AWSConfig, args) = AWSCore.Services.appsync(aws, "GET", "/v1/apis/{apiId}/apikeys", args)

@inline list_api_keys(args) = list_api_keys(default_aws_config(), args)

"""
    using AWSSDK.AppSync.list_data_sources
    list_data_sources([::AWSConfig], arguments::Dict)
    list_data_sources([::AWSConfig]; apiId=, <keyword arguments>)

    using AWSCore.Services.appsync
    appsync([::AWSConfig], "GET", "/v1/apis/{apiId}/datasources", arguments::Dict)
    appsync([::AWSConfig], "GET", "/v1/apis/{apiId}/datasources", apiId=, <keyword arguments>)

# ListDataSources Operation

Lists the data sources for a given API.

# Arguments

## `apiId = ::String` -- *Required*
The API ID.

## `nextToken = ::String`
An identifier that was returned from the previous call to this operation, which can be used to return the next set of items in the list.

## `maxResults = ::Int`
The maximum number of results you want the request to return.

# Returns

`ListDataSourcesResponse`

# Exceptions

`BadRequestException`, `NotFoundException`, `UnauthorizedException` or `InternalFailureException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/appsync-2017-07-25/ListDataSources)
"""
@inline list_data_sources(aws::AWSConfig=default_aws_config(); args...) = list_data_sources(aws, args)

@inline list_data_sources(aws::AWSConfig, args) = AWSCore.Services.appsync(aws, "GET", "/v1/apis/{apiId}/datasources", args)

@inline list_data_sources(args) = list_data_sources(default_aws_config(), args)

"""
    using AWSSDK.AppSync.list_graphql_apis
    list_graphql_apis([::AWSConfig], arguments::Dict)
    list_graphql_apis([::AWSConfig]; <keyword arguments>)

    using AWSCore.Services.appsync
    appsync([::AWSConfig], "GET", "/v1/apis", arguments::Dict)
    appsync([::AWSConfig], "GET", "/v1/apis", <keyword arguments>)

# ListGraphqlApis Operation

Lists your GraphQL APIs.

# Arguments

## `nextToken = ::String`
An identifier that was returned from the previous call to this operation, which can be used to return the next set of items in the list.

## `maxResults = ::Int`
The maximum number of results you want the request to return.

# Returns

`ListGraphqlApisResponse`

# Exceptions

`BadRequestException`, `UnauthorizedException` or `InternalFailureException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/appsync-2017-07-25/ListGraphqlApis)
"""
@inline list_graphql_apis(aws::AWSConfig=default_aws_config(); args...) = list_graphql_apis(aws, args)

@inline list_graphql_apis(aws::AWSConfig, args) = AWSCore.Services.appsync(aws, "GET", "/v1/apis", args)

@inline list_graphql_apis(args) = list_graphql_apis(default_aws_config(), args)

"""
    using AWSSDK.AppSync.list_resolvers
    list_resolvers([::AWSConfig], arguments::Dict)
    list_resolvers([::AWSConfig]; apiId=, typeName=, <keyword arguments>)

    using AWSCore.Services.appsync
    appsync([::AWSConfig], "GET", "/v1/apis/{apiId}/types/{typeName}/resolvers", arguments::Dict)
    appsync([::AWSConfig], "GET", "/v1/apis/{apiId}/types/{typeName}/resolvers", apiId=, typeName=, <keyword arguments>)

# ListResolvers Operation

Lists the resolvers for a given API and type.

# Arguments

## `apiId = ::String` -- *Required*
The API ID.

## `typeName = ::String` -- *Required*
The type name.

## `nextToken = ::String`
An identifier that was returned from the previous call to this operation, which can be used to return the next set of items in the list.

## `maxResults = ::Int`
The maximum number of results you want the request to return.

# Returns

`ListResolversResponse`

# Exceptions

`BadRequestException`, `NotFoundException`, `UnauthorizedException` or `InternalFailureException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/appsync-2017-07-25/ListResolvers)
"""
@inline list_resolvers(aws::AWSConfig=default_aws_config(); args...) = list_resolvers(aws, args)

@inline list_resolvers(aws::AWSConfig, args) = AWSCore.Services.appsync(aws, "GET", "/v1/apis/{apiId}/types/{typeName}/resolvers", args)

@inline list_resolvers(args) = list_resolvers(default_aws_config(), args)

"""
    using AWSSDK.AppSync.list_types
    list_types([::AWSConfig], arguments::Dict)
    list_types([::AWSConfig]; apiId=, format=, <keyword arguments>)

    using AWSCore.Services.appsync
    appsync([::AWSConfig], "GET", "/v1/apis/{apiId}/types", arguments::Dict)
    appsync([::AWSConfig], "GET", "/v1/apis/{apiId}/types", apiId=, format=, <keyword arguments>)

# ListTypes Operation

Lists the types for a given API.

# Arguments

## `apiId = ::String` -- *Required*
The API ID.

## `format = "SDL" or "JSON"` -- *Required*
The type format: SDL or JSON.

## `nextToken = ::String`
An identifier that was returned from the previous call to this operation, which can be used to return the next set of items in the list.

## `maxResults = ::Int`
The maximum number of results you want the request to return.

# Returns

`ListTypesResponse`

# Exceptions

`BadRequestException`, `ConcurrentModificationException`, `NotFoundException`, `UnauthorizedException` or `InternalFailureException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/appsync-2017-07-25/ListTypes)
"""
@inline list_types(aws::AWSConfig=default_aws_config(); args...) = list_types(aws, args)

@inline list_types(aws::AWSConfig, args) = AWSCore.Services.appsync(aws, "GET", "/v1/apis/{apiId}/types", args)

@inline list_types(args) = list_types(default_aws_config(), args)

"""
    using AWSSDK.AppSync.start_schema_creation
    start_schema_creation([::AWSConfig], arguments::Dict)
    start_schema_creation([::AWSConfig]; apiId=, definition=)

    using AWSCore.Services.appsync
    appsync([::AWSConfig], "POST", "/v1/apis/{apiId}/schemacreation", arguments::Dict)
    appsync([::AWSConfig], "POST", "/v1/apis/{apiId}/schemacreation", apiId=, definition=)

# StartSchemaCreation Operation

Adds a new schema to your GraphQL API.

This operation is asynchronous. Use to determine when it has completed.

# Arguments

## `apiId = ::String` -- *Required*
The API ID.

## `definition = blob` -- *Required*
The schema definition, in GraphQL schema language format.

# Returns

`StartSchemaCreationResponse`

# Exceptions

`BadRequestException`, `ConcurrentModificationException`, `NotFoundException`, `UnauthorizedException` or `InternalFailureException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/appsync-2017-07-25/StartSchemaCreation)
"""
@inline start_schema_creation(aws::AWSConfig=default_aws_config(); args...) = start_schema_creation(aws, args)

@inline start_schema_creation(aws::AWSConfig, args) = AWSCore.Services.appsync(aws, "POST", "/v1/apis/{apiId}/schemacreation", args)

@inline start_schema_creation(args) = start_schema_creation(default_aws_config(), args)

"""
    using AWSSDK.AppSync.update_api_key
    update_api_key([::AWSConfig], arguments::Dict)
    update_api_key([::AWSConfig]; apiId=, id=, <keyword arguments>)

    using AWSCore.Services.appsync
    appsync([::AWSConfig], "POST", "/v1/apis/{apiId}/apikeys/{id}", arguments::Dict)
    appsync([::AWSConfig], "POST", "/v1/apis/{apiId}/apikeys/{id}", apiId=, id=, <keyword arguments>)

# UpdateApiKey Operation

Updates an API key.

# Arguments

## `apiId = ::String` -- *Required*
The ID for the GraphQL API

## `id = ::String` -- *Required*
The API key ID.

## `description = ::String`
A description of the purpose of the API key.

## `expires = ::Int`
The time from update time after which the API key expires. The date is represented as seconds since the epoch. For more information, see .

# Returns

`UpdateApiKeyResponse`

# Exceptions

`BadRequestException`, `NotFoundException`, `UnauthorizedException`, `LimitExceededException`, `InternalFailureException` or `ApiKeyValidityOutOfBoundsException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/appsync-2017-07-25/UpdateApiKey)
"""
@inline update_api_key(aws::AWSConfig=default_aws_config(); args...) = update_api_key(aws, args)

@inline update_api_key(aws::AWSConfig, args) = AWSCore.Services.appsync(aws, "POST", "/v1/apis/{apiId}/apikeys/{id}", args)

@inline update_api_key(args) = update_api_key(default_aws_config(), args)

"""
    using AWSSDK.AppSync.update_data_source
    update_data_source([::AWSConfig], arguments::Dict)
    update_data_source([::AWSConfig]; apiId=, name=, type=, <keyword arguments>)

    using AWSCore.Services.appsync
    appsync([::AWSConfig], "POST", "/v1/apis/{apiId}/datasources/{name}", arguments::Dict)
    appsync([::AWSConfig], "POST", "/v1/apis/{apiId}/datasources/{name}", apiId=, name=, type=, <keyword arguments>)

# UpdateDataSource Operation

Updates a `DataSource` object.

# Arguments

## `apiId = ::String` -- *Required*
The API ID.

## `name = ::String` -- *Required*
The new name for the data source.

## `description = ::String`
The new description for the data source.

## `type = "AWS_LAMBDA", "AMAZON_DYNAMODB", "AMAZON_ELASTICSEARCH", "NONE" or "HTTP"` -- *Required*
The new data source type.

## `serviceRoleArn = ::String`
The new service role ARN for the data source.

## `dynamodbConfig = [ ... ]`
The new DynamoDB configuration.
```
 dynamodbConfig = [
        "tableName" => <required> ::String,
        "awsRegion" => <required> ::String,
        "useCallerCredentials" =>  ::Bool
    ]
```

## `lambdaConfig = ["lambdaFunctionArn" => <required> ::String]`
The new Lambda configuration.

## `elasticsearchConfig = [ ... ]`
The new Elasticsearch configuration.
```
 elasticsearchConfig = [
        "endpoint" => <required> ::String,
        "awsRegion" => <required> ::String
    ]
```

## `httpConfig = ["endpoint" =>  ::String]`
The new http endpoint configuration

# Returns

`UpdateDataSourceResponse`

# Exceptions

`BadRequestException`, `ConcurrentModificationException`, `NotFoundException`, `UnauthorizedException` or `InternalFailureException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/appsync-2017-07-25/UpdateDataSource)
"""
@inline update_data_source(aws::AWSConfig=default_aws_config(); args...) = update_data_source(aws, args)

@inline update_data_source(aws::AWSConfig, args) = AWSCore.Services.appsync(aws, "POST", "/v1/apis/{apiId}/datasources/{name}", args)

@inline update_data_source(args) = update_data_source(default_aws_config(), args)

"""
    using AWSSDK.AppSync.update_graphql_api
    update_graphql_api([::AWSConfig], arguments::Dict)
    update_graphql_api([::AWSConfig]; apiId=, name=, <keyword arguments>)

    using AWSCore.Services.appsync
    appsync([::AWSConfig], "POST", "/v1/apis/{apiId}", arguments::Dict)
    appsync([::AWSConfig], "POST", "/v1/apis/{apiId}", apiId=, name=, <keyword arguments>)

# UpdateGraphqlApi Operation

Updates a `GraphqlApi` object.

# Arguments

## `apiId = ::String` -- *Required*
The API ID.

## `name = ::String` -- *Required*
The new name for the `GraphqlApi` object.

## `logConfig = [ ... ]`
The Amazon CloudWatch logs configuration for the `GraphqlApi` object.
```
 logConfig = [
        "fieldLogLevel" => <required> "NONE", "ERROR" or "ALL",
        "cloudWatchLogsRoleArn" => <required> ::String
    ]
```

## `authenticationType = "API_KEY", "AWS_IAM", "AMAZON_COGNITO_USER_POOLS" or "OPENID_CONNECT"`
The new authentication type for the `GraphqlApi` object.

## `userPoolConfig = [ ... ]`
The new Amazon Cognito User Pool configuration for the `GraphqlApi` object.
```
 userPoolConfig = [
        "userPoolId" => <required> ::String,
        "awsRegion" => <required> ::String,
        "defaultAction" => <required> "ALLOW" or "DENY",
        "appIdClientRegex" =>  ::String
    ]
```

## `openIDConnectConfig = [ ... ]`
The Open Id Connect configuration configuration for the `GraphqlApi` object.
```
 openIDConnectConfig = [
        "issuer" => <required> ::String,
        "clientId" =>  ::String,
        "iatTTL" =>  ::Int,
        "authTTL" =>  ::Int
    ]
```

# Returns

`UpdateGraphqlApiResponse`

# Exceptions

`BadRequestException`, `ConcurrentModificationException`, `NotFoundException`, `UnauthorizedException` or `InternalFailureException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/appsync-2017-07-25/UpdateGraphqlApi)
"""
@inline update_graphql_api(aws::AWSConfig=default_aws_config(); args...) = update_graphql_api(aws, args)

@inline update_graphql_api(aws::AWSConfig, args) = AWSCore.Services.appsync(aws, "POST", "/v1/apis/{apiId}", args)

@inline update_graphql_api(args) = update_graphql_api(default_aws_config(), args)

"""
    using AWSSDK.AppSync.update_resolver
    update_resolver([::AWSConfig], arguments::Dict)
    update_resolver([::AWSConfig]; apiId=, typeName=, fieldName=, dataSourceName=, requestMappingTemplate=, <keyword arguments>)

    using AWSCore.Services.appsync
    appsync([::AWSConfig], "POST", "/v1/apis/{apiId}/types/{typeName}/resolvers/{fieldName}", arguments::Dict)
    appsync([::AWSConfig], "POST", "/v1/apis/{apiId}/types/{typeName}/resolvers/{fieldName}", apiId=, typeName=, fieldName=, dataSourceName=, requestMappingTemplate=, <keyword arguments>)

# UpdateResolver Operation

Updates a `Resolver` object.

# Arguments

## `apiId = ::String` -- *Required*
The API ID.

## `typeName = ::String` -- *Required*
The new type name.

## `fieldName = ::String` -- *Required*
The new field name.

## `dataSourceName = ::String` -- *Required*
The new data source name.

## `requestMappingTemplate = ::String` -- *Required*
The new request mapping template.

## `responseMappingTemplate = ::String`
The new response mapping template.

# Returns

`UpdateResolverResponse`

# Exceptions

`ConcurrentModificationException`, `NotFoundException`, `UnauthorizedException` or `InternalFailureException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/appsync-2017-07-25/UpdateResolver)
"""
@inline update_resolver(aws::AWSConfig=default_aws_config(); args...) = update_resolver(aws, args)

@inline update_resolver(aws::AWSConfig, args) = AWSCore.Services.appsync(aws, "POST", "/v1/apis/{apiId}/types/{typeName}/resolvers/{fieldName}", args)

@inline update_resolver(args) = update_resolver(default_aws_config(), args)

"""
    using AWSSDK.AppSync.update_type
    update_type([::AWSConfig], arguments::Dict)
    update_type([::AWSConfig]; apiId=, typeName=, format=, <keyword arguments>)

    using AWSCore.Services.appsync
    appsync([::AWSConfig], "POST", "/v1/apis/{apiId}/types/{typeName}", arguments::Dict)
    appsync([::AWSConfig], "POST", "/v1/apis/{apiId}/types/{typeName}", apiId=, typeName=, format=, <keyword arguments>)

# UpdateType Operation

Updates a `Type` object.

# Arguments

## `apiId = ::String` -- *Required*
The API ID.

## `typeName = ::String` -- *Required*
The new type name.

## `definition = ::String`
The new definition.

## `format = "SDL" or "JSON"` -- *Required*
The new type format: SDL or JSON.

# Returns

`UpdateTypeResponse`

# Exceptions

`BadRequestException`, `ConcurrentModificationException`, `NotFoundException`, `UnauthorizedException` or `InternalFailureException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/appsync-2017-07-25/UpdateType)
"""
@inline update_type(aws::AWSConfig=default_aws_config(); args...) = update_type(aws, args)

@inline update_type(aws::AWSConfig, args) = AWSCore.Services.appsync(aws, "POST", "/v1/apis/{apiId}/types/{typeName}", args)

@inline update_type(args) = update_type(default_aws_config(), args)

end # module AppSync

#==============================================================================#
# End of file
#==============================================================================#


text:
primitives(vp::AbstractVolumePrimitive) = (vp,)
function primitives(csg::AbstractConstructiveGeometry)
    ps = []
    push!(ps, primitives(csg.a)...)
    push!(ps, primitives(csg.b)...)
    ps
end

@recipe function f(csg::AbstractConstructiveGeometry)
    ps = primitives(csg)
    @series begin
        label --> "CSG"
        if !isClosedPrimitive(ps[1])
            fillcolor := :white
            fillalpha --> 0.2
            if haskey(plotattributes, :seriestype)
                if plotattributes[:seriestype] in [:csg, :wireframe]
                    linewidth := 0.5
                end
            end
        end
        ps[1]
    end
    for i in 2:length(ps)
        @series begin
            label := ""
            if !isClosedPrimitive(ps[i])
                fillcolor := :white
                fillalpha --> 0.2
                if haskey(plotattributes, :seriestype)
                    if plotattributes[:seriestype] in [:csg, :wireframe]
                        linewidth := 0.5
                    end
                end
            end
            ps[i]
        end
    end
end

ext: jl


text:
julia> expr="2 * (3 -1) + 2 * 5"
"2 * (3 -1) + 2 * 5"

julia> parsed = parse(expr) #Julia provides low-level access to language parser for AST/Expr creation
:(+(*(2,-(3,1)),*(2,5)))

julia> t = typeof(parsed)
Expr

julia> names(t) #shows type fields
(:head,:args,:typ)

julia> parsed.args #Inspect our 'Expr' type innards
3-element Any Array:
 :+
 :(*(2,-(3,1)))
 :(*(2,5))

julia> typeof(parsed.args[2]) #'Expr' types can nest
Expr

julia> parsed.args[2].args
3-element Any Array:
  :*
 2
  :(-(3,1))

julia> parsed.args[2].args[3].args #Will nest until lowest level of AST
3-element Any Array:
  :-
 3
 1

julia> eval(parsed)
14

julia> eval(parse("1 - 5 * 2 / 20 + 1"))
1.5

julia> eval(parse("2 * (3 + ((5) / (7 - 11)))"))
3.5

max_stars_repo_name: ethansaxenian/RosettaDecode

max_issues_repo_name: ethansaxenian/RosettaDecode

max_forks_repo_name: ethansaxenian/RosettaDecode


text:
module KP
using Distributions, Roots, Optim, LinearAlgebra, MLDataUtils, Statistics

##VG Consider killing these exports
export x, best_x_tau, x_MM, x_MLE,
      x_dual, lam, shrink, x_l2reg,
      x_l2reg_CV, x_sure_MSE, x_stein_exact,
      x_OR_MSE, x_stein_box

### The main workhorse
#cs_unsc (unscaled) should have entries on order unity.
#The dual return fails with value -1 if the particular run is degenerate.
function x_dual(cs_unsc, rs)
    n = length(rs)
    ratios = rs ./ cs_unsc
    cs = cs_unsc/n #deliberately makes a copy
    indx = sortperm(ratios, rev=true)
    out = zeros(Float64, length(indx))
    weight = 0.
    dual = -1
    for ix = 1:length(indx)
    	#check if the item has positive value, else skip
    	if rs[indx[ix]] <=0.
    		continue
    	end

        #check if next item fits and it has positive value
        if weight + cs[indx[ix]] <= 1
            out[indx[ix]] = 1.
            weight += cs[indx[ix]]
        else
            #take fractional part
            # VG DEBUG out[[indx[ix]]] .= (1 - weight)/cs[indx[ix]]
            out[indx[ix]] = (1 - weight)/cs[indx[ix]]
            dual = ratios[indx[ix]]
            break
        end
    end
    out, dual
end

### Some generic helpers
function shrink(muhat, vs, tau)
    vmin = minimum(vs)
#    return @. (vmin + tau)/vmin * (vs / (vs + tau)) * muhat
    return (vmin + tau)/vmin * (vs ./ (vs .+ tau)) .* muhat
end

x(cs_unsc, rs) = x_dual(cs_unsc, rs)[1]

function lam(muhat, tau, vs, cs_unsc)
    rs = shrink(muhat, vs, tau)
    x_dual(cs_unsc, rs)[2]
end

function dual_obj(muhat, tau, vs, cs_unsc)
    l = lam(muhat, tau, vs, cs_unsc)
    l + mean(max(0, shrink(muhat, vs, tau) .- l * cs_unsc))
end

## Computing the whole grid
# helper used to identify next crossing point
# not to be exposed
function sbars(muhat, cs, vs, f_indx)
    out = zeros(Float64, length(muhat))
    for i = 1:length(out)
        out[i] = vs[i] * vs[f_indx] * (cs[i] * muhat[f_indx] - cs[f_indx] * muhat[i])
        out[i] /= cs[f_indx] * vs[i] * muhat[i] - cs[i] * vs[f_indx] * muhat[f_indx]
    end
    out
end

#Min_indx above a threshold
#returns -1 if there are no values above thresh
function indmin_thresh(vals, thresh)
	min_indx = -1
	min_val = Inf
	for ix = 1:length(vals)
		if thresh < vals[ix] < min_val
			min_indx = ix
			min_val = vals[ix]
		end
	end
	min_indx
end

# searches over bfs to figure out the best value of tau0
# cs_unsc has entries order unity.  cs has entires order 1/n
# returns max_xs, tau_vals, objs
# objs[ix] is the objective at tau_vals[ix] + eps
# For oracle, use muhat, thetas
# For Hold_out, use muhat1, muhat2
function best_x_tau(cs_unsc, muhat, vs, thetas)
	TOL = 1e-10
	n = length(muhat)
	ratios = muhat ./ cs_unsc
	indx = sortperm(ratios, rev=true)
	cs = cs_unsc/n  #makes a copy

	vals = Float64[]
	objs = Float64[]

	#first determine tau0 = 0 solution
	xs = zeros(n)
	total_weight = 0.
	frac_indx = -1
    for ix = 1:n
    	#check if the item has positive value, else skip
    	if muhat[indx[ix]] <=0.
    		continue
    	end

        #check if next item fits entirely
        if total_weight + cs[indx[ix]] <= 1
            xs[indx[ix]] = 1.
            total_weight += cs[indx[ix]]
        else
            #take fractional part
            xs[indx[ix]] = (1 - total_weight)/cs[indx[ix]]
            frac_indx = indx[ix]
            total_weight = 1.
            break
        end
    end

    ##check for a trivial solution
    if frac_indx == -1 || total_weight < 1
    	println("Trivial Problem Set-up:  All items fit.")
    	println("total_weight:\t $total_weight")
    	println("xs:\n", xs)
    	return xs, [0.], [dot(xs, thetas)/n]
    end

    #Now search across all possible tau0, constructing grid as you go
	tau0 = 0.  #always represents current value
    svals = sbars(muhat, cs, vs, frac_indx)
    max_obj = -1
    max_tau0 = 0.

    #At the beginining of every iteration xs is solution for tau0 + eps
   	iter = 0
    while tau0 > -1.
    	iter += 1
    	@assert iter < 1e7 "Max iterations exceeded"

	    #assess solution and record value
	    obj = dot(thetas, xs)/n
		push!(objs, obj)
    	push!(vals, tau0)
    	if obj > max_obj
    		max_obj = obj
    		max_tau0 = tau0
    	end

    	##Find the entering indx if it exists
    	indx_p = indmin_thresh(svals, tau0)
    	if indx_p == -1
    		tau0 = -1
    		continue
    	end

    	#pivot depends on whether element is already in basis or not.
    	if xs[indx_p] >= 1-TOL
    		#Case 1: Exiting Variable becomes zero
    		if cs[indx_p]/cs[frac_indx] <= 1 - xs[frac_indx]
    			xs[indx_p] = 0
    			xs[frac_indx] += cs[indx_p]/cs[frac_indx]
    			@assert xs[frac_indx] < 1  "Degeneracy? $(xs[frac_indx])"

    			#frac_indx and s_vals stay the same
    			tau0 = svals[indx_p]
    		else #Case 2: Exiting Variable becomes fractional
    			xs[indx_p] -= (1. - xs[frac_indx]) * cs[frac_indx]/cs[indx_p]
    			@assert xs[indx_p] > 0 "Dengeracy?"

    			xs[frac_indx] = 1
    			tau0 = svals[indx_p]
    			frac_indx = indx_p
    			svals = sbars(muhat, cs, vs, frac_indx)
    		end
    	else  #xs[indx_p] == 0
	    	frac_weight = xs[frac_indx] * cs[frac_indx]
    		#Case 1: Entering Variable becomes 1
	    	if frac_weight > cs[indx_p]
	    		xs[indx_p] = 1.
	    		xs[frac_indx] -= cs[indx_p]/cs[frac_indx]
	    		@assert xs[frac_indx] > 0 "Dengeracy?"

	    		#frac_indx and svals are unchanged
	    		tau0 = svals[indx_p]
	    	else #Case 2: Entering Variable becomes fractional
				xs[indx_p] = frac_weight / cs[indx_p]
				xs[frac_indx] = 0.
				tau0 = svals[indx_p]
				frac_indx = indx_p
				svals = sbars(muhat, cs, vs, frac_indx)
			end
		end
    end

    ##assume that solving one last time is short relative to costs
    indmax = findfirst(vals .>= max_tau0)
    if indmax == length(vals)
        max_xs = x(cs_unsc, shrink(muhat, vs, 1.1*max_tau0))
    else
        max_xs = x(cs_unsc, shrink(muhat, vs, .5*max_tau0 + .5*vals[indmax + 1]))
    end

    return max_xs, vals, objs
end

### Empirical Bayes Type Estimators
##EB Method of Moments
function x_MM(cs, muhat, vs)
	tau_mm = 1/mean(@. muhat^2 - 1/vs )
	tau_mm = max.(0, tau_mm)
	tau_mm, x(cs, shrink(muhat, vs, tau_mm))
end

##EB MLE
#Note, mathematically MLE might not solve.
#In this case, returns -1 for tau and the xs corresponding to tau0 = 0
function x_MLE(cs, muhat, vs, max_bnd = 1e2)
	#solve the MLE using a rootfinder solver for the variance and then invert
	vars = 1 ./ vs
	deriv_loglik(v) = mean(muhat.^2 ./ (v .+ vars).^2 - 1 ./(v .+ vars))

    #Check the bracket
    if deriv_loglik(0) * deriv_loglik(max_bnd) > 0
        return -1, x(cs, muhat)
    else
        v0 = fzero(deriv_loglik, 0, max_bnd)
        #check if you ran up against a bound
        if v0 >= max_bnd
            return -1, x(cs, muhat)
        end
    return 1/v0, x(cs, shrink(muhat, vs, 1/v0))
    end
end

### Other Estimate then Optimize Heuristics
##Selects tau0 to minimize oracle MSE
#We can use the old shrinkage to compute tau.
function x_OR_MSE(cs, muhat, thetas, vs; max_iter = 10)
    n = length(cs)
    function deriv_f(tau0)
        #use old scaling
        rs = muhat .* vs ./ (vs .+ tau0)
        mean( (thetas - rs) .* rs ./ (vs .+ tau0))
    end
    #bracketting tau0
    #this code is a bit lazy.
    max_bnd = 1
    sgn = sign(deriv_f(0))
    iter_ = 0
    for iter = 1:max_iter
        if sgn * deriv_f(max_bnd) < 0
            break
        else
            max_bnd *= 2
        end
        iter_ = iter  #to get around scoping problem
    end
    #if iteration limit reached, just return zero
    tau_star = 0.
    if iter_ != max_iter
        tau_star = fzero(deriv_f, 0, max_bnd)
    end
    return x(cs, shrink(muhat, vs, tau_star)), tau_star
end

#Selects tau0 to minimize SURE of MSE
function x_sure_MSE(cs, muhat, vs)
    f_deriv(tau) = dot(vs .* (muhat.^2 * tau .- 1) .- tau,
                            1. ./(vs .+ tau).^3)

    #bracket for ub
    lb, ub = 0., 1.
    iter = 1
    MAX_ITER = 20
    while f_deriv(ub) < 0 && iter < MAX_ITER
        lb = ub
        ub *= 2
        iter += 1
    end
    if iter == MAX_ITER
        return x(cs, muhat), -1 #Returnthe SAA with an error flat
    end

    @assert iter < MAX_ITER "max iterations reached"
    tau_star = fzero(f_deriv, lb, ub)
    rs = shrink(muhat, vs, tau_star)

    return x_dual(cs, rs)[1], tau_star
end

## Cross-val procedure for EB class
#dat is assumed column major size(dat) = (n, S) (S for samples)
#vs is the precision of \xi, i.e, one column of dat
#muhat has precision vs * S
function x_kFoldCV(cs, vs_xi, dat, numFolds;
                    tau_grid = linspace(0, 10, 100))
    #divy the folds
    S = size(dat, 2)
    n = size(dat, 1)
    train, test = kfolds(S, numFolds)
    objs_all = zeros(length(tau_grid))
    vs_sc = zeros(length(vs_xi))

    xs_t = zeros(n)
    for i = 1:numFolds
        num_train = length(train[i])
        @. vs_sc = vs_xi * num_train

        #form muhat  and leftover
        muhat = vec(mean(dat[:, train[i]], dims=2))
        zeta  = vec(mean(dat[:,  test[i]], dims=2))

        #eval on tau_grid pseudo-manually
        for j = 1:length(objs_all)
            xs_t[:] = x(cs, shrink(muhat, vs_sc, tau_grid[j]))
            objs_all[j] += dot(zeta, xs_t) / n /numFolds
        end
    end
    tau_hat = tau_grid[argmax(objs_all)]
    x(cs, shrink(vec(mean(dat, dims=2)), vs_xi * S, tau_hat)), tau_grid, objs_all
end

#######
### Regularization based Methods
#########
function g_j(Gamma, lam, cj, muhat_j, vj, sqrt_vmin)
    t = muhat_j - lam * cj
    if t < 0
        return 0.
    elseif t < Gamma * sqrt_vmin / vj
        return t * vj / Gamma / sqrt_vmin
    else
        return 1.
    end
end

#cs are unscaled (each element order unity)
#this is a bad signature.  x_out is overwritten and it returns dual variable
#Try to rationalize this and think about what is most memory efficient in code
function x_l2reg2!(cs, muhat, vs, Gamma, x_out;
                    lam_guess::Float64 = -1., ROOT_TOL::Float64=1e-6, TOL::Float64=1e-6)
    n = length(cs)
    sqrt_vmin = sqrt(minimum(vs))
    @assert length(x_out) == n "Return vector wrong size $(n) vs. $(length(x_out))"

    #Find lambda by making knapsack tight
    function f(lam)
        mean(cs .* g_j.(Gamma, lam, cs, muhat, vs, sqrt_vmin)) - 1
    end

    #if you have lam_guess, assume gammas are close together
    #use this to guess a reasonable STARTING bracket
    if lam_guess  > 0
        lhs_prev = f(lam_guess)
        if lhs_prev > TOL
            lb = lam_guess
            ub = 2lb
        elseif lhs_prev < -TOL
            ub = lam_guess
            lb = .5*ub
        else #by luck, lam_guess is perfect
            #exit early
            x_out[:] = g_j.(Gamma, lam_guess, cs[jx], muhat[jx], vs[jx], sqrt_vmin)
            return lam_guess
        end
    else #solving from scratch
        lb, ub = 0.1, 1.
    end

    #Now refine/correct the bracket so it is valid
    #A valid bracket satisfies f(lb) > 0, f(ub) < 0
    iter = 1
    MAX_ITER = 20
    while f(ub)*f(lb) > 0. && iter < MAX_ITER
        f(lb) <= 0 && (lb /= 2.)
        f(ub) >= 0 && (ub *= 2.)
        iter += 1
    end

    if iter == MAX_ITER
        #maybe everything fits in the knapsack
        if f(0.) <= 0
            for jx = 1:n
                x_out[jx] = g_j(Gamma, 0., cs[jx], muhat[jx], vs[jx], sqrt_vmin)
            end
            return 0.
        else #bracketing failed
            @assert iter < MAX_ITER "Maximum bracketing iterations reached in regularized dual"
        end
    end

    #refine solution. Default to bisection if goes badly.
    lam_out = 0.
    try
        lam_out = find_zero(lam -> f(lam), [lb, ub], FalsePosition(), ftol=ROOT_TOL)
    catch
        println("False Position Failed")
        try
            lam_out = find_zero(lam -> f(lam), [lb, ub], Bisection(), ftol=ROOT_TOL)
        catch
            println("Bisection also fails??")
            error()
        end
    end

    x_out[:] = g_j.(Gamma, lam_out, cs, muhat, vs, sqrt_vmin)
    lam_out
end

#Selects Gamma via hold-out validation
#Use muhat/thetas to compute oracle value
#Use muhat1/muhat2 for holdout validation
#output xhat, Gamma_grid, objs
function x_l2reg_CV(cs, muhat, vs, thetas;
                    Gamma_step = .01, Gamma_min = .1, Gamma_max = 10)
    n = length(muhat)
    Gamma_grid = collect(Gamma_min:Gamma_step:Gamma_max)

    #Exhaustive search
    best_val = -1.
    xhat = zeros(n)
    x_t  = zeros(n)
    lam_t = 0.
    objs = zeros(length(Gamma_grid))

    for (ix, Gamma) in enumerate(Gamma_grid)
        if ix > 1 #warm start
            lam_t = x_l2reg2!(cs, muhat, vs, Gamma, x_t, lam_guess=lam_t)
        else
            lam_t = x_l2reg2!(cs, muhat, vs, Gamma, x_t)
        end

        objs[ix] = dot(thetas, x_t)/n
        if objs[ix] > best_val
            best_val = objs[ix]
            xhat[:] = x_t
        end
    end

    return xhat, Gamma_grid, objs
end

## Cross-val procedure for Regularization Class
#dat is column major size(dat) = (n, S)  (S for samples)
#vs is the \xi, i.e, one column of dat
#muhat has precision vs * S
function x_l2reg_kFoldCV(cs, vs, dat, numFolds;
                    Gamma_step = .01, Gamma_min = .1, Gamma_max = 10)
    #divy the folds
    S = size(dat, 2)
    train, test = kfolds(S, numFolds)
    Gamma_grid = collect(Gamma_min:Gamma_step:Gamma_max)
    objs_all = zeros(length(Gamma_grid))
    vs_sc = zeros(length(vs))

    for i = 1:numFolds
        #scale by size of fold, might not be equal for all flds
        num_train = length(train[i])
        vs_sc[:] = vs .* num_train

        #form muhat  and leftover
        muhat = mean(dat[:, train[i]], dims=2)
        zeta  = mean(dat[:,  test[i]], dims=2)

        #eval on GammaGrid using above workhorse
        objs = x_l2reg_CV(cs, muhat, vs_sc, zeta;
                    Gamma_step=Gamma_step, Gamma_min=Gamma_min, Gamma_max=Gamma_max)[3]
        objs_all[:] += objs ./ numFolds
    end
    #avg and choose Gammahat
    #Crucially gamma_grid same between runs and as above
    Gammahat = Gamma_grid[argmax(objs_all)]
    xs = zeros(size(dat, 1))
    x_l2reg2!(cs, mean(dat, dims=2), vs * S, Gammahat, xs)

    xs, Gamma_grid, objs_all
end

### EB Optimization Approaches

##Dirac Expansion
#Evaluation of Stein term by approximating lambda approx
#Serves as an upperbound on choice of bandwidth
#cs are unscaled
function dirac_bias(vs, tau, muhat, lam, cs_unsc, thetas)
    out = 0.
    n = length(vs)
    vmin = minimum(vs)
    for jx = 1:n
        rj = (vmin + tau)/vmin * vs[jx]/(vs[jx] + tau) * thetas[jx]
        arg = (lam * cs_unsc[jx] - rj)
        arg *= (vs[jx] + tau) * vmin / (vmin + tau) / sqrt(vs[jx])
        out += exp(-.5 * arg^2) / sqrt(2*pi * vs[jx])
    end
    return out/n
end

##Stein approach using an exact dirac calculation
#only approximations are lam(t,z) -> lam(t) and ULLN
#Serves as an upperbound on performance of a kernel bandwith
function x_stein_exact(cs_unsc, muhat, vs, thetas; tau_step = .01, tau_max = 5.)
    n = length(vs)
    tau_grid = collect(0.:tau_step:tau_max)
    objs = zeros(length(tau_grid))
    obj_best = -Inf
    tau_best = -1.
    for ix = 1:length(tau_grid)
        xs, lam = x_dual(cs_unsc, shrink(muhat, vs, tau_grid[ix]))
        #compute the value corresponding to evaluating the dirac
        objs[ix] = dot(muhat, xs)/n - dirac_bias(vs, tau_grid[ix], muhat, lam, cs_unsc, thetas)

        if objs[ix] > obj_best
            tau_best = tau_grid[ix]
            obj_best = objs[ix]
        end
    end
    #solving once more is fast compared to rest of algorithm
    return x(cs_unsc, shrink(muhat, vs, tau_best)), tau_grid, objs
end

#Approximate the dirac with an box kernel
#rs is the shrunken value
function approx_bias(vs, tau, rs, lam, cs, h)
    out = 0.
    n = length(vs)
    vmin = minimum(vs)
    hj = h
    for jx = 1:n
        hj = h * (vmin + tau)/vmin * sqrt(vs[jx])/(vs[jx] + tau)
        if abs(rs[jx] - lam * cs[jx]) <= hj
            out += 1/sqrt(vs[jx]) / h / 2
        end
    end
    out/n
end

#Stein formula using an kernel approximation for the dirac
function x_stein_box(cs_unsc, muhat, vs, h;
                     tau_step = .01, tau_max = 5.)
    n = length(vs)
    tau_grid = collect(0.:tau_step:tau_max)
    objs = fill(0., size(tau_grid))
    obj_best = -Inf
    tau_best = -1.
    for ix = 1:length(tau_grid)
        xs, lam = x_dual(cs_unsc, shrink(muhat, vs, tau_grid[ix]))
        #compute the value corresponding to evaluating the dirac
        #approximates lambda by the finite dual value...
        objs[ix] = dot(muhat, xs)/n -
                approx_bias(vs, tau_grid[ix], shrink(muhat, vs, tau_grid[ix]),
                                lam, cs_unsc, h)

        if objs[ix] > obj_best
            tau_best = tau_grid[ix]
            obj_best = objs[ix]
        end
    end

    return x(cs_unsc, shrink(muhat, vs, tau_best)), tau_grid, objs
end

##Approximating Stein by First Order (primal) difference
#Lazy direct way.
function primal_approx_bias(vs, tau, muhat, lam, cs, h)
    out = 0.
    n = length(vs)
    ej = zeros(n)
    for jx = 1:n
        if jx > 1
            ej[jx-1] = 0.
        end
        ej[jx] = h / sqrt(vs[jx])

        xs_p = x(cs, shrink(muhat .+ ej, vs, tau))[jx]
        xs_m = x(cs, shrink(muhat .- ej, vs, tau))[jx]

        out += (xs_p - xs_m) / 2 / h / sqrt(vs[jx])
    end
    out/n
end

# a smarter way to do this would leverage the parametric programming
function x_stein_primal(cs_unsc, muhat, vs, h; tau_step = .01, tau_max = 5.)
    tau_grid = collect(0.:tau_step:tau_max)
    objs = zeros(length(tau_grid))
    obj_best = -Inf
    tau_best = -1.
    n =length(vs)
    for ix = 1:length(tau_grid)
        xs, lam = x_dual(cs_unsc, shrink(muhat, vs, tau_grid[ix]))
        #compute the value corresponding to evaluating the dirac
        #approximates lambda by the finite dual value...
        objs[ix] = dot(muhat, xs)/n - primal_approx_bias(vs, tau_grid[ix], muhat, lam, cs_unsc, h)

        if objs[ix] > obj_best
            tau_best = tau_grid[ix]
            obj_best = objs[ix]
        end
    end

    return x(cs_unsc, shrink(muhat, vs, tau_best)), tau_grid, objs
end

##Regularization bias via stein's lemma
function reg_bias(cs, vs, muhats, lam, Gamma)
    out = 0.
    n = length(vs)
    sqrt_vmin = sqrt(minimum(vs))
    for jx = 1:n
        if 0 <= muhats[jx] - lam * cs[jx] <= Gamma * sqrt_vmin/vs[jx]
            out += 1
        end
    end
    out / Gamma / sqrt_vmin / n
end

function x_stein_reg(cs_unsc, muhat, vs; Gamma_step = .01, Gamma_min = .1, Gamma_max = 10)
    Gamma_grid = collect(Gamma_min:Gamma_step:Gamma_max)

    #preallocated for speed
    n =length(vs)
    objs = fill(0., size(Gamma_grid))
    xs = zeros(n)

    #updated as we find better values
    obj_best, Gamma_best, lam = -Inf, -1., -1.

    for ix = 1:length(Gamma_grid)
        #use warm-start information
        if ix > 1
            lam = x_l2reg2!(cs_unsc, muhat, vs, Gamma_grid[ix], xs, lam_guess=lam)
        else
            lam = x_l2reg2!(cs_unsc, muhat, vs, Gamma_grid[ix], xs)
        end
        objs[ix] = dot(muhat, xs)/n - reg_bias(cs_unsc, vs, muhat, lam, Gamma_grid[ix])

        if objs[ix] > obj_best
            Gamma_best = Gamma_grid[ix]
            obj_best = objs[ix]
        end
    end
    Gamma_best >= Gamma_max-1e-10 && println("Gamma Grid too small ", Gamma_min, " ", Gamma_max)
    lam = x_l2reg2!(cs_unsc, muhat, vs, Gamma_best, xs)
    return xs, Gamma_grid, objs
end

function x_LOO_reg(cs_unsc, muhat1, muhat2, vs;
                    Gamma_step = .01, Gamma_min = .1, Gamma_max = 10)
    #VG What is the nice way to do this?
    xs1, Gamma_grid, objs1 = x_l2reg_CV(cs_unsc, muhat1, vs/2, muhat2,
                        Gamma_step=Gamma_step, Gamma_min=Gamma_min,
                        Gamma_max=Gamma_max)
    xs2, Gamma_grid, objs2 = x_l2reg_CV(cs_unsc, muhat2, vs/2, muhat1,
                        Gamma_step=Gamma_step, Gamma_min=Gamma_min,
                        Gamma_max=Gamma_max)

    #Exploits fact that Gamma_grid is identical.
    objs = .5 .* (objs1 .+ objs2)
    Gamma_best = Gamma_grid[argmax(objs)]
    Gamma_best >= Gamma_max-1e-10 && println("Gamma Grid too small ", Gamma_min, " ", Gamma_max)

    lam = x_l2reg2!(cs_unsc, .5 .* (muhat1 .+ muhat2), vs, Gamma_best, xs1)
    return xs1, Gamma_grid, objs
end

#Solves the robust problem using FW
#assumes r is radius of ellipse, i.e. rob counterpart has r/n * norm(xs)_vs
function x_robFW(cs, muhat, vs, r; MAX_ITER = 100, TOL=1e-6)
    iter = 1
    n = length(muhat)
    sqrt_vs = sqrt.(vs)
    function grad!(xs, g)
        g[:] = muhat/n - r/norm(xs ./ sqrt_vs)/n * xs ./ vs
    end
    g = zeros(n)
    d = zeros(n)
    xp = x(cs, muhat)
    prev_value = -Inf
    while iter < MAX_ITER
        #solve the subproblem to find a direction.
        grad!(xp, g)
        d[:] = x(cs, g)

        #optimize the step
        #notice the negatives because we are maximizing.
        f(step) = -dot(muhat, xp + step * (d - xp))/n +
                    r/n * norm((xp + step * (d - xp))./ sqrt_vs)
        step_star = Optim.minimizer(optimize(f, 0, 1))

        if abs(-f(step_star) - prev_value) <= TOL
            break
        else
            prev_value = -f(step_star)
        end

        xp += step_star * (d - xp)
        iter += 1
    end

    @assert iter < MAX_ITER "Maximum Iterations reached in FW"
    return xp
end

end #ends module

max_stars_repo_path: Normal Model/KPNormal.jl

max_issues_repo_path: Normal Model/KPNormal.jl

max_forks_repo_path: Normal Model/KPNormal.jl


text:
export CollisionChecker, DiscreteCollisionChecker, SweptCollisionChecker
export is_free_state, is_free_motion, is_free_path, inflate, addobstacle, addblocker, close, closest

abstract CollisionChecker
abstract DiscreteCollisionChecker <: CollisionChecker
abstract SweptCollisionChecker <: CollisionChecker

include("collisioncheckers/SAT2D.jl")
include("collisioncheckers/robots2D.jl")
include("collisioncheckers/bvls.jl")
include("collisioncheckers/boxesND.jl")


text:
# __precompile__()
module XRayQuadrics

using Distributed, DistributedArrays
using LinearAlgebra
using Random
import JSON, HDF5, CSV, DataFrames
using Colors
using Plots

export Particle, PixelatedAttenuator
export Quadric, Plane, Cylinder, Paraboloid, Hyperboloid, TruncatedQuadric, normal, changerepresentation
export in_out
export PlotTruncatedQuadric, convert_arguments, cartesian_grid, get_mesh, plot, plot!
export bin
export get_reflection_data

include("quadrics.jl")
include("optical.jl")
include("tracing.jl")
include("plotting.jl")
include("analysis.jl")
include("utils.jl")

end


text:
mutable struct indiv{X, N, Y}

    x::X
    y::NTuple{N, Y}
    normalized_y::Vector{Float64}
    rank::Int
    CV::Float64
    dom_count::Int
    dom_list::Vector{indiv{X,N,Y}}
    ref_point::Int
    distance_ref::Float64

    indiv(x::X, y::NTuple{N, Y}, cv) where {X,N,Y} = new{X, N, Y}(x, y, zeros(N), 0, cv, 0, indiv{X,N,Y}[], 0, 0.)
end
indiv(x, z::Function, fCV::Function) = indiv(x, z(x), fCV(x))

function dominates(a::indiv, b::indiv)
    a.CV != b.CV && return a.CV < b.CV

    res = false
    for i in eachindex(a.y)
        a.y[i] > b.y[i] && return false
        a.y[i] < b.y[i] && (res=true)
    end
    res
end
⋖(a::indiv, b::indiv) = dominates(a, b)

import Base.==; ==(a::indiv, b::indiv) = a.x == b.x
import Base.hash; hash(a::indiv) = hash(a.x)
import Base.show; show(io::IO, ind::indiv) = print(io, "ind($(ind.x) : $(ind.y) | rank : $(ind.rank))")

function show(io::IO, ind::indiv{X, Y}) where {X<:AbstractArray{Bool}, Y}
    genotype = String([xx ? '1' : '0' for xx in ind.x])
    if VERSION >= v"0.7-"
        print(io, "ind(") ; show(IOContext(io, :limit=>true, :compact=>true), genotype) ; print(io, " : $(ind.y) | rank : $(ind.rank))")
    else
        print(io, "ind(") ; show(IOContext(io, limit=true, compact=true), genotype) ; print(io, " : $(ind.y) | rank : $(ind.rank))")
    end
end

function eval!(indiv::indiv, z::Function, fCV::Function)
    indiv.y = z(indiv.x)
    indiv.CV = fCV(indiv.x)
    indiv
end


text:
module JukaiNLP

export train

include("segmentation/segmenter.jl")

end

max_stars_repo_name: hshindo/JukaiNLP

max_issues_repo_name: hshindo/JukaiNLP

max_forks_repo_name: hshindo/JukaiNLP


text:
## Solve MergingMDP for different human action spaces

using Revise
using Random
using LinearAlgebra
using POMDPs
using POMDPModelTools
using POMDPPolicies
using POMDPSimulators
using IterTools
using AutomotiveDrivingModels
using AutomotivePOMDPs: polygon, overlap
using Parameters
using GridInterpolations
using StaticArrays
using AutoUrban
using AutoViz
using Printf
using Reel
using DiscreteValueIteration
using SparseArrays
using ProgressMeter
using JLD2
using FileIO

includet("environment.jl")
includet("mdp_definition.jl")
includet("helpers.jl")

mdp = MergingMDP()

@show n_states(mdp)

assumptions = [:wide, :cv, :ca, :cd]
action_spaces = [[-2.0, 0.0, 2.0], [0.0], [2.0], [-2.0]]
# solver = SparseValueIterationSolver(max_iterations=300, verbose=true)

# policies = ValueIterationPolicy[]

# for (i, human_actions) in enumerate(action_spaces)
#     mdp.human_actions = human_actions
#     push!(policies, solve(solver, mdp))
# end

# # mdp.human_actions = [-2.0]
# # policies[end] = solve(solver, mdp)

# @save "/scratch/boutonm/policies.jld2" policies

@load "policies.jld2" policies

## Display policies
using Plots
using Interact
using Blink

function policy_plot(mdp::MergingMDP, policy::ValueIterationPolicy, ve::Float64=0.0, vo::Float64 = 0.0, assumption::Symbol=:wide)
    xs = mdp.ego_grid[1:end]
    ys = mdp.human_grid
    ae = mdp.acceleration_grid[3]
    z = map(((y,x),) -> value(policy, Float64[x, ve, ae, y, vo]), Iterators.product(ys, xs))
    za = map(((y,x),) -> action(policy, Float64[x, ve, ae, y, vo]), Iterators.product(ys, xs))
    p = [heatmap(xs, ys, z, title="Pr(success) ($assumption)",
                     aspect_ratio=1, color=:plasma, clim=(0,1), size=(1400, 600), colorbar=false),
        heatmap(xs, ys, za, title="Action Map",  xlabel="Ego longitudinal position",
                     aspect_ratio=1,color=:viridis, clim=(1,7), size=(1400, 600), colorbar=false)
        ]
    scatter!(p[1], [20.0], [20.0], axis=:none, legend=:none, color=:red)
    scatter!(p[2], [20.0], [20.0], axis=:none, legend=:none, color=:red)
    return p
end

w1 = Window()
ui = @manipulate for ve = mdp.velocity_grid, vo = mdp.velocity_grid
    xs = mdp.ego_grid[1:end]
    ys = mdp.human_grid
    ae = mdp.acceleration_grid[3]
    plots = []
    for (i, policy) in enumerate(policies)
        push!.(Ref(plots), policy_plot(mdp, policy, ve, vo, assumptions[i]))
    end
    plot!(plots[1],  ylabel="Other longitudinal position")
    plot!(plots[end], colorbar=true, zticks=String["brake", "-0.2", "-0.1", "0.0", "0.1", "0.2", "release"])
    plot!(plots[end-1], colorbar=true)
    plot(plot([plots[i] for i=1:2:7]..., layout=(1, 4)),
         plot([plots[i] for i=2:2:8]..., layout=(1, 4)), layout=(2,1))
end
body!(w1, ui)

## Visualize policy running

policy = policies[3]
hr = HistoryRecorder(rng = rng, max_steps=200)
rng = MersenneTwister(1)
s0 = [mdp.ego_grid[1], mdp.velocity_grid[5], mdp.acceleration_grid[3], mdp.human_grid[1], mdp.velocity_grid[3]]
hist = simulate(hr, mdp, policy, s0)

w3 = Window()
ui = @manipulate for step in 1:n_steps(hist)
    s = state_hist(hist)[step]
    a = action_hist(hist)[step]
    v = MergingViz(mdp=mdp, s=s, a=a, action_values = actionvalues(policy, s))
    AutoViz.render([v], cam=StaticCamera(VecE2(0.0, 0.0), 20.0))
end
body!(w3, ui)


text:
using Pkg; haskey(Pkg.installed(),"Knet") || Pkg.add("Knet")

# TODO: improve example and document metadata return type further
# TODO: document low-level API
"""This module implements the ResNet 50,101,150 and CIFAR models from
'Deep Residual Learning for Image Regocnition', Kaiming He, Xiangyu Zhang,
Shaoqing Ren, Jian Sun, arXiv technical report 1512.03385, 2015.

* Paper url: https://arxiv.org/abs/1512.03385
* Project page: https://github.com/KaimingHe/deep-residual-networks
* MatConvNet weight: http://www.vlfeat.org/matconvnet/pretrained

-------------------------------
Initialization functions of ImageNet models:

 `w, m, meta = resnet50init( ;kwargs...)`

 `w, m, meta = resnet101init(;kwargs...)`

 `w, m, meta = resnet152init(;kwargs...)`

# Return value
All initialization functions return 3-element tuples of the form `(weights, moments, metadata)`.
The `metadata` is pretrained model's "meta" cell if `trained=true`, `nothing` otherwise.
`moments` are to be used in `batchnorm` operations.

# Keyword arguments
 `trained=true`: if true, corresponding pretrained model is loaded. Otherwise,
models are initialized from scratch.

 `etype=Float32`: numeric type of the parameters and moments

 `stage=0`: Used when an earlier stage of the input used as feature. `stage=0` means full
classification is desired. `stage=n` means the output after the nth residual layer group
is desided, when 1<=n<=4. For n=5, global average pooling is also included.
An error is thrown for n > 5.

-------------------------------

Forward functions of ImageNet models:

 `y = resnet50(w, m, x; stage)`

 `y = resnet101(w, m, x; stage)`

 `y = resnet152(w, m, x; stage)`

# Arguments
    `w`, `m` and `x` correspond to weights, batchnorm moments and input.

# Keywords
    `stage=0`: Same argument provided to the init functions.

# Return Values
    functions returns an array of size (1000, batch_size).

# Usage Example for Classification
    w, m, meta = resnet101init()
    # use meta to resize, crop and normalize x
    y = resnet101(w, m, x)

---------------------------
CIFAR models can be used as:

   `w, m = resnetcifarinit(110; nclasses=10) #nclasses=100 for CIFAR100`

   `y = resnetcifar(w, m, x)`

"""
module ResNetLib

using Knet
include(Knet.dir("data","imagenet.jl"))

resnet50init(;  o...)  = resnetinit([3, 4, 6,  3]; o...)
resnet101init(; o...)  = resnetinit([3, 4, 23, 3]; o...)
resnet152init(; o...)  = resnetinit([3, 8, 36, 3]; o...)

resnet50( ws, ms, x; o...)  = resnet(ws, ms, x, [3, 4, 6,  3]; o...)
resnet101(ws, ms, x; o...)  = resnet(ws, ms, x, [3, 4, 23, 3]; o...)
resnet152(ws, ms, x; o...)  = resnet(ws, ms, x, [3, 8, 36, 3]; o...)

resnetcifarinit(depth::Int; nclasses=10) =
    let n = div(depth-2, 3)
        dataset = nclasses == 10 ? :cifar10 : :cifar100
        nrep = div(n, 2)
        # call the generic fn
        resnetinit([nrep, nrep, nrep];
                   dataset=dataset,
                   channels=[16,32,64],
                   resize=[false,true,true],
                   trained=false,
                   blockinit=basicinit)
    end

resnetcifar(w, m, x) =
    let depth = div(length(w)-4, 2)
        n = div(depth-2, 3)
        nrep = div(n, 2)
        nclasses = length(w[end])
        dataset = nclasses == 10 ? :cifar10 : :cifar100
        # call the generic fn
        resnet(w, m, x, [nrep, nrep, nrep];
               strides=[1,2,2],
               resize=[false,true,true],
               block=basic,
               dataset=dataset)
    end

const basic_channels = [64, 128, 256, 512]
const bneck_channels = 4basic_channels

function resnetinit(repeats;
                    channels=bneck_channels,
                    resize=[true, true, true, true], #size changes require 1x1 conv shortcuts
                    etype=Float32,
                    atype=(gpu() >= 0) ? KnetArray : Array,
                    trained=true,
                    blockinit=bneckinit,
                    stage=0,
                    dataset=:imagenet)
    @assert (dataset in [:imagenet, :cifar10, :cifar100]) "dataset kwarg should be :imagenet, :cifar10, or :cifar100"
    @assert (stage <= length(repeats)+1) "Use stage=0 to perform classification"
    ws = []
    ms = []
    if dataset === :imagenet
        push!(ws, cinit([7,7,3,64], etype))
        push!(ws, bnparams(etype, 64))
        channels = [64, channels...]
    else
        push!(ws, cinit([3,3,3,channels[1]], etype))
        push!(ws, bnparams(etype, channels[1]))
        channels = [channels[1], channels...]
    end
    push!(ms, bnmoments())
    for i = 1:length(repeats)
        w, m = layerinit(repeats[i], blockinit,
                         channels[i], channels[i+1];
                         downsample=resize[i],
                         etype=etype)
        push!(ws, w...)
        push!(ms, m...)
        (stage == i) && break
    end
    if stage == 0
        nclasses = dataset == :cifar10 ? 10 : dataset == :cifar100 ? 100 : 1000
        push!(ws, xavier(etype, nclasses, channels[end]))
        push!(ws, zeros(etype, nclasses, 1))
    end
    if trained
        depth = sum(repeats .* (blockinit == bneckinit ? 3 : 2)) + 2
        metadata = load_resnet!(ws, ms; atype=atype, stage=stage, depth=depth)
    else
        metadata = nothing
    end
    ws = map(atype, ws)
    return ws, ms, metadata #todo: add non-matconvnet metadata
end

function resnet(ws, ms, x, repeats;
                block=bneck,
                resize=[true, true, true, true],
                strides=[1,2,2,2],
                stage=0,
                dataset=:imagenet)
    @assert (dataset in [:imagenet, :cifar10, :cifar100]) "dataset kwarg should be :imagenet, :cifar10, or :cifar100"

    if dataset === :imagenet
        o = conv4(ws[1], x; padding=3, stride=2)
        # There is a forgotten bias in resnet50 pre-trained model
        # which happens to learn some small values.
        # This hack is to support that.
        if ndims(ws[end]) == 4
            o = o .+ last(ws)
            ws = ws[1:end-1]
        end
        o = batchnorm(o, ms[1], ws[2])
        o = relu.(o)
        o = pool(o; window=3, stride=2)
    else
        o = conv4(ws[1], x; padding=1)
        o = batchnorm(o, ms[1], ws[2])
        o = relu.(o)
    end
    wstart = 3
    mstart = 2
    for (i, r) in enumerate(repeats)
        d = resize[i]
        wi, mi = nlparams(r, d, block)
        o = layer(ws[wstart:wstart+wi-1],
                  ms[mstart:mstart+mi-1],
                  o, r, block;
                  stride=strides[i],
                  downsample=d)
        wstart += wi
        mstart += mi
        (stage == i) && return o
    end
    # global average pooling & output
    o = pool(o; window=(size(o,1),size(o,2)), mode=2)
    stage == length(repeats)+1 && return o
    return ws[end-1] * mat(o) .+ ws[end]
end

nlparams(repeat, downsample, block) =
    let np = (block == bneck) ? 6 : 4
        nm = div(np, 2)
        nd = Int(downsample)
        repeat * np + 2nd, repeat * nm + nd
    end

function layerinit(repeat, blockinit, input, output;
                   downsample=true, etype=Float32)
    @assert (blockinit in [basicinit, bneckinit]) "Unknown blockinit function"
    ws, ms = [], []
    # add downsample
    for i = 1:repeat
        w, m = blockinit(input, output;
                         downsample=downsample, etype=etype)
        push!(ws, w...); push!(ms, m...)
        input = output
        downsample = false
    end
    return ws, ms
end

function layer(w, m, x, repeat, block;
               stride=1, downsample=true)
    @assert (block in [basic, bneck]) "Unknown block function"
    nparams = (block == bneck) ? 6 : 4
    nmoments = div(nparams, 2)
    wstart = 1
    mstart = 1
    for i = 1:repeat
        winc = nparams + (downsample ? 2 : 0)
        minc = nmoments + (downsample ? 1 : 0)
        # run the block
        x = block(w[wstart:wstart+winc-1], m[mstart:mstart+minc-1], x;
                  downsample=downsample, stride=stride)
        # update metadata
        wstart += winc
        mstart += minc
        downsample = false
        stride = 1
    end
    return x
end

# BOTTLENECK BLOCK
function bneckinit(input, output; downsample=false, etype=Float32)
    planes = div(output, 4)
    w = Any[
        (downsample ? [cinit([1, 1, input, output], etype), bnparams(etype,output)] : [])...,
        cinit([1, 1, input,  planes],  etype),  bnparams(etype, planes),
        cinit([3, 3, planes, planes],  etype),  bnparams(etype, planes),
        cinit([1, 1, planes, output],  etype),  bnparams(etype, output)
    ]
    m = Any[bnmoments() for i=1:div(length(w), 2)]
    return w, m
end

function bneck(w, m, x; stride=1, downsample=false)
    if downsample
        x_ = batchnorm(conv4(w[1], x; stride=stride), m[1], w[2])
        w = w[3:end]
        m = m[2:end]
    else
        x_ = x
    end
    o = relu.(batchnorm(conv4(w[1], x; stride=stride), m[1], w[2]))
    o = relu.(batchnorm(conv4(w[3], o; padding=1), m[2], w[4]))
    o = batchnorm(conv4(w[5], o), m[3], w[6])
    return relu.(x_ .+ o)
end

# BASIC BLOCK
function basicinit(input, output; downsample=false, etype=Float32)
    w = Any[
        (downsample ? [cinit([1, 1, input, output], etype), bnparams(etype,output)] : [])...,
        cinit([3, 3, input,  output],  etype),  bnparams(etype, output),
        cinit([3, 3, output, output],  etype),  bnparams(etype, output)
    ]
    m = Any[bnmoments() for i=1:div(length(w), 2)]
    return w, m
end

function basic(w, m, x; stride=1, downsample=false)
    if downsample
        x_ = batchnorm(conv4(w[1], x; stride=stride), m[1], w[2])
        w = w[3:end]
        m = m[2:end]
    else
        x_ = x
    end
    o = relu.(batchnorm(conv4(w[1], x; padding=1, stride=stride), m[1], w[2]))
    o = relu.(batchnorm(conv4(w[3], o; padding=1), m[2], w[4]))
    return relu.(x_ .+ o)
end

cinit(dims, etype=Float32) = etype(sqrt(2 / prod(dims[[1,2,4]]))) .* randn(etype, dims...)

function load_resnet!(weights, moments;
                      modeldir=Knet.dir("data"),
                      stage=0, depth=101,
                      o...)
    @info("Loading pretrained weights...")
    # All of this is implemented in Knet/data/imagenet.jl
    # urls = Dict([
    #     50  => "http://www.vlfeat.org/matconvnet/models/imagenet-resnet-50-dag.mat",
    #     101 => "http://www.vlfeat.org/matconvnet/models/imagenet-resnet-101-dag.mat",
    #     152 => "http://www.vlfeat.org/matconvnet/models/imagenet-resnet-152-dag.mat",
    # ])
    # filename = "imagenet-resnet-$depth-dag.mat"
    # dest = joinpath(modeldir, filename)
    # if ~isfile(dest)
    #     info("Downloading resnet ", depth, " weights to ", dest)
    #     download(urls[depth], dest)
    # end
    # r = matread(dest)
    r = matconvnet("imagenet-resnet-$depth-dag")
    load_params!(weights, moments, r["params"];
                 first_bias=depth==50,
                 stage=stage,
                 o...)
    return r["meta"]
end

function load_params!(weights, moments, matparams;
                      first_bias=false,
                      atype=(gpu()>=0 ? KnetArray : Array),
                      stage=0)
    et = eltype(weights[1])
    params = matparams["value"]
    params = map(x->et.(x), params)
    if first_bias
        b = params[2]
        params = Any[params[1], params[3:end]...]
        push!(weights, reshape(atype(b), (1,1,length(b),1)))
    end
    len = length(params)
    wc = 1
    mc = 1
    for i = 1:4:len-2
        copyto!(weights[wc], params[i])
        bnw = weights[wc+1]
        copyto!(bnw, vcat(params[i+1][:], params[i+2][:]))
        m = params[i+3]
        sz = (1, 1, size(m, 1), 1)
        moments[mc].mean = reshape(atype(m[:, 1]), sz)
        moments[mc].var  = reshape(atype(m[:, 2].^2), sz)
        wc += 2
        mc += 1
        stage !== 0 && wc > length(weights) && return
    end
    (stage == 5) && return
    w, b = params[end-1], params[end]
    copyto!(weights[wc], mat(w)')
    copyto!(weights[wc+1], b)
end

end #module