text:
function maketable6(panel::DataFrame; trialrunonly::Bool=trialrunonly,
    )::Nothing
  #load the data we will work with
  #panel::DataFrame = constructportfolios(refreshportfolios=false, trialrunonly=trialrunonly)
  sort!(panel, [:permno, :date])

  ################common data

  ###################PANEL A############
  T6_PANEL_A_ROWKEYS::Vector{Symbol} = [:baseline,
    :bknegcash,
    :mknegcash,
    :Dbkflev,
    :Dmkflev,
    :Dbkliab,
    :Dmkliab,
    :Dbknegcash,
    :Dmknegcash]
  T6_PANEL_A_ROWGROUPNAME::Dict = Dict(
    :baseline=>:baseline,
    :bknegcash => :P_bknegcash,
    :mknegcash => :P_mknegcash,
    :Dbkflev => :P_Dbkflev,
    :Dmkflev => :P_Dmkflev,
    :Dbkliab => :P_Dbkliab,
    :Dmkliab => :P_Dmkliab,
    :Dbknegcash => :P_Dbknegcash,
    :Dmknegcash => :P_Dmknegcash,)

  T6_PANEL_A_ROWLABEL::Dict = Dict(
    :baseline=>"none",
    :bknegcash=>"\\midrule bknegcash",
    :mknegcash=>"mknegcash",
    :Dbkflev=>"\\midrule\$\\Delta\$bkflev",
    :Dmkflev=>"\$\\Delta\$mkflev",
    :Dbkliab=>"\$\\Delta\$bkliab",
    :Dmkliab=>"\$\\Delta\$mkliab",
    :Dbknegcash=>"\$\\Delta\$bknegcash",
    :Dmknegcash=>"\$\\Delta\$mknegcash",)

  ALL_ROW_FOCALS::Vector{Symbol} = [:mkt, :P_ff5_smb,	:P_ff5_hml,	:P_ff5_rmw,	:P_ff5_cma, :P_ff3m_umd]
  T6_PANEL_A_TEST_FOCALS::Vector{Symbol} = [:P_bknegcash, :P_mknegcash, :P_Dmknegcash,
    :P_Dbknegcash, :P_Dmkflev, :P_Dbkflev, :P_Dmkliab, :P_Dbkliab]

  T6_PANEL_A_NAME::String = "t6panela-$(REPLICATION_TYPE[])-$(OUT_SUFFIX[])"

  T6_PANEL_A_MIN_ROWS::Int = 24
  T6_PANEL_A_COLKEYS = [:stat, :ret, :mkt, :P_ff5_hml, :P_ff5_smb,	:P_ff5_rmw,	:P_ff5_cma, :P_ff3m_umd]
  T6_PANEL_A_COLLABEL = Dict(
    :stat=>"stat",
    :ret=>"see left",
    :mkt=>"xmkt",
    :P_ff5_hml=>"hml",
    :P_ff5_smb=>"smb",
    :P_ff5_rmw=>"rmw",
    :P_ff5_cma=>"cma",
    :P_ff3m_umd=>"umd")

  table6panela(panel,
    rowgroupname = T6_PANEL_A_ROWGROUPNAME,
    rowkeys=T6_PANEL_A_ROWKEYS,
    rowlabel=T6_PANEL_A_ROWLABEL,
    collabel=T6_PANEL_A_COLLABEL,
    testfocals=T6_PANEL_A_TEST_FOCALS,
    tablename=T6_PANEL_A_NAME,
    minrowspergroup = T6_PANEL_A_MIN_ROWS,
    allrowfocals = ALL_ROW_FOCALS,
    colkeys = T6_PANEL_A_COLKEYS
  )

  return nothing
end

function table6panela(panel::DataFrame;
    rowgroupname::Dict= error("portname is required"),
    rowkeys::Vector{Symbol} = error("rowkeys is required"),
    rowlabel::Dict = error("rowlabel is required"),
    colkeys::Vector{Symbol} = error("colkeys is required"),
    collabel::Dict = error("collabel is required"),
    testfocals::Vector{Symbol} = error("testfocals is required"),
    tablename::String = error("table name is required"),
    tablepath::String = TABLE_PATH,
    decimals::Int = DEFAULT_DECIMALS,
    minrowspergroup::Int = error("minrowspergroup is required"),
    allrowfocals::Vector{Symbol} = error("allrowfocals is required"))

  local parallel::Bool = PARALLEL[] && (!DISABLE_FM_PARALLEL)

  #################################
  #build a small  panel of portfolios
  allcols::Vector{Symbol} = [:date; allrowfocals; testfocals]
  minipanel::DataFrame = unique(panel[!, allcols])
  idcols::Vector{Symbol} = setdiff(allcols, testfocals)
  minipanel = stack(minipanel, testfocals, idcols, variable_name = :portname, value_name = :ret)
  minipanel.portname = (Symbol).(Vector{String}(minipanel.portname))
  sort!(minipanel, [:portname, :date])

  #make the regression specifications
  fs::FactorSpecification = FactorSpecification(minipanel, :ret, :date, :portname,
    Ffactors = allrowfocals,
    Fcharacteristics=nothing,
    Fcontrols = Vector{Symbol}(),
    name=Symbol("t6"),
    skipcrosssectiondfcheck=true,
    minrowspergroup=minrowspergroup)

  frindex::Dict = BJSFF(fs)
  #println(keys(frindex))

  #now build the table
  Ncols::Int = length(colkeys)
  Nrows::Int = length(rowkeys) * 3
  colnames::Vector{Vector{String}} = [(colkey->collabel[colkey]).(colkeys)]
  colidx::Dict = Dict(colkey=>i for (i,colkey) ∈ enumerate(colkeys))

  desccontent::Vector{Vector{String}} = (i->Vector{String}(undef, Ncols)).(1:Nrows)
  descrownames::Vector{String} = Vector{String}(undef, Nrows)

  #now populate the the table
  for (i,rowkey) ∈ enumerate(rowkeys)
    local r::Int = (i-1)*3 + 1 #gets the row index
    descrownames[r] = rowlabel[rowkey]
    descrownames[r+1] = ""
    descrownames[r+2] = ""

    desccontent[r][colidx[:stat]] = "\\text{alpha}"
    desccontent[r+1][colidx[:stat]] = "\\text{T(alpha)}"
    desccontent[r+2][colidx[:stat]] = "\\text{\$R^2\$ \\%}"

    #now get the core content
    for (c,colkey) ∈ enumerate(colkeys)
      #a couple of special cases where the fr object doesn't provide any content
      (colkey == :stat) && continue
      if (rowkey == :baseline) && (colkey == :ret)
        desccontent[r][colidx[colkey]] = ""
        desccontent[r+1][colidx[colkey]] = ""
        desccontent[r+2][colidx[colkey]] = ""
        continue
      end

      frkey::Symbol = Symbol("$(rowgroupname[rowkey])_col$(colkey)")
      fr::FactorRegression = frindex[frkey]
      αidx::Int = fr.coefidx[:intercept]

      #pull the content
      α::Float64 = fr.λᵢ[αidx]
      t::Float64 = fr.λᵢ[αidx] / fr.σᵢ[αidx]
      αR²::Float64 = fr.otherstats[:R²]

      desccontent[r][colidx[colkey]] = brnum(α*100, decimals)
      desccontent[r+1][colidx[colkey]] = brnum(t, decimals)
      desccontent[r+2][colidx[colkey]] = brnum(αR²*100, 0)
    end
  end
  alignmentstring::String = "ll rrrrrrr"

  #display(desccontent)
  #construct the tex table
  tt::String = textable(colnames=colnames,
    descrownames=descrownames,
    desccontent=desccontent,
    alignmentstring=alignmentstring)

  writetextable(tt, path=tablepath, outname="$tablename.tex")
end

max_stars_repo_name: clintonTE/CCA

max_issues_repo_name: clintonTE/CCA

max_forks_repo_name: clintonTE/CCA


text:
using LinearAlgebra: norm, dot, cross
using Statistics: mean
using MeshCore: IncRel, indextype, nshapes, attribute, nentities, nrelations, manifdim, n1storderv

"""
    eselect(ir::IncRel; kwargs...)

Select finite elements.

# Arguments
- `ir` = incidence relation representing finite element set `(d, 0)`. The
  "elements" are the shapes on the left of the incidence relation.
- `kwargs` = keyword arguments to specify the selection criteria

## Selection criteria

### facing
Select all "boundary" elements that "face" a certain direction.
```
exteriorbfl = eselect(ir, facing=true, direction=x -> [1.0, 1.0, 0.0]);
```
or
```
exteriorbfl = eselect(ir, facing=true, direction=xyz -> xyz/norm(xyz), dotmin = 0.99);
```
where `xyz` is the location of the centroid  of  a boundary element.
Here the finite element is considered "facing" in the given direction if the dot
product of its normal and the direction vector is greater than `dotmin`.
The default value for `dotmin` is 0.01 (this corresponds to  almost 90 degrees
between the normal to the finite element  and the given direction).

This selection method makes sense only for elements that are  surface-like (i. e.
for boundary meshes).

### label
Select elements based on their label.
```
rl1 = eselect(ir, label=1)
```

### box, distance
Select elements based on some criteria that their nodes satisfy.  See the
function `vselect()`.

Example:
Select all  elements whose nodes are closer than `R+inflate` from the point `from`.
```
linner = eselect(ir, distance = R, from = [0.0 0.0 0.0], inflate = tolerance)
```

Example:

```
exteriorbfl = eselect(ir, box=[1.0, 1.0, 0.0, pi/2, 0.0, Th], inflate=tolerance)
```
where `Th` is a variable.

### Optional keyword arguments
Should we consider the element only if all its nodes are in?
- `allin` = Boolean: if true, then all nodes of an element must satisfy the
  criterion; otherwise  one is enough.

# Output
- `felist` = list of finite elements (shapes) from the from the collection on
  the left of the incidence relation that satisfy the criteria
"""
function eselect(ir::IncRel; kwargs...)

    # Extract arguments
    allin = nothing; flood = nothing; facing = nothing; label = nothing;
    # nearestto = nothing; smoothpatch = nothing;
    startnode = 0; dotmin = 0.01
    overlappingbox = nothing
    for apair in pairs(kwargs)
        sy, val = apair
        if sy == :flood
            flood = val
        elseif sy == :facing
            facing = val
        elseif sy == :label
            label = val
        elseif sy == :overlappingbox
            overlappingbox = val
        elseif sy == :nearestto
            nearestto = val
        elseif sy == :allin
            allin = val
        end
    end

    if flood != nothing
        for apair in pairs(kwargs)
            sy, val = apair
            if sy == :startnode
                startnode = val
            end
        end
    end

    if facing != nothing
        facing = true;
        direction = nothing
        dotmin = 0.01;
        for apair in pairs(kwargs)
            sy, val = apair
            if sy == :direction
                direction = val
            elseif (sy == :dotmin) || (sy == :tolerance)# allow for obsolete keyword  to work
                dotmin = val
            end
        end
    end

    # The  elements of this array are flipped from zero  when the element satisfies
    # the search condition. This list is  eventually purged of the zero elements and
    # returned.
    felist = zeros(indextype(ir),nshapes(ir.left));

    #     Select based on fe label
    if label != nothing
        _label = attribute(ir.left, "label")
        for i in 1:nshapes(ir.left)
            if label == _label[i]
                felist[i] = i;   # matched this element
            end
        end
        return  felist[findall(x->x!=0, felist)]; # return the nonzero element numbers
    end

    # Select by flooding
    # if flood != nothing && (flood)
    #     @assert startnode > 0
    #     fen2fe = FENodeToFEMap(connasarray(fes), count(fens))
    #     felist = zeros(FInt, count(fes));
    #     pfelist = zeros(FInt, count(fes));
    #     felist[fen2fe.map[startnode]] .= 1;
    #     while true
    #         copyto!(pfelist, felist);
    #         markedl = findall(x -> x != 0, felist)
    #         for j = markedl
    #             for k = fes.conn[j]
    #                 felist[fen2fe.map[k]] .= 1;
    #             end
    #         end
    #         if sum(pfelist-felist) == 0 # If there are no more changes in this pass, we are done
    #             break;
    #         end
    #     end
    #     return findall(x -> x != 0, felist); # return the nonzero element numbers;
    # end

    # Helper function: calculate the normal to a boundary finite element
    function normal2d(c, locs, n1stov)
        t = locs[c[2]] - locs[c[1]]
        n = [t[2], -t[1]]
        return n/norm(n);
    end
    function normal3d(c, locs, n1stov)
        if n1stov == 3 # triangle
            v1 = locs[c[2]] - locs[c[1]]
            v2 = locs[c[3]] - locs[c[1]]
            n = cross(v1, v2)
            return n/norm(n);
        else
            v1 = locs[c[3]] - locs[c[1]]
            v2 = locs[c[4]] - locs[c[2]]
            n = cross(v1, v2)
            return n/norm(n);
        end
    end
    center(c, locs) = begin
        r = locs[c[1]]
        for i in 2:length(c)
            r += locs[c[i]]
        end
        return r  ./ length(c)
    end

    # Select by in which direction the normal of the fes face
    if (facing != nothing) && (facing)
        locs = attribute(ir.right, "geom")
        sdim = length(locs[1])
        mdim = manifdim(shapedesc(ir.left));
        @assert (mdim == sdim-1) "'Facing': only for Manifold dim. == Space dim.-1"
        n1stov = n1storderv(shapedesc(ir.left))
        @assert (mdim == 1) && (n1stov == 2) ||
                (mdim == 2) && ((n1stov == 2) || (n1stov == 3)) "'Facing': shapes with n1stov = $(n1stov)"
        normal = (mdim == 2) ? normal3d : normal2d
        for i in 1:nrelations(ir)
            c = ir[i]
            n = normal(c, locs, n1stov)
            d = direction(center(c, locs))
            d = d / norm(d)
            if (dot(vec(n),vec(d)) > dotmin)
                felist[i] = i;
            end
        end
        return  felist[findall(x->x!=0, felist)]; # return the nonzero element numbers
    end

    #  Default:   Select based on location of nodes
    #   Should we consider the element only if all its nodes are in?
    allinvalue = (allin == nothing) || ((allin != nothing) && (allin))
    # Select elements whose nodes are in the selected node list
    locs = attribute(ir.right, "geom")
    vlist = vselect(locs; kwargs...);
    allv = zeros(Bool, nshapes(ir.right));
    allv[vlist] .= true
    for i in 1:nrelations(ir)
        found = 0
        for nd in ir[i]
            if allv[nd]
                found = found + 1
            end
        end
        if allinvalue
            if found == nentities(ir, i)
                felist[i] = i;
            end
        else
            if found >= 1
                felist[i] = i;
            end
        end
    end
    return felist[findall(x -> x!=0, felist)]; # return the nonzero element numbers

end

ext: jl


text:
# parameters
mass_bin_name = ARGS[1]# "1540_1560"
tslice = "t1"
path_wavelist = "src"
path_to_working_folder = "data"

#########################################################
@show ARGS
push!(LOAD_PATH,"src")
using SDMHelper
using PWAHelper

const BmatFU = let

    println("1. load data")
    @time PsiFU = read_precalc_basis(
        joinpath(path_to_working_folder,"functions_$(mass_bin_name)_$(tslice)_fu.txt"));

    println("2. calculate sums")
    PsiTFU = transpose(PsiFU)
    @views v = sum(PsiTFU[:,e] * PsiTFU[:,e]' for e in 1:size(PsiTFU,2)) ./ size(PsiFU,1);
    conj(v)
    v
end

println("3. save the result")
write_cmatrix(BmatFU,
    joinpath(path_to_working_folder,"integrmat_$(mass_bin_name)_$(tslice)_fu.txt"))


text:
"""
    richardson(f, a; delta = 1e-9)
adalah fungsi yang digunakan untuk mencari nilai turunan `f` pada titik `a`
menggunakan formula ekstrapolasi Richardson. Secara default, digunakan nilai
toleransi `delta=1e-9`

# Examples
```jl
julia> sol,flag,err,D = richardson(sin,pi/3);

julia> sol
0.49999999999998856

julia> flag
0

julia> err
3.323475383787411e-10

julia> D
5×5 Array{Float64,2}:
 0.420735  0.0       0.0       0.0  0.0
 0.479426  0.498989  0.0       0.0  0.0
 0.494808  0.499935  0.499998  0.0  0.0
 0.498699  0.499996  0.5       0.5  0.0
 0.499675  0.5       0.5       0.5  0.5

julia> sol,flag,err,D = richardson(sin,pi/3,delta=1e-12);

julia> sol
0.5000000000000013

julia> flag
0

julia> err
1.27675647831893e-14

julia> D
6×6 Array{Float64,2}:
 0.420735  0.0       0.0       0.0  0.0  0.0
 0.479426  0.498989  0.0       0.0  0.0  0.0
 0.494808  0.499935  0.499998  0.0  0.0  0.0
 0.498699  0.499996  0.5       0.5  0.0  0.0
 0.499675  0.5       0.5       0.5  0.5  0.0
 0.499919  0.5       0.5       0.5  0.5  0.5
```
return solusi `sol` dengan `flag` bernilai 0 jika toleransi terpenuhi, `flag`
bernilai 1 jika maksimum iterasi tercapai. Serta, error `err` dan matriks `D`
yang berisi tabel ekstrapolasi Richardson.
"""
function richardson(f, a; delta = 1e-9)
  maxi = 50;
  flag = 1;
  h = 1;
  D = (f(a+h)-f(a-h))/(2*h);
  err = NaN;
  for j=1:maxi
    h = h/2;
    D = [D zeros(size(D,1),1);
		(f(a.+h).-f(a.-h))./(2*h) zeros(1, size(D,1))];
    for k = 1:j
      D[j+1,k+1] = D[j+1,k] + (D[j+1,k]-D[j,k])/(4^k-1);
    end
    err = abs(D[j+1,j+1]-D[j,j]);
    if err<delta
      flag=0;
      break
    end
  end
  sol = D[end,end];
  return sol, flag, err, D
end


text:
# Linear algebra functions not in the standard library.

export orthogonal, orthogonal!, pca, explained_variance, projection_distance

"""Return the angle between a and b"""
function Base.angle(a::AbstractVector, b::AbstractVector)
    length(a) == length(b) || throw(DimensionMismatch("a has dimension $(length(a)), but b has dimension $(length(b))"))
    acos(min(max(-1.0, dot(a, b) / norm(a) / norm(b)), 1.0))
end

"""return the angle between w and v, accounting for their sign"""
minangle(w, v) = min(angle(w, v), angle(w, -v))

"""
    pca(X::AbstractMatrix, k::Integer=min(size(X)...))

Compute the top `k` PCs of `X` via `LinearAlgebra.svd`. The columns of `X` correspond to samples and
the rows to features.
"""
function pca(X::AbstractMatrix, k::Integer=min(size(X)...))
    F = svd(X)
    return F.U[:, 1:k]
end

"""Orthogonalize and normalize the columns of A in-place."""
function orthogonal!(A::AbstractMatrix)
    m, n = size(A)
    for i in 1:n
        for j in 1:i-1
            l = dot(view(A, :, j), view(A, :, i))
            for k in 1:size(A, 1)
                A[k, i] -= l*A[k, j]
            end
        end
        g = norm(view(A, :, i))
        if g > sqrt(eps(eltype(A)) * size(A, 1))
            view(A, :, i) ./= g
        end
        replace!(view(A, :, i), NaN=>zero(eltype(A)))
    end
    return A
end

"""Orthogonalize and normalize the columns of A."""
orthogonal(A::AbstractMatrix) = orthogonal!(copy(A))

"""
    explained_variance(X, V, den)

Explained variance with pre-computed denominator.
"""
explained_variance(X, V, Xnorm::Real) = min((norm(X'*V) / Xnorm)^2, 1.0-eps(Float64))

"""
    explained_variance(X, V)

Return the fraction of variance explained by the principal components
in V, defined as tr(V'X'XV) / tr(X'X).

"""
explained_variance(X, V) = explained_variance(X, V, norm(X))

"""

Compute the right-singular vectors from the left-singular vectors `U` and the data matrix `X`.
"""
right_from_left_singular_vectors(X, U) = orthogonal!(U'*X)

"""

In-place version of the above.
"""
right_from_left_singular_vectors!(V, X, U) = orthogonal!(mul!(V, U', X))

projection_distance(X, V) = sqrt(norm(X .- (X*V)*V')) / reduce(*, size(X))

function projection_distance(X::SparseMatrixCSC, V)
    rv = 0.0
    L = X*V
    R = V'
    Is, Js, Vs = findnz(X)
    for (i, j, v) in zip(Is, Js, Vs)
        rv += (Float64(v) - dot(view(L, i, :), view(R, :, j)))^2
    end
    rv = sqrt(rv)
    rv /= length(V)
end

"""
    matrix_from_tensor(T)

Convert a tensor (i.e., a 3D matrix) to a matrix by flattening the first two dimensions. For
example, if the tensor corresponds to a vector of images, each image corresponds to a row of
the resulting matrix.
"""
function matrix_from_tensor(T)
    d1, d2, n = size(T)
    d = d1*d2
    Matrix(reshape(T, d, n)')
end

import SparseArrays.AbstractSparseMatrixCSC
import SparseArrays.permute, SparseArrays.permute!
import SparseArrays.getcolptr
import SparseArrays._checkargs_sourcecompatdest_permute!, SparseArrays._checkargs_sourcecompatperms_permute!, SparseArrays._ispermutationvalid_permute!

function perm!(X::AbstractSparseMatrixCSC{Tv,Ti}, A::AbstractSparseMatrixCSC{Tv,Ti}, q::AbstractVector{<:Integer}, f::Function=identity) where {Tv,TvA,Ti}
    Xi = 1
    getcolptr(X)[1] = Xi
    for Xj in 1:size(A, 2) # column of X, add @inbounds
        Aj = q[Xj] # corresponding column of A
        for Ai in nzrange(A, Aj) # row of A
            rowvals(X)[Xi] = rowvals(A)[Ai]
            nonzeros(X)[Xi] = f(nonzeros(A)[Ai])
            Xi += 1
        end
        getcolptr(X)[Xj+1] = Xi
    end
    return X
end

function permute!(X::AbstractSparseMatrixCSC{Tv,Ti}, A::AbstractSparseMatrixCSC{Tv,Ti}, q::AbstractVector{<:Integer}) where {Tv,Ti}
    _checkargs_sourcecompatdest_permute!(A, X)
    _checkargs_sourcecompatperms_permute!(A, 1:size(A, 1), q)
    if !_ispermutationvalid_permute!(q, getcolptr(X))
        throw(ArgumentError("column-permutation argument `q` must be a valid permutation"))
    end
    perm!(X, A, q)
end

function permute(A::AbstractSparseMatrixCSC{Tv,Ti}, q::AbstractVector{<:Integer}) where {Tv,Ti}
    _checkargs_sourcecompatperms_permute!(A, 1:size(A, 1), q)
    X = SparseMatrixCSC(size(A, 1), size(A, 2),
                        ones(Ti, size(A, 2) + 1),
                        Vector{Ti}(undef, nnz(A)),
                        Vector{Tv}(undef, nnz(A)))
    _checkargs_sourcecompatdest_permute!(A, X)
    if !_ispermutationvalid_permute!(q, getcolptr(X))
        throw(ArgumentError("column-permutation argument `q` must be a valid permutation"))
    end
    perm!(X, A, q)
end


text:
import Base: close, show, eof

struct FortranFile{A<:AccessMode, C<:Conversion}
   io     :: IO    # the underyling I/O stream
   acctyp :: A
   convert:: C
end

"""
    FortranFile(io::IO; kwargs...)

Wrap the given `IO` stream as a `FortranFile` containing Fortran "unformatted"
(i.e. binary) data. The keyword arguments can be:
* `access` for specifying the access mode; a `String` being one of
  * "sequential": sequential access as in Fortran, where records have leading
    and trailing record markers. This is the default.
  * "direct": direct access as in Fortran, where records have fixed length
    and can be accessed in random order. The "recl" keyword must be given
    to specify the record length. `read` and `write` operations on these files
    must use the `rec` keyword argument to specify which record to read/write.
* `marker`: for specifying the type of record marker; one of
  * `RECMRK4B`: 4-byte record markers (with support for subrecords) [default]
  * `RECMRK8B`: 8-byte record markers
  This is ignored for direct access files.
* `recl`: for specifying the record length if access=="direct".
  The record length is counted in bytes and must be specified as an Integer.
* `convert`: for specifying the byte-order of the file data; one of
  * "native": use the host byte order [default]
  * "big-endian": use big-endian byte-order
  * "little-endian": use little-endian byte-order

The returned `FortranFile` can be used with Julia's `read` and `write`
functions. See their documentation for more information.
"""
function FortranFile(io::IO; access = "sequential", marker = RECMRKDEF, recl::Integer = 0, convert = "native")
   conv = get_convert(convert)
   if access == "sequential"
      if recl != 0
         fthrow("sequential-access with fixed-length records not supported")
      end
      acctyp = SequentialAccess(marker)
   elseif access == "direct"
      if recl == 0
         fthrow("must specify record length for direct-access files (use recl keyword argument)")
      end
      acctyp = DirectAccess(Int64(recl))
   else
      fthrow("unsupported access mode \"$(access)\"")
   end
   return FortranFile(io, acctyp, conv)
end

"""
    FortranFile(fn::String [, mode="r" ]; kwargs...)

Open a file containing Fortran unformatted (i.e. binary) data for reading
or writing, depending on `mode` which is used as in `open`. The keyword
arguments are as in `FortranFile(io::IO; kwargs...)`.
"""
FortranFile(fn::String, mode = "r"; kwargs...) = FortranFile(open(fn,mode); kwargs...)

"Re-position a `FortranFile` at its beginning."
rewind(f::FortranFile) = seek(f.io, 0)

close(f::FortranFile) = close(f.io)

eof(f::FortranFile) = eof(f.io)

function show(io::IO, f::FortranFile)
   print(io, "FortranFile(")
   show(io, f.io)
   print(io, "), $(f.convert.name) byte order, ")
   show(io, f.acctyp)
end


text:
module EDA

using CImGui
using CImGui.CSyntax
using CImGui.CSyntax.CStatic
using CImGui.GLFWBackend
using CImGui.OpenGLBackend
using CImGui.GLFWBackend.GLFW
using CImGui.OpenGLBackend.ModernGL
using CImGui: ImVec2, ImVec4, IM_COL32, ImS32, ImU32, ImS64, ImU64
using Printf
using DataFrames
using CSV
using Dates
using Statistics

include("filedialog.jl")
include("new_GUI.jl")

export launch

end # module


text:
push!(LOAD_PATH,"../src/")
using Documenter
using StatsModels, DataFrames, VegaLite
using LinearRegressionKit

makedocs(sitename="LinearRegressionKit.jl", modules = [LinearRegressionKit] ,
    pages = Any[
        "Home" => "index.md",
        "Tutorials" => Any[
            "Basic" => "basic_tutorial.md",
            "Multiple regression" => "multi_tutorial.md",
            "Weighted regression" => "weighted_regression_tutorial.md",
            "Ridge regression" => "ridge_regression_tutorial.md" ]
    ])

deploydocs(
    repo = "github.com/ericqu/LinearRegressionKit.jl.git",
    push_preview = false,
    devbranch = "main",
    devurl = "dev",
)


text:
using LinearAlgebra, Plots, JLD2
using Flux, Flux.Zygote, Optim, DiffEqFlux
using KitBase, ProgressMeter
import KitML

# one-cell simplification
begin
    quadratureorder = 5
    points, triangulation = KitBase.octa_quadrature(quadratureorder)
    weights = KitBase.quadrature_weights(points, triangulation)
    nq = size(points, 1)
    L = 1
    ne = (L + 1)^2

    α = zeros(ne)
    u0 = [2.0, 0.0, 0.0, 0.0]
    m = KitBase.eval_spherharmonic(points, L)

    res = KitBase.optimize_closure(α, m, weights, u0, KitBase.maxwell_boltzmann_dual)
    u = KitBase.realizable_reconstruct(
        res.minimizer,
        m,
        weights,
        KitBase.maxwell_boltzmann_dual_prime,
    )
end

# multi-cell case
begin
    # space
    x0 = -1.5
    x1 = 1.5
    y0 = -1.5
    y1 = 1.5
    nx = 60#100
    ny = 60#100
    dx = (x1 - x0) / nx
    dy = (y1 - y0) / ny

    pspace = KitBase.PSpace2D(x0, x1, nx, y0, y1, ny)

    # time
    tEnd = 1.0
    cfl = 0.5
    dt = cfl / 2 * (dx * dy) / (dx + dy)

    # quadrature
    quadratureorder = 5
    points, triangulation = KitBase.octa_quadrature(quadratureorder)
    weights = KitBase.quadrature_weights(points, triangulation)
    nq = size(points, 1)

    # particle
    SigmaS = 1 * ones(ny + 4, nx + 4)
    SigmaA = 0 * ones(ny + 4, nx + 4)
    SigmaT = SigmaS + SigmaA

    # moments
    L = 1
    ne = (L + 1)^2
    phi = zeros(ne, nx, ny)
    α = zeros(ne, nx, ny)
    m = KitBase.eval_spherharmonic(points, L)
end

# initial distribution
begin
    s2 = 0.03^2
    flr = 1e-4
    init_field(x, y) = max(flr, 1.0 / (4.0 * pi * s2) * exp(-(x^2 + y^2) / 4.0 / s2))
    for j = 1:nx
        for i = 1:ny
            y = y0 + (i - 0.5) * dy
            x = x0 + (j - 0.5) * dx
            # only zeroth order moment is non-zero
            phi[1, i, j] = init_field(x, y)
        end
    end
end

global t = 0.0
flux1 = zeros(ne, nx + 1, ny)
flux2 = zeros(ne, nx, ny + 1)

# mechanical solver
anim = @animate for iter = 1:140
    println("iteration $(iter)")

    # regularization
    @inbounds Threads.@threads for j = 1:ny
        for i = 1:nx
            res = KitBase.optimize_closure(α[:, i, j], m, weights, phi[:, i, j], KitBase.maxwell_boltzmann_dual)
            α[:, i, j] .= res.minimizer

            phi[:, i, j] .= KitBase.realizable_reconstruct(res.minimizer, m, weights, KitBase.maxwell_boltzmann_dual_prime)
        end
    end

    # flux
    fη1 = zeros(nq)
    @inbounds for j = 1:ny
        for i = 2:nx
            KitBase.flux_kfvs!(fη1, KitBase.maxwell_boltzmann_dual.(α[:, i-1, j]' * m)[:], KitBase.maxwell_boltzmann_dual.(α[:, i, j]' * m)[:], points[:, 1], dt)

            for k in axes(flux1, 1)
                flux1[k, i, j] = sum(m[k, :] .* weights .* fη1)
            end
        end
    end

    fη2 = zeros(nq)
    @inbounds for i = 1:nx
        for j = 2:ny
            KitBase.flux_kfvs!(fη2, KitBase.maxwell_boltzmann_dual.(α[:, i, j-1]' * m)[:], KitBase.maxwell_boltzmann_dual.(α[:, i, j]' * m)[:], points[:, 2], dt)

            for k in axes(flux2, 1)
                flux2[k, i, j] = sum(m[k, :] .* (weights .* fη2))
            end
        end
    end

    # update
    @inbounds for j = 2:ny-1
        for i = 2:nx-1
            for q = 1:1
                phi[q, i, j] =
                    phi[q, i, j] +
                    (flux1[q, i, j] - flux1[q, i+1, j]) / dx +
                    (flux2[q, i, j] - flux2[q, i, j+1]) / dy +
                    (SigmaS[i, j] * phi[q, i, j] - SigmaT[i, j] * phi[q, i, j]) * dt
            end

            for q = 2:ne
                phi[q, i, j] =
                    phi[q, i, j] +
                    (flux1[q, i, j] - flux1[q, i+1, j]) / dx +
                    (flux2[q, i, j] - flux2[q, i, j+1]) / dy +
                    (- SigmaT[i, j] * phi[q, i, j]) * dt
            end
        end
    end

    global t += dt
    contourf(pspace.x[1:nx, 1], pspace.y[1, 1:ny], phi[1, :, :])
end

cd(@__DIR__)
gif(anim, "linesource_mn.gif")

begin
    # create neural network
    #nn = KitML.create_neural_closure(ne, 1)
    nn = KitML.ICNNChain(4, 1, [10, 10, 10], tanh)

    # load saved params
    #cd(@__DIR__)
    #@load "model.jld2" nn
    #@info "model loaded"
end

X = zeros(4, 1)
Y = zeros(1, 1)
X[:, 1] .= phi[:, 1, 1]
Y[1, 1] = sum(weights .*
maxwell_boltzmann_dual.(maxwell_boltzmann_dual_prime.(m' * α[:, 1, 1])))

for i = 1:nx, j = 1:ny
    X = hcat(X, phi[:, i, j])

    η = sum(weights .*
    maxwell_boltzmann_dual.(maxwell_boltzmann_dual_prime.(m' * α[:, i, j])))
    Y = hcat(Y, η)
end

X = zeros(4, 1)
Y = zeros(4, 1)
X[:, 1] .= phi[:, 1, 1]
Y[:, 1] .= α[:, 1, 1]

for i = 21:30, j = 21:30
    X = hcat(X, phi[:, i, j])
    Y = hcat(Y, α[:, i, j])
end

nn = Chain(Dense(4, 16, tanh), Dense(16, 16, tanh), Dense(16, 16, tanh), Dense(16, 4))
data = Flux.Data.DataLoader(X, Y, batchsize = 50, shuffle = true)
KitML.sci_train!(nn, data, ADAM(), 500)

# unified solver
@showprogress for iter = 1:5
    #=
    # regularization
    Threads.@threads for j = 1:ny
        for i = 1:nx
            phi_old = phi

            #res = KitBase.optimize_closure(α[:, i, j], m, weights, phi[:, i, j], KitBase.maxwell_boltzmann_dual)
            #α[:, i, j] .= res.minimizer
            #phi[:, i, j] .= KitBase.realizable_reconstruct(res.minimizer, m, weights, KitBase.maxwell_boltzmann_dual_prime)

            #training phase network
            KitML.sci_train!(nn, (phi[:, i, j], α[:, i, j]))

            # calculate η' = f'(u0, u1, u2, u3)
            α[:, i, j] = gradient(x -> first(nn(x)), phi[:, i, j])[1]
            phi[:, i, j] .= KitBase.realizable_reconstruct(
                α[:, i, j],
                m,
                weights,
                KitBase.maxwell_boltzmann_dual_prime,
            )
        end
    end

    KitML.sci_train!(nn, (phi[:, i, j], η[i, j]))
    =#
    #=
    Threads.@threads for j = 1:ny
        for i = 1:nx
            α[:, i, j] .= nn(phi[:, i, j])
            phi[:, i, j] .= KitBase.realizable_reconstruct(
                α[:, i, j],
                m,
                weights,
                KitBase.maxwell_boltzmann_dual_prime,
            )
        end
    end
    =#

    # flux
    fη1 = zeros(nq)
    for j = 1:ny
        for i = 2:nx
            #αL = gradient(x -> first(nn(x)), phi[:, i-1, j])[1]
            #αR = gradient(x -> first(nn(x)), phi[:, i, j])[1]
            αL = nn(phi[:, i-1, j])
            αR = nn(phi[:, i, j])
            KitBase.flux_kfvs!(
                fη1,
                KitBase.maxwell_boltzmann_dual.(αL' * m)[:],
                KitBase.maxwell_boltzmann_dual.(αR' * m)[:],
                points[:, 1],
                dt,
            )

            for k in axes(flux1, 1)
                flux1[k, i, j] = sum(m[k, :] .* weights .* fη1)
            end
        end
    end

    fη2 = zeros(nq)
    for i = 1:nx
        for j = 2:ny
            #αL = gradient(x -> first(nn(x)), phi[:, i, j-1])[1]
            #αR = gradient(x -> first(nn(x)), phi[:, i, j])[1]
            αL = nn(phi[:, i, j-1])
            αR = nn(phi[:, i, j])
            KitBase.flux_kfvs!(
                fη2,
                KitBase.maxwell_boltzmann_dual.(αL' * m)[:],
                KitBase.maxwell_boltzmann_dual.(αR' * m)[:],
                points[:, 2],
                dt,
            )

            for k in axes(flux2, 1)
                flux2[k, i, j] = sum(m[k, :] .* (weights .* fη2))
            end
        end
    end

    # update
    for j = 2:ny-1
        for i = 2:nx-1
            for q = 1:1
                phi[q, i, j] =
                    phi[q, i, j] +
                    (flux1[q, i, j] - flux1[q, i+1, j]) / dx +
                    (flux2[q, i, j] - flux2[q, i, j+1]) / dy +
                    (SigmaS[i, j] * phi[q, i, j] - SigmaT[i, j] * phi[q, i, j]) * dt
            end

            for q = 2:ne
                phi[q, i, j] =
                    phi[q, i, j] +
                    (flux1[q, i, j] - flux1[q, i+1, j]) / dx +
                    (flux2[q, i, j] - flux2[q, i, j+1]) / dy +
                    (-SigmaT[i, j] * phi[q, i, j]) * dt
            end
        end
    end

    global t += dt
end

using Plots
contourf(pspace.x[1:nx, 1], pspace.y[1, 1:ny], phi[1, :, :])
#contourf(pspace.x[1:nx, 1], pspace.y[1, 1:ny], α[1, :, :])

# saving neural network Progress
@save "model.jld2" nn
@info "model saved"

res = KitBase.optimize_closure(α[:, 25, 25], m, weights, phi[:, 25, 25], KitBase.maxwell_boltzmann_dual)
res.minimizer

savefig("test.png")


text:
#=
Author : Ng Yeesian
=#
type DSMDeployment <: DeploymentModel
    m::JuMP.Model
    x::Vector{JuMP.Variable}
end
deployment(m::StochasticDeployment) = [round(Int,x) for x in JuMP.getValue(m.x)]

function DSMDeployment(p::DeploymentProblem,
                          q::Float64; # busy fraction
                          max_amb::Int = 5
                          tol = params.δ,
                          solver = GurobiSolver(OutputFlag=0))
    demand = mean(p.demand[p.train,:],1)
    @assert length(demand) == problem.nregions
    I = 1:p.nlocations
    J = 1:problem.nregions
    K = 1:max_amb

    m = JuMP.Model(solver=solver)
    JuMP.@variable(m, x[1:p.nlocations] >= 0, Int)
    JuMP.@variable(m, z[1:p.nregions, 1:max_amb] >= 0, Bin)

    JuMP.@objective(m, Min, sum((1-q)*(q^k)*demand[j]*z[j,k] for j=J, k=K))

    JuMP.@constraint(m, sum(x[i] for i=I) <= p.nambulances)
    for j in J # coverage over all regions
        JuMP.@constraint(m, sum(x[i] for i in filter(i->p.coverage[j,i], I)) >= sum(z[j,k] for k=1:K))
    end

    DSMDeployment(m, x)
end

solve(model::DSMDeployment) = JuMP.solve(model.m)
solve(model::DSMDeployment, p::DeploymentProblem) = JuMP.solve(model.m)

max_stars_repo_name: michaelhilborn/AmbulanceDeployement

max_issues_repo_name: joshua-ong/AmbulanceDeployment

max_forks_repo_name: michaelhilborn/AmbulanceDeployement


text:
# Copyright (c) 2017: Miles Lubin and contributors
# Copyright (c) 2017: Google Inc.
#
# Use of this source code is governed by an MIT-style license that can be found
# in the LICENSE.md file or at https://opensource.org/licenses/MIT.

"""
    _UnsafeVectorView(offset, len, ptr)

Lightweight unsafe view for vectors.

## Motivation

`_UnsafeVectorView` is needed as an allocation-free equivalent of `view`. Other
alternatives, like `view(x, 1:len)` or a struct like
```
struct _SafeView{T}
    x::Vector{T}
    len::Int
end
```
will allocate so that `x` can be tracked by Julia's GC.

`_UnsafeVectorView` relies on the fact that the use-cases of `_UnsafeVectorView`
only temporarily wrap a long-lived vector like `d.jac_storage` so that we don't
have to worry about the GC removing `d.jac_storage` while `_UnsafeVectorView`
exists. This lets us use a `Ptr{T}` and create a struct that is `isbitstype` and
therefore does not allocate.

## Example

Instead of `view(x, 1:10)`, use `_UnsafeVectorView(0, 10, pointer(x))`.

## Unsafe behavior

`_UnsafeVectorView` is unsafe because it assumes that the vector `x` that the
pointer `ptr` refers to remains valid during the usage of `_UnsafeVectorView`.
"""
struct _UnsafeVectorView{T} <: DenseVector{T}
    offset::Int
    len::Int
    ptr::Ptr{T}
end

Base.getindex(x::_UnsafeVectorView, i) = unsafe_load(x.ptr, i + x.offset)

function Base.setindex!(x::_UnsafeVectorView, value, i)
    unsafe_store!(x.ptr, value, i + x.offset)
    return value
end

Base.length(v::_UnsafeVectorView) = v.len

Base.size(v::_UnsafeVectorView) = (v.len,)

"""
    _UnsafeVectorView(x::Vector, N::Int)

Create a new [`_UnsafeVectorView`](@ref) from `x`, and resize `x` if needed to
ensure it has a length of at least `N`.

## Unsafe behavior

In addition to the usafe behavior of `_UnsafeVectorView`, this constructor is
additionally unsafe because it may resize `x`. Only call it if you are sure that
the usage of `_UnsafeVectorView(x, N)` is short-lived, and that there are no
other views to `x` while the returned value is within scope.
"""
function _UnsafeVectorView(x::Vector, N::Int)
    if length(x) < N
        resize!(x, N)
    end
    return _UnsafeVectorView(0, N, pointer(x))
end

"""
    _UnsafeLowerTriangularMatrixView(x, N)

Lightweight unsafe view that converts a vector `x` into the lower-triangular
component of a symmetric `N`-by-`N` matrix.

## Motivation

`_UnsafeLowerTriangularMatrixView` is needed as an allocation-free equivalent of
`view`. Other alternatives, like `reshape(view(x, 1:N^2), N, N)` or a struct
like
```julia
struct _SafeView{T}
    x::Vector{T}
    len::Int
end
```
will allocate so that `x` can be tracked by Julia's GC.
`_UnsafeLowerTriangularMatrixView` relies on the fact that the use-cases of
`_UnsafeLowerTriangularMatrixView` only temporarily wrap a long-lived vector
like `d.jac_storage` so that we don't have to worry about the GC removing
`d.jac_storage` while `_UnsafeLowerTriangularMatrixView` exists. This lets us
use a `Ptr{T}` and create a struct that is `isbitstype` and therefore does not
allocate.

## Unsafe behavior

`_UnsafeLowerTriangularMatrixView` is unsafe because it assumes that the vector
`x` remains valid during the usage of `_UnsafeLowerTriangularMatrixView`.
"""
struct _UnsafeLowerTriangularMatrixView <: AbstractMatrix{Float64}
    N::Int
    ptr::Ptr{Float64}
end

Base.size(x::_UnsafeLowerTriangularMatrixView) = (x.N, x.N)

function _linear_index(row, col)
    if row < col
        error("Unable to access upper-triangular component: ($row, $col)")
    end
    return div((row - 1) * row, 2) + col
end

function Base.getindex(x::_UnsafeLowerTriangularMatrixView, i, j)
    return unsafe_load(x.ptr, _linear_index(i, j))
end

function Base.setindex!(x::_UnsafeLowerTriangularMatrixView, value, i, j)
    unsafe_store!(x.ptr, value, _linear_index(i, j))
    return value
end

"""
    _UnsafeLowerTriangularMatrixView(x::Vector{Float64}, N::Int)

Create a new [`_UnsafeLowerTriangularMatrixView`](@ref) from `x`, zero the
elements in `x`, and resize `x` if needed to ensure it has a length of at least
`N * (N + 1) / 2`.

## Unsafe behavior

In addition to the usafe behavior of `_UnsafeLowerTriangularMatrixView`, this
constructor is additionally unsafe because it may resize `x`. Only call it if
you are sure that the usage of `_UnsafeLowerTriangularMatrixView(x, N)` is
short-lived, and that there are no other views to `x` while the returned value
is within scope.
"""
function _UnsafeLowerTriangularMatrixView(x::Vector{Float64}, N::Int)
    z = div(N * (N + 1), 2)
    if length(x) < z
        resize!(x, z)
    end
    for i in 1:z
        x[i] = 0.0
    end
    return _UnsafeLowerTriangularMatrixView(N, pointer(x))
end

function _reinterpret_unsafe(::Type{T}, x::Vector{R}) where {T,R}
    # how many T's fit into x?
    @assert isbitstype(T) && isbitstype(R)
    len = length(x) * sizeof(R)
    p = reinterpret(Ptr{T}, pointer(x))
    return _UnsafeVectorView(0, div(len, sizeof(T)), p)
end


text:
using Documenter, ImageChipper

makedocs(;
    modules=[ImageChipper],
    format=Documenter.HTML(),
    pages=[
        "Home" => "index.md",
    ],
    repo="https://github.com/caseykneale/ImageChipper.jl/blob/{commit}{path}#L{line}",
    sitename="ImageChipper.jl",
    authors="Casey Kneale",
    assets=String[],
)

deploydocs(;
    repo="github.com/caseykneale/ImageChipper.jl",
)


text:
const USE_GPU = true

const outdir = "sia_hershel_bulkley_bn_0.5"

using ParallelStencil
using ParallelStencil.FiniteDifferences2D

@static if USE_GPU
    @init_parallel_stencil(CUDA, Float64, 2)
else
    @init_parallel_stencil(Threads, Float64, 2)
end

using Printf
using Plots
using MAT

@views function run()
    # physics
    npow    = 3.0 # Glen's power law exponent
    lz      = 1.0 # m
    a_ρg_n  = 1.0 # m^(-npow)*s^(-1)
    # scales
    tsc     = lz^(-npow) / a_ρg_n # s
    dsc     = lz^2 / tsc          # m^2/s
    # non-dimensional
    lx_lz   = 100.0
    ly_lz   = 150.0
    w_lz    = 10.0
    theta   = π / 18
    bn      = 0.5  # bn = τY_ρg/Lz - Bingham number
    H0_lz   = 25
    # dependent physics
    lx      = lx_lz * lz
    ly      = ly_lz * lz
    w       = w_lz * lz
    ttot    = 2e2 * tsc
    τY_ρg   = bn * lz
    # numerics
    nx      = 512
    ny      = ceil(Int, ly_lz / lx_lz * nx)
    niter   = 2 * max(nx, ny)
    eiter   = 1e-12
    nout    = 10
    ncheck  = ceil(Int, 0.2*nx)
    CFL     = 0.5 / sqrt(2)
    Resc    = 1.2
    # preprocessing
    dx, dy  = lx / (nx - 1), ly / (ny - 1)
    x, y    = LinRange(-lx / 2, lx / 2, nx), LinRange(-ly / 2, ly / 2, ny)
    Vpdt    = CFL * min(dx, dy)
    dtmin   = 1e-8 * tsc
    dtmax   = 1e0 * tsc
    dt0     = min(2*dtmin, dtmax)
    max_lxy = max(lx, ly)
    # init
    H0      = Data.Array(H0_lz * lz * exp.(-(x ./ w).^2 .- ((y .- ly/4)' ./ w).^2))
    B0      = Data.Array(y' .* tan(theta) .- 5lz .* cos.(2π .* x ./ lx) .+ 2lz .* sin.(7π .* y' ./ ly))
    H       = @ones(nx,ny) .* H0
    H_old   = @zeros(nx,ny)
    dH      = @zeros(nx,ny)
    B       = @ones(nx,ny) .* B0
    S       = B .+ H
    dSdx    = @zeros(nx - 1,ny)
    dSdy    = @zeros(nx,ny - 1)
    Deff    = @zeros(nx - 1,ny - 1)
    Deffm   = @zeros(nx - 1,ny - 1)
    Yi      = @zeros(nx - 1,ny - 1)
    Qx      = @zeros(nx - 1,ny - 2)
    Qy      = @zeros(nx - 2,ny - 1)
    Qx_old  = @zeros(nx - 1,ny - 2)
    Qy_old  = @zeros(nx - 2,ny - 1)
    # static data
    if isdir(outdir)
        rm(outdir, recursive=true, force=true)
    end
    mkdir(outdir)
    matwrite("$outdir/static.mat", Dict(
        "npow" => npow, "ArhogN" => a_ρg_n, "theta" => theta, "Bn" => bn,
        "Ly_Lz" => lx_lz, "Ly_Lz" => ly_lz, "w_Lz"  => w_lz, "H0_Lz" => w_lz,
        "ttot" => ttot,
        "Lx" => lx, "Ly"=> ly, "Lz" => lz,
        "tauY_rhog" =>τY_ρg,
        "nx" => nx, "ny" => ny,
        "dx" => dx, "dy" => dy,
        "niter" => niter, "eiter" => eiter,
        "x" => Array(x), "y" => Array(y),
        "B" => Array(B), "H0" => Array(H0)
    ))
    # action
    t      = 0.0
    it     = 0
    dt     = dt0
    while t < ttot
        @printf "  # it = %d\n" it
        iter = 0; err = Inf
        H_old  .= H
        Qx_old .= Qx
        Qy_old .= Qy
        while iter < niter && err > eiter
            if iter % ncheck == 0 dH .= H end
            @parallel compute_slope!(dSdx, dSdy, S, dx, dy)
            @parallel compute_Deff!(Deff, H, S, Yi, dSdx, dSdy, npow, a_ρg_n, τY_ρg, dx, dy)
            @parallel compute_Deffm!(Deffm, Deff)
            @parallel update_fluxes!(Qx, Qy, dSdx, dSdy, Deff, Deffm, Vpdt, Resc, max_lxy, dsc, dt, dx, dy)
            @parallel update_surface!(H, H_old, S, B, Qx, Qy, Deff, Deffm, Vpdt, Resc, max_lxy, dsc, dt, dx, dy)
            S .= B .+ H
            if iter % ncheck == 0
                dH .= dH .- H
                errsc = maximum(H)
                err = maximum(abs.(dH))/errsc
                if !isfinite(err) || !isfinite(errsc) || isapprox(err, 0.0; atol = 1e-18); err = NaN; break end
                @printf "    # iter/ndof = %.3f, err = %g\n" iter/max(nx,ny) err
            end
            iter += 1
        end
        if err > eiter || isnan(err)
            @printf "    Recalculating, didn't converge...\n"
            H  .= H_old
            Qx .= Qx_old
            Qy .= Qy_old
            S .= B .+ H
            dt /= 2.0
            if dt < dtmin error("sim failed") end
            continue
        end
        t  += dt; it += 1
        dt = min(dt*1.1, dtmax)
        if it % nout == 0
            display(heatmap(x, y, Array(H'),
                        aspect_ratio=1, framestyle=:box,
                        xlims=(x[1],x[end]), ylims=(y[1],y[end]),
                        xlabel="x", ylabel="y", color=:jet,
                        title = @sprintf "# it = %d, t = %g/%g, dt = %g" it t ttot dt))
            matwrite("$outdir/step_$it.mat", Dict(
                "H" => Array(H), "S" => Array(S), "Yi" => Array(Yi),
                "dt" => dt, "time" => t, "iter" => iter
            ); compress=true)
        end
        end
end

macro gam()      esc(:( sqrt(@av_ya(dSdx)^2 + @av_xa(dSdy)^2)                                     )) end
macro Re_ax()    esc(:( π + sqrt(π * π + max_lxy * max_lxy / max(@av_ya(Deffm), 1e-5 * dsc) / dt) )) end
macro Re_ay()    esc(:( π + sqrt(π * π + max_lxy * max_lxy / max(@av_xa(Deffm), 1e-5 * dsc) / dt) )) end
macro Re_av()    esc(:( π + sqrt(π * π + max_lxy * max_lxy / max(@av(Deffm), 1e-5 * dsc) / dt)    )) end
macro τr_dτ_ax() esc(:( max_lxy / Vpdt / @Re_ax() / Resc                                          )) end
macro τr_dτ_ay() esc(:( max_lxy / Vpdt / @Re_ay() / Resc                                          )) end
macro dτ_ρ()     esc(:( Vpdt * max_lxy / max(@av(Deffm), 1e-5 * dsc) / @Re_av() / Resc            )) end
macro divQ()     esc(:( @d_xa(Qx) / dx + @d_ya(Qy) / dy                                           )) end

@parallel function compute_slope!(dSdx, dSdy, S, dx, dy)
    @all(dSdx) = @d_xa(S) / dx
    @all(dSdy) = @d_ya(S) / dy
    return
end

@parallel function compute_Deff!(Deff, H, S, Yi, dSdx, dSdy, npow, a_ρg_n, τY_ρg, dx, dy)
    @all(Yi)   = max(@av(H) - τY_ρg / @gam(), 0.0)
    @all(Deff) = a_ρg_n * @all(Yi)^(npow + 1.0) * (@av(H) * (npow + 2.0) - @all(Yi)) * @gam()^(npow - 1.0) / (npow + 1.0)
    return
end

@parallel function compute_Deffm!(Deffm, Deff)
    @inn(Deffm) = @maxloc(Deff)
    return
end

@parallel function update_fluxes!(Qx, Qy, dSdx, dSdy, Deff, Deffm, Vpdt, Resc, max_lxy, dsc, dt, dx, dy)
    @all(Qx) = (@all(Qx) * @τr_dτ_ax() - @av_ya(Deff) * @inn_y(dSdx)) / (1.0 + @τr_dτ_ax())
    @all(Qy) = (@all(Qy) * @τr_dτ_ay() - @av_xa(Deff) * @inn_x(dSdy)) / (1.0 + @τr_dτ_ay())
    return
end

@parallel function update_surface!(H, Hold, S, B, Qx, Qy, Deff, Deffm, Vpdt, Resc, max_lxy, dsc, dt, dx, dy)
    @inn(H) = (@inn(H) + @dτ_ρ() * (@inn(Hold) / dt - @divQ())) / (1.0 + @dτ_ρ() / dt)
    return
end

run()


text:
md"""
# Iterators

While not part of the scope of this package, some simple utilities for iterating over data sets is provided.

The only iterator which is in some sense special for this package is [`RepeatPartitionIterator`](@ref) which produces
iterators over a subset of its wrapped iterator. This is useful when one wants to ensure that all models see
the same (possibly randomly augmented) data in the same order. Note that this is not certain to be the best
strategy for finding good models for a given data set and this package does (intentionally) blur the lines a
bit between model training protocol and architecture search.
"""

@testset "Iterators" begin #src
data = reshape(collect(1:4*5), 4,5)
labels = collect(1:5)

# Simple and fast batching of in-memory data is done by [`BatchIterator`](@ref)
biter = BatchIterator((data, labels), 2)
@test size.(first(biter)) == ((4, 2), (2,))

# Move data to gpu.
giter = GpuIterator(biter)
@test first(giter) == first(biter) |> gpu

# This is the only iterator which is "special" for this package:
rpiter = RepeatPartitionIterator(biter, 2)
# It produces iterators over a subset of the wrapped iterator (2 batches in this case).
piter = first(rpiter)
@test length(piter) == 2
# This allows for easily training several models on the same subset of the data.
for modeli in 1:3
    for ((feature, label), (expf, expl)) in zip(piter, biter)
        @test feature == expf
        @test label == expl
    end
end

# [`StatefulGenerationIter`](@ref) is typically used in conjunction with [`TrainThenFitness`](@ref) to map a generation.
# number to an iterator from a [`RepeatPartitionIterator`](@ref).
sgiter = StatefulGenerationIter(rpiter)
for (generationnr, topiter) in enumerate(rpiter)
    gendata = collect(NaiveGAflux.itergeneration(sgiter, generationnr))
    expdata = collect(topiter)
    @test gendata == expdata
end

# [`TimedIterator`](@ref) is useful for preventing that models which take very long time to train/validate slow down the process.
timediter = TimedIterator(;
                    timelimit=0.1,
                    patience=4,
                    timeoutaction = () -> TimedIteratorStop,
                    accumulate_timeouts=false,
                    base=1:100)

last = 0
for i in timediter
    last = i
    if i > 2
        # Does not matter here if overloaded CI VM takes longer than this to get back to us. #src
        sleep(0.11)
    end
end
@test last === 6 # Sleep after 2, then 4 patience.
end #src


text:
module x86

using Switch

macro rotl32(var, value)
    :(($var << $value) | ($var >> $(32-value)))
end

macro fmix32(var)
    quote
      local value = $(var)
      value $= (value >> 16)
      value = UInt32(value * UInt32(0x85ebca6b))
      value $= (value >> 13)
      value = UInt32(value * UInt32(0xc2b2ae35))
      value $= (value >> 16)
      value
    end
end

function hash32(data::Array{UInt8}, seed::UInt32)
    c1 = UInt32(0xcc9e2d51)
    c2 = UInt32(0x1b873593)
    h = seed

    len = UInt32(length(data))
    remainder = len & 3
    blocks = div(len, 4)
    p = convert(Ptr{UInt32}, pointer(data))

    # Body
    for next_block = 1:blocks
        k = UInt32(unsafe_load(p, next_block))
        k = k * c1
        k = @rotl32(k, 15)
        k = k * c2

        h $= k
        h = @rotl32(h, 13)
        h = h * UInt32(5) + UInt32(0xe6546b64)
    end

    # Tail
    k = UInt32(0)
    last = blocks*4 + 1
    @switch remainder begin
        @case 3
            k |= UInt32(data[last + 2]) << 16
        @case 2
            k |= UInt32(data[last + 1]) << 8
        @case 1
            k |= UInt32(data[last])
    end

    k = k * c1
    k = @rotl32(k, 15)
    k = k * c2
    h $= k

    # Finalization
    h $= len
    h = @fmix32(h)

    return h

end

hash32(data::Array{UInt8}, seed::Int) = hash32(data, UInt32(seed))
hash32(data::Array{UInt8}) = hash32(data, UInt32(0))
hash32(data::AbstractString, seed::UInt32) = hash32(convert(Array{UInt8}, data), seed)
hash32(data::AbstractString, seed::Int) = hash32(convert(Array{UInt8}, data), UInt32(seed))
hash32(data::AbstractString) = hash32(convert(Array{UInt8}, data), UInt32(0))

function hash128(data::Array{UInt8}, seed::UInt32)
    c1 = UInt32(0x239b961b)
    c2 = UInt32(0xab0e9789)
    c3 = UInt32(0x38b34ae5)
    c4 = UInt32(0xa1e38b93)

    h1 = seed
    h2 = seed
    h3 = seed
    h4 = seed

    len = UInt32(length(data))
    remainder = len & 15
    blocks = div(len, 16)
    p = convert(Ptr{UInt32}, pointer(data))

    # Body
    for next_block = 1:4:blocks*4
        k1 = UInt32(unsafe_load(p, next_block))
        k2 = UInt32(unsafe_load(p, next_block+1))
        k3 = UInt32(unsafe_load(p, next_block+2))
        k4 = UInt32(unsafe_load(p, next_block+3))

        k1 = k1 * c1
        k1 = @rotl32(k1, 15)
        k1 = k1 * c2
        h1 $= k1

        h1 = @rotl32(h1, 19)
        h1 = h1 + h2
        h1 = h1 * UInt32(5) + UInt32(0x561ccd1b)

        k2 = k2 * c2
        k2 = @rotl32(k2, 16)
        k2 = k2 * c3
        h2 $= k2

        h2 = @rotl32(h2, 17)
        h2 = h2 + h3
        h2 = h2 * UInt32(5) + UInt32(0x0bcaa747)

        k3 = k3 * c3
        k3 = @rotl32(k3, 17)
        k3 = k3 * c4
        h3 $= k3

        h3 = @rotl32(h3, 15)
        h3 = h3 + h4
        h3 = h3 * UInt32(5) + UInt32(0x96cd1c35)

        k4 = k4 * c4
        k4 = @rotl32(k4, 18)
        k4 = k4 * c1
        h4 $= k4

        h4 = @rotl32(h4, 13)
        h4 = h4 + h1
        h4 = h4 * UInt32(5) + 0x32ac3b17

    end

    # Tail
    last = blocks*16
    k1 = UInt32(0)
    k2 = UInt32(0)
    k3 = UInt32(0)
    k4 = UInt32(0)

    @switch remainder begin
        @case 15
            k4 $= UInt32(data[last+15]) << 16
        @case 14
            k4 $= UInt32(data[last+14]) << 8
        @case 13
            k4 $= UInt32(data[last+13])
            k4 = k4 * c4
            k4 = @rotl32(k4, 18)
            k4 = k4 * c1
            h4 $= k4
        @case 12
            k3 $= UInt32(data[last+12]) << 24
        @case 11
            k3 $= UInt32(data[last+11]) << 16
        @case 10
            k3 $= UInt32(data[last+10]) << 8
        @case 9
            k3 $= UInt32(data[last+9])
            k3 = k3 * c3
            k3 = @rotl32(k3, 17)
            k3 = k3 * c4
            h3 $= k3
        @case 8
            k2 $= UInt32(data[last+8]) << 24
        @case 7
            k2 $= UInt32(data[last+7]) << 16
        @case 6
            k2 $= UInt32(data[last+6]) << 8
        @case 5
            k2 $= UInt32(data[last+5])
            k2 = k2 * c2
            k2 = @rotl32(k2, 16)
            k2 = k2 * c3
            h2 $= k2
        @case 4
            k1 $= UInt32(data[last+4]) << 24
        @case 3
            k1 $= UInt32(data[last+3]) << 16
        @case 2
            k1 $= UInt32(data[last+2]) << 8
        @case 1
            k1 $= UInt32(data[last+1])
            k1 = k1 * c1
            k1 = @rotl32(k1, 15)
            k1 = k1 * c2
            h1 $= k1
    end

    # Finalization
    h1 $= len
    h2 $= len
    h3 $= len
    h4 $= len

    h1 = h1 + h2
    h1 = h1 + h3
    h1 = h1 + h4
    h2 = h2 + h1
    h3 = h3 + h1
    h4 = h4 + h1

    h1 = @fmix32(h1)
    h2 = @fmix32(h2)
    h3 = @fmix32(h3)
    h4 = @fmix32(h4)

    h1 = h1 + h2
    h1 = h1 + h3
    h1 = h1 + h4
    h2 = h2 + h1
    h3 = h3 + h1
    h4 = h4 + h1

    return UInt128(h1)<<96 | (UInt128(h2)<<64) | (UInt128(h3)<<32) | (UInt128(h4))
end

hash128(data::Array{UInt8}, seed::Int) = hash128(data, UInt32(seed))
hash128(data::Array{UInt8}) = hash128(data, UInt32(0))
hash128(data::AbstractString, seed::UInt32) = hash128(convert(Array{UInt8}, data), seed)
hash128(data::AbstractString, seed::Int) = hash128(convert(Array{UInt8}, data), UInt32(seed))
hash128(data::AbstractString) = hash128(convert(Array{UInt8}, data), UInt32(0))

end


text:
using SparseArrays
using Diderot: Arc, Node
using Diderot.SetCover

const SC = SetCover

@testset "model" begin
    values = [-2.0, -3.0, -4.0, -2.0]
    sets = sparse(Bool[1 1 0 0; 0 1 1 0; 0 0 1 1])
    instance = SC.Instance(values, sets)

    @test Diderot.domain_type(instance) == Bool
    @test Diderot.value_type(instance) == Float64
    @test Diderot.initial_state(instance) == BitSet(1:3)
    @test length(instance) == 4

    @test Diderot.transitions(instance, BitSet(1:3), 1) ==
        Dict(Arc(BitSet(1:3), true, -2.0) => BitSet(2:3),
             Arc(BitSet(1:3), false, 0.0) => BitSet(1:3))
    @test Diderot.transitions(instance, BitSet(1:3), 2) ==
        Dict(Arc(BitSet(1:3), true, -3.0) => BitSet([3]))
    @test Diderot.transitions(instance, BitSet(1:3), 3) ==
        Dict(Arc(BitSet(1:3), true, -4.0) => BitSet([1]))
    @test Diderot.transitions(instance, BitSet(1:3), 4) ==
        Dict(Arc(BitSet(1:3), true, -2.0) => BitSet(1:2))
end

@testset "exact decision diagram" begin
    N = Node{BitSet,Bool,Float64}

    values = [-2.0, -3.0, -4.0, -2.0, -1.5]
    sets = sparse(Bool[1 1 0 0 1; 0 1 1 0 0; 0 0 1 1 0])
    instance = SC.Instance(values, sets)

    # build diagram
    diagram = Diderot.Diagram(instance)
    Diderot.top_down!(diagram, instance)

    @test length(diagram.layers) == 6

    @test length(diagram.layers[1]) == 1
    @test diagram.layers[1][BitSet(1:3)] == N(0.0, nothing)

    @test length(diagram.layers[2]) == 2
    @test diagram.layers[2][BitSet(1:3)] ==
        N(0.0, Arc(BitSet(1:3), false, 0.0))
    @test diagram.layers[2][BitSet(2:3)] ==
        N(-2.0, Arc(BitSet(1:3), true, -2.0))

    # and so on ...

    @test length(diagram.layers[6]) == 1  # terminal

    # extract solution
    solution = Diderot.longest_path(diagram)
    @test solution.decisions == [0, 1, 0, 1, 0]
    @test solution.objective == -5.0
end

@testset "restriction" begin
    values = [-2.0, -3.0, -4.0, -2.0, -1.5]
    sets = sparse(Bool[1 1 0 0 1; 0 1 1 0 0; 0 0 1 1 0])
    instance = SC.Instance(values, sets)

    @testset "width 1" begin
        diagram = Diderot.Diagram(instance)
        Diderot.top_down!(diagram, instance, processing=RestrictLowDistance(1))
        @test length(diagram.layers) == 6
        @test all(l -> length(l) == 1, diagram.layers)

        solution = Diderot.longest_path(diagram)
        @test solution.objective <= -5.0
    end

    @testset "width 2" begin
        diagram = Diderot.Diagram(instance)
        Diderot.top_down!(diagram, instance, processing=RestrictLowDistance(2))
        @test length(diagram.layers) == 6
        @test all(l -> length(l) <= 2, diagram.layers)

        solution = Diderot.longest_path(diagram)
        @test solution.objective <= -5.0
    end
end

@testset "relaxation" begin
    values = [-2.0, -3.0, -4.0, -2.0, -1.5]
    sets = sparse(Bool[1 1 0 0 1; 0 1 1 0 0; 0 0 1 1 0])
    instance = SC.Instance(values, sets)

    @testset "width 1" begin
        diagram = Diderot.Diagram(instance)
        Diderot.top_down!(diagram, instance, processing=SC.relax(1))
        @test length(diagram.layers) == 6
        @test all(l -> length(l) == 1, diagram.layers)

        solution = Diderot.longest_path(diagram)
        @test solution.objective >= -5.0
    end

    @testset "width 2" begin
        diagram = Diderot.Diagram(instance)
        Diderot.top_down!(diagram, instance, processing=SC.relax(2))
        @test length(diagram.layers) == 6
        @test all(l -> length(l) <= 2, diagram.layers)

        solution = Diderot.longest_path(diagram)
        @test solution.objective >= -5.0
    end
end

@testset "branch and bound" begin
    values = [-2.0, -3.0, -4.0, -2.0, -1.5]
    sets = sparse(Bool[1 1 0 0 1; 0 1 1 0 0; 0 0 1 1 0])
    instance = SC.Instance(values, sets)

    # Relaxation needs at least width 2 for branching.

    @testset "width 1" begin
        solution = Diderot.branch_and_bound(
            instance, restrict=RestrictLowDistance(1), relax=SC.relax(2))
        @test solution.decisions == [0, 1, 0, 1, 0]
        @test solution.objective ≈ -5.0
    end

    @testset "width 2" begin
        solution = Diderot.branch_and_bound(
            instance, restrict=RestrictLowDistance(2), relax=SC.relax(2))
        @test solution.decisions == [0, 1, 0, 1, 0]
        @test solution.objective ≈ -5.0
    end
end


text:
"""
For when there is no valid location available to save to.
"""
struct NoValidPathError <: Exception
    msg::String
end

"""
For when a users has selected to abourt
"""
struct UserAbortError <: Exception
    msg::String
end
abort(msg) = throw(UserAbortError(msg))

"""
DisabledError
For when functionality that is disabled is attempted to be used
"""
struct DisabledError <: Exception
    msg::String
end


text:
module GPDPS

using Printf
using FileIO, JLD2
using ImageMagick, GR
using LinearAlgebra, SparseArrays

export test_enep
export test_potts

include("enep.jl")
include("potts.jl")

function test_enep(N=128)
    α = 1
    a = -0.5
    b = 0.5

    S,Sᵀ,z₁,z₂,ue₁,ue₂ = setup_enep(N,α,a,b)
    data = S,Sᵀ,z₁,z₂,α,a,b,ue₁,ue₂

    σ = 1.0
    τ = 0.99
    ω = 1.0
    maxit = 10
    params = σ,τ,ω,maxit

    u = zeros(N*N,2)
    v = zeros(N*N,2)
    gpdps_enep!(u,v,data,params)
    return u,v
end

function test_potts(α=1, γ=1e-3;
                    image     = "blobs",
                    isotropic = true,
                    maxit     = 100000)

    # load test image
    imgfile = joinpath(dirname(pathof(GPDPS)), "..", "img", image*".tif")
    f = Float64.(load(imgfile))
    data = α,γ,f,isotropic

    # compute step size estimates
    τ,σ,ω = estimate_steplengths(f,α,γ,isotropic,expected_max_jump=1.0,γ_for_my=10)
    @printf("Step length parameters: τ = %g, σ = %g, ω = %f\n", τ, σ, ω)
    params = σ,τ,ω,maxit

    # starting points
    u = copy(f)
    v = zeros((size(f)...,2))

    # load reference file to compute errors
    h = string(hash((isotropic,α,γ)));
    ref_file = "ref_" * image * "_" * h * ".jld"
    if isfile(ref_file)
        println("Loading reference file "*ref_file)
        @load ref_file uref vref
    else
        println("No reference file, using uref=(0,0)")
        uref = zero(u)
        vref = zero(v)
    end

    gpdps_potts!(u,v,data,params, uref=uref, vref=vref)

    # save reference file to compute errors
    println("Saving reference file " * ref_file)
    uref = u; vref = v;
    @save ref_file uref vref

    return u,v
end

end


text:
"""
    (new_trace, accepted) = mala(trace, selection::Selection, tau::Real)

Apply a Metropolis-Adjusted Langevin Algorithm (MALA) update.

[Reference URL](https://en.wikipedia.org/wiki/Metropolis-adjusted_Langevin_algorithm)
"""
function mala(trace, selection::Selection, tau::Real)
    args = get_args(trace)
    argdiffs = map((_) -> NoChange(), args)
    std = sqrt(2 * tau)
    retval_grad = accepts_output_grad(get_gen_fn(trace)) ? zero(get_retval(trace)) : nothing

    # forward proposal
    (_, values_trie, gradient_trie) = choice_gradients(trace, selection, retval_grad)
    values = to_array(values_trie, Float64)
    gradient = to_array(gradient_trie, Float64)
    forward_mu = values + tau * gradient
    forward_score = 0.
    proposed_values = Vector{Float64}(undef, length(values))
    for i=1:length(values)
        proposed_values[i] = random(normal, forward_mu[i], std)
        forward_score += logpdf(normal, proposed_values[i], forward_mu[i], std)
    end

    # evaluate model weight
    constraints = from_array(values_trie, proposed_values)
    (new_trace, weight, _, discard) = update(trace,
        args, argdiffs, constraints)

    # backward proposal
    (_, _, backward_gradient_trie) = choice_gradients(new_trace, selection, retval_grad)
    backward_gradient = to_array(backward_gradient_trie, Float64)
    @assert length(backward_gradient) == length(values)
    backward_score = 0.
    backward_mu  = proposed_values + tau * backward_gradient
    for i=1:length(values)
        backward_score += logpdf(normal, values[i], backward_mu[i], std)
    end

    # accept or reject
    alpha = weight - forward_score + backward_score
    if log(rand()) < alpha
        (new_trace, true)
    else
        (trace, false)
    end
end

export mala

max_stars_repo_name: dendisuhubdy/Gen

max_issues_repo_name: kumsh/Gen

max_forks_repo_name: kumsh/Gen


text:
using Documenter, MarineEcosystemsJuliaCon2021
import PlutoSliderServer
using Plots

makedocs(;
    modules=[MarineEcosystemsJuliaCon2021],
    format=Documenter.HTML(),
    repo="https://github.com/JuliaOcean/MarineEcosystemsJuliaCon2021.jl/blob/{commit}{path}#L{line}",
    sitename="MarineEcosystemsJuliaCon2021.jl",
    authors="gaelforget <gforget@mit.edu>",
)

pth = joinpath(@__DIR__, "build")
lst=("AIBECSExample.jl","PlanktonIndividualExample.jl","MITgcm_tutorial_global_oce_biogeo.jl","IndividualDisplacementsExample.jl")
for i in lst
    fil_in=joinpath(@__DIR__,"..","src",i)
    fil_out=joinpath(pth,i[1:end-2]*"html")
    PlutoSliderServer.export_notebook(fil_in)
    mv(fil_in[1:end-2]*"html",fil_out)
    cp(fil_in,fil_out[1:end-4]*"jl")
end

deploydocs(;
    repo="github.com/JuliaOcean/MarineEcosystemsJuliaCon2021.jl",
    devbranch = "main",
)


text:
module CellValuesAppendTests

using Test
using Gridap
using Gridap.CellValuesGallery

# append

vc1_l = [1, 1, 2, 2, 1, 1, 2, 2]
vc1_p = [1, 2, 4, 4, 5, 6, 8, 9]
vc1 = CellVectorFromDataAndPtrs(vc1_l, vc1_p)

vc2_l = [1, 1, 1, 1, 2, 2, 2, 2]
vc2_p = [1, 2, 2, 4, 7, 8, 9]
vc2 = CellVectorFromDataAndPtrs(vc2_l, vc2_p)

vc3_l = [3, 3, 4, 5, 6]
vc3_p = [1, 2, 6]
vc3 = CellVectorFromDataAndPtrs(vc3_l, vc3_p)

vc = append(vc1,vc2,vc3)

a1 = collect(vc1)
a2 = collect(vc2)
a3 = collect(vc3)
a = vcat(a1,a2,a3)

test_index_cell_array(vc,a)

# local_append

vc1_l = [1, 1, 2, 2, 1, 1, 2, 2]
vc1_p = [1, 2, 4, 4, 5, 6, 8, 9]
vc1 = CellVectorFromDataAndPtrs(vc1_l, vc1_p)

vc2_l = [1, 1, 1, 1, 2, 2, 2, 2]
vc2_p = [1, 2, 2, 4, 6, 7, 8, 9]
vc2 = CellVectorFromDataAndPtrs(vc2_l, vc2_p)

vc3_l = [5, 9, 1, 3, 2, 2, 3, 2]
vc3_p = [1, 1, 2, 4, 5, 7, 8, 9]
vc3 = CellVectorFromDataAndPtrs(vc3_l, vc3_p)

o = 30
vc = local_append(o,vc1,vc2)
a1 = collect(vc1)
a2 = collect(vc2)
a3 = collect(vc3)
a = [ vcat(a1i,a2i.+o) for (a1i,a2i) in zip(a1,a2) ]
test_index_cell_array(vc,a)

o2 = 24
o3 = 14
vc = local_append((o2,o3),vc1,vc2,vc3)
a = [ vcat(a1i,a2i.+o2,a3i.+o3) for (a1i,a2i,a3i) in zip(a1,a2,a3) ]
test_index_cell_array(vc,a)

end # module


text:
using Gadfly

set_default_plot_size(6inch, 3inch)

plot(x=[0.236033, 0.346517, 0.312707, 0.00790928, 0.488613, 0.210968, 0.951916, 0.999905, 0.251662, 0.986666],
     y=[0.555751, 0.437108, 0.424718, 0.773223, 0.28119, 0.209472, 0.251379, 0.0203749, 0.287702, 0.859512],
     color=[0.0769509, 0.640396, 0.873544, 0.278582, 0.751313, 0.644883, 0.0778264, 0.848185, 0.0856352, 0.553206],
     Scale.color_continuous(minvalue=-10, maxvalue=10))


text:
push!(LOAD_PATH,"$(pwd())/structures")
push!(LOAD_PATH,"$(pwd())/functions")
include("./load_packages.jl")
include("./load_structures.jl")
include("./load_data.jl")
include("./load_functions.jl")
include("./load_printfunctions.jl")


text:
NamedDimVector = Pair{<:AbstractString,<:QuantityOrUnitlike}

"""
    print_dimensionless([io, ]named_dim_vector, basis)

Print the dimensionless number that can be constructed using `named_dim_vector` in the specified dimensional `basis`.
"""
function print_dimensionless(io::IO, named_dim_vector::NamedDimVector, basis::NamedDimBase)
    powers = -1 * (basis.dim_mat \ dim_matrix(basis.basis_dims, named_dim_vector.second))[:]
    perm = exps_perm(powers)

    showoperators = get(io, :showoperators, false)
    sep = showoperators ? "*" : " "
    showrep(io, named_dim_vector.first, 1//1)
    for i in perm
        if powers[i] != 0
            print(io, sep)
            showrep(io, basis.basis_vector_names[i], powers[i])
        end
    end
    nothing
end

print_dimensionless(named_dim_vector::NamedDimVector, basis::NamedDimBase) =
print_dimensionless(stdout, named_dim_vector, basis)

"""
    showrep(io, identifier, exponent)

Print the `identifier` followed by the corresponding `exponent` to the specified stream `io`.
"""
function showrep(io::IO, identifier::String, exp::Rational)
        print(io, identifier)
        if exp != 1
            exp_str = exp.den == 1 ? "^" * string(exp.num) : "^" * replace(string(exp), "//" => "/")
            print(io, exp_str)
        end
    nothing
end

"""
    exps_perm(powers)
Return the permutation of exponents so that large positive values are showed first followed by large negative values.
"""
function exps_perm(powers)
    perm = sortperm(powers; rev=true)
    first_negative = count(powers .> 0) + 1
    perm[first_negative:end] .= reverse(perm[first_negative:end])
    return perm
end


text:
using ClimateTasks
using Test

@testset "ClimateTasks.jl" begin
    MITgcm()
end


text:
function plotresonancegroups(projects_dir)
    #import Clustering

    PyPlot.close("all")
    fig_num = 1

    Random.seed!(25)
    PyPlot.matplotlib["rcParams"][:update](["font.size" => 22, "font.family" => "serif"])

    #projects_dir = save_folder_path
    #projects_dir = "/home/roy/MEGAsync/outputs/NMR/calibrate/final/Nam2022_Serine"
    #projects_dir = "/home/roy/MEGAsync/outputs/NMR/calibrate/final/L-Serine-700"
    #projects_dir = "/home/roy/MEGAsync/outputs/NMR/calibrate/final/D-(+)-Glucose-NRC-600"

    plots_save_folder = joinpath(projects_dir, "plots")
    isdir(plots_save_folder) || mkdir(plots_save_folder)
    project_title = "resonance groupings"

    T = Float64

    ### load block.
    #load_path = joinpath(joinpath(projects_dir, project_name), "results_full.bson")
    load_path = joinpath(projects_dir, "results_full.bson")
    dict = BSON.load(load_path)
    As = collect( dict[:As][i] for i = 1:length(dict[:As]) )
    Es = collect( NMRSpectraSimulator.κCompoundFIDType(As[i]) for i = 1:length(As) )

    Δsys_cs = convert(Vector{Vector{Float64}}, dict[:Δsys_cs])
    y = convert(Vector{Complex{Float64}}, dict[:y])
    U_y = convert(Vector{Float64}, dict[:U_y])
    SW = dict[:SW]
    fs = dict[:fs]
    ν_0ppm = dict[:ν_0ppm]

    hz2ppmfunc = uu->(uu - ν_0ppm)*SW/fs
    ppm2hzfunc = pp->(ν_0ppm + pp*fs/SW)
    P_y = hz2ppmfunc.(U_y)

    ΩS_ppm = NMRSpectraSimulator.getPsnospininfo(As, hz2ppmfunc)
    ΩS_ppm_sorted = sort(NMRSpectraSimulator.combinevectors(ΩS_ppm))
    u_offset = 0.5
    u_min = ppm2hzfunc(ΩS_ppm_sorted[1] - u_offset)
    u_max = ppm2hzfunc(ΩS_ppm_sorted[end] + u_offset)

    P = LinRange(hz2ppmfunc(u_min), hz2ppmfunc(u_max), 50000)
    U = ppm2hzfunc.(P)

    p_star_set = dict[:p_star_set]
    κ_lb_default = dict[:κ_lb_default]
    κ_ub_default = dict[:κ_ub_default]
    κ_star_set = dict[:κ_star_set]
    d_star_set = dict[:d_star_set]
    β_star_set = dict[:β_star_set]
    λ_star_set = dict[:λ_star_set]
    cost_inds_set = dict[:cost_inds_set]
    w = dict[:w]

    As = collect( Es[n].core for n = 1:length(Es))
    ### end load block.

    hz2ppmfunc = uu->(uu - ν_0ppm)*SW/fs
    ppm2hzfunc = pp->(ν_0ppm + pp*fs/SW)

    ### plot.

    f = uu->NMRSpectraSimulator.evalmixture(uu, As)

    # test params.
    ΩS_ppm = collect( hz2ppmfunc.( NMRSpectraSimulator.combinevectors(A.Ωs) ./ (2*π) ) for A in As )
    #ΩS_ppm_flat = NMRSpectraSimulator.combinevectors(ΩS_ppm)

    P = LinRange(hz2ppmfunc(u_min), hz2ppmfunc(u_max), 50000)
    U = ppm2hzfunc.(P)

    ## parameters that affect qs.
    # A.ss_params.d, A.ss_params.κs_λ, A.ss_params.κs_β
    # A.d_singlets, A.αs_singlets, A.Ωs_singlets, A.β_singlets, A.λ0, A.κs_λ_singlets
    q = uu->NMRSpectraSimulator.evalitpproxymixture(uu, As)

    #g = uu->evalitpproxycompoundresonance(uu, As[1])
    A = As[1]
    g1 = uu->evalitpproxysysresonance(A.qs, uu, A.ss_params.d, A.ss_params.κs_λ, A.ss_params.κs_β)
    g2 = uu->evalsingletsresonance(uu, A.d_singlets, A.αs_singlets, A.Ωs_singlets,
    A.β_singlets, A.λ0, A.κs_λ_singlets)

    f_U = f.(U)
    q_U = q.(U)
    g1_U = g1.(U)
    g2_U = g2.(U)

    #g_qs_U, g_singlets_U = convertresonancetimeseries(g_U)

    z1 = Destruct.destruct(g1_U);
    q_singlets_evals = Destruct.destruct(g2_U);

    # collect( length(z1[i]) for i = 1:length(z1))
    # collect( length(z2[i]) for i = 1:length(z2))
    qs_evals = assembleqsevals(z1, A.qs)

    sanity_check = zeros(Complex{Float64}, length(q_U))
    if !isempty(z1)
        sanity_check += sum(z1)
    end
    if !isempty(q_singlets_evals)
        sanity_check += sum(q_singlets_evals)
    end
    @assert norm(sanity_check - q_U) < 1e-14
    println("sanity: ", norm(sanity_check - q_U))
    println()

    discrepancy = abs.(f_U-q_U)
    max_val, ind = findmax(discrepancy)
    println("relative discrepancy = ", norm(discrepancy)/norm(f_U))
    println("max discrepancy: ", max_val)
    println()

    ## visualize.
    PyPlot.plot(P, real.(f_U), label = "f")
    PyPlot.plot(P, real.(q_U), label = "q")

    #visualizesubgroups(P, qs_evals, q_singlets_evals, real)

    PyPlot.legend()
    PyPlot.xlabel("ppm")
    PyPlot.ylabel("real")
    PyPlot.title("f vs q")

    #@assert 1==2

    plots_save_path = joinpath(plots_save_folder, "groups_real.html")
    title_string = "$(project_title), real"
    savefiggroups(plots_save_path, title_string,
        P, q_U, qs_evals, q_singlets_evals, real)

    #
    plots_save_path = joinpath(plots_save_folder, "groups_imag.html")
    title_string = "$(project_title), imag"
    savefiggroups(plots_save_path, title_string,
        P, q_U, qs_evals, q_singlets_evals, real)
    #
    plots_save_path = joinpath(plots_save_folder, "groups_modulus.html")
    title_string = "$(project_title), modulus"
    savefiggroups(plots_save_path, title_string,
        P, q_U, qs_evals, q_singlets_evals, real)

end


text:
"""
    Plexification{T <: Number} <: Number

An abstract plexification.
"""
abstract type Plexification{T <: Number} <: Number end

"""
    unreal(::T) where T <: Real

The unreal part of a real number is an empty array.
"""
function unreal(::T) where T <: Real
    T[]
end

"""
    array(z::Plexification) -> Array

Return an array with all the `Real` components of `z`.
"""
function array(z::Plexification)
    vcat(real(z), unreal(z))
end

"""
    iszerodivisor(a::Real) -> Bool

Return `true` if a is zero. Equivalent to `iszero(a)`.
"""
function iszerodivisor(a::Real)
    iszero(a)
end

"""
    iszero(z::Plexification) -> Bool

Return `true` if all `Real` components of `z` are zero.
"""
function iszero(z::Plexification)
    iszero(array(z))
end

"""
    isreal(z::Plexification) -> Bool

Return `true` if the unreal part of `z` is zero.
"""
function isreal(z::Plexification)
    iszero(unreal(z))
end

"""
    (+)(z::Plexification)

The identity operation on Cayley-Dickson constructs.
"""
function (+)(z::Plexification)
    z
end

"""
    commutator(x::Plexification, y::Plexification)

Measure the failure of commutativity of the multiplication operation:
```julia
    (x * y) - (y * x)
```
If `commutator(x, y)` is zero, then the multiplication operation is commutative.
"""
function commutator(x::Plexification, y::Plexification)
    (x * y) - (y * x)
end

"""
    associator(x::Plexification, y::Plexification, z::Plexification)

Measure the failure of associativity of the multiplication operation:
```julia
    ((x * y) * z) - (x * (y * z))
```
If `associator(x, y, z)` is zero, then the multiplication operation is associative.
"""
function associator(x::Plexification, y::Plexification, z::Plexification)
    ((x * y) * z) - (x * (y * z))
end

"""
    jacobiator(x::Plexification, y::Plexification, z::Plexification)

Measure the failure of the multiplication operation to satisfy the Jacobi identity:
```julia
    ((x * y) * z) + ((z * x) * y) + ((y * z) * x)
```
If `jacobiator(x, y, z)` is zero, then the multiplication operation satisfies the Jacobi
identity.
"""
function jacobiator(x::Plexification, y::Plexification, z::Plexification)
    ((x * y) * z) + ((z * x) * y) + ((y * z) * x)
end

"""
    alternatorL(x::Plexification, y::Plexification)

Measure the failure of the multiplication operation to be left-alternative:
```julia
    ((x * x) * y) - (x * (x * y))
```
If `alternatorL(x, y)` is zero, then the multiplication operation is left-alternative.
"""
function alternatorL(x::Plexification, y::Plexification)
    associator(x, x, y)
end

"""
    alternatorR(x::Plexification, y::Plexification)

Measure the failure of the multiplication operation to be right-alternative:
```julia
    ((x * y) * y) - (x * (y * y))
```
If `alternatorR(x, y)` is zero, then the multiplication operation is right-alternative.
"""
function alternatorR(x::Plexification, y::Plexification)
    associator(x, y, y)
end

"""
    flexator(x::Plexification, y::Plexification)

Measure the failure of the multiplication operation to be flexible:
```julia
    ((x * y) * x) - (x * (y * x))
```
If `flexator(x, y)` is zero, then the multiplication operation is flexible.
"""
function flexator(x::Plexification, y::Plexification)
    associator(x, y, x)
end

"""
    (/)(x::Plexification, y::Plexification)

Naive right quotient of two Cayley-Dickson constructs.
Equivalent to multiplying `x` on the right by the inverse of `y`.
"""
function (/)(x::Plexification, y::Plexification)
    x * inv(y)
end

"""
    (\\)(y::Plexification, x::Plexification)

Naive left quotient of two Cayley-Dickson constructs.
Equivalent to multiplying `x` on the left by the inverse of `y`.
"""
function (\)(y::Plexification, x::Plexification)
    inv(y) * x
end

"""
    (/)(a::Real, z::Plexification)

Equivalent to multiplying the inverse of `z` by `a`.
"""
function (/)(a::Real, z::Plexification)
    a * inv(z)
end

"""
    (\\)(z::Plexification, a::Real)

Equivalent to multiplying the inverse of `z` by `a`.
"""
function (\)(z::Plexification, a::Real)
    inv(z) * a
end


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

using Markdown
using InteractiveUtils

# ╔═╡ 95215666-c5d8-11ec-33b4-cb787d5b56ad
begin
	using Symbolics
	@variables x y t     # 定义三个变量
	D = Differential(t)  # 定义微分算子
end

# ╔═╡ b02e68e6-b91a-4537-8689-51c338bf4a33
begin
	z = x^2 + y
end

# ╔═╡ 583ac52b-4d0e-49c3-8a79-322493d2af86
md">以数组形式传递函数参数效率很高, 类似于你干活需要有很多工具, 把工具放到工具箱里,这时候需要什么工具的时候直接取出来用就可以了, 不需要在用的时候慢慢去找工具在那里."

# ╔═╡ 78f7c1ba-c041-410c-859a-f10523b4d34a
begin

	function f(u)
  		[u[1] - u[3], u[1]^2 - u[2], u[3] + u[2]]
	end
	f([x, y, z])
end

# ╔═╡ 14e2181b-8aa7-4458-baf1-a14d1cdfd401
let
	z = t + t^2
	dz=expand_derivatives(D(z))

end

# ╔═╡ 44368169-b68d-4669-bdb6-d84476be342e
begin
	Symbolics.jacobian([x + x*y, x^2 + y], [x, y])
end

# ╔═╡ 00000000-0000-0000-0000-000000000001
PLUTO_PROJECT_TOML_CONTENTS = """
[deps]
Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7"

[compat]
Symbolics = "~4.4.2"
"""

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

julia_version = "1.7.1"
manifest_format = "2.0"

[[deps.AbstractAlgebra]]
deps = ["GroupsCore", "InteractiveUtils", "LinearAlgebra", "MacroTools", "Markdown", "Random", "RandomExtensions", "SparseArrays", "Test"]
git-tree-sha1 = "f4a6ecff7407a29d5d15503508144b7cc81bdc63"
uuid = "c3fe647b-3220-5bb0-a1ea-a7954cac585d"
version = "0.25.3"

[[deps.AbstractTrees]]
git-tree-sha1 = "03e0550477d86222521d254b741d470ba17ea0b5"
uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c"
version = "0.3.4"

[[deps.Adapt]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "af92965fb30777147966f58acb05da51c5616b5f"
uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
version = "3.3.3"

[[deps.ArgCheck]]
git-tree-sha1 = "a3a402a35a2f7e0b87828ccabbd5ebfbebe356b4"
uuid = "dce04be8-c92d-5529-be00-80e4d2c0e197"
version = "2.3.0"

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

[[deps.ArrayInterface]]
deps = ["Compat", "IfElse", "LinearAlgebra", "Requires", "SparseArrays", "Static"]
git-tree-sha1 = "c933ce606f6535a7c7b98e1d86d5d1014f730596"
uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9"
version = "5.0.7"

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

[[deps.AutoHashEquals]]
git-tree-sha1 = "45bb6705d93be619b81451bb2006b7ee5d4e4453"
uuid = "15f4f7f2-30c1-5605-9d31-71845cf9641f"
version = "0.2.0"

[[deps.BangBang]]
deps = ["Compat", "ConstructionBase", "Future", "InitialValues", "LinearAlgebra", "Requires", "Setfield", "Tables", "ZygoteRules"]
git-tree-sha1 = "b15a6bc52594f5e4a3b825858d1089618871bf9d"
uuid = "198e06fe-97b7-11e9-32a5-e1d131e6ad66"
version = "0.3.36"

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

[[deps.Baselet]]
git-tree-sha1 = "aebf55e6d7795e02ca500a689d326ac979aaf89e"
uuid = "9718e550-a3fa-408a-8086-8db961cd8217"
version = "0.1.1"

[[deps.Bijections]]
git-tree-sha1 = "705e7822597b432ebe152baa844b49f8026df090"
uuid = "e2ed5e7c-b2de-5872-ae92-c73ca462fb04"
version = "0.1.3"

[[deps.ChainRulesCore]]
deps = ["Compat", "LinearAlgebra", "SparseArrays"]
git-tree-sha1 = "9950387274246d08af38f6eef8cb5480862a435f"
uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
version = "1.14.0"

[[deps.ChangesOfVariables]]
deps = ["ChainRulesCore", "LinearAlgebra", "Test"]
git-tree-sha1 = "bf98fa45a0a4cee295de98d4c1462be26345b9a1"
uuid = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0"
version = "0.1.2"

[[deps.Combinatorics]]
git-tree-sha1 = "08c8b6831dc00bfea825826be0bc8336fc369860"
uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa"
version = "1.0.2"

[[deps.CommonSolve]]
git-tree-sha1 = "68a0743f578349ada8bc911a5cbd5a2ef6ed6d1f"
uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2"
version = "0.2.0"

[[deps.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 = "b153278a25dd42c65abbf4e62344f9d22e59191b"
uuid = "34da2185-b29b-5c13-b0c7-acf172513d20"
version = "3.43.0"

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

[[deps.CompositeTypes]]
git-tree-sha1 = "d5b014b216dc891e81fea299638e4c10c657b582"
uuid = "b152e2b5-7a66-4b01-a709-34e65c35f657"
version = "0.1.2"

[[deps.CompositionsBase]]
git-tree-sha1 = "455419f7e328a1a2493cabc6428d79e951349769"
uuid = "a33af91c-f02d-484b-be07-31d278c5ca2b"
version = "0.1.1"

[[deps.ConstructionBase]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "f74e9d5388b8620b4cee35d4c5a618dd4dc547f4"
uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9"
version = "1.3.0"

[[deps.DataAPI]]
git-tree-sha1 = "fb5f5316dd3fd4c5e7c30a24d50643b73e37cd40"
uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a"
version = "1.10.0"

[[deps.DataStructures]]
deps = ["Compat", "InteractiveUtils", "OrderedCollections"]
git-tree-sha1 = "3daef5523dd2e769dad2365274f760ff5f282c7d"
uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
version = "0.18.11"

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

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

[[deps.DefineSingletons]]
git-tree-sha1 = "0fba8b706d0178b4dc7fd44a96a92382c9065c2c"
uuid = "244e2a9f-e319-4986-a169-4d1fe445cd52"
version = "0.1.2"

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

[[deps.DensityInterface]]
deps = ["InverseFunctions", "Test"]
git-tree-sha1 = "80c3e8639e3353e5d2912fb3a1916b8455e2494b"
uuid = "b429d917-457f-4dbc-8f4c-0cc954292b1d"
version = "0.4.0"

[[deps.DiffRules]]
deps = ["IrrationalConstants", "LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"]
git-tree-sha1 = "dd933c4ef7b4c270aacd4eb88fa64c147492acf0"
uuid = "b552c78f-8df3-52c6-915a-8e097449b14b"
version = "1.10.0"

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

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

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

[[deps.DomainSets]]
deps = ["CompositeTypes", "IntervalSets", "LinearAlgebra", "StaticArrays", "Statistics"]
git-tree-sha1 = "5f5f0b750ac576bcf2ab1d7782959894b304923e"
uuid = "5b8099bc-c8ec-5219-889f-1d9e522a28bf"
version = "0.5.9"

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

[[deps.DynamicPolynomials]]
deps = ["DataStructures", "Future", "LinearAlgebra", "MultivariatePolynomials", "MutableArithmetics", "Pkg", "Reexport", "Test"]
git-tree-sha1 = "d0fa82f39c2a5cdb3ee385ad52bc05c42cb4b9f0"
uuid = "7c1d4256-1411-5781-91ec-d7bc3513ac07"
version = "0.4.5"

[[deps.EllipsisNotation]]
deps = ["ArrayInterface"]
git-tree-sha1 = "d064b0340db45d48893e7604ec95e7a2dc9da904"
uuid = "da5c29d0-fa7d-589e-88eb-ea29b0a81949"
version = "1.5.0"

[[deps.ExprTools]]
git-tree-sha1 = "56559bbef6ca5ea0c0818fa5c90320398a6fbf8d"
uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04"
version = "0.1.8"

[[deps.FillArrays]]
deps = ["LinearAlgebra", "Random", "SparseArrays", "Statistics"]
git-tree-sha1 = "246621d23d1f43e3b9c368bf3b72b2331a27c286"
uuid = "1a297f60-69ca-5386-bcde-b61e274b549b"
version = "0.13.2"

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

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

[[deps.Groebner]]
deps = ["AbstractAlgebra", "Combinatorics", "Logging", "MultivariatePolynomials", "Primes", "Random"]
git-tree-sha1 = "18e3139ab69bfc03a8609027fd0e5572a5cffe6e"
uuid = "0b43b601-686d-58a3-8a1c-6623616c7cd4"
version = "0.2.3"

[[deps.GroupsCore]]
deps = ["Markdown", "Random"]
git-tree-sha1 = "9e1a5e9f3b81ad6a5c613d181664a0efc6fe6dd7"
uuid = "d5909c97-4eac-4ecc-a3dc-fdd0858a4120"
version = "0.4.0"

[[deps.IfElse]]
git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1"
uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173"
version = "0.1.1"

[[deps.InitialValues]]
git-tree-sha1 = "4da0f88e9a39111c2fa3add390ab15f3a44f3ca3"
uuid = "22cec73e-a1b8-11e9-2c92-598750a2cf9c"
version = "0.3.1"

[[deps.IntegerMathUtils]]
git-tree-sha1 = "f366daebdfb079fd1fe4e3d560f99a0c892e15bc"
uuid = "18e54dd8-cb9d-406c-a71d-865a43cbb235"
version = "0.1.0"

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

[[deps.IntervalSets]]
deps = ["Dates", "EllipsisNotation", "Statistics"]
git-tree-sha1 = "bcf640979ee55b652f3b01650444eb7bbe3ea837"
uuid = "8197267c-284f-5f27-9208-e0e47529a953"
version = "0.5.4"

[[deps.InverseFunctions]]
deps = ["Test"]
git-tree-sha1 = "91b5dcf362c5add98049e6c29ee756910b03051d"
uuid = "3587e190-3f89-42d0-90ee-14403ec27112"
version = "0.1.3"

[[deps.IrrationalConstants]]
git-tree-sha1 = "7fd44fd4ff43fc60815f8e764c0f352b83c49151"
uuid = "92d709cd-6900-40b7-9082-c6be49f344b6"
version = "0.1.1"

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

[[deps.JLLWrappers]]
deps = ["Preferences"]
git-tree-sha1 = "abc9885a7ca2052a736a600f7fa66209f96506e1"
uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210"
version = "1.4.1"

[[deps.LaTeXStrings]]
git-tree-sha1 = "f2355693d6778a178ade15952b7ac47a4ff97996"
uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
version = "1.3.0"

[[deps.LabelledArrays]]
deps = ["ArrayInterface", "ChainRulesCore", "LinearAlgebra", "MacroTools", "StaticArrays"]
git-tree-sha1 = "fbd884a02f8bf98fd90c53c1c9d2b21f9f30f42a"
uuid = "2ee39098-c373-598a-b85f-a56591580800"
version = "1.8.0"

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

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

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

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

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

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

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

[[deps.LogExpFunctions]]
deps = ["ChainRulesCore", "ChangesOfVariables", "DocStringExtensions", "InverseFunctions", "IrrationalConstants", "LinearAlgebra"]
git-tree-sha1 = "a970d55c2ad8084ca317a4658ba6ce99b7523571"
uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688"
version = "0.3.12"

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

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

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

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

[[deps.Metatheory]]
deps = ["AutoHashEquals", "DataStructures", "Dates", "DocStringExtensions", "Parameters", "Reexport", "TermInterface", "ThreadsX", "TimerOutputs"]
git-tree-sha1 = "0886d229caaa09e9f56bcf1991470bd49758a69f"
uuid = "e9d8d322-4543-424a-9be4-0cc815abe26c"
version = "1.3.3"

[[deps.MicroCollections]]
deps = ["BangBang", "InitialValues", "Setfield"]
git-tree-sha1 = "6bb7786e4f24d44b4e29df03c69add1b63d88f01"
uuid = "128add7d-3638-4c79-886c-908ea0c25c34"
version = "0.1.2"

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

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

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

[[deps.MultivariatePolynomials]]
deps = ["ChainRulesCore", "DataStructures", "LinearAlgebra", "MutableArithmetics"]
git-tree-sha1 = "393fc4d82a73c6fe0e2963dd7c882b09257be537"
uuid = "102ac46a-7ee4-5c85-9060-abc95bfdeaa3"
version = "0.4.6"

[[deps.MutableArithmetics]]
deps = ["LinearAlgebra", "SparseArrays", "Test"]
git-tree-sha1 = "ba8c0f8732a24facba709388c74ba99dcbfdda1e"
uuid = "d8a4904e-b15c-11e9-3269-09a3773c0cb0"
version = "1.0.0"

[[deps.NaNMath]]
git-tree-sha1 = "b086b7ea07f8e38cf122f5016af580881ac914fe"
uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3"
version = "0.3.7"

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

[[deps.OpenBLAS_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"]
uuid = "4536629a-c528-5b80-bd46-f80d51c5b363"

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

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

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

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

[[deps.Parameters]]
deps = ["OrderedCollections", "UnPack"]
git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe"
uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a"
version = "0.12.3"

[[deps.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"

[[deps.Preferences]]
deps = ["TOML"]
git-tree-sha1 = "47e5f437cc0e7ef2ce8406ce1e7e24d44915f88d"
uuid = "21216c6a-2e73-6563-6e65-726566657250"
version = "1.3.0"

[[deps.Primes]]
deps = ["IntegerMathUtils"]
git-tree-sha1 = "747f4261ebe38a2bc6abf0850ea8c6d9027ccd07"
uuid = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae"
version = "0.5.2"

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

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

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

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

[[deps.RandomExtensions]]
deps = ["Random", "SparseArrays"]
git-tree-sha1 = "062986376ce6d394b23d5d90f01d81426113a3c9"
uuid = "fb686558-2515-59ef-acaa-46db3789a887"
version = "0.4.3"

[[deps.RecipesBase]]
git-tree-sha1 = "6bf3f380ff52ce0832ddd3a2a7b9538ed1bcca7d"
uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
version = "1.2.1"

[[deps.RecursiveArrayTools]]
deps = ["Adapt", "ArrayInterface", "ChainRulesCore", "DocStringExtensions", "FillArrays", "LinearAlgebra", "RecipesBase", "Requires", "StaticArrays", "Statistics", "ZygoteRules"]
git-tree-sha1 = "bfe14f127f3e7def02a6c2b1940b39d0dabaa3ef"
uuid = "731186ca-8d62-57ce-b412-fbd966d074cd"
version = "2.26.3"

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

[[deps.Referenceables]]
deps = ["Adapt"]
git-tree-sha1 = "e681d3bfa49cd46c3c161505caddf20f0e62aaa9"
uuid = "42d2dcc6-99eb-4e98-b66c-637b7d73030e"
version = "0.1.2"

[[deps.Requires]]
deps = ["UUIDs"]
git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7"
uuid = "ae029012-a4dd-5104-9daa-d747884805df"
version = "1.3.0"

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

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

[[deps.RuntimeGeneratedFunctions]]
deps = ["ExprTools", "SHA", "Serialization"]
git-tree-sha1 = "cdc1e4278e91a6ad530770ebb327f9ed83cf10c4"
uuid = "7e49a35a-f44a-4d26-94aa-eba1b4ca6b47"
version = "0.5.3"

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

[[deps.SciMLBase]]
deps = ["ArrayInterface", "CommonSolve", "ConstructionBase", "Distributed", "DocStringExtensions", "IteratorInterfaceExtensions", "LinearAlgebra", "Logging", "Markdown", "RecipesBase", "RecursiveArrayTools", "StaticArrays", "Statistics", "Tables", "TreeViews"]
git-tree-sha1 = "a5305dca1b3ebf83d9c92e2fa244424f1bdb1627"
uuid = "0bca4576-84f4-4d90-8ffe-ffa030f20462"
version = "1.31.0"

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

[[deps.Setfield]]
deps = ["ConstructionBase", "Future", "MacroTools", "Requires"]
git-tree-sha1 = "38d88503f695eb0301479bc9b0d4320b378bafe5"
uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46"
version = "0.8.2"

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

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

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

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

[[deps.SpecialFunctions]]
deps = ["ChainRulesCore", "IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"]
git-tree-sha1 = "5ba658aeecaaf96923dce0da9e703bd1fe7666f9"
uuid = "276daf66-3868-5448-9aa4-cd146d93841b"
version = "2.1.4"

[[deps.SplittablesBase]]
deps = ["Setfield", "Test"]
git-tree-sha1 = "39c9f91521de844bad65049efd4f9223e7ed43f9"
uuid = "171d559e-b47b-412a-8079-5efa626c420e"
version = "0.1.14"

[[deps.Static]]
deps = ["IfElse"]
git-tree-sha1 = "2114b1d8517764a8c4625a2e97f40640c7a301a7"
uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3"
version = "0.6.1"

[[deps.StaticArrays]]
deps = ["LinearAlgebra", "Random", "Statistics"]
git-tree-sha1 = "cd56bf18ed715e8b09f06ef8c6b781e6cdc49911"
uuid = "90137ffa-7385-5640-81b9-e52037218182"
version = "1.4.4"

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

[[deps.StatsAPI]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "c82aaa13b44ea00134f8c9c89819477bd3986ecd"
uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0"
version = "1.3.0"

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

[[deps.StatsFuns]]
deps = ["ChainRulesCore", "InverseFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"]
git-tree-sha1 = "5950925ff997ed6fb3e985dcce8eb1ba42a0bbe7"
uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c"
version = "0.9.18"

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

[[deps.SymbolicUtils]]
deps = ["AbstractTrees", "Bijections", "ChainRulesCore", "Combinatorics", "ConstructionBase", "DataStructures", "DocStringExtensions", "DynamicPolynomials", "IfElse", "LabelledArrays", "LinearAlgebra", "Metatheory", "MultivariatePolynomials", "NaNMath", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArrays", "TermInterface", "TimerOutputs"]
git-tree-sha1 = "bfa211c9543f8c062143f2a48e5bcbb226fd790b"
uuid = "d1185830-fcd6-423d-90d6-eec64667417b"
version = "0.19.7"

[[deps.Symbolics]]
deps = ["ArrayInterface", "ConstructionBase", "DataStructures", "DiffRules", "Distributions", "DocStringExtensions", "DomainSets", "Groebner", "IfElse", "Latexify", "Libdl", "LinearAlgebra", "MacroTools", "Metatheory", "NaNMath", "RecipesBase", "Reexport", "Requires", "RuntimeGeneratedFunctions", "SciMLBase", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArrays", "SymbolicUtils", "TermInterface", "TreeViews"]
git-tree-sha1 = "31f8130b2ee33985f10d7999ece5ed7d72c1be70"
uuid = "0c5d862f-8b57-4792-8d23-62f2024744c7"
version = "4.4.2"

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

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

[[deps.Tables]]
deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits", "Test"]
git-tree-sha1 = "5ce79ce186cc678bbb5c5681ca3379d1ddae11a1"
uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
version = "1.7.0"

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

[[deps.TermInterface]]
git-tree-sha1 = "7aa601f12708243987b88d1b453541a75e3d8c7a"
uuid = "8ea1fca8-c5ef-4a55-8b96-4e9afe9c9a3c"
version = "0.2.3"

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

[[deps.ThreadsX]]
deps = ["ArgCheck", "BangBang", "ConstructionBase", "InitialValues", "MicroCollections", "Referenceables", "Setfield", "SplittablesBase", "Transducers"]
git-tree-sha1 = "d223de97c948636a4f34d1f84d92fd7602dc555b"
uuid = "ac1d9e8a-700a-412c-b207-f0111f4b6c0d"
version = "0.1.10"

[[deps.TimerOutputs]]
deps = ["ExprTools", "Printf"]
git-tree-sha1 = "11db03dd5bbc0d2b57a570d228a0f34538c586b1"
uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f"
version = "0.5.17"

[[deps.Transducers]]
deps = ["Adapt", "ArgCheck", "BangBang", "Baselet", "CompositionsBase", "DefineSingletons", "Distributed", "InitialValues", "Logging", "Markdown", "MicroCollections", "Requires", "Setfield", "SplittablesBase", "Tables"]
git-tree-sha1 = "c76399a3bbe6f5a88faa33c8f8a65aa631d95013"
uuid = "28d57a85-8fef-5791-bfe6-a80928e7c999"
version = "0.4.73"

[[deps.TreeViews]]
deps = ["Test"]
git-tree-sha1 = "8d0d7a3fe2f30d6a7f833a5f19f7c7a5b396eae6"
uuid = "a2a6695c-b41b-5b7d-aed9-dbfdeacea5d7"
version = "0.3.0"

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

[[deps.UnPack]]
git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b"
uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed"
version = "1.0.2"

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

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

[[deps.ZygoteRules]]
deps = ["MacroTools"]
git-tree-sha1 = "8c1a8e4dfacb1fd631745552c8db35d0deb09ea0"
uuid = "700de1a5-db45-46bc-99cf-38207098b444"
version = "0.2.2"

[[deps.libblastrampoline_jll]]
deps = ["Artifacts", "Libdl", "OpenBLAS_jll"]
uuid = "8e850b90-86db-534c-a0d3-1478176c7d93"

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

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

# ╔═╡ Cell order:
# ╠═95215666-c5d8-11ec-33b4-cb787d5b56ad
# ╠═b02e68e6-b91a-4537-8689-51c338bf4a33
# ╠═583ac52b-4d0e-49c3-8a79-322493d2af86
# ╠═78f7c1ba-c041-410c-859a-f10523b4d34a
# ╠═14e2181b-8aa7-4458-baf1-a14d1cdfd401
# ╠═44368169-b68d-4669-bdb6-d84476be342e
# ╟─00000000-0000-0000-0000-000000000001
# ╟─00000000-0000-0000-0000-000000000002

max_stars_repo_name: phpsmarter/plutonote

max_issues_repo_name: phpsmarter/plutonote

max_forks_repo_name: phpsmarter/plutonote