text:
__precompile__()
module eps_InAs_ntype
using QuadGK
export OmegatoeV, m_star, Gamma_ntype, E0_T_InAs,epsFCL,epsIB
#from integration import Integrate
#from scipy.integrate import quad
 #but I can't use QuadGk for larger values of eV, can only functionine function Integrate, tested E = 0.0037eV, get same eps of 10.240628772514803 + 0.03160036047883907im

const e = 1.602*^(10,-19)
const eV = 1.60218*^(10,-19)
const eps_0 = 8.8542*^(10,-12)
const c = 3*^(10,8)
const hbar = 1.05457*^(10,-34) #m2kg/s
const hbar_eV = 6.5821*^(10,-16) #eV s
const m_e =9.109*^(10,-31)#kg
const m_0 = 0.9109*^(10,-30)
const m_0_eV = 0.51099906*^(10,6) #eV

const E0_InAs = 0.42
const dt0_InAs = 0.28*0.001
const b0_InAs = 93
const A_InAs = 14*10^(-9) #for n-type  InAs
const B_InAs = 1.97*10^(-7)
const C_InAs = 57.9*10^(-12) #N in m^(-3)

@inline function OmegatoeV(omega)
    return omega*hbar_eV
end
precompile(OmegatoeV,(Float64,))

@inline function m_star(n) # change m_e according to MB shift
    P_square = 11.9   #eV
    E_g= 0.416 #eV
    term = 8.0*P_square/eV*hbar^2*(3.0*pi^2*n)^(2/3)/(3.0*m_e*E_g^2)
    return (1.0+(4.0*P_square/(3.0*E_g))*(1.0+term)^(-1/2))^(-1)*m_0
end
precompile(m_star, (Float64,))

@inline function Gamma_ntype(N_Base,T)
    umin = 1000.0
    umax = 34000.0
    Nref = 1.1*10^17*10^6 #in m^(-3) since N_base in m^(-3)
    phi = 0.32
    t1 = 1.57
    t2 = 3.0
    mu_franc =  umin + (umax*(300.0/T)^t1-umin)/(1+(N_Base/(Nref*(T/300.0)^t2))^phi)#from Francoeur
    return e/(m_star(N_Base)*mu_franc*10000.0) #s^(-1) change mu from cm^(-2) to m^(-2)
end
precompile(Gamma_ntype, (Float64,Float64))

@inline function E0_T_InAs(N0,T)
    delta_Eg_InAs = A_InAs*(N0/10^6)^(1/3) + B_InAs*(N0/10^6)^(1/4) + C_InAs*(N0/10^6)^(1/2)
    mstar = m_star(N0)
    #Need to include the effect of Moss Burstein shift on E0_InAs??
    E_T = E0_InAs+ (hbar^2/(2*mstar))*(3*pi^2*N0)^(2/3)-dt0_InAs*T^2/(T+b0_InAs)
    return E_T+ delta_Eg_InAs
end
precompile(E0_T_InAs, (Float64,Float64))

@inline function epsFCL(omega,mstar,gamma,N_base)
    eps_inf_InAs = 12.3
    g = 2.89*10.0^11  #s^(-1), gamma
    o_TO = 4.12*10.0^(13) #s^(-1)
    o_LO = 4.58*10.0^(13)
    o_p_square=N_base*e^2/(12.3*eps_0*mstar) #s^(-2)
    return eps_inf_InAs*(1.0+(o_LO^2-o_TO^2)/(o_TO^2-omega^2-im*omega*g)-o_p_square/(omega*(omega+ im*gamma)))
end
precompile(epsFCL,(Float64,Float64,Float64,Float64))

@inline function epsIB(omega,N0,T,E0_T_InAs_value)
    if(hbar_eV*omega<=E0_T_InAs_value)
        alpha_lb_2=0.0
    else
        alpha_lb_2= (3*10^8*(hbar_eV*omega-E0_T_InAs_value))^(1/2)*100
    end
    m_IB_pp = alpha_lb_2*c/(2*omega)
    #imaginary part is 0 when below bandgap
    integratedfn(omega_p) = alpha_lb_2(omega_p,N0,T)/(omega^2-omega_p^2)
    if(hbar_eV*omega<E0_T_InAs_value)
        m_IB_p_value =1.0
    else
     #   result  =1.0 + (c/pi)*quadgk(integratedfn,100.0,10.0^25,rtol=1e-8)[1] # result  =(1.0 + (c/pi)*Integrate(integratedfn, 10000,100.0,10.0^25))
        m_IB_p_value = (1.0 + 0.00026172525)
    end
    return (m_IB_p_value^2-m_IB_pp^2) + im*2*m_IB_p_value*m_IB_pp
end
precompile(epsIB,(Float64,Float64,Float64,Float64))

end
#function eps_InAs_ntype(E_photon::Float64,N_base::Float64)::ComplexF64 #N_base in m^(-3)
    #E_photon= eVtoOmega(omega)
#    omega = eVtoOmega(E_photon)
#    T=300.0 #o_angular = 5.38*10^14   #hbar*5.38*10^14/eV = 0.35eV
#    if(E_photon>0.35)
#        return epsIB(omega,N_base,T) +  epsFCL(omega,N_base,T)
#    else
#        return epsFCL(omega,N_base,T)
#    end

#end

#omegalist= 2.0*10.0^14:5.75*10.0^13:2.5*10.0^15#
#eVlist=  0.2:0.02:1.5
#epslist = []
#for ind = 1:length(eVlist)
#    eps = eps_InAs_ntype(eVlist[ind],10.0^23)
#    println("eps_InAs",eps)
#    push!(epslist, imag(eps))
#end
#plot(eVlist,epslist)
#savefig("test_InAs_real.png")


text:
# Load Julia packages (libraries) needed.

using StatisticalRethinking
using CSV, DataFrames
using StanSample, MonteCarloMeasurements

ProjDir = @__DIR__

df = DataFrame!(CSV.File(joinpath(ProjDir, "sports.csv"), delim=','));
scale!(df, [:TM, :WUE, :PGP])
println()

m3 = "
data {
 int < lower = 1 > N; // Sample size
 vector[N] WUE; // Outcome
 vector[N] TM; // Predictor
 vector[N] PGP; // Predictor
}

parameters {
 real a; // Intercept
 real bPGP; // Slope (regression coefficients)
 real bTM; // Slope (regression coefficients)
 real < lower = 0 > sigma;    // Error SD
}

model {
  vector[N] mu;               // mu is a vector
  a ~ normal(0, 0.2);         //Priors
  bPGP ~ normal(0, 0.5);
  bTM ~ normal(0, 0.5);
  sigma ~ exponential(1);
  mu = a + bPGP * PGP + bTM * TM;
  WUE ~ normal(mu , sigma);     // Likelihood
}
";

# Define the SampleModel and set the output format to :mcmcchains.

m3s = SampleModel("m3", m3);

# Input data for cmdstan

m3_data = Dict("N" => size(df, 1), "PGP" => df[:, :PGP_s],
    "TM" => df[:, :TM_s], "WUE" => df[:, :WUE_s]);

# Sample using StanSample

rc = stan_sample(m3s, data=m3_data);

if success(rc)

  # Describe the draws

  dfa3 = read_samples(m3s; output_format=:dataframe)

  p3 = Particles(dfa3)

end

ext: jl


text:
using GeoJSON, Turf, FactCheck

points = GeoJSON.parsefile(joinpath(dirname(@__FILE__),"geojson/pts.geojson"))
quantiled = Turf.quantile(points, "elevation", [10,30,40,60,80,90,99])
@fact length(quantiled) --> 7 # what should be the expected values?

infield = "elevation"
outfield = "heightIndex"
translations = Vector[[0,20,1], [20,40,2], [40,60,3], [60,Inf,4]]
reclassed = Turf.reclass(points, infield, outfield, translations)
@fact typeof(reclassed.features[1].geometry) --> GeoJSON.Point
# what's the expected output here?


text:
# ============================================================
# Neural & Universal Differential Equations
# ============================================================

export ube_dfdt, ube_dfdt!

"""
    ube_dfdt(f, p, t)

Right-hand side of universal Boltzmann equation

* @args f: particle distribution function in 1D formulation
* @args p: M, τ, ann (network & parameters)
* @args t: tspan

"""
function ube_dfdt(f, p, t)
    M, τ, ann = p

    if ann[1] isa FastChain
        df = (M - f) / τ + ann[1](M - f, ann[2])
    elseif ann[1] isa Chain
        df = (M - f) / τ + ann[1](M - f)
    end

    return df
end

"""
    ube_dfdt!(df, f, p, t)

Right-hand side of universal Boltzmann equation

* @args df: derivatives of particle distribution function
* @args f: particle distribution function in 1D formulation
* @args p: M, τ, ann (network & parameters)
* @args t: tspan

"""
function ube_dfdt!(df, f, p, t)
    M, τ, ann = p

    if ann[1] isa FastChain
        df .= (M - f) / τ + ann[1](M - f, ann[2])
    elseif ann[1] isa Chain
        df .= (M - f) / τ + ann[1](M - f)
    end
end


text:
# included in module Wut

struct CategoryEncoder  <: AbstractEncoder
    cL::Dict{String,Int64}
    sE::ScalarEncoder

    function CategoryEncoder(;w=0, categoryList=(), forced=false)

        tcL=Dict(categoryList[i] => i for i = 1:length(categoryList))

        e=ScalarEncoder(w = w, minval=0, maxval=length(categoryList),
                      radius=1, periodic=false, forced=forced)
        new(tcL,e)

end

end
export CategoryEncoder

function getWidth(e::CategoryEncoder)
    e.sE.n
end
export getWidth

function getDescription(e::CategoryEncoder)
    e.sE.name
end
export getDescription

function getName(e::CategoryEncoder)
    e.sE.name
end
export getName

function getBucketIndices(e::CategoryEncoder)

end
export getBucketIndices

function encodeIntoArray(e::CategoryEncoder,n::Void,b::BitPat;learn=true)
    fill!(b.b,false)
    b
end
function encodeIntoArray(e::CategoryEncoder,n::AbstractString,b::BitPat;learn=true)
    t=get(e.cL,n,0)
    encodeIntoArray(e.sE,convert(Int32,t),b)

    b
end
export encodeIntoArray

#function decode(e::CategoryEncoder, b::BitPat; parentFieldName="")
#
#end
#export decode

function getBucketValues(e::CategoryEncoder)

end
export getBucketValues

function getBucketInfo(e::CategoryEncoder)

end
export getBucketInfo

function topDownCompute(e::CategoryEncoder)

end
export topDownCompute

function closenessScores(e::CategoryEncoder)

end
export closenessScores

# end # module


text:
# This file was generated, do not modify it. # hide
using MeasureTheory
basemeasure(Normal())

max_stars_repo_name: cscherrer/InformativePrior

max_issues_repo_name: cscherrer/InformativePrior

max_forks_repo_name: cscherrer/InformativePrior


text:
# Implementation of reverse-mode sensitivities for `getindex`.
import Base.getindex
for i = 1:7
    T = Expr(:curly, :Tuple, fill(:Any, i)...)
    is_node = Expr(:vect, true, fill(false, i - 1)...)
    @eval @explicit_intercepts getindex $T $is_node
end

function ∇(Ā, ::typeof(getindex), ::Type{Arg{1}}, p, y, ȳ, A, inds...)
    Ā[inds...] += ȳ
    return Ā
end
function ∇(Ā, ::typeof(getindex), ::Type{Arg{1}}, p, y::AbstractArray, ȳ::AbstractArray, A, inds...)
    @views Ā[inds...] .+= reshape(ȳ, size(y)...)
    return Ā
end
function ∇(::typeof(getindex), ::Type{Arg{1}}, p, y, ȳ, A, inds...)
    return ∇(zerod_container(A), getindex, Arg{1}, p, y, ȳ, A, inds...)
end

# # Implementation of reverse-mode sensitivities for `view`. Not currently in use because
# `view` turns out to actually be a bit awkward.
# eval(DiffBase, add_intercept(:view, :(Base.view), :(Tuple{Any, Vararg})))
# @inline function ∇(Ā, ::typeof(view), ::Type{Arg{1}}, p, y, ȳ, A, inds...)
#     return Base.setindex!(Ā, ȳ, inds...)
# end
# @inline function ∇(::typeof(view), ::Type{Arg{1}}, p, y, ȳ, A, inds...)
#     return ∇(zeros(A), view, Arg{1}, p, y, ȳ, A, inds...)
# end


text:
module FlipGravityTrigger
    using ..Ahorn, Maple
    @mapdef Trigger "vvvvvv/flipGravityTrigger" FlipGravity(x::Integer, y::Integer, width::Integer=8, height::Integer=8)

    const placements = Ahorn.PlacementDict(
        "Flip Gravity" => Ahorn.EntityPlacement(
            FlipGravity,
            "rectangle"
        ),
    )
end


text:
## Operators for cartesian Arakawa C-Grid ##
# TODO: Needs to be generalized

@inline cyclic_index(i::Int, N::Int) = mod(i - 1, N) + 1

const add_default = true

@inline add_op(a, b) = a + b
@inline ass_op(a, b) = b

assign_op(add::Bool) = add ? add_op : ass_op

## Derivative operators for cartesian C-Grid ##

@inline function dx_u!(result::T, var::T, add::Bool=add_default) where {T<:AbstractArray}
    n, m = size(var)
    @boundscheck checkbounds(result, n, m)
    op = assign_op(add)
    for j in 1:m
        for i in 1:n
            @inbounds result[i, j] = op(result[i, j], var[cyclic_index(i+1, n), j] - var[i, j])
        end
    end
    return result
end
dx_u(var) = dx_u!(similar(var), var, false)

@inline function dy_u!(result::T, var::T, add::Bool=add_default) where {T<:AbstractArray}
    n, m = size(var)
    @boundscheck checkbounds(result, n, m)
    op = assign_op(add)
    for j in 1:m
        for i in 1:n
            @inbounds result[i, j] = op(result[i, j], var[i, j] - var[i, cyclic_index(j-1, m)])
        end
    end
    return result
end
dy_u(var) = dy_u!(similar(var), var, false)

@inline function dx_v!(result::T, var::T, add::Bool=add_default) where {T<:AbstractArray}
    n, m = size(var)
    @boundscheck checkbounds(result, n, m)
    op = assign_op(add)
    for j in 1:m
        for i in 1:n
            @inbounds result[i, j] = op(result[i, j], var[i, j] - var[cyclic_index(i-1, n), j])
        end
    end
    return result
end
dx_v(var) = dx_v!(similar(var), var, false)

@inline function dy_v!(result::T, var::T, add::Bool=add_default) where {T<:AbstractArray}
    n, m = size(var)
    @boundscheck checkbounds(result, n, m)
    op = assign_op(add)
    for j in 1:m
        for i in 1:n
            @inbounds result[i, j] = op(result[i, j], var[i, cyclic_index(j+1, m)] - var[i, j])
        end
    end
    return result
end
dy_v(var) = dy_v!(similar(var), var, false)

dx_η! = dx_v!
dx_η = dx_v
dy_η! = dy_u!
dy_η = dy_u

@inline function d2x!(result::T, var::T, add::Bool=add_default) where {T<:AbstractArray}
    n, m = size(var)
    @boundscheck checkbounds(result, n, m)
    op = assign_op(add)
    for j in 1:m
        for i in 1:n
            @inbounds result[i, j] = op(
                result[i, j],
                var[cyclic_index(i+1, n), j] - 2var[i, j] + var[cyclic_index(i-1, n), j])
        end
    end
    return result
end
d2x(var) = d2x!(similar(var), var, false)
d2x_u! = d2x!
d2x_u = d2x
d2x_v! = d2x!
d2x_v = d2x
d2x_η! = d2x!
d2x_η = d2x

@inline function d2y!(result::T, var::T, add::Bool=add_default) where {T<:AbstractArray}
    n, m = size(var)
    @boundscheck checkbounds(result, n, m)
    op = assign_op(add)
    for j in 1:m
        for i in 1:n
            @inbounds result[i, j] = op(
                result[i, j],
                var[i, cyclic_index(j+1, m)] - 2var[i, j] + var[i, cyclic_index(j-1, m)])
        end
    end
    return result
end
d2y(var) = d2y!(similar(var), var, false)
d2y_u! = d2y!
d2y_u = d2y
d2y_v! = d2y!
d2y_v = d2y
d2y_η! = d2y!
d2y_η = d2y

@inline function ∇²!(result::T, var::T, add::Bool=add_default) where {T<:AbstractArray}
    n, m = size(var)
    @boundscheck checkbounds(result, n, m)
    op = assign_op(add)
    @inbounds for j in 1:m
        for i in 1:n
            result[i, j] =  op(
                result[i, j],
                var[cyclic_index(i+1, n), j] - 2var[i, j] + var[cyclic_index(i-1, n), j]
                + var[i, cyclic_index(j+1, m)] - 2var[i, j] + var[i, cyclic_index(j-1, m)]
            )
        end
    end
    return result
end

## interpolation between grids (Arakawa C-Grid)

@inline function i_u2v!(result::T, var::T, add::Bool=add_default) where {T<:AbstractArray}
    n, m = size(var)
    @boundscheck checkbounds(result, n, m)
    op = assign_op(add)
    for j in 1:m
        for i in 1:n
            @inbounds result[i, j] = op(
                result[i, j],
                .25 * (var[i, j] + var[cyclic_index(i+1, n), cyclic_index(j-1, m)]
                + var[i, cyclic_index(j-1, m)] + var[cyclic_index(i+1, n), j])
            )
        end
    end
    return result
end
i_u2v!(var, add=add_default) = res -> i_u2v!(res, var, add)
i_u2v(var) = i_u2v!(similar(var), var, false)

@inline function i_v2u!(result::T, var::T, add::Bool=add_default) where {T<:AbstractArray}
    n, m = size(var)
    @boundscheck checkbounds(result, n, m)
    op = assign_op(add)
    for j in 1:m
        for i in 1:n
            @inbounds result[i, j] = op(
                result[i, j],
                .25 * (var[i, j] + var[cyclic_index(i-1, n), cyclic_index(j+1, m)]
                + var[cyclic_index(i-1, n), j] + var[i, cyclic_index(j+1, m)])
            )
        end
    end
    return result
end
i_v2u!(var, add=add_default) = res -> i_v2u!(res, var, add)
i_v2u(var) = i_v2u!(similar(var), var, false)

@inline function i_u2η!(result::T, var::T, add::Bool=add_default) where {T<:AbstractArray}
    n, m = size(var)
    @boundscheck checkbounds(result, n, m)
    op = assign_op(add)
    for j in 1:m
        for i in 1:n
            @inbounds result[i, j] = op(
                result[i, j],
                .5 * (var[i, j] + var[cyclic_index(i+1, n), j])
            )
        end
    end
    return result
end
i_u2η!(var, add=add_default) = res -> i_u2η!(res, var, add)
i_u2η(var) = i_u2η!(similar(var), var, false)

@inline function i_v2η!(result::T, var::T, add::Bool=add_default) where T<:AbstractArray
    n, m = size(var)
    @boundscheck checkbounds(result, n, m)
    op = assign_op(add)
    for j in 1:m
        for i in 1:n
            @inbounds result[i, j] = op(
                result[i, j],
                .5 * (var[i, j] + var[i, cyclic_index(j+1, m)])
            )
        end
    end
    return result
end
i_v2η!(var, add=add_default) = res -> i_v2η!(res, var, add)
i_v2η(var) = i_v2η!(similar(var), var, false)


text:
export path_info

struct PathInfo
    # per step info
    s::Vector{Float64}
    Δs::Vector{Float64}
    ω::Vector{Float64}
    Δx₀::Vector{Float64}
    accepted_rejected::Vector{Bool}
    norm_x::Vector{Float64}
    accuracy::Vector{Float64}
    μ::Vector{Float64}
    τ::Vector{Float64}
    Δx_t::Vector{Float64}
    Δx̂x::Vector{Float64}
    high_prec::Vector{Bool}
    # total info
    return_code::TrackerCode.codes
    n_factorizations::Int
    n_ldivs::Int
end

"""
    path_info(tracker::Tracker, x₀, t₁ = 1.0, t₀ = 0.0; debug::Bool = false, kwargs...)

Track a path using the given `tracker` and start value `x₀`.
This returns a struct containing detailed information about the tracked path.
"""
function path_info(tracker::Tracker, x₀, t₁ = 1.0, t₀ = 0.0; debug::Bool = false, kwargs...)
    state = tracker.state

    s = Float64[]
    Δs = Float64[]
    ω = Float64[]
    Δx₀ = Float64[]
    accepted_rejected = Bool[]
    norm_x = Float64[]
    cond = Float64[]
    accuracy = Float64[]
    μ = Float64[]
    τ = Float64[]
    Δx_t = Float64[]
    Δx̂x = Float64[]
    high_prec = Bool[]

    p = order(tracker.predictor)

    init!(tracker, x₀, t₁, t₀; kwargs...)
    while is_tracking(tracker.state.code)
        push!(s, real(state.t))
        push!(Δs, real(state.Δt))
        e = local_error(tracker.predictor)
        push!(Δx_t, e * abs(state.Δt)^p)
        push!(τ, tracker.options.parameters.β_τ * trust_region(tracker.predictor))
        push!(ω, state.ω)
        push!(accuracy, state.accuracy)
        push!(μ, state.μ)
        push!(high_prec, state.extended_prec)
        step!(tracker, debug)

        push!(accepted_rejected, !state.last_step_failed)
        push!(Δx₀, state.norm_Δx₀)
        push!(norm_x, maximum(abs, state.x))
        push!(Δx̂x, state.norm(state.x .- state.x̂))
    end

    PathInfo(
        s,
        Δs,
        ω,
        Δx₀,
        accepted_rejected,
        norm_x,
        accuracy,
        μ,
        τ,
        Δx_t,
        Δx̂x,
        high_prec,
        tracker.state.code,
        state.jacobian.factorizations[],
        state.jacobian.ldivs[],
    )
end

path_table(info::PathInfo) = path_table(stdout, info)
function path_table(io::IO, info::PathInfo)
    header = ["", "s", "Δs", "ω", "|Δx₀|", "h₀", "acc", "μ", "τ", "Δx_t", "Δpred ", "|x|"]
    h1 = PrettyTables.Highlighter(
        f = (data, i, j) -> j == 1 && data[i, 1] == :✗,
        crayon = PrettyTables.crayon"red",
    )
    h2 = PrettyTables.Highlighter(
        f = (data, i, j) -> j == 1 && data[i, 1] == :✓,
        crayon = PrettyTables.crayon"green",
    )
    h3 = PrettyTables.Highlighter(
        f = (data, i, j) -> j == 3 && data[i, 3] ≈ -data[i, 9],
        crayon = PrettyTables.crayon"blue",
    )
    h4 = PrettyTables.Highlighter(
        f = (data, i, j) -> j == 8 && info.high_prec[i],
        crayon = PrettyTables.crayon"blue",
    )

    ✓✗ = map(v -> v ? :✓ : :✗, info.accepted_rejected)
    data = hcat(
        ✓✗,
        info.s,
        info.Δs,
        info.ω,
        info.Δx₀,
        info.ω .* info.Δx₀,
        info.accuracy,
        info.μ,
        info.τ,
        info.Δx_t,
        info.Δx̂x,
        info.norm_x,
    )

    ft1 = PrettyTables.ft_printf("%5.2g", [4, 5, 6, 7, 8, 10, 11, 12])
    ft2 = PrettyTables.ft_printf("%5.2g", [3, 9])
    ft4 = PrettyTables.ft_printf("%3.3g", [2, 4])

    PrettyTables.pretty_table(
        io,
        data,
        header,
        crop = :none,
        formatters = (ft1, ft2, ft4),
        highlighters = (h1, h2, h3, h4),
    )
end

function Base.show(io::IO, info::PathInfo)
    println(io, "PathInfo:")
    println(io, " • # return code → ", info.return_code)
    println(
        io,
        " • # steps (✓/✗) → ",
        length(info.s),
        " ( ",
        count(info.accepted_rejected),
        " / ",
        count(!, info.accepted_rejected),
        " )",
    )
    println(io, " • # factorizations → ", info.n_factorizations)
    println(io, " • # ldivs → ", info.n_ldivs)
    path_table(io, info)
end


text:
export CMAEvolutionStrategyOpt
struct CMAEvolutionStrategyOpt end

function __solve(prob::OptimizationProblem, opt::CMAEvolutionStrategyOpt, data = DEFAULT_DATA;
                 cb = (args...) -> (false), maxiters = nothing,
                 progress = false, kwargs...)
    local x, cur, state

    if data != DEFAULT_DATA
        maxiters = length(data)
    end

    cur, state = iterate(data)

    function _cb(trace)
        cb_call = cb(decompose_trace(trace).metadata["x"],trace.value...)
        if !(typeof(cb_call) <: Bool)
            error("The callback should return a boolean `halt` for whether to stop the optimization process.")
        end
        cur, state = iterate(data, state)
        cb_call
    end

    _loss = function(θ)
        x = prob.f(θ, prob.p, cur...)
        return first(x)
    end

    if !(isnothing(maxiters)) && maxiters <= 0.0
        error("The number of maxiters has to be a non-negative and non-zero number.")
    elseif !(isnothing(maxiters))
        maxiters = convert(Int, maxiters)
    end

    result = CMAEvolutionStrategy.minimize(_loss, prob.u0, 0.1; lower = prob.lb, upper = prob.ub, maxiter = maxiters, kwargs...)
    CMAEvolutionStrategy.print_header(result)
    CMAEvolutionStrategy.print_result(result)
    println("\n")
    criterion = true

    if (result.stop.reason === :maxtime) #this is an arbitrary choice of convergence (based on the stop.reason values)
        criterion = false
    end

    SciMLBase.build_solution(prob, opt, result.logger.xbest[end], result.logger.fbest[end]; original=result)
end


text:
# Very simple implementation of some adaptive MCMC algorithms.
module AdaptiveParticleMCMC

export adaptive_pg, adaptive_pmmh, SMCState

using Random, SequentialMonteCarlo, ProgressMeter, AdaptiveMCMC

include("common.jl") # Data types
include("smc.jl") # SequentialMonteCarlo.jl interface
include("pmmh.jl") # Particle marginal Metropolis-Hastings
include("pg.jl")   # Particle Gibbs

end # module


text:
module STLFile

using TriMeshes

export STL_ASCII, STL_BIN

function STL_ASCII(n::Net)
	STL_ASCII(n, STDOUT)
end

function STL_ASCII(n::Net, fn::String)
	fid = open(fn, "w+")
	STL_ASCII(n, fid)
	close(fid)
end

function STL_ASCII(n::Net, io::IO)
	println(io, "solid Mesh.jl")
	for f in n.Faces
		abf = n.Vertices[f.AB.From]
		abt = n.Vertices[f.AB.To]
		bct = n.Vertices[f.BC.To]
		println(io, "facet normal 0 0 0")
		println(io, "\touter loop")
		println(io, "\t\tvertex $(abf.x), $(abf.y), $(abf.z)")
		println(io, "\t\tvertex $(abt.x), $(abt.y), $(abt.z)")
		println(io, "\t\tvertex $(bct.x), $(bct.y), $(bct.z)")
		println(io, "\tendloop")
	end
	println(io, "endsolid Mesh.jl")
end

function STL_BIN(n::Net)
	STL(n, STDOUT)
end

function STL_BIN(n::Net, fn::String)
	fid = open(fn, "w+")
	STL(n, fid)
	close(fid)
end

function STL_BIN(n::Net, io)
	for k in 1:10
		write(io, Int64(0))
	end
	write(io, Int32(length(n.Faces)))
	for f in n.Faces
		write(io, Float32(0), Float32(0), Float32(0),  f.AB.From.x, f.AB.From.y, f.AB.From.z, f.AB.To.x, f.AB.To.y, f.AB.To.z, f.BC.To.x, f.BC.To.y, f.BC.To.z)
	end
	write(io, Int16(0))
end

### STAHP

end


text:
"""
    MetaGraph(g::Node)

Convert an MTG into a [MetaGraph](https://juliagraphs.org/MetaGraphsNext.jl/dev/).

# Examples

```julia
# Importing an mtg from the package:
file = joinpath(dirname(dirname(pathof(MultiScaleTreeGraph))),"test","files","simple_plant.mtg")
mtg = read_mtg(file)

MetaGraph(mtg)
```
"""
function MetaGraph(g::Node)
    meta_mtg =
        MetaGraph(
            DiGraph(),
            Label = Int,
            VertexMeta = typeof(g.attributes),
            EdgeMeta = String,
            gprops = "MTG"
        )

    traverse!(g, to_MetaGraph, meta_mtg)
    return meta_mtg
end

function to_MetaGraph(node, meta_mtg)
    meta_mtg[node.id] = node.attributes

    if !isroot(node)
        code_node = code_for(meta_mtg, node.id)
        code_parent = code_for(meta_mtg, parent(node).id)
        add_edge!(meta_mtg, code_parent, code_node, node.MTG.link)
    end
end


text:
## Implimentación del modelo de Ising con el algoritmo de Metropolis-Hastings ##

module Ising

export MicroEstado, edo_aleatorio, energia_total, magnetizacion_total, simulacion_montecarlo
export microEstados_montecarlo
import Base.show

type MicroEstado
    σ::Array{Int,2}
	# Vamos a suponer que todas las configuraciones son cuadradas
    L::Int
end

show(io::IO, m::MicroEstado) = print(io, m.σ)

function edo_aleatorio(L::Int)
    σ = ones(Int, (L,L))
    for i in 1:L^2
        if rand() <= 0.5
			σ[i] = -1
        end
	end
    MicroEstado(σ,L)
end

function voltea_espin!(m::MicroEstado, i::Int, j::Int)
    m.σ[i,j] *= -1
end

function energia_total(m::MicroEstado)
	out = 0.
    for i in 1:m.L, j in m.L
		out += energia_ij(m,i,j)
    end
    out/2
end

function energia_ij(m::MicroEstado, i::Int, j::Int)
	L = m.L
	-m.σ[i,j]*(m.σ[mod1(i-1,L),j] + m.σ[mod1(i+1,L),j] + m.σ[i,mod1(j-1,L)] + m.σ[i,mod1(j+1,L)])
end

function propone_cambio(m::MicroEstado, β::Float64)
    i, j = rand(1:m.L), rand(1:m.L)  # Es más rápido que rand(1:m.L, 2)
	ΔE = -2*energia_ij(m, i, j)

	ΔE, i, j
end

function paso_montecarlo!(m::MicroEstado, β::Float64)
	aceptado = false

	while aceptado == false
		ΔE, i, j = propone_cambio(m, β)

		# El parámetro de aceptación
		α = min(1., e^(-β*ΔE))

		if rand() < α
			aceptado = true
			ΔM = -2*m.σ[i,j]
			voltea_espin!(m, i, j)
			return ΔE, ΔM
		end
    end
end

# function simulacion_montecarlo(L::Int, T, num_pasos::Int)
# 	β = 1/T
# 	m = edo_aleatorio(L)

# 	for i in 1:num_pasos-1
# 		paso_montecarlo!(m,β)
# 	end

# 	m
# end

magnetizacion_total(m::MicroEstado) = sum(m.σ)

function simulacion_montecarlo(L::Int, T, num_pasos::Int)
	β = 1/T
	m = edo_aleatorio(L)

	ener = Array(Float64, num_pasos)
	ener[1] = energia_total(m)
	mag = Array(Float64, num_pasos)
	mag[1] = magnetizacion_total(m)

	for i in 1:num_pasos-1
		ΔE, ΔM = paso_montecarlo!(m, β)
		ener[i+1] = ener[i] + ΔE
		mag[i+1] = mag[i] + ΔM
	end

	ener, mag
end

function microEstados_montecarlo(L::Int, T, num_pasos::Int)
	β = 1/T
	m = edo_aleatorio(L)

	out = Array{Int,2}[copy(m.σ)]
	sizehint(out, num_pasos)

	for i in 1:num_pasos-1
		paso_montecarlo!(m, β)
		push!(out, copy(m.σ))
	end

	out
end

end

max_stars_repo_name: rodrigolece/modelo-ising

max_issues_repo_name: rodrigolece/modelo-ising

max_forks_repo_name: rodrigolece/modelo-ising


text:
export corrplot

"""

  corrplot(C)

Plot a CorrData matrix.
"""
function corrplot(C::CorrData)
    lags = -C.maxlag:1/C.fs:C.maxlag
    times = Dates.format.(Dates.unix2datetime.(C.t),"yyyy/m/d HH:MM")
    Cstack = stack(C,allstack=true)
    plot(
         heatmap(lags,times,C.corr',c=:balance,legend=:none),
         plot(lags,Cstack.corr,c=:black,linewidth=1.5,legend=:none,xlabel="Lag [s]"),
         layout = grid(2,1,heights=[0.75,0.25]), link=:x,dpi=1000)
end


text:
# Computes samples of unitary invariant ensembles matrices of size nxn
#
# InvariantEnsemble(str,n) represents an n x n unitary invariant ensemble
# with distribution
#
#   exp(- Tr Q(M)) dM
#
# str specifies an ensemble with precomputed recurrence coefficients.
#  The currently include ensembles are
#
#       Quartic:            Q(M) = n M^4
#       Eight:              Q(M) = n M^8
#       HODecay:            Q(M) = n (M^4/20 - 4/15M^3 +M^2/5 + 8/5M)
#       CoshUnscaled:       Q(M) = cosh(M)
#       QuarticUnscaled:    Q(M) = M^4
#       EightUnscaled:      Q(M) = M^8
#
# References:
#    Olver, Rao & Trogdon 2014 arXiv:1404.007

module InvariantEnsembles
    using ApproxFun, RandomMatrices, Compat

export InvariantEnsemble

## Construct orthogonal polynomials as Funs from first moment and recurrence relationship
function orthonormalpolynomials(μ0,α::Vector,β::Vector,d)
    n=length(α)+1

    p=Array(Fun{Chebyshev,Float64},n)
    p[1] = Fun([μ0],d)
    p[2] = multiplybyx(p[1])./β[1] - p[1].*α[1]./β[1]
    for k = 3:n
       p[k] =  multiplybyx(p[k-1])./β[k-1] - p[k-1].*α[k-1]./β[k-1] - p[k-2].*β[k-2]./β[k-1]
    end
    p
end

function orthonormalpolynomials(μ0,α::Function,β::Function,d,n)
    orthonormalpolynomials(μ0,map(α,[1:n-1]),map(β,[1:n-1]),d)
end

function legendrepolynomials(n)
  orthonormalpolynomials(1./sqrt(2),k->0,k->sqrt(k^2./(4k^2-1)),[-1.,1.],n)
end
function scaledhermitepolynomials(n)
  orthonormalpolynomials(n^(1/4)/(1.0π)^(1/4),k->0,k->sqrt((k)/(2n)),[-3.,3.],n)
end

## Evaluate orthogonal polynomials at points x from first moment and recurrence relationship
function orthonormalpolynomialsvalues(μ0,α::Vector,β::Vector,x)
    n=length(α)+1
    m=length(x)

    p=Array(Float64,m,n)

    p[:,1] = μ0*ones(m)
    p[:,2] = x.*p[:,1]./β[1] - p[:,1].*α[1]./β[1]
    for k = 3:n
       p[:,k] =  x.*p[:,k-1]./β[k-1] - p[:,k-1].*α[k-1]./β[k-1] - p[:,k-2].*β[k-2]./β[k-1]
    end
    p
end

## Ensembles

type InvariantEnsemble{D<:Interval}
    basis::Array{Float64,2}         # the m x n array of the first n weighted OPs evaluated at m Chebyshev points
    domain::D                       # the sub domain  of the real line
end

InvariantEnsemble(basis,d::Vector)=InvariantEnsemble(basis,Interval(d))

## n, where the invariant ensemble is n x n
Base.size(ie::InvariantEnsemble)=size(ie.basis,2),size(ie.basis,2)
Base.size(ie::InvariantEnsemble,n)=size(ie.basis,2)

#Takes in list of OPs, constructs phis
# can be unstable for large n
function InvariantEnsemble{F<:Fun}(p::Array{F},V::Function,d,n::Integer)
    error("Reimplement with matrix")

#     wsq=IFun(x->exp(-n/2.*V(x)),d)
#
#     #We now extend the lengths
#     m=length(wsq)+2n
#     p=map(f->pad(f,m),p)
#
#     # We want to multiply, but in value space to
#     # take advantage of wsq being very small
#
#     wsqv=exp(-n/2.*V(points(wsq.domain,m)))
#     q=map(f->IFun(chebyshevtransform(wsqv.*values(f)),f.domain),p)
#
#     InvariantEnsemble(q)

end

##Adaptively construct invariant ensemble from weight, first moment and recurrence relationship
function adaptiveie(w,μ0,α,β,d)
  for logn = 4:20
    m=2^logn + 1
    pts=points(Interval(d),m)
    pv=orthonormalpolynomialsvalues(μ0,α,β,pts)

    wv=w(pts)

    cfs=chebyshevtransform(pv[:,end].^2.*wv)

    if maximum(abs(cfs[end-8:end])) < 200*eps()
        ## chop to minimize oversample

        m=length(chop!(cfs,200*eps()))

        pts=points(Interval(d),m)
        pv=orthonormalpolynomialsvalues(μ0,α,β,pts)
        wv=w(pts)

        return InvariantEnsemble(diagm(sqrt(wv))*pv,d)
    end
  end

  error("Did not converge")
end

#Reads in recurrence relationship and constructs OPs
function InvariantEnsemble(str::AbstractString,V::Function,d,n::Integer)
    file = joinpath(dirname(@__FILE__), "../data/CoefficientDatabase/" * str * "/" * string(n))
    μ0=readdlm(file * "norm.csv")[1]
    A=readdlm(file * "rc.csv",',')
    a=reshape((A[1,1:end-1]),size(A)[2]-1)
    b=reshape(A[2,2:end],size(A)[2]-1)

    adaptiveie(x->exp(-n.*V(x)),μ0,a,sqrt(b),d)
end

# For constructing InvariantEnsembles that do not scale with n
function InvariantEnsembleUnscaled(str::AbstractString,V::Function,d,n::Integer)
    file = joinpath(dirname(@__FILE__), "../data/CoefficientDatabaseUnscaled/" * str * "/")
    μ0=readdlm(file * "norm.csv")[1]
    A=readdlm(file * "rc.csv",',')
    a=reshape((A[1,1:end-1]),size(A)[2]-1)
    b=reshape(A[2,2:end],size(A)[2]-1)

    adaptiveie(x->exp(-V(x)),μ0,a[1:n-1],sqrt(b[1:n-1]),d)
end

#Decides whether to use built in recurrence or read it in
# Also contains ensemble data
function InvariantEnsemble(str::AbstractString,n::Integer)
    if(str == "GUE")
        InvariantEnsemble(str,x->x.^2,[-3.,3.],n)
    elseif(str == "Quartic")
        InvariantEnsemble(str,x->x.^4,[-3.,3.],n)
    elseif(str == "Eight")
        InvariantEnsemble(str,x->x.^8,[-3.,3.],n)
    elseif(str == "HODecay")
        InvariantEnsemble(str,x->x.^4/20 -4/15*x.^3 + x.^2/5+8/5*x,[-4.,6.],n)
    elseif(str == "Legendre")
        error("Legendre not implemented")
        #InvariantEnsembles(map(f->pad(f,2n),legendrepolynomials(n)))
    elseif(str == "CoshUnscaled")
        InvariantEnsembleUnscaled("Cosh",x->cosh(x),[-2acosh(1.0n),2acosh(1.0n)],n)
    elseif(str == "EightUnscaled")
        InvariantEnsembleUnscaled("Eight",x->x.^8,[-3.0n^(1/8),3.0n^(1/8)],n)
    elseif(str == "QuarticUnscaled")
        InvariantEnsembleUnscaled("Quartic",x->x.^4,[-3.0n^(1/4),3.0n^(1/4)],n)
    end
end

##  Construct the invariant ensemble kernel K_n(x,x)
iekernel(q::Array{Float64,2},d)=iekernel(q,d,plan_chebyshevtransform(q[:,1]))
function iekernel(q::Array{Float64,2},d,plan::Function)
    n=size(q)[1]
    m=size(q)[2]
    ret=zeros(n)
    for i = 1:m
        for k = 1:n
            ret[k] += q[k,i].*q[k,i]
        end
    end

  Fun(chebyshevtransform(ret,plan),d)
end

samplespectra(str::AbstractString,n::Integer,m::Integer)=samplespectra(InvariantEnsemble(str,n),m)

# Sample eigenvalues of invariant ensemble, m times
function RandomMatrices.eigvalrand(p::InvariantEnsemble,m::Integer)
    q = p.basis
    plan = plan_chebyshevtransform(q[:,1])
    pts=chebyshevpoints(size(q,1))

    hcat([samplespectra(p.basis,p.domain,plan,pts) for i=1:m]...)'
end

RandomMatrices.eigvalrand(p::InvariantEnsemble)=[eigvalrand(p,1)[1,:]...]

# Sample invariant ensemble
function Base.rand(p::InvariantEnsemble)
    Q=rand(Haar(2),size(p,1))
    Q*diagm(eigvalrand(p))*Q'
end

# Sample invariant ensemble, m times
function Base.rand(p::InvariantEnsemble,m::Integer)
    ei = eigvalrand(p,m)
    Array{Complex{Float64},2}[(    Q=rand(Haar(2),size(p,1));
    Q*diagm([ei[k,:]...])*Q') for k=1:size(ei,1)]
end

## samplespectra is back end for eigvalrand
samplespectra(q::Array{Float64,2},d)=samplespectra(q,d,plan_chebyshevtransform(q[:,1]),chebyshevpoints(size(q,1)))

function samplespectra(q::Array{Float64,2},d,plan::Function,pts)
    n = size(q,2)
    r=Array(Float64,n)

    for k=1:n-1
        m = n - k + 1
        r[k] = samplecdf(normalizedcumsum!(iekernel(q,d,plan).coefficients/m))
        f=Float64[bary(q[:,j],pts,r[k]) for j = 1:m]
        r[k] = fromcanonical(d,r[k])
        Q=null(f')
        q=q*Q
    end

    r[n] = sample(iekernel(q,d,plan))

    r
end

function iekernel{F<:Fun}(p::Array{F})
    ret = 0.*p[1]
    for i = 1:length(p)
        ret += fasttimes(p[i],p[i])
    end

    ret
end

function samplespectra{F<:Fun}(p::Array{F})
    n = length(p)
    r=sample(iekernel(p)/n)
    if n==1
        r
    else
        f=map(q->q[r],p)
        Q=null(f')'
        [r ;samplespectra(Q*p)]
    end
end

iekernel(p::InvariantEnsemble)=iekernel(p.basis,p.domain)
samplespectra(p::InvariantEnsemble)=samplespectra(p.basis,p.domain)

## Spectra database supports building up a database of precomputed samples

function spectradatabase(str,n::Integer,m::Colon)
  file = joinpath(dirname(@__FILE__), "../data/SpectraDatabase/" * str * "/" * string(n) * ".csv");

  if(filesize(file) == 0)
    []
  else
    readdlm(file,',')
  end
end

function spectradatabase(str,n::Integer,m::Integer)
    if  filesize(joinpath(dirname(@__FILE__), "../data/CoefficientDatabase")) == 0 ||
        filesize(joinpath(dirname(@__FILE__), "../data/CoefficientDatabaseUnscaled")) == 0
        error("No coefficient database found.  InvariantEnsembles package corrupted.")
    end

    dir = joinpath(dirname(@__FILE__), "../data/SpectraDatabase")
    if filesize(dir) == 0
        warn("Creating SpectraDatabase folder " * dir)

        mkdir(dir)
    end

    dir = joinpath(dirname(@__FILE__), "../data/SpectraDatabase/" * str)

    if filesize(dir) == 0
        warn("Creating folder " * dir)

        mkdir(dir)
    end

  file = dir * "/" * string(n) * ".csv"

  if filesize(file) == 0
    warn("No existing samples found.  Creating sample database.");

    ie = InvariantEnsemble(str,n)

    A=eigvalrand(ie,m+1)
    writedlm(file,A,',')
  else
    A = readdlm(file,',')

    if ( m > size(A)[1])
      warn(string(m) * " is greater than current samples " * string(size(A)[1]) * ".  Generating more samples");

      ie = InvariantEnsemble(str,n)

      An=eigvalrand(ie,m-size(A)[1]+1)

      A = vcat(A,An)

      writedlm(file,A,',')
    end
  end

    return A[1:m,:]
end

end #module


text:
## NamedArrays.jl
## (c) 2013--2014 David A. van Leeuwen

## Julia type that implements a drop-in replacement of Array with named dimensions.

## This code is licensed under the MIT license
## See the file LICENSE.md in this distribution

VERSION >= v"0.4.0-dev+6521" && __precompile__()

module NamedArrays

using Compat
using DataStructures

export NamedArray, NamedVector, NamedMatrix, Not

## type definition
include("namedarraytypes.jl")

export allnames, dimnames, setnames!, setdimnames!, array

include("compat.jl")
include("constructors.jl")
include("arithmetic.jl")
include("base.jl")
include("changingnames.jl")
include("index.jl")
include("keepnames.jl")
include("names.jl")
include("rearrange.jl")
include("show.jl")
include("convert.jl")

end


text:
using DrWatson
@quickactivate
using ArgParse
using GenerativeAD
import StatsBase: fit!, predict
using StatsBase
using BSON
# because of vae and 2stage
using DataFrames
using CSV
using ValueHistories
using Flux
using ConditionalDists
using GenerativeModels
import GenerativeModels: VAE
using Distributions
using DistributionsAD

s = ArgParseSettings()
@add_arg_table! s begin
	"max_seed"
		default = 1
		arg_type = Int
		help = "max_seed"
	"category"
		default = "wood"
		arg_type = String
		help = "dataset"
	"contamination"
		arg_type = Float64
		help = "contamination rate of training data"
		default = 0.0
end
parsed_args = parse_args(ARGS, s)
@unpack category, max_seed, contamination = parsed_args

#######################################################################################
################ THIS PART IS TO BE PROVIDED FOR EACH MODEL SEPARATELY ################

tab_name = "vae_LOSS_images_mvtec"
mi = 1
sp = split(tab_name, "_")
enc = sp[1]
criterion = lowercase(sp[2])

modelname = "$(enc)_knn"

# max(10, 0.03n)
function set_params(data)
	D, N = size(data[1][1])
	nn = max(10, ceil(Int,0.03*N))
	return (k=nn,)
end

function fit(data, parameters, aux_info)
	# construct model - constructor should only accept kwargs
	model = GenerativeAD.Models.knn_constructor(;v=:kappa, parameters...)

	# fit train data
	try
		global info, fit_t, _, _, _ = @timed fit!(model, data[1][1])
	catch e
		# return an empty array if fit fails so nothing is computed
		return (fit_t = NaN,), []
	end

	# construct return information - put e.g. the model structure here for generative models
	training_info = (
		fit_t = fit_t,
		model = nothing
		)

	# now return the different scoring functions
	function knn_predict(model, x, v::Symbol)
		try
			return predict(model, x, v)
		catch e
			if isa(e, ArgumentError) # this happens in the case when k > number of points
				return NaN # or nothing?
			else
				rethrow(e)
			end
		end
	end
	parameters = merge(parameters, aux_info)
	training_info, [(x -> knn_predict(model, x, v), merge(parameters, (distance = v,))) for v in [:delta]]
end

####################################################################
################ THIS PART IS COMMON FOR ALL MODELS ################
# set a maximum for parameter sampling retries
try_counter = 0
max_tries = 1
cont_string = (contamination == 0.0) ? "" : "_contamination-$contamination"
while try_counter < max_tries
	for seed in 1:max_seed
		savepath = datadir("experiments/images_mvtec_clean_val_default$cont_string/$(modelname)/$(category)/seed=$(seed)")
		aux_info = (model_index=mi, criterion=criterion)

		# load data
		global data = GenerativeAD.load_data("MVTec-AD", seed=seed, category=category,
			contamination=contamination, img_size=64)
		not_loaded = true
		while not_loaded
			try
				global data, encoding_name, encoder_params =
				GenerativeAD.Models.load_encoding(tab_name, data, 1, dataset=category, seed=seed, model_index=mi)
				not_loaded = false
			catch e
				println(e)
				@info "model index $mi not working, trying the next one"
				global mi += 1
			end
		end
		parameters = set_params(data)

		# here, check if a model with the same parameters was already tested
		@info "Trying to fit $modelname on $category with parameters $(parameters)..."
		if GenerativeAD.check_params(savepath, merge(parameters, aux_info))
			training_info, results = fit(data, parameters, aux_info)
			# here define what additional info should be saved together with parameters, scores, labels and predict times
			save_entries = merge(training_info, (modelname = modelname,
												 seed = seed,
												 dataset = "MVTec-AD_$category",
												 category = category,
												 encoder=encoding_name,
												 encoder_params=encoder_params,
												 model_index=mi,
												 criterion=criterion,
												 contamination=contamination))
			# now loop over all anomaly score funs
			for result in results
				GenerativeAD.experiment(result..., data, savepath; save_entries...)
			end
			global try_counter = max_tries + 1
		else
			@info "Model already present, sampling new hyperparameters..."
			global try_counter += 1
		end
	end
end
(try_counter == max_tries) ? (@info "Reached $(max_tries) tries, giving up.") : nothing


text:
module Examples

using ShowGraphviz: @derive, @deriveall, @dot_str

const hello_world = dot"digraph G {Hello->World}"

# https://graphviz.org/Gallery/directed/cluster.html
const cluster = dot"""
digraph G {

	subgraph cluster_0 {
		style=filled;
		color=lightgrey;
		node [style=filled,color=white];
		a0 -> a1 -> a2 -> a3;
		label = "process #1";
	}

	subgraph cluster_1 {
		node [style=filled];
		b0 -> b1 -> b2 -> b3;
		label = "process #2";
		color=blue
	}
	start -> a0;
	start -> b0;
	a1 -> b3;
	b2 -> a3;
	a3 -> a0;
	a3 -> end;
	b3 -> end;

	start [shape=Mdiamond];
	end [shape=Msquare];
}
"""

abstract type AbstractHelloWorld end
struct HelloWorldSVG <: AbstractHelloWorld end
struct HelloWorldAll <: AbstractHelloWorld end

Base.show(io::IO, m::MIME"text/vnd.graphviz", ::AbstractHelloWorld) =
    show(io, m, hello_world)

@derive HelloWorldSVG "image/svg+xml"
@deriveall HelloWorldAll

end  # module


text:
module InfiniteLinearAlgebra
using BlockArrays, BlockBandedMatrices, BandedMatrices, LazyArrays, LazyBandedMatrices,
        FillArrays, InfiniteArrays, MatrixFactorizations, LinearAlgebra

import Base: +, -, *, /, \, ^, OneTo, getindex, promote_op, _unsafe_getindex, print_matrix_row, size, axes,
            AbstractMatrix, AbstractArray, Matrix, Array, Vector, AbstractVector, Slice,
            show, getproperty
import Base.Broadcast: BroadcastStyle, Broadcasted

import ArrayLayouts: colsupport, rowsupport, triangularlayout, MatLdivVec, triangulardata, TriangularLayout, sublayout
import BandedMatrices: BandedMatrix, _BandedMatrix, AbstractBandedMatrix, bandeddata, bandwidths, BandedColumns, bandedcolumns,
                        _default_banded_broadcast
import FillArrays: AbstractFill, getindex_value
import InfiniteArrays: OneToInf, InfUnitRange, Infinity, InfStepRange, AbstractInfUnitRange
import LinearAlgebra: lmul!,  ldiv!, matprod, qr, AbstractTriangular, AbstractQ, adjoint, transpose
import LazyArrays: applybroadcaststyle, CachedArray, CachedMatrix, CachedVector, DenseColumnMajor, FillLayout, ApplyMatrix, check_mul_axes, ApplyStyle, LazyArrayApplyStyle, LazyArrayStyle,
                    CachedMatrix, CachedArray, resizedata!, MemoryLayout, mulapplystyle, LmulStyle, RmulStyle,
                    factorize, sub_materialize, LazyLayout, LazyArrayStyle,
                    @lazymul, applylayout, ApplyLayout, PaddedLayout, materialize!
import MatrixFactorizations: ql, ql!, QLPackedQ, getL, getR, reflector!, reflectorApply!, QL, QR, QRPackedQ

import BlockArrays: BlockSizes, cumulsizes, _find_block, AbstractBlockVecOrMat, sizes_from_blocks

import BandedMatrices: BandedMatrix, bandwidths, AbstractBandedLayout, _banded_qr!, _banded_qr, _BandedMatrix

import BlockBandedMatrices: _BlockSkylineMatrix, _BandedMatrix, AbstractBlockSizes, cumulsizes, _BlockSkylineMatrix, BlockSizes, blockstart, blockstride,
        BlockSkylineSizes, BlockSkylineMatrix, BlockBandedMatrix, _BlockBandedMatrix, BlockTridiagonal

LazyArrays.@lazymul BandedMatrix{<:Any,<:Any,<:OneToInf}

# BroadcastStyle(::Type{<:BandedMatrix{<:Any,<:Any,<:OneToInf}}) = LazyArrayStyle{2}()

function ^(A::BandedMatrix{T,<:Any,<:OneToInf}, p::Integer) where T
    if p < 0
        inv(A)^(-p)
    elseif p == 0
        Eye{T}(∞)
    elseif p == 1
        copy(A)
    else
        A*A^(p-1)
    end
end

if VERSION < v"1.2-"
    import Base: has_offset_axes
    require_one_based_indexing(A...) = !has_offset_axes(A...) || throw(ArgumentError("offset arrays are not supported but got an array with index other than 1"))
else
    import Base: require_one_based_indexing
end

export Vcat, Fill, ql, ql!, ∞, ContinuousSpectrumError, BlockTridiagonal

include("banded/hessenbergq.jl")

include("banded/infbanded.jl")
include("blockbanded/infblocktridiagonal.jl")
include("banded/infqltoeplitz.jl")
include("infql.jl")
include("infqr.jl")

###
# temporary work arounds
###

# Fix ∞ BandedMatrix
ApplyStyle(::typeof(*), ::Type{<:Diagonal}, ::Type{<:BandedMatrix{<:Any,<:Any,<:OneToInf}}) =
    LmulStyle()
ApplyStyle(::typeof(*), ::Type{<:BandedMatrix{<:Any,<:Any,<:OneToInf}}, ::Type{<:Diagonal}) =
    RmulStyle()
ApplyStyle(::typeof(*), ::Type{<:BandedMatrix{<:Any,<:Any,<:OneToInf}}, ::Type{<:BandedMatrix{<:Any,<:Any,<:OneToInf}}) =
    LazyArrayApplyStyle()
ApplyStyle(::typeof(*), ::Type{<:AbstractArray}, ::Type{<:BandedMatrix{<:Any,<:Any,<:OneToInf}}) =
    LazyArrayApplyStyle()
ApplyStyle(::typeof(*), ::Type{<:BandedMatrix{<:Any,<:Any,<:OneToInf}}, ::Type{<:AbstractArray}) =
    LazyArrayApplyStyle()
ApplyStyle(::typeof(*), ::Type{<:Adjoint{<:Any,<:BandedMatrix{<:Any,<:Any,<:OneToInf}}}, ::Type{<:AbstractArray}) =
    LazyArrayApplyStyle()
ApplyStyle(::typeof(*), ::Type{<:Transpose{<:Any,<:BandedMatrix{<:Any,<:Any,<:OneToInf}}}, ::Type{<:AbstractArray}) =
    LazyArrayApplyStyle()
end # module


text:
using QuDirac

# This file is an example of a discrete-time quantum random walk
# implemented using QuDirac.

# First, we define the Hadamard operator `H`, defined as
#
# H | 0 ⟩ = 1/√2 * ( | 0 ⟩ + | 1 ⟩ )
# H | 1 ⟩ = 1/√2 * ( | 0 ⟩ - | 1 ⟩ )
#
@rep_op " H | n > = 1/√2 * ( | 0 > + (-1)^n * | 1 > )" 0:1

# If an operation on a state only alters basis labels, not coefficients,
# it can be simpler and more efficient to use `maplabels` than to construct
# a whole new operator.
#
# In this case, we make a function `shift_ket`
# that maps over the basis labels of the input Ket such that:
#
# shift_ket(| 0, j ⟩) -> | 0, j - 1 ⟩
# shift_ket(| 1, j ⟩) -> | 1, j + 1 ⟩
#
function shift_map(label::StateLabel)
    if label[1] == 0
        return StateLabel(0, label[2] - 1)
    else
        return StateLabel(1, label[2] + 1)
    end
end

shift_ket(kt::Ket) = maplabels(shift_map, kt)

function walk_nsteps(steps)
    steps += 1

    # Allocate space for the results
    results = Array(Ket{KroneckerDelta, 2, Float64}, steps);

    # Initial state
    results[1] = d" 1.0 * | 0,0 > "

    # Calculate the each step by referring to the previous step
    for i=2:steps
        results[i] = shift_ket(act_on(H, results[i-1], 1))
    end

    return results
end

println("""
This example provides the `walk_nsteps` function, which takes in the
number of steps to walk and returns an array containing the result of
each step. The initial state is | 0,0 ⟩.""")


text:
@testset "Architecture Spaces" begin
    import NaiveNASflux: weights

    @testset "BasicLayerSpace" begin
        import NaiveGAflux: outsize, activation
        rng = SeqRng()
        space = BaseLayerSpace([1,2,3], [relu,σ,identity])
        @test outsize(space, rng) == 1
        @test activation(space, rng) == σ
        @test outsize(space, rng) == 3
        @test activation(space, rng) == relu
    end

    @testset "SingletonParSpace" begin
        @test SingletonParSpace(666)() == 666
        for d in 2:4
            @test SingletonParSpace(1:d...)() == Tuple(1:d)
        end
        @test Singleton2DParSpace(7)() == (7,7)
    end

    @testset "ParSpace" begin
        rng = SeqRng()
        space = ParSpace(1:3)
        @test [space(rng) for _ in 1:4]== [1,2,3,1]

        rng.ind = 0
        space = ParSpace2D(2:4)
        @test space(rng) == (2, 3)
        @test space(rng) == (4, 2)

        rng.ind = 0
        space = ParSpace(1:4, 5:7, 8:9)
        @test space(rng) == (1, 6, 8)
        @test space(rng) == (2, 7, 9)
    end

    @testset "NamedLayerSpace" begin
        rng = SeqRng()
        s1 = DenseSpace(2, identity)
        s2 = NamedLayerSpace("test", s1)

        @test name(s1) == ""
        @test name(s2) == "test"

        l1 = s1(3, rng)
        l2 = s2(3, rng)

        @test l1.σ == l2.σ
        @test size(weights(l1)) == size(weights(l2))

        l1 = s1(3, rng, outsize = 4)
        l2 = s2(3, rng, outsize = 4)
        @test size(weights(l1)) == size(weights(l2))
    end

    @testset "LoggingLayerSpace" begin
        rng = SeqRng()
        s1 = DenseSpace(2, identity)
        s2 = LoggingLayerSpace(NamedLayerSpace("test", s1))

        @test name(s2) == "test"

        l1 = s1(3, rng)
        l2 = (@test_logs (:debug, "Create Dense(3, 2) from test") min_level=Logging.Debug s2(3,rng))

        @test l1.σ == l2.σ
        @test size(weights(l1)) == size(weights(l2))

        l1 = s1(3, rng, outsize = 4)
        l2 = (@test_logs s2(3,rng, outsize = 4))

        @test size(weights(l1)) == size(weights(l2))
    end

    @testset "DenseSpace" begin
        rng = SeqRng()
        space = DenseSpace(3, σ)
        l = space(2, rng)
        @test l.σ == σ
        @test size(weights(l)) == (3,2)
        l = space(3, rng,outsize=2)
        @test l.σ == σ
        @test size(weights(l)) == (2,3)
    end

    @testset "ConvSpace" begin
        rng = SeqRng()
        space = ConvSpace{2}(outsizes=5, activations=relu, kernelsizes=2:5)
        l = space(4, rng)
        @test size(weights(l)) == (2,3,4,5)
        @test size(l(ones(Float32, 5,5,4,1))) == (5,5,5,1)

        rng.ind = 0
        space = ConvSpace{1}(outsizes=4, activations=elu, kernelsizes=2:5)
        l = space(3, rng)
        @test size(weights(l)) == (2,3,4)
        @test size(l(ones(Float32, 5,3,1))) == (5,4,1)

        l = space(4, rng, outsize=3)
        @test size(weights(l)) == (3,4,3)
        @test size(l(ones(Float32, 5,4,1))) == (5,3,1)
    end

    @testset "BatchNormSpace" begin
        space = BatchNormSpace(relu)
        @test space(2).λ == relu
        @test space(3).λ == relu

        rng = SeqRng()
        space = BatchNormSpace(relu,elu,identity)
        @test space(2,rng).λ == relu
        @test space(3,rng).λ == elu
        @test space(4,rng).λ == identity

        rng = SeqRng()
        space = BatchNormSpace([relu,elu,identity])
        @test space(2,rng).λ == relu
        @test space(3,rng).λ == elu
        @test space(4,rng).λ == identity
    end

    @testset "PoolSpace" begin
        rng = SeqRng()
        space = PoolSpace{1}(windowsizes=1:3, strides=1, poolfuns=MeanPool)
        @test space(2, rng).k == (1,)
        @test space(2, rng).k == (2,)
        @test space(2, rng).k == (3,)
        @test space(2, rng) isa MeanPool{1}

        space = PoolSpace{2}(windowsizes=1:3, strides=(2,3), poolfuns=MaxPool)
        @test space(2, rng).k == (2,3)
        @test space(2, rng).k == (1,2)
        @test space(2) isa MaxPool{2}
        @test space(2).stride == (2,3)
    end

    @testset "VertexSpace" begin
        space = VertexSpace(DenseSpace(3,relu))
        inpt = inputvertex("in", 2)
        v = space(inpt)
        @test nin(v) == [2]
        @test nout(v) == 3

        v = space("v", inpt)
        @test name(v) == "v"

        space = VertexSpace(NamedLayerSpace("dense", DenseSpace(3,relu)))
        v = space("v", inpt)
        @test name(v) == "v.dense"
    end

    @testset "LoggingArchSpace" begin
        space = LoggingArchSpace(VertexSpace(NamedLayerSpace("dense", DenseSpace(3, identity))))
        inpt = inputvertex("in", 2)

        v = (@test_logs (:debug, "Created test.dense") min_level=Logging.Debug space("test", inpt))
        @test nin(v) == [2]
        @test nout(v) == 3

        v = (@test_logs space(inpt))
        @test nin(v) == [2]
        @test nout(v) == 3
    end

    @testset "NoOpArchSpace" begin
        inpt = inputvertex("in", 4)
        @test NoOpArchSpace()(inpt) === inpt
    end

    @testset "ArchSpace" begin
        inpt = inputvertex("in", 2)

        @test ArchSpace(NoOpArchSpace())(inpt) === inpt

        @testset "Singleton Dense" begin
            bs = BaseLayerSpace(3, elu)
            space = ArchSpace(DenseSpace(bs))

            v = space(inpt)
            @test nin(v) == [2]
            @test nout(v) == 3

            v = space(inpt, outsize = 4)
            @test nin(v) == [2]
            @test nout(v) == 4

            v = space("v", inpt, outsize = 4)
            @test name(v) == "v"
            @test nin(v) == [2]
            @test nout(v) == 4
        end

        @testset "Conv BN Pool" begin
            rng = SeqRng()
            space = ArchSpace(ConvSpace{2}(outsizes=3, kernelsizes=2:5), BatchNormSpace(relu), PoolSpace{2}(windowsizes=2))

            v = space("conv", inpt, rng)
            @test layer(v) isa Flux.Conv
            @test nin(v) == [2]
            @test nout(v) == 3
            @test name(v) == "conv"

            rng.ind = 1
            v = space("bn", inpt, rng)
            @test layer(v) isa BatchNorm
            @test nin(v) == [2]
            @test nout(v) == 2
            @test name(v) == "bn"
        end
    end

    @testset "ConditionalArchSpace" begin
        s1 = ArchSpace(DenseSpace(1, identity))
        pred = v -> nout(v) > 2

        v1 = inputvertex("in", 3)
        @test layer(ConditionalArchSpace(pred, s1)(v1)) isa Dense

        v2 = inputvertex("in", 1)
        @test ConditionalArchSpace(pred, s1)(v2) === v2

        s2 = ArchSpace(ConvSpace{2}(outsizes=1, kernelsizes=1))
        @test layer(ConditionalArchSpace(pred, s1,s2)(v1)) isa Dense
        @test layer(ConditionalArchSpace(pred, s1,s2)(v2)) isa Conv
    end

    @testset "RepeatArchSpace" begin
        space = RepeatArchSpace(VertexSpace(BatchNormSpace(relu)), 3)
        inpt = inputvertex("in", 3)
        v = space(inpt)
        @test nvertices(CompGraph(inpt, v)) == 4

        v = space("test", inpt)
        @test name.(ancestors(v)) == ["in", "test.1", "test.2", "test.3"]

        space = RepeatArchSpace(VertexSpace(BatchNormSpace(relu)), [2,5])
        rng = SeqRng()
        v = space(inpt, rng)
        @test nvertices(CompGraph(inpt, v)) == 3

        v = space(inpt, rng)
        @test nvertices(CompGraph(inpt, v)) == 6

        space = RepeatArchSpace(VertexSpace(DenseSpace(3, relu)), 2)
        v = space(inpt, outsize=4)
        @test nout(v) == 4
        @test nin(v) == [4]

        v = space("test", inpt, outsize=4)
        @test name.(ancestors(v)) == ["in", "test.1", "test.2"]
        @test nout(v) == 4
        @test nin(v) == [4]

        space = RepeatArchSpace(VertexSpace(BatchNormSpace(relu)), 0)
        @test space(inpt) == inpt
    end

    @testset "ArchSpaceChain" begin
        space = ArchSpaceChain(VertexSpace.(DenseSpace.((2,3), relu))...)
        inpt = inputvertex("in", 3)

        v = space(inpt)
        @test nvertices(CompGraph(inpt, v)) == 3
        @test nout(v) == 3
        @test nin(v) == [2]

        v = space("v", inpt)
        @test name.(ancestors(v)) == ["in", "v.1", "v.2"]
        @test nvertices(CompGraph(inpt, v)) == 3
        @test nout(v) == 3
        @test nin(v) == [2]

        v = space(inpt, outsize=4)
        @test nvertices(CompGraph(inpt, v)) == 3
        @test nout(v) == 4
        @test nin(v) == [4]

        v = space("v", inpt, outsize=4)
        @test name.(ancestors(v)) == ["in", "v.1", "v.2"]
        @test nvertices(CompGraph(inpt, v)) == 3
        @test nout(v) == 4
        @test nin(v) == [4]
    end

    @testset "ForkArchSpace" begin
        # No concatenation when only one path is rolled
        space = ForkArchSpace(VertexSpace(BatchNormSpace(relu)), 1)
        inpt = denseinputvertex("in", 3)
        v = space(inpt)
        @test inputs(v) == [inpt]

        space = ForkArchSpace(VertexSpace(BatchNormSpace(relu)), 3)
        v = space(inpt)
        @test length(inputs(v)) == 3

        v = space("test", inpt)
        @test name.(ancestors(v)) == ["in", "test.path1", "test.path2", "test.path3", "test.cat"]

        space = ForkArchSpace(VertexSpace(BatchNormSpace(relu)), [2,5])
        rng = SeqRng()

        v = space(inpt, rng)
        @test length(inputs(v)) == 2

        v = space(inpt, rng)
        @test length(inputs(v)) == 5

        space = ForkArchSpace(VertexSpace(DenseSpace(3, relu)), 3)
        v = space(inpt, outsize=13)
        @test nout(v) == 13
        @test nin(v) == [4, 4, 5]

        v = space("v", inpt, outsize=13)
        @test name(v) == "v.cat"
        @test nout(v) == 13
        @test nin(v) == [4, 4, 5]

        # Edge case: Smaller outsize than number of paths
        v = space(inpt, outsize=2)
        @test nout(v) == 2
        @test nin(v) == [1, 1]

        v = space("v", inpt, outsize=2)
        @test nout(v) == 2
        @test nin(v) == [1, 1]

        space = ForkArchSpace(VertexSpace(DenseSpace(3, relu)), 0)
        @test space(inpt) == inpt
    end

    @testset "ResidualArchSpace" begin
        space = ResidualArchSpace(DenseSpace(3, relu))
        inpt = inputvertex("in", 4)

        v = space(inpt)
        @test nin(v) == [4, 4]
        @test nout(v) == 4
        @test layer(inputs(v)[2]) isa Dense

        v = space("v", inpt)
        @test name.(ancestors(v)) == ["in", "v.res", "v.add"]
        @test nin(v) == [4, 4]
        @test nout(v) == 4
        @test layer(inputs(v)[2]) isa Dense
    end

    @testset "FunctionSpace" begin
        space = FunctionSpace(x -> 2 .* x; namesuff=".fun")
        inpt = inputvertex("in", 3)

        v = space(inpt)
        @test nin(v) == [3]
        @test nout(v) == 3
        @test v([1 2 3]) == [2 4 6]

        v = space("v", inpt)
        @test name(v) == "v.fun"
        @test nin(v) == [3]
        @test nout(v) == 3
        @test v([1 2 3]) == [2 4 6]

        space = GlobalPoolSpace()
        v = space("v", inpt)

        @test size(v(ones(Float32, 3,4,5,6))) == (5,6)
    end

    @testset "WeightInit" begin

        @testset "DenseSpace" begin
            space = DenseSpace(3, identity)
            indata = reshape(1:2*4, :, 2)
            insize = size(indata, 1)

            @testset "IdentityWeightInit" begin
                v = space(insize, outsize=insize, wi=IdentityWeightInit())
                @test v(indata) == indata
            end

            @testset "ZeroWeightInit" begin
                v = space(insize, wi=ZeroWeightInit())
                @test v(indata) == zeros(nout(v), size(indata,2))
            end
        end

        @testset "ConvSpace 2D" begin
            space = ConvSpace{2}(outsizes=3, kernelsizes=3)
            indata = Float32.(reshape(1:2*4*5*6,4,5,6,2))
            insize = size(indata, 3)

            @testset "IdentityWeightInit" begin
                v = space(insize, outsize=insize, wi=IdentityWeightInit())
                @test v(indata) == indata
            end

            @testset "ZeroWeightInit" begin
                v = space(insize, wi=ZeroWeightInit())
                @test v(indata) == zeros(size(indata,1), size(indata,2), nout(v), size(indata,4))
            end
        end

        function test_identity_dense(space, inpt = inputvertex("in", 3))
            v = space(inpt, outsize=nout(inpt), wi=IdentityWeightInit())
            g = CompGraph(inpt, v)

            indata = reshape(1:2*nout(inpt), :, 2)
            @test g(indata) == indata
        end

        function test_identity_conv(space, inpt = inputvertex("in", 3))
            v = space(inpt, outsize=nout(inpt), wi=IdentityWeightInit())
            g = CompGraph(inpt, v)

            indata = Float32.(reshape(1:nout(inpt)*4*5, 5,4,nout(inpt), 1))
            @test g(indata) == indata
        end

        @testset "RepeatArchSpace identity" begin
            test_identity_dense(RepeatArchSpace(VertexSpace(DenseSpace(3, identity)), 3))
        end

        @testset "ArchSpaceChain identity" begin
            test_identity_dense(ArchSpaceChain(VertexSpace.(DenseSpace.((2,3), relu))...))
        end

        conv2dspace(os, ks) = ConvSpace{2}(outsizes=os, kernelsizes=ks)

        @testset "ForkArchSpace identity $npaths paths" for npaths in (1, 2, 3)
            test_identity_dense(ForkArchSpace(VertexSpace(DenseSpace(3, identity)), npaths), inputvertex("in", npaths*2+1))
            test_identity_conv(ForkArchSpace(VertexSpace(conv2dspace(3, 3)), npaths), inputvertex("in", npaths*2+1))
        end

        @testset "ForkArchSpace RepeatArchSpace identity $nreps repetitions" for nreps in (1,2,3)
            test_identity_dense(ForkArchSpace(RepeatArchSpace(VertexSpace(DenseSpace(3, identity)), nreps), 3), inputvertex("in", 3*2+1))
            test_identity_conv(ForkArchSpace(RepeatArchSpace(VertexSpace(conv2dspace(3, 3)), nreps), 3), inputvertex("in", 3*2+1))
        end

        @testset "ForkArchSpace ArchSpaceChain identity $sizes sizes" for sizes in ((3,), (2,3), (2,3,4))
            test_identity_dense(ForkArchSpace(ArchSpaceChain(VertexSpace.(DenseSpace.(sizes, identity))...), 3), inputvertex("in", 3*2+1))
            test_identity_conv(ForkArchSpace(ArchSpaceChain(VertexSpace.((PoolSpace{2}(windowsizes=1), conv2dspace.(sizes, 3)...))...), 3), inputvertex("in", 3*2+1))
        end

        @testset "ResidualArchSpace identity" begin
            test_identity_dense(ResidualArchSpace(DenseSpace(3, identity)))
            test_identity_conv(ResidualArchSpace(conv2dspace(3, 3)))
        end

        @testset "ResidualArchSpace ForkArchSpace identity $npaths paths" for npaths in (1,2,3)
            test_identity_dense(ResidualArchSpace(ForkArchSpace(VertexSpace(DenseSpace(3, identity)), npaths)))
            test_identity_conv(ResidualArchSpace(ForkArchSpace(VertexSpace(conv2dspace(3, 3)), npaths)))
        end

        @testset "ForkArchSpace ResidualArchSpace identity" begin
            # ID mapping only possible with one path
            test_identity_dense(ForkArchSpace(ResidualArchSpace(VertexSpace(DenseSpace(3, identity))), 1))
            test_identity_conv(ForkArchSpace(ResidualArchSpace(VertexSpace(conv2dspace(3, 3))), 1))
        end

    end

end


text:
function place_order_command(k, v, id_str, config, open_orders, closed_orders, bot_path, client, usr, fees)
    @info("test")
    sleep(2)
    t = try Pinguu.examine_order(closed_orders[id_str], id_str, client, config, bot_path)
    catch
        open(joinpath(bot_path, "trigger.json"), "w") do f
            JSON.print(f, Dict(), 4)
        end
        @info("examine_order failed")
        return nothing
    end
    qty = floor(t["use_vol"], digits=config["precision"])
    price = Pinguu.price2string(round((abs(t["current_profit"]) / qty *
        (1 + fees["maker"] +
            parse(Float64, config["take_profit"])/100)
            * t["price_correction"]), digits=config["sell_precision"]), config["sell_precision"])

    account = client.get_account()["balances"];
    new = 0
    for bal in account
        if bal["asset"] == config["farm_coin"]
            if parse(Float64, bal["free"]) <= qty
                new = parse(Float64, bal["free"])
            end
        end
    end
    if qty > new && new != 0
        reference = qty * parse(Float64, price)
        qty = floor(new, digits=config["precision"])
        price = Pinguu.price2string(round(reference / qty, digits=config["sell_precision"]), config["sell_precision"])
    end
    @info("Try to place sell")
    @info("Qty  = $qty")
    @info("Price = " * price)

    order = try client.order_limit_sell(
        symbol=config["symbol"],
        quantity=qty,
        price=price);
        catch
        nothing
    end
    if order !== nothing
        order["time"] = string(now())
        open_orders["SELL"][k] = order
        @info("Success")
    else
        v["fail"] = 1
        @info("Failed.. Placing another trigger")
    end
    open(joinpath(bot_path, "open_orders.json"), "w") do f
        JSON.print(f, open_orders, 4)
    end
    open(joinpath(bot_path, "trigger.json"), "w") do f
        JSON.print(f, Dict(), 4)
    end
end
export place_order_command


text:
"""
    ReTest.load(testpath::AbstractString;
                parentmodule::Module=Main, [revise::Bool])

Include file `testpath` into `parentmodule`. If `revise` is `true`, `Revise`,
which must be loaded beforehand in your Julia session, is used to track all
recursively included files (in particular testsets). The `revise` keyword
defaults to `true` when `Revise` is loaded and `VERSION >= v"1.5"`, and to
`false` otherwise.

The point of using this function is when `revise` is `true` and in particular
when files are included recursively.
If `revise` is false, this is equivalent to `parentmodule.include(testpath)`,
and if there are no recursively included files, this should be equivalent
to `Revise.includet(testpath)`, provided `parentmodule == Main` and
all `@testset`s defined in `testpath` are in a module defining
 `__revise_mode__ = :eval`.

!!! compat "Julia 1.5"
    This function requires at least Julia 1.5 when `revise` is `true`.
"""
function load(testpath::AbstractString;
              parentmodule::Module=Main, revise::Maybe{Bool}=nothing)

    revise === true && VERSION < v"1.5" &&
        error("the `revise` keyword requires at least Julia 1.5")
    Revise = get_revise(revise)

    if Revise === nothing
        Base.include(parentmodule, testpath)
    else
        files = Dict{String,Module}(testpath => parentmodule)
        substitute!(x) = substitute_retest!(x, false, nothing, files; ishijack=false)
        res = Base.include(substitute!, parentmodule, testpath)
        revise_track(Revise, files)
        res
    end
end

"""
    ReTest.load(Mod::Module, testfile::AbstractString="ModTests.jl";
                parentmodule::Module=Main, [revise::Bool])

Given a package `Mod`, include into `parentmodule`
the corresponding tests from file `testfile`, which is assumed to be
located in the "test" directory of the package.
It is expected that a unique new test module is created within `parentmodule`
after the inclusion, which is then returned.
Otherwise, the list of all newly created test modules is returned, triggering
a warning if it's empty.

If `revise` is `true`, `Revise`, which must be loaded beforehand in your Julia
session, is used to track the test files (in particular testsets). Note that
this might be brittle, and it's recommended instead to load your test module
via `using ModTests`. The `revise` keyword defaults to `true` when `Revise` is
loaded and `VERSION >= v"1.5"`, and to `false` otherwise.

!!! compat "Julia 1.5"
    This function requires at least Julia 1.5 when `revise` is `true`.
"""
function load(packagemod::Module, testfile::Maybe{AbstractString}=nothing;
              parentmodule::Module=Main, revise::Maybe{Bool}=nothing,
              maybe::Bool=false)

    newly_loaded = Module[]
    packagepath = pathof(packagemod)
    if packagepath === nothing
        maybe ? (return newly_loaded) : error("$packagemod is not a package")
    end
    default_testfile = string(packagemod, "Tests.jl")
    testfile = something(testfile, default_testfile)
    testpath = joinpath(dirname(dirname(packagepath)), "test", testfile)
    if !isfile(testpath)
        maybe ? (return newly_loaded) : error("file $testpath does not exist")
    end

    old_loaded = copy(update_TESTED_MODULES!())
    load(testpath; parentmodule=parentmodule, revise=revise)
    newly_loadedpars = parentmodules.(setdiff(update_TESTED_MODULES!(), old_loaded))
    for lpars in newly_loadedpars
        idx = findlast(==(parentmodule), lpars)
        if idx === nothing
            @warn "test module $(first(lpars)) was defined but is not a (recursive) submodule of $parentmodule"
        elseif idx == 1
            @warn "testsets were added directly into module $parentmodule"
        else
            root = lpars[idx-1]
            root ∈ newly_loaded || push!(newly_loaded, root)
        end
    end
    if testfile == default_testfile
        loaded_testmodules[packagemod] = newly_loaded
    end
    if !maybe && length(newly_loaded) == 1
        newly_loaded[1]
    else
        isempty(newly_loaded) &&
            @warn "test file $testpath loaded but it did not define any test module within $parentmodule"
        newly_loaded
    end
end

const loaded_testmodules = Dict{Module,Vector{Module}}()

"""
    ReTest.hijack(source, [modname];
                  parentmodule::Module=Main, lazy=false, [revise::Bool],
                  [include::Symbol], include_functions=[:include])

Given test files defined in `source` using the `Test` package, try to load
them by replacing `Test` with `ReTest`, wrapping them in a module `modname`
defined within `parentmodule`. If successful, the newly created module
`modname` is returned and `modname.runtests()` should be callable.

If `source::AbstractString`, then it's interpreted as the top level test file
(possibly including other files), and `modname` defaults to a name based
on `basename(source)`.

If `source::Module`, then it's interpreted as the name of a package, and the
"test/runtests.jl" file from this package is loaded. In this case, `modname`
defaults to `Symbol(source, :Tests)`.

The current procedure is as follows:
1. replace toplevel `using Test` occurrences by `using ReTest` (`using` can
   have multiple arguments);
2. apply recursively these two rules:
   * for all `include`d files, provided the `include` statement is at the toplevel,
     or nested within these toplevel constructs:
     `begin`, `let`, `for`, `while`, `if`, `try`;
   * on the content of all included modules.

When `source` is `Base` or a standard library module, a slightly different
mechanism is used to find test files (which can contain e.g. non-toplevel
`include`s), i.e. `ReTest.hijack_base` is used underneath.

#### `lazy` keyword

The `lazy` keyword specifies whether some toplevel expressions should be skipped:
* `false` means nothing is skipped;
* `true` means toplevel `@test*` macros are removed, as well as those defined
  within these toplevel (but possible nested) blocks:
  `begin`, `let`, `for`, `while`, `if`, `try`;
* `:brutal` means toplevel `@test*` macros are removed, as well as toplevel
  `begin`, `let`, `for` or `if` blocks.

#### `include` keyword

The `include` keyword can help to handle the case where `@testset`s contain
`include` expressions, like in the following example:
```julia
@testset "parent" begin
    @test true
    include("file_with_other_testsets.jl")
end
```

This works well with `Test` because testsets are run immediately, as well as
testsets contained in the included files, which are also recognized as children
of the testset which include them. With `ReTest`, the `include` expressions
would be evaluated only when the parent testsets are run, so that included
testsets are not run themselves, but only "declared".

If the `include` keyword is set to `:static`, `include(...)` expressions are
evaluated when `@testset` expressions containing them are parsed, before
filtering and before testsets are run. Testsets which are declared (within the
same module) as a side effect of `include(...)` are then inserted in place of
the call to `include(...)`.

If the `include` keyword is set to `:outline`, `hijack` inspects topelevel
`@testset` expressions and puts toplevel `include(...)` expressions outside of
the containing testset, and should therefore be evaluated immediately. This is
not ideal, but at least allows `ReTest` to know about all the testsets right
after the call to `hijack`, and to not declare new testsets when parent
testsets are run.

The `:outline` option might be deprecated in the future, and `include=:static`
should generally be preferred. One case where `:outline` might work better is
when the included file defines a submodule: `ReTest` doesn't have the concept
of a nested testset belonging to a different module than the parent testset,
so the best that can be done here is to "outline" such nested testsets; with
`include=:outline`, `hijack` will "process" the content of such submodules
(replace `using Test` by `using ReTest`, etc.), whereas with
`include=:static`, the subdmodules will get defined after `hijack` has
returned (on the first call to `retest` thereafter), so won't be "processed".

#### `include_functions` keyword

When the `include=:static` keyword argument is passed, it's possible to
tell `hijack` to apply the same treatment to other functions than
`include`, by passing a list a symbols to `include_functions`.
For example, if you defined a custom function `custom_include(x)`
which itself calls out to `include`, you can pass
`include_functions=[:custom_include]` to `hijack`.

#### `revise` keyword

The `revise` keyword specifies whether `Revise` should be used to track
the test files (in particular the testsets). If `true`, `Revise` must
be loaded beforehand in your Julia session. Note that this might be brittle
and not work in all cases. `revise` defaults to `true` when `Revise` is loaded,
and to `false` otherwise.

!!! compat "Julia 1.5"
    This function requires at least Julia 1.5.
"""
function hijack end

# TODO 0.4: remove `testset` kwarg
# TODO: maybe deprecate `include=:outline`?

function hijack(path::AbstractString, modname=nothing; parentmodule::Module=Main,
                lazy=false, revise::Maybe{Bool}=nothing,
                include::Maybe{Symbol}=nothing, testset::Bool=false,
                include_functions=[:include])

    # do first, to error early if necessary
    Revise = get_revise(revise)

    if modname === nothing
        modname = replace(splitext(basename(path))[1], ['-', '.'] => '_')
    end
    modname = Symbol(modname)

    newmod = @eval parentmodule module $modname end
    populate_mod!(newmod, path; lazy=lazy, include=setinclude(include, testset),
                  include_functions=include_functions,
                  Revise=Revise)
    newmod
end

function setinclude(include, testset)
    if testset
        include === nothing || error("cannot specify both `testset` and `include` arguments")
        :outline
    else
        include === nothing || include === :static || include === :outline ||
            error("`include` keyword only accepts `:static` or `:outline` as value")
        include
    end
end

# this is just a work-around for v"1.5", where @__MODULE__ can't be used in
# expressions; root_module[] is set equal to @__MODULE__ within modules
const root_module = Ref{Symbol}()

__init__() = root_module[] = gensym("MODULE")

function populate_mod!(mod::Module, path; lazy, Revise, include::Maybe{Symbol}=nothing,
                       include_functions)
    lazy ∈ (true, false, :brutal) ||
        throw(ArgumentError("the `lazy` keyword must be `true`, `false` or `:brutal`"))

    files = Revise === nothing ? nothing : Dict(path => mod)
    substitute!(x) = substitute_retest!(x, lazy, include, files;
                                        include_functions=include_functions)

    @eval mod begin
        using ReTest # for files which don't have `using Test`
        const $(root_module[]) = $mod
        include($substitute!, $path)
        if !@isdefined __revise_mode__
            __revise_mode__ = :eval
        end
    end

    if Revise !== nothing
        revise_track(Revise, files)
    end
end

function revise_track(Revise, files)
    # uniquemod serves in v1.5 to make hijack w/ revise still work in many cases,
    # when there aren't nested submodules/includes
    for (filepath, mod) in files
        if isfile(filepath) # some files might not exist when they are conditionally
                            # included
            Revise.track(mod, filepath)
        end
    end
end

function hijack(packagemod::Module, modname=nothing; parentmodule::Module=Main,
                lazy=false, revise::Maybe{Bool}=nothing,
                include::Maybe{Symbol}=nothing, testset::Bool=false,
                include_functions=[:include])
    packagepath = pathof(packagemod)
    packagepath === nothing && packagemod !== Base &&
        throw(ArgumentError("$packagemod is not a package"))

    if modname === nothing
        modname = Symbol(packagemod, :Tests)
    end

    if packagemod === Base
        hijack_base(:_Base_tests,
                    base=modname, parentmodule=parentmodule, lazy=lazy, revise=revise)
    elseif startswith(packagepath, Sys.STDLIB) # packagemod is an STDLIB
        hijack_base(string(packagemod), modname,
                    parentmodule=parentmodule, lazy=lazy, revise=revise)
    else
        path = joinpath(dirname(dirname(packagepath)), "test", "runtests.jl")
        hijack(path, modname, parentmodule=parentmodule,
               lazy=lazy, testset=testset, include=include, revise=revise,
               include_functions=include_functions)
    end
end

function substitute_retest!(ex, lazy, include_::Maybe{Symbol}, files=nothing;
                            ishijack::Bool=true, include_functions::Vector{Symbol}=[:include])
    substitute!(x) = substitute_retest!(x, lazy, include_, files, ishijack=ishijack,
                                        include_functions=include_functions)

    if Meta.isexpr(ex, :using)
        ishijack || return ex
        for used in ex.args
            if Meta.isexpr(used, :., 1) && used.args[1] == :ReTest
                throw(ArgumentError("ReTest is already used"))
            elseif Meta.isexpr(used, :., 1) && used.args[1] == :Test
                used.args[1] = :ReTest
            end
        end
    elseif Meta.isexpr(ex, :call) && ex.args[1] == :include
        if length(ex.args) > 2
            throw(ArgumentError("cannot handle include with two arguments"))
        else
            if files !== nothing
                newfile = ex.args[2]
                ex2 =
                    :(let newfile = $_include_dependency($newfile)
                          haskey($files, newfile) &&
                              error("file belong to multiple modules, currently not supported")
                          include($substitute!, $newfile)
                          $files[newfile] = $(root_module[])
                      end)
                if VERSION >= v"1.6"
                    # v1.5 doesn't play well with @__MODULE__, the let expression
                    # simply... vanishes; so we have to use root_module instead
                    push!(ex2.args[2].args, :(@assert $(root_module[]) == @__MODULE__))
                end
                # TODO: add `copy!(::Expr, ::Expr)` to Base
                ex.head = ex2.head
                copy!(ex.args, ex2.args)
            else
                insert!(ex.args, 2, substitute!)
            end
        end
    elseif Meta.isexpr(ex, :module)
        body = ex.args[3]
        @assert Meta.isexpr(body, :block)
        substitute!.(body.args)
        insert!(body.args, 2, :(const $(root_module[]) = $(ex.args[2])))
        # ^^^ we insert between two LineNumberNode, not sure if this is the way: 1st one
        # seems to relate to the `module` line, while the 2nd relates to next expression
        push!(body.args, :(if !@isdefined __revise_mode__
                               __revise_mode__ = :eval
                           end))
    elseif Meta.isexpr(ex, :macrocall)
        ishijack || return ex
        if lazy != false && ex.args[1] ∈ TEST_MACROS
            empty_expr!(ex)
        elseif include_ !== nothing && ex.args[1] == Symbol("@testset")
            if include_ === :outline
                # we remove `include` expressions and put them out of the `@testset`
                body = ex.args[end]
                if body.head == :for
                    body = body.args[end]
                end
                includes = splice!(body.args,
                                   findall(body.args) do x
                                       Meta.isexpr(x, :call) && x.args[1] ∈ include_functions
                                   end)
                map!(substitute!, includes, includes)
                ex.head = :block
                newts = Expr(:macrocall, ex.args...)
                push!(empty!(ex.args), newts, includes...)
            elseif include_ == :static
                pos = ex.args[2] isa LineNumberNode ? 3 : 2
                insert!(ex.args, pos, :(static_include=true))
                if !isempty(include_functions)
                    # enabled only for :static currently, would need to change ex.args
                    # to newts.args in order to make it work for :outline
                    ifn_expr = Expr(:vect)
                    for ifn in include_functions
                        push!(ifn_expr.args, QuoteNode(ifn))
                    end
                    insert!(ex.args, length(ex.args)-1, :(include_functions=$ifn_expr))
                end
            else
                @assert false
            end
        end
    elseif ex isa Expr && ex.head ∈ (:block, :let, :for, :while, :if, :try)
        if lazy == :brutal
            empty_expr!(ex)
        else
            beg = ex.head ∈ (:block, :try) ? 1 : 2
            for x in ex.args[beg:end]
                substitute!(x)
            end
        end
    end
    ex
end

function empty_expr!(ex)
    ex.head = :block
    empty!(ex.args)
    ex
end

# from Base, but without touching _track_dependencies
# this allows to get the absolute path from within included files,
# and to update the list of tracked files
# - bare abspath won't work directly, as it's based on CWD
# - @__DIR__ won't work as it will refer to this file if used bare,
#   and if constructed via `Expr(:macrocall, ...)`, a LineNumberNode
#   is required to be passed, which defeats the purpose
function _include_dependency(_path::AbstractString)
    prev = Base.source_path(nothing)
    if prev === nothing
        abspath(_path)
    else
        normpath(joinpath(dirname(prev), _path))
    end
end

const TEST_MACROS = Symbol.(["@test", "@test_throws", "@test_broken", "@test_skip",
                             "@test_warn", "@test_nowarn", "@test_logs",
                             "@test_deprecated", "@inferred"])

"""
    hijack_base(tests, [modname];
                parentmodule::Module=Main, lazy=false, [revise::Bool])

Similar to `ReTest.hijack`, but specifically for `Base` and stdlib tests.
`tests` speficies which test files should be loaded, in the exact same format
as `Base.runtests` (i.e. it uses the same `choosetests` function to
select the tests).

Tests corresponding to a "test/[somedir/]sometest.jl" file are loaded in the
`BaseTests.[somedir.]sometest` module (if `sometest` is defined in `Base`,
then `sometest_` is used instead).

Tests corresponding to a standard library `Lib` are loaded in the
`StdLibTests.Lib_` module. When there are "testgroups", submodules
are created accordingly.

If `modname` is specified (experimental), this will be the name of the module
in which testsets are defined; passing `modname` is allowed only when all
the loaded tests would otherwise be defined in the same second top-most
module, the one under `BaseTests` or `StdLibTests` (e.g. `somedir` if any,
or `sometest` otherwise, or `Lib_`). This unique module is then named `modname`,
and not enclosed within `BaseTests` or `StdLibTests`.

The `lazy` and `revise` keywords have the same meaning as in [`ReTest.hijack`](@ref).
Depending on the value of `lazy`, some test files are skipped when they
are known to fail.

!!! compat "Julia 1.5"
    This function requires at least Julia 1.5.
"""
function hijack_base(tests, modname=nothing; parentmodule::Module=Main, lazy=false,
                     base=:BaseTests, stdlib=:StdLibTests, revise::Maybe{Bool}=nothing)

    Revise = get_revise(revise)
    if isa(tests, AbstractString)
        tests = split(tests)
    end

    tests, = ChooseTests.call_choosetests(tests) # TODO: handle other return values?
    allcomponents = (components -> Symbol.(components)).(split.(tests, '/'))

    if modname !== nothing
        modname = Symbol(modname)
        allequal(components[1] for components in allcomponents) ||
            throw(ArgumentError("can't specify `modname` for multiple test roots"))
        # if modname was passed, it seems nicer to have it fresh, otherwise it might
        # contain left-overs from previous incantations (and potentially lead to
        # a series of "WARNING: replacing module submodule_i")
        @eval parentmodule module $modname end
    end

    for (test, components) in zip(tests, allcomponents)
        if test ∈ ChooseTests.BLACKLIST ||
            lazy == true && test ∈ ChooseTests.BLACKLIST_SOFT ||
            lazy == :brutal && test ∈ ChooseTests.BLACKLIST_BRUTAL
            @warn "skipping \"$test\" test (incompatible with ReTest)"
            continue
        end
        if test ∈ ["show"] && !isdefined(Main, :Distributed)
            @eval Main using Distributed
        end

        if modname === nothing
            if string(components[1]) in ChooseTests.STDLIBS
                # it's an stdlib Lib, make toplevel modules StdLibTests/Lib_
                components[1] = Symbol(components[1], :_)
                pushfirst!(components, Symbol(stdlib))
            else
                # it's a Base test, use BaseTests as toplevel module
                pushfirst!(components, Symbol(base))
            end
        else
            components[1] = modname
        end

        mod = parentmodule
        for (ith, comp) in enumerate(components)
            if isdefined(Base, comp) || comp ∈ ChooseTests.EPONYM_TESTS
                # e.g. `tuple`, collision betwen the tuple function and test/tuple.jl
                comp = Symbol(comp, :_)
            end
            if isdefined(mod, comp) && ith != length(components) ||
                    modname !== nothing && ith == 1 # module already freshly created
                mod = getfield(mod, comp)
            else
                # we always re-eval leaf-modules
                mod = @eval mod module $comp end
            end
        end

        @eval mod begin
            using Random
        end
        populate_mod!(mod, ChooseTests.test_path(test), lazy=lazy, Revise=Revise)
    end
end

get_revise(revise) =
    if revise === true || revise === nothing && VERSION >= v"1.5"
        Revise = get(Base.loaded_modules, revise_pkgid(), nothing)
        Revise === nothing && revise === true &&
            error("Revise is not loaded")
        Revise
    end

module ChooseTests
# choosetests.jl requires the Sockets package, which is why it's a ReTest dependency

const BASETESTPATH = joinpath(Sys.BINDIR, "..", "share", "julia", "test")

# we include "choosetests.jl" on the fly, because the computation of the
# STDLIBS constant in this file currently doubles the load time of ReTest
# (quite negligible though, takes about 0.005s)

function call_choosetests(choices)
    isdefined(ChooseTests, :STDLIBS) ||
        include(joinpath(BASETESTPATH, "choosetests.jl"))

    if choices === :_Base_tests
        # we compute choices lazily, as in recent Julia versions, TESTNAMES is defined
        # globally in choosetests.jl, and therefore defined only after the include above
        choices = filter(x -> x != "stdlib", TESTNAMES)
    end
    Base.invokelatest(choosetests, choices)
end

# adapted from julia/tests/runtests.jl
function test_path(test)
    t = split(test, '/')

    if t[1] in STDLIBS
        if length(t) == 2
            return joinpath(STDLIB_DIR, t[1], "test", "$(t[2]).jl")
        else
            return joinpath(STDLIB_DIR, t[1], "test", "runtests.jl")
        end
    else
        return joinpath(BASETESTPATH, "$test.jl")
    end
end

if VERSION < v"1.8.0-DEV.34"
    const TESTNAMES = [
        "subarray", "core", "compiler", "worlds",
        "keywordargs", "numbers", "subtype",
        "char", "strings", "triplequote", "unicode", "intrinsics",
        "dict", "hashing", "iobuffer", "staged", "offsetarray",
        "arrayops", "tuple", "reduce", "reducedim", "abstractarray",
        "intfuncs", "simdloop", "vecelement", "rational",
        "bitarray", "copy", "math", "fastmath", "functional", "iterators",
        "operators", "ordering", "path", "ccall", "parse", "loading", "gmp",
        "sorting", "spawn", "backtrace", "exceptions",
        "file", "read", "version", "namedtuple",
        "mpfr", "broadcast", "complex",
        "floatapprox", "stdlib", "reflection", "regex", "float16",
        "combinatorics", "sysinfo", "env", "rounding", "ranges", "mod2pi",
        "euler", "show", "client",
        "errorshow", "sets", "goto", "llvmcall", "llvmcall2", "ryu",
        "some", "meta", "stacktraces", "docs",
        "misc", "threads", "stress", "binaryplatforms", "atexit",
        "enums", "cmdlineargs", "int", "interpreter",
        "checked", "bitset", "floatfuncs", "precompile",
        "boundscheck", "error", "ambiguous", "cartesian", "osutils",
        "channels", "iostream", "secretbuffer", "specificity",
        "reinterpretarray", "syntax", "corelogging", "missing", "asyncmap",
        "smallarrayshrink", "opaque_closure"
    ]
end

const BLACKLIST = [
    # failing at load time (in hijack_base)
    "backtrace", "misc", "threads", "cmdlineargs","boundscheck",
    "SharedArrays", # problem with workers (should be sortable out)
    "Test",
    # failing at runtime (in retest)
    "precompile", # no toplevel testset, just one with interpolated subject
]

const BLACKLIST_BRUTAL = split("core worlds bitarray file reflection errorshow asyncmap
                                opaque_closure") # llvmcall: doesn't work if loaded twice

const BLACKLIST_SOFT = split("core worlds offsetarray spawn file errorshow")

# file names which define a global variable of the same name as the file
const EPONYM_TESTS = [:worlds, :file]

end # ChooseTests

max_issues_repo_name: rfourquet/InlineTest

max_forks_repo_name: rfourquet/InlineTest