text:
# todo
# using Yao, LinearAlgebra, YaoBlocks
#
# Ugate(nbit::Int, i::Int) = put(nbit, i=>chain(Rz(0), Rx(0), Rz(0)));
# Ugate(i::Int) = put(i=>chain(Rz(0), Rx(0), Rz(0)));
#
# struct InitStateMatrix
#     m1::Matrix{ComplexF64}
#     m2::Matrix{ComplexF64}
# end
#
# function build_state(mats::InitStateMatrix)
#     # return zero_state(2) |> chain(2, put(1=>chain(Rz(1), Rx(2))), put(2=>chain(Rz(1), Rx(2))))
#     return zero_state(3) |> chain(3, put(3, (2)=>matblock(mats.m1)), put(3, (3)=>matblock(mats.m2)))
# end
#
# # @show probs(build_state())
#
# function overlap(mats::InitStateMatrix)
#     return dot(zero_state(2) |> chain(2, put(2, (1)=>matblock(mats.m1)), put(2, (2)=>matblock(mats.m2)), control(1, 2=>X), put(1=>H)) |> probs,[1, 1, 1, -1])
# end
#
# function cost(trainX, trainY, circuit, c)
#     actual_out = [dot(i |> circuit |> probs, c) for i in map(build_state, trainX)]
#     return sum((trainY-actual_out).^2)/length(trainY)
# end
#
# function gradient(circuit, trainX, trainY, delta)
#     n = nqubits(circuit)
#     grad = zeros(Float64, nparameters(circuit))
#     params = parameters(circuit)
#
#     count = 1
#     for k in 1:nparameters(circuit)
#         params[k] += delta
#         dispatch!(circuit, params)
#         cost_pos = cost(trainX, trainY, circuit, c)
#
#         params[k] -= 2 * delta
#         dispatch!(circuit, params)
#         cost_neg = cost(trainX, trainY, circuit, c)
#
#         params[k] += delta
#         dispatch!(circuit, params)
#
#         # @show (cost_pos - cost_neg)
#
#         grad[count] = (cost_pos - cost_neg)/(2 * delta)
#         count += 1
#     end
#     return grad
# end
#
# function generate_gates_set(n::Int64)
#     rtn = []
#     push!(rtn, control(n, 2, 1=>X))
#     push!(rtn, control(n, 3, 1=>X))
#     push!(rtn, control(n, 3, 2=>X))
#
#     for i in 1:n
#         push!(rtn, Ugate(n, i))
#     end
#
#     return rtn
# end
#
# # 检测生成的circuit是否合法
# function validate_circuit(circuit)
#     last = circuit[1]
#     for i in 2:length(circuit)
#         now = circuit[i]
#         if isa(last, ControlBlock) && last == now
#             return false
#         end
#         if (!isa(last, ControlBlock)) && (!isa(now, ControlBlock)) && occupied_locs(last) == occupied_locs(now)
#             return false
#         end
#         last = now
#     end
#
#     return true
# end
#
# function generate_init_circuit(n::Int64, d::Int64)
#     gate_set = generate_gates_set(n)
#     rtn = chain(n)
#     while length(rtn) < d
#         push!(rtn, rand(gate_set))
#         if !validate_circuit(rtn)
#             pop!(rtn)
#         end
#     end
#     return rtn
# end
#
# function random_modify(circuit, gate_set)
#     circuit2 = deepcopy(circuit)
#     index = rand(1:length(circuit2))
#     # @show index
#     circuit2[index] = rand(gate_set)
#     if validate_circuit(circuit2)
#         return circuit2
#     end
#     return random_modify(circuit, gate_set)
# end
#
#
#
#
#
# using Flux.Optimise
#
# c = [1, -1, 1, -1, 1, -1, 1, -1];
# const cost_threshold = 2e-7
# # circuit = build_circuit()
# trainX = [InitStateMatrix(rand_unitary(2), rand_unitary(2)) for _ in 1:8]
# trainY = map(overlap, trainX)
# opt = Descent(0.8)
# # opt = ADAM()
#
# function train(circuit, trainX, trainY, cost_threshold)
#     history = Float64[]
#     last_cost = now_cost = 0
#     for i in 1:100
#         last_cost = now_cost
#         now_cost = cost(trainX, trainY, circuit, c)
#         push!(history, now_cost)
#         ps = parameters(circuit)
#         # @show (i, ps, now_cost)
#         if (abs(now_cost - last_cost) < cost_threshold / 3) || now_cost < cost_threshold
#             # @show now_cost
#             break
#         end
#         Optimise.update!(opt, ps, gradient(circuit, trainX, trainY, .001))
#         popdispatch!(circuit, ps)
#         # if i == 200
#         #     println("Warning: failed to converge")
#         # end
#     end
#     return (now_cost, history)
# end
#
# function find_algo(annealing_param, d::Int64, trainX, trainY, max_steps::Int64, cost_threshold)
#     gate_set = generate_gates_set(3)
#     circuit = generate_init_circuit(3, d)
#     (best_cost, history) = train(circuit, trainX, trainY, cost_threshold)
#     step = 0
#     circuit_backup = circuit
#     while best_cost > cost_threshold && step < max_steps
#         step += 1;
#         # if mod(step, 60) == 59 && d > 8
#         #
#         #     println("尝试压缩circuit")
#         #     newTrainY = [dot(i |> circuit |> probs, c) for i in map(build_state, trainX)]
#         #     (new_circuit, sucs) = find_algo(annealing_param, d - 1, trainX, newTrainY, 100, best_cost / 2)
#         #     if sucs
#         #         println("成功压缩circuit！！")
#         #         circuit = new_circuit
#         #         best_cost = cost(trainX, trainY, circuit, c)
#         #         while length(circuit) < d
#         #             push!(circuit, rand(gate_set))
#         #             if !validate_circuit(circuit)
#         #                 pop!(circuit)
#         #             end
#         #         end
#         #         continue
#         #     else
#         #         println("压缩circuit失败")
#         #     end
#         # end
#
#         circuit_backup = deepcopy(circuit)
#         circuit = random_modify(circuit, gate_set)
#         (new_cost, history) = train(circuit, trainX, trainY, cost_threshold)
#
#         accept_prob = exp(-annealing_param * (new_cost - best_cost))
#         if new_cost < best_cost
#             @show (step, new_cost)
#             best_cost = new_cost
#             continue
#         elseif rand() < accept_prob
#             # accept
#             # best_cost = new_cost
#             println("accepted")
#         else
#             # println("fallback")
#             circuit = circuit_backup
#         end
#         @show (step, d, best_cost, accept_prob)
#     end
#     return (circuit, best_cost < cost_threshold)
# end
#
# function find_nearest_pi(x::Float64)
#     rtn = mod(x, 2*π);
#     rtn = rtn > π ? rtn - 2*π : rtn;
#     rtn = π / 4 * round(4 * rtn / π)
# end
#
# function enhance_circuit_to_pi(circuit)
#     params = parameters(circuit)
#     params = map(find_nearest_pi, params)
#     dispatch!(circuit, params)
# end
#
# # (tmp, history) = train(generate_init_circuit(3, 9), trainX, trainY, cost_threshold)
# # using Plots
# # function plot_history(history)
# #     pyplot() # Choose a backend
# #     fig1 = plot(history; legend=nothing)
# #     title!("training history")
# #     xlabel!("steps"); ylabel!("cost")
# # end
# # plot_history(history)
#
# @show (circuit, ) = find_algo(5000.0, 9, trainX, trainY, 600000, cost_threshold)
# enhance_circuit_to_pi(circuit)
# @show cost(trainX, trainY, circuit, c)


text:
using Ion
using Ion.Internal.Blueprints

t = Template(
    name="test",
    src=SrcDir()
)

using Configurations

to_toml(t)|>print

s = """
name = "test"

[project]
version = "0.1.0"
deps = []

[src]
"""

using TOML
d = TOML.parse(s)
t = from_dict(Template, d)

create(t, pkgdir(Ion, "test", "TestProject"); name="TestName", force=true)

t = from_toml(Template, pkgdir(Ion, "blueprints", "project.toml"))
create(t, pkgdir(Ion, "test", "TestProject"); name="TestName", force=true)

ext: jl


text:
module GridWorldPathFollowing

# Usings
using Reexport

# Base Module Includes
include("utils.jl")
include("grid_paths.jl")
include("trajectories.jl")
include("robot_models.jl")
include("deploy.jl")

# Export Module Contents
@reexport using GridWorldPathFollowing.Utils
@reexport using GridWorldPathFollowing.GridPaths
@reexport using GridWorldPathFollowing.Trajectories
@reexport using GridWorldPathFollowing.RobotModels
@reexport using GridWorldPathFollowing.Deploy

end # module


text:
struct MPIData
    function MPIData()
        error("no MPI on this package")
    end
end

function mpibroadcast(mpid, t_split, data::Array{T,N}) where {T,N}
    error("no MPI on this package")
end


text:
# Pkg.add("ForwardDiff")
using ForwardDiff

"""
```
f(x) = x^2 - 2;
x0 = 1;
x = newton(f, x0);
```
"""
function newton(f, x0)
  # 求目标函数导数
  Δf = x -> ForwardDiff.derivative(f, x);

  xk = Base.float(x0);
  xk_1 = Base.float(x0);

  # 比机器精度少一个数量级
  epsilon = Base.eps(xk) * 10;

  while true
    xk_1 = xk - f(xk)/Δf(xk);
    if Base.abs(xk_1 - xk) < epsilon || Base.abs(f(xk_1)) < epsilon
      break;
    end
    xk = xk_1;
  end

  return xk_1;
end

max_stars_repo_name: HereChen/Algorithm

max_issues_repo_name: HereChen/Algorithm

max_forks_repo_name: HereChen/Algorithm


text:
using Lazy

module CumulantTypes
@enum enum begin
    Observation = 1
    Composition = 2
    Reward = 3
end
end

mutable struct Cumulant
    typ::CumulantTypes.enum
    dependent::Int64
end

function get_cumulant(cumulant::Cumulant, obs, preds_tilde)
    if cumulant.typ == CumulantTypes.Observation
        return obs[cumulant.dependent]
    elseif cumulant.typ == CumulantTypes.Composition
        # println("Composition")
        return preds_tilde[cumulant.dependent]
    else
        return 0
    end
end

# const ContinuationType = ["Observation", "Constant"]
module ContinuationTypes
@enum enum begin
    Observation = 1
    Constant = 2
    Myopic = 3
    Functional = 4
end
end

mutable struct Continuation
    typ::ContinuationTypes.enum
    γ_const::Float64
    terminate
    func
    Continuation(typ, γ_const, terminate) = new(typ, γ_const, terminate, nothing)
    Continuation(typ, γ_const, terminate, func) = new(typ, γ_const, terminate, func)
end

function get_continuation(continuation::Continuation, obs, preds_tilde)
    if continuation.typ == ContinuationTypes.Observation
        if continuation.terminate(obs)
            return 0.0
        else
            return continuation.γ_const
        end
    elseif continuation.typ == ContinuationTypes.Constant
        return continuation.γ_const
    elseif continuation.typ == ContinuationTypes.Functional
        return continuation.func(continuation, obs, preds_tilde)
    else
        return 0.0
    end
end

module PolicyTypes
@enum enum begin
    Probabilities
    Functional
end
end

mutable struct Policy
    typ::PolicyTypes.enum
    probabilities::Array{Float64, 1}
    func
end

Policy(probabilities::Array{Float64,1}) = Policy(PolicyTypes.Probabilities, probabilities, nothing)

function get_probability(policy::Policy, state, action)
    if policy.typ == PolicyTypes.Probabilities
        return policy.probabilities[action]
    elseif policy.typ == PolicyTypes.Functional
        return policy.func(policy, state, action)
    else
        throw(ErrorException("Policy Type doesn't exist!"))
    end
end

mutable struct GVF
    cumulant::Cumulant
    continuation::Continuation
    policy::Policy
end

@forward GVF.cumulant get_cumulant
@forward GVF.continuation get_continuation
@forward GVF.policy get_probability

max_stars_repo_name: mkschleg/JuliaRL

max_issues_repo_name: mkschleg/JuliaRL

max_forks_repo_name: mkschleg/JuliaRL


text:
#contains methods and associated helper functions for forming a MetaDictionary object
#each object contains the complete metadata of a file

mutable struct MetaDictionary
  fileName::String
  metaTuples::Vector{MetaTuple}

  nonprofitType::Symbol
  fileYear::Int
  fullFile::Bool
  fileDescription::String

  dictionary::Dict
  index::Dict
end

#return a metadictionary object. The actual dictionary can be passed as a type lookup file
function MetaDictionary(metaTuples::Vector{MetaTuple}, indexRow::DataFrameRow)::MetaDictionary
  NTuples = length(metaTuples)

  fileName::String = indexRow[:name]
  nonprofitType::Symbol = Symbol(FILE_TYPES_NAME_TO_CODE[indexRow[:type]])
  fileYear::Int = indexRow[:year]
  fullFile::Bool = uppercase(indexRow[:full]) == "TRUE"
  fileDescription::String = indexRow[:description]

  dictionary::Dict = Dict(metaTuples[i].fieldName => metaTuples[i].columnType for i::Int ∈ 1:NTuples)
  index::Dict = Dict(metaTuples[i].fieldName => i for i::Int ∈ 1:NTuples)

  #extract the information from the row and create the object
  return MetaDictionary(fileName, metaTuples, nonprofitType,
    fileYear, fullFile, fileDescription, dictionary, index)
end

#createas a MetaDictionary from the metadata file
function MetaDictionary(indexRow::DataFrameRow;
   metaPath::String = META_PATH,
  subTablePath::String = SUB_TABLES_PATH)::MetaDictionary

  fileName::String = indexRow[:name]
  #first open the file
  metaDF::DataFrame = CSV.read("$metaPath\\$(fileName).csv",# strings=:raw,
    categorical=false)
  #metaDF::DataFrame = load("$metaPath\\$(fileName).csv") |> DataFrame

  NFields::Int = size(metaDF,1)

  #this is where we will put the results
  metaTuples::Vector{MetaTuple} = Vector{MetaTuple}(undef, NFields)

  #these are the data
  names::Vector{Symbol} = (Symbol).(metaDF[:name])
  types::Vector{Symbol} = (Symbol).(metaDF[:type])
  subTables::Vector{Bool} = (s::String->s=="True" ? true : false).(metaDF[:subTable])
  shortDescriptions::Vector{MString} = metaDF[:shortDesc]
  longDescriptions::Vector{MString} = metaDF[:longDesc]

  for i::Int ∈ 1:NFields
    metaTuples[i] = MetaTuple(fileName, names[i], types[i],
      subTables[i], shortDescriptions[i], longDescriptions[i])
  end

  return MetaDictionary(metaTuples, indexRow)
end

#rebuilds the metadata table from the dictionary
function metaTable(meta::MetaDictionary)::DataFrame
  N::Int = length(meta.metaTuples)

  #pre-allocate
  fieldNames::Vector{Symbol} = Vector{Symbol}(undef, N)
  types::Vector{Type} = Vector{Type}(undef, N)
  typeNames::Vector{String} = Vector{String}(undef, N)
  shortDescriptions::Vector{MString} = Vector{MString}(undef, N)
  longDescriptions::Vector{MString} = Vector{MString}(undef, N)
  numeric::Vector{MBool} = Vector{MBool}(undef, N)

  @inbounds @simd for i ∈ 1:N
    fieldNames[i] = meta.metaTuples[i].fieldName
    types[i] = meta.metaTuples[i].columnType
    shortDescriptions[i] = meta.metaTuples[i].shortDescription
    longDescriptions[i] = meta.metaTuples[i].longDescription

    #need to figure out the types
    typeNames[i] =
      ifelse(types[i] <: MFloat64, "Float64",
        ifelse(types[i] <: MInt, "Int",
          ifelse(types[i] <: MBool, "Bool",
            ifelse(types[i] <: MString, "String",
              ifelse((types[i] <: CategoricalValue) || (CategoricalValue <: types[i]), "Conformed", "UNK")))))
    numeric[i] = ifelse(types[i] <: MFloat64 || types[i] <: MInt, true, false)
  end

  #now build the dataframe
  df::DataFrame = DataFrame(fieldNames = fieldNames, shortDescriptions=shortDescriptions,
    longDescriptions=longDescriptions, types=typeNames, numeric=numeric)

  #now write the file-level metadata
  df[:fileNames] = Vector{String}(undef, N)
  df[:nonprofitTypes] = Vector{Symbol}(undef, N)
  df[:fileYears] = Vector{Int}(undef, N)
  df[:fullFiles] = Vector{Bool}(undef, N)
  df[:fileDescriptions] = Vector{MString}(undef, N)

  df[:fileNames] .= meta.fileName
  df[:nonprofitTypes] .= meta.nonprofitType
  df[:fileYears] .= meta.fileYear
  df[:fullFiles] .= meta.fullFile
  df[:fileDescriptions] .= meta.fileDescription

  return df
end

#removes fields from a meta dictionary
function removeField!(meta::MetaDictionary, field::Symbol)::MetaDictionary
  target::Int = meta.index[field]
  meta.metaTuples = meta.metaTuples[(i::Int->i≠target).(1:end)]

  NTuples = length(meta.metaTuples)
  delete!(meta.dictionary, field)
  meta.index = Dict(meta.metaTuples[i].fieldName => i for i::Int ∈ 1:NTuples)

  return meta
end

#removes fields from a meta dictionary
function removeFields!(meta::MetaDictionary, fields::Vector{Symbol})::MetaDictionary
  targets::Vector{Int} = ((s::Symbol)->meta.index[s]).(fields) #get the indices
  meta.metaTuples = meta.metaTuples[(i::Int->i ∉ targets).(1:end)] #delete the data

  NTuples = length(meta.metaTuples) #update the dictionaries
  #(delete!).(meta.dictionary, fields)
  meta.dictionary = Dict(
    meta.metaTuples[i].fieldName => meta.metaTuples[i].columnType for i::Int ∈ 1:NTuples)
  meta.index = Dict(
    meta.metaTuples[i].fieldName => i for i::Int ∈ 1:NTuples)

  return meta
end

function removeDictionary(metadata::Vector{MetaDictionary}, fileName::String)
  targets::Vector{Int} = Vector{Int}()
  NMeta::Int = length(metadata)

  for i::Int ∈ 1:NMeta
    if metadata[i].fileName == fileName
      push!(targets, i)
    end
  end

  if length(targets) < 1
    error("Attempted to delete $fileName but $fileName not found.")
  end

  metadata = metadata[((i::Int)->i ∉ targets).(1:NMeta)]

  return metadata
end

#returns a dictionary for converting data names to meta names
meta2Index(metadata::Vector{MetaDictionary})::Dict =
  Dict(metadata[i].fileName => i for i::Int ∈ 1:length(metadata))

max_stars_repo_name: clintonTE/CCA

max_issues_repo_name: clintonTE/CCA

max_forks_repo_name: clintonTE/CCA


text:
# Use baremodule to shave off a few KB from the serialized `.ji` file
baremodule STYRENE_jll
using Base
using Base: UUID
import JLLWrappers

JLLWrappers.@generate_main_file_header("STYRENE")
JLLWrappers.@generate_main_file("STYRENE", UUID("26c1a390-a91f-50e6-ae38-ce2477450035"))
end  # module STYRENE_jll


text:
# Autogenerated wrapper script for LibGit2_jll for aarch64-apple-darwin
export libgit2

using MbedTLS_jll
using LibSSH2_jll
JLLWrappers.@generate_wrapper_header("LibGit2")
JLLWrappers.@declare_library_product(libgit2, "@rpath/libgit2.1.1.dylib")
function __init__()
    JLLWrappers.@generate_init_header(MbedTLS_jll, LibSSH2_jll)
    JLLWrappers.@init_library_product(
        libgit2,
        "lib/libgit2.1.1.0.dylib",
        RTLD_LAZY | RTLD_DEEPBIND,
    )

    JLLWrappers.@generate_init_footer()
end  # __init__()


text:
using Jets, JetPackTransforms, LinearAlgebra, Test, FFTW

n1,n2 = 500,5
dt = 0.001

@testset "JopSft correctness test, T=$(T)" for T in (Float64,Float32)
    global n1,n2,dt
    f = fftfreq(n1) ./ dt
    freqs = T[f[5],f[9],f[13]]
    nfreq = length(freqs)
    dt = convert(T,dt)
    dom = JetSpace(T,n1,n2)
    rng = JetSpace(Complex{T},nfreq,n2)
    op = JopSft(dom,freqs,dt)
    x = zeros(domain(op))

    amp1 = 15.2873
    amp2 = 49.39874
    amp3 = 97.298743
    phs1 = 0.54321
    phs2 = 0.7654321
    phs3 = 1.87654321
    for k2 = 1:n2
        for k1 = 1:n1
            t = dt * (k1 - 1)
            x1 = amp1 * exp(im * (2 * pi * freqs[1] * t + phs1))
            x2 = amp2 * exp(im * (2 * pi * freqs[2] * t + phs2))
            x3 = amp3 * exp(im * (2 * pi * freqs[3] * t + phs3))
            x[k1,k2] = real(x1 + x2 + x3)
        end
    end

    y = op * x

    # actual amplitude and phase
    a1 = abs.(y[1,:])
    a2 = abs.(y[2,:])
    a3 = abs.(y[3,:])
    p1 = atan.(imag.(y[1,:]),real.(y[1,:]))
    p2 = atan.(imag.(y[2,:]),real.(y[2,:]))
    p3 = atan.(imag.(y[3,:]),real.(y[3,:]))

    rmsa1 = sqrt(norm(a1 .- amp1)^2/length(a1))
    rmsa2 = sqrt(norm(a2 .- amp2)^2/length(a2))
    rmsa3 = sqrt(norm(a3 .- amp3)^2/length(a3))

    rmsp1 = sqrt(norm(p1 .- phs1)^2/length(p1))
    rmsp2 = sqrt(norm(p2 .- phs2)^2/length(p2))
    rmsp3 = sqrt(norm(p3 .- phs3)^2/length(p3))

    @test rmsa1 < 1000 * eps(T)
    @test rmsa2 < 1000 * eps(T)
    @test rmsa3 < 1000 * eps(T)
    @test rmsp1 < 1000 * eps(T)
    @test rmsp2 < 1000 * eps(T)
    @test rmsp3 < 1000 * eps(T)
end

@testset "JopSft dot product test, T=$(T)" for T in (Float64,Float32)
    global n1,n2,dt
    f = fftfreq(n1) ./ dt
    freqs = T[f[5],f[9],f[13]]
    nfreq = length(freqs)
    dt = convert(T,dt)
    dom = JetSpace(T,n1,n2)
    rng = JetSpace(Complex{T},nfreq,n2)
    op = JopSft(dom,freqs,dt)
    x1 = rand(dom)
    y1 = rand(rng)
    y1 = op * rand(dom)
    lhs, rhs = dot_product_test(op, x1, y1)
    diff = abs((lhs - rhs) / (lhs + rhs))
    @test lhs ≈ rhs
end

@testset "JopSft linearity test, T=$(T)" for T in (Float64,Float32)
    global n1,n2,dt
    f = fftfreq(n1) ./ dt
    freqs = T[f[5],f[9],f[13]]
    nfreq = length(freqs)
    dt = convert(T,dt)
    dom = JetSpace(T,n1,n2)
    rng = JetSpace(Complex{T},nfreq,n2)
    op = JopSft(dom,freqs,dt)

    lhs,rhs = linearity_test(op)
    @test lhs ≈ rhs
end

nothing


text:
"""
Opaque handle referring to internal Vulkan data.
Finalizer registration is taken care of by constructors.
"""
abstract type Handle <: VulkanStruct{false} end

Base.:(==)(x::H, y::H) where {H<:Handle} = x.vks == y.vks
Base.hash(handle::Handle, h::UInt) = hash(handle.vks, h)

Base.show(io::IO, h::Handle) = print(io, typeof(h), '(', h.vks, ')')

handle(h::Handle) = h

const RefCounter = Threads.Atomic{UInt}

function increment_refcount!(handle::Handle)
    @pref_log_refcount Threads.atomic_add!(handle.refcount, UInt(1))
end

function decrement_refcount!(handle::Handle)
    @pref_log_refcount Threads.atomic_sub!(handle.refcount, UInt(1))
end

function try_destroy(f, handle::Handle, parent)
    decrement_refcount!(handle)
    if iszero(handle.refcount[])
        @pref_log_destruction f(handle) ≠ handle
        if !isnothing(parent)
            parent.destructor()
        end
    end
end

function init_handle!(handle::Handle, destructor, parent=nothing)
    handle.destructor = () -> try_destroy(destructor, handle, parent)
    finalizer(x -> handle.destructor(), handle)
end

function (T::Type{<:Handle})(ptr::Ptr{Cvoid}, destructor)
    init_handle!(T(ptr, RefCounter(UInt(1))), destructor)
end

function (T::Type{<:Handle})(ptr::Ptr{Cvoid}, destructor, parent)
    parent = handle(parent)
    increment_refcount!(parent)
    init_handle!(T(ptr, parent, RefCounter(UInt(1))), destructor, parent)
end

macro dispatch(handle, expr)
    if @load_preference("USE_DISPATCH_TABLE", "true") == "true"
        @match expr begin
            :($f($(args...))) => begin
                quote
                    fptr = get_fptr(global_dispatcher, $(esc(handle)), $(QuoteNode(f)))
                    $f($(esc.(args)...), fptr)
                end
            end
            _ => error("Expected a function call, got $expr")
        end
    else
        esc(expr)
    end
end


text:
################################################################################
# Define wrapped functions
module AddIntegersRust
using CxxInterface

const libAddIntegersRust = joinpath(pwd(), "libAddIntegersRust")

eval(rustsetup())
eval(rustnewfile("AddIntegersRust.rs", ""))

eval(rustfunction(FnName(:add_int, "add_int", libAddIntegersRust), FnResult(Int32, "i32", Int, expr -> :(convert(Int, $expr))),
                  [FnArg(:x, Int32, "x", "i32", Integer, identity), FnArg(:y, Int32, "y", "i32", Integer, identity)], "x + y"))
end

################################################################################
# Extract Rust code
using CxxInterface
using .AddIntegersRust
AddIntegersRust.rust_write_code!()

################################################################################
# Compile Rust code
# (This fails if there is no Rust compiler available)
using Libdl: dlext
run(`rustc --crate-type dylib -o libAddIntegersRust.$dlext AddIntegersRust.rs`)

# Please, DO NOT call a Rust compiler manually in your own Julia
# packages. This works only in very controlled environments such as on
# CI infrastructure. If you do, your package will be fragile, and will
# create lots of headaches for your users in the wild. Instead, use
# [BinaryBuilder](https://binarybuilder.org) and store your build
# recipes on [Yggdrasil](https://github.com/JuliaPackaging/Yggdrasil).

################################################################################
# Call the wrapped function
# (This fails if the Rust compiler is not compatible with the
# currently running Julia executable)

# Only test cases where the Github CI environment supports this (:i686 is not supported)
if Sys.ARCH ≡ :x86_64
    @test AddIntegersRust.add_int(2, 3) == 5
end


text:
function bleu{T<:Array{String,1}}(hyps::T, refs::Array{T}; captioning=false)
    if length(hyps) != length(refs)
        error("Hypothesis/references dimension mismatch")
    end

    N = 4
    hypothesis_length = references_length = 0
    clipped = Array{Float64}(N)
    total = Array{Float64}(N)

    for (hyp,ref) in zip(hyps, refs)
        # word or n-gram counts
        hypwc = map(n -> ngram_counts(hyp,n), 1:N)
        refwc = map(r -> map(n -> ngram_counts(r,n), 1:N), ref)

        hyplen = sum(values(hypwc[1]))
        reflen = map(x->sum(values(x[1])), refwc)
        diffs = sort(map(x -> (abs(x - hyplen), x), reflen))

        hypothesis_length += hyplen
        references_length += diffs[1][2]

        for n = 1:N
            c1 = collect(values(hypwc[n]))
            c2 = map(
                x -> mapreduce(r -> get(r[n], x, 0), max, refwc),
                keys(hypwc[n]))
            if length(c1) >= 1
                clipped[n] += sum(map(k->min(c1[k],c2[k]), 1:length(c1)))
                total[n] += sum(c1)
            end
        end
    end

    scores = zeros(N)
    if length(hyps) != 0
        scores = map(i -> clipped[i]/total[i], 1:N)
    end

    # brevity penalty
    bp = 1
    if hypothesis_length < references_length
        bp = exp(1-references_length/hypothesis_length)
    end

    bleuN = map(
        k -> bp * exp(mean(map(log, scores[(captioning ? 1 : k):k]))), 1:N)

    (bleuN, bp, hypothesis_length, references_length)
end

report_bleu(x::Tuple{Array{Float64,1},Int64,Int64,Int64}) = report_bleu(x...)
function report_bleu(
    bleuN::Array{Float64,1}, bp::Int64, hyplen::Int64, reflen::Int64)
    @printf("\nBLEU = %.1f/%.1f/%.1f/%.1f ", map(i->i*100,scores)...)
end


text:
module Lumira

# package code goes here
using Gadfly
using Base.show

export setId,setName,getId,getName,setToWriteToFile,exportToSVG,createTemplate,createChartCode,createLumiraExtension

type LumiraExtension
    Id::String
    Name::String
end

type flagToWriteToFile
    flag::Bool
end

extn = LumiraExtension("","")
fileotpt = flagToWriteToFile(true)

function setId(identifier)
	extn.Id = identifier
end

function setName(name)
    extn.Name = name
end

function getId()
    extn.Id
end

function getName()
    extn.Name
end

function setToWriteToFile(flag)
    fileotpt.flag = flag
end

function exportToSVG(plot)
    draw(SVG("tempplot.svg",22cm ,16cm), plot)
end

#use this function to create SAP Lumira Extension

function createLumiraExtension()
    if extn.Id != "" && extn.Name != ""
        folderloc = extn.Id
        commandList = ""
        commandList = string(commandList,"mkdir $folderloc","\ncd $folderloc","\nmkdir bundles","\ncd bundles")

        IdStr = extn.Id
        folderPath = ""
        pathFormer = ""

        for count = 1:endof(IdStr)
            if IdStr[count]=='.'
                commandList = string(commandList,"\nmkdir $folderPath","\ncd $folderPath")
                pathFormer = string(pathFormer,folderPath,"/")
                folderPath = ""
            else
                folderPath = string(folderPath,IdStr[count])
            end
        end
        commandList = string(commandList,"\nmkdir $folderPath","\ncd $folderPath")
        commandList = string(commandList,"\nmkdir resources","\ncd resources","\nmkdir templates","\ncd templates","\nmkdir sample","\ncd sample")

        pathFormer = string(pathFormer,folderPath,"/")
        templatePathFormer = string("resources/","templates/","sample/")

        if fileotpt.flag==true
            file = open("createFolderStruct.bat","w")
            write(file,commandList)
            close(file)
        else
            return true
        end

        run (`createFolderStruct.bat`)
        run (`rm createFolderStruct.bat`)
        createChartCode(string(extn.Id,"/","bundles","/",pathFormer,folderPath,"-bundle.js"))
        createTemplate(string(extn.Id,"/","bundles","/",pathFormer,templatePathFormer,"template.js"))

        run(`rm tempplot.svg`)
    end
end

function parseXML()
    if isfile("tempplot.svg")
        file = open("tempplot.svg")
        lines = readlines(file)
        close(file)

        finalArr = String[]
        push!(finalArr,"<svg")
        newCount = 0

        for count = 5:length(lines)
            line = chomp(lines[count])
            newline = ""
            flag = 0
            for index = 1:length(line)
                if line[index]=='\'' && flag==0
                    newline = string(newline,"' + \"'")
                    flag = 1
                elseif line[index]=='\'' && flag==1
                    newline = string(newline,"'\" + '")
                    flag = 0
                else
                    newline = string(newline,line[index])
                end
            end
            push!(finalArr,newline)
            newCount = newCount + 1
        end

        finalArr
    end
end

function createChartCode(folderPath)
    if fileotpt.flag==true
        file = open(folderPath,"w")
    end

    jsCodeString = string("(function() {",
"    /**",
"     * This function is a drawing function; you should put all your drawing logic in it.\n",
"     * it's called in moduleFunc.prototype.render\n",
"     * @param {Object} data - data set passed in\n",
"     * @param {SVG Group} vis - canvas which is an svg group element\n",
"     * @param {float} width - width of canvas\n",
"     * @param {float} height - height of canvas\n",
"     * @param {Array of color string} colorPalette - color palette\n",
"     * @param {Object} properties - properties of chart\n",
"     * @param {Object} dispatch - event dispatcher\n",
"     */\n",
"    function render(data, vis, width, height, colorPalette, properties, dispatch) {\n",
"        document.getElementsByTagName(\"head\")[0].innerHTML = document.getElementsByTagName(\"head\")[0].innerHTML + '<script type=\"text/javascript\"' + \n",
"'src=\"http://canvg.googlecode.com/svn/trunk/rgbcolor.js\"></script><script type=\"text/javascript\" src=\"http://canvg.googlecode.com/svn/trunk/StackBlur.js\">'+ \n",       "  '</script><script type=\"text/javascript\" src=\"http://canvg.googlecode.com/svn/trunk/canvg.js\"></script>'; \n",
"        document.getElementsByClassName(\"viz-controls-chart-layer\")[0].innerHTML = '<canvas id=\"canvas\"></canvas>';\n",
"        canvg(document.getElementById('canvas'),")

    svgReturned = parseXML()

    for count = 1:(length(svgReturned)-1)
        jsCodeString = string(jsCodeString,"'",svgReturned[count],"' +\n")
    end
    jsCodeString = string(jsCodeString,"'",svgReturned[length(svgReturned)],"'\n")

    jsCodeString = string(jsCodeString,");")

    jsCodeString = string(jsCodeString,"\n}\n",
"\n",
"\n",
"    /*------------------------------------------------------------------------*/\n",
"\n",
"    /*\n",
"     * In most cases, you don't need to modify the following code.\n",
"     */\n",
"\n",
"    var _util = {/*__FOLD__*/\n",
"        mapping : {\n",
"            dses : [],\n",
"            mses : []\n",
"        },\n",
"        /**\n",
"         * extract dimension sets from data\n",
"         * @param data [Crosstable Dataset] crosstable dataset\n",
"         * @returns array of dimension sets, and each dimension set is an object of {dimension: \"dimension name\", data: [members]}.\n",
"         * e.g. [{dimension: 'country', data: ['China', 'US', ...]}, {dimension: 'year', data: ['2010', '2011', ...]}, ...]\n",
"         */\n",
"        extractDimSets : function(data) {\n",
"            var dimSet1, dimSet2, res = [];\n",
"            if (data.getAnalysisAxisDataByIdx) {\n",
"                dimSet1 = data.getAnalysisAxisDataByIdx(0);\n",
"                dimSet2 = data.getAnalysisAxisDataByIdx(1);\n",
"            } else if (data.dataset && data.dataset.data) {\n",
"                data.dataset.data().analysisAxis.forEach(function(g){\n",
"                    var resg = [];\n",
"                    g.data.forEach(function(d){\n",
"                        var length = d.values.length;\n",
"                        var result = {};\n",
"                        result.data = [];\n",
"                        for(var i in d.values){\n",
"                            result.data[i] = d.values[i];\n",
"                        };\n",
"                        result.dimension = d.name;\n",
"                        resg.push(result);\n",
"                    });\n",
"                    res.push(resg);\n",
"                });\n",
"                return res;\n",
"            };\n",
"\n",
"            ",'\u0024',".each([dimSet1, dimSet2], function(idx, dimSet) {\n",
"                dimSet = dimSet ? dimSet.values : undefined;\n",
"                if (!dimSet)\n",
"                    return;\n",
"                var dims = [], dim;\n",
"                for (var i = 0; i < dimSet.length; i++) {\n",
"                    dim = {\n",
"                        dimension : dimSet[i].col.val,\n",
"                        data : []\n",
"                    };\n",
"                    for (var j = 0; j < dimSet[i].rows.length; j++)\n",
"                        dim.data.push(dimSet[i].rows[j].val);\n",
"                    dims.push(dim);\n",
"                }\n",
"                res.push(dims);\n",
"            });\n",
"            return res;\n",
"        },\n",
"        /**\n",
"         * extract measure sets from data\n",
"         * @param data [Crosstable Dataset] crosstable dataset\n",
"         * @returns array of measures, and each measure is an object of {measure: \"measure name\", data: [measure data]}.\n",
"         * for example, [[{measure: 'income', data: [555, 666, 777, ...]}, {measure: 'cost', data:[55, 66, 77, ...]}, ...], ...]\n",
"         */\n",
"        extractMeasureSets : function(data) {\n",
"\n",
"            var measureSet1, measureSet2, measureSet3, reses = [];\n",
"            if (data.getMeasureValuesGroupDataByIdx) {\n",
"                measureSet1 = data.getMeasureValuesGroupDataByIdx(0);\n",
"                measureSet2 = data.getMeasureValuesGroupDataByIdx(1);\n",
"                measureSet3 = data.getMeasureValuesGroupDataByIdx(2);\n",
"            }\n",
"            else if (data.dataset && data.dataset.data) {\n",
"                data.dataset.data().measureValuesGroup.forEach(function(g){\n",
"                    var resg = [];\n",
"                    g.data.forEach(function(d){\n",
"                        var length = d.values.length;\n",
"                        var result = {};\n",
"                        result.data = [];\n",
"                        for (var i in d.values) {\n",
"                            result.data[i] = d.values[i];\n",
"                        };\n",
"                        result.measure = d.name;\n",
"                        resg.push(result);\n",
"                    });\n",
"                    reses.push(resg);\n",
"                });\n",
"                return reses;\n",
"            };\n",
"\n",
"            ",'\u0024',".each([measureSet1, measureSet2, measureSet3], function(idx, measureSet) {\n",
"                measureSet = measureSet ? measureSet.values : undefined;\n",
"                if (!measureSet)\n",
"                    return;\n",
"                var res = [], resItem, resData, measure;\n",
"                for (var k = 0; k < measureSet.length; k++) {\n",
"                    measure = measureSet[k];\n",
"                    resItem = {\n",
"                        measure : measure.col,\n",
"                        data : []\n",
"                    };\n",
"                    resData = resItem.data;\n",
"                    for (var i = 0; i < measure.rows.length; i++) {\n",
"                        resData[i] = [];\n",
"                        for (var j = 0; j < measure.rows[i].length; j++) {\n",
"                            resData[i].push(measure.rows[i][j].val);\n",
"                        }\n",
"                    }\n",
"                    res.push(resItem);\n",
"                }\n",
"                reses.push(res);\n",
"            });\n",
"\n",
"            return reses;\n",
"        },\n",
"\n",
"        /**\n",
"         * convert crosstable data to flatten table data\n",
"         * @param data [Crosstable Dataset] crosstable dataset\n",
"         * @returns array of objects, and each object represents a row of data table:\n",
"         * [{\"dim set name\": [dim1 member, dim2 member, ...], ..., \"measure set name\": [measure1 value, measure2 value, ...]}, ...]\n",
"         * e.g. [{Time: ['2010', 'Jan'], Entity: ['China'], Profit: [555, 444]},  ...]\n",
"         *\n",
"         * In addition, the array has a meta data property; its name is meta.\n",
"         * It is an object with dim set name or measure set name as key,\n",
"         * and names of dims and names of measures as value:\n",
"         * {\"dim set name\": [dim1 name, dim2name, ...], ..., \"measure set name\": [measure1 name, measure2 name, ...], ...}\n",
"         * for example, {Time: ['Year', 'Month'], Entity: ['Country'], Profit: ['Gross Profit', 'Net Profit']}\n",
"         */\n",
"        toFlattenTable : function(data) {\n",
"            var dimSets = this.extractDimSets(data), measureSets = this.extractMeasureSets(data), fdata = [], datum, measure0Data, measure, me = this;\n",
"            //measureValueGroup is necessary in crosstable dataset\n",
"            //please directly call _util.extractDimSets() to get dimension values \n",
"            if (measureSets.length === 0) {\n",
"                return;\n",
"            }\n",
"            var i, j, k, m;\n",
"            //fill meta data\n",
"            fdata.meta = {};\n",
"            ",'\u0024',".each(dimSets, function(idx, dset) {\n",
"                if (!dset)\n",
"                    return;\n",
"                var name = me.mapping.dses[idx];\n",
"                fdata.meta[name] = dset.map(function(ele) {\n",
"                    return ele.dimension;\n",
"                });\n",
"            });\n",
"            ",'\u0024',".each(measureSets, function(idx, mset) {\n",
"                if (!mset)\n",
"                    return;\n",
"                var name = me.mapping.mses[idx];\n",
"                fdata.meta[name] = mset.map(function(ele) {\n",
"                    return ele.measure;\n",
"                });\n",
"            });\n",
"            //convert data from ct to flat\n",
"            measure0Data = measureSets[0][0].data;\n",
"            for ( i = 0; i < measure0Data.length; i++) {\n",
"                for ( j = 0; j < measure0Data[i].length; j++) {\n",
"                    datum = {};\n",
"                    ",'\u0024',".each(dimSets, function(idx, dimSet) {\n",
"                        if (!dimSet)\n",
"                            return;\n",
"                        var name = me.mapping.dses[idx];\n",
"                        var val = datum[name] = datum[name] || [];\n",
"                        var counter = idx === 0 ? j : i;\n",
"                        for ( m = 0; m < dimSet.length; m++) {\n",
"                            val.push(dimSet[m].data[counter]);\n",
"                        }\n",
"                    });\n",
"                    ",'\u0024',".each(measureSets, function(idx, measureSet) {\n",
"                        if (!measureSet)\n",
"                            return;\n",
"                        var name = me.mapping.mses[idx];\n",
"                        var val = datum[name] = datum[name] || [];\n",
"                        for ( m = 0; m < measureSet.length; m++) {\n",
"                            measure = measureSet[m];\n",
"                            val.push(measure.data[i][j]);\n",
"                        }\n",
"                    });\n",
"                    fdata.push(datum);\n",
"                }\n",
"            }\n",
"            return fdata;\n",
"        }\n",
"    };\n",
"\n",
"    (function() {/*__FOLD__*/\n",
"        // Drawing Function used by new created module\n",
"        var moduleFunc = {\n",
"            _colorPalette : d3.scale.category20().range().concat(d3.scale.category20b().range()).concat(d3.scale.category20c().range()), // color palette used by chart\n",
"            _dispatch : d3.dispatch(\"initialized\", \"startToInit\", 'barData') //event dispatcher\n",
"        };\n",
"\n",
"        moduleFunc.dispatch = function(_){\n",
"            if(!arguments.length){\n",
"                return this._dispatch;\n",
"            }\n",
"            this._dispatch = _;\n",
"            return this;\n",
"        };\n",
"\n",
"        //a temp flag used to distinguish new and old module style in manifest\n",
"\n",
"        /*\n",
"         * function of drawing chart\n",
"         */\n",
"        moduleFunc.render = function(selection) {\n",
"            //add xml ns for root svg element, so the image element can be exported to canvas\n",
"            ",'\u0024',"(selection.node().parentNode.parentNode).attr(\"xmlns:xlink\", \"http://www.w3.org/1999/xlink\");\n",
"\n",
"            //save instance variables to local variables because *this* is not referenced to instance in selection.each\n",
"            var _data = this._data, _width = this._width, _height = this._height, _colorPalette = this._colorPalette, _properties = this._properties, _dispatch = this._dispatch;\n",
"            _dispatch.startToInit();\n",
"            selection.each(function() {\n",
"                //prepare canvas with width and height of div container\n",
"                d3.select(this).selectAll('g.vis').remove();\n",
"                var vis = d3.select(this).append('g').attr('class', 'vis').attr('width', _width).attr('height', _height);\n",
"\n",
"                render.call(this, _data, vis, _width, _height, _colorPalette, _properties, _dispatch);\n",
"\n",
"            });\n",
"            _dispatch.initialized({\n",
"                name : \"initialized\"\n",
"            });\n",
"        };\n",
"\n",
"        /*\n",
"         * get/set your color palette if you support color palette\n",
"         */\n",
"        moduleFunc.colorPalette = function(_) {\n",
"            if (!arguments.length) {\n",
"                return this._colorPalette;\n",
"            }\n",
"            this._colorPalette = _;\n",
"            return this;\n",
"        };\n",
"\n",
"        /*flow Definition*/\n",
"        /*<<flow*/\n",
"        var flowRegisterFunc = function(){\n",
"            var flow = sap.viz.extapi.Flow.createFlow({\n",
"                id : '",extn.Id,"',\n",
"                name : '",extn.Name,"',\n",
"                dataModel : 'sap.viz.api.data.CrosstableDataset',\n",
"                type : 'BorderSVGFlow'\n",
"            });\n",
"            var element  = sap.viz.extapi.Flow.createElement({\n",
"                id : 'sap.viz.ext.module.HelloWorldModule',\n",
"                name : 'Hello World Module',\n",
"            });\n",
"            element.implement('sap.viz.elements.common.BaseGraphic', moduleFunc);\n",
"            /*Feeds Definition*/\n",
"            //ds1: City, Year\n",
"            var ds1 = {\n",
"                \"id\": \"sap.viz.ext.module.HelloWorldModule.DS1\",\n",
"                \"name\": \"Entity\",\n",
"                \"type\": \"Dimension\",\n",
"                \"min\": 1,\n",
"                \"max\": 2,\n",
"                \"aaIndex\": 1\n",
"            };\n",
"            _util.mapping.dses.push(\"Entity\");\n",
"            //ms1: Margin, Quantity sold, Sales revenue\n",
"            var ms1 = {\n",
"                \"id\": \"sap.viz.ext.module.HelloWorldModule.MS1\",\n",
"                \"name\": \"Sales Data\",\n",
"                \"type\": \"Measure\",\n",
"                \"min\": 1,\n",
"                \"max\": Infinity,\n",
"                \"mgIndex\": 1\n",
"            };\n",
"            _util.mapping.mses.push(\"Sales Data\");\n",
"            element.addFeed(ds1);\n",
"            element.addFeed(ms1);\n",
"            flow.addElement({\n",
"                'element':element,\n",
"                'propertyCategory' : '",extn.Id,"'\n",
"            });\n",
"            sap.viz.extapi.Flow.registerFlow(flow);\n",
"        };\n",
"        flowRegisterFunc.id = '",extn.Id,"';\n",
"         \n",
"        /*flow>>*/  \n",
"        var flowDefinition = {\n",
"          id:flowRegisterFunc.id,\n",
"          init:flowRegisterFunc  \n",
"        };\n",
"\n",
"        /*<<bundle*/\n",
"        var vizExtImpl = {\n",
"            viz   : [flowDefinition],\n",
"            module: [],\n",
"            feeds : []\n",
"        };\n",
"        var vizExtBundle = sap.bi.framework.declareBundle({\n",
"            \"id\" : \"",extn.Id,"\",\n",
"            \"loadAfter\" : [\"sap.viz.aio\"],\n",
"            \"components\" : [{\n",
"                \"id\" : \"",extn.Id,"\",\n",
"                \"provide\" : \"sap.viz.impls\",\n",
"                \"instance\" : vizExtImpl,\n",
"                \"customProperties\" : {\n",
"                    \"name\" : \"",extn.Name,"\",\n",
"                    \"description\" : \"",extn.Name,"\",\n",
"                    \"icon\" : {\"path\" : \"\"},\n",
"                    \"category\" : [],\n",
"                    \"resources\" : [{\"key\":\"sap.viz.api.env.Template.loadPaths\", \"path\":\"./resources/templates\"}]\n",
"                }\n",
"            }]\n",
"       });\n",
"       // sap.bi.framework.getService is defined in BundleLoader, which is\n",
"       // always available at this timeframe\n",
"       // in standalone mode sap.viz.js will force load and active the\n",
"       // \"sap.viz.aio\" bundle\n",
"       if (sap.bi.framework.getService(\"sap.viz.aio\", \"sap.viz.extapi\")) {\n",
"           // if in standalone mode, sap.viz.loadBundle will be available,\n",
"           // and we load the bundle directly\n",
"           sap.bi.framework.getService(\"sap.viz.aio\", \"sap.viz.extapi\").core.registerBundle(vizExtBundle);\n",
"       } else {\n",
"           // if loaded by extension framework, return the \"sap.viz.impls\"\n",
"           // provider component via define()\n",
"           define(function() {\n",
"               return vizExtBundle;\n",
"           });\n",
"       } \n",
"        /*bundle>>*/ \n",
"\n",
"        //register the chart so it can be created\n",
"    })();\n",
"\n",
"})();\n"
)

    if fileotpt.flag==true
        write(file,jsCodeString)
        close(file)
    else
        return true
    end
end

function createTemplate(path)
    templateCode = string("var sampleTemplate = \n",
"{\n",
"    \"id\": \"sample\",\n",
"    \"name\": \"Sample\",\n",
"    \"properties\": {\n",
"        \"",extn.Id,"\": {\n",
"            \"legend\": {\n",
"                \"title\": {\n",
"                    \"visible\": true,\n",
"                    \"text\": \"Legends\"\n",
"                }\n",
"            }\n",
"        }\n",
"    },\n",
"    \"css\": \".viz-title-label.v-title {fill: #000fff}\"\n",
"};\n",
"sap.viz.extapi.env.Template.register(sampleTemplate);\n"
)

    if fileotpt.flag==true
        file = open(path,"w")
        write(file,templateCode)
        close(file)
    else
        true
    end

end

end # module


text:
#=
LCM Server: an LCM interface to Caesar.jl

=#

using Caesar
using LCMCore, CaesarLCMTypes
using TransformUtils, Rotations, CoordinateTransformations, Distributions
using LibBSON, Unmarshal

using RobotTestDatasets

# Does: using SynchronySDK
include(joinpath(dirname(@__FILE__), "synchronySDKIntegration.jl"))

"""
Store robot parameters in the centralized database system.
"""
function setRobotParameters!(sslaml::SyncrSLAM)
  rovconf = Dict{String, String}() # TODO relax to Dict{String, Any}
  rovconf["robot"] = "hovering-rov"
  rovconf["bTc"] = "[0.0;0.0;0.0; 1.0; 0.0; 0.0; 0.0]"
  rovconf["bTc_format"] = "xyzqwqxqyqz"
  # currently unused, but upcoming
  rovconf["pointcloud_description_name"] = "BSONpointcloud"
  rovconf["pointcloud_color_description_name"] = "BSONcolors"

  # Actually modify the databases
  Syncr.updateRobotConfig(sslaml.syncrconf, sslaml.robotId, rovconf)

  nothing
end

"""
Adds pose nodes to graph with a prior on Z, pitch, and roll.
"""
function handle_poses!(slaml::SyncrSLAM,
                       msg::pose_node_t)
    #
    id = msg.id
    println("[Caesar.jl] Received pose msg for x$(id)")

    mean = msg.mean
    covar = msg.covar
    t = [mean[1], mean[2], mean[3]]
    qw = mean[4]
    qxyz = [mean[5], mean[6], mean[7]]
    q = Quaternion(qw,qxyz) # why not a (w,x,y,z) constructor?
    pose = SE3(t,q)
    euler = Euler(q)

    node_label = Symbol("x$(id)")
    xn = addNode!(slaml, node_label, Pose3) # this is an incremental inference call
    slaml.lastposesym = node_label; # update object

    if id == 1
        println("[Caesar.jl] First pose")
        # this is the first msg, and it does not carry odometry, but the prior on the first node.

        # add 6dof prior
        initPosePrior = PriorPose3( MvNormal( veeEuler(pose), diagm([covar...]) ) )
        addFactor!(slaml, [xn], initPosePrior)

        # auto init is coming, this code will likely be removed
        initializeNode!(slaml, node_label)

        # set robot parameters in the first pose, this will become a separate node in the future
        println("[Caesar.jl] Setting robot parameters")
        setRobotParameters!(slaml)
    end
end

"""
Handle ZPR priors on poses.
"""
function handle_priors!(slam::SyncrSLAM,
                         msg::prior_zpr_t)

    id = msg.id
    println("[Caesar.jl] Adding prior on RPZ to x$(id)")

    node_label = Symbol("x$(id)")
    xn = getVert(slam,node_label)

    z = msg.z
    pitch = msg.pitch
    roll = msg.roll

    var_z = msg.var_z
    var_pitch = msg.var_pitch
    var_roll = msg.var_roll

    rp_dist = MvNormal( [roll;pitch], diagm([var_roll, var_pitch]))
    z_dist = Normal(z, var_z)
    prior_rpz = PartialPriorRollPitchZ(rp_dist, z_dist)
    addFactor!(slam, [xn], prior_rpz)
end

"""
Handle partial x, y, and heading odometry constraints between Pose3 variables.
"""
function handle_partials!(slam::SyncrSLAM,
                         msg::pose_pose_xyh_t)

    origin_id = msg.node_1_id
    destination_id = msg.node_2_id
    origin_label = Symbol("x$(origin_id)")
    destination_label = Symbol("x$(destination_id)")

    println("[Caesar.jl] Adding XYH odometry constraint between(x$(origin_id), x$(destination_id))")

    delta_x = msg.delta_x
    delta_y = msg.delta_y
    delta_yaw = msg.delta_yaw

    var_x = msg.var_x
    var_y = msg.var_y
    var_yaw = msg.var_yaw

    origin_label, destination_label
    xo = getVert(slam,origin_label)
    xd = getVert(slam,destination_label)

    xyh_dist = MvNormal([delta_x, delta_y, delta_yaw], diagm([var_x, var_y, var_yaw]))
    xyh_factor = PartialPose3XYYaw(xyh_dist)
    addFactor!(slam, [xo;xd], xyh_factor)

    initializeNode!(slam, destination_label)
    println()
end

"""
Handle loop closure proposals with chance of being a null hypothesis likelihood.
"""
function handle_loops!(slaml::SyncrSLAM,
                       msg::pose_pose_xyh_nh_t)

    origin_id = msg.node_1_id
    destination_id = msg.node_2_id
    origin_label = Symbol("x$(origin_id)")
    destination_label = Symbol("x$(destination_id)")

    delta_x = msg.delta_x
    delta_y = msg.delta_y
    delta_yaw = msg.delta_yaw

    var_x = msg.var_x
    var_y = msg.var_y
    var_yaw = msg.var_yaw
    confidence = msg.confidence

    xo = getVert(slaml.fg,origin_label)
    xd = getVert(slaml.fg,destination_label)

    # if (destination_id - origin_id == 1)
    #     warn("Avoiding parallel factor! See: https://github.com/dehann/IncrementalInference.jl/issues/63To ")
    #     return
    # end

    println("[Caesar.jl] Adding XYH-NH loop closure constraint between (x$(origin_id), x$(destination_id))")
    xyh_dist = MvNormal([delta_x, delta_y, delta_yaw], diagm([var_x, var_y, var_yaw]))
    xyh_factor = PartialPose3XYYawNH(xyh_dist ,[1.0-confidence, confidence]) # change to NH
    addFactor!(slaml, [xo;xd], xyh_factor )

    # println("[Caesar.jl] Adding P3P3NH loop closure constraint between (x$(origin_id), x$(destination_id))")

    # # line below fails!
    # lcf = Pose3Pose3NH( MvNormal(veeEuler(rel_pose), diagm(1.0./covar)), [0.5;0.5]) # define 50/50% hypothesis
    # lcf_label = Symbol[origin_label;destination_label]

    # addFactor!(slaml, lcf_label, lcf)
end

# type Cloud
#     points::
#     colors::
# end

# function add_pointcloud!(slaml::SyncrSLAM, nodeID::Symbol, cloud::Cloud )
#     # fetch from database
#     vert = getVert(slaml.fg, nodeID, api=IncrementalInference.dlapi)

#     # add points blob
#     serialized_point_cloud = BSONObject(Dict("pointcloud" => cloud.points))
#     appendvertbigdata!(slaml.fg, vert, "BSONpointcloud", string(serialized_point_cloud).data)

#     # add colors blob
#     serialized_colors = BSONObject(Dict("colors" => cloud.colors))
#     appendvertbigdata!(slaml.fg, vert, "BSONcolors", string(serialized_colors).data)
# end

"""
Callback for caesar_point_cloud_t msgs. Adds point cloud to SLAM_Client
"""
function handle_clouds!(slaml::SyncrSLAM,
                        msg::point_cloud_t)
    # TODO: interface here should be as simple as slam_client.add_pointcloud(nodeID, pc::SomeCloudType)

    # TODO: check for empty clouds!

    id = msg.id

    last_pose = Symbol("x$(id)")
    println("[Caesar.jl] Got cloud $id")

    # 2d arrays of points and colors (from LCM data into arrays{arrays})
    points = [[pt[1], pt[2], pt[3]] for pt in msg.points]
    colors = [[UInt8(c.data[1]),UInt8(c.data[2]),UInt8(c.data[3])] for c in msg.colors]

    # TODO: check if vert exists or not (may happen if msgs are lost or out of order)
    vert = getVert(slaml, last_pose, api=IncrementalInference.dlapi) # fetch from database

    # push to mongo (using BSON as a quick fix)
    # (for deserialization, see src/DirectorVisService.jl:cachepointclouds!)
    serialized_point_cloud = BSONObject(Dict("pointcloud" => points))
    appendvertbigdata!(slaml, vert, "BSONpointcloud", string(serialized_point_cloud).data)
    serialized_colors = BSONObject(Dict("colors" => colors))
    appendvertbigdata!(slaml, vert, "BSONcolors", string(serialized_colors).data)
end

# this function handles lcm msgs
function listener!(lcm_node::Union{LCMCore.LCM, LCMCore.LCMLog})
    # handle traffic
    # TODO: handle termination
    while true
        handle(lcm_node)
    end
end

# 0. Constants
println("[Caesar.jl] defining constants.")
robotId = "HROV"
sessionId = "LCM_01"

# create a SLAM container object
slam_client = SyncrSLAM(robotId=robotId,sessionId=sessionId)

# initialize a new session ready for SLAM using the built in SynchronySDK
println("[Caesar.jl] Setting up remote solver")
initialize!(slam_client)

setRobotParameters!(slam_client)
# TEST: Getting robotConfig
@show robotConfig = Syncr.getRobotConfig(slam_client.syncrconf, slam_client.robotId)

# TODO - should have a function that allows first pose and prior to be set by user.

# create new handlers to pass in additional data
lcm_pose_handler = (channel, message_data) -> handle_poses!(slam_client, message_data )
lcm_odom_handler = (channel, message_data) -> handle_partials!(slam_client, message_data )
lcm_prior_handler = (channel, message_data) -> handle_priors!(slam_client, message_data )
lcm_cloud_handler = (channel, message_data) -> handle_clouds!(slam_client, message_data )
lcm_loop_handler = (channel, message_data) -> handle_loops!(slam_client, message_data )

# create LCM object and subscribe to messages on the following channels
logfile = robotdata("rovlcm_singlesession_01")
lcm_node = LCMLog(logfile) # for direct log file access
# lcm_node = LCM() # for UDP Ethernet traffic version

# poses
subscribe(lcm_node, "CAESAR_POSES", lcm_pose_handler, pose_pose_nh_t)
# factors
subscribe(lcm_node, "CAESAR_PARTIAL_XYH", lcm_odom_handler, pose_pose_xyh_t)
subscribe(lcm_node, "CAESAR_PARTIAL_ZPR", lcm_prior_handler, prior_zpr_t)
# loop closures come in via p3p3nh factors
subscribe(lcm_node, "CAESAR_PARTIAL_XYH_NH", lcm_loop_handler, pose_pose_xyh_nh_t)
# sensor data
subscribe(lcm_node, "CAESAR_POINT_CLOUDS", lcm_cloud_handler, point_cloud_t)

println("[Caesar.jl] Running LCM listener")
listener!(lcm_node)


text:
using DirectDependents
using Test

@testset "DirectDependents.jl" begin
    @test !isempty(direct_dependents("RecipesBase"))
end


text:
using BenchmarkTools, LiiBRA, MAT, StatsBase, Plots

BenchmarkTools.DEFAULT_PARAMETERS.seconds = 50
Cell = Construct("LG M50")
#SList = collect(0.725:-0.025:0.625)
SList = collect(1:-0.25:0.0)
#SList = collect(0.8)
SOC = 0.717
T = 298.15

function DRA_Loop(Cell, SList::Array, T::Float64)
    A = B = C = D = Time = x = tuple()
    for i in 2500:2500:2500

        #Arrhenius
        Cell.Const.T = T
        Arr_Factor = (1/Cell.Const.T_ref-1/Cell.Const.T)/R

        Cell.RA.H1 = 1:i
        Cell.RA.H2 = 1:i
        Cell.RA.Tlen = 16200
        Cell.RA.Fs = 4
        Cell.RA.M = 6
        Cell.RA.SamplingT = 1/4

        #Set Cell Constants
        Cell.Const.κ = Cell.Const.κf(Cell.Const.ce0)*exp(Cell.Const.Ea_κ*Arr_Factor)
        Cell.RA.Nfft = Cell.RA.Nfft!(Cell.RA.Fs, Cell.RA.Tlen)
        Cell.RA.f = Cell.RA.f!(Cell.RA.Nfft)
        Cell.RA.s = Cell.RA.s!(Cell.RA.Fs,Cell.RA.Nfft,Cell.RA.f)
        Cell.Neg.β = Cell.Neg.β!(Cell.RA.s)
        Cell.Pos.β = Cell.Pos.β!(Cell.RA.s)

        for Cell.Const.SOC in SList
            #Realisation
            A_DRA, B_DRA, C_DRA, D_DRA = DRA(Cell)
            A = flatten_(A,A_DRA)
            B = flatten_(B,B_DRA)
            C = flatten_(C,C_DRA)
            D = flatten_(D,D_DRA)
        end
        # x = @benchmark DRA(Cell)
        # Time = flatten_(Time,x)

    end
    return Time, A, B, C, D
end

#---------- Experimental Data -----------------#

function Sim_loop(Cell, Input, SList, SOC, A, B, C, D)
    CellV = tDra = Ce = jNeg = jPos = RtotNeg = RtotPos = η0 = ηL = η_neg = η_pos = ϕ_ẽ1 = ϕ_ẽ2 = Uocp_Neg = Uocp_Pos = ϕ_e = Cse_Neg = Cse_Pos = Cell_SOC = SimTime = x = tuple()
       for i in Int64(1/Cell.RA.SamplingT):Int64(1/Cell.RA.SamplingT):Int64(1/Cell.RA.SamplingT)
           Tk = ones(length(Input))*298.15 #Cell Temperature
           time_ = 0:(1.0/i):(length(Input)*(1/i))
           tDra = flatten_(tDra,time_)

           u = 1
           k = 0
           for i in 1:Int64(tuple_len(C)/length(SList))

                k += length(SList)
                Cell_V, Ce_, jNeg, jPos, Rtot_neg, Rtot_pos, η0, ηL, η_neg, η_pos, ϕ_ẽ1, ϕ_ẽ2, Uocp_Neg_, Uocp_Pos_, ϕ_e, Cse_Neg_, Cse_Pos_, Cell_SOC, jeq_neg, jeq_pos, j0, jL, tDra = Sim_Model(Cell,Input,"Power",Tk,SList,SOC,A[u:k],B[u:k],C[u:k],D[u:k],tDra)
                u = k+1

                CellV = flatten_(CellV,Cell_V)
                Ce = flatten_(Ce,Ce_)
                Cse_Neg = flatten_(Cse_Neg,Cse_Neg_)
                Cse_Pos = flatten_(Cse_Pos,Cse_Pos_)
                Uocp_Neg = flatten_(Uocp_Neg,Uocp_Neg_)
                Uocp_Pos = flatten_(Uocp_Pos,Uocp_Pos_)

           end
           #for i in 1:12
           # @time Sim_Model(Cell,Input,"Power",Tk,SList,SOC,A,B,C,D)
           #end
       end
       return CellV, Ce, jNeg, jPos, RtotNeg, RtotPos, η0, ηL, η_neg, η_pos, ϕ_ẽ1, ϕ_ẽ2, Uocp_Neg, Uocp_Pos, ϕ_e, Cse_Neg, Cse_Pos, tDra, Cell_SOC, SimTime
   end

   function Stats()
       for i in 1:tuple_len(CellV)
           Rms_V[i] = rmsd(CellV[i],Pyb_V) # V
           Max_V[i] = maxad(CellV[i],Pyb_V) # V

           Rms_Cn[i] = rmsd(Cse_Neg[i][:,end],Pyb_Cn[20,20,:]) #mol
           Max_Cn[i] = maxad(Cse_Neg[i][:,end],Pyb_Cn[20,20,:]) #mol

           Rms_Cp[i] = rmsd(Cse_Pos[i][:,end],Pyb_Cp[20,20,:]) #mol
           Max_Cp[i] = maxad(Cse_Pos[i][:,end],Pyb_Cp[20,20,:]) #mol

       end
   return Rms_Cn, Max_Cn, Rms_Cp, Max_Cp, Rms_V, Max_V
   end

   Time, A, B, C, D = DRA_Loop(Cell, SList, T)
   WLTP_File = matopen("test/WLTP/WLTP_M50_M3.mat")
   WLTP_P = read(WLTP_File,"P_Models")
   #Iapp = [ones(1)*0.; ones(10*i)*4.8181; ones(40*i)*0.; ones(10*i)*-3.613; ones(40*i+1)*0.] #1C HPPC Experiment Current Profile
   CellV, Ce, jNeg, jPos, RtotNeg, RtotPos, η0, ηL, η_neg, η_pos, ϕ_ẽ1, ϕ_ẽ2, Uocp_Neg, Uocp_Pos, ϕ_e, Cse_Neg, Cse_Pos, tDra, Cell_SOC, SimTime = Sim_loop(Cell, WLTP_P, SList, SOC, A, B, C, D)

   Pyb_File = matopen("test/WLTP/sol_data.mat")#
   Pyb_Cn = read(Pyb_File,"c_n")
   Pyb_Cp = read(Pyb_File,"c_p")
   Pyb_T = read(Pyb_File,"t")
   Pyb_V = read(Pyb_File,"V")
   Rms_Cn = Array{Float64}(undef,tuple_len(CellV),1)
   Max_Cn = Array{Float64}(undef,tuple_len(CellV),1)
   Rms_Cp = Array{Float64}(undef,tuple_len(CellV),1)
   Max_Cp = Array{Float64}(undef,tuple_len(CellV),1)
   Rms_V = Array{Float64}(undef,tuple_len(CellV),1)
   Max_V = Array{Float64}(undef,tuple_len(CellV),1)

   Rms_Cn, Max_Cn, Rms_Cp, Max_Cp, Rms_V = Stats()

max_stars_repo_name: BradyPlanden/LiBRA

max_forks_repo_name: BradyPlanden/LiBRA


text:
rig_key = "ocpi-1"
push!(RIGS, rig_key)
#Mappings from DAQ channel to friendlier default names
const ocpi1_mappings = Dict("AO0"=>"axial piezo",
                      "AO1"=>"analogout1",
                      "AI0"=>"axial piezo monitor",
                      "AI1"=>"stimuli",
                      "AI2"=>"analogin1",
                      "AI3"=>"analogin2",
                      "AI4"=>"analogin3",
                      "AI5"=>"analogin4",
                      "AI6"=>"analogin5",
                      "AI7"=>"analogin6",
                      "AI8"=>"analogin7",
                      "AI9"=>"analogin8",
                      "AI10"=>"analogin9",
                      "AI11"=>"analogin10",
                      "AI12"=>"analogin11",
                      "AI13"=>"analogin12",
                      "AI14"=>"analogin13",
                      "AI15"=>"analogin14",
                      "P0.0"=>"stimulus1",
                      "P0.1"=>"stimulus2",
                      "P0.2"=>"stimulus3",
                      "P0.3"=>"stimulus4",
                      "P0.4"=>"488nm laser shutter",
                      "P0.5"=>"camera1",
                      "P0.6"=>"stimulus5",
                      "P0.7"=>"camera1 frame monitor")

DEFAULT_DAQCHANS_TO_NAMES[rig_key] = ocpi1_mappings
DEFAULT_NAMES_TO_DAQCHANS[rig_key] = dictmap(reverse, ocpi1_mappings)

const ocpi1_aochans = map(x->"AO$(x)", 0:1)
const ocpi1_aichans = map(x->"AI$(x)", 0:15)
const ocpi1_dochans = map(x->"P0.$(x)", 0:6)
const ocpi1_dichans = ["P0.7";]
const ocpi1_pos_ctrl_chans = map(x->DEFAULT_NAMES_TO_DAQCHANS[rig_key][x], ["axial piezo"])
const ocpi1_pos_mon_chans = map(x->DEFAULT_NAMES_TO_DAQCHANS[rig_key][x], ["axial piezo monitor"])
const ocpi1_cam_ctrl_chans = map(x->DEFAULT_NAMES_TO_DAQCHANS[rig_key][x], ["camera1"])
const ocpi1_cam_mon_chans = map(x->DEFAULT_NAMES_TO_DAQCHANS[rig_key][x], ["camera1 frame monitor"])
const ocpi1_laschans = map(x->DEFAULT_NAMES_TO_DAQCHANS[rig_key][x], ["488nm laser shutter"])
const ocpi1_stimchans = map(x->DEFAULT_NAMES_TO_DAQCHANS[rig_key][x], ["stimulus$x" for x = 1:5])
const ocpi1_fixed_names = ["axial piezo", "axial piezo monitor", "488nm laser shutter", "camera1", "camera1 frame monitor", "stimuli"]
const ocpi1_fixed_daqchans = map(x->DEFAULT_NAMES_TO_DAQCHANS[rig_key][x], ocpi1_fixed_names)

AO_CHANS[rig_key] = OrderedSet(ocpi1_aochans)
AI_CHANS[rig_key] = OrderedSet(ocpi1_aichans)
DO_CHANS[rig_key] = OrderedSet(ocpi1_dochans)
DI_CHANS[rig_key] = OrderedSet(ocpi1_dichans)
POS_CONTROL_CHANS[rig_key] = ocpi1_pos_ctrl_chans
POS_MONITOR_CHANS[rig_key] = ocpi1_pos_mon_chans
CAM_CONTROL_CHANS[rig_key] = ocpi1_cam_ctrl_chans
CAM_MONITOR_CHANS[rig_key] = ocpi1_cam_mon_chans
LAS_CONTROL_CHANS[rig_key] = ocpi1_laschans
STIM_CHANS[rig_key] =OrderedSet(ocpi1_stimchans)
GALVO_CONTROL_CHANS[rig_key] = String[]
GALVO_MONITOR_CHANS[rig_key] = String[]
FIXED_NAMES[rig_key] = ocpi1_fixed_names
FIXED_DAQ_CHANS[rig_key] = ocpi1_fixed_daqchans

RIG_CHIP_SIZES[rig_key] = PCO_EDGE_5_5_CHIP_SIZE
RIG_FRAMERATE_FUNCS[rig_key] = PCO_EDGE_5_5_FRAMERATE_FUNC
RIG_ROI_FUNCS[rig_key] = PCO_EDGE_5_5_ROI_FUNC

LASER_ON_TIME[rig_key] = 100 * Unitful.ms
LASER_OFF_TIME[rig_key] = 100 * Unitful.ms

CAMERA_ON_TIME[rig_key] = 19526.0 * Unitful.ns #This is the worst jitter measured with Edge 5.5 and 4.2 cameras, see ImagineInterface issue #18
CAMERA_OFF_TIME[rig_key] = 19526.0 * Unitful.ns #This is the worst jitter measured with Edge 5.5 and 4.2 cameras, see ImagineInterface issue #18

PIEZO_RANGES[rig_key] = (0.0μm .. 400.0μm, 0.0V .. 10.0V)
PIEZO_MAX_SPEED[rig_key] = 2000*Unitful.μm / Unitful.s
AO_RANGE[rig_key] = -10.0V .. 10.0V
AI_RANGE[rig_key] = AO_RANGE[rig_key] #TODO: make sure this is true.  (true if we are recording -10..10V on analog inputs)

max_forks_repo_name: HolyLab/ImagineInterface


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

mutable struct IoK8sApiNodeV1beta1RuntimeClass <: SwaggerModel
    apiVersion::Any # spec type: Union{ Nothing, String } # spec name: apiVersion
    handler::Any # spec type: Union{ Nothing, String } # spec name: handler
    kind::Any # spec type: Union{ Nothing, String } # spec name: kind
    metadata::Any # spec type: Union{ Nothing, IoK8sApimachineryPkgApisMetaV1ObjectMeta } # spec name: metadata

    function IoK8sApiNodeV1beta1RuntimeClass(;apiVersion=nothing, handler=nothing, kind=nothing, metadata=nothing)
        o = new()
        validate_property(IoK8sApiNodeV1beta1RuntimeClass, Symbol("apiVersion"), apiVersion)
        setfield!(o, Symbol("apiVersion"), apiVersion)
        validate_property(IoK8sApiNodeV1beta1RuntimeClass, Symbol("handler"), handler)
        setfield!(o, Symbol("handler"), handler)
        validate_property(IoK8sApiNodeV1beta1RuntimeClass, Symbol("kind"), kind)
        setfield!(o, Symbol("kind"), kind)
        validate_property(IoK8sApiNodeV1beta1RuntimeClass, Symbol("metadata"), metadata)
        setfield!(o, Symbol("metadata"), metadata)
        o
    end
end # type IoK8sApiNodeV1beta1RuntimeClass

const _property_map_IoK8sApiNodeV1beta1RuntimeClass = Dict{Symbol,Symbol}(Symbol("apiVersion")=>Symbol("apiVersion"), Symbol("handler")=>Symbol("handler"), Symbol("kind")=>Symbol("kind"), Symbol("metadata")=>Symbol("metadata"))
const _property_types_IoK8sApiNodeV1beta1RuntimeClass = Dict{Symbol,String}(Symbol("apiVersion")=>"String", Symbol("handler")=>"String", Symbol("kind")=>"String", Symbol("metadata")=>"IoK8sApimachineryPkgApisMetaV1ObjectMeta")
Base.propertynames(::Type{ IoK8sApiNodeV1beta1RuntimeClass }) = collect(keys(_property_map_IoK8sApiNodeV1beta1RuntimeClass))
Swagger.property_type(::Type{ IoK8sApiNodeV1beta1RuntimeClass }, name::Symbol) = Union{Nothing,eval(Meta.parse(_property_types_IoK8sApiNodeV1beta1RuntimeClass[name]))}
Swagger.field_name(::Type{ IoK8sApiNodeV1beta1RuntimeClass }, property_name::Symbol) =  _property_map_IoK8sApiNodeV1beta1RuntimeClass[property_name]

function check_required(o::IoK8sApiNodeV1beta1RuntimeClass)
    (getproperty(o, Symbol("handler")) === nothing) && (return false)
    true
end

function validate_property(::Type{ IoK8sApiNodeV1beta1RuntimeClass }, name::Symbol, val)
end


text:
abstract type FirstColCount end

struct FirstMultiCol <: FirstColCount end
struct FirstSingleCol <: FirstColCount end

firstcoltype(firstmulticol::Bool) =
    firstmulticol ? FirstMultiCol() : FirstSingleCol()

# Wrapping automatically adds column names when the value returned
# by the user-provided function lacks them
wrap(x::Union{AbstractDataFrame, DataFrameRow}) = x
wrap(x::NamedTuple) = x
function wrap(x::NamedTuple{<:Any, <:Tuple{Vararg{AbstractVector}}})
    if !isempty(x)
        len1 = length(x[1])
        for i in 2:length(x)
            length(x[i]) == len1 || throw(DimensionMismatch("all vectors returned in a " *
                                                            "NamedTuple must have the same length"))
        end
    end
    return x
end
wrap(x::AbstractMatrix) =
    NamedTuple{Tuple(gennames(size(x, 2)))}(Tuple(view(x, :, i) for i in 1:size(x, 2)))
wrap(x::Any) = (x1=x,)

const ERROR_ROW_COUNT = "return value must not change its kind " *
                        "(single row or variable number of rows) across groups"

const ERROR_COL_COUNT = "function must return only single-column values, " *
                        "or only multiple-column values"

wrap_table(x::Any, ::FirstSingleCol) =
    throw(ArgumentError(ERROR_ROW_COUNT))
wrap_table(x::Any, ::FirstMultiCol) =
    throw(ArgumentError(ERROR_ROW_COUNT))
wrap_table(x::Union{NamedTuple{<:Any, <:Tuple{Vararg{AbstractVector}}},
                    AbstractDataFrame, AbstractMatrix}, ::FirstSingleCol) =
        throw(ArgumentError(ERROR_COL_COUNT))
wrap_table(x::Union{NamedTuple{<:Any, <:Tuple{Vararg{AbstractVector}}},
                    AbstractDataFrame, AbstractMatrix}, ::FirstMultiCol) =
    wrap(x)
wrap_table(x::AbstractVector, ::FirstSingleCol) = wrap(x)
wrap_table(x::AbstractVector, ::FirstMultiCol) = throw(ArgumentError(ERROR_COL_COUNT))

wrap_row(x::DataFrameRow, ::FirstSingleCol) = throw(ArgumentError(ERROR_COL_COUNT))
wrap_row(x::DataFrameRow, ::FirstMultiCol) = wrap(x)
wrap_row(x::Any, ::FirstSingleCol) = wrap(x)
# NamedTuple is not possible in this branch
wrap_row(x::Any, ::FirstMultiCol) = throw(ArgumentError(ERROR_COL_COUNT))

wrap_row(x::Union{AbstractArray{<:Any, 0}, Ref}, ::FirstMultiCol) =
    throw(ArgumentError(ERROR_COL_COUNT))
wrap_row(x::Union{AbstractArray{<:Any, 0}, Ref}, ::FirstSingleCol) =
    (x1 = x[],)
# note that also NamedTuple() is correctly captured by this definition
# as it is more specific than the one below
wrap_row(::Union{AbstractVecOrMat, AbstractDataFrame,
                 NamedTuple{<:Any, <:Tuple{Vararg{AbstractVector}}}}, ::FirstSingleCol) =
    throw(ArgumentError(ERROR_ROW_COUNT))
wrap_row(::Union{AbstractVecOrMat, AbstractDataFrame,
                 NamedTuple{<:Any, <:Tuple{Vararg{AbstractVector}}}}, ::FirstMultiCol) =
    throw(ArgumentError(ERROR_ROW_COUNT))

wrap_row(x::NamedTuple, ::FirstSingleCol) = throw(ArgumentError(ERROR_COL_COUNT))

function wrap_row(x::NamedTuple, ::FirstMultiCol)
    if any(v -> v isa AbstractVector, x)
        throw(ArgumentError("mixing single values and vectors in a named tuple is not allowed"))
    end
    return x
end

# idx, starts and ends are passed separately to avoid cost of field access in tight loop
# Manual unrolling of Tuple is used as it turned out more efficient than @generated
# for small number of columns passed.
# For more than 4 columns `map` is slower than @generated
# but this case is probably rare and if huge number of columns is passed @generated
# has very high compilation cost
function do_call(f::Base.Callable, idx::AbstractVector{<:Integer},
                 starts::AbstractVector{<:Integer}, ends::AbstractVector{<:Integer},
                 gd::GroupedDataFrame, incols::Tuple{}, i::Integer)
    if f isa ByRow
        return [f.fun() for _ in 1:(ends[i] - starts[i] + 1)]
    else
        return f()
    end
end

function do_call(f::Base.Callable, idx::AbstractVector{<:Integer},
                 starts::AbstractVector{<:Integer}, ends::AbstractVector{<:Integer},
                 gd::GroupedDataFrame, incols::Tuple{AbstractVector}, i::Integer)
    idx = view(idx, starts[i]:ends[i])
    return f(view(incols[1], idx))
end

function do_call(f::Base.Callable, idx::AbstractVector{<:Integer},
                 starts::AbstractVector{<:Integer}, ends::AbstractVector{<:Integer},
                 gd::GroupedDataFrame, incols::NTuple{2, AbstractVector}, i::Integer)
    idx = view(idx, starts[i]:ends[i])
    return f(view(incols[1], idx), view(incols[2], idx))
end

function do_call(f::Base.Callable, idx::AbstractVector{<:Integer},
                 starts::AbstractVector{<:Integer}, ends::AbstractVector{<:Integer},
                 gd::GroupedDataFrame, incols::NTuple{3, AbstractVector}, i::Integer)
    idx = view(idx, starts[i]:ends[i])
    return f(view(incols[1], idx), view(incols[2], idx), view(incols[3], idx))
end

function do_call(f::Base.Callable, idx::AbstractVector{<:Integer},
                 starts::AbstractVector{<:Integer}, ends::AbstractVector{<:Integer},
                 gd::GroupedDataFrame, incols::NTuple{4, AbstractVector}, i::Integer)
    idx = view(idx, starts[i]:ends[i])
    return f(view(incols[1], idx), view(incols[2], idx), view(incols[3], idx),
             view(incols[4], idx))
end

function do_call(f::Base.Callable, idx::AbstractVector{<:Integer},
                 starts::AbstractVector{<:Integer}, ends::AbstractVector{<:Integer},
                 gd::GroupedDataFrame, incols::Tuple, i::Integer)
    idx = view(idx, starts[i]:ends[i])
    return f(map(c -> view(c, idx), incols)...)
end

function do_call(f::Base.Callable, idx::AbstractVector{<:Integer},
                 starts::AbstractVector{<:Integer}, ends::AbstractVector{<:Integer},
                 gd::GroupedDataFrame, incols::NamedTuple, i::Integer)
    if f isa ByRow && isempty(incols)
        return [f.fun(NamedTuple()) for _ in 1:(ends[i] - starts[i] + 1)]
    else
        idx = view(idx, starts[i]:ends[i])
        return f(map(c -> view(c, idx), incols))
    end
end

function do_call(f::Base.Callable, idx::AbstractVector{<:Integer},
                 starts::AbstractVector{<:Integer}, ends::AbstractVector{<:Integer},
                 gd::GroupedDataFrame, incols::Nothing, i::Integer)
    idx = view(idx, starts[i]:ends[i])
    return f(view(parent(gd), idx, :))
end


text:
using BufferedStreams
using Compat

if VERSION >= v"0.5-"
    using Base.Test
else
    using BaseTestNext
    const Test = BaseTestNext
end

# A few things that might not be obvious:
#   * In a few places we wrap an array in an IOBuffer before wrapping it in a
#     BufferedInputStream. This is to force the BufferedInputStream to read
#     incrementally to expose possible bugs in buffer refilling logic.
#   * Similar, we manually set the buffer size to be smaller than the default to
#     force more buffer refills.

@testset "BufferedInputStream" begin
    @testset "read" begin
        data = rand(UInt8, 1000000)
        stream = BufferedInputStream(IOBuffer(data), 1024)
        read_data = UInt8[]
        while !eof(stream)
            push!(read_data, read(stream, UInt8))
        end
        @test data == read_data
        @test data == read(BufferedInputStream(IOBuffer(data), 1024))

        halfn = div(length(data), 2)
        @test data[1:halfn] == read(BufferedInputStream(IOBuffer(data), 1024), halfn)

        # read multi-byte data
        buffer = IOBuffer()
        write(buffer, UInt8(1))
        write(buffer, UInt16(2))
        write(buffer, UInt32(3))
        write(buffer, UInt64(4))
        write(buffer, UInt128(5))
        seekstart(buffer)
        stream = BufferedInputStream(buffer)
        @test read(stream, UInt8) === UInt8(1)
        @test read(stream, UInt16) === UInt16(2)
        @test read(stream, UInt32) === UInt32(3)
        @test read(stream, UInt64) === UInt64(4)
        @test read(stream, UInt128) === UInt128(5)
    end

    @testset "peek" begin
        stream = BufferedInputStream(IOBuffer([0x01, 0x02]))
        @test peek(stream) === 0x01
        @test peek(stream) === 0x01
        read(stream, UInt8)
        @test peek(stream) === 0x02
        @test peek(stream) === 0x02
    end

    @testset "peekbytes!" begin
        data = rand(UInt8, 1000000)
        stream = BufferedInputStream(IOBuffer(data), 1024)

        read_data = Array{UInt8}(1000)
        @test peekbytes!(stream, read_data, 1000) == 1000
        @test data[1:1000] == read_data
        # Check that we read the bytes we just peeked, i.e. that the position
        # wasn't advanced on peekbytes!()
        readbytes!(stream, read_data, 1000)
        @test data[1:1000] == read_data
        # Check that we now peek the next 24 bytes, as we don't go past the end
        # of the buffer
        @test peekbytes!(stream, read_data, 1000) == 24
        @test data[1001:1024] == read_data[1:24]

        # Reset the data
        data = rand(UInt8, 1000000)
        stream = BufferedInputStream(IOBuffer(data), 1024)

        read_data = Array{UInt8}(2000)
        @test peekbytes!(stream, read_data, 2000) == 1024
        # Note that we truncate at buffer size, as
        @test data[1:1024] == read_data[1:1024]

        # Check that we only read up to the buffer size
        read_data = Array{UInt8}(5)
        @test peekbytes!(stream, read_data) == 5
        @test data[1:5] == read_data

        close(stream)
        @test_throws Exception peekbytes!(stream, read_data)
    end

    @testset "readbytes!" begin
        stream = BufferedInputStream(IOBuffer([0x01:0xff;]), 4)
        @test !eof(stream)
        out = zeros(UInt8, 2)
        @test BufferedStreams.readbytes!(stream, out) === 2
        @test out == [0x01, 0x02]
        out = zeros(UInt8, 3)
        @test BufferedStreams.readbytes!(stream, out) === 3
        @test out == [0x03, 0x04, 0x05]
        out = zeros(UInt8, 5)
        @test BufferedStreams.readbytes!(stream, out) === 5
        @test out == [0x06, 0x07, 0x08, 0x09, 0x0a]
        @test !eof(stream)
        @test read(stream) == [0x0b:0xff;]
        @test eof(stream)
    end

    @testset "readuntil" begin
        data = rand(UInt8, 1000000)
        stream = BufferedInputStream(IOBuffer(data), 1024)

        true_num_zeros = 0
        zero_positions = Int[]
        for (i, b) in enumerate(data)
            if b == 0x00
                push!(zero_positions, i)
                true_num_zeros += 1
            end
        end

        num_zeros = 0
        chunk_results = Bool[]
        while true
            # are we extracting the right chunk?
            chunk = readuntil(stream, 0x00)
            first = num_zeros == 0 ? 1 : zero_positions[num_zeros]+1
            last = num_zeros < length(zero_positions) ?  zero_positions[num_zeros+1] : length(data)
            true_chunk = data[first:last]
            push!(chunk_results, true_chunk == chunk)

            if !eof(stream)
                num_zeros += 1
            else
                break
            end
        end

        @test all(chunk_results)
        @test num_zeros == true_num_zeros
    end

    @testset "arrays" begin
        data = rand(UInt8, 1000000)
        stream = BufferedInputStream(data)
        read_data = UInt8[]
        while !eof(stream)
            push!(read_data, read(stream, UInt8))
        end
        @test data == read_data
        @test data == read(BufferedInputStream(data))
    end

    @testset "marks" begin
        # very small buffer
        stream = BufferedInputStream(IOBuffer([0x01:0xff;]), 2)
        @test !ismarked(stream)
        mark(stream)
        @test ismarked(stream)
        a = read(stream, UInt8)
        b = read(stream, UInt8)
        c = read(stream, UInt8)
        reset(stream)
        @test !ismarked(stream)
        a′ = read(stream, UInt8)
        b′ = read(stream, UInt8)
        c′ = read(stream, UInt8)
        @test (a, b, c) == (a′, b′, c′) == (0x01, 0x02, 0x03)
        mark(stream)
        @test unmark(stream)
        @test !unmark(stream)
        @test_throws ErrorException reset(stream)
    end

    @testset "anchors" begin
        data = rand(UInt8, 100000)

        function random_range(n)
            a = rand(1:n)
            b = rand(a:n)
            return a:b
        end

        # test that anchors work correctly by extracting random intervals from a
        # buffered stream.
        function test_anchor()
            r = random_range(length(data))
            i = 1
            stream = BufferedInputStream(IOBuffer(data), 1024)
            while !eof(stream)
                if i == r.start
                    anchor!(stream)
                end
                if i == r.stop + 1
                    return takeanchored!(stream) == data[r]
                end
                read(stream, UInt8)
                i += 1
            end
            if i == r.stop + 1
                return takeanchored!(stream) == data[r]
            end
            error("nothing extracted (range: $r)")
        end

        @test all(Bool[test_anchor() for _ in 1:100])
    end

    @testset "seek" begin
        n = 100000
        data = rand(UInt8, n)
        positions = rand(0:n-1, 1000)

        function test_seek(stream, p)
            seek(stream, p)
            return position(stream) == p && read(stream, UInt8) == data[p + 1]
        end

        stream = BufferedInputStream(data)
        @test all(Bool[test_seek(stream, p) for p in positions])

        stream = BufferedInputStream(IOBuffer(data), 1024)
        @test all(Bool[test_seek(stream, p) for p in positions])
    end

    @testset "skip" begin
        n = 100000
        data = rand(UInt8, n)
        positions = rand(0:n-1, 1000)
        sort!(positions)

        last = 1
        offsets = Int[]
        for p in positions
            push!(offsets, p - last)
            last = p
        end

        function test_skip(stream, p, offset)
            skip(stream, offset)
            peek(stream) == data[p]
        end

        stream = BufferedInputStream(IOBuffer(data), 1024)
        @test_throws Exception skip(stream, n + 1)
        @test_throws Exception skip(stream, -1)

        stream = BufferedInputStream(IOBuffer(data), 1024)
        @test all(Bool[test_skip(stream, p, offset)
                       for (p, offset) in zip(positions, offsets)])
    end

    @testset "close" begin
        iobuffer = IOBuffer([0x00, 0x01])
        stream = BufferedInputStream(iobuffer)
        @test isopen(stream)
        @test isopen(iobuffer)
        read(stream, UInt8)
        close(stream)
        @test !isopen(stream)
        @test !isopen(iobuffer)
        @test_throws Exception read(stream, UInt8)
    end

    @testset "iostream" begin
        mktemp() do path, input
            write(input, [0x01, 0x02, 0x03, 0x04, 0x05])
            flush(input)
            seekstart(input)

            stream = BufferedInputStream(input, 2)
            @test !eof(stream)
            @test read(stream, UInt8) === 0x01
            @test !eof(stream)
            @test read(stream, UInt8) === 0x02
            @test !eof(stream)
            @test read(stream) == [0x03, 0x04, 0x05]
            @test eof(stream)

            @test isopen(stream)
            @test isopen(input)
            close(stream)
            @test !isopen(stream)
            @test !isopen(input)
        end
    end

    @testset "misc." begin
        stream = BufferedInputStream(IOBuffer("foobar"), 10)
        @test !BufferedStreams.ensurebuffered!(stream, 10)
        @test ismatch(r"^BufferedStreams\.BufferedInputStream{.*}\(<.* \d+% filled>\)$", string(stream))
        close(stream)
        @test ismatch(r"^BufferedStreams\.BufferedInputStream{.*}\(<closed>\)$", string(stream))
        @test_throws ArgumentError BufferedInputStream(IOBuffer("foo"), 0)
    end
end

@testset "BufferedOutputStream" begin
    @testset "write" begin
        data = rand(UInt8, 1000000)
        stream1 = BufferedOutputStream()
        sink = IOBuffer()
        stream2 = BufferedOutputStream(sink, 1024)
        for c in data
            write(stream1, c)
            write(stream2, c)
        end
        flush(stream1)
        flush(stream2)
        @test takebuf_array(stream1) == data
        @test takebuf_array(sink) == data
        close(stream1)
        close(stream2)
        @test !isopen(sink)
    end

    @testset "arrays" begin
        expected = UInt8[]
        stream1 = BufferedOutputStream()
        sink = IOBuffer()
        stream2 = BufferedOutputStream(sink, 1024)
        for _ in 1:1000
            data = rand(UInt8, rand(1:1000))
            append!(expected, data)
            write(stream1, data)
            write(stream2, data)
        end
        flush(stream1)
        flush(stream2)
        @test takebuf_array(stream1) == expected
        @test takebuf_array(sink) == expected
        close(stream1)
        close(stream2)
    end

    @testset "takebuf_string" begin
        data = rand('A':'z', 1000000)
        iobuf = IOBuffer()
        stream = BufferedOutputStream()
        for c in data
            write(stream, c)
            write(iobuf, c)
        end
        @test takebuf_string(stream) == takebuf_string(iobuf)
    end

    @testset "write_result" begin
        sink = IOBuffer()
        stream = BufferedOutputStream(sink, 16)
        for len in 0:10:100
            result = write(stream, repeat("x", len))
            @test result == len
        end
    end

    @testset "close" begin
        iobuffer = IOBuffer()
        stream = BufferedOutputStream(iobuffer)
        @test isopen(stream)
        @test isopen(iobuffer)
        write(stream, 0x00)
        close(stream)
        @test !isopen(stream)
        @test !isopen(iobuffer)
        @test_throws Exception write(stream, 0x00)
    end

    @testset "vector sink" begin
        sink = UInt8[]
        stream = BufferedOutputStream(sink)
        write(stream, 0x00)
        write(stream, 0x01)
        write(stream, 0x02)
        flush(stream)
        @test takebuf_array(stream) == [0x00, 0x01, 0x02]
        @test isopen(stream)
        close(stream)
        @test !isopen(stream)
        @test_throws Exception write(stream, 0x00)
    end

    @testset "iostream" begin
        mktemp() do path, out
            stream = BufferedOutputStream(out, 10)
            write(stream, "hello")
            @test stat(path).size == 0
            write(stream, "world")
            @test stat(path).size == 0
            write(stream, "!")
            # BufferedOutputStream buffer has run out of space,
            # but IOStream buffer has not
            @test stat(path).size == 0
            flush(stream)
            @test stat(path).size == 11
            write(stream, "...")
            @test stat(path).size == 11
            close(stream)
            @test !isopen(out)
            @test stat(path).size == 14
        end
    end

    @testset "misc." begin
        stream = BufferedOutputStream(IOBuffer(), 5)
        @test eof(stream)
        @test pointer(stream) == pointer(stream.buffer)
        @test ismatch(r"^BufferedStreams\.BufferedOutputStream{.*}\(<.* \d+% filled>\)$", string(stream))
        close(stream)
        @test ismatch(r"^BufferedStreams\.BufferedOutputStream{.*}\(<closed>\)$", string(stream))
        @test_throws ArgumentError BufferedOutputStream(IOBuffer(), 0)
    end
end


text:
module TestExamplesUnstructuredMesh2D

using Test
using Trixi

include("test_trixi.jl")

# pathof(Trixi) returns /path/to/Trixi/src/Trixi.jl, dirname gives the parent directory
EXAMPLES_DIR = joinpath(pathof(Trixi) |> dirname |> dirname, "examples", "unstructured_2d_dgsem")

# Start with a clean environment: remove Trixi output directory if it exists
outdir = "out"
isdir(outdir) && rm(outdir, recursive=true)

@testset "UnstructuredMesh2D" begin
  @trixi_testset "elixir_euler_periodic.jl" begin
    @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_euler_periodic.jl"),
      l2   = [0.00010978828464875207, 0.00013010359527356914, 0.00013010359527326057, 0.0002987656724828824],
      linf = [0.00638626102818618, 0.009804042508242183, 0.009804042508253286, 0.02183139311614468])
  end

  @trixi_testset "elixir_euler_free_stream.jl" begin
    @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_euler_free_stream.jl"),
      l2   = [3.357431396258123e-14, 2.439943089578555e-13, 1.4655386790023588e-13, 4.670410488845425e-13],
      linf = [1.0169198816356584e-11, 6.838458965763294e-11, 4.456759961080081e-11, 1.4207657272891083e-10],
      tspan = (0.0, 0.1),
      atol = 3.0e-13)
  end

  @trixi_testset "elixir_euler_wall_bc.jl" begin
    @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_euler_wall_bc.jl"),
      l2   = [0.040189107976346644, 0.04256154998030852, 0.03734120743842209, 0.10057425897733507],
      linf = [0.24455374304626365, 0.2970686406973577, 0.29339040847600434, 0.5915610037764794],
      tspan = (0.0, 0.25))
  end

  @trixi_testset "elixir_euler_basic.jl" begin
    @test_trixi_include(default_example_unstructured(),
      l2   = [0.0007258658867098887, 0.000676268065087451, 0.0006316238024054346, 0.0014729738442086392],
      linf = [0.004476908674416524, 0.0052614635050272085, 0.004926298866533951, 0.018058026023565432],
      tspan = (0.0, 1.0))
  end

  @trixi_testset "elixir_euler_restart.jl" begin
    @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_euler_restart.jl"),
      l2   = [0.0007258658867098887, 0.000676268065087451, 0.0006316238024054346, 0.0014729738442086392],
      linf = [0.004476908674416524, 0.0052614635050272085, 0.004926298866533951, 0.018058026023565432])
  end

  @trixi_testset "elixir_euler_ec.jl" begin
    @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_euler_ec.jl"),
      l2   = [0.06594600495903137, 0.10803914821786433, 0.10805946357846291, 0.1738171782368222],
      linf = [0.31880214280781305, 0.3468488554333352, 0.34592958184413264, 0.784555926860546],
      tspan = (0.0, 1.0))
  end

  @trixi_testset "elixir_advection_basic.jl" begin
    @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_advection_basic.jl"),
      l2   = [0.00023219572238346008],
      linf = [0.0017401556568237275])
  end

  @trixi_testset "elixir_ape_gauss_wall.jl" begin
    @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_ape_gauss_wall.jl"),
      l2   = [0.02933124798548954, 0.029346167217325133, 0.03803253571320853, 0.0,
              7.175152371650832e-16, 1.4350304743301665e-15, 1.4350304743301665e-15],
      linf = [0.3626825396196767, 0.3684490307932009, 0.847747871258089, 0.0,
              8.881784197001252e-16, 1.7763568394002505e-15, 1.7763568394002505e-15],
      tspan = (0.0, 5.0))
  end

  @trixi_testset "elixir_mhd_ec.jl" begin
    @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_mhd_ec.jl"),
      l2   = [0.06418293357851637, 0.12085176618704108, 0.12085099342419513, 0.07743005602933221,
              0.1622218916638482, 0.04044434425257972, 0.04044440614962498, 0.05735896706356321,
              0.0020992340041681734],
      linf = [0.1417000509328017, 0.3210578460652491, 0.335041095545175, 0.22500796423572675,
              0.44230628074326406, 0.16743171716317784, 0.16745989278866702, 0.17700588224362557,
              0.02692320090677309],
      tspan = (0.0, 0.5))
  end

  @trixi_testset "elixir_mhd_alfven_wave.jl" begin
    @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_mhd_alfven_wave.jl"),
      l2   = [5.377518922553881e-5, 0.09999999206243514, 0.09999999206243441, 0.1414213538550799,
              8.770450430886394e-6, 0.0999999926130084, 0.0999999926130088, 0.14142135396487032,
              1.1553833987291942e-5],
      linf = [0.00039334982566352483, 0.14144904937275282, 0.14144904937277897, 0.20003315928443416,
              6.826863293230012e-5, 0.14146512909995967, 0.14146512909994702, 0.20006706837452526,
              0.00013645610312810813],
      tspan = (0.0, 0.5))
  end
end

# Clean up afterwards: delete Trixi output directory
@test_nowarn rm(outdir, recursive=true)

end # module