text:
function __init__fashionmnist()
    DEPNAME = "FashionMNIST"
    TRAINIMAGES = "train-images-idx3-ubyte.gz"
    TRAINLABELS = "train-labels-idx1-ubyte.gz"
    TESTIMAGES  = "t10k-images-idx3-ubyte.gz"
    TESTLABELS  = "t10k-labels-idx1-ubyte.gz"

    register(DataDep(
        DEPNAME,
        """
        Dataset: FashionMNIST
        Authors: Han Xiao, Kashif Rasul, Roland Vollgraf
        Website: https://github.com/zalandoresearch/fashion-mnist
        License: MIT

        [Han Xiao et al. 2017]
            Han Xiao, Kashif Rasul, and Roland Vollgraf.
            "Fashion-MNIST: a Novel Image Dataset for Benchmarking Machine Learning Algorithms."
            arXiv:1708.07747

        The files are available for download at the offical
        website linked above. Note that using the data
        responsibly and respecting copyright remains your
        responsibility.
        """,
        "http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/" .* [TRAINIMAGES, TRAINLABELS, TESTIMAGES, TESTLABELS],
        "c916b6e00d3083643332b70f3c5c3543d3941334b802e252976893969ee6af67",
    ))
end

"""
    FashionMNIST(; Tx=Float32, split=:train, dir=nothing)
    FashionMNIST([Tx, split])

FashionMNIST is a dataset of Zalando's article images consisting
of a training set of 60_000 examples and a test set of 10_000
examples. Each example is a 28x28 grayscale image, associated
with a label from 10 classes. It can serve as a drop-in
replacement for MNIST.

- Authors: Han Xiao, Kashif Rasul, Roland Vollgraf
- Website: https://github.com/zalandoresearch/fashion-mnist

See [`MNIST`](@ref) for details of the interface.
"""
struct FashionMNIST <: SupervisedDataset
    metadata::Dict{String, Any}
    split::Symbol
    features::Array{<:Any,3}
    targets::Vector{Int}
end

FashionMNIST(; split=:train, Tx=Float32, dir=nothing) = FashionMNIST(Tx, split; dir)

function FashionMNIST(Tx, split::Symbol; dir=nothing)
    @assert split in [:train, :test]
    if split == :train
        IMAGESPATH = "train-images-idx3-ubyte.gz"
        LABELSPATH = "train-labels-idx1-ubyte.gz"
    else
        IMAGESPATH  = "t10k-images-idx3-ubyte.gz"
        LABELSPATH  = "t10k-labels-idx1-ubyte.gz"
    end

    features_path = datafile("FashionMNIST", IMAGESPATH, dir)
    features = bytes_to_type(Tx, MNISTReader.readimages(features_path))

    targets_path = datafile("FashionMNIST", LABELSPATH, dir)
    targets = Vector{Int}(MNISTReader.readlabels(targets_path))
    # targets = reshape(targets, 1, :)

    metadata = Dict{String,Any}()
    metadata["n_observations"] = size(features)[end]
    metadata["features_path"] = features_path
    metadata["targets_path"] = targets_path
    metadata["class_names"] = ["T-Shirt", "Trouser", "Pullover", "Dress", "Coat", "Sandal", "Shirt", "Sneaker", "Bag", "Ankle boot"]

    return FashionMNIST(metadata, split, features, targets)
end

convert2image(::Type{<:FashionMNIST}, x::AbstractArray) = convert2image(MNIST, x)

# DEPRECATED INTERFACE, REMOVE IN v0.7 (or 0.6.x)
function Base.getproperty(::Type{FashionMNIST}, s::Symbol)
    if s == :traintensor
        @warn "FashionMNIST.traintensor() is deprecated, use `FashionMNIST(split=:train).features` instead." maxlog=2
        traintensor(T::Type=N0f8; kws...) = traintensor(T, :; kws...)
        traintensor(i; kws...) = traintensor(N0f8, i; kws...)
        function traintensor(T::Type, i; dir=nothing)
            FashionMNIST(; split=:train, Tx=T, dir)[i][1]
        end
        return traintensor
    elseif s == :testtensor
        @warn "FashionMNIST.testtensor() is deprecated, use `FashionMNIST(split=:test).features` instead."  maxlog=2
        testtensor(T::Type=N0f8; kws...) = testtensor(T, :; kws...)
        testtensor(i; kws...) = testtensor(N0f8, i; kws...)
        function testtensor(T::Type, i; dir=nothing)
            FashionMNIST(; split=:test, Tx=T, dir)[i][1]
        end
        return testtensor
    elseif s == :trainlabels
        @warn "FashionMNIST.trainlabels() is deprecated, use `FashionMNIST(split=:train).targets` instead."  maxlog=2
        trainlabels(; kws...) = trainlabels(:; kws...)
        function trainlabels(i; dir=nothing)
            FashionMNIST(; split=:train, dir)[i][2]
        end
        return trainlabels
    elseif s == :testlabels
        @warn "FashionMNIST.testlabels() is deprecated, use `FashionMNIST(split=:test).targets` instead." maxlog=2
        testlabels(; kws...) = testlabels(:; kws...)
        function testlabels(i; dir=nothing)
            FashionMNIST(; split=:test, dir)[i][2]
        end
        return testlabels
    elseif s == :traindata
        @warn "FashionMNIST.traindata() is deprecated, use `FashionMNIST(split=:train)[]` instead." maxlog=2
        traindata(T::Type=N0f8; kws...) = traindata(T, :; kws...)
        traindata(i; kws...) = traindata(N0f8, i; kws...)
        function traindata(T::Type, i; dir=nothing)
            FashionMNIST(; split=:train, Tx=T, dir)[i]
        end
        return traindata
    elseif s == :testdata
        @warn "FashionMNIST.testdata() is deprecated, use `FashionMNIST(split=:test)[]` instead."  maxlog=2
        testdata(T::Type=N0f8; kws...) = testdata(T, :; kws...)
        testdata(i; kws...) = testdata(N0f8, i; kws...)
        function testdata(T::Type, i; dir=nothing)
            FashionMNIST(; split=:test, Tx=T, dir)[i]
        end
        return testdata
    elseif s == :convert2image
        @warn "FashionMNIST.convert2image(x) is deprecated, use `convert2image(FashionMNIST, x)` instead." maxlog=2
        return x -> convert2image(FashionMNIST, x)
    elseif s == :classnames
        @warn "FashionMNIST.classnames() is deprecated, use `FashionMNIST().metadata[\"class_names\"]` instead." maxlog=2
        return () -> ["T-Shirt", "Trouser", "Pullover", "Dress", "Coat", "Sandal", "Shirt", "Sneaker", "Bag", "Ankle boot"]
    else
        return getfield(FashionMNIST, s)
    end
end


text:
####### Single source per instance ##################
# Modeling
@batchdef function time_modeling_azure(_model::BatchFuture, srcG, q, recG, D, _dm, op, mode, opt)
    nsrc = isnothing(srcG) ? length(recG.xloc) : length(srcG.xloc)
    check_njulia(nsrc)
    model = fetch(_model)
    dm = isnothing(_dm) ? _dm : fetch(_dm)
    if nsrc > 1
        argout = time_modeling(model, srcG, q, recG, D, dm, 1:nsrc, op, mode, opt)
    else
        argout = time_modeling(model, srcG, q, recG, D, dm, op, mode, opt)
    end
    rmprocs(workers())
    return argout
end

#FWI
@batchdef function fwi_objective_azure(_model::BatchFuture, q, D, opt)
    check_njulia(q.nsrc)
    model = fetch(_model)
    f, g = fwi_objective(model, q, D; options=opt)
    rmprocs(workers())
    return f, g
end

#LSRTM
@batchdef function lsrtm_objective_azure(_model::BatchFuture, q, D, _dm, opt; nlind=false)
    check_njulia(q.nsrc)
    model = fetch(_model)
    dm = isnothing(_dm) ? _dm : fetch(_dm)
    f, g = lsrtm_objective(model,q, D, dm; options=opt, nlind=nlind)
    rmprocs(workers())
    return f, g
end

### julia distributed setup ###
@batchdef function check_njulia(nsrc::Integer)
    if _nproc_loc == 1 || nsrc == 1
        @info "Only $(nsrc) source or $(_nproc_loc) workers, running serial julia"
        return
    end
    nw = nsrc >= _nproc_loc ? _nproc_loc : nsrc
    @info "Starting julia distributed with $(nw) workers for $(nsrc) sources"
    addprocs(nw)
    eval(macroexpand(Main, quote @everywhere using JUDI end))
end

ext: jl


text:
export load_obj

# ------------------------- #
# - Parse OBJ & MTL Files - #
# ------------------------- #
"""
    triangulate_faces(vertices::Vector, texture_coordinates::Vector,
                      faces::Vector, material_map::Dict)

Triangulates the `faces` and converts it into valid [`Triangle`](@ref) objects.

!!! warning
    Avoid using this function in itself. It is designed to be used internally
    by the [`load_obj`](@ref) function.
"""
function triangulate_faces(vertices::Vector, texture_coordinates::Vector,
                           faces::Vector, material_map::Dict)
    scene = Vector{Triangle}()
    for face in faces
        for i in 2:(length(face[1]) - 1)
            if isnothing(face[2])
                uv_coordinates = nothing
            else
                uv_coordinates = [[texture_coordinates[face[2][1]]...],
                                  [texture_coordinates[face[2][i]]...],
                                  [texture_coordinates[face[2][i + 1]]...]]
            end
            mat = Material(;uv_coordinates = uv_coordinates,
                           material_map[face[3]]...)
            push!(scene, Triangle(deepcopy(vertices[face[1][1]]),
                                  deepcopy(vertices[face[1][i]]),
                                  deepcopy(vertices[face[1][i + 1]]),
                                  mat))
        end
    end
    try
        scene_stable = Vector{typeof(scene[1])}()
        for s in scene
            push!(scene_stable, s)
        end
        return scene_stable
    catch e
        # If all the triangles are not of the same type return the non-infered
        # version of the scene. In this case type inference for `raytrace` will
        # also fail
        @warn "Could not convert the triangles to the same type. Type inference for raytrace will fail"
        return scene
    end
end

"""
    parse_mtllib!(file, material_map, outtype)

Parses `.mtl` file and creates a map from the material name to
[`Material`](@ref) objects.

Not all fields of the `mtl` file are parsed. We only parse :
`newmtl`, `Ka`, `Kd`, `Ks`, `Ns`, `d`, `Tr`, `map_Kd`, `map_Ks`,
and `map_Ka`.
"""
function parse_mtllib!(file, material_map, outtype)
    color_diffuse = Vec3(outtype(1.0f0))
    color_ambient = Vec3(outtype(1.0f0))
    color_specular = Vec3(outtype(1.0f0))
    specular_exponent = outtype(50.0f0)
    reflection = outtype(0.5f0)
    texture_ambient = nothing
    texture_diffuse = nothing
    texture_specular = nothing
    last_mat = "RayTracer Default"
    if isnothing(file)
        material_map[last_mat] = (color_diffuse = color_diffuse,
                                  color_ambient = color_ambient,
                                  color_specular = color_specular,
                                  specular_exponent = specular_exponent,
                                  reflection = reflection,
                                  texture_ambient = texture_ambient,
                                  texture_diffuse = texture_diffuse,
                                  texture_specular = texture_specular)
        return nothing
    end
    for line in eachline(file)
        wrds = split(line)
        isempty(wrds) && continue
        if wrds[1] == "newmtl"
            material_map[last_mat] = (color_diffuse = color_diffuse,
                                      color_ambient = color_ambient,
                                      color_specular = color_specular,
                                      specular_exponent = specular_exponent,
                                      reflection = reflection,
                                      texture_ambient = texture_ambient,
                                      texture_diffuse = texture_diffuse,
                                      texture_specular = texture_specular)
            last_mat = wrds[2]
            # In case any of these values are not defined for the material
            # we shall use the default values
            color_diffuse = Vec3(outtype(1.0f0))
            color_ambient = Vec3(outtype(1.0f0))
            color_specular = Vec3(outtype(1.0f0))
            specular_exponent = outtype(50.0f0)
            reflection = outtype(0.5f0)
            texture_ambient = nothing
            texture_diffuse = nothing
            texture_specular = nothing
        elseif wrds[1] == "Ka"
            color_ambient = Vec3(parse.(outtype, wrds[2:4])...)
        elseif wrds[1] == "Kd"
            color_diffuse = Vec3(parse.(outtype, wrds[2:4])...)
        elseif wrds[1] == "Ks"
            color_specular = Vec3(parse.(outtype, wrds[2:4])...)
        elseif wrds[1] == "Ns"
            specular_exponent = parse(outtype, wrds[2])
        elseif wrds[1] == "d"
            reflection = parse(outtype, wrds[2])
        elseif wrds[1] == "Tr"
            reflection = 1 - parse(outtype, wrds[2])
        elseif wrds[1] == "map_Ka"
            texture_file = "$(rsplit(file, '/', limit = 2)[1])/$(wrds[2])"
            texture_ambient = Vec3([outtype.(permutedims(channelview(load(texture_file)),
                                                         (3, 2, 1)))[:,end:-1:1,i]
                                    for i in 1:3]...)
        elseif wrds[1] == "map_Kd"
            texture_file = "$(rsplit(file, '/', limit = 2)[1])/$(wrds[2])"
            texture_diffuse = Vec3([outtype.(permutedims(channelview(load(texture_file)),
                                                         (3, 2, 1)))[:,end:-1:1,i]
                                    for i in 1:3]...)
        elseif wrds[1] == "map_Ks"
            texture_file = "$(rsplit(file, '/', limit = 2)[1])/$(wrds[2])"
            texture_specular = Vec3([outtype.(permutedims(channelview(load(texture_file)),
                                                          (3, 2, 1)))[:,end:-1:1,i]
                                     for i in 1:3]...)
        end
    end
    material_map[last_mat] = (color_diffuse = color_diffuse,
                              color_ambient = color_ambient,
                              color_specular = color_specular,
                              specular_exponent = specular_exponent,
                              texture_ambient = texture_ambient,
                              texture_diffuse = texture_diffuse,
                              texture_specular = texture_specular)
    return nothing
end

"""
    load_obj(file; outtype = Float32)

Parser for `obj` file. It returns a set of Triangles that make up the scene.

Only the following things are parsed as of now: `v`, `vt`, `vn`, `f`, `usemtl`
and `mtllib`.
"""
function load_obj(file; outtype = Float32)
    vertices = Vector{Vec3{Vector{outtype}}}()
    texture_coordinates = Vector{Tuple}()
    normals = Vector{Vec3{Vector{outtype}}}()
    faces = Vector{Tuple{Vector{Int}, Union{Vector{Int}, Nothing}, String}}()
    material_map = Dict{String, Union{NamedTuple, Nothing}}()
    last_mat = "RayTracer Default"
    mtllib = nothing
    for line in eachline(file)
        wrds = split(line)
        isempty(wrds) && continue
        if wrds[1] == "v" # Vertices
            push!(vertices, Vec3(parse.(outtype, wrds[2:4])...))
        elseif wrds[1] == "vt" # Texture Coordinates
            push!(texture_coordinates, tuple(parse.(outtype, wrds[2:3])...))
        elseif wrds[1] == "vn" # Normal
            push!(normals, Vec3(parse.(outtype, wrds[2:4])...))
        elseif wrds[1] == "f" # Faces
            # Currently we shall only be concerned with the vertices of the face
            # and safely throw away vertex normal information
            fstwrd = split(wrds[2], '/')
            texture_c = isempty(fstwrd[2]) ? nothing : [parse(Int, fstwrd[2])]
            @assert length(fstwrd) == 3 "Incorrect number of /'s in the obj file"
            push!(faces, ([parse(Int, fstwrd[1])], texture_c, last_mat))
            for wrd in wrds[3:end]
                splitwrd = split(wrd, '/')
                @assert length(splitwrd) == 3 "Incorrect number of /'s in the obj file"
                push!(faces[end][1], parse(Int, splitwrd[1]))
                !isnothing(texture_c) && push!(faces[end][2], parse(Int, splitwrd[2]))
            end
        elseif wrds[1] == "usemtl" # Key for parsing mtllib file
            last_mat = wrds[2]
            material_map[last_mat] = nothing
        elseif wrds[1] == "mtllib" # Material file
            mtllib = "$(rsplit(file, '/', limit = 2)[1])/$(wrds[2])"
        end
    end

    if !isnothing(mtllib)
        parse_mtllib!(mtllib, material_map, outtype)
    else
        parse_mtllib!(nothing, material_map, outtype)
    end

    return triangulate_faces(vertices, texture_coordinates, faces, material_map)
end


text:
water = cc"H2O"
H_ion = cc"H{+1}"
O_ion = cc"O{-2}"

@testset "Compound" begin
    @test Compound("{-1}").tuples == cc"{1-}".tuples ==
        cc"{-}".tuples == [("e", 1)]
    @test cc"Γ(Θ2Π)5".tuples == [("Γ", 1), ("Θ", 10), ("Π", 5)]
    @test cc"CoN5H15BrSO4".tuples ==
        [("Co", 1), ("N", 5), ("H", 15), ("Br", 1), ("S", 1), ("O", 4)]

    @test water.charge == 0
    @test H_ion.charge == 1
    @test O_ion.charge == -2
end

@testset "@cc_str" begin
    @test cc"H2O" == water
end

@testset "==" begin
    @test cc"H2" == cc"H2"
    @test cc"{-}" == cc"{-1}"
    @test cc"CH2(OH)2(CH)" == cc"O2H5C2"

    @test cc"H H" == cc"H2"
    @test cc"H_1C_1O_1" == cc"HCO"
    @test cc"Mg(OH)2(s)" == cc"Mg(OH)2(aq)"
end

@testset "string" begin
    @test string(cc"C1O1") == "CO"
    @test string(H_ion) == "H{+}"
    @test string(O_ion) == "O{-2}"

    @test string(cc"CuSO4*5H2O") == "CuSO9H10"
    @test string(cc"MgOH * OH * CO") == "MgO3H2C"
    @test string(cc"Mg OH * 5 (OH)2") == "MgO11H11"

    @test string(cc"H(OH)") == "H2O"
    @test string(cc"(XyZx)2{+2}") == "Xy2Zx2{+2}"
    @test string(cc"(CH3COOH)2Mg") == "C4H8O4Mg"
end

@testset "show" begin
    @test isa(repr(water), String) == true
end

@testset "elements" begin
    @test elements(water) == ["H", "O"]
end

@testset "hascharge" begin
    @test hascharge(water) == false
    @test hascharge(H_ion) == true
    @test hascharge(O_ion) == true
end


text:
module OpenML

using HTTP
using JSON
import ARFFFiles
import ScientificTypes: Continuous, Count, Textual, Multiclass, coerce, autotype
using Markdown
if VERSION > v"1.3.0"
    using Pkg.Artifacts
end

export OpenML

include("data.jl")

end # module


text:
using GeoPhyInv
using SparseArrays
using StatsBase
using LinearAlgebra
using Random
using ProgressMeter
using LinearAlgebra
using Test
using ForwardDiff
using Calculus
using LinearMaps

nx=21
nz=21
nt=4
nznx=nz*nx
mgrid=[range(-div(nz,2), step=1.0, length=nz), range(-div(nx,2), step=1.0, length=nx)]
tgrid=range(0.0,step=0.5, length=nt)
@info "Grids are all set."

Qv=abs.(randn(nz,nx))
η=abs.(randn(nz,nx))
k=abs.(randn(nz,nx))
σ=abs.(randn(nz,nx))
p=randn(nz,nx,nt)

σobs=abs.(randn(nz,nx))
Qobs=abs.(randn(nz,nx))
nr=10 # number of abstract receivers
ACQ=sprandn(nr,nz*nx,0.6); # choose a random acquisition operator
@info "We are ready for the PoissonExpt."

paE=PoissonExpt(p, tgrid, mgrid, Qv, k, η, σ, ACQ, σobs=σobs, Qobs=Qobs,)
F=LinearMap(paE, σ); # extract the linearized forward operator from `Expt`
GeoPhyInv.Utils.test_linearmap(F) # finally do some tests on the linearmap

δx=randn(size(F,2)) # random model pertubation
δd=F*δx # corresponding pertubation in data
@info string("Length of data: (nt*nr)=",length(δd))


text:
using Plots

@testset "Plotting" begin
    println("Plotting 1D data")
    plot(wave_z)
    plot(metrics_x)
    plot(metrics_y; isppa=true)
    plot(metrics_z; isppa=true, ispta=true)
    checkpoint_1d_reached = true
    @test checkpoint_1d_reached

    println("Plotting 2D data")
    plot(wave_yz)
    plot(metrics_xy)
    plot(metrics_xz; isppa=true)
    plot(metrics_yz; isppa=true, ispta=true, mi=true)
    checkpoint_2d_reached = true
    @test checkpoint_2d_reached

    println("Plotting 3D data")
    plot(wave_xyz)
    plot(metrics_xyz; xslice=0u"mm")
    plot(metrics_xyz; yslice=20u"mm")
    plot(metrics_xyz; zslice=40u"mm")
    checkpoint_3d_reached = true
    @test checkpoint_3d_reached

    println("Plotting 2D data with descending axis coordinates")
    plot(wave_yz_descending_coords)
    plot(metrics_yz_descending_coords; isppa=true, ispta=true, mi=true)
    checkpoint_2d_descending_coords_reached = true
    @test checkpoint_2d_descending_coords_reached

    println("Plotting 3D data with descending axis coordinates")
    plot(wave_xyz_descending_coords)
    plot(mertrics_xyz_descending_coords; xslice=0u"mm")
    plot(mertrics_xyz_descending_coords; yslice=20u"mm")
    plot(mertrics_xyz_descending_coords; zslice=40u"mm")
    checkpoint_3d_descending_coords_reached = true
    @test checkpoint_3d_descending_coords_reached
end


text:
include("random.jl")

"""Approximates Pi using the Monte-Carlo method over n iterations."""
function monte_carlo(n :: Int64) :: Float64
    p = 0
    for i = 0 : (n - 1)
        x = random::rand()
        y = random::rand()
        if (x * x + y * y < 1.)
            p = p + 1
        end
    end
    return div(4 * p + 0., n + 0.)
end


text:
# # How to make your data type reducible
#
# Let's see how to make a vector-of-vector a [reducible
# collection](@ref Glossary); i.e., a type that can be fed to
# [`foldl`](@ref).

struct VecOfVec{T}
    vectors::Vector{Vector{T}}
end

# We need [`@next`](@ref Transducers.@next) and [`complete`](@ref
# Transducers.complete) to invoke the reducing function `rf`.

using Transducers
using Transducers: @next, complete

# Supporting [`foldl`](@ref) and similar only requires
# [`Transducers.__foldl__`](@ref):

function Transducers.__foldl__(rf, val, vov::VecOfVec)
    for vector in vov.vectors
        for x in vector
            val = @next(rf, val, x)
        end
    end
    return complete(rf, val)
end

# Note that it's often a good idea to implement `Base.eltype`:

Base.eltype(::VecOfVec{T}) where {T} = T

# It can be then used as the input to the transducers:

vov = VecOfVec(collect.([1:n for n in 1:3]))
collect(Map(identity), vov)

# Macro `@next` is used instead of function [`next`](@ref
# Transducers.next) to avoid the boilerplate for supporting early
# termination (see the details in in [`@next`](@ref Transducers.@next)
# documentation).  In practice, using `@next` means that your
# `__foldl__` supports early termination:

collect(Take(3), vov)

# More complex example:

collect(PartitionBy(isequal(1)) |> Zip(Map(copy), Map(sum)), vov)

# Notice that writing [`Transducers.__foldl__`](@ref) is very
# straightforward comparing to how to define an iterator:

function Base.iterate(vov::VecOfVec, state=(1, 1))
#+
# Iterator `state` is a tuple of an index `i` to `vov.vectors` and an
# index `j` to `vov.vectors[i]`:
    i, j = state
#+
# If `i` is larger than the number of items, we are done:
    i > length(vov.vectors) && return nothing
#+
# If `j` is in bound, we are iterating the same sub-vector:
    vi = vov.vectors[i]
    if j <= length(vi)
        return vi[j], (i, j + 1)
    end
#+
# Otherwise, find the next non-empty sub-vector and start iterating it:
    for k in i + 1:length(vov.vectors)
        vk = vov.vectors[k]
        if !isempty(vk)
            return vk[1], (k, 2)  # i=k, j=2
        end
    end
    return nothing
end

Base.length(vov::VecOfVec) = sum(length, vov.vectors)

collect(vov)


text:
include("mpii.annotation.reader.jl")
include("../helper.jl")
include("../models.jl")
include("loss.jl")
include("../utils.jl")
include("variant.data.jl")
using Images, FileIO, ImageDraw
using Knet

function run_visualizer(
    model_location_name = "29-12-20-training_model",
    Knet_data_location_name = "29-12-20-dval";
    visualization_idxs = 1:10,
    pred_threshold = 0.2,
    focus_on_argmax = false,
    add_loc_ref_offset = false,
    show_only_predictions = false,
    show_body_skeleton = false,
)
    model = Knet.load("$(model_name).jld2", model_name)
    dval = Knet.load("$(Knet_data_location_name).jld2", Knet_data_location_name)

    visualize_part_detection_results(
        model,
        data;
        pred_threshold = pred_threshold,
        focus_on_argmax = focus_on_argmax,
        add_loc_ref_offset = add_loc_ref_offset,
        show_only_predictions = show_only_predictions,
        visualization_idxs = visualization_idxs,
        show_body_skeleton = show_body_skeleton,
    )
end

# TODO: Can we add heatmap like visualization
function visualize_part_detection_results(
    model,
    data;
    visualization_idxs = 1:10,
    pred_threshold = 0.2,
    focus_on_argmax = false,
    add_loc_ref_offset = false,
    show_only_predictions = false,
    show_body_skeleton = false,
    should_color_scmap_for_gt = true,
)

    if isa(data, VariantData)

        for (i, (x, y_gold)) in enumerate(data)
            output = Array{Float32}(model(x))
            img = reduce_dim(Array(x))

            # TODO: you can make below seperate functions
            if !show_only_predictions
                gt_scmap = Array(y_gold)
                gt_images = show_scmap_on_image(
                    img,
                    gt_scmap;
                    confidence_threshold = 0.5,
                    should_use_scmap_size = false,
                    return_single_image = show_body_skeleton,
                    should_color_scmap = should_color_scmap_for_gt,
                )

                if (show_body_skeleton)
                    gt_images = draw_body_skeleton(gt_images, gt_scmap)
                end

                println("****** GROUND TRUTH ******")
                show_body_skeleton ? display(gt_images) : mosaicify(gt_images)
            end

            pred_scmap = output[:, :, :, 1]
            pred_images = show_scmap_on_image(
                img,
                pred_scmap;
                confidence_threshold = pred_threshold,
                should_use_scmap_size = false,
                focus_on_argmax = focus_on_argmax,
                add_loc_ref_offset = add_loc_ref_offset,
                return_single_image = show_body_skeleton,
            )

            if (show_body_skeleton)
                pred_images = draw_body_skeleton(pred_images, pred_scmap)
            end

            println("****** PART PREDICTIONS ******")
            show_body_skeleton ? display(pred_images) : mosaicify(pred_images)
        end
    else
        data_x = Knet.atype()(reshape(data.x[:, visualization_idxs], data.xsize))
        data_y = Knet.atype()(reshape(data.y[:, visualization_idxs], data.ysize))
        output = model(data_x)
        output = Array(output)
        for idx = 1:length(visualization_idxs)
            img = Array(data_x[:, :, :, idx])
            if !show_only_predictions
                gt_scmap = Array(data_y[:, :, :, idx])
                gt_images = show_scmap_on_image(
                    img,
                    gt_scmap;
                    confidence_threshold = 0.5,
                    should_use_scmap_size = false,
                    return_single_image = show_body_skeleton,
                    should_color_scmap = should_color_scmap_for_gt,
                )

                if (show_body_skeleton)
                    gt_images = draw_body_skeleton(gt_images, gt_scmap)
                end

                println("****** GROUND TRUTH ******")
                show_body_skeleton ? display(gt_images) : mosaicify(gt_images)
            end
            pred_scmap = output[:, :, :, idx]
            pred_images = show_scmap_on_image(
                img,
                pred_scmap;
                confidence_threshold = pred_threshold,
                should_use_scmap_size = false,
                focus_on_argmax = focus_on_argmax,
                add_loc_ref_offset = add_loc_ref_offset,
                return_single_image = show_body_skeleton,
            )

            if (show_body_skeleton)
                pred_images = draw_body_skeleton(pred_images, pred_scmap)
            end

            println("****** PART PREDICTIONS ******")
            show_body_skeleton ? display(pred_images) : mosaicify(pred_images)
        end

    end
end

function draw_body_skeleton(img, scmap)
    colors = [
        RGB{Float32}(0.9, 0.1, 0.1),
        RGB{Float32}(0.1, 0.9, 0.1),
        RGB{Float32}(0.1, 0.1, 0.9),
        RGB{Float32}(0.4, 0.1, 0.1),
        RGB{Float32}(0.1, 0.4, 0.1),
        RGB{Float32}(0.1, 0.1, 0.4),
        RGB{Float32}(0.2, 0.6, 0.2),
    ]

    all_joints = [
        [1, 2],
        [2, 3],
        [3, 4],
        [4, 5],
        [5, 6],
        [7, 8],
        [8, 9],
        [9, 10],
        [3, 9],
        [4, 10],
        [10, 11],
        [11, 12],
        [13, 14],
    ]

    for (i, (joint_group)) in enumerate(all_joints)
        color_idx = i % length(colors) + 1
        color = colors[color_idx]
        joint_1 = joint_group[1]
        joint_2 = joint_group[2]
        pred_f8_1 = fetch_loc_reffed_max_point(scmap, joint_1)
        pred_f8_2 = fetch_loc_reffed_max_point(scmap, joint_2)
        img = draw!(img, LineSegment(pred_f8_1, pred_f8_2), color)
    end
    return img
end


text:
include("test_mapreduce.jl")
include("test_map.jl")
include("perf.jl")


text:
using Documenter, DynamicGridsInteract

makedocs(
    sitename = "DynamicGridsInteract.jl",
)

deploydocs(
    repo = "github.com/cesaraustralia/DynamicGridsInteract.jl.git",
)


text:
using Knet, KnetModules
# for correct dispatch
import KnetModules.forward

#=
Declare a simple cnn model.
=#
type MyCNN <: KnetModule
    c1::Conv;    bc1::BatchNorm
    c2::Conv;    bc2::BatchNorm
    c3::Conv;    bc3::BatchNorm
    fc1::Linear; bfc1::BatchNorm
    fc2::Linear
end

MyCNN(;chs=[16,32,64], hsize=100, nclasses=10) = MyCNN(
    Conv(3,3,3,     chs[1];  padding=1, bias=false), BatchNorm(chs[1]),
    Conv(3,3,chs[1],chs[2];  padding=1, bias=false), BatchNorm(chs[2]),
    Conv(3,3,chs[2],chs[3];  padding=1, bias=false), BatchNorm(chs[3]),
    Linear(hsize, 8 * 8 * chs[3]; bias=false),       BatchNorm(hsize),
    Linear(10, hsize)
)

# Forward pass executes a regular julia code with macros, functions
# and program control if necessary
function forward(ctx, m::MyCNN, x)
    x = pool(relu.(@mc m.bc1(@mc m.c1(x))))
    x = pool(relu.(@mc m.bc2(@mc m.c2(x))))
    x = relu.(@mc m.bc3(@mc m.c3(x)))
    x = relu.(@mc m.bfc1(@mc m.fc1(x)))
    return @mc m.fc2(x)
end

# Load the data
include(Pkg.dir("Knet", "data", "cifar.jl"))

function loaddata()
    xtrn, ytrn, xtst, ytst = cifar10()
    mn = mean(xtrn, 4)
    xtrn = xtrn .- mn
    xtst = xtst .- mn
    return (xtrn, ytrn), (xtst, ytst)
end

const atype = gpu() >= 0 ? KnetArray : Array

# Perform training
function epoch!(model, gradfn, dtrn, optims;  mbatch=64)
    data = minibatch(dtrn[1], dtrn[2], mbatch;
                     shuffle=true,
                     xtype=atype)

    for (x, y) in data
        # Note the gradfn call just needs data
        grads = gradfn(x, y)
        update!(model, grads, optims)
    end
end

# Accuracy computation
function acc(model, xtst, ytst; mbatch=64)
    data = minibatch(xtst, ytst, mbatch;
                     partial=true,
                     xtype=atype)
    # Accuracy can directly take model and data
    return accuracy(model, data; average=true)
end

function report(epoch, model, dtrn, dtst)
    println("epoch: ", epoch)
    println("training accuracy ", acc(model, dtrn...))
    println("test accuracy ",     acc(model, dtst...))
end

function train(;epochs=5,
               checkpoint_filename="cnn_train",
               start_epoch=0,
               from_checkpoint=false)
    dtrn, dtst = loaddata()
    jld_file(epoch) = string(checkpoint_filename, "_epoch_",
                             epoch, ".jld")
    #model = MyCNN()
    if from_checkpoint && start_epoch > 0
        # ctx switch -> clean up the old model contents
        model = load_module(jld_file(start_epoch); ctx_switch=true)
    else
        model = MyCNN()
    end
    gpu!(model) # ignored if gpu id is -1
    gradfn = grad(model, nll)
    optims = optimizers(model, Momentum; lr=.1)
    for i = 1:epochs
        epoch!(model, gradfn, dtrn, optims)
        report(i, model, dtrn, dtst)
        info("Backing up model...")
        save_module(jld_file(start_epoch+i), model)
        println()
    end
    return model
end

endswith(string(PROGRAM_FILE), "cnn.jl") && train()


text:
# ellipse to multiple forward simulated shapes
# only final landmark positions observed

using Revise
using BridgeLandmarks
using Random
using Distributions
using StaticArrays
using LinearAlgebra
using JLD2

workdir = @__DIR__
println(workdir)
cd(workdir)

n = 40  # in the final experiment we'll take n = 18
nshapes = 1
T = 1.0

a = 1.0     # Hamiltonian kernel parameter (the larger, the stronger landmarks behave similarly)
c = 0.1     # multiplicative factor in kernel
γ = 0.7     # Noise level

xobs0 = [PointF(2.0cos(t), sin(t))  for t in collect(0:(2pi/n):2pi)[2:end]]

θ, ψ =  π/3, 0.2
rot =  SMatrix{2,2}(cos(θ), sin(θ), -sin(θ), cos(θ))
stretch = SMatrix{2,2}(1.0 + ψ, 0.0, 0.0, 1.0 - ψ)
shift = [0.2, 0.0]
#xobsT = [rot * stretch * xobs0[i] + shift  for i in 1:n ]
#xobsT = α*[rot*stretch*PointF(cos(t)^3, sin(t)^3)  + shift for t in collect(0:(2pi/n):2pi)[2:end]]

# α = 1.2
# xobs0 = α*[rot*stretch*PointF(cos(t)^3, sin(t)^3)  + shift for t in collect(0:(2pi/n):2pi)[2:end]]
#
 P = MarslandShardlow(1.0, 2.0, 0.5, 0.0, n)
 Random.seed!(2)
 initmom = 0.5*randn(PointF,length(xobs0))

 x0 = State(xobs0, initmom)
 W,X = BridgeLandmarks.landmarksforward(collect(0.0:0.001:0.5), x0, P)
 xobsT = [BridgeLandmarks.q(X[end][2])[j] for j ∈ 1:n]

# template matching
# x0 = []
# nshapes = 2
# xobsT = [xobs0, xobsT]

JLD2.@save "data_exp1_hard.jld2" xobs0 xobsT n nshapes


text:
export filterwav
export splitwav
export spectrum

function filterwav(data, α)
    n = length(data)
    @. data[1:n-1] = data[2:n] - α * data[1:n-1]
    data[n] = data[n-1]
    return data
end

function splitwav(data, win, winlen::Int, stride::Int)
    nframes  = div(length(data)-winlen, stride) + 1
    firstIds = (0:(nframes-1)) .* stride .+ 1   # 帧起始下标
    lasstIds = firstIds .+ (winlen - 1)         # 帧结束下标
    frames   = zeros(eltype(data), winlen, nframes)
    for i = 1:nframes
        frames[:,i] = data[firstIds[i]:lasstIds[i]] .* win
    end
    return frames, nframes
end

function spectrum(data, win, winlen::Int, stride::Int, nffts::Int)
    # @assert nffts>=winlen
    T = div(length(data)-winlen, stride) + 1   # nframs
    F = nffts>>1                               # max effective freq bin index
    firstIds = (0:(T-1)) .* stride .+ 1        # 帧起始下标
    lasstIds = firstIds .+ (winlen - 1)        # 帧结束下标
    frames   = zeros(eltype(data), nffts, T)   # 如果 nffts>winlen 则零填充帧
    for i = 1:T
        frames[1:winlen,i] = data[firstIds[i]:lasstIds[i]] .* win
    end
    C = fft(frames, 1)       # 时域到频域 𝐑ⁿ ↣ 𝐂ⁿ ,按列计算
    X = abs2.(C[1:F,1:T])    # 功率谱,提取有用部分
    return X
end


text:
# instantiate environment
using Pkg; Pkg.instantiate()

using DataFrames
using PrettyTables
using ColorSchemes
using CSV

# valid colors for the integer range 1, 2, ..., kmax
function color(k, kmax)
  cs = reverse(colorschemes[:nuuk])
  nc = length(cs)
  i = ceil(Int, (k / kmax) * nc)
  R = round(Int,cs[i].r*255)
  G = round(Int,cs[i].g*255)
  B = round(Int,cs[i].b*255)
  R, G, B
end

# -------------
# MAIN SCRIPT
# -------------

# load results table
df = CSV.read(joinpath(@__DIR__,"newzealand.csv"))

# index of source, target, and error estimate columns
serror, terror, errors = 2, 3, 4:6

# enable/disable LaTeX output
print_latex = true

# highlight table entries
function best(d, i, j)
  k = argmin([abs(d[i,k] - d[i,terror]) for k in errors])
  j ∈ errors && errors[k] == j
end
function worst(d, i, j)
  k = argmax([abs(d[i,k] - d[i,terror]) for k in errors])
  j ∈ errors && errors[k] == j
end
function target(d, i, j)
  j == terror
end
hb  = Highlighter(best, bold=true, foreground=:blue)
hw  = Highlighter(worst, bold=true, foreground=:red)
ht  = Highlighter(target, bold=true)
hbl = LatexHighlighter(best, ["color{NavyBlue}","textbf"])
hwl = LatexHighlighter(worst, ["color{Maroon}","textbf"])
htl = LatexHighlighter(target, ["textbf"])

for g in groupby(df, :SHIFT)
  # shift and number of models
  s = g[1,:SHIFT] == "YES" ? "onoff" : "noshift"
  n = size(g, 1)

  # drop shift column
  g = g[!,Not(:SHIFT)]

  pretty_table(g, nosubheader=true, crop=:none, vlines=[0,1,3,6],
               alignment=[:c,:r,:r,:r,:r,:r],
               formatters=ft_round(3, serror ∪ terror ∪ errors),
               highlighters=(hb, hw, ht))

  if print_latex
    open("newzealand-$s.tex", "w") do io
      pretty_table(io, g, backend=:latex, tf=latex_simple,
                   nosubheader=true, alignment=:c, vlines=[1,3],
                   formatters=ft_round(3, serror ∪ terror ∪ errors),
                   highlighters=(hbl, hwl, htl))
    end
  end

  # model ranking based on each method
  ranks = map([:TARGET,:CV,:BCV,:DRV]) do err
    r = sortperm(g[!,err])
    Symbol(err," RANK") => g[!,:MODEL][r]
  end
  r = DataFrame(ranks)

  colorval(k) = color(k, n)
  hs = Tuple([Highlighter((d, i, j) -> d[i,j] == r[k,Symbol("TARGET RANK")],
             background=colorval(k), foreground=:black) for k in 1:n])
  pretty_table(r, nosubheader=true, crop=:none, alignment=:c, highlighters=hs)

  if print_latex
    colorstr(k) = "cellcolor[RGB]{" * join(color(k, n), ",") * "}"
    hs = Tuple([LatexHighlighter((d, i, j) -> d[i,j] == r[k,Symbol("TARGET RANK")],
               [colorstr(k), "color{white}", "textbf"]) for k in 1:n])
    open("newzealand-rank-$s.tex", "w") do io
      pretty_table(io, r, backend=:latex, tf=latex_simple,
                   nosubheader=true, alignment=:c, highlighters=hs)
    end
  end
end

max_issues_repo_name: IBM/geostats-gen-error

max_forks_repo_name: IBM/geostats-gen-error


text:
using JuMP
using Cbc
using Test

export sudoku_model
export sudoku_fix_cells
export sudoku_table
export test_sudoku_model

const I = 1:9
const J = 1:9
const K = 1:9

function sudoku_model()
    model = Model()
    @variable(model, x[I, J, K], Bin)
    # --- Student's task ---
    # TODO: Implement constraints
    @constraint(model, [i in I, j in J], sum(x[i, j, k] for k in K) == 1)
    @constraint(model, [j in J, k in K], sum(x[i, j, k] for i in I) == 1)
    @constraint(model, [i in I, k in K], sum(x[i, j, k] for j in J) == 1)
    @constraint(model, [k in K, m in 1:3, n in 1:3],
        sum(sum(x[i, j, k] for j in (3m-2):(3m)) for i in (3n-2):3n) == 1)
    # TODO: implement objective function
    @objective(model, Min, 1)
    # --- end of task ---
    return model
end

function sudoku_fix_cells(model, fixed::Array{NTuple{3, Int}})
    x = model[:x]
    @constraint(model, [(i, j, k) in fixed], x[i, j, k] == 1)
end

function sudoku_table(model)
    x_value = value.(model[:x])
    return [findmax(collect(x_value[i, j, :]))[2] for i in I, j in J]
end

function test_sudoku_model()
    @info "Creating the sudoku model"
    model = sudoku_model()
    sudoku_fix_cells(model, [
        (1,2,6), (1,4,1), (1,6,4), (1,8,5), (2,3,8), (2,4,3), (2,6,5), (2,7,6),
        (3,1,2), (3,7,7), (4,1,8), (4,4,4), (4,6,7), (4,9,6), (5,3,6), (5,7,3),
        (6,1,7), (6,4,9), (6,6,1), (6,9,4), (7,1,5), (7,9,2), (8,3,7), (8,4,2),
        (8,6,6), (8,7,9), (9,2,4), (9,4,5), (9,6,8), (9,8,7)
    ])

    @info "Solving the sudoku"
    optimizer = optimizer_with_attributes(Cbc.Optimizer, "logLevel" => 0)
    set_optimizer(model, optimizer)
    optimize!(model)

    answer = sudoku_table(model)
    solution = [9 6 3 1 7 4 2 5 8;
                1 7 8 3 2 5 6 4 9;
                2 5 4 6 8 9 7 3 1;
                8 2 1 4 3 7 5 9 6;
                4 9 6 8 5 2 3 1 7;
                7 3 5 9 6 1 8 2 4;
                5 8 9 7 1 3 4 6 2;
                3 1 7 2 4 6 9 8 5;
                6 4 2 5 9 8 1 7 3]
    @info "Printing the result"
    @info answer
    @test answer == solution
end


text:
module VarianceComponentModelsTest
  include("multivariate_calculus_test.jl")
  include("variance_component_models_test.jl")
  include("two_variance_component_test.jl")
  #include("benchmark.jl")
end

max_stars_repo_name: Hua-Zhou/VarianceComponentModels

max_issues_repo_name: Hua-Zhou/VarianceComponentModels

max_forks_repo_name: Hua-Zhou/VarianceComponentModels


text:
module StencilFunctor

using Funs

export stencil_fmap

stencil_fmap{FT,C}(f::Callable, g::Callable, xs::FT, bm::C, bp::C;
        R::Type=eltype(f)) =
    error("stencil_fmap not specialized for type $FT")

# Array
function stencil_fmap{T,C}(f::Callable, g::Callable,
        xs::Vector{T}, bm::C, bp::C; R::Type=eltype(f))
    s = length(xs)
    rs = similar(xs, R)
    if s == 0
        # do nothing
    elseif s == 1
        @inbounds rs[1] = f(xs[1], bm, bp)
    else
        @inbounds rs[1] = f(xs[1], bm, g(xs[2], false))
        @simd for i in 2:s-1
            @inbounds rs[i] = f(xs[i], g(xs[i-1], true), g(xs[i+1], false))
        end
        @inbounds rs[s] = f(xs[s], g(xs[s-1], true), bp)
    end
    rs::Vector{R}
end

end


text:
struct MinDegreePermuter
    assumesymmetry::Bool
    checksymmetry::Bool
end

MinDegreePermuter(; assumesymmetry=false, checksymmetry=true) = MinDegreePermuter(assumesymmetry, checksymmetry)

function permute_stripe(A::Symmetric{Tv, SparseMatrixCSC{Tv, Ti}}, method::MinDegreePermuter) where {Tv, Ti}
    prm = AMD.symamd(SparseMatrixCSC(A))
    return DomainPermutation(prm)
end

function permute_stripe(A::SparseMatrixCSC, method::MinDegreePermuter)
    return permute_plaid(A, method)[end]
end

function permute_plaid(A::Symmetric{Tv, SparseMatrixCSC{Tv, Ti}}, method::MinDegreePermuter) where {Tv, Ti}
    prm = AMD.symamd(SparseMatrixCSC(A))
    return (DomainPermutation(prm), DomainPermutation(prm))
end

function permute_plaid(A::SparseMatrixCSC, method::MinDegreePermuter)
    m, n = size(A)
    if m == n
        if method.assumesymmetry || (method.checksymmetry && issymmetric(pattern(A)))
            prm = AMD.symamd(A)
            return (DomainPermutation(prm), DomainPermutation(prm))
        else
            prm = AMD.amd(A)
            return (DomainPermutation(prm), DomainPermutation(prm))
        end
    else
        B = hvcat((2, 2), spzeros(m, m), A, spzeros(n, m), spzeros(n, n))
        prm = AMD.amd(B)
        iprm = Int[]
        jprm = Int[]
        for v in prm
            if v > m
                push!(jprm, v - m)
            else
                push!(iprm, v)
            end
        end
        return (DomainPermutation(iprm), DomainPermutation(jprm))
    end
end

struct ColumnMinDegreePermuter
    assumesymmetry::Bool
    checksymmetry::Bool
end

ColumnMinDegreePermuter(; assumesymmetry=false, checksymmetry=true) = ColumnMinDegreePermuter(assumesymmetry, checksymmetry)

function permute_stripe(A::Symmetric{Tv, SparseMatrixCSC{Tv, Ti}}, method::ColumnMinDegreePermuter) where {Tv, Ti}
    prm = AMD.colamd(SparseMatrixCSC(A))
    return DomainPermutation(prm)
end

function permute_stripe(A::SparseMatrixCSC, method::ColumnMinDegreePermuter)
    prm = AMD.colamd(A)
    return DomainPermutation(prm)
end


text:
using ProtoBuf

type MyType
  x::Array{Float64,1}
  d::Dict{Int64,Int64}
  MyType() = new()
  MyType(a::Array{Float64,1},b::Dict{Int64,Int64}) = new(a,b)
end

type CompType
  mt::MyType
  str::ASCIIString
  CompType() = new()
  CompType(a::MyType,s::ASCIIString) = new(a,s)
end

iob  = PipeBuffer()

mt = MyType(rand(3),Dict{Int,Int}(1 => 10, 2 => 20))
s = ASCIIString("Hello world.")
ct = CompType(mt,s)

writeproto(iob, ct)
dd = readproto(iob, CompType())

@time writeproto(iob, ct)
@time dd = readproto(iob, CompType())


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

export
    #avutil_version,
    avutil_configuration,
    avutil_license,
    av_get_picture_type_char

function avutil_version()
    ccall((:avutil_version,libavutil),UInt32,())
end

function avutil_configuration()
    ccall((:avutil_configuration,libavutil),Ptr{UInt8},())
end

function avutil_license()
    ccall((:avutil_license,libavutil),Ptr{UInt8},())
end

function av_get_picture_type_char(pict_type::AVPictureType)
    ccall((:av_get_picture_type_char,libavutil),UInt8,(AVPictureType,),pict_type)
end

max_stars_repo_name: asafasban/AAVideoIO

max_issues_repo_name: asafasban/AAVideoIO

max_forks_repo_name: asafasban/AAVideoIO


text:
"""
    AnimeContainer(interval::Int, frames::Vector{String}, animate_type::String)

Construct an `AnimeContainer`, animation container literally.
"""
mutable struct AnimeContainer
    interval::Int
    frames::Vector{String}
    animate_type::String

    function AnimeContainer(interval::Int, frames::Vector{String}, animate_type::String)
        self = new()
        self.interval = interval
        self.frames = frames
        self.animate_type = animate_type

        return self
    end
end

# Animes from cli-spinners goes here...

const dots = AnimeContainer(
    80,
    [
        "⠋",
        "⠙",
        "⠹",
        "⠸",
        "⠼",
        "⠴",
        "⠦",
        "⠧",
        "⠇",
        "⠏"
     ],
    "linear"
)

const dots2 = AnimeContainer(
    80,
    [
        "⣾",
        "⣽",
        "⣻",
        "⢿",
        "⡿",
        "⣟",
        "⣯",
        "⣷"
     ],
    "linear"
)

const dots3 = AnimeContainer(
    80,
    [
        "⠋",
        "⠙",
        "⠚",
        "⠞",
        "⠖",
        "⠦",
        "⠴",
        "⠲",
        "⠳",
        "⠓"
     ],
    "linear"
)

const dots4 = AnimeContainer(
    80,
    [
        "⠄",
        "⠆",
        "⠇",
        "⠋",
        "⠙",
        "⠸",
        "⠰",
        "⠠",
        "⠰",
        "⠸",
        "⠙",
        "⠋",
        "⠇",
        "⠆"
     ],
    "linear"
)

const dots5 = AnimeContainer(
    80,
    [
        "⠋",
        "⠙",
        "⠚",
        "⠒",
        "⠂",
        "⠂",
        "⠒",
        "⠲",
        "⠴",
        "⠦",
        "⠖",
        "⠒",
        "⠐",
        "⠐",
        "⠒",
        "⠓",
        "⠋"
     ],
    "linear"
)

const dots6 = AnimeContainer(
    80,
    [
        "⠁",
        "⠉",
        "⠙",
        "⠚",
        "⠒",
        "⠂",
        "⠂",
        "⠒",
        "⠲",
        "⠴",
        "⠤",
        "⠄",
        "⠄",
        "⠤",
        "⠴",
        "⠲",
        "⠒",
        "⠂",
        "⠂",
        "⠒",
        "⠚",
        "⠙",
        "⠉",
        "⠁"
      ],
    "linear"
)

const dots7 = AnimeContainer(
    80,
    [
        "⠈",
        "⠉",
        "⠋",
        "⠓",
        "⠒",
        "⠐",
        "⠐",
        "⠒",
        "⠖",
        "⠦",
        "⠤",
        "⠠",
        "⠠",
        "⠤",
        "⠦",
        "⠖",
        "⠒",
        "⠐",
        "⠐",
        "⠒",
        "⠓",
        "⠋",
        "⠉",
        "⠈"
      ],
    "linear"
)

const dots8 = AnimeContainer(
    80,
    [
        "⠁",
        "⠁",
        "⠉",
        "⠙",
        "⠚",
        "⠒",
        "⠂",
        "⠂",
        "⠒",
        "⠲",
        "⠴",
        "⠤",
        "⠄",
        "⠄",
        "⠤",
        "⠠",
        "⠠",
        "⠤",
        "⠦",
        "⠖",
        "⠒",
        "⠐",
        "⠐",
        "⠒",
        "⠓",
        "⠋",
        "⠉",
        "⠈",
        "⠈"
      ],
    "linear"
)

const dots9 = AnimeContainer(
    80,
    [
        "⢹",
        "⢺",
        "⢼",
        "⣸",
        "⣇",
        "⡧",
        "⡗",
        "⡏"
     ],
    "linear"
)

const dots10 = AnimeContainer(
    80,
    [
        "⢄",
        "⢂",
        "⢁",
        "⡁",
        "⡈",
        "⡐",
        "⡠"
     ],
    "linear"
)

const dots11 = AnimeContainer(
    100,
    [
        "⠁",
        "⠂",
        "⠄",
        "⡀",
        "⢀",
        "⠠",
        "⠐",
        "⠈"
     ],
    "linear"
)

const dots12 = AnimeContainer(
    80,
    [
        "⢀⠀",
        "⡀⠀",
        "⠄⠀",
        "⢂⠀",
        "⡂⠀",
        "⠅⠀",
        "⢃⠀",
        "⡃⠀",
        "⠍⠀",
        "⢋⠀",
        "⡋⠀",
        "⠍⠁",
        "⢋⠁",
        "⡋⠁",
        "⠍⠉",
        "⠋⠉",
        "⠋⠉",
        "⠉⠙",
        "⠉⠙",
        "⠉⠩",
        "⠈⢙",
        "⠈⡙",
        "⢈⠩",
        "⡀⢙",
        "⠄⡙",
        "⢂⠩",
        "⡂⢘",
        "⠅⡘",
        "⢃⠨",
        "⡃⢐",
        "⠍⡐",
        "⢋⠠",
        "⡋⢀",
        "⠍⡁",
        "⢋⠁",
        "⡋⠁",
        "⠍⠉",
        "⠋⠉",
        "⠋⠉",
        "⠉⠙",
        "⠉⠙",
        "⠉⠩",
        "⠈⢙",
        "⠈⡙",
        "⠈⠩",
        "⠀⢙",
        "⠀⡙",
        "⠀⠩",
        "⠀⢘",
        "⠀⡘",
        "⠀⠨",
        "⠀⢐",
        "⠀⡐",
        "⠀⠠",
        "⠀⢀",
        "⠀⡀"
      ],
    "linear"
)

const line = AnimeContainer(
    130,
     [
        "-",
        "\\",
        "|",
        "/"
     ],
    "linear"
)

const line2 = AnimeContainer(
    100,
    [
        "⠂",
        "-",
        "–",
        "—",
        "–",
        "-"
    ],
    "linear"
)

const pipe = AnimeContainer(
    100,
    [
        "┤",
        "┘",
        "┴",
        "└",
        "├",
        "┌",
        "┬",
        "┐"
     ],
    "linear"
)

const simpleDots = AnimeContainer(
    400,
    [
        ".  ",
        ".. ",
        "...",
        "   "
     ],
    "linear"
)

const simpleDotsScrolling = AnimeContainer(
    200,
    [
        ".  ",
        ".. ",
        "...",
        " ..",
        "  .",
        "   "
    ],
    "linear"
)

const star = AnimeContainer(
    70,
    [
        "✶",
        "✸",
        "✹",
        "✺",
        "✹",
        "✷"
    ],
    "linear"
)

const star2 = AnimeContainer(
    80,
    [
        "+",
        "x",
        "*"
     ],
    "linear"
)

const flip = AnimeContainer(
    70,
    [
        "_",
        "_",
        "_",
        "-",
        "`",
        "`",
        "'",
        "´",
        "-",
        "_",
        "_",
        "_"
     ],
    "linear"
)

const hamburger = AnimeContainer(
    100,
    [
        "☱",
        "☲",
        "☴"
     ],
    "linear"
)

const growVertical = AnimeContainer(
    120,
    [
        "▁",
        "▃",
        "▄",
        "▅",
        "▆",
        "▇",
        "▆",
        "▅",
        "▄",
        "▃"
     ],
    "linear"
)

const growHorizontal = AnimeContainer(
    120,
    [
        "▏",
        "▎",
        "▍",
        "▌",
        "▋",
        "▊",
        "▉",
        "▊",
        "▋",
        "▌",
        "▍",
        "▎"
     ],
     "linear"
)

const balloon = AnimeContainer(
    140,
    [
        " ",
        ".",
        "o",
        "O",
        "@",
        "*",
        " "
     ],
    "linear"
)

const balloon2 = AnimeContainer(
    120,
    [
        ".",
        "o",
        "O",
        "°",
        "O",
        "o",
        "."
     ],
    "linear"
)

const noise = AnimeContainer(
    100,
    [
        "▓",
        "▒",
        "░"
     ],
    "linear"
)

const bounce = AnimeContainer(
    120,
    [
        "⠁",
        "⠂",
        "⠄",
        "⠂"
     ],
    "linear"
)

const boxBounce = AnimeContainer(
    120,
    [
        "▖",
        "▘",
        "▝",
        "▗"
     ],
    "linear"
)

const boxBounce2 = AnimeContainer(
    100,
    [
        "▌",
        "▀",
        "▐",
        "▄"
     ],
    "linear"
)

const triangle = AnimeContainer(
    50,
    [
        "◢",
        "◣",
        "◤",
        "◥"
     ],
    "linear"
)

const arc = AnimeContainer(
    100,
    [
        "◜",
        "◠",
        "◝",
        "◞",
        "◡",
        "◟"
     ],
    "linear"
)

const circle = AnimeContainer(
    120,
    [
        "◡",
        "⊙",
        "◠"
    ],
    "linear"
)

const squareCorners = AnimeContainer(
    180,
    [
        "◰",
        "◳",
        "◲",
        "◱"
    ],
    "linear"
)

const circleQuarters = AnimeContainer(
    120,
    [
        "◴",
        "◷",
        "◶",
        "◵"
    ],
    "linear"
)

const circleHalves = AnimeContainer(
    50,
    [
        "◐",
        "◓",
        "◑",
        "◒"
    ],
    "linear"
)

const squish = AnimeContainer(
    100,
    [
        "╫",
        "╪"
    ],
    "linear"
)

const toggle = AnimeContainer(
    250,
    [
        "⊶",
        "⊷"
    ],
    "linear"
)

const toggle2 = AnimeContainer(
    80,
    [
        "▫",
        "▪"
    ],
    "linear"
)

const toggle3 = AnimeContainer(
    120,
    [
        "□",
        "■"
    ],
    "linear"
)

const toggle4 = AnimeContainer(
    100,
    [
        "■",
        "□",
        "▪",
        "▫"
    ],
    "linear"
)

const toggle5 = AnimeContainer(
    100,
    [
        "▮",
        "▯"
    ],
    "linear"
)

const toggle6 = AnimeContainer(
    300,
    [
        "ဝ",
        "၀"
    ],
    "linear"
)

const toggle7 = AnimeContainer(
    80,
    [
        "⦾",
        "⦿"
    ],
    "linear"
)

const toggle8 = AnimeContainer(
    100,
    [
        "◍",
        "◌"
    ],
    "linear"
)

const toggle9 = AnimeContainer(
    100,
    [
        "◉",
        "◎"
    ],
    "linear"
)

const toggle10 = AnimeContainer(
    100,
    [
        "㊂",
        "㊀",
        "㊁"
    ],
    "linear"
)

const toggle11 = AnimeContainer(
    50,
    [
        "⧇",
        "⧆"
    ],
    "linear"
)

const toggle12 = AnimeContainer(
    120,
    [
        "☗",
        "☖"
    ],
    "linear"
)

const toggle13 = AnimeContainer(
    80,
    [
        "=",
        "*",
        "-"
    ],
    "linear"
)

const arrow = AnimeContainer(
    100,
    [
        "←",
        "↖",
        "↑",
        "↗",
        "→",
        "↘",
        "↓",
        "↙"
    ],
    "linear"
)

const arrow2 = AnimeContainer(
    80,
    [
        "⬆ ",
        "↗ ",
        "➡ ",
        "↘ ",
        "⬇ ",
        "↙ ",
        "⬅ ",
        "↖ "
    ],
    "linear"
)

const arrow3 = AnimeContainer(
    120,
    [
        "▹▹▹▹▹",
        "▸▹▹▹▹",
        "▹▸▹▹▹",
        "▹▹▸▹▹",
        "▹▹▹▸▹",
        "▹▹▹▹▸"
    ],
    "linear"
)

const bouncingBar = AnimeContainer(
    80,
    [
        "[    ]",
        "[=   ]",
        "[==  ]",
        "[=== ]",
        "[ ===]",
        "[  ==]",
        "[   =]",
        "[    ]",
        "[   =]",
        "[  ==]",
        "[ ===]",
        "[====]",
        "[=== ]",
        "[==  ]",
        "[=   ]"
    ],
    "linear"
)

const bouncingBall = AnimeContainer(
    80,
    [
        "( ●    )",
        "(  ●   )",
        "(   ●  )",
        "(    ● )",
        "(     ●)",
        "(    ● )",
        "(   ●  )",
        "(  ●   )",
        "( ●    )",
        "(●     )"
    ],
    "linear"
)

const smiley = AnimeContainer(
    200,
    [
        "😄 ",
        "😝 "
    ],
    "linear"
)

const monkey = AnimeContainer(
    300,
    [
        "🙈 ",
        "🙈 ",
        "🙉 ",
        "🙊 "
    ],
    "linear"
)

const hearts = AnimeContainer(
    100,
    [
        "💛 ",
        "💙 ",
        "💜 ",
        "💚 ",
        "❤ "
    ],
    "linear"
)

const clock = AnimeContainer(
    100,
    [
        "🕐 ",
        "🕑 ",
        "🕒 ",
        "🕓 ",
        "🕔 ",
        "🕕 ",
        "🕖 ",
        "🕗 ",
        "🕘 ",
        "🕙 ",
        "🕚 "
      ],
      "linear"
)

const earth = AnimeContainer(
    180,
    [
        "🌍 ",
        "🌎 ",
        "🌏 "
    ],
    "linear"
)

const moon = AnimeContainer(
    80,
    [
        "🌑 ",
        "🌒 ",
        "🌓 ",
        "🌔 ",
        "🌕 ",
        "🌖 ",
        "🌗 ",
        "🌘 "
    ],
    "linear"
)

const runner = AnimeContainer(
    140,
    [
        "🚶 ",
        "🏃 "
    ],
    "linear"
)

const pong = AnimeContainer(
    80,
    [
        "▐⠂       ▌",
        "▐⠈       ▌",
        "▐ ⠂      ▌",
        "▐ ⠠      ▌",
        "▐  ⡀     ▌",
        "▐  ⠠     ▌",
        "▐   ⠂    ▌",
        "▐   ⠈    ▌",
        "▐    ⠂   ▌",
        "▐    ⠠   ▌",
        "▐     ⡀  ▌",
        "▐     ⠠  ▌",
        "▐      ⠂ ▌",
        "▐      ⠈ ▌",
        "▐       ⠂▌",
        "▐       ⠠▌",
        "▐       ⡀▌",
        "▐      ⠠ ▌",
        "▐      ⠂ ▌",
        "▐     ⠈  ▌",
        "▐     ⠂  ▌",
        "▐    ⠠   ▌",
        "▐    ⡀   ▌",
        "▐   ⠠    ▌",
        "▐   ⠂    ▌",
        "▐  ⠈     ▌",
        "▐  ⠂     ▌",
        "▐ ⠠      ▌",
        "▐ ⡀      ▌",
        "▐⠠       ▌"
    ],
    "linear"
)

const shark = AnimeContainer(
    120,
    [
        "▐|\\____________▌",
        "▐_|\\___________▌",
        "▐__|\\__________▌",
        "▐___|\\_________▌",
        "▐____|\\________▌",
        "▐_____|\\_______▌",
        "▐______|\\______▌",
        "▐_______|\\_____▌",
        "▐________|\\____▌",
        "▐_________|\\___▌",
        "▐__________|\\__▌",
        "▐___________|\\_▌",
        "▐____________|\\▌",
        "▐____________/|▌",
        "▐___________/|_▌",
        "▐__________/|__▌",
        "▐_________/|___▌",
        "▐________/|____▌",
        "▐_______/|_____▌",
        "▐______/|______▌",
        "▐_____/|_______▌",
        "▐____/|________▌",
        "▐___/|_________▌",
        "▐__/|__________▌",
        "▐_/|___________▌",
        "▐/|____________▌"
    ],
    "linear"
)

const dqpb = AnimeContainer(
    100,
    [
        "d",
        "q",
        "p",
        "b"
    ],
    "linear"
)

const weather = AnimeContainer(
    100,
    [
        "☀ ",
        "☀ ",
        "☀ ",
        "🌤 ",
        "⛅ ",
        "🌥 ",
        "☁ ",
        "🌧 ",
        "🌨 ",
        "🌧 ",
        "🌨 ",
        "🌧 ",
        "🌨 ",
        "⛈ ",
        "🌨 ",
        "🌧 ",
        "🌨 ",
        "☁ ",
        "🌥 ",
        "⛅ ",
        "🌤 ",
        "☀ ",
        "☀ "
    ],
    "linear"
)

const christmas = AnimeContainer(
    400,
    [
        "🌲",
        "🎄"
    ],
    "linear"
)


text:
using Test
using Forecast
using Plots, RecipesBase

@testset "plots" begin

    # plot DataFrame
    @test typeof(plot(co2())) == Plots.Plot{Plots.GRBackend}

    # plot CCF
    @test typeof(plot(ccf(rand(100), rand(100)))) == Plots.Plot{Plots.GRBackend}

    # plot STL
    stl_co2 = stl(co2(),365; robust=true, spm=true)
    @test typeof(plot(stl_co2)) == Plots.Plot{Plots.GRBackend}

    # plot FORECAST
    @test typeof(plot(forecast(ar(rand(100),1),10))) == Plots.Plot{Plots.GRBackend}

end


text:
using APIGenerator
using Base.Test

info("Sorry, there aren't any real tests...yet")
@test true


text:
using CxxCall
using Documenter

DocMeta.setdocmeta!(CxxCall, :DocTestSetup, :(using CxxCall); recursive=true)

makedocs(;
    modules=[CxxCall],
    authors="Jan Weidner <jw3126@gmail.com> and contributors",
    repo="https://github.com/jw3126/CxxCall.jl/blob/{commit}{path}#{line}",
    sitename="CxxCall.jl",
    format=Documenter.HTML(;
        prettyurls=get(ENV, "CI", "false") == "true",
        canonical="https://jw3126.github.io/CxxCall.jl",
        assets=String[],
    ),
    pages=[
        "Home" => "index.md",
    ],
)

deploydocs(;
    repo="github.com/jw3126/CxxCall.jl",
    devbranch="main",
)


text:
# ******************************************************************************************
# Notices:
#
# Copyright © 2022 United States Government as represented by the Administrator of the
# National Aeronautics and Space Administration.  All Rights Reserved.
#
# Disclaimers
#
# No Warranty: THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY KIND,
# EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY
# THAT THE SUBJECT SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY
# WARRANTY THAT THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT DOCUMENTATION,
# IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE. THIS AGREEMENT DOES NOT, IN ANY MANNER,
# CONSTITUTE AN ENDORSEMENT BY GOVERNMENT AGENCY OR ANY PRIOR RECIPIENT OF ANY RESULTS,
# RESULTING DESIGNS, HARDWARE, SOFTWARE PRODUCTS OR ANY OTHER APPLICATIONS RESULTING FROM
# USE OF THE SUBJECT SOFTWARE.  FURTHER, GOVERNMENT AGENCY DISCLAIMS ALL WARRANTIES AND
# LIABILITIES REGARDING THIRD-PARTY SOFTWARE, IF PRESENT IN THE ORIGINAL SOFTWARE, AND
# DISTRIBUTES IT "AS IS."
#
# Waiver and Indemnity:  RECIPIENT AGREES TO WAIVE ANY AND ALL CLAIMS AGAINST THE UNITED
# STATES GOVERNMENT, ITS CONTRACTORS AND SUBCONTRACTORS, AS WELL AS ANY PRIOR RECIPIENT.
# IF RECIPIENT'S USE OF THE SUBJECT SOFTWARE RESULTS IN ANY LIABILITIES, DEMANDS, DAMAGES,
# EXPENSES OR LOSSES ARISING FROM SUCH USE, INCLUDING ANY DAMAGES FROM PRODUCTS BASED ON,
# OR RESULTING FROM, RECIPIENT'S USE OF THE SUBJECT SOFTWARE, RECIPIENT SHALL INDEMNIFY AND
# HOLD HARMLESS THE UNITED STATES GOVERNMENT, ITS CONTRACTORS AND SUBCONTRACTORS, AS WELL
# AS ANY PRIOR RECIPIENT, TO THE EXTENT PERMITTED BY LAW.  RECIPIENT'S SOLE REMEDY FOR ANY
# SUCH MATTER SHALL BE THE IMMEDIATE, UNILATERAL TERMINATION OF THIS AGREEMENT.
# ******************************************************************************************

#=
These functions automatically manage SSH tunneling, allowing a remote AdaStress architecture
to be established over secure channels. They do not need to be invoked directly, since they
are used by the `connect!` and `disconnect!` functions when the appropriate keyword
arguments are set.

The Linux/Apple version uses SSH multiplexing to maintain a handle on the SSH session, while
the Windows version stores the raw SSH process id.
=#

const TUNNEL_SOCK = Sys.iswindows() ? "" : joinpath(homedir(), ".ssh", "adastress.sock")
const TUNNEL_PROC = Ref(0)

"""
Open SSH tunnel to/from remote server.
"""
function open_tunnel(obj::Union{ASTClient, ASTServer}, remote::String, remote_port::Int64)
    (p1, p2, F) = obj isa ASTClient ? (obj.port, remote_port, "L") : (remote_port, obj.port, "R")

    if Sys.iswindows()
        ssh_args = "-$F $p1:localhost:$p2 $remote"
        pwsh_cmd = "(Start-Process ssh -Passthru -ArgumentList \"$ssh_args\").id"
        pipe = pipeline(`cmd /c powershell $pwsh_cmd`)
        out = read(pipe, String) # capturing the ssh pid
        TUNNEL_PROC[] = parse(Int64, match(r"\d*", out).match)
        @info """
        Enter credentials in pop-up terminal window, leave window open, and return to Julia.
        Press enter to continue...
        """
        readline()
    else
        ssh_args = `-fN -M -S $TUNNEL_SOCK -$F $p1:localhost:$p2 $remote`
        Base.run(`ssh $ssh_args`)
    end

    @info "Tunnel is open."
    obj.tunnel = true
    return
end

"""
Close SSH tunnel to/from remote server.
"""
function close_tunnel()
    if Sys.iswindows()
        pwsh_cmd = "kill $(TUNNEL_PROC[])"
        Base.run(`cmd /c powershell $pwsh_cmd`)
        TUNNEL_PROC[] = 0
    else
        ssh_args = `-S $TUNNEL_SOCK -O exit ""`
        Base.run(`ssh $ssh_args`)
    end
    @info "Tunnel is closed."
    return
end


text:
# Formatted Output (B.17)

export @cuprintf

const cuprintf_endline = Sys.iswindows() ? "\r\n" : "\n"

@generated function promote_c_argument(arg)
    # > When a function with a variable-length argument list is called, the variable
    # > arguments are passed using C's old ``default argument promotions.'' These say that
    # > types char and short int are automatically promoted to int, and type float is
    # > automatically promoted to double. Therefore, varargs functions will never receive
    # > arguments of type char, short int, or float.

    if arg == Cchar || arg == Cshort
        return :(Cint(arg))
    elseif arg == Cfloat
        return :(Cdouble(arg))
    else
        return :(arg)
    end
end

"""
Print a formatted string in device context on the host standard output:

    @cuprintf("%Fmt", args...)

Note that this is not a fully C-compliant `printf` implementation; see the CUDA
documentation for supported options and inputs.

Also beware that it is an untyped, and unforgiving `printf` implementation. Type widths need
to match, eg. printing a 64-bit Julia integer requires the `%ld` formatting string.
"""
macro cuprintf(fmt::String, args...)
    fmt_val = Val(Symbol(fmt))

    return :(_cuprintf($fmt_val, $(map(arg -> :(promote_c_argument($arg)), esc.(args))...)))
end

function cuprintf!(builder::Builder, fmt::String, params...)
    block = position(builder)
    llvm_f = LLVM.parent(block)
    mod = LLVM.parent(llvm_f)
    ctx = context(mod)

    T_int32 = LLVM.Int32Type(ctx)
    T_pint8 = LLVM.PointerType(LLVM.Int8Type(ctx))

    str = globalstring_ptr!(builder, fmt)

    # construct and fill args buffer
    if isempty(params)
        buffer = LLVM.PointerNull(T_pint8)
    else
        param_types = LLVMType[llvmtype.(params)...]
        argtypes = LLVM.StructType("printf_args", ctx)
        elements!(argtypes, param_types)

        args = alloca!(builder, argtypes)
        for (i, param) in enumerate(params)
            p = struct_gep!(builder, args, i-1)
            store!(builder, param, p)
        end

        buffer = bitcast!(builder, args, T_pint8)
    end

    vprintf = if haskey(functions(mod), "vprintf")
        functions(mod)["vprintf"]
    else
        vprintf_typ = LLVM.FunctionType(T_int32, [T_pint8, T_pint8])
        LLVM.Function(mod, "vprintf", vprintf_typ)
    end

    call!(builder, vprintf, [str, buffer])
end

@generated function _cuprintf(::Val{fmt}, argspec...) where {fmt}
    arg_exprs = [:( argspec[$i] ) for i in 1:length(argspec)]
    arg_types = [argspec...]

    T_int32 = LLVM.Int32Type(JuliaContext())

    # create the function
    param_types = LLVMType[convert.(LLVMType, arg_types)...]
    llvm_f, _ = create_function(T_int32, param_types)

    # generate IR
    Builder(JuliaContext()) do builder
        entry = BasicBlock(llvm_f, "entry", JuliaContext())
        position!(builder, entry)

        chars = cuprintf!(builder, String(fmt), parameters(llvm_f)...)

        ret!(builder, chars)
    end

    # invoke the function
    arg_tuple = Expr(:tuple, arg_exprs...)
    call_function(llvm_f, Int32, Tuple{arg_types...}, arg_tuple)
end


text:
hs33 = AmplModel(joinpath(@__DIR__, "hs033.nl"))
result = madnlp(hs33;print_level=MadNLP.ERROR)

@test result.status == :first_order
@test solcmp(result.solution,[0.0,1.4142135570650927,1.4142135585382265])
@test solcmp(result.multipliers,[0.17677669589725922,-0.17677669527079812])
@test solcmp(result.multipliers_L,[11.000000117266442,1.7719330023793877e-9,1.7753439380861844e-9])
@test solcmp(result.multipliers_U,[0.,0.,0.])
@test solcmp([result.objective],[-4.585786548956206])

finalize(hs33)


text:
# CSCI5573Final/utilities.jl
# Licensed under the MIT License. See LICENSE.md file in the project root for
# full license information.

function parentsof(ID, tasks)
    parents = []
    for task in collect(Int64, keys(tasks))
        if ID in tasks[task].Children
            push!(parents, task)
        end
    end
    return parents
end

function write_to_CSV(var::SimLynx.Variable, file="Statistics.csv")
    stats = var.stats
    open(file, "w") do f
        write(f, "min, max, n, mean, variance, stddev\n")
        write(f, "$(stats.min), $(stats.max), $(stats.n), $(stats.mean), $(stats.variance), $(stats.stddev)\n")
    end
end

function print_results(RUN_PATH)
    for i = 1:length(PROCESSORS)
        if !isdir("$(RUN_PATH)/Processor$(i)")
            mkdir("$(RUN_PATH)/Processor$(i)")
        end
        write_to_CSV(
            PROCESSORS[i].resource.wait,
            "$(RUN_PATH)/Processor$(i)/waitStatistics.csv",
        )
        write_to_CSV(
            PROCESSORS[i].resource.queue_length,
            "$(RUN_PATH)/Processor$(i)/QueueLengthStatistics.csv",
        )
        plot_history(
            PROCESSORS[i].resource.wait,
            file = "$(RUN_PATH)/Processor$(i)/WaitHistory.png",
            title = "Processor $i Wait History",
        )
        plot_history(
            PROCESSORS[i].resource.allocated,
            file = "$(RUN_PATH)/Processor$(i)/AllocationHistory.png",
            title = "Processor $i Allocation History",
        )
    end

    write_to_CSV(
        READY_QUEUE.n,
        "$(RUN_PATH)/READY_QUEUEStatistics.csv",
    )
    plot_history(
        READY_QUEUE.n,
        file = "$(RUN_PATH)/READY_QUEUE.png",
        title = "Ready Queue History",
    )
end


text:
##### Beginning of file

Test.@test( isdir(RepoSnapshots.package_directory()) )

Test.@test( isdir(RepoSnapshots.package_directory("ci")) )

Test.@test( isdir(RepoSnapshots.package_directory("ci", "travis")) )

Test.@test( isdir(RepoSnapshots.package_directory(TestModuleA)) )

Test.@test( isdir(RepoSnapshots.package_directory(TestModuleB)) )

Test.@test(
    isdir( RepoSnapshots.package_directory(TestModuleB, "directory2",) )
    )

Test.@test(
    isdir(
        RepoSnapshots.package_directory(
            TestModuleB, "directory2", "directory3",
            )
        )
    )

Test.@test_throws(
    ErrorException,RepoSnapshots.package_directory(TestModuleC),
    )

##### End of file


text:
module BenchDot

using BenchmarkTools
using LinearAlgebra
using Transducers

function manual_dot(xs, ys)
    acc = zero(promote_type(eltype(xs), eltype(ys)))
    @inbounds @simd for i in eachindex(xs, ys)
        acc += xs[i] * ys[i]
    end
    return acc
end

multiplied(iters...) = eduction(MapSplat(*), zip(iters...))

suite = BenchmarkGroup()

let xs = randn(10),
    ys = zero(xs)
    @assert manual_dot(xs, ys) == foldl(+, multiplied(xs, ys); simd=true)
end

n = 10^4

suite["xf"] = @benchmarkable(
    foldl(+, ed; simd=true),
    setup=(ed = multiplied(randn($n), randn($n))))

# This is a bit "cheating" since it's using non-public API.  It is
# just to show the lower-bound of Transducers.jl runtime:
rf = reducingfunction(
    MapSplat(*), +;
    simd = true)
suite["rf"] = @benchmarkable(
    transduce($rf, 0.0, zs),
    setup=(zs = zip(randn($n), randn($n))))

suite["blas"] = @benchmarkable(
    dot(xs, ys),
    setup=(xs = randn($n); ys = randn($n)))
suite["man"] = @benchmarkable(
    manual_dot(xs, ys),
    setup=(xs = randn($n); ys = randn($n)))

end  # module
BenchDot.suite


text:
module Homotopy

    using ..HomConBase
    import ..HomConBase: AbstractHomotopy, AbstractPolySystem, evaluate, substitute, removepoly,
        startsystem, targetsystem,
        differentiate, dt,
        homogenize, ishomogenous, homogenized,
        degrees, weylnorm, nvariables, coefftype

    import Base: length
    include("straight_line.jl")
    include("gamma_trick.jl")
    include("fixedhomotopy.jl")

    export evaluate, removepoly, substitute, startsystem, targetsystem, differentiate,
        dt, homogenize, homogenized, degrees, weylnorm, nvariables
    export StraightLineHomotopy, GammaTrickHomotopy, FixedHomotopy
end


text:
module SymbolContexts

include("./utils.jl")
include("./SymbolContext.jl")
include("./walk_expr_for_syms.jl")
include("./sym.jl")
include("./syms.jl")

end


text:
# Test functions from the Utilities module

using RANSAC: findAABB, smallestdistance

@testset "rand 3D points" begin
    rs3 = [SVector{3}(rand(3)) for _ in 1:30]
    iV3 = SVector(-1.0,-1,-1)
    aV3 = SVector(2.0,2.0,2.0)
    push!(rs3, iV3)
    push!(rs3, aV3)

    minV3, maxV3 = findAABB(rs3)
    @test minV3 == iV3
    @test maxV3 == aV3
end

@testset "rand 2D points" begin
    rs2 = [SVector{2}(rand(2)) for _ in 1:30]
    iV2 = SVector(-1.0,-1)
    aV2 = SVector(2.0,2.0)
    push!(rs2, iV2)
    push!(rs2, aV2)

    minV2, maxV2 = findAABB(rs2)
    @test minV2 == iV2
    @test maxV2 == aV2
end

@testset "smallest distance 2D" begin
    tv = [SVector(0.0, 0), SVector(1.0, 1), SVector(2.2, 2)]
    sd = smallestdistance(tv)
    @test isapprox(sd, sqrt(2))
end

@testset "smallest distance 3D" begin
    tv = [SVector(0.0,0,0), SVector(1.0,1,1), SVector(2.2,2,2)]
    sd = smallestdistance(tv)
    @test isapprox(sd, sqrt(3))
end

@testset "default common parameters" begin
    cp = (common=(collin_threshold = 0.2, parallelthrdeg = 1.),)
    @test isntequal(cp, RANSAC.defaultcommonparameters())
end

@testset "default iteration parameters" begin
    ip = (drawN=3, minsubsetN=15, prob_det=0.9, shape_types=[FittedSphere, FittedPlane, FittedCone], τ=900, itermax=1000, extract_s=:nofminset, terminate_s=:nofminset)
    @test isntequal((iteration=ip,), RANSAC.defaultiterationparameters([FittedSphere, FittedPlane, FittedCone]))

    ip = (drawN=3, minsubsetN=15, prob_det=0.9, shape_types=[FittedCone], τ=900, itermax=1000, extract_s=:nofminset, terminate_s=:nofminset)
    @test isntequal((iteration=ip,), RANSAC.defaultiterationparameters([FittedCone]))
end

@testset "default shape parameters" begin
    # sphere
    fsp = (sphere=(ϵ=0.3, α=deg2rad(5), sphere_par=0.02,),)
    @test isntequal(fsp, RANSAC.defaultshapeparameters(FittedSphere))

    # plane
    @test isntequal((plane=(ϵ=0.3, α=deg2rad(5)),), RANSAC.defaultshapeparameters(FittedPlane))
    # cylinder
    @test isntequal((cylinder=(ϵ=0.3, α=deg2rad(5)),), RANSAC.defaultshapeparameters(FittedCylinder))
    # cone
    @test isntequal((cone=(ϵ=0.3, α=deg2rad(5), minconeopang=deg2rad(2)),), RANSAC.defaultshapeparameters(FittedCone))
end

@testset "defaultparameters()" begin
    dfp = RANSAC.defaultparameters([FittedSphere])

    ip = (iteration=(drawN=3, minsubsetN=15, prob_det=0.9, shape_types=[FittedSphere], τ=900, itermax=1000, extract_s=:nofminset, terminate_s=:nofminset),)
    fsp = (sphere=(ϵ=0.3, α=deg2rad(5), sphere_par=0.02,),)
    cp = (common=(collin_threshold = 0.2, parallelthrdeg = 1.),)
    dip = merge(merge(ip, fsp), cp)
    @test isntequal(dfp, dip)

    dfp = RANSAC.defaultparameters([FittedSphere, FittedPlane])

    ip = (iteration=(drawN=3, minsubsetN=15, prob_det=0.9, shape_types=[FittedSphere, FittedPlane], τ=900, itermax=1000, extract_s=:nofminset, terminate_s=:nofminset),)
    dip = merge(dip, ip)
    dip = merge(dip, (plane=(ϵ=0.3, α=deg2rad(5)),))
    @test isntequal(dfp, dip)
end

@testset "ransacparameters() - named tuple" begin
    # named tuple version method
    rp = ransacparameters()
    @test isntequal(rp, RANSAC.DEFAULT_PARAMETERS)

    rp = ransacparameters(; sphere=(ϵ=0.9, α=deg2rad(1),), plane=(ϵ=1.0,))
    dp = RANSAC.defaultparameters([FittedPlane, FittedCone, FittedCylinder, FittedSphere])
    dp = merge(dp, (sphere=(ϵ=0.9, α=deg2rad(1),sphere_par = 0.02,),))
    dp = merge(dp, (plane=(ϵ=1.0,α=deg2rad(5),),))
    @test isntequal(rp, dp)
end

@testset "ransacparameters() - array" begin
    # method that takes an array of FittedShapes
    rp = ransacparameters([FittedCone, FittedCylinder])
    dpars = RANSAC.defaultparameters([FittedCone, FittedCylinder])

    @test isntequal(rp, dpars)

    rpn = ransacparameters([FittedCone, FittedCylinder], cone=(ϵ=0.9, α=deg2rad(12),), cylinder=(ϵ=0.001,))
    cop = RANSAC.defaultshapeparameters(FittedCone)
    copb = merge(cop.cone, (ϵ=0.9, α=deg2rad(12),))
    cop = (cone=copb,)

    cyp = RANSAC.defaultshapeparameters(FittedCylinder)
    cypb = merge(cyp.cylinder, (ϵ=0.001,))
    cyp = (cylinder=cypb,)
    dpars = merge(dpars, cyp)
    dpars = merge(dpars, cop)
    @test isntequal(rpn, dpars)
end

@testset "cross prod" begin
    A = rand(3,3)
    val = deg2rad(15)
    vec = normalize(rand(3))

    orival = A + sin(val) .* RANSAC.crossprodtensor(vec)
    dA = deepcopy(A)
    RANSAC.pluscrossprod!(dA, sin(val), vec)
    @test orival == dA

    orival2 = A + RANSAC.crossprodtensor(vec)
    dA2 = deepcopy(A)
    RANSAC.pluscrossprod!(dA2, 1, vec)
    @test orival2 == dA2

    newval3 = RANSAC.pluscrossprod!(deepcopy(A), 0, vec)
    @test A == newval3
end

@testset "push2candidatesandlevels!" begin
    fp = FittedPlane(SVector(0.5,0.5,0.5), SVector{3}(0,0,1.))
    candidates = FittedShape[]
    levels = Int[]

    RANSAC.push2candidatesandlevels!(candidates, fp, levels, 3)
    @test size(candidates) == (1,)
    @test size(levels) == (1,)

    RANSAC.push2candidatesandlevels!(candidates, [fp, fp], levels, 0)
    @test size(candidates) == (3,)
    @test size(levels) == (3,)
    @test levels[1] == 3
    @test levels[2] == 0
    @test levels[3] == 0
end

@testset "setfloattype" begin
    nta = (α=1.0, somepar = "key1", intpar=1,)
    ntb = (α=1, otherpar=0.145f0, str="str")
    nt = (α=9, ϵ=0.1, γ=0.01f0, shapea=nta, shapeb=ntb,)

    ntf32 = setfloattype(nt, Float32)
    @test ntf32.α === 9
    @test ntf32.ϵ isa Float32
    @test isapprox(ntf32.ϵ, 0.1f0)
    @test ntf32.γ isa Float32
    @test isapprox(ntf32.γ, 0.01f0)

    @test ntf32.shapea.α isa Float32
    @test isapprox(ntf32.shapea.α, 1.0f0)
    @test ntf32.shapea.somepar == "key1"
    @test ntf32.shapea.intpar === 1

    @test ntf32.shapeb.α === 1
    @test ntf32.shapeb.otherpar isa Float32
    @test isapprox(ntf32.shapeb.otherpar, 0.145f0)
    @test ntf32.shapeb.str === "str"

    ntf64 = setfloattype(ntf32, Float64)
    @test ntf64.α === 9
    @test ntf64.ϵ isa Float64
    @test isapprox(ntf64.ϵ, 0.1; rtol=sqrt(eps(Float32)))
    @test ntf64.γ isa Float64
    @test isapprox(ntf64.γ, 0.01; rtol=sqrt(eps(Float32)))

    @test ntf64.shapea.α isa Float64
    @test isapprox(ntf64.shapea.α, 1.0; rtol=sqrt(eps(Float32)))
    @test ntf64.shapea.somepar == "key1"
    @test ntf64.shapea.intpar === 1

    @test ntf64.shapeb.α === 1
    @test ntf64.shapeb.otherpar isa Float64
    @test isapprox(ntf64.shapeb.otherpar, 0.145; rtol=sqrt(eps(Float32)))
    @test ntf64.shapeb.str === "str"
end


text:
"""
    Res0d <: Block
Res0d is a residual block whose neuron deals with 0-d data, but without BatchNorm.

# Structure
       Rⁱ → Rᵐ         Rᵐ → Rⁱ
        ┌───┐   ┌───┐   ┌───┐   ┌───┐   ┌───┐
    ─┬─►│ W ├──►│f()├──►│ W ├──►│ + ├──►│f()├──►
     │  └───┘   └───┘   └───┘   └─┬─┘   └───┘
     └────────────────►───────────┘
"""
mutable struct Res0d <: Block
    blocks::Vector
    function Res0d(i::Int, m::Int; type::Type=Array{Float32})
        l1 = Linear(i, m, type=type)
        l2 = Linear(m, i, type=type)
        new([l1, l2])
    end
    function Res0d()
        new(Vector(undef,2))
    end
end

@extend(Res0d, blocks)

function clone(this::Res0d; type::Type=Array{Float32})
    cloned = Res0d()
    cloned[1] = clone(this[1], type=type)
    cloned[2] = clone(this[2], type=type)
    return cloned
end

function forward(m::Res0d, x0)
    x1 = relu(forward(m[1], x0))
    x2 = x0 + forward(m[2], x1)
    return relu(x2)
end

function predict(m::Res0d, x0)
    x1 = relu(predict(m[1], x0))
    x2 = x0 + predict(m[2], x1)
    return relu(x2)
end

max_stars_repo_name: sonosole/Delta

max_issues_repo_name: sonosole/Delta

max_forks_repo_name: sonosole/Delta


text:
# Copyright 2018 Erik Edin
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

using Behavior: @given, @when, @then, @expect

@given("that the context variable :x has value 1") do context
    context[:x] = 1
end

@when("the context variable :x is compared with 1") do context
    v = context[:x] == 1
    context[:result] = v
end

@then("the comparison is true") do context
    @expect context[:result]
end

@when("this step fails") do context
    @expect 1 == 2
end

@then("this step is skipped") do context
    @assert false "This code is never executed, because the previous step failed."
end

@when("this step throws an exception, the result is \"Unknown exception\"") do context
    throw(ErrorException("This is an unknown exception"))
end

# This step is commented to show what happens when a step definition is not found.
#@given("a step that has no corresponding step definition in steps/spec.jl") do context
#
#end

@when("it is executed") do context
    @assert false "This step should be skipped, because the previous failed."
end

@then("it fails with error \"No matching step\"") do context
    @assert false "This step should be skipped, because a previous step failed."
end


text:
import Base.alignment

# A bit of a mess but does the job...

# sortedin(p, sc)
# returns true if `p` is in `sc`, assuming that `sc` is monotonically increasing.
function sortedin(x, itr)
    for y in itr
        if y == x
            return true
        elseif y > x
            return false
        end
    end
    return false
end

function _blockarray_print_matrix_row(io::IO,
        X::AbstractVecOrMat, A::Vector,
        i::Integer, cols::AbstractVector, sep::AbstractString)
    cumul = 0
    block = 1

    row_buf = IOBuffer()

    row_sum = blocklasts(axes(X,1))
    if ndims(X) == 2
        col_sum = blocklasts(axes(X,2))[1:end-1]
    end

    # Loop over row
    for k = 1:length(A)
        n_chars = 0
        j = cols[k]

        if isassigned(X,Int(i),Int(j)) # isassigned accepts only `Int` indices
            x = X[i,j]
            a = Base.alignment(io, x)
            sx = sprint(show, x; context=io, sizehint=0)
        else
            a = Base.undef_ref_alignment
            sx = Base.undef_ref_str
        end
        l = repeat(" ",A[k][1]-a[1]) # pad on left and right as needed
        r = repeat(" ", A[k][2]-a[2])
        prettysx = Base.replace_in_print_matrix(X,i,j,sx)
        # Print the element
        print(io, l, prettysx, r)

        # Jump forward
        n_chars += length(l) + length(prettysx) + length(r) + 2

        cumul += 1
        if ndims(X) == 2
            # Have accumulated enough for the block, should print a |
            if block < blocksize(X,2) && cumul == length(axes(X,2)[Block(block)])
                block += 1
                cumul = 0
                print(io, "  │")
                n_chars += 3
            end
        end

        if k == 1
            n_chars -= 2
        end

        if sortedin(i, row_sum)
            print(row_buf, "─"^(n_chars-1))
            if ndims(X) == 2 && sortedin(k,col_sum)
                print(row_buf, "┼")
            else
                print(row_buf, "─")
            end
        end

        if k < length(A); print(io, sep); end
    end

    if i < size(X, 1)
        row_str = String(take!(row_buf))
        if length(row_str) > 0
            print(io, "\n ")
            print(io, row_str)
        end
    end
end

function _show_typeof(io::IO, a::BlockVector{T,Vector{Vector{T}},Tuple{DefaultBlockAxis}}) where T
    print(io, "BlockVector{")
    show(io, T)
    print(io, '}')
end

function _show_typeof(io::IO, a::BlockMatrix{T,Matrix{Matrix{T}},NTuple{2,DefaultBlockAxis}}) where T
    print(io, "BlockMatrix{")
    show(io, T)
    print(io, '}')
end

function _show_typeof(io::IO, a::BlockArray{T,N,Array{Array{T,N},N},NTuple{N,DefaultBlockAxis}}) where {T,N}
    Base.show_type_name(io, typeof(a).name)
    print(io, '{')
    show(io, T)
    print(io, ", ")
    show(io, N)
    print(io, '}')
end

# LayoutArray with blocked axes will dispatch to here
axes_print_matrix_row(::Tuple{BlockedUnitRange}, io, X, A, i, cols, sep) =
        _blockarray_print_matrix_row(io, X, A, i, cols, sep)
axes_print_matrix_row(::NTuple{2,BlockedUnitRange}, io, X, A, i, cols, sep) =
        _blockarray_print_matrix_row(io, X, A, i, cols, sep)
axes_print_matrix_row(::Tuple{AbstractUnitRange,BlockedUnitRange}, io, X, A, i, cols, sep) =
        _blockarray_print_matrix_row(io, X, A, i, cols, sep)
axes_print_matrix_row(::Tuple{BlockedUnitRange,AbstractUnitRange}, io, X, A, i, cols, sep) =
        _blockarray_print_matrix_row(io, X, A, i, cols, sep)

# Need to handled BlockedUnitRange, which is not a LayoutVector
Base.print_matrix_row(io::IO, X::BlockedUnitRange, A::Vector, i::Integer, cols::AbstractVector, sep::AbstractString) =
        _blockarray_print_matrix_row(io, X, A, i, cols, sep)

function _show_typeof(io::IO, a::PseudoBlockVector{T,Vector{T},Tuple{DefaultBlockAxis}}) where T
    print(io, "PseudoBlockVector{")
    show(io, T)
    print(io, '}')
end

function _show_typeof(io::IO, a::PseudoBlockMatrix{T,Matrix{T},NTuple{2,DefaultBlockAxis}}) where T
    print(io, "PseudoBlockMatrix{")
    show(io, T)
    print(io, '}')
end

function _show_typeof(io::IO, a::PseudoBlockArray{T,N,Array{T,N},NTuple{N,DefaultBlockAxis}}) where {T,N}
    Base.show_type_name(io, typeof(a).name)
    print(io, '{')
    show(io, T)
    print(io, ", ")
    show(io, N)
    print(io, '}')
end

## Cumsum

Base.show(io::IO, mimetype::MIME"text/plain", a::BlockedUnitRange) =
    Base.invoke(show, Tuple{typeof(io),MIME"text/plain",AbstractArray},io, mimetype, a)


text:
# Transition callback
function callback(fsm::StateMachine,
                  action::AbstractString, name::AbstractString, from::AbstractString, to::AbstractString)
    if haskey(fsm.actions, action)
        fsm.actions[action](fsm, name, from, to)
    end
end

# Before event
function before_event(fsm::StateMachine, name::AbstractString, from::AbstractString, to::AbstractString)
    before_this_event(fsm, name, from, to)
    before_any_event(fsm, name, from, to)
end

before_this_event(fsm::StateMachine, name::AbstractString, from::AbstractString, to::AbstractString) =
    callback(fsm, "onbefore" * name, name, from, to)

before_any_event(fsm::StateMachine, name::AbstractString, from::AbstractString, to::AbstractString) =
    callback(fsm, "onbeforeevent", name, from, to)

# After event
function after_event(fsm::StateMachine, name::AbstractString, from::AbstractString, to::AbstractString)
    after_this_event(fsm, name, from, to)
    after_any_event(fsm, name, from, to)
end

after_this_event(fsm::StateMachine, name::AbstractString, from::AbstractString, to::AbstractString) =
    callback(fsm, "onafter" * name, name, from, to)

function after_any_event(fsm::StateMachine, name::AbstractString, from::AbstractString, to::AbstractString)
    if haskey(fsm.actions, "onafterevent")
        action = "onafterevent"
    elseif haskey(fsm.actions, "onevent")
        action = "onevent"
    else
        return
    end
    callback(fsm, action, name, from, to)
end

# Change of state
change_state(fsm::StateMachine, name::AbstractString, from::AbstractString, to::AbstractString) =
    callback(fsm, "onchangestate", name, from, to)

# Entering a state
function enter_state(fsm::StateMachine, name::AbstractString, from::AbstractString, to::AbstractString)
    enter_this_state(fsm, name, from, to)
    enter_any_state(fsm, name, from, to)
end

enter_this_state(fsm::StateMachine, name::AbstractString, from::AbstractString, to::AbstractString) =
    callback(fsm, "onenter" * to, name, from, to)

function enter_any_state(fsm::StateMachine, name::AbstractString, from::AbstractString, to::AbstractString)
    if haskey(fsm.actions, "onenterstate")
        action = "onenterstate"
    elseif haskey(fsm.actions, "onstate")
        action = "onstate"
    else
        return
    end
    callback(fsm, action, name, from, to)
end

# Leaving a state
function leave_state(fsm::StateMachine, name::AbstractString, from::AbstractString, to::AbstractString)
    leave_this_state(fsm, name, from, to)
    leave_any_state(fsm, name, from, to)
end

leave_this_state(fsm::StateMachine, name::AbstractString, from::AbstractString, to::AbstractString) =
    callback(fsm, "onleave" * from, name, from, to)

leave_any_state(fsm::StateMachine, name::AbstractString, from::AbstractString, to::AbstractString) =
    callback(fsm, "onleavestate", name, from, to)


text:
#!/usr/bin/julia

# Copyright (C) 2021 Matheus Fernandes Bigolin <mfrdrbigolin@disroot.org>
# SPDX-License-Identifier: MIT

"Day Sixteen, Packet Decoder."

#= This was a really fun day to write.  Initially glossed over this day, because
 = I went to the movies.
 =#

include("Utils.jl")

using .Utils

"Operators used by the packet system."
const OPERATORS = [+, *, min, max, missing, Int ∘ >, Int ∘ <, Int ∘ ==]

"Process a `packet` and return its version sum, total value and stop point."
function process_packet(packet :: Array{Int8})
    ptype = bin2dec(packet[4:6])
    plength = 1
    step = 7

    if ptype != 4
        length_type = Bool(packet[7])
        length_bits = if length_type 11 else 15 end

        plength = bin2dec(packet[8:7 + length_bits])

        step += 1 + length_bits
    end

    version_sum = bin2dec(packet[1:3])
    number = 0
    operands = Array{Int}([])

    is_final_group = false

    while !is_final_group && plength > 0
        if ptype == 4
            is_final_group = !Bool(packet[step])
            number = 16number + bin2dec(packet[step + 1:step + 4])

            step += 5
        else
            (version, op, j) = process_packet(packet[step:end])

            push!(operands, op)
            version_sum += version

            plength -= if length_type 1 else j end

            step += j
        end
    end

    if ptype != 4
        number = OPERATORS[ptype + 1](operands...)
    end

    return (version_sum, number, step - 1)
end

"Hexadecimal to four-bit (nibble) binary table."
const HEX = Dict(['0' => "0000", '1' => "0001", '2' => "0010", '3' => "0011",
                  '4' => "0100", '5' => "0101", '6' => "0110", '7' => "0111",
                  '8' => "1000", '9' => "1001", 'A' => "1010", 'B' => "1011",
                  'C' => "1100", 'D' => "1101", 'E' => "1110", 'F' => "1111"])

"Find the version sum and the final value of the `packet`."
function solve(packet :: String)
    bits = Array{Int8}([])

    for hex in collect(packet)
        push!(bits, parse.(Int8, collect(HEX[hex]))...)
    end

    return process_packet(bits)[1:2]
end

function main()
    usage_and_exit(length(ARGS) != 1)

    data = readline(first(ARGS))

    S₁, S₂ = solve(data)

    println(S₁)
    println(S₂)
end

if abspath(PROGRAM_FILE) == @__FILE__
    main()
end


text:
"""
Generates a few plots that summarise a solution.
"""
function plot(rd::RoutingData, flows;
              basename="$(@__DIR__)",
              sourceNode=colorant"orange", destinationNode=colorant"green", intermediateNode=colorant"steelblue",
              usedEdge=colorant"red", unusedEdge=colorant"lightgray")
    # Ensures the graph is no more directed: otherwise, risk of plotting y -> x on top of x -> y,
    # which hides the edge x -> y.
    g = SimpleGraph(SimpleDiGraph(rd.g))

    # Make a matrix out of the flows (they have a sparse representation).
    routing_matrix = zeros(n_demands(rd), n_paths(rd))
    for k in eachindex(flows)
        routing_matrix[k[1], k[2]] = flows[k...]
    end

    # If the locations of the nodes have not yet been computed, do it now.
    if rd.locs_x == nothing || rd.locs_y == nothing
        rd.locs_x, rd.locs_y = rd.locs_f(rd.g)
    end

    node_names = [get_prop(rd.g, n, :name) for n in vertices(rd.g)]

    # First, plot the complete graph, with just topology information.
    draw(PNG("$(basename).png"), gplot(g, rd.locs_x, rd.locs_y, nodelabel=node_names))

    # Then, plot the total load of each edge.
    paths = sum(routing_matrix[d, :] for d in 1:n_demands(rd))
    ps = findall(paths .> 0)
    edge_colours = [any(in(e, rd.paths_edges[p]) for p in ps) ? usedEdge : unusedEdge for e in edges(g)]
    edge_widths = [any(in(e, rd.paths_edges[p]) for p in ps) ?
                        2. * sum(paths[p] * in(e, rd.paths_edges[p]) for p in ps) :
                        1.0
                        for e in edges(g)]

    draw(
        PNG("$(basename)_load.png"),
        gplot(g, rd.locs_x, rd.locs_y, nodelabel=node_names, edgestrokec=edge_colours, edgelinewidth=edge_widths)
    )

    # Finally, plot each demand separately with the load it creates on each edge.
    vertex_to_colour(i, k_d) = i == src(k_d) ? sourceNode : (i == dst(k_d) ? destinationNode : intermediateNode)
    for d in 1:n_demands(rd)
        k_d = rd.demand_id_to_demand[d]
        node_colours = [vertex_to_colour(i, k_d) for i in vertices(g)]

        d_paths = routing_matrix[d, :]
        ps = findall(d_paths .> 0)
        edge_colours = [any(in(e, rd.paths_edges[p]) for p in ps) ? usedEdge : unusedEdge for e in edges(g)]
        edge_widths = [any(in(e, rd.paths_edges[p]) for p in ps) ?
                            2. * sum(d_paths[p] * in(e, rd.paths_edges[p]) for p in ps) :
                            1.0
                            for e in edges(g)]

        draw(
            PNG("$(basename)_$d.png"),
            gplot(g, rd.locs_x, rd.locs_y, nodelabel=node_names, nodefillc=node_colours,
                edgestrokec=edge_colours, edgelinewidth=edge_widths)
        )
    end
end


text:
# Mel-cepstrum analysis
# re-coded from SPTK

!isdefined(Base, :FFTW) && using FFTW

function fill_al!{T<:AbstractFloat}(al::Vector{T}, α::AbstractFloat)
    al[1] = one(T)
    for i=2:length(al)
        @inbounds al[i] = -α*al[i-1]
    end
    al
end

function fill_toeplitz!{T}(A::AbstractMatrix{T}, t::AbstractVector{T})
    n = length(t)
    for j=1:n, i=1:n
        @inbounds A[i,j] = i-j+1 >= 1 ? t[i-j+1] : t[j-i+1]
    end
    A
end

function fill_hankel!{T}(A::AbstractMatrix{T}, h::AbstractVector{T})
    n = length(h)>>1 + 1
    for j=1:n, i=1:n
        @inbounds A[i,j] = h[i+j-1]
    end
    A
end

function fill_only_real_part!{T}(y::AbstractVector{Complex{T}},
                                 v::AbstractVector{T})
    for i=1:length(v)
        @inbounds y[i] = Complex(v[i], zero(T))
    end
    y
end

function update_hankel_elements!(he::AbstractVector, c::AbstractVector)
    for j=1:length(he)
        @inbounds he[j] = c[j]
    end
    for j=1:2:length(he)
        @inbounds he[j] -= c[1]
    end
    he
end

function update_toeplitz_elements!(te::AbstractVector, c::AbstractVector)
    for j=1:2:length(te)
        @inbounds te[j] += c[1]
    end
    te
end

function periodogram2mcep{T<:AbstractFloat}(periodogram::AbstractVector{T}, # modified periodogram
                                            order::Int=40,                  # order of mel-cepstrum
                                            α::AbstractFloat=0.41;          # all-pass constant
                                            miniter::Int=2,
                                            maxiter::Int=30,
                                            criteria::AbstractFloat=0.001,  # stopping criteria
                                            e::T=zero(T),                   # floor of periodogram
                                            verbose::Bool=false)
    logperiodogram = log.(periodogram + e)

    fftlen = (size(logperiodogram, 1)-1)*2
    const xh = fftlen>>1

    # create FFT workspace and plan
    y = Array{Complex{T},1}(xh+1)
    c = Array{T,1}(fftlen)
    # fplan = FFTW.Plan(c, y, 1, FFTW.ESTIMATE, FFTW.NO_TIMELIMIT)
    # bplan = FFTW.Plan(y, c, 1, FFTW.ESTIMATE, FFTW.NO_TIMELIMIT)
    fplan = plan_rfft(c)
    bplan = plan_brfft(y, fftlen)

    # Initial value of cepstrum
    fill_only_real_part!(y, logperiodogram)
    A_mul_B!(c, bplan, y)
    # FFTW.execute(T, bplan.plan)
    # FFTW.execute(bplan.plan, y, c)
    scale!(c, 1. / fftlen)
    # scale!(c, FFTW.normalization(c))
    c[1] /= 2.0
    c[xh+1] /= 2.0

    # Initial value of mel-cesptrum
    mc = freqt(view(c, 1:xh+1), order, α)
    czero = c[1]

    # Allocate memory for solving linear equation (Tm + Hm)d = b
    Tm = Array{T,2}(order+1, order+1)
    Hm = Array{T,2}(order+1, order+1)
    Tm_plus_Hm = Array{T,2}(order+1, order+1)
    he = Array{T,1}(2order+1) # elements of hankel matrix
    te = Array{T,1}(order+1)  # elements of toeplitz matrix
    b = Array{T,1}(order+1)   # right side of linear equation

    al = Array{T,1}(order+1)
    fill_al!(al, α)

    # Newton raphson roop
    ch = view(c, 1:xh+1)
    ch_copy = Array{T,1}(xh+1)
    c_frqtr = view(c, 1:2order+1)
    for i=1:maxiter
        fill!(c, zero(T))
        freqt!(ch, mc, -α)

        A_mul_B!(y, fplan, c)
        # FFTW.execute(fplan.plan, c, y)
        for i=1:length(y)
            @inbounds y[i] = Complex(periodogram[i] / exp(2real(y[i])), zero(T))
        end
        A_mul_B!(c, bplan, y)
        # FFTW.execute(bplan.plan, y, c)
        # scale!(c, FFTW.normalization(c))
        scale!(c, 1.0 / fftlen)

        copy!(ch_copy, ch)
        frqtr!(c_frqtr, ch_copy, α)

        # check convergence
        if i >= miniter
            err = abs((c[1]-czero)/c[1])
            verbose && println("czero nmse: $err")
            if err < criteria
                break
            end
            czero = c[1]
        end

        copy!(te, 1, c, 1, order+1)

        for j=1:order+1
            @inbounds b[j] = c[j] - al[j]
        end

        update_hankel_elements!(he, c)
        update_toeplitz_elements!(te, c)

        fill_hankel!(Hm, he)
        fill_toeplitz!(Tm, te)

        for i=1:length(Hm)
            @inbounds Tm_plus_Hm[i] = Hm[i] + Tm[i]
        end

        # Solve Ax = b
        # NOTE: both Tm_plus_Hm and b are overwritten
        A_ldiv_B!(lufact!(Tm_plus_Hm), b)

        # Add the solution vector to mel-cepstrum
        for i=1:length(b)
            @inbounds mc[i] += b[i]
        end
    end

    mc
end

function _mcep(x::AbstractVector,  # a *windowed* signal
               order=25,           # order of mel-cepstrum
               α=0.35;             # all-pass constant
               kargs...)
    periodgram = abs2.(rfft(x))
    periodogram2mcep(periodgram, order, α; kargs...)
end

function estimate(mgc::MelCepstrum, x::AbstractArray;
                  use_sptk::Bool=false,
                  kargs...)
    order = param_order(mgc)
    α = allpass_alpha(mgc)
    # Note that mcep in julia is more stable than SPTK.mcep
    mcepfunc::Function = use_sptk ? SPTK.mcep : _mcep
    data = mcepfunc(x, order, α; kargs...)
    SpectralParamState(mgc, data, true, true)
end

function mcep(x::AbstractArray, order=25, α=0.35; kargs...)
    estimate(MelGeneralizedCepstrum(order, α, 0.0), x; kargs...)
end