text:
# This file was generated by the Julia Swagger Code Generator
# Do not modify this file directly. Modify the swagger specification instead.

struct VirtualNetworkGatewaysApi <: SwaggerApi
    client::Swagger.Client
end

"""

Creates or updates a virtual network gateway in the specified resource group.
Param: resourceGroupName::String (required)
Param: virtualNetworkGatewayName::String (required)
Param: parameters::VirtualNetworkGateway (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Return: VirtualNetworkGateway
"""
function virtualNetworkGatewaysCreateOrUpdate(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, parameters, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "PUT", VirtualNetworkGateway, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}", ["azure_auth"], parameters)
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "virtualNetworkGatewayName", virtualNetworkGatewayName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json", "text/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json", "text/json"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

Deletes the specified virtual network gateway.
Param: resourceGroupName::String (required)
Param: virtualNetworkGatewayName::String (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Return: Nothing
"""
function virtualNetworkGatewaysDelete(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "DELETE", Nothing, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}", ["azure_auth"])
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "virtualNetworkGatewayName", virtualNetworkGatewayName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json", "text/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json", "text/json"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

Generates VPN client package for P2S client of the virtual network gateway in the specified resource group.
Param: resourceGroupName::String (required)
Param: virtualNetworkGatewayName::String (required)
Param: parameters::VpnClientParameters (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Return: String
"""
function virtualNetworkGatewaysGeneratevpnclientpackage(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, parameters, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "POST", String, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}/generatevpnclientpackage", ["azure_auth"], parameters)
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "virtualNetworkGatewayName", virtualNetworkGatewayName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json", "text/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json", "text/json"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

Gets the specified virtual network gateway by resource group.
Param: resourceGroupName::String (required)
Param: virtualNetworkGatewayName::String (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Return: VirtualNetworkGateway
"""
function virtualNetworkGatewaysGet(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "GET", VirtualNetworkGateway, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}", ["azure_auth"])
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "virtualNetworkGatewayName", virtualNetworkGatewayName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json", "text/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json", "text/json"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

This operation retrieves a list of routes the virtual network gateway is advertising to the specified peer.
Param: resourceGroupName::String (required)
Param: virtualNetworkGatewayName::String (required)
Param: peer::String (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Return: GatewayRouteListResult
"""
function virtualNetworkGatewaysGetAdvertisedRoutes(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, peer::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "POST", GatewayRouteListResult, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}/getAdvertisedRoutes", ["azure_auth"])
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "virtualNetworkGatewayName", virtualNetworkGatewayName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "peer", peer)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json", "text/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json", "text/json"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

The GetBgpPeerStatus operation retrieves the status of all BGP peers.
Param: resourceGroupName::String (required)
Param: virtualNetworkGatewayName::String (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Param: peer::String
Return: BgpPeerStatusListResult
"""
function virtualNetworkGatewaysGetBgpPeerStatus(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; peer=nothing, _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "POST", BgpPeerStatusListResult, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}/getBgpPeerStatus", ["azure_auth"])
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "virtualNetworkGatewayName", virtualNetworkGatewayName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "peer", peer)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json", "text/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json", "text/json"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

This operation retrieves a list of routes the virtual network gateway has learned, including routes learned from BGP peers.
Param: resourceGroupName::String (required)
Param: virtualNetworkGatewayName::String (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Return: GatewayRouteListResult
"""
function virtualNetworkGatewaysGetLearnedRoutes(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "POST", GatewayRouteListResult, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}/getLearnedRoutes", ["azure_auth"])
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "virtualNetworkGatewayName", virtualNetworkGatewayName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json", "text/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json", "text/json"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

Gets all virtual network gateways by resource group.
Param: resourceGroupName::String (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Return: VirtualNetworkGatewayListResult
"""
function virtualNetworkGatewaysList(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "GET", VirtualNetworkGatewayListResult, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways", ["azure_auth"])
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json", "text/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json", "text/json"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

Resets the primary of the virtual network gateway in the specified resource group.
Param: resourceGroupName::String (required)
Param: virtualNetworkGatewayName::String (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Param: gatewayVip::String
Return: VirtualNetworkGateway
"""
function virtualNetworkGatewaysReset(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; gatewayVip=nothing, _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "POST", VirtualNetworkGateway, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}/reset", ["azure_auth"])
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "virtualNetworkGatewayName", virtualNetworkGatewayName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "gatewayVip", gatewayVip)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json", "text/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json", "text/json"] : [_mediaType])
    Swagger.exec(_ctx)
end

export virtualNetworkGatewaysCreateOrUpdate, virtualNetworkGatewaysDelete, virtualNetworkGatewaysGeneratevpnclientpackage, virtualNetworkGatewaysGet, virtualNetworkGatewaysGetAdvertisedRoutes, virtualNetworkGatewaysGetBgpPeerStatus, virtualNetworkGatewaysGetLearnedRoutes, virtualNetworkGatewaysList, virtualNetworkGatewaysReset


text:
function strategic_pref(m_prefs::Vector{Vector{Int}},
                        f_prefs::Vector{Vector{Int}},
                        m_matched::Vector{Int},
                        f_matched::Vector{Int},
                        P_count::Vector{Int},
                        no_f::Vector{Int},
                        false_prefs::Vector{Vector{Int}})
    m = length(m_prefs)
    n = length(f_prefs)
    results = fill([0], (n, factorial(m)))
    f_require = zeros(Int64, n)
    for i in 1:n
        if f_matched[i] == f_prefs[i][1]
            f_require[i] = 1
        end
        if p_count[i] <= 1
            f_require[i]+=10
        end
    end

    for i in 1:n
        if f_require[i] == 0
            f_new_prefs = copy(f_prefs)
            for j in 1:factorial(m)
                f_new_prefs[i] = false_prefs[j]
                m_new_matched, f_new_matched = my_deferred_acceptance(m_prefs, f_new_prefs)
                if findfirst(f_prefs, f_new_matched[i]) < findfirst(f_prefs, f_matched[i])
                    results[i, j] = false_prefs[j]
                end
            end
        end
    end
    return results
end

ext: jl


text:
include("NonSimpleNumField/Field.jl")
include("NonSimpleNumField/Conjugates.jl")
include("NonSimpleNumField/ComplexEmbeddings.jl")


text:
include("setup.jl")

srand(5)
simname = "blocks"
hyper = false

quc = 95
qu = quc/100

if simid == 1
    a1 = 1/10
    a = 20.0
    aζ = a

    M = 25
elseif simid == 2
    a1 = 1/10
    a = 40.0
    aζ = a

    M = 12
elseif simid == 5
    a1 = 1/10
    a = 40.0
    aζ = a

    M = 25
elseif simid == 6
    a1 = 1/10
    a = 20.0
    aζ = a

    M = 12
elseif simid == 3
    a1 = 1/10
    a = 20.0 # initialisation
    aζ = a

    M = 25
    hyper = true

    σa = 1.0
elseif simid == 4
    a1 = 1/10
    a = 20.0
    aζ = a

    M = 12
    hyper = true

    σa = 1.5
else
    error("")
end

pri = InverseGamma(0.1, 0.1)
pri2 = InverseGamma(0.3, 0.3)

if hyper
    iterations = 200000
else
    iterations = 200000
end
#
#M = (length(td)-1) ÷ H # observed intervals per bin
#r = length(td)-1 - H*M
#assert(H*M == length(td)-1)
H = (N-1)÷M
r = length(td)-1 - H*M

ss = [0.1,0.13,0.15,0.23,0.25,0.4,0.44,0.65,0.76,0.78,0.81]
const hh = 3.655606*[4,-5,3,-4,5,-4.2,2.1,4.3,-3.1,2.1,-4.2]

tx = linspace(0, 1, 1000)
s3(t) = 10 + sum(hh[1:last(searchsorted(ss, t))])

display(plot(tx, s3.(tx), ylim = (0, 31), size = (400, 400/1.4), color=colorant"#0044FF",  label = LaTeXString("\$s_3\$")))

savefig("output/volatility/fig$simname.pdf")

Xf = euler1(ttf, 0., b, s3, zeros(ttf), dW(ttf))
Xd = Xf[1:step:end]

sub = 10
lim = (-5.2, 15)
display(plot(td[1:sub:end], Xd[1:sub:end], linewidth = 0.4, ylim = lim, size = (400, 400/1.4), color=colorant"#0044FF",  label=L"X"))
savefig("output/volatility/fig$(simname)path.pdf")

# compute independent posterior

post = Vector(H)
Z = Vector(H)

for i in 1:H
    if i == H
        ii = 1+(i-1)*M:N
    else
        ii = 1+(i-1)*M:(i)*M+1
    end
    tx = td[ii]

    x = diff(Xd[ii])./sqrt.(diff(tx)) # normalize obs
    Z[i] = sum(diff(Xd[ii]).^2)
    post[i] = ConjugatePriors.posterior((0., pri), Normal, x)
end

lim = (-2, 80)
bands = map(p->sqrt(quantile(p, (1 - qu)/2)), post), map(p->sqrt(quantile(p, 1 - (1 - qu)/2)), post)

ttplot = linspace(0, 1, 1000)[2:end-1]

plot(ttplot, s3.(ttplot), ylim = lim, size = (400, 400/1.4), linewidth = 0.7, color="red", label=L"s");
plot!(piecewise( Bridge.SamplePathBand(td[1:M:end], bands...) ),
    color=colorant"#0044FF", label = "marginal $quc\\% cred.~band",);
display(Plots.current())
savefig("output/volatility/fig$(simname)postind$simid.pdf")

v = zeros(H)
ζ = zeros(H)

# initialize MCMC with a draw from the prior

v[1] = rand(InverseGamma(a1, a1))
for i in 2:H
    ζ[i] = rand(InverseGamma(aζ, inv(v[i-1]/aζ)))
    v[i] = rand(InverseGamma(a, inv(ζ[i]/a)))
end

subsampl = 1
burnin = 0
subinds = (1 + burnin):subsampl:iterations
samples = zeros(H, length(subinds))

state = Bridge.mcstart(v)
si = 1
printiter = 10
as = []
acc = 0
for iter in 1:iterations
    # move: parameters
    v[1] = rand(InverseGamma(a1 + aζ + M/2, a1 + aζ/ζ[2] + Z[1]/2/dt))
    for h in 2:H-1
        v[h] = rand(InverseGamma(aζ + a + M/2, (a/ζ[h] + aζ/ζ[h+1] + Z[h]/2/dt)))
    end
    v[H] = rand(InverseGamma(aζ + (M+r)/2, a/ζ[H] + Z[H]/2/dt))

    # move: latent
    if iter in subinds
        samples[:, si] = v
        si += 1
    end
    for h in 2:H
        ζ[h] = rand(InverseGamma(aζ + a, (aζ/v[h-1] + a/v[h])))
    end

    state = Bridge.mcnext(state, v)

    # move: hyper parameters
    if hyper
        a˚ = a + σa*randn()
        while a˚ < eps()
            a˚ = a + σa*randn()
        end

        lq = logpdf(pri2, a)
        lq += (2*(H-1))*(a*log(a) - lgamma(a))
        s = sum(log(v[k-1]*v[k]*ζ[k]*ζ[k]) + (1/v[k-1] + 1/v[k])/ζ[k]  for k = 2:H)
        lq += -a*s

        lq˚ = logpdf(pri2, a˚)
        lq˚ += (2*(H-1))*(a˚*log(a˚) - lgamma(a˚))
        lq˚ += -a˚*s
        mod(iter, printiter) == 0 && print("$iter \t α ", a˚)
        if rand() < exp(lq˚ - lq)*cdf(Normal(0, σa), a)/cdf(Normal(0, σa), a˚)
            acc = acc + 1
            aζ = a = a˚
            mod(iter, printiter) == 0 && print("✓")
        end
        mod(iter, printiter) == 0 && println()
        push!(as, a)
    end

end
hyper && println("acc prob hyper ", acc/iterations)
writecsv("output/volatility/samples$simname$simid.csv", samples')
if hyper
    writecsv("output/volatility/samplesas$simname$simid.csv", as)
end

lim = (-2, 80)

bands = mapslices(v->sqrt(quantile(v, (1-qu)/2)), samples, (2,))[:],  mapslices(v->sqrt(quantile(v, 1 - (1 - qu)/2)), samples, (2,))[:]
ttplot = linspace(0, 1, 1000)[2:end-1]

plot(ttplot, s3.(ttplot), ylim = lim, size = (400, 400/1.4), linewidth = 0.7, color="red", label=L"s");
plot!(piecewise( Bridge.SamplePathBand(td[1:M:end], bands...) ),
    color=colorant"#0044FF", label = "marginal $quc\\% cred.~band",);
display(Plots.current())
savefig("output/volatility/fig$(simname)post$simid.pdf")

open(joinpath("output", "volatility", "$(simname)$(simid)info.txt"), "w") do f
    println(f, "α1 ", a1)
    !hyper && println(f, "α ", a)
    println(f, "M ", M)
    println(f, "iterations ", iterations)
    println(f, "samples at ", subinds)
    println(f, "$quc % credible bands")

    println(f, "hyper ", hyper)
    if hyper
        println(f, "acc ", round(acc/iterations, 3))
        println(f,  "σa ", σa)
    end
end

# TODO
# use quantiles
# add samplepath


text:
export Layer, Connection, GridNetwork, HyperNEATIndividual, height_of
## Neuron Layer

mutable struct Layer
    size::Int64
    values::Array{Float64}
    biases::Array{Float64}
    activ_func::Function
    depth::Float64
    connections_towards::Array
end

function Layer(size::Int64, depth::Float64, activ_func::Function)
    values = zeros(size)
    biases = zeros(size)
    Layer(size, values, biases, activ_func, depth, [])
end

## Connection between layers

mutable struct Connection
    layer_from::Layer
    layer_to::Layer
    weights::Array{Float64}
end

function Connection(layer_from::Layer, layer_to::Layer)
    values = rand(Float64, (layer_from.size, layer_to.size))
    c = Connection(layer_from, layer_to, values)
    push!(layer_to.connections_towards, c)
    c
end

function normalize(i::Int64, layer_size::Int64)
    if layer_size <= 1
        0
    else
        -1 + (i-1) * 2 / (layer_size - 1)
    end
end

function Connection(generator_func::Function, layer_from::Layer, layer_to::Layer)
    w = zeros((layer_from.size, layer_to.size))
    for i in 1:layer_from.size
        for j in 1:layer_to.size
            x1 = normalize(j, layer_from.size)
            y1 = layer_from.depth
            x2 = normalize(j, layer_to.size)
            y2 = layer_to.depth
            w[i, j] = generator_func([x1, y1, x2, y2])
        end
    end
    Connection(layer_from, layer_to, w)
end

function Connection(values::Array{Float64}, layer_from::Layer, layer_to::Layer)
    w = reshape(values, (layer_from.size, layer_to.size))
    c = Connection(layer_from, layer_to, w)
    push!(layer_to.connections_towards, c)
    c
end

function set_weights!(conn::Connection, generator_func::Function)
    w = zeros((conn.layer_from.size, conn.layer_to.size))
    for i in 1:conn.layer_from.size
        for j in 1:conn.layer_to.size
            x1 = normalize(j, conn.layer_from.size)
            y1 = conn.layer_from.depth
            x2 = normalize(j, conn.layer_to.size)
            y2 = conn.layer_to.depth
            w[i, j] = generator_func([x1, y1, x2, y2])[1]
        end
    end
    conn.weights = w
end

## Full Network

mutable struct GridNetwork
    layers::Array{Layer}
    connections::Array{Connection}
end

function GridNetwork(cfg::Dict)
    layers::Array{Layer} = []
    layers_size = [cfg["n_in"]]
    append!(layers_size, cfg["hn_hidden_layers"])
    push!(layers_size, cfg["n_out"])
    # Add the neuron layers
    for i in 1:length(layers_size)
        depth = normalize(i, length(layers_size))
        push!(layers, Layer(layers_size[i], depth, cfg["hn_activ_func"]))
    end
    # Add connextions between layers
    connections::Array{Connection} = []
    for j in 2:length(layers) # Layer_to
        if cfg["hn_link_all_layers"] # Connect from all previous layers
            for i in 1:j-1 # Layer_from
                push!(connections, Connection(layers[i], layers[j]))
            end
        else # Only connect from previous layer
            push!(connections, Connection(layers[j-1], layers[j]))
        end
    end
    # println("Network ", getfield.(layers, :size))
    GridNetwork(layers, connections)
end

function set_weights!(net::GridNetwork, generator_func::Function)
    for c in net.connections
        set_weights!(c, generator_func)
    end
end

## Process network

function process(net::GridNetwork, last_features::Array{Float64})
    # Set values of the first
    net.layers[1].values = reshape(last_features, (1, net.layers[1].size))

    for l in net.layers[2:length(net.layers)]
        l.values = zeros((1, l.size)) # Reset sum
        for c in l.connections_towards
            v = reshape(c.layer_from.values, (1, c.layer_from.size))
            l.values += v * c.weights
        end
        l.values = l.activ_func.(l.values)
    end
    sort!(net.connections, by=x-> x.layer_to.depth)
    for c in net.connections

    end
    net.layers[end].values
end

"Process an array of inputs"
function process(net::GridNetwork, last_features::Array{Array{Float64}})
    out::Array=[]
    for x in last_features
        push!(out, process(net, x))
    end
    out
end

## HyperNEAT fitness transformator

mutable struct HyperNEATIndividual <: NEATIndiv
    genes::Dict
    fitness::Array{Float64}
    neuron_pos::Array{Float64}
    network::Network
    activ_functions::Dict
    hn_net::GridNetwork
end

function HyperNEATIndividual(cfg::Dict)
    n_in = 4
    n_out = 1
    neuron_pos::Array{Float64}=[]

    # Neuron positions: Input and output
    neuron_pos = -n_in:n_out

    # Neurons activation functions
    activ_functions = Dict()
    for i in neuron_pos
        activ_functions[i]=rand(cfg["activation_functions"])
    end

    # Add genes
    genes=Dict()
    if cfg["start_fully_connected"]
        for i in 1:n_in
            for j in 1:n_out
                inno = i * n_out + j
                genes[inno] = Gene(-1.0 * i, 1.0 * j, inno)
            end
        end
        cfg["innovation_max"] = maximum([cfg["innovation_max"], n_in * n_out])
    end

    sort!(neuron_pos)

    fitness = -Inf .* ones(cfg["d_fitness"])

    neat_network = Network(n_in, n_out, Dict())
    grid_net = GridNetwork(cfg)

    HyperNEATIndividual(genes, fitness, neuron_pos, neat_network, activ_functions, grid_net)
end

function HyperNEATIndividual(cfg::Dict, s::String)
	NEATIndiv(cfg, s)
end

## Build / process

function build!(indiv::HyperNEATIndividual)
    reset(indiv.network)
    build_NEAT!(indiv)
    # Network generator function
    generator::Function = x -> process_NEAT(indiv, x)
    set_weights!(indiv.hn_net, generator)
end

function process(indiv::HyperNEATIndividual, last_features::Array{Float64})
    process(indiv.hn_net, last_features)
end


text:
"""
An instance of the m-set problem.

Values are not restricted.

It can be formalised as follows:

``\\max \\sum_i \\mathrm{values}_i x_i``
``\\mathrm{s.t.} \\sum_i x_i \\leq m, \\quad x \\in \\{0, 1\\}^d``
"""
struct MSetInstance <: CombinatorialInstance
  values::Vector{Float64}
  m::Int

  function MSetInstance(values::Vector{Float64}, m::Int)
    # Error checking.
    if m < 0
      error("m is less than zero: there is no solution.")
    end

    if m == 0
      error("m is zero: the only solution is to take no items.")
    end

    # Return a new instance.
    new(values, m)
  end
end

values(i::MSetInstance) = i.values
m(i::MSetInstance) = i.m

value(i::MSetInstance, o::Int) = values(i)[o]
values(i::MSetInstance, o) = values(i)[o]
dimension(i::MSetInstance) = length(values(i))

struct MSetSolution <: CombinatorialSolution
  instance::MSetInstance
  items::Vector{Int} # Indices to the chosen items.
end

function value(s::MSetSolution)
  return sum(s.instance.values[i] for i in s.items)
end


text:
# Script to calculate the availabily of solar power over the year
using DataFrames, FeatherFiles, Statistics

const SUN_AREA = 16.0 # area of the solar panels in m²

function calc_average_power(df)
    return SUN_AREA * mean(df.Power_Generation)
end

function calc_peak_power(df)
    return SUN_AREA * maximum(df.Power_Generation)
end

function calc_capacity_factor(df)
    return 100 * calc_average_power(df) / calc_peak_power(df)
end

function calc_rel_availability(df, min_power)
    minpower = df[df.Power_Generation * SUN_AREA .> min_power, :Power_Generation]
    return 100 * size(minpower, 1) / size(df, 1)
end

if !isdefined(@__MODULE__, :df) df=DataFrame(load("data/solaryear.feather")) end

av = calc_average_power(df)
println("Average solar power [W]:                     ", round(av, digits=1))
println("Capacity factor [%]:                          ", round(calc_capacity_factor(df), digits=1))
println("Percentage of solar power availability   [%]: ", round(calc_rel_availability(df, 2.0), digits=1))
println("Percentage of time for more than 50% av. [%]: ", round(calc_rel_availability(df, av/2), digits=1))
println("Percentage of time for more than average [%]: ", round(calc_rel_availability(df, av), digits=1))


text:
import Base: ∈

export Rectification

"""
    RectificationCache{N<:Real}

Struct that is used as a cache for [`Rectification`](@ref)s.
"""
struct RectificationCache{N<:Real}
    # empty for now
end

"""
    Rectification{N<:Real, S<:LazySet{N}}

Type that represents the rectification of a convex set.

### Fields

- `X`     -- convex set
- `cache` -- storage of information computed before

### Notes

Given a vector ``v = (v_1, …, v_n)``, its rectification is defined as
``\\text{rectify}(v) = (v_1', …, v_n')`` such that ``v_i' = \\max(v_i, 0)`` for
each ``i = 1, …, n``.

The extension to a set ``X`` is defined elementwise:

```math
    \\text{rectify}(X) = \\{\\text{rectify}(x) \\mid x ∈ X\\}
```

The rectification of a convex set ``X`` is not necessarily convex.
It can be expressed exactly as the union of the intersection of ``X`` with the
nonnegative orthant and the projection of the intersection of ``X`` with each
other orthant.
This can be seen as follows.

First we observe that rectification distributes with union.

```math
    \\text{rectify}(X_1 ∪ … ∪ X_m) = ⋃_j \\text{rectify}(X_j)
```

Next we express ``X`` as the union of the intersection of ``X`` with each
orthant ``O``.

```math
    X = ⋃_j (X ∩ O_j)
```

Thus we have

```math
    \\text{rectify}(X) = \\text{rectify}((X ∩ O_1) ∪ … ∪ (X ∩ O_m)) = ⋃_j \\text{rectify}(X ∩ O_j).
```

Clearly, ``\\text{rectify}(X ∩ O_j) = X`` if ``O_j`` is the nonnegative orthant.

For example, consider a two-dimensional case and call the orthants
``O_1, …, O_4`` in clockwise fashion, starting with the nonnegative orthant.
We conclude that

```math
    \\text{rectify}(X) = (X ∩ O_1) ∪ \\text{rectify}(X ∩ O_2) ∪ \\text{rectify}(X ∩ O_3) ∪ \\text{rectify}(X ∩ O_4).
```

The rectification of the intersection in the nonpositive orthant,
``\\text{rectify}(X ∩ O_3)``, is either the empty set or the singleton
containing the origin.
The rectification of ``X ∩ O_2`` and ``X ∩ O_4`` both result in flat
``1``-dimensional line segments on the corresponding hyperplane of ``O_1``.
"""
struct Rectification{N<:Real, S<:LazySet{N}}
    X::S
    cache::RectificationCache{N}

    # default constructor that initializes cache
    function Rectification{N, S}(X::S) where {N<:Real, S<:LazySet{N}}
        cache = RectificationCache{N}()
        return new{N, S}(X, cache)
    end
end

# convenience constructor without type parameter
Rectification(X::S) where {N<:Real, S<:LazySet{N}} = Rectification{N, S}(X)

"""
    dim(r::Rectification)::Int

Return the dimension of a rectification.

### Input

- `r` -- rectification

### Output

The ambient dimension of the rectification.
"""
function dim(r::Rectification)::Int
    return dim(r.X)
end

"""
    σ(d::AbstractVector{N}, r::Rectification{N}) where {N<:Real}

Return the support vector of a rectification.

### Input

- `d` -- direction
- `r` -- rectification

### Output

If the rectified set is one-dimensional, we convert it to an `Interval` and call
a specialized method.
Otherise, we throw an error because we currently do not support higher
dimensions.
"""
function σ(d::AbstractVector{N}, r::Rectification{N}) where {N<:Real}
    if dim(r) == 1
        # rectification in 1D is easy
        return σ(d, Rectification(convert(Interval, r.X)))
    end
    error("the exact support vector of a rectification is not implemented")
end

"""
    σ(d::AbstractVector{N},
      r::Rectification{N, <:AbstractHyperrectangle{N}}) where {N<:Real}

Return the support vector of the rectification of a hyperrectangular set.

### Input

- `d` -- direction
- `r` -- rectification of a hyperrectangular set

### Output

The support vector in the given direction.

### Algorithm

Let ``r(·)`` be the rectification of a vector respectively a set, and let ``H``
be a hyperrectangle.
Then ``σ_{r(H)}(d) = r(σ_{H}(d))``.
"""
function σ(d::AbstractVector{N},
           r::Rectification{N, <:AbstractHyperrectangle{N}}) where {N<:Real}
    return rectify(σ(d, r.X))
end

"""
    σ(d::AbstractVector{N},
      r::Rectification{N, <:CartesianProduct{N}}) where {N<:Real}

Return the support vector of the rectification of a Cartesian product of two
convex sets.

### Input

- `d` -- direction
- `r` -- rectification of a Cartesian product of two convex sets

### Output

The support vector in the given direction.

### Algorithm

Rectification distributes with the Cartesian product.
Let ``r(·)`` be the rectification of a set.
We can just query the support vector for ``r(X)`` and ``r(Y)`` recursively:
``σ_{r(X × Y)}(d) = σ_{r(X)}(d_X) × σ_{r(Y)}(d_Y)``, where ``x × y``
concatenates vectors ``x`` and ``y``.
"""
function σ(d::AbstractVector{N},
           r::Rectification{N, <:CartesianProduct{N}}) where {N<:Real}
    X, Y = r.X.X, r.X.Y
    n1 = dim(X)
    return vcat(σ(d[1:n1], Rectification(X)), σ(d[n1+1:end], Rectification(Y)))
end

"""
    σ(d::AbstractVector{N},
      r::Rectification{N, <:CartesianProductArray{N}}) where {N<:Real}

Return the support vector of the rectification of a Cartesian product of a
finite number of convex sets.

### Input

- `d` -- direction
- `r` -- rectification of a Cartesian product of a finite number of convex sets

### Output

The support vector in the given direction.

### Algorithm

Rectification distributes with the Cartesian product.
Let ``r(·)`` be the rectification of a set.
We can just query the support vector for each subspace recursively:
``σ_{r(X_1 × ⋯ × X_m)}(d) = σ_{r(X_1)}(d_{X_1}) × ⋯ × σ_{r(X_m)}(d_{X_m})``,
where ``x × y`` concatenates vectors ``x`` and ``y``.
"""
function σ(d::AbstractVector{N},
           r::Rectification{N, <:CartesianProductArray{N}}) where {N<:Real}
    svec = similar(d)
    i = 1
    for X in array(r.X)
        nX = dim(X)
        j = i + nX - 1
        svec[i:j] = σ(d[i:j], Rectification(X))
        i = j + 1
    end
    return svec
end

"""
    an_element(r::Rectification{N})::Vector{N} where {N<:Real}

Return some element of a rectification.

### Input

- `r` -- rectification

### Output

An element in the rectification.
The implementation relies on the `an_element` function of the wrapped set.
"""
function an_element(r::Rectification{N})::Vector{N} where {N<:Real}
    return rectify(an_element(r.X))
end

"""
    ∈(x::AbstractVector{N}, r::Rectification{N})::Bool where {N<:Real}

Check whether a given point is contained in a rectification.

### Input

- `x` -- point/vector
- `r` -- rectification

### Output

`true` iff ``x ∈ r``.

### Algorithm

We first scan for negative entries in the vector.
If there are any, the vector is not contained in the rectification.

Next we ask a membership query in the wrapped set.
If the answer is positive, the vector is contained in the rectification.

Otherwise, we scan for zero entries in the vector.
If there are none, membership reduces to membership in the wrapped set, and so
the answer is negative.

Finally, if there are zero entries in the vector and the vector is not contained
in the wrapped set, we give up and throw an error.
"""
function ∈(x::AbstractVector{N}, r::Rectification{N})::Bool where {N<:Real}
    # scan for negative entries
    if any(xi -> xi < zero(N), x)
        return false
    end

    # membership test in the wrapped set
    if x ∈ r.X
        return true
    end

    # scan for zero entries
    if all(xi -> !iszero(xi), x)
        return false
    end

    # give up
    error("cannot determine membership of a vector with zero entries in a " *
          "lazy rectification")
end

"""
    isempty(r::Rectification)::Bool

Check whether a rectification is empty or not.

### Input

- `r` -- rectification

### Output

`true` iff the wrapped set is empty.
"""
function isempty(r::Rectification)::Bool
    return isempty(r.X)
end

"""
    isbounded(r::Rectification)::Bool

Determine whether a rectification is bounded.

### Input

- `r` -- rectification

### Output

`true` iff the rectification is bounded.

### Algorithm

Let ``X`` be the set wrapped by rectification ``r``.
We first check whether ``X`` is bounded (because then ``r`` is bounded).
Otherwise, we check unboundedness of ``X`` in direction ``(1, 1, …, 1)``, which
is sufficient for unboundedness of ``r``; this step is not necessary but rather
a heuristics.
Otherwise, we check boundedness of ``X`` in every positive unit direction, which
is sufficient and necessary for boundedness of ``r``.
"""
function isbounded(r::Rectification{N})::Bool where {N<:Real}
    # check boundedness of the wrapped set
    if isbounded(r.X)
        return true
    end

    # heuristics: check boundedness in the one-vector direction
    n = dim(r.X)
    if ρ(ones(N, n), r.X) == N(Inf)
        return false
    end

    # check boundedness in positive unit directions
    @inbounds for i in 1:n
        d = SingleEntryVector(i, n, one(N))
        if ρ(d, r.X) == N(Inf)
            return false
        end
    end
    return true
end


text:
# ENV["JULIA_DEBUG"] = "all"

pushfirst!(LOAD_PATH, joinpath(@__DIR__, "..", "packages"))
import VSCodeDebugger
popfirst!(LOAD_PATH)

Base.load_julia_startup()

VSCodeDebugger.startdebugger()


text:
#=
For the sake of DQMC measurements it's often useful to iterate through the
lattice in a specific way. Masks allow for exactly this.

For example:

Charge density correlations are given by ⟨nᵢnⱼ⟩, a N by N matrix (with N being
the numebr of lattice sites). However we are typically not interested in the
real space charge density correlation, but rather it's Fourier transform, the
charge density structure factor. It is given by
C(q) = ∑ᵢⱼ exp(im*q*(rᵢ - rⱼ)) ⟨nᵢnⱼ⟩
Given that the exponential uses the difference between two lattice positions r
we do not need to save the whole matrix ⟨nᵢnⱼ⟩. We can perform the summation
over equal rᵢ - rⱼ immediately to "compress" ⟨nᵢnⱼ⟩. To do so we need reframe
the observable as ⟨n[i]n[i+Δ(i)]⟩, where Δ[i] gives us indices ordered by
distance and direction, so that we can record
C(rι - rⱼ) = C(Δ) = ∑(Δ) ⟨n[i]n[i+Δ(i)]⟩
=#

abstract type AbstractMask end

"""
    RawMask(lattice)

Constructs a mask that returns `1:N` for each site.
"""
struct RawMask <: AbstractMask
    nsites::Int64
end
RawMask(lattice::AbstractLattice) = RawMask(length(lattice))
Base.getindex(mask::RawMask, source, ::Colon) = 1:mask.nsites
# TODO name?
getorder(mask::RawMask, source) = enumerate(1:mask.nsites)
Base.size(mask::RawMask) = (mask.nsites, mask.nsites)
Base.size(mask::RawMask, dim) = dim <= 2 ? mask.nsites : 1
function directions(mask::RawMask, lattice::AbstractLattice)
    pos = positions(lattice)
    [p2 .- p1 for p2 in pos for p1 in pos]
end

################################################################################
### dir -> (src, trg) masks
################################################################################

"""
    DistanceMask(lattice) <: AbstractMask

Constructs a mask that orders sites by distance and direction relative to each
other site.

Related Functions:
* `getorder(mask)`: Returns an iterable of (idx, src, trg) tuples, ordered by
distance. `idx` has a 1:1 correspondence with a directions, i.e. every
`(idx, trg, src)` pair which points in the same direction will have the same `idx`.
* `getdirorder(mask, idx)`: Returns all (src, trg) pairs which point in `idx`
direction.
* `directions(mask, lattice)`: Returns a list of directions which can be indexed
by the `idx` returned from `getorder` to get the corresponding direction.
* `length(mask)`: Number of unqiue directions.

Warning: For this to work correctly the lattice must provide the neighbors in
order. Furthermore each bond is assumed to be of equal length.
"""
abstract type DistanceMask <: AbstractMask end
DistanceMask(lattice::AbstractLattice) = MethodError(DistanceMask, (lattice))
DistanceMask(mc::MonteCarloFlavor, model::Model) = DistanceMask(lattice(model))

# SimpleDistanceMask deals with lattices where each distance vector exists for
# every site in the lattice (assuming periodic bonds)
struct SimpleDistanceMask <: DistanceMask
    targets::Matrix{Int64}
end
function default_distance_mask(lattice::AbstractLattice)
    targets = Array{Int64}(undef, length(lattice), length(lattice))
    for origin in 1:length(lattice)
        new_sites = [origin]
        sites = [origin]
        marked = fill(false, length(lattice))
        marked[origin] = true

        while !isempty(new_sites)
            old_sites = copy(new_sites)
            new_sites = Int64[]
            for site in old_sites
                append!(new_sites, mark_unmarked(lattice, marked, site))
            end
            append!(sites, new_sites)
        end
        targets[origin, :] .= sites
    end

    SimpleDistanceMask(targets)
end
function mark_unmarked(lattice, marked, from)
    @assert from != 0
    new_sites = Int64[]
    for to in neighbors(lattice, from)
        if !marked[to]
            marked[to] = true
            push!(new_sites, to)
        end
    end
    new_sites
end

# All (dir, src, trg) in mask
function getorder(mask::SimpleDistanceMask)
    ((dir, src, trg) for src in 1:size(mask.targets, 1)
                     for (dir, trg) in enumerate(mask.targets[src, :])
    )
end

# All (src, trg) in dir
function getdirorder(mask::SimpleDistanceMask, dir)
    ((src, mask.targets[src, dir]) for src in 1:size(mask.targets, 1))
end

# Number of source sites
nsources(mask::SimpleDistanceMask) = size(mask.targets, 1)
Base.length(mask::SimpleDistanceMask) = size(mask.targets, 1)
dirlength(mask::SimpleDistanceMask, dir_idx) = size(mask.targets, 1)
dirlengths(mask::SimpleDistanceMask) = (size(mask.targets, 1) for _ in 1:size(mask.targets, 1))
"""
    directions(mask, lattice)

Returns a vector of directions in the order emposed by the given mask.

For a `RawMask` the output directly mimics the mask, i.e.
`directions(mask, lattice)[idx]` is the direction to
`trg = mask[src, idx]`.
For a `DistanceMask` the `directions(mask, lattice)[dir_idx]` return the
direction of `getdirorder(mask, dir_idx)`.
"""
function directions(mask::SimpleDistanceMask, lattice::AbstractLattice)
    pos = positions(lattice)
    [p .- pos[1] for p in pos[mask.targets[1, :]]]
end

# VerboseDistanceMask can deal with lattices that have different bond
# directions.
struct VerboseDistanceMask <: DistanceMask
    targets::Vector{Vector{Tuple{Int64, Int64}}}
end
function getorder(mask::VerboseDistanceMask)
    ((dir, src, trg) for dir in eachindex(mask.targets)
                     for (src, trg) in mask.targets[dir]
    )
end
getdirorder(mask::VerboseDistanceMask, dir) = ((src, trg) for (src, trg) in mask.targets[dir])

# Number of source sites
function nsources(mask::VerboseDistanceMask)
    out = -1
    for xs in mask.targets
        out = max(out, mapreduce(first, max, xs))
    end
    out
end
Base.length(mask::VerboseDistanceMask) = length(mask.targets)
dirlength(mask::DistanceMask, dir_idx) = length(mask.targets[dir_idx])
dirlengths(mask::DistanceMask) = length.(mask.targets)

function directions(mask::VerboseDistanceMask, lattice::AbstractLattice)
    pos = MonteCarlo.positions(lattice)
    dirs = [pos[src] - pos[trg] for (src, trg) in first.(mask.targets)]
    dirs
end
function VerboseDistanceMask(lattice, wrap)
    _positions = positions(lattice)
    directions = Vector{Float64}[]
    # (src, trg), first index is dir, second index irrelevant
    bonds = [Tuple{Int64, Int64}[] for _ in 1:length(lattice)]

    for origin in 1:length(lattice)
        for (trg, p) in enumerate(_positions)
            d = round.(_positions[origin] .- p .+ wrap[1], digits=6)
            for v in wrap[2:end]
                new_d = round.(_positions[origin] .- p .+ v, digits=6)
                if norm(new_d) < norm(d)
                    d .= new_d
                end
            end
            # I think the rounding will allow us to use == here
            idx = findfirst(dir -> dir == d, directions)
            if idx === nothing
                push!(directions, d)
                if length(bonds) < length(directions)
                    push!(bonds, Tuple{Int64, Int64}[])
                end
                push!(bonds[length(directions)], (origin, trg))
            else
                push!(bonds[idx], (origin, trg))
            end
        end
    end

    temp = sortperm(directions, by=norm)
    VerboseDistanceMask(bonds[temp])
end

################################################################################
### src -> (dir, trg) masks (restriced)
################################################################################

"""
    RestrictedSourceMask(mask::DistanceMask, N_directions)

A RestrictedSourceMask is a mask that allows indexing `(dir, trg)` tuples by
`src`, where the number of available directions is initially restricted.

As such it implements `getorder(mask, src)`.
"""
struct RestrictedSourceMask
    targets::Vector{Vector{Tuple{Int64, Int64}}}
end

function RestrictedSourceMask(mask::DistanceMask, directions)
    targets = [Tuple{Int64, Int64}[] for _ in 1:nsources(mask)]
    for dir in 1:directions
        for (src, trg) in getdirorder(mask, dir)
            push!(targets[src], (dir, trg))
        end
    end
    RestrictedSourceMask(targets)
end

getorder(mask::RestrictedSourceMask, src) = mask.targets[src]

DistanceMask(lattice::Chain) = default_distance_mask(lattice)
DistanceMask(lattice::CubicLattice) = default_distance_mask(lattice)
DistanceMask(lattice::SquareLattice) = default_distance_mask(lattice)
DistanceMask(lattice::TriangularLattice) = default_distance_mask(lattice)


text:
### A Pluto.jl notebook ###
# v0.14.5

using Markdown
using InteractiveUtils

# ╔═╡ acd87eb2-b0e9-11eb-3bf7-bde51637d662
md"""
# [Day 21: RPG Simulator 20XX](https://adventofcode.com/2015/day/21)

Little Henry Case got a new video game for Christmas. It's an [RPG](https://en.wikipedia.org/wiki/Role-playing_video_game), and he's stuck on a boss. He needs to know what equipment to buy at the shop. He hands you the [controller](https://en.wikipedia.org/wiki/Game_controller).

In this game, the player (you) and the enemy (the boss) take turns attacking. The player always goes first. Each attack reduces the opponent's hit points by at least `1`. The first character at or below `0` hit points loses.

Damage dealt by an attacker each turn is equal to the attacker's damage score minus the defender's armor score. An attacker always does at least `1` damage. So, if the attacker has a damage score of `8`, and the defender has an armor score of `3`, the defender loses `5` hit points. If the defender had an armor score of `300`, the defender would still lose `1` hit point.

Your damage score and armor score both start at zero. They can be increased by buying items in exchange for gold. You start with no items and have as much gold as you need. Your total damage or armor is equal to the sum of those stats from all of your items. You have 100 hit points.

Here is what the item shop is selling:

```
Weapons:    Cost  Damage  Armor
Dagger        8     4       0
Shortsword   10     5       0
Warhammer    25     6       0
Longsword    40     7       0
Greataxe     74     8       0

Armor:      Cost  Damage  Armor
Leather      13     0       1
Chainmail    31     0       2
Splintmail   53     0       3
Bandedmail   75     0       4
Platemail   102     0       5

Rings:      Cost  Damage  Armor
Damage +1    25     1       0
Damage +2    50     2       0
Damage +3   100     3       0
Defense +1   20     0       1
Defense +2   40     0       2
Defense +3   80     0       3

```

You must buy exactly one weapon; no dual-wielding. Armor is optional, but you can't use more than one. You can buy 0-2 rings (at most one for each hand). You must use any items you buy. The shop only has one of each item, so you can't buy, for example, two rings of Damage +3.

For example, suppose you have `8` hit points, `5` damage, and `5` armor, and that the boss has `12` hit points, `7` damage, and `2` armor:

-   The player deals `5-2 = 3` damage; the boss goes down to 9 hit points.
-   The boss deals `7-5 = 2` damage; the player goes down to 6 hit points.
-   The player deals `5-2 = 3` damage; the boss goes down to 6 hit points.
-   The boss deals `7-5 = 2` damage; the player goes down to 4 hit points.
-   The player deals `5-2 = 3` damage; the boss goes down to 3 hit points.
-   The boss deals `7-5 = 2` damage; the player goes down to 2 hit points.
-   The player deals `5-2 = 3` damage; the boss goes down to 0 hit points.

In this scenario, the player wins! (Barely.)

You have 100 hit points. The boss's actual stats are in your puzzle input. **What is the least amount of gold you can spend and still win the fight?**
"""

# ╔═╡ 61ef7fce-2cd7-42d8-825a-3337a726ee78
puzzle_input = "Hit Points: 103
Damage: 9
Armor: 2"

# ╔═╡ Cell order:
# ╟─acd87eb2-b0e9-11eb-3bf7-bde51637d662
# ╟─61ef7fce-2cd7-42d8-825a-3337a726ee78


text:
using nctools
using NCDatasets

# f = "/mnt/g/Researches/CMIP6/CMIP6_ChinaHW_mergedFiles/HItasmax/hist-GHG/HItasmax_day_ACCESS-CM2_hist-GHG_r1i1p1f1_gn_19610101-20141231.nc"
# f = "/mnt/z/ChinaHW/CMIP6_ChinaHW_cluster/HItasmax/ncell_4/ssp126/clusterId_HItasmax_movTRS_EC-Earth3_m95.nc"
f = "z:/ChinaHW/CMIP6_ChinaHW_mergedFiles/HItasmax/historical/HItasmax_day_ACCESS-CM2_historical_r1i1p1f1_gn_18500101-20141231.nc"

nc = nc_open(f)
fid = NCDatasets.NCDataset(f)
# nc_dims(f)
@time data = nc["HI"][:];


text:
using RobHood

#function main(portfilename)
    portfilename="./YahooDatabase10.csv";
    portfile = portfilename;
    portfdat = readdlm(portfile,',');
    portfolio = portfdat[:,1];
    description = portfdat[:,2];

    nS = length(portfolio);
    nT,x,y,group = RobHood.readPortData(portfolio,nS);

    nS,nT,x,y,group,ymat = RobHood.vecToMat(x,y,group);
    zbar = RobHood.getzbar(x,ymat,group,nS,nT);
    M,stdevs = RobHood.getVarCovMatrix(x,ymat,group,nS,nT);
    mu,minvar,minstd = RobHood.getEffFrontier(zbar,M,nS);

    RobHood.tsplot(x,y,group)
    RobHood.efffrontplot(stdevs,zbar,mu,minstd,group,"Standard deviation","Expected return (%)")
    RobHood.efffrontplot(stdevs,zbar,mu,minvar,group,"Variance","Expected return (%)")
#end

#main(ARGS[1]);
#main("./YahooDatabase10.csv");


text:
### A Pluto.jl notebook ###
# v0.17.3

using Markdown
using InteractiveUtils

# ╔═╡ 8738d1c4-6907-4a7c-96bf-0467b6eb696d
begin
	import Pkg
	Pkg.develop("PoreMatMod")
end

# ╔═╡ ee100c2d-30aa-4b29-b85e-49417e1ed91c
# load required packages (Pluto.jl will automatically install them)
using PoreMatMod, PlutoUI

# ╔═╡ 172f819b-fca8-433a-9a72-e533078e814c
using PoreMatMod.ExampleHelpers

# ╔═╡ 8d523993-6e85-443a-9949-12030552b457
md"""
## Example: correct disorder and remove guest molecules from experimental data
"""

# ╔═╡ 33992496-1700-4033-8deb-694f82bdd1bc
input_file_message()

# ╔═╡ dc03627f-3da3-4175-b52e-664522df2302
xtal_folder_message()

# ╔═╡ 4be347c1-3f1a-40c1-ae38-f82ed692381e
rc[:paths][:crystals]

# ╔═╡ de84b4a3-a365-4860-9729-2377367c64db
moiety_folder_message()

# ╔═╡ b6dff24a-d0a0-4824-8bb2-2dcb60196b0a
rc[:paths][:moieties]

# ╔═╡ 5b71d14a-be80-4ac3-8983-62571d0d4e7d
md"""
!!! example \"the task\"
	we have the experimental structure of SIFSIX-Cu-2-i, which features disordered pyridyl rings in the linkers---presumably as an artifact of X-ray structure determination---and acetylene guest molecules in the pores.  We wish to (i) correct the disorder by selecting a single conformation for each ring and (ii) remove the guest molecules from its pores.

**Parent crystal structure**: first, we read in the `.cif` file describing the SIFSIX-Cu-2-i parent structure, which presents disordered ligands and guest molecules in the pores.
"""

# ╔═╡ 6d9c3b97-fd26-470c-8acf-8ce10b33b82d
begin
	# read in the parent xtal
	parent = Crystal("SIFSIX-2-Cu-i.cif", check_overlap=false)

	infer_bonds!(parent, true)	# infer bonds
	view_structure(parent)      # view structure
end

# ╔═╡ c0feae1a-a228-40eb-a234-e58617fa71dd
fragment_construction_note()

# ╔═╡ ba265b61-9341-48fd-9f93-befd3e65d315
md"""
**Query fragment 1 (disordered ring)**: second, we construct a query fragment to match the disordered rings in the parent structure by cutting one out of the parent structure. we mask all atoms of the query fragment except those belonging to a single conformation of the ring. the masked hydrogen and carbon atoms below are shown in light pink and dark pink, respectively.
"""

# ╔═╡ f2907335-798c-4f9f-bbab-fa8763fb43bb
query_disordered_ring = moiety("disordered_ligand!.xyz");

# ╔═╡ efd5d374-929c-4851-9219-d8e2b86ebb85
view_query_or_replacement("disordered_ligand!.xyz")

# ╔═╡ 3077d0db-01e7-4aab-b183-c0f69a1f2da3
with_terminal() do
	display_query_or_replacement_file("disordered_ligand!.xyz")
end

# ╔═╡ 10911157-64eb-485b-86f1-e83dc201b054
md"""
**Query fragment 2 (guest molecule)**: we also construct an acetylene query fragment to match the guest molecules in the parent structure.
"""

# ╔═╡ db0efdc0-9d29-46ca-8992-39cd7a9ad36c
query_guest = moiety("acetylene.xyz");

# ╔═╡ b5a090eb-5796-44bf-a19c-3705e99d26dd
view_query_or_replacement("acetylene.xyz")

# ╔═╡ 83d00463-ae3b-47d8-b65d-ff8a0aa522e8
with_terminal() do
	display_query_or_replacement_file("acetylene.xyz")
end

# ╔═╡ 25ed4da3-525c-4045-82c4-b3cbf8e707e3
md"""
**Replacement fragment**: next, we construct a replacement fragment---a (non-disordered) pyridyl ring---as a corrected version of the first query fragment that represented the disordered ligand.
"""

# ╔═╡ b57e57d8-897b-466a-b2b5-517afd969123
replacement_ring = moiety("4-pyridyl.xyz");

# ╔═╡ fee26c78-75c2-4844-acdb-d2c4cd71d654
view_query_or_replacement("4-pyridyl.xyz")

# ╔═╡ e85d27a8-ec86-4e38-92a4-f8a2ad9a0ce3
with_terminal() do
	display_query_or_replacement_file("4-pyridyl.xyz")
end

# ╔═╡ da89adc2-0688-44c6-9fd2-791bd13c8d74
md"""
**Find and replace**: finally,
1. search the parent MOF for the first query fragment (disordered rings) and effect the replacements with the corrected (single-conformation ring), then
2. search the parent for the second query fragment (guest molecules) as disconnected components, and delete them.

Hooray; we have a simulation-ready SIFSIX-Cu-2-i structure. 💖

n.b.
* if we had not passed the `disconnected_component=true` kwarg, the algorithm would have found and removed the sides of the pyridyl rings which contain a H-C-C-H fragment!
"""

# ╔═╡ 74aa19d2-b1a4-4333-9ff9-e6ea74e7d989
begin
	# repair ring disorder
	child = replace(parent, query_disordered_ring => replacement_ring)

	# search for disconnected acetylene components
	search = substructure_search(query_guest, child, disconnected_component=true)
	# delete guest molecules
	child = substructure_replace(search, nothing)

	view_structure(child)
end

# ╔═╡ 11095805-7c76-42f4-836d-919c2cb27d1c
write_cif_message()

# ╔═╡ c5e14b94-427d-4684-9dd7-bc44d965c570
write_cif(child, "simulation_ready_SIFSIX-Cu-2-i.cif")

# ╔═╡ Cell order:
# ╟─8738d1c4-6907-4a7c-96bf-0467b6eb696d
# ╟─8d523993-6e85-443a-9949-12030552b457
# ╠═ee100c2d-30aa-4b29-b85e-49417e1ed91c
# ╠═172f819b-fca8-433a-9a72-e533078e814c
# ╟─33992496-1700-4033-8deb-694f82bdd1bc
# ╟─dc03627f-3da3-4175-b52e-664522df2302
# ╠═4be347c1-3f1a-40c1-ae38-f82ed692381e
# ╟─de84b4a3-a365-4860-9729-2377367c64db
# ╠═b6dff24a-d0a0-4824-8bb2-2dcb60196b0a
# ╟─5b71d14a-be80-4ac3-8983-62571d0d4e7d
# ╠═6d9c3b97-fd26-470c-8acf-8ce10b33b82d
# ╟─c0feae1a-a228-40eb-a234-e58617fa71dd
# ╟─ba265b61-9341-48fd-9f93-befd3e65d315
# ╠═f2907335-798c-4f9f-bbab-fa8763fb43bb
# ╟─efd5d374-929c-4851-9219-d8e2b86ebb85
# ╟─3077d0db-01e7-4aab-b183-c0f69a1f2da3
# ╟─10911157-64eb-485b-86f1-e83dc201b054
# ╠═db0efdc0-9d29-46ca-8992-39cd7a9ad36c
# ╟─b5a090eb-5796-44bf-a19c-3705e99d26dd
# ╟─83d00463-ae3b-47d8-b65d-ff8a0aa522e8
# ╟─25ed4da3-525c-4045-82c4-b3cbf8e707e3
# ╠═b57e57d8-897b-466a-b2b5-517afd969123
# ╟─fee26c78-75c2-4844-acdb-d2c4cd71d654
# ╟─e85d27a8-ec86-4e38-92a4-f8a2ad9a0ce3
# ╟─da89adc2-0688-44c6-9fd2-791bd13c8d74
# ╠═74aa19d2-b1a4-4333-9ff9-e6ea74e7d989
# ╟─11095805-7c76-42f4-836d-919c2cb27d1c
# ╠═c5e14b94-427d-4684-9dd7-bc44d965c570


text:
using RoME
using Test
using DistributedFactorGraphs
# @testset "Test hexagonal for pose3" begin

# start with an empty factor graph object
fg = initfg()

# Add the first pose :x0
x0 = addVariable!(fg, :x0, Pose3)

# Add at a fixed location PriorPose3
prior = addFactor!(fg, [:x0], PriorPose3( MvNormal([0., 0, 0, 0, 0, 0], [0.1, 0.1, 0.1, 0.01, 0.01, 0.01])))

# Drive around in a hexagon horizontally
for i in 0:5
    psym = Symbol("x$i")
    nsym = Symbol("x$(i+1)")
    addVariable!(fg, nsym, Pose3)
    pp = Pose3Pose3(MvNormal([10.0, 0, 0, 0, 0, pi/3], [0.5, 0.5, 0.5, 0.05, 0.05, 0.05]))
    addFactor!(fg, [psym;nsym], pp )
end

ensureAllInitialized!(fg)
getPPESuggested.(fg, sortDFG(ls(fg)))

# tree = solveTree!(fg)

# end

# @testset "Test hexagonal for pose3" begin

# start with an empty factor graph object
fg = initfg()

# Add the first pose :x0
x0 = addVariable!(fg, :x0, Pose3)

# Add at a fixed location PriorPose3
# prior = addFactor!(fg, [:x0], PriorPose3( MvNormal([2., 2, 2, 0, 0, pi], [0.1, 0.1, 0.1, 0.01, 0.01, 0.01])))
prior = addFactor!(fg, [:x0], PriorPose3( MvNormal([0., 0, 0, 0, 0, pi], [0.1, 0.1, 0.1, 0.01, 0.01, 0.01])))

# Drive around in a hexagon vertically
for i in 0:5
    psym = Symbol("x$i")
    nsym = Symbol("x$(i+1)")
    addVariable!(fg, nsym, Pose3)
    pp = Pose3Pose3(MvNormal([10.0, 0, 0, 0, pi/3, 0], [0.5, 0.5, 0.5, 0.05, 0.05, 0.05]))
    addFactor!(fg, [psym;nsym], pp )
end

ensureAllInitialized!(fg)
getPPESuggested.(fg, sortDFG(ls(fg)))

# tree = solveTree!(fg)

# end


text:
"""
A julia serialized object (JLSO) file format for storing checkpoint data.

# Structure

The .jlso files are BSON files containing the dictionaries with a specific schema.
NOTE: The raw dictionary should be loadable by any BSON library even if serialized objects
themselves aren't reconstructable.

Example)
```
Dict(
    "metadata" => Dict(
        "version" => v"2.0",
        "julia" => v"1.0.4",
        "format" => :bson,  # Could also be :julia_serialize
        "compression" => :gzip_fastest, # could also be: :none, :gzip_smallest, or :gzip
        "image" => "xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/myrepository:latest"
        "project" => Dict{String, Any}(...),
        "manifest" => Dict{String, Any}(...),
    ),
    "objects" => Dict(
        "var1" => [0x35, 0x10, 0x01, 0x04, 0x44],
        "var2" => [...],
    ),
)
```
WARNING: Regardless of serialization `format`, the serialized objects can not be deserialized
into structures with different fields, or if the types have been renamed or removed from the
packages.
Further, the `:julia_serialize` format is not intended for long term storage and is not
portable across julia versions. As a result, we're storing the serialized object data
in a json file which should also be able to load the docker image and versioninfo to allow
reconstruction.
"""
module JLSO

using BSON
using CodecZlib
using Serialization
using Memento
using Pkg: Pkg
using Pkg.Types: semver_spec

@static if VERSION < v"1.3.0"
    macro spawn(ex)
        esc(ex)
    end
else
    using Base.Threads: @spawn
end

# We need to import these cause of a deprecation on object index via strings.
import Base: getindex, setindex!

export JLSOFile

const READABLE_VERSIONS = semver_spec("1, 2, 3")
const WRITEABLE_VERSIONS = semver_spec("3")

const LOGGER = getlogger(@__MODULE__)
__init__() = Memento.register(LOGGER)

include("JLSOFile.jl")
include("upgrade.jl")
include("file_io.jl")
include("metadata.jl")
include("serialization.jl")

end  # module


text:
#This library is used to plot the data
# more: https://github.com/dcjones/Gadfly.jl
using Gadfly

@doc """
Takes an Array of pair length, like: [a,b,c,d,e,f,g,h] and returns
2 arrays splited in half -> [a,b,c,d] [e,f,g,h]
call: a,b = split_indexes(myArray)
""" ->
function split_indexes(input::Array)
	mid = length(input)/2
	tail = length(input)
	return input[1:mid], input[mid+1:tail]
end

@doc """
It takes the raw data stored in /tests_output/input_data and fetch it in the layer() format in order to make the data readable for Gadfly
The raw data format is: n lines with pairs of numbers (one int and one float) separated by a coma, just like:
1,0.5
2,3.10
""" ->
function gadfly_output(input_data::AbstractString)
	logs_dir = joinpath(realpath("."),"tests_output",input_data)
	layers = layer(x=[],y=[],Geom.point)
	logs = readdir(logs_dir)
	for i in logs
		data = readdlm(joinpath(logs_dir,i),',')
		X, Y = split_indexes(data)
        Ymin = 0.9*Y
        Ymax = 1.1*Y
		layers = vcat(layers,layer(x=X,y=Y, ymin=Ymin, ymax=Ymax, Geom.errorbar, Geom.line, Geom.point))
	end

	return(layers)
end

@doc """
Takes an input path for a data which has been used to create a DArray(input_data::AbstractString, debug=true), gadfly the data with gadfly_output(...) and plots it.
""" ->
function plot_tests(input_data::AbstractString)
	plot(gadfly_output(input_data),Guide.title("Parallel reduce execution"),Guide.xlabel("Amount of chunks"),Guide.ylabel("Time to reduce (s)"))
end


text:
module CustomTest
export vecarray, run_tests, test_approx_eq

using ControlSystems
using Base.Test

# Length not defined for StateSpace, so use custom function
function Base.Test.test_approx_eq(va::StateSpace, vb::StateSpace, Eps, astr, bstr)
    fields = [:Ts, :nx, :ny, :nu, :inputnames, :outputnames, :statenames]
    for field in fields
        if getfield(va, field) != getfield(vb, field)
            return false
        end
    end
    diff = 0.0
    valfields = [:A, :B, :C, :D]
    for field in valfields
        mata = getfield(va, field)
        matb = getfield(vb, field)
        diff = max(diff, maximum(abs(mata - matb)))
    end
    if !isnan(Eps) && !(diff <= Eps)
        sdiff = string("|", astr, " - ", bstr, "| <= ", Eps)
        return false
    end
    return true
end

Base.Test.test_approx_eq(va::StateSpace, vb::StateSpace, astr, bstr) =
    Base.Test.test_approx_eq(va, vb, 1E4*length(va.A)*max(Base.Test.array_eps(va.A),
    Base.Test.array_eps(vb.A)), astr, bstr)

# Length not defined for TransferFunction, so use custom function
Base.Test.test_approx_eq(a::TransferFunction, b::TransferFunction, meps, astr, bstr) = isapprox(a, b, rtol=meps)

Base.Test.test_approx_eq(a::TransferFunction, b::TransferFunction, astr, bstr) = (a ≈ b)

function run_tests(my_tests)
  @testset "All tests" begin
      for test in my_tests
      println("$test")
      @testset "$test" begin include("$test.jl") end
      end
  end
end

function vecarray(T::Type, ny::Int,nx::Int, args::AbstractArray...)
    if ny*nx != length(args)
        error("Number of vectors must fit dimensions")
    end
    array = reshape(collect(Array{T,1},args),nx,ny)
    permutedims(array,[2,1])
end
vecarray{T}(ny::Int,nx::Int, args::AbstractArray{T}...) = vecarray(T, ny, nx, args...)

function vecarray(ny::Int,nx::Int, args::AbstractArray...)
    args2 = promote(args...)
    vecarray(eltype(args2[1]), ny, nx, args2...)
end

end  # module


text:
#==============================================================================#
# Connect.jl
#
# This file is generated from:
# https://github.com/aws/aws-sdk-js/blob/master/apis/connect-2017-08-08.normal.json
#==============================================================================#

__precompile__()

module Connect

using AWSCore

"""
    using AWSSDK.Connect.create_user
    create_user([::AWSConfig], arguments::Dict)
    create_user([::AWSConfig]; Username=, PhoneConfig=, SecurityProfileIds=, RoutingProfileId=, InstanceId=, <keyword arguments>)

    using AWSCore.Services.connect
    connect([::AWSConfig], "PUT", "/users/{InstanceId}", arguments::Dict)
    connect([::AWSConfig], "PUT", "/users/{InstanceId}", Username=, PhoneConfig=, SecurityProfileIds=, RoutingProfileId=, InstanceId=, <keyword arguments>)

# CreateUser Operation

Creates a new user account in your Amazon Connect instance.

# Arguments

## `Username = ::String` -- *Required*
The user name in Amazon Connect for the user to create.

## `Password = ::String`
The password for the user account to create. This is required if you are using Amazon Connect for identity management. If you are using SAML for identity management and include this parameter, an `InvalidRequestException` is returned.

## `IdentityInfo = [ ... ]`
Information about the user, including email address, first name, and last name.
```
 IdentityInfo = [
        "FirstName" =>  ::String,
        "LastName" =>  ::String,
        "Email" =>  ::String
    ]
```

## `PhoneConfig = [ ... ]` -- *Required*
Specifies the phone settings for the user, including AfterContactWorkTimeLimit, AutoAccept, DeskPhoneNumber, and PhoneType.
```
 PhoneConfig = [
        "PhoneType" => <required> "SOFT_PHONE" or "DESK_PHONE",
        "AutoAccept" =>  ::Bool,
        "AfterContactWorkTimeLimit" =>  ::Int,
        "DeskPhoneNumber" =>  ::String
    ]
```

## `DirectoryUserId = ::String`
The unique identifier for the user account in the directory service directory used for identity management. If Amazon Connect is unable to access the existing directory, you can use the `DirectoryUserId` to authenticate users. If you include the parameter, it is assumed that Amazon Connect cannot access the directory. If the parameter is not included, the UserIdentityInfo is used to authenticate users from your existing directory.

This parameter is required if you are using an existing directory for identity management in Amazon Connect when Amazon Connect cannot access your directory to authenticate users. If you are using SAML for identity management and include this parameter, an `InvalidRequestException` is returned.

## `SecurityProfileIds = [::String, ...]` -- *Required*
The unique identifier of the security profile to assign to the user created.

## `RoutingProfileId = ::String` -- *Required*
The unique identifier for the routing profile to assign to the user created.

## `HierarchyGroupId = ::String`
The unique identifier for the hierarchy group to assign to the user created.

## `InstanceId = ::String` -- *Required*
The identifier for your Amazon Connect instance. To find the ID of your instance, open the AWS console and select Amazon Connect. Select the alias of the instance in the Instance alias column. The instance ID is displayed in the Overview section of your instance settings. For example, the instance ID is the set of characters at the end of the instance ARN, after instance/, such as 10a4c4eb-f57e-4d4c-b602-bf39176ced07.

# Returns

`CreateUserResponse`

# Exceptions

`InvalidRequestException`, `InvalidParameterException`, `LimitExceededException`, `DuplicateResourceException`, `ResourceNotFoundException`, `ThrottlingException` or `InternalServiceException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/connect-2017-08-08/CreateUser)
"""
@inline create_user(aws::AWSConfig=default_aws_config(); args...) = create_user(aws, args)

@inline create_user(aws::AWSConfig, args) = AWSCore.Services.connect(aws, "PUT", "/users/{InstanceId}", args)

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

"""
    using AWSSDK.Connect.delete_user
    delete_user([::AWSConfig], arguments::Dict)
    delete_user([::AWSConfig]; InstanceId=, UserId=)

    using AWSCore.Services.connect
    connect([::AWSConfig], "DELETE", "/users/{InstanceId}/{UserId}", arguments::Dict)
    connect([::AWSConfig], "DELETE", "/users/{InstanceId}/{UserId}", InstanceId=, UserId=)

# DeleteUser Operation

Deletes a user account from Amazon Connect.

# Arguments

## `InstanceId = ::String` -- *Required*
The identifier for your Amazon Connect instance. To find the ID of your instance, open the AWS console and select Amazon Connect. Select the alias of the instance in the Instance alias column. The instance ID is displayed in the Overview section of your instance settings. For example, the instance ID is the set of characters at the end of the instance ARN, after instance/, such as 10a4c4eb-f57e-4d4c-b602-bf39176ced07.

## `UserId = ::String` -- *Required*
The unique identifier of the user to delete.

# Exceptions

`InvalidRequestException`, `InvalidParameterException`, `ResourceNotFoundException`, `ThrottlingException` or `InternalServiceException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/connect-2017-08-08/DeleteUser)
"""
@inline delete_user(aws::AWSConfig=default_aws_config(); args...) = delete_user(aws, args)

@inline delete_user(aws::AWSConfig, args) = AWSCore.Services.connect(aws, "DELETE", "/users/{InstanceId}/{UserId}", args)

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

"""
    using AWSSDK.Connect.describe_user
    describe_user([::AWSConfig], arguments::Dict)
    describe_user([::AWSConfig]; UserId=, InstanceId=)

    using AWSCore.Services.connect
    connect([::AWSConfig], "GET", "/users/{InstanceId}/{UserId}", arguments::Dict)
    connect([::AWSConfig], "GET", "/users/{InstanceId}/{UserId}", UserId=, InstanceId=)

# DescribeUser Operation

Returns a `User` object that contains information about the user account specified by the `UserId`.

# Arguments

## `UserId = ::String` -- *Required*
Unique identifier for the user account to return.

## `InstanceId = ::String` -- *Required*
The identifier for your Amazon Connect instance. To find the ID of your instance, open the AWS console and select Amazon Connect. Select the alias of the instance in the Instance alias column. The instance ID is displayed in the Overview section of your instance settings. For example, the instance ID is the set of characters at the end of the instance ARN, after instance/, such as 10a4c4eb-f57e-4d4c-b602-bf39176ced07.

# Returns

`DescribeUserResponse`

# Exceptions

`InvalidRequestException`, `InvalidParameterException`, `ResourceNotFoundException`, `ThrottlingException` or `InternalServiceException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/connect-2017-08-08/DescribeUser)
"""
@inline describe_user(aws::AWSConfig=default_aws_config(); args...) = describe_user(aws, args)

@inline describe_user(aws::AWSConfig, args) = AWSCore.Services.connect(aws, "GET", "/users/{InstanceId}/{UserId}", args)

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

"""
    using AWSSDK.Connect.describe_user_hierarchy_group
    describe_user_hierarchy_group([::AWSConfig], arguments::Dict)
    describe_user_hierarchy_group([::AWSConfig]; HierarchyGroupId=, InstanceId=)

    using AWSCore.Services.connect
    connect([::AWSConfig], "GET", "/user-hierarchy-groups/{InstanceId}/{HierarchyGroupId}", arguments::Dict)
    connect([::AWSConfig], "GET", "/user-hierarchy-groups/{InstanceId}/{HierarchyGroupId}", HierarchyGroupId=, InstanceId=)

# DescribeUserHierarchyGroup Operation

Returns a `HierarchyGroup` object that includes information about a hierarchy group in your instance.

# Arguments

## `HierarchyGroupId = ::String` -- *Required*
The identifier for the hierarchy group to return.

## `InstanceId = ::String` -- *Required*
The identifier for your Amazon Connect instance. To find the ID of your instance, open the AWS console and select Amazon Connect. Select the alias of the instance in the Instance alias column. The instance ID is displayed in the Overview section of your instance settings. For example, the instance ID is the set of characters at the end of the instance ARN, after instance/, such as 10a4c4eb-f57e-4d4c-b602-bf39176ced07.

# Returns

`DescribeUserHierarchyGroupResponse`

# Exceptions

`InvalidRequestException`, `InvalidParameterException`, `ResourceNotFoundException`, `ThrottlingException` or `InternalServiceException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/connect-2017-08-08/DescribeUserHierarchyGroup)
"""
@inline describe_user_hierarchy_group(aws::AWSConfig=default_aws_config(); args...) = describe_user_hierarchy_group(aws, args)

@inline describe_user_hierarchy_group(aws::AWSConfig, args) = AWSCore.Services.connect(aws, "GET", "/user-hierarchy-groups/{InstanceId}/{HierarchyGroupId}", args)

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

"""
    using AWSSDK.Connect.describe_user_hierarchy_structure
    describe_user_hierarchy_structure([::AWSConfig], arguments::Dict)
    describe_user_hierarchy_structure([::AWSConfig]; InstanceId=)

    using AWSCore.Services.connect
    connect([::AWSConfig], "GET", "/user-hierarchy-structure/{InstanceId}", arguments::Dict)
    connect([::AWSConfig], "GET", "/user-hierarchy-structure/{InstanceId}", InstanceId=)

# DescribeUserHierarchyStructure Operation

Returns a `HiearchyGroupStructure` object, which contains data about the levels in the agent hierarchy.

# Arguments

## `InstanceId = ::String` -- *Required*
The identifier for your Amazon Connect instance. To find the ID of your instance, open the AWS console and select Amazon Connect. Select the alias of the instance in the Instance alias column. The instance ID is displayed in the Overview section of your instance settings. For example, the instance ID is the set of characters at the end of the instance ARN, after instance/, such as 10a4c4eb-f57e-4d4c-b602-bf39176ced07.

# Returns

`DescribeUserHierarchyStructureResponse`

# Exceptions

`InvalidRequestException`, `InvalidParameterException`, `ResourceNotFoundException`, `ThrottlingException` or `InternalServiceException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/connect-2017-08-08/DescribeUserHierarchyStructure)
"""
@inline describe_user_hierarchy_structure(aws::AWSConfig=default_aws_config(); args...) = describe_user_hierarchy_structure(aws, args)

@inline describe_user_hierarchy_structure(aws::AWSConfig, args) = AWSCore.Services.connect(aws, "GET", "/user-hierarchy-structure/{InstanceId}", args)

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

"""
    using AWSSDK.Connect.get_federation_token
    get_federation_token([::AWSConfig], arguments::Dict)
    get_federation_token([::AWSConfig]; InstanceId=)

    using AWSCore.Services.connect
    connect([::AWSConfig], "GET", "/user/federate/{InstanceId}", arguments::Dict)
    connect([::AWSConfig], "GET", "/user/federate/{InstanceId}", InstanceId=)

# GetFederationToken Operation

Retrieves a token for federation.

# Arguments

## `InstanceId = ::String` -- *Required*
The identifier for your Amazon Connect instance. To find the ID of your instance, open the AWS console and select Amazon Connect. Select the alias of the instance in the Instance alias column. The instance ID is displayed in the Overview section of your instance settings. For example, the instance ID is the set of characters at the end of the instance ARN, after instance/, such as 10a4c4eb-f57e-4d4c-b602-bf39176ced07.

# Returns

`GetFederationTokenResponse`

# Exceptions

`InvalidRequestException`, `InvalidParameterException`, `ResourceNotFoundException`, `UserNotFoundException`, `InternalServiceException` or `DuplicateResourceException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/connect-2017-08-08/GetFederationToken)
"""
@inline get_federation_token(aws::AWSConfig=default_aws_config(); args...) = get_federation_token(aws, args)

@inline get_federation_token(aws::AWSConfig, args) = AWSCore.Services.connect(aws, "GET", "/user/federate/{InstanceId}", args)

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

"""
    using AWSSDK.Connect.list_routing_profiles
    list_routing_profiles([::AWSConfig], arguments::Dict)
    list_routing_profiles([::AWSConfig]; InstanceId=, <keyword arguments>)

    using AWSCore.Services.connect
    connect([::AWSConfig], "GET", "/routing-profiles-summary/{InstanceId}", arguments::Dict)
    connect([::AWSConfig], "GET", "/routing-profiles-summary/{InstanceId}", InstanceId=, <keyword arguments>)

# ListRoutingProfiles Operation

Returns an array of `RoutingProfileSummary` objects that includes information about the routing profiles in your instance.

# Arguments

## `InstanceId = ::String` -- *Required*
The identifier for your Amazon Connect instance. To find the ID of your instance, open the AWS console and select Amazon Connect. Select the alias of the instance in the Instance alias column. The instance ID is displayed in the Overview section of your instance settings. For example, the instance ID is the set of characters at the end of the instance ARN, after instance/, such as 10a4c4eb-f57e-4d4c-b602-bf39176ced07.

## `nextToken = ::String`
The token for the next set of results. Use the value returned in the previous response in the next request to retrieve the next set of results.

## `maxResults = ::Int`
The maximum number of routing profiles to return in the response.

# Returns

`ListRoutingProfilesResponse`

# Exceptions

`InvalidRequestException`, `InvalidParameterException`, `ResourceNotFoundException`, `ThrottlingException` or `InternalServiceException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/connect-2017-08-08/ListRoutingProfiles)
"""
@inline list_routing_profiles(aws::AWSConfig=default_aws_config(); args...) = list_routing_profiles(aws, args)

@inline list_routing_profiles(aws::AWSConfig, args) = AWSCore.Services.connect(aws, "GET", "/routing-profiles-summary/{InstanceId}", args)

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

"""
    using AWSSDK.Connect.list_security_profiles
    list_security_profiles([::AWSConfig], arguments::Dict)
    list_security_profiles([::AWSConfig]; InstanceId=, <keyword arguments>)

    using AWSCore.Services.connect
    connect([::AWSConfig], "GET", "/security-profiles-summary/{InstanceId}", arguments::Dict)
    connect([::AWSConfig], "GET", "/security-profiles-summary/{InstanceId}", InstanceId=, <keyword arguments>)

# ListSecurityProfiles Operation

Returns an array of SecurityProfileSummary objects that contain information about the security profiles in your instance, including the ARN, Id, and Name of the security profile.

# Arguments

## `InstanceId = ::String` -- *Required*
The identifier for your Amazon Connect instance. To find the ID of your instance, open the AWS console and select Amazon Connect. Select the alias of the instance in the Instance alias column. The instance ID is displayed in the Overview section of your instance settings. For example, the instance ID is the set of characters at the end of the instance ARN, after instance/, such as 10a4c4eb-f57e-4d4c-b602-bf39176ced07.

## `nextToken = ::String`
The token for the next set of results. Use the value returned in the previous response in the next request to retrieve the next set of results.

## `maxResults = ::Int`
The maximum number of security profiles to return.

# Returns

`ListSecurityProfilesResponse`

# Exceptions

`InvalidRequestException`, `InvalidParameterException`, `ResourceNotFoundException`, `ThrottlingException` or `InternalServiceException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/connect-2017-08-08/ListSecurityProfiles)
"""
@inline list_security_profiles(aws::AWSConfig=default_aws_config(); args...) = list_security_profiles(aws, args)

@inline list_security_profiles(aws::AWSConfig, args) = AWSCore.Services.connect(aws, "GET", "/security-profiles-summary/{InstanceId}", args)

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

"""
    using AWSSDK.Connect.list_user_hierarchy_groups
    list_user_hierarchy_groups([::AWSConfig], arguments::Dict)
    list_user_hierarchy_groups([::AWSConfig]; InstanceId=, <keyword arguments>)

    using AWSCore.Services.connect
    connect([::AWSConfig], "GET", "/user-hierarchy-groups-summary/{InstanceId}", arguments::Dict)
    connect([::AWSConfig], "GET", "/user-hierarchy-groups-summary/{InstanceId}", InstanceId=, <keyword arguments>)

# ListUserHierarchyGroups Operation

Returns a `UserHierarchyGroupSummaryList`, which is an array of `HierarchyGroupSummary` objects that contain information about the hierarchy groups in your instance.

# Arguments

## `InstanceId = ::String` -- *Required*
The identifier for your Amazon Connect instance. To find the ID of your instance, open the AWS console and select Amazon Connect. Select the alias of the instance in the Instance alias column. The instance ID is displayed in the Overview section of your instance settings. For example, the instance ID is the set of characters at the end of the instance ARN, after instance/, such as 10a4c4eb-f57e-4d4c-b602-bf39176ced07.

## `nextToken = ::String`
The token for the next set of results. Use the value returned in the previous response in the next request to retrieve the next set of results.

## `maxResults = ::Int`
The maximum number of hierarchy groups to return.

# Returns

`ListUserHierarchyGroupsResponse`

# Exceptions

`InvalidRequestException`, `InvalidParameterException`, `ResourceNotFoundException`, `ThrottlingException` or `InternalServiceException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/connect-2017-08-08/ListUserHierarchyGroups)
"""
@inline list_user_hierarchy_groups(aws::AWSConfig=default_aws_config(); args...) = list_user_hierarchy_groups(aws, args)

@inline list_user_hierarchy_groups(aws::AWSConfig, args) = AWSCore.Services.connect(aws, "GET", "/user-hierarchy-groups-summary/{InstanceId}", args)

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

"""
    using AWSSDK.Connect.list_users
    list_users([::AWSConfig], arguments::Dict)
    list_users([::AWSConfig]; InstanceId=, <keyword arguments>)

    using AWSCore.Services.connect
    connect([::AWSConfig], "GET", "/users-summary/{InstanceId}", arguments::Dict)
    connect([::AWSConfig], "GET", "/users-summary/{InstanceId}", InstanceId=, <keyword arguments>)

# ListUsers Operation

Returns a `UserSummaryList`, which is an array of `UserSummary` objects.

# Arguments

## `InstanceId = ::String` -- *Required*
The identifier for your Amazon Connect instance. To find the ID of your instance, open the AWS console and select Amazon Connect. Select the alias of the instance in the Instance alias column. The instance ID is displayed in the Overview section of your instance settings. For example, the instance ID is the set of characters at the end of the instance ARN, after instance/, such as 10a4c4eb-f57e-4d4c-b602-bf39176ced07.

## `nextToken = ::String`
The token for the next set of results. Use the value returned in the previous response in the next request to retrieve the next set of results.

## `maxResults = ::Int`
The maximum number of results to return in the response.

# Returns

`ListUsersResponse`

# Exceptions

`InvalidRequestException`, `InvalidParameterException`, `ResourceNotFoundException`, `ThrottlingException` or `InternalServiceException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/connect-2017-08-08/ListUsers)
"""
@inline list_users(aws::AWSConfig=default_aws_config(); args...) = list_users(aws, args)

@inline list_users(aws::AWSConfig, args) = AWSCore.Services.connect(aws, "GET", "/users-summary/{InstanceId}", args)

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

"""
    using AWSSDK.Connect.start_outbound_voice_contact
    start_outbound_voice_contact([::AWSConfig], arguments::Dict)
    start_outbound_voice_contact([::AWSConfig]; DestinationPhoneNumber=, ContactFlowId=, InstanceId=, <keyword arguments>)

    using AWSCore.Services.connect
    connect([::AWSConfig], "PUT", "/contact/outbound-voice", arguments::Dict)
    connect([::AWSConfig], "PUT", "/contact/outbound-voice", DestinationPhoneNumber=, ContactFlowId=, InstanceId=, <keyword arguments>)

# StartOutboundVoiceContact Operation

The `StartOutboundVoiceContact` operation initiates a contact flow to place an outbound call to a customer.

There is a throttling limit placed on usage of the API that includes a RateLimit of 2 per second, and a BurstLimit of 5 per second.

If you are using an IAM account, it must have permission to the `connect:StartOutboundVoiceContact` action.

# Arguments

## `DestinationPhoneNumber = ::String` -- *Required*
The phone number of the customer in E.164 format.

## `ContactFlowId = ::String` -- *Required*
The identifier for the contact flow to connect the outbound call to.

To find the `ContactFlowId`, open the contact flow you want to use in the Amazon Connect contact flow editor. The ID for the contact flow is displayed in the address bar as part of the URL. For example, the contact flow ID is the set of characters at the end of the URL, after 'contact-flow/' such as `78ea8fd5-2659-4f2b-b528-699760ccfc1b`.

## `InstanceId = ::String` -- *Required*
The identifier for your Amazon Connect instance. To find the ID of your instance, open the AWS console and select Amazon Connect. Select the alias of the instance in the Instance alias column. The instance ID is displayed in the Overview section of your instance settings. For example, the instance ID is the set of characters at the end of the instance ARN, after instance/, such as 10a4c4eb-f57e-4d4c-b602-bf39176ced07.

## `ClientToken = ::String`
A unique, case-sensitive identifier that you provide to ensure the idempotency of the request. The token is valid for 7 days after creation. If a contact is already started, the contact ID is returned. If the contact is disconnected, a new contact is started.

## `SourcePhoneNumber = ::String`
The phone number, in E.164 format, associated with your Amazon Connect instance to use for the outbound call.

## `QueueId = ::String`
The queue to add the call to. If you specify a queue, the phone displayed for caller ID is the phone number specified in the queue. If you do not specify a queue, the queue used will be the queue defined in the contact flow.

To find the `QueueId`, open the queue you want to use in the Amazon Connect Queue editor. The ID for the queue is displayed in the address bar as part of the URL. For example, the queue ID is the set of characters at the end of the URL, after 'queue/' such as `queue/aeg40574-2d01-51c3-73d6-bf8624d2168c`.

## `Attributes = ::Dict{String,String}`
Specify a custom key-value pair using an attribute map. The attributes are standard Amazon Connect attributes, and can be accessed in contact flows just like any other contact attributes.

There can be up to 32,768 UTF-8 bytes across all key-value pairs. Attribute keys can include only alphanumeric, dash, and underscore characters.

For example, if you want play a greeting when the customer answers the call, you can pass the customer name in attributes similar to the following:

# Returns

`StartOutboundVoiceContactResponse`

# Exceptions

`InvalidRequestException`, `InvalidParameterException`, `ResourceNotFoundException`, `InternalServiceException`, `LimitExceededException`, `DestinationNotAllowedException` or `OutboundContactNotPermittedException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/connect-2017-08-08/StartOutboundVoiceContact)
"""
@inline start_outbound_voice_contact(aws::AWSConfig=default_aws_config(); args...) = start_outbound_voice_contact(aws, args)

@inline start_outbound_voice_contact(aws::AWSConfig, args) = AWSCore.Services.connect(aws, "PUT", "/contact/outbound-voice", args)

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

"""
    using AWSSDK.Connect.stop_contact
    stop_contact([::AWSConfig], arguments::Dict)
    stop_contact([::AWSConfig]; ContactId=, InstanceId=)

    using AWSCore.Services.connect
    connect([::AWSConfig], "POST", "/contact/stop", arguments::Dict)
    connect([::AWSConfig], "POST", "/contact/stop", ContactId=, InstanceId=)

# StopContact Operation

Ends the contact initiated by the `StartOutboundVoiceContact` operation.

If you are using an IAM account, it must have permission to the `connect:StopContact` action.

# Arguments

## `ContactId = ::String` -- *Required*
The unique identifier of the contact to end.

## `InstanceId = ::String` -- *Required*
The identifier for your Amazon Connect instance. To find the ID of your instance, open the AWS console and select Amazon Connect. Select the alias of the instance in the Instance alias column. The instance ID is displayed in the Overview section of your instance settings. For example, the instance ID is the set of characters at the end of the instance ARN, after instance/, such as 10a4c4eb-f57e-4d4c-b602-bf39176ced07.

# Returns

`StopContactResponse`

# Exceptions

`InvalidRequestException`, `ContactNotFoundException`, `InvalidParameterException`, `ResourceNotFoundException` or `InternalServiceException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/connect-2017-08-08/StopContact)
"""
@inline stop_contact(aws::AWSConfig=default_aws_config(); args...) = stop_contact(aws, args)

@inline stop_contact(aws::AWSConfig, args) = AWSCore.Services.connect(aws, "POST", "/contact/stop", args)

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

"""
    using AWSSDK.Connect.update_user_hierarchy
    update_user_hierarchy([::AWSConfig], arguments::Dict)
    update_user_hierarchy([::AWSConfig]; UserId=, InstanceId=, <keyword arguments>)

    using AWSCore.Services.connect
    connect([::AWSConfig], "POST", "/users/{InstanceId}/{UserId}/hierarchy", arguments::Dict)
    connect([::AWSConfig], "POST", "/users/{InstanceId}/{UserId}/hierarchy", UserId=, InstanceId=, <keyword arguments>)

# UpdateUserHierarchy Operation

Assigns the specified hierarchy group to the user.

# Arguments

## `HierarchyGroupId = ::String`
The identifier for the hierarchy group to assign to the user.

## `UserId = ::String` -- *Required*
The identifier of the user account to assign the hierarchy group to.

## `InstanceId = ::String` -- *Required*
The identifier for your Amazon Connect instance. To find the ID of your instance, open the AWS console and select Amazon Connect. Select the alias of the instance in the Instance alias column. The instance ID is displayed in the Overview section of your instance settings. For example, the instance ID is the set of characters at the end of the instance ARN, after instance/, such as 10a4c4eb-f57e-4d4c-b602-bf39176ced07.

# Exceptions

`InvalidRequestException`, `InvalidParameterException`, `ResourceNotFoundException`, `ThrottlingException` or `InternalServiceException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/connect-2017-08-08/UpdateUserHierarchy)
"""
@inline update_user_hierarchy(aws::AWSConfig=default_aws_config(); args...) = update_user_hierarchy(aws, args)

@inline update_user_hierarchy(aws::AWSConfig, args) = AWSCore.Services.connect(aws, "POST", "/users/{InstanceId}/{UserId}/hierarchy", args)

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

"""
    using AWSSDK.Connect.update_user_identity_info
    update_user_identity_info([::AWSConfig], arguments::Dict)
    update_user_identity_info([::AWSConfig]; IdentityInfo=, UserId=, InstanceId=)

    using AWSCore.Services.connect
    connect([::AWSConfig], "POST", "/users/{InstanceId}/{UserId}/identity-info", arguments::Dict)
    connect([::AWSConfig], "POST", "/users/{InstanceId}/{UserId}/identity-info", IdentityInfo=, UserId=, InstanceId=)

# UpdateUserIdentityInfo Operation

Updates the identity information for the specified user in a `UserIdentityInfo` object, including email, first name, and last name.

# Arguments

## `IdentityInfo = [ ... ]` -- *Required*
A `UserIdentityInfo` object.
```
 IdentityInfo = [
        "FirstName" =>  ::String,
        "LastName" =>  ::String,
        "Email" =>  ::String
    ]
```

## `UserId = ::String` -- *Required*
The identifier for the user account to update identity information for.

## `InstanceId = ::String` -- *Required*
The identifier for your Amazon Connect instance. To find the ID of your instance, open the AWS console and select Amazon Connect. Select the alias of the instance in the Instance alias column. The instance ID is displayed in the Overview section of your instance settings. For example, the instance ID is the set of characters at the end of the instance ARN, after instance/, such as 10a4c4eb-f57e-4d4c-b602-bf39176ced07.

# Exceptions

`InvalidRequestException`, `InvalidParameterException`, `ResourceNotFoundException`, `ThrottlingException` or `InternalServiceException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/connect-2017-08-08/UpdateUserIdentityInfo)
"""
@inline update_user_identity_info(aws::AWSConfig=default_aws_config(); args...) = update_user_identity_info(aws, args)

@inline update_user_identity_info(aws::AWSConfig, args) = AWSCore.Services.connect(aws, "POST", "/users/{InstanceId}/{UserId}/identity-info", args)

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

"""
    using AWSSDK.Connect.update_user_phone_config
    update_user_phone_config([::AWSConfig], arguments::Dict)
    update_user_phone_config([::AWSConfig]; PhoneConfig=, UserId=, InstanceId=)

    using AWSCore.Services.connect
    connect([::AWSConfig], "POST", "/users/{InstanceId}/{UserId}/phone-config", arguments::Dict)
    connect([::AWSConfig], "POST", "/users/{InstanceId}/{UserId}/phone-config", PhoneConfig=, UserId=, InstanceId=)

# UpdateUserPhoneConfig Operation

Updates the phone configuration settings in the `UserPhoneConfig` object for the specified user.

# Arguments

## `PhoneConfig = [ ... ]` -- *Required*
A `UserPhoneConfig` object that contains settings for `AfterContactWorkTimeLimit`, `AutoAccept`, `DeskPhoneNumber`, and `PhoneType` to assign to the user.
```
 PhoneConfig = [
        "PhoneType" => <required> "SOFT_PHONE" or "DESK_PHONE",
        "AutoAccept" =>  ::Bool,
        "AfterContactWorkTimeLimit" =>  ::Int,
        "DeskPhoneNumber" =>  ::String
    ]
```

## `UserId = ::String` -- *Required*
The identifier for the user account to change phone settings for.

## `InstanceId = ::String` -- *Required*
The identifier for your Amazon Connect instance. To find the ID of your instance, open the AWS console and select Amazon Connect. Select the alias of the instance in the Instance alias column. The instance ID is displayed in the Overview section of your instance settings. For example, the instance ID is the set of characters at the end of the instance ARN, after instance/, such as 10a4c4eb-f57e-4d4c-b602-bf39176ced07.

# Exceptions

`InvalidRequestException`, `InvalidParameterException`, `ResourceNotFoundException`, `ThrottlingException` or `InternalServiceException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/connect-2017-08-08/UpdateUserPhoneConfig)
"""
@inline update_user_phone_config(aws::AWSConfig=default_aws_config(); args...) = update_user_phone_config(aws, args)

@inline update_user_phone_config(aws::AWSConfig, args) = AWSCore.Services.connect(aws, "POST", "/users/{InstanceId}/{UserId}/phone-config", args)

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

"""
    using AWSSDK.Connect.update_user_routing_profile
    update_user_routing_profile([::AWSConfig], arguments::Dict)
    update_user_routing_profile([::AWSConfig]; RoutingProfileId=, UserId=, InstanceId=)

    using AWSCore.Services.connect
    connect([::AWSConfig], "POST", "/users/{InstanceId}/{UserId}/routing-profile", arguments::Dict)
    connect([::AWSConfig], "POST", "/users/{InstanceId}/{UserId}/routing-profile", RoutingProfileId=, UserId=, InstanceId=)

# UpdateUserRoutingProfile Operation

Assigns the specified routing profile to a user.

# Arguments

## `RoutingProfileId = ::String` -- *Required*
The identifier of the routing profile to assign to the user.

## `UserId = ::String` -- *Required*
The identifier for the user account to assign the routing profile to.

## `InstanceId = ::String` -- *Required*
The identifier for your Amazon Connect instance. To find the ID of your instance, open the AWS console and select Amazon Connect. Select the alias of the instance in the Instance alias column. The instance ID is displayed in the Overview section of your instance settings. For example, the instance ID is the set of characters at the end of the instance ARN, after instance/, such as 10a4c4eb-f57e-4d4c-b602-bf39176ced07.

# Exceptions

`InvalidRequestException`, `InvalidParameterException`, `ResourceNotFoundException`, `ThrottlingException` or `InternalServiceException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/connect-2017-08-08/UpdateUserRoutingProfile)
"""
@inline update_user_routing_profile(aws::AWSConfig=default_aws_config(); args...) = update_user_routing_profile(aws, args)

@inline update_user_routing_profile(aws::AWSConfig, args) = AWSCore.Services.connect(aws, "POST", "/users/{InstanceId}/{UserId}/routing-profile", args)

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

"""
    using AWSSDK.Connect.update_user_security_profiles
    update_user_security_profiles([::AWSConfig], arguments::Dict)
    update_user_security_profiles([::AWSConfig]; SecurityProfileIds=, UserId=, InstanceId=)

    using AWSCore.Services.connect
    connect([::AWSConfig], "POST", "/users/{InstanceId}/{UserId}/security-profiles", arguments::Dict)
    connect([::AWSConfig], "POST", "/users/{InstanceId}/{UserId}/security-profiles", SecurityProfileIds=, UserId=, InstanceId=)

# UpdateUserSecurityProfiles Operation

Update the security profiles assigned to the user.

# Arguments

## `SecurityProfileIds = [::String, ...]` -- *Required*
The identifiers for the security profiles to assign to the user.

## `UserId = ::String` -- *Required*
The identifier of the user account to assign the security profiles.

## `InstanceId = ::String` -- *Required*
The identifier for your Amazon Connect instance. To find the ID of your instance, open the AWS console and select Amazon Connect. Select the alias of the instance in the Instance alias column. The instance ID is displayed in the Overview section of your instance settings. For example, the instance ID is the set of characters at the end of the instance ARN, after instance/, such as 10a4c4eb-f57e-4d4c-b602-bf39176ced07.

# Exceptions

`InvalidRequestException`, `InvalidParameterException`, `ResourceNotFoundException`, `ThrottlingException` or `InternalServiceException`.

See also: [AWS API Documentation](https://docs.aws.amazon.com/goto/WebAPI/connect-2017-08-08/UpdateUserSecurityProfiles)
"""
@inline update_user_security_profiles(aws::AWSConfig=default_aws_config(); args...) = update_user_security_profiles(aws, args)

@inline update_user_security_profiles(aws::AWSConfig, args) = AWSCore.Services.connect(aws, "POST", "/users/{InstanceId}/{UserId}/security-profiles", args)

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

end # module Connect

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