text:
function image(img, kw_args)
  visualize(img, Style(:default), kw_args)
end

function handle_segment{P}(lines, line_segments, points::Vector{P}, segment)
    (isempty(segment) || length(segment) < 2) && return
    if length(segment) == 2
         append!(line_segments, view(points, segment))
    elseif length(segment) == 3
        p = view(points, segment)
        push!(line_segments, p[1], p[2], p[2], p[3])
    else
        append!(lines, view(points, segment))
        push!(lines, P(NaN))
    end
end
function lines(points, kw_args)
  result = []
  isempty(points) && return result
  P = eltype(points)
  lines = P[]
  line_segments = P[]
  last = 1
  for (i,p) in enumerate(points)
      if p == P(NaN) || i==length(points)
          handle_segment(lines, line_segments, points, last:(i-1))
          last = i+1
      end
  end
  if !isempty(lines)
      push!(result, visualize(lines, Style(:lines), kw_args))
  end
  if !isempty(line_segments)
      push!(result, visualize(line_segments, Style(:linesegment), kw_args))
  end
  return result
end
function shape(points, kw_args)
    result = []
    last = 1
    for (i,p) in enumerate(points)
        if p == P(NaN) || i==length(points)
            mesh = GLNormalMesh(view(points, last:(i-1)))
            if !isempty(GeometryTypes.faces(mesh))
                vis = GLVisualize.visualize(mesh, Style(:default), kw_args)
                push!(result, vis)
            end
        end
    end
    result
end

function scatter(points, kw_args)
    prim = get(kw_args, :primitive, Circle)
    visualize(prim, points), Style(:default), kw_args)
end

function poly(points, kw_args)
    push!(points, Point2f0(last(points)[1], 0), Point2f0(0)) # fill shape
    mesh = GLNormalMesh(points) # make polygon
    if !isempty(GeometryTypes.faces(mesh)) # check if polygonation has any faces
        return GLVisualize.visualize(mesh, Style(:default), kw_args)
    end
    []
end

function surface(x,y,z, kw_args)
    if isa(x, AbstractMatrix) && isa(y, AbstractMatrix)
        main = map(s->map(Float32, s), (x, y, z))
    elseif isa(x, Range) && isa(y, Range)
        main = z
        kw_args[:ranges] = (x, y)
    end
    #TODO wireframe
    return visualize(main, Style(:surface), kw_args)
end

function contour(x,y,z, kw_args)
    delete!(kw_args, :color)
    if d[:fillrange] != nothing
        main = map(z) do val
            GLVisualize.Intensity{1, Float32}(val)
        end
        GLVisualize.visualize(main, Style(:default), kw_args)
    else
        h = kw_args[:levels]
        levels = Contour.contours(x, y, z, h)
        result = Point2f0[]
        for c in levels
            for elem in c.lines
                push!(result, Point2f0(NaN32))
                append!(result, elem.vertices)
            end
        end
    return GLVisualize.visualize(result, Style(:lines),kw_args)
    end
end

function heatmap(x,y,z, kw_args)
    zmin, zmax = get(kw_args, :limits, Vec2f0(extrema(z)))
    cmap = get(kw_args, :color_map, get(kw_args, :color, RGBA{Float32}(0,0,0,1)))
    heatmap = map(z) do val
        color_lookup(cmap, val, zmin, zmax)
    end
    tex = Texture(heatmap, minfilter=:nearest)
    visualize(tex, Style(:default), kw_args)
end
function alignment2num(x::Symbol)
    (x == :hcenter || :vcenter)  && return 0.5
    (x == :left || :bottom) && return 0.0
    (x == :right || :top) && return 1.0
    0.0 # 0 default, or better to error?
end
function alignment2num(font)
    Vec2f0(map(alignment2num, (font.valign, font.halign)))
end
function text(position, text, kw_args)
    text_align = alignment2num(text.font)
    text_offset = Vec2f0(position)
    hyper_align = HyperCube(text_offset, text_align)
    text_plot(text, hyper_align, kw_args)
end
function text_plot(text, alignment, kw_args)
    transmat = kw_args[:model]
    obj = visualize(text, Style(:default), kw_args)
    bb = value(GLAbstraction.boundingbox(obj))
    w,h,_ = widths(bb)
    x,y,_ = minimum(bb)
    pivot = origin(alignment)
    pos = pivot - (Point2f0(x, y) .* widths(alignment))
    if kw_args[:rotation] != 0.0
        rot = GLAbstraction.rotationmatrix_z(Float32(font.rotation))
        transmat *= translationmatrix(pivot)*rot*translationmatrix(-pivot)
    end

    transmat *= GLAbstraction.translationmatrix(Vec3f0(pos..., 0))
    GLAbstraction.transformation(obj, transmat)
    view(obj, img.screen, camera=:orthographic_pixel)
end


text:
#Set the costum plot
function set_my_cairo_theme()

    CairoMakie.activate!()

    set_theme!(

        #Spacing between plots
        rowgap = 10,
        colgap = 10,

        #Font
        fontsize = 14,
        font = joinpath(@__DIR__ , "fonts" , "my_inter_font.otf" ),

        Axis = (

            #Default color
            backgroundcolor = :white,

            #Grid!
            xgridcolor = "#E0E0E0",
            ygridcolor = "#E0E0E0",

            xgridstyle=:dash,
            ygridstyle=:dash,

            xminorgridstyle=:dash,
            yminorgridstyle=:dash,

            xminorticksvisible = true,
            yminorticksvisible = true,

            xminorgridvisible = false,
            yminorgridvisible = true,

            xminorticks = IntervalsBetween(8),
            yminorticks = IntervalsBetween(8),

            xgridwidth=1,
            ygridwidth=1,

            #Borders
            leftspinevisible = true,
            bottomspinevisible = true,

            rightspinevisible = true,
            topspinevisible = true,

            spinewidth = 1.5,
            xtickwidth = 1.5,
            ytickwidth = 1.5,

            ),
            Legend = (
                tellheight = false,
                tellwidth = false,
                halign = :right,
                valign = :bottom,
                labelsize = 13,
                linewidth = 2,
                margin = (50, 10, 10, 10),
                framevisible = true)

)
end

ext: jl


text:
using BinaryProvider # requires BinaryProvider 0.3.0 or later

# Parse some basic command-line arguments
const verbose = "--verbose" in ARGS
const prefix = Prefix(get([a for a in ARGS if a != "--verbose"], 1, joinpath(@__DIR__, "usr")))

# These are the two binary objects we care about
products = [
    LibraryProduct(prefix, ["libfontconfig"], :jl_libfontconfig),
]

dependencies = [
    # Freetype2-related dependencies
    "build_Zlib.v1.2.11.jl",
    "build_Bzip2.v1.0.6.jl",
    "build_FreeType2.v2.10.1.jl",
    # Fontconfig-related dependencies
    "build_Libuuid.v2.34.0.jl",
    "build_Expat.v2.2.7.jl",
    "build_Fontconfig.v2.13.1.jl",
]

for dependency in dependencies
    # On macOS let's use system libuuid, this library is not available for Windows
    platform_key_abi() isa Union{MacOS,Windows} &&
        occursin(r"^build_Libuuid", dependency) &&
        continue

    # it's a bit faster to run the build in an anonymous module instead of
    # starting a new julia process

    # Build the dependencies
    Mod = @eval module Anon end
    Mod.include(dependency)
end

# Finally, write out a deps.jl file
write_deps_file(joinpath(@__DIR__, "deps.jl"), products)


text:
### Lowering

export @lower, @arrayop

import Base: eltype

"""
`Indexing(A, (idx...))`

Represents indexing over an N dimensional array A, with N `idx`
Each index could be either:
- `IndexSym{:sym}()` object: denotes iteration using `sym` as the iteration index
- `IndexConst{T}(val::T)` object: denotes a constant in that dimension
                                 (e.g.this would be wrapping an Int in case of reducedim)
"""
immutable Indexing{A, I}
    array::A
    idx::I # Tuple of Union{IndexSym, IndexConst}
end

eltype{A,I}(::Type{Indexing{A,I}}) = eltype(A)
arraytype{A,I}(::Type{Indexing{A,I}}) = A

immutable IndexSym{d} end

immutable IndexConst{T}
    val::T
end

"""
`Map(f, (arrays...))`

Represents application of function `f` on corresponding elements of `arrays`.

# Example:

`A[i]*B[j]*42` would lower to:

`Map(*, Indexing(A, IndexSym{:i}()), Indexing(B, IndexSym{:j}()), ConstArg{Int}(42))`
"""
immutable Map{F, Ts<:Tuple}
    f::F
    arrays::Ts # Tuple of Union{Indexing, ConstArg}
end

@pure function eltype{F,Ts}(::Type{Map{F,Ts}})
    promote_op_t(F, eltypes(Ts))
end

@pure function arraytype{F,Ts}(::Type{Map{F, Ts}})
    #promote_arraytype(F, map(arraytype, Ts.parameters)...)
    arraytype(Ts.parameters[1])
end

# A constant argument to Map
immutable ConstArg{T}
    val::T
end

eltype{T}(::Type{ConstArg{T}}) = T
"""
`Assign(lhs, rhs)`

represents a tensor operation. `lhs` is an `Indexing` representing the LHS of the tensor expression
`rhs` isa `Union{Indexing, Map}`
"""
immutable Assign{L<:Indexing,R,F,E}
    lhs::L
    rhs::R
    reducefn::F
    empty::E
end
Assign(lhs, rhs) = Assign(lhs, rhs, +, nothing)

function lower_index(idx, only_symbols=false)
    if isa(idx, Symbol)
        IndexSym{idx}()
    else
        if only_symbols
            throw(ArgumentError("Got $idx instead of a symbol"))
        end
        if isa(idx, Expr) && idx.head == :$
            idx = idx.args[1]
        end

        :(ArrayMeta.IndexConst($idx))
    end
end

# lower Indexing and Maps
function lower_indexing_and_maps(expr)
    @match expr begin
        A_[idx__] => :(ArrayMeta.Indexing($A, ($(map(lower_index, idx)...),)))
        f_(arg_)   => :(ArrayMeta.Map($f, ($(lower_indexing_and_maps(arg)),)))
        f_(args__)  => :(ArrayMeta.Map($f, ($(reduce(vcat, [lower_indexing_and_maps(x) for x in args])...),)))
        x_ => :(ArrayMeta.ConstArg($x))
    end
end

immutable AllocVar{sym} end # the output variable name
arraytype{A<:AllocVar}(x::Type{A}) = A
function lower_alloc_indexing(expr)
    @match expr begin
        A_[idx__] => :(ArrayMeta.Indexing(ArrayMeta.AllocVar{$(Expr(:quote, A))}(), ($(map(lower_index, idx)...),)))
        x_ => :(ArrayMeta.ConstArg($x))
    end
end

function lower(expr, reducefn, default=nothing)
    lhs, rhs, alloc = @match expr begin
        (lhs_ = rhs_) => lhs, rhs, false
        (lhs_ := rhs_) => lhs, rhs, true
        _ => error("Expression is not of the form LHS = RHS")
    end
    lidxs = indicesinvolved(lhs)
    ridxs = indicesinvolved(rhs)

    rhs_lowered = lower_indexing_and_maps(rhs)

    # which indices are reduced over
    reduceddims = setdiff(flatten(last.(ridxs)), flatten(last.(lidxs)))

    if alloc
        :(ArrayMeta.Assign($(lower_alloc_indexing(lhs)), $rhs_lowered,
                            $reducefn, $default))
    else
        :(ArrayMeta.Assign($(lower_indexing_and_maps(lhs)), $rhs_lowered,
                            $reducefn, $default))
    end
end

macro lower(expr, reducefn=+, default=nothing)
    lower(expr, reducefn, default) |> esc
end

"""
`arrayop!(t::Assign)`

Perform a tensor operation
"""
macro arrayop(expr, reducefn=+, default=nothing)
    :(ArrayMeta.arrayop!($(lower(expr, reducefn, default)))) |> esc
end

@inline function arrayop!{L,R}(t::Assign{L,R})
    arrayop!(arraytype(L), t)
end

function index_spaces{X,Idx}(name, itr::Type{Indexing{X, Idx}})
    idx_spaces = Dict()

    for (dim, idx) in enumerate(Idx.parameters)
        j = indexing_expr(name, idx, dim)
        if isa(j, Symbol)
            # store mapping from index symbol to "index space" of arrays
            # being iterated over
            Base.@get! idx_spaces j []
            push!(idx_spaces[j], (X, dim, :($name.array)))
        end
    end

    idx_spaces
end

indexing_expr{x}(name, ::Type{IndexSym{x}}, i) = x
indexing_expr{C<:IndexConst}(name, ::Type{C}, i) = :($name.idx[$i].val)

function index_spaces{F, X}(name, itr::Type{Map{F, X}})
    inner = [index_spaces(:($name.arrays[$i]), idx)
             for (i, idx) in enumerate(X.parameters)]
    merge_dictofvecs(inner...)
end

function index_spaces{L,R,F,E}(name, itr::Type{Assign{L,R,F,E}})
    merge_dictofvecs(index_spaces(:($name.lhs), L), index_spaces(:($name.rhs), R))
end

function hasreduceddims{L,R,F,E}(op::Type{Assign{L,R,F,E}})
    rspaces = index_spaces(:(rhs), R)
    lspaces = index_spaces(:(lhs), L)
    !isempty(setdiff(keys(rspaces), keys(lspaces)))
end
hasreduceddims(op::Assign) = hasreduceddims(typeof(op))

function get_subscripts{X,Idx}(name, itr::Type{Indexing{X, Idx}})
    [indexing_expr(name, idx, i) for (i, idx) in  enumerate(Idx.parameters)]
end

# Kind of a hack,
# this method is the allocating version of arrayop!
@inline @generated function arrayop!{var, L,R}(::Type{AllocVar{var}}, t::Assign{L,R})

    rspaces = index_spaces(:(t.rhs), R)
    lspaces = index_spaces(:(t.lhs), L)
    reduced_dims = setdiff(keys(rspaces), keys(lspaces))
    dims = Any[]
    for (i, k) in enumerate(L.parameters[2].parameters)
        if k <: IndexSym
            sym = k.parameters[1]

            if !haskey(rspaces, sym)
                error("Could not figure out output dimension for symbol $sym.")
            end

            dim = first(rspaces[sym])
            dimsz = :(indices($(dim[3]), $(dim[2])))
            push!(dims, dimsz)
        else
            # Indexed by a constant
            push!(dims, :(indices($(indexing_expr(:(t.lhs), k, i)), 1)))
        end
    end

    if !isempty(reduced_dims)
        # this means that the operation involves some kind of
        # accumulation. We need to fill the array with an appropriate initial value
        lhsarray = quote
            init = t.empty === nothing ?
                reduction_identity(t.reducefn, $(eltype(R))) : t.empty
            lhs = ArrayMeta.allocarray($(arraytype(R)), init, $(dims...))
        end
    else
        # we don't care how the array is initialized we're going to overwrite it fully anyway.
        lhsarray = quote
            lhs = ArrayMeta.allocarray($(arraytype(R)), nothing, $(dims...))
        end
    end

    quote
        $lhsarray
        arrayop!(ArrayMeta.Assign(Indexing(lhs, t.lhs.idx), t.rhs,
                                   t.reducefn, t.empty))
    end
end

function allocarray{T,N}(::Type{Array{T,N}}, default, sz...)
    x = similar(Array{T}, sz...)
    if default !== nothing
        fill!(x, default)
    else
        x
    end
end


text:
using Test, Random, LinearAlgebra

@testset "gesvd" begin
    include("gesvd/runtests.jl")
end


text:
module PathWeightSampling

using Distributions
import DiffEqBase
using DiffEqJump
include("trajectories/trajectory.jl")
include("EventIter.jl")
include("MetropolisSampler.jl")
include("marginal_strategies/strategies.jl")
include("GaussianSystem.jl")
include("trajectories/distribution.jl")
include("EmpiricalDistribution.jl")
include("model_setup/DrivenJumpProblem.jl")
include("JumpNetwork.jl")
include("write_hdf5.jl")

include("example_systems.jl")

include("ParallelRun.jl")

using .DrivenJumpProblems

export TIEstimate, AnnealingEstimate, DirectMCEstimate, SMCEstimate,
    generate_configuration, mutual_information

end # module


text:
"""
	VAMP{K<:Int,P<:AbstractArray}(X::P)
	VAMP{K<:Int,P<:AbstractArray}(K::Int, xdim::Union{Tuple, Int})

Vamp prior with `K` pseudoinputs of type `P`. If only the pseudoinput `X` is given, `K` is the size of
the last dimension of the input array.

# Arguments
* `K`: Number of pseudoinputs
* `xdim`: Size of an individual pseudoinput
* `X`: Pseudoinput array

# Example
Initialize a VAMP with K pseudoinputs of size xdim:
```julia-repl
julia> v = VAMP(2, 2)
VAMP{Int64,Array{Float32,2}}(
K: 2
pseudoinputs: Float32[0.876433 0.56233144; 0.24732344 0.44447201]
)

julia> v = VAMP(2, (3, 2))
VAMP{Int64,Array{Float32,3}}(
K: 2
pseudoinputs: Float32[0.21458945 0.8710681; 0.2402707 -0.20706704; 0.9916858 0.6571086]

Float32[0.6324719 0.27955383; -0.39046887 0.18451884; -0.18170312 -1.3017029]
)

julia> v = VAMP(zeros(3,2))
VAMP{Int64,Array{Float64,2}}(
K: 2
pseudoinputs: [0.0 0.0; 0.0 0.0; 0.0 0.0]
)
```
"""
struct VAMP{K<:Int,P<:AbstractArray} <: ContinuousMultivariateDistribution # add type here
	K::K
	pseudoinputs::P
end
VAMP(K::Int, xdim::Union{Tuple, Int}) = VAMP(K, randn(Float32, xdim..., K))
VAMP(X::AbstractArray) = VAMP(size(X)[end], X)

Flux.@functor VAMP

function Flux.trainable(m::VAE{<:VAMP})
    (prior=m.prior, encoder=m.encoder, decoder=m.decoder)
end

_nograd_rand(a,b) = rand(a,b)
_nograd_repeat(a,b) = repeat(a,b)
Flux.Zygote.@nograd _nograd_rand
Flux.Zygote.@nograd _nograd_repeat

"""
	init_vamp_mean(K::Int, X::AbstractArray[, σ=1f0])

Initialize a VAMP whose pseudoinputs are `K` slightly perturbed means of `X`. Currently only works
for X on cpu.
"""
init_vamp_mean(K::Int, X::AbstractArray, σ=1f0) = VAMP(K, σ*randn(eltype(X), size(X)[1:end-1]..., K) .+ mean(X, dims=ndims(X)))

"""
	init_vamp_sample(K::Int, X::AbstractArray)

Initialize a VAMP whose pseudoinputs are `K` random samples of `X`.
"""
init_vamp_sample(K::Int, X::AbstractArray) = VAMP(K,  X[repeat([:], ndims(X)-1)..., rand(1:size(X)[end], K)])

"""
	rand(p::VAMP[, batchsize, component_id])

Sample batchsize pseudoinputs of VAMP.
"""
function Random.rand(p::VAMP, batchsize::Int=1)
	ids = _nograd_rand(1:p.K, batchsize)
	_sampleVamp(p, ids)
end
function Random.rand(p::VAMP, batchsize::Int, k::Int)
	k > p.K ? error("requested samples from pseudoinput $k, only $(p.K) available") :
		nothing
	ids = _nograd_repeat([k], batchsize)
	_sampleVamp(p, ids)
end
_sampleVamp(p::VAMP, ids) =
	p.pseudoinputs[_nograd_repeat([:], ndims(p.pseudoinputs)-1)..., ids]

"""
    mmd_mean_vamp(m::AbstractVAE{<:VAMP}, x::AbstractArray, k[; distance])

MMD distance between a VAE VAMP prior and the encoding of X. This version uses mean
of encoder.
"""
function mmd_mean(m::VAE{<:VAMP}, x::AbstractArray, k::AbstractKernel;
                  distance = IPMeasures.pairwisel2)
    mmd(k, mean(m.encoder, x), mean(m.encoder, rand(m.prior, size(x, 2))), distance)
end

mmd_mean_vamp(m,x,k,distance=IPMeasures.pairwisel2) = mmd_mean(m,x,k,distance)


text:
using Test
using MianalyzerBackend
const GaussianMixture = MianalyzerBackend.GaussianMixture

@testset "GaussianMixture" begin
  @testset ".fit" begin
    actual = GaussianMixture.fit([100.0, 200.0, 300.0], 1)
    @test isapprox(actual.means_[:, 2][1], 200; atol=eps(Float32), rtol=0)
    @test isapprox(actual.covariances_[:, 2][1], 6666.6666676666; atol=eps(Float32), rtol=0)
    @test isapprox(actual.weights_[1], 1; atol=eps(Float32), rtol=0)
  end
end


text:
"""
Types deriving from `AbstractSegment{T}` must have a `range[1]` and `range[2]` function each returning a value of type
`T`, and `first(i) <= last(i)` must always be true.
"""
abstract type AbstractSegment{T} end

Base.first(i::AbstractSegment{T}) where T = i.range[1]
Base.last(i::AbstractSegment{T}) where T = i.range[1]

function basic_isless(u::AbstractSegment, v::AbstractSegment)
    return first(u) < first(v) || (first(u) == first(v) && last(u) < last(v))
end

function Base.isless(u::AbstractSegment, v::AbstractSegment)
    return basic_isless(u, v)
end

"""
A basic Segment.
"""
mutable struct Segment{T} <: AbstractSegment{T}
    range::Tuple{Int,Int}
    aux::Union{Nothing,T}

    left::Segment{T}
    right::Segment{T}

    function Segment(s::Int, Int::T, aux::T) where {T}
        @assert range[1] < range[2] "The beginning of the segment must be lower than the end."

        key = nothing
        if range[2] - range[1] > 1
            key = ceil((range[1] + range[2]) / 2)
        end

        return new((s, t), aux, Segment((s, key), nothing), Segment((key, t), nothing))
    end

end

"""
    DataArray
"""
DataArray{T} = Vector{T}


text:
# findbranches(g) = begin
# 	vs = findall(outdegree(g) .> 1)
# 	idx = map(vs) do v
# 		onb = outneighbors(g, v)
# 		any(outdegree(g, onb) .> 0) && return true
# 		return false
# 	end
# 	vs[idx]
# end

# findmerges(g) = begin
# 	vs = findall(indegree(g) .> 1)
# 	idx = map(vs) do v
# 		onb = inneighbors(g, v)
# 		any(indegree(g, onb) .> 0) && return true
# 		return false
# 	end
# 	vs[idx]
# end

# findjunctions(mp) = intersect(findbranches(mp), findmerges(mp))

function diversity(fams::Vector{Family}, levelfun)
	class = classification.(fams) |> Iterators.flatten .|> levelfun

	# class = classification.(fams)
	# class = map(class) do c
	# 	cs = levelfun.(c)
	# 	unique(cs)
	# end
	# class = Iterators.flatten(class) |> collect

	n = length(class)
    d = StatsBase.countmap(class)
    s = 0.0
    for v in values(d)
        p = v/n
        s += p * log(p)
    end
    -s
end

function orgdiversity(fams::Vector{Family})
	apps = reduce(vcat, applicants.(fams))
	n = length(apps)
    d = StatsBase.countmap(apps)
    s = 0.0
    for v in values(d)
        p = v/n
        s += p * log(p)
    end
    -s
end

function share_same_applicant(fams::Vector{Family})
	apps = reduce(vcat, applicants.(fams))
    d = StatsBase.countmap(apps)
    maximum(values(d)) / length(fams)
end

function jurdiversity(fams::Vector{Family})
	apps = reduce(vcat, jurisdiction.(fams))
	n = length(apps)
	d = StatsBase.countmap(apps)
	s = 0.0
	for v in values(d)
		p = v/n
		s += p * log(p)
	end
	-s
end

function organizational_branching(mp, fam, v)
    focal = fam[v]
    outnb = fam[outneighbors(mp, v)]
    res = 0.0
    for o in outnb
        for a in applicants(o)
            if a in applicants(focal)
                res += 1
                break
            end
        end
    end
    return res / length(outnb)
end

function organizational_merging(mp, fam, v)
    focal = fam[v]
    innb = fam[inneighbors(mp, v)]
    res = 0.0
    for o in innb
        for a in applicants(o)
            if a in applicants(focal)
                res += 1
                break
            end
        end
    end
    return res / length(innb)
end

function merged_diversity_intersect(fams, net, v)
	fam = fams[v]
	cpc = subgroup.(classification(fam))
	citedcpc = String[]
	cited = inneighbors(net, v)
	length(cited) == 0 && return nothing
	for c in cited
		append!(citedcpc, subgroup.(classification(fams[c])))
	end
	return length(intersect(cpc, citedcpc)) / length(union(cpc, citedcpc))
end

function branched_diversity_intersect(fams, net, v)
	fam = fams[v]
	cpc = subgroup.(classification(fam))
	citedcpc = String[]
	citing = outneighbors(net, v)
	length(citing) == 0 && return nothing
	for c in citing
		append!(citedcpc, subgroup.(classification(fams[c])))
	end
	return length(intersect(cpc, citedcpc)) / length(union(cpc, citedcpc))
end

function backward_diversity(fams, net, v; normalize=true)
	fam = fams[v]
	citedcpc = String[]
	cited = inneighbors(net, v)
	length(cited) == 0 && return 0.0
	for c in cited
		append!(citedcpc, section.(classification(fams[c])))
	end

	res = length(unique(citedcpc))
	normalize && return res / length(cited)
	return float.(res)
end

function forward_diversity(fams, net, v; normalize=true)
	fam = fams[v]
	citingcpc = String[]
	citing = outneighbors(net, v)
	length(citing) == 0 && return 0.0
	for c in citing
		append!(citingcpc, section.(classification(fams[c])))
	end

	res = length(unique(citingcpc))
	normalize && return res / length(citing)
	return float.(res)
end

function merge_mode(fams, net, v)
	fam = fams[v]
	citedcpc = String[]
	cited = inneighbors(net, v)
	length(cited) == 0 && return nothing
	for c in cited
		append!(citedcpc, subgroup.(classification(fams[c])))
	end

	freq = StatsBase.countmap(citedcpc)
	return maximum(values(freq))
end

function branch_mode(fams, net, v)
	fam = fams[v]
	citingcpc = String[]
	citing = outneighbors(net, v)
	length(citing) == 0 && return nothing
	for c in citing
		append!(citingcpc, subgroup.(classification(fams[c])))
	end

	freq = StatsBase.countmap(citingcpc)
	return maximum(values(freq))
end


text:
#=
This file is auto-generated. Do not edit.
=#

#! format: off

"""
    mutable struct FixedDCSource <: DCSource
        voltage::Float64
        ext::Dict{String, Any}
        states::Vector{Symbol}
        n_states::Int
        internal::InfrastructureSystemsInternal
    end

Parameters of a Fixed DC Source that returns a fixed DC voltage

# Arguments
- `voltage::Float64`: rated VA, validation range: `(0, nothing)`
- `ext::Dict{String, Any}`
- `states::Vector{Symbol}`
- `n_states::Int`: FixedDCSource has no states
- `internal::InfrastructureSystemsInternal`: power system internal reference, do not modify
"""
mutable struct FixedDCSource <: DCSource
    "rated VA"
    voltage::Float64
    ext::Dict{String, Any}
    states::Vector{Symbol}
    "FixedDCSource has no states"
    n_states::Int
    "power system internal reference, do not modify"
    internal::InfrastructureSystemsInternal
end

function FixedDCSource(voltage, ext=Dict{String, Any}(), )
    FixedDCSource(voltage, ext, Vector{Symbol}(), 0, InfrastructureSystemsInternal(), )
end

function FixedDCSource(; voltage, ext=Dict{String, Any}(), states=Vector{Symbol}(), n_states=0, internal=InfrastructureSystemsInternal(), )
    FixedDCSource(voltage, ext, states, n_states, internal, )
end

# Constructor for demo purposes; non-functional.
function FixedDCSource(::Nothing)
    FixedDCSource(;
        voltage=0,
        ext=Dict{String, Any}(),
    )
end

"""Get [`FixedDCSource`](@ref) `voltage`."""
get_voltage(value::FixedDCSource) = value.voltage
"""Get [`FixedDCSource`](@ref) `ext`."""
get_ext(value::FixedDCSource) = value.ext
"""Get [`FixedDCSource`](@ref) `states`."""
get_states(value::FixedDCSource) = value.states
"""Get [`FixedDCSource`](@ref) `n_states`."""
get_n_states(value::FixedDCSource) = value.n_states
"""Get [`FixedDCSource`](@ref) `internal`."""
get_internal(value::FixedDCSource) = value.internal

"""Set [`FixedDCSource`](@ref) `voltage`."""
set_voltage!(value::FixedDCSource, val) = value.voltage = val
"""Set [`FixedDCSource`](@ref) `ext`."""
set_ext!(value::FixedDCSource, val) = value.ext = val


text:
# The following benchmarks demonstrate
# that devectorising code can lead to substantial speed improvement
x = randn(10000000)
y = randn(10000000)

function inner(x, y)
    result = 0.0
    for i=1:length(x)
        result += x[i] * y[i]
    end
    result
end

# GC.enable(false)
@time for i=1:50 result = sum(x .* y); end
# with 1 processor: Array operations took 89.43973046 ms - avg: 90 ms
# with 9 processors: 4.895387 seconds (336.22 k allocations: 3.742 GiB, 20.99% gc time)

@time for i=1:50 result = inner(x, y) end
# 0.967685 seconds (14.13 k allocations: 746.626 KiB)

x = randn(1, 10000000)
y = randn(10000000, 1)

@time for i=1:50 result = x * y end
# 2.815247 seconds (927.43 k allocations: 44.635 MiB, 0.83% gc time)


text:
myParse(x) = parse.(Int, x)
fishes = myParse.(split.(readline("input.txt"), ','))

function simulateFishes!(fishVec, nDays)
    bucket = [0, 0, 0, 0, 0, 0, 0, 0, 0]

    for fish in fishVec
        bucket[fish+1] += 1
    end

    for _ in 1:nDays
        bucket = circshift(bucket, -1)
        bucket[6+1] += bucket[8+1] # For each fish that generates a new fish (bucket tracking 8), add count to the 6 counter as the fish resets
    end
    return sum(bucket)
end

#! Part 1

simulateFishes!(fishes, 80)

#! Part 2

simulateFishes!(fishes, 256)

max_stars_repo_path: Day 6/main.jl

max_issues_repo_path: Day 6/main.jl

max_forks_repo_path: Day 6/main.jl


text:
using FFTW

"""
    snr, amp = simulateSNR(ntf, osr, amp, f0=0, nlev=2, f=1/(4*osr), k=13)
    snr, amp = simulateSNR(ABCD, osr, amp, f0=0, nlev=2, f=1/(4*osr), k=13)

Determine the `snr` for a delta-sigma modulator by using simulations.

The modulator is described by a noise transfer function `ntf` and the
number of quantizer levels `nlev`. Alternatively, the first argument may
be an `ABCD` matrix.

The band of interest is defined by the oversampling ratio `osr` and the
center frequency `f0`.

The input signal is characterized by the `amp` vector and the `f` variable.
- `amp` defaults to [-120, -110, ... -20, -15, -10, -9, -8, ... 0] dB, where
  0 dB means a full-scale (peak value = `nlev`-1) sine wave.
- `f` is the input frequency, normalized such that 1 -> fs; `f` is rounded
  to an FFT bin.

Using sine waves located in FFT bins, the `snr` is calculated as the ratio
of the sine wave power to the power in all in-band bins other than those
associated with the input tone. Due to spectral smearing, the input tone
is not allowed to lie in bins 0 or 1. The length of the FFT is 2`ᵏ`.
"""
function simulateSNR(arg1, osr, amp=[-120:10:-20; -15; -10:0], f0=0, nlev=2, f=NaN, k=13)
    osr_mult = 2
    if f0 != 0
        osr_mult = 4
    end
    if isnan(f)
        f = f0 + 0.5/(osr*osr_mult)   # Halfway across the band
    end
    M = nlev - 1

    if abs(f-f0) > 1/(osr*osr_mult)
        @warn "the input tone is out-of-band."
    end

    N = 2^k
    if N < 8*2*osr  # Require at least 8 bins to be "in-band"
        @warn "Increasing k to accommodate a large oversampling ratio."
        k = ceil(Int, log2(8*2*osr))
        N = 2^k
    end

    F = round(Int, f*N)
    if abs(F) <= 1
        @warn "Increasing k to accomodate a low input frequency."
        # Want f*N >= 1
        k = ceil(Int, log2(1/f))
        N = 2^k
        F = 2
    end

    Ntransient = 100
    soft_start = 0.5 * (1 .- cos.(2*pi/Ntransient * (0:(Ntransient/2-1))))
    tone = M * sin.(2*pi*F/N * (0:(N+Ntransient-1)))
    tone[1:(Ntransient÷2)] = tone[1:(Ntransient÷2)] .* soft_start
    window = ds_hann(N) # Hann window

    if f0 == 0
        # Exclude DC and its adjacent bin
        inBandBins = N÷2 .+ (3:round(Int, N/(osr_mult*osr)))
        F = F - 2
    else
        f1 = round(Int, N * (f0 - 1/(osr_mult*osr)))
        inBandBins = N÷2 .+ (f1:round(Int, N * (f0 + 1/(osr_mult*osr)))) # Should exclude DC
        F = F - f1 + 1
    end

    i = 1
    snr = zeros(size(amp))
    for A = 10 .^ (amp/20)
        v, = simulateDSM(A*tone, arg1, nlev)
        hwfft = fftshift(fft(window .* v[(1+Ntransient):(N+Ntransient)]))
        snr[i] = calculateSNR(hwfft[inBandBins], F)
        i = i+1
    end

    return snr, amp
end

max_stars_repo_name: Mahmoud-Kharsa/DeltaSigma

max_issues_repo_name: Mahmoud-Kharsa/DeltaSigma

max_forks_repo_name: Mahmoud-Kharsa/DeltaSigma


text:
using CMDimData.MDDatasets
using CMDimData.EasyPlot
using CMDimData.EasyData

@testset "EasyData tests" begin #Scope for test data
	show_testset_description()

	function _isequal(d1::DataF1, d2::DataF1)
		Δ = abs(d2 - d1)
		return maximum(Δ) == 0
	end

@testset "Write/Read DataF1 comparison" begin
	show_testset_description()
	tmpfilepath = "test_datafile.hdf5"

	x = DataF1(0:.1:2π)
	s_sin = sin(x); s_cos = cos(x)

	EasyData.openwriter(tmpfilepath) do w
		write(w, s_cos, "cos")
		write(w, s_sin, "sin")
	end

	local d_sin, d_cos
	EasyData.openreader(tmpfilepath) do r
		d_sin = EasyData.readdata(r, "sin")
		d_cos = EasyData.readdata(r, "cos")
	end
	@test _isequal(s_sin, d_sin)
	@test _isequal(s_cos, d_cos)
end

@testset "Write/Read demo plot comparison" begin
	show_testset_description()
	filelist = EasyPlot.demofilelist()
	@warn("TODO: Check correspondance of all plot elements!!!")

	for filepath in filelist
		@info("Evaluating plots in $filepath...")
		fname = splitext(basename(filepath))[1]
		tmpfilepath = "test_$fname.hdf5"
		src = evalfile(filepath)
		EasyData.writeplot(tmpfilepath, src)
		dest = EasyData.readplot(tmpfilepath)

		@test src.title == dest.title
	end
end

end


text:
using Iris
using NLsolve
using Test

@testset "Helmholtz" begin
    @testset "1D cPML" begin
        ω0 = 150.5
        nD = 153
        D0s = LinRange(0,-.9,nD)
        global flag = false
        global Ω = ω0
        for D ∈ D0s
            lat = Lattices.Cartesian(.00035)
            bnd = Boundary(Interval(-.7,.7),cPML,DirichletBC)
            cell = LatticeDomain(bnd,lat)
            ndcavity = NondispersiveDomain(Interval(-.5,.5),3)
            tls = TwoLevelSystem(ωa=ω0,D0=D,γp=1)
            dcavity = DispersiveDomain(Interval(-.5,.5),tls)
            sim = Simulation(ω0, ndcavity, dcavity, cell)
            if !flag
                nep = HelmholtzNEP(sim)
                ωs, ψs = helmholtzeigen(nep, Ω; neigs=1, maxit=40)
                global Ω = ωs[1]
                if imag(ωs[1]) < 0
                    global flag = true
                end
            end
            if flag
                scpa = @test_nowarn HelmholtzSCPA(sim, 1)
                @test_nowarn nlsolve(scpa, real(Ω), ψs; show_trace=false, ftol=1e-6, iterations=250)
                global ψs = scpa.ψs
                @test scpa.converged[]
            end
        end
    end
    @testset "1D Matching" begin
        ω0 = 150.5
        nD = 153
        D0s = LinRange(0,-.9,nD)
        global flag = false
        global Ω = ω0
        for D ∈ D0s
            lat = Lattices.Cartesian(.00035)
            bnd = Boundary(Interval(-.7,.7),MatchedBC{1}(in=1),MatchedBC{2}(in=1))
            cell = LatticeDomain(bnd,lat)
            ndcavity = NondispersiveDomain(Interval(-.5,.5),3)
            tls = TwoLevelSystem(ωa=ω0,D0=D,γp=1)
            dcavity = DispersiveDomain(Interval(-.5,.5),tls)
            sim = Simulation(ω0, ndcavity, dcavity, cell)
            if !flag
                nep = HelmholtzNEP(sim)
                ωs, ψs = helmholtzeigen(nep, Ω; neigs=1, maxit=100)
                global Ω = ωs[1]
                if imag(ωs[1]) < 0
                    global flag = true
                end
            end
            if flag
                scpa = @test_nowarn HelmholtzSCPA(sim, 1)
                @test_nowarn nlsolve(scpa, real(Ω), ψs; show_trace=false, ftol=1e-6, iterations=250)
                global ψs = scpa.ψs
                @test scpa.converged[]
            end
        end
    end
end


text:
# indicator of nonpositive orthant

"""
  IndNonpositive()

Returns the indicator function the nonpositive orthant, that is

  `g(x) = 0 if x ⩽ 0, +∞ otherwise`
"""

immutable IndNonpositive <: IndicatorConvexCone end

function (f::IndNonpositive){R <: Real}(x::AbstractArray{R})
  for k in eachindex(x)
    if x[k] > 0
      return +Inf
    end
  end
  return 0.0
end

function prox!{R <: Real}(f::IndNonpositive, x::AbstractArray{R}, y::AbstractArray{R}, gamma::Real=1.0)
  for k in eachindex(x)
    if x[k] > 0
      y[k] = zero(R)
    else
      y[k] = x[k]
    end
  end
  return 0.0
end

fun_name(f::IndNonpositive) = "indicator of the Nonpositive cone"
fun_dom(f::IndNonpositive) = "AbstractArray{Real}"
fun_expr(f::IndNonpositive) = "x ↦ 0 if all(0 ⩾ x), +∞ otherwise"
fun_params(f::IndNonpositive) = "none"

function prox_naive{R <: Real}(f::IndNonpositive, x::AbstractArray{R}, gamma::Real=1.0)
  y = min.(zero(R), x)
  return y, 0.0
end


text:
using PlugAndPlot
datafile = joinpath(Pkg.dir("PlugAndPlot"), "example", "school.csv")
build_window(datafile)


text:
load("utils/namespace.jl")

ex = namespace(:nspace, :(let
# @namespace nspace let
    const x=3
    f(x) = x^2

end
))

if false
let
    type T
    end
    T
end

let
    type T
    end
    T()
end
end

#if false
@namespace nspace let
#ex = namespace(:nspace, :(let
    const x=3
    f(x) = x^2
    function g(x, y)
        x*y
    end
    abstract R
    type T<:R
        x::Int
        T(x) = new(x^2)
    end
    typealias S T
end
#))
#end

@assert nspace.x == 3
@assert nspace.f(3) == 9
@assert nspace.g(2,3) == 6
nspace.R::AbstractKind
@assert nspace.T <: nspace.R
#@assert nspace.T(5).x == 25
assert is(nspace.T, nspace.S)

max_stars_repo_name: toivoh/julia-kernels

max_issues_repo_name: toivoh/julia-kernels

max_forks_repo_name: toivoh/julia-kernels


text:
"""    issome(x)

predicate for being neither missing or nothing
"""
issome(x) = !ismissing(x) && !isa(x, Nothing)

"""    head(x)

gets the head of an Expr or nothing for LineNumberNodes
"""
head(x::Expr) = x.head
head(n::LineNumberNode) = nothing

"""    isblock(x)

predicate for an expression being a block node. Exists to make filter(x->head(x)==:block) shorter.
"""
isblock(x) = isexpr(x) && head(x) == :block

"""    isfunc(x)

predicate for an expression being a function definition. Exists to make filter(x->head(x)==:function) shorter.
"""
isfunc(x) = isexpr(x) && head(x) == :function

"""    iscall(x)

predicate for an expression being a function call. Exists to make filter(x->head(x)==:call) shorter.
"""
iscall(x) = isexpr(x) && head(x) == :call

"""    isimport(x)

predicate for an expression being an import statement. Exists to make filter(x->head(x)==:import) shorter.
"""
isimport(x) = isexpr(x) && head(x) == :import

"""    isusing(x)

predicate for an expression being a using statement. Exists to make filter(x->head(x)==:using) shorter.
"""
isusing(x) = isexpr(x) && head(x) == :using

"""    or(f,g) = x->f(x) || g(x)
"""
or(f::Function, g::Function) = x->(f(x) || g(x))

"""    and(f,g) = x->f(x) && g(x)
"""
and(f::Function, g::Function) = x->(f(x) && g(x))

"""    funcname(ex::Expr)

get the function name from an expression object return :nothing for non function expressions.
"""
function funcname(ex::Expr)
    if isfunc(ex)
        return ex.args[1].args[1]
    elseif iscall(ex)
        return ex.args[1]
    end
    return :nothing
end


text:
# Intersection
# ============

# An iterator over entries in a BigBed file that intersect a given interval.
# Constructed by indexing into `BigBedReader` with an interval.
type BigBedIntersectIterator
    bb::BigBedReader

    query_seqname::StringField
    query_first::Int64
    query_last::Int64
    query_chrom_id::UInt32
    query_chrom_size::UInt32

    # (offset, size) pairs giving the extents of data blocks that may contain
    # (overlapping intervals
    blocks::Vector{Tuple{UInt64, UInt64}}

    # Index of block currently being parsed
    block_num::Int

    reader::Nullable{BigBedDataReader}
    nextinterval::BEDInterval
    done::Bool
end

function Base.iteratorsize(::BigBedIntersectIterator)
    return Base.SizeUnknown()
end

function Base.intersect(bb::BigBedReader, query::Interval)
    seqname, first, last = query.seqname, query.first, query.last
    chrom_id, chrom_size = lookup_seqname(bb, seqname)

    # stack of nodes yet to visit
    root_position = bb.header.full_index_offset + sizeof(BigBedRTreeHeader)
    node_positions = UInt64[root_position]

    # stack of data blocks that may contain overlapping intervals
    blocks = Tuple{UInt64, UInt64}[]

    seek(bb.stream, bb.header.full_index_offset + sizeof(BigBedRTreeHeader))
    while !isempty(node_positions)
        pos = pop!(node_positions)
        seek(bb.stream, pos)
        node = read(bb.stream, BigBedRTreeNode)
        if node.isleaf == 0
            for i in 1:node.count
                internal_node = read(bb.stream, BigBedRTreeInternalNode)
                if internal_node.start_chrom_ix <= chrom_id <= internal_node.end_chrom_ix &&
                    (chrom_id < internal_node.end_chrom_ix || first <= internal_node.end_base) &&
                    (chrom_id > internal_node.start_chrom_ix || last - 1 >= internal_node.start_base)
                    push!(node_positions, internal_node.data_offset)
                end
            end
        else
            for i in 1:node.count
                leaf_node = read(bb.stream, BigBedRTreeLeafNode)
                if leaf_node.start_chrom_ix <= chrom_id <= leaf_node.end_chrom_ix &&
                    (chrom_id < leaf_node.end_chrom_ix || first <= leaf_node.end_base) &&
                    (chrom_id > leaf_node.start_chrom_ix || last - 1 >= leaf_node.start_base)
                    push!(blocks, (leaf_node.data_offset, leaf_node.data_size))
                end
            end
        end
    end

    return BigBedIntersectIterator(bb, seqname, first, last, chrom_id,
                                   chrom_size, blocks, 0,
                                   Nullable{BigBedDataReader}(),
                                   BEDInterval(), false)
end

function Base.start(it::BigBedIntersectIterator)
    find_next_intersection!(it)
    return nothing
end

function Base.next(it::BigBedIntersectIterator, ::Void)
    value = copy(it.nextinterval)
    find_next_intersection!(it)
    return value, nothing
end

function Base.done(it::BigBedIntersectIterator, ::Void)
    return it.done
end

# Find the given seqname in the BigBed file's index and read the corresponding
# sequence id and length.
function lookup_seqname(bb::BigBedReader, seqname::AbstractString)
    seek(bb.stream, bb.header.chromosome_tree_offset + sizeof(BigBedBTreeHeader))

    fill!(bb.key, 0)
    copy!(bb.key, seqname)

    while true
        node = read(bb.stream, BigBedBTreeNode)
        if node.isleaf == 0
            for i in 1:bb.btree_header.block_size
                read!(bb.stream, bb.btree_internal_nodes[i])
                bb.node_keys[i] = bb.btree_internal_nodes[i].key
            end
            i = searchsortedfirst(bb.node_keys, bb.key, Base.Order.Lt(memisless))
            if !(1 <= i <= bb.btree_header.block_size)
                break
            end

            seek(bb.stream, bb.btree_internal_nodes[i].child_offset)
        else
            for i in 1:bb.btree_header.block_size
                read!(bb.stream, bb.btree_leaf_nodes[i])
                bb.node_keys[i] = bb.btree_leaf_nodes[i].key
            end
            i = searchsortedfirst(bb.node_keys, bb.key, Base.Order.Lt(memisless))
            if !(1 <= i <= bb.btree_header.block_size) ||
                bb.btree_leaf_nodes[i].key != bb.key
                break
            end

            return (bb.btree_leaf_nodes[i].chrom_id,
                    bb.btree_leaf_nodes[i].chrom_size)
        end
    end
    error(string("Seqname \"", seqname, "\" is not present in the BigBed file."))
end

function find_next_intersection!(it::BigBedIntersectIterator)
    it.done = true
    while !isnull(it.reader) || it.block_num < length(it.blocks)
        it.done = true
        while !isnull(it.reader)
            reader = get(it.reader)
            # Run the reader until we find an intersection
            it.done = isnull(tryread!(reader, it.nextinterval))
            if it.done
                it.reader = Nullable{BigBedDataReader}()
                break
            end

            if reader.chrom_id == it.query_chrom_id &&
               it.nextinterval.first <= it.query_last &&
               it.nextinterval.last >= it.query_first
                it.done = false
                return
            end
        end

        if it.block_num < length(it.blocks)
            # advance to the next block of interest ant initialize a new reader
            it.block_num += 1
            block_offset, block_size = it.blocks[it.block_num]

            seek(it.bb.stream, block_offset)
            @assert block_size <= length(it.bb.uncompressed_data)
            unc_block_size = readbytes!(Libz.ZlibInflateInputStream(it.bb.stream, reset_on_end=false),
                                        it.bb.uncompressed_data,
                                        length(it.bb.uncompressed_data))
            it.reader = BigBedDataReader(
                BufferedInputStream(it.bb.uncompressed_data, unc_block_size),
                assumed_seqname=Nullable(it.query_seqname))
        else
            it.done = true
            return
        end
    end
end

function memisless(a::Vector{UInt8}, b::Vector{UInt8})
    if length(a) != length(b)
        return length(a) < length(b)
    end
    i = 1
    while i ≤ length(a)
        if a[i] != b[i]
            return a[i] < b[i]
        end
        i += 1
    end
    return false
end


text:
### A Pluto.jl notebook ###
# v0.17.1

using Markdown
using InteractiveUtils

# ╔═╡ 92c4155d-c639-4ce8-97e5-9f8bb68ba57c
begin
    using PlutoUI       # Pluto 附加函数, 如 PlutoUI.TableOfContents(), PlutoUI.LocalResource(), PlutoUI.with_terminal() 等
	using Pipe          # 宏 `@pipe`
	using Downloads     # 只包含 `download()` 一个函数
	using CSV           # 数据读入包
	using DataFrames    # 数据预处理包
	using Dates         # 日期数据
	using Plots         # 作图包
	using ShiftedArrays # lag() 函数
	using GLM           # 函数拟合和统计分析
	using StatsBase     # 统计模型的提取函数, 如 coeftable 等
	using Distributions # 用到的函数 Normal(), ccdf()
	# using LinearAlgebra
	# using Statistics
end

# ╔═╡ 3148423c-7fce-4fd0-b44a-b9ec82641b75
html"<button onclick='present()'> Presentation Mode </button>"

# ╔═╡ d0492b8b-64f2-47e1-8afb-6b14d5ddb322
PlutoUI.TableOfContents(title = "目录", depth = 1, aside = false)

# ╔═╡ 36a7677b-d589-42a8-a45d-28c133b5b94b
md"""

# Julia 语言是什么

$(PlutoUI.LocalResource("Covid-with-Julia.jl.assets/julia-logo-color-large.png"))

- Julia 是面向未来的技术型编程语言。
- [_The Technical Programming Language of the Future_](http://pages.stat.wisc.edu/~bates/JuliaForRProgrammers.pdf) - Douglas Bates

"""

# ╔═╡ 8d71ed8d-3022-4f6c-83ad-b75b56b1b121
begin
struct TwoColumn{T, L, R}
	top::T
    left::L
    right::R
	end

function Base.show(io, mime::MIME"text/html", tc::TwoColumn)
    write(io, """

""")
    show(io, mime, tc.top)
    write(io, """

""")
    show(io, mime, tc.left)
    write(io, """

""")
    show(io, mime, tc.right)
    write(io, """

""")
	end
TwoColumn(md"## 编程语言编年史",
	PlutoUI.LocalResource("Covid-with-Julia.jl.assets/Turris_Babel_by_Athanasius_Kircher.jpg"),
	md"""
	- 1966: FORTRAN
	- 1972: C, Proglog, SQL
	- 1975: Scheme
	- 1976: S, SAS
	- 1978: MATLAB
	- 1980: Ada, Smalltalk-80
	- 1982: PostScript
	- 1983: Objective-C, C++
	- 1984: Common Lisp, Standard ML
	- 1986: Eiffel, Erlang
	- 1987: Perl, Mathematica
	- 1988: Tcl
	- 1990: Haskell
	- 1991: Python, Visual Basic
	- 1993: Lua, R
	- 1995: Java, PHP, Ruby, JavaScript, Racket
	- 1996: OCaml
	- 2000: C#
	- 2001: D
	- 2003: Scala
	- 2005: F#
	- 2007: Clojure
	- 2009: Go
	- 2010: Rust
	- 2011: Dart, Kotlin
	- 2012: Elixir, Elm, TypeScript, **Julia**
	- 2014: Hack, Swift
	""")
end

# ╔═╡ 02376d65-c884-45a2-8537-27896d5994fd
md"""
## Julia 语言的设计者很 "贪婪"

这门编程语言应该：

- 是开源的和自由许可的；

- 同时拥有 `C` 的速度和 `Ruby` 的动态性；

- 同像的， 既与 `Lisp` 一样有真正的宏， 也与 `Matlab` 一样有熟悉的数学符号系统；

- 像 `Python` 一样高效地进行通用编程， 像 `R` 一样简单地执行统计分析， 像 `Perl` 一样自然地处理字符串, 像 `Matlab` 一样强劲地进行线性代数运算， 像胶水语言 `sheel` 一样擅长把不同程序粘合到一起;

- 既简单易学， 又要让最苛刻的极客们开心;

- 既是交互式的， 又能被编译。

[全文链接](https://julialang.org/blog/2012/02/why-we-created-julia/)
"""

# ╔═╡ a2914ab7-2048-46ab-abaf-5e4604a94eb2
md"""
## 编程的双语言问题
$(PlutoUI.LocalResource("Covid-with-Julia.jl.assets/Julia-Speed.png"))

- Julia 在两个世界中都实现了很好的效果， Julia 语言是面向未来的技术性编程语言。 [Douglas Bates](http://pages.stat.wisc.edu/~bates/JuliaForRProgrammers.md)

[图片来源 (https://statisticswithjulia.org)](https://statisticswithjulia.org)
"""

# ╔═╡ b54c9ef9-cae8-4f0e-a152-0d24686ad8e0
md"""
## Julia 语言的设计团队
$(PlutoUI.LocalResource("Covid-with-Julia.jl.assets/Julia-Citation.png"))
"""

# ╔═╡ 9c49c542-d813-47cd-bfa4-2fcfa78f2267
md"""
## Julia 语言的诞生
$(PlutoUI.LocalResource("Covid-with-Julia.jl.assets/Julia-Start.png"))
- [全文链接](https://julialang.org/assets/blog/2018-08-08-one-point-zero/release-1.0-keynote.pdf)
"""

# ╔═╡ b6c11ebe-d1d6-47fe-86e8-2047cd61ef03
md"""
## Julia 语言简史

- Aug 2009:

- Feb 2012: Julia 0.0

- Aug 2018: Julia 1.0

- Aug 2021: Julia 1.6.2
"""

# ╔═╡ 3aea3c3e-fb5e-4deb-a33f-7fdd92bb08cc
md"""
## Julia 语言更快
![](https://julialang.org/assets/benchmarks/benchmarks.svg)
- [源文件链接](https://julialang.org/benchmarks/)
"""

# ╔═╡ b1e164c2-712e-4b7f-863c-5779b97afd1e
md"""
## Julia 编译器不特别
- Julia 使用的是公众熟知的开源编译器 LLVM (Low Level Virtual Machine)， 所以其后端并没有任何特别之处， Julia 并没有什么秘密武器。

- Julia 的速度优势完全来源于其前端设计： Julia 的语义系统使得编译器更有机会产生更加高效的代码和内存布局。

- 如果只是简单地把 Matlab 或 Python 代码在 Julia 中进行编译， 那么受限于这些语言的语义系统， 此类代码甚至会比在 Matalb 或 Python 中表现更差。

- 基于此类语义系统的关键作用， Python 编译器对某些子模块的优化效果也是非常好的， 如 Numba。 但是此类优化是很难应用于整个解释性编程语言系统的。

- Julia 的优势在于代码的高效性并不局限于某些特定内在类型和操作， 而能在任何研究者自行设定的类型中实现。

[原文链接](https://docs.julialang.org/en/v1/manual/faq/#Why-don't-you-compile-Matlab/Python/R/…-code-to-Julia?)
"""

# ╔═╡ c38e1222-43f7-4564-a7f7-ddaee168e499
md"""
## Julia 语言为什么能更快？
- 语言实现 (Language Implementation)

- 语言设计 (Language Design)

- 代码风格 (Programming Style)
"""

# ╔═╡ c524c211-5426-43f8-8770-f1686f33b150
md"""
## 语言实现

$(PlutoUI.LocalResource("Covid-with-Julia.jl.assets/Julia-Compile-Pipline.png"))

- 泛型特化 (Specialization)

- 函数内联 (inlining)

- 无需封装和解封 (unboxing)

"""

# ╔═╡ 9dbeecc0-d149-4bc6-a625-04516050c8a7
md"""
## 编译过程

1. 首先， 所有代码本质上都是一些字符串 （string）， 存储在硬盘上的文本文件中；

2. 我们首先要解析 （`Meta.parse`） 这些字符串， 得到一个抽象语法数 （Abstract Syntax Tree， AST）

3. 而 AST 里有一些节点是宏， 这些宏是一些只接受编译时期变量的， 里面描述了如何产生更多的 AST。 在这一步将会运行这些宏， 我们称为展开 AST。 你可以通过 `@macroexpand` 宏查看这一步的编译结果

4. 这个时候我们再将 AST 里的语法糖等节点全部替换为函数调用， 并且使用 SSA （Static Single Assignment） 形式的 中介码（IR， intermediate representation） 作为更低级的表示。 你可以用 `@code_lowered` 来查看这一步的结果。

到此位置我们完成了代码的初始化过程。

5. 函数在被派发时会被继续编译， 因为范型函数 （generic function） 的变量类型在编译阶段无法确定的， 从而无法产生定制的机器码。

6. 然后开始进行类型推导 （type inference）， 这是为什么你可以不用写清楚到底是什么类型的原因。同时有了类型以后编译器才能做很多优化。 这样我们就得到了带类型的 IR （typed IR）。 你可以用 `@code_typed` 来查看这部分编译结果。

7. 然后我们用这个 IR 来产生 LLVM IR。 你可以用 `@code_llvm` 来查看此阶段编译结果。

8. LLVM IR 会用来产生机器码， 你可以用 `@code_native` 宏来获得这个编译结果

- [全文链接](https://blog.rogerluo.dev/2019/07/27/yassad/)

"""

# ╔═╡ 76b8ca26-b868-4ff4-991f-d93c142284d2
# Meta.parse； @macroexpand；  @code_lowered， @code_typed， @code_llvm， @code_native

# ╔═╡ 46add8a1-913d-4d83-bc3d-491dcd72e0a6
md"""
## 语言设计

- 类型有高表达性，不可擦除：减少分支，多重派发； \
  Expressive, non-erased, types: Reduces branching in code, instead relies on multi-dispatch

- 字段存储值是核查过的: 字段的存储值均为被标记的类型； \
  Checked field stores: Field always hold values of adverstised type

- 继承是单一的：派发简单、快速； \
  Single inheritance: Simpler, faster, dispatch

- 实体类型是终态的：其数据结构没有子类型，编译器知道其布局； \
  Concrete types are final: No subtyping for data structure, layout is know to the compiler

- `eval` 函数受限于全局作用域和世界时代：不会干扰编译过的编码； \
  eval restricted & world age: no interference with compiled code

Bezanson, J., Chen, J., Chung, B., Karpinski, S., Shah, V. B., Vitek, J., & Zoubritzky, L. (2018). Julia: Dynamism and performance reconciled by design. *Proceedings of the ACM on Programming Languages, 2*, 1-23. https://doi.org/10.1145/3276490

"""

# ╔═╡ 786411b0-0191-4e67-830b-cfb8ad5d04cd
md"""
## 代码风格

- 自定义类型：能根据输入值对范型进行特化； \
  Define types: Allows differentiating between values；

- 用派发而非分支：派发是特化的，而分支不是； \
  Prefer dispatch over branches: Dispatch is specialzied whereas branches are not;

- 保持类型稳定： 单态代码有确定的布局， 并能进行函数内联； \
  Write type code: Monomorphis code has a know layout, and allows for inlining

"""

# ╔═╡ 47f2b4f9-1062-4f1e-b33e-c1b54189d250
md"""
## 一个例子
"""

# ╔═╡ ec4e5ea3-1234-4425-9311-37278392cb51
removetype(@nospecialize(x)) = Ref{Any}(x)[];

# ╔═╡ 5f4469a1-8917-43f2-bf54-a63b070e8f28
foo(x) = 42 * x

# ╔═╡ aadb4b5a-94f1-4909-a806-0345efb62b71
function with_type(x)
	y = x
	return foo(y)
end

# ╔═╡ fadd14f1-7b6a-453f-b6d6-0d3e8e5c78f8
function no_type(x)
	y = removetype(x)
	return foo(y)
end

# ╔═╡ 667297fc-2bf2-4842-9cb8-ca60a6e27bdc
with_type(3) == no_type(3) == 126

# ╔═╡ db49e131-f5b3-4c48-b97b-50f362c4d343
# @code_typed with_type(3)

# ╔═╡ 86513f98-152a-4d0d-ae07-4c85689d24ab
# @code_typed no_type(3)

# ╔═╡ d820af77-e19a-42b1-86b2-a2ec0a06cc78
# with_terminal() do
# 	@code_native with_type(3)
# end

# ╔═╡ 005d7a08-728b-44c3-9d1a-8e5eb2a87b2b
# with_terminal() do
# 	@code_native no_type(3)
# end

# ╔═╡ 4d74b0b1-c4a4-48af-b9d7-e87d2974b0d9
md"""
# 软件安装和使用
- 用于科学计算的动态编程语言
- A dynamic language for scientific computing
"""

# ╔═╡ b280a3f3-058b-4e7e-9a30-086b88782a2b
md"""
## 代码编辑器
$(PlutoUI.LocalResource("Covid-with-Julia.jl.assets/Editors-and-IDEs.png"))

"""

# ╔═╡ 34110910-2f87-44b4-b028-74f8972f92be
md"""
## 软件安装和运行
- [安装二进制版](https://julialang.org/downloads/)
- [自行编译源代码](https://github.com/JuliaLang/julia)
"""

# ╔═╡ a5a8db8b-c14d-4e0d-8102-a367bc7a022b
PlutoUI.with_terminal() do
	versioninfo()
end

# ╔═╡ 49a5a52e-6652-4724-a758-de45db08377d
# varinfo() # Core, Base, Main

# ╔═╡ ab8b326b-ad96-445e-97d6-5dd8ab68f224
md"""
## 安装和运行额外包
"""

# ╔═╡ e2deac36-9b92-492d-ac61-502d9714aed2
md"""
# 数据整理和展示

- 走起来像 Python， 跑起来像 C。
- *Walks like Python, Runs like C*.
"""

# ╔═╡ 69e31dcc-788a-443e-8532-a69463b470a3
md"""
## 下载数据
"""

# ╔═╡ 50c71109-7918-4ffb-a902-bf9c214c4ee2
covid_github = "https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/";

# ╔═╡ 19d0923c-0450-4007-b8d7-76ec0064a1bb
confirmed_global = covid_github * "time_series_covid19_confirmed_global.csv";

# ╔═╡ 702e85a8-fc89-45bc-8ce2-3cb178eda547
confirmed_wide = CSV.read(Downloads.download(confirmed_global, "covid_global.csv"), DataFrame);

# ╔═╡ 65b1bf77-6c35-4b5f-831c-9907829abb70
# describe(confirmed_wide)

# ╔═╡ a166d57d-2723-40f2-97a7-e9678d1e3bec
# methods(), @edit

# ╔═╡ 44c4ef27-73db-4c87-9cf9-4e3709290cdd
md"""
## 数据整洁性
- 每个变量必读独占一列;
- 每个观测必须独占一行；
- 每个值必须独占一个单元格；
$(PlutoUI.LocalResource("Covid-with-Julia.jl.assets/Tidy-Data.png"))
"""

# ╔═╡ 05885122-92e3-4052-97fd-6ec815c65e65
# describe(confirmed_wide)

# ╔═╡ 43f89505-4af3-4a1e-a967-2b92eebb0768
md"""
## 整洁数据和修改格式
"""

# ╔═╡ 546c55ce-be0c-44a1-9f0c-f842d0a9896b
confirmed_long = stack(
	confirmed_wide,
	names(confirmed_wide)[5:end],
	variable_name = "Date",
	value_name = "Confirmed"
);

# ╔═╡ 9a77d594-9bfe-4988-9387-91b924b30f5d
# confirmed_long

# ╔═╡ b1d1ad9f-0f02-474b-9177-2d8d0965fac9
confirmed_long.Date = parse.(Date,
	confirmed_long.Date,
	Dates.DateFormat("m/d/Y")) + Year(2000);

# ╔═╡ a9d9fd7d-bc16-48ca-be19-eeb4cbeca899
describe(confirmed_long)

# ╔═╡ 66ab70b5-115b-4e48-9b9c-5c768e4869a5
md"""
## 处理台湾省数据
"""

# ╔═╡ 4bc28463-9036-4a3f-bd40-4717334ca1d0
subset(confirmed_long, Symbol("Country/Region") => x -> startswith.(x, "Taiwan"))

# ╔═╡ 817f78d9-24f2-4a6c-aaef-0190a0a5b5a8
confirmed_long."Country/Region" .= ifelse.(
	occursin.("Taiwan", confirmed_long."Country/Region"),
	"China", confirmed_long."Country/Region");

# ╔═╡ 2152c4d4-35ab-4f06-83d5-4c882a3d3e0a
subset(confirmed_long, Symbol("Country/Region") => x -> startswith.(x, "Taiwan"))

# ╔═╡ 027246a1-2393-49d2-9abe-f7a39c0ff4b9
describe(confirmed_long)

# ╔═╡ a9e2e3ee-c5d8-4481-94cd-1e7745d1bba9
md"""
## 按国家整合数据
"""

# ╔═╡ 0d53f235-4180-4df3-b123-8dd3eb240f4c
confirmed = @pipe confirmed_long                  |>
	groupby(_, [Symbol("Country/Region"), :Date]) |>
	combine(_, :Confirmed => sum => :Confirmed)   |>
	groupby(_, Symbol("Country/Region"))          |>
	transform(_, :Confirmed => (x -> x - lag(x; default = 0)) => :Daily);

# ╔═╡ f542b846-dc76-421a-9cf1-ef55ddaf4535
describe(confirmed)

# ╔═╡ f72433f1-2411-4c7a-b804-c0485380d444
md"""
## 探索数据基本信息
"""

# ╔═╡ 1aae1226-15f0-4f35-8a44-918ab3f2c005
length(unique(confirmed."Country/Region")) # 国家和地区总数

# ╔═╡ 824b0730-4129-4473-b02d-47a120076d41
min, max = extrema(confirmed.Date)         # 数据时间范围

# ╔═╡ 3f511575-ec35-4823-97de-17e4609aa271
diff([min, max])                           # 数据总天数

# ╔═╡ df72b3dc-5cb5-4b2b-a4cc-9d269764346d
md"""
## 按确诊总数筛选国家
"""

# ╔═╡ 207a52a3-9e8f-4df3-9e40-eb3fea3cbc78
function Select_Country(Data, N_day, N_country)
	N_country = N_country - 1
	min, max = extrema(Data.Date)
	(N_day > (max - min).value) && error("N_day exceed max ($((max-min).value))")
	Day_Data = Data[Data.Date .== (min + Day(N_day)), :]
	Country_List(Day_Data, N_country) =
		sort(Day_Data, :Confirmed, rev = true)[1:N_country, :("Country/Region")]
	if "China" ∈ Country_List(Day_Data, N_country)
		return  Country_List(Day_Data, N_country + 1)
	else
		return [Country_List(Day_Data, N_country); "China"]
	end
end

# ╔═╡ 9cb98725-c250-4bb4-b7b3-dbd4f49478a1
Select_Country(confirmed, 1, 10)

# ╔═╡ 26a8bea8-235e-48b6-b685-3ef6270d1801
md"""
## 选定国家确诊总数
"""

# ╔═╡ 042388ff-6c79-4309-a32d-3775688c2557
function Day_N_Country(Data, N_day, N_country)
	min_date     = minimum(Data.Date)
	Country_List = Select_Country(Data, N_day, N_country)
	return filter(x -> (x.Date == (min_date + Day(N_day))) &
					   (x."Country/Region" ∈ Country_List),
		   Data)
end

# ╔═╡ 50194e91-5b5f-470d-a558-e6a4388e0015
Day_N_Country(confirmed, 500, 5)

# ╔═╡ 961a68ba-a800-4e86-be66-e05b4557cb9f
md"""
## 确诊总数的柱形图
"""

# ╔═╡ c37c22cb-baef-43af-905c-8124d88de9c4
Day_Data = Day_N_Country(confirmed, 100, 20);

# ╔═╡ f5afaa88-616a-4643-9db3-ff12be4c2a9c
plot(
	Day_Data."Country/Region",
	Day_Data.Confirmed,
	group = Day_Data."Country/Region",
	yticks = :all,
	bar_width = 1,
	yflip = true,
	orientation = :h,
	seriestype = :bar,
	framestyle = :semi,
	tickfontsize = 8,
	xlabel = "Confirmed Cases",
	ylabel = "Country/Region",
	grid = false,
	legend = false,
	size = (800, 600)
	)

# ╔═╡ 9c338a22-8939-409c-ac89-9fc0acd2cc6c
md"""
## 确诊总数的动态变化
"""

# ╔═╡ 35890f54-ea48-4cca-acb6-1e9b803f2afc
anim = @animate for i ∈ 1:(max - min).value
	List_Selected  = Select_Country(confirmed, i, 5)
	Select_Data = filter(x -> (x."Country/Region" ∈ List_Selected) &
							  (x.Date <= min + Day(i)), confirmed)
	LastDay = Select_Data[Select_Data.Date .== (min + Day(i)), :]
	plot(
		Select_Data.Date,
		Select_Data.Confirmed,
		group = Select_Data."Country/Region",
		seriestype = :line, arrow = true,
		xlims = (min, max),
		xlabel = "Date",
		ylabel = "Confirmed Cases",
		xrotation = 0, legend = false)
	annotate!(
		LastDay.Date,
		LastDay.Confirmed,
		LastDay."Country/Region",
		annotationfontsize = 9,
		annotationhalign = :right,
		annotationvalign =  :bottom
		)
end;

# ╔═╡ ce6d98ab-cad1-46cc-aef5-f1b85fad8f14
gif(anim, "anim_fps15.gif", fps = 15)

# ╔═╡ ed271d15-c42e-4083-b768-50b5d77ef578
md"""
# 统计和模型拟合

- 因其句法而来， 因其速度而留。
- [_Come for the Syntax, Stay for the Speed._](https://media.nature.com/original/magazine-assets/d41586-019-02310-3/d41586-019-02310-3.pdf) - Nature
"""

# ╔═╡ 36cfc0cd-adb3-427d-a445-a400f8084090
md"""
## 数据提取和转化
"""

# ╔═╡ 01a404b1-d941-42f7-b5ce-d7f6684970d3
China_US = confirmed[confirmed."Country/Region" .∈ (["US", "China"],), :]

# ╔═╡ e3127bbf-c246-4eec-8480-4592ce071cee
rename!(China_US, "Country/Region" => "Country");

# ╔═╡ 3923b173-0f94-4de2-8112-907cc479aaf1
# China_US

# ╔═╡ 29388df7-db60-43c2-962a-447cae593500
transform!(China_US, :Date => ByRow(x -> getfield((x - min), :value)) => :Day);

# ╔═╡ a28039e8-f3f6-44ad-826e-4474375309b7
# China_US

# ╔═╡ f3549035-c80c-4b98-9c2b-f93c3bb1c7b4
md"""
## 模型定义和拟合
"""

# ╔═╡ 45201cfb-a31e-4740-bd82-4541ebc3a86b
model = @formula(Confirmed ~ 1 + Country + Day + Day^2 + Day^3 );

# ╔═╡ 965a1f3f-8c35-4488-8ed3-41cdcdb2cc3b
contr = Dict(:Country => EffectsCoding())

# ╔═╡ a340487e-afa0-428e-87eb-a0cd89ef8cc0
fm = fit(GeneralizedLinearModel, model, China_US, Poisson(), contrasts = contr);

# ╔═╡ c435caf9-2232-4969-becc-796ef77a7c8c
md"""
## 模型拟合结果
"""

# ╔═╡ 7ceb96ae-42f8-4361-a56d-635b90a3ec20
fm

# ╔═╡ d8a0fbb1-3d60-4b75-883b-b843327ce2d9
md"""
## 拟合的准确性
"""

# ╔═╡ 0c189181-d0f8-4059-b673-485769d8b80e
begin
	plot(China_US.Date, China_US.Confirmed,
		group = China_US.Country, label = ["Observed-China" "Observed-US"],
		legend = :topleft)
    plot!(China_US.Date, predict(fm),
		group = China_US.Country, label = ["Predicted-China" "Predict-US"])
end

# ╔═╡ 3bc6de1f-eb5b-4e45-b616-23bb8d5a75cc
md"""
## 提取相关参数
"""

# ╔═╡ 3ea0f8a1-4114-41b1-adba-ced5fce99d7c
## 常见提取函数: coef, coeftable, confint, deviance, nulldeviance, dof, dof_residual, loglikelihood, nullloglikelihood, nobs, stderror, vcov, residuals, predict, fitted, fit, fit!, model_response, response, modelmatrix, r2, r², adjr2, adjr²

# ╔═╡ 70a746fd-29e3-409a-908f-abcd5a495498
coeftable(fm)

# ╔═╡ 2d21d130-7eb7-412d-9234-e144e52719a8
b_val = coef(fm)

# ╔═╡ 99aab59e-6978-4dfe-a121-5ae8e06f7ed0
se = stderror(fm)# ≈ sqrt.(diag(vcov(fm)))

# ╔═╡ 276dd17a-3cb5-4ecf-832d-0087d7ec5ee4
z_val = b_val ./ se

# ╔═╡ c61b42a3-a94f-4973-90a5-e8eb276de56a
p_val = @. ccdf(Normal(0, 1), abs(z_val))

# ╔═╡ 0741c318-2807-4c37-a524-1f8d03e1b6c5
zz = cquantile(Normal(0, 1), (1 - 0.95)/2)

# ╔═╡ bc7d1235-4db5-4275-8807-0257dac2d1a8
conf_low = b_val .-  zz .* se

# ╔═╡ c6308cea-6719-4183-b418-2ad2f16bfc52
conf_high = b_val .+  zz .* se

# ╔═╡ f769acf5-5972-4362-87ce-2d33a0aa1bc2
[b_val se z_val p_val conf_low conf_high]

# ╔═╡ 00000000-0000-0000-0000-000000000001
PLUTO_PROJECT_TOML_CONTENTS = """
[deps]
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6"
GLM = "38e38edf-8417-5370-95a0-9cbb8c7f171a"
Pipe = "b98c9c47-44ae-5843-9183-064241ee97a0"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
PlutoUI = "7f904dfe-b85e-4ff6-b463-dae2292396a8"
ShiftedArrays = "1277b4bf-5013-50f5-be3d-901d8477a67a"
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"

[compat]
CSV = "~0.9.4"
DataFrames = "~1.2.2"
Distributions = "~0.25.16"
GLM = "~1.5.1"
Pipe = "~1.3.0"
Plots = "~1.22.2"
PlutoUI = "~0.7.10"
ShiftedArrays = "~1.0.0"
StatsBase = "~0.33.10"
"""

# ╔═╡ 00000000-0000-0000-0000-000000000002
PLUTO_MANIFEST_TOML_CONTENTS = """
# This file is machine-generated - editing it directly is not advised

[[Adapt]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "84918055d15b3114ede17ac6a7182f68870c16f7"
uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
version = "3.3.1"

[[ArgTools]]
uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f"

[[Artifacts]]
uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33"

[[Base64]]
uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"

[[Bzip2_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "19a35467a82e236ff51bc17a3a44b69ef35185a2"
uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0"
version = "1.0.8+0"

[[CSV]]
deps = ["CodecZlib", "Dates", "FilePathsBase", "Mmap", "Parsers", "PooledArrays", "SentinelArrays", "Tables", "Unicode", "WeakRefStrings"]
git-tree-sha1 = "3a877c2fc5c9b88ed7259fd0bdb7691aad6b50dc"
uuid = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
version = "0.9.4"

[[Cairo_jll]]
deps = ["Artifacts", "Bzip2_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"]
git-tree-sha1 = "f2202b55d816427cd385a9a4f3ffb226bee80f99"
uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a"
version = "1.16.1+0"

[[ChainRulesCore]]
deps = ["Compat", "LinearAlgebra", "SparseArrays"]
git-tree-sha1 = "bd4afa1fdeec0c8b89dad3c6e92bc6e3b0fec9ce"
uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
version = "1.6.0"

[[CodecZlib]]
deps = ["TranscodingStreams", "Zlib_jll"]
git-tree-sha1 = "ded953804d019afa9a3f98981d99b33e3db7b6da"
uuid = "944b1d66-785c-5afd-91f1-9de20f533193"
version = "0.7.0"

[[ColorSchemes]]
deps = ["ColorTypes", "Colors", "FixedPointNumbers", "Random"]
git-tree-sha1 = "9995eb3977fbf67b86d0a0a0508e83017ded03f2"
uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4"
version = "3.14.0"

[[ColorTypes]]
deps = ["FixedPointNumbers", "Random"]
git-tree-sha1 = "024fe24d83e4a5bf5fc80501a314ce0d1aa35597"
uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f"
version = "0.11.0"

[[Colors]]
deps = ["ColorTypes", "FixedPointNumbers", "Reexport"]
git-tree-sha1 = "417b0ed7b8b838aa6ca0a87aadf1bb9eb111ce40"
uuid = "5ae59095-9a9b-59fe-a467-6f913c188581"
version = "0.12.8"

[[Compat]]
deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "SHA", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"]
git-tree-sha1 = "1a90210acd935f222ea19657f143004d2c2a1117"
uuid = "34da2185-b29b-5c13-b0c7-acf172513d20"
version = "3.38.0"

[[CompilerSupportLibraries_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae"

[[Contour]]
deps = ["StaticArrays"]
git-tree-sha1 = "9f02045d934dc030edad45944ea80dbd1f0ebea7"
uuid = "d38c429a-6771-53c6-b99e-75d170b6e991"
version = "0.5.7"

[[Crayons]]
git-tree-sha1 = "3f71217b538d7aaee0b69ab47d9b7724ca8afa0d"
uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f"
version = "4.0.4"

[[DataAPI]]
git-tree-sha1 = "cc70b17275652eb47bc9e5f81635981f13cea5c8"
uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a"
version = "1.9.0"

[[DataFrames]]
deps = ["Compat", "DataAPI", "Future", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrettyTables", "Printf", "REPL", "Reexport", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"]
git-tree-sha1 = "d785f42445b63fc86caa08bb9a9351008be9b765"
uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
version = "1.2.2"

[[DataStructures]]
deps = ["Compat", "InteractiveUtils", "OrderedCollections"]
git-tree-sha1 = "7d9d316f04214f7efdbb6398d545446e246eff02"
uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
version = "0.18.10"

[[DataValueInterfaces]]
git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6"
uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464"
version = "1.0.0"

[[Dates]]
deps = ["Printf"]
uuid = "ade2ca70-3891-5945-98fb-dc099432e06a"

[[DelimitedFiles]]
deps = ["Mmap"]
uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab"

[[Distributed]]
deps = ["Random", "Serialization", "Sockets"]
uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b"

[[Distributions]]
deps = ["ChainRulesCore", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SparseArrays", "SpecialFunctions", "Statistics", "StatsBase", "StatsFuns"]
git-tree-sha1 = "f4efaa4b5157e0cdb8283ae0b5428bc9208436ed"
uuid = "31c24e10-a181-5473-b8eb-7969acd0382f"
version = "0.25.16"

[[DocStringExtensions]]
deps = ["LibGit2"]
git-tree-sha1 = "a32185f5428d3986f47c2ab78b1f216d5e6cc96f"
uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
version = "0.8.5"

[[Downloads]]
deps = ["ArgTools", "LibCURL", "NetworkOptions"]
uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6"

[[EarCut_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "3f3a2501fa7236e9b911e0f7a588c657e822bb6d"
uuid = "5ae413db-bbd1-5e63-b57d-d24a61df00f5"
version = "2.2.3+0"

[[Expat_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "b3bfd02e98aedfa5cf885665493c5598c350cd2f"
uuid = "2e619515-83b5-522b-bb60-26c02a35a201"
version = "2.2.10+0"

[[FFMPEG]]
deps = ["FFMPEG_jll"]
git-tree-sha1 = "b57e3acbe22f8484b4b5ff66a7499717fe1a9cc8"
uuid = "c87230d0-a227-11e9-1b43-d7ebe4e7570a"
version = "0.4.1"

[[FFMPEG_jll]]
deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "Pkg", "Zlib_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"]
git-tree-sha1 = "d8a578692e3077ac998b50c0217dfd67f21d1e5f"
uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5"
version = "4.4.0+0"

[[FilePathsBase]]
deps = ["Dates", "Mmap", "Printf", "Test", "UUIDs"]
git-tree-sha1 = "6d4b609786127030d09e6b1ee0e2044ec20eb403"
uuid = "48062228-2e41-5def-b9a4-89aafe57970f"
version = "0.9.11"

[[FillArrays]]
deps = ["LinearAlgebra", "Random", "SparseArrays", "Statistics"]
git-tree-sha1 = "7f6ad1a7f4621b4ab8e554133dade99ebc6e7221"
uuid = "1a297f60-69ca-5386-bcde-b61e274b549b"
version = "0.12.5"

[[FixedPointNumbers]]
deps = ["Statistics"]
git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc"
uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93"
version = "0.8.4"

[[Fontconfig_jll]]
deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Pkg", "Zlib_jll"]
git-tree-sha1 = "21efd19106a55620a188615da6d3d06cd7f6ee03"
uuid = "a3f928ae-7b40-5064-980b-68af3947d34b"
version = "2.13.93+0"

[[Formatting]]
deps = ["Printf"]
git-tree-sha1 = "8339d61043228fdd3eb658d86c926cb282ae72a8"
uuid = "59287772-0a20-5a39-b81b-1366585eb4c0"
version = "0.4.2"

[[FreeType2_jll]]
deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
git-tree-sha1 = "87eb71354d8ec1a96d4a7636bd57a7347dde3ef9"
uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7"
version = "2.10.4+0"

[[FriBidi_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "aa31987c2ba8704e23c6c8ba8a4f769d5d7e4f91"
uuid = "559328eb-81f9-559d-9380-de523a88c83c"
version = "1.0.10+0"

[[Future]]
deps = ["Random"]
uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820"

[[GLFW_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Pkg", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll"]
git-tree-sha1 = "0c603255764a1fa0b61752d2bec14cfbd18f7fe8"
uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89"
version = "3.3.5+1"

[[GLM]]
deps = ["Distributions", "LinearAlgebra", "Printf", "Reexport", "SparseArrays", "SpecialFunctions", "Statistics", "StatsBase", "StatsFuns", "StatsModels"]
git-tree-sha1 = "f564ce4af5e79bb88ff1f4488e64363487674278"
uuid = "38e38edf-8417-5370-95a0-9cbb8c7f171a"
version = "1.5.1"

[[GR]]
deps = ["Base64", "DelimitedFiles", "GR_jll", "HTTP", "JSON", "Libdl", "LinearAlgebra", "Pkg", "Printf", "Random", "Serialization", "Sockets", "Test", "UUIDs"]
git-tree-sha1 = "c2178cfbc0a5a552e16d097fae508f2024de61a3"
uuid = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71"
version = "0.59.0"

[[GR_jll]]
deps = ["Artifacts", "Bzip2_jll", "Cairo_jll", "FFMPEG_jll", "Fontconfig_jll", "GLFW_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pixman_jll", "Pkg", "Qt5Base_jll", "Zlib_jll", "libpng_jll"]
git-tree-sha1 = "ef49a187604f865f4708c90e3f431890724e9012"
uuid = "d2c73de3-f751-5644-a686-071e5b155ba9"
version = "0.59.0+0"

[[GeometryBasics]]
deps = ["EarCut_jll", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"]
git-tree-sha1 = "58bcdf5ebc057b085e58d95c138725628dd7453c"
uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326"
version = "0.4.1"

[[Gettext_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "XML2_jll"]
git-tree-sha1 = "9b02998aba7bf074d14de89f9d37ca24a1a0b046"
uuid = "78b55507-aeef-58d4-861c-77aaff3498b1"
version = "0.21.0+0"

[[Glib_jll]]
deps = ["Artifacts", "Gettext_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE_jll", "Pkg", "Zlib_jll"]
git-tree-sha1 = "7bf67e9a481712b3dbe9cb3dac852dc4b1162e02"
uuid = "7746bdde-850d-59dc-9ae8-88ece973131d"
version = "2.68.3+0"

[[Graphite2_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "344bf40dcab1073aca04aa0df4fb092f920e4011"
uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472"
version = "1.3.14+0"

[[Grisu]]
git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2"
uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe"
version = "1.0.2"

[[HTTP]]
deps = ["Base64", "Dates", "IniFile", "Logging", "MbedTLS", "NetworkOptions", "Sockets", "URIs"]
git-tree-sha1 = "60ed5f1643927479f845b0135bb369b031b541fa"
uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3"
version = "0.9.14"

[[HarfBuzz_jll]]
deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"]
git-tree-sha1 = "8a954fed8ac097d5be04921d595f741115c1b2ad"
uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566"
version = "2.8.1+0"

[[HypertextLiteral]]
git-tree-sha1 = "72053798e1be56026b81d4e2682dbe58922e5ec9"
uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2"
version = "0.9.0"

[[IniFile]]
deps = ["Test"]
git-tree-sha1 = "098e4d2c533924c921f9f9847274f2ad89e018b8"
uuid = "83e8ac13-25f8-5344-8a64-a9f2b223428f"
version = "0.5.0"

[[InteractiveUtils]]
deps = ["Markdown"]
uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240"

[[InvertedIndices]]
git-tree-sha1 = "bee5f1ef5bf65df56bdd2e40447590b272a5471f"
uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f"
version = "1.1.0"

[[IrrationalConstants]]
git-tree-sha1 = "f76424439413893a832026ca355fe273e93bce94"
uuid = "92d709cd-6900-40b7-9082-c6be49f344b6"
version = "0.1.0"

[[IterTools]]
git-tree-sha1 = "05110a2ab1fc5f932622ffea2a003221f4782c18"
uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e"
version = "1.3.0"

[[IteratorInterfaceExtensions]]
git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856"
uuid = "82899510-4779-5014-852e-03e436cf321d"
version = "1.0.0"

[[JLLWrappers]]
deps = ["Preferences"]
git-tree-sha1 = "642a199af8b68253517b80bd3bfd17eb4e84df6e"
uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210"
version = "1.3.0"

[[JSON]]
deps = ["Dates", "Mmap", "Parsers", "Unicode"]
git-tree-sha1 = "8076680b162ada2a031f707ac7b4953e30667a37"
uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
version = "0.21.2"

[[JpegTurbo_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "d735490ac75c5cb9f1b00d8b5509c11984dc6943"
uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8"
version = "2.1.0+0"

[[LAME_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "f6250b16881adf048549549fba48b1161acdac8c"
uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d"
version = "3.100.1+0"

[[LZO_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "e5b909bcf985c5e2605737d2ce278ed791b89be6"
uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac"
version = "2.10.1+0"

[[LaTeXStrings]]
git-tree-sha1 = "c7f1c695e06c01b95a67f0cd1d34994f3e7db104"
uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
version = "1.2.1"

[[Latexify]]
deps = ["Formatting", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "Printf", "Requires"]
git-tree-sha1 = "a4b12a1bd2ebade87891ab7e36fdbce582301a92"
uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316"
version = "0.15.6"

[[LibCURL]]
deps = ["LibCURL_jll", "MozillaCACerts_jll"]
uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21"

[[LibCURL_jll]]
deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"]
uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0"

[[LibGit2]]
deps = ["Base64", "NetworkOptions", "Printf", "SHA"]
uuid = "76f85450-5226-5b5a-8eaa-529ad045b433"

[[LibSSH2_jll]]
deps = ["Artifacts", "Libdl", "MbedTLS_jll"]
uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8"

[[Libdl]]
uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"

[[Libffi_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "0b4a5d71f3e5200a7dff793393e09dfc2d874290"
uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490"
version = "3.2.2+1"

[[Libgcrypt_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll", "Pkg"]
git-tree-sha1 = "64613c82a59c120435c067c2b809fc61cf5166ae"
uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4"
version = "1.8.7+0"

[[Libglvnd_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll", "Xorg_libXext_jll"]
git-tree-sha1 = "7739f837d6447403596a75d19ed01fd08d6f56bf"
uuid = "7e76a0d4-f3c7-5321-8279-8d96eeed0f29"
version = "1.3.0+3"

[[Libgpg_error_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "c333716e46366857753e273ce6a69ee0945a6db9"
uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8"
version = "1.42.0+0"

[[Libiconv_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "42b62845d70a619f063a7da093d995ec8e15e778"
uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531"
version = "1.16.1+1"

[[Libmount_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "9c30530bf0effd46e15e0fdcf2b8636e78cbbd73"
uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9"
version = "2.35.0+0"

[[Libtiff_jll]]
deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Pkg", "Zlib_jll", "Zstd_jll"]
git-tree-sha1 = "340e257aada13f95f98ee352d316c3bed37c8ab9"
uuid = "89763e89-9b03-5906-acba-b20f662cd828"
version = "4.3.0+0"

[[Libuuid_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "7f3efec06033682db852f8b3bc3c1d2b0a0ab066"
uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700"
version = "2.36.0+0"

[[LinearAlgebra]]
deps = ["Libdl"]
uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"

[[LogExpFunctions]]
deps = ["ChainRulesCore", "DocStringExtensions", "IrrationalConstants", "LinearAlgebra"]
git-tree-sha1 = "34dc30f868e368f8a17b728a1238f3fcda43931a"
uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688"
version = "0.3.3"

[[Logging]]
uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"

[[MacroTools]]
deps = ["Markdown", "Random"]
git-tree-sha1 = "5a5bc6bf062f0f95e62d0fe0a2d99699fed82dd9"
uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
version = "0.5.8"

[[Markdown]]
deps = ["Base64"]
uuid = "d6f4376e-aef5-505a-96c1-9c027394607a"

[[MbedTLS]]
deps = ["Dates", "MbedTLS_jll", "Random", "Sockets"]
git-tree-sha1 = "1c38e51c3d08ef2278062ebceade0e46cefc96fe"
uuid = "739be429-bea8-5141-9913-cc70e7f3736d"
version = "1.0.3"

[[MbedTLS_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1"

[[Measures]]
git-tree-sha1 = "e498ddeee6f9fdb4551ce855a46f54dbd900245f"
uuid = "442fdcdd-2543-5da2-b0f3-8c86c306513e"
version = "0.3.1"

[[Missings]]
deps = ["DataAPI"]
git-tree-sha1 = "bf210ce90b6c9eed32d25dbcae1ebc565df2687f"
uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28"
version = "1.0.2"

[[Mmap]]
uuid = "a63ad114-7e13-5084-954f-fe012c677804"

[[MozillaCACerts_jll]]
uuid = "14a3606d-f60d-562e-9121-12d972cd8159"

[[NaNMath]]
git-tree-sha1 = "bfe47e760d60b82b66b61d2d44128b62e3a369fb"
uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3"
version = "0.3.5"

[[NetworkOptions]]
uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908"

[[Ogg_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "7937eda4681660b4d6aeeecc2f7e1c81c8ee4e2f"
uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051"
version = "1.3.5+0"

[[OpenLibm_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "05823500-19ac-5b8b-9628-191a04bc5112"

[[OpenSSL_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "15003dcb7d8db3c6c857fda14891a539a8f2705a"
uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95"
version = "1.1.10+0"

[[OpenSpecFun_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "13652491f6856acfd2db29360e1bbcd4565d04f1"
uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e"
version = "0.5.5+0"

[[Opus_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "51a08fb14ec28da2ec7a927c4337e4332c2a4720"
uuid = "91d4177d-7536-5919-b921-800302f37372"
version = "1.3.2+0"

[[OrderedCollections]]
git-tree-sha1 = "85f8e6578bf1f9ee0d11e7bb1b1456435479d47c"
uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
version = "1.4.1"

[[PCRE_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "b2a7af664e098055a7529ad1a900ded962bca488"
uuid = "2f80f16e-611a-54ab-bc61-aa92de5b98fc"
version = "8.44.0+0"

[[PDMats]]
deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"]
git-tree-sha1 = "4dd403333bcf0909341cfe57ec115152f937d7d8"
uuid = "90014a1f-27ba-587c-ab20-58faa44d9150"
version = "0.11.1"

[[Parsers]]
deps = ["Dates"]
git-tree-sha1 = "9d8c00ef7a8d110787ff6f170579846f776133a9"
uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
version = "2.0.4"

[[Pipe]]
git-tree-sha1 = "6842804e7867b115ca9de748a0cf6b364523c16d"
uuid = "b98c9c47-44ae-5843-9183-064241ee97a0"
version = "1.3.0"

[[Pixman_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "b4f5d02549a10e20780a24fce72bea96b6329e29"
uuid = "30392449-352a-5448-841d-b1acce4e97dc"
version = "0.40.1+0"

[[Pkg]]
deps = ["Artifacts", "Dates", "Downloads", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"]
uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"

[[PlotThemes]]
deps = ["PlotUtils", "Requires", "Statistics"]
git-tree-sha1 = "a3a964ce9dc7898193536002a6dd892b1b5a6f1d"
uuid = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a"
version = "2.0.1"

[[PlotUtils]]
deps = ["ColorSchemes", "Colors", "Dates", "Printf", "Random", "Reexport", "Statistics"]
git-tree-sha1 = "2537ed3c0ed5e03896927187f5f2ee6a4ab342db"
uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043"
version = "1.0.14"

[[Plots]]
deps = ["Base64", "Contour", "Dates", "Downloads", "FFMPEG", "FixedPointNumbers", "GR", "GeometryBasics", "JSON", "Latexify", "LinearAlgebra", "Measures", "NaNMath", "PlotThemes", "PlotUtils", "Printf", "REPL", "Random", "RecipesBase", "RecipesPipeline", "Reexport", "Requires", "Scratch", "Showoff", "SparseArrays", "Statistics", "StatsBase", "UUIDs"]
git-tree-sha1 = "457b13497a3ea4deb33d273a6a5ea15c25c0ebd9"
uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
version = "1.22.2"

[[PlutoUI]]
deps = ["Base64", "Dates", "HypertextLiteral", "InteractiveUtils", "JSON", "Logging", "Markdown", "Random", "Reexport", "Suppressor"]
git-tree-sha1 = "26b4d16873562469a0a1e6ae41d90dec9e51286d"
uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8"
version = "0.7.10"

[[PooledArrays]]
deps = ["DataAPI", "Future"]
git-tree-sha1 = "a193d6ad9c45ada72c14b731a318bedd3c2f00cf"
uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720"
version = "1.3.0"

[[Preferences]]
deps = ["TOML"]
git-tree-sha1 = "00cfd92944ca9c760982747e9a1d0d5d86ab1e5a"
uuid = "21216c6a-2e73-6563-6e65-726566657250"
version = "1.2.2"

[[PrettyTables]]
deps = ["Crayons", "Formatting", "Markdown", "Reexport", "Tables"]
git-tree-sha1 = "0d1245a357cc61c8cd61934c07447aa569ff22e6"
uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d"
version = "1.1.0"

[[Printf]]
deps = ["Unicode"]
uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"

[[Qt5Base_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "xkbcommon_jll"]
git-tree-sha1 = "ad368663a5e20dbb8d6dc2fddeefe4dae0781ae8"
uuid = "ea2cea3b-5b76-57ae-a6ef-0a8af62496e1"
version = "5.15.3+0"

[[QuadGK]]
deps = ["DataStructures", "LinearAlgebra"]
git-tree-sha1 = "78aadffb3efd2155af139781b8a8df1ef279ea39"
uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc"
version = "2.4.2"

[[REPL]]
deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"]
uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"

[[Random]]
deps = ["Serialization"]
uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"

[[RecipesBase]]
git-tree-sha1 = "44a75aa7a527910ee3d1751d1f0e4148698add9e"
uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
version = "1.1.2"

[[RecipesPipeline]]
deps = ["Dates", "NaNMath", "PlotUtils", "RecipesBase"]
git-tree-sha1 = "7ad0dfa8d03b7bcf8c597f59f5292801730c55b8"
uuid = "01d81517-befc-4cb6-b9ec-a95719d0359c"
version = "0.4.1"

[[Reexport]]
git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b"
uuid = "189a3867-3050-52da-a836-e630ba90ab69"
version = "1.2.2"

[[Requires]]
deps = ["UUIDs"]
git-tree-sha1 = "4036a3bd08ac7e968e27c203d45f5fff15020621"
uuid = "ae029012-a4dd-5104-9daa-d747884805df"
version = "1.1.3"

[[Rmath]]
deps = ["Random", "Rmath_jll"]
git-tree-sha1 = "bf3188feca147ce108c76ad82c2792c57abe7b1f"
uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa"
version = "0.7.0"

[[Rmath_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "68db32dff12bb6127bac73c209881191bf0efbb7"
uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f"
version = "0.3.0+0"

[[SHA]]
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"

[[Scratch]]
deps = ["Dates"]
git-tree-sha1 = "0b4b7f1393cff97c33891da2a0bf69c6ed241fda"
uuid = "6c6a2e73-6563-6170-7368-637461726353"
version = "1.1.0"

[[SentinelArrays]]
deps = ["Dates", "Random"]
git-tree-sha1 = "54f37736d8934a12a200edea2f9206b03bdf3159"
uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c"
version = "1.3.7"

[[Serialization]]
uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"

[[SharedArrays]]
deps = ["Distributed", "Mmap", "Random", "Serialization"]
uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383"

[[ShiftedArrays]]
git-tree-sha1 = "22395afdcf37d6709a5a0766cc4a5ca52cb85ea0"
uuid = "1277b4bf-5013-50f5-be3d-901d8477a67a"
version = "1.0.0"

[[Showoff]]
deps = ["Dates", "Grisu"]
git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de"
uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f"
version = "1.0.3"

[[Sockets]]
uuid = "6462fe0b-24de-5631-8697-dd941f90decc"

[[SortingAlgorithms]]
deps = ["DataStructures"]
git-tree-sha1 = "b3363d7460f7d098ca0912c69b082f75625d7508"
uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c"
version = "1.0.1"

[[SparseArrays]]
deps = ["LinearAlgebra", "Random"]
uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"

[[SpecialFunctions]]
deps = ["ChainRulesCore", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"]
git-tree-sha1 = "ad42c30a6204c74d264692e633133dcea0e8b14e"
uuid = "276daf66-3868-5448-9aa4-cd146d93841b"
version = "1.6.2"

[[StaticArrays]]
deps = ["LinearAlgebra", "Random", "Statistics"]
git-tree-sha1 = "3240808c6d463ac46f1c1cd7638375cd22abbccb"
uuid = "90137ffa-7385-5640-81b9-e52037218182"
version = "1.2.12"

[[Statistics]]
deps = ["LinearAlgebra", "SparseArrays"]
uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"

[[StatsAPI]]
git-tree-sha1 = "1958272568dc176a1d881acb797beb909c785510"
uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0"
version = "1.0.0"

[[StatsBase]]
deps = ["DataAPI", "DataStructures", "LinearAlgebra", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"]
git-tree-sha1 = "8cbbc098554648c84f79a463c9ff0fd277144b6c"
uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
version = "0.33.10"

[[StatsFuns]]
deps = ["ChainRulesCore", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"]
git-tree-sha1 = "46d7ccc7104860c38b11966dd1f72ff042f382e4"
uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c"
version = "0.9.10"

[[StatsModels]]
deps = ["DataAPI", "DataStructures", "LinearAlgebra", "Printf", "REPL", "ShiftedArrays", "SparseArrays", "StatsBase", "StatsFuns", "Tables"]
git-tree-sha1 = "1bc8cc83e458c8a5036ec7206a04d749b9729fe8"
uuid = "3eaba693-59b7-5ba5-a881-562e759f1c8d"
version = "0.6.26"

[[StructArrays]]
deps = ["Adapt", "DataAPI", "StaticArrays", "Tables"]
git-tree-sha1 = "2ce41e0d042c60ecd131e9fb7154a3bfadbf50d3"
uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a"
version = "0.6.3"

[[SuiteSparse]]
deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"]
uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9"

[[Suppressor]]
git-tree-sha1 = "a819d77f31f83e5792a76081eee1ea6342ab8787"
uuid = "fd094767-a336-5f1f-9728-57cf17d0bbfb"
version = "0.2.0"

[[TOML]]
deps = ["Dates"]
uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76"

[[TableTraits]]
deps = ["IteratorInterfaceExtensions"]
git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39"
uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c"
version = "1.0.1"

[[Tables]]
deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "TableTraits", "Test"]
git-tree-sha1 = "1162ce4a6c4b7e31e0e6b14486a6986951c73be9"
uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
version = "1.5.2"

[[Tar]]
deps = ["ArgTools", "SHA"]
uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e"

[[Test]]
deps = ["InteractiveUtils", "Logging", "Random", "Serialization"]
uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[[TranscodingStreams]]
deps = ["Random", "Test"]
git-tree-sha1 = "216b95ea110b5972db65aa90f88d8d89dcb8851c"
uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa"
version = "0.9.6"

[[URIs]]
git-tree-sha1 = "97bbe755a53fe859669cd907f2d96aee8d2c1355"
uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4"
version = "1.3.0"

[[UUIDs]]
deps = ["Random", "SHA"]
uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"

[[Unicode]]
uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"

[[Wayland_jll]]
deps = ["Artifacts", "Expat_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg", "XML2_jll"]
git-tree-sha1 = "3e61f0b86f90dacb0bc0e73a0c5a83f6a8636e23"
uuid = "a2964d1f-97da-50d4-b82a-358c7fce9d89"
version = "1.19.0+0"

[[Wayland_protocols_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Wayland_jll"]
git-tree-sha1 = "2839f1c1296940218e35df0bbb220f2a79686670"
uuid = "2381bf8a-dfd0-557d-9999-79630e7b1b91"
version = "1.18.0+4"

[[WeakRefStrings]]
deps = ["DataAPI", "Parsers"]
git-tree-sha1 = "4a4cfb1ae5f26202db4f0320ac9344b3372136b0"
uuid = "ea10d353-3f73-51f8-a26c-33c1cb351aa5"
version = "1.3.0"

[[XML2_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "Zlib_jll"]
git-tree-sha1 = "1acf5bdf07aa0907e0a37d3718bb88d4b687b74a"
uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a"
version = "2.9.12+0"

[[XSLT_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "Pkg", "XML2_jll", "Zlib_jll"]
git-tree-sha1 = "91844873c4085240b95e795f692c4cec4d805f8a"
uuid = "aed1982a-8fda-507f-9586-7b0439959a61"
version = "1.1.34+0"

[[Xorg_libX11_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libxcb_jll", "Xorg_xtrans_jll"]
git-tree-sha1 = "5be649d550f3f4b95308bf0183b82e2582876527"
uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc"
version = "1.6.9+4"

[[Xorg_libXau_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "4e490d5c960c314f33885790ed410ff3a94ce67e"
uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec"
version = "1.0.9+4"

[[Xorg_libXcursor_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"]
git-tree-sha1 = "12e0eb3bc634fa2080c1c37fccf56f7c22989afd"
uuid = "935fb764-8cf2-53bf-bb30-45bb1f8bf724"
version = "1.2.0+4"

[[Xorg_libXdmcp_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "4fe47bd2247248125c428978740e18a681372dd4"
uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05"
version = "1.1.3+4"

[[Xorg_libXext_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"]
git-tree-sha1 = "b7c0aa8c376b31e4852b360222848637f481f8c3"
uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3"
version = "1.3.4+4"

[[Xorg_libXfixes_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"]
git-tree-sha1 = "0e0dc7431e7a0587559f9294aeec269471c991a4"
uuid = "d091e8ba-531a-589c-9de9-94069b037ed8"
version = "5.0.3+4"

[[Xorg_libXi_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXfixes_jll"]
git-tree-sha1 = "89b52bc2160aadc84d707093930ef0bffa641246"
uuid = "a51aa0fd-4e3c-5386-b890-e753decda492"
version = "1.7.10+4"

[[Xorg_libXinerama_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll"]
git-tree-sha1 = "26be8b1c342929259317d8b9f7b53bf2bb73b123"
uuid = "d1454406-59df-5ea1-beac-c340f2130bc3"
version = "1.1.4+4"

[[Xorg_libXrandr_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll"]
git-tree-sha1 = "34cea83cb726fb58f325887bf0612c6b3fb17631"
uuid = "ec84b674-ba8e-5d96-8ba1-2a689ba10484"
version = "1.5.2+4"

[[Xorg_libXrender_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"]
git-tree-sha1 = "19560f30fd49f4d4efbe7002a1037f8c43d43b96"
uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa"
version = "0.9.10+4"

[[Xorg_libpthread_stubs_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "6783737e45d3c59a4a4c4091f5f88cdcf0908cbb"
uuid = "14d82f49-176c-5ed1-bb49-ad3f5cbd8c74"
version = "0.1.0+3"

[[Xorg_libxcb_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "XSLT_jll", "Xorg_libXau_jll", "Xorg_libXdmcp_jll", "Xorg_libpthread_stubs_jll"]
git-tree-sha1 = "daf17f441228e7a3833846cd048892861cff16d6"
uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b"
version = "1.13.0+3"

[[Xorg_libxkbfile_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"]
git-tree-sha1 = "926af861744212db0eb001d9e40b5d16292080b2"
uuid = "cc61e674-0454-545c-8b26-ed2c68acab7a"
version = "1.1.0+4"

[[Xorg_xcb_util_image_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"]
git-tree-sha1 = "0fab0a40349ba1cba2c1da699243396ff8e94b97"
uuid = "12413925-8142-5f55-bb0e-6d7ca50bb09b"
version = "0.4.0+1"

[[Xorg_xcb_util_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libxcb_jll"]
git-tree-sha1 = "e7fd7b2881fa2eaa72717420894d3938177862d1"
uuid = "2def613f-5ad1-5310-b15b-b15d46f528f5"
version = "0.4.0+1"

[[Xorg_xcb_util_keysyms_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"]
git-tree-sha1 = "d1151e2c45a544f32441a567d1690e701ec89b00"
uuid = "975044d2-76e6-5fbe-bf08-97ce7c6574c7"
version = "0.4.0+1"

[[Xorg_xcb_util_renderutil_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"]
git-tree-sha1 = "dfd7a8f38d4613b6a575253b3174dd991ca6183e"
uuid = "0d47668e-0667-5a69-a72c-f761630bfb7e"
version = "0.3.9+1"

[[Xorg_xcb_util_wm_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"]
git-tree-sha1 = "e78d10aab01a4a154142c5006ed44fd9e8e31b67"
uuid = "c22f9ab0-d5fe-5066-847c-f4bb1cd4e361"
version = "0.4.1+1"

[[Xorg_xkbcomp_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libxkbfile_jll"]
git-tree-sha1 = "4bcbf660f6c2e714f87e960a171b119d06ee163b"
uuid = "35661453-b289-5fab-8a00-3d9160c6a3a4"
version = "1.4.2+4"

[[Xorg_xkeyboard_config_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xkbcomp_jll"]
git-tree-sha1 = "5c8424f8a67c3f2209646d4425f3d415fee5931d"
uuid = "33bec58e-1273-512f-9401-5d533626f822"
version = "2.27.0+4"

[[Xorg_xtrans_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "79c31e7844f6ecf779705fbc12146eb190b7d845"
uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10"
version = "1.4.0+3"

[[Zlib_jll]]
deps = ["Libdl"]
uuid = "83775a58-1f1d-513f-b197-d71354ab007a"

[[Zstd_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "cc4bf3fdde8b7e3e9fa0351bdeedba1cf3b7f6e6"
uuid = "3161d3a3-bdf6-5164-811a-617609db77b4"
version = "1.5.0+0"

[[libass_jll]]
deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
git-tree-sha1 = "5982a94fcba20f02f42ace44b9894ee2b140fe47"
uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0"
version = "0.15.1+0"

[[libfdk_aac_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "daacc84a041563f965be61859a36e17c4e4fcd55"
uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280"
version = "2.0.2+0"

[[libpng_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
git-tree-sha1 = "94d180a6d2b5e55e447e2d27a29ed04fe79eb30c"
uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f"
version = "1.6.38+0"

[[libvorbis_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"]
git-tree-sha1 = "c45f4e40e7aafe9d086379e5578947ec8b95a8fb"
uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a"
version = "1.3.7+0"

[[nghttp2_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d"

[[p7zip_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0"

[[x264_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "4fea590b89e6ec504593146bf8b988b2c00922b2"
uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a"
version = "2021.5.5+0"

[[x265_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "ee567a171cce03570d77ad3a43e90218e38937a9"
uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76"
version = "3.5.0+0"

[[xkbcommon_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Wayland_jll", "Wayland_protocols_jll", "Xorg_libxcb_jll", "Xorg_xkeyboard_config_jll"]
git-tree-sha1 = "ece2350174195bb31de1a63bea3a41ae1aa593b6"
uuid = "d8fb68d0-12a3-5cfd-a85a-d49703b185fd"
version = "0.9.1+5"
"""

# ╔═╡ Cell order:
# ╟─3148423c-7fce-4fd0-b44a-b9ec82641b75
# ╟─d0492b8b-64f2-47e1-8afb-6b14d5ddb322
# ╟─36a7677b-d589-42a8-a45d-28c133b5b94b
# ╟─8d71ed8d-3022-4f6c-83ad-b75b56b1b121
# ╟─02376d65-c884-45a2-8537-27896d5994fd
# ╟─a2914ab7-2048-46ab-abaf-5e4604a94eb2
# ╟─b54c9ef9-cae8-4f0e-a152-0d24686ad8e0
# ╟─9c49c542-d813-47cd-bfa4-2fcfa78f2267
# ╟─b6c11ebe-d1d6-47fe-86e8-2047cd61ef03
# ╟─3aea3c3e-fb5e-4deb-a33f-7fdd92bb08cc
# ╟─b1e164c2-712e-4b7f-863c-5779b97afd1e
# ╟─c38e1222-43f7-4564-a7f7-ddaee168e499
# ╟─c524c211-5426-43f8-8770-f1686f33b150
# ╟─9dbeecc0-d149-4bc6-a625-04516050c8a7
# ╠═76b8ca26-b868-4ff4-991f-d93c142284d2
# ╟─46add8a1-913d-4d83-bc3d-491dcd72e0a6
# ╟─786411b0-0191-4e67-830b-cfb8ad5d04cd
# ╟─47f2b4f9-1062-4f1e-b33e-c1b54189d250
# ╠═ec4e5ea3-1234-4425-9311-37278392cb51
# ╠═5f4469a1-8917-43f2-bf54-a63b070e8f28
# ╠═aadb4b5a-94f1-4909-a806-0345efb62b71
# ╠═fadd14f1-7b6a-453f-b6d6-0d3e8e5c78f8
# ╠═667297fc-2bf2-4842-9cb8-ca60a6e27bdc
# ╠═db49e131-f5b3-4c48-b97b-50f362c4d343
# ╠═86513f98-152a-4d0d-ae07-4c85689d24ab
# ╠═d820af77-e19a-42b1-86b2-a2ec0a06cc78
# ╠═005d7a08-728b-44c3-9d1a-8e5eb2a87b2b
# ╟─4d74b0b1-c4a4-48af-b9d7-e87d2974b0d9
# ╟─b280a3f3-058b-4e7e-9a30-086b88782a2b
# ╟─34110910-2f87-44b4-b028-74f8972f92be
# ╟─a5a8db8b-c14d-4e0d-8102-a367bc7a022b
# ╠═49a5a52e-6652-4724-a758-de45db08377d
# ╟─ab8b326b-ad96-445e-97d6-5dd8ab68f224
# ╠═92c4155d-c639-4ce8-97e5-9f8bb68ba57c
# ╟─e2deac36-9b92-492d-ac61-502d9714aed2
# ╟─69e31dcc-788a-443e-8532-a69463b470a3
# ╠═50c71109-7918-4ffb-a902-bf9c214c4ee2
# ╠═19d0923c-0450-4007-b8d7-76ec0064a1bb
# ╠═702e85a8-fc89-45bc-8ce2-3cb178eda547
# ╠═65b1bf77-6c35-4b5f-831c-9907829abb70
# ╠═a166d57d-2723-40f2-97a7-e9678d1e3bec
# ╟─44c4ef27-73db-4c87-9cf9-4e3709290cdd
# ╠═05885122-92e3-4052-97fd-6ec815c65e65
# ╟─43f89505-4af3-4a1e-a967-2b92eebb0768
# ╠═546c55ce-be0c-44a1-9f0c-f842d0a9896b
# ╠═9a77d594-9bfe-4988-9387-91b924b30f5d
# ╠═b1d1ad9f-0f02-474b-9177-2d8d0965fac9
# ╠═a9d9fd7d-bc16-48ca-be19-eeb4cbeca899
# ╟─66ab70b5-115b-4e48-9b9c-5c768e4869a5
# ╠═4bc28463-9036-4a3f-bd40-4717334ca1d0
# ╠═817f78d9-24f2-4a6c-aaef-0190a0a5b5a8
# ╠═2152c4d4-35ab-4f06-83d5-4c882a3d3e0a
# ╠═027246a1-2393-49d2-9abe-f7a39c0ff4b9
# ╟─a9e2e3ee-c5d8-4481-94cd-1e7745d1bba9
# ╠═0d53f235-4180-4df3-b123-8dd3eb240f4c
# ╠═f542b846-dc76-421a-9cf1-ef55ddaf4535
# ╟─f72433f1-2411-4c7a-b804-c0485380d444
# ╠═1aae1226-15f0-4f35-8a44-918ab3f2c005
# ╠═824b0730-4129-4473-b02d-47a120076d41
# ╠═3f511575-ec35-4823-97de-17e4609aa271
# ╟─df72b3dc-5cb5-4b2b-a4cc-9d269764346d
# ╟─207a52a3-9e8f-4df3-9e40-eb3fea3cbc78
# ╠═9cb98725-c250-4bb4-b7b3-dbd4f49478a1
# ╟─26a8bea8-235e-48b6-b685-3ef6270d1801
# ╟─042388ff-6c79-4309-a32d-3775688c2557
# ╠═50194e91-5b5f-470d-a558-e6a4388e0015
# ╟─961a68ba-a800-4e86-be66-e05b4557cb9f
# ╠═c37c22cb-baef-43af-905c-8124d88de9c4
# ╟─f5afaa88-616a-4643-9db3-ff12be4c2a9c
# ╟─9c338a22-8939-409c-ac89-9fc0acd2cc6c
# ╠═35890f54-ea48-4cca-acb6-1e9b803f2afc
# ╠═ce6d98ab-cad1-46cc-aef5-f1b85fad8f14
# ╟─ed271d15-c42e-4083-b768-50b5d77ef578
# ╟─36cfc0cd-adb3-427d-a445-a400f8084090
# ╠═01a404b1-d941-42f7-b5ce-d7f6684970d3
# ╠═e3127bbf-c246-4eec-8480-4592ce071cee
# ╠═3923b173-0f94-4de2-8112-907cc479aaf1
# ╠═29388df7-db60-43c2-962a-447cae593500
# ╠═a28039e8-f3f6-44ad-826e-4474375309b7
# ╟─f3549035-c80c-4b98-9c2b-f93c3bb1c7b4
# ╠═45201cfb-a31e-4740-bd82-4541ebc3a86b
# ╠═965a1f3f-8c35-4488-8ed3-41cdcdb2cc3b
# ╠═a340487e-afa0-428e-87eb-a0cd89ef8cc0
# ╟─c435caf9-2232-4969-becc-796ef77a7c8c
# ╠═7ceb96ae-42f8-4361-a56d-635b90a3ec20
# ╟─d8a0fbb1-3d60-4b75-883b-b843327ce2d9
# ╟─0c189181-d0f8-4059-b673-485769d8b80e
# ╟─3bc6de1f-eb5b-4e45-b616-23bb8d5a75cc
# ╠═3ea0f8a1-4114-41b1-adba-ced5fce99d7c
# ╠═70a746fd-29e3-409a-908f-abcd5a495498
# ╠═2d21d130-7eb7-412d-9234-e144e52719a8
# ╠═99aab59e-6978-4dfe-a121-5ae8e06f7ed0
# ╠═276dd17a-3cb5-4ecf-832d-0087d7ec5ee4
# ╠═c61b42a3-a94f-4973-90a5-e8eb276de56a
# ╠═0741c318-2807-4c37-a524-1f8d03e1b6c5
# ╠═bc7d1235-4db5-4275-8807-0257dac2d1a8
# ╠═c6308cea-6719-4183-b418-2ad2f16bfc52
# ╠═f769acf5-5972-4362-87ce-2d33a0aa1bc2
# ╟─00000000-0000-0000-0000-000000000001
# ╟─00000000-0000-0000-0000-000000000002