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

"""
    associate_lenses(lens_aliases, workload_id)
    associate_lenses(lens_aliases, workload_id, params::Dict{String,<:Any})

Associate a lens to a workload. Up to 10 lenses can be associated with a workload in a
single API operation. A maximum of 20 lenses can be associated with a workload.
Disclaimer  By accessing and/or applying custom lenses created by another Amazon Web
Services user or account, you acknowledge that custom lenses created by other users and
shared with you are Third Party Content as defined in the Amazon Web Services Customer
Agreement.

# Arguments
- `lens_aliases`:
- `workload_id`:

"""
function associate_lenses(
    LensAliases, WorkloadId; aws_config::AbstractAWSConfig=global_aws_config()
)
    return wellarchitected(
        "PATCH",
        "/workloads/$(WorkloadId)/associateLenses",
        Dict{String,Any}("LensAliases" => LensAliases);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function associate_lenses(
    LensAliases,
    WorkloadId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "PATCH",
        "/workloads/$(WorkloadId)/associateLenses",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("LensAliases" => LensAliases), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    create_lens_share(client_request_token, lens_alias, shared_with)
    create_lens_share(client_request_token, lens_alias, shared_with, params::Dict{String,<:Any})

Create a lens share. The owner of a lens can share it with other Amazon Web Services
accounts and IAM users in the same Amazon Web Services Region. Shared access to a lens is
not removed until the lens invitation is deleted.   Disclaimer  By sharing your custom
lenses with other Amazon Web Services accounts, you acknowledge that Amazon Web Services
will make your custom lenses available to those other accounts. Those other accounts may
continue to access and use your shared custom lenses even if you delete the custom lenses
from your own Amazon Web Services account or terminate your Amazon Web Services account.

# Arguments
- `client_request_token`:
- `lens_alias`:
- `shared_with`:

"""
function create_lens_share(
    ClientRequestToken,
    LensAlias,
    SharedWith;
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "POST",
        "/lenses/$(LensAlias)/shares",
        Dict{String,Any}(
            "ClientRequestToken" => ClientRequestToken, "SharedWith" => SharedWith
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function create_lens_share(
    ClientRequestToken,
    LensAlias,
    SharedWith,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "POST",
        "/lenses/$(LensAlias)/shares",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "ClientRequestToken" => ClientRequestToken, "SharedWith" => SharedWith
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    create_lens_version(client_request_token, lens_alias, lens_version)
    create_lens_version(client_request_token, lens_alias, lens_version, params::Dict{String,<:Any})

Create a new lens version. A lens can have up to 100 versions. After a lens has been
imported, create a new lens version to publish it. The owner of a lens can share the lens
with other Amazon Web Services accounts and IAM users in the same Amazon Web Services
Region. Only the owner of a lens can delete it.

# Arguments
- `client_request_token`:
- `lens_alias`:
- `lens_version`: The version of the lens being created.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"IsMajorVersion"`: Set to true if this new major lens version.
"""
function create_lens_version(
    ClientRequestToken,
    LensAlias,
    LensVersion;
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "POST",
        "/lenses/$(LensAlias)/versions",
        Dict{String,Any}(
            "ClientRequestToken" => ClientRequestToken, "LensVersion" => LensVersion
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function create_lens_version(
    ClientRequestToken,
    LensAlias,
    LensVersion,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "POST",
        "/lenses/$(LensAlias)/versions",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "ClientRequestToken" => ClientRequestToken, "LensVersion" => LensVersion
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    create_milestone(client_request_token, milestone_name, workload_id)
    create_milestone(client_request_token, milestone_name, workload_id, params::Dict{String,<:Any})

Create a milestone for an existing workload.

# Arguments
- `client_request_token`:
- `milestone_name`:
- `workload_id`:

"""
function create_milestone(
    ClientRequestToken,
    MilestoneName,
    WorkloadId;
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "POST",
        "/workloads/$(WorkloadId)/milestones",
        Dict{String,Any}(
            "ClientRequestToken" => ClientRequestToken, "MilestoneName" => MilestoneName
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function create_milestone(
    ClientRequestToken,
    MilestoneName,
    WorkloadId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "POST",
        "/workloads/$(WorkloadId)/milestones",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "ClientRequestToken" => ClientRequestToken,
                    "MilestoneName" => MilestoneName,
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    create_workload(client_request_token, description, environment, lenses, review_owner, workload_name)
    create_workload(client_request_token, description, environment, lenses, review_owner, workload_name, params::Dict{String,<:Any})

Create a new workload. The owner of a workload can share the workload with other Amazon Web
Services accounts and IAM users in the same Amazon Web Services Region. Only the owner of a
workload can delete it. For more information, see Defining a Workload in the
Well-Architected Tool User Guide.

# Arguments
- `client_request_token`:
- `description`:
- `environment`:
- `lenses`:
- `review_owner`:
- `workload_name`:

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"AccountIds"`:
- `"ArchitecturalDesign"`:
- `"AwsRegions"`:
- `"Industry"`:
- `"IndustryType"`:
- `"NonAwsRegions"`:
- `"Notes"`:
- `"PillarPriorities"`:
- `"Tags"`: The tags to be associated with the workload.
"""
function create_workload(
    ClientRequestToken,
    Description,
    Environment,
    Lenses,
    ReviewOwner,
    WorkloadName;
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "POST",
        "/workloads",
        Dict{String,Any}(
            "ClientRequestToken" => ClientRequestToken,
            "Description" => Description,
            "Environment" => Environment,
            "Lenses" => Lenses,
            "ReviewOwner" => ReviewOwner,
            "WorkloadName" => WorkloadName,
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function create_workload(
    ClientRequestToken,
    Description,
    Environment,
    Lenses,
    ReviewOwner,
    WorkloadName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "POST",
        "/workloads",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "ClientRequestToken" => ClientRequestToken,
                    "Description" => Description,
                    "Environment" => Environment,
                    "Lenses" => Lenses,
                    "ReviewOwner" => ReviewOwner,
                    "WorkloadName" => WorkloadName,
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    create_workload_share(client_request_token, permission_type, shared_with, workload_id)
    create_workload_share(client_request_token, permission_type, shared_with, workload_id, params::Dict{String,<:Any})

Create a workload share. The owner of a workload can share it with other Amazon Web
Services accounts and IAM users in the same Amazon Web Services Region. Shared access to a
workload is not removed until the workload invitation is deleted. For more information, see
Sharing a Workload in the Well-Architected Tool User Guide.

# Arguments
- `client_request_token`:
- `permission_type`:
- `shared_with`:
- `workload_id`:

"""
function create_workload_share(
    ClientRequestToken,
    PermissionType,
    SharedWith,
    WorkloadId;
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "POST",
        "/workloads/$(WorkloadId)/shares",
        Dict{String,Any}(
            "ClientRequestToken" => ClientRequestToken,
            "PermissionType" => PermissionType,
            "SharedWith" => SharedWith,
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function create_workload_share(
    ClientRequestToken,
    PermissionType,
    SharedWith,
    WorkloadId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "POST",
        "/workloads/$(WorkloadId)/shares",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "ClientRequestToken" => ClientRequestToken,
                    "PermissionType" => PermissionType,
                    "SharedWith" => SharedWith,
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    delete_lens(client_request_token, lens_alias, lens_status)
    delete_lens(client_request_token, lens_alias, lens_status, params::Dict{String,<:Any})

Delete an existing lens. Only the owner of a lens can delete it. After the lens is deleted,
Amazon Web Services accounts and IAM users that you shared the lens with can continue to
use it, but they will no longer be able to apply it to new workloads.    Disclaimer  By
sharing your custom lenses with other Amazon Web Services accounts, you acknowledge that
Amazon Web Services will make your custom lenses available to those other accounts. Those
other accounts may continue to access and use your shared custom lenses even if you delete
the custom lenses from your own Amazon Web Services account or terminate your Amazon Web
Services account.

# Arguments
- `client_request_token`:
- `lens_alias`:
- `lens_status`: The status of the lens to be deleted.

"""
function delete_lens(
    ClientRequestToken,
    LensAlias,
    LensStatus;
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "DELETE",
        "/lenses/$(LensAlias)",
        Dict{String,Any}(
            "ClientRequestToken" => ClientRequestToken, "LensStatus" => LensStatus
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function delete_lens(
    ClientRequestToken,
    LensAlias,
    LensStatus,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "DELETE",
        "/lenses/$(LensAlias)",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "ClientRequestToken" => ClientRequestToken, "LensStatus" => LensStatus
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    delete_lens_share(client_request_token, lens_alias, share_id)
    delete_lens_share(client_request_token, lens_alias, share_id, params::Dict{String,<:Any})

Delete a lens share. After the lens share is deleted, Amazon Web Services accounts and IAM
users that you shared the lens with can continue to use it, but they will no longer be able
to apply it to new workloads.   Disclaimer  By sharing your custom lenses with other Amazon
Web Services accounts, you acknowledge that Amazon Web Services will make your custom
lenses available to those other accounts. Those other accounts may continue to access and
use your shared custom lenses even if you delete the custom lenses from your own Amazon Web
Services account or terminate your Amazon Web Services account.

# Arguments
- `client_request_token`:
- `lens_alias`:
- `share_id`:

"""
function delete_lens_share(
    ClientRequestToken,
    LensAlias,
    ShareId;
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "DELETE",
        "/lenses/$(LensAlias)/shares/$(ShareId)",
        Dict{String,Any}("ClientRequestToken" => ClientRequestToken);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function delete_lens_share(
    ClientRequestToken,
    LensAlias,
    ShareId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "DELETE",
        "/lenses/$(LensAlias)/shares/$(ShareId)",
        Dict{String,Any}(
            mergewith(
                _merge, Dict{String,Any}("ClientRequestToken" => ClientRequestToken), params
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    delete_workload(client_request_token, workload_id)
    delete_workload(client_request_token, workload_id, params::Dict{String,<:Any})

Delete an existing workload.

# Arguments
- `client_request_token`:
- `workload_id`:

"""
function delete_workload(
    ClientRequestToken, WorkloadId; aws_config::AbstractAWSConfig=global_aws_config()
)
    return wellarchitected(
        "DELETE",
        "/workloads/$(WorkloadId)",
        Dict{String,Any}("ClientRequestToken" => ClientRequestToken);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function delete_workload(
    ClientRequestToken,
    WorkloadId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "DELETE",
        "/workloads/$(WorkloadId)",
        Dict{String,Any}(
            mergewith(
                _merge, Dict{String,Any}("ClientRequestToken" => ClientRequestToken), params
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    delete_workload_share(client_request_token, share_id, workload_id)
    delete_workload_share(client_request_token, share_id, workload_id, params::Dict{String,<:Any})

Delete a workload share.

# Arguments
- `client_request_token`:
- `share_id`:
- `workload_id`:

"""
function delete_workload_share(
    ClientRequestToken,
    ShareId,
    WorkloadId;
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "DELETE",
        "/workloads/$(WorkloadId)/shares/$(ShareId)",
        Dict{String,Any}("ClientRequestToken" => ClientRequestToken);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function delete_workload_share(
    ClientRequestToken,
    ShareId,
    WorkloadId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "DELETE",
        "/workloads/$(WorkloadId)/shares/$(ShareId)",
        Dict{String,Any}(
            mergewith(
                _merge, Dict{String,Any}("ClientRequestToken" => ClientRequestToken), params
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    disassociate_lenses(lens_aliases, workload_id)
    disassociate_lenses(lens_aliases, workload_id, params::Dict{String,<:Any})

Disassociate a lens from a workload. Up to 10 lenses can be disassociated from a workload
in a single API operation.  The Amazon Web Services Well-Architected Framework lens
(wellarchitected) cannot be removed from a workload.

# Arguments
- `lens_aliases`:
- `workload_id`:

"""
function disassociate_lenses(
    LensAliases, WorkloadId; aws_config::AbstractAWSConfig=global_aws_config()
)
    return wellarchitected(
        "PATCH",
        "/workloads/$(WorkloadId)/disassociateLenses",
        Dict{String,Any}("LensAliases" => LensAliases);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function disassociate_lenses(
    LensAliases,
    WorkloadId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "PATCH",
        "/workloads/$(WorkloadId)/disassociateLenses",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("LensAliases" => LensAliases), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Export an existing lens. Lenses are defined in JSON. For more information, see JSON format
specification in the Well-Architected Tool User Guide. Only the owner of a lens can export
it.    Disclaimer  Do not include or gather personal identifiable information (PII) of end
users or other identifiable individuals in or via your custom lenses. If your custom lens
or those shared with you and used in your account do include or collect PII you are
responsible for: ensuring that the included PII is processed in accordance with applicable
law, providing adequate privacy notices, and obtaining necessary consents for processing
such data.

# Arguments
- `lens_alias`:

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"LensVersion"`: The lens version to be exported.
"""
function export_lens(LensAlias; aws_config::AbstractAWSConfig=global_aws_config())
    return wellarchitected(
        "GET",
        "/lenses/$(LensAlias)/export";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function export_lens(
    LensAlias,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "GET",
        "/lenses/$(LensAlias)/export",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    get_answer(lens_alias, question_id, workload_id)
    get_answer(lens_alias, question_id, workload_id, params::Dict{String,<:Any})

Get the answer to a specific question in a workload review.

# Arguments
- `lens_alias`:
- `question_id`:
- `workload_id`:

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"MilestoneNumber"`:
"""
function get_answer(
    LensAlias, QuestionId, WorkloadId; aws_config::AbstractAWSConfig=global_aws_config()
)
    return wellarchitected(
        "GET",
        "/workloads/$(WorkloadId)/lensReviews/$(LensAlias)/answers/$(QuestionId)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function get_answer(
    LensAlias,
    QuestionId,
    WorkloadId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "GET",
        "/workloads/$(WorkloadId)/lensReviews/$(LensAlias)/answers/$(QuestionId)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Get an existing lens.

# Arguments
- `lens_alias`:

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"LensVersion"`: The lens version to be retrieved.
"""
function get_lens(LensAlias; aws_config::AbstractAWSConfig=global_aws_config())
    return wellarchitected(
        "GET",
        "/lenses/$(LensAlias)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function get_lens(
    LensAlias,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "GET",
        "/lenses/$(LensAlias)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    get_lens_review(lens_alias, workload_id)
    get_lens_review(lens_alias, workload_id, params::Dict{String,<:Any})

Get lens review.

# Arguments
- `lens_alias`:
- `workload_id`:

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"MilestoneNumber"`:
"""
function get_lens_review(
    LensAlias, WorkloadId; aws_config::AbstractAWSConfig=global_aws_config()
)
    return wellarchitected(
        "GET",
        "/workloads/$(WorkloadId)/lensReviews/$(LensAlias)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function get_lens_review(
    LensAlias,
    WorkloadId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "GET",
        "/workloads/$(WorkloadId)/lensReviews/$(LensAlias)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    get_lens_review_report(lens_alias, workload_id)
    get_lens_review_report(lens_alias, workload_id, params::Dict{String,<:Any})

Get lens review report.

# Arguments
- `lens_alias`:
- `workload_id`:

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"MilestoneNumber"`:
"""
function get_lens_review_report(
    LensAlias, WorkloadId; aws_config::AbstractAWSConfig=global_aws_config()
)
    return wellarchitected(
        "GET",
        "/workloads/$(WorkloadId)/lensReviews/$(LensAlias)/report";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function get_lens_review_report(
    LensAlias,
    WorkloadId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "GET",
        "/workloads/$(WorkloadId)/lensReviews/$(LensAlias)/report",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Get lens version differences.

# Arguments
- `lens_alias`:

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"BaseLensVersion"`: The base version of the lens.
- `"TargetLensVersion"`: The lens version to target a difference for.
"""
function get_lens_version_difference(
    LensAlias; aws_config::AbstractAWSConfig=global_aws_config()
)
    return wellarchitected(
        "GET",
        "/lenses/$(LensAlias)/versionDifference";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function get_lens_version_difference(
    LensAlias,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "GET",
        "/lenses/$(LensAlias)/versionDifference",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    get_milestone(milestone_number, workload_id)
    get_milestone(milestone_number, workload_id, params::Dict{String,<:Any})

Get a milestone for an existing workload.

# Arguments
- `milestone_number`:
- `workload_id`:

"""
function get_milestone(
    MilestoneNumber, WorkloadId; aws_config::AbstractAWSConfig=global_aws_config()
)
    return wellarchitected(
        "GET",
        "/workloads/$(WorkloadId)/milestones/$(MilestoneNumber)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function get_milestone(
    MilestoneNumber,
    WorkloadId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "GET",
        "/workloads/$(WorkloadId)/milestones/$(MilestoneNumber)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Get an existing workload.

# Arguments
- `workload_id`:

"""
function get_workload(WorkloadId; aws_config::AbstractAWSConfig=global_aws_config())
    return wellarchitected(
        "GET",
        "/workloads/$(WorkloadId)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function get_workload(
    WorkloadId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "GET",
        "/workloads/$(WorkloadId)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    import_lens(client_request_token, jsonstring)
    import_lens(client_request_token, jsonstring, params::Dict{String,<:Any})

Import a new lens. The lens cannot be applied to workloads or shared with other Amazon Web
Services accounts until it's published with CreateLensVersion  Lenses are defined in JSON.
For more information, see JSON format specification in the Well-Architected Tool User
Guide. A custom lens cannot exceed 500 KB in size.   Disclaimer  Do not include or gather
personal identifiable information (PII) of end users or other identifiable individuals in
or via your custom lenses. If your custom lens or those shared with you and used in your
account do include or collect PII you are responsible for: ensuring that the included PII
is processed in accordance with applicable law, providing adequate privacy notices, and
obtaining necessary consents for processing such data.

# Arguments
- `client_request_token`:
- `jsonstring`: The JSON representation of a lens.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"LensAlias"`:
- `"Tags"`: Tags to associate to a lens.
"""
function import_lens(
    ClientRequestToken, JSONString; aws_config::AbstractAWSConfig=global_aws_config()
)
    return wellarchitected(
        "PUT",
        "/importLens",
        Dict{String,Any}(
            "ClientRequestToken" => ClientRequestToken, "JSONString" => JSONString
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function import_lens(
    ClientRequestToken,
    JSONString,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "PUT",
        "/importLens",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "ClientRequestToken" => ClientRequestToken, "JSONString" => JSONString
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    list_answers(lens_alias, workload_id)
    list_answers(lens_alias, workload_id, params::Dict{String,<:Any})

List of answers.

# Arguments
- `lens_alias`:
- `workload_id`:

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"MaxResults"`: The maximum number of results to return for this request.
- `"MilestoneNumber"`:
- `"NextToken"`:
- `"PillarId"`:
"""
function list_answers(
    LensAlias, WorkloadId; aws_config::AbstractAWSConfig=global_aws_config()
)
    return wellarchitected(
        "GET",
        "/workloads/$(WorkloadId)/lensReviews/$(LensAlias)/answers";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_answers(
    LensAlias,
    WorkloadId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "GET",
        "/workloads/$(WorkloadId)/lensReviews/$(LensAlias)/answers",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    list_lens_review_improvements(lens_alias, workload_id)
    list_lens_review_improvements(lens_alias, workload_id, params::Dict{String,<:Any})

List lens review improvements.

# Arguments
- `lens_alias`:
- `workload_id`:

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"MaxResults"`: The maximum number of results to return for this request.
- `"MilestoneNumber"`:
- `"NextToken"`:
- `"PillarId"`:
"""
function list_lens_review_improvements(
    LensAlias, WorkloadId; aws_config::AbstractAWSConfig=global_aws_config()
)
    return wellarchitected(
        "GET",
        "/workloads/$(WorkloadId)/lensReviews/$(LensAlias)/improvements";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_lens_review_improvements(
    LensAlias,
    WorkloadId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "GET",
        "/workloads/$(WorkloadId)/lensReviews/$(LensAlias)/improvements",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

List lens reviews.

# Arguments
- `workload_id`:

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"MaxResults"`:
- `"MilestoneNumber"`:
- `"NextToken"`:
"""
function list_lens_reviews(WorkloadId; aws_config::AbstractAWSConfig=global_aws_config())
    return wellarchitected(
        "GET",
        "/workloads/$(WorkloadId)/lensReviews";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_lens_reviews(
    WorkloadId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "GET",
        "/workloads/$(WorkloadId)/lensReviews",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

List the lens shares associated with the lens.

# Arguments
- `lens_alias`:

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"MaxResults"`: The maximum number of results to return for this request.
- `"NextToken"`:
- `"SharedWithPrefix"`: The Amazon Web Services account ID or IAM role with which the lens
  is shared.
"""
function list_lens_shares(LensAlias; aws_config::AbstractAWSConfig=global_aws_config())
    return wellarchitected(
        "GET",
        "/lenses/$(LensAlias)/shares";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_lens_shares(
    LensAlias,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "GET",
        "/lenses/$(LensAlias)/shares",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

List the available lenses.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"LensName"`:
- `"LensStatus"`: The status of lenses to be returned.
- `"LensType"`: The type of lenses to be returned.
- `"MaxResults"`:
- `"NextToken"`:
"""
function list_lenses(; aws_config::AbstractAWSConfig=global_aws_config())
    return wellarchitected(
        "GET", "/lenses"; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET
    )
end
function list_lenses(
    params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return wellarchitected(
        "GET", "/lenses", params; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET
    )
end

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

List all milestones for an existing workload.

# Arguments
- `workload_id`:

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"MaxResults"`:
- `"NextToken"`:
"""
function list_milestones(WorkloadId; aws_config::AbstractAWSConfig=global_aws_config())
    return wellarchitected(
        "POST",
        "/workloads/$(WorkloadId)/milestonesSummaries";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_milestones(
    WorkloadId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "POST",
        "/workloads/$(WorkloadId)/milestonesSummaries",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

List lens notifications.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"MaxResults"`: The maximum number of results to return for this request.
- `"NextToken"`:
- `"WorkloadId"`:
"""
function list_notifications(; aws_config::AbstractAWSConfig=global_aws_config())
    return wellarchitected(
        "POST", "/notifications"; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET
    )
end
function list_notifications(
    params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return wellarchitected(
        "POST",
        "/notifications",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

List the workload invitations.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"LensNamePrefix"`: An optional string added to the beginning of each lens name returned
  in the results.
- `"MaxResults"`: The maximum number of results to return for this request.
- `"NextToken"`:
- `"ShareResourceType"`: The type of share invitations to be returned.
- `"WorkloadNamePrefix"`:
"""
function list_share_invitations(; aws_config::AbstractAWSConfig=global_aws_config())
    return wellarchitected(
        "GET", "/shareInvitations"; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET
    )
end
function list_share_invitations(
    params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return wellarchitected(
        "GET",
        "/shareInvitations",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

List the tags for a resource.

# Arguments
- `workload_arn`:

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

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

List the workload shares associated with the workload.

# Arguments
- `workload_id`:

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"MaxResults"`: The maximum number of results to return for this request.
- `"NextToken"`:
- `"SharedWithPrefix"`: The Amazon Web Services account ID or IAM role with which the
  workload is shared.
"""
function list_workload_shares(WorkloadId; aws_config::AbstractAWSConfig=global_aws_config())
    return wellarchitected(
        "GET",
        "/workloads/$(WorkloadId)/shares";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_workload_shares(
    WorkloadId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "GET",
        "/workloads/$(WorkloadId)/shares",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

List workloads. Paginated.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"MaxResults"`: The maximum number of results to return for this request.
- `"NextToken"`:
- `"WorkloadNamePrefix"`:
"""
function list_workloads(; aws_config::AbstractAWSConfig=global_aws_config())
    return wellarchitected(
        "POST",
        "/workloadsSummaries";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_workloads(
    params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return wellarchitected(
        "POST",
        "/workloadsSummaries",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Adds one or more tags to the specified resource.

# Arguments
- `tags`: The tags for the resource.
- `workload_arn`:

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

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

Deletes specified tags from a resource. To specify multiple tags, use separate tagKeys
parameters, for example:  DELETE /tags/WorkloadArn?tagKeys=key1&tagKeys=key2

# Arguments
- `workload_arn`:
- `tag_keys`: A list of tag keys. Existing tags of the resource whose keys are members of
  this list are removed from the resource.

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

"""
    update_answer(lens_alias, question_id, workload_id)
    update_answer(lens_alias, question_id, workload_id, params::Dict{String,<:Any})

Update the answer to a specific question in a workload review.

# Arguments
- `lens_alias`:
- `question_id`:
- `workload_id`:

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"ChoiceUpdates"`: A list of choices to update on a question in your workload. The String
  key corresponds to the choice ID to be updated.
- `"IsApplicable"`:
- `"Notes"`:
- `"Reason"`: The reason why a question is not applicable to your workload.
- `"SelectedChoices"`:
"""
function update_answer(
    LensAlias, QuestionId, WorkloadId; aws_config::AbstractAWSConfig=global_aws_config()
)
    return wellarchitected(
        "PATCH",
        "/workloads/$(WorkloadId)/lensReviews/$(LensAlias)/answers/$(QuestionId)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function update_answer(
    LensAlias,
    QuestionId,
    WorkloadId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "PATCH",
        "/workloads/$(WorkloadId)/lensReviews/$(LensAlias)/answers/$(QuestionId)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    update_lens_review(lens_alias, workload_id)
    update_lens_review(lens_alias, workload_id, params::Dict{String,<:Any})

Update lens review.

# Arguments
- `lens_alias`:
- `workload_id`:

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"LensNotes"`:
- `"PillarNotes"`:
"""
function update_lens_review(
    LensAlias, WorkloadId; aws_config::AbstractAWSConfig=global_aws_config()
)
    return wellarchitected(
        "PATCH",
        "/workloads/$(WorkloadId)/lensReviews/$(LensAlias)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function update_lens_review(
    LensAlias,
    WorkloadId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "PATCH",
        "/workloads/$(WorkloadId)/lensReviews/$(LensAlias)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    update_share_invitation(share_invitation_action, share_invitation_id)
    update_share_invitation(share_invitation_action, share_invitation_id, params::Dict{String,<:Any})

Update a workload invitation.

# Arguments
- `share_invitation_action`:
- `share_invitation_id`: The ID assigned to the share invitation.

"""
function update_share_invitation(
    ShareInvitationAction,
    ShareInvitationId;
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "PATCH",
        "/shareInvitations/$(ShareInvitationId)",
        Dict{String,Any}("ShareInvitationAction" => ShareInvitationAction);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function update_share_invitation(
    ShareInvitationAction,
    ShareInvitationId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "PATCH",
        "/shareInvitations/$(ShareInvitationId)",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}("ShareInvitationAction" => ShareInvitationAction),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Update an existing workload.

# Arguments
- `workload_id`:

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"AccountIds"`:
- `"ArchitecturalDesign"`:
- `"AwsRegions"`:
- `"Description"`:
- `"Environment"`:
- `"ImprovementStatus"`:
- `"Industry"`:
- `"IndustryType"`:
- `"IsReviewOwnerUpdateAcknowledged"`: Flag indicating whether the workload owner has
  acknowledged that the Review owner field is required. If a Review owner is not added to the
  workload within 60 days of acknowledgement, access to the workload is restricted until an
  owner is added.
- `"NonAwsRegions"`:
- `"Notes"`:
- `"PillarPriorities"`:
- `"ReviewOwner"`:
- `"WorkloadName"`:
"""
function update_workload(WorkloadId; aws_config::AbstractAWSConfig=global_aws_config())
    return wellarchitected(
        "PATCH",
        "/workloads/$(WorkloadId)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function update_workload(
    WorkloadId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "PATCH",
        "/workloads/$(WorkloadId)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    update_workload_share(permission_type, share_id, workload_id)
    update_workload_share(permission_type, share_id, workload_id, params::Dict{String,<:Any})

Update a workload share.

# Arguments
- `permission_type`:
- `share_id`:
- `workload_id`:

"""
function update_workload_share(
    PermissionType, ShareId, WorkloadId; aws_config::AbstractAWSConfig=global_aws_config()
)
    return wellarchitected(
        "PATCH",
        "/workloads/$(WorkloadId)/shares/$(ShareId)",
        Dict{String,Any}("PermissionType" => PermissionType);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function update_workload_share(
    PermissionType,
    ShareId,
    WorkloadId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "PATCH",
        "/workloads/$(WorkloadId)/shares/$(ShareId)",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("PermissionType" => PermissionType), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    upgrade_lens_review(lens_alias, milestone_name, workload_id)
    upgrade_lens_review(lens_alias, milestone_name, workload_id, params::Dict{String,<:Any})

Upgrade lens review.

# Arguments
- `lens_alias`:
- `milestone_name`:
- `workload_id`:

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"ClientRequestToken"`:
"""
function upgrade_lens_review(
    LensAlias, MilestoneName, WorkloadId; aws_config::AbstractAWSConfig=global_aws_config()
)
    return wellarchitected(
        "PUT",
        "/workloads/$(WorkloadId)/lensReviews/$(LensAlias)/upgrade",
        Dict{String,Any}("MilestoneName" => MilestoneName);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function upgrade_lens_review(
    LensAlias,
    MilestoneName,
    WorkloadId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return wellarchitected(
        "PUT",
        "/workloads/$(WorkloadId)/lensReviews/$(LensAlias)/upgrade",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("MilestoneName" => MilestoneName), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end


text:
import JSONWebTokens, SHA, MbedTLS, JSON

using Test
using Random

@testset "base64url_encode/decode" begin
    header = """{"alg":"HS256","typ":"JWT"}"""
    claims = """{"sub":"1234567890","name":"John Doe","iat":1516239022}"""
    secret = "123"
    header_and_claims_encoded = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ"
    @test JSONWebTokens.base64url_encode(header) * "." * JSONWebTokens.base64url_encode(claims) == header_and_claims_encoded
    @test JSONWebTokens.base64url_encode(SHA.hmac_sha2_256( JSONWebTokens.to_byte_array(secret), header_and_claims_encoded)) == "pF3q46_CLIyP_1QZPpeccbs-hC4n9YW2VMBjKrSO6Wg"
    encoding = JSONWebTokens.None()
    show(IOBuffer(), encoding)
    claims_dict = JSON.parse(claims)
    @test JSONWebTokens.decode(encoding, JSONWebTokens.encode(encoding, claims_dict)) == claims_dict
end

@testset "HS256 valid JSONWebTokens decode" begin
    jwt_encoded = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.8TLPbKjmE0uGLQyLnfHx2z-zy6G8qu5zFFXRSuJID_Y"
    encoding = JSONWebTokens.HS256("secretkey")
    show(IOBuffer(), encoding)
    json = JSONWebTokens.decode_as_json(encoding, jwt_encoded)
    println("JSON: $json")
    claims_dict = JSONWebTokens.decode(encoding, jwt_encoded)
    @test claims_dict["sub"] == "1234567890"
    @test claims_dict["name"] == "John Doe"
    @test claims_dict["iat"] == 1516239022
end

@testset "HS256 invalid JSONWebTokens decode" begin
    encoding = JSONWebTokens.HS256("secretkey")
    jwt_encoded_invalid_1 = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.fyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.8TLPbKjmE0uGLQyLnfHx2z-zy6G8qu5zFFXRSuJID_Y"
    jwt_encoded_invalid_2 = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.8TLPbKjmE0uGLQyLnfHx2z-zy6G8qu5zFFXRSuJJD_Y"
    @test_throws JSONWebTokens.InvalidSignatureError JSONWebTokens.decode(encoding, jwt_encoded_invalid_1)
    @test_throws JSONWebTokens.InvalidSignatureError JSONWebTokens.decode(encoding, jwt_encoded_invalid_2)
end

@testset "HS256 encode/decode" begin
    encoding = JSONWebTokens.HS256("secretkey")
    claims_json = """{"sub":"1234567890","name":"John Doe","iat":1516239022}"""
    claims_dict = JSON.parse(claims_json)
    @test JSONWebTokens.encode(encoding, claims_json) == "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.8TLPbKjmE0uGLQyLnfHx2z-zy6G8qu5zFFXRSuJID_Y"
    @test JSONWebTokens.decode(encoding, JSONWebTokens.encode(encoding, claims_dict)) == claims_dict
end

# how to generate public/private key using openssl
# https://www.devco.net/archives/2006/02/13/public_-_private_key_encryption_using_openssl.php

# private.pem / public.pem generated using
# $ openssl genrsa -out private.pem 2048
# $ openssl rsa -in private.pem -out public.pem -outform PEM -pubout
# $ openssl genrsa -out private2.pem 2048
# $ openssl rsa -in private2.pem -out public2.pem -outform PEM -pubout

@testset "MbedTLS" begin
    header = """{"alg":"RS256","typ":"JWT"}"""
    claims = """{"sub":"1234567890","name":"John Doe","admin":true,"iat":1516239022}"""
    header_and_claims_encoded = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0"
    signature_encoded = "o9uMYrmOqgdBqhbOBzuiN_0nFp2Ed1J4urFx-TyY61AgM6tUTutTGfIsIZERVjqRXAKd6bGYPuVlGf5m-XADAmqnKTpxcaP_t5ipNfsB6g9rudi7U3uWYldbSfW0-cnayISt5Eyga23Qs5ZqY7e7uQHN_z_mI2Cmoari91ZGnt1jte11gFNd7icMDGz9laBZESeFGFECAxP2hCvrg_G0dCySh_AVnYerD0iF0MznMvV1dxxuprjeQDunQtG3h2uQrJMTBEvCVPxrf7Kql3_k9S4pQDQaoPGQPO9yogpdYdgS5OV3LdSvjlDwRQL6FlDTgB3l1sv0NkEpRviR3x9VLA"
    @test JSONWebTokens.base64url_encode(header) * "." * JSONWebTokens.base64url_encode(claims) == header_and_claims_encoded

    private_key_file = joinpath(@__DIR__, "private.pem")
    @assert isfile(private_key_file) "Couldn't find test private key file $private_key_file."
    key = MbedTLS.parse_keyfile(private_key_file)
    _hash = MbedTLS.digest(MbedTLS.MD_SHA256, header_and_claims_encoded)
    output = MbedTLS.sign(key, MbedTLS.MD_SHA256, _hash, MersenneTwister(0))
    @test JSONWebTokens.base64url_encode(output) == signature_encoded

    public_key_file = joinpath(@__DIR__, "public.pem")
    @assert isfile(public_key_file) "Couldn't find test public key file $public_key_file."
    pubkey_string = read(open(public_key_file, "r"))
    pubkey = MbedTLS.PKContext()
    MbedTLS.parse_public_key!(pubkey, pubkey_string)
    @test MbedTLS.verify(pubkey, MbedTLS.MD_SHA256, _hash, JSONWebTokens.base64url_decode(signature_encoded)) == 0
end

@testset "RSA - keys in files" begin
    fp_public = joinpath(@__DIR__, "public.pem")
    fp_private = joinpath(@__DIR__, "private.pem")
    @assert isfile(fp_public)
    @assert isfile(fp_private)
    rsa_public = JSONWebTokens.RS256(fp_public)
    rsa_private = JSONWebTokens.RS256(fp_private)
    show(IOBuffer(), rsa_public)
    show(IOBuffer(), rsa_private)

    claims_dict = JSON.parse("""{"sub":"1234567890","name":"John Doe","admin":true,"iat":1516239022}""")
    jwt = JSONWebTokens.encode(rsa_private, claims_dict)
    @test startswith(jwt, "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.")
    @test JSONWebTokens.decode(rsa_public, jwt) == claims_dict

    fp_public2 = joinpath(@__DIR__, "public2.pem")
    fp_private2 = joinpath(@__DIR__, "private2.pem")
    @assert isfile(fp_public2)
    @assert isfile(fp_private2)
    rsa_public2 = JSONWebTokens.RS256(fp_public2)
    rsa_private2 = JSONWebTokens.RS256(fp_private2)

    @test_throws JSONWebTokens.InvalidSignatureError JSONWebTokens.decode(rsa_public2, jwt)
    jwt2 = JSONWebTokens.encode(rsa_private2, claims_dict)
    @test jwt != jwt2
    @test JSONWebTokens.decode(rsa_public2, jwt2) == claims_dict
    @test_throws JSONWebTokens.InvalidSignatureError JSONWebTokens.decode(rsa_public, jwt2)

    @test_throws AssertionError JSONWebTokens.encode(rsa_public, claims_dict)
end

@testset "RSA - keys inline" begin

    public_key = """-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwh4KT/453FE+H2myUOtY
MJlyDMtkElgdM2G8CkupqbTy7ucCgMb5rrNGKW22ZdyAoPDXCkpqc0jkCEco1nKi
wYNE4nfcit1MDUwOqXWMVgYUsFZNQEqBYUKxJYApXbiaybkKw7Yn26VFu6+culTN
+05RXSg2I6gYcWoiQMjnPqcrvTlhYRbCLW+0+bISKSoUxm5hRV6FwfEmR30LWtaF
jHIUNHAX9dg+PVGrKPgK85T4uXKI4SNg6h+Rvgty2pQ9XMbkdli5j/450oWFOa6F
NJfYQZOX5DMLOIWKOOM0IPCmRwBxzTpOCVgvc7g1KBnw1efzdwhZo1yp5PmqbiLC
gQIDAQAB
-----END PUBLIC KEY-----"""

    private_key = """-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAwh4KT/453FE+H2myUOtYMJlyDMtkElgdM2G8CkupqbTy7ucC
gMb5rrNGKW22ZdyAoPDXCkpqc0jkCEco1nKiwYNE4nfcit1MDUwOqXWMVgYUsFZN
QEqBYUKxJYApXbiaybkKw7Yn26VFu6+culTN+05RXSg2I6gYcWoiQMjnPqcrvTlh
YRbCLW+0+bISKSoUxm5hRV6FwfEmR30LWtaFjHIUNHAX9dg+PVGrKPgK85T4uXKI
4SNg6h+Rvgty2pQ9XMbkdli5j/450oWFOa6FNJfYQZOX5DMLOIWKOOM0IPCmRwBx
zTpOCVgvc7g1KBnw1efzdwhZo1yp5PmqbiLCgQIDAQABAoIBAGDgYx8m7jNw7EL7
Gf3eZiXi/pM6ElhBV1lkRlcRCbxjTPZDnfEs3ED+wV49ndDaKeuoJnnBR7z/PKaQ
9OWJUoam/4LSdONsq97a/Vo/CumHoV2bxHP4evdSNFxVyM84KS/RRHkF+IBazCFt
9Bbd6eqoXFzUi6hh5Mj9Qdj5KscOAmore/4HYw5DkzuNvtutgUaPx7SA+LwBobXP
NfVG+EKjIWan4XVUbm8QwgCdYqbpY2s5NFZMq/zu6mFGz2my73fZyCIRy0reOs5x
dg9A8xrjXMWMU8HsCAqS6o+3FXgQBmupMd53S6PAsjM7CHVS2we8T0nY1Yqfiylx
nhUZ9H0CgYEA5CbJd2RJ+9asqT+ykTKFV3qlt9Nq1Z2s7QHTfbLOPc6Jm4f+bXgD
C2Ae2v3YvSCHVs40WkJHwJA715AZm9rtlSE4QdzVCxr4D0vhbdhp7CPArnCSeyAF
Yoqt7ZHCbm3JhM31OBOwJJuRZ2jZobzTsvOCX8vyTxT6svyU9/vXtfMCgYEA2c/D
b3dib34ShJtY8MMTcCTiAv4PGrsbYF9p+9OPKvL4+na5gH9mKmwukgLBSnzeesle
ywpk2yy2Y/J3HSIOW1FUgu64bt9l0MKEFx+3Vwex3rllqhMFp7AozRLw3H+5olMT
5syy9ql8kMSsqEB9OWERQ3CJ5P2Qx6XlcsCAPrsCgYACscqTVGXjSYfEf/IV8OjO
Pa6TWzXZzADs06axx1jUNgo+Af8pP8+ZZMs4fuL+aNHwXoMTxdCfH5T1WMhUpONF
bZ0Ceh8yAGGJnLXO3E1z8oAmD0JLnfcyULz5H02SjE1i+iO5Q9JCvGudMwnO9THy
3RlfFEOKV48WahFAVIMZrQKBgCgZ6l+BWWwxh/NGLq/VGqURBVOLtvgy7q1lo7ur
jbZYmaJzbV/NFOBGnqRfQXsXVlbA8GTtevgnWUU5hNimRoJljOu2S9qN4s72oR8o
xbaOQh9Bfwg7DFV9R2XKUPInyeOq7AUYNvLW7Yoxy6AGj4ea6XTDKYAxdxBq6L2h
13q1AoGAZ6szDCRLW+69n+QKPlujfM8CSjDofnLLvr9RHSuIiFv3+moWXPPUQJf5
Gt/YOYUZ+k9mfMpC5OIrE/O+9NlUYciwl6wwJjdK9GBJuAQNqa1ZwtEioPYO3ZW6
hL1Hq+f0MJkBnql53kFDSth1fQSkSMMHIb1LGFYmoT3mSDwHDho=
-----END RSA PRIVATE KEY-----"""

    rsa_public = JSONWebTokens.RS256(public_key)
    rsa_private = JSONWebTokens.RS256(private_key)
    show(IOBuffer(), rsa_public)
    show(IOBuffer(), rsa_private)

    claims_dict = JSON.parse("""{"sub":"1234567890","name":"John Doe","admin":true,"iat":1516239022}""")
    jwt = JSONWebTokens.encode(rsa_private, claims_dict)
    @test startswith(jwt, "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.")
    @test JSONWebTokens.decode(rsa_public, jwt) == claims_dict

    @testset "base64 encoded key" begin
        pub_key_encoded = JSONWebTokens.Base64.base64encode(public_key)
        rsa_public = JSONWebTokens.RS256(pub_key_encoded)
        @test JSONWebTokens.decode(rsa_public, jwt) == claims_dict
    end
end

ext: jl


text:
# Native intrinsics

export
    # Indexing and dimensions
    threadId_x, threadId_y, threadId_z,
    numThreads_x, numThreads_y, numThreads_z,
    blockId_x, blockId_y, blockId_z,
    numBlocks_x, numBlocks_y, numBlocks_z,
    warpsize,

    # Memory management
    sync_threads,
    setCuSharedMem, getCuSharedMem,

    # Math
    sin, cos, floor

#
# Indexing and dimensions
#

for dim in (:x, :y, :z)
    # Thread index
    fname = symbol("threadId_$dim")
    intrinsic = "llvm.nvvm.read.ptx.sreg.tid.$dim"
    @eval begin
        $fname() = Base.llvmcall(
            ($("""declare i32 @$intrinsic() readnone nounwind"""),
             $("""%1 = tail call i32 @$intrinsic()
                  ret i32 %1""")),
            Int32, ()) + 1
    end

    # Block dimension (#threads per block)
    fname = symbol("numThreads_$dim")
    intrinsic = "llvm.nvvm.read.ptx.sreg.ntid.$dim"
    @eval begin
        $fname() = Base.llvmcall(
            ($("""declare i32 @$intrinsic() readnone nounwind"""),
             $("""%1 = tail call i32 @$intrinsic()
                  ret i32 %1""")),
            Int32, ())
    end

    # Block index
    fname = symbol("blockId_$dim")
    intrinsic = "llvm.nvvm.read.ptx.sreg.ctaid.$dim"
    @eval begin
        $fname() = Base.llvmcall(
            ($("""declare i32 @$intrinsic() readnone nounwind"""),
             $("""%1 = tail call i32 @$intrinsic()
                  ret i32 %1""")),
            Int32, ()) + 1
    end

    # Grid dimension (#blocks)
    fname = symbol("numBlocks_$dim")
    intrinsic = "llvm.nvvm.read.ptx.sreg.nctaid.$dim"
    @eval begin
        $fname() = Base.llvmcall(
            ($("""declare i32 @$intrinsic() readnone nounwind"""),
             $("""%1 = tail call i32 @$intrinsic()
                  ret i32 %1""")),
            Int32, ())
    end
end

# Tuple accessors
# TODO: these get boxed no matter what -- avoid that!
#threadId() = (threadId_x(), threadId_y(), threadId_z())
#numThreads() = (numThreads_x(), numThreads_y(), numThreads_z())
#blockId() = (blockId_x(), blockId_y(), blockId_z())
#numBlocks() = (numBlocks_x(), numBlocks_y(), numBlocks_z())

# Warpsize
warpsize() = Base.llvmcall(
    ("""declare i32 @llvm.nvvm.read.ptx.sreg.warpsize() readnone nounwind""",
     """%1 = tail call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
        ret i32 %1"""),
    Int32, ())

#
# Memory management
#

# Synchronization
sync_threads() = Base.llvmcall(
    ("""declare void @llvm.nvvm.barrier0() readnone nounwind""",
     """call void @llvm.nvvm.barrier0()
        ret void"""),
    Void, ())

# Shared memory
setCuSharedMem(shmem, index, value) = Base.llvmcall(
    ("""@shmem = external addrspace(3) global [0 x float]""",
     """%4 = tail call float addrspace(3)* @llvm.nvvm.ptr.gen.to.shared.p3f32.p0f32( float* %0 )
        %5 = getelementptr inbounds float addrspace(3)* %4, i64 %1
        store float %2, float addrspace(3)* %5
        ret void"""),
    Void, (Ptr{Float32}, Int64, Float32), shmem, index-1, value)
getCuSharedMem(shmem, index) = Base.llvmcall(
    ("""@shmem = external addrspace(3) global [0 x float]""",
     """%3 = tail call float addrspace(3)* @llvm.nvvm.ptr.gen.to.shared.p3f32.p0f32( float* %0 )
       %4 = getelementptr inbounds float addrspace(3)* %3, i64 %1
       %5 = load float addrspace(3)* %4
       ret float %5"""),
    Float32, (Ptr{Float32}, Int64), shmem, index-1)

#
# Math
#

# Trigonometric
sin(x::Float32) = Base.llvmcall(
    ("""declare float @__nv_sinf(float)""",
     """%2 = call float @__nv_sinf(float %0)
        ret float %2"""),
    Float32, (Float32,), x)
sin(x::Float64) = Base.llvmcall(
    ("""declare double @__nv_sin(double)""",
     """%2 = call double @__nv_sin(double %0)
        ret double %2"""),
    Float64, (Float64,), x)
cos(x::Float32) = Base.llvmcall(
    ("""declare float @__nv_cosf(float)""",
     """%2 = call float @__nv_cosf(float %0)
        ret float %2"""),
    Float32, (Float32,), x)
cos(x::Float64) = Base.llvmcall(
    ("""declare double @__nv_cos(double)""",
     """%2 = call double @__nv_cos(double %0)
        ret double %2"""),
    Float64, (Float64,), x)

# Rounding
floor(x::Float32) = Base.llvmcall(
    ("""declare float @__nv_floorf(float)""",
     """%2 = call float @__nv_floorf(float %0)
        ret float %2"""),
    Float32, (Float32,), x)
floor(x::Float64) = Base.llvmcall(
    ("""declare double @__nv_floor(double)""",
     """%2 = call double @__nv_floor(double %0)
        ret double %2"""),
    Float64, (Float64,), x)


text:
# Example for linearized modeling with Flux networks
# Author: Philipp Witte, pwitte3@gatech.edu
# Date: April 2020
#

using JUDI, SegyIO, JOLI, Flux, JUDI4Flux

# Set up model structure
n = (120, 100)   # (x,y,z) or (x,z)
d = (10., 10.)
o = (0., 0.)

# Velocity [km/s]
v = ones(Float32,n) .+ 0.4f0
v0 = ones(Float32,n) .+ 0.4f0
v[:, Int(round(end/2)):end] .= 4f0

# Slowness squared [s^2/km^2]
m = (1f0 ./ v).^2
m0 = (1f0 ./ v0).^2
dm = vec(m - m0)

# Setup info and model structure
nsrc = 1	# number of sources
model0 = Model(n, d, o, m0)

# Set up receiver geometry
nxrec = 120
xrec = range(50f0, stop=1150f0, length=nxrec)
yrec = 0f0
zrec = range(50f0, stop=50f0, length=nxrec)

# receiver sampling and recording time
time = 1000f0   # receiver recording time [ms]
dt = 1f0    # receiver sampling interval [ms]

# Set up receiver structure
recGeometry = Geometry(xrec, yrec, zrec; dt=dt, t=time, nsrc=nsrc)

## Set up source geometry (cell array with source locations for each shot)
xsrc = convertToCell([600f0])
ysrc = convertToCell([0f0])
zsrc = convertToCell([20f0])

# Set up source structure
srcGeometry = Geometry(xsrc, ysrc, zsrc; dt=dt, t=time)

# setup wavelet
f0 = 0.01f0     # MHz
wavelet = ricker_wavelet(time, dt, f0)
q = judiVector(srcGeometry, wavelet)

# Set up info structure for linear operators
ntComp = get_computational_nt(srcGeometry, recGeometry, model0)
info = Info(prod(n), nsrc, ntComp)

# return linearized data as Julia array
opt = Options(return_array=true)

# Non-linear forward modeling operator
F0 = judiModeling(info, model0, srcGeometry, recGeometry; options=opt)
num_samples = recGeometry.nt[1] * nxrec

##################################################################################

# Fully connected neural network with linearized modeling operator
n_in = 100
n_out = 10

W1 = randn(Float32, info.n, n_in)
b1 = randn(Float32, info.n)

W2 = judiJacobian(F0, q)
b2 = randn(Float32, num_samples)

W3 = randn(Float32, n_out, num_samples)
b3 = randn(Float32, n_out)

function network(x)
    x = W1*x .+ b1
    x = W2*x .+ b2
    x = W3*x .+ b3
    return x
end

# Gradient
x = zeros(Float32, n_in)
y = randn(Float32, n_out)

# Evaluate MSE loss
loss(x, y) = Flux.mse(network(x), y)

# Compute gradient w.r.t. x and y
Δx, Δy = gradient(loss, x, y)

# Compute gradient for x, y and weights (except for W2)
p = params(x, y, W1, b1, b2, W3, b3)
gs = gradient(() -> loss(x, y), p)

# Access gradients
Δx = gs[x]
ΔW1 = gs[W1]
Δb1 = gs[b1]

# and so on...


text:
using Colors, CSV, DataFrames, Dates, PGFPlotsX
push!(PGFPlotsX.CUSTOM_PREAMBLE, raw"\usetikzlibrary{plotmarks}")
inf_eur_8108_se = CSV.File("data/inf_eur_8108_se.csv") |> DataFrame
sexes = Dict("women"=>"kvinnor", "men"=>"män")
seasontypes = ["H1", "H3", "H1+H3", "B", "H1+B", "H3+B", "H1+H3+B"]

function fluseason(m, y)
    if ((m=="Unknown") || month(Date(m, dateformat"U")) > 6)
       return y
    else
       return y-1
    end
end

function se_dmon_df(path)
    df = CSV.File(path, delim="\t") |> DataFrame
    df[:season] = map(fluseason, df[:month], df[:year])
    join(df, inf_eur_8108_se, on = :season)
end

se_dmon = se_dmon_df("data/se_dmon1851_2019_en.tsv")

function plot_seasontypes(sex, syr, eyr)
    sax = @pgf Axis({"yticklabel style"={"/pgf/number format/use comma"},
              "xticklabel style"={"/pgf/number format/set thousands separator={}"},
              "yticklabel style"={"/pgf/number format/set thousands separator={}"},
              "legend style"={"font=\\tiny"},
              legend_pos="outer north east", xlabel="Säsong", ylabel="Döda månad",
              title = "Antal dödsfall per månad $(sexes[sex]) Sverige",
              xmajorgrids, ymajorgrids})
    plotcolors = distinguishable_colors(length(seasontypes)+1, [RGB(1,1,1)])[2:end]
    for i in 1:length(seasontypes)
        @pgf push!(sax, "\\definecolor{col$(i)}{HTML}{$(hex(plotcolors[i]))}",
            "\\addlegendimage{only marks,col$(i),mark=x}")
    end
    for i in 1:length(seasontypes)
        plot_seasontype(sex, i, syr, eyr, sax, plotcolors[i])
    end
    sax
end

function plot_seasontype(sex, seasontype, syr, eyr, p, plotcolor)
    @pgf push!(p, LegendEntry(seasontypes[seasontype]))
    for m in 1:12
        se_dmon_sub = se_dmon[((se_dmon[:sex].==sex) .& (se_dmon[:month].==monthname(m))
            .& (se_dmon[:seasontype].==seasontype)
            .& (se_dmon[:season].>=syr) .& (se_dmon[:season].<=eyr)), :]
        @pgf push!(p, PlotInc({"only marks", "mark=text", "text mark"="$(m)", "text mark as node",
            "text mark style={font=\\tiny}", color=plotcolor},
            Table([se_dmon_sub[:season], se_dmon_sub[:Deaths]])))
    end
end

max_stars_repo_name: klpn/static-dust

max_issues_repo_name: klpn/static-dust

max_forks_repo_name: klpn/static-dust


text:
#=##############################################################################
# DESCRIPTION
    Blown wing with one rotor half way the midspan on each side.

# AUTHORSHIP
  * Author    : Eduardo J. Alvarez
  * Email     : Edo.AlvarezR@gmail.com
  * Created   : Dec 2019
  * License   : MIT
=###############################################################################

function blownwing(; xfoil=true,
                        pos_bs=[-0.5, 0.5],  # Position on the semispan of every rotor
                        CWs=[false, false],  # Clock-wise rotation of every rotor
                        VehicleType=uns.VLMVehicle,   # Vehicle type
                        add_wing=true,
                        nrevs=30,            # Number of revolutions in simulation
                        # OUTPUT OPTIONS
                        save_path=nothing,
                        run_name="blownwing",
                        prompt=true,
                        verbose=true, v_lvl=0
                        )

    # ------------ PARAMETERS --------------------------------------------------
    if verbose; println("\t"^(v_lvl+1)*"Defining parameters..."); end;

    # Rotor parameters
    rotor_file = "apc10x7.csv"          # Rotor geometry
    data_path = uns.def_data_path       # Path to rotor database
    pitch = 0.0                         # (deg) collective pitch of blades
    n_r = 10                            # Number of blade elements
    # xfoil = false                     # Whether to run XFOIL
    # pos_bs = [-0.5, 0.5]                # Position on the semispan of every rotor
    # CWs = [false, false]                # Clock-wise rotation of every rotor
    offx = 1.25                         # Clearance to LE as a fraction of R
    init_rot = 90                       # Initial rotation

    # Read radius of this rotor and number of blades
    R, B = uns.read_rotor(rotor_file; data_path=data_path)[[1,3]]

    # Simulation parameters
    J = 0.6                             # Advance ratio Vinf/(nD)
    ReD07 = 1.5e6                       # Diameter-based Reynolds at 70% span
    ReD = ReD07/0.7                     # Diameter-based Reynolds
    rho = 1.225                         # (kg/m^3) air density
    mu = 1.81e-5                        # (kg/ms) air dynamic viscosity
    nu = mu/rho
    sound_spd = 343                     # (m/s) speed of sound
    RPM = uns.calc_RPM(ReD, J, R, 2*R, nu) # RPM
    magVinf = J*RPM/60*2*R              # (m/s) freestream velocity
    Minf = magVinf / sound_spd
    Mtip = 2*pi*RPM/60*R / sound_spd
    Rob = 0.075                         # Ratio of rotor radius over span
    b = R/Rob                           # (m) wing span
    Reb = magVinf*b/nu

    # magVinf = 163*0.3048              # (m/s) freestream
    rhoinf = rho                        # (kg/m^3) air density
    alpha = 4.2                         # (deg) angle of attack
    qinf = 0.5*rhoinf*magVinf^2         # (Pa) static pressure

    # Wing geometry
    twist = 0.0                         # (deg) root twist
    lambda = 45.0                       # (deg) sweep
    gamma = 0.0                         # (deg) Dihedral
    # b = 98*0.0254                     # (m) span
    ar = 5.0                            # Aspect ratio
    tr = 1.0                            # Taper ratio
    n_w = 4*2^3                         # Number of horseshoes
    r_w = 3.0                           # Expansion ratio of horeshoes
    n_rot = 1.75                        # Factor for HS density behind rotors

    chord = b/ar
    Rec = magVinf*chord/nu

    # Freestream function
    # Vinf(X, t) = magVinf*[cos(alpha*pi/180), 0.0, sin(alpha*pi/180)]
    # Vinf(X, t) = 1e-12*ones(3)      # (Don't make this zero or things will break)
    # Here I had to give it an initial freestream or the unsteady shedding would
    # in the first step
    Vinf(X, t) = t==0 ? magVinf*[1,0,0] : 1e-12*ones(3)

    # Solver parameters
    # nrevs = 30                        # Number of revolutions in simulation
    nsteps_per_rev = 72                 # Time steps per revolution
    # nsteps_per_rev = 36
    p_per_step = 2                      # Sheds per time step
    # p_per_step = 1
    ttot = nrevs/(RPM/60)               # (s) total simulation time
    nsteps = nrevs*nsteps_per_rev       # Number of time steps
    lambda_vpm = 2.125                  # Core overlap
    overwrite_sigma = lambda_vpm * 2*pi*R/(nsteps_per_rev*p_per_step) # Smoothing core size
    nsteps_relax = 1                    # Relax VPM every this many steps
    vpm_relax = 0.3                     # VPM relaxation factor
    vpm_surface = true                  # Whether to include surfaces in the VPM
    surf_sigma = R/10                   # Smoothing radius of lifting surface
    # vlm_sigma = surf_sigma              # Smoothing radius of VLM
    vlm_sigma = -1                      # NOTE: keep this disabled or the VLM will go awry
    shed_unsteady = true                # Shed particles from unsteady loading
                                        # Max particles for memory pre-allocation
    max_particles = ((2*n_r+1)*B*length(CWs) + 2*n_w+1)*(nrevs*nsteps_per_rev+1)*p_per_step
    plot_disc = false                   # Plot blade discretization for debugging
    wake_coupled = true                 # Coupled VLM solver with VPM
    vlm_rlx = 0.75                      # VLM relaxation (deactivated with -1)
    # vlm_rlx = 0.0
    # vlm_init = true                     # Initialize with the VLM semi-infinite wake solution
    vlm_init = false

    if verbose
        println("\t"^(v_lvl+2)*"J:\t\t$(J)")
        println("\t"^(v_lvl+2)*"ReD07:\t\t$(ReD07)")
        println("\t"^(v_lvl+2)*"RPM:\t\t$(ceil(Int, RPM))")
        println("\t"^(v_lvl+2)*"Mtip:\t\t$(round(Mtip, digits=3))")
        println("\t"^(v_lvl+2)*"Minf:\t\t$(round(Minf, digits=3))")
        println("\t"^(v_lvl+2)*"R/b:\t\t$(round(Rob, digits=3))")
        println("\t"^(v_lvl+2)*"b:\t\t$(round(b, digits=2)) m")
        println("\t"^(v_lvl+2)*"c:\t\t$(round(chord, digits=2)) m")
        println("\t"^(v_lvl+2)*"Reb:\t\t$(ceil(Int, Reb))")
        println("\t"^(v_lvl+2)*"Rec:\t\t$(ceil(Int, Rec))")
        println("\t"^(v_lvl+2)*"Solution time: "*
            "$(round(magVinf*nrevs/(RPM/60)/b, digits=3)) spans ($nrevs revolutions)")
        println("\t"^(v_lvl+2)*"vlm_fsgm:\t\t$(round(vlm_sigma/b, digits=6))")
    end

    # ------------ GENERATING GEOMETRY -----------------------------------------
    if verbose; println("\t"^(v_lvl+1)*"Generating geometry..."); end;

    if length(pos_bs) != length(CWs)
        error("Invalid rotor definition: length(pos_bs) != length(CWs)")
    end

    # Generate clockwise rotor
    rotor_cw = uns.generate_rotor(rotor_file; pitch=pitch,
                                            n=n_r, CW=true, ReD=ReD,
                                            verbose=verbose, xfoil=xfoil,
                                            data_path=data_path,
                                            plot_disc=plot_disc,
                                            verbose=verbose, v_lvl=v_lvl+1)
    # Generate counter-clockwise rotor
    rotor_ccw = vlm.Rotor(!rotor_cw.CW, rotor_cw.r, rotor_cw.chord,
                                            rotor_cw.theta, rotor_cw.LE_x,
                                            rotor_cw.LE_z, rotor_cw.B,
                                            rotor_cw.airfoils)
    vlm.initialize(rotor_ccw, rotor_cw.m)

    base_props = [rotor_cw, rotor_ccw]      # Base rotors

    # Generate the actual rotors to use along wing
    rotors = vlm.Rotor[]
    # @warn("Rotors disabled!")
    # pos_bs = []
    # CWs = []
    for (i, pos) in enumerate(pos_bs)
        # Rotor geometry
        copy_prop = base_props[2^!CWs[i]]
        this_prop = deepcopy(copy_prop)
        # Position
        x = abs(pos)*b/2*tan(pi/180*lambda) - offx*R
        y = pos*b/2
        z = abs(pos)*b/2*tan(pi/180*gamma)
        # Account for angle of attack of wing
        nrm = norm([x,z])
        x = nrm*cos(pi/180*alpha)
        z = -nrm*sin(pi/180*alpha)
        this_O = [x, y, z]
        # Orientation
        this_Oaxis = Float64[1 0 0; 0 1 0; 0 0 1]

        vlm.setcoordsystem(this_prop, this_O, this_Oaxis; user=true)

        # Rotates props
        vlm.rotate(this_prop, (-1)^(!CWs[i]) * init_rot)

        # Adds the original polars that don't get copied in deepcopy
        this_prop.airfoils = copy_prop.airfoils
        this_prop._polars = copy_prop._polars
        this_prop._polarroot = copy_prop._polarroot
        this_prop._polartip = copy_prop._polartip

        push!(rotors, this_prop)
    end

    # Wing discretization
    _pos_bs = unique(abs.(pos_bs))
    if length(pos_bs)!=0 && length(pos_bs)!=1 && length(pos_bs)/length(_pos_bs)!=2
        error("Logic error: Position of rotors is expected to be symmetric.")
    end
    refinement = []
    for pos_b in _pos_bs
        # Add wing section before rotor
        pos = pos_b - R/(b/2)                   # Position along semi span
        if pos > 0                              # Length of segment
            len = pos - (length(refinement)!=0 ? refinement[end][1] : 0)
            nfrac = len                         # fraction of horseshoes
            if length(refinement) != 0
                push!(refinement, [len/2, nfrac/2, r_w])
                push!(refinement, [len/2, nfrac/2, 1/r_w])
            else
                push!(refinement, [len, nfrac, 1/r_w])
            end
        end

        # Add rotor section
        pos = min(pos_b + R/(b/2), 1.0)
        len = pos - (length(refinement)!=0 ? refinement[end][1] : 0)
        nfrac = len
        push!(refinement, [len, n_rot*nfrac, 1.01])
    end
    if length(refinement) == 0
        push!(refinement, [1.0, 1.0, 1/r_w])
    end
    # Add tip
    sumc = sum(ref[1] for ref in refinement)
    if abs(sumc-1.0) > 0.0001
        len = abs(sumc-1)
        nfrac = 1.5*len
        push!(refinement, [len/2, nfrac/2, r_w])
        push!(refinement, [len/2, nfrac/2, 1/r_w])
    end

    # Generate wing
    wing = vlm.simpleWing(b, ar, tr, twist, lambda, gamma;
                                                n=n_w, refinement=refinement)

    # Pitch wing to corresponding angle of attack
    O = zeros(3)                                    # Coordinate system origin
    Oaxis = gt.rotation_matrix2(0.0, -alpha, 0.0)   # Coordinate system axes
    vlm.setcoordsystem(wing, O, Oaxis)

    # ------------- SIMULATION SETUP -------------------------------------------
    if verbose; println("\t"^(v_lvl+1)*"Simulation setup..."); end;

    # ----- VEHICLE DEFINITION
    # System of all FLOWVLM objects
    system = vlm.WingSystem()
    if add_wing; vlm.addwing(system, "Wing", wing); end;
    for (ri, rotor) in enumerate(rotors)
        vlm.addwing(system, "Rotor$ri", rotor)
    end

    # Systems of rotors
    rotor_systems = (rotors, )

    # System solved through VLM solver
    vlm_system = vlm.WingSystem()
    if add_wing; vlm.addwing(vlm_system, "Wing", wing); end;

    # Wake-shedding system
    wake_system = vlm.WingSystem()
    if add_wing; vlm.addwing(wake_system, "Wing", wing); end;

    if VehicleType != uns.QVLMVehicle
        for (ri, rotor) in enumerate(rotors)
            vlm.addwing(wake_system, "Rotor$ri", rotor)
        end
    else
        # Mute colinear warnings. This is needed since the quasi-steady solver
        #   will probe induced velocities at the lifting line of the blade
        uns.vlm.VLMSolver._mute_warning(true)
    end

    # FVS's Vehicle object
    vehicle = VehicleType(   system;
                                vlm_system=vlm_system,
                                rotor_systems=rotor_systems,
                                wake_system=wake_system
                             )

    # ----- MANEUVER DEFINITION
    RPM_fun(t) = 1.0                # RPM (normalized by reference RPM) as a
                                    # function of normalized time

    angle = ()                      # Angle of each tilting system (none in this case)
    sysRPM = (RPM_fun, )            # RPM of each rotor system
    Vvehicle(t) = [-1,0,0]          # Translational velocity of vehicle over Vref
    anglevehicle(t) = zeros(3)      # (deg) angle of the vehicle

    Vref = magVinf                  # (m/s) aircraft velocity during cruise
    RPMref = RPM                    # Reference RPM

    # FVS's Maneuver object
    maneuver = uns.KinematicManeuver(angle, sysRPM, Vvehicle, anglevehicle)

    # Plot maneuver path and controls
    uns.plot_maneuver(maneuver; vis_nsteps=nsteps)

    # ----- SIMULATION DEFINITION
    Vinit = Vref*Vvehicle(0)       # Initial vehicle velocity
    simulation = uns.Simulation(vehicle, maneuver, Vref, RPMref, ttot; Vinit=Vinit)

    monitor_rotor = generate_monitor_prop(J, rho, RPM, nsteps; save_path=save_path,
                                                    run_name=run_name*"_rotors")
    monitor_wing = generate_monitor_wing(wing, b, ar, nsteps, Vinf, rhoinf, qinf,
                                                magVinf, wake_coupled;
                                                save_path=save_path,
                                                run_name=run_name*"_wing")
    monitor(args...) = monitor_rotor(args...) || (add_wing ? monitor_wing(args...) : false)

    # ------------- RUN SIMULATION ---------------------------------------------
    if verbose; println("\t"^(v_lvl+1)*"Running simulation..."); end;
    pfield = uns.run_simulation(simulation, nsteps;
                                      # SIMULATION OPTIONS
                                      Vinf=Vinf,
                                      # SOLVERS OPTIONS
                                      p_per_step=p_per_step,
                                      overwrite_sigma=overwrite_sigma,
                                      vlm_sigma=vlm_sigma,
                                      vpm_surface=vpm_surface,
                                      surf_sigma=surf_sigma,
                                      vlm_init=vlm_init,
                                      vlm_rlx=vlm_rlx,
                                      max_particles=max_particles,
                                      nsteps_relax=nsteps_relax,
                                      relaxfactor=vpm_relax,
                                      wake_coupled=wake_coupled,
                                      shed_unsteady=shed_unsteady,
                                      extra_runtime_function=monitor,
                                      # OUTPUT OPTIONS
                                      save_path=save_path,
                                      run_name=run_name,
                                      prompt=prompt,
                                      verbose=verbose, v_lvl=v_lvl+1,
                                      save_code=splitdir(@__FILE__)[1],
                                      save_horseshoes=false
                                      )
    return pfield, wing, rotors
end


text:
#
# Generate an initial point in a grid, with a minimum distance defined
#

# To plot:
# using Plots
# scatter([ p[i][1] for i in 1:N ],[ p[i][2] for i in 1:N ],markersize=0.5,label="")

import Random

# Function that introduces a perturbation in the grid point
perturbation(step,σ) = -σ + 2*σ*rand()

"""

```
initial_point(N,side,tol;seed=123)
```

Generates a grid of N particles in a square of side `side`, with
perturbed coordinates but which satisfy a minimum distance greater
than `tol`

`N`: number of particles.

`side`: side of the square

`tol`: minimum distance allowed between particles

The optional keyword parameter `seed`, if set to `-1`, produces a
random seed at each run.

## Example

Generate 10_000 points in a grid of side 100, with a guaranteed minimum
distance greater than 0.5:

```
p = initial_point(10_000,100,0.5)
```

Use a random seed:

```
p = initial_point(10_000,100,0.5,seed=-1)
```

"""
function initial_point(N,side,tol;seed=123)

  # Use a different seed if desired
  if seed > 0
    Random.seed!(seed)
  else
    Random.seed!()
  end
  p = [ zeros(2) for i in 1:N ]

  # Properties of the regular grid
  l = ceil(Int,sqrt(N))
  step = (side-tol)/l
  if tol > step
    error("tol must be smaller than (side-tol)/√N = $step")
  end

  # The grid has l^2 points, but this is generally greater
  # than N. Thus, we generate list of points to be skiped
  skip = Int[]
  while length(skip) < l^2 - N
    i = rand(1:l^2)
    if findfirst(isequal(i), skip) == nothing
      push!(skip,i)
    end
  end

  # Maximum perturbation
  σ = (step-tol)/2

  # Generate points
  ip = 0
  igrid = 0
  x = [ tol/2, tol/2 ]
  for i in 1:l
    for j in 1:l
      igrid += 1
      if findfirst(isequal(igrid),skip) != nothing
        continue
      end
      # update x, with a perturbation of ±0.1*step
      ip += 1
      p[ip] .= x .+ perturbation(step,σ)
      x[2] = x[2] + step
    end
    x[2] = tol/2
    x[1] = x[1] + step
  end

  return p
end

# From data
initial_point(data::Data;tol=0.9,seed=123) = initial_point(data.N,data.side,tol,seed=seed)


text:
# This file is a part of GERDAMetadata.jl, licensed under the MIT License (MIT).

export PolCalFunc

struct PolCalFunc{N,T<:Number} <:Function
    params::NTuple{N,T}

    PolCalFunc(params::T...) where T = new{length(params),T}(params)
end

function (f::PolCalFunc{N,T})(x::U) where {N,T,U}
    R = promote_type(T, U)
    y = zero(R)
    xn = one(U)
    @inbounds for p in f.params
        y = R(fma(p, xn, y))
        xn *= x
    end
    y
end

function Base.convert(::Type{PolCalFunc{N,T}}, p::PropDict) where {N,T}
    funcstr = p.func
    if !(funcstr in ("pol1", "[0]+[1]*x", "pol2"))
        error("Unsupported function \"$funcstr\" for $(PolCalFunc{N,T})")
    end

    coeffs = zeros(T, N)
    for (i,v) in p.params
        coeffs[i + 1] = v
    end
    PolCalFunc(coeffs...)
end

function Base.convert(::Type{Dict{Int, PolCalFunc{N,T}}}, p::PropDict) where {N,T}
    calfuncs = Dict{Int, PolCalFunc{N,T}}()
    for (ch, caldict) in p
        calfuncs[ch] = convert(PolCalFunc{2,Float64}, caldict)
    end
    calfuncs
end

const CalFuncDict = Dict{Int,PolCalFunc{2,Float64}}
export CalFuncDict


text:
mutable struct CSVExporter{T <: AbstractSchema} <: AbstractExporter
    isenabled::Bool
    schema::T
end

function isenabled(exporter::CSVExporter)
    return exporter.isenabled
end

function enable!(exporter::CSVExporter)
    exporter.isenabled = true
end

function disable!(exporter::CSVExporter)
    exporter.isenabled  = false
end

function (store::CSVExporter{<:AbstractSchema})(path::Path, data::DataFrame)
    disable!(store)
    path₁ = joinpath(get_directory(path), get_filename(path))
    # We are trying to create a new file.
    if !is_queryable_file(path₁)
        try
            CSV.write(path₁, data)
        catch e
            println(e)
            CImGui.OpenPopup("Do you have permission to create the file?")
        end
    # We are modifying an existing file.
    elseif is_writeable_file(path₁)
        try
            CSV.write(path₁, data)
        catch e
            println(e)
            CImGui.OpenPopup("Do you have permission to modify the file?")
        end
    else
        CImGui.OpenPopup("Do you have permission to modify the file?")
    end
    handle_export_error_messages()

end

function handle_export_error_messages()
    if CImGui.BeginPopupModal("Do you have permission to create the file?", C_NULL, CImGui.ImGuiWindowFlags_AlwaysAutoResize)
        CImGui.Text("Unable to write to the specified file.\nPlease verify that you have permission to create the file.\n\n")
        CImGui.Separator()
        CImGui.Button("OK", (120, 0)) && CImGui.CloseCurrentPopup()
        CImGui.SetItemDefaultFocus()
        CImGui.EndPopup()
    end

    if CImGui.BeginPopupModal("Do you have permission to modify the file?", C_NULL, CImGui.ImGuiWindowFlags_AlwaysAutoResize)
        CImGui.Text("Unable to write to the specified file.\nPlease verify that: \n   (1) the file exists; \n   (2) you have permission to modify the file.\n\n")
        CImGui.Separator()
        CImGui.Button("OK", (120, 0)) && CImGui.CloseCurrentPopup()
        CImGui.SetItemDefaultFocus()
        CImGui.EndPopup()
    end

    if CImGui.BeginPopupModal("Do you have permission to read the file?", C_NULL, CImGui.ImGuiWindowFlags_AlwaysAutoResize)
        CImGui.Text("Unable to access the specified file.\nPlease verify that: \n   (1) the file exists; \n   (2) you have permission to read the file.\n\n")
        CImGui.Separator()
        CImGui.Button("OK", (120, 0)) && CImGui.CloseCurrentPopup()
        CImGui.SetItemDefaultFocus()
        CImGui.EndPopup()
    end
end


text:
using JuMP, EAGO

                     m = Model()

                     EAGO.register_eago_operators!(m)

                     @variable(m, -1 <= x[i=1:3] <= 1)

                     @variable(m, -13.110901270484293 <= q <= 11.380819522292354)

                     add_NL_constraint(m, :(softplus(-0.7773677229963925 + -0.31823111196481735*softplus(0.13898320039278467 + -0.4573031975765818*softplus(-0.1658975405753922 + 0.8948668185465118*$(x[1]) + 0.5677868700589963*$(x[2]) + -0.004745367697401193*$(x[3])) + -0.027363793963717686*softplus(0.8084147176169236 + 0.6887886991760568*$(x[1]) + 0.9976411528938542*$(x[2]) + 0.9554800615635051*$(x[3])) + -0.7118578003946046*softplus(-0.23665048660081967 + 0.22941639672835912*$(x[1]) + 0.6694807543091978*$(x[2]) + 0.08612932953468189*$(x[3]))) + -0.05869662098445039*softplus(0.7177153834386609 + 0.046197114005355644*softplus(-0.1658975405753922 + 0.8948668185465118*$(x[1]) + 0.5677868700589963*$(x[2]) + -0.004745367697401193*$(x[3])) + 0.8341427099559482*softplus(0.8084147176169236 + 0.6887886991760568*$(x[1]) + 0.9976411528938542*$(x[2]) + 0.9554800615635051*$(x[3])) + -0.5961814570241306*softplus(-0.23665048660081967 + 0.22941639672835912*$(x[1]) + 0.6694807543091978*$(x[2]) + 0.08612932953468189*$(x[3]))) + -0.31920840200501477*softplus(-0.05621054225465549 + -0.4685096496776473*softplus(-0.1658975405753922 + 0.8948668185465118*$(x[1]) + 0.5677868700589963*$(x[2]) + -0.004745367697401193*$(x[3])) + -0.723697578017108*softplus(0.8084147176169236 + 0.6887886991760568*$(x[1]) + 0.9976411528938542*$(x[2]) + 0.9554800615635051*$(x[3])) + 0.643520408356284*softplus(-0.23665048660081967 + 0.22941639672835912*$(x[1]) + 0.6694807543091978*$(x[2]) + 0.08612932953468189*$(x[3])))) + softplus(-0.2800668423712529 + 0.5241807567635033*softplus(0.13898320039278467 + -0.4573031975765818*softplus(-0.1658975405753922 + 0.8948668185465118*$(x[1]) + 0.5677868700589963*$(x[2]) + -0.004745367697401193*$(x[3])) + -0.027363793963717686*softplus(0.8084147176169236 + 0.6887886991760568*$(x[1]) + 0.9976411528938542*$(x[2]) + 0.9554800615635051*$(x[3])) + -0.7118578003946046*softplus(-0.23665048660081967 + 0.22941639672835912*$(x[1]) + 0.6694807543091978*$(x[2]) + 0.08612932953468189*$(x[3]))) + 0.9218858277065758*softplus(0.7177153834386609 + 0.046197114005355644*softplus(-0.1658975405753922 + 0.8948668185465118*$(x[1]) + 0.5677868700589963*$(x[2]) + -0.004745367697401193*$(x[3])) + 0.8341427099559482*softplus(0.8084147176169236 + 0.6887886991760568*$(x[1]) + 0.9976411528938542*$(x[2]) + 0.9554800615635051*$(x[3])) + -0.5961814570241306*softplus(-0.23665048660081967 + 0.22941639672835912*$(x[1]) + 0.6694807543091978*$(x[2]) + 0.08612932953468189*$(x[3]))) + 0.0068491484591501894*softplus(-0.05621054225465549 + -0.4685096496776473*softplus(-0.1658975405753922 + 0.8948668185465118*$(x[1]) + 0.5677868700589963*$(x[2]) + -0.004745367697401193*$(x[3])) + -0.723697578017108*softplus(0.8084147176169236 + 0.6887886991760568*$(x[1]) + 0.9976411528938542*$(x[2]) + 0.9554800615635051*$(x[3])) + 0.643520408356284*softplus(-0.23665048660081967 + 0.22941639672835912*$(x[1]) + 0.6694807543091978*$(x[2]) + 0.08612932953468189*$(x[3])))) + softplus(-0.0923150493931284 + -0.18688964829603716*softplus(0.13898320039278467 + -0.4573031975765818*softplus(-0.1658975405753922 + 0.8948668185465118*$(x[1]) + 0.5677868700589963*$(x[2]) + -0.004745367697401193*$(x[3])) + -0.027363793963717686*softplus(0.8084147176169236 + 0.6887886991760568*$(x[1]) + 0.9976411528938542*$(x[2]) + 0.9554800615635051*$(x[3])) + -0.7118578003946046*softplus(-0.23665048660081967 + 0.22941639672835912*$(x[1]) + 0.6694807543091978*$(x[2]) + 0.08612932953468189*$(x[3]))) + 0.4699561510424055*softplus(0.7177153834386609 + 0.046197114005355644*softplus(-0.1658975405753922 + 0.8948668185465118*$(x[1]) + 0.5677868700589963*$(x[2]) + -0.004745367697401193*$(x[3])) + 0.8341427099559482*softplus(0.8084147176169236 + 0.6887886991760568*$(x[1]) + 0.9976411528938542*$(x[2]) + 0.9554800615635051*$(x[3])) + -0.5961814570241306*softplus(-0.23665048660081967 + 0.22941639672835912*$(x[1]) + 0.6694807543091978*$(x[2]) + 0.08612932953468189*$(x[3]))) + -0.26284635568255643*softplus(-0.05621054225465549 + -0.4685096496776473*softplus(-0.1658975405753922 + 0.8948668185465118*$(x[1]) + 0.5677868700589963*$(x[2]) + -0.004745367697401193*$(x[3])) + -0.723697578017108*softplus(0.8084147176169236 + 0.6887886991760568*$(x[1]) + 0.9976411528938542*$(x[2]) + 0.9554800615635051*$(x[3])) + 0.643520408356284*softplus(-0.23665048660081967 + 0.22941639672835912*$(x[1]) + 0.6694807543091978*$(x[2]) + 0.08612932953468189*$(x[3])))) - $q <= 0.0))

                     @objective(m, Min, q)

                     return m

max_stars_repo_name: PSORLab/RSActivationFunctions

max_issues_repo_name: PSORLab/RSActivationFunctions

max_forks_repo_name: PSORLab/RSActivationFunctions


text:
################################################# FILE DESCRIPTION #########################################################

# This file contains graph mutation methods

################################################# IMPORT/EXPORT ############################################################

export addvertex!, addedge!, rmvertex!, rmedge!

################################################# ADDVERTEX! ###############################################################

""" Add a vertex to the graph. Returns the internal identifier of the new vertex """
function addvertex!(g::Graph)
   g.nv += 1
   g.indxs = addvertex!(indxs(g))
   addvertex!(g.vdata)
   g.lmap = addvertex!(lmap(g))
   return nv(g)
end

""" Add a labelled vertex to the graph """
function addvertex!(g::Graph, l)
   if !haslabel(g, l)
      g.nv += 1
      g.indxs = addvertex!(indxs(g))
      addvertex!(g.vdata)
      g.lmap = addvertex!(lmap(g), l)
   end
   return decode(g, l)
end

###
# + FOR ADDVERTEX
###
""" Shorthand notation for adding a labelled vertex to the graph """
function (+)(g::Graph, x)
   addvertex!(g, x)
end

""" Shorthand notation for adding multiple lablled vertices """
(+)(g::Graph, xs::AbstractVector) = [g + x for x in xs]

################################################# ADDEDGE! ################################################################

""" Add an edge to the graph. Returns true if successfull """
function addedge!(g::Graph, e::EdgeID)
   if hasedge(g, e)
      return false
   else
      g.ne += 1
      addedge!(indxs(g), e, ne(g))
      addedge!(edata(g))
      return true
   end
end

###
# SETINDEX FOR ADDEDGE
###
""" Shorthand notation for adding an edge between labelled vertices """
function Base.setindex!(g::Graph, y, x)
   addedge!(g, (g + x)=>(g + y))
end

""" Shorthand notation for adding multiple edges between labelled vertices """
function Base.setindex!(g::Graph, ys::Vector, x)
   for y in ys
      addedge!(g, (g + x)=>(g + y))
   end
end

################################################# RMVERTEX! ################################################################

""" Remove a vertex from the graph """
function rmvertex!(g::Graph, v::VertexID)
   if hasvertex(g, v)
      # Decrement vertex count
      g.nv -= 1

      # Reorder entries in the Edge DataFrame
      reorder!(edata(g), indxs(g).nzval)

      # Remove indexes for edges on v
      g.indxs, erows = rmvertex!(indxs(g), v)

      # Calculate new edge count
      g.ne = nnz(indxs(g))

      # Remove rows from vertex dataframe
      rmvertex!(vdata(g), v)

      # Remove rows from edge dataframe
      rmedge!(edata(g), erows)

      # Remove vertex labels
      g.lmap  = rmvertex!(lmap(g), v)
      return nothing
   else
      error("Vertex $v doesn't exist")
   end
end

""" Remove a list of vertices from the graph """
function rmvertex!(g::Graph, vs::VertexList)
   if all(hasvertex(g, vs))
      g.nv -= length(vs)

      # Reorder entries in the Edge DataFrame
      reorder!(edata(g), indxs(g).nzval)

      # Remove indexes for edges on v
      g.indxs, erows = rmvertex!(indxs(g), vs)

      # Calculate new edge count
      g.ne = nnz(indxs(g))

      # Remove rows from vertex dataframe
      rmvertex!(vdata(g), vs)

      # Remove rows from edge dataframe
      rmedge!(edata(g), erows)

      # Remove vertex labels
      g.lmap  = rmvertex!(lmap(g), vs)
      return nothing
   else
      error("Invalid vertices: $(filter(x->!hasvertex(g, x), vs))")
   end
end

""" Remove a labelled vertex from the graph """
(-)(g::Graph, x) = rmvertex!(g, decode(g, x))

""" Remove a list of labelled vertices from the graph """
function (-)(g::Graph, xs::Vector)
   rmvertex!(g, decode(g, xs))
end

################################################# RMEDGE! ####################################################################

""" Remove an edge from the graph """
function rmedge!(g::Graph, e::EdgeID)
   if hasedge(g, e)
      g.ne -= 1

      # Remove index for e
      erow = rmedge!(indxs(g), e)

      # Remove row from edge dataframe
      rmedge!(edata(g), erow)

      # Reorder entries in the Edge DataFrame
      reorder!(edata(g), indxs(g).nzval)
      return nothing
   else
      error("Invalid edge $e")
   end
end


text:
# Tests for SPMF-code

using NonlinearEigenproblemsTest
using NonlinearEigenproblems
using Test
using LinearAlgebra
using Random
using SparseArrays

@testset "SPMF stability" begin
    n=5;
    Random.seed!(1)
    A0=sparse([  0.297288    0.311111   0.583708  -0.0504512  -1.72976
  0.382396    2.29509    0.963272  -0.693654    0.795949
 -0.597634   -2.26709    0.458791  -1.77383     0.670062
 -0.0104452   0.529966  -0.522337   0.120766    0.550852
          -0.839027    0.431422   0.408396  -0.757633   -0.0633746]);
    A1=sparse([  1.33694    -0.165136   0.763499  -1.28905     1.29992
 -0.0731486  -2.11537    0.378599  -0.33527     0.206364
 -0.745464   -0.066768  -0.645597   0.0704676  -1.00886
 -1.22006     1.22246   -0.664646   0.341794   -0.850056
 -0.0531773   0.567695  -1.80303    1.73517     1.12941 ]);

    t=3.0

    minusop = S -> -S
    oneop = S -> one(S)
    expmop = S -> exp(-t*S)
    fi=[minusop, oneop, expmop];

    J = SparseMatrixCSC(1.0I, n, n)
    nep1 = SPMF_NEP([J, A0, A1], fi)
    nep2 = SPMF_NEP([J, A0, A1], fi; Schur_fact=true)

    m=4;
    V=randn(n,m);
    λ=3;
    S=randn(m,m);
    @inferred compute_MM(nep1,S,V)

    compute_Mlincomb(nep1,λ,V)

    @inferred compute_Mlincomb(nep1,3,V)
    @inferred compute_Mlincomb(nep1,3+1im,V)

    nep2=SPMF_NEP(get_Av(nep1),get_fv(nep1),Ftype=Float64);

    @inferred compute_Mlincomb(nep1,3,V)
    @inferred compute_Mlincomb(nep1,3+1im,V)

end


text:
"""
   Module for performing Sinc interpolation
From
https://github.com/christiangil/GP-Research/blob/master/julia/src/interpolation_functions.jl
https://github.com/christiangil/GP-Research/blob/master/julia/src/general_functions.jl

Authors: Joe Ninan (original)
         Christian Gilbertson (Converted to Julia and optimized)
         Eric Ford (Further adapted/optimizations)
"""
module SincInterpolation

using Base.Math
using DSP
using Interpolations
using RvSpectMLBase
#import ..RvSpectML: searchsortednearest

export spectra_interpolate

include("low_level.jl")

include("convenience.jl")
export interp_chunk_to_shifted_grid_sinc, interp_chunk_to_shifted_grid_sinc!
export interp_chunk_to_grid_sinc, interp_chunk_to_grid_sinc!

end # module