text:
module LibAaron

"""
forward methods on a struct to an attribute of that struct
good for your composition.
syntax: `@forward CompositeType.attr Base.iterate Base.length :*`
Symbol literals automatically become Base.:symbol. Good for adding
methods to built-in operators.
"""
macro forward(structfield, functions...)
    structname = structfield.args[1]
    field = structfield.args[2].value
    block = quote end
    for f in functions
        # case for operator symbols
        if f isa QuoteNode
            f = :(Base.$(f.value))
            def1 = :($f(x::$structname, y) = $f(x.$field, y))
            def2 = :($f(x, y::$structname) = $f(x, y.$field))
            push!(block.args, def1, def2)
        # normal case
        else
            def = :(
                $f(x::$structname, args...; kwargs...) = $f(x.$field, args...; kwargs...)
            )
            push!(block.args, def)
        end
    end
    esc(block)
end

"""
Check if you're running as a script. Normally used with `@__FILE__` as the
argument. Usage:

    isscript(@__FILE__)
"""
isscript(__FILE__) = abspath(PROGRAM_FILE) == @__FILE__

"""
    update_env(source_file, command)

Many programming languages (including but not limited to Python) provide
scripts which modif the shell's environment for deveopment purposes.
Such modifications may include modifying `\$PATH` and many other tweaks.

Because these scripts are generally meant for execution in a shell, it
can be difficult to use them inside a program. `update_env` works
around this executing the appropriate commands in a `bash` shell, then
running `env` from that shell, and parsing the output into the
environment of the running Julia program.

- `source_file`: should be the file that contains the defintions to be
  made available to the shell. In the case of a Python virtualenv, it
  would be something like `venv/bin/activate`. Use an empty string,
  `""`, if no file is to be sourced. This is for cases like ocaml, where
  the command is something like `eval \$(opam env)`. In the case of
  `conda`, it may be a file which is normally sourced in .bashrc,
  .bash_profile or similar.
- `command`: the command to run once the file is sourced (probably a
  shell function defined therein). This may also be an empty string if
  no command is required.

Note that the `command` argument may be a `Cmd` instance or an instance
of `AbstractString`. If an `AbstractString` is given, the command will be
handed directly to the shell to exectute and could create an injection
vulnerability if input is not validated. Using a `Cmd` instance will
properly escape the command, but will make certain things impossible;
e.g. `eval \$(opam env)` will not work because it relies on shell
operators. Also note that operator shared between Julia strings and
the shell, like `\$` or `\$()` must be properly escaped in order to reach
the shell--with `raw""` or backslashes.
"""
function update_env(source_file::AbstractString, command::AbstractString)
    source_file = Base.shell_escape(source_file)
    script = if source_file == ""
        """
        $command
        env --null
        """
    else
        """
        source $source_file
        $command
        env --null
        """
    end
    proc = open(`sh`, write=true, read=true)
    reader = @async split(read(proc, String), '\0')
    close(proc)

    foreach(fetch(reader)) do line
        if '=' in line
            (key, value) = split(line, "="; limit=2)
            ENV[key] = value
        end
    end
end

# safe version
update_env(source_file::AbstractString, command::Cmd) =
    let command = join(Base.shell_escape.(command.exec), " ")
        update_env(source_file, command)
    end

# flatten things. Probably not as fast as the one in the standard
# library, but more flexible.
struct Flatten
    iterable
    noflatten::Type
    dictfunc::Function

    Flatten(it, nf; dictfunc=nothing) = new(
        it, Union{Number,AbstractChar,nf}, dictfunc == nothing ? d->d : dictfunc
    )
end
flatten(it, nf::Type=AbstractString; kwargs...) = Flatten(it, nf; kwargs...)

function Base.iterate(f::Flatten, stack)
    while length(stack) > 0
        @inbounds node = stack[end]
        if isempty(node)
            pop!(stack)
            continue
        end
        next = popfirst!(node)
        if next isa f.noflatten
            return next, stack
        else
            try
                push!(stack, Iterators.Stateful(
                    next isa AbstractDict ? f.dictfunc(next) : next
                ))
            catch e
                e isa MethodError && return next, stack
                rethrow(e)
            end
        end
    end
    nothing
end

Base.iterate(f::Flatten) =
    iterate(f, Iterators.Stateful[Iterators.Stateful(f.iterable)])

# use a process as a filter
function procwrite!(proc, str::Union{AbstractVector{UInt8}, AbstractString})
    write(proc, str)
    close(proc.in)
end

function procwrite!(proc, lines)
    for line in lines
        write(proc, line, '\n')
    end
    close(proc.in)
end

function openfilter(fn::Function, cmd::Base.AbstractCmd, input)
    proc = open(cmd, read=true, write=true)
    writer = @async procwrite!(proc, input)
    reader = @async fn(proc)
    try
        wait(writer)
        return fetch(reader)
    finally
        close(proc)
    end
end

function openfilter(cmd::Base.AbstractCmd, input)
    proc = open(cmd, read=true, write=true)
    writer = @async procwrite!(proc, input)
    proc
end

# I wanted a uri escape function. The one in URIParser was weird, and
# the one in GLib is much faster anyway.
getlib(start) = filter(split.(readlines(`ldconfig -p`))) do fields
    startswith(fields[1], start)
end[1][1]

function geturiescape()
    glib::String = getlib("libglib-2.0")
    return function(uri, allowed_chars=C_NULL; allow_utf8=false)
        cstr = ccall(
            (:g_uri_escape_string, glib),
            Cstring,
            (Cstring, Cstring, Cint),
            uri, allowed_chars, allow_utf8
        )
        out = unsafe_string(cstr)
        ccall(:free, Cvoid, (Cstring,), cstr)
        out
    end
end

# how are hard links missing from the Julia standard library?
function hardlink(oldpath::AbstractString, newpath::AbstractString)
    err = ccall(:link, Cint, (Cstring, Cstring), oldpath, newpath)
    systemerror("linking $oldpath -> $newpath", err != 0)
    newpath
end

# and fifos?
function mkfifo(pathname::AbstractString, mode=0o644)
    err = ccall(:mkfifo, Cint, (Cstring, Cuint), pathname, mode)
    systemerror("couldn't make fifo, $(repr(pathname))", err != 0)
    pathname
end

struct ExportName
    name::Symbol
    isconst::Bool
end
geteq(sym::Symbol) = ExportName(sym, false)
geteq(expr::Expr) =
    expr.head == :call ? ExportName(expr.args[1], true) : nothing

function getexports(expr, acc=[])
    if Meta.isexpr(expr, :block)
        foreach((e)->getexports(e, acc), expr.args)
    elseif Meta.isexpr(expr, :(=))
        push!(geteq(expr.args[1]))
    elseif Meta.isexpr(expr, :function)
        push!(ExportName(expr.args[1].args[1], true))
    elseif Meta.isexpr(expr, :module)
        push!(ExportName(expr.args[2], true))
    elseif Meta.isexpr(expr, :struct)
        push!(ExportName(expr.args[2], true))
    elseif Meta.isexpr(expr, :const)
        push!(ExportName(getexport(expr.args[1]).name, true))
    end
    return acc
end

mkassignment(mod, name, isconst) =
    isconst ? :(const $name = $mod.$name) : :($name = $mod.$name)

function use_this(mod, expr; noconst=false)
    dummyname = gensym(:DummyModule)
    exports = getexports(expr)
    exprs = Meta.isexpr(expr, :block) ? expr.args : [expr]
    assign = if noconst
        e->mkassignment(dummyname, e.name, false)
    else
        e->mkassignment(dummyname, e.name, e.isconst)
    end
    exported = map(assign, filter(!isnothing, exports))
    usemod = :(using $mod)
    outmod = quote
        module $dummyname
        $usemod
        $(exprs...)
        end
    end

    return quote
        @eval $(outmod.args[2])
        $(exported...)
    end
end

macro use(mod, expr)
    esc(use_this(mod, expr))
end

macro use_local(mod, expr)
    esc(use_this(mod, expr; noconst=true))
end

end # LibAaron module


text:
module Blosc2
include("Lib/lib.jl")
include("common/common.jl")
include("compression/compression.jl")
include("superchunks/superchunks.jl")
include("init.jl")
export Compressor, available_compressors, available_compressors_names, has_compressor, max_compression_overhead
export compressor_by_name, default_compressor_name, default_compressor
export CompressionParams, DecompressionParams, Context, CompressionContext, DecompressionContext
export compress!, compress, unsafe_compress!, decompress!, decompress, unsafe_decompress!, decompress_items!
export sizes, uncompressed_sizeof, uncompressed_length, compressed_sizeof, max_compressed_size, make_compress_buffer
export filter_pipeline, has_filter, available_filter_names, filter_description, max_filters_count
export Storage, SChunk
export clevel, typesize, chunksize, blocksize, nchunks, nbytes, cbytes
export unsafe_append_buffer!, unsafe_decompress_chunk, unsafe_append_chunk!, unsafe_update_chunk!, unsafe_insert_chunk!, unsafe_get_chunk
export delete_chunk!
end # module

ext: jl


text:
include("normcol_lessequal.jl")
include("diagadd!.jl")

function add_sub!(aMat::Matrix{Float64}, bMat::Matrix{Float64}, cMat::Matrix{Float64})
   # aMat <- aMat + bMat - cMat
    Dim = size(aMat)
    for j=1:Dim[2], i=1:Dim[1]
        @inbounds aMat[i,j] += bMat[i,j] - cMat[i,j]
    end
end

function updateD!(D::Array{Any,1}, A::Array{Any,1}, DataMat::Array{Any,1})
   # Update D by Eq. (12)
    for (i, Aᵢ) in enumerate(A)
        @inbounds TempData::Matrix{Float64} = DataMat[i]
        ρ::Float64 = 1.
        rate_ρ::Float64 = 1.2
        @inbounds TempS::Matrix{Float64} = D[i]
        TempT::Matrix{Float64} = zeros(TempS)
        @inbounds preD::Matrix{Float64} = D[i]
        Iter::Int = 1
        lossᴰ::Float64 = 1.
        while lossᴰ > 1e-8 && Iter < 100

            tempMat::Matrix{Float64} = TempData*Aᵢ'
            tempMat += (TempS-TempT) .* ρ # tempMat <- tempMat + ρ(TempS - TempT)
            tempMatCoef::Matrix{Float64} = Aᵢ*Aᵢ'
            diagadd!(tempMatCoef, ρ)
            TempD::Matrix{Float64} = tempMat/tempMatCoef

            TempS = normcol_lessequal(TempD+TempT)
            add_sub!(TempT, TempD, TempS) # TemP <- TemP + (TempD-TempS)
            ρ *= rate_ρ
            lossᴰ = mean(abs2(preD-TempD))
            preD = TempD
            Iter += 1
        end
        @inbounds D[i] = preD
    end
end


text:
using FillArrays: Zeros
using LinearAlgebra: Diagonal, Bidiagonal, SymTridiagonal

const Diagonals = Union{Diagonal{T}, Bidiagonal{T}, SymTridiagonal{T}} where T
const BiTriDiagonals = Union{Bidiagonal, SymTridiagonal}

_main_diagonal(D::Diagonal) = D.diag
_main_diagonal(M::Bidiagonal) = M.dv
_main_diagonal(M::SymTridiagonal) = M.dv

superdiagonal(M::Diagonal) = _offdiagonal_Zeros(M, 1)
subdiagonal(M::Diagonal) = _offdiagonal_Zeros(M, 1)

superdiagonal(M::SymTridiagonal) = _super_sub_diagonal_data(M)
subdiagonal(M::SymTridiagonal) = _super_sub_diagonal_data(M)

superdiagonal(M::Bidiagonal) = _superdiagonal(M, Val(M.uplo))
subdiagonal(M::Bidiagonal) = _subdiagonal(M, Val(M.uplo))

_superdiagonal(M::Bidiagonal, ::Val{'U'}) = _super_sub_diagonal_data(M)
_superdiagonal(M::Bidiagonal, ::Val{'L'}) = _offdiagonal_Zeros(M, 1)
_subdiagonal(M::Bidiagonal, ::Val{'L'}) = _super_sub_diagonal_data(M)
_subdiagonal(M::Bidiagonal, ::Val{'U'}) = _offdiagonal_Zeros(M, 1)

_super_sub_diagonal_data(M::BiTriDiagonals) = M.ev

"""
    _offdiagonal_Zeros(M::AbstractMatrix{T}, k)

Return a `Zeros` array representing the `k`th offdiagonal, regardless
of whether the `k`th offdiagonal of `M` is zeros or not.
"""
_offdiagonal_Zeros(::Type{T}, diaglen::Integer, k::Integer) where T = Zeros{T}(max(diaglen - abs(k), 0))
_offdiagonal_Zeros(M::AbstractMatrix{T}, k) where T = _offdiagonal_Zeros(T, size(M, 1), k)

function diagonal(D::Diagonals, k::Integer=0)
    k == 0 && return _main_diagonal(D)
    return offdiagonal(D, k)
end

"""
    offdiagonal(M, k)

`k`th diagonal of `M` for `abs(k) ≥ 2`.
"""
function offdiagonal end

offdiagonal(D::Diagonal, k) = _offdiagonal_Zeros(D, k)
function offdiagonal(D::BiTriDiagonals, k)
    k = 1 && return superdiagonal(D)
    k = -1 && return subdiagonal(D)
    return _offdiagonal_Zeros(D, k)
end


text:
#=
xml_preprocessor:
- Julia version: 1.1.0
- Author: bramb
- Date: 2019-03-21
=#

isopendel(t::XMLToken) = isa(t,XMLStartElement) && t.name == "del"
isclosedel(t::XMLToken) = isa(t,XMLEndElement) && t.name == "del"
isopenadd(t::XMLToken) = isa(t,XMLStartElement) && t.name == "add"
iscloseadd(t::XMLToken) = isa(t,XMLEndElement) && t.name == "add"
ends_subst(t::XMLToken) = isa(t,TextToken) ? !isempty(strip(t.text)) : (isa(t,XMLStartElement) && (t.name != "del" && t.name != "add") || isa(t,XMLEndElement))
is_whitespace(t::XMLToken) = isa(t,TextToken) && isempty(strip(t.text))

@enum SubstState begin
    _normal
    _tentative_subst
    _subst
    _after_del
    _after_add
end

mutable struct SubstContext
    buf::IOBuffer
    state::SubstState
    subst::Bool
    tail::String

    SubstContext() = new(IOBuffer(),_normal,false,"")
end

function add_subst(xml::String)::String
    contexts = []
    push!(contexts,SubstContext())
    tokens = tokenize(strip(xml))
    ti = 1
    max=length(tokens)
    while ti<=max
        t = tokens[ti]
        @debug("$(contexts[1].state) | $(string_value(t))")
        if isopendel(t) && contexts[1].state != _after_del && contexts[1].state != _after_add
            @debug(1," push!")
            pushfirst!(contexts,SubstContext())
            (contexts[1].state != _subst) && (contexts[1].state = _tentative_subst)
            print(contexts[1].buf,string_value(t))

        elseif contexts[1].state == _tentative_subst && isclosedel(t)
            @debug(2)
            print(contexts[1].buf,string_value(t))
            contexts[1].state = _after_del

        elseif contexts[1].state == _after_del
            if ends_subst(t)
                @debug(3.1)
                outbuf = contexts[2].buf
                if contexts[1].subst
                    print(outbuf, "<subst>", String(take!(contexts[1].buf)), "</subst>")
                else
                    print(outbuf, String(take!(contexts[1].buf)))
                end
                ti -= 1
                deleteat!(contexts,1)
                @debug("pop!")
            else
                @debug(3.2)
                if !(isa(t,TextToken) && isempty(strip(t.text))) # ignore whitespace tokens between subst elements
                    print(contexts[1].buf,string_value(t))
                end
                contexts[1].state = _subst
                contexts[1].subst = true
            end

        elseif contexts[1].state == _subst && iscloseadd(t)
            @debug(4)
            print(contexts[1].buf,string_value(t))
            contexts[1].state = _after_add

        elseif contexts[1].state == _after_add
            if ends_subst(t) || isopendel(t)
                @debug(5.1)
                print(contexts[2].buf, "<subst>", String(take!(contexts[1].buf)), "</subst>", contexts[1].tail)
                ti -= 1
                deleteat!(contexts,1)
                @debug("pop!")
            elseif is_whitespace(t)
                @debug(5.2)
                contexts[1].tail = t.text
            elseif isopenadd(t)
                @debug(5.3)
                print(contexts[1].buf,string_value(t))
                contexts[1].state = _subst
            else
                @debug(5.4)
                print(contexts[1].buf,string_value(t))
            end

        elseif contexts[1].state == _subst && ti == max
            @debug(6)
            print(contexts[2].buf, String(take!(contexts[1].buf)), contexts[1].tail)
            ti -= 1
            deleteat!(contexts,1)
            @debug("pop!")

        else
            @debug(7)
            print(contexts[1].buf, string_value(t))
        end
        ti += 1
    end
    return strip(String(take!(contexts[1].buf)))
end


text:
function throw_dim_error(@nospecialize(x), @nospecialize(dim))
    throw(DimensionMismatch("$x does not have dimension corresponding to $dim"))
end

@propagate_inbounds function _promote_shape(a::Tuple{A,Vararg{Any}}, b::Tuple{B,Vararg{Any}}) where {A,B}
    (_try_static(getfield(a, 1), getfield(b, 1)), _promote_shape(tail(a), tail(b))...)
end
_promote_shape(::Tuple{}, ::Tuple{}) = ()
@propagate_inbounds function _promote_shape(::Tuple{}, b::Tuple{B}) where {B}
    (_try_static(static(1), getfield(b, 1)),)
end
@propagate_inbounds function _promote_shape(a::Tuple{A}, ::Tuple{}) where {A}
    (_try_static(static(1), getfield(a, 1)),)
end
@propagate_inbounds function Base.promote_shape(a::Tuple{Vararg{CanonicalInt}}, b::Tuple{Vararg{CanonicalInt}})
    _promote_shape(a, b)
end

#julia> @btime ArrayInterface.is_increasing(ArrayInterface.nstatic(Val(10)))
#  0.045 ns (0 allocations: 0 bytes)
#ArrayInterface.True()
function is_increasing(perm::Tuple{StaticInt{X},StaticInt{Y},Vararg}) where {X, Y}
    if X <= Y
        return is_increasing(tail(perm))
    else
        return False()
    end
end
function is_increasing(perm::Tuple{StaticInt{X},StaticInt{Y}}) where {X, Y}
    if X <= Y
        return True()
    else
        return False()
    end
end
is_increasing(::Tuple{StaticInt{X}}) where {X} = True()

"""
    from_parent_dims(::Type{T}) -> Tuple{Vararg{Union{Int,StaticInt}}}
    from_parent_dims(::Type{T}, dim) -> Union{Int,StaticInt}

Returns the mapping from parent dimensions to child dimensions.
"""
from_parent_dims(x) = from_parent_dims(typeof(x))
from_parent_dims(::Type{T}) where {T} = nstatic(Val(ndims(T)))
from_parent_dims(::Type{T}) where {T<:VecAdjTrans} = (StaticInt(2),)
from_parent_dims(::Type{T}) where {T<:MatAdjTrans} = (StaticInt(2), One())
from_parent_dims(::Type{<:SubArray{T,N,A,I}}) where {T,N,A,I} = _from_sub_dims(I)
@generated function _from_sub_dims(::Type{I}) where {I<:Tuple}
    out = Expr(:tuple)
    dim_i = 1
    for i in 1:length(I.parameters)
        p = I.parameters[i]
        if p <: Integer
            push!(out.args, :(StaticInt(0)))
        else
            push!(out.args, :(StaticInt($dim_i)))
            dim_i += 1
        end
    end
    out
end
from_parent_dims(::Type{<:PermutedDimsArray{T,N,<:Any,I}}) where {T,N,I} = static(Val(I))
function from_parent_dims(::Type{R}) where {T,N,S,A,R<:ReinterpretArray{T,N,S,A}}
    if !_is_reshaped(R) || sizeof(S) === sizeof(T)
        return nstatic(Val(ndims(A)))
    elseif sizeof(S) > sizeof(T)
        return tail(nstatic(Val(ndims(A) + 1)))
    else  # sizeof(S) < sizeof(T)
        return (Zero(), nstatic(Val(N))...)
    end
end

from_parent_dims(x, dim) = from_parent_dims(typeof(x), dim)
Compat.@constprop :aggressive function from_parent_dims(::Type{T}, dim::Int)::Int where {T}
    if dim > ndims(T)
        return static(ndims(parent_type(T)) + dim - ndims(T))
    elseif dim > 0
        return @inbounds(getfield(from_parent_dims(T), dim))
    else
        throw_dim_error(T, dim)
    end
end

function from_parent_dims(::Type{T}, ::StaticInt{dim}) where {T,dim}
    if dim > ndims(T)
        return static(ndims(parent_type(T)) + dim - ndims(T))
    elseif dim > 0
        return @inbounds(getfield(from_parent_dims(T), dim))
    else
        throw_dim_error(T, dim)
    end
end

"""
    to_parent_dims(::Type{T}) -> Tuple{Vararg{Union{Int,StaticInt}}}
    to_parent_dims(::Type{T}, dim) -> Union{Int,StaticInt}

Returns the mapping from child dimensions to parent dimensions.
"""
to_parent_dims(x) = to_parent_dims(typeof(x))
to_parent_dims(::Type{T}) where {T} = nstatic(Val(ndims(T)))
to_parent_dims(::Type{T}) where {T<:Union{Transpose,Adjoint}} = (StaticInt(2), One())
to_parent_dims(::Type{<:PermutedDimsArray{T,N,I}}) where {T,N,I} = static(Val(I))
to_parent_dims(::Type{<:SubArray{T,N,A,I}}) where {T,N,A,I} = _to_sub_dims(I)
@generated function _to_sub_dims(::Type{I}) where {I<:Tuple}
    out = Expr(:tuple)
    n = 1
    for p in I.parameters
        if !(p <: Integer)
            push!(out.args, :(StaticInt($n)))
        end
        n += 1
    end
    out
end
function to_parent_dims(::Type{R}) where {T,N,S,A,R<:ReinterpretArray{T,N,S,A}}
    pdims = nstatic(Val(ndims(A)))
    if !_is_reshaped(R) || sizeof(S) === sizeof(T)
        return pdims
    elseif sizeof(S) > sizeof(T)
        return (Zero(), pdims...,)
    else
        return tail(pdims)
    end
end

to_parent_dims(x, dim) = to_parent_dims(typeof(x), dim)
Compat.@constprop :aggressive function to_parent_dims(::Type{T}, dim::Int)::Int where {T}
    if dim > ndims(T)
        return static(ndims(parent_type(T)) + dim - ndims(T))
    elseif dim > 0
        return @inbounds(getfield(to_parent_dims(T), dim))
    else
        throw_dim_error(T, dim)
    end
end

function to_parent_dims(::Type{T}, ::StaticInt{dim}) where {T,dim}
    if dim > ndims(T)
        return static(ndims(parent_type(T)) + dim - ndims(T))
    elseif dim > 0
        return @inbounds(getfield(to_parent_dims(T), dim))
    else
        throw_dim_error(T, dim)
    end
end

_nunderscore(::Val{N}) where {N} = ntuple(Compat.Returns(:_), Val(N))

"""
    has_dimnames(::Type{T}) -> StaticBool

Returns `static(true)` if `x` has on or more named dimensions. If all dimensions correspond
to `static(:_)`, then `static(false)` is returned.
"""
Compat.@constprop :aggressive has_dimnames(x) = static(_is_named(known_dimnames(x)))
_is_named(x::NTuple{N,Symbol}) where {N} = x !== _nunderscore(Val(N))
_is_named(::Any) = true

"""
    known_dimnames(::Type{T}) -> Tuple{Vararg{Union{Symbol,Missing}}}
    known_dimnames(::Type{T}, dim::Union{Int,StaticInt}) -> Union{Symbol,Missing}

Return the names of the dimensions for `x`. `:_` is used to indicate a dimension does not
have a name.
"""
@inline known_dimnames(x, dim::Integer) = _known_dimname(known_dimnames(x), canonicalize(dim))
known_dimnames(x) = known_dimnames(typeof(x))
known_dimnames(::Type{T}) where {T} = _known_dimnames(T, parent_type(T))
_known_dimnames(::Type{T}, ::Type{T}) where {T} = _unknown_dimnames(Base.IteratorSize(T))
_unknown_dimnames(::Base.HasShape{N}) where {N} = _nunderscore(Val(N))
_unknown_dimnames(::Any) = (:_,)
function _known_dimnames(::Type{C}, ::Type{P}) where {C,P}
    eachop(_inbounds_known_dimname, to_parent_dims(C), known_dimnames(P))
end
@inline function _known_dimname(x::Tuple{Vararg{Any,N}}, dim::CanonicalInt) where {N}
    @boundscheck (dim > N || dim < 1) && return :_
    return @inbounds(x[dim])
end
@inline _inbounds_known_dimname(x, dim) = @inbounds(_known_dimname(x, dim))

"""
    dimnames(x) -> Tuple{Vararg{Union{Symbol,StaticSymbol}}}
    dimnames(x, dim::Union{Int,StaticInt}) -> Union{Symbol,StaticSymbol}

Return the names of the dimensions for `x`. `:_` is used to indicate a dimension does not
have a name.
"""
@inline dimnames(x, dim::Integer) = _dimname(dimnames(x), canonicalize(dim))
@inline dimnames(x) = _dimnames(has_parent(x), x)
@inline function _dimnames(::True, x)
    eachop(_inbounds_dimname, to_parent_dims(x), dimnames(parent(x)))
end
_dimnames(::False, x) = ntuple(_->static(:_), Val(ndims(x)))
@inline function _dimname(x::Tuple{Vararg{Any,N}}, dim::CanonicalInt) where {N}
    @boundscheck (dim > N || dim < 1) && return static(:_)
    return @inbounds(x[dim])
end
@inline _inbounds_dimname(x, dim) = @inbounds(_dimname(x, dim))

"""
    to_dims(x, dim) -> Union{Int,StaticInt}

This returns the dimension(s) of `x` corresponding to `dim`.
"""
to_dims(x, dim::Colon) = dim
to_dims(x, dim::Integer) = canonicalize(dim)
to_dims(x, dim::Union{StaticSymbol,Symbol}) = _to_dim(dimnames(x), dim)
function to_dims(x, dims::Tuple{Vararg{Any,N}}) where {N}
    eachop(_to_dims, nstatic(Val(N)), dimnames(x), dims)
end
@inline _to_dims(x::Tuple, d::Tuple, n::StaticInt{N}) where {N} = _to_dim(x, getfield(d, N))
@inline function _to_dim(x::Tuple, d::Union{Symbol,StaticSymbol})
    i = find_first_eq(d, x)
    i === nothing && throw(DimensionMismatch("dimension name $(d) not found"))
    return i
end

#=
    order_named_inds(names, namedtuple)
    order_named_inds(names, subnames, inds)

Returns the tuple of index values for an array with `names`, when indexed by keywords.
Any dimensions not fixed are given as `:`, to make a slice.
An error is thrown if any keywords are used which do not occur in `nda`'s names.

1. parse into static dimnension names and key words.
2. find each dimnames in key words
3. if missing is found use Colon()
4. if (ndims - ncolon) === nkwargs then all were found, else error
=#
@generated function find_all_dimnames(x::Tuple{Vararg{Any,ND}}, nd::Tuple{Vararg{Any,NI}}, inds::Tuple, default) where {ND,NI}
    if NI === 0
        return :(())
    else
        out = Expr(:block, Expr(:(=), :names_found, 0))
        t = Expr(:tuple)
        for i in 1:ND
            index_i = Symbol(:index_, i)
            val_i = Symbol(:val_, i)
            push!(t.args, val_i)
            push!(out.args, quote
                $index_i = find_first_eq(getfield(x, $i), nd)
                if $index_i === nothing
                    $val_i = default
                else
                    $val_i = @inbounds(inds[$index_i])
                    names_found += 1
                end
            end)
        end
        return quote
            $out
            @boundscheck names_found === $NI || error("Not all keywords matched dimension names.")
            return $t
        end
    end
end


text:
module AMDGPUnative

using LLVM, LLVM.Interop
using GPUCompiler
using HSARuntime, HSARuntime.HSA
using Adapt
using Libdl
using Requires

@enum DeviceRuntime HSA_rt OCL_rt
const RUNTIME = Ref{DeviceRuntime}(HSA_rt)
#=
if get(ENV, "AMDGPUNATIVE_OPENCL", "") != ""
    RUNTIME[] = OCL_rt
end
=#
include("runtime.jl")

const configured = HSARuntime.configured

# ROCm-Device-Libs bitcode path
include(joinpath(@__DIR__, "..", "deps", "deps.jl"))
const device_libs_path = joinpath(@__DIR__, "..", "deps", "usr", "lib")

struct Adaptor end

# Device sources must load _before_ the compiler infrastructure
# because of generated functions.
include(joinpath("device", "tools.jl"))
include(joinpath("device", "pointer.jl"))
include(joinpath("device", "array.jl"))
include(joinpath("device", "gcn.jl"))
include(joinpath("device", "runtime.jl"))
include(joinpath("device", "llvm.jl"))
include(joinpath("device", "globals.jl"))

include("compiler.jl")
include("execution_utils.jl")
include("execution.jl")
include("reflection.jl")

function __init__()
    try
        # Try to load deps if possible
        check_deps()
    catch err
        @warn """
        AMDGPUnative dependencies have not been built, some functionality may be missing.
        Please run Pkg.build("AMDGPUnative") and reload AMDGPUnative.
        """
    end
    @require OpenCL="08131aa3-fb12-5dee-8b74-c09406e224a2" include("opencl.jl")
end

end # module


text:
using OrdinaryDiffEq, ModelingToolkit, Test, LinearAlgebra
@parameters t
@variables y[1:3](t)
@parameters k[1:3]
D = Differential(t)

eqs = [D(y[1]) ~ -k[1] * y[1] + k[3] * y[2] * y[3],
    D(y[2]) ~ k[1] * y[1] - k[3] * y[2] * y[3] - k[2] * y[2]^2,
    0 ~ y[1] + y[2] + y[3] - 1]

@named sys = ODESystem(eqs, t, y, k)
@test_throws ArgumentError ODESystem(eqs, y[1])
M = calculate_massmatrix(sys)
@test M == [1 0 0
            0 1 0
            0 0 0]

f = ODEFunction(sys)
prob_mm = ODEProblem(f, [1.0, 0.0, 0.0], (0.0, 1e5), (0.04, 3e7, 1e4))
sol = solve(prob_mm, Rodas5(), reltol = 1e-8, abstol = 1e-8)

function rober(du, u, p, t)
    y₁, y₂, y₃ = u
    k₁, k₂, k₃ = p
    du[1] = -k₁ * y₁ + k₃ * y₂ * y₃
    du[2] = k₁ * y₁ - k₃ * y₂ * y₃ - k₂ * y₂^2
    du[3] = y₁ + y₂ + y₃ - 1
    nothing
end
f = ODEFunction(rober, mass_matrix = M)
prob_mm2 = ODEProblem(f, [1.0, 0.0, 0.0], (0.0, 1e5), (0.04, 3e7, 1e4))
sol2 = solve(prob_mm2, Rodas5(), reltol = 1e-8, abstol = 1e-8, tstops = sol.t,
             adaptive = false)

# MTK expression are canonicalized, so the floating point numbers are slightly
# different
@test Array(sol) ≈ Array(sol2)

# Test mass matrix in the identity case
eqs = [D(y[1]) ~ y[1], D(y[2]) ~ y[2], D(y[3]) ~ y[3]]

@named sys = ODESystem(eqs, t, y, k)

@test calculate_massmatrix(sys) === I


text:
include("Map/Map.jl")
include("Map/Composition.jl")
include("Map/ResidueRingPoly.jl")
include("Map/NumberField.jl")
include("Map/AbGrp.jl")


text:
@testset "Transformer" begin
    import Flux: gpu
    t = Transformer(10, 3, 15, 20) |> gpu
    td = TransformerDecoder(10, 3, 15, 20) |> gpu
    x = cu(randn(10, 7, 3))
    y = cu(randn(10, 6, 3))

    @test size(t(x)) == (10, 7, 3)
    @test size(t(x[:, :, 2])) == (10, 7)

    @test size(td(y, x)) == (10, 6, 3)
    @test size(td(y[:,:,2], x[:,:,2])) == (10, 6)
end


text:
include("../imports.jl")

@testset ExtendedTestSet "`ComposedProjectiveTransform`" begin
    tfms = (Project(Translation(10, 10)), Project(Translation(-10, 10)))
    tfm = ComposedProjectiveTransform(tfms[1], tfms[2])
    item = Image(rand(10, 10))
    ## composition of `AbstractProjective`s creates a `ComposedProjectiveTransform`
    @test tfm == tfms[1] |> tfms[2]
    ## can be `apply`ed
    @test_nowarn apply(tfm, item)

    ## identical result to sequential application
    @test itemdata(apply(tfm, item)) == itemdata(apply(Sequence(tfms), item))
end


text:
# TODO test jldoctests
function genGaussWGrid(aG, mG, AG;
                  xmin=nothing, xmax=nothing, nPts=nothing)
    """
    Calculate sum of Gaussians given amplitudes, means, and covariance matrices.

    Evaluates nGaussian Gaussian functions on a grid, returns their sum.
    The grid models space with nPts discretization points along nDims dimensions.
    LaTeX pseudocode:

       sum_i aG_i * exp( - (x-mG_i)' * AG_i * (x-mG_i)).

    Arguments nGauss and nDims are not declared explicitely, but calculated from
    means vector mG, see below.

    # Arguments
    - `aG::Array{Float64}`: amplitudes of Gaussians, vector of length nGauss
    - `mG::Array{Float64}`: coordinates of Gaussians,
                            matrix of size nDims x nGauss
    - `AG::Array{Float64}`: covariance matrices of Gaussians,
                            tensor of size nDims x nDims x nGauss

    # Keyword Arguments
    - `xmin[=-ones(nDims)]`: lower bound of the discretization box
    - `xmax[= ones(nDims)]`: upper bound of the discretization box
    - `nPts[= 67 .* ones(Int64, nDims)]`: number of discretization points
                                          along each dimension

    # Examples for GenGauss (different handle for this function, cf. below)
    ```jldoctest
    julia> # Generate 3 Gaussians
    julia> aG = ones(3);
    julia> mG = zeros(2,3);
    julia> mG[1,:] = [0.0, 0.7, -0.3];
    julia> mG[2,:] = [0.0, -0.6, -0.06];
    julia> AG = zeros(2,2,3);
    julia> AG[:,:,1] = [100 0.05; 0 100];
    julia> AG[:,:,2] = [100 0.15; 0 100];
    julia> AG[:,:,3] = [100 -0.3; 0.4 100];
    julia>
    julia> g = FPRS.genGauss(aG, mG, AG);
    julia> g[32:35,33:36]
    3×3 Array{Float64,2}:
     0.912746  0.832567  0.632048
     1.00009   0.912317  0.692624
     0.912275  0.832193  0.631775
    julia>
    julia> # Double the resolution
    julia> # Make grid bounds larger if necessary
    julia> xmin = [-1.0 -2.0];
    julia> xmax = [2.0   1.0];
    julia> g = FPRS.genGauss(aG, mG, AG, nPts = [127,127], xmin=xmin, xmax=xmax);
    julia> g[71:73, 59:61]
    3×3 Array{Float64,2}:
     0.862873  0.892834  0.824811
     0.955636  0.988733  0.913326
     0.944926  0.977569  0.902937
    julia>
    julia> # At which x1 coordinate was this Gaussian? Calculate with
    julia> x1 = range(xmin[1], stop=xmax[1], length=127);
    julia> collect(x1[73:75])
    3-element Array{Float64,1}:
     0.7142857142857143
     0.7380952380952381
     0.7619047619047619
    ```
    """
    # Convenience variables
    nDims  = size(mG,1)
    nGauss = size(mG,2)

    # Check input size
    size(aG) == (nGauss,) || throw(DimensionMismatch("size of aG, $(size(aG)), does not equal (size(mG,2),), $((size(mG,2),))"))
    size(AG) == (nDims, nDims, nGauss) || throw(DimensionMismatch("size of AG, $(size(AG)), does not equal (size(mG,1),size(mG,1),size(mG,2)), $((size(mG,1),size(mG,1),(size(mG,2))))"))

    # instantiate keyword args
    xmin == nothing ? xmin = - ones(Float64, nDims) : nothing
    xmax == nothing ? xmax = + ones(Float64, nDims) : nothing
    nPts == nothing ? nPts = 67 .* ones(Int64, nDims) : nothing

    # One-dimensional case
    if nDims == 1
        x1 = range(xmin[1], stop=xmax[1], length=nPts[1]);
        xGrid = (x1); # To return underlying grid in the end
        g = zeros(nPts[1]);

        for iG = 1:nGauss
            g = g + aG[iG] .*
                exp.( - (x1 .- mG[iG]) .^2 * AG[iG] .^2)
        end
    end

    # Two-dimensional case
    if nDims == 2
        x1 = range(xmin[1], stop=xmax[1], length=nPts[1]);
        x2 = range(xmin[2], stop=xmax[2], length=nPts[2]);
        xGrid = (x1, x2); # To return underlying grid in the end
        g = zeros(nPts[1], nPts[2]);

        for iG = 1:nGauss
            for ix2 = 1:nPts[2], ix1 = 1:nPts[1]
                x = [x1[ix1]; x2[ix2]]
                g[ix1,ix2] = g[ix1,ix2] +
                    aG[iG] * exp.(- transpose(x .- mG[:,iG]) *
                                  AG[:,:,iG] * (x .- mG[:,iG]))
            end
        end
    end

    if nDims == 3
        x1 = range(xmin[1], stop=xmax[1], length=nPts[1]);
        x2 = range(xmin[2], stop=xmax[2], length=nPts[2]);
        x3 = range(xmin[3], stop=xmax[3], length=nPts[3]);
        xGrid = (x1, x2, x3); # To return underlying grid in the end
        g = zeros(nPts[1], nPts[2], nPts[3]);

        for iG = 1:nGauss
            for ix3 = 1:nPts[3], ix2 = 1:nPts[2], ix1 = 1:nPts[1]
                x = [x1[ix1]; x2[ix2]; x3[ix3]]
                g[ix1,ix2,ix3] = g[ix1,ix2,ix3] +
                    aG[iG] * exp.(- transpose(x .- mG[:,iG]) *
                                  AG[:,:,iG] * (x .- mG[:,iG]))
            end
        end
    end

    return g, xGrid
end

function genGauss(aG, mG, AG;
                  xmin=nothing, xmax=nothing, nPts=nothing)
    """
    Return only the density of genGaussWGrid (do not return the grid)
    """
    res, ~ = genGaussWGrid(aG, mG, AG; xmin=xmin, xmax=xmax, nPts=nPts)
    return res
end

function genRandGaussWGrid(; nGauss=30,
                          nPts = [67; 67],
                          aGmin = 0.2,
                          aGmax = 2.0,
                          mGrad = 0.6,
                          AGmin = 100,
                          AGmax = 800,
                          randSeed = nothing,
                          suppShape = "ball")
    """
    Evaluate sum of Gaussians with random amplitudes, means, and covariance matrices.

    Generates random amplitudes, means, and covariance matrices, and calls
    genGauss function. Dimension is determined from the size of nPts arguments.

    # Keyword Arguments
    - `nGauss::Int64`: number of Gaussians
    - `nPts::Array{Int64}`: number of discr. pts along each dimension
    - `aGmin::Float64`
    - `aGmax::Float64` :
          amplitudes are uniformely distributed between these values.
    - `mGrad::Float64` :
          means (each coordinate) are  uniformely distributed between
          -mGrad and mGrad, if suppShape = "box"
    - `mGrad::Float64` :
          means are  uniformely distributed in the nDim-dimensional
          ball with radius mGrad, if suppShape = "ball"
    - `AGmin::Float64`
    - `AGmax::Float64` :
          eigenvalues of covariance matrices are uniformely distributed
          between these values. AGmin small --> slowly decaying gaussians
          (try AGmin = 10, AGmax = 15). AGmin large --> fast decaying gaussians
          (try AGmin = 500, AGmax = 1000).
    - `randSeed::Int64` : set random seed.
    - `suppShape::String` : "ball" or "box", see mGrad variable above.

    # Examples
    ```jldoctest
    julia> # Default 2D density with 30 Gaussians
    julia> g = genRandGauss();
    julia> # With specific random seed:
    julia> g = genRandGauss(randSeed = 0);
    julia> # The same with better resolution:
    julia> g = genRandGauss(randSeed = 0, nPts=[512,512]);
    julia> # One-dimensional, 10 Gaussians, smaller support
    julia> FPRS.genRandGauss(nGauss = 10, nPts=[512], AGmin=30, AGmax=45, mGrad=0.5, randSeed=0)
    julia> # 50 Gaussians, three-dimensional, with means in a box and faster decay
    julia> g = FPRS.genRandGauss(nGauss = 50, nPts=[80,80,80], AGmin=100, AGmax=1000, mGrad=0.5, randSeed=0, suppShape="box")
    julia> # E.g., plot after integrating with >>> heatmap(sum(g,dims=3)[:,:,1])
    ```
    """

    if suppShape != "box" && suppShape != "ball"
         throw(ArgumentError("suppShape, $(suppShape), must be either 'box' or 'ball'"))
    end

    # Convenience variables
    nDims = length(nPts)

    if randSeed == nothing
        seedVal = Random.seed!()
    else
        seedVal = Int(randSeed)
        Random.seed!(seedVal)
    end

    aG = (aGmax-aGmin) * rand(nGauss) .+ aGmin

    if nDims == 1
        mG = zeros(1,nGauss);
        mG[1,:] = 2.0 * mGrad * rand(nGauss) .- mGrad
        AG = zeros(1,1,nGauss);
        AG[1,1,:] = (AGmax-AGmin) * rand(nGauss) .+ AGmin
    end

    if nDims == 2
        # Generate means of Gaussians
        if suppShape == "box"
            mG = zeros(2,nGauss)
            mG[1,:] = 2.0 * mGrad * rand(nGauss) .- mGrad
            mG[2,:] = 2.0 * mGrad * rand(nGauss) .- mGrad
        elseif suppShape == "ball"
            mG = mGrad * randBall(2,nGauss)
        end

        # Generate variance matrices of Gaussians
        AG = zeros(2,2,nGauss);
        for iG = 1:nGauss
            # Prepare random rotation matrix (SO(2))
            theta = 2. * pi * rand();
            Omx = [cos(theta) -sin(theta); sin(theta) cos(theta)]
            Dmx = Diagonal((AGmax-AGmin) * rand(2) .+ AGmin)
            Amx = transpose(Omx) * Dmx * Omx
            AG[:,:,iG] = Amx[:,:]
        end
    end

    if nDims == 3
        # Generate means of Gaussians
        if suppShape == "box"
            mG = zeros(3,nGauss)
            mG[1,:] = 2.0 * mGrad * rand(nGauss) .- mGrad
            mG[2,:] = 2.0 * mGrad * rand(nGauss) .- mGrad
            mG[3,:] = 2.0 * mGrad * rand(nGauss) .- mGrad
        elseif suppShape == "ball"
            mG = mGrad * randBall(3,nGauss)
        end

        # Generate variance matrices of Gaussians
        AG = zeros(3,3,nGauss);
        for iG = 1:nGauss
            # Prepare random rotation matrix (SO(2))
            Omx = randRotationMatrix()
            Dmx = Diagonal((AGmax-AGmin) * rand(3) .+ AGmin)
            Amx = transpose(Omx) * Dmx * Omx
            AG[:,:,iG] = Amx[:,:]
        end
    end

    return genGaussWGrid(aG, mG, AG; nPts=nPts)
end

function genRandGauss(; nGauss=30,
                      nPts = [67; 67],
                      aGmin = 0.2,
                      aGmax = 2.0,
                      mGrad = 0.6,
                      AGmin = 100,
                      AGmax = 800,
                      randSeed = nothing,
                      suppShape = "ball")
    res, ~ = genRandGaussWGrid(; nGauss=nGauss,
                              nPts = nPts,
                              aGmin = aGmin,
                              aGmax = aGmax,
                              mGrad = mGrad,
                              AGmin = AGmin,
                              AGmax = AGmax,
                              randSeed = randSeed,
                              suppShape = suppShape)
    return res
end

max_stars_repo_name: tsipenyuk/FPRS

max_issues_repo_name: tsipenyuk/FPRS

max_forks_repo_name: tsipenyuk/FPRS


text:
using Jevo, Test, BenchmarkTools, LinearAlgebra

@testset "Initiating " begin
    @testset "Simple sites" begin

        pop = Jevo.simple_sites(N=4, l=10, n=4)
        Jevo.initiate!(pop, 3)
        # Test population size
        @test sum(pop.freqs) == pop.N
        # Test number of species
        @test length(pop.seqs) == 3
        # Test sequence length of species
        @test length.(pop.seqs) == (ones(Int64, 3) .* pop.l)

        emat = ones(4,4)
        pop = Jevo.simple_sites(N=4, l=10, n=4)
        @test_throws DimensionMismatch Jevo.initiate!(pop, emat)

        emat = ones(4, 10)
        emat[1, :] .-= 1
        pop = Jevo.simple_sites(N=4, l=10, n=4)
        Jevo.initiate!(pop, emat)
        @test pop.seqs[1] == ones(Int, 10)

    end

    @testset "Driver Trailer sites" begin
        @testset "Random sequences" begin

            pop1 = Jevo.driver_trailer(N=4, l=10, n=4, m=4)
            Jevo.initiate!(pop1, 3)
            # Test population size
            @test sum(pop1.freqs) == pop1.N
            # Test number of species
            @test length(pop1.seqs) == 3
            # Test sequence length of species
            @test length.(pop1.seqs) == (ones(Int64, 3) .* pop1.L)
            # Test length of driver
            @test length(pop1.driver) == pop1.L
            #@test_nowarn Jevo.initiate!(pop1, overwrite=true)

        end

        @testset "Optimal Sequence" begin
            pop = Jevo.driver_trailer(N=4, l=10, n=4, m=4)
            emat = ones(4, 3)
            @test_throws DimensionMismatch Jevo.initiate!(pop, emat)

            pop = Jevo.driver_trailer(N=4, l=10, n=4, m=4)
            emat = ones(4, 4)
            emat[1, :] .-= 1
            Jevo.initiate!(pop, emat)
            @test pop.seqs[1] == ones(Int, 10)
            @test length(pop.seqs) == 1

            emat = ones(4, 4) - Matrix{Float64}(I, 4, 4)
            pop = Jevo.driver_trailer_l(N=4, l_0=10, n=4, m=4, L=20)
            Jevo.initiate!(pop, emat)
            @test pop.seqs[1] == pop.driver
            @test length(pop.freqs) == 1
            @test pop.freqs[1] == 4

        end

        @testset "Given Driver" begin

            pop2 = Jevo.driver_trailer(N=4, l=10, n=4, m=4)
            Jevo.initiate!(pop2, 3, driver=[1, 2, 3, 4])
            # Test that partial driver sequence is incorporated
            @test pop2.driver[1:4] == [1, 2, 3, 4]
            pop3 = Jevo.driver_trailer(N=4, L=10, n=4, m=12)
            Jevo.initiate!(pop3, 3, driver=collect(1:12))
            # Test that driver too long is cut short
            @test pop3.driver == collect(1:10)
            # Test warning message
            @test_logs (:warn, "l>L. Choosing L=l.") Jevo.driver_trailer(N=4, l=10, L=2, n=4)

            pop4 = Jevo.driver_trailer(N=4, L=10, n=4, m=4)
            # Test error message for wrong driver sequence
            @test_throws ArgumentError Jevo.initiate!(pop4, 3, driver=collect(1:12))

        end
    end

    @testset "Driver Trailer sites variable length" begin
        @testset "Random Sequences" begin

            pop1 = Jevo.driver_trailer_l(N=4, l_0=10, n=4, m=4, L=20)
            Jevo.initiate!(pop1, 3)
            # Test population size
            @test sum(pop1.freqs) == pop1.N
            # Test number of species
            @test length(pop1.seqs) == 3
            # Test sequence length of species
            @test length.(pop1.seqs) == (ones(Int64, 3) .* pop1.L)
            # Test length of driver
            @test length(pop1.driver) == pop1.L
            # test binding site lengths
            @test length(pop1.l) == 3
            @test pop1.l == ones(Int64, 3) * pop1.l_0

        end

        @testset "Optimal Sequence" begin
            pop = Jevo.driver_trailer(N=4, l=10, n=4, m=4)
            emat = ones(4, 3)
            @test_throws DimensionMismatch Jevo.initiate!(pop, emat)

            emat = ones(4, 4)
            emat[1, :] .-= 1
            pop = Jevo.driver_trailer_l(N=4, l_0=10, n=4, m=4, L=20)
            Jevo.initiate!(pop, emat)
            @test pop.seqs[1] == ones(Int, 20)
            @test length(pop.seqs) == 1

            emat = ones(4, 4) - Matrix{Float64}(I, 4, 4)
            pop = Jevo.driver_trailer_l(N=4, l_0=10, n=4, m=4, L=20)
            Jevo.initiate!(pop, emat)
            @test pop.seqs[1] == pop.driver
            @test length(pop.freqs) == 1
            @test pop.freqs[1] == 4
            @test length(pop.l) == 1
            @test pop.l[1] == 10
        end

        @testset "Given Trailer" begin
            pop2 = Jevo.driver_trailer_l(N=4, l_0=10, n=4, m=4)
            Jevo.initiate!(pop2, 3, driver=[1, 2, 3, 4])
            # Test that partial driver sequence is incorporated
            @test pop2.driver[1:4] == [1, 2, 3, 4]

            pop3 = Jevo.driver_trailer_l(N=4, L=10, n=4, m=12)
            Jevo.initiate!(pop3, 3, driver=collect(1:12))
            # Test that driver too long is cut short
            @test pop3.driver == collect(1:10)
            # Test warning message
            @test_logs (:warn, "l_0>L. Choosing L=l_0.") Jevo.driver_trailer_l(N=4, l_0=10, L=2, n=4)

            pop4 = Jevo.driver_trailer_l(N=4, L=10, n=4, m=4)
            # Test error message for wrong driver sequence
            @test_throws ArgumentError Jevo.initiate!(pop4, 3, driver=collect(1:12))
        end
    end

    @testset "Monomorphic Population" begin

        @testset "Initiate Random" begin
            pop = Jevo.mono_pop(N=10, l=10, n=4, m=4)
            Jevo.initiate!(pop)
            @test length(pop.seqs) == 10
            @test length(pop.driver) == 10
        end

        @testset "Initiate Optimal" begin
            pop = Jevo.driver_trailer(N=4, l=10, n=4, m=4)
            emat = ones(4, 3)
            @test_throws DimensionMismatch Jevo.initiate!(pop, emat)

            emat = ones(4, 4)
            emat[1, :] .-= 1
            pop = Jevo.mono_pop(N=10, l=10, n=4, m=4)
            Jevo.initiate!(pop, emat)
            @test length(pop.seqs) == 10
            @test length(pop.driver) == 10
            @test pop.seqs == ones(Int64, 10)

            emat = ones(4, 4) - Matrix{Float64}(I, 4, 4)
            pop = Jevo.mono_pop(N=10, l=10, n=4, m=4)
            Jevo.initiate!(pop, emat)
            @test length(pop.seqs) == 10
            @test length(pop.driver) == 10
            @test pop.seqs == pop.driver
        end

    end
end

@testset "Mutations" begin
    @testset "Find existing sequences" begin
        pop = Jevo.simple_sites(N=8, l=1, n=4, seqs=[[1], [2], [3], [4]], freqs=[2, 2, 2, 2])
        Jevo.mutation!(pop)
        # Test that mutation to existing species does not add new species
        @test length(pop.seqs) == 4
        @test length(pop.freqs) == 4
    end

    @testset "Add new species" begin
        pop = Jevo.simple_sites(N=2, l=1, n=2)
        Jevo.initiate!(pop, 1)
        Jevo.mutation!(pop)
        # Test that new species is created
        @test length(pop.seqs) == 2
        @test length(pop.freqs) == 2
    end

    @testset "Driver mutation" begin
        pop = Jevo.driver_trailer(N=4, L=10, n=4, m=12)
        Jevo.initiate!(pop, 1, driver=collect(1:12))
        Jevo.mutation!(pop)
        # Test that new species is created
        @test length(pop.seqs) == 2
        @test length(pop.freqs) == 2

        pop2 = Jevo.driver_trailer(N=4, L=10, n=4, m=4)
        Jevo.initiate!(pop2, 3)
        tmp_driver = copy(pop2.driver)
        Jevo.driver_mutation!(pop2)
        # Test that driver sequence is mutated
        @test tmp_driver != pop2.driver
        @test sum(tmp_driver .!= pop2.driver) == 1
    end

    @testset "Length mutation" begin
        pop = Jevo.driver_trailer_l(N=4, L=10, n=4, m=12)
        Jevo.initiate!(pop, 1, driver=collect(1:12))
        Jevo.mutation!(pop)
        # Test that new species is created
        @test length(pop.seqs) == 2
        @test length(pop.freqs) == 2
        @test length(pop.l) == 2

        pop2 = Jevo.driver_trailer_l(N=4, L=10, n=4, m=4)
        Jevo.initiate!(pop2, 3)
        tmp_driver = copy(pop2.driver)
        Jevo.driver_mutation!(pop2)
        # Test that driver sequence is mutated
        @test tmp_driver != pop2.driver
        @test sum(tmp_driver .!= pop2.driver) == 1

        pop3 = Jevo.driver_trailer_l(N=1, L=10, n=4, m=4)
        Jevo.initiate!(pop3, 1)
        Jevo.mutation!(pop3)
        # Test that new species is created
        @test length(pop3.seqs) == 1
        @test length(pop3.freqs) == 1
        @test length(pop3.l) == 1

        pop4 = Jevo.driver_trailer_l(N=1, L=10, n=4, m=4)
        Jevo.initiate!(pop4, 1)
        Jevo.length_mutation!(pop4)
        # Test that new species is created
        @test length(pop4.seqs) == 1
        @test length(pop4.freqs) == 1
        @test length(pop4.l) == 1
    end
end

@testset "Substitutions" begin
    pop = Jevo.driver_trailer(N=4, l=10, n=4, m=4)
    Jevo.initiate!(pop, 2)
    emat = ones(4, 4) .- Matrix{Float64}(I, 4, 4)
    f = Jevo.fermi_fitness(l=10, beta=1, f0=1, fl=0)
    # Test error for too many species
    @test_throws ArgumentError Jevo.bp_substitution!(pop, emat, f)

    pop = Jevo.driver_trailer(N=4, l=10, n=4, m=4)
    Jevo.initiate!(pop, 1)
    temp_seqs = deepcopy(pop.seqs)

    Jevo.bp_substitution!(pop, emat, f)

    @test length(pop.seqs) == 1
    @test length(pop.seqs[1]) == 10

    @test sum(temp_seqs[1] .!= pop.seqs[1]) <= 1

    @testset "Monomorphic Population" begin

    end
end

@testset "Misc" begin
    @testset "Constant Selection Coefficient" begin
    f = Jevo.const_fitness(s=1)
    @test Jevo.fitness(f) == 1
    @test Jevo.fitness(1, f) == 1
    @test Jevo.fitness(1, 1, f) == 1
    end
end


text:
using Turing, Random, Test
using Turing: Utilities

dir = splitdir(splitdir(pathof(Turing))[1])[1]
include(dir*"/test/test_utils/AllUtils.jl")

@testset "io.jl" begin
    @testset "chain save/resume" begin
        Random.seed!(1234)

        alg1 = HMCDA(3000, 1000, 0.65, 0.15)
        alg2 = PG(20, 500)
        alg3 = Gibbs(500, PG(30, 10, :s), HMCDA(1, 500, 0.65, 0.05, :m))

        chn1 = sample(gdemo_default, alg1; save_state=true)
        check_gdemo(chn1)

        chn1_resumed = Turing.Inference.resume(chn1, 1000)
        check_gdemo(chn1_resumed)

        chn1_contd = sample(gdemo_default, alg1; resume_from=chn1)
        check_gdemo(chn1_contd)

        chn1_contd2 = sample(gdemo_default, alg1; resume_from=chn1, reuse_spl_n=1000)
        check_gdemo(chn1_contd2)

        chn2 = sample(gdemo_default, alg2; save_state=true)
        check_gdemo(chn2)

        chn2_contd = sample(gdemo_default, alg2; resume_from=chn2)
        check_gdemo(chn2_contd)

        chn3 = sample(gdemo_default, alg3; save_state=true)
        check_gdemo(chn3)

        chn3_contd = sample(gdemo_default, alg3; resume_from=chn3)
        check_gdemo(chn3_contd)
    end
    @testset "split var string" begin
        var_str = "x"
        sym, inds = Utilities.split_var_str(var_str)
        @test sym == "x"
        @test inds == Vector{String}[]

        var_str = "x[1,1][2,3]"
        sym, inds = Utilities.split_var_str(var_str)
        @test sym == "x"
        @test inds[1] == ["1", "1"]
        @test inds[2] == ["2", "3"]

        var_str = "x[Colon(),1][2,Colon()]"
        sym, inds = Utilities.split_var_str(var_str)
        @test sym == "x"
        @test inds[1] == ["Colon()", "1"]
        @test inds[2] == ["2", "Colon()"]

        var_str = "x[2:3,1][2,1:2]"
        sym, inds = Utilities.split_var_str(var_str)
        @test sym == "x"
        @test inds[1] == ["2:3", "1"]
        @test inds[2] == ["2", "1:2"]

        var_str = "x[2:3,2:3][[1,2],[1,2]]"
        sym, inds = Utilities.split_var_str(var_str)
        @test sym == "x"
        @test inds[1] == ["2:3", "2:3"]
        @test inds[2] == ["[1,2]", "[1,2]"]
    end
end


text:
function plotχ2(hval, cval, χ2, βZQ, βDQ, βDQQ, βQQ)
    χ2min = minimum(vec(χ2))
    ξHmin = hval[argmin(χ2)[1]]
    ξCmin = cval[argmin(χ2)[2]]

    clev = log10.(χ2min .+ [2.3, 6.7])
    plt = plot(framestyle=:box, legend=nothing, xguide="ξH", yguide="ξC", title="$(methyls[resi])", xlims=(-.3, .3), ylims=(-.3, .3))

    plot!(plt, hval,   hval .+ Measurements.value(sqrt(βZQ-(ξCcsa[resi]-ξHcsa[resi])^2)),
        ribbon=0hval .+ Measurements.uncertainty(sqrt(βZQ-(ξCcsa[resi]-ξHcsa[resi])^2)), c=1)
    plot!(plt, hval,   hval .- Measurements.value(sqrt(βZQ-(ξCcsa[resi]-ξHcsa[resi])^2)),
        ribbon=0hval .+ Measurements.uncertainty(sqrt(βZQ-(ξCcsa[resi]-ξHcsa[resi])^2)), c=1)
    plot!(plt, hval,  -hval .+ Measurements.value(sqrt(βDQ-(ξCcsa[resi]+ξHcsa[resi])^2)),
        ribbon=0hval .+ Measurements.uncertainty(sqrt(βDQ-(ξCcsa[resi]+ξHcsa[resi])^2)), c=2)
    plot!(plt, hval,  -hval .- Measurements.value(sqrt(βDQ-(ξCcsa[resi]+ξHcsa[resi])^2)),
        ribbon=0hval .+ Measurements.uncertainty(sqrt(βDQ-(ξCcsa[resi]+ξHcsa[resi])^2)), c=2)
    plot!(plt, hval,  3hval .+ Measurements.value(sqrt(βDQQ-(ξCcsa[resi]-3ξHcsa[resi])^2)),
        ribbon=0hval .+ Measurements.uncertainty(sqrt(βDQQ-(ξCcsa[resi]-3ξHcsa[resi])^2)), c=3)
    plot!(plt, hval,  3hval .- Measurements.value(sqrt(βDQQ-(ξCcsa[resi]-3ξHcsa[resi])^2)),
        ribbon=0hval .+ Measurements.uncertainty(sqrt(βDQQ-(ξCcsa[resi]-3ξHcsa[resi])^2)), c=3)
    plot!(plt, hval, -3hval .+ Measurements.value(sqrt(βQQ-(ξCcsa[resi]+3ξHcsa[resi])^2)),
        ribbon=0hval .+ Measurements.uncertainty(sqrt(βQQ-(ξCcsa[resi]+3ξHcsa[resi])^2)), c=4)
    plot!(plt, hval, -3hval .- Measurements.value(sqrt(βQQ-(ξCcsa[resi]+3ξHcsa[resi])^2)),
        ribbon=0hval .+ Measurements.uncertainty(sqrt(βQQ-(ξCcsa[resi]+3ξHcsa[resi])^2)), c=4)

    contour!(plt, hval, cval, log10.(χ2'), levels=clev, c=:red)

    return plt
end

function plotlinefits(ξH, ξC, resi)
    βZQ = Measurements.value((ξCcsa[resi]-ξHcsa[resi])^2 + (ξC-ξH)^2)
    βDQ = Measurements.value((ξCcsa[resi]+ξHcsa[resi])^2 + (ξC+ξH)^2)
    βDQQ = Measurements.value((ξCcsa[resi]-3ξHcsa[resi])^2 + (ξC-3ξH)^2)
    βQQ = Measurements.value((ξCcsa[resi]+3ξHcsa[resi])^2 + (ξC+3ξH)^2)

    plt = plot(frame=:box, legend=:topleft, xguide="B₀² / T²", yguide="Relaxation rate / s⁻¹")
    c0 = [10.0]

    scatter!(plt, B0², zq[resi,:],label="ZQ")
    fit = LsqFit.lmfit(c -> resid(B0², zq[resi,:], βZQ, c), c0, Float64[])
    c = fit.param[1]
    B2 = [0; B0²]
    plot!(plt, B2, line(B2, βZQ, c),primary=false)

    scatter!(plt, B0², dq[resi,:],label="DQ")
    fit = LsqFit.lmfit(c -> resid(B0², dq[resi,:], βDQ, c), c0, Float64[])
    c = fit.param[1]
    B2 = [0; B0²]
    plot!(plt, B2, line(B2, βDQ, c),primary=false)

    scatter!(plt, B0², dqq[resi,:],label="DQQ")
    fit = LsqFit.lmfit(c -> resid(B0², dqq[resi,:], βDQQ, c), c0, Float64[])
    c = fit.param[1]
    B2 = [0; B0²]
    plot!(plt, B2, line(B2, βDQQ, c),primary=false)

    scatter!(plt, B0², qq[resi,:],label="QQ")
    fit = LsqFit.lmfit(c -> resid(B0², qq[resi,:], βQQ, c), c0, Float64[])
    c = fit.param[1]
    B2 = [0; B0²]
    plot!(plt, B2, line(B2, βQQ, c),primary=false)
    ylims!(0, ylims()[2])
    return plt
end

max_stars_repo_name: chriswaudby/qq-hahnecho

max_issues_repo_name: chriswaudby/qq-hahnecho

max_forks_repo_name: chriswaudby/qq-hahnecho


text:
using Test, Colors

@testset "Colormaps" begin
    @testset "distinguishable_colors" begin
        cols = distinguishable_colors(10)
        @test isconcretetype(eltype(cols))

        mindiff = Inf
        for i = 1:10, j = i+1:10
            mindiff = min(mindiff, colordiff(cols[i], cols[j]))
        end
        @test mindiff > 8

        seed = distinguishable_colors(1)
        @test colordiff(distinguishable_colors(1, seed)[1], seed[1]) == 0.0
        @test colordiff(distinguishable_colors(1, seed; dropseed=true)[1], seed[1]) > 50

        cols_i = distinguishable_colors(4, LCHab(60, 50, 40), transform=identity,
                                        lchoices=[40, 60], cchoices=[50], hchoices=[40, 140])
        cols_p = distinguishable_colors(4, LCHab(60, 50, 40), transform=protanopic,
                                        lchoices=[40, 60], cchoices=[50], hchoices=[40, 140])
        @test cols_i[2] ≈ LCHab(40, 50, 140) atol=1f-3 # green
        @test cols_p[2] ≈ LCHab(40, 50,  40) atol=1f-3 # red
    end

    @test length(colormap("RdBu", 100)) == 100

    @test isconcretetype(eltype(colormap("Grays")))

    @test_throws ArgumentError colormap("Grays", N=10) # optional arguments, not keyword

    # not return values to check here, just checking that keywords can be used
    # Sequential
    default_blues = colormap("Blues", 10)
    @test_throws ArgumentError colormap("Blues", 10; mid=0.9) # `mid` is for diverging colormaps only (issue #300)
    @test colormap("Blues", 10; logscale=true) != default_blues
    @test colormap("Blues", 10; h=0.5) != default_blues
    @test colormap("Blues", 10; w=0.5) != default_blues
    @test colormap("Blues", 10; d=0.5) != default_blues
    @test colormap("Blues", 10; c=0.5) != default_blues
    @test colormap("Blues", 10; s=0.5) != default_blues
    @test colormap("Blues", 10; b=0.5) != default_blues
    @test colormap("Blues", 10; wcolor=colorant"white") != default_blues
    @test colormap("Blues", 10; dcolor=colorant"black") != default_blues
    @test_throws ArgumentError colormap("Blues", 10; h1=0.5)

    # Diverging
    default_rdbu = colormap("RdBu", 10)
    @test colormap("RdBu", 10; mid=0.9) != default_rdbu
    @test colormap("RdBu", 10; logscale=true) != default_rdbu
    @test colormap("RdBu", 10; h1=0.5) != default_rdbu
    @test colormap("RdBu", 10; h2=0.5) != default_rdbu
    @test colormap("RdBu", 10; w=0.5) != default_rdbu
    @test colormap("RdBu", 10; d1=0.5) != default_rdbu
    @test colormap("RdBu", 10; d2=0.5) != default_rdbu
    @test colormap("RdBu", 10; c=0.5) != default_rdbu
    @test colormap("RdBu", 10; s=0.5) != default_rdbu
    @test colormap("RdBu", 10; b=0.5) != default_rdbu
    @test colormap("RdBu", 10; wcolor=colorant"white") != default_rdbu
    @test colormap("RdBu", 10; dcolor1=colorant"black") != default_rdbu
    # `dcolor2` is disabled by the default `d2`(=0)
    @test colormap("RdBu", 10; dcolor2=colorant"black", d2=1) != default_rdbu
    @test_throws ArgumentError colormap("RdBu", 10; h=0.5)

    # The outputs of `colormap()` were slightly affected by the bug fix of
    # `MSC(h)` (issue #349).
    # The following were generated by `colormap()` in Colors.jl v0.9.6.
    blues_old   = (0xF4FDFF, 0xB3E3F4, 0x65B9E7, 0x2978BE, 0x0B2857)
    greens_old  = (0xFAFFF7, 0xB6EEA0, 0x75C769, 0x308B40, 0x00391A)
    grays_old   = (0xFFFFFF, 0xDCDCDC, 0xA9A9A9, 0x626262, 0x000000)
    oranges_old = (0xFFFBF6, 0xFFD6B4, 0xFF9D5F, 0xE2500D, 0x732108)
    purples_old = (0xFBFBFB, 0xDBD7F6, 0xAFA7E6, 0x7666BF, 0x3C0468)
    reds_old    = (0xFFF1EE, 0xFFC4B9, 0xFF8576, 0xE72823, 0x6D0B0C)
    rdbu_old    = (0x610102, 0xFF8D7B, 0xF9F8F9, 0x76B4E8, 0x092C58)

    to_rgb(s) = reinterpret(RGB24, s)
    max_colordiff(a1, a2) = maximum(colordiff.(a1, a2))
    @test max_colordiff(colormap("Blues", 5), to_rgb.(blues_old)) < 1
    @test max_colordiff(colormap("Greens", 5), to_rgb.(greens_old)) < 1
    @test max_colordiff(colormap("Grays", 5), to_rgb.(grays_old)) < 1
    @test max_colordiff(colormap("Oranges", 5), to_rgb.(oranges_old)) < 1
    @test max_colordiff(colormap("Purples", 5), to_rgb.(purples_old)) < 1
    @test max_colordiff(colormap("Reds", 5), to_rgb.(reds_old)) < 1
    @test max_colordiff(colormap("RdBu", 5), to_rgb.(rdbu_old)) < 1

    cyans = sequential_palette(192, w=1.0, d=1.0, wcolor=RGB(1,1,1), dcolor=RGB(0,0,0))
    @test all(c -> isapprox(green(c), blue(c), atol=1e-3), cyans)

    ryr = diverging_palette(0.0, 359.999, 45, w=0.9, c=0.7, dcolor1=RGB(0,0,1))
    @test all(c -> isapprox(c[1], c[2], atol=1e-3), zip(ryr, reverse(ryr)))
end


text:
Pkg.add("DataStructures");
using DataStructures;

chem_dict = Dict()
f = open("day14.txt");
for line in readlines(f)
    input,output = split(line, " => ")
    o_quant, o_name = split(output)
    push!(chem_dict,o_name => Dict("quantity"=>o_quant, "required_mats"=>[(parse(Int64,each[1]),each[2]) for each in [split(mat) for mat in split(input,", ")]]))
end

function compute_ore_required(fuel_amount)
    global chem_dict
    production_queue = Queue{Any}()
    reserves = DefaultDict(0)
    enqueue!(production_queue,(fuel_amount,"FUEL"))
    while isempty(production_queue) != true
        chem = dequeue!(production_queue)
        quantity,name = chem[1],chem[2]
        if name == "ORE" # Terminal. We are now adding ORES
            reserves["ORE"] += quantity
        elseif reserves[name] >= quantity # We have enough w.o producing
            reserves[name] -= quantity
        else
            required = quantity - reserves[name] #amount we need
            runs = ceil(required/parse(Int64,chem_dict[name]["quantity"])) # Each run produces no fractional output. Only exacts
            reserves[name] = runs * parse(Int64,chem_dict[name]["quantity"]) - required # Compute how much new stuff we got subtract required for current rxn
            for each in chem_dict[name]["required_mats"]
                req_quant,req_name = each[1],each[2]
                enqueue!(production_queue,(req_quant*runs,req_name)) # multiply each ele in mats by how many runs of production we need and enqueue
            end
        end
    end
    return reserves["ORE"]
end

println(compute_ore_required(1))
# Binary search
low = 0
high = 10^12
while low+1 < high
    global low,high
    mid = low + floor((high - low)//2)
    result =  compute_ore_required(mid)
    if result < 10^12
        low = mid
    else
        high = mid - 1
    end
end
println(Int(low))


text:
type TwUser
  contributors_enabled::Bool #Account has contributor mode enabled
  created_at::AbstractString #UTC datetime of account creation
  default_profile::Bool #If true, user has not altered the theme or background of their user profile
  default_profile_image::Bool #If true, user has not uploaded their own avatar
  description::Nullable{AbstractString} #Nullable, UTF-8 string describing their account
  #entities::Array{TwEntity} #Entities which have been parsed out of the urlor description fields defined by the user
  favourites_count::Int #Number of tweets favorited by the user
  follow_request_sent::Nullable{Bool} #When true, the authenticating user has issued a follow request to this user account
  following::Nullable{Bool} #DEPRECEATED, When true, the authenticating user is following this user
  followers_count::Int #Number of followers this account has
  friends_count::Int #The number of users this account is following
  geo_enabled::Bool #When true, the user has enabled the possibility of geotagging their tweets
  id::Int64 #Integer representation of the unique identifier for this User
  id_str::ASCIIString #String representation of the unique identifier
  is_translator::Bool #When true, indecates that the user is a participant in Twitter's translator community
  lang::ASCIIString #The BCP 47 code for the user's ui language
  listed_count::Int #Number of public lists that this user is a member of
  location::Nullable{AbstractString} #User defined location for this account
  name::AbstractString #User defined name for the account
  notifications::Nullable{Bool} #DEPRECEATED Indecates whether the authenticated user has chosen to recieve this users tweets by SMS
  profile_background_color::ASCIIString #Hexadecimal color for the user's background
  profile_background_image_url::AbstractString #HTTP URL pointing to the background image
  profile_background_image_url_https::AbstractString #HTTPS URL pointing to the background image
  profile_background_tile::Bool #When true, indicates that the user’s profile_background_image_url should be tiled when displayed
  profile_banner_url::AbstractString #HTTPS URL pointing to the standard web representation of the user's profile banner
  profile_image_url::AbstractString #A HTTP URL pointing to the user’s avatar image
  profile_image_url_https::AbstractString #A HTTPS URL pointing to the user’s avatar image
  profile_link_color::ASCIIString #The hexadecimal color the user has chosen to display links with in their Twitter UI
  profile_sidebar_border_color::ASCIIString #The hexadecimal color the user has chosen to display sidebar borders with in their Twitter UI
  profile_sidebar_fill_color::ASCIIString #The hexadecimal color the user has chosen to display sidebar backgrounds with in their Twitter UI
  profile_text_color::ASCIIString #The hexadecimal color the user has chosen to display text with in their Twitter UI
  profile_use_background_image::Bool #When true, indicates the user wants their uploaded background image to be used
  protected::Bool #When true, indicates that this user has chosen to protect their Tweets
  screen_name::AbstractString #The screen name, handle, or alias that this user identifies themselves with
  show_all_inline_media::Bool #Indicates that the user would like to see media inline
  status::Dict{AbstractString, Any} #Nullable. If possible, the user’s most recent tweet or retweet
  statuses_count::Int #The number of tweets (including retweets) issued by the user
  time_zone::Nullable{ASCIIString} #Nullable. A string describing the Time Zone this user declares themselves within
  url::Nullable{AbstractString} #Nullable. A URL provided by the user in association with their profile
  utc_offset::Nullable{Int} #Nullable. The offset from GMT/UTC in seconds
  verified::Bool #When true, indicates that the user has a verified account
  withheld_in_countries::ASCIIString #When present, indicates a textual representation of the two-letter country codes this user is withheld from
  withheld_scope::ASCIIString #When present, indicates whether the content being withheld is the “status” or a “user.”

  TwUser(d::Dict{AbstractString, Any}) = new(
    get(d, "contributors_enabled", false),
    get(d, "created_at", ""),
    get(d, "default_profile", true),
    get(d, "default_profile_image", true),
    get(d, "description", Nullable{AbstractString}()),
    #get(d, "entities", Array{TwEntity}()),
    get(d, "favourites_count", 0),
    get(d, "follow_request_sent", Nullable{Bool}()),
    get(d, "following", Nullable{Bool}()),
    get(d, "followers_count", 0),
    get(d, "friends_count", 0),
    get(d, "geo_enabled", false),
    get(d, "id", 0),
    get(d, "id_str", "0"),
    get(d, "is_translator", false),
    get(d, "lang", ""),
    get(d, "listed_count", 0),
    get(d, "location", Nullable{AbstractString}()),
    get(d, "name", ""),
    get(d, "notifications", Nullable{Bool}()),
    get(d, "profile_background_color", ""),
    get(d, "profile_background_image_url", ""),
    get(d, "profile_background_image_url_https", ""),
    get(d, "profile_background_tile", false),
    get(d, "profile_banner_url", ""),
    get(d, "profile_image_url", ""),
    get(d, "profile_image_url_https", ""),
    get(d, "profile_link_color", ""),
    get(d, "profile_sidebar_border_color", ""),
    get(d, "profile_sidebar_fill_color", ""),
    get(d, "profile_text_color", ""),
    get(d, "profile_use_background_image", false),
    get(d, "protected", false),
    get(d, "screen_name", ""),
    get(d, "show_all_inline_media", false),
    get(d,"status", Dict{AbstractString, Any}()),
    get(d, "statuses_count", 0),
    get(d, "time_zone", Nullable{ASCIIString}()),
    get(d, "url", Nullable{ASCIIString}()),
    get(d, "utc_offset", Nullable{Int}()),
    get(d, "verified", false),
    get(d, "withheld_in_countries", ""),
    get(d, "withheld_scope", "")
  )
end

max_stars_repo_name: nick-paul/JuliaTwitter

max_issues_repo_name: nick-paul/JuliaTwitter

max_forks_repo_name: nick-paul/JuliaTwitter


text:
using Infinity
include("../utils/distancias.jl")
"""
    RELIEF(data::Matrix{<:Real}, labels)
Algoritmo greedy para determinar el peso W
"""
function RELIEF(data::Matrix{<:Real}, labels)
    dimensiones = size(data)
    # Calculamos tabla de distancias y si son amigos o enemigos
    distancias = Dict()
    for (i,fila) in enumerate(eachrow(data))
        for j in (i+1):dimensiones[1]
            distancias[(i,j)] =(EuclideanDistance(fila, data[j, :]), labels[i]==labels[j])
        end
    end

    # Calculamos tabla de distancias y si son amigos o enemigos
    distancia_enemigo = ∞
    indice_enemigo = 0
    distancia_amigo = ∞
    indice_amigo = 0

    w = zeros(dimensiones[2])
    for i in 1:dimensiones[2]
        for j in (i+1):dimensiones[2]
            # vemos si es amigo
            if distancias[(i,j)][2] == true
                if distancias[(i,j)][1] < distancia_amigo
                    distancia_amigo = distancias[(i,j)][1]
                    indice_amigo = j
                end
            else
                if distancias[(i,j)][1] < distancia_enemigo
                    distancia_enemigo = distancias[(i,j)][1]
                    indice_enemigo = j
                end
            end
        end
        for j in 1:i-1
            # vemos si es amigo
            if distancias[(j,i)][2] == true
                if distancias[(j,i)][1] < distancia_amigo
                    distancia_amigo = distancias[(j,i)][1]
                    indice_amigo = j
                end
            else
                if distancias[(j,i)][1] < distancia_enemigo
                    distancia_enemigo = distancias[(j,i)][1]
                    indice_enemigo = j
                end
            end
        end
        if(indice_amigo != 0)
            w = w  + map(abs, data[i, :] - data[indice_amigo, :])
        end
        if(indice_enemigo != 0)
            w = w + map(abs,data[i, :] - data[indice_enemigo, :])
        end
    end
    w = map(x-> max(0,x), w)
    w = w / maximum(w)
    return w
end

function RELIEF_LearnerOneNN(data::Matrix{<:Real}, labels)
    # Creamos función objetivo
    a = 0.5
    umbral_tasa_reduccion = 0.1
    F = CrearFuncionObjetivo(data, labels, a, umbral_tasa_reduccion )

    # Buscamos pesos de acorde al algoritmo Greedy
    w = RELIEF(data, labels)

    return WeightedLearnerEuclideanOneNN(w, data, labels), F(w), w
end


text:
function assess_convergence(x::Array,
                            x_previous::Array,
                            f_x::Real,
                            f_x_previous::Real,
                            gr::Array,
                            x_tol::Real,
                            f_tol::Real,
                            g_tol::Real)
    x_converged, f_converged, g_converged = false, false, false

    if maxdiff(x, x_previous) < x_tol
        x_converged = true
    end

    # Absolute Tolerance
    # if abs(f_x - f_x_previous) < f_tol
    # Relative Tolerance
    if abs(f_x - f_x_previous) / (abs(f_x) + f_tol) < f_tol || nextfloat(f_x) >= f_x_previous
        f_converged = true
    end

    if vecnorm(gr, Inf) < g_tol
        g_converged = true
    end

    converged = x_converged || f_converged || g_converged

    return x_converged, f_converged, g_converged, converged
end


text:
export GCV, GCVMetadata

import StatsFuns: log2π

struct GCVMetadata{ A <: AbstractApproximationMethod }
    approximation :: A
end

get_approximation(meta::GCVMetadata) = meta.approximation

struct GCV end

@node GCV Stochastic [ y, x, z, κ, ω ]

const DefaultGCVNodeMetadata = GCVMetadata(GaussHermiteCubature(21))

default_meta(::Type{ GCV }) = DefaultGCVNodeMetadata

@average_energy GCV (q_y_x::MultivariateNormalDistributionsFamily, q_z::NormalDistributionsFamily, q_κ::Any, q_ω::Any) = begin
    m, c = mean(q_y_x), cov(q_y_x)

    ksi = (mean(q_κ) ^ 2) * var(q_z) + (mean(q_z) ^ 2) * var(q_κ) + var(q_κ) * var(q_z)
    psi = (m[2] - m[1]) ^ 2 + c[1, 1] + c[2, 2] - c[1, 2] - c[2, 1]
    A = exp(-mean(q_ω) + var(q_ω) / 2)
    B = exp(-mean(q_κ) * mean(q_z) + ksi / 2)

    0.5 * log2π + 0.5 * (mean(q_z) * mean(q_κ) + mean(q_ω)) + 0.5 * (psi * A * B)
end

@average_energy GCV (q_y::NormalDistributionsFamily,q_x::NormalDistributionsFamily, q_z::NormalDistributionsFamily, q_κ::Any, q_ω::Any) = begin
    my,vy = mean(q_y), cov(q_y)
    mx,vx = mean(q_x), cov(q_x)

    ksi = (mean(q_κ) ^ 2) * var(q_z) + (mean(q_z) ^ 2) * var(q_κ) + var(q_κ) * var(q_z)
    psi = (my - mx) ^ 2 + vy+vx
    A = exp(-mean(q_ω) + var(q_ω) / 2)
    B = exp(-mean(q_κ) * mean(q_z) + ksi / 2)

    0.5 * log2π + 0.5 * (mean(q_z) * mean(q_κ) + mean(q_ω)) + 0.5 * (psi * A * B)
end


text:
export with_terminal, @terminal

import Suppressor: @color_output, @capture_out, @capture_err
import Logging:  ConsoleLogger, with_logger
import Markdown: htmlesc
import Base: show

struct WithTerminalOutput
    stdout::String
    stderr::String
    value::Any
end

function show(io::IO, mime::MIME"text/html", with_terminal::WithTerminalOutput)
	show(io, mime, HTML("""
		$(terminal_css)

$(htmlesc(with_terminal.stdout))

            $(isempty(with_terminal.stderr) ? "" : "
" * htmlesc(with_terminal.stderr) * "
")

    """))
end

const terminal_css = """

"""

"""
Run the function, and capture all messages to `stdout`. The result will be a small terminal displaying the captured text.

This allows you to to see the messages from `println`, `dump`, `Pkg.status`, etc.

Example:

```julia
with_terminal() do
    x=1+1
    println(x)
    @warn "Oopsie!"
end
```

```julia
with_terminal(dump, [1,2,[3,4]])
```

See also [PlutoUI.Dump](@ref).

"""
function with_terminal(f::Function, args...; kwargs...)
    local spam_out, spam_err, value
	@color_output false begin
		spam_out = @capture_out begin
            spam_err = @capture_err begin
	            with_logger(ConsoleLogger(stdout)) do
                    value = f(args...; kwargs...)
                end
			end
		end
  end
	WithTerminalOutput(spam_out, spam_err, value)
end

"""
A convenience macro for `with_terminal` calls. See usage below.

__Usage:__

```julia
@terminal @show 2+2
@terminal begin
	println("2+2 = ", 2+2)
	println("also...")
	println("4+4 = ", 4+4)
end
@terminal print("Hello, world!")
```
"""
macro terminal(expr)
	quote
		with_terminal() do
			$(esc(expr))
		end
	end
end


text:
function SciMLBase.solve(cache::LinearCache, alg::AbstractFactorization; kwargs...)
    if cache.isfresh
        fact = do_factorization(alg, cache.A, cache.b, cache.u)
        cache = set_cacheval(cache, fact)
    end

    copyto!(cache.u,cache.b)
    y = ldiv!(cache.cacheval, cache.u)
    SciMLBase.build_linear_solution(alg,y,nothing,cache)
end

# Bad fallback: will fail if `A` is just a stand-in
# This should instead just create the factorization type.
init_cacheval(alg::AbstractFactorization, A, b, u, Pl, Pr, maxiters, abstol, reltol, verbose) = do_factorization(alg, A, b, u)

## LU Factorizations

struct LUFactorization{P} <: AbstractFactorization
    pivot::P
end

function LUFactorization()
    pivot = @static if VERSION < v"1.7beta"
        Val(true)
    else
        RowMaximum()
    end
    LUFactorization(pivot)
end

function do_factorization(alg::LUFactorization, A, b, u)
    A isa Union{AbstractMatrix,AbstractDiffEqOperator} ||
        error("LU is not defined for $(typeof(A))")

    if A isa AbstractDiffEqOperator
        A = A.A
    end
    fact = lu!(A, alg.pivot)
    return fact
end

init_cacheval(alg::LUFactorization, A, b, u, Pl, Pr, maxiters, abstol, reltol, verbose) = ArrayInterface.lu_instance(A)

# This could be a GenericFactorization perhaps?
Base.@kwdef struct UMFPACKFactorization <: AbstractFactorization
    reuse_symbolic::Bool = true
end

function init_cacheval(alg::UMFPACKFactorization, A, b, u, Pl, Pr, maxiters, abstol, reltol, verbose)
    zerobased = SparseArrays.getcolptr(A)[1] == 0
    res = SuiteSparse.UMFPACK.UmfpackLU(C_NULL, C_NULL, size(A, 1), size(A, 2),
                    zerobased ? copy(SparseArrays.getcolptr(A)) : SuiteSparse.decrement(SparseArrays.getcolptr(A)),
                    zerobased ? copy(rowvals(A)) : SuiteSparse.decrement(rowvals(A)),
                    copy(nonzeros(A)), 0)
    finalizer(SuiteSparse.UMFPACK.umfpack_free_symbolic, res)
    res
end

function do_factorization(::UMFPACKFactorization, A, b, u)
    if A isa AbstractDiffEqOperator
        A = A.A
    end
    if A isa SparseMatrixCSC
        return lu(A)
    else
        error("Sparse LU is not defined for $(typeof(A))")
    end
end

function SciMLBase.solve(cache::LinearCache, alg::UMFPACKFactorization)
    A = cache.A
    if A isa AbstractDiffEqOperator
        A = A.A
    end
    if cache.isfresh
        if cache.cacheval !== nothing && alg.reuse_symbolic
            # If we have a cacheval already, run umfpack_symbolic to ensure the symbolic factorization exists
            # This won't recompute if it does.
            SuiteSparse.UMFPACK.umfpack_symbolic!(cache.cacheval)
            fact = lu!(cache.cacheval, A)
        else
            fact = do_factorization(alg, A, cache.b, cache.u)
        end
        cache = set_cacheval(cache, fact)
    end

    y = ldiv!(cache.u, cache.cacheval, cache.b)
    SciMLBase.build_linear_solution(alg,y,nothing,cache)
end

Base.@kwdef struct KLUFactorization <: AbstractFactorization
    reuse_symbolic::Bool = true
end

function do_factorization(::KLUFactorization, A, b, u)
    if A isa AbstractDiffEqOperator
        A = A.A
    end
    if A isa SparseMatrixCSC
        return klu(A)
    else
        error("KLU is not defined for $(typeof(A))")
    end
end

function SciMLBase.solve(cache::LinearCache, alg::KLUFactorization)
    A = cache.A
    if A isa AbstractDiffEqOperator
        A = A.A
    end
    if cache.isfresh
        if cache.cacheval !== nothing && alg.reuse_symbolic
            # If we have a cacheval already, run umfpack_symbolic to ensure the symbolic factorization exists
            # This won't recompute if it does.
            KLU.klu_analyze!(cache.cacheval)
            fact = klu!(cache.cacheval, A)
        else
            fact = do_factorization(alg, A, cache.b, cache.u)
        end
        cache = set_cacheval(cache, fact)
    end

    y = ldiv!(cache.u, cache.cacheval, cache.b)
    SciMLBase.build_linear_solution(alg,y,nothing,cache)
end

## QRFactorization

struct QRFactorization{P} <: AbstractFactorization
    pivot::P
    blocksize::Int
    inplace::Bool
end

function QRFactorization(inplace = true)
    pivot = @static if VERSION < v"1.7beta"
        Val(false)
    else
        NoPivot()
    end
    QRFactorization(pivot, 16, inplace)
end

function do_factorization(alg::QRFactorization, A, b, u)
    A isa Union{AbstractMatrix,AbstractDiffEqOperator} ||
        error("QR is not defined for $(typeof(A))")

    if A isa AbstractDiffEqOperator
        A = A.A
    end
    if alg.inplace
        fact = qr!(A, alg.pivot; blocksize = alg.blocksize)
    else
        fact = qr(A) # CUDA.jl does not allow other args!
    end
    return fact
end

## SVDFactorization

struct SVDFactorization{A} <: AbstractFactorization
    full::Bool
    alg::A
end

SVDFactorization() = SVDFactorization(false, LinearAlgebra.DivideAndConquer())

function do_factorization(alg::SVDFactorization, A, b, u)
    A isa Union{AbstractMatrix,AbstractDiffEqOperator} ||
        error("SVD is not defined for $(typeof(A))")

    if A isa AbstractDiffEqOperator
        A = A.A
    end

    fact = svd!(A; full = alg.full, alg = alg.alg)
    return fact
end

## GenericFactorization

struct GenericFactorization{F} <: AbstractFactorization
    fact_alg::F
end

GenericFactorization(;fact_alg = LinearAlgebra.factorize) =
    GenericFactorization(fact_alg)

function do_factorization(alg::GenericFactorization, A, b, u)
    A isa Union{AbstractMatrix,AbstractDiffEqOperator} ||
        error("GenericFactorization is not defined for $(typeof(A))")

    if A isa AbstractDiffEqOperator
        A = A.A
    end
    fact = alg.fact_alg(A)
    return fact
end

init_cacheval(alg::GenericFactorization{typeof(lu)}, A, b, u, Pl, Pr, maxiters, abstol, reltol, verbose) = ArrayInterface.lu_instance(A)
init_cacheval(alg::GenericFactorization{typeof(lu!)}, A, b, u, Pl, Pr, maxiters, abstol, reltol, verbose) = ArrayInterface.lu_instance(A)

init_cacheval(alg::GenericFactorization{typeof(lu)}, A::StridedMatrix{<:LinearAlgebra.BlasFloat}, b, u, Pl, Pr, maxiters, abstol, reltol, verbose) = ArrayInterface.lu_instance(A)
init_cacheval(alg::GenericFactorization{typeof(lu!)}, A::StridedMatrix{<:LinearAlgebra.BlasFloat}, b, u, Pl, Pr, maxiters, abstol, reltol, verbose) = ArrayInterface.lu_instance(A)
init_cacheval(alg::GenericFactorization{typeof(lu)}, A::Diagonal, b, u, Pl, Pr, maxiters, abstol, reltol, verbose) = Diagonal(inv.(A.diag))
init_cacheval(alg::GenericFactorization{typeof(lu)}, A::Tridiagonal, b, u, Pl, Pr, maxiters, abstol, reltol, verbose) = ArrayInterface.lu_instance(A)
init_cacheval(alg::GenericFactorization{typeof(lu!)}, A::Diagonal, b, u, Pl, Pr, maxiters, abstol, reltol, verbose) = Diagonal(inv.(A.diag))
init_cacheval(alg::GenericFactorization{typeof(lu!)}, A::Tridiagonal, b, u, Pl, Pr, maxiters, abstol, reltol, verbose) = ArrayInterface.lu_instance(A)

init_cacheval(alg::GenericFactorization, A::Diagonal, b, u, Pl, Pr, maxiters, abstol, reltol, verbose) = Diagonal(inv.(A.diag))
init_cacheval(alg::GenericFactorization, A::Tridiagonal, b, u, Pl, Pr, maxiters, abstol, reltol, verbose) = ArrayInterface.lu_instance(A)
init_cacheval(alg::GenericFactorization, A::SymTridiagonal{T,V}, b, u, Pl, Pr, maxiters, abstol, reltol, verbose) where {T,V} = LinearAlgebra.LDLt{T,SymTridiagonal{T,V}}(A)

function init_cacheval(alg::Union{GenericFactorization,GenericFactorization{typeof(bunchkaufman!)},GenericFactorization{typeof(bunchkaufman)}},
                       A::Union{Hermitian,Symmetric}, b, u, Pl, Pr, maxiters, abstol, reltol, verbose)
    BunchKaufman(A.data, Array(1:size(A,1)), A.uplo, true, false, 0)
end

function init_cacheval(alg::Union{GenericFactorization,GenericFactorization{typeof(bunchkaufman!)},GenericFactorization{typeof(bunchkaufman)}},
                       A::StridedMatrix{<:LinearAlgebra.BlasFloat}, b, u, Pl, Pr, maxiters, abstol, reltol, verbose)
   if eltype(A) <: Complex
       return bunchkaufman!(Hermitian(A))
   else
       return bunchkaufman!(Symmetric(A))
   end
end

# Fallback, tries to make nonsingular and just factorizes
# Try to never use it.
function init_cacheval(alg::Union{QRFactorization,SVDFactorization,GenericFactorization}, A, b, u, Pl, Pr, maxiters, abstol, reltol, verbose)
    newA = copy(A)
    fill!(newA,true)
    do_factorization(alg, newA, b, u)
end

## RFLUFactorization

RFLUFactorization() = GenericFactorization(;fact_alg=RecursiveFactorization.lu!)
init_cacheval(alg::GenericFactorization{typeof(RecursiveFactorization.lu!)}, A, b, u, Pl, Pr, maxiters, abstol, reltol, verbose) = ArrayInterface.lu_instance(A)
init_cacheval(alg::GenericFactorization{typeof(RecursiveFactorization.lu!)}, A::StridedMatrix{<:LinearAlgebra.BlasFloat}, b, u, Pl, Pr, maxiters, abstol, reltol, verbose) = ArrayInterface.lu_instance(A)


text:
#!/usr/bin/env julia

using Test

import KeyboardDriven:
    CharKey,
    bytestokey,
    escape,
    f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12,
    arrowUp, arrowDown, arrowLeft, arrowRight,
    endKey, home, ins, del,
    pgUp, pgDn,
    returnKey

@testset "Test single byte character keys" begin
    @test bytestokey(0x20) == CharKey(' ')
    @test bytestokey(0x35) == CharKey('5')
    @test bytestokey(0x7a) == CharKey('z')
end

@testset "Test single byte special keys" begin
    @test bytestokey(0x0a) == returnKey
    @test bytestokey(0x1b) == escape
end

@testset "Test single byte modified keys" begin
    @test bytestokey(0x00) == ctrl | CharKey(' ')
    @test bytestokey(0x06) == ctrl | CharKey('f')
    @test bytestokey(0x1d) == ctrl | CharKey('5')
    @test bytestokey(0x1e) == ctrl | CharKey('6')
    @test bytestokey(0x1f) == ctrl | CharKey('7')
end

@testset "Test two-byte modified character keys" begin
    @test bytestokey((0x1b, 0x72)) == alt | CharKey('r')
end

@testset "Test two-byte regional character keys" begin
    @test bytestokey((0xc3, 0x9f)) == CharKey('ß')
    @test bytestokey((0xc3, 0xa5)) == CharKey('å')
    @test bytestokey((0xc3, 0xb8)) == CharKey('ø')
end

@testset "Test two-byte special character keys" begin
    @test bytestokey((0xc2, 0xa4)) == CharKey('¤')
    @test bytestokey((0xc2, 0xa7)) == CharKey('§')
end

@testset "Test two-byte modified regional character keys" begin
    @test bytestokey((0xd1, 0x8d)) == ctrl | CharKey('ä')
    @test bytestokey((0xd1, 0x8b)) == ctrl | CharKey('ß')
end

@testset "Test two-byte modified character keys" begin
    @test bytestokey((0x1b, 0x00)) == alt | ctrl | CharKey(' ')
    @test bytestokey((0x1b, 0x01)) == alt | ctrl | CharKey('a')
    @test bytestokey((0x1b, 0x0b)) == alt | ctrl | CharKey('k')
end

@testset "Test three-byte modified regional character keys" begin
    @test bytestokey((0x1b, 0xd0, 0xb6)) == alt |  ctrl | CharKey('ö')
    @test bytestokey((0x1b, 0xd1, 0x85)) == alt |  ctrl | CharKey('å')
end

@testset "Test three-byte special keys" begin
    @test bytestokey((0x1b, 0x4f, 0x50)) == f1
    @test bytestokey((0x1b, 0x4f, 0x51)) == f2
    @test bytestokey((0x1b, 0x4f, 0x52)) == f3
    @test bytestokey((0x1b, 0x4f, 0x53)) == f4
    @test bytestokey((0x1b, 0x5b, 0x41)) == arrowUp
    @test bytestokey((0x1b, 0x5b, 0x42)) == arrowDown
    @test bytestokey((0x1b, 0x5b, 0x43)) == arrowRight
    @test bytestokey((0x1b, 0x5b, 0x44)) == arrowLeft
    @test bytestokey((0x1b, 0x5b, 0x46)) == endKey
    @test bytestokey((0x1b, 0x5b, 0x48)) == home
end

@testset "Test three-byte special character keys" begin
    @test bytestokey((0xe2, 0x82, 0xac)) == CharKey('€')
end

@testset "Test four-byte special keys" begin
    @test bytestokey((0x1b, 0x5b, 0x32, 0x7e)) == ins
    @test bytestokey((0x1b, 0x5b, 0x33, 0x7e)) == del
    @test bytestokey((0x1b, 0x5b, 0x35, 0x7e)) == pgUp
    @test bytestokey((0x1b, 0x5b, 0x36, 0x7e)) == pgDn
end

@testset "Test five-byte special keys" begin
    @test bytestokey((0x1b, 0x5b, 0x31, 0x35, 0x7e)) == f5
    @test bytestokey((0x1b, 0x5b, 0x31, 0x37, 0x7e)) == f6
    @test bytestokey((0x1b, 0x5b, 0x31, 0x38, 0x7e)) == f7
    @test bytestokey((0x1b, 0x5b, 0x31, 0x39, 0x7e)) == f8
    @test bytestokey((0x1b, 0x5b, 0x32, 0x30, 0x7e)) == f9
    @test bytestokey((0x1b, 0x5b, 0x32, 0x31, 0x7e)) == f10
    @test bytestokey((0x1b, 0x5b, 0x32, 0x33, 0x7e)) == f11
    @test bytestokey((0x1b, 0x5b, 0x32, 0x34, 0x7e)) == f12
end

@testset "Test six-byte modified special keys" begin
    @test bytestokey((0x1b, 0x5b, 0x35, 0x3b, 0x35, 0x7e)) == ctrl | pgUp
    @test bytestokey((0x1b, 0x5b, 0x36, 0x3b, 0x35, 0x7e)) == ctrl | pgDn
    @test bytestokey((0x1b, 0x5b, 0x33, 0x3b, 0x35, 0x7e)) == ctrl | del
    @test bytestokey((0x1b, 0x5b, 0x31, 0x3b, 0x37, 0x41)) == alt | ctrl | arrowUp
    @test bytestokey((0x1b, 0x5b, 0x31, 0x3b, 0x37, 0x42)) == alt | ctrl | arrowDown
    @test bytestokey((0x1b, 0x5b, 0x31, 0x3b, 0x37, 0x43)) == alt | ctrl | arrowRight
    @test bytestokey((0x1b, 0x5b, 0x31, 0x3b, 0x37, 0x44)) == alt | ctrl | arrowLeft
    @test bytestokey((0x1b, 0x5b, 0x31, 0x3b, 0x32, 0x41)) == shift | arrowUp
    @test bytestokey((0x1b, 0x5b, 0x31, 0x3b, 0x32, 0x42)) == shift | arrowDown
    @test bytestokey((0x1b, 0x5b, 0x31, 0x3b, 0x32, 0x43)) == shift | arrowRight
    @test bytestokey((0x1b, 0x5b, 0x31, 0x3b, 0x32, 0x44)) == shift | arrowLeft
end

@testset "Test seven-byte modified special keys" begin
    @test bytestokey((0x1b, 0x5b, 0x31, 0x39, 0x3b, 0x35, 0x7e)) == ctrl | f8
    @test bytestokey((0x1b, 0x5b, 0x32, 0x30, 0x3b, 0x35, 0x7e)) == ctrl | f9
    @test bytestokey((0x1b, 0x5b, 0x32, 0x31, 0x3b, 0x35, 0x7e)) == ctrl | f10
    @test bytestokey((0x1b, 0x5b, 0x32, 0x33, 0x3b, 0x35, 0x7e)) == ctrl | f11
    @test bytestokey((0x1b, 0x5b, 0x32, 0x34, 0x3b, 0x35, 0x7e)) == ctrl | f12
    @test bytestokey((0x1b, 0x5b, 0x31, 0x37, 0x3b, 0x36, 0x7e)) == ctrl | shift | f6
    @test bytestokey((0x1b, 0x5b, 0x31, 0x38, 0x3b, 0x36, 0x7e)) == ctrl | shift | f7
    @test bytestokey((0x1b, 0x5b, 0x31, 0x39, 0x3b, 0x36, 0x7e)) == ctrl | shift | f8
    @test bytestokey((0x1b, 0x5b, 0x32, 0x30, 0x3b, 0x36, 0x7e)) == ctrl | shift | f9
    @test bytestokey((0x1b, 0x5b, 0x32, 0x31, 0x3b, 0x36, 0x7e)) == ctrl | shift | f10
    @test bytestokey((0x1b, 0x5b, 0x32, 0x33, 0x3b, 0x36, 0x7e)) == ctrl | shift | f11
    @test bytestokey((0x1b, 0x5b, 0x32, 0x34, 0x3b, 0x36, 0x7e)) == ctrl | shift | f12
end


text:
module MINLPTests

using JuMP
using Test

###
### Default tolerances that are used in the tests.
###

# Absolute tolerance when checking the objective value.
const OPT_TOL = 1e-6

# Absolute tolerance when checking the primal solution value.
const PRIMAL_TOL = 1e-6

# Absolue tolerance when checking the dual solution value.
const DUAL_TOL = 1e-6

###
### Default expected status codes for different types of problems and solvers.
###

# We only distinguish between feasible and infeasible problems now.
@enum ProblemTypeCode FEASIBLE_PROBLEM INFEASIBLE_PROBLEM

# Target status codes for local solvers:
const TERMINATION_TARGET_LOCAL = Dict(
    FEASIBLE_PROBLEM => JuMP.MOI.LOCALLY_SOLVED,
    INFEASIBLE_PROBLEM => JuMP.MOI.LOCALLY_INFEASIBLE,
)
const PRIMAL_TARGET_LOCAL = Dict(
    FEASIBLE_PROBLEM => JuMP.MOI.FEASIBLE_POINT,
    INFEASIBLE_PROBLEM => JuMP.MOI.INFEASIBLE_POINT,
)

# Target status codes for global solvers:
const TERMINATION_TARGET_GLOBAL = Dict(
    FEASIBLE_PROBLEM => JuMP.MOI.OPTIMAL,
    INFEASIBLE_PROBLEM => JuMP.MOI.INFEASIBLE,
)
const PRIMAL_TARGET_GLOBAL = Dict(
    FEASIBLE_PROBLEM => JuMP.MOI.FEASIBLE_POINT,
    INFEASIBLE_PROBLEM => JuMP.MOI.NO_SOLUTION,
)

###
### Helper functions for the tests.
###

function check_status(
    model,
    problem_type::ProblemTypeCode,
    termination_target = TERMINATION_TARGET_LOCAL,
    primal_target = PRIMAL_TARGET_LOCAL,
)
    @test JuMP.termination_status(model) == termination_target[problem_type]
    @test JuMP.primal_status(model) == primal_target[problem_type]
end

function check_objective(model, solution; tol = OPT_TOL)
    if !isnan(tol)
        @test isapprox(JuMP.objective_value(model), solution, atol = tol)
    end
end

function check_solution(variables, solutions; tol = PRIMAL_TOL)
    if !isnan(tol)
        @assert length(variables) == length(solutions)
        for (variable, solution) in zip(variables, solutions)
            @test isapprox(JuMP.value(variable), solution, atol = tol)
        end
    end
end

function check_dual(constraints, solutions; tol = DUAL_TOL)
    if !isnan(tol)
        @assert length(constraints) == length(solutions)
        for (constraint, solution) in zip(constraints, solutions)
            @test isapprox(JuMP.dual(constraint), solution, atol = tol)
        end
    end
end

###
### Loop through and include every model function.
###

for directory in ["nlp", "nlp-cvx", "nlp-mi"]
    files = readdir(joinpath(@__DIR__, directory))
    for file_name in filter(f -> endswith(f, ".jl"), files)
        include(joinpath(@__DIR__, directory, file_name))
    end
end

"""
    test_directory(
        directory,
        optimizer;
        debug::Bool = false,
        exclude = String[],
        include = String[],
        objective_tol = OPT_TOL,
        primal_tol = PRIMAL_TOL,
        dual_tol = DUAL_TOL,
        termination_target = TERMINATION_TARGET_LOCAL,
        primal_target = PRIMAL_TARGET_LOCAL,
    )

Test all of the files in `directory` using `optimizer`.

If `debug`, print the name of the file befor running it.

Use `exclude` and `include` to run a subset of the files in a directory.

Use the remaining args to control tolerances and status targets.

## Example

Test all but nlp_001_010:
```julia
test_directory("nlp", optimizer; exclude = ["001_010"])
```

Test only nlp_001_010:
```julia
test_directory("nlp", optimizer; include = ["001_010"])
```
"""
function test_directory(
    directory,
    optimizer;
    debug::Bool = false,
    exclude = String[],
    include = String[],
    objective_tol = OPT_TOL,
    primal_tol = PRIMAL_TOL,
    dual_tol = DUAL_TOL,
    termination_target = TERMINATION_TARGET_LOCAL,
    primal_target = PRIMAL_TARGET_LOCAL,
)
    @testset "$(directory)" begin
        models = _list_of_models(directory, exclude, include)
        @testset "$(model_name)" for model_name in models
            if debug
                println("Running $(model_name)")
            end
            getfield(MINLPTests, model_name)(
                optimizer,
                objective_tol,
                primal_tol,
                dual_tol,
                termination_target,
                primal_target,
            )
        end
    end
end

function _list_of_models(
    directory,
    exclude::Vector{String},
    include::Vector{String},
)
    dir = replace(directory, "-" => "_")
    if length(include) > 0
        return [Symbol("$(dir)_$(i)") for i in include]
    else
        models = Symbol[]
        for file in readdir(joinpath(@__DIR__, directory))
            if !endswith(file, ".jl")
                continue
            end
            file = replace(file, ".jl" => "")
            if file in exclude
                continue
            end
            push!(models, Symbol("$(dir)_$(file)"))
        end
        return models
    end
end

###
### Helper functions to test a subset of models.
###

function test_nlp(
    optimizer;
    debug::Bool = false,
    exclude = String[],
    objective_tol = OPT_TOL,
    primal_tol = PRIMAL_TOL,
    dual_tol = DUAL_TOL,
    termination_target = TERMINATION_TARGET_LOCAL,
    primal_target = PRIMAL_TARGET_LOCAL,
)
    return test_directory(
        "nlp",
        optimizer;
        debug = debug,
        exclude = exclude,
        objective_tol = objective_tol,
        primal_tol = primal_tol,
        dual_tol = dual_tol,
        termination_target = termination_target,
        primal_target = primal_target,
    )
end

function test_nlp_cvx(
    optimizer;
    debug::Bool = false,
    exclude = String[],
    objective_tol = OPT_TOL,
    primal_tol = PRIMAL_TOL,
    dual_tol = DUAL_TOL,
    termination_target = TERMINATION_TARGET_LOCAL,
    primal_target = PRIMAL_TARGET_LOCAL,
)
    return test_directory(
        "nlp-cvx",
        optimizer;
        debug = debug,
        exclude = exclude,
        objective_tol = objective_tol,
        primal_tol = primal_tol,
        dual_tol = dual_tol,
        termination_target = termination_target,
        primal_target = primal_target,
    )
end

function test_nlp_mi(
    optimizer;
    debug::Bool = false,
    exclude = String[],
    objective_tol = OPT_TOL,
    primal_tol = PRIMAL_TOL,
    dual_tol = DUAL_TOL,
    termination_target = TERMINATION_TARGET_LOCAL,
    primal_target = PRIMAL_TARGET_LOCAL,
)
    return test_directory(
        "nlp-mi",
        optimizer;
        debug = debug,
        exclude = exclude,
        objective_tol = objective_tol,
        primal_tol = primal_tol,
        dual_tol = dual_tol,
        termination_target = termination_target,
        primal_target = primal_target,
    )
end

### Tests that haven't been updated.

include("nlp-mi-cvx/tests.jl")
include("poly/tests.jl")
include("poly-cvx/tests.jl")
include("poly-mi/tests.jl")
include("poly-mi-cvx/tests.jl")

end


text:
function mysum_linear(a::AbstractArray)
s=zero(eltype(a))
for i = 1:length(a)
s=s+a[i]
end
return s
end

max_stars_repo_path: Module 2/Chapter06/linear.jl

max_issues_repo_path: Module 2/Chapter06/linear.jl

max_forks_repo_path: Module 2/Chapter06/linear.jl