text:
module DiskArrayShufflers
# using Zarr
# using Zarr: AbstractStore
using StatsBase
include("pickaxisarray.jl")
using .PickAxisArrays
using DiskArrays: GridChunks, DiskArrays
export DiskArrayShuffler, readbatch, FullSliceSampler

function getbatchinds(batchsize,currentchunk_views)
    s = eachindex.(currentchunk_views)
    wchunks = weights(length.(currentchunk_views))
    map(1:batchsize) do _
        chunk = sample(1:length(s),wchunks)
        ii = sample(s[chunk])
        chunk,ii
    end
end

struct ChunkCollection{P<:PickAxisArray,B}
    chunkviews::Vector{P}
    batches::B
end
retdims(::ChunkCollection{<:PickAxisArray{T}}) where T = ndims(T)
function getbatch(c::ChunkCollection)
    cv = c.chunkviews
    bnext = nextbatch(c.batches)
    if bnext === nothing
        return nothing
    else
        return [cv[ii[1]][ii[2]] for ii in bnext]
    end
end

struct BatchIndexList{I}
    indices::I
    icur::Ref{Int}
    lock::ReentrantLock
end
function nextbatch(b::BatchIndexList)
    lock(b.lock) do
        icur = b.icur[]
        if icur > length(b.indices)
            nothing
        else
            b.icur[] = icur+1
            b.indices[icur]
        end
    end
end

struct FullSliceSampler{SD}
    batchsize::Int
    nchunks::Int
    batchespercoll::Int
    sd::Val{SD}
end
function FullSliceSampler(sd::Int...;batchsize=100, nchunks=10,batchespercoll=100)
    FullSliceSampler(batchsize,nchunks,batchespercoll,Val(sd))
end

function create_new_chunklist(s::FullSliceSampler{SD}, a, c::GridChunks) where SD
    chunkinds = sample(c,s.nchunks,replace=false)
    data = [a[ci...] for ci in chunkinds]
    isinsampledim = [i ∉ SD ? true : Colon() for i in 1:ndims(a)]
    data_views = PickAxisArray.(data, Ref(isinsampledim));
    bi = [getbatchinds(s.batchsize,data_views) for _ in 1:s.batchespercoll]
    bl = BatchIndexList(bi,Ref(1),ReentrantLock())
    ChunkCollection(data_views, bl)
end

struct DiskArrayShuffler{A<:AbstractArray,G<:GridChunks,CT,S}
    parent::A
    parentchunks::G
    currentcoll::Ref{CT}
    nextcoll::Ref{Task}
    sampler::S
    lock::ReentrantLock
end
function DiskArrayShuffler(parent, sampler; chunks::GridChunks = DiskArrays.eachchunk(parent))
    coll = create_new_chunklist(sampler, parent, chunks)
    next = @async create_new_chunklist(sampler, parent, chunks)
    DiskArrayShuffler(parent,chunks,Ref(coll),Ref(next),sampler,ReentrantLock())
end
function readbatch(s::DiskArrayShuffler)
    r = getbatch(s.currentcoll[])
    if r !== nothing
        return r
    else
        if trylock(s.lock)
            @debug "Exchanging chunk collection"
            s.currentcoll[] = fetch(s.nextcoll[])
            s.nextcoll[] = @async create_new_chunklist(s.sampler, s.parent, s.parentchunks)
            unlock(s.lock)
        else
            sleep(0.2)
        end
        return readbatch(s)
    end
end
include("zarr.jl")

end


text:
# Julia wrapper for header: /usr/include/libavutil/dict.h
# Automatically generated using Clang.jl wrap_c, version 0.0.0

export
    av_dict_get,
    av_dict_count,
    av_dict_set,
    av_dict_set_int,
    av_dict_parse_string,
    av_dict_copy,
    av_dict_free,
    av_dict_get_string

function av_dict_get(m, key, prev, flags::Integer)
    ccall((:av_dict_get, libavutil), Ptr{AVDictionaryEntry}, (Ptr{AVDictionary}, Cstring, Ptr{AVDictionaryEntry}, Cint), m, key, prev, flags)
end

function av_dict_count(m)
    ccall((:av_dict_count, libavutil), Cint, (Ptr{AVDictionary},), m)
end

function av_dict_set(pm, key, value, flags::Integer)
    ccall((:av_dict_set, libavutil), Cint, (Ref{Ptr{AVDictionary}}, Cstring, Cstring, Cint), pm, key, value, flags)
end

function av_dict_set_int(pm, key, value::Int64, flags::Integer)
    ccall((:av_dict_set_int, libavutil), Cint, (Ref{Ptr{AVDictionary}}, Cstring, Int64, Cint), pm, key, value, flags)
end

function av_dict_parse_string(pm, str, key_val_sep, pairs_sep, flags::Integer)
    ccall((:av_dict_parse_string, libavutil), Cint, (Ref{Ptr{AVDictionary}}, Cstring, Cstring, Cstring, Cint), pm, str, key_val_sep, pairs_sep, flags)
end

function av_dict_copy(dst, src, flags::Integer)
    ccall((:av_dict_copy, libavutil), Cint, (Ref{Ptr{AVDictionary}}, Ptr{AVDictionary}, Cint), dst, src, flags)
end

function av_dict_free(m)
    ccall((:av_dict_free, libavutil), Cvoid, (Ref{Ptr{AVDictionary}},), m)
end

function av_dict_get_string(m, buffer, key_val_sep::UInt8, pairs_sep::UInt8)
    ccall((:av_dict_get_string, libavutil), Cint, (Ptr{AVDictionary}, Ptr{Cstring}, UInt8, UInt8), m, buffer, key_val_sep, pairs_sep)
end

ext: jl


text:
using Test, StatsModels
using DataFrames
using StatsBase

using unfold
include("test_utilities.jl")

data,evts = loadtestdata("testCase1") #
data_e,times = unfold.epoch(data=data_r,tbl=evts,τ=(-1.,1.1),sfreq=10) # cut the data into epochs
basisfunction = firbasis(τ=(-1,1),sfreq=10,name="A")

f  = @formula 0~1 # 1
m_tul,m_tul_results = fit(UnfoldLinearModel,f,evts,data_r,basisfunction)
m_mul,m_mul_results = fit(UnfoldLinearModel,f,evts,data_e,times)

yhat = predict(m_tul,evts)
@test yhat[end-3,:yhat] ≈ mean(data[data.!=0])
yhat2 = predict(m_mul,evts)
@test yhat.yhat ≈ yhat2.yhat
f  = @formula 0~1+continuousA# 1
m_tul,m_tul_results = fit(UnfoldLinearModel,f,evts,data_r,basisfunction)
m_mul,m_mul_results = fit(UnfoldLinearModel,f,evts,data_e,times)
yhat = predict(m_tul,evts)
@test predict(m_mul,evts).yhat ≈ yhat.yhat
@test yhat.continuousA[end] .* m_tul.beta[end-1] + m_tul.beta[20] ≈ yhat.yhat[end-3]


text:
#!/usr/bin/env julia

using Luxor

using Test

using Colors

using Random

Random.seed!(42)

demomovie = Movie(400, 400, "test", 0:359)

function backdrop(scene, framenumber)
    background("black")
end

function frame(scene, framenumber)
    sethue(Colors.HSV(framenumber, 1, 1))
    p = scene.easingfunction(framenumber, 0, 1, scene.framerange.stop)
    circle(polar(100, -pi/2 - p * 2pi), 80, :fill)
    text(string("frame $framenumber of $(length(scene.movie.movieframerange))"), Point(O.x, O.y-190))
end

mktempdir() do tmpdir
    @test animate(demomovie, [Scene(demomovie, backdrop), Scene(demomovie, frame, 0:359, easingfunction=easeinoutquad)], creategif=false) == true
end

demo = Movie(400, 100, "test")

backdrop(scene, framenumber) =  background("black")

function frame1(scene, framenumber)
    sethue("purple")
    eased_n = scene.easingfunction(framenumber, 0, 1, scene.framerange.stop)
    circle(Point(-180 + (360 * eased_n), -20), 10, :fill)
end

function frame2(scene, framenumber)
    sethue("green")
    eased_n = scene.easingfunction(framenumber, 0, 1, scene.framerange.stop)
    circle(Point(-180 + (360 * eased_n), 0), 10, :fill)
end

function frame3(scene, framenumber)
    sethue("red")
    eased_n = scene.easingfunction(framenumber, 0, 1, scene.framerange.stop)
    circle(Point(-180 + (360 * eased_n), 20), 10, :fill)
end

function frame4(scene, framenumber)
    sethue("red")
    eased_n = scene.easingfunction(framenumber, 0, 1, scene.framerange.stop)
    circle(Point(-180 + (360 * eased_n), 20), 10, :fill)
    sethue("white")
    fontsize(20)
    text(string(scene.opts))
end

mktempdir() do tmpdir
    @test animate(demo, [
        Scene(demo, backdrop, 0:200),
        Scene(demo, frame1,   0:200, easingfunction=easeinsine),
        Scene(demo, frame2,   0:200, easingfunction=easeinoutcubic),
        Scene(demo, frame3,   0:200, easingfunction=easeinoutquint),
        Scene(demo, frame4,   0:200, easingfunction=easeinoutquint, optarg=42),
        ],
        creategif=false) == true
end

@testset "test pathname parameter of animate()" begin
    mktempdir() do tmpdir
        # test that animation is saved to 'pathname' if valid pathname is given
        testfile = joinpath(tmpdir, "test.gif")

        #= ffmpeg is not supported on travis and co -> disable gif generation
        # dependent test
        @test !isfile(testfile)
        =#
        @test animate(demo, Scene(demo, backdrop, 0:200),
            creategif=false,
            pathname=testfile) == true

        touch(testfile)
        @test isfile(testfile)

        # test that error is thrown if the passed pathname points to a directory
        # and that the content of that directory is not removed (ticket #57)
        @test isdir(tmpdir)
        @warn "This is about to error..."
        @test animate(demo, Scene(demo, backdrop, 0:200),
            creategif=false,
            pathname=tmpdir) == false
        @test isfile(testfile)
    end
end

println("...finished animation tests")


text:
##################################################

## Q Factorization
## We have two  different Q factorizations: one with a Descending chaing,  one with a  Twisted Chain
abstract type AbstractQFactorization{T, S} <: LinearAlgebra.Factorization{S} end

# implement Array interface
Base.length(QF::AbstractQFactorization) = length(QF.Q)
Base.size(QF::AbstractQFactorization) = (length(QF)+1, length(QF)+1)
Base.eltype(QF::AbstractQFactorization{T, S}) where {T,S} = S

Base.zero(QF::AbstractQFactorization) = zero(eltype(QF))
Base.one(QF::AbstractQFactorization) = one(eltype(QF))

# Factorization for a Descending Chain
struct QFactorization{T, S, V} <: AbstractQFactorization{T, S}
  Q::DescendingChain{T, S, V}
  D::SparseDiagonal{S}
  QFactorization(Q::DescendingChain{T, S, V}, D::SparseDiagonal{S}) where {T, S, V} = new{T, S, V}(Q,D)
  QFactorization(Q::DescendingChain{T, S, V}) where {T, S, V} = QFactorization(Q, SparseDiagonal(S, length(Q)+1))
end

### QFactorization  Twisted
struct QFactorizationTwisted{T, S, Vt, PVt} <: AbstractQFactorization{T, S}
  Q::TwistedChain{T,S, Vt, PVt} ## Twisted
  D::SparseDiagonal{S}
  QFactorizationTwisted(Q::TwistedChain{T, S, Vt, PVt}, D::SparseDiagonal{S}) where  {T, S, Vt, PVt} = new{T, S, Vt, PVt}(Q,D)
  QFactorizationTwisted(Q::TwistedChain{T, S, Vt, PVt}) where {T, S, Vt, PVt} = QFactorizationTwisted(Q, SparseDiagonal{S}(length(Q)+1))

end

Base.eltype(::QFactorization{T, S, V}) where {T, S, V} = S
Base.eltype(::QFactorizationTwisted{T, S, Vt, PVt}) where {T, S, Vt, PVt} = S
Base.copy(QF::QFactorization) = QFactorization(copy(QF.Q), copy(QF.D))
Base.copy(QF::QFactorizationTwisted) = QFactorizationTwisted(copy(QF.Q), copy(QF.D))

# constructor
# for descending chain
function q_factorization(Q::DescendingChain{T, S, V}) where {T, S, V}

    N = length(Q)
    D = SparseDiagonal(S, N+1)

    QFactorization(Q, D)

end

function q_factorization(Q::TwistedChain{T, S, Vt, PVt}) where {T, S, Vt, PVt}

    N = length(Q)
    D = SparseDiagonal{S}(N+1) # note subtlety here, for real+twisted case we have a diagonal

    QFactorizationTwisted(Q, D)

end

## Find Q[j,k] from its factored form
## QFactorization is Hessenberg
## We will only need near  diagonal elements, as we multiply by
## an  upper triangular matrix

function Base.getindex(QF::QFactorization, j, k)
    (j <= 0 || k <= 0) && return zero(QF)
    QF.Q[j,k] * QF.D[k]
end

function Base.Matrix(QF::QFactorization{T, S}) where {T, S}
    n = length(QF) + 1
    M = diagm(0 => ones(S, n))
    QF.Q * (Matrix(QF.D) * M)
end

## For Twisted, one would need to do the inefficient: Matrix(QF)[i,j]

##################################################
##
## Transformations
##
function passthrough!(QF::QFactorization, U::AbstractRotator)

    U = passthrough!(QF.D, U)
    passthrough!(QF.Q, U)

end

function passthrough!(U::AbstractRotator, QF::QFactorization)

    U = passthrough!(U, QF.Q)
    passthrough!(U, QF.D)

end

# pass diagonal rotator through and merge into D
function passthrough_phase!(Di::DiagonalRotator, QF::QFactorization)
    passthrough_phase!(Di, QF.Q, QF.D)
end

function passthrough_phase!(Di::DiagonalRotator, QF::QFactorizationTwisted)
    i = idx(Di)

    asc = ascending_part(QF.Q, i)
    des = descending_part(QF.Q, i)

    passthrough_phase!(Di, (des, asc), QF.D)

end

## fuse! modifies QF and handles phase, if needed
function fuse!(QF::QFactorization{T, S}, U::AbstractRotator) where {T, S <: Real}
    i = idx(U)
    QF.Q[i], Di = fuse(QF.Q[i], U)

    return nothing
end

function fuse!(U::AbstractRotator, QF::QFactorization{T,S}) where {T, S <: Real}
    i = idx(U)
    QF.Q[i], Di = fuse(U, QF.Q[i])

    return nothing
end

function fuse!(QF::QFactorization{T, S}, U::AbstractRotator) where {T, S <: Complex}
    i = idx(U)
    QF.Q[i], Di = fuse(QF.Q[i], U)
    Di

    alpha, _ = vals(Di)
    @inbounds QF.D[i] = QF.D[i] * alpha
    @inbounds QF.D[i+1] = QF.D[i+1] * conj(alpha)

    return nothing
end

function fuse!(U::AbstractRotator, QF::QFactorization{T,S}) where {T, S <: Complex}
    i = idx(U)
    QF.Q[i], Di = fuse(U, QF.Q[i])
    passthrough_phase!(Di, QF)

    return nothing
end


text:
module Particula

using Unitful

include("inputting.jl")
include("dviscosity.jl")
include("meanfreepath.jl")

# Write your package code here.
function greet()

    print("Hello World! \n")
    print("Oh wow, molar mass of air is: ", M_air)
    print("\t and viscosity is: ", µ(T = 300 * u"K"))

end

end # end the Particula module


text:
function find_edges(A)
    "
    This function finds the edges by finding the distance to the nearest background (0)
    pixel and keeping only the pixels that are adjacent to the nearest background pixel
    "

    # Set every pixel that is currently background (0) equal to 1, as these are the pixels we are interested in
    A = A .== 0

    # Find the indeces of these background pixels (now set equal to 1)
    A = feature_transform(A)

    # Find the distance away from the nearest background pixel (now set to 1)
    A = distance_transform(A)

    # Return the indeces where the distance is equal to 1 as this means this pixel is adjacent to a background pixel
    return Tuple.(findall(x->x==1, A))
end


text:
struct DeepEnsemble
        models::Array
        DeepEnsemble(generator, N::Int) = new([generator() for _=1:N])
end

Flux.@functor DeepEnsemble

Flux.trainable(m::DeepEnsemble) = (Flux.trainable(model) for model in m.models)

# Get the mean and variance estimate from each network individually
function individual_forward(m::DeepEnsemble, x)
        os = [m(x) for m in m.models]
        ndim = Int(size(os[1],1) / 2)
        μs = [o[1:ndim, :] for o in os]
        σ²s = [softplus.(o[ndim+1:end, :]) .+ 1f-3 for o in os]
        μs, σ²s
end

# Compute the prediction and uncertainty of the ensemble
function (m::DeepEnsemble)(x)
        μs, σ²s = individual_forward(m, x)
        t1 = [σ² .+ μ .^2 for (μ, σ²) in zip(μs, σ²s)]
        mean(μs), mean(t1) .- mean(μs).^2
end

# The equation for the gaussian logpdf
de_gaussian_logpdf(μ, σ², y) = -log.(σ²) ./ 2f0 .- (y .- μ).^2 ./ (2f0 .*  σ²)

# Logpdf of some some x and y pair according to the full ensemble
Distributions.logpdf(m::DeepEnsemble, x, y) = de_gaussian_logpdf(m(x)..., y)

# Gets the mean negative log pdf for each network
function training_loss(m::DeepEnsemble, x, y, weights = ones(Float32, size(y)...))
        μs, σ²s = individual_forward(m, x)
        mean([-mean(weights .* de_gaussian_logpdf(μ, σ², y)) for (μ, σ²) in zip(μs, σ²s)])
end

struct DeepClassificationEnsemble
        models::Array
        DeepClassificationEnsemble(generator, N::Int) = new([generator() for _=1:N])
end

Flux.@functor DeepClassificationEnsemble

Flux.trainable(m::DeepClassificationEnsemble) = (Flux.trainable(model) for model in m.models)

# Get the mean and variance estimate from each network individually
function individual_forward(m::DeepClassificationEnsemble, x)
        ps = [softmax(m(x)) for m in m.models]
end

# Compute the prediction and uncertainty of the ensemble
function (m::DeepClassificationEnsemble)(x)
        ps = individual_forward(m, x)
        mean(ps)
end

# Logpdf of some some x and y pair according to the full ensemble
function Distributions.logpdf(m::DeepClassificationEnsemble, x, y)
        log.(sum(m(x) .* y, dims=1) .+ 1f-10)
end

# Gets the mean negative log pdf for each network
function training_loss(m::DeepClassificationEnsemble, x, y, weights = ones(Float32, size(y)...))
        ps = individual_forward(m, x)
        mean([Flux.Losses.crossentropy(p, y) for p in ps])
end


text:
include("liftedfrombindeps.jl")

# define current version:
mskvmajor = "8"
mskvminor = "0"

mskplatform,distroext =
  if Sys.ARCH == :i386 || Sys.ARCH == :i686
    if     is_linux()   "linux32x86",  ".tar.bz2"
    elseif is_windows() "win32x86",  ".zip"
    else   error("Platform not supported")
    end
  elseif Sys.ARCH == :x86_64
    if     is_linux()   "linux64x86",".tar.bz2"
    elseif is_apple()   "osx64x86",  ".tar.bz2"
    elseif is_windows() "win64x86",  ".zip"
    else   error("Platform not supported")
    end
  else
    error("Platform not supported")
  end

libalternatives =
  if     mskplatform == "linux32x86"
                                       [ ("libmosek.so.7.0",     "libmosekscopt7_0.so"),    ("libmosek.so.7.1",     "libmosekscopt7_1.so"),    ("libmosek.so.8.0",     "libmosekscopt8_0.so"),    ]
  elseif mskplatform == "linux64x86"
                                       [ ("libmosek64.so.7.0",   "libmosekscopt7_0.so"),    ("libmosek64.so.7.1",   "libmosekscopt7_1.so"),    ("libmosek64.so.8.0",   "libmosekscopt8_0.so"),    ]
  elseif mskplatform == "osx64x86"
                                       [ ("libmosek64.7.0.dylib","libmosekscopt7_0.dylib"), ("libmosek64.7.1.dylib","libmosekscopt7_1.dylib"), ("libmosek64.8.0.dylib","libmosekscopt8_0.dylib"), ]
  elseif mskplatform == "win32x86"
                                       [ ("mosek7_0.dll",        "mosekscopt7_0.dll"),      ("mosek7_1.dll",        "mosekscopt7_1.dll"),      ("mosek8_0.dll",        "mosekscopt8_0.dll"),      ]
  elseif mskplatform == "win64x86"
                                       [ ("mosek64_7_0.dll",     "mosekscopt7_0.dll"),      ("mosek64_7_1.dll",     "mosekscopt7_1.dll"),      ("mosek64_8_0.dll",     "mosekscopt8_0.dll"),      ]
  else   error("Platform not supported")
  end

bindepsdir = dirname(@__FILE__)

usepreinstalled = ! haskey(ENV,"MOSEKJL_FORCE_DOWNLOAD")

mskbindir =
# 1. Is MOSEKBINDIR set? If so this must point to the binaries dir in the MOSEK DISTRO
    if  usepreinstalled && haskey(ENV,"MOSEKBINDIR")
        ENV["MOSEKBINDIR"]
    elseif ! usepreinstalled && haskey(ENV,"MOSEK_8_0_BINDIR")
        ENV["MOSEK_8_0_BINDIR"]
    elseif ! usepreinstalled && haskey(ENV,"MOSEK_7_1_BINDIR")
        ENV["MOSEK_7_1_BINDIR"]
# 2a. Otherwise, use the default installation path (Linux)
    elseif usepreinstalled && ( haskey(ENV,"HOME") &&
                                  isdir(joinpath(ENV["HOME"],"mosek","8","tools","platform",mskplatform)))
        joinpath(ENV["HOME"],"mosek","8","tools","platform",mskplatform,"bin")
    elseif usepreinstalled && ( haskey(ENV,"HOME") &&
                                  isdir(joinpath(ENV["HOME"],"mosek","7","tools","platform",mskplatform)))
        joinpath(ENV["HOME"],"mosek","7","tools","platform",mskplatform,"bin")
# 2b. Windows default install path
    elseif usepreinstalled && (haskey(ENV,"HOMEDRIVE") &&
                                 haskey(ENV,"HOMEPATH") &&
                                 isdir(joinpath(string(ENV["HOMEDRIVE"],ENV["HOMEPATH"]),"mosek","8","tools","platform",mskplatform)))
        home = string(ENV["HOMEDRIVE"],ENV["HOMEPATH"])
        joinpath(home,"mosek","8","tools","platform",mskplatform,"bin")
    elseif usepreinstalled && (haskey(ENV,"HOMEDRIVE") &&
                                 haskey(ENV,"HOMEPATH") &&
                                 isdir(joinpath(string(ENV["HOMEDRIVE"],ENV["HOMEPATH"]),"mosek","7","tools","platform",mskplatform)))
        home = string(ENV["HOMEDRIVE"],ENV["HOMEPATH"])
        joinpath(home,"mosek","7","tools","platform",mskplatform,"bin")
# 3. Otherwise, fetch the MOSEK distro and unpack it
    else
        srcdir  = joinpath(bindepsdir,"src")
        dldir   = joinpath(bindepsdir,"downloads")
        tarname = string("mosektools",mskplatform, distroext)

        basename,ext,sndext = splittarpath(tarname)

        mkpath(dldir)
        info("Download MOSEK distro (http://download.mosek.com/stable/7/$tarname)")
        success(download_cmd(string("http://download.mosek.com/stable/7/",tarname), joinpath(dldir,tarname))) || error("Failed to download MOSEK distro")
        mkpath(srcdir)
        info("Unpack MOSEK distro ($dldir/$tarname -> $srcdir)")
        success(unpack_cmd(joinpath(dldir,tarname),srcdir, ext, sndext)) || error("Failed to unpack MOSEK distro")

        joinpath(srcdir,"mosek","7","tools","platform",mskplatform,"bin")
    end
mskbindir = replace(mskbindir,"\\","/")

idxs = reverse(find(libs -> all(lib -> isfile(joinpath(mskbindir,lib)), libs), libalternatives))
if length(idxs) == 0
    error("Failed to find any usable MOSEK libraries")
else
    libmosek,libmosekscopt = libalternatives[idxs[1]]

    libmosekpath = escape_string(normpath("$mskbindir/$libmosek"))
    libscoptpath = escape_string(normpath("$mskbindir/$libmosekscopt"))

    open(joinpath(bindepsdir,"deps.jl"),"w") do f
        write(f,"""# This is an auto-generated file; do not edit\n""")
        write(f,"""# Macro to load a library\n""")
        write(f,"""macro checked_lib(libname, path)\n""")
        write(f,"""    (Libdl.dlopen_e(path) == C_NULL) && error("Unable to load \\n\\n\$libname (\$path)\\n\\nPlease re-run Pkg.build(package), and restart Julia.")\n""")
        write(f,"""    quote const \$(esc(libname)) = \$path end\n""")
        write(f,"""end\n""")

        write(f,"""\n""")
        write(f,"""# Load dependencies\n""")
        write(f,string("""@checked_lib libmosek      \"$libmosekpath\"\n"""))
        write(f,string("""@checked_lib libmosekscopt \"$libscoptpath\"\n"""))
    end
end


text:
abstract BaseRegression

type LinearRegression <: BaseRegression
    C::Float64
    reg::String
    lr::Float64
    tolerance::Float64
    max_iters::Integer
    params::Vector
    errors::Vector
end

type LogisticRegression <: BaseRegression
    C::Float64
    reg::String
    lr::Float64
    tolerance::Float64
    max_iters::Integer
    params::Vector
    errors::Vector
end

type LeastAngleRegression <: BaseRegression
    normalize::Bool
    max_iters::Integer
    params::Vector
    errors::Vector
end

function LinearRegression(;
                          C=0.01,
                          tolerance=0.1,
                          max_iters=1000,
                          reg="None",
                          lr=0.001,
                          params=nothing,
                          errors=nothing)
    if params == nothing
        params = randn(1)
    end
    if errors == nothing
        errors = randn(1)
    end
    return LinearRegression(C,reg,lr,tolerance,max_iters,params,errors)
end

function LogisticRegression(;
                          C=0.01,
                          tolerance=0.1,
                          max_iters=1000,
                          reg="None",
                          lr=0.001,
                          params=nothing,
                          errors=nothing)
    if params == nothing
        params = randn(1)
    end
    if errors == nothing
        errors = randn(1)
    end
    return LogisticRegression(C,reg,lr,tolerance,max_iters,params,errors)
end

function LeastAngleRegression(;
    normalize=false,
    max_iters=1000,
    params=nothing,
    errors=nothing)
    if params == nothing
        params = randn(1)
    end
    if errors == nothing
        errors = randn(1)
    end
    return LeastAngleRegression(normalize,max_iters,params,errors)
end

function train!(model1::LinearRegression,
                X::Matrix,
                y::Vector)
    println("LinearRegression!$(model1.max_iters)")
    global model= model1
    n_sample = size(X,1)
    n_feature = size(X,2)

    model.params = randn(n_feature+1)*10
    model.errors = randn(n_feature+1)*10

    global X_global = hcat(X,ones(n_sample))
    global y_global = y
    cost_d = x -> ForwardDiff.gradient(cost_linear,x)
    errors_norm = 1e10
    iter_count = 0
    while errors_norm > model.tolerance && iter_count < model.max_iters
        model.params -= model.C*cost_d(model.params)
        errors_norm = cost_linear(model.params)
        println("Epoch: $(iter_count): current errors norm is $(errors_norm)")
        iter_count = iter_count + 1
    end
end

function train!(model::LogisticRegression,
                X::Matrix,
                y::Vector)
    #println("LogisticRegression!$(model.max_iters)")
    #global model = model1
    n_sample = size(X,1)
    n_feature = size(X,2)

    model.params = randn(n_feature+1)
    model.errors = randn(n_feature+1)
    X = hcat(X,ones(n_sample))
    #global X_global = hcat(X,ones(n_sample))
    #global y_global = y
    #@show y_global
    #cost_d = x -> ForwardDiff.gradient(cost_logistic,x)
    errors_norm = 1e10
    iter_count = 0
    while abs(errors_norm) > model.tolerance && iter_count < model.max_iters
        model.params -= model.C*(X' * (sigmoid(X * model.params) - y))
        errors_norm = norm(predict(model, X[:, 1:(end-1)]) - y)
        #println("Epoch: $(iter_count): current errors norm is $(errors_norm)")
        iter_count = iter_count + 1
    end
end

function train!(model1::LeastAngleRegression,
    X::Matrix,
    y::Vector)
    println("LeastAngleRegression!")
    global model= model1
    n_sample = size(X,1)
    n_feature = size(X,2)

    model.params = randn(n_feature+1)*10
    model.errors = randn(n_feature+1)*10

    if model.normalize
        for i = 1:n_feature
            X[:, i] = (X[:, i] - mean(X[:, i])) / norm(X[:, i])
        end

        y = y - mean(y)
    end

    var_y = var(y)

    global X_global = X
    global y_global = y

    coefs = zeros(1, n_feature)
    mu = zeros(n_sample, 1)

    risk = Inf

    for i = 1:n_feature
        if i > model.max_iters
            break
        end

        c = X' * (y - mu)

        # print("c ", c, '\n')

        cabs = abs(c)
        C = maximum(cabs)

        a = []
        for j = 1:n_feature
            if abs(cabs[j] - C) < 1e-10
                push!(a, j)
            end
        end

        s = sign(c[a])

        a_size = size(a)[1]

        Xa = zeros(n_sample, a_size)
        for j = 1:a_size
            Xa[:, j] = s[j] * X[:, a[j]]
        end

        Ga = Xa' * Xa

        o = ones(a_size, 1)
        Ga_inv = inv(Ga)
        Aa = sqrt(o' * Ga_inv * o)[1,1]

        wa = Aa * Ga_inv * o
        ua = Xa * wa

        A = X' * ua

        a_complement = []
        for j = 1:n_feature
            if !in(j, a)
                push!(a_complement, j)
            end
        end

        # print("C ", C, '\n')
        # print("Aa ", Aa, '\n')
        # print("c[a_c] ", c[a_complement], '\n')
        # print("A[a_c] ", A[a_complement], '\n')

        m1 = (C - c[a_complement]) ./ (Aa - A[a_complement])
        m2 = (C + c[a_complement]) ./ (Aa + A[a_complement])

        gamma = Inf

        for j = 1:size(m1)[1]
            if (m1[j] < gamma && m1[j] >= 0)
                gamma = m1[j]
            end
            if (m2[j] < gamma && m2[j] >= 0)
                gamma = m2[j]
            end
        end

        mu += gamma * ua

        riskI = norm(y - mu)^2 / var_y - n_sample + 2 * i
        if risk < riskI
            break
        end
        risk = riskI

        coefs[a] += s * gamma

        # print(coefs, '\n')
    end

    model.params = vec(coefs)
end

function predict(model::LogisticRegression,
                 x)
    n = size(x,1)
    b = ones(n)
    res = sigmoid(hcat(x,b)*model.params)
    n_ = size(res,1)
    for i = 1:n_
        if res[i] >= 0.5
            res[i] = 1
        else
            res[i] = 0
        end
    end
    return res
end

function predict(model::LinearRegression,
                 x)
    n = size(x,1)
    b = ones(n)
    return hcat(x,b)*model.params
end

function predict(model::LeastAngleRegression,
                 x)
    return x*model.params
end

function cost_linear(w::Vector)
    return add_reg(mean_squared_error(y_global, X_global*w),w)
end

function cost_logistic(X, y, w::Vector,model)
   return add_reg(binary_crossentropy(y, sign(sigmoid(X*w))),w, model)
end

function add_reg(loss,w,model)
    if model.reg == "l1"
        return loss + model.C * sum(abs(w[1:(end-1)]))
    elseif model.reg == "l2"
        return loss + 0.5 * model.C * mean(abs2(w))
    end
    return loss
end

function test_LinearRegression(;reg = "l1")

    X_train, X_test, y_train, y_test = make_reg(n_features = 1)
    model = LinearRegression(lr=0.01, max_iters=200, reg=reg, C=0.03)
    train!(model,X_train, y_train)
    predictions = predict(model,X_test)
    print("regression mse: ", mean_squared_error(y_test, predictions))
    PyPlot.scatter(X_test, y_test, color = "black")
    PyPlot.scatter(X_test, predictions, color = "green")
    legend(loc="upper right",fancybox="true")
end

function test_LogisticRegression(; reg = "l2")
    # Generate a random binary classification problem.
    X_train, X_test, y_train, y_test = make_cla()
    y_train = (y_train + 1)/2
    y_test = (y_test + 1)/2
    model = LogisticRegression(lr=0.1, max_iters=1000, reg=reg, C=0.01)
    train!(model,X_train, y_train)
    predictions = predict(model,X_test)
    println("classification accuracy: ", accuracy(y_test, predictions))

    #PCA

    pca_model = PCA()
    train!(pca_model, X_test)
    plot_in_2d(pca_model, X_test, predictions, "LogisticRegression")
end

function test_LeastAngleRegression()

    n_features = 20

    X_train, X_test, y_train, y_test = make_reg(n_features = n_features)

    for i = 1:n_features
        X_train[:, i] = (X_train[:, i] - mean(X_train[:, i])) / norm(X_train[:, i])
        X_test[:, i] = (X_test[:, i] - mean(X_test[:, i])) / norm(X_test[:, i])
    end

    y_train = y_train - mean(y_train)
    y_test = y_test - mean(y_test)

    model = LeastAngleRegression(normalize=false)
    train!(model,X_train, y_train)
    predictions = predict(model,X_test)

    print("regression mse: ", mean_squared_error(y_test, predictions))
end


text:
using IndentWrappers, Test

@testset "indent" begin
    io = IOBuffer()
    print(io, "toplevel")
    let io = indent(io, 4)
        print(io, '\n', "- level1")
        let io = indent(io, 4)
            print(io, '\n', "- level 2")
            println(io)
            println(io, "test")
            print(io, "closing")
        end
    end
    buffer = String(take!(io))
    expected = "toplevel\n    - level1\n        - level 2\n        test\n        closing"
    @test buffer == expected
end

@testset "indent string" begin
    io = IOBuffer()
    print(indent(io, 4), "hello\nworld")
    buffer = String(take!(io))
    expected = "hello\n    world"
    @test buffer == expected
end

@testset "write count" begin
    str = "a fish"
    io = indent(IOBuffer(), 8)
    @test write(io, str) == length(str)
    @test write(io, '\n', str) == length(str) + 8 + 1
end

@testset "forwarding" begin
    io = IOContext(stdout, :foo => 42)
    iw = indent(io, 5)
    @test in(:foo => 42, iw)
    @test haskey(iw, :foo)
    @test !haskey(iw, :bar)
    @test iw[:foo] == io[:foo]
    @test displaysize(iw) == displaysize(stdout)
    @test get(iw, :foo, 9) == get(io, :foo, 9)
    @test get(iw, :bar, 9) == get(io, :bar, 9)
end

@testset "show" begin
    @test repr(indent(stdout, 4)) == repr(stdout) * " indented by 4 spaces"
end


text:
# ---
# title: 1016. Binary String With Substrings Representing 1 To N
# id: problem1016
# author: Tian Jun
# date: 2020-10-31
# difficulty: Medium
# categories: String
# link: <https://leetcode.com/problems/binary-string-with-substrings-representing-1-to-n/description/>
# hidden: true
# ---
#
# Given a binary string `S` (a string consisting only of '0' and '1's) and a
# positive integer `N`, return true if and only if for every integer X from 1 to
# N, the binary representation of X is a substring of S.
#
#
#
# **Example 1:**
#
#
#
#     Input: S = "0110", N = 3
#     Output: true
#
#
# **Example 2:**
#
#
#
#     Input: S = "0110", N = 4
#     Output: false
#
#
#
#
# **Note:**
#
#   1. `1 <= S.length <= 1000`
#   2. `1 <= N <= 10^9`
#
#
## @lc code=start
using LeetCode

## add your code here:
## @lc code=end


text:
const API_TOURNAMENT_URL = "https://api-tournament.numer.ai"

abstract type BaseAPI end

function _handle_call_error()
  # TODO
end

function raw_query(api::BaseAPI, query::String;
                    variables::Union{Dict,Nothing}=nothing,
                    authorization::Bool=false)::Dict

  body = Dict( "query" => query, "variables" => variables )

  headers = Dict(
    "Content-Type" => "application/json",
    "Accept" => "application/json"
  )

  if authorization
    public_id = api.public_id
    secret_key = api.secret_key
    headers["Authorization"] = "Token $public_id\$$secret_key"
  end

  result = post_with_err_handling(API_TOURNAMENT_URL, body, headers)

  # if result and "errors" in result:
  #     err = self._handle_call_error(result['errors'])
  #     # fail!
  #     raise ValueError(err)
  # end

  return result
end

function _get_account(api::BaseAPI)::Dict{String,Any}
  query = """
    query {
      account {
        username
        walletAddress
        availableNmr
        email
        id
        mfaEnabled
        status
        insertedAt
        models {
          id
          name
          submissions {
            id
            filename
          }
          v2Stake {
            status
            txHash
          }
        }
        apiTokens {
          name
          public_id
          scopes
        }
      }
    }
  """
  data = raw_query(api, query, authorization=true)["data"]["account"]
  data["insertedAt"] = parse_datetime_string(data["insertedAt"])
  data["availableNmr"] = parse_float_string(data["availableNmr"])
  return data
end

function _get_models(api::BaseAPI)::Dict{String,String}
  query = """
    query {
      account {
        models {
          id
          name
          tournament
        }
      }
    }
  """
  data = raw_query(api, query, authorization=true)["data"]["account"]["models"]
  mapping = Dict(
    model["name"] => model["id"]
      for model in data if model["tournament"] == api.tournament
  )
  return mapping
end

function _get_current_round(api::BaseAPI)::Union{Real,Nothing}
  query = """
    query(\$tournament: Int!) {
      rounds(tournament: \$tournament number: 0) {
        number
      }
    }
  """
  variables = Dict( "tournament" => api.tournament )
  data = raw_query(api, query, variables=variables)["data"]["rounds"][1]
  round_num = isempty(data) ? nothing : data["number"]
  return round_num
end

function _get_account_transactions(api::BaseAPI)::Dict{String,Vector}
  query = """
    query {
      account {
        nmrDeposits {
          from
          posted
          status
          to
          txHash
          value
          insertedAt
        }
        nmrWithdrawals {
          from
          posted
          status
          to
          txHash
          value
          insertedAt
        }
      }
    }
  """
  account = raw_query(api, query, authorization=true)["data"]["account"]

  for transaction in account["nmrWithdrawals"]
    transaction["value"] = parse_float_string(transaction["value"])
    transaction["insertedAt"] = parse_datetime_string(transaction["insertedAt"])
  end

  for transaction in account["nmrDeposits"]
    transaction["value"] = parse_float_string(transaction["value"])
    transaction["insertedAt"] = parse_datetime_string(transaction["insertedAt"])
  end

  return account
end

"""
    set_submission_webhook(api::BaseAPI,
                            model_id::String,
                            webook::String)

Set a model's submission webhook used in Numerai Compute

"""
function _set_submission_webhook(api::BaseAPI, model_id::String, webook::String)::Bool
  # TODO
  query = """
    mutation (
      \$modelId: String!
      \$newSubmissionWebhook: String
    ) {
      setSubmissionWebhook(
        modelId: \$modelId
        newSubmissionWebhook: \$newSubmissionWebhook
      )
    }
  """
  variables = Dict(
    "modelId" => model_id,
    "newSubmissionWebhook" => webook
  )
  res = raw_query(api, query, variables=variables, authorization=true)
  return res["data"]["setSubmissionWebhook"] == "true"
end


text:
# a distribution sampler samples from a named univariate parameter distribution; it ignores any support constraints
abstract DistributionSampler <: Sampler
abstract DiscreteDistributionSampler <: DistributionSampler
abstract ContinuousDistributionSampler <: DistributionSampler

paramranges(s::DistributionSampler) = copy(s.paramranges)

function sample(s::DistributionSampler, support, cc::ChoiceContext)
	x = rand(s.distribution)
	# we return both the sampled value, and a dict as trace information
	x, Dict{Symbol,Any}(:rnd=>x)
end

function extractsamplesfromtraces(s::DistributionSampler, traces)
	samples = map(trace->trace[:rnd], traces)
	convert(typeof(s) <: DiscreteDistributionSampler ? Vector{Int} : Vector{Float64}, samples)
end

# workaround for call to fit: it needs the unparameterised (primary) type of the distribution
# otherwise function suffstats raises an error as there isn't a suitable method to use (in Distributions.jl 0.11.0+)
primarydistributiontype(d::Distribution) = typeof(d).name.primary

# for Normal, Uniform, and DiscreteUniform, there is a type-specific version that calls this with minsamples of 2
function estimateparams!(s::DistributionSampler, traces, minsamples::Int = 1)
	samples = extractsamplesfromtraces(s, traces)
	if length(samples) >= minsamples
		s.distribution = fit(primarydistributiontype(s.distribution), samples)
	end
end

amendtrace(s::DistributionSampler, trace, x) = trace[:rnd] = x

include("sampler_utils.jl")
include("bernoulli_sampler.jl")
include("categorical_sampler.jl")
include("discrete_uniform_sampler.jl")
include("geometric_sampler.jl")
include("normal_sampler.jl")
include("uniform_sampler.jl")
include("poisson_sampler.jl")

# pretty print the sampler
function show(io::IO, s::DistributionSampler, indentdepth::Int=1)
	# since this sampler will be a 'leaf' in the sampler tree, can finish with a new line
	println(io, getsamplertypename(s) * " $(getparams(s))")
end

minimumsupport(s::DistributionSampler) = minimum(s.distribution)


text:
module COSMIC

using Logging
@Logging.configure(level=DEBUG)
using DataFrames
using Compat
#using Docile
using JLD
using HDF5
using ParallelAccelerator
import Base.start, Base.next, Base.done

export
    start,next,done,
    build_raw_samples

include("utils.jl")
include("cosmic.jl")

function __init__()
#     @pline "1"
end

end # module


text:
using Test
using Bigsimr
using Distributions

@testset "Generalized S-Distribution" begin
    D = Gamma(2, 2)
    G = Bigsimr.GSDist(D)

    @testset "Parameter retrieval" begin
        @test_nowarn params(G)
    end

    @testset "Computation of statistics" begin
        @test_nowarn mean(G)
        @test_nowarn var(G)
        @test_nowarn std(G)
        @test_nowarn median(G)
    end

    @testset "Probability evaluation" begin
        x = median(G)
        y = median(G) + 1

        @test_nowarn quantile(G, 0.3)
        @test_nowarn cquantile(G, 0.3)
    end

    @testset "Sampling" begin
        @test_nowarn sampler(G)
        @test_nowarn rand(G, 10)
    end

    @testset "Pearson Matching w/ GSDist" begin
        dA = NegativeBinomial(20, 0.1)
        dB = Gamma(100, 4)

        # Converting to GSDist must warn the user
        msg = "$dA was converted to a GSDist for computational efficiency"
        @test_logs (:warn, msg) (:warn, msg) pearson_match(-0.9, dA, dA)
        @test_logs (:warn, msg)              pearson_match(-0.9, dA, dB)
        @test_logs (:warn, msg)              pearson_match(-0.9, dB, dA)

        # Not converting does not warn the user
        @test_nowarn pearson_match(-0.9, dB, dB)
        @test_nowarn pearson_match(-0.9, dA, dA, convert=false)
        @test_nowarn pearson_match(-0.9, dA, dB, convert=false)
        @test_nowarn pearson_match(-0.9, dB, dA, convert=false)
        @test_nowarn pearson_match(-0.9, dB, dB, convert=false)

        # Converting must retain accuracy
        @test pearson_match(-0.9, dA, dA) ≈ pearson_match(-0.9, dA, dA, convert=false) atol=0.05
        # @test pearson_match(-0.9, dA, dB) ≈ pearson_match(-0.9, dA, dB, convert=false) atol=0.05
        # @test pearson_match(-0.9, dB, dA) ≈ pearson_match(-0.9, dB, dA, convert=false) atol=0.05
        @test pearson_match(-0.9, dB, dB) ≈ pearson_match(-0.9, dB, dB, convert=false) atol=0.05
    end

end


text:
#-------------------------------------------------------------------------#
#                                                                         #
#                               Simulating_nets                           #
#                                                                         #
#-------------------------------------------------------------------------#

#-------------------------------------------------------------------------#
# OBSERVATIONS:

# 1. This code is for simulating phylogenetic networks in a Newick format
# 2. This code is a work in progress
# 3. The functions are in the file Fn_PhyloSim
# 4. The principal example is on "Example of a random tree generation" section
#
#-------------------------------------------------------------------------#

## Packages
# using Plots
using PhyloNetworks
using PhyloPlots

## Example of a random tree generation

# Including functions
include("Fn_PhyloSim.jl")
# Fixing seed
# Random.seed!(42)

# Different taxa examples
taxa = ["1ba","b","c","d"]
taxa = ["A","B"]
taxa = collect('a':'d')
taxa = collect('a':'z')
taxa = string.(1:40)

# Total branch lengths
total_bl = 10

# Return a network of a tree
is_network = true

# Generating a random tree topology and branch length in Newikc format
x = Sim_tree(taxa,total_bl,is_network)
print(join(x))

# Transformation to a "HybridNetwork" variable of the package PhyloNetworks
net = readTopology(join(x))
tipLabels(net)

# Plot of the network
plot(net,:R,showEdgeLength=true,showGamma=true)
# plot(net,:R,showEdgeLength=true)
# plot(net,:R)
net
## Some info about the network
printEdges(net)

max_stars_repo_name: ArrigoCoen/PhyloSim

max_issues_repo_name: ArrigoCoen/PhyloSim

max_forks_repo_name: ArrigoCoen/PhyloSim


text:
"""
    #checks for parity errors.
    $(SIGNATURES)

    # Details
    # Uses the parity algorithm to compute parity and compare them to given parity bits
"""
function parity_check(word, prev_29, prev_30)

        # Parity check to verify the data integrity:
    D_25 = prev_29 ⊻ word[1] ⊻ word[2] ⊻ word[3] ⊻ word[5] ⊻ word[6] ⊻ word[10] ⊻ word[11] ⊻ word[12] ⊻ word[13] ⊻ word[14] ⊻ word[17] ⊻ word[18] ⊻ word[20] ⊻ word[23]
    D_26 = prev_30 ⊻ word[2] ⊻ word[3] ⊻ word[4] ⊻ word[6] ⊻ word[7] ⊻ word[11] ⊻ word[12] ⊻ word[13] ⊻ word[14] ⊻ word[15] ⊻ word[18] ⊻ word[19] ⊻ word[21] ⊻ word[24]
    D_27 = prev_29 ⊻ word[1] ⊻ word[3] ⊻ word[4] ⊻ word[5] ⊻ word[7] ⊻ word[8] ⊻ word[12] ⊻ word[13] ⊻ word[14] ⊻ word[15] ⊻ word[16] ⊻ word[19] ⊻ word[20] ⊻ word[22]
    D_28 = prev_30 ⊻ word[2] ⊻ word[4] ⊻ word[5] ⊻ word[6] ⊻ word[8] ⊻ word[9] ⊻ word[13] ⊻ word[14] ⊻ word[15] ⊻ word[16] ⊻ word[17] ⊻ word[20] ⊻ word[21] ⊻ word[23]
    D_29 = prev_30 ⊻ word[1] ⊻ word[3] ⊻ word[5] ⊻ word[6] ⊻ word[7] ⊻ word[9] ⊻ word[10] ⊻ word[14] ⊻ word[15] ⊻ word[16] ⊻ word[17] ⊻ word[18] ⊻ word[21] ⊻ word[22] ⊻ word[24]
    D_30 = prev_29 ⊻ word[3] ⊻ word[5] ⊻ word[6] ⊻ word[8] ⊻ word[9] ⊻ word[10] ⊻ word[11] ⊻ word[13] ⊻ word[15] ⊻ word[19] ⊻ word[22] ⊻ word[23] ⊻ word[24]

    computed_parity_bits = [D_25, D_26, D_27, D_28, D_29, D_30]
    data_integrity = computed_parity_bits == word[25:30]
    return data_integrity
end


text:
using ImageCore, ImageAxes, IndirectArrays
using Test, Statistics

mods0 = (Statistics, ImageCore, ImageAxes, IndirectArrays, Base, Core)
ambs0 = detect_ambiguities(mods0...)

using ImageMetadata
ambs = setdiff(detect_ambiguities(ImageMetadata, mods0...), ambs0)
if !isempty(ambs)
    println("Ambiguities:")
    for a in ambs
        println(a)
    end
end
#@test isempty(ambs)

include("core.jl")
include("operations.jl")
include("deprecations.jl")


text:
#=
This file is auto-generated. Do not edit.
=#
"""
    mutable struct HydroDispatch <: HydroGen
        name::String
        available::Bool
        bus::Bus
        activepower::Float64
        reactivepower::Float64
        rating::Float64
        primemover::PrimeMovers.PrimeMover
        activepowerlimits::Min_Max
        reactivepowerlimits::Union{Nothing, Min_Max}
        ramplimits::Union{Nothing, NamedTuple{(:up, :down), Tuple{Float64, Float64}}}
        timelimits::Union{Nothing, NamedTuple{(:up, :down), Tuple{Float64, Float64}}}
        basepower::Float64
        services::Vector{Service}
        dynamic_injector::Union{Nothing, DynamicInjection}
        ext::Dict{String, Any}
        forecasts::InfrastructureSystems.Forecasts
        internal::InfrastructureSystemsInternal
    end

# Arguments
- `name::String`
- `available::Bool`
- `bus::Bus`
- `activepower::Float64`
- `reactivepower::Float64`, validation range: reactivepowerlimits, action if invalid: warn
- `rating::Float64`: Thermal limited MVA Power Output of the unit. <= Capacity, validation range: (0, nothing), action if invalid: error
- `primemover::PrimeMovers.PrimeMover`: PrimeMover Technology according to EIA 923
- `activepowerlimits::Min_Max`
- `reactivepowerlimits::Union{Nothing, Min_Max}`, action if invalid: warn
- `ramplimits::Union{Nothing, NamedTuple{(:up, :down), Tuple{Float64, Float64}}}`: ramp up and ramp down limits, validation range: (0, nothing), action if invalid: error
- `timelimits::Union{Nothing, NamedTuple{(:up, :down), Tuple{Float64, Float64}}}`: Minimum up and Minimum down time limits in hours, validation range: (0, nothing), action if invalid: error
- `basepower::Float64`: Base power of the unit in system base per unit, validation range: (0, nothing), action if invalid: warn
- `services::Vector{Service}`: Services that this device contributes to
- `dynamic_injector::Union{Nothing, DynamicInjection}`: corresponding dynamic injection device
- `ext::Dict{String, Any}`
- `forecasts::InfrastructureSystems.Forecasts`: internal forecast storage
- `internal::InfrastructureSystemsInternal`: power system internal reference, do not modify
"""
mutable struct HydroDispatch <: HydroGen
    name::String
    available::Bool
    bus::Bus
    activepower::Float64
    reactivepower::Float64
    "Thermal limited MVA Power Output of the unit. <= Capacity"
    rating::Float64
    "PrimeMover Technology according to EIA 923"
    primemover::PrimeMovers.PrimeMover
    activepowerlimits::Min_Max
    reactivepowerlimits::Union{Nothing, Min_Max}
    "ramp up and ramp down limits"
    ramplimits::Union{Nothing, NamedTuple{(:up, :down), Tuple{Float64, Float64}}}
    "Minimum up and Minimum down time limits in hours"
    timelimits::Union{Nothing, NamedTuple{(:up, :down), Tuple{Float64, Float64}}}
    "Base power of the unit in system base per unit"
    basepower::Float64
    "Services that this device contributes to"
    services::Vector{Service}
    "corresponding dynamic injection device"
    dynamic_injector::Union{Nothing, DynamicInjection}
    ext::Dict{String, Any}
    "internal forecast storage"
    forecasts::InfrastructureSystems.Forecasts
    "power system internal reference, do not modify"
    internal::InfrastructureSystemsInternal
end

function HydroDispatch(name, available, bus, activepower, reactivepower, rating, primemover, activepowerlimits, reactivepowerlimits, ramplimits, timelimits, basepower, services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), forecasts=InfrastructureSystems.Forecasts(), )
    HydroDispatch(name, available, bus, activepower, reactivepower, rating, primemover, activepowerlimits, reactivepowerlimits, ramplimits, timelimits, basepower, services, dynamic_injector, ext, forecasts, InfrastructureSystemsInternal(), )
end

function HydroDispatch(; name, available, bus, activepower, reactivepower, rating, primemover, activepowerlimits, reactivepowerlimits, ramplimits, timelimits, basepower, services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), forecasts=InfrastructureSystems.Forecasts(), )
    HydroDispatch(name, available, bus, activepower, reactivepower, rating, primemover, activepowerlimits, reactivepowerlimits, ramplimits, timelimits, basepower, services, dynamic_injector, ext, forecasts, )
end

# Constructor for demo purposes; non-functional.
function HydroDispatch(::Nothing)
    HydroDispatch(;
        name="init",
        available=false,
        bus=Bus(nothing),
        activepower=0.0,
        reactivepower=0.0,
        rating=0.0,
        primemover=PrimeMovers.HY,
        activepowerlimits=(min=0.0, max=0.0),
        reactivepowerlimits=nothing,
        ramplimits=nothing,
        timelimits=nothing,
        basepower=0.0,
        services=Device[],
        dynamic_injector=nothing,
        ext=Dict{String, Any}(),
        forecasts=InfrastructureSystems.Forecasts(),
    )
end

InfrastructureSystems.get_name(value::HydroDispatch) = value.name
"""Get HydroDispatch available."""
get_available(value::HydroDispatch) = value.available
"""Get HydroDispatch bus."""
get_bus(value::HydroDispatch) = value.bus
"""Get HydroDispatch activepower."""
get_activepower(value::HydroDispatch) = value.activepower
"""Get HydroDispatch reactivepower."""
get_reactivepower(value::HydroDispatch) = value.reactivepower
"""Get HydroDispatch rating."""
get_rating(value::HydroDispatch) = value.rating
"""Get HydroDispatch primemover."""
get_primemover(value::HydroDispatch) = value.primemover
"""Get HydroDispatch activepowerlimits."""
get_activepowerlimits(value::HydroDispatch) = value.activepowerlimits
"""Get HydroDispatch reactivepowerlimits."""
get_reactivepowerlimits(value::HydroDispatch) = value.reactivepowerlimits
"""Get HydroDispatch ramplimits."""
get_ramplimits(value::HydroDispatch) = value.ramplimits
"""Get HydroDispatch timelimits."""
get_timelimits(value::HydroDispatch) = value.timelimits
"""Get HydroDispatch basepower."""
get_basepower(value::HydroDispatch) = value.basepower
"""Get HydroDispatch services."""
get_services(value::HydroDispatch) = value.services
"""Get HydroDispatch dynamic_injector."""
get_dynamic_injector(value::HydroDispatch) = value.dynamic_injector
"""Get HydroDispatch ext."""
get_ext(value::HydroDispatch) = value.ext

InfrastructureSystems.get_forecasts(value::HydroDispatch) = value.forecasts
"""Get HydroDispatch internal."""
get_internal(value::HydroDispatch) = value.internal

InfrastructureSystems.set_name!(value::HydroDispatch, val::String) = value.name = val
"""Set HydroDispatch available."""
set_available!(value::HydroDispatch, val::Bool) = value.available = val
"""Set HydroDispatch bus."""
set_bus!(value::HydroDispatch, val::Bus) = value.bus = val
"""Set HydroDispatch activepower."""
set_activepower!(value::HydroDispatch, val::Float64) = value.activepower = val
"""Set HydroDispatch reactivepower."""
set_reactivepower!(value::HydroDispatch, val::Float64) = value.reactivepower = val
"""Set HydroDispatch rating."""
set_rating!(value::HydroDispatch, val::Float64) = value.rating = val
"""Set HydroDispatch primemover."""
set_primemover!(value::HydroDispatch, val::PrimeMovers.PrimeMover) = value.primemover = val
"""Set HydroDispatch activepowerlimits."""
set_activepowerlimits!(value::HydroDispatch, val::Min_Max) = value.activepowerlimits = val
"""Set HydroDispatch reactivepowerlimits."""
set_reactivepowerlimits!(value::HydroDispatch, val::Union{Nothing, Min_Max}) = value.reactivepowerlimits = val
"""Set HydroDispatch ramplimits."""
set_ramplimits!(value::HydroDispatch, val::Union{Nothing, NamedTuple{(:up, :down), Tuple{Float64, Float64}}}) = value.ramplimits = val
"""Set HydroDispatch timelimits."""
set_timelimits!(value::HydroDispatch, val::Union{Nothing, NamedTuple{(:up, :down), Tuple{Float64, Float64}}}) = value.timelimits = val
"""Set HydroDispatch basepower."""
set_basepower!(value::HydroDispatch, val::Float64) = value.basepower = val
"""Set HydroDispatch services."""
set_services!(value::HydroDispatch, val::Vector{Service}) = value.services = val
"""Set HydroDispatch ext."""
set_ext!(value::HydroDispatch, val::Dict{String, Any}) = value.ext = val

InfrastructureSystems.set_forecasts!(value::HydroDispatch, val::InfrastructureSystems.Forecasts) = value.forecasts = val
"""Set HydroDispatch internal."""
set_internal!(value::HydroDispatch, val::InfrastructureSystemsInternal) = value.internal = val


text:
#df = readtime(Pkg.dir("PortfolioModels/test/data/monthlies.csv"))
df = readtime(Pkg.dir("PortfolioModels/test/data/monthlies_parsable.csv"))

g  = globalmin(df)

@test_approx_eq 0.456204551678408   g[1,1] #  0.4562 from Zivot's derivation
@test_approx_eq 0.2232518040053831  g[1,2] #  0.2233
@test_approx_eq 0.223251804005383   g[1,2] #  0.2233
@test_approx_eq 0.05122725260835459 g[1,3] #  0.0512
@test_approx_eq 0.2693163917078543  g[1,4] #  0.2693

# > muhat.vals
#    Boeing Nordstrom Starbucks Microsoft
#  0.011300  0.001545  0.028461  0.042712


text:
# This file checks that the compiled CSS files for the HTML themes are up to date.
#
# This does not run as part of the standard test suite, since the CSS produced by libsass
# is likely not deterministic across libsass versions.
#
# However, we can still run these tests as part of the CI, and ignore the results as needed.
using Test
using Documenter.Writers: HTMLWriter
using DocumenterTools: Themes

@testset "HTML themes" begin
    @test isdir(HTMLWriter.ASSETS)
    @test isdir(HTMLWriter.ASSETS_SASS)
    @test isdir(HTMLWriter.ASSETS_THEMES)

    for theme in HTMLWriter.THEMES
        @test isfile(joinpath(HTMLWriter.ASSETS_SASS, "$(theme).scss"))
        @test isfile(joinpath(HTMLWriter.ASSETS_THEMES, "$(theme).css"))
    end

    mktempdir() do tmpdir
        for theme in HTMLWriter.THEMES
            dst = joinpath(tmpdir, "$(theme).css")
            Themes.compile_native_theme(theme; dst=dst)
            css_compiled = read(dst)
            css_repo = read(joinpath(HTMLWriter.ASSETS_THEMES, "$(theme).css"))
            @test css_compiled == css_repo
        end
    end
end


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

using Markdown
using InteractiveUtils

# ╔═╡ 7306f20f-9da1-4419-9222-1704fd296ee8
begin
	using ClimateBase, NCDatasets, Downloads, Dates, PlutoUI
	"Done with loading packages"
end

# ╔═╡ 15f947af-0485-433c-a424-ba0c0a5f376a
md"""# Alternative NetCDF Methods

The examples below focus on reading CF-compliant NetCDF datasets.

- [NCDataSets.jl](https://alexander-barth.github.io/NCDatasets.jl/latest/) : loading/writing NetCDF data, as well as doing basic numerics with them.
- [ClimateBase.jl](https://juliaclimate.github.io/ClimateBase.jl/dev/) provides tools to analyze and manipulate climate (spatiotemporal) data.
- [ClimateTools.jl](https://github.com/JuliaClimate/ClimateTools.jl) is a collection of commonly-used tools in Climate science.

_More packages to add : NetCDF.jl, DiskArrays.jl, NCTiles.jl, ..._
"""

# ╔═╡ e112e6e8-50b8-496e-b4ea-8c37a288e4a0
TableOfContents()

# ╔═╡ d9874aec-7c7f-4818-81a8-a5fd520159d5
md"""## Standard Test Case : NCDataSets.jl"""

# ╔═╡ e39f0208-c7a1-44fc-b4b9-07f83a86e8d8
md"""## Standard Test Case : ClimateBase.jl"""

# ╔═╡ 0a92c84f-bc1c-4624-ada3-d4202e9f37fa
md"""## Standard Test Case : ClimateTools.jl

!!! warning
    The `ClimateTools.jl` test are commented out due to the package's use of deprecated package dependency versions -- using these seems to conflict with using of e.g. current version of ClimateBase.jl.
"""

# ╔═╡ d2ae000a-4c5a-4289-aaee-431e064a7aef
md"""
```
let
	using ClimateTools
	fil=joinpath(tempdir(),"sresa1b_ncar_ccsm3-example.nc")

	C=load(fil,"tas")
	Csub =  temporalsubset(C, (2000,05,16,12), (2000,05,16,12))
	poly=[NaN -90.0 0.0 0.0 -90.0 -90.0 ; NaN -90.0 -90.0 0.0 0.0 -90.0]
	spatialsubset(C,poly)
end
```
"""

# ╔═╡ e5ef340e-e087-4b2b-be6e-da6255e3677a
md"""## Extended Testing : ClimateTools.jl"""

# ╔═╡ bd831162-b479-4148-9031-de6529f4bf89
md"""
```
let
	using ClimateTools
	fil=joinpath(tempdir(),"tas_day_MIROC5_piControl_r1i1p1_20000101-20091231.nc")

	if isfile(fil)
		C=load(fil,"tas")
		Csub = resample(C, "JJA") # hardcoded ClimateTools's season
		Csub =  temporalsubset(C, (2000,06,01,12), (2000,06,02,12))
		poly=[NaN -90.0 0.0 0.0 -90.0 -90.0 ; NaN -90.0 -90.0 0.0 0.0 -90.0]
		spatialsubset(C,poly)
	end
end
```
"""

# ╔═╡ af6450d9-d92a-4331-853f-cd19ff72abd2
begin
		url_large_file="http://esgf-data1.diasjp.net/thredds/fileServer/esg_dataroot/cmip5/output1/MIROC/MIROC5/piControl/day/atmos/day/r1i1p1/v20161012/tas/tas_day_MIROC5_piControl_r1i1p1_20000101-20091231.nc"
	md"""## Download Test File

	For extended and performance testing, download the large file ([this url](url_large_file)).
	"""
end

# ╔═╡ 9f0a3ab4-9d79-11ec-33e2-eb9616058d43
begin
	#url="http://esgf-data1.diasjp.net/thredds/fileServer/esg_dataroot/cmip5/output1/MIROC/MIROC5/piControl/day/atmos/day/r1i1p1/v20161012/tas/tas_day_MIROC5_piControl_r1i1p1_20000101-20091231.nc"
	#fil=joinpath(tempdir(),"tas_day_MIROC5_piControl_r1i1p1_20000101-20091231.nc")

	url="https://github.com/JuliaClimate/ClimateTools.jl/raw/master/test/data/sresa1b_ncar_ccsm3-example.nc"
	fil=joinpath(tempdir(),"sresa1b_ncar_ccsm3-example.nc")

	!isfile(fil) ? Downloads.download(url,fil) : nothing
	"File currently used : $(fil)"
end

# ╔═╡ 6c52f938-86db-496c-a1c2-ffdd7836f533
begin
	ds=NCDataset(fil)
	tas_NCDatasets = ds["tas"]
end

# ╔═╡ 88714902-cf5f-4cd7-adb3-443dd6d48c35
begin
	#Tutorial example:
	lats = -90:5:90
	lons = 0:10:359
	t = Date(2000, 3, 15):Month(1):Date(2020, 3, 15)
	dimensions = (Lon(lons), Lat(lats), Ti(t))
	data = rand(36, 37, 241) # same size as `dimensions`
	A = ClimArray(data, dimensions)

	#Reading from file:
	tas_ClimateBase = ncread(fil,"tas")
end

# ╔═╡ d164f293-b571-4218-8411-bf01f52e7a20
md"""## Packages"""

# ╔═╡ 00000000-0000-0000-0000-000000000001
PLUTO_PROJECT_TOML_CONTENTS = """
[deps]
ClimateBase = "35604d93-0fb8-4872-9436-495b01d137e2"
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6"
NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab"
PlutoUI = "7f904dfe-b85e-4ff6-b463-dae2292396a8"

[compat]
ClimateBase = "~0.15.1"
NCDatasets = "~0.11.9"
PlutoUI = "~0.7.36"
"""

# ╔═╡ 00000000-0000-0000-0000-000000000002
PLUTO_MANIFEST_TOML_CONTENTS = """
# This file is machine-generated - editing it directly is not advised

julia_version = "1.7.2"
manifest_format = "2.0"

[[deps.AbstractFFTs]]
deps = ["ChainRulesCore", "LinearAlgebra"]
git-tree-sha1 = "6f1d9bc1c08f9f4a8fa92e3ea3cb50153a1b40d4"
uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c"
version = "1.1.0"

[[deps.AbstractPlutoDingetjes]]
deps = ["Pkg"]
git-tree-sha1 = "8eaf9f1b4921132a4cff3f36a1d9ba923b14a481"
uuid = "6e696c72-6542-2067-7265-42206c756150"
version = "1.1.4"

[[deps.Adapt]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "af92965fb30777147966f58acb05da51c5616b5f"
uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
version = "3.3.3"

[[deps.ArgTools]]
uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f"

[[deps.ArrayInterface]]
deps = ["Compat", "IfElse", "LinearAlgebra", "Requires", "SparseArrays", "Static"]
git-tree-sha1 = "d49f55ff9c7ee06930b0f65b1df2bfa811418475"
uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9"
version = "4.0.4"

[[deps.ArrayLayouts]]
deps = ["Compat", "FillArrays", "LinearAlgebra", "SparseArrays"]
git-tree-sha1 = "a577e27915fdcb3f6b96118b56655b38e3b466f2"
uuid = "4c555306-a7a7-4459-81d9-ec55ddd5c99a"
version = "0.4.12"

[[deps.Artifacts]]
uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33"

[[deps.AxisAlgorithms]]
deps = ["LinearAlgebra", "Random", "SparseArrays", "WoodburyMatrices"]
git-tree-sha1 = "66771c8d21c8ff5e3a93379480a2307ac36863f7"
uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950"
version = "1.0.1"

[[deps.BandedMatrices]]
deps = ["ArrayLayouts", "Compat", "FillArrays", "LinearAlgebra", "Random", "SparseArrays"]
git-tree-sha1 = "8c83ee44dc9835263760ad4e77ed4eed4b3490c1"
uuid = "aae01518-5342-5314-be14-df237901396f"
version = "0.15.25"

[[deps.Base64]]
uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"

[[deps.CFTime]]
deps = ["Dates", "Printf"]
git-tree-sha1 = "bca6cb6ee746e6485ca4535f6cc29cf3579a0f20"
uuid = "179af706-886a-5703-950a-314cd64e0468"
version = "0.1.1"

[[deps.Calculus]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "f641eb0a4f00c343bbc32346e1217b86f3ce9dad"
uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9"
version = "0.5.1"

[[deps.ChainRulesCore]]
deps = ["Compat", "LinearAlgebra", "SparseArrays"]
git-tree-sha1 = "c9a6160317d1abe9c44b3beb367fd448117679ca"
uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
version = "1.13.0"

[[deps.ChangesOfVariables]]
deps = ["ChainRulesCore", "LinearAlgebra", "Test"]
git-tree-sha1 = "bf98fa45a0a4cee295de98d4c1462be26345b9a1"
uuid = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0"
version = "0.1.2"

[[deps.ClimateBase]]
deps = ["Dates", "DimensionalData", "Interpolations", "NCDatasets", "Requires", "SignalDecomposition", "StaticArrays", "Statistics", "StatsBase"]
git-tree-sha1 = "71ff28714da3f02404f8ff4c522301aec74c305a"
uuid = "35604d93-0fb8-4872-9436-495b01d137e2"
version = "0.15.1"

[[deps.ColorTypes]]
deps = ["FixedPointNumbers", "Random"]
git-tree-sha1 = "024fe24d83e4a5bf5fc80501a314ce0d1aa35597"
uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f"
version = "0.11.0"

[[deps.Compat]]
deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "SHA", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"]
git-tree-sha1 = "44c37b4636bc54afac5c574d2d02b625349d6582"
uuid = "34da2185-b29b-5c13-b0c7-acf172513d20"
version = "3.41.0"

[[deps.CompilerSupportLibraries_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae"

[[deps.ConstructionBase]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "f74e9d5388b8620b4cee35d4c5a618dd4dc547f4"
uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9"
version = "1.3.0"

[[deps.DSP]]
deps = ["FFTW", "IterTools", "LinearAlgebra", "Polynomials", "Random", "Reexport", "SpecialFunctions", "Statistics"]
git-tree-sha1 = "2a63cb5fc0e8c1f0f139475ef94228c7441dc7d0"
uuid = "717857b8-e6f2-59f4-9121-6e50c889abd2"
version = "0.6.10"

[[deps.DataAPI]]
git-tree-sha1 = "cc70b17275652eb47bc9e5f81635981f13cea5c8"
uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a"
version = "1.9.0"

[[deps.DataStructures]]
deps = ["Compat", "InteractiveUtils", "OrderedCollections"]
git-tree-sha1 = "3daef5523dd2e769dad2365274f760ff5f282c7d"
uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
version = "0.18.11"

[[deps.DataValueInterfaces]]
git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6"
uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464"
version = "1.0.0"

[[deps.Dates]]
deps = ["Printf"]
uuid = "ade2ca70-3891-5945-98fb-dc099432e06a"

[[deps.DelayEmbeddings]]
deps = ["Distances", "Distributions", "LinearAlgebra", "Neighborhood", "Random", "StaticArrays", "Statistics", "StatsBase"]
git-tree-sha1 = "78fe228cf9f8b4f7badc393cd40b6af8de936479"
uuid = "5732040d-69e3-5649-938a-b6b4f237613f"
version = "2.1.0"

[[deps.DelimitedFiles]]
deps = ["Mmap"]
uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab"

[[deps.DensityInterface]]
deps = ["InverseFunctions", "Test"]
git-tree-sha1 = "80c3e8639e3353e5d2912fb3a1916b8455e2494b"
uuid = "b429d917-457f-4dbc-8f4c-0cc954292b1d"
version = "0.4.0"

[[deps.DimensionalData]]
deps = ["Adapt", "ArrayInterface", "ConstructionBase", "Dates", "IntervalSets", "LinearAlgebra", "Random", "RecipesBase", "SparseArrays", "Statistics", "Tables"]
git-tree-sha1 = "40bf62b8912fbe675c2f11ec6ba491e67ae4d5d9"
uuid = "0703355e-b756-11e9-17c0-8b28908087d0"
version = "0.20.4"

[[deps.Distances]]
deps = ["LinearAlgebra", "SparseArrays", "Statistics", "StatsAPI"]
git-tree-sha1 = "3258d0659f812acde79e8a74b11f17ac06d0ca04"
uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7"
version = "0.10.7"

[[deps.Distributed]]
deps = ["Random", "Serialization", "Sockets"]
uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b"

[[deps.Distributions]]
deps = ["ChainRulesCore", "DensityInterface", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SparseArrays", "SpecialFunctions", "Statistics", "StatsBase", "StatsFuns", "Test"]
git-tree-sha1 = "9d3c0c762d4666db9187f363a76b47f7346e673b"
uuid = "31c24e10-a181-5473-b8eb-7969acd0382f"
version = "0.25.49"

[[deps.DocStringExtensions]]
deps = ["LibGit2"]
git-tree-sha1 = "b19534d1895d702889b219c382a6e18010797f0b"
uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
version = "0.8.6"

[[deps.Downloads]]
deps = ["ArgTools", "LibCURL", "NetworkOptions"]
uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6"

[[deps.DualNumbers]]
deps = ["Calculus", "NaNMath", "SpecialFunctions"]
git-tree-sha1 = "90b158083179a6ccbce2c7eb1446d5bf9d7ae571"
uuid = "fa6b7ba4-c1ee-5f82-b5fc-ecf0adba8f74"
version = "0.6.7"

[[deps.EllipsisNotation]]
deps = ["ArrayInterface"]
git-tree-sha1 = "d7ab55febfd0907b285fbf8dc0c73c0825d9d6aa"
uuid = "da5c29d0-fa7d-589e-88eb-ea29b0a81949"
version = "1.3.0"

[[deps.ExprTools]]
git-tree-sha1 = "56559bbef6ca5ea0c0818fa5c90320398a6fbf8d"
uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04"
version = "0.1.8"

[[deps.FFTW]]
deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"]
git-tree-sha1 = "505876577b5481e50d089c1c68899dfb6faebc62"
uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341"
version = "1.4.6"

[[deps.FFTW_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "c6033cc3892d0ef5bb9cd29b7f2f0331ea5184ea"
uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a"
version = "3.3.10+0"

[[deps.FillArrays]]
deps = ["LinearAlgebra", "Random", "SparseArrays"]
git-tree-sha1 = "ff537e5a3cba92fb48f30fec46723510450f2c0e"
uuid = "1a297f60-69ca-5386-bcde-b61e274b549b"
version = "0.10.2"

[[deps.FixedPointNumbers]]
deps = ["Statistics"]
git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc"
uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93"
version = "0.8.4"

[[deps.HDF5_jll]]
deps = ["Artifacts", "JLLWrappers", "LibCURL_jll", "Libdl", "OpenSSL_jll", "Pkg", "Zlib_jll"]
git-tree-sha1 = "bab67c0d1c4662d2c4be8c6007751b0b6111de5c"
uuid = "0234f1f7-429e-5d53-9886-15a909be8d59"
version = "1.12.1+0"

[[deps.HypergeometricFunctions]]
deps = ["DualNumbers", "LinearAlgebra", "SpecialFunctions", "Test"]
git-tree-sha1 = "65e4589030ef3c44d3b90bdc5aac462b4bb05567"
uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a"
version = "0.3.8"

[[deps.Hyperscript]]
deps = ["Test"]
git-tree-sha1 = "8d511d5b81240fc8e6802386302675bdf47737b9"
uuid = "47d2ed2b-36de-50cf-bf87-49c2cf4b8b91"
version = "0.0.4"

[[deps.HypertextLiteral]]
git-tree-sha1 = "2b078b5a615c6c0396c77810d92ee8c6f470d238"
uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2"
version = "0.9.3"

[[deps.IOCapture]]
deps = ["Logging", "Random"]
git-tree-sha1 = "f7be53659ab06ddc986428d3a9dcc95f6fa6705a"
uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89"
version = "0.2.2"

[[deps.IfElse]]
git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1"
uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173"
version = "0.1.1"

[[deps.InlineStrings]]
deps = ["Parsers"]
git-tree-sha1 = "61feba885fac3a407465726d0c330b3055df897f"
uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48"
version = "1.1.2"

[[deps.IntelOpenMP_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "d979e54b71da82f3a65b62553da4fc3d18c9004c"
uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0"
version = "2018.0.3+2"

[[deps.InteractiveUtils]]
deps = ["Markdown"]
uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240"

[[deps.Interpolations]]
deps = ["AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "Requires", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"]
git-tree-sha1 = "b15fc0a95c564ca2e0a7ae12c1f095ca848ceb31"
uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59"
version = "0.13.5"

[[deps.IntervalSets]]
deps = ["Dates", "EllipsisNotation", "Statistics"]
git-tree-sha1 = "3cc368af3f110a767ac786560045dceddfc16758"
uuid = "8197267c-284f-5f27-9208-e0e47529a953"
version = "0.5.3"

[[deps.Intervals]]
deps = ["Dates", "Printf", "RecipesBase", "Serialization", "TimeZones"]
git-tree-sha1 = "323a38ed1952d30586d0fe03412cde9399d3618b"
uuid = "d8418881-c3e1-53bb-8760-2df7ec849ed5"
version = "1.5.0"

[[deps.InverseFunctions]]
deps = ["Test"]
git-tree-sha1 = "a7254c0acd8e62f1ac75ad24d5db43f5f19f3c65"
uuid = "3587e190-3f89-42d0-90ee-14403ec27112"
version = "0.1.2"

[[deps.IrrationalConstants]]
git-tree-sha1 = "7fd44fd4ff43fc60815f8e764c0f352b83c49151"
uuid = "92d709cd-6900-40b7-9082-c6be49f344b6"
version = "0.1.1"

[[deps.IterTools]]
git-tree-sha1 = "fa6287a4469f5e048d763df38279ee729fbd44e5"
uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e"
version = "1.4.0"

[[deps.IteratorInterfaceExtensions]]
git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856"
uuid = "82899510-4779-5014-852e-03e436cf321d"
version = "1.0.0"

[[deps.JLLWrappers]]
deps = ["Preferences"]
git-tree-sha1 = "abc9885a7ca2052a736a600f7fa66209f96506e1"
uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210"
version = "1.4.1"

[[deps.JSON]]
deps = ["Dates", "Mmap", "Parsers", "Unicode"]
git-tree-sha1 = "3c837543ddb02250ef42f4738347454f95079d4e"
uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
version = "0.21.3"

[[deps.LPVSpectral]]
deps = ["DSP", "FFTW", "LinearAlgebra", "Printf", "Random", "RecipesBase", "Requires", "Statistics", "StatsBase"]
git-tree-sha1 = "959cd3dde8f82e3f6929ee3c73a2b9ba6fc3d06d"
uuid = "26dcc766-85df-5edc-b560-6076d5dbac63"
version = "0.3.1"

[[deps.LazyArtifacts]]
deps = ["Artifacts", "Pkg"]
uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3"

[[deps.LibCURL]]
deps = ["LibCURL_jll", "MozillaCACerts_jll"]
uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21"

[[deps.LibCURL_jll]]
deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"]
uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0"

[[deps.LibGit2]]
deps = ["Base64", "NetworkOptions", "Printf", "SHA"]
uuid = "76f85450-5226-5b5a-8eaa-529ad045b433"

[[deps.LibSSH2_jll]]
deps = ["Artifacts", "Libdl", "MbedTLS_jll"]
uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8"

[[deps.Libdl]]
uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"

[[deps.LinearAlgebra]]
deps = ["Libdl", "libblastrampoline_jll"]
uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"

[[deps.LogExpFunctions]]
deps = ["ChainRulesCore", "ChangesOfVariables", "DocStringExtensions", "InverseFunctions", "IrrationalConstants", "LinearAlgebra"]
git-tree-sha1 = "e5718a00af0ab9756305a0392832c8952c7426c1"
uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688"
version = "0.3.6"

[[deps.Logging]]
uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"

[[deps.MKL_jll]]
deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"]
git-tree-sha1 = "e595b205efd49508358f7dc670a940c790204629"
uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7"
version = "2022.0.0+0"

[[deps.Markdown]]
deps = ["Base64"]
uuid = "d6f4376e-aef5-505a-96c1-9c027394607a"

[[deps.MbedTLS_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1"

[[deps.Missings]]
deps = ["DataAPI"]
git-tree-sha1 = "bf210ce90b6c9eed32d25dbcae1ebc565df2687f"
uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28"
version = "1.0.2"

[[deps.Mmap]]
uuid = "a63ad114-7e13-5084-954f-fe012c677804"

[[deps.Mocking]]
deps = ["Compat", "ExprTools"]
git-tree-sha1 = "29714d0a7a8083bba8427a4fbfb00a540c681ce7"
uuid = "78c3b35d-d492-501b-9361-3d52fe80e533"
version = "0.7.3"

[[deps.MozillaCACerts_jll]]
uuid = "14a3606d-f60d-562e-9121-12d972cd8159"

[[deps.NCDatasets]]
deps = ["CFTime", "DataStructures", "Dates", "NetCDF_jll", "Printf"]
git-tree-sha1 = "17e39eb5bbe564f48bdbefbd103bd3f49fcfcb9b"
uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab"
version = "0.11.9"

[[deps.NaNMath]]
git-tree-sha1 = "737a5957f387b17e74d4ad2f440eb330b39a62c5"
uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3"
version = "1.0.0"

[[deps.NearestNeighbors]]
deps = ["Distances", "StaticArrays"]
git-tree-sha1 = "16baacfdc8758bc374882566c9187e785e85c2f0"
uuid = "b8a86587-4115-5ab1-83bc-aa920d37bbce"
version = "0.4.9"

[[deps.Neighborhood]]
deps = ["Distances", "NearestNeighbors", "Random", "Test"]
git-tree-sha1 = "1159fcaf3b72923cf623b2748f238a5115ed2623"
uuid = "645ca80c-8b79-4109-87ea-e1f58159d116"
version = "0.2.3"

[[deps.NetCDF_jll]]
deps = ["Artifacts", "HDF5_jll", "JLLWrappers", "LibCURL_jll", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Pkg", "Zlib_jll", "nghttp2_jll"]
git-tree-sha1 = "598f1a5e9829b3e57f233f98b34a22b376dff373"
uuid = "7243133f-43d8-5620-bbf4-c2c921802cf3"
version = "400.702.402+0"

[[deps.NetworkOptions]]
uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908"

[[deps.OffsetArrays]]
deps = ["Adapt"]
git-tree-sha1 = "043017e0bdeff61cfbb7afeb558ab29536bbb5ed"
uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
version = "1.10.8"

[[deps.OpenBLAS_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"]
uuid = "4536629a-c528-5b80-bd46-f80d51c5b363"

[[deps.OpenLibm_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "05823500-19ac-5b8b-9628-191a04bc5112"

[[deps.OpenSSL_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "648107615c15d4e09f7eca16307bc821c1f718d8"
uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95"
version = "1.1.13+0"

[[deps.OpenSpecFun_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "13652491f6856acfd2db29360e1bbcd4565d04f1"
uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e"
version = "0.5.5+0"

[[deps.OrderedCollections]]
git-tree-sha1 = "85f8e6578bf1f9ee0d11e7bb1b1456435479d47c"
uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
version = "1.4.1"

[[deps.PDMats]]
deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"]
git-tree-sha1 = "7e2166042d1698b6072352c74cfd1fca2a968253"
uuid = "90014a1f-27ba-587c-ab20-58faa44d9150"
version = "0.11.6"

[[deps.Parsers]]
deps = ["Dates"]
git-tree-sha1 = "85b5da0fa43588c75bb1ff986493443f821c70b7"
uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
version = "2.2.3"

[[deps.Pkg]]
deps = ["Artifacts", "Dates", "Downloads", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"]
uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"

[[deps.PlutoUI]]
deps = ["AbstractPlutoDingetjes", "Base64", "ColorTypes", "Dates", "Hyperscript", "HypertextLiteral", "IOCapture", "InteractiveUtils", "JSON", "Logging", "Markdown", "Random", "Reexport", "UUIDs"]
git-tree-sha1 = "2c87c85e397b7ffed5ffec054f532d4edd05d901"
uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8"
version = "0.7.36"

[[deps.Polynomials]]
deps = ["Intervals", "LinearAlgebra", "OffsetArrays", "RecipesBase"]
git-tree-sha1 = "0b15f3597b01eb76764dd03c3c23d6679a3c32c8"
uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45"
version = "1.2.1"

[[deps.Preferences]]
deps = ["TOML"]
git-tree-sha1 = "de893592a221142f3db370f48290e3a2ef39998f"
uuid = "21216c6a-2e73-6563-6e65-726566657250"
version = "1.2.4"

[[deps.Printf]]
deps = ["Unicode"]
uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"

[[deps.QuadGK]]
deps = ["DataStructures", "LinearAlgebra"]
git-tree-sha1 = "78aadffb3efd2155af139781b8a8df1ef279ea39"
uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc"
version = "2.4.2"

[[deps.REPL]]
deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"]
uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"

[[deps.Random]]
deps = ["SHA", "Serialization"]
uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"

[[deps.Ratios]]
deps = ["Requires"]
git-tree-sha1 = "dc84268fe0e3335a62e315a3a7cf2afa7178a734"
uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439"
version = "0.4.3"

[[deps.RecipesBase]]
git-tree-sha1 = "6bf3f380ff52ce0832ddd3a2a7b9538ed1bcca7d"
uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
version = "1.2.1"

[[deps.Reexport]]
git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b"
uuid = "189a3867-3050-52da-a836-e630ba90ab69"
version = "1.2.2"

[[deps.Requires]]
deps = ["UUIDs"]
git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7"
uuid = "ae029012-a4dd-5104-9daa-d747884805df"
version = "1.3.0"

[[deps.Rmath]]
deps = ["Random", "Rmath_jll"]
git-tree-sha1 = "bf3188feca147ce108c76ad82c2792c57abe7b1f"
uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa"
version = "0.7.0"

[[deps.Rmath_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "68db32dff12bb6127bac73c209881191bf0efbb7"
uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f"
version = "0.3.0+0"

[[deps.SHA]]
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"

[[deps.Serialization]]
uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"

[[deps.SharedArrays]]
deps = ["Distributed", "Mmap", "Random", "Serialization"]
uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383"

[[deps.SignalDecomposition]]
deps = ["BandedMatrices", "Dates", "DelayEmbeddings", "FFTW", "LPVSpectral", "LinearAlgebra", "Neighborhood", "Random", "StaticArrays", "Statistics"]
git-tree-sha1 = "1a341589c721154f5cac57aaae4a344fdc5bfd6a"
uuid = "11a47235-7b84-4c7c-b885-fc3e2a9cf955"
version = "1.0.3"

[[deps.Sockets]]
uuid = "6462fe0b-24de-5631-8697-dd941f90decc"

[[deps.SortingAlgorithms]]
deps = ["DataStructures"]
git-tree-sha1 = "b3363d7460f7d098ca0912c69b082f75625d7508"
uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c"
version = "1.0.1"

[[deps.SparseArrays]]
deps = ["LinearAlgebra", "Random"]
uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"

[[deps.SpecialFunctions]]
deps = ["ChainRulesCore", "IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"]
git-tree-sha1 = "cbf21db885f478e4bd73b286af6e67d1beeebe4c"
uuid = "276daf66-3868-5448-9aa4-cd146d93841b"
version = "1.8.4"

[[deps.Static]]
deps = ["IfElse"]
git-tree-sha1 = "65068e4b4d10f3c31aaae2e6cb92b6c6cedca610"
uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3"
version = "0.5.6"

[[deps.StaticArrays]]
deps = ["LinearAlgebra", "Random", "Statistics"]
git-tree-sha1 = "74fb527333e72ada2dd9ef77d98e4991fb185f04"
uuid = "90137ffa-7385-5640-81b9-e52037218182"
version = "1.4.1"

[[deps.Statistics]]
deps = ["LinearAlgebra", "SparseArrays"]
uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"

[[deps.StatsAPI]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "c3d8ba7f3fa0625b062b82853a7d5229cb728b6b"
uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0"
version = "1.2.1"

[[deps.StatsBase]]
deps = ["DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"]
git-tree-sha1 = "8977b17906b0a1cc74ab2e3a05faa16cf08a8291"
uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
version = "0.33.16"

[[deps.StatsFuns]]
deps = ["ChainRulesCore", "HypergeometricFunctions", "InverseFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"]
git-tree-sha1 = "25405d7016a47cf2bd6cd91e66f4de437fd54a07"
uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c"
version = "0.9.16"

[[deps.SuiteSparse]]
deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"]
uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9"

[[deps.TOML]]
deps = ["Dates"]
uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76"

[[deps.TableTraits]]
deps = ["IteratorInterfaceExtensions"]
git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39"
uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c"
version = "1.0.1"

[[deps.Tables]]
deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits", "Test"]
git-tree-sha1 = "5ce79ce186cc678bbb5c5681ca3379d1ddae11a1"
uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
version = "1.7.0"

[[deps.Tar]]
deps = ["ArgTools", "SHA"]
uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e"

[[deps.Test]]
deps = ["InteractiveUtils", "Logging", "Random", "Serialization"]
uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[[deps.TimeZones]]
deps = ["Dates", "Downloads", "InlineStrings", "LazyArtifacts", "Mocking", "Printf", "RecipesBase", "Serialization", "Unicode"]
git-tree-sha1 = "2d4b6de8676b34525ac518de36006dc2e89c7e2e"
uuid = "f269a46b-ccf7-5d73-abea-4c690281aa53"
version = "1.7.2"

[[deps.UUIDs]]
deps = ["Random", "SHA"]
uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"

[[deps.Unicode]]
uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"

[[deps.WoodburyMatrices]]
deps = ["LinearAlgebra", "SparseArrays"]
git-tree-sha1 = "de67fa59e33ad156a590055375a30b23c40299d3"
uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6"
version = "0.5.5"

[[deps.Zlib_jll]]
deps = ["Libdl"]
uuid = "83775a58-1f1d-513f-b197-d71354ab007a"

[[deps.libblastrampoline_jll]]
deps = ["Artifacts", "Libdl", "OpenBLAS_jll"]
uuid = "8e850b90-86db-534c-a0d3-1478176c7d93"

[[deps.nghttp2_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d"

[[deps.p7zip_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0"
"""

# ╔═╡ Cell order:
# ╟─15f947af-0485-433c-a424-ba0c0a5f376a
# ╟─e112e6e8-50b8-496e-b4ea-8c37a288e4a0
# ╟─d9874aec-7c7f-4818-81a8-a5fd520159d5
# ╟─6c52f938-86db-496c-a1c2-ffdd7836f533
# ╟─e39f0208-c7a1-44fc-b4b9-07f83a86e8d8
# ╟─88714902-cf5f-4cd7-adb3-443dd6d48c35
# ╟─0a92c84f-bc1c-4624-ada3-d4202e9f37fa
# ╟─d2ae000a-4c5a-4289-aaee-431e064a7aef
# ╟─e5ef340e-e087-4b2b-be6e-da6255e3677a
# ╟─bd831162-b479-4148-9031-de6529f4bf89
# ╟─af6450d9-d92a-4331-853f-cd19ff72abd2
# ╟─9f0a3ab4-9d79-11ec-33e2-eb9616058d43
# ╟─d164f293-b571-4218-8411-bf01f52e7a20
# ╟─7306f20f-9da1-4419-9222-1704fd296ee8
# ╟─00000000-0000-0000-0000-000000000001
# ╟─00000000-0000-0000-0000-000000000002

max_issues_repo_name: gaelforget/MeshArrayNotebooks

max_forks_repo_name: JuliaClimate/Notebooks


text:
module SDPA_GMP
using LinearAlgebra # for diag()
using DelimitedFiles # for writing SDPA input file
using MathOptInterface
MOI = MathOptInterface
MOIB = MOI.Bridges
const sdpa_gmp_path = "C:\\Users\\zhuji\\Downloads\\sdpa-gmp-7.1.3\\sdpa_gmp" # make sure sdpa_gmp binary is in the system PATH

export sdpa_gmp_binary_solve!, read_results!

include("MOI_wrapper.jl")
include("file_io.jl")
include("presolve.jl")
include("binary_call.jl")

end # module


text:
allFiles = [
	"A_014_#ABS1_15_1.prp",
	"A_014_ABS10_15_1.prp",
	"A_014_ABS10_15_2.prp",
	"A_014_ABS10_15_3.prp",
	"A_014_ABS10_15_4.prp",
	"A_014_ABS10_15_5.prp",
	"A_014_ABS11_15_1.prp",
	"A_014_ABS11_15_2.prp",
	"A_014_ABS11_15_3.prp",
	"A_014_ABS11_15_4.prp",
	"A_014_ABS11_15_5.prp",
	"A_014_ABS12_15_1.prp",
	"A_014_ABS12_15_2.prp",
	"A_014_ABS12_15_3.prp",
	"A_014_ABS12_15_4.prp",
	"A_014_ABS12_15_5.prp",
	"A_014_ABS13_15_1.prp",
	"A_014_ABS13_15_2.prp",
	"A_014_ABS13_15_3.prp",
	"A_014_ABS13_15_4.prp",
	"A_014_ABS13_15_5.prp",
	"A_014_ABS14_15_1.prp",
	"A_014_ABS14_15_2.prp",
	"A_014_ABS14_15_3.prp",
	"A_014_ABS14_15_4.prp",
	"A_014_ABS14_15_5.prp",
	"A_014_ABS15_15_1.prp",
	"A_014_ABS15_15_2.prp",
	"A_014_ABS15_15_3.prp",
	"A_014_ABS15_15_4.prp",
	"A_014_ABS15_15_5.prp",
	"A_014_ABS16_15_1.prp",
	"A_014_ABS16_15_2.prp",
	"A_014_ABS16_15_3.prp",
	"A_014_ABS16_15_4.prp",
	"A_014_ABS16_15_5.prp",
	"A_014_ABS17_15_1.prp",
	"A_014_ABS17_15_2.prp",
	"A_014_ABS17_15_3.prp",
	"A_014_ABS17_15_4.prp",
	"A_014_ABS17_15_5.prp",
	"A_014_ABS18_15_1.prp",
	"A_014_ABS18_15_2.prp",
	"A_014_ABS18_15_3.prp",
	"A_014_ABS18_15_4.prp",
	"A_014_ABS18_15_5.prp",
	"A_014_ABS19_15_1.prp",
	"A_014_ABS19_15_2.prp",
	"A_014_ABS19_15_3.prp",
	"A_014_ABS19_15_4.prp",
	"A_014_ABS19_15_5.prp",
	"A_014_ABS1_15_1.prp",
	"A_014_ABS1_15_2.prp",
	"A_014_ABS1_15_3.prp",
	"A_014_ABS1_15_4.prp",
	"A_014_ABS1_15_5.prp",
	"A_014_ABS20_15_1.prp",
	"A_014_ABS20_15_2.prp",
	"A_014_ABS20_15_3.prp",
	"A_014_ABS20_15_4.prp",
	"A_014_ABS20_15_5.prp",
	"A_014_ABS21_15_1.prp",
	"A_014_ABS21_15_2.prp",
	"A_014_ABS21_15_3.prp",
	"A_014_ABS21_15_4.prp",
	"A_014_ABS21_15_5.prp",
	"A_014_ABS22_15_1.prp",
	"A_014_ABS22_15_2.prp",
	"A_014_ABS22_15_3.prp",
	"A_014_ABS22_15_4.prp",
	"A_014_ABS22_15_5.prp",
	"A_014_ABS23_15_1.prp",
	"A_014_ABS23_15_2.prp",
	"A_014_ABS23_15_3.prp",
	"A_014_ABS23_15_4.prp",
	"A_014_ABS23_15_5.prp",
	"A_014_ABS24_15_1.prp",
	"A_014_ABS24_15_2.prp",
	"A_014_ABS24_15_3.prp",
	"A_014_ABS24_15_4.prp",
	"A_014_ABS24_15_5.prp",
	"A_014_ABS25_15_1.prp",
	"A_014_ABS25_15_2.prp",
	"A_014_ABS25_15_3.prp",
	"A_014_ABS25_15_4.prp",
	"A_014_ABS25_15_5.prp",
	"A_014_ABS26_15_1.prp",
	"A_014_ABS26_15_2.prp",
	"A_014_ABS26_15_3.prp",
	"A_014_ABS26_15_4.prp",
	"A_014_ABS26_15_5.prp",
	"A_014_ABS27_15_1.prp",
	"A_014_ABS27_15_2.prp",
	"A_014_ABS27_15_3.prp",
	"A_014_ABS27_15_4.prp",
	"A_014_ABS27_15_5.prp",
	"A_014_ABS28_15_1.prp",
	"A_014_ABS28_15_2.prp",
	"A_014_ABS28_15_3.prp",
	"A_014_ABS28_15_4.prp",
	"A_014_ABS28_15_5.prp",
	"A_014_ABS29_15_1.prp",
	"A_014_ABS29_15_2.prp",
	"A_014_ABS29_15_3.prp",
	"A_014_ABS29_15_4.prp",
	"A_014_ABS29_15_5.prp",
	"A_014_ABS2_15_1.prp",
	"A_014_ABS2_15_2.prp",
	"A_014_ABS2_15_3.prp",
	"A_014_ABS2_15_4.prp",
	"A_014_ABS2_15_5.prp",
	"A_014_ABS30_15_1.prp",
	"A_014_ABS30_15_2.prp",
	"A_014_ABS30_15_3.prp",
	"A_014_ABS30_15_4.prp",
	"A_014_ABS30_15_5.prp",
	"A_014_ABS31_15_1.prp",
	"A_014_ABS31_15_2.prp",
	"A_014_ABS31_15_3.prp",
	"A_014_ABS31_15_4.prp",
	"A_014_ABS31_15_5.prp",
	"A_014_ABS32_15_1.prp",
	"A_014_ABS32_15_2.prp",
	"A_014_ABS32_15_3.prp",
	"A_014_ABS32_15_4.prp",
	"A_014_ABS32_15_5.prp",
	"A_014_ABS33_15_1.prp",
	"A_014_ABS33_15_2.prp",
	"A_014_ABS33_15_3.prp",
	"A_014_ABS33_15_4.prp",
	"A_014_ABS33_15_5.prp",
	"A_014_ABS34_15_1.prp",
	"A_014_ABS34_15_2.prp",
	"A_014_ABS34_15_3.prp",
	"A_014_ABS34_15_4.prp",
	"A_014_ABS34_15_5.prp",
	"A_014_ABS35_15_1.prp",
	"A_014_ABS35_15_2.prp",
	"A_014_ABS35_15_3.prp",
	"A_014_ABS35_15_4.prp",
	"A_014_ABS35_15_5.prp",
	"A_014_ABS36_15_1.prp",
	"A_014_ABS36_15_2.prp",
	"A_014_ABS36_15_3.prp",
	"A_014_ABS36_15_4.prp",
	"A_014_ABS36_15_5.prp",
	"A_014_ABS37_15_1.prp",
	"A_014_ABS37_15_2.prp",
	"A_014_ABS37_15_3.prp",
	"A_014_ABS37_15_4.prp",
	"A_014_ABS37_15_5.prp",
	"A_014_ABS38_15_1.prp",
	"A_014_ABS38_15_2.prp",
	"A_014_ABS38_15_3.prp",
	"A_014_ABS38_15_4.prp",
	"A_014_ABS38_15_5.prp",
	"A_014_ABS39_15_1.prp",
	"A_014_ABS39_15_2.prp",
	"A_014_ABS39_15_3.prp",
	"A_014_ABS39_15_4.prp",
	"A_014_ABS39_15_5.prp",
	"A_014_ABS3_15_1.prp",
	"A_014_ABS3_15_2.prp",
	"A_014_ABS3_15_3.prp",
	"A_014_ABS3_15_4.prp",
	"A_014_ABS3_15_5.prp",
	"A_014_ABS40_15_1.prp",
	"A_014_ABS40_15_2.prp",
	"A_014_ABS40_15_3.prp",
	"A_014_ABS40_15_4.prp",
	"A_014_ABS40_15_5.prp",
	"A_014_ABS41_15_1.prp",
	"A_014_ABS41_15_2.prp",
	"A_014_ABS41_15_3.prp",
	"A_014_ABS41_15_4.prp",
	"A_014_ABS41_15_5.prp",
	"A_014_ABS42_15_1.prp",
	"A_014_ABS42_15_2.prp",
	"A_014_ABS42_15_3.prp",
	"A_014_ABS42_15_4.prp",
	"A_014_ABS42_15_5.prp",
	"A_014_ABS43_15_1.prp",
	"A_014_ABS43_15_2.prp",
	"A_014_ABS43_15_3.prp",
	"A_014_ABS43_15_4.prp",
	"A_014_ABS43_15_5.prp",
	"A_014_ABS44_15_1.prp",
	"A_014_ABS44_15_2.prp",
	"A_014_ABS44_15_3.prp",
	"A_014_ABS44_15_4.prp",
	"A_014_ABS44_15_5.prp",
	"A_014_ABS45_15_1.prp",
	"A_014_ABS45_15_2.prp",
	"A_014_ABS45_15_3.prp",
	"A_014_ABS45_15_4.prp",
	"A_014_ABS45_15_5.prp",
	"A_014_ABS46_15_1.prp",
	"A_014_ABS46_15_2.prp",
	"A_014_ABS46_15_3.prp",
	"A_014_ABS46_15_4.prp",
	"A_014_ABS46_15_5.prp",
	"A_014_ABS47_15_1.prp",
	"A_014_ABS47_15_2.prp",
	"A_014_ABS47_15_3.prp",
	"A_014_ABS47_15_4.prp",
	"A_014_ABS47_15_5.prp",
	"A_014_ABS48_15_1.prp",
	"A_014_ABS48_15_2.prp",
	"A_014_ABS48_15_3.prp",
	"A_014_ABS48_15_4.prp",
	"A_014_ABS48_15_5.prp",
	"A_014_ABS49_15_1.prp",
	"A_014_ABS49_15_2.prp",
	"A_014_ABS49_15_3.prp",
	"A_014_ABS49_15_4.prp",
	"A_014_ABS49_15_5.prp",
	"A_014_ABS4_15_1.prp",
	"A_014_ABS4_15_2.prp",
	"A_014_ABS4_15_3.prp",
	"A_014_ABS4_15_4.prp",
	"A_014_ABS4_15_5.prp",
	"A_014_ABS50_15_1.prp",
	"A_014_ABS50_15_2.prp",
	"A_014_ABS50_15_3.prp",
	"A_014_ABS50_15_4.prp",
	"A_014_ABS50_15_5.prp",
	"A_014_ABS51_15_1.prp",
	"A_014_ABS51_15_2.prp",
	"A_014_ABS51_15_3.prp",
	"A_014_ABS51_15_4.prp",
	"A_014_ABS51_15_5.prp",
	"A_014_ABS52_15_1.prp",
	"A_014_ABS52_15_2.prp",
	"A_014_ABS52_15_3.prp",
	"A_014_ABS52_15_4.prp",
	"A_014_ABS52_15_5.prp",
	"A_014_ABS53_15_1.prp",
	"A_014_ABS53_15_2.prp",
	"A_014_ABS53_15_3.prp",
	"A_014_ABS53_15_4.prp",
	"A_014_ABS53_15_5.prp",
	"A_014_ABS54_15_1.prp",
	"A_014_ABS54_15_2.prp",
	"A_014_ABS54_15_3.prp",
	"A_014_ABS54_15_4.prp",
	"A_014_ABS54_15_5.prp",
	"A_014_ABS55_15_1.prp",
	"A_014_ABS55_15_2.prp",
	"A_014_ABS55_15_3.prp",
	"A_014_ABS55_15_4.prp",
	"A_014_ABS55_15_5.prp",
	"A_014_ABS56_15_1.prp",
	"A_014_ABS56_15_2.prp",
	"A_014_ABS56_15_3.prp",
	"A_014_ABS56_15_4.prp",
	"A_014_ABS56_15_5.prp",
	"A_014_ABS57_15_1.prp",
	"A_014_ABS57_15_2.prp",
	"A_014_ABS57_15_3.prp",
	"A_014_ABS57_15_4.prp",
	"A_014_ABS57_15_5.prp",
	"A_014_ABS58_15_1.prp",
	"A_014_ABS58_15_2.prp",
	"A_014_ABS58_15_3.prp",
	"A_014_ABS58_15_4.prp",
	"A_014_ABS58_15_5.prp",
	"A_014_ABS59_15_1.prp",
	"A_014_ABS59_15_2.prp",
	"A_014_ABS59_15_3.prp",
	"A_014_ABS59_15_4.prp",
	"A_014_ABS59_15_5.prp",
	"A_014_ABS5_15_1.prp",
	"A_014_ABS5_15_2.prp",
	"A_014_ABS5_15_3.prp",
	"A_014_ABS5_15_4.prp",
	"A_014_ABS5_15_5.prp",
	"A_014_ABS60_15_1.prp",
	"A_014_ABS60_15_2.prp",
	"A_014_ABS60_15_3.prp",
	"A_014_ABS60_15_4.prp",
	"A_014_ABS60_15_5.prp",
	"A_014_ABS61_15_1.prp",
	"A_014_ABS61_15_2.prp",
	"A_014_ABS61_15_3.prp",
	"A_014_ABS61_15_4.prp",
	"A_014_ABS61_15_5.prp",
	"A_014_ABS62_15_1.prp",
	"A_014_ABS62_15_2.prp",
	"A_014_ABS62_15_3.prp",
	"A_014_ABS62_15_4.prp",
	"A_014_ABS62_15_5.prp",
	"A_014_ABS63_15_1.prp",
	"A_014_ABS63_15_2.prp",
	"A_014_ABS63_15_3.prp",
	"A_014_ABS63_15_4.prp",
	"A_014_ABS63_15_5.prp",
	"A_014_ABS64_15_1.prp",
	"A_014_ABS64_15_2.prp",
	"A_014_ABS64_15_3.prp",
	"A_014_ABS64_15_4.prp",
	"A_014_ABS64_15_5.prp",
	"A_014_ABS65_15_1.prp",
	"A_014_ABS65_15_2.prp",
	"A_014_ABS65_15_3.prp",
	"A_014_ABS65_15_4.prp",
	"A_014_ABS65_15_5.prp",
	"A_014_ABS66_15_1.prp",
	"A_014_ABS66_15_2.prp",
	"A_014_ABS66_15_3.prp",
	"A_014_ABS66_15_4.prp",
	"A_014_ABS66_15_5.prp",
	"A_014_ABS67_15_1.prp",
	"A_014_ABS67_15_2.prp",
	"A_014_ABS67_15_3.prp",
	"A_014_ABS67_15_4.prp",
	"A_014_ABS67_15_5.prp",
	"A_014_ABS68_15_1.prp",
	"A_014_ABS68_15_2.prp",
	"A_014_ABS68_15_3.prp",
	"A_014_ABS68_15_4.prp",
	"A_014_ABS68_15_5.prp",
	"A_014_ABS69_15_1.prp",
	"A_014_ABS69_15_2.prp",
	"A_014_ABS69_15_3.prp",
	"A_014_ABS69_15_4.prp",
	"A_014_ABS69_15_5.prp",
	"A_014_ABS6_15_1.prp",
	"A_014_ABS6_15_2.prp",
	"A_014_ABS6_15_3.prp",
	"A_014_ABS6_15_4.prp",
	"A_014_ABS6_15_5.prp",
	"A_014_ABS70_15_1.prp",
	"A_014_ABS70_15_2.prp",
	"A_014_ABS70_15_3.prp",
	"A_014_ABS70_15_4.prp",
	"A_014_ABS70_15_5.prp",
	"A_014_ABS71_15_1.prp",
	"A_014_ABS71_15_2.prp",
	"A_014_ABS71_15_3.prp",
	"A_014_ABS71_15_4.prp",
	"A_014_ABS71_15_5.prp",
	"A_014_ABS72_15_1.prp",
	"A_014_ABS72_15_2.prp",
	"A_014_ABS72_15_3.prp",
	"A_014_ABS72_15_4.prp",
	"A_014_ABS72_15_5.prp",
	"A_014_ABS73_15_1.prp",
	"A_014_ABS73_15_2.prp",
	"A_014_ABS73_15_3.prp",
	"A_014_ABS73_15_4.prp",
	"A_014_ABS73_15_5.prp",
	"A_014_ABS74_15_1.prp",
	"A_014_ABS74_15_2.prp",
	"A_014_ABS74_15_3.prp",
	"A_014_ABS74_15_4.prp",
	"A_014_ABS74_15_5.prp",
	"A_014_ABS75_15_1.prp",
	"A_014_ABS75_15_2.prp",
	"A_014_ABS75_15_3.prp",
	"A_014_ABS75_15_4.prp",
	"A_014_ABS75_15_5.prp",
	"A_014_ABS76_15_1.prp",
	"A_014_ABS76_15_2.prp",
	"A_014_ABS76_15_3.prp",
	"A_014_ABS76_15_4.prp",
	"A_014_ABS76_15_5.prp",
	"A_014_ABS77_15_1.prp",
	"A_014_ABS77_15_2.prp",
	"A_014_ABS77_15_3.prp",
	"A_014_ABS77_15_4.prp",
	"A_014_ABS77_15_5.prp",
	"A_014_ABS78_15_1.prp",
	"A_014_ABS78_15_2.prp",
	"A_014_ABS78_15_3.prp",
	"A_014_ABS78_15_4.prp",
	"A_014_ABS78_15_5.prp",
	"A_014_ABS79_15_1.prp",
	"A_014_ABS79_15_2.prp",
	"A_014_ABS79_15_3.prp",
	"A_014_ABS79_15_4.prp",
	"A_014_ABS79_15_5.prp",
	"A_014_ABS7_15_1.prp",
	"A_014_ABS7_15_2.prp",
	"A_014_ABS7_15_3.prp",
	"A_014_ABS7_15_4.prp",
	"A_014_ABS7_15_5.prp",
	"A_014_ABS80_15_1.prp",
	"A_014_ABS80_15_2.prp",
	"A_014_ABS80_15_3.prp",
	"A_014_ABS80_15_4.prp",
	"A_014_ABS80_15_5.prp",
	"A_014_ABS81_15_1.prp",
	"A_014_ABS81_15_2.prp",
	"A_014_ABS81_15_3.prp",
	"A_014_ABS81_15_4.prp",
	"A_014_ABS81_15_5.prp",
	"A_014_ABS82_15_1.prp",
	"A_014_ABS82_15_2.prp",
	"A_014_ABS82_15_3.prp",
	"A_014_ABS82_15_4.prp",
	"A_014_ABS82_15_5.prp",
	"A_014_ABS83_15_1.prp",
	"A_014_ABS83_15_2.prp",
	"A_014_ABS83_15_3.prp",
	"A_014_ABS83_15_4.prp",
	"A_014_ABS83_15_5.prp",
	"A_014_ABS84_15_1.prp",
	"A_014_ABS84_15_2.prp",
	"A_014_ABS84_15_3.prp",
	"A_014_ABS84_15_4.prp",
	"A_014_ABS84_15_5.prp",
	"A_014_ABS85_15_1.prp",
	"A_014_ABS85_15_2.prp",
	"A_014_ABS85_15_3.prp",
	"A_014_ABS85_15_4.prp",
	"A_014_ABS85_15_5.prp",
	"A_014_ABS86_15_1.prp",
	"A_014_ABS86_15_2.prp",
	"A_014_ABS86_15_3.prp",
	"A_014_ABS86_15_4.prp",
	"A_014_ABS86_15_5.prp",
	"A_014_ABS87_15_1.prp",
	"A_014_ABS87_15_2.prp",
	"A_014_ABS87_15_3.prp",
	"A_014_ABS87_15_4.prp",
	"A_014_ABS87_15_5.prp",
	"A_014_ABS88_15_1.prp",
	"A_014_ABS88_15_2.prp",
	"A_014_ABS88_15_3.prp",
	"A_014_ABS88_15_4.prp",
	"A_014_ABS88_15_5.prp",
	"A_014_ABS89_15_1.prp",
	"A_014_ABS89_15_2.prp",
	"A_014_ABS89_15_3.prp",
	"A_014_ABS89_15_4.prp",
	"A_014_ABS89_15_5.prp",
	"A_014_ABS8_15_1.prp",
	"A_014_ABS8_15_2.prp",
	"A_014_ABS8_15_3.prp",
	"A_014_ABS8_15_4.prp",
	"A_014_ABS8_15_5.prp",
	"A_014_ABS90_15_1.prp",
	"A_014_ABS90_15_2.prp",
	"A_014_ABS90_15_3.prp",
	"A_014_ABS90_15_4.prp",
	"A_014_ABS90_15_5.prp",
	"A_014_ABS91_15_1.prp",
	"A_014_ABS91_15_2.prp",
	"A_014_ABS91_15_3.prp",
	"A_014_ABS91_15_4.prp",
	"A_014_ABS91_15_5.prp",
	"A_014_ABS92_15_1.prp",
	"A_014_ABS92_15_2.prp",
	"A_014_ABS92_15_3.prp",
	"A_014_ABS92_15_4.prp",
	"A_014_ABS92_15_5.prp",
	"A_014_ABS93_15_1.prp",
	"A_014_ABS93_15_2.prp",
	"A_014_ABS93_15_3.prp",
	"A_014_ABS93_15_4.prp",
	"A_014_ABS93_15_5.prp",
	"A_014_ABS94_15_1.prp",
	"A_014_ABS94_15_2.prp",
	"A_014_ABS94_15_3.prp",
	"A_014_ABS94_15_4.prp",
	"A_014_ABS94_15_5.prp",
	"A_014_ABS95_15_1.prp",
	"A_014_ABS95_15_2.prp",
	"A_014_ABS95_15_3.prp",
	"A_014_ABS95_15_4.prp",
	"A_014_ABS95_15_5.prp",
	"A_014_ABS96_15_1.prp",
	"A_014_ABS96_15_2.prp",
	"A_014_ABS96_15_3.prp",
	"A_014_ABS96_15_4.prp",
	"A_014_ABS96_15_5.prp",
	"A_014_ABS9_15_1.prp",
	"A_014_ABS9_15_2.prp",
	"A_014_ABS9_15_3.prp",
	"A_014_ABS9_15_4.prp",
	"A_014_ABS9_15_5.prp",
]


text:
module Pastebin
export
    paste!,
    delpaste!,
    getraw,
    content,
    success

using Requests
include("TypeDeclarations.jl")

const API = "http://pastebin.com/api/api_post.php"

function paste!(client::PastebinClient, title::AbstractString, text::AbstractString, expiration::Expiration=NEVER, access::Access=PUBLIC)
    userKey = client.userKey
    devKey = client.devKey

    format = "Text"
    accessString = 1
    expirationNode = ""
    accessNode = 0

    if expiration == NEVER
        expirationNode = "N"
    elseif expiration == TEN_M
        expirationNode = "10M"
    elseif expiration == HOUR
        expirationNode = "1H"
    elseif expiration == DAY
        expirationNode = "1D"
    elseif expiration == WEEK
        expirationNode = "1W"
    elseif expiration == TWO_WEEKS
        expirationNode = "2W"
    elseif expiration == MONTH
        expirationNode = "1M"
    end

    if access == PUBLIC
        accessNode = 0
    elseif access == PRIVATE
        accessNode = isempty(userKey) ? error("For a private paste, providing a USER_KEY is required. Exiting.") : 2
    elseif access == UNLISTED
        access = 1
    end

    data = Dict(
        "api_option"            => "paste",
        "api_paste_private"     => accessString,
        "api_paste_name"        => title,
        "api_paste_expire_date" => expirationNode,
        "api_paste_format"      => format,
        "api_dev_key"           => devKey,
        "api_paste_code"        => text
    )

    if !isnull(userKey)
        data["api_user_key"] = get(userKey)
    end

    response = readall(Requests.post(API, data=data))
    contains("Bad API Request", response) ? PastebinResponse(false, response) : PastebinResponse(true, response)
end

function delpaste!(client::PastebinClient, key::PasteKey)
    data = Dict(
        "api_option"            => "delete",
        "api_dev_key"           => client.devKey,
        "api_paste_key"         => key.key,
    )

    if !isnull(client.userKey)
        data["api_user_key"] = get(client.userKey)
    end

    response = readall(Requests.post(API, data=data))
    contains("Bad API Request", response) ? PastebinResponse(false, response) : PastebinResponse(true, response)
end

function getraw(key::PasteKey)
    response = readall(Requests.get("http://pastebin.com/raw/" * key.key))
    contains("Bad API Request", response) ? PastebinResponse(false, response) : PastebinResponse(true, response)
end

content(resp::PastebinResponse) = resp.response
success(resp::PastebinResponse) = resp.successful

end # end of module


text:
@testset "array fluents" begin

# Load domain and problem
path = joinpath(dirname(pathof(PDDL)), "..", "test", "arrays")
domain = load_domain(joinpath(path, "domain.pddl"))
problem = load_problem(joinpath(path, "problem.pddl"))

# Make sure function declarations have the right output type
@test PDDL.get_function(domain, :walls).type == Symbol("bit-matrix")

# Register array theory
PDDL.Arrays.register!()

state = initstate(domain, problem)
implementations = [
    "concrete interpreter" => (domain, state),
    "ground interpreter" => (ground(domain, state), state),
    "concrete compiler" => compiled(domain, state),
]

@testset "array fluents ($name)" for (name, (domain, _)) in implementations
    # Initialize state, test array dimensios, access and goal
    state = initstate(domain, problem)
    @test domain[state => pddl"(width (walls))"] == 3
    @test domain[state => pddl"(height (walls))"] == 3
    @test domain[state => pddl"(get-index walls 2 2)"] == true
    @test domain[state => pddl"(get-index walls 1 2)"] == true
    @test satisfy(domain, state, problem.goal) == false

    # Check that we can only move down because of wall
    actions = available(domain, state) |> collect
    @test length(actions) == 1 && actions[1].name == :down

    # Execute plan to reach goal
    state = execute(domain, state, pddl"(down)")
    state = execute(domain, state, pddl"(down)")
    state = execute(domain, state, pddl"(right)")
    state = execute(domain, state, pddl"(right)")
    state = execute(domain, state, pddl"(up)")
    state = execute(domain, state, pddl"(up)")

    # Check that goal is achieved
    @test satisfy(domain, state, problem.goal) == true
end

# Deregister array theory
PDDL.Arrays.deregister!()
end # array fluents