text:
# This file is auto-generated by AWSMetadata.jl
using AWS
using AWS.AWSServices: batch
using AWS.Compat
using AWS.UUIDs

"""
    cancel_job(job_id, reason)
    cancel_job(job_id, reason, params::Dict{String,<:Any})

Cancels a job in an Batch job queue. Jobs that are in the SUBMITTED, PENDING, or RUNNABLE
state are canceled. Jobs that have progressed to STARTING or RUNNING aren't canceled, but
the API operation still succeeds, even if no job is canceled. These jobs must be terminated
with the TerminateJob operation.

# Arguments
- `job_id`: The Batch job ID of the job to cancel.
- `reason`: A message to attach to the job that explains the reason for canceling it. This
  message is returned by future DescribeJobs operations on the job. This message is also
  recorded in the Batch activity logs.

"""
function cancel_job(jobId, reason; aws_config::AbstractAWSConfig=global_aws_config())
    return batch(
        "POST",
        "/v1/canceljob",
        Dict{String,Any}("jobId" => jobId, "reason" => reason);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function cancel_job(
    jobId,
    reason,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return batch(
        "POST",
        "/v1/canceljob",
        Dict{String,Any}(
            mergewith(
                _merge, Dict{String,Any}("jobId" => jobId, "reason" => reason), params
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    create_compute_environment(compute_environment_name, type)
    create_compute_environment(compute_environment_name, type, params::Dict{String,<:Any})

Creates an Batch compute environment. You can create MANAGED or UNMANAGED compute
environments. MANAGED compute environments can use Amazon EC2 or Fargate resources.
UNMANAGED compute environments can only use EC2 resources. In a managed compute
environment, Batch manages the capacity and instance types of the compute resources within
the environment. This is based on the compute resource specification that you define or the
launch template that you specify when you create the compute environment. Either, you can
choose to use EC2 On-Demand Instances and EC2 Spot Instances. Or, you can use Fargate and
Fargate Spot capacity in your managed compute environment. You can optionally set a maximum
price so that Spot Instances only launch when the Spot Instance price is less than a
specified percentage of the On-Demand price.  Multi-node parallel jobs aren't supported on
Spot Instances.  In an unmanaged compute environment, you can manage your own EC2 compute
resources and have a lot of flexibility with how you configure your compute resources. For
example, you can use custom AMIs. However, you must verify that each of your AMIs meet the
Amazon ECS container instance AMI specification. For more information, see container
instance AMIs in the Amazon Elastic Container Service Developer Guide. After you created
your unmanaged compute environment, you can use the DescribeComputeEnvironments operation
to find the Amazon ECS cluster that's associated with it. Then, launch your container
instances into that Amazon ECS cluster. For more information, see Launching an Amazon ECS
container instance in the Amazon Elastic Container Service Developer Guide.  Batch doesn't
upgrade the AMIs in a compute environment after the environment is created. For example, it
doesn't update the AMIs when a newer version of the Amazon ECS optimized AMI is available.
Therefore, you're responsible for managing the guest operating system (including its
updates and security patches) and any additional application software or utilities that you
install on the compute resources. To use a new AMI for your Batch jobs, complete these
steps:   Create a new compute environment with the new AMI.   Add the compute environment
to an existing job queue.   Remove the earlier compute environment from your job queue.
Delete the earlier compute environment.

# Arguments
- `compute_environment_name`: The name for your compute environment. Up to 128 letters
  (uppercase and lowercase), numbers, hyphens, and underscores are allowed.
- `type`: The type of the compute environment: MANAGED or UNMANAGED. For more information,
  see Compute Environments in the Batch User Guide.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"computeResources"`: Details about the compute resources managed by the compute
  environment. This parameter is required for managed compute environments. For more
  information, see Compute Environments in the Batch User Guide.
- `"serviceRole"`: The full Amazon Resource Name (ARN) of the IAM role that allows Batch to
  make calls to other Amazon Web Services services on your behalf. For more information, see
  Batch service IAM role in the Batch User Guide.  If your account already created the Batch
  service-linked role, that role is used by default for your compute environment unless you
  specify a different role here. If the Batch service-linked role doesn't exist in your
  account, and no role is specified here, the service attempts to create the Batch
  service-linked role in your account.  If your specified role has a path other than /, then
  you must specify either the full role ARN (recommended) or prefix the role name with the
  path. For example, if a role with the name bar has a path of /foo/ then you would specify
  /foo/bar as the role name. For more information, see Friendly names and paths in the IAM
  User Guide.  Depending on how you created your Batch service role, its ARN might contain
  the service-role path prefix. When you only specify the name of the service role, Batch
  assumes that your ARN doesn't use the service-role path prefix. Because of this, we
  recommend that you specify the full ARN of your service role when you create compute
  environments.
- `"state"`: The state of the compute environment. If the state is ENABLED, then the
  compute environment accepts jobs from a queue and can scale out automatically based on
  queues. If the state is ENABLED, then the Batch scheduler can attempt to place jobs from an
  associated job queue on the compute resources within the environment. If the compute
  environment is managed, then it can scale its instances out or in automatically, based on
  the job queue demand. If the state is DISABLED, then the Batch scheduler doesn't attempt to
  place jobs within the environment. Jobs in a STARTING or RUNNING state continue to progress
  normally. Managed compute environments in the DISABLED state don't scale out. However, they
  scale in to minvCpus value after instances become idle.
- `"tags"`: The tags that you apply to the compute environment to help you categorize and
  organize your resources. Each tag consists of a key and an optional value. For more
  information, see Tagging Amazon Web Services Resources in Amazon Web Services General
  Reference. These tags can be updated or removed using the TagResource and UntagResource API
  operations. These tags don't propagate to the underlying compute resources.
"""
function create_compute_environment(
    computeEnvironmentName, type; aws_config::AbstractAWSConfig=global_aws_config()
)
    return batch(
        "POST",
        "/v1/createcomputeenvironment",
        Dict{String,Any}(
            "computeEnvironmentName" => computeEnvironmentName, "type" => type
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function create_compute_environment(
    computeEnvironmentName,
    type,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return batch(
        "POST",
        "/v1/createcomputeenvironment",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "computeEnvironmentName" => computeEnvironmentName, "type" => type
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    create_job_queue(compute_environment_order, job_queue_name, priority)
    create_job_queue(compute_environment_order, job_queue_name, priority, params::Dict{String,<:Any})

Creates an Batch job queue. When you create a job queue, you associate one or more compute
environments to the queue and assign an order of preference for the compute environments.
You also set a priority to the job queue that determines the order that the Batch scheduler
places jobs onto its associated compute environments. For example, if a compute environment
is associated with more than one job queue, the job queue with a higher priority is given
preference for scheduling jobs to that compute environment.

# Arguments
- `compute_environment_order`: The set of compute environments mapped to a job queue and
  their order relative to each other. The job scheduler uses this parameter to determine
  which compute environment should run a specific job. Compute environments must be in the
  VALID state before you can associate them with a job queue. You can associate up to three
  compute environments with a job queue. All of the compute environments must be either EC2
  (EC2 or SPOT) or Fargate (FARGATE or FARGATE_SPOT); EC2 and Fargate compute environments
  can't be mixed.  All compute environments that are associated with a job queue must share
  the same architecture. Batch doesn't support mixing compute environment architecture types
  in a single job queue.
- `job_queue_name`: The name of the job queue. Up to 128 letters (uppercase and lowercase),
  numbers, and underscores are allowed.
- `priority`: The priority of the job queue. Job queues with a higher priority (or a higher
  integer value for the priority parameter) are evaluated first when associated with the same
  compute environment. Priority is determined in descending order. For example, a job queue
  with a priority value of 10 is given scheduling preference over a job queue with a priority
  value of 1. All of the compute environments must be either EC2 (EC2 or SPOT) or Fargate
  (FARGATE or FARGATE_SPOT); EC2 and Fargate compute environments can't be mixed.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"state"`: The state of the job queue. If the job queue state is ENABLED, it is able to
  accept jobs. If the job queue state is DISABLED, new jobs can't be added to the queue, but
  jobs already in the queue can finish.
- `"tags"`: The tags that you apply to the job queue to help you categorize and organize
  your resources. Each tag consists of a key and an optional value. For more information, see
  Tagging your Batch resources in Batch User Guide.
"""
function create_job_queue(
    computeEnvironmentOrder,
    jobQueueName,
    priority;
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return batch(
        "POST",
        "/v1/createjobqueue",
        Dict{String,Any}(
            "computeEnvironmentOrder" => computeEnvironmentOrder,
            "jobQueueName" => jobQueueName,
            "priority" => priority,
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function create_job_queue(
    computeEnvironmentOrder,
    jobQueueName,
    priority,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return batch(
        "POST",
        "/v1/createjobqueue",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "computeEnvironmentOrder" => computeEnvironmentOrder,
                    "jobQueueName" => jobQueueName,
                    "priority" => priority,
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    delete_compute_environment(compute_environment)
    delete_compute_environment(compute_environment, params::Dict{String,<:Any})

Deletes an Batch compute environment. Before you can delete a compute environment, you must
set its state to DISABLED with the UpdateComputeEnvironment API operation and disassociate
it from any job queues with the UpdateJobQueue API operation. Compute environments that use
Fargate resources must terminate all active jobs on that compute environment before
deleting the compute environment. If this isn't done, the compute environment enters an
invalid state.

# Arguments
- `compute_environment`: The name or Amazon Resource Name (ARN) of the compute environment
  to delete.

"""
function delete_compute_environment(
    computeEnvironment; aws_config::AbstractAWSConfig=global_aws_config()
)
    return batch(
        "POST",
        "/v1/deletecomputeenvironment",
        Dict{String,Any}("computeEnvironment" => computeEnvironment);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function delete_compute_environment(
    computeEnvironment,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return batch(
        "POST",
        "/v1/deletecomputeenvironment",
        Dict{String,Any}(
            mergewith(
                _merge, Dict{String,Any}("computeEnvironment" => computeEnvironment), params
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    delete_job_queue(job_queue)
    delete_job_queue(job_queue, params::Dict{String,<:Any})

Deletes the specified job queue. You must first disable submissions for a queue with the
UpdateJobQueue operation. All jobs in the queue are eventually terminated when you delete a
job queue. The jobs are terminated at a rate of about 16 jobs each second. It's not
necessary to disassociate compute environments from a queue before submitting a
DeleteJobQueue request.

# Arguments
- `job_queue`: The short name or full Amazon Resource Name (ARN) of the queue to delete.

"""
function delete_job_queue(jobQueue; aws_config::AbstractAWSConfig=global_aws_config())
    return batch(
        "POST",
        "/v1/deletejobqueue",
        Dict{String,Any}("jobQueue" => jobQueue);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function delete_job_queue(
    jobQueue,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return batch(
        "POST",
        "/v1/deletejobqueue",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("jobQueue" => jobQueue), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    deregister_job_definition(job_definition)
    deregister_job_definition(job_definition, params::Dict{String,<:Any})

Deregisters an Batch job definition. Job definitions are permanently deleted after 180 days.

# Arguments
- `job_definition`: The name and revision (name:revision) or full Amazon Resource Name
  (ARN) of the job definition to deregister.

"""
function deregister_job_definition(
    jobDefinition; aws_config::AbstractAWSConfig=global_aws_config()
)
    return batch(
        "POST",
        "/v1/deregisterjobdefinition",
        Dict{String,Any}("jobDefinition" => jobDefinition);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function deregister_job_definition(
    jobDefinition,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return batch(
        "POST",
        "/v1/deregisterjobdefinition",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("jobDefinition" => jobDefinition), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    describe_compute_environments()
    describe_compute_environments(params::Dict{String,<:Any})

Describes one or more of your compute environments. If you're using an unmanaged compute
environment, you can use the DescribeComputeEnvironment operation to determine the
ecsClusterArn that you should launch your Amazon ECS container instances into.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"computeEnvironments"`: A list of up to 100 compute environment names or full Amazon
  Resource Name (ARN) entries.
- `"maxResults"`: The maximum number of cluster results returned by
  DescribeComputeEnvironments in paginated output. When this parameter is used,
  DescribeComputeEnvironments only returns maxResults results in a single page along with a
  nextToken response element. The remaining results of the initial request can be seen by
  sending another DescribeComputeEnvironments request with the returned nextToken value. This
  value can be between 1 and 100. If this parameter isn't used, then
  DescribeComputeEnvironments returns up to 100 results and a nextToken value if applicable.
- `"nextToken"`: The nextToken value returned from a previous paginated
  DescribeComputeEnvironments request where maxResults was used and the results exceeded the
  value of that parameter. Pagination continues from the end of the previous results that
  returned the nextToken value. This value is null when there are no more results to return.
  This token should be treated as an opaque identifier that's only used to retrieve the next
  items in a list and not for other programmatic purposes.
"""
function describe_compute_environments(; aws_config::AbstractAWSConfig=global_aws_config())
    return batch(
        "POST",
        "/v1/describecomputeenvironments";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function describe_compute_environments(
    params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return batch(
        "POST",
        "/v1/describecomputeenvironments",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    describe_job_definitions()
    describe_job_definitions(params::Dict{String,<:Any})

Describes a list of job definitions. You can specify a status (such as ACTIVE) to only
return job definitions that match that status.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"jobDefinitionName"`: The name of the job definition to describe.
- `"jobDefinitions"`: A list of up to 100 job definitions. Each entry in the list can
  either be an ARN of the form
  arn:aws:batch:{Region}:{Account}:job-definition/{JobDefinitionName}:{Revision} or a short
  version using the form {JobDefinitionName}:{Revision}.
- `"maxResults"`: The maximum number of results returned by DescribeJobDefinitions in
  paginated output. When this parameter is used, DescribeJobDefinitions only returns
  maxResults results in a single page and a nextToken response element. The remaining results
  of the initial request can be seen by sending another DescribeJobDefinitions request with
  the returned nextToken value. This value can be between 1 and 100. If this parameter isn't
  used, then DescribeJobDefinitions returns up to 100 results and a nextToken value if
  applicable.
- `"nextToken"`: The nextToken value returned from a previous paginated
  DescribeJobDefinitions request where maxResults was used and the results exceeded the value
  of that parameter. Pagination continues from the end of the previous results that returned
  the nextToken value. This value is null when there are no more results to return.  This
  token should be treated as an opaque identifier that's only used to retrieve the next items
  in a list and not for other programmatic purposes.
- `"status"`: The status used to filter job definitions.
"""
function describe_job_definitions(; aws_config::AbstractAWSConfig=global_aws_config())
    return batch(
        "POST",
        "/v1/describejobdefinitions";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function describe_job_definitions(
    params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return batch(
        "POST",
        "/v1/describejobdefinitions",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    describe_job_queues()
    describe_job_queues(params::Dict{String,<:Any})

Describes one or more of your job queues.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"jobQueues"`: A list of up to 100 queue names or full queue Amazon Resource Name (ARN)
  entries.
- `"maxResults"`: The maximum number of results returned by DescribeJobQueues in paginated
  output. When this parameter is used, DescribeJobQueues only returns maxResults results in a
  single page and a nextToken response element. The remaining results of the initial request
  can be seen by sending another DescribeJobQueues request with the returned nextToken value.
  This value can be between 1 and 100. If this parameter isn't used, then DescribeJobQueues
  returns up to 100 results and a nextToken value if applicable.
- `"nextToken"`: The nextToken value returned from a previous paginated DescribeJobQueues
  request where maxResults was used and the results exceeded the value of that parameter.
  Pagination continues from the end of the previous results that returned the nextToken
  value. This value is null when there are no more results to return.  This token should be
  treated as an opaque identifier that's only used to retrieve the next items in a list and
  not for other programmatic purposes.
"""
function describe_job_queues(; aws_config::AbstractAWSConfig=global_aws_config())
    return batch(
        "POST",
        "/v1/describejobqueues";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function describe_job_queues(
    params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return batch(
        "POST",
        "/v1/describejobqueues",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    describe_jobs(jobs)
    describe_jobs(jobs, params::Dict{String,<:Any})

Describes a list of Batch jobs.

# Arguments
- `jobs`: A list of up to 100 job IDs.

"""
function describe_jobs(jobs; aws_config::AbstractAWSConfig=global_aws_config())
    return batch(
        "POST",
        "/v1/describejobs",
        Dict{String,Any}("jobs" => jobs);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function describe_jobs(
    jobs, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return batch(
        "POST",
        "/v1/describejobs",
        Dict{String,Any}(mergewith(_merge, Dict{String,Any}("jobs" => jobs), params));
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    list_jobs()
    list_jobs(params::Dict{String,<:Any})

Returns a list of Batch jobs. You must specify only one of the following items:   A job
queue ID to return a list of jobs in that job queue   A multi-node parallel job ID to
return a list of nodes for that job   An array job ID to return a list of the children for
that job   You can filter the results by job status with the jobStatus parameter. If you
don't specify a status, only RUNNING jobs are returned.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"arrayJobId"`: The job ID for an array job. Specifying an array job ID with this
  parameter lists all child jobs from within the specified array.
- `"filters"`: The filter to apply to the query. Only one filter can be used at a time.
  When the filter is used, jobStatus is ignored. The filter doesn't apply to child jobs in an
  array or multi-node parallel (MNP) jobs. The results are sorted by the createdAt field,
  with the most recent jobs being first.  JOB_NAME  The value of the filter is a
  case-insensitive match for the job name. If the value ends with an asterisk (*), the filter
  will match any job name that begins with the string before the '*'. This corresponds to the
  jobName value. For example, test1 matches both Test1 and test1, and test1* matches both
  test1 and Test10. When the JOB_NAME filter is used, the results are grouped by the job name
  and version.  JOB_DEFINITION  The value for the filter is the name or Amazon Resource Name
  (ARN) of the job definition. This corresponds to the jobDefinition value. The value is case
  sensitive. When the value for the filter is the job definition name, the results include
  all the jobs that used any revision of that job definition name. If the value ends with an
  asterisk (*), the filter will match any job definition name that begins with the string
  before the '*'. For example, jd1 matches only jd1, and jd1* matches both jd1 and jd1A. The
  version of the job definition that's used doesn't affect the sort order. When the
  JOB_DEFINITION filter is used and the ARN is used (which is in the form
  arn:{Partition}:batch:{Region}:{Account}:job-definition/{JobDefinitionName}:{Revision}),
  the results include jobs that used the specified revision of the job definition. Asterisk
  (*) is not supported when the ARN is used.  BEFORE_CREATED_AT  The value for the filter is
  the time that's before the job was created. This corresponds to the createdAt value. The
  value is a string representation of the number of seconds since 00:00:00 UTC (midnight) on
  January 1, 1970.  AFTER_CREATED_AT  The value for the filter is the time that's after the
  job was created. This corresponds to the createdAt value. The value is a string
  representation of the number of seconds since 00:00:00 UTC (midnight) on January 1, 1970.
- `"jobQueue"`: The name or full Amazon Resource Name (ARN) of the job queue used to list
  jobs.
- `"jobStatus"`: The job status used to filter jobs in the specified queue. If the filters
  parameter is specified, the jobStatus parameter is ignored and jobs with any status are
  returned. If you don't specify a status, only RUNNING jobs are returned.
- `"maxResults"`: The maximum number of results returned by ListJobs in paginated output.
  When this parameter is used, ListJobs only returns maxResults results in a single page and
  a nextToken response element. The remaining results of the initial request can be seen by
  sending another ListJobs request with the returned nextToken value. This value can be
  between 1 and 100. If this parameter isn't used, then ListJobs returns up to 100 results
  and a nextToken value if applicable.
- `"multiNodeJobId"`: The job ID for a multi-node parallel job. Specifying a multi-node
  parallel job ID with this parameter lists all nodes that are associated with the specified
  job.
- `"nextToken"`: The nextToken value returned from a previous paginated ListJobs request
  where maxResults was used and the results exceeded the value of that parameter. Pagination
  continues from the end of the previous results that returned the nextToken value. This
  value is null when there are no more results to return.  This token should be treated as an
  opaque identifier that's only used to retrieve the next items in a list and not for other
  programmatic purposes.
"""
function list_jobs(; aws_config::AbstractAWSConfig=global_aws_config())
    return batch(
        "POST", "/v1/listjobs"; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET
    )
end
function list_jobs(
    params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return batch(
        "POST",
        "/v1/listjobs",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    list_tags_for_resource(resource_arn)
    list_tags_for_resource(resource_arn, params::Dict{String,<:Any})

Lists the tags for an Batch resource. Batch resources that support tags are compute
environments, jobs, job definitions, and job queues. ARNs for child jobs of array and
multi-node parallel (MNP) jobs are not supported.

# Arguments
- `resource_arn`: The Amazon Resource Name (ARN) that identifies the resource that tags are
  listed for. Batch resources that support tags are compute environments, jobs, job
  definitions, and job queues. ARNs for child jobs of array and multi-node parallel (MNP)
  jobs are not supported.

"""
function list_tags_for_resource(
    resourceArn; aws_config::AbstractAWSConfig=global_aws_config()
)
    return batch(
        "GET",
        "/v1/tags/$(resourceArn)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_tags_for_resource(
    resourceArn,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return batch(
        "GET",
        "/v1/tags/$(resourceArn)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    register_job_definition(job_definition_name, type)
    register_job_definition(job_definition_name, type, params::Dict{String,<:Any})

Registers an Batch job definition.

# Arguments
- `job_definition_name`: The name of the job definition to register. Up to 128 letters
  (uppercase and lowercase), numbers, hyphens, and underscores are allowed.
- `type`: The type of job definition. For more information about multi-node parallel jobs,
  see Creating a multi-node parallel job definition in the Batch User Guide.  If the job is
  run on Fargate resources, then multinode isn't supported.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"containerProperties"`: An object with various properties specific to single-node
  container-based jobs. If the job definition's type parameter is container, then you must
  specify either containerProperties or nodeProperties.  If the job runs on Fargate
  resources, then you must not specify nodeProperties; use only containerProperties.
- `"nodeProperties"`: An object with various properties specific to multi-node parallel
  jobs. If you specify node properties for a job, it becomes a multi-node parallel job. For
  more information, see Multi-node Parallel Jobs in the Batch User Guide. If the job
  definition's type parameter is container, then you must specify either containerProperties
  or nodeProperties.  If the job runs on Fargate resources, then you must not specify
  nodeProperties; use containerProperties instead.
- `"parameters"`: Default parameter substitution placeholders to set in the job definition.
  Parameters are specified as a key-value pair mapping. Parameters in a SubmitJob request
  override any corresponding parameter defaults from the job definition.
- `"platformCapabilities"`: The platform capabilities required by the job definition. If no
  value is specified, it defaults to EC2. To run the job on Fargate resources, specify
  FARGATE.
- `"propagateTags"`: Specifies whether to propagate the tags from the job or job definition
  to the corresponding Amazon ECS task. If no value is specified, the tags are not
  propagated. Tags can only be propagated to the tasks during task creation. For tags with
  the same name, job tags are given priority over job definitions tags. If the total number
  of combined tags from the job and job definition is over 50, the job is moved to the FAILED
  state.
- `"retryStrategy"`: The retry strategy to use for failed jobs that are submitted with this
  job definition. Any retry strategy that's specified during a SubmitJob operation overrides
  the retry strategy defined here. If a job is terminated due to a timeout, it isn't retried.
- `"tags"`: The tags that you apply to the job definition to help you categorize and
  organize your resources. Each tag consists of a key and an optional value. For more
  information, see Tagging Amazon Web Services Resources in Batch User Guide.
- `"timeout"`: The timeout configuration for jobs that are submitted with this job
  definition, after which Batch terminates your jobs if they have not finished. If a job is
  terminated due to a timeout, it isn't retried. The minimum value for the timeout is 60
  seconds. Any timeout configuration that's specified during a SubmitJob operation overrides
  the timeout configuration defined here. For more information, see Job Timeouts in the Batch
  User Guide.
"""
function register_job_definition(
    jobDefinitionName, type; aws_config::AbstractAWSConfig=global_aws_config()
)
    return batch(
        "POST",
        "/v1/registerjobdefinition",
        Dict{String,Any}("jobDefinitionName" => jobDefinitionName, "type" => type);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function register_job_definition(
    jobDefinitionName,
    type,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return batch(
        "POST",
        "/v1/registerjobdefinition",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}("jobDefinitionName" => jobDefinitionName, "type" => type),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    submit_job(job_definition, job_name, job_queue)
    submit_job(job_definition, job_name, job_queue, params::Dict{String,<:Any})

Submits an Batch job from a job definition. Parameters that are specified during SubmitJob
override parameters defined in the job definition. vCPU and memory requirements that are
specified in the ResourceRequirements objects in the job definition are the exception. They
can't be overridden this way using the memory and vcpus parameters. Rather, you must
specify updates to job definition parameters in a ResourceRequirements object that's
included in the containerOverrides parameter.  Jobs that run on Fargate resources can't be
guaranteed to run for more than 14 days. This is because, after 14 days, Fargate resources
might become unavailable and job might be terminated.

# Arguments
- `job_definition`: The job definition used by this job. This value can be one of name,
  name:revision, or the Amazon Resource Name (ARN) for the job definition. If name is
  specified without a revision then the latest active revision is used.
- `job_name`: The name of the job. The first character must be alphanumeric, and up to 128
  letters (uppercase and lowercase), numbers, hyphens, and underscores are allowed.
- `job_queue`: The job queue where the job is submitted. You can specify either the name or
  the Amazon Resource Name (ARN) of the queue.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"arrayProperties"`: The array properties for the submitted job, such as the size of the
  array. The array size can be between 2 and 10,000. If you specify array properties for a
  job, it becomes an array job. For more information, see Array Jobs in the Batch User Guide.
- `"containerOverrides"`: A list of container overrides in the JSON format that specify the
  name of a container in the specified job definition and the overrides it should receive.
  You can override the default command for a container, which is specified in the job
  definition or the Docker image, with a command override. You can also override existing
  environment variables on a container or add new environment variables to it with an
  environment override.
- `"dependsOn"`: A list of dependencies for the job. A job can depend upon a maximum of 20
  jobs. You can specify a SEQUENTIAL type dependency without specifying a job ID for array
  jobs so that each child array job completes sequentially, starting at index 0. You can also
  specify an N_TO_N type dependency with a job ID for array jobs. In that case, each index
  child of this job must wait for the corresponding index child of each dependency to
  complete before it can begin.
- `"nodeOverrides"`: A list of node overrides in JSON format that specify the node range to
  target and the container overrides for that node range.  This parameter isn't applicable to
  jobs that are running on Fargate resources; use containerOverrides instead.
- `"parameters"`: Additional parameters passed to the job that replace parameter
  substitution placeholders that are set in the job definition. Parameters are specified as a
  key and value pair mapping. Parameters in a SubmitJob request override any corresponding
  parameter defaults from the job definition.
- `"propagateTags"`: Specifies whether to propagate the tags from the job or job definition
  to the corresponding Amazon ECS task. If no value is specified, the tags aren't propagated.
  Tags can only be propagated to the tasks during task creation. For tags with the same name,
  job tags are given priority over job definitions tags. If the total number of combined tags
  from the job and job definition is over 50, the job is moved to the FAILED state. When
  specified, this overrides the tag propagation setting in the job definition.
- `"retryStrategy"`: The retry strategy to use for failed jobs from this SubmitJob
  operation. When a retry strategy is specified here, it overrides the retry strategy defined
  in the job definition.
- `"tags"`: The tags that you apply to the job request to help you categorize and organize
  your resources. Each tag consists of a key and an optional value. For more information, see
  Tagging Amazon Web Services Resources in Amazon Web Services General Reference.
- `"timeout"`: The timeout configuration for this SubmitJob operation. You can specify a
  timeout duration after which Batch terminates your jobs if they haven't finished. If a job
  is terminated due to a timeout, it isn't retried. The minimum value for the timeout is 60
  seconds. This configuration overrides any timeout configuration specified in the job
  definition. For array jobs, child jobs have the same timeout configuration as the parent
  job. For more information, see Job Timeouts in the Amazon Elastic Container Service
  Developer Guide.
"""
function submit_job(
    jobDefinition, jobName, jobQueue; aws_config::AbstractAWSConfig=global_aws_config()
)
    return batch(
        "POST",
        "/v1/submitjob",
        Dict{String,Any}(
            "jobDefinition" => jobDefinition, "jobName" => jobName, "jobQueue" => jobQueue
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function submit_job(
    jobDefinition,
    jobName,
    jobQueue,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return batch(
        "POST",
        "/v1/submitjob",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "jobDefinition" => jobDefinition,
                    "jobName" => jobName,
                    "jobQueue" => jobQueue,
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    tag_resource(resource_arn, tags)
    tag_resource(resource_arn, tags, params::Dict{String,<:Any})

Associates the specified tags to a resource with the specified resourceArn. If existing
tags on a resource aren't specified in the request parameters, they aren't changed. When a
resource is deleted, the tags that are associated with that resource are deleted as well.
Batch resources that support tags are compute environments, jobs, job definitions, and job
queues. ARNs for child jobs of array and multi-node parallel (MNP) jobs are not supported.

# Arguments
- `resource_arn`: The Amazon Resource Name (ARN) of the resource that tags are added to.
  Batch resources that support tags are compute environments, jobs, job definitions, and job
  queues. ARNs for child jobs of array and multi-node parallel (MNP) jobs are not supported.
- `tags`: The tags that you apply to the resource to help you categorize and organize your
  resources. Each tag consists of a key and an optional value. For more information, see
  Tagging Amazon Web Services Resources in Amazon Web Services General Reference.

"""
function tag_resource(resourceArn, tags; aws_config::AbstractAWSConfig=global_aws_config())
    return batch(
        "POST",
        "/v1/tags/$(resourceArn)",
        Dict{String,Any}("tags" => tags);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function tag_resource(
    resourceArn,
    tags,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return batch(
        "POST",
        "/v1/tags/$(resourceArn)",
        Dict{String,Any}(mergewith(_merge, Dict{String,Any}("tags" => tags), params));
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    terminate_job(job_id, reason)
    terminate_job(job_id, reason, params::Dict{String,<:Any})

Terminates a job in a job queue. Jobs that are in the STARTING or RUNNING state are
terminated, which causes them to transition to FAILED. Jobs that have not progressed to the
STARTING state are cancelled.

# Arguments
- `job_id`: The Batch job ID of the job to terminate.
- `reason`: A message to attach to the job that explains the reason for canceling it. This
  message is returned by future DescribeJobs operations on the job. This message is also
  recorded in the Batch activity logs.

"""
function terminate_job(jobId, reason; aws_config::AbstractAWSConfig=global_aws_config())
    return batch(
        "POST",
        "/v1/terminatejob",
        Dict{String,Any}("jobId" => jobId, "reason" => reason);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function terminate_job(
    jobId,
    reason,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return batch(
        "POST",
        "/v1/terminatejob",
        Dict{String,Any}(
            mergewith(
                _merge, Dict{String,Any}("jobId" => jobId, "reason" => reason), params
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    untag_resource(resource_arn, tag_keys)
    untag_resource(resource_arn, tag_keys, params::Dict{String,<:Any})

Deletes specified tags from an Batch resource.

# Arguments
- `resource_arn`: The Amazon Resource Name (ARN) of the resource from which to delete tags.
  Batch resources that support tags are compute environments, jobs, job definitions, and job
  queues. ARNs for child jobs of array and multi-node parallel (MNP) jobs are not supported.
- `tag_keys`: The keys of the tags to be removed.

"""
function untag_resource(
    resourceArn, tagKeys; aws_config::AbstractAWSConfig=global_aws_config()
)
    return batch(
        "DELETE",
        "/v1/tags/$(resourceArn)",
        Dict{String,Any}("tagKeys" => tagKeys);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function untag_resource(
    resourceArn,
    tagKeys,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return batch(
        "DELETE",
        "/v1/tags/$(resourceArn)",
        Dict{String,Any}(mergewith(_merge, Dict{String,Any}("tagKeys" => tagKeys), params));
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    update_compute_environment(compute_environment)
    update_compute_environment(compute_environment, params::Dict{String,<:Any})

Updates an Batch compute environment.

# Arguments
- `compute_environment`: The name or full Amazon Resource Name (ARN) of the compute
  environment to update.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"computeResources"`: Details of the compute resources managed by the compute
  environment. Required for a managed compute environment. For more information, see Compute
  Environments in the Batch User Guide.
- `"serviceRole"`: The full Amazon Resource Name (ARN) of the IAM role that allows Batch to
  make calls to other Amazon Web Services services on your behalf. For more information, see
  Batch service IAM role in the Batch User Guide.  If the compute environment has a
  service-linked role, it can't be changed to use a regular IAM role. Likewise, if the
  compute environment has a regular IAM role, it can't be changed to use a service-linked
  role.  If your specified role has a path other than /, then you must either specify the
  full role ARN (this is recommended) or prefix the role name with the path.  Depending on
  how you created your Batch service role, its ARN might contain the service-role path
  prefix. When you only specify the name of the service role, Batch assumes that your ARN
  doesn't use the service-role path prefix. Because of this, we recommend that you specify
  the full ARN of your service role when you create compute environments.
- `"state"`: The state of the compute environment. Compute environments in the ENABLED
  state can accept jobs from a queue and scale in or out automatically based on the workload
  demand of its associated queues. If the state is ENABLED, then the Batch scheduler can
  attempt to place jobs from an associated job queue on the compute resources within the
  environment. If the compute environment is managed, then it can scale its instances out or
  in automatically, based on the job queue demand. If the state is DISABLED, then the Batch
  scheduler doesn't attempt to place jobs within the environment. Jobs in a STARTING or
  RUNNING state continue to progress normally. Managed compute environments in the DISABLED
  state don't scale out. However, they scale in to minvCpus value after instances become idle.
"""
function update_compute_environment(
    computeEnvironment; aws_config::AbstractAWSConfig=global_aws_config()
)
    return batch(
        "POST",
        "/v1/updatecomputeenvironment",
        Dict{String,Any}("computeEnvironment" => computeEnvironment);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function update_compute_environment(
    computeEnvironment,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return batch(
        "POST",
        "/v1/updatecomputeenvironment",
        Dict{String,Any}(
            mergewith(
                _merge, Dict{String,Any}("computeEnvironment" => computeEnvironment), params
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    update_job_queue(job_queue)
    update_job_queue(job_queue, params::Dict{String,<:Any})

Updates a job queue.

# Arguments
- `job_queue`: The name or the Amazon Resource Name (ARN) of the job queue.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"computeEnvironmentOrder"`: Details the set of compute environments mapped to a job
  queue and their order relative to each other. This is one of the parameters used by the job
  scheduler to determine which compute environment should run a given job. Compute
  environments must be in the VALID state before you can associate them with a job queue. All
  of the compute environments must be either EC2 (EC2 or SPOT) or Fargate (FARGATE or
  FARGATE_SPOT). EC2 and Fargate compute environments can't be mixed.  All compute
  environments that are associated with a job queue must share the same architecture. Batch
  doesn't support mixing compute environment architecture types in a single job queue.
- `"priority"`: The priority of the job queue. Job queues with a higher priority (or a
  higher integer value for the priority parameter) are evaluated first when associated with
  the same compute environment. Priority is determined in descending order, for example, a
  job queue with a priority value of 10 is given scheduling preference over a job queue with
  a priority value of 1. All of the compute environments must be either EC2 (EC2 or SPOT) or
  Fargate (FARGATE or FARGATE_SPOT). EC2 and Fargate compute environments can't be mixed.
- `"state"`: Describes the queue's ability to accept new jobs. If the job queue state is
  ENABLED, it can accept jobs. If the job queue state is DISABLED, new jobs can't be added to
  the queue, but jobs already in the queue can finish.
"""
function update_job_queue(jobQueue; aws_config::AbstractAWSConfig=global_aws_config())
    return batch(
        "POST",
        "/v1/updatejobqueue",
        Dict{String,Any}("jobQueue" => jobQueue);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function update_job_queue(
    jobQueue,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return batch(
        "POST",
        "/v1/updatejobqueue",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("jobQueue" => jobQueue), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end


text:
## ExoplanetsSysSim/src/eval_model_macro.jl
## (c) 2015 Eric B. Ford

# Macro to create functions that access variables with global scope (i.e., within the current module), so they can be used inside the evaluate model functions
macro make_evaluate_model(param,cat_phys,cat_obs,sum_stat,sum_stat_ref)
  @eval begin
    function evaluate_model(param_vector::Vector{Float64})
      global $param
      update_sim_param_from_vector!(param_vector,$param)
      global $cat_phys = generate_kepler_physical_catalog($param)
      #global $cat_obs = observe_kepler_targets_sky_avg($cat_phys,$param)
      global $cat_obs = observe_kepler_targets_single_obs($cat_phys,$param)
      global $sum_stat = calc_summary_stats_sim_pass_one_demo($cat_obs,$cat_phys,$param)
      dist1 = calc_distance_vector_demo($sum_stat_ref,$sum_stat, 1, $param)
      #if haskey($param,"minimum ABC dist skip pass 2")
      #   if calc_scalar_distance(dist1) > get($param,"minimum ABC dist skip pass 2")
      #      return dist1
      #   end
      #end
      $sum_stat = calc_summary_stats_sim_pass_two_demo($cat_obs,$cat_phys,$sum_stat,$param)
      dist2 = calc_distance_vector_demo($sum_stat_ref,$sum_stat, 2, $param)
      return [dist1; dist2]
    end

    function evaluate_model_pass_one(param_vector::Vector{Float64})
      global $param
      update_sim_param_from_vector!(param_vector,$param)
      global $cat_phys = generate_kepler_physical_catalog($param)
      #global $cat_obs = observe_kepler_targets_sky_avg($cat_phys,$param)
      global $cat_obs = observe_kepler_targets_single_obs($cat_phys,$param)
      global $sum_stat = calc_summary_stats_sim_pass_one_demo($cat_obs,$cat_phys,$param)
      dist1 = calc_distance_vector_demo($sum_stat_ref,$sum_stat, 1, $param)
    end

    function evaluate_model_pass_two(param_vector::Vector{Float64})
      global $param
      global $cat_phys
      global $cat_obs
      global $sum_stat = calc_summary_stats_sim_pass_two_demo($cat_obs,$cat_phys,$sum_stat,$param)
      dist2 = calc_distance_vector_demo($sum_stat_ref,$sum_stat, 2, $param)
    end

    function evaluate_model_scalar_ret(param::Vector{Float64})
      calc_scalar_distance(evaluate_model(param))
    end

    function evaluate_model_pass_one_scalar_ret(param::Vector{Float64})
      calc_scalar_distance(evaluate_model_pass_one(param))
    end

    function evaluate_model_pass_two_scalar_ret(param::Vector{Float64})
      calc_scalar_distance(evaluate_model_pass_two(param))
    end

    #if module_name(current_module()) != :Main
    if !isequal(@__MODULE__,Module(:Main))
      export evaluate_model, evaluate_model_pass_one, evaluate_model_pass_two, evaluate_model_scalar_ret, evaluate_model_pass_one_scalar_ret, evaluate_model_pass_two_scalar_ret
    end

  end
end

ext: jl


text:
struct L_BFGS_B
    nmax::Int
    mmax::Int
    task::Vector{UInt8}
    csave::Vector{UInt8}
    lsave::Vector{Cint}
    isave::Vector{Cint}
    dsave::Vector{Cdouble}
    wa::Vector{Cdouble}
    iwa::Vector{Cint}
    g::Vector{Cdouble}
    nbd::Vector{Cint}
    l::Vector{Cdouble}
    u::Vector{Cdouble}
    function L_BFGS_B(nmax, mmax)
        task = fill(Cuchar(' '), 60)
        csave = fill(Cuchar(' '), 60)
        lsave = zeros(Cint, 4)
        isave = zeros(Cint, 44)
        dsave = zeros(Cdouble, 29)
        wa = zeros(Cdouble, 2mmax*nmax + 5nmax + 11mmax*mmax + 8mmax)
        iwa = zeros(Cint, 3*nmax)
        g = zeros(Cdouble, nmax)
        nbd = zeros(Cint, nmax)
        l = zeros(Cdouble, nmax)
        u = zeros(Cdouble, nmax)
        new(nmax, mmax, task, csave, lsave, isave, dsave, wa, iwa, g, nbd, l, u)
    end
end

function (obj::L_BFGS_B)(func, grad!, x0::AbstractVector, bounds::AbstractMatrix;
    m=10, factr=1e7, pgtol=1e-5, iprint=-1, maxfun=15000, maxiter=15000)
    x = copy(x0)
    n = length(x)
    f = 0.0
    # clean up
    fill!(obj.task, Cuchar(' '))
    fill!(obj.csave, Cuchar(' '))
    fill!(obj.lsave, zero(Cint))
    fill!(obj.isave, zero(Cint))
    fill!(obj.dsave, zero(Cdouble))
    fill!(obj.wa, zero(Cdouble))
    fill!(obj.iwa, zero(Cint))
    fill!(obj.g, zero(Cdouble))
    fill!(obj.nbd, zero(Cint))
    fill!(obj.l, zero(Cdouble))
    fill!(obj.u, zero(Cdouble))
    # set bounds
    for i = 1:n
        obj.nbd[i] = bounds[1,i]
        obj.l[i] = bounds[2,i]
        obj.u[i] = bounds[3,i]
    end
    # start
    obj.task[1:5] = b"START"
    while true
        setulb(n, m, x, obj.l, obj.u, obj.nbd, f, obj.g, factr, pgtol, obj.wa,
               obj.iwa, obj.task, iprint, obj.csave, obj.lsave, obj.isave, obj.dsave)
        if obj.task[1:2] == b"FG"
            f = func(x)
            grad!(obj.g, x)
        elseif obj.task[1:5] == b"NEW_X"
            if obj.isave[30] ≥ maxiter
                obj.task[1:43] = b"STOP: TOTAL NO. of ITERATIONS REACHED LIMIT"
            elseif obj.isave[34] ≥ maxfun
                obj.task[1:52] = b"STOP: TOTAL NO. of f AND g EVALUATIONS EXCEEDS LIMIT"
            end
        else
            return f, x
        end
    end
end

function (obj::L_BFGS_B)(func, x0::AbstractVector, bounds::AbstractMatrix;
    m=10, factr=1e7, pgtol=1e-5, iprint=-1, maxfun=15000, maxiter=15000)
    x = copy(x0)
    n = length(x)
    f = 0.0
    # clean up
    fill!(obj.task, Cuchar(' '))
    fill!(obj.csave, Cuchar(' '))
    fill!(obj.lsave, zero(Cint))
    fill!(obj.isave, zero(Cint))
    fill!(obj.dsave, zero(Cdouble))
    fill!(obj.wa, zero(Cdouble))
    fill!(obj.iwa, zero(Cint))
    fill!(obj.g, zero(Cdouble))
    fill!(obj.nbd, zero(Cint))
    fill!(obj.l, zero(Cdouble))
    fill!(obj.u, zero(Cdouble))
    # set bounds
    for i = 1:n
        obj.nbd[i] = bounds[1,i]
        obj.l[i] = bounds[2,i]
        obj.u[i] = bounds[3,i]
    end
    # start
    obj.task[1:5] = b"START"
    while true
        setulb(n, m, x, obj.l, obj.u, obj.nbd, f, obj.g, factr, pgtol, obj.wa,
               obj.iwa, obj.task, iprint, obj.csave, obj.lsave, obj.isave, obj.dsave)
        if obj.task[1:2] == b"FG"
            f, grad = func(x)
            obj.g[1:n] = grad
        elseif obj.task[1:5] == b"NEW_X"
            if obj.isave[30] ≥ maxiter
                obj.task[1:43] = b"STOP: TOTAL NO. of ITERATIONS REACHED LIMIT"
            elseif obj.isave[34] ≥ maxfun
                obj.task[1:52] = b"STOP: TOTAL NO. of f AND g EVALUATIONS EXCEEDS LIMIT"
            end
        else
            return f, x
        end
    end
end


text:
module EverestSmoothCameraOffsetTrigger

using ..Ahorn, Maple

const placements = Ahorn.PlacementDict(
    "Smooth Camera Offset (Everest)" => Ahorn.EntityPlacement(
        Maple.EverestSmoothCameraOffsetTrigger,
        "rectangle"
    ),
)

function Ahorn.editingOptions(trigger::Maple.EverestSmoothCameraOffsetTrigger)
    return Dict{String, Any}(
        "positionMode" => Maple.trigger_position_modes
    )
end

end


text:
# Triangle in 3D defined by its 3 vertices.

struct Triangle_3D{T <: AbstractFloat}
    points::NTuple{3, Point_3D{T}}
end

# Constructors
# -------------------------------------------------------------------------------------------------
Triangle_3D(p₁::Point_3D{T},
            p₂::Point_3D{T},
            p₃::Point_3D{T}) where {T <: AbstractFloat} = Triangle_3D((p₁, p₂, p₃))

# Methods
# -------------------------------------------------------------------------------------------------
# Interpolation
function (tri::Triangle_3D{T})(r::R, s::S) where {T <: AbstractFloat,
                                                  R <: Real,
                                                  S <: Real}
    return (1 - T(r) - T(s))*tri.points[1] + T(r)*tri.points[2] + T(s)*tri.points[3]
end

function area(tri::Triangle_3D{T}) where {T <: AbstractFloat}
    # A = bh/2
    # Let u⃗ = |v₂ - v₁|, v⃗ = |v₃ - v₁|
    # b = |u⃗|
    # h = |sin(θ) v⃗|, where θ is the angle between u⃗ and v⃗
    # u⃗ × v⃗ = |u⃗||v⃗| sin(θ), hence
    # A = |u⃗ × v⃗|/2 = bh/2
    u⃗ = tri.points[2] - tri.points[1]
    v⃗ = tri.points[3] - tri.points[1]
    return norm(u⃗ × v⃗)/2
end

function intersect(l::LineSegment_3D{type}, tri::Triangle_3D{type}) where {type <: AbstractFloat}
    # Algorithm is from
    # Möller, T., & Trumbore, B. (1997). Fast, minimum storage ray-triangle intersection.
    p = Point_3D(type, 0)
    E₁ = tri.points[2] - tri.points[1]
    E₂ = tri.points[3] - tri.points[1]
    T = l.points[1] - tri.points[1]
    D = l.points[2] - l.points[1]
    P = D × E₂
    Q = T × E₁
    det = P ⋅ E₁
    if abs(det) < 5e-6
        return false, p
    else
        u = (P ⋅ T)/det
        v = (Q ⋅ D)/det
        t = (Q ⋅ E₂)/det
        return (u < 0) || (v < 0) || (u + v > 1) || (t < 0) || (1 < t) ? (false, p) : (true, l(t))
    end
end

max_stars_repo_name: KyleVaughn/MOCNeutronTransport

max_issues_repo_name: KyleVaughn/MOCNeutronTransport

max_forks_repo_name: KyleVaughn/MOCNeutronTransport


text:
machinesuri(cli::Client) = "http://$(cli.host):$(cli.port)/$(cli.version)/machines"

"""
    machines(cli) -> Array

Returns an array of machines (socket addresses) in the cluster.
"""
function machines(cli::Client)
    resp = request(Requests.get, machinesuri(cli), Dict())
    return map(strip, split(resp, ','))
end


text:
import ..update!, ..select_action, ..reset!

using Ramnet.Models.AltDiscriminators:RegressionDiscriminator
using StatsBase: mean, sample, pweights
using StaticArrays

struct QDiscriminator{AS,OS,T <: Real,O <: StaticArray{Tuple{OS},T,1},A <: Real,E <: AbstractEncoder{T}}
    actions::SVector{AS,A}
    Q::Dict{A,RegressionDiscriminator{1}}
    last_q_values::Vector{Float64}
    rng::MersenneTwister
end

function QDiscriminator(::Type{O}, actions::StaticArray{Tuple{AS},A,1}, n::Int, γ::Float64, encoder::E, seed::Union{Nothing,UInt}) where {AS,OS,T <: Real,O <: StaticArray{Tuple{OS},T,1},A <: Real,E <: AbstractEncoder{T}}
    !isnothing(seed) && seed < 0 && throw(DomainError(seed, "Seed must be non-negative"))
    rng = isnothing(seed) ? MersenneTwister() : MersenneTwister(seed)

    Q = Dict(a => RegressionDiscriminator{1}(OS, n, encoder; seed, γ) for a in actions)
    QDiscriminator{AS,OS,T,O,A,E}(actions, Q, zeros(Float64, AS), rng)
end

function update!(q::QDiscriminator{AS,OS,T,O,A,E}, observation::O, action::A, G) where {AS,OS,T <: Real,O <: StaticArray{Tuple{OS},T,1},A <: Real,E <: AbstractEncoder{T}}
    train!(q.Q[action], observation, G)
end

function (q::QDiscriminator{AS,OS,T,O,A,E})(observation::O, action::A) where {AS,OS,T,O,A,E}
    predict(q.Q[action], observation) |> first
end

function q_values!(q::QDiscriminator{AS,OS,T,O,A,E}, observation::O) where {AS,OS,T,O,A,E}
    q_max = typemin(Float64)
    v = 0.0
    for (i, action) in Iterators.zip(eachindex(q.last_q_values), q.actions)
        v = q(observation, action)
        q.last_q_values[i] = v
        q_max = v > q_max ? v : q_max
    end

    return q_max
end

function select_action(q::QDiscriminator{AS,OS,T,O,A,E}, observation::O) where {AS,OS,T,O,A,E}
    q_max = q_values!(q, observation)

    return sample(q.rng, q.actions, pweights(q.last_q_values .== q_max))
end

function reset!(q::QDiscriminator; seed::Union{Nothing,UInt}=nothing)
    if !isnothing(seed)
        if seed >= 0
            Random.seed!(q.rng, seed)
        else
            throw(DomainError(seed, "Seed must be non-negative"))
        end
    end

    # reset!(q.Q; seed)
    for (_, v) in q.Q
        Ramnet.reset!(v; seed)
    end
    fill!(q.last_q_values, 0.0)

    nothing
end


text:
#UTILITY  REPORTS WORKER NUMBER AND CURRENT ITERATE
mutable struct ProgressNS{T<:Real} <: AbstractProgress
    interval::T
    dt::AbstractFloat
    start_it::Integer
    counter::Integer
    triggered::Bool
    tfirst::AbstractFloat
    tlast::AbstractFloat
    tstp::AbstractFloat
    printed::Bool        # true if we have issued at least one status update
    desc::AbstractString # prefix to the percentage, e.g.  "Computing..."
    color::Symbol        # default to green
    output::IO           # output stream into which the progress is written
    numprintedvalues::Integer   # num values printed below progress in last iteration
    offset::Integer             # position offset of progress bar (default is 0)

    e::IPM_Ensemble
    wm::Worker_Monitor
    tuner::Permute_Tuner
    top_m::ICA_PWM_Model

    mean_stp_time::AbstractFloat

    wk_disp::Bool
    tuning_disp::Bool
    conv_plot::Bool
    ens_disp::Bool
    lh_disp::Bool
    liwi_disp::Bool
    src_disp::Bool
    no_displayed_srcs::Integer

    disp_rotate_inst::Vector{Any}

    convergence_history::Vector{Float64}

    function ProgressNS{T}(    e::IPM_Ensemble,
                               top_m::ICA_PWM_Model,
                               wm::Worker_Monitor,
                               tuner::Permute_Tuner,
                               interval::T;
                               dt::Real=0.1,
                               desc::AbstractString="Nested Sampling::",
                               color::Symbol=:green,
                               output::IO=stdout,
                               offset::Int=0,
                               start_it::Int=1,
                               wk_disp::Bool=false,
                               tuning_disp::Bool=false,
                               conv_plot::Bool=true,
                               ens_disp::Bool=false,
                               lh_disp::Bool=false,
                               liwi_disp::Bool=false,
                               src_disp::Bool=true,
                               nsrcs::Integer=0,
                               disp_rotate_inst=[false,0,0,Vector{Vector{Symbol}}()]) where T
        tfirst = tlast = time()
        printed = false
        new{T}(interval,
         dt,
         start_it,
         start_it,
         false,
         tfirst,
         tlast,
         0.,
         printed,
         desc,
         color,
         output,
         0,
         offset,
         e,
         wm,
         tuner,
         top_m,
         0.,
         wk_disp,
         tuning_disp,
         conv_plot,
         ens_disp,
         lh_disp,
         liwi_disp,
         src_disp,
         nsrcs,
         disp_rotate_inst,
         zeros(CONVERGENCE_MEMORY))
    end
end

function ProgressNS(e::IPM_Ensemble, wm::Worker_Monitor, tuner::Permute_Tuner, interval::Real; dt::Real=0.1, desc::AbstractString="Nested Sampling::", color::Symbol=:green, output::IO=stderr, offset::Integer=0, start_it::Integer=1, wk_disp::Bool=false, tuning_disp::Bool=false, conv_plot::Bool=false, lh_disp::Bool=false, liwi_disp::Bool=false, ens_disp::Bool=false, src_disp::Bool=false, nsrcs=0, disp_rotate_inst::Vector{Any}=[false,0,0,Vector{Vector{Symbol}}()])
    top_m = deserialize(e.models[findmax([model.log_Li for model in e.models])[2]].path)

    return ProgressNS{typeof(interval)}(e, top_m, wm, tuner, interval, dt=dt, desc=desc, color=color, output=output, offset=offset, start_it=start_it, wk_disp=wk_disp, tuning_disp=tuning_disp, conv_plot=conv_plot, lh_disp=lh_disp, liwi_disp=liwi_disp, ens_disp=ens_disp, src_disp=src_disp, nsrcs=nsrcs, disp_rotate_inst=disp_rotate_inst)
end

function update!(p::ProgressNS, val, thresh; options...)
    p.counter += 1

    p.tstp=time()-p.tlast
    popfirst!(p.tuner.time_history)
    push!(p.tuner.time_history, p.tstp)

    p.interval = val - thresh
    popfirst!(p.convergence_history)
    push!(p.convergence_history, p.interval)

    p.top_m.name != basename(p.e.models[findmax([model.log_Li for model in p.e.models])[2]].path) && (p.top_m=deserialize(p.e.models[findmax([model.log_Li for model in p.e.models])[2]].path))

    updateProgress!(p; options...)
end

function updateProgress!(p::ProgressNS; offset::Integer = p.offset, keep = (offset == 0))
    p.offset = offset
    t = time()
    p.disp_rotate_inst[1] && p.counter%p.disp_rotate_inst[2] == 0 && rotate_displays(p)

    if p.interval <= 0 && !p.triggered
        p.triggered = true
        if p.printed
            p.triggered = true
            dur = durationstring(t-p.tfirst)
            msg = @sprintf "%s Converged. Time: %s (%d iterations). logZ: %s\n" p.desc dur p.counter p.e.log_Zi[end]

            print(p.output, "\n" ^ (p.offset + p.numprintedvalues))
            move_cursor_up_while_clearing_lines(p.output, p.numprintedvalues)
            upper_lines=display_upper_dash(p)
            printover(p.output, msg, :magenta)
            lower_lines=display_lower_dash(p)

            p.numprintedvalues=upper_lines + lower_lines + 1

            if keep
                println(p.output)
            else
                print(p.output, "\r\u1b[A" ^ (p.offset + p.numprintedvalues))
            end
        end
        return
    end

    if t > p.tlast+p.dt && !p.triggered
        p.counter < CONVERGENCE_MEMORY ? mean_step_time=mean(p.tuner.time_history[end-(p.counter-1):end]) :
                                            mean_step_time=mean(p.tuner.time_history)
        msg = @sprintf "%s Iterate: %s Recent step time μ: %s Convergence Interval: %g\n" p.desc p.counter hmss(mean_step_time) p.interval

        print(p.output, "\n" ^ (p.offset + p.numprintedvalues))
        move_cursor_up_while_clearing_lines(p.output, p.numprintedvalues)
        upper_lines=display_upper_dash(p)
        printover(p.output, msg, p.color)
        lower_lines=display_lower_dash(p)

        p.numprintedvalues=upper_lines + lower_lines + 1
        print(p.output, "\r\u1b[A" ^ (p.offset + p.numprintedvalues))

        # Compensate for any overhead of printing. This can be
        # especially important if you're running over a slow network
        # connection.
        p.tlast = t + 2*(time()-t)
        p.printed = true
    end
end
                function rotate_displays(p)
                    curr_inst=p.disp_rotate_inst[3]
                    curr_inst+1>length(p.disp_rotate_inst[4]) ? next_inst=1 : next_inst=curr_inst+1
                    next_disps=p.disp_rotate_inst[4][next_inst]
                    for disp in [:wk_disp,:tuning_disp,:conv_plot,:ens_disp,:lh_disp,:liwi_disp,:src_disp]
                        disp in next_disps ?  setproperty!(p, disp, true) : setproperty!(p, disp, false)
                    end
                    p.disp_rotate_inst[3]=next_inst
                end

                function hmss(dt)
                    dt<0 ? (dt=-dt; prfx="-") : (prfx="")
                    isnan(dt) && return "NaN"
                    (h,r) = divrem(dt,60*60)
                    (m,r) = divrem(r, 60)
                    (isnan(h)||isnan(m)||isnan(r)) && return "NaN"
                    string(prfx,Int(h),":",Int(m),":",Int(ceil(r)))
                end

                function display_upper_dash(p::ProgressNS)
                    wklines = tunelines = cilines = 0
                    p.wk_disp && (wklines=show(p.output, p.wm, progress=true);println())
                    p.tuning_disp && (tunelines=show(p.output, p.tuner, progress=true);println())
                    if p.conv_plot
                        ciplot=lineplot([p.counter-(length(p.convergence_history)-1):p.counter...], p.convergence_history, title="Convergence Interval Recent History", xlabel="Iterate",ylabel="CI", color=:yellow)
                        cilines=nrows(ciplot.graphics)+5
                        show(p.output, ciplot); println()
                    end
                    return wklines + tunelines + cilines
                end

                function display_lower_dash(p::ProgressNS)
                    lhlines = liwilines = ensemblelines = srclines = 0
                    if p.lh_disp
                        lhplot=lineplot(p.e.log_Li[2:end], title="Contour History", xlabel="Iterate", color=:magenta, name="Ensemble logLH")
                        lineplot!(lhplot, [p.e.naive_lh for it in 1:length(p.e.log_Li[2:end])], name="Naive logLH")
                        lhlines=nrows(lhplot.graphics)+5
                        show(p.output, lhplot); println()
                    end
                    if p.liwi_disp && p.counter>2
                        liwiplot=lineplot([max(2,p.counter-(CONVERGENCE_MEMORY-1)):p.counter...],p.e.log_Liwi[max(2,end-(CONVERGENCE_MEMORY-1)):end], title="Recent iterate evidentiary weight", xlabel="Iterate", name="Ensemble log Liwi", color=:cyan)
                        liwilines=nrows(liwiplot.graphics)+5
                        show(p.output, liwiplot); println()
                    end
                    p.ens_disp && (ensemblelines=show(p.output, p.e, progress=true))
                    p.src_disp && (println("MLE Model Sources:");srclines=show(p.output, p.top_m, nsrc=p.no_displayed_srcs, progress=true))
                    return lhlines + liwilines + ensemblelines + srclines
                end


text:
module WeightsAndBiasLogger
    using PyCall
    using PyPlot: Figure
    const wandb = PyNULL()

    function __init__()
        copy!(wandb, pyimport("wandb"))
    end

    using Base.CoreLogging: CoreLogging, AbstractLogger, LogLevel, Info, handle_message, shouldlog, min_enabled_level, catch_exceptions, with_logger

    ### WBLogger

    mutable struct WBLogger <: AbstractLogger
        min_level::LogLevel
        force_pyplot::Bool
    end

    function WBLogger(; min_level::LogLevel=Info, reinit=true, force_pyplot=true, init_args...)
        wandb.init(; reinit=reinit, init_args...)
        return WBLogger(min_level, force_pyplot)
    end

    function string_dict(prefix, cfg; ignores=[], delimiter="/")
        ignores = string.(ignores)
        # Make string dict
        dict = Dict(string(k) => cfg[k] for k in keys(cfg))
        # Ignore some keys
        dict = filter(p -> !(string(p.first) in ignores), dict)
        # Add prefix
        prefix = prefix == "" ? "" : "$prefix$delimiter"
        dict = Dict(prefix * k => dict[k] for k in keys(dict))
        return dict
    end

    config!(wblogger::WBLogger, p::Pair; kwargs...) = config!(wblogger, p.first, p.second; kwargs...)
    config!(wblogger::WBLogger, cfg; kwargs...) = config!(wblogger, "", cfg; kwargs...)
    config!(wblogger::WBLogger, name::String, cfg; kwargs...) =
        wandb.config.update(string_dict(name, cfg; kwargs...))

    ### Preprocessing

    preprocess(lg, x) = x
    preprocess(wblogger::WBLogger, x::Figure) = wblogger.force_pyplot ? wandb.Image(x) : x

    ### AbstractLogger interface

    CoreLogging.catch_exceptions(lg::WBLogger) = false

    CoreLogging.min_enabled_level(lg::WBLogger) = lg.min_level

    CoreLogging.shouldlog(lg::WBLogger, level, _module, group, id) = true

    function CoreLogging.handle_message(lg::WBLogger, level, message, _module, group, id, file, line; commit=true, kwargs...)
        prefix = isempty(message) ? "" : "$message/"
        info_dict = Dict("$prefix$k" => preprocess(lg, kwargs[k]) for k in keys(kwargs))
        wandb.log(info_dict, commit=commit)
    end

    # Utilites

    with(f::Function, lg::AbstractLogger) = with_logger(f, lg)

    export wandb, WBLogger, config!, with
end # module


text:
using AbstractGPs
using ConjugateComputationVI
using Distributions
using Optim
using ParameterHandling
using Plots
using Random
using RDatasets
using StatsBase
using StatsFuns
using Zygote

using ConjugateComputationVI: GaussHermiteQuadrature, UnivariateFactorisedLikelihood

# Adjoint for the Poisson logpdf.
# log(λ^x exp(-λ) / x!) =
# x log(λ) - λ - log(x!)
# dλ = x / λ - 1
Zygote.@adjoint function StatsFuns.poislogpdf(λ::Float64, x::Union{Float64, Int})
    function poislogpdf_pullback(Δ::Real)
        return Δ * (x / λ - 1), nothing
    end
    return StatsFuns.poislogpdf(λ, x), poislogpdf_pullback
end

# Download the data.
data = dataset("boot", "coal")

# Bin the data
h = fit(Histogram, data.Date, range(minimum(data.Date), maximum(data.Date); length=200))

# Construct data set to learn on.
x = collect(only(h.edges)[1:end-1])
y = h.weights

# Specify a model.
θ_init = (scale=positive(1.0), stretch=positive(1e-3))
θ_init_flat, unflatten = ParameterHandling.flatten(θ_init)

function build_latent_gp(θ::AbstractVector{<:Real})
    return build_latent_gp(ParameterHandling.value(unflatten(θ)))
end
function build_latent_gp(θ::NamedTuple)
    gp = GP(θ.scale * SEKernel() ∘ ScaleTransform(θ.stretch))
    lik = UnivariateFactorisedLikelihood(f -> Poisson(exp(f)))
    return LatentGP(gp, lik, 1e-9)
end

f_approx_post, results_summary = ConjugateComputationVI.optimize_elbo(
    build_latent_gp,
    GaussHermiteQuadrature(10),
    x,
    y,
    θ_init_flat,
    BFGS(
        alphaguess = Optim.LineSearches.InitialStatic(scaled=true),
        linesearch = Optim.LineSearches.BackTracking(),
    ),
    Optim.Options(
        show_trace = true,
        iterations=25,
        f_calls_limit=50,
    ),
);

function approx_post_marginal_samples(x::AbstractVector, N::Int)
    return map(marginals(f_approx_post(x))) do latent_marginal
        f = rand(latent_marginal, N)
        return exp.(f)
    end
end

function approx_post_95_CI(x::AbstractVector, N::Int)
    samples = approx_post_marginal_samples(x, N)
    return quantile.(samples, Ref((0.025, 0.5, 0.975)))
end

# Plot the predictions.
qs = approx_post_95_CI(x, 10_000);
p1 = plot(
    x, getindex.(qs, 1);
    linealpha=0,
    fillrange=getindex.(qs, 3),
    label="95% CI",
    fillalpha=0.3,
    color=:blue,
);
scatter!(p1, x, y; markersize=2, label="Observations");

p2 = plot(f_approx_post(x, 1e-6); ribbon_scale=3, color=:blue, label="approx post latent");
sampleplot!(f_approx_post(x, 1e-6), 10; color=:blue);

plot(p1, p2; layout=(2, 1))