text:
using LinearAlgebra
using Yao

include("circuit.jl")

export QNNL, forward, back_propagation
export Layer

abstract type Layer{T} end

struct QNNL{T} <: Layer{T}
	encoder::YaoBlocks.ChainBlock
	transform::YaoBlocks.ChainBlock
	params::Array{T}
	Hami::Array{<:YaoBlocks.AbstractBlock, 1}
	bias::Array{T,1}
end

function QNNL{T}(n::Integer, l1::Integer, l2::Integer, w::Array{T}, b::Array{T,1}, Hami::Array{<:YaoBlocks.AbstractBlock, 1}) where {T}
	cir_e = QDNN.encoder_circuit(n, l1)
	cir_t = QDNN.transform_circuit(n, l2)
	QNNL{T}(cir_e, cir_t, w, Hami, b)
end

function QNNL{T}(n::Integer, l1::Integer, l2::Integer, Hami::Array{<:YaoBlocks.AbstractBlock, 1}; no_bias = false) where {T}
	cir_e = QDNN.encoder_circuit(n, l1)
	cir_t = QDNN.transform_circuit(n, l2)
	w = (rand(T, size(parameters(cir_t))) .- 0.5) * 2π
	if no_bias
		b = T[]
	else
		b = rand(T, size(Hami)) .- 0.5
	end
	QNNL{T}(cir_e, cir_t, w, Hami, b)
end

function QNNL{T}(n::Integer, l1::Integer, l2::Integer, w::Array{T}, b::Array{T,1}, Hs::String) where {T}
	Hami = YaoBlocks.ChainBlock[]
	for c in Hs
		Hami = [Hami; genH(n, c)]
	end
	cir_e = QDNN.encoder_circuit(n, l1)
	cir_t = QDNN.transform_circuit(n, l2)
	QNNL{T}(cir_e, cir_t, w, Hami, b)
end

function QNNL{T}(n::Integer, l1::Integer, l2::Integer, Hs::String; no_bias = false) where T
	Hami = YaoBlocks.ChainBlock[]
	for c in Hs
		Hami = [Hami; genH(n, c)]
	end
	cir_e = QDNN.encoder_circuit(n, l1)
	cir_t = QDNN.transform_circuit(n, l2)
	w = (rand(T, size(parameters(cir_t))) .- 0.5) * 2π
	if no_bias
		b = T[]
	else
		b = rand(T, size(Hami)) .- 0.5
	end
	QNNL{Float64}(cir_e, cir_t, w, Hami, b)
end

function forward(ql::QNNL{T}, x::Array{T}) where {N, T}
	cir = chain(ql.encoder, ql.transform)
	n = nqubits(cir)
	dispatch!(cir, [x; ql.params])

	m = size(ql.Hami, 1)
	psi = zero_state(n)
	psi |> cir
	y = [real(expect((ql.Hami[i]), psi)) for i = 1:m]
	if size(ql.bias, 1) > 0
		y += ql.bias
	end
	return y
end

function back_propagation(ql::QNNL{T}, x::Array{T}) where {N,T}
	m = size(ql.Hami, 1)
	s1 = size(x, 1)
	s2 = size(ql.params, 1)
	s3 = size(ql.bias, 1)

	if s3 > 0
		L_b = 1
	else
		L_b = 0
	end

	L_x = zeros(s1, m)
	L_w = zeros(s2, m)

	for i = 1:s1
		x[i] += π/2
		y_pos = forward(ql, x)
		x[i] -= π
		y_neg = forward(ql, x)
		x[i] += π/2

		L_x[i, :] = (y_pos - y_neg) / 2
	end

	for i = 1:s2
		ql.params[i] += π/2
		y_pos = forward(ql, x)
		ql.params[i] -= π
		y_neg = forward(ql, x)
		ql.params[i] += π/2

		L_w[i, :] = (y_pos - y_neg) / 2
	end

	return L_x, L_w, L_b
end


text:
function WACM(W,X,Y)
	K = size(W,1)
	eff = zeros(K,1)
	for k=1:K
		eff[k,:] = [minimum(X[all(Y .>= Y[k,:],2),:]*W[k,:]')]/(W[k,:]*X[k,:]')
	end
	return eff
end

ext: jl

max_stars_repo_name: kepiej/NEPA


text:
using ..Continuations: as, ContinuationCache

"""
`AugmentedSystem` subtypes specify how to construct an augmented system.
"""
abstract type AugmentedSystem end

augsys(::T) where T = AugmentedSystem(T)

""" Normalize the eigenvector.  Works only for saddle-node. """
struct NormalizingAS <: AugmentedSystem end

""" Project onto the previous eigenvector (*reference vector*). """
struct BackReferencingAS <: AugmentedSystem end

struct NormalizingASCache end

mutable struct BackReferencingASCache{T}
    v::T
end

get_augsys_cache(prob) = _get_augsys_cache(augsys(prob), prob)
_get_augsys_cache(::NormalizingAS, ::Any) = NormalizingASCache()

set_augsys_cache!(::NormalizingASCache, ::ContinuationCache) = nothing

function set_augsys_cache!(augsys_cache::BackReferencingASCache,
                           cont_cache::ContinuationCache)
    prob = cont_cache.prob_cache.prob  # TODO: interface
    v = ds_eigvec(prob, cont_cache.u)
    augsys_cache.v = v ./ norm(v)
end

function set_augsys_cache!(wrapper)
    cont_cache = as(wrapper, ContinuationCache)
    augsys_cache = cont_cache.prob_cache.augsys_cache  # TODO: interface
    set_augsys_cache!(augsys_cache, cont_cache)
end

function preferred_augsys(point)
    # TODO: Default to NormalizingAS for Hopf as well?
    if point.point_type == Codim1.PointTypes.saddle_node
        return NormalizingAS()
    end
    return BackReferencingAS()
end

preferred_augsys(::HopfCont) = BackReferencingAS()
preferred_augsys(::SaddleNodeCont) = NormalizingAS()


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

"""
    create_dataset(dataset_type, project_name)
    create_dataset(dataset_type, project_name, params::Dict{String,<:Any})

Creates a new dataset in an Amazon Lookout for Vision project. CreateDataset can create a
training or a test dataset from a valid dataset source (DatasetSource). If you want a
single dataset project, specify train for the value of DatasetType. To have a project with
separate training and test datasets, call CreateDataset twice. On the first call, specify
train for the value of DatasetType. On the second call, specify test for the value of
DatasetType.  This operation requires permissions to perform the
lookoutvision:CreateDataset operation.

# Arguments
- `dataset_type`: The type of the dataset. Specify train for a training dataset. Specify
  test for a test dataset.
- `project_name`: The name of the project in which you want to create a dataset.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"DatasetSource"`: The location of the manifest file that Amazon Lookout for Vision uses
  to create the dataset. If you don't specify DatasetSource, an empty dataset is created and
  the operation synchronously returns. Later, you can add JSON Lines by calling
  UpdateDatasetEntries.  If you specify a value for DataSource, the manifest at the S3
  location is validated and used to create the dataset. The call to CreateDataset is
  asynchronous and might take a while to complete. To find out the current status, Check the
  value of Status returned in a call to DescribeDataset.
- `"X-Amzn-Client-Token"`: ClientToken is an idempotency token that ensures a call to
  CreateDataset completes only once. You choose the value to pass. For example, An issue
  might prevent you from getting a response from CreateDataset. In this case, safely retry
  your call to CreateDataset by using the same ClientToken parameter value. If you don't
  supply a value for ClientToken, the AWS SDK you are using inserts a value for you. This
  prevents retries after a network error from making multiple dataset creation requests.
  You'll need to provide your own value for other use cases.  An error occurs if the other
  input parameters are not the same as in the first request. Using a different value for
  ClientToken is considered a new call to CreateDataset. An idempotency token is active for 8
  hours.
"""
function create_dataset(
    DatasetType, projectName; aws_config::AbstractAWSConfig=global_aws_config()
)
    return lookoutvision(
        "POST",
        "/2020-11-20/projects/$(projectName)/datasets",
        Dict{String,Any}(
            "DatasetType" => DatasetType, "X-Amzn-Client-Token" => string(uuid4())
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function create_dataset(
    DatasetType,
    projectName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return lookoutvision(
        "POST",
        "/2020-11-20/projects/$(projectName)/datasets",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "DatasetType" => DatasetType, "X-Amzn-Client-Token" => string(uuid4())
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    create_model(output_config, project_name)
    create_model(output_config, project_name, params::Dict{String,<:Any})

Creates a new version of a model within an an Amazon Lookout for Vision project.
CreateModel is an asynchronous operation in which Amazon Lookout for Vision trains, tests,
and evaluates a new version of a model.  To get the current status, check the Status field
returned in the response from DescribeModel. If the project has a single dataset, Amazon
Lookout for Vision internally splits the dataset to create a training and a test dataset.
If the project has a training and a test dataset, Lookout for Vision uses the respective
datasets to train and test the model.  After training completes, the evaluation metrics are
stored at the location specified in OutputConfig.  This operation requires permissions to
perform the lookoutvision:CreateModel operation. If you want to tag your model, you also
require permission to the lookoutvision:TagResource operation.

# Arguments
- `output_config`: The location where Amazon Lookout for Vision saves the training results.
- `project_name`: The name of the project in which you want to create a model version.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"Description"`: A description for the version of the model.
- `"KmsKeyId"`: The identifier for your AWS KMS key. The key is used to encrypt training
  and test images copied into the service for model training. Your source images are
  unaffected. If this parameter is not specified, the copied images are encrypted by a key
  that AWS owns and manages.
- `"Tags"`: A set of tags (key-value pairs) that you want to attach to the model.
- `"X-Amzn-Client-Token"`: ClientToken is an idempotency token that ensures a call to
  CreateModel completes only once. You choose the value to pass. For example, An issue might
  prevent you from getting a response from CreateModel. In this case, safely retry your call
  to CreateModel by using the same ClientToken parameter value.  If you don't supply a value
  for ClientToken, the AWS SDK you are using inserts a value for you. This prevents retries
  after a network error from starting multiple training jobs. You'll need to provide your own
  value for other use cases.  An error occurs if the other input parameters are not the same
  as in the first request. Using a different value for ClientToken is considered a new call
  to CreateModel. An idempotency token is active for 8 hours.
"""
function create_model(
    OutputConfig, projectName; aws_config::AbstractAWSConfig=global_aws_config()
)
    return lookoutvision(
        "POST",
        "/2020-11-20/projects/$(projectName)/models",
        Dict{String,Any}(
            "OutputConfig" => OutputConfig, "X-Amzn-Client-Token" => string(uuid4())
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function create_model(
    OutputConfig,
    projectName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return lookoutvision(
        "POST",
        "/2020-11-20/projects/$(projectName)/models",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "OutputConfig" => OutputConfig, "X-Amzn-Client-Token" => string(uuid4())
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Creates an empty Amazon Lookout for Vision project. After you create the project, add a
dataset by calling CreateDataset. This operation requires permissions to perform the
lookoutvision:CreateProject operation.

# Arguments
- `project_name`: The name for the project.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"X-Amzn-Client-Token"`: ClientToken is an idempotency token that ensures a call to
  CreateProject completes only once. You choose the value to pass. For example, An issue
  might prevent you from getting a response from CreateProject. In this case, safely retry
  your call to CreateProject by using the same ClientToken parameter value.  If you don't
  supply a value for ClientToken, the AWS SDK you are using inserts a value for you. This
  prevents retries after a network error from making multiple project creation requests.
  You'll need to provide your own value for other use cases.  An error occurs if the other
  input parameters are not the same as in the first request. Using a different value for
  ClientToken is considered a new call to CreateProject. An idempotency token is active for 8
  hours.
"""
function create_project(ProjectName; aws_config::AbstractAWSConfig=global_aws_config())
    return lookoutvision(
        "POST",
        "/2020-11-20/projects",
        Dict{String,Any}(
            "ProjectName" => ProjectName, "X-Amzn-Client-Token" => string(uuid4())
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function create_project(
    ProjectName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return lookoutvision(
        "POST",
        "/2020-11-20/projects",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "ProjectName" => ProjectName, "X-Amzn-Client-Token" => string(uuid4())
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    delete_dataset(dataset_type, project_name)
    delete_dataset(dataset_type, project_name, params::Dict{String,<:Any})

Deletes an existing Amazon Lookout for Vision dataset.  If your the project has a single
dataset, you must create a new dataset before you can create a model. If you project has a
training dataset and a test dataset consider the following.    If you delete the test
dataset, your project reverts to a single dataset project. If you then train the model,
Amazon Lookout for Vision internally splits the remaining dataset into a training and test
dataset.   If you delete the training dataset, you must create a training dataset before
you can create a model.   This operation requires permissions to perform the
lookoutvision:DeleteDataset operation.

# Arguments
- `dataset_type`: The type of the dataset to delete. Specify train to delete the training
  dataset. Specify test to delete the test dataset. To delete the dataset in a single dataset
  project, specify train.
- `project_name`: The name of the project that contains the dataset that you want to delete.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"X-Amzn-Client-Token"`: ClientToken is an idempotency token that ensures a call to
  DeleteDataset completes only once. You choose the value to pass. For example, An issue
  might prevent you from getting a response from DeleteDataset. In this case, safely retry
  your call to DeleteDataset by using the same ClientToken parameter value.  If you don't
  supply a value for ClientToken, the AWS SDK you are using inserts a value for you. This
  prevents retries after a network error from making multiple deletetion requests. You'll
  need to provide your own value for other use cases.  An error occurs if the other input
  parameters are not the same as in the first request. Using a different value for
  ClientToken is considered a new call to DeleteDataset. An idempotency token is active for 8
  hours.
"""
function delete_dataset(
    datasetType, projectName; aws_config::AbstractAWSConfig=global_aws_config()
)
    return lookoutvision(
        "DELETE",
        "/2020-11-20/projects/$(projectName)/datasets/$(datasetType)",
        Dict{String,Any}("X-Amzn-Client-Token" => string(uuid4()));
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function delete_dataset(
    datasetType,
    projectName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return lookoutvision(
        "DELETE",
        "/2020-11-20/projects/$(projectName)/datasets/$(datasetType)",
        Dict{String,Any}(
            mergewith(
                _merge, Dict{String,Any}("X-Amzn-Client-Token" => string(uuid4())), params
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    delete_model(model_version, project_name)
    delete_model(model_version, project_name, params::Dict{String,<:Any})

Deletes an Amazon Lookout for Vision model. You can't delete a running model. To stop a
running model, use the StopModel operation. It might take a few seconds to delete a model.
To determine if a model has been deleted, call ListModels and check if the version of the
model (ModelVersion) is in the Models array.   This operation requires permissions to
perform the lookoutvision:DeleteModel operation.

# Arguments
- `model_version`: The version of the model that you want to delete.
- `project_name`: The name of the project that contains the model that you want to delete.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"X-Amzn-Client-Token"`: ClientToken is an idempotency token that ensures a call to
  DeleteModel completes only once. You choose the value to pass. For example, an issue might
  prevent you from getting a response from DeleteModel. In this case, safely retry your call
  to DeleteModel by using the same ClientToken parameter value. If you don't supply a value
  for ClientToken, the AWS SDK you are using inserts a value for you. This prevents retries
  after a network error from making multiple model deletion requests. You'll need to provide
  your own value for other use cases.  An error occurs if the other input parameters are not
  the same as in the first request. Using a different value for ClientToken is considered a
  new call to DeleteModel. An idempotency token is active for 8 hours.
"""
function delete_model(
    modelVersion, projectName; aws_config::AbstractAWSConfig=global_aws_config()
)
    return lookoutvision(
        "DELETE",
        "/2020-11-20/projects/$(projectName)/models/$(modelVersion)",
        Dict{String,Any}("X-Amzn-Client-Token" => string(uuid4()));
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function delete_model(
    modelVersion,
    projectName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return lookoutvision(
        "DELETE",
        "/2020-11-20/projects/$(projectName)/models/$(modelVersion)",
        Dict{String,Any}(
            mergewith(
                _merge, Dict{String,Any}("X-Amzn-Client-Token" => string(uuid4())), params
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Deletes an Amazon Lookout for Vision project. To delete a project, you must first delete
each version of the model associated with the project. To delete a model use the
DeleteModel operation. You also have to delete the dataset(s) associated with the model.
For more information, see DeleteDataset. The images referenced by the training and test
datasets aren't deleted.  This operation requires permissions to perform the
lookoutvision:DeleteProject operation.

# Arguments
- `project_name`: The name of the project to delete.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"X-Amzn-Client-Token"`: ClientToken is an idempotency token that ensures a call to
  DeleteProject completes only once. You choose the value to pass. For example, An issue
  might prevent you from getting a response from DeleteProject. In this case, safely retry
  your call to DeleteProject by using the same ClientToken parameter value.  If you don't
  supply a value for ClientToken, the AWS SDK you are using inserts a value for you. This
  prevents retries after a network error from making multiple project deletion requests.
  You'll need to provide your own value for other use cases.  An error occurs if the other
  input parameters are not the same as in the first request. Using a different value for
  ClientToken is considered a new call to DeleteProject. An idempotency token is active for 8
  hours.
"""
function delete_project(projectName; aws_config::AbstractAWSConfig=global_aws_config())
    return lookoutvision(
        "DELETE",
        "/2020-11-20/projects/$(projectName)",
        Dict{String,Any}("X-Amzn-Client-Token" => string(uuid4()));
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function delete_project(
    projectName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return lookoutvision(
        "DELETE",
        "/2020-11-20/projects/$(projectName)",
        Dict{String,Any}(
            mergewith(
                _merge, Dict{String,Any}("X-Amzn-Client-Token" => string(uuid4())), params
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    describe_dataset(dataset_type, project_name)
    describe_dataset(dataset_type, project_name, params::Dict{String,<:Any})

Describe an Amazon Lookout for Vision dataset. This operation requires permissions to
perform the lookoutvision:DescribeDataset operation.

# Arguments
- `dataset_type`: The type of the dataset to describe. Specify train to describe the
  training dataset. Specify test to describe the test dataset. If you have a single dataset
  project, specify train
- `project_name`: The name of the project that contains the dataset that you want to
  describe.

"""
function describe_dataset(
    datasetType, projectName; aws_config::AbstractAWSConfig=global_aws_config()
)
    return lookoutvision(
        "GET",
        "/2020-11-20/projects/$(projectName)/datasets/$(datasetType)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function describe_dataset(
    datasetType,
    projectName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return lookoutvision(
        "GET",
        "/2020-11-20/projects/$(projectName)/datasets/$(datasetType)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    describe_model(model_version, project_name)
    describe_model(model_version, project_name, params::Dict{String,<:Any})

Describes a version of an Amazon Lookout for Vision model. This operation requires
permissions to perform the lookoutvision:DescribeModel operation.

# Arguments
- `model_version`: The version of the model that you want to describe.
- `project_name`: The project that contains the version of a model that you want to
  describe.

"""
function describe_model(
    modelVersion, projectName; aws_config::AbstractAWSConfig=global_aws_config()
)
    return lookoutvision(
        "GET",
        "/2020-11-20/projects/$(projectName)/models/$(modelVersion)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function describe_model(
    modelVersion,
    projectName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return lookoutvision(
        "GET",
        "/2020-11-20/projects/$(projectName)/models/$(modelVersion)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    describe_model_packaging_job(job_name, project_name)
    describe_model_packaging_job(job_name, project_name, params::Dict{String,<:Any})

Describes an Amazon Lookout for Vision model packaging job.  This operation requires
permissions to perform the lookoutvision:DescribeModelPackagingJob operation. For more
information, see Using your Amazon Lookout for Vision model on an edge device in the Amazon
Lookout for Vision Developer Guide.

# Arguments
- `job_name`: The job name for the model packaging job.
- `project_name`: The name of the project that contains the model packaging job that you
  want to describe.

"""
function describe_model_packaging_job(
    jobName, projectName; aws_config::AbstractAWSConfig=global_aws_config()
)
    return lookoutvision(
        "GET",
        "/2020-11-20/projects/$(projectName)/modelpackagingjobs/$(jobName)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function describe_model_packaging_job(
    jobName,
    projectName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return lookoutvision(
        "GET",
        "/2020-11-20/projects/$(projectName)/modelpackagingjobs/$(jobName)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Describes an Amazon Lookout for Vision project. This operation requires permissions to
perform the lookoutvision:DescribeProject operation.

# Arguments
- `project_name`: The name of the project that you want to describe.

"""
function describe_project(projectName; aws_config::AbstractAWSConfig=global_aws_config())
    return lookoutvision(
        "GET",
        "/2020-11-20/projects/$(projectName)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function describe_project(
    projectName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return lookoutvision(
        "GET",
        "/2020-11-20/projects/$(projectName)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    detect_anomalies(body, content-_type, model_version, project_name)
    detect_anomalies(body, content-_type, model_version, project_name, params::Dict{String,<:Any})

Detects anomalies in an image that you supply.  The response from DetectAnomalies includes
a boolean prediction that the image contains one or more anomalies and a confidence value
for the prediction.  Before calling DetectAnomalies, you must first start your model with
the StartModel operation. You are charged for the amount of time, in minutes, that a model
runs and for the number of anomaly detection units that your model uses. If you are not
using a model, use the StopModel operation to stop your model.   This operation requires
permissions to perform the lookoutvision:DetectAnomalies operation.

# Arguments
- `body`: The unencrypted image bytes that you want to analyze.
- `content-_type`: The type of the image passed in Body. Valid values are image/png (PNG
  format images) and image/jpeg (JPG format images).
- `model_version`: The version of the model that you want to use.
- `project_name`: The name of the project that contains the model version that you want to
  use.

"""
function detect_anomalies(
    Body,
    Content_Type,
    modelVersion,
    projectName;
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return lookoutvision(
        "POST",
        "/2020-11-20/projects/$(projectName)/models/$(modelVersion)/detect",
        Dict{String,Any}(
            "Body" => Body, "headers" => Dict{String,Any}("Content-Type" => Content_Type)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function detect_anomalies(
    Body,
    Content_Type,
    modelVersion,
    projectName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return lookoutvision(
        "POST",
        "/2020-11-20/projects/$(projectName)/models/$(modelVersion)/detect",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "Body" => Body,
                    "headers" => Dict{String,Any}("Content-Type" => Content_Type),
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    list_dataset_entries(dataset_type, project_name)
    list_dataset_entries(dataset_type, project_name, params::Dict{String,<:Any})

Lists the JSON Lines within a dataset. An Amazon Lookout for Vision JSON Line contains the
anomaly information for a single image, including the image location and the assigned
label. This operation requires permissions to perform the lookoutvision:ListDatasetEntries
operation.

# Arguments
- `dataset_type`: The type of the dataset that you want to list. Specify train to list the
  training dataset. Specify test to list the test dataset. If you have a single dataset
  project, specify train.
- `project_name`: The name of the project that contains the dataset that you want to list.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"anomalyClass"`: Specify normal to include only normal images. Specify anomaly to only
  include anomalous entries. If you don't specify a value, Amazon Lookout for Vision returns
  normal and anomalous images.
- `"createdAfter"`: Only includes entries after the specified date in the response. For
  example, 2020-06-23T00:00:00.
- `"createdBefore"`: Only includes entries before the specified date in the response. For
  example, 2020-06-23T00:00:00.
- `"labeled"`: Specify true to include labeled entries, otherwise specify false. If you
  don't specify a value, Lookout for Vision returns all entries.
- `"maxResults"`: The maximum number of results to return per paginated call. The largest
  value you can specify is 100. If you specify a value greater than 100, a
  ValidationException error occurs. The default value is 100.
- `"nextToken"`: If the previous response was incomplete (because there is more data to
  retrieve), Amazon Lookout for Vision returns a pagination token in the response. You can
  use this pagination token to retrieve the next set of dataset entries.
- `"sourceRefContains"`: Perform a \"contains\" search on the values of the source-ref key
  within the dataset. For example a value of \"IMG_17\" returns all JSON Lines where the
  source-ref key value matches *IMG_17*.
"""
function list_dataset_entries(
    datasetType, projectName; aws_config::AbstractAWSConfig=global_aws_config()
)
    return lookoutvision(
        "GET",
        "/2020-11-20/projects/$(projectName)/datasets/$(datasetType)/entries";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_dataset_entries(
    datasetType,
    projectName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return lookoutvision(
        "GET",
        "/2020-11-20/projects/$(projectName)/datasets/$(datasetType)/entries",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

 Lists the model packaging jobs created for an Amazon Lookout for Vision project.  This
operation requires permissions to perform the lookoutvision:ListModelPackagingJobs
operation.  For more information, see Using your Amazon Lookout for Vision model on an edge
device in the Amazon Lookout for Vision Developer Guide.

# Arguments
- `project_name`:  The name of the project for which you want to list the model packaging
  jobs.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: The maximum number of results to return per paginated call. The largest
  value you can specify is 100. If you specify a value greater than 100, a
  ValidationException error occurs. The default value is 100.
- `"nextToken"`: If the previous response was incomplete (because there is more results to
  retrieve), Amazon Lookout for Vision returns a pagination token in the response. You can
  use this pagination token to retrieve the next set of results.
"""
function list_model_packaging_jobs(
    projectName; aws_config::AbstractAWSConfig=global_aws_config()
)
    return lookoutvision(
        "GET",
        "/2020-11-20/projects/$(projectName)/modelpackagingjobs";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_model_packaging_jobs(
    projectName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return lookoutvision(
        "GET",
        "/2020-11-20/projects/$(projectName)/modelpackagingjobs",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Lists the versions of a model in an Amazon Lookout for Vision project. The ListModels
operation is eventually consistent. Recent calls to CreateModel might take a while to
appear in the response from ListProjects. This operation requires permissions to perform
the lookoutvision:ListModels operation.

# Arguments
- `project_name`: The name of the project that contains the model versions that you want to
  list.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: The maximum number of results to return per paginated call. The largest
  value you can specify is 100. If you specify a value greater than 100, a
  ValidationException error occurs. The default value is 100.
- `"nextToken"`: If the previous response was incomplete (because there is more data to
  retrieve), Amazon Lookout for Vision returns a pagination token in the response. You can
  use this pagination token to retrieve the next set of models.
"""
function list_models(projectName; aws_config::AbstractAWSConfig=global_aws_config())
    return lookoutvision(
        "GET",
        "/2020-11-20/projects/$(projectName)/models";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_models(
    projectName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return lookoutvision(
        "GET",
        "/2020-11-20/projects/$(projectName)/models",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Lists the Amazon Lookout for Vision projects in your AWS account. The ListProjects
operation is eventually consistent. Recent calls to CreateProject and DeleteProject might
take a while to appear in the response from ListProjects. This operation requires
permissions to perform the lookoutvision:ListProjects operation.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: The maximum number of results to return per paginated call. The largest
  value you can specify is 100. If you specify a value greater than 100, a
  ValidationException error occurs. The default value is 100.
- `"nextToken"`: If the previous response was incomplete (because there is more data to
  retrieve), Amazon Lookout for Vision returns a pagination token in the response. You can
  use this pagination token to retrieve the next set of projects.
"""
function list_projects(; aws_config::AbstractAWSConfig=global_aws_config())
    return lookoutvision(
        "GET",
        "/2020-11-20/projects";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_projects(
    params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return lookoutvision(
        "GET",
        "/2020-11-20/projects",
        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})

Returns a list of tags attached to the specified Amazon Lookout for Vision model. This
operation requires permissions to perform the lookoutvision:ListTagsForResource operation.

# Arguments
- `resource_arn`: The Amazon Resource Name (ARN) of the model for which you want to list
  tags.

"""
function list_tags_for_resource(
    resourceArn; aws_config::AbstractAWSConfig=global_aws_config()
)
    return lookoutvision(
        "GET",
        "/2020-11-20/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 lookoutvision(
        "GET",
        "/2020-11-20/tags/$(resourceArn)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    start_model(min_inference_units, model_version, project_name)
    start_model(min_inference_units, model_version, project_name, params::Dict{String,<:Any})

Starts the running of the version of an Amazon Lookout for Vision model. Starting a model
takes a while to complete. To check the current state of the model, use DescribeModel. A
model is ready to use when its status is HOSTED. Once the model is running, you can detect
custom labels in new images by calling DetectAnomalies.  You are charged for the amount of
time that the model is running. To stop a running model, call StopModel.  This operation
requires permissions to perform the lookoutvision:StartModel operation.

# Arguments
- `min_inference_units`: The minimum number of inference units to use. A single inference
  unit represents 1 hour of processing. Use a higher number to increase the TPS throughput of
  your model. You are charged for the number of inference units that you use.
- `model_version`: The version of the model that you want to start.
- `project_name`: The name of the project that contains the model that you want to start.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"X-Amzn-Client-Token"`: ClientToken is an idempotency token that ensures a call to
  StartModel completes only once. You choose the value to pass. For example, An issue might
  prevent you from getting a response from StartModel. In this case, safely retry your call
  to StartModel by using the same ClientToken parameter value.  If you don't supply a value
  for ClientToken, the AWS SDK you are using inserts a value for you. This prevents retries
  after a network error from making multiple start requests. You'll need to provide your own
  value for other use cases.  An error occurs if the other input parameters are not the same
  as in the first request. Using a different value for ClientToken is considered a new call
  to StartModel. An idempotency token is active for 8 hours.
"""
function start_model(
    MinInferenceUnits,
    modelVersion,
    projectName;
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return lookoutvision(
        "POST",
        "/2020-11-20/projects/$(projectName)/models/$(modelVersion)/start",
        Dict{String,Any}(
            "MinInferenceUnits" => MinInferenceUnits,
            "X-Amzn-Client-Token" => string(uuid4()),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function start_model(
    MinInferenceUnits,
    modelVersion,
    projectName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return lookoutvision(
        "POST",
        "/2020-11-20/projects/$(projectName)/models/$(modelVersion)/start",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "MinInferenceUnits" => MinInferenceUnits,
                    "X-Amzn-Client-Token" => string(uuid4()),
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    start_model_packaging_job(configuration, model_version, project_name)
    start_model_packaging_job(configuration, model_version, project_name, params::Dict{String,<:Any})

Starts an Amazon Lookout for Vision model packaging job. A model packaging job creates an
AWS IoT Greengrass component for a Lookout for Vision model. You can use the component to
deploy your model to an edge device managed by Greengrass.  Use the
DescribeModelPackagingJob API to determine the current status of the job. The model
packaging job is complete if the value of Status is SUCCEEDED. To deploy the component to
the target device, use the component name and component version with the AWS IoT Greengrass
CreateDeployment API. This operation requires the following permissions:
lookoutvision:StartModelPackagingJobs     s3:PutObject     s3:GetBucketLocation
greengrass:CreateComponentVersion     greengrass:DescribeComponent    (Optional)
greengrass:TagResource. Only required if you want to tag the component.   For more
information, see Using your Amazon Lookout for Vision model on an edge device in the Amazon
Lookout for Vision Developer Guide.

# Arguments
- `configuration`: The configuration for the model packaging job.
- `model_version`:  The version of the model within the project that you want to package.
- `project_name`:  The name of the project which contains the version of the model that you
  want to package.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"Description"`: A description for the model packaging job.
- `"JobName"`: A name for the model packaging job. If you don't supply a value, the service
  creates a job name for you.
- `"X-Amzn-Client-Token"`: ClientToken is an idempotency token that ensures a call to
  StartModelPackagingJob completes only once. You choose the value to pass. For example, An
  issue might prevent you from getting a response from StartModelPackagingJob. In this case,
  safely retry your call to StartModelPackagingJob by using the same ClientToken parameter
  value. If you don't supply a value for ClientToken, the AWS SDK you are using inserts a
  value for you. This prevents retries after a network error from making multiple dataset
  creation requests. You'll need to provide your own value for other use cases.  An error
  occurs if the other input parameters are not the same as in the first request. Using a
  different value for ClientToken is considered a new call to StartModelPackagingJob. An
  idempotency token is active for 8 hours.
"""
function start_model_packaging_job(
    Configuration,
    ModelVersion,
    projectName;
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return lookoutvision(
        "POST",
        "/2020-11-20/projects/$(projectName)/modelpackagingjobs",
        Dict{String,Any}(
            "Configuration" => Configuration,
            "ModelVersion" => ModelVersion,
            "X-Amzn-Client-Token" => string(uuid4()),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function start_model_packaging_job(
    Configuration,
    ModelVersion,
    projectName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return lookoutvision(
        "POST",
        "/2020-11-20/projects/$(projectName)/modelpackagingjobs",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "Configuration" => Configuration,
                    "ModelVersion" => ModelVersion,
                    "X-Amzn-Client-Token" => string(uuid4()),
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    stop_model(model_version, project_name)
    stop_model(model_version, project_name, params::Dict{String,<:Any})

Stops the hosting of a running model. The operation might take a while to complete. To
check the current status, call DescribeModel.  After the model hosting stops, the Status of
the model is TRAINED. This operation requires permissions to perform the
lookoutvision:StopModel operation.

# Arguments
- `model_version`: The version of the model that you want to stop.
- `project_name`: The name of the project that contains the model that you want to stop.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"X-Amzn-Client-Token"`: ClientToken is an idempotency token that ensures a call to
  StopModel completes only once. You choose the value to pass. For example, An issue might
  prevent you from getting a response from StopModel. In this case, safely retry your call to
  StopModel by using the same ClientToken parameter value. If you don't supply a value for
  ClientToken, the AWS SDK you are using inserts a value for you. This prevents retries after
  a network error from making multiple stop requests. You'll need to provide your own value
  for other use cases.  An error occurs if the other input parameters are not the same as in
  the first request. Using a different value for ClientToken is considered a new call to
  StopModel. An idempotency token is active for 8 hours.
"""
function stop_model(
    modelVersion, projectName; aws_config::AbstractAWSConfig=global_aws_config()
)
    return lookoutvision(
        "POST",
        "/2020-11-20/projects/$(projectName)/models/$(modelVersion)/stop",
        Dict{String,Any}("X-Amzn-Client-Token" => string(uuid4()));
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function stop_model(
    modelVersion,
    projectName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return lookoutvision(
        "POST",
        "/2020-11-20/projects/$(projectName)/models/$(modelVersion)/stop",
        Dict{String,Any}(
            mergewith(
                _merge, Dict{String,Any}("X-Amzn-Client-Token" => string(uuid4())), params
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Adds one or more key-value tags to an Amazon Lookout for Vision model. For more
information, see Tagging a model in the Amazon Lookout for Vision Developer Guide.  This
operation requires permissions to perform the lookoutvision:TagResource operation.

# Arguments
- `tags`: The key-value tags to assign to the model.
- `resource_arn`: The Amazon Resource Name (ARN) of the model to assign the tags.

"""
function tag_resource(Tags, resourceArn; aws_config::AbstractAWSConfig=global_aws_config())
    return lookoutvision(
        "POST",
        "/2020-11-20/tags/$(resourceArn)",
        Dict{String,Any}("Tags" => Tags);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function tag_resource(
    Tags,
    resourceArn,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return lookoutvision(
        "POST",
        "/2020-11-20/tags/$(resourceArn)",
        Dict{String,Any}(mergewith(_merge, Dict{String,Any}("Tags" => Tags), 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})

Removes one or more tags from an Amazon Lookout for Vision model. For more information, see
Tagging a model in the Amazon Lookout for Vision Developer Guide.  This operation requires
permissions to perform the lookoutvision:UntagResource operation.

# Arguments
- `resource_arn`: The Amazon Resource Name (ARN) of the model from which you want to remove
  tags.
- `tag_keys`: A list of the keys of the tags that you want to remove.

"""
function untag_resource(
    resourceArn, tagKeys; aws_config::AbstractAWSConfig=global_aws_config()
)
    return lookoutvision(
        "DELETE",
        "/2020-11-20/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 lookoutvision(
        "DELETE",
        "/2020-11-20/tags/$(resourceArn)",
        Dict{String,Any}(mergewith(_merge, Dict{String,Any}("tagKeys" => tagKeys), params));
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    update_dataset_entries(changes, dataset_type, project_name)
    update_dataset_entries(changes, dataset_type, project_name, params::Dict{String,<:Any})

Adds or updates one or more JSON Line entries in a dataset. A JSON Line includes
information about an image used for training or testing an Amazon Lookout for Vision model.
To update an existing JSON Line, use the source-ref field to identify the JSON Line. The
JSON line that you supply replaces the existing JSON line. Any existing annotations that
are not in the new JSON line are removed from the dataset.  For more information, see
Defining JSON lines for anomaly classification in the Amazon Lookout for Vision Developer
Guide.   The images you reference in the source-ref field of a JSON line, must be in the
same S3 bucket as the existing images in the dataset.   Updating a dataset might take a
while to complete. To check the current status, call DescribeDataset and check the Status
field in the response. This operation requires permissions to perform the
lookoutvision:UpdateDatasetEntries operation.

# Arguments
- `changes`: The entries to add to the dataset.
- `dataset_type`: The type of the dataset that you want to update. Specify train to update
  the training dataset. Specify test to update the test dataset. If you have a single dataset
  project, specify train.
- `project_name`: The name of the project that contains the dataset that you want to update.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"X-Amzn-Client-Token"`: ClientToken is an idempotency token that ensures a call to
  UpdateDatasetEntries completes only once. You choose the value to pass. For example, An
  issue might prevent you from getting a response from UpdateDatasetEntries. In this case,
  safely retry your call to UpdateDatasetEntries by using the same ClientToken parameter
  value. If you don't supply a value for ClientToken, the AWS SDK you are using inserts a
  value for you. This prevents retries after a network error from making multiple updates
  with the same dataset entries. You'll need to provide your own value for other use cases.
  An error occurs if the other input parameters are not the same as in the first request.
  Using a different value for ClientToken is considered a new call to UpdateDatasetEntries.
  An idempotency token is active for 8 hours.
"""
function update_dataset_entries(
    Changes, datasetType, projectName; aws_config::AbstractAWSConfig=global_aws_config()
)
    return lookoutvision(
        "PATCH",
        "/2020-11-20/projects/$(projectName)/datasets/$(datasetType)/entries",
        Dict{String,Any}("Changes" => Changes, "X-Amzn-Client-Token" => string(uuid4()));
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function update_dataset_entries(
    Changes,
    datasetType,
    projectName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return lookoutvision(
        "PATCH",
        "/2020-11-20/projects/$(projectName)/datasets/$(datasetType)/entries",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "Changes" => Changes, "X-Amzn-Client-Token" => string(uuid4())
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end


text:
function rail_coords(mapf::MAPF)
    g::FlatlandGraph = mapf.graph

    P1 = Dict(NORTH => (0, -0.5), EAST => (-0.5, 0), SOUTH => (0, 0.5), WEST => (0.5, 0))
    P2 = Dict(NORTH => (0, -0.3), EAST => (-0.3, 0), SOUTH => (0, 0.3), WEST => (0.3, 0))
    P3 = Dict(NORTH => (0, 0.3), EAST => (0.3, 0), SOUTH => (0, -0.3), WEST => (-0.3, 0))
    P4 = Dict(NORTH => (0, 0.5), EAST => (0.5, 0), SOUTH => (0, -0.5), WEST => (-0.5, 0))

    grid = get_grid(g)
    h, w = size(grid)
    X_lines, Y_lines = Float64[], Float64[]
    X_limits, Y_limits = Float64[], Float64[]
    X_stations, Y_stations = Float64[], Float64[]

    station_vertices = union(mapf.sources, mapf.destinations)
    station_coords = [get_label(g, v)[1:2] for v in station_vertices]

    for i in 1:h, j in 1:w
        cell = grid[i, j]
        if cell > 0
            transition_map = bitstring(cell)
            for direction in CARDINAL_POINTS, destination in CARDINAL_POINTS
                if transition_exists(transition_map, direction, destination)
                    p1, p2 = P1[direction], P2[direction]
                    p3, p4 = P3[destination], P4[destination]
                    X_cell = [p1[1], p2[1], p3[1], p4[1], NaN]
                    Y_cell = [p1[2], p2[2], p3[2], p4[2], NaN]

                    append!(X_lines, j .+ X_cell)
                    append!(Y_lines, (h - i + 1) .+ Y_cell)

                    append!(X_limits, j .+ X_cell[[1, end - 1]])
                    append!(Y_limits, (h - i + 1) .+ Y_cell[[1, end - 1]])
                end
            end

            if (i, j) in station_coords
                append!(X_stations, j .+ 0.7 * [-0.5, 0.5, 0.5, -0.5, -0.5, NaN])
                append!(Y_stations, (h - i + 1) .+ 0.7 * [-0.5, -0.5, 0.5, 0.5, -0.5, NaN])
            end
        end
    end
    return (X_lines, Y_lines), (X_limits, Y_limits), (X_stations, Y_stations)
end

function flatland_agent_coords(mapf::MAPF, solution::Solution, t::Integer)
    g::FlatlandGraph = mapf.graph
    h, w = get_height(g), get_width(g)
    XY = Tuple{Float64,Float64}[]
    M, A = Symbol[], Int[]

    for a in 1:length(solution)
        path = solution[a]
        for (s, v) in path
            if s == t
                i, j, direction, kind = get_label(g, v)
                if kind == REAL
                    x, y = j, h - i + 1
                    if direction == NORTH
                        m = :utriangle
                    elseif direction == EAST
                        m = :rtriangle
                    elseif direction == SOUTH
                        m = :dtriangle
                    elseif direction == WEST
                        m = :ltriangle
                    else
                        m = :xcross
                    end

                    push!(A, a)
                    push!(XY, (x, y))
                    push!(M, m)
                end
            end
        end
    end

    return A, XY, M
end

function add_agents!(ax)
    A = Observable(Int[])
    XY = Observable(Point2f[])
    M = Observable(Symbol[])
    scatter!(ax, XY; marker=:rect, color=:red, markersize=30)
    scatter!(ax, XY; marker=M, color="white", markersize=15)
    text!(ax, @lift(string.($A)); position=XY, color="black", align=(:center, :center))
    return A, XY, M
end

function plot_flatland_graph(mapf::MAPF)
    g::FlatlandGraph = mapf.graph
    xy_lines, xy_limits, xy_stations = rail_coords(mapf)
    h, w = get_height(g), get_width(g)
    fig = Figure(; figure_padding=1)
    ax = GLMakie.Axis(fig[1, 1]; xticks=1:w, yticks=(1:h, string.(h:-1:1)))
    Makie.lines!(ax, xy_lines...; color="black")
    ax.aspect = DataAspect()
    scatter!(ax, xy_limits...; color="black", marker=:cross)
    Makie.lines!(ax, xy_stations...; color="black")
    colsize!(fig.layout, 1, Aspect(1, 1.0))
    resize_to_layout!(fig)
    A, XY, M = add_agents!(ax)
    return fig, (A, XY, M)
end


text:
ENV["PYTHON"] = "/usr/bin/python3"
using PyCall
using PartsBasedDetector: make_estimator, estimate

filename = "dress.jpg"
url = "http://images0.chictopia.com/photos/districtofchic/9466442894/" *
      "black-skinny-jeans-dl1961-jeans-sky-blue-pixie-market-shirt_400.jpg"

filename_png = replace(filename, ".jpg", ".png")
run(`wget --continue $url -O $filename`)
run(`convert $filename $filename_png`)

estimator = make_estimator()
candidates = estimate(estimator, filename, n_candidates = 3)
parts = candidates[1].parts
x, y = parts[:, 1], parts[:, 2]

@pyimport matplotlib.pyplot as plt
image = plt.imread(filename_png)
plt.imshow(image)
plt.plot(x, y, color="r", marker="o", ls="")

for i in 1:size(parts, 1)
    plt.annotate(i, (x[i], y[i]), color="w")
end

plt.show()


text:
module DeepShiba
    include("core/core_structures.jl")
    include("core/core_functions.jl")
    include("utils/output_txt.jl")
    include("utils/plot.jl")
    include("functions/math_functions.jl")
    include("functions/trans_functions.jl")
    export Variable, Func, variable, @variable, backward!, numerical_diff, cleargrad!, show, +, -, *, /, reshape, sin, cos, tanh, plot
end


text:
"""
A `Cluster` specifies a collection of `edges` adjacent to `node` that belong to the same
`PosteriorFactor`. A joint marginal can be computed over a cluster.
"""
mutable struct Cluster <: Region
    id::Symbol
    node::FactorNode
    edges::Vector{Edge}

    function Cluster(node::FactorNode, edges::Vector{Edge})
        id = Symbol(join([edge.variable.id for edge in edges], "_"))
        self = new(id, node, edges)
        return self
    end
end

Base.isless(c1::Cluster, c2::Cluster) = isless("$(c1.id)", "$(c2.id)")
Base.isless(v::Variable, c::Cluster) = isless("$(v.id)", "$(c.id)")
Base.isless(c::Cluster, v::Variable) = isless("$(c.id)", "$(v.id)")

"""
Return the region that the node-edge combination belongs to (if available)
"""
function region(node::FactorNode, edge::Edge)
    dict = current_posterior_factorization.node_edge_to_cluster
    if haskey(dict, (node, edge))
        cl = dict[(node, edge)]
    else # No cluster is registered, return the edge variable
        cl = edge.variable
    end

    return cl::Region
end


text:
# JuLIP.jl master file.

module JuLIP

using Reexport

export Atoms

# TODO: correctly use import versus using throughout this package!

# quickly switch between Matrices and Vectors of Vecs
include("arrayconversions.jl")

# define types and abstractions of generic functions
include("abstractions.jl")

# a few auxiliary routines
include("utils.jl")

# implementation of some key functionality via ASE
include("ASE.jl")

# define the default atoms object
"""
`type Atoms`

Technically not a type but a type-alias, to possibly allow different "backends".
At the moment, `Atoms = ASE.ASEAtoms`; see its help for more details.
This will likely remain for the foreseeable future.
"""
typealias Atoms ASE.ASEAtoms

# only try to import Visualise, it is not needed for the rest to work.
try
   # some visualisation options
   include("Visualise.jl")
catch
   warn("""JuLIP.Visualise did not import correctly, probably because
               `imolecule` is not correctly installed.""")
end

# submodule JuLIP.Constraints
include("Constraints.jl")
@reexport using JuLIP.Constraints

# interatomic potentials prototypes and some example implementations
include("Potentials.jl")

# basic preconditioning capabilities
include("preconditioners.jl")

# some solvers
include("Solve.jl")
@reexport using JuLIP.Solve

# codes to facilitate testing
include("Testing.jl")

end # module


text:
function get_ephemeris_spice(t::ASCIIString)
  get_ephemeris_spice([DateTime(t)])
end

function get_ephemeris_spice(t::DateTime)
  get_ephemeris_spice([t])
end

function get_eph(tt::Vector{DateTime})
  gc_enable(false)
  furnsh("/home/abieler/rosetta/spiceKernels/metafiles/operationalKernels.tm")
  for t in tt
    tStr = string(t)
    et = utc2et(tStr)
  end
  gc_enable(true)
end

function get_ephemeris_spice(tt::Vector{DateTime})
  furnsh("/home/abieler/rosetta/spiceKernels/metafiles/operationalKernels.tm")
  N = length(tt)
  objectName = "ROSETTA"
  CG_ID = 1000012
  frame = "67P/C-G_CK"
  observer = "CHURYUMOV-GERASIMENKO"
  km2AU = 6.68458712 * 1e-9
  rotAxis = [0.0,0.0,1.0]
  pCenter = zeros(Float64, 3)
  lon = zeros(Float64, N)
  lat = zeros(Float64, N)
  localHourFloat = zeros(Float64, N)
  xSC = zeros(Float64, N)
  ySC = zeros(Float64, N)
  zSC = zeros(Float64, N)
  xSUN = zeros(Float64, N)
  ySUN = zeros(Float64, N)
  zSUN = zeros(Float64, N)
  lonSunArr = zeros(Float64, N)
  latSunArr = zeros(Float64, N)
  lonSC_cso = zeros(Float64, N)
  latSC_cso = zeros(Float64, N)
  heliocentricDistance = zeros(Float64, N)
  heliocentricDistance_AU = zeros(Float64, N)
  cometocentricDistance = zeros(Float64, N)
  phaseAngle = zeros(Float64, N)
  offNadirAngle = zeros(Float64, N)
  et = 0.0
  gc_enable(false)
  for (i,t) in enumerate(tt)
    timeStamp = string(t)
    et = utc2et(timeStamp)
    r_SC, lt = spkpos("ROSETTA", et, "67P/C-G_CK", "NONE", observer)
    r_SUN, lt = spkpos("SUN", et, "67P/C-G_CK", "NONE", observer)
    r_CG, lt = spkpos("67P/C-G", et, "ROS_VIRTIS-H", "NONE", "ROSETTA")
    r_SC_cso, lt = spkpos("ROSETTA", et, "67P/C-G_CSO", "NONE", observer)

    cometocentricDistance[i] = norm(r_SC)
    heliocentricDistance[i] = norm(r_SUN)
    heliocentricDistance_AU[i] = heliocentricDistance[i] * km2AU

    r_SC_hat = r_SC ./ cometocentricDistance[i]
    r_SUN_hat = r_SUN ./ heliocentricDistance[i]

    pA = vsep(r_SC, r_SUN)
    oNA = vsep(r_CG, rotAxis)
    phaseAngle[i] = pA / pi * 180.0
    offNadirAngle[i] = oNA / pi * 180.0

    xSC[i] = r_SC[1]
    ySC[i] = r_SC[2]
    zSC[i] = r_SC[3]
    xSUN[i] = r_SUN[1]
    ySUN[i] = r_SUN[2]
    zSUN[i] = r_SUN[3]

    r, llon, llat = reclat(r_SC)
    llon = llon / pi * 180.0
    llat = llat / pi * 180.0
    lon[i] = llon
    lat[i] = llat

    rSun, lonSun, latSun = reclat(r_SUN)
    lonSun = lonSun / pi * 180
    latSun = latSun / pi * 180
    lonSunArr[i] = lonSun
    latSunArr[i] = latSun

    rr, lon_cso, lat_cso = reclat(r_SC_cso)
    lon_cso = lon_cso / pi * 180
    lat_cso = lat_cso / pi * 180
    lonSC_cso[i] = lon_cso
    latSC_cso[i] = lat_cso

    deltaLongitude = (((llon - lonSun) + 180) % 360) - 180
    localHour = 12 + (deltaLongitude / 180.0 * 12.0)
    localHourFloat[i] = localHour
    localMin = round(Int, floor(localHour % 1 * 60))
    localSec = round(Int, (localHour % 1 * 60) % 1 * 60)
    localHour = round(Int, floor(localHour))
  end
  gc_enable(true)

  df = DataFrame()
  df[:date] = tt
  df[:localHourFloat] = localHourFloat
  df[:rSC_km] = cometocentricDistance
  df[:rSUN_km] = heliocentricDistance
  df[:rSUN_AU] = heliocentricDistance_AU
  df[:lonSC_deg] = lon
  df[:latSC_deg] = lat
  df[:lonSUN_deg] = lonSunArr
  df[:latSUN_deg] = latSunArr
  df[:lonSC_cso_deg] = lonSC_cso
  df[:latSC_cso_deg] = latSC_cso
  df[:phaseAngle_deg] = phaseAngle
  df[:offNadirAngle_deg] = offNadirAngle
  df[:xSC_km] = xSC
  df[:ySC_km] = ySC
  df[:zSC_km] = zSC
  df[:xSUN_km] = xSUN
  df[:ySUN_km] = ySUN
  df[:zSUN_km] = zSUN

  return df
end


text:
using Adapt
using Statistics
using KernelAbstractions: @kernel, @index, Event
using Oceananigans.Grids
using Oceananigans.BoundaryConditions: fill_halo_regions!

struct ComputedField{X, Y, Z, S, O, A, D, G, T, C} <: AbstractDataField{X, Y, Z, A, G, T}
                   data :: D
           architecture :: A
                   grid :: G
                operand :: O
    boundary_conditions :: C
                 status :: S

    function ComputedField{X, Y, Z}(data::D,
                                    arch::A,
                                    grid::G,
                                    operand::O,
                                    boundary_conditions::C;
                                    recompute_safely=true) where {X, Y, Z, D, A, G, O, C}

        validate_field_data(X, Y, Z, data, grid)

        # Use FieldStatus if we want to avoid always recomputing
        status = recompute_safely ? nothing : FieldStatus(0.0)

        S = typeof(status)
        T = eltype(grid)

        return new{X, Y, Z, S, O, A, D, G, T, C}(data, arch, grid, operand, boundary_conditions, status)
    end
end

# We define special default boundary conditions for ComputedField, because currently
# `DefaultBoundaryCondition` uses ImpenetrableBoundaryCondition() in bounded directions
# and for fields on Faces, which is not what we want in general for ComputedFields.
DefaultComputedFieldBoundaryCondition(::Type{Grids.Periodic}, loc) = PeriodicBoundaryCondition()
DefaultComputedFieldBoundaryCondition(::Type{Flat}, loc) = nothing
DefaultComputedFieldBoundaryCondition(::Type{Bounded}, ::Type{Center}) = NoFluxBoundaryCondition()
DefaultComputedFieldBoundaryCondition(::Type{Bounded}, ::Type{Face}) = nothing

function ComputedFieldBoundaryConditions(grid, loc;
                                           east = DefaultComputedFieldBoundaryCondition(topology(grid, 1), loc[1]),
                                           west = DefaultComputedFieldBoundaryCondition(topology(grid, 1), loc[1]),
                                          south = DefaultComputedFieldBoundaryCondition(topology(grid, 2), loc[2]),
                                          north = DefaultComputedFieldBoundaryCondition(topology(grid, 2), loc[2]),
                                         bottom = DefaultComputedFieldBoundaryCondition(topology(grid, 3), loc[3]),
                                            top = DefaultComputedFieldBoundaryCondition(topology(grid, 3), loc[3]))

    return FieldBoundaryConditions(grid, loc; east=east, west=west, south=south, north=north, bottom=bottom, top=top)
end

"""
    ComputedField(operand [, arch=nothing]; data = nothing, recompute_safely = true,
                  boundary_conditions = ComputedFieldBoundaryConditions(operand.grid, location(operand))

Returns a field whose data is `computed` from `operand`. If `arch`itecture is not supplied it
is inferred from `operand`.

If the keyword argument `data` is not provided, memory is allocated to store
the result. The `arch`itecture of `data` is inferred from `operand`.

If `data` is provided and `recompute_safely=false`, then "recomputation" of the `ComputedField`
is avoided if possible.
"""
function ComputedField(operand, arch=nothing; kwargs...)

    loc = location(operand)
    grid = operand.grid

    return ComputedField(loc..., operand, arch, grid; kwargs...)
end

function ComputedField(LX, LY, LZ, operand, arch, grid;
                       data = nothing,
                       recompute_safely = true,
                       boundary_conditions = ComputedFieldBoundaryConditions(grid, (LX, LY, LZ)))

    # Architecturanigans
    operand_arch = architecture(operand)
    arch = isnothing(operand_arch) ? arch : operand_arch
    isnothing(arch) && error("The architecture must be provided, or inferrable from `operand`!")

    if isnothing(data)
        data = new_data(arch, grid, (LX, LY, LZ))
        recompute_safely = false
    end

    return ComputedField{LX, LY, LZ}(data, arch, grid, operand, boundary_conditions; recompute_safely=recompute_safely)
end

"""
    compute!(comp::ComputedField)

Compute `comp.operand` and store the result in `comp.data`.
"""
function compute!(comp::ComputedField{LX, LY, LZ}, time=nothing) where {LX, LY, LZ}
    compute_at!(comp.operand, time) # ensures any 'dependencies' of the computation are computed first

    arch = architecture(comp)

    workgroup, worksize = work_layout(comp.grid,
                                      :xyz,
                                      include_right_boundaries=true,
                                      location=(LX, LY, LZ))

    compute_kernel! = _compute!(device(arch), workgroup, worksize)

    event = compute_kernel!(comp.data, comp.operand; dependencies=Event(device(arch)))

    wait(device(arch), event)

    fill_halo_regions!(comp, arch)

    return nothing
end

compute_at!(field::ComputedField{LX, LY, LZ, <:FieldStatus}, time) where {LX, LY, LZ} =
    conditional_compute!(field, time)

"""Compute an `operand` and store in `data`."""
@kernel function _compute!(data, operand)
    i, j, k = @index(Global, NTuple)
    @inbounds data[i, j, k] = operand[i, j, k]
end

#####
##### Adapt
#####

Adapt.adapt_structure(to, computed_field::ComputedField) = Adapt.adapt(to, computed_field.data)


text:
using HorizonSideRobots
include("../basics.jl")

md"""
    ДАНО: Робот находится в произвольной клетке ограниченного прямоугольного поля без внутренних перегородок и маркеров.

    РЕЗУЛЬТАТ: Робот — в исходном положении в центре прямого креста из маркеров, расставленных вплоть до внешней рамки.

    Рассмотреть отдельно еще случай, когда изначально в некоторых клетках поля могут находиться маркеры.
"""

"""Аналогично {move!}, но маркирует (немаркированные) клетки по дороге."""
function go_and_mark!(r, side)
    move!(r, side)
    putmarker!(r)
 end

 """Двигает робота до границы поля в сторону {side}, маркируя клетки по пути, после чего возвращает его в точку старта"""
 function mark_till_border!(r, side)
     while isborder(r, side) == 0
         go_and_mark!(r, side)
     end
     while ismarker(r)
         move!(r, opposite_side(side))
     end
 end

  """Решение задачи 1"""
 function solve_problem_1!(r)
    for side in [Nord, Ost, Sud, West]
        mark_till_border!(r, side)
     end
     putmarker!(r)
     show(r)
 end

md"""
        Cлучай, когда изначально в некоторых клетках поля могут находиться маркеры.
"""

"""Решение задачи 1; работает не только с маркерами, но и барьерами"""
 function solve_problem_1_wth_barriers_and_markers!(r)
    visited = Set()
    (M, N), (I, J) = get_field_size_and_position!(r)
    cells = Set()

    for i in 1:M
        push!(cells, (i, J))
    end
    for j in 1:N
        push!(cells, (I, j))
    end

    mark_some_cells_with_dfs!(r, visited, (I, J), false, cells)

    show(r)
end


text:
# Julia script to map quartets on one network
# to quartets in a different network
# Claudia February 2022

function mapNright2Ndown(n)
    length(n) == 4 || error("n should correspond to a quartet and should have length of 4")
    return [n[3],n[1],n[4],n[2]]
end

max_stars_repo_name: gtiley/bad-diamonds

max_issues_repo_name: gtiley/diamond-identifiability

max_forks_repo_name: gtiley/diamond-identifiability


text:
##==============================================================================
# deprecation staging area
##==============================================================================
##==============================================================================
## Deprecated in v0.9 Remove in the v0.10 cycle
##==============================================================================

Base.promote_rule(::Type{DateTime}, ::Type{ZonedDateTime}) = DateTime
function Base.convert(::Type{DateTime}, ts::ZonedDateTime)
    @warn "DFG now uses ZonedDateTime, temporary promoting and converting to DateTime local time"
    return DateTime(ts, Local)
end

@deprecate listSolvekeys(x...) listSolveKeys(x...)

##==============================================================================
## Deprecated in v0.10 Remove in 0.11
##==============================================================================

@deprecate getMaxPPE(est::AbstractPointParametricEst) getPPEMax(est)
@deprecate getMeanPPE(est::AbstractPointParametricEst) getPPEMean(est)
@deprecate getSuggestedPPE(est::AbstractPointParametricEst) getPPESuggested(est)

@deprecate addVariableSolverData!(dfg::AbstractDFG, variablekey::Symbol, vnd::VariableNodeData, solveKey::Symbol) addVariableSolverData!(dfg, variablekey, vnd)

@deprecate updatePPE!(dfg::AbstractDFG, variablekey::Symbol, ppe::AbstractPointParametricEst, ppekey::Symbol) updatePPE!(dfg, variablekey, ppe)

@deprecate addPPE!(dfg::AbstractDFG, variablekey::Symbol, ppe::AbstractPointParametricEst, ppekey::Symbol) addPPE!(dfg, variablekey, ppe)

export AbstractDataStore
abstract type AbstractDataStore end
struct GeneralDataEntry <: AbstractDataEntry end
GeneralDataEntry(args...; kwargs...) = error("`GeneralDataEntry` is deprecated, use `BlobStoreEntry`")

export InMemoryDataStore, FileDataStore

struct FileDataStore <: AbstractDataStore end
FileDataStore(args...; kwargs...) = error("`FileDataStore` is deprecated, use `FolderStore`")

struct InMemoryDataStore <: AbstractDataStore end
InMemoryDataStore(args...; kwargs...) = error("`InMemoryDataStore` is deprecated, use TBD")#TODO

_uniqueKey(dfg::AbstractDFG, v::AbstractDFGVariable, key::Symbol)::Symbol = error("_uniqueKey is deprecated")

getDataBlob(store::AbstractDataStore, entry::AbstractDataEntry) = error("AbstractDataStore $(typeof(store)) is deprecated.")
addDataBlob!(store::AbstractDataStore, entry::AbstractDataEntry, data) = error("AbstractDataStore $(typeof(store)) is deprecated.")
updateDataBlob!(store::AbstractDataStore, entry::AbstractDataEntry, data)  = error("AbstractDataStore $(typeof(store)) is deprecated.")
deleteDataBlob!(store::AbstractDataStore, entry::AbstractDataEntry) = error("AbstractDataStore $(typeof(store)) is deprecated.")
listDataBlobs(store::AbstractDataStore) = error("AbstractDataStore $(typeof(store)) is deprecated.")

addData!(dfg::AbstractDFG,
         lbl::Symbol,
         datastore::Union{FileDataStore, InMemoryDataStore},
         descr::Symbol,
         mimeType::AbstractString,
         data::Vector{UInt8} ) = error("This API, FileDataStore and in MemoryDataStore is deprecated use new api parameter order and FolderStore")

export addDataElement!
addDataElement!(dfg::AbstractDFG,
                lbl::Symbol,
                datastore::Union{FileDataStore, InMemoryDataStore},
                descr::Symbol,
                mimeType::AbstractString,
                data::Vector{UInt8} ) = error("This API, FileDataStore and in MemoryDataStore is deprecated use addData! and FolderStore")

export getDataEntryBlob
getDataEntryBlob(dfg::AbstractDFG,
                 dfglabel::Symbol,
                 datastore::Union{FileDataStore, InMemoryDataStore},
                 datalabel::Symbol) = error("This API, FileDataStore and in MemoryDataStore is deprecated use getData and FolderStore")

export fetchDataEntryElement
const fetchDataEntryElement = getDataEntryBlob
export fetchData
const fetchData = getDataEntryBlob

#

## softtype deprections
function Base.getproperty(x::InferenceVariable, f::Symbol)
  if f==:dims
      Base.depwarn("Softtype $(typeof(x)), field dims is deprecated, extend and use `getDimension` instead",:getproperty)
  elseif f==:manifolds
      Base.depwarn("Softtype $(typeof(x)), field manifolds is deprecated, extend and use `getManifolds` instead",:getproperty)
  else
    if !(@isdefined softtypeFieldsWarnOnce)
      Base.depwarn("Softtype $(typeof(x)), will be required to be a singleton type in the future and can no longer have fields. *.$f called. Further warnings are suppressed",:getproperty)
      global softtypeFieldsWarnOnce = true
    end
  end
  return getfield(x,f)
end

# SmallData is now a Symbol Dict
function createSymbolDict(d::Dict{String, String})
  newsmalld = Dict{Symbol,SmallDataTypes}()
  for p in pairs(d)
    push!(newsmalld, Symbol(p.first) => p.second)
  end
  return newsmalld
end

@deprecate setSmallData!(v::DFGVariable, smallData::Dict{String, String}) setSmallData!(v, createSymbolDict(smallData))

#update deprecation with warn_if_absent
function updateVariableSolverData!(dfg::AbstractDFG,
                                   variablekey::Symbol,
                                   vnd::VariableNodeData,
                                   useCopy::Bool,
                                   fields::Vector{Symbol},
                                   verbose::Bool)
  Base.depwarn("updateVariableSolverData! argument verbose is deprecated in favor of keyword argument `warn_if_absent`, see #643", :updateVariableSolverData!)
  updateVariableSolverData!(dfg, variablekey, vnd, useCopy, fields; warn_if_absent = verbose)
end

function updateVariableSolverData!(dfg::AbstractDFG,
                                   variablekey::Symbol,
                                   vnd::VariableNodeData,
                                   solveKey::Symbol,
                                   useCopy::Bool,
                                   fields::Vector{Symbol},
                                   verbose::Bool)
  Base.depwarn("updateVariableSolverData! argument verbose is deprecated in favor of keyword argument `warn_if_absent`, see #643", :updateVariableSolverData!)
  updateVariableSolverData!(dfg, variablekey, vnd, solveKey, useCopy, fields; warn_if_absent = verbose)
end

##==============================================================================
## Deprecated in v0.11 Remove in the v0.12 cycle
##==============================================================================

# # @warn("BREAKING CHANGE coming to DistributedFactorGraphs v0.12: deprecating AbstractRelativeFactor, use AbstractRelativeRoots instead")
# # @warn("BREAKING CHANGE coming to DistributedFactorGraphs v0.12: deprecating AbstractRelativeFactorMinimize, use AbstractRelativeMinimize instead")
# # export AbstractRelativeFactor, AbstractRelativeFactorMinimize
# const AbstractRelativeFactor = AbstractRelativeRoots
# const AbstractRelativeFactorMinimize = AbstractRelativeMinimize

# ##-------------------------------------------------------------------------------
# ## softtype -> variableType deprecation
# ##-------------------------------------------------------------------------------

# function Base.getproperty(x::VariableNodeData,f::Symbol)
#   if f == :softtype
#     Base.depwarn("`VariableNodeData` field `softtype` is deprecated, use `variableType`", :getproperty)
#     f = :variableType
#   end
#   getfield(x,f)
# end

# function Base.setproperty!(x::VariableNodeData, f::Symbol, val)
#   if f == :softtype
#       Base.depwarn("`VariableNodeData` field `softtype` is deprecated, use `variableType`", :getproperty)
#     f = :variableType
#   end
#   return setfield!(x, f, convert(fieldtype(typeof(x), f), val))
# end

# function Base.getproperty(x::PackedVariableNodeData,f::Symbol)
#   if f == :softtype
#     Base.depwarn("`PackedVariableNodeData` field `softtype` is deprecated, use `variableType`", :getproperty)
#     f = :variableType
#   end
#   getfield(x,f)
# end

# function Base.setproperty!(x::PackedVariableNodeData, f::Symbol, val)
#   if f == :softtype
#       Base.depwarn("`PackedVariableNodeData` field `softtype` is deprecated, use `variableType`", :getproperty)
#   f = :variableType
#   end
#   return setfield!(x, f, convert(fieldtype(typeof(x), f), val))
# end

# function Base.getproperty(x::DFGVariableSummary,f::Symbol)
#   if f == :softtypename
#     Base.depwarn("`DFGVariableSummary` field `softtypename` is deprecated, use `variableTypeName`", :getproperty)
#     f = :variableTypeName
#   end
#   getfield(x,f)
# end

# function Base.setproperty!(x::DFGVariableSummary, f::Symbol, val)
#   if f == :softtypename
#       Base.depwarn("`DFGVariableSummary` field `softtypename` is deprecated, use `variableTypeName`", :getproperty)
#   f = :variableTypeName
#   end
#   return setfield!(x, f, convert(fieldtype(typeof(x), f), val))
# end

# @deprecate getSofttype(args...) getVariableType(args...)
# @deprecate getSofttypename(args...) getVariableTypeName(args...)

## ================================================================================
## Deprecate before v0.17
##=================================================================================

Base.propertynames(x::VariableNodeData, private::Bool=false) = private ? (:inferdim, :infoPerCoord) : (:infoPerCoord,)

Base.getproperty(x::VariableNodeData,f::Symbol) = begin
  if f == :inferdim
    Base.depwarn("vnd.inferdim::Float64 is deprecated, use vnd.infoPerCoord::Vector{Float64} instead", :getproperty)
    # @warn "vnd.inferdim is deprecated, use .infoPerCoord instead"
    getfield(x, :infoPerCoord)
  else
    getfield(x,f)
  end
end

function Base.setproperty!(x::VariableNodeData, f::Symbol, val::Real)
  _val = if f == :inferdim
    Base.depwarn("vnd.inferdim::Float64 is deprecated, use vnd.infoPerCoord::Vector{Float64} instead", :setproperty!)
    f = :infoPerCoord
    Float64[val;]
  else
    val
  end
  return setfield!(x, f, _val)
end

function Base.setproperty!(x::VariableNodeData, f::Symbol, val::AbstractVector{<:Real})
  if f == :inferdim
    Base.depwarn("vnd.inferdim::Float64 is deprecated, use vnd.infoPerCoord::Vector{Float64} instead", :setproperty!)
    f = :infoPerCoord
  end
  return setfield!(x, f, val)
end

#

Base.propertynames(x::PackedVariableNodeData, private::Bool=false) = private ? (:inferdim, :infoPerCoord) : (:infoPerCoord,)

Base.getproperty(x::PackedVariableNodeData,f::Symbol) = begin
  if f == :inferdim
    Base.depwarn("pvnd.inferdim::Float64 is deprecated, use vnd.infoPerCoord::Vector{Float64} instead", :getproperty)
    getfield(x, :infoPerCoord)
  else
    getfield(x,f)
  end
end

function Base.setproperty!(x::PackedVariableNodeData, f::Symbol, val::Real)
  _val = if f == :inferdim
    Base.depwarn("pvnd.inferdim::Float64 is deprecated, use vnd.infoPerCoord::Vector{Float64} instead", :setproperty!)
    f = :infoPerCoord
    Float64[val;]
  else
    val
  end
  return setfield!(x, f, _val)
end

function Base.setproperty!(x::PackedVariableNodeData, f::Symbol, val::AbstractVector{<:Real})
  if f == :inferdim
    Base.depwarn("pvnd.inferdim::Float64 is deprecated, use vnd.infoPerCoord::Vector{Float64} instead", :setproperty!)
    f = :infoPerCoord
  end
  return setfield!(x, f, val)
end

@deprecate VariableNodeData(val::Vector,bw::AbstractMatrix{<:Real},BayesNetOutVertIDs::AbstractVector{Symbol},dimIDs::AbstractVector{Int},dims::Int,eliminated::Bool,BayesNetVertID::Symbol,separator::AbstractVector{Symbol},variableType,initialized::Bool,inferdim::Real,w...;kw...) VariableNodeData(val,bw,BayesNetOutVertIDs,dimIDs,dims,eliminated,BayesNetVertID,separator,variableType,initialized,Float64[inferdim;],w...;kw...)

#


text:
# ndgrid-range.jl

using LazyGrids: ndgrid, ndgrid_array, GridAR, GridUR
using Test: @test, @testset, @test_throws, @inferred

@testset "range" begin
    (x, y, z) = (LinRange(0,1,4), 1:1//2:3, 6:9)
    (xa, ya, za) = @inferred ndgrid_array(x, y, z)
    (xl, yl, zl) = @inferred ndgrid(x, y, z)

    @test eltype(xl) === eltype(x)
    @test eltype(yl) === eltype(y)
    @test eltype(zl) === eltype(z)
    @test size(xl) === (length(x), length(y), length(z))
    @test xl isa GridAR
    @test yl isa GridAR
    @test zl isa GridUR
    @test xl ≈ xa
    @test yl == ya
    @test zl == za
    @test xl[2,3,4] ≈ xa[2,3,4] ≈ x[2]
    @test yl[2,3,4] == ya[2,3,4] == y[3]
    @test zl[2,3,4] == za[2,3,4] == z[4]
end


text:
module SPRING2
    using Plots

    export SpringParam,InitParam,AnimParam
    export animate_spring

    Base.@kwdef struct SpringParam
        ls::Float64 # Spring length
        ms::Float64 # Mass
        ks::Float64 # Rigidity
        ns::Int     # Mass number
    end
    getvalues(p::SpringParam) = p.ls,p.ms,p.ks,p.ns

    Base.@kwdef struct InitParam
        λ::Float64      # wavelength of initial deformation
        shift::Float64  # Maximal initial mode displacement
        pos::Float64    # Central position of the node displacement
    end
    getvalues(p::InitParam) = p.λ,p.shift,p.pos

    Base.@kwdef struct AnimParam #Base.@kwdef:allow define fields by name
        δt::Float64         # Time step
        nδt::Int            # Number of timesteps
        nδtperframe::Int    # Number of timesteps per animation frame
    end
    getvalues(p::AnimParam) = p.δt,p.nδt,p.nδtperframe

    steady_position(i,ls) = (i-1)*ls

    function initial_position(i,ls,λ,shift,pos)
        xs = steady_position(i,ls)
        dx = xs - pos
        xs-λ*dx*shift*exp(-0.5*dx^2/λ^2)
    end

    function update_force!(fx,xc,ks)
        ns= length(xc)
        for i ∈ 2:ns-1
            fx[i] = -ks*(2xc[i]-xc[i-1]-xc[i+1])
        end
    end

# Integration de Verlet
    function update_position!(xt,xc,xp,fx,δt,ms)
        coef=δt^2/ms
        @. xt=2xc-xp+fx*coef
    end

    function advance_nδtpf(xc,xp,xt,fx,sp,ap)
        ls,ms,ks,ns = getvalues(sp)
        δt,nδt,nδtperframe = getvalues(ap)

        for _ ∈ 1:nδtperframe
            update_force!(fx,xc,ks)
            update_position!(xt,xc,xp,fx,δt,ms)
            xc,xp,xt=xt,xc,xp
        end
        xc,xp,xt
    end

    function animate_spring(sp,ip,ap)
        ls,ms,ks,ns = getvalues(sp)
        λ,shift,pos = getvalues(ip)
        δt,nδt,nδtperframe = getvalues(ap)

        xs=[steady_position(i,ls) for i ∈ 1:ns]
        xc=[initial_position(i,ls,λ,shift,pos) for i ∈ 1:ns]

        dc=zero(xc)
        @. dc = xc - xs
        mdc=maximum(dc)

        # plot(xs,dc)
        fx=zero(xc)
        update_force!(fx,xc,ks)
        # plot(xs,fx)

        xt=zero(xc)
        xp=copy(xc)

        nf=nδt ÷  nδtperframe
        t=0.0
        anim= @animate for i ∈ 1:nf
            xc,xp,xt=advance_nδtpf(xc,xp,xt,fx,sp,ap)
            @. dc = xc - xs
            t+=nδtperframe*δt
            plot(xs,dc,ylims=(-mdc,mdc),title="t=$t")
        end
        gif(anim,"toto.gif",fps=15)
    end
end # module