text:
module types

mutable struct signal

    A::Vector{Number} #Amplitude of the signal
    n::Vector{Real} #horizontal axis (discrete) of signal (in samples)

    function signal(A::Number, n::Int) # construction of signal with amplitude A and n samples starting from 0.
        A = A .*ones(n)
        n = [x for x in range(0, length=n)]
        new(A, n)
    end

    function signal(A::Number, start::Int, stop::Int)

        n = [x for x in range(start, stop)]
        A = A .*ones(length(n))
        new(A, n)
    end

    function signal(A::Vector, n::Vector)
        @assert length(A) == length(n) "lengths of A and n must be equal"
        new(A, n)
    end

end

end

max_stars_repo_name: gjunqueira-sys/MySignalProcessing

max_issues_repo_name: gjunqueira-sys/MySignalProcessing

max_forks_repo_name: gjunqueira-sys/MySignalProcessing


text:
using Documenter, LEAPMacro

"""
    Documenter.Writers.HTMLWriter.analytics_script(line::String)

Overload of Documenter.Writers.HTMLWriter.analytics_script() that provides
compatibility with Google Analytics 4.
"""
function Documenter.Writers.HTMLWriter.analytics_script(tracking_id::AbstractString)
    if isempty(tracking_id)
        return Documenter.Utilities.DOM.Tag(Symbol("#RAW#"))("")
    else
        return Documenter.Utilities.DOM.Tag(Symbol("#RAW#"))("""<!-- Global site tag (gtag.js) - Google Analytics -->
        <script async src="https://www.googletagmanager.com/gtag/js?id=$(tracking_id)"></script>
        <script>
          window.dataLayer = window.dataLayer || [];
          function gtag(){dataLayer.push(arguments);}
          gtag('js', new Date());
          gtag('config', '$(tracking_id)');
        </script>""")
    end
end  # Documenter.Writers.HTMLWriter.analytics_script(tracking_id::AbstractString)

makedocs(
    sitename = "LEAP-Macro",
    format = Documenter.HTML(analytics="G-VFCCCS3YR4"),
    pages = [
        "Introduction" => "index.md"
        "Getting started" => [
            "Installation" => "installation.md"
            "Quick start" => "quickstart.md"
        ]
        "Model overview" => [
            "LEAP-Macro link" => "leap-macro-link.md"
            "About demand-led growth" => "demand-led-growth.md"
            "Limitations of the model" => "limitations.md"
        ]
        "Using LEAP-Macro" => [
            "Configuration file" => "config.md"
            "Supply-use table" => "sut.md"
            "External parameter files" => "params.md"
            "Running the Macro model" => "running-macro.md"
            "Output files" => "model-outputs.md"
            "Preparing a model" => "prep-model.md"
         ]
        "Technical details" => [
            "Variables" => "variables.md"
            "Linear goal program" => "lgp.md"
            "Dynamics" => "dynamics.md"
            "Isolating the energy sector" => "isolate-energy.md"
            "Processing the supply-use table" => "process-sut.md"
        ]
    ]
)

deploydocs(
    repo = "github.com/sei-international/LEAPMacro.jl.git"
)

ext: jl

max_stars_repo_name: sei-international/LEAPMacro

max_issues_repo_name: sei-international/LEAPMacro

max_forks_repo_name: sei-international/LEAPMacro


text:
########## Functions ##########

cost(pos1, pos2) = abs(pos1 - pos2)

function cost2(pos1, pos2)::Int
    n_step = cost(pos1, pos2)
    n_step * (n_step + 1) / 2
end

optimal_cost(cost_fn, data) =
    minimum([sum(cost_fn.(data, pos)) for pos in 0:maximum(data)])

########## Script ##########

function main()

    # open file and store content into an input string
    input = open("inputs//day7.txt", "r") do io
        read(io, String)
    end

    # split input into a data vector of numbers
    data = parse.(Int, String.(split(input, ",")))

    println("part 1: ", optimal_cost(cost, data))
    println("part 2: ", optimal_cost(cost2, data))

end

main()


text:
using Logging
using .LC

const a1 = "arg1"
const a2 = "arg2"
const a3 = 4711

const h0 = 0
const h1 = 1
const hmany = 13

city = "Frankfurt"
temp = 29.0
ndhi = 15

set_locale!(LocaleId("en-us"), LC.MESSAGES)
@test tr"T3" == "T3 - en_US"
@test tr"original $a1($a2) : $(a3*2)" == "US version $(a3*2) / $a2 $a1"

# test with invalid plural forms
@test_throws ArgumentError tr"error1"
@test tr"error2 $h1" == "error2a"

# attention: en-US defines a non-standard plurals rule
@test tr"missing argument value $(99)" == "missing argument value 99"
@test tr"These are $h1 houses" == "This is a house"
@test tr"These are $hmany houses" == "These are at least $(hmany) houses"
@test tr"These are $(0) houses" == "This is not a house"
@test tr"These are $(hmany-hmany) houses" == "This is not a house"

set_locale!(LocaleId("fr"), LC.MESSAGES)
@test tr"original $a1($a2) : $(a3*2)" == "original $a1($a2) : $(a3*2)"

@test tr"These are $(1) houses" == "C'est 1 maison"
@test tr"These are $(hmany*3+3) houses" == "Ce sont beaucoup(42) de maisons"
@test tr"These are $(10) houses" == "Ce sont beaucoup(10) de maisons"
@test tr"These are $h0 houses" == "C'est 0 maison"

# data for this locale are stored in po-file
set_locale!(LocaleId("de-AT"), LC.MESSAGES)
@test tr"These are $(1) houses" == "Das ist ein Haus"
@test tr"These are $(hmany*3+3) houses" == "Das sind 42 Häuser"
@test tr"These are $(10) houses" == "Das sind 10 Häuser"
@test tr"These are $h0 houses" == "Das sind 0 Häuser"
@test tr"In $(city) the temperature was above $(temp) °C" == "Die Temperatur von $(temp) °C wurde in $(city) überschritten"
@test tr"In $(city) the temperature was above $(temp) °C at $(!ndhi) days" == "In $(city) war die Temperatur an $(ndhi) Tagen über $(temp) °C"
@test tr"In $(city) the temperature was above $(temp) °C at $(!h1) days" == "In $(city) war die Temperatur an einem \"Tag\" über $(temp) °C"

# Permutations
@test tr"123 $(1) $(2) $(3)" == "123 1 2 3"
@test tr"132 $(1) $(2) $(3)" == "132 1 3 2"
@test tr"213 $(1) $(2) $(3)" == "213 2 1 3"
@test tr"213 $(1) $(2) $(3)" == "213 2 1 3"
@test tr"312 $(1) $(2) $(3)" == "312 3 1 2"
@test tr"321 $(1) $(2) $(3)" == "321 3 2 1"

# Primary Forms
@test tr"123 $(1) $(!2) $(3)" == "123 1 2 3"
@test tr"132 $(1) $(!2) $(3)" == "132 1 3 2" #
@test tr"213 $(1) $(!2) $(3)" == "213 2 1 3"
@test tr"213 $(1) $(!2) $(3)" == "213 2 1 3"
@test tr"312 $(1) $(!2) $(3)" == "312 3 1 2" #
@test tr"321 $(1) $(!2) $(3)" == "321 3 2 1" #
@test tr"123 $(1) $(2) $(!3)" == "123 1 2 3" #
@test tr"132 $(1) $(2) $(!3)" == "132 1 3 2" #
@test tr"213 $(1) $(2) $(!3)" == "213 2 1 3" #
@test tr"213 $(1) $(2) $(!3)" == "213 2 1 3" #
@test tr"312 $(1) $(2) $(!3)" == "312 3 1 2" #
@test tr"321 $(1) $(2) $(!3)" == "321 3 2 1" #

# Context
@test tr"§testctx§original" == "O r i g i n a l"

# evoke warnings when reading files
log = Test.TestLogger(min_level=Logging.Info)
with_logger(log) do
    load_file(joinpath("resources", "messages.pox"))
end
mess = isempty(log.logs) ? "" : log.logs[1].message
@test occursin("invalid extension of file name", mess)

empty!(log.logs)
with_logger(log) do
    load_file(joinpath("resources", "messages_tv.po"))
end
mess = isempty(log.logs) ? "" : log.logs[1].message
@test occursin("unexpected msgid", mess)

@test string_to_key("simple") == "simple"
@test string_to_key(raw"with $v1 and $(expr+2)") == raw"with $(1) and $(2)"
@test string_to_key(raw"with $v1 and $(!(expr+2))") == raw"with $(2) and $(1)"

# data for this locale are stored in little-endian mo-file
set_locale!(LocaleId("de-LU"), LC.MESSAGES)
@test tr"§testctx§original" == "O r i g i n a l"

# data for this locale are stored in big-endian mo-file
set_locale!(LocaleId("de-CH"), LC.MESSAGES)
@test tr"§testctx§original" == "O r i g i n a l"


text:
using Base.Test
using SkewDist
println("Testing SkewTDist...")

df = 4.0
ξ = 1.0
ω = 0.5
α = 1.0

dist = SkewTDist(ξ, ω, α, df)

# Test PDF integrates to one
@test_approx_eq_eps quadgk(x->pdf(dist,x), -Inf, Inf)[1] 1.0 1e-6

cdf(dist, 1.0)

# Monte Carlo tests for basic statistics
n = 100000
x = rand(dist, n)
@test_approx_eq_eps mean(x) mean(dist) 1e-1
@test_approx_eq_eps var(x) var(dist) 1e-1


text:
## Turing Complete Interpreter
### A Very Tiny Turing Complete Programming Language defined with denotational semantics

# semantica dalle dispense degano
using Metatheory

import Base.ImmutableDict
Mem = Dict{Symbol,Union{Bool,Int}}

read_mem = @theory v σ begin
  (v::Symbol, σ::Mem) => if v == :skip
    σ
  else
    σ[v]
  end
end

@testset "Reading Memory" begin
  ex = :((x), $(Mem(:x => 2)))
  @test true == areequal(read_mem, ex, 2)
end

arithm_rules = @theory a b σ begin
  (a + b, σ::Mem) --> (a, σ) + (b, σ)
  (a * b, σ::Mem) --> (a, σ) * (b, σ)
  (a - b, σ::Mem) --> (a, σ) - (b, σ)
  (a::Int, σ::Mem) --> a
  (a::Int + b::Int) => a + b
  (a::Int * b::Int) => a * b
  (a::Int - b::Int) => a - b
end

@testset "Arithmetic" begin
  @test areequal(read_mem ∪ arithm_rules, :((2 + 3), $(Mem())), 5)
end

# don't need to access memory
bool_rules = @theory a b σ begin
  (a < b, σ::Mem) --> (a, σ) < (b, σ)
  (a ∨ b, σ::Mem) --> (a, σ) ∨ (b, σ)
  (a ∧ b, σ::Mem) --> (a, σ) ∧ (b, σ)
  (¬(a), σ::Mem) --> ¬((a, σ))

  (a::Bool, σ::Mem)   => a
  (¬a::Bool)          => !a
  (a::Bool ∨ b::Bool) => (a || b)
  (a::Bool ∧ b::Bool) => (a && b)
  (a::Int < b::Int)   => (a < b)
end

t = read_mem ∪ arithm_rules ∪ bool_rules

@testset "Booleans" begin
  @test areequal(t, :((false ∨ false), $(Mem())), false)

  exx = :((false ∨ false) ∨ ¬(false ∨ false), $(Mem(:x => 2)))
  g = EGraph(exx)
  saturate!(g, t)
  ex = extract!(g, astsize)
  @test ex == true
  params = SaturationParams(timeout = 12)
  @test areequal(t, exx, true; params = params)

  @test areequal(t, :((2 < 3) ∧ (3 < 4), $(Mem(:x => 2))), true)
  @test areequal(t, :((2 < x) ∨ ¬(3 < 4), $(Mem(:x => 2))), false)
  @test areequal(t, :((2 < x) ∨ ¬(3 < 4), $(Mem(:x => 4))), true)
end

if_rules = @theory guard t f σ begin
  (
    if guard
      t
    end
  ) --> (
    if guard
      t
    else
      :skip
    end
  )
  (if guard
    t
  else
    f
  end, σ::Mem) --> (if (guard, σ)
    t
  else
    f
  end, σ)
  (if true
    t
  else
    f
  end, σ::Mem) --> (t, σ)
  (if false
    t
  else
    f
  end, σ::Mem) --> (f, σ)
end

if_language = read_mem ∪ arithm_rules ∪ bool_rules ∪ if_rules

@testset "If Semantics" begin
  @test areequal(if_language, 2, :(if true
    x
  else
    0
  end, $(Mem(:x => 2))))
  @test areequal(if_language, 0, :(if false
    x
  else
    0
  end, $(Mem(:x => 2))))
  @test areequal(if_language, 2, :(if ¬(false)
    x
  else
    0
  end, $(Mem(:x => 2))))
  params = SaturationParams(timeout = 10)
  @test areequal(if_language, 0, :(if ¬(2 < x)
    x
  else
    0
  end, $(Mem(:x => 3))); params = params)
end

while_rules = @theory a b σ begin
  (:skip, σ::Mem) --> σ
  ((a; b), σ::Mem) --> ((a, σ); b)
  (a::Int; b) --> b
  (a::Bool; b) --> b
  (σ::Mem; b) --> (b, σ)
  (while a
    b
  end, σ::Mem) --> (if a
    (b;
    while a
      b
    end)
  else
    :skip
  end, σ)
end

write_mem = @theory sym val σ begin
  (sym::Symbol = val, σ::Mem) --> (sym = (val, σ), σ)
  (sym::Symbol = val::Int, σ::Mem) => merge(σ, Dict(sym => val))
end

while_language = if_language ∪ write_mem ∪ while_rules;

@testset "While Semantics" begin
  exx = :((x = 3), $(Mem(:x => 2)))
  g = EGraph(exx)
  saturate!(g, while_language)
  ex = extract!(g, astsize)

  @test areequal(while_language, Mem(:x => 3), exx)

  exx = :((x = 4; x = x + 1), $(Mem(:x => 3)))
  g = EGraph(exx)
  saturate!(g, while_language)
  ex = extract!(g, astsize)

  params = SaturationParams(timeout = 10)
  @test areequal(while_language, Mem(:x => 5), exx; params = params)

  params = SaturationParams(timeout = 14)
  exx = :((
    if x < 10
      x = x + 1
    else
      skip
    end
  ), $(Mem(:x => 3)))
  @test areequal(while_language, Mem(:x => 4), exx; params = params)

  exx = :((while x < 10
    x = x + 1
  end;
  x), $(Mem(:x => 3)))
  g = EGraph(exx)
  params = SaturationParams(timeout = 100, scheduler = Schedulers.SimpleScheduler)
  saturate!(g, while_language, params)
  @test 10 == extract!(g, astsize)
end


text:
using DrWatson
@quickactivate "StatReth"

# %%
using CSV
using DataFrames
using Turing
using Plots
using StatsPlots

include(srcdir("quap.jl"))
include(srcdir("tools.jl"))

# %% 4E1
"""
The first line: yᵢ ~ Normal(μ, σ).
"""

# %% 4E2
"""
There are two parameters, μ and σ.
"""

# %% 4E3
"""
Bayes Theorem: P(A|B) = P(B|A) * P(A) / P(B)
P(μ,σ | y) = P(y | μ,σ) * P(μ,σ) / P(y)
           = pdf(Normal(μ, σ), yᵢ) * pdf(Normal(0, 10), μ) * pdf(Exponential(1)), μ) / P(y)
"""

# %% 4E4
"""
The line μᵢ = α + βxᵢ
"""

# %% 4E5
"""
There are three parameters, α, β, and σ.
"""


text:
module AtomModule
export Atom, Element
import Base.==

using ..BaseModule

atomicNumbers = Dict{String,Int}(
  "H" => 	1,
  "He" => 	2,
  "Li" => 	3,
  "Be" =>	4,
  "B" =>	5,
  "C" =>	6,
  "N" =>	7,
  "O" =>	8,
  "F" =>	9,
  "Ne" =>	10,
  "Na" =>	11,
  "Mg" =>	12,
  "Al" =>	13,
  "Si" =>	14,
  "P" =>	15,
  "S" =>	16,
  "Cl" =>	17,
  "Ar" =>	18,
  "K" =>	19,
  "Ca" =>	20,
  "Sc" =>	21,
  "Ti" =>	22,
  "V" =>	23,
  "Cr" =>	24,
  "Mn" =>	25,
  "Fe" =>	26,
  "Co" =>	27,
  "Ni" =>	28,
  "Cu" =>	29,
  "Zn" =>	30,
  "Ga" =>	31,
  "Ge" =>	32,
  "As" =>	33,
  "Se" =>	34,
  "Br" =>	35,
  "Kr" =>	36,
  "Rb" =>	37,
  "Sr" =>	38,
  "Y" =>	39,
  "Zr" =>	40,
  "Nb" =>	41,
  "Mo" =>	42,
  "Tc" =>	43,
  "Ru" =>	44,
  "Rh" =>	45,
  "Pd" =>	46,
  "Ag" =>	47,
  "Cd" =>	48,
  "In" =>	49,
  "Sn" =>	50,
  "Sb" =>	51,
  "Te" =>	52,
  "I" =>	53,
  "Xe" =>	54,
  "Cs" =>	55,
  "Ba" =>	56,
  "La" =>	57,
  "Ce" =>	58,
  "Pr" =>	59,
  "Nd" =>	60,
  "Pm" =>	61,
  "Sm" =>	62,
  "Eu" =>	63,
  "Gd" =>	64,
  "Tb" =>	65,
  "Dy" =>	66,
  "Ho" =>	67,
  "Er" =>	68,
  "Tm" =>	69,
  "Yb" =>	70,
  "Lu" =>	71,
  "Hf" =>	72,
  "Ta" =>	73,
  "W" =>	74,
  "Re" =>	75,
  "Os" =>	76,
  "Ir" =>	77,
  "Pt" =>	78,
  "Au" =>	79,
  "Hg" =>	80,
  "Tl" =>	81,
  "Pb" =>	82,
  "Bi" =>	83,
  "Po" =>	84,
  "At" =>	85,
  "Rn" =>	86,
  "Fr" =>	87,
  "Ra" =>	88,
  "Ac" =>	89,
  "Th" =>	90,
  "Pa" =>	91,
  "U" =>	92,
  "Np" =>	93,
  "Pu" =>	94,
  "Am" =>	95,
  "Cm" =>	96,
  "Bk" =>	97,
  "Cf" =>	98,
  "Es" =>	99,
  "Fm" =>	100,
  "Md" =>	101,
  "No" =>	102,
  "Lr" =>	103,
  "Rf" =>	104,
  "Db" =>	105,
  "Sg" =>	106,
  "Bh" =>	107,
  "Hs" =>	108,
  "Mt" =>	109,
  "Ds" =>	110,
  "Rg" =>	111,
  "Cp" =>	112,
  "Uut" =>	113,
  "Uuq" =>	114,
  "Uup" =>	115,
  "Uuh" =>	116,
  "Uus" =>	117,
  "Uuo" =>	118
)

atomicWeight = Dict{Int64,Float64}(# according to IUPAC Pure Appl. Chem. 2016, 88(12), 1203-1224
  1  => 1.008,
  2  => 4.002,
  3  => 6.94,
  4  => 9.012,
  5  => 10.81,
  6  => 12.011,
  7  => 14.007,
  8  => 15.999,
  9  => 18.998,
  10 => 20.1797,
  11 => 22.989,
  12 => 24.305,
  13 => 26.981,
  14 => 28.085,
  15 => 30.973,
  16 => 32.06,
  17 => 35.45,
  18 => 39.948,
  19 => 39.0983,
  20 => 40.078,
  21 => 44.955,
  22 => 47.867,
  23 => 50.9415,
  24 => 51.9961,
  25 => 54.938,
  26 => 55.845,
  27 => 58.933,
  28 => 58.6934,
  29 => 63.546,
  30 => 65.38,
  31 => 69.723,
  32 => 72.630,
  33 => 74.921,
  34 => 78.971,
  35 => 79.904,
  36 => 83.798,
  37 => 85.4678,
  38 => 87.62,
  39 => 88.905,
  40 => 91.224,
  41 => 92.906,
  42 => 95.95,
  44 => 101.07,
  45 => 102.905,
  46 => 106.42,
  47 => 107.8682,
  48 => 112.414,
  49 => 114.818,
  50 => 118.710,
  51 => 121.760,
  52 => 127.60,
  53 => 126.904,
  54 => 131.293,
  55 => 132.905,
  56 => 137.327,
  57 => 138.905,
  58 => 140.116,
  59 => 140.907,
  60 => 144.242,
  62 => 150.36,
  63 => 151.964,
  64 => 157.25,
  65 => 158.925,
  66 => 162.500,
  67 => 164.930,
  68 => 167.259,
  69 => 168.934,
  70 => 173.045,
  71 => 174.9668,
  72 => 178.49,
  73 => 180.947,
  74 => 183.84,
  75 => 186.207,
  76 => 190.23,
  77 => 192.217,
  78 => 195.084,
  79 => 196.966,
  80 => 200.592,
  81 => 204.38,
  82 => 207.2,
  83 => 208.980,
  90 => 232.0377,
  91 => 231.035,
  92 => 238.028
)

struct Element
	symbol::String
	atomicNumber::Int

	Element(sym::AbstractString) = new(sym,atomicNumbers[sym])
end

==(el1::Element,el2::Element) = el1.symbol==el2.symbol && el1.atomicNumber==el2.atomicNumber
#isequal(el1::Element,el2::Element) = isequal(el1.symbol,el2.symbol) && isequal(el1.atomicNumber,el2.atomicNumber)

import Base.hash
hash(el::Element) = hash(el.symbol,hash(el.atomicNumber))

mutable struct Atom
	element::Element
	position::Position
end

import ..BaseModule.distance
distance(at1::Atom,at2::Atom) = distance(at1.position,at2.position)

end # module


text:
#
# sparse-tests.jl -
#
# Testing sparse operators.
#
module TestingLazyAlgebraSparseOperators

using SparseArrays
using StructuredArrays
using LazyAlgebra
using LazyAlgebra: identical
using LazyAlgebra.Foundations
using LazyAlgebra.SparseMethods
using LazyAlgebra.SparseOperators: check_structure, compute_offsets
using Test
using Random

is_csc(::Any) = false
is_csc(::CompressedSparseOperator{:CSC}) = true
is_csc(::Adjoint{<:CompressedSparseOperator{:CSR}}) = true

is_csr(::Any) = false
is_csr(::CompressedSparseOperator{:CSR}) = true
is_csr(::Adjoint{<:CompressedSparseOperator{:CSC}}) = true

is_coo(::Any) = false
is_coo(::CompressedSparseOperator{:COO}) = true
is_coo(::Adjoint{<:CompressedSparseOperator{:COO}}) = true

# Generate a possibly sparse array of random values.  Value are small signed
# integers so that all computations should be exact (except with non-integer
# multipliers).
genarr(T::Type, dims::Integer...; kwds...) = genarr(T, dims; kwds...)
function genarr(T::Type, dims::Tuple{Vararg{Integer}};
                sparsity::Real = 0,
                range::AbstractUnitRange{<:Integer} = -17:17)
    @assert 0 ≤ sparsity ≤ 1
    A = Array{T}(undef, dims)
    for i in eachindex(A)
        if sparsity > 0 && rand() ≤ sparsity
            A[i] = zero(T)
        elseif T <: Complex
            A[i] = T(rand(range), rand(range))
        else
            A[i] = T(rand(range))
        end
    end
    return A
end

# Unpack a sparse operator into a regular array using simplest iterator.  There
# may be duplicates.
function unpack_with_iterator!(dest::Array{T},
                               A::SparseOperator{E},
                               op = (E === Bool ? (|) : (+))) where {T,E}
    C = fill!(reshape(dest, (nrows(A), ncols(A))), zero(T))
    for (Aij, i, j) in A
        C[i,j] = op(C[i,j], Aij)
    end
    return dest
end

@testset "Low level sparse utilities" begin
    @test compute_offsets(2, Int[]) == [0,0,0]
    @test compute_offsets(5, [2,2,3,5]) == [0,0,2,3,3,4]
    @test compute_offsets(5, [1,3,3]) == [0,1,1,3,3,3]
    # Check for non-increasing order.
    @test_throws ErrorException compute_offsets(5, [1,3,2])
    # Check for out-of-bounds.
    @test_throws ErrorException compute_offsets(5, [0,3,3,7])
    @test_throws ErrorException compute_offsets(5, [1,3,7])
end

@testset "Compressed sparse formats " begin
    # Parameters.
    siz = (5, 6) # these tests only for A a 2-D array
    T = Float64;
    Tp = Float32; # for conversion

    # Make a banded matrix with random entries.
    A = genarr(T, siz) .* StructuredArray((i,j) -> -1 ≤ i - j ≤ 2, siz)
    spm = sparse(A);
    csr = convert(SparseOperatorCSR, A); # same as SparseOperatorCSR(A)
    csc = SparseOperatorCSC(A);
    coo = SparseOperatorCOO(A);
    x = genarr(T, siz[2]);
    y = genarr(T, siz[1]);

    # Make a COO version with randomly permuted entries.
    kp = randperm(nnz(coo));
    coo_perm = SparseOperatorCOO(get_vals(coo)[kp],
                                 get_rows(coo)[kp],
                                 get_cols(coo)[kp],
                                 row_size(coo),
                                 col_size(coo));

    # Make a COO version with randomly permuted entries and some duplicates.
    # Use fractions 1/3 and 3/4 for duplicating so that there is no loss of
    # precision.
    l = 7
    k = zeros(Int, length(kp) + l)
    w = ones(T, length(k))
    k[1:length(kp)] = kp
    for i in 1:l
        j1 = length(kp) - i + 1
        j2 = length(kp) + i
        w[j1] *= 1/4
        w[j2] *= 3/4
        k[j2] = k[j1]
    end
    coo_dups = SparseOperatorCOO(get_vals(coo)[k] .* w,
                                 get_rows(coo)[k],
                                 get_cols(coo)[k],
                                 row_size(coo),
                                 col_size(coo))

    # Check structures.
    @test check_structure(csr) === csr
    @test check_structure(csc) === csc
    @test check_structure(coo) === coo

    # Basic array-like methods
    @test eltype(csr) === eltype(A)
    @test eltype(csc) === eltype(A)
    @test eltype(coo) === eltype(A)

    @test length(csr) === length(A)
    @test length(csc) === length(A)
    @test length(coo) === length(A)

    @test ndims(csr) === ndims(A)
    @test ndims(csc) === ndims(A)
    @test ndims(coo) === ndims(A)

    @test size(csr) === size(A)
    @test size(csc) === size(A)
    @test size(coo) === size(A)

    @test nrows(csr) === size(A,1)
    @test nrows(csc) === size(A,1)
    @test nrows(coo) === size(A,1)
    @test nrows(spm) === size(A,1)

    @test ncols(csr) === size(A,2)
    @test ncols(csc) === size(A,2)
    @test ncols(coo) === size(A,2)
    @test ncols(spm) === size(A,2)

    # Number of structural non-zeros.
    nvals = count(x -> x != zero(x), A);
    @test nnz(csr) === nvals
    @test nnz(csc) === nvals
    @test nnz(coo) === nvals
    @test nnz(spm) === nvals
    @test length(get_vals(csr)) === nvals
    @test length(get_vals(csc)) === nvals
    @test length(get_vals(coo)) === nvals
    @test length(get_vals(spm)) === nvals

    # `nonzeros` and `get_vals` should yield the same object.
    @test get_vals(csr) === nonzeros(csr)
    @test get_vals(csc) === nonzeros(csc)
    @test get_vals(coo) === nonzeros(coo)
    @test get_vals(spm) === nonzeros(spm)

    # Julia arrays are column-major so values and row indices should be the
    # same in compressed sparse column (CSC) and compressed sparse coordinate
    # (COO) formats.
    @test get_vals(coo) == get_vals(csc)
    @test get_rows(coo) == get_rows(csc)
    @test get_cols(coo) == get_cols(csc)
    @test get_vals(coo) == get_vals(spm)
    @test get_rows(coo) == get_rows(spm)
    @test get_cols(coo) == get_cols(spm)

    # Check converting back to standard array.
    @test Array(csr) == A
    @test Array(csc) == A
    @test Array(coo) == A
    @test Array(spm) == A
    @test Array(coo_perm) == A
    @test Array(coo_dups) == A

    # Check matrix-vector multiplication (more serious tests in another
    # section).
    Ax = A*x
    Aty = A'*y
    @test csr*x == Ax
    @test csc*x == Ax
    @test coo*x == Ax
    @test csr'*y == Aty
    @test csc'*y == Aty
    @test coo'*y == Aty

    # Check iterators.
    B = Array{T}(undef, size(A))
    @test unpack_with_iterator!(B, csr) == A
    @test unpack_with_iterator!(B, csc) == A
    @test unpack_with_iterator!(B, coo) == A

    # Check conversions to COO, CSC and CSR formats.
    for F in (:COO, :CSC, :CSR)
        for src in (A, csc, csr, coo, coo_perm, coo_dups)
            for (t, cnv) in ((T, CompressedSparseOperator{F}(src)),
                             (T, CompressedSparseOperator{F,T}(src)),
                             (Tp, CompressedSparseOperator{F,Tp}(src)),)
                @test check_structure(cnv) === cnv
                @test eltype(cnv) === t
                if F === :COO
                    @test (cnv === coo) == (t === T && src === coo)
                    @test identical(cnv, coo) == (t === T && src === coo)
                    if is_csc(src) || is_csr(src)
                        if is_csc(src)
                            @test get_rows(cnv) === get_rows(src)
                        else
                            @test get_rows(cnv) == get_rows(src)
                        end
                        if is_csr(src)
                            @test get_cols(cnv) === get_cols(src)
                        else
                            @test get_cols(cnv) == get_cols(src)
                        end
                        if t === T
                            @test get_vals(cnv) === get_vals(src)
                        else
                            @test get_vals(cnv) == get_vals(src)
                        end
                    end
                elseif F === :CSC
                    @test (cnv === csc) == (t === T && src === csc)
                    @test identical(cnv, csc) == (t === T && src === csc)
                    if is_csc(src)
                        @test get_rows(cnv) === get_rows(csc)
                    else
                        @test get_rows(cnv) == get_rows(csc)
                    end
                    @test each_col(cnv) === each_col(csc)
                    @test get_cols(cnv) == get_cols(csc)
                    if is_csc(src) && t === T
                        @test get_vals(cnv) === get_vals(csc)
                    else
                        @test get_vals(cnv) == get_vals(csc)
                    end
                elseif F === :CSR
                    @test (cnv === csr) == (t === T && src === csr)
                    @test identical(cnv, csr) == (t === T && src === csr)
                    @test each_row(cnv) === each_row(csr)
                    @test get_rows(cnv) == get_rows(csr)
                    if is_csr(src)
                        @test get_cols(cnv) === get_cols(csr)
                    else
                        @test get_cols(cnv) == get_cols(csr)
                    end
                    if is_csr(src) && t === T
                        @test get_vals(cnv) === get_vals(csr)
                    else
                        @test get_vals(cnv) == get_vals(csr)
                    end
                end
            end
        end
    end

end # testset

@testset "Sparse operations         " begin
    rows = (2,3,4)
    cols = (5,6)
    M = length(rows)
    N = length(cols)
    for T in (Float32, Float64, Complex{Float64})
        R = real(T);
        ε = eps(R);
        A = genarr(T, rows..., cols...; sparsity=0.7); # 70% of zeros
        x = genarr(T, cols);
        xsav = vcopy(x);
        y = genarr(T, rows);
        ysav = vcopy(y);
        Scsc = SparseOperatorCSC{T,M,N}(A);
        Scsr = SparseOperatorCSR{T,M,N}(A);
        Scoo = SparseOperatorCOO{T,M,N}(A);

        # Check basic methods.
        for S in (Scsc, Scsr, Scoo)
            @test eltype(S) === T
            @test ndims(S) == length(rows) + length(cols)
            @test is_endomorphism(S) == (rows == cols)
            @test (LazyAlgebra.MorphismType(S) ===
                   LazyAlgebra.Endomorphism()) == (rows == cols)
            @test row_size(S) == rows
            @test col_size(S) == cols
            @test nrows(S) == prod(rows)
            @test ncols(S) == prod(cols)
            @test output_size(S) == rows
            @test input_size(S) == cols
            @test SparseOperator(S) === S
            @test SparseOperator{T}(S) === S
            @test SparseOperator{T,M}(S) === S
            @test SparseOperator{T,M,N}(S) === S
            @test LazyAlgebra.identical(SparseOperator(S), S)
            @test LazyAlgebra.identical(SparseOperator{T}(S), S)
            @test LazyAlgebra.identical(SparseOperator{T,M}(S), S)
            @test LazyAlgebra.identical(SparseOperator{T,M,N}(S), S)

            # Check `apply!` and `vcreate` with integer valued multipliers so
            # that exact results are expected.
            Sx  = S*x;  @test x == xsav;
            Sty = S'*y; @test y == ysav;
            @test vdot(y, Sx) == vdot(Sty, x);
            for α in (0, 1, -1, 3),
                β in (0, 1, -1, 7),
                scratch in (false, true)
                # Test operator.
                @test apply!(α, Direct, S, x, scratch, β, vcopy(y)) ==
                    R(α)*Sx + R(β)*y
                if scratch
                    vcopy!(x, xsav)
                else
                    @test x == xsav
                end
                # Test  adjoint.
                @test apply!(α, Adjoint, S, y, scratch, β, vcopy(x)) ==
                    R(α)*Sty + R(β)*x
                if scratch
                    vcopy!(y, ysav)
                else
                    @test y == ysav
                end
            end

            # Compare to results with a general matrix.
            G = GeneralMatrix(A);
            Gx  = G*x;  @test x == xsav;
            Gty = G'*y; @test y == ysav;
            @test Sx  == Gx
            @test Sty == Gty

            # Compare to results with a 2D matrix and 1D vectors.
            Aflat = reshape(A, prod(rows), prod(cols));
            xflat = reshape(x, prod(cols));
            yflat = reshape(y, prod(rows));
            @test Sx  == reshape(Aflat*xflat,  rows)
            @test Sty == reshape(Aflat'*yflat, cols)

            # Extract coefficients as an array or as a matrix.
            A1 = Array(S);
            @test eltype(A1) === eltype(S)
            @test ndims(A1) == ndims(S)
            @test size(A1) == (rows..., cols...,)
            @test A1 == A
            # FIXME: A2 = Matrix(S)
            # FIXME: @test eltype(A2) === eltype(S)
            # FIXME: @test ndims(A2) == 2
            # FIXME: @test size(A2) == (prod(rows), prod(cols))
            # FIXME: @test A2 == reshape(A, size(A2))
            # FIXME: B = (A .!= 0) # make an array of booleans
            # FIXME: @test Array(SparseOperator(B, length(rows))) == B

            # Convert to another floating-point type.
            T1 = (T <: Complex ?
                  (real(T) === Float32 ? Complex{Float64} : Complex{Float32}) :
                  (T === Float32 ? Float64 : Float32))
            S1 = SparseOperator{T1}(S)
            @test eltype(S1) === T1
            @test ndims(S1) == ndims(S)
            if is_csc(S) || is_coo(S)
                @test get_rows(S1) === get_rows(S)
            else
                @test get_rows(S1) == get_rows(S)
            end
            if is_csr(S) || is_coo(S)
                @test get_cols(S1) === get_cols(S)
            else
                @test get_cols(S1) == get_cols(S)
            end
            @test coefficients(S1) == coefficients(S)
            @test LazyAlgebra.identical(S1, S) == false

            # Check reshaping.
            S2d = reshape(S, prod(output_size(S)), prod(input_size(S)))
            @test eltype(S2d) === eltype(S)
            @test ndims(S2d) == 2
            if is_csc(S) || is_coo(S)
                @test get_rows(S2d) === get_rows(S)
            else
                @test get_rows(S2d) == get_rows(S)
            end
            if is_csr(S) || is_coo(S)
                @test get_cols(S2d) === get_cols(S)
            else
                @test get_cols(S2d) == get_cols(S)
            end
            @test coefficients(S2d) === coefficients(S)
            @test LazyAlgebra.identical(S2d, S) == false

            # FIXME: # Convert to a sparse matrix.
            # FIXME: S2 = sparse(S)
            # FIXME: @test eltype(S2) === eltype(S)
            # FIXME: S3 = SparseOperator(S2)
            # FIXME: @test eltype(S3) === eltype(S)
            # FIXME: x2 = genarr(T, input_size(S3))
            # FIXME: y2 = genarr(T, output_size(S3))
            # FIXME: @test S2*x2 == S3*x2
            # FIXME: @test S2'*y2 == S3'*y2
            # FIXME:
            # FIXME: # Check multiplication by a scalar.
            # FIXME: @test 1*S === S
            # FIXME: S0 = 0*S
            # FIXME: @test isa(S0, SparseOperator)
            # FIXME: @test length(get_rows(S0)) == 0
            # FIXME: @test length(get_cols(S0)) == 0
            # FIXME: @test length(coefficients(S0)) == 0
            # FIXME: @test eltype(S0) == eltype(S)
            # FIXME: @test input_size(S0) == input_size(S)
            # FIXME: @test output_size(S0) == output_size(S)
            # FIXME: α = R(π)
            # FIXME: αS = α*S
            # FIXME: @test isa(αS, SparseOperator)
            # FIXME: @test get_rows(αS) === get_rows(S)
            # FIXME: @test get_cols(αS) === get_cols(S)
            # FIXME: @test coefficients(αS) == α*coefficients(S)
            # FIXME: @test eltype(αS) == eltype(S)
            # FIXME: @test input_size(αS) == input_size(S)
            # FIXME: @test output_size(αS) == output_size(S)
            # FIXME:
            # FIXME: # Check left and right multiplication by a non-uniform rescaling
            # FIXME: # operator.
            # FIXME: w1 = genarr(T, output_size(S))
            # FIXME: W1 = NonuniformScaling(w1)
            # FIXME: W1_S = W1*S
            # FIXME: c1 = (w1 .* A)[A .!= zero(T)]
            # FIXME: @test isa(W1_S, SparseOperator)
            # FIXME: @test eltype(W1_S) === T
            # FIXME: @test output_size(W1_S) == output_size(S)
            # FIXME: @test input_size(W1_S) == input_size(S)
            # FIXME: @test get_rows(W1_S) === get_rows(S)
            # FIXME: @test get_cols(W1_S) === get_cols(S)
            # FIXME: @test coefficients(W1_S) == c1
            # FIXME: w2 = genarr(T, input_size(S))
            # FIXME: W2 = NonuniformScaling(w2)
            # FIXME: S_W2 = S*W2
            # FIXME: c2 = (A .* reshape(w2, (ones(Int, length(output_size(S)))...,
            # FIXME:                         input_size(S)...,)))[A .!= zero(T)]
            # FIXME: @test isa(S_W2, SparseOperator)
            # FIXME: @test eltype(S_W2) === T
            # FIXME: @test output_size(S_W2) == output_size(S)
            # FIXME: @test input_size(S_W2) == input_size(S)
            # FIXME: @test get_cols(S_W2) === get_cols(S)
            # FIXME: @test get_rows(S_W2) === get_rows(S)
            # FIXME: @test coefficients(S_W2) == c2
            # FIXME:
            # FIXME: # Use another constructor with integer conversion.
            # FIXME: R = SparseOperator(Int32.(get_rows(S)),
            # FIXME:                    Int64.(get_cols(S)),
            # FIXME:                    coefficients(S),
            # FIXME:                    Int32.(output_size(S)),
            # FIXME:                    Int64.(input_size(S)))
            # FIXME: @test Sx  == R*x
            # FIXME: @test Sty == R'*y
        end
    end
end
nothing

end # module


text:
# Test parsing strings as numbers!

    # `Base.parse` is the frontend, but strtod, strotol, and strtoul are the backend
    # Test basic methods for both of our string types
    m = m"123456789" # MallocString
    @test parse(Float64, c"123456789") === 123456789.0
    @test parse(Float64, m) === 123456789.0
    @test parse(Float64, MallocString(pointer(m))) === 123456789.0
    @test parse(Int64, c"123456789") === 123456789
    @test parse(Int64, m) === 123456789
    @test parse(Int64, MallocString(pointer(m))) === 123456789
    @test parse(UInt64, c"123456789") === 0x00000000075bcd15
    @test parse(UInt64, m) === 0x00000000075bcd15
    @test parse(UInt64, MallocString(pointer(m))) === 0x00000000075bcd15
    free(m)

    # Signed Integers (via strtol)
    @test parse(Int64, c"123") === Int64(123)
    @test parse(Int32, c"123") === Int32(123)
    @test parse(Int16, c"123") === Int16(123)
    @test parse(Int16, c"123") === Int16(123)
    @test parse(Int8, c"123") === Int8(123)

    # Unsigned Integers (via strtol)
    @test parse(UInt64, c"18446744073709551615") === 0xffffffffffffffff
    @test parse(UInt64, c"123") === UInt64(123)
    @test parse(UInt32, c"123") === UInt32(123)
    @test parse(UInt16, c"123") === UInt16(123)
    @test parse(UInt16, c"123") === UInt16(123)
    @test parse(UInt8, c"123") === UInt8(123)

    # Floats (via strtod)
    @test parse(Float64, c"123") === Float64(123.)
    @test parse(Float32, c"123") === Float32(123.)
    @test parse(Float16, c"123") === Float16(123.)
    @test parse(Float16, c"123") === Float16(123.)

    # More complicated cases
    @test parse(Float64, c"3.1415926535897") === 3.1415926535897

    # Strtod and strtol are a bit more forgiving than Base.parse,
    # and I, for one, am here for it
    @test parse(Int64, c"3.1415926535897") === 3
    @test parse(Int64, c"3asdfasdf") === 3
    @test parse(Float64, c"3 4 5") === 3.0
    @test parse(Float64, c"3asdfasdf") === 3.0
    @test parse(Float64, c"3 4 5") === 3.0
    @test parse(Float64, c"asdfasdf") === NaN

    # Test parsing from Ptr{Ptr{UInt8}} as in argv
    s1,s2 = "1", "2.0"
    a = [pointer(s1), pointer(s2)]
    argv = pointer(a)
    @test parse(Int64, argv, 1) === 1
    @test parse(Float64, argv, 2) === 2.0

## --- Test parsedlm

    fp = fopen(c"testfile.tsv", c"w")
    m = (1:10) * (1:10)'
    @test printf(fp, m) == 0
    @test fclose(fp) == 0

    m_parsed = parsedlm(Float64, c"testfile.tsv", '\t')
    @test isa(m_parsed, MallocMatrix)
    @test m_parsed == m

    # Clean up
    rm("testfile.tsv")


text:
"""
    Dinfo

The basic structure for working with loaded data, distributed amongst workers. In completeness, it represents a dataset as such:

- `val` is the "value name" under which the data are saved in processes. E.g.
  `val=:foo` means that there is a variable `foo` on each process holding a
  part of the matrix.
- `workers` is a list of workers (in correct order!) that hold the data
  (similar to `DArray.pids`)
"""
struct Dinfo
    val::Symbol
    workers::Array{Int64}
    Dinfo(val, workers) = new(val, workers)
end


text:
# Don't care about the ID when comparing
@valueequals [id] @fieldproxy mutable struct Entity{T}
    name::String
    data::Dict{String, Any}

    id::Integer

    Entity{T}(name::String, data::Dict{String, Any}, id::Integer=nextEntityId()) where T = new{T}(name, data, id)
    Entity{T}(name::String, id::Integer=nextEntityId(); kwargs...) where T = new{T}(name, Dict{String, Any}(String(k) => v for (k, v) in kwargs), id)

    Entity(name::String, data::Dict{String, Any}, id::Integer=nextEntityId()) = new{Symbol(name)}(name, data, id)
    Entity(name::String, id::Integer=nextEntityId(); kwargs...) = new{Symbol(name)}(name, Dict{String, Any}(String(k) => v for (k, v) in kwargs), id)
end

entityIdSerial = 0

const defaultBlockWidth = 16
const defaultBlockHeight = 16

const defaultSpikeWidth = 8
const defaultSpikeHeight = 8

function nextEntityId()
    return global entityIdSerial += 1
end

@mapdef Entity "player" Player(x::Integer, y::Integer)
@mapdef Entity "darkChaser" DarkChaser(x::Integer, y::Integer, canChangeMusic::Bool=true)
BadelineChaser = DarkChaser

# Added by Everest to make Dark Chasers useable by custom maps
@mapdef Entity "darkChaserEnd" DarkChaserEnd(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight)
DarkChaserBarrier = DarkChaserEnd
BadelineChaserEnd = DarkChaserEnd
BadelineChaserBarrier = DarkChaserEnd

@mapdef Entity "strawberry" Strawberry(x::Integer, y::Integer, winged::Bool=false, moon::Bool=false, checkpointID::Integer=-1, order::Integer=-1, nodes::Array{Tuple{Integer, Integer}, 1}=Tuple{Integer, Integer}[])
@mapdef Entity "goldenBerry" GoldenStrawberry(x::Integer, y::Integer, winged::Bool=false, nodes::Array{Tuple{Integer, Integer}, 1}=Tuple{Integer, Integer}[])
@mapdef Entity "memorialTextController" MemorialTextController(x::Integer, y::Integer, nodes::Array{Tuple{Integer, Integer}, 1}=Tuple{Integer, Integer}[])
GoldenStrawberryNoDash = MemorialTextController

@mapdef Entity "badelineBoost" BadelineBoost(x::Integer, y::Integer, nodes::Array{Tuple{Integer, Integer}, 1}=Tuple{Integer, Integer}[], lockCamera::Bool=true, canSkip::Bool=false, finalCh9Boost::Bool=false, finalCh9GoldenBoost::Bool=false, finalCh9Dialog::Bool=false)
@mapdef Entity "finalBoss" BadelineBoss(x::Integer, y::Integer, nodes::Array{Tuple{Integer, Integer}, 1}=Tuple{Integer, Integer}[], patternIndex::Integer=1, startHit::Bool=false, cameraPastY::Number=120.0, cameraLockY::Bool=true, canChangeMusic::Bool=true)

FinalBoss = BadelineBoss

@mapdef Entity "fireBall" FireBall(x::Integer, y::Integer, nodes::Array{Tuple{Integer, Integer}, 1}=Tuple{Integer, Integer}[], amount::Integer=1, offset::Number=0.0, speed::Number=1.0, notCoreMode::Bool=false)

@mapdef Entity "tentacles" Tentacles(x::Integer, y::Integer, nodes::Array{Tuple{Integer, Integer}, 1}=Tuple{Integer, Integer}[], fear_distance::String="", slide_until::Integer=0)

# Cobweb color exposed by Everest
@mapdef Entity "cobweb" Cobweb(x::Integer, y::Integer, nodes::Array{Tuple{Integer, Integer}, 1}=Tuple{Integer, Integer}[], color::String="696A6A")

@mapdef Entity "seeker" Seeker(x::Integer, y::Integer, nodes::Array{Tuple{Integer, Integer}, 1}=Tuple{Integer, Integer}[])
@mapdef Entity "seekerStatue" SeekerStatue(x::Integer, y::Integer, hatch::String="Distance", nodes::Array{Tuple{Integer, Integer}, 1}=Tuple{Integer, Integer}[])

@mapdef Entity "playerSeeker" PlayerSeeker(x::Integer, y::Integer)

@pardef Cassette(x1::Integer, y1::Integer, x2::Integer=x1, y2::Integer=y1) = Entity("cassette", x=x1, y=y1, nodes=Tuple{Int, Int}[(0, 0), (x2, y2)])

@mapdef Entity "towerviewer" Towerviewer(x::Integer, y::Integer, summit::Bool=false, onlyY::Bool=false)
Lookout = Towerviewer

@mapdef Entity "floatingDebris" FloatingDebris(x::Integer, y::Integer)
@mapdef Entity "foregroundDebris" ForegroundDebris(x::Integer, y::Integer)

@mapdef Entity "dreammirror" DreamMirror(x::Integer, y::Integer)
@mapdef Entity "resortmirror" ResortMirror(x::Integer, y::Integer)
@mapdef Entity "templeMirror" TempleMirror(x::Integer, y::Integer, reflectX::Number=0.0, reflectY::Number=0.0)

@mapdef Entity "refill" Refill(x::Integer, y::Integer, twoDash::Bool=false, oneUse::Bool=false)
@mapdef Entity "infiniteStar" Feather(x::Integer, y::Integer, shielded::Bool=false, singleUse::Bool=false)

# Everest needs null values here for automatic fills
# Inventory and Dreaming has to be nullable, -1 for checkpointID is considered null
@mapdef Entity "checkpoint" ChapterCheckpoint(x::Integer, y::Integer, inventory::Union{String, Nothing}=nothing, dreaming::Union{Bool, Nothing}=nothing, coreMode::Union{String, Nothing}=nothing, checkpointID::Integer=-1, bg::String=""; allowOrigin::Bool=false)

@mapdef Entity "summitcheckpoint" Checkpoint(x::Integer, y::Integer, number::Integer=0)

@mapdef Entity "spikesUp" SpikesUp(x::Integer, y::Integer, width::Integer=defaultSpikeWidth, type::String="default")
@mapdef Entity "spikesDown" SpikesDown(x::Integer, y::Integer, width::Integer=defaultSpikeWidth, type::String="default")
@mapdef Entity "spikesLeft" SpikesLeft(x::Integer, y::Integer, height::Integer=defaultSpikeHeight, type::String="default")
@mapdef Entity "spikesRight" SpikesRight(x::Integer, y::Integer, height::Integer=defaultSpikeHeight, type::String="default")

@mapdef Entity "triggerSpikesUp" TriggerSpikesUp(x::Integer, y::Integer, width::Integer=defaultSpikeWidth)
@mapdef Entity "triggerSpikesDown" TriggerSpikesDown(x::Integer, y::Integer, width::Integer=defaultSpikeWidth)
@mapdef Entity "triggerSpikesLeft" TriggerSpikesLeft(x::Integer, y::Integer, height::Integer=defaultSpikeHeight)
@mapdef Entity "triggerSpikesRight" TriggerSpikesRight(x::Integer, y::Integer, height::Integer=defaultSpikeHeight)

# Added by Everest
@mapdef Entity "triggerSpikesOriginalUp" TriggerSpikesOriginalUp(x::Integer, y::Integer, width::Integer=defaultSpikeWidth, type::String="default")
@mapdef Entity "triggerSpikesOriginalDown" TriggerSpikesOriginalDown(x::Integer, y::Integer, width::Integer=defaultSpikeWidth, type::String="default")
@mapdef Entity "triggerSpikesOriginalLeft" TriggerSpikesOriginalLeft(x::Integer, y::Integer, height::Integer=defaultSpikeHeight, type::String="default")
@mapdef Entity "triggerSpikesOriginalRight" TriggerSpikesOriginalRight(x::Integer, y::Integer, height::Integer=defaultSpikeHeight, type::String="default")

@mapdef Entity "spinner" Spinner(x::Integer, y::Integer, attachToSolid::Bool=false)

# Star and Dust added by Everest
@pardef TrackSpinner(x1::Integer, y1::Integer, x2::Integer=x1 + 16, y2::Integer=y1, speed::String="Normal", startCenter::Bool=false, dust::Bool=false, star::Bool=false) = Entity("trackSpinner", x=x1, y=y1, nodes=Tuple{Int, Int}[(x2, y2)], speed=speed, startCenter=startCenter, dust=dust, star)
@pardef RotateSpinner(x1::Integer, y1::Integer, x2::Integer=x1 + 16, y2::Integer=y1, clockwise::Bool=false, dust::Bool=false, star::Bool=false) = Entity("rotateSpinner", x=x1, y=y1, nodes=Tuple{Int, Int}[(x2, y2)], clockwise=clockwise, dust=dust, star=star)

@mapdef Entity "jumpThru" JumpThru(x::Integer, y::Integer, width::Integer=8, texture::String="wood", surfaceIndex::Int=-1)

@mapdef Entity "wallBooster" WallBooster(x::Integer, y::Integer, height::Integer=8, left::Bool=false, notCoreMode::Bool=false)
@mapdef Entity "booster" Booster(x::Integer, y::Integer, red::Bool=false, ch9_hub_booster::Bool=false)
GreenBooster(x::Integer, y::Integer) = Booster(x, y, false) # Helper
RedBooster(x::Integer, y::Integer) = Booster(x, y, true) # Helper

@mapdef Entity "lightbeam" Lightbeam(x::Integer, y::Integer, width::Integer=32, height::Integer=24, flag::String="", rotation::Integer=0)

@mapdef Entity "torch" Torch(x::Integer, y::Integer, startLit::Bool=false)

# Wire color exposed by Everest
@pardef Wire(x1::Integer, y1::Integer, x2::Integer=x1 + 8, y2::Integer=y1, above::Bool=false, color::String="595866") = Entity("wire", x=x1, y=y1, nodes=Tuple{Int, Int}[(x2, y2)], above=above, color=color)
@pardef ClothesLine(x1::Integer, y1::Integer, x2::Integer=x1 + 8, y2::Integer=y1) = Entity("clothesline", x=x1, y=y1, nodes=Tuple{Int, Int}[(x2, y2)])
@pardef CliffFlags(x1::Integer, y1::Integer, x2::Integer=x1 + 8, y2::Integer=y1) = Entity("cliffflag", x=x1, y=y1, nodes=Tuple{Int, Int}[(x2, y2)])
FlagLine = CliffFlags

@pardef SwapBlock(x1::Integer, y1::Integer, x2::Integer=x1+16, y2::Integer=y1, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight, theme="Normal") = Entity("swapBlock", x=x1, y=y1, nodes=Tuple{Int, Int}[(x2, y2)], width=width, height=height, theme=theme)
MoonSwapBlock(x1::Integer, y1::Integer, x2::Integer=x1+16, y2::Integer=y1, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight) = SwapBlock(x1, y1, x2, y2, width, height, "Moon")

@pardef SwitchGate(x1::Integer, y1::Integer, x2::Integer=x1+16, y2::Integer=y1, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight, persistent::Bool=false, sprite::String="block") = Entity("switchGate", x=x1, y=y1, nodes=Tuple{Int, Int}[(x2, y2)], width=width, height=height, persistent=persistent, sprite=sprite)
@mapdef Entity "touchSwitch" TouchSwitch(x::Integer, y::Integer)

# Texture exposed by Everest
@mapdef Entity "sinkingPlatform" SinkingPlatform(x::Integer, y::Integer, width::Integer=defaultBlockWidth, texture::String="default")
@pardef MovingPlatform(x1::Integer, y1::Integer, x2::Integer=x1 + 16, y2::Integer=y1, width::Integer=defaultBlockWidth, texture::String="default") = Entity("movingPlatform", x=x1, y=y1, nodes=Tuple{Int, Int}[(x2, y2)], width=width, texture=texture)

@pardef ZipMover(x1::Integer, y1::Integer, x2::Integer=x1 + 16, y2::Integer=y1, width::Integer=defaultBlockWidth, height::Integer=defaultBlockWidth, theme="Normal") = Entity("zipMover", x=x1, y=y1, nodes=Tuple{Int, Int}[(x2, y2)], width=width, height=height, theme=theme)
MoonZipMover(x1::Integer, y1::Integer, x2::Integer=x1 + 16, y2::Integer=y1, width::Integer=defaultBlockWidth, height::Integer=defaultBlockWidth) = Zipmover(x1, y1, x2, y2, width, height, "Moon")

@mapdef Entity "coreModeToggle" CoreFlag(x::Integer, y::Integer, onlyIce::Bool=false, onlyFire::Bool=false, persistent::Bool=false)

@mapdef Entity "slider" Slider(x::Integer, y::Integer, clockwise::Bool=true, surface::String="Floor")

@mapdef Entity "blackGem" CrystalHeart(x::Integer, y::Integer, fake::Bool=false, removeCameraTriggers::Bool=false, fakeHeartDialog::String="CH9_FAKE_HEART", keepGoingDialog::String="CH9_KEEP_GOING")
@mapdef Entity "fakeHeart" FakeCrystalHeart(x::Integer, y::Integer, color::String="Random")
@mapdef Entity "dreamHeartGem" DreamCrystalHeart(x::Integer, y::Integer)
@mapdef Entity "heartGemDoor" HeartDoor(x::Integer, y::Integer, width::Integer=40, requires::Integer=0, startHidden::Bool=false)

@mapdef Entity "plateau" Plateau(x::Integer, y::Integer)
@mapdef Entity "resortRoofEnding" ResortRoofEnding(x::Integer, y::Integer, width::Integer=defaultBlockWidth)

# CrumbleBlock texture exposed by Everest
@mapdef Entity "crumbleBlock" CrumbleBlock(x::Integer, y::Integer, width::Integer=defaultBlockWidth, texture::String="default")
@mapdef Entity "fakeWall" FakeWall(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight, tiletype::String="3")
@mapdef Entity "floatySpaceBlock" FloatySpaceBlock(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight, tiletype::String="3", disableSpawnOffset::Bool=false)
@mapdef Entity "crumbleWallOnRumble" CrumbleWallOnRumble(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight, tiletype::String="m", blendin::Bool=true, persistent::Bool=false)
@mapdef Entity "fakeBlock" FakeBlock(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight, tiletype::String="3", playTransitionReveal::Bool=false)
@mapdef Entity "exitBlock" ExitBlock(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight, tileType::String="3", playTransitionReveal::Bool=false)
@mapdef Entity "conditionBlock" ConditionBlock(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight, tileType::String="3", condition::String="Key", conditionID::String="1:1")
@mapdef Entity "coverupWall" CoverupWall(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight, tiletype::String="3")
@mapdef Entity "dashBlock" DashBlock(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight, tiletype::String="3", blendin::Bool=true, canDash::Bool=true, permanent::Bool=true)
@mapdef Entity "fallingBlock" FallingBlock(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight, tiletype::String="3", climbFall::Bool=true, behind::Bool=false)
@mapdef Entity "finalBossFallingBlock" BadelineFallingBlock(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight)

@mapdef Entity "introCrusher" IntroCrusher(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight, tiletype::String="3", flags::String="1,0b")

# Is actually not resizable, but still has a width for collision purposes
@pardef RidgeGate(x1::Integer, y1::Integer, x2::Integer=x1 + 16, y2::Integer=y1, strawberries::String="", keys::String="", texture::String="objects/ridgeGate") = Entity("ridgeGate", x=x1, y=y1, nodes=Tuple{Int, Int}[(x2, y2)], width=32, height=32, strawberries=strawberries, keys=keys, texture=texture)

@mapdef Entity "cassetteBlock" CassetteBlock(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight, index::Integer=0, tempo::Number=1.0)
@mapdef Entity "negaBlock" NegaBlock(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight)
@mapdef Entity "moveBlock" MoveBlock(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight, direction::String="Up", canSteer::Bool=false, fast::Bool=false)
@mapdef Entity "crushBlock" CrushBlock(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight, axes::String="both", chillout::Bool=false)
KevinBlock = CrushBlock

@mapdef Entity "iceBlock" IceBlock(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight)
@mapdef Entity "fireBarrier" FireBarrier(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight)

@mapdef Entity "dreamBlock" DreamBlock(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight, fastMoving::Bool=false, oneUse::Bool=false, below::Bool=false)
@mapdef false Entity "dreamBlock" MovingDreamBlock(x1::Integer, y1::Integer, x2::Integer, y2::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight, fastMoving::Bool=false, oneUse::Bool=false, below::Bool=false)
SpaceJam = DreamBlock
MovingSpaceJam = MovingDreamBlock

@mapdef Entity "starJumpBlock" StarJumpBlock(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight, sinks::Bool=true)
@mapdef Entity "starClimbController" StarJumpController(x::Integer, y::Integer)
@mapdef Entity "everest/starClimbGraphicsController" StarJumpClimbGraphicsController(x::Integer, y::Integer, fgColor::String="A3FFFF", bgColor::String="293E4B")
StarClimbController = StarJumpController
StarClimbGraphicsController = StarJumpClimbGraphicsController

@mapdef Entity "blockField" BlockField(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight)
StrawberryBlockField = BlockField

@mapdef Entity "bounceBlock" BounceBlock(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight, notCoreMode::Bool=false)

@mapdef Entity "whiteblock" WhiteBlock(x::Integer, y::Integer)
@mapdef Entity "goldenBlock" GoldenBlock(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight)

@mapdef Entity "invisibleBarrier" Barrier(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight)
@mapdef Entity "seekerBarrier" SeekerBarrier(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight)

@mapdef Entity "templeCrackedBlock" TempleCrackedBlock(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight, persistent::Bool=false)
@mapdef Entity "templeMirrorPortal" TempleMirrorPortal(x::Integer, y::Integer)

@pardef BadelineMovingBlock(x1::Integer, y1::Integer, x2::Integer=x1+16, y2::Integer=y1, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight, nodeIndex::Integer=0) = Entity("finalBossMovingBlock", x=x1, y=y1, nodes=Tuple{Int, Int}[(x2, y2)], width=width, height=height, nodeIndex=nodeIndex)

@mapdef Entity "killbox" Killbox(x::Integer, y::Integer, width::Integer=defaultBlockWidth)

@mapdef Entity "cliffside_flag" CliffsideFlag(x::Integer, y::Integer, index::Integer=0)

@mapdef Entity "water" Water(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight, hasBottom::Bool=false)
@mapdef Entity "waterfall" Waterfall(x::Integer, y::Integer)
@mapdef Entity "bigWaterfall" BigWaterfall(x::Integer, y::Integer, width::Integer=16, height::Integer=64, layer::String="FG")

@mapdef Entity "hanginglamp" HangingLamp(x::Integer, y::Integer, height::Integer=16)
@mapdef Entity "resortLantern" ResortLantern(x::Integer, y::Integer)
@mapdef Entity "lamp" Lamp(x::Integer, y::Integer, broken::Bool=false)
BrokenLamp(x::Integer, y::Integer) = Lamp(x, y, true) # Helper

@mapdef Entity "door" Door(x::Integer, y::Integer, type::String="wood")
@mapdef Entity "oshirodoor" OshiroDoor(x::Integer, y::Integer)
@mapdef Entity "trapdoor" Trapdoor(x::Integer, y::Integer)

@mapdef Entity "picoconsole" PicoConsole(x::Integer, y::Integer)

@mapdef Entity "soundSource" SoundSource(x::Integer, y::Integer, sound::String="")

@mapdef Entity "introCar" IntroCar(x::Integer, y::Integer, hasRoadAndBarriers::Bool=false)
@pardef Gondola(x::Integer, y::Integer, stopX::Integer=x+128, stopY::Integer=y-128, active::Bool=true) = Entity("gondola", x=x, y=y, nodes=Tuple{Int, Int}[(stopX, stopY)])

@mapdef Entity "templeEye" TempleEye(x::Integer, y::Integer)
@mapdef Entity "templeBigEyeball" TempleBigEyeball(x::Integer, y::Integer)
TempleBigEye = TempleBigEyeball

@mapdef Entity "summitcloud" SummitCloud(x::Integer, y::Integer)
@mapdef Entity "cloud" Cloud(x::Integer, y::Integer, fragile::Bool=false, small::Bool=false)
FragileCloud(x::Integer, y::Integer, small::Bool=false) = Cloud(x, y, true, small)

@mapdef Entity "spring" Spring(x::Integer, y::Integer, playerCanUse::Bool=true)
@mapdef Entity "wallSpringRight" SpringRight(x::Integer, y::Integer, playerCanUse::Bool=true)
@mapdef Entity "wallSpringLeft" SpringLeft(x::Integer, y::Integer, playerCanUse::Bool=true)

@mapdef Entity "colorSwitch" ColorSwitch(x::Integer, y::Integer, type::String="red")
@mapdef Entity "yellowBlocks" YellowBlock(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight)
@mapdef Entity "greenBlocks" GreenBlock(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight)
@mapdef Entity "redBlocks" RedBlock(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight)
@mapdef Entity "clutterCabinet" ClutterCabinet(x::Integer, y::Integer)
@mapdef Entity "clutterDoor" ClutterDoor(x::Integer, y::Integer, width::Integer=24, height::Integer=24, type::String="green")
ClutterSwitch = ColorSwitch

@mapdef Entity "dashSwitchH" DashSwitchHorizontal(x::Integer, y::Integer, leftSide::Bool=false, persistent::Bool=false, sprite::String="default")
@mapdef Entity "dashSwitchV" DashSwitchVertical(x::Integer, y::Integer, ceiling::Bool=false, persistent::Bool=false, sprite::String="default")
@mapdef Entity "templeGate" TempleGate(x::Integer, y::Integer, height::Integer=48, type::String="NearestSwitch", sprite::String="default")

@mapdef Entity "theoCrystalPedestal" TheoCrystalPedestal(x::Integer, y::Integer)
@mapdef Entity "theoCrystal" TheoCrystal(x::Integer, y::Integer)

@mapdef Entity "bigSpinner" Bumper(x::Integer, y::Integer)

@mapdef Entity "bonfire" Bonfire(x::Integer, y::Integer, mode::String="Lit")
@mapdef Entity "friendlyGhost" FriendlyGhost(x::Integer, y::Integer)
OshiroBoss = FriendlyGhost

@mapdef Entity "key" Key(x::Integer, y::Integer)
@mapdef Entity "lockBlock" LockBlock(x::Integer, y::Integer, sprite::String="wood", unlock_sfx::String="", stepMusicProgress::Bool=false)

@mapdef Entity "flutterbird" Flutterbird(x::Integer, y::Integer)
@mapdef Entity "bird" Bird(x::Integer, y::Integer, mode::String="Sleeping", onlyOnce::Bool=false, onlyIfPlayerLeft::Bool=false, nodes::Array{Tuple{Integer, Integer}, 1}=Tuple{Integer, Integer}[])
@pardef Hahaha(x1::Integer, y1::Integer, x2::Integer=x1+16, y2::Integer=y1, ifset::String="", triggerLaughSfx::Bool=false) = Entity("hahaha", x=x1, y=y1, nodes=Tuple{Int, Int}[(x2, y2)], ifset=ifset, triggerLaughSfx=triggerLaughSfx)
@mapdef Entity "npc" NPC(x::Integer, y::Integer, npc::String="granny_00_house")
Npc = NPC

@mapdef Entity "SummitBackgroundManager" SummitBackgroundManager(x::Integer, y::Integer, index::Integer=0, cutscene::String="", intro_launch::Bool=false, dark::Bool=false, ambience::String="")

@mapdef Entity "cutsceneNode" CutsceneNode(x::Integer, y::Integer, nodeName::String="")

@mapdef Entity "everest/npc" EverestCustomNPC(x::Integer, y::Integer, sprite::String="player/idle", spriteRate::Int=1, dialogId::String="", onlyOnce::Bool=true, endLevel::Bool=false, flipX::Bool=false, flipY::Bool=false, approachWhenTalking::Bool=false, approachDistance::Int=16, indicatorOffsetX::Int=0, indicatorOffsetY::Int=0)
EverestCustomNpc = EverestCustomNPC

@pardef ReflectionHeartStatue(x::Integer, y::Integer, hintX1::Integer=x+32, hintY1::Integer=y, hintX2::Integer=x+64, hintY2::Integer=y, hintX3::Integer=x+96, hintY3::Integer=y, hintX4::Integer=x+128, hintY4::Integer=y, gemX::Integer=x, gemY::Integer=y-64) = Entity("reflectionHeartStatue", x=x, y=y, nodes=Tuple{Int, Int}[(hintX1, hintY1), (hintX2, hintY2), (hintX3, hintY3), (hintX4, hintY4), (gemX, gemY)])
@pardef BirdForsakenCityGem(x::Integer, y::Integer, birdX::Integer=x+64, birdY::Integer=y, gemX::Integer=x+48, gemY::Integer=y) = Entity("birdForsakenCityGem", x=x, y=y, nodes=Tuple{Int, Int}[(birdX, birdY), (gemX, gemY)])
ForsakenCitySatellite = BirdForsakenCityGem

@mapdef Entity "coreMessage" CoreMessage(x::Integer, y::Integer, line::Integer=0)
@mapdef Entity "everest/coreMessage" EverestCoreMessage(x::Integer, y::Integer, line::Integer=0, dialog::String="app_ending", outline::Bool=false)
@mapdef Entity "memorial" Memorial(x::Integer, y::Integer)
@mapdef Entity "everest/memorial" EverestMemorial(x::Integer, y::Integer, dialog::String="MEMORIAL", sprite::String="scenery/memorial/memorial", spacing::Integer=16)

@mapdef Entity "payphone" Payphone(x::Integer, y::Integer)

@mapdef Entity "risingLava" RisingLava(x::Integer, y::Integer, intro::Bool=false)
@mapdef Entity "sandwichLava" SandwichLava(x::Integer, y::Integer)

@pardef Bridge(x::Integer, y::Integer, width::Integer=32, gapStartX::Integer=x+96, gapStopX::Integer=x+128) = Entity("bridge", x=x, y=y, width=width, nodes=Tuple{Int, Int}[(gapStartX, y), (gapStopX, y)])
@mapdef Entity "bridgeFixed" BridgeFixed(x::Integer, y::Integer, width::Integer=32)

@mapdef Entity "glassBlock" GlassBlock(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight, sinks::Bool=false)

@mapdef Entity "summitgem" SummitGem(x::Integer, y::Integer, gem::Integer=0)
@mapdef Entity "summitGemManager" SummitGemManager(x::Integer, y::Integer)

@mapdef Entity "moonCreature" MoonCreature(x::Integer, y::Integer, number::Integer=1)

@mapdef Entity "glider" Glider(x::Integer, y::Integer, bubble::Bool=false, tutorial::Bool=false)
Jellyfish = Glider

@mapdef Entity "eyebomb" Puffer(x::Integer, y::Integer, right::Bool=false)

@mapdef Entity "lightning" Lightning(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight, perLevel::Bool=false, moveTime::Number=5.0, nodes::Array{Tuple{Integer, Integer}, 1}=Tuple{Integer, Integer}[])
@mapdef Entity "lightningBlock" LightningBreakerBox(x::Integer, y::Integer, flipX::Bool=false, music_progress::Integer=-1, music_session::Bool=false, music::String="", flag::Bool=false)

@mapdef Entity "birdPath" BirdPath(x::Integer, y::Integer, only_once::Bool=false, onlyIfLeft::Bool=false, speedMult::Number=1.0)
@mapdef Entity "flingBird" FlingBird(x::Integer, y::Integer, waiting::Bool=false)
@mapdef Entity "flingBirdIntro" FlingBirdIntro(x::Integer, y::Integer, nodes::Array{Tuple{Integer, Integer}, 1}=Tuple{Integer, Integer}[])

@mapdef Entity "playbackBillboard" PlaybackBillboard(x::Integer, y::Integer, width::Integer=defaultBlockWidth, height::Integer=defaultBlockHeight)
@mapdef Entity "playbackTutorial" PlayerPlayback(x::Integer, y::Integer, tutorial::String="", nodes::Array{Tuple{Integer, Integer}, 1}=Tuple{Integer, Integer}[])

@mapdef Entity "kevins_pc" KevinsPC(x::Integer, y::Integer)
@mapdef Entity "wavedashmachine" WaveDashMachine(x::Integer, y::Integer)
InternetCafe = WaveDashMachine

@mapdef Entity "everest/customBirdTutorial" EverestCustomBird(x::Integer, y::Integer, birdId::String="", onlyOnce::Bool=false, caw::Bool=true, faceLeft::Bool=true, info::String="TUTORIAL_DREAMJUMP", controls::String="DownRight,+,Dash,tinyarrow,Jump")

blacklistedEntityAttrs = String["nodes"]

function Base.Dict(e::Entity)
    res = Dict{String, Any}()
    res["__name"] = e.name
    res["id"] = e.id

    for (key, value) in e.data
        if !(key in blacklistedEntityAttrs)
            res[key] = value
        end
    end

    if haskey(e.data, "nodes")
        if length(e.data["nodes"]) > 0
            res["__children"] = Dict{String, Any}[]

            for node in e.data["nodes"]
                push!(res["__children"], Dict{String, Any}(
                    "__name" => "node",
                    "x" => node[1],
                    "y" => node[2]
                ))
            end
        end
    end

    return res
end

max_stars_repo_name: CelestialCartographers/Maple

max_issues_repo_name: CelestialCartographers/Maple

max_forks_repo_name: CelestialCartographers/Maple


text:
# This function implements Kalman Filter on a state-space model of the form:
# α_{t} = T * α_{t-1} + η_{t}
# y_{t} = Z * α_{t} + ϵ_{t}
# E[η_{t}η'_{t}] = Q, E[ϵ_{t}ϵ'_{t}] = H

function KalmanFilter(T::Matrix, Z::Matrix, Q::Matrix, H::Matrix, n::Integer, α0, y)

    # Initialize state variables
    αhat = repeat([zeros(size(α0))], n);
    αhat[1] = T*α0;

    yhat = repeat([zeros(size(y[1]))], n);
    v = copy(yhat);

    P0 = Q * Q;
    d = 10;
    tol = 10^(-8);
    maxiter = 1000;
    iter = 1;
    while d > tol && iter <= maxiter
        P1 = T * P0 * T' + Q;
        d = maximum(abs.(P0 - P1));
        P0 = P1;
        iter = iter + 1;
    end

    P = repeat([zeros(size(Q))], n);
    P[1] = T * P0 * T' + Q;

    F = repeat([zeros(size(H))], n)
    G = repeat([zeros(size(Z * Q))], n)
    K = repeat([zeros(size(T * G[1]' * ones(size(H))))], n)

    for i in 1:n-1
        yhat[i] = Z * αhat[i];
        v[i] = y[i] - yhat[i];

        F[i] = Z * P[i] * Z' + H;
        G[i] = Z * P[i];
        K[i] = T * G[i]' * inv(F[i]);

        αhat[i + 1] = T * αhat[i] + K[i] * v[i];
        P[i + 1] = T * (P[i] - G[i]' * inv(F[i]) * G[i]) * T' + Q;
    end

    yhat[n] = Z * αhat[n];
    v[n] = y[n] - yhat[n];

    F[n] = Z * P[n] * Z' + H;
    G[n] = Z * P[n];
    K[n] = T * G[n]' * inv(F[n]);

    return αhat, v, yhat, P, F, G, K
end