text:
developing = false; # are you developing the package or just using?
if developing
	# ] add Revise # if you don't have it
    path = pwd()
    if path[end-6:end] != "MatLang"
        error("cd(to the MatLang path)")
    end
    push!(LOAD_PATH, ".")
    using Revise
    using MatLang
else
    using MatLang
end
################################################################
################################################################
mzero0 = zerosM(:mat, 2) # same as zeros(2,2)

mzero1 = zerosM(:mat, 2, like = zerosM(Int32, 2, 2)) # like method

A=[2 1 2]
mzero2 = zerosM(2, like=A) # same as zeros(Int64,2)

mzero3 = zerosM(2) # same as zeros(2)

mzero4 = zerosM(Int32, 2, 2) # same as zeros(Int32,2,2)

# giving size as Tuple
mzero5 = zerosM((2, 2)) # = zerosM(2,2)

mzero6 = zerosM(Int32, (2, 2))

# giving size as an Array
## non-efficient Matlab way. Array should be Integer otherwise you will get errors.

mzero7 = zerosM([2, 2])

mzero8 = zerosM(Int32, [2, 2])

mzero9 = zerosM([2, 2], like = [2.5 3.0])
################################################################
mone0 = onesM(:mat, 2) # same as ones(2,2)

mone1 = onesM(:mat, 2, like = onesM(Int32, 2, 2)) # like method

A=[2 1 2]
mone2 = onesM(2, like=A) # same as ones(Int64,2)

mone3 = onesM(2) # same as ones(2)

mone4 = onesM(Int32, 2, 2) # same as ones(Int32,2,2)

# giving size as Tuple
mone5 = onesM((2, 2)) # = onesM(2,2)

mone6 = onesM(Int32, (2, 2))

# giving size as an Array
## non-efficient Matlab way. Array should be Integer otherwise you will get errors.

mone7 = onesM([2, 2])

mone8 = onesM(Int32, [2, 2])

mone9 = onesM([2, 2], like = [2.5 3.0])
################################################################
mrandom0 = randM(:mat, 2) # same as rand(2,2)

mrandom1 = randM(:mat, 2, like = randM(Int32, 2, 2)) # like method

A=[2 1 2]
mrandom2 = randM(2, like=A) # same as rand(Int64,2)

mrandom3 = randM(2) # same as rand(2)

mrandom4 = randM(Int32, 2, 2) # same as rand(Int32,2,2)

# giving size as Tuple
mrandom5 = randM((2, 2)) # = randM(2,2)

mrandom6 = randM(Int32, (2, 2))

# giving size as an Array
## non-efficient Matlab way. Array should be Integer otherwise you will get errors.

mrandom7 = randM([2, 2])

mrandom8 = randM(Int32, [2, 2])

mrandom9 = randM([2, 2], like = [2.5 3.0])
################################################################
mtrue0 = trueM(:mat, 2) # same as trues(2,2)

mtrue1 = trueM(2) # same as trues(2)

# giving size as Tuple
mtrue2 = trueM((2, 2)) # = trues(2,2)

# giving size as an Array
## non-efficient Matlab way. Array should be Integer otherwise you will get errors.
mtrue3 = trueM([2, 2])
################################################################
mfalse0 = falseM(:mat, 2) # same as falses(2,2)

mfalse1 = falseM(2) # same as falses(2)

# giving size as Tuple
mfalse2 = falseM((2, 2)) # = falses(2,2)

# giving size as an Array
## non-efficient Matlab way. Array should be Integer otherwise you will get errors.
mfalse3 = falseM([2, 2])
################################################################
mEye0 = eyeM(2); # [1 0 0; 0 1 0]

mEye1 = eyeM(2, 3); # [1 0 0; 0 1 0]

mEye2 = eyeM(Int32, 2, 3); # [1 0 0; 0 1 0]

mEye3 = eyeM(2, 3, like = zerosM(Int8, 2, 2))

mEye4 = eyeM((2, 2))  # giving size as a Tuple. In Julia we use (2,2) instead of giving it as [2,2]

mEye5 = eyeM(Int32, (2, 2))  # giving size as a Tuple. In Julia we use (2,2) instead of giving it as [2,2]

mEye6 = eyeM([2, 2]) # non-efficient Matlab way

mEye7 = eyeM(Int32, [2, 2]) # non-efficient Matlab way

s1 = size(ones(2, 3)) # getting size from another matrix or calculation
mEye8 = eyeM(s1)  # giving size as a variable (Tuple).
################################################################
mDiag = diagM([2, 3, 4]) # [0 2 0 ; 0 3 0; 0 4]

mDiag2 = diagM([2, 3, 4], 1) # [0 2 3 0; 0 0 3 0; 0 0 0 4; 0 0 0 0]

mDiag3 = diagM([1 2 3; 4 5 6; 7 8 9]) # [1;5;9]

mDiag4 = diagM([1 2 3; 4 5 6; 7 8 9], 1) # [2;6]
################################################################
A1 = 3 * ones(2, 2);
A2 = 4 * ones(2, 2);
A3 = rand(3, 3);
mBlkdiag1 = blkdiagM(A1, A2, A3)

mBlkdiag2 = blkdiagM(ones(2, 2), 2 * ones(2, 2)) # [ones(2, 2) zeros(2, 2); zeros(2, 2)  2 * ones(2, 2)]

A1 = ones(2, 4);
A2 = 2 * ones(3, 2);
mBlkdiag3 = blkdiagM(A1, A2) # [ones(2,4) zeros(2,2); zeros(3,4) 2*ones(3,2)]

mBlkdiag1obj = blkdiagM(:obj, A1, A2, A3) # returning BlockDiagonal object

mBlkdiag2obj = blkdiagM(:obj, ones(2, 2), 2 * ones(2, 2)) # returning BlockDiagonal object for [ones(2, 2) zeros(2, 2); zeros(2, 2)  2 * ones(2, 2)]
################################################################
mCat1 = catM(1, ones(3, 3), zeros(3, 3)) # [ones(3, 3); zeros(3, 3)]

mCat2 = catM(2, ones(3, 3), zeros(3, 3)) # [ones(3, 3) zeros(3, 3)]

mCat3 = catM(1, ones(3, 3), zeros(3, 3), 2 * ones(3, 3)) # [ones(3, 3); zeros(3, 3); 2 * ones(3, 3)]

mCat4 = catM(3, ones(2, 2, 2), zeros(2, 2, 2)) # [ones(2, 2, 2) zeros(2, 2, 2)]
################################################################
mHCat1 = horzcatM(ones(3, 3), zeros(3, 3)) # [ones(3, 3) zeros(3, 3)]
################################################################
mVCat1 = vertcatM(ones(3, 3), zeros(3, 3)) # [ones(3, 3); zeros(3, 3)]
################################################################
V1 = [1 2 3 4];
mRepelem1 = repelemM(V1, 3) # [1 1 1 2 2 2 3 3 3 4 4 4]

# mRepelem2 = repelemM(V1, (3,2,1,1)) # [1 1 1 2 2 3 4]

# mRepelem3 = repelemM(V1, vec([3 2 1 1])) # [1 1 1 2 2 3 4]
################################################################
mRempat1 = repmatM(10, 3, 2) # [10 10; 10 10; 10 10]

V = [1; 2]
mRempat2 = repmatM(V, 3, 2)   # [[1; 2] [1; 2]; [1; 2] [1; 2]; [1; 2] [1; 2]]

mRempat3 = repmatM(V, [3, 2]) # [[1; 2] [1; 2]; [1; 2] [1; 2]; [1; 2] [1; 2]]

mRempat4 = repmatM(V, (3, 2)) # [[1; 2] [1; 2]; [1; 2] [1; 2]; [1; 2] [1; 2]]

mRempat5 = repmatM(V, 2) # [[1; 2] [1; 2]; [1; 2] [1; 2]]

mRempat6 = repmatM(V, 1, 3) # [[1; 2] [1; 2] [1; 2]]
################################################################
mLinspace1 = linspaceM(1, 10) # 1:10

mLinspace2 = linspaceM(1, 10, 2) # 1:2:10 == 1:2:9

mLinspace3 = linspaceM(:arr, 1, 10) # collect(1:10)

mLinspace4 = linspaceM(:arr, 1, 10, 2) # collect(1:2:10)
################################################################
mLogspace1 = logspaceM(1, 5) # 50 logarithmically spaced points between 10^1 and 10^5

mLogspace2 = logspaceM(1, 5, 10) # 10 logarithmically spaced points between 10^1 and 10^5

mLogspace3 = logspaceM(1, 5, :equal) # [10.0^1, 10.0^2, 10.0^3, 10.0^4, 10.0^5] == 10.0.^(1:5)
################################################################
m1Meshgrid0, m2Meshgrid0 = meshgridM(1:2:5) # a 2-D rectangle spanning 1:2:5 in x and y direction == [[1;1;1][3;3;3] [5;5;5]] and [1 1 1; 3 3 3; 5 5 5]

m1Meshgrid1, m2Meshgrid1 = meshgridM(1:2:5, 1:2:5) #  a 2-D rectangle spanning 1:2:5 in x and y direction == ([1 3 5;1 3 5; 1 3 5],[1 1 1; 3 3 3; 5 5 5])

m1Meshgrid2, m2Meshgrid2, m3Meshgrid2 = meshgridM(1:6, 20:25, 5:10) # a 3-D rectangle spanning 1:6 in x, 20:25 in y, and 5:10 in z
################################################################
m1Ndgrid0, m2Ndgrid0 = ndgridM(1:2:5, dim = 2) # a 2-D rectangle spanning 1:2:5 in x and y direction == [1 1 1; 3 3 3; 5 5 5] and [1 3 5;1 3 5; 1 3 5]

m1Ndgrid1, m2Ndgrid1 = ndgridM(1:2:5, 1:2:5) #  a 2-D rectangle spanning 1:2:5 in x and y direction == ([1 1 1; 3 3 3; 5 5 5], [1 3 5;1 3 5; 1 3 5])

m1Ndgrid2, m2Ndgrid2, m3Ndgrid2 = ndgridM(1:6, 20:25, 5:10) # a 3-D rectangle spanning 1:6 in x, 20:25 in y, and 5:10 in z
################################################################
mFreqspace1 = freqspaceM(10, dim = 1) # 0:0.2:1

mFreqspace2 = freqspaceM(10, :whole, dim = 1) # 0:0.2:1.8

m1Freqspace3, m2Freqspace3 = freqspaceM(10, dim = 2) # returns two -1:0.2:0.8

m1Freqspace4, m2Freqspace4 = freqspaceM(10, :meshgrid, dim = 2) # returns mesgridM(-1:0.2:0.8, -1:0.2:0.8), which is two -1:0.2:0.8
################################################################
A1 = [2 3 4 5 6 7;
      1 2 3 4 5 6]
nLength1 = lengthM(A1); # 6

A2 = ["Hi" 6;
      "Goodbye" 5;
      "Hello" 1]
nLength2 = lengthM(A2); # 3
################################################################
A1 = [2 3 4 5 6 7;
      1 2 3 4 5 6]
mSize1 = sizeM(:arr, A1); # [2; 6]
tSize1 = sizeM(A1); # (2, 6)

nA1Size2 = sizeM(A1, 2); # 6
sizeM(A1, 2) == 6 # true
sizeM(:arr, A1, 2) == 6 # false
sizeM(:arr, A1, 2) == [6] # true

nA1Size1, nA1Size2 = sizeM(A1); # 2 and 6

A2 = rand(3, 5, 4)
mSize2 = sizeM(:arr, A2, 2, 3); # [5; 4]
tSize2 = sizeM(A2, 2, 3); # (5, 4)
################################################################
A = rand(3,4,5);
nDim1 = ndims(A) # 3
################################################################
nNumel1 = numelM(1:5) # 5

nNumel2 = numelM([1, 2, 3, 4]) # 4

nNumel3 = numelM([1 2; 3 4]) # 4
################################################################
bIsscalar1 = isscalarM(1) # true

bIsscalar2 = isscalarM(5 * ones(1, 1, 1)) # false

# bIsscalar3 = isscalarM("H") # gives error
#
# bIsscalar4 = isscalarM("Hi") # gives error

bIsscalar5 = isscalarM(["Hi"]) # false

bIsscalar6 = isscalarM(["Hi" "Bye"]) # false

bIsscalar7 = isscalarM('H') # true # becareful that in Julia, chars are always singular.

bIsscalar8 = isscalarM(true) # true

# Matlab way:
bIsscalarMat1 = isscalarM(:mat, 1) # true

bIsscalarMat2 = isscalarM(:mat, [1]) # true

bIsscalarMat3 = isscalarM(:mat, 5 * ones(1, 1, 1)) # true

bIsscalarMat4 = isscalarM(:mat, "H") # true

bIsscalarMat5 = isscalarM(:mat, "Hi") # false

bIsscalarMat6 = isscalarM(:mat, ["Hi"]) # true

bIsscalarMat7 = isscalarM(:mat, ["Hi" "Bye"]) # false

bIsscalarMat8 = isscalarM(:mat, 'H') # true # becareful that in Julia, chars are always singular.

bIsscalarMat9 = isscalarM(:mat, true) # true
################################################################
A1 = [1; 2; 3] # or [1, 2, 3]
bIsvector1 = isvectorM(A1) # true

A2 = [1 2 3]
bIsvector2 = isvectorM(A2) # false

bIsvector3 = isvectorM(ones(3, 1)) # false

bIsvector4 = isvectorM(ones(1, 3)) # false

bIsvector5 = isvectorM(ones(3)) # true

bIsvector6 = isvectorM(1) # false

bIsvector7 = isvectorM("Hi") # false

bIsvector8 = isvectorM(["Hi", "Bye"]) # true

bIsMatrix9 = isvectorM(["Hi" "Bye"]) # false

# Matlab Way:
bIsvectorMat1 = isvectorM(:mat, A1) # true

bIsvectorMat2 = isvectorM(:mat, A2) # true

bIsvectorMat3 = isvectorM(:mat, ones(3, 1)) # true

bIsvectorMat4 = isvectorM(:mat, ones(1, 3)) # true

bIsvectorMat5 = isvectorM(:mat, ones(3)) # true

bIsvectorMat6 = isvectorM(:mat, 1) # true

bIsvectorMat7 = isvectorM(:mat, "Hi") # true

bIsvectorMat8 = isvectorM(:mat, ["Hi", "Bye"]) # true
################################################################
A1 = [1 2 3; 3 5 6]
bIsMatrix1 = ismatrixM(A1) # true

A2 = [1;2;3] # or [1,2,3]
bIsMatrix2 = ismatrixM(A2) # false

bIsMatrix3 = ismatrixM(ones(3, 1)) # true

bIsMatrix4 = ismatrixM(ones(1, 3)) # true

bIsMatrix5 = ismatrixM(ones(3)) # false

bIsMatrix6 = ismatrixM("Hi") # false

bIsMatrix7 = ismatrixM(["Hi", "Bye"]) # false

bIsMatrix8 = ismatrixM(["Hi" "Bye"]) # true

# Matlab Way:

bIsMatrixMat1 = ismatrixM(:mat, A1) # true

bIsMatrixMat2 = ismatrixM(:mat, A2) # true

bIsMatrixMat3 = ismatrixM(:mat, ones(3, 1)) # true

bIsMatrixMat4 = ismatrixM(:mat, ones(1, 3)) # true

bIsMatrixMat5 = ismatrixM(:mat, ones(3)) # true

bIsMatrixMat6 = ismatrixM(:mat, "Hi") # true

bIsMatrixMat7 = ismatrixM(:mat, ["Hi", "Bye"]) # true
################################################################
A1 = [1; 2; 3] # or [1, 2, 3]
bIsrow1 = isrowM(A1) # false

A2 = [1 2 3]
bIsrow2 = isrowM(A2) # true

bIsrow3 = isrowM(ones(3, 1)) # false

bIsrow4 = isrowM(ones(1, 3)) # true

bIsrow5 = isrowM(ones(3)) # false

bIsrow6 = isrowM(1) # false

bIsrow7 = isrowM("Hi") # false

bIsrow8 = isrowM(["Hi", "Bye"]) # false

bIsrow9 = isrowM(["Hi" "Bye"]) # true

# Matlab Way:
bIsrowMat1 = isrowM(:mat, A1) # false

bIsrowMat2 = isrowM(:mat, A2) # true

bIsrowMat3 = isrowM(:mat, ones(3, 1)) # false

bIsrowMat4 = isrowM(:mat, ones(1, 3)) # true

bIsrowMat5 = isrowM(:mat, ones(3)) # false

bIsrowMat6 = isrowM(:mat, 1) # true

bIsrowMat7 = isrowM(:mat, "Hi") # true

bIsrowMat8 = isrowM(:mat, ["Hi", "Bye"]) # false
################################################################
A1 = [1; 2; 3] # or [1, 2, 3]
bIscolumn1 = iscolumnM(A1) # false

A2 = [1 2 3]
bIscolumn2 = iscolumnM(A2) # false

bIscolumn3 = iscolumnM(ones(3, 1)) # tue

bIscolumn4 = iscolumnM(ones(1, 3)) #false

bIscolumn5 = iscolumnM(ones(3)) # false

bIscolumn6 = iscolumnM(1) # false

bIscolumn7 = iscolumnM("Hi") # false

bIscolumn8 = iscolumnM(["Hi", "Bye"]) # false

bIscolumn9 = iscolumnM(["Hi" "Bye"]) # false

# Matlab Way:
bIscolumnMat1 = iscolumnM(:mat, A1) # true

bIscolumnMat2 = iscolumnM(:mat, A2) # false

bIscolumnMat3 = iscolumnM(:mat, ones(3, 1)) # true

bIscolumnMat4 = iscolumnM(:mat, ones(1, 3)) # false

bIscolumnMat5 = iscolumnM(:mat, ones(3)) # true

bIscolumnMat6 = iscolumnM(:mat, 1) # true

bIscolumnMat7 = iscolumnM(:mat, "Hi") # true

bIscolumnMat8 = iscolumnM(:mat, ["Hi", "Bye"]) # true
################################################################
mSort0 = sortM([5, 3, 19, 20, 1, 4]) # [1, 3, 4, 5, 19, 20]

A = [5, 3, 19, 20, 1, 4]
mSort1, iSort1 = sortM(A, I = true)  # returning sort index
A[iSort1] == mSort1

mSort2 = sortM([5, 3, 19, 20, 1, 4], :descend) # [20,19,5,4,3,1]

mSort3 = sortM([1 5 3; 4 1 10]) # [1 1 3; 4 5 10]

mSort4 = sortM([1 5 3; 4 1 10], 2, :ascend) # [1 3 5; 1 4 10]

B = [1 5 3; 4 1 10]
mSort5, iSort5 = sortM(B, 2, :ascend, I = true) # [1 3 5; 1 4 10]
B[iSort5] == mSort5

A = zerosM(Integer, 2, 2, 2)
A[:, :, 1] = [2 3; 1 6]
A[:, :, 2] = [-1 9; 0 12]
mSort6 = sortM(A, 3) # 3D sort
################################################################
sFlip1 = flipM("Hi") # "iH"

mFlip2 = flipM([1; 2; 3; 4]) #[4;3;2;1]

mFlip3 = flipM([1 2; 3 4]) # flips every column: # [3 4; 1 2]

mFlip4 = flipM([1 2; 3 4], 2) # flip along dims 2: #[2 1; 4 3]
################################################################
mRot1 = rot90M([1 2; 3 4]) #[2 4; 1 3]

mRot2 = rot90M([1 2; 3 4], 3) # [3 1; 4 2]
################################################################
A1 = [2 3 4 5 6 7;
      1 2 3 4 5 6]
mTranspose1 = transposeM(A1)

mTranspose2 = transposeM(:arr, A1)
################################################################
A1 = ones(2, 1, 2); # 3 dimensional
mSqueeze1 = squeezeM(A1) # [1 1; 1 1]

A2 = zeros(1, 4, 1);
A2[:, 1:4, ] = [5; 3; 6; 0]
mSqueeze2 = squeezeM(A2) # When it gets one dimensional, it is vertical.

mSqueeze2 == [5; 3; 6; 0] # true
mSqueeze2 == [5 3 6 0] # false
################################################################


text:
using TDAmeritrade, HTTP
using Test

@testset "TDAmeritrade.jl" begin
    # Write your tests here.
    @test TDAmeritrade.construct_api("marketdata/quotes",
                        (;symbol="AAPL,FB")
                        ) ==
    HTTP.URI("https://api.tdameritrade.com/v1/marketdata/quotes?symbol=AAPL%2CFB")
end

ext: jl


text:
using Documenter
using BOMoD

makedocs(sitename="BOMoD.jl",
        authors = "Sam Dierickx",
        format = Documenter.HTML(),
       modules = [BOMoD])

deploydocs(
        repo = "github.com/SamDier/BOMoD.jl.git",
        )

max_stars_repo_name: SamDier/BOMoD

max_issues_repo_name: SamDier/BOMoD

max_forks_repo_name: SamDier/BOMoD


text:
using LineThermalModel, Test
const atol=1e-6

include("basic.jl")
include("powermodels.jl")


text:
seq = SequentialResampling(StrictlyIncreasing())

@test seq isa SequentialResampling


text:
using Test
using Logging
using RobustDecisionProgramming

function test_cross_assignment()
    @test isapprox(cross_assignment(Deviation([1.0], 0.1)), [0.0])

    p = [0.6, 0.4]
    d⁻ = [-0.2, -0.2]
    d⁺ = [0.2, 0.2]
    @test isapprox(cross_assignment(Deviation(p, 0.1)), [0.1, -0.1])
    @test isapprox(cross_assignment(Deviation(p, d⁻, d⁺)), [0.2, -0.2])
    @test isapprox(cross_assignment(Deviation(p, d⁻, d⁺, 0.1)), [0.1, -0.1])

    p = [0.2, 0.7, 0.1]
    d⁻ = [-0.2, -0.1, -0.1]
    d⁺ = [0.05, 0.2, 0.02]
    @test isapprox(cross_assignment(Deviation(p, 0.15)), [0.15, -0.05, -0.1])
    @test isapprox(cross_assignment(Deviation(p, d⁻, d⁺)), [0.05, 0.05, -0.1])
    @test isapprox(cross_assignment(Deviation(p, d⁻, d⁺, 0.08)), [0.05, 0.03, -0.08])

    # p = [0.1, 0.3, 0.6]
    p = [0.6, 0.3, 0.1]
    @test isapprox(cross_assignment(Deviation(p, 0.0)), [0.0, 0.0, 0.0])

    p = [0.0, 1.0]
    @test isapprox(cross_assignment(Deviation(p, 1.0)), [1.0, -1.0])
end

function test_polyhedral_uncertainty_set()
    p = [0.4, 0.6]
    d⁻ = [-0.2, -0.2]
    d⁺ = [0.2, 0.2]
    @test isapprox(
        polyhedral_uncertainty_set(Deviation(p, 0.1)),
        [[0.3, 0.7], [0.5, 0.5]]
    )
    @test isapprox(
        polyhedral_uncertainty_set(Deviation(p, d⁻, d⁺)),
        [[0.6, 0.4], [0.2, 0.8]]
    )
    @test isapprox(
        polyhedral_uncertainty_set(Deviation(p, d⁻, d⁺, 0.1)),
        [[0.3, 0.7], [0.5, 0.5]]
    )
end

test_cross_assignment()
test_polyhedral_uncertainty_set()

max_stars_repo_name: jaantollander/RobustDecisionProgramming

max_issues_repo_name: jaantollander/RobustDecisionProgramming

max_forks_repo_name: jaantollander/RobustDecisionProgramming


text:
using LinearAlgebra
function Volume(x1,y1,z1,x2,y2,z2,x3,y3,z3,x4,y4,z4)

    a = [1 1 1 1; x1 x2 x3 x4; y1 y2 y3 y4; z1 z2 z3 z4]
    v = 1/6*det(a)
    u = abs(v)
    return u
end

max_stars_repo_path: src/single-core juSFEM/volume.jl

max_stars_repo_name: Elliothuo/juSFEM

max_issues_repo_path: src/single-core juSFEM/volume.jl

max_issues_repo_name: Elliothuo/juSFEM

max_forks_repo_path: src/single-core juSFEM/volume.jl

max_forks_repo_name: Elliothuo/juSFEM


text:
function info_dump(D::Dict{String, Any}, level::Int)
  p = 38-level
  w = max(40, displaysize(stdout)[2]-40)
  K = sort(collect(keys(D)))
  subdicts = String[]

  for k in K
    if isa(D[k], Dict{String, Any})
      push!(subdicts, k)
    else
      println(lpad(k, p), ": ", strip(string(D[k])))
    end
  end

  for k in subdicts
    (level > 0) && print(" "^(2*level))
    printstyled(k * "\n", color=level+1, bold=true)
    info_dump(D[k], level+1)
  end
  return nothing
end
info_dump(S::NodalData) = (printstyled(":info\n", color=14, bold=true); info_dump(S.info, 1))


text:
@timedtestset "gp" begin

    # Ensure that basic functionality works as expected.
    @timedtestset "GP" begin
        rng, gpc, N, N′ = MersenneTwister(123456), GPC(), 5, 6
        m = AbstractGPs.CustomMean(sin)
        k = SqExponentialKernel()
        f = wrap(GP(m, k), gpc)
        x = collect(range(-1.0, 1.0; length=N))
        x′ = collect(range(-1.0, 1.0; length=N′))

        @test mean(f, x) == AbstractGPs._map_meanfunction(m, x)
        @test cov(f, x) == kernelmatrix(k, x)
        AbstractGPs.TestUtils.test_internal_abstractgps_interface(rng, f, x, x′)
    end

    # Test the creation of indepenent GPs.
    @timedtestset "independent GPs" begin
        rng, N, N′ = MersenneTwister(123456), 5, 6
        x, x′ = randn(rng, N), randn(rng, N′)

        # Specification of two independent GPs
        gpc = GPC()
        m1, m2 = AbstractGPs.ZeroMean(), AbstractGPs.ConstMean(5)
        k1, k2 = SqExponentialKernel(), SqExponentialKernel()
        f1, f2 = wrap(GP(m1, k1), gpc), wrap(GP(m2, k2), gpc)

        @test mean(f1, x) == AbstractGPs._map_meanfunction(m1, x)
        @test mean(f2, x) == AbstractGPs._map_meanfunction(m2, x)

        @test cov(f1, f2, x, x′) == zeros(N, N′)
        @test var(f1, x) == ones(N)

        @test cov(f1, f1, x′, x) ≈ cov(f1, f1, x, x′)'
    end
end


text:
# This file is a part of PropDicts.jl, licensed under the MIT License (MIT).

function deepmerge!(d::AbstractDict, others::AbstractDict...)
    for other in others
        for (k, v) in other
            if haskey(d, k)
                v_curr = d[k]
                if isa(v_curr, AbstractDict)
                    deepmerge!(v_curr, v)
                else
                    d[k] = v
                end
            else
                d[k] = v
            end
        end
    end
    d
end

function deepmerge(d::AbstractDict, others::AbstractDict...)
    K = Base.promoteK(keytype(d), others...)
    V = Base.promoteV(valtype(d), others...)
    result = Dict{K,V}(d)
    deepmerge!(result, others...)
end

"""
    trim_null!(d::AbstractDict; recursive::Bool = true)

Remove values equal to `nothing` from `d`.

Operates recursively on values in `d` if `recursive == true`.
"""
function trim_null! end

function trim_null!(d::AbstractDict; recursive::Bool = true)
    for (k, v) in d
        if isa(v, AbstractDict)
            if recursive
                trim_null!(v, recursive = recursive)
            end
        elseif typeof(v) == Nothing
            delete!(d, k)
        end
    end
    d
end

trim_null(d::AbstractDict; recursive::Bool = true) =
    trim_null!(deepcopy(d), recursive = recursive)


text:
using Test
using ClickHouse
using ClickHouse: read_client_packet, read_server_packet
using DataFrames
using Dates
using UUIDs
using DecFP

function recursive_miss_cmp(a::AbstractVector,b::AbstractVector)
    length(a) != length(b) && return false
    for i in 1:length(a)
        (!recursive_miss_cmp(a[i], b[i])) && return false
    end
    return true
end
function recursive_miss_cmp(a,b)
    return (ismissing(a) && ismissing(b)) ||
        (!ismissing(a == b) && a==b)
end

function mock_server_info()
    return ClickHouse.ServerInfo(
        "mock",
        19,
        11,
        54423,
        "UTC",
        "mock server",
        10
    )
end

include("defines.jl")
include("tcp.jl")
include("columns_io.jl")

function miss_or_equal(a, b)
    return (ismissing(a) && ismissing(b)) ||
            (a==b)
end
@test begin
    sock = IOBuffer([0xC2, 0x0A]) |> ClickHouseSock
    ClickHouse.chread(sock, ClickHouse.VarUInt) == ClickHouse.VarUInt(0x542)
end

@test begin
    sock = IOBuffer(UInt8[], read=true, write=true, maxsize=10) |>
        ClickHouseSock
    ClickHouse.chwrite(sock, ClickHouse.VarUInt(100_500))
    seek(sock.io, 0)
    read(sock.io, 3) == [0x94, 0x91, 0x06]
end

@testset "Decode & re-encode client packets (SELECT 1)" begin
    # This .bin file was extracted from a tcpdump captured from a session
    # with the official ClickHouse command line client.
    data = read(open("select1/client-query.bin"), 100_000, all = true)
    sock = data |> IOBuffer |> ClickHouseSock
    sock.server_rev = ClickHouse.DBMS_VER_REV
    packets = []

    # Read packets.

    packet = read_client_packet(sock)
    push!(packets, packet)
    @test typeof(packet) == ClickHouse.ClientHello

    packet = read_client_packet(sock)
    push!(packets, packet)
    @test typeof(packet) == ClickHouse.ClientPing

    packet = read_client_packet(sock)
    push!(packets, packet)
    @test typeof(packet) == ClickHouse.ClientQuery

    packet = read_client_packet(sock)
    push!(packets, packet)
    @test typeof(packet) == ClickHouse.Block

    @test eof(sock.io)

    # Re-encode them.

    sock = IOBuffer(UInt8[], write = true, read = true, maxsize = 100_000) |>
        ClickHouseSock
    sock.server_rev = ClickHouse.DBMS_VER_REV

    for packet ∈ packets
        ClickHouse.write_packet(sock, packet)
    end

    seek(sock.io, 0)
    reencoded_data = read(sock.io, 100_000)

    @test reencoded_data == data
end

@testset "Decode server packets (SELECT 1)" begin
    sock = open("select1/server-query-resp.bin") |> ClickHouseSock
    sock.server_rev = ClickHouse.DBMS_VER_REV

    packet = read_server_packet(sock)
    @test typeof(packet) == ClickHouse.ServerInfo

    packet = read_server_packet(sock)
    @test typeof(packet) == ClickHouse.ServerPong

    packet = read_server_packet(sock)
    @test typeof(packet) == ClickHouse.ServerData

    packet = read_server_packet(sock)
    @test typeof(packet) == ClickHouse.ServerData

    packet = read_server_packet(sock)
    @test typeof(packet) == ClickHouse.ServerProfileInfo

    packet = read_server_packet(sock)
    @test typeof(packet) == ClickHouse.ServerProgress

    packet = read_server_packet(sock)
    @test typeof(packet) == ClickHouse.ServerData

    packet = read_server_packet(sock)
    @test typeof(packet) == ClickHouse.ServerEndOfStream

    @test eof(sock.io)
end

@testset "Decode client packets (INSERT INTO woof VALUES (1))" begin
    sock = open("insert1/client.bin") |> ClickHouseSock
    sock.server_rev = ClickHouse.DBMS_VER_REV

    while !eof(sock.io)
        packet = read_client_packet(sock)
    end

    @test true
end

@testset "Decode server packets (OHLC data)" begin
    sock = open("insert-ohlc/server.bin") |> ClickHouseSock
    sock.server_rev = ClickHouse.DBMS_VER_REV

    while !eof(sock.io)
        packet = read_server_packet(sock)
    end
end

@testset "Decode server packets (enums)" begin
    sock = open("enum/server.bin") |> ClickHouseSock
    sock.server_rev = ClickHouse.DBMS_VER_REV

    while !eof(sock.io)
        packet = read_server_packet(sock)
    end
end

@testset "Decode & re-encode client packets (enums)" begin
    data = read(open("enum/client.bin"), 10_000, all = true)
    sock = IOBuffer(data) |> ClickHouseSock
    sock.server_rev = ClickHouse.DBMS_VER_REV

    # Read packets.

    packets = []
    while !eof(sock.io)
        packet = read_client_packet(sock)
        push!(packets, packet)
    end

    @test eof(sock.io)

    # Re-encode them.

    sock = IOBuffer(UInt8[], write = true, read = true, maxsize = 10_000) |>
        ClickHouseSock
    sock.server_rev = ClickHouse.DBMS_VER_REV
    for packet ∈ packets
        ClickHouse.write_packet(sock, packet)
    end

    seek(sock.io, 0)
    reencoded_data = read(sock.io, 10_000)

    @test reencoded_data == data
end

@testset "Decode server packets (exception)" begin
    sock = open("error/server.bin") |> ClickHouseSock
    sock.server_rev = ClickHouse.DBMS_VER_REV

    while !eof(sock.io)
        try
            packet = read_server_packet(sock)
        catch exc
            if !isa(exc, ClickHouseServerException)
                rethrow()
            end
        end
    end
end

@testset "Decode & re-encode client packets (OHLC data)" begin
    data = read(open("insert-ohlc/client.bin"), 1_000_000, all = true)
    sock = IOBuffer(data) |> ClickHouseSock
    sock.server_rev = ClickHouse.DBMS_VER_REV

    # Read packets.

    packets = []
    while !eof(sock.io)
        packet = read_client_packet(sock)
        push!(packets, packet)
    end

    @test eof(sock.io)

    # Re-encode them.

    sock = IOBuffer(UInt8[], write = true, read = true, maxsize = 1_000_000) |>
        ClickHouseSock
    sock.server_rev = ClickHouse.DBMS_VER_REV
    for packet ∈ packets
        ClickHouse.write_packet(sock, packet)
    end

    seek(sock.io, 0)
    reencoded_data = read(sock.io, 1_000_000)

    @test reencoded_data == data
end

@testset "Queries on localhost DB" begin
    table = "ClickHouseJL_Test"
    sock = connect()

    try
        execute(sock, """
            CREATE TABLE $(table) (
                lul UInt64,
                oof Float32,
                foo String,
                foo_fixed FixedString(5),
                ddd Date,
                dt DateTime,
                dt_tz DateTime('CET'),
                enu Enum8('a' = 1, 'c' = 3, 'foobar' = 44, 'd' = 9),
                uuid UUID,
                nn Nullable(Int64),
                ns Nullable(String),
                ne Nullable(Enum16('a' = 1, 'b' = 2)),
                las LowCardinality(String),
                lan LowCardinality(Nullable(String)),
                arrs Array(LowCardinality(String)),
                arrsn Array(Array(Int64)),
                arrsnn Array(Array(Nullable(Int64))),
                safunc SimpleAggregateFunction(sum, Int64),
                ip4 Nullable(IPv4),
                ip6 Nullable(IPv6),
                dt64 DateTime64(6),
                dt64_1 DateTime64(1),
                dt64_1tz DateTime64(1, 'GMT'),
                dec32 Decimal32(4),
                dec Decimal(11,4)
            )
            ENGINE = Memory
        """)
    catch exc
        rethrow(exc)
        #exc::ClickHouseServerException
        #occursin(r"Table .* already exists", exc.exc.message) || rethrow()
        #sock = connect()
    end
    NullInt = Union{Int64, Missing}
    td = today()
    data = Dict(
        :lul => UInt64[42, 1337, 123],
        :oof => Float32[0., ℯ, π],
        :foo => String["aa", "bb", "cc"],
        :foo_fixed => String["aaaaa", "bbb", "cc"],
        :ddd => Date[td, td, td],
        :dt => DateTime[td, td, td],
        :dt_tz => DateTime[td, td, td],
        :enu => ["a", "c", "foobar"],
        :uuid => [
            UUID("c187abfa-31c1-4131-a33e-556f23f7aa67"),
            UUID("f9a7e2b9-dc22-4ca6-b4fe-83ba551ea3bb"),
            UUID("dc986a81-9f1d-4d96-b618-6e8d034285c1")
             ],
        :nn => [10, missing, 20],
        :ns => [missing, "sst", "aaa"],
        :ne => CategoricalVector(["a", "b", missing]),
        :las => ["a", "b", "a"],
        :lan => [missing, "b", "a"],
        :arrs => [
            ["a", "b"],
            ["a"],
            ["v", "b"]
             ],
        :arrsn => [
            [[1,2], [3,4]],
            [[5,6],[7]],
            [[1], [2]]
            ],
        :arrsnn => [
            [NullInt[1,2], NullInt[3,4]],
            [NullInt[5,6],NullInt[7]],
            [NullInt[1], NullInt[missing]]
            ],
        :safunc => Int64[42, 1337, 123],
        :ip4 => [IPv4("127.0.0.2"), missing, IPv4("127.0.0.1")],
        :ip6 => [
            IPv6("2a02:aa08:e000:3100::2"),
            missing,
            IPv6("2a02:aa08:e000:3100::3")
        ],
        :dt64 => [
            DateTime(2020, 02, 02, 10, 5, 10, 320),
            DateTime(2020, 02, 02, 10, 5, 10, 322),
            DateTime(2020, 02, 02, 10, 5, 10, 323)
        ],
        :dt64_1 => [
            DateTime(2020, 02, 02, 10, 5, 10, 320),
            DateTime(2020, 02, 02, 10, 5, 10, 422),
            DateTime(2020, 02, 02, 10, 5, 10, 523)
        ],
        :dt64_1tz => [
            DateTime(2020, 02, 02, 10, 5, 11, 320),
            DateTime(2020, 02, 02, 10, 5, 11, 422),
            DateTime(2020, 02, 02, 10, 5, 10, 529)
        ],
        :dec32 => [
            Dec32("221.3213"),
            Dec32("225.3215"),
            Dec32("227.3219"),
        ],
        :dec => [
            Dec64("5432221.3213"),
            Dec64("6432221.4213"),
            Dec64("7432221.5213")
        ]
    )

    # Single block inserts.
    for _ ∈ 1:3
        insert(sock, table, [data])
    end

    # Multi block insert.
    insert(sock, table, repeat([data], 100))

    # SELECT -> Dict
    proj = ClickHouse.select(sock, "SELECT * FROM $(table) LIMIT 4")
    @test proj[:lul] == UInt64[42, 1337, 123, 42]
    @test proj[:oof] == Float32[0., ℯ, π, 0.]
    @test proj[:foo] == String["aa", "bb", "cc", "aa"]
    @test proj[:foo_fixed] == String["aaaaa", "bbb  ", "cc   ", "aaaaa"]
    @test proj[:ddd] == Date[td, td, td, td]
    @test proj[:dt] == DateTime[td, td, td, td]
    @test proj[:dt_tz] == DateTime[td, td, td, td]
    @test proj[:uuid] == vcat(data[:uuid], data[:uuid][1:1])
    @test recursive_miss_cmp(proj[:nn], [10, missing, 20 , 10])
    @test recursive_miss_cmp(proj[:ns], [missing, "sst", "aaa" , missing])
    @test recursive_miss_cmp(proj[:ne], ["a", "b", missing, "a"])

    @test proj[:las] == ["a", "b", "a", "a"]

    @test recursive_miss_cmp(proj[:lan], [missing, "b", "a",  missing])

    @test proj[:arrsn] == [
        [[1,2], [3,4]],
        [[5,6],[7]],
        [[1], [2]],
        [[1,2], [3,4]],
    ]

    @test proj[:arrs] == [
        ["a", "b"],
        ["a"],
        ["v", "b"],
        ["a", "b"],
    ]

    @test recursive_miss_cmp(proj[:arrsnn],
        [
            [NullInt[1,2], NullInt[3,4]],
            [NullInt[5,6],NullInt[7]],
            [NullInt[1], NullInt[missing]],
            [NullInt[1,2], NullInt[3,4]],
        ]
    )

    @test proj[:safunc] == Int64[42, 1337, 123, 42]

    @test recursive_miss_cmp(proj[:ip4], [
        IPv4("127.0.0.2"),
        missing,
        IPv4("127.0.0.1"),
        IPv4("127.0.0.2")
        ])
    @test recursive_miss_cmp(proj[:ip6], [
        IPv6("2a02:aa08:e000:3100::2"),
        missing,
        IPv6("2a02:aa08:e000:3100::3"),
        IPv6("2a02:aa08:e000:3100::2")
    ])

    @test proj[:dt64] ==  [
        DateTime(2020, 02, 02, 10, 5, 10, 320),
        DateTime(2020, 02, 02, 10, 5, 10, 322),
        DateTime(2020, 02, 02, 10, 5, 10, 323),
        DateTime(2020, 02, 02, 10, 5, 10, 320)
    ]

    @test proj[:dt64_1] == [
            DateTime(2020, 02, 02, 10, 5, 10, 300),
            DateTime(2020, 02, 02, 10, 5, 10, 400),
            DateTime(2020, 02, 02, 10, 5, 10, 500),
            DateTime(2020, 02, 02, 10, 5, 10, 300),
        ]

    @test proj[:dt64_1tz] == [
        DateTime(2020, 02, 02, 10, 5, 11, 300),
        DateTime(2020, 02, 02, 10, 5, 11, 400),
        DateTime(2020, 02, 02, 10, 5, 10, 500),
        DateTime(2020, 02, 02, 10, 5, 11, 300),
    ]

    @test proj[:dec32] == [
        Dec32("221.3213"),
        Dec32("225.3215"),
        Dec32("227.3219"),
        Dec32("221.3213"),
    ]
    @test proj[:dec] == [
        Dec64("5432221.3213"),
        Dec64("6432221.4213"),
        Dec64("7432221.5213"),
        Dec64("5432221.3213"),

    ]

    # SELECT Tuple -> Dict

    proj = ClickHouse.select(sock, "SELECT tuple(ddd, tuple(lul, foo)) as tup FROM $(table) LIMIT 2")
    @test proj[:tup] == [
        (td, (UInt64(42), "aa")),
        (td, (UInt64(1337), "bb")),
    ]

    proj = ClickHouse.select(sock, "SELECT null as n, array() as arr FROM $(table) LIMIT 3")
    @test all(ismissing.(proj[:n]))
    @test all(proj[:arr] .== Ref(Missing[]))

    # SELECT -> DF
    proj_df = select_df(sock, "SELECT * FROM $(table) LIMIT 3, 3")
    exp_df = DataFrame(data)

    # Normalize column order.
    order = [:lul, :oof, :foo, :ddd]
    proj_df = proj_df[:, order]
    exp_df = exp_df[:, order]

    @test proj_df == exp_df

    # Clean up.
    execute(sock, "DROP TABLE $(table)")
end


text:
# We create a simple function to test
A = rand(5, 5);
Q = A' * A

f(x) = x' * Q * x
nlp = ADNLPModel(f, zeros(5))
mpcc = MPCCNLPs(nlp)
nlp_at_x = MPCCAtX(zeros(5), zeros(0))
stop_nlp = MPCCStopping(mpcc, nlp_at_x, optimality0 = 0.0, optimality_check = SStat)

a = zeros(5)
fill_in!(stop_nlp, a)

# we make sure that the fill_in! function works properly
@test obj(mpcc, a) == stop_nlp.current_state.fx
@test grad(mpcc, a) == stop_nlp.current_state.gx
@test stop_nlp.meta.optimality0 == 0.0

# we make sure the optimality check works properly
@test stop!(stop_nlp)
# we make sure the counter of stop works properly
@test stop_nlp.meta.nb_of_stop == 1

reinit!(stop_nlp, rstate = true, x = ones(5))
@test stop_nlp.current_state.x == ones(5)
@test stop_nlp.current_state.fx == nothing
@test stop_nlp.meta.nb_of_stop == 0

#We know test how to initialize the counter:
test_max_cntrs = _init_max_counters_mpcc(obj = 2)
stop_nlp_cntrs = MPCCStopping(mpcc, max_cntrs = test_max_cntrs)
@test stop_nlp_cntrs.meta.max_cntrs[:neval_obj] == 2
@test stop_nlp_cntrs.meta.max_cntrs[:neval_grad] == 40000
@test stop_nlp_cntrs.meta.max_cntrs[:neval_sum] == 40000*11

x0 = ones(6)
c(x) = [sum(x)]
meta = NLPModelMeta(6, x0=x0, lvar = fill(-10.0,size(x0)), uvar = fill(10.0,size(x0)),
                    ncon = 1, y0 = [0.0], lcon = [-Inf], ucon = [6.])
mp2 = ADNLPModel(meta, Counters(), rosenbrock,  c)
nlp2 = MPCCNLPs(mp2)
nlp_at_x_c = MPCCAtX(x0, NaN*ones(nlp2.meta.ncon))
stop_nlp_c = MPCCStopping(nlp2, nlp_at_x_c, optimality_check = SStat)

a = zeros(6)
fill_in!(stop_nlp_c, a)

@test cons(nlp2, a) == stop_nlp_c.current_state.cx
@test jac(nlp2, a) == stop_nlp_c.current_state.Jx

@test stop!(stop_nlp_c) == false
# we make sure the counter of stop works properly
@test stop_nlp_c.meta.nb_of_stop == 1

sol = ones(6)
fill_in!(stop_nlp_c, sol)

@test stop!(stop_nlp_c) == true

stop_nlp_default = MPCCStopping(nlp2, atol = 1.0)
fill_in!(stop_nlp_default, sol)
@test stop_nlp_default.meta.atol == 1.0
@test stop!(stop_nlp_default) == true

#Keywords in the stop! call
nlp_at_x_kargs = MPCCAtX(x0, NaN*ones(nlp2.meta.ncon))
stop_nlp_kargs = MPCCStopping(nlp2, nlp_at_x_c, optimality_check = (x,y; test = 1.0, kwargs...) -> MStat(x,y; kwargs...) + test)
fill_in!(stop_nlp_kargs, sol)
@test stop!(stop_nlp_kargs) == false
@test stop!(stop_nlp_kargs, test = 0.0) == true

test1 = ex1()
stop_w = MPCCStopping(test1, MPCCAtX(x0, zeros(nlp2.meta.ncon)), optimality_check = WStat)
stop_s = MPCCStopping(test1, MPCCAtX(x0, zeros(nlp2.meta.ncon)), optimality_check = SStat)
Wpoint, Spoint = zeros(2), [0.0, 1.0]
fill_in!(stop_w, Wpoint)
@test stop_w.current_state.lambdaG == [1.0]
@test stop_w.current_state.lambdaH == [-1.0]
#lambdaW = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, -1.0]
#update_and_stop!(stop_w, lambdaG = [1.0], lambdaH = [-1.0])
stop!(stop_w)
@test status(stop_w) == :Optimal
fill_in!(stop_s, Spoint)
@test stop_s.current_state.lambdaG == [1.0]
@test stop_s.current_state.lambdaH == [0.0]
#lambdaS = [0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0]
#update_and_stop!(stop_s, lambdaG = [1.0], lambdaH = [0.0])
stop!(stop_s)
@test status(stop_s) == :Optimal
reinit!(stop_s)
stop_s.meta.optimality_check = WStat
stop!(stop_s)
@test status(stop_s) == :Optimal

a = MPCC.neval_obj(stop_s.pb)
decrement!(stop_s.pb, :neval_obj)
@test MPCC.neval_obj(stop_s.pb) == a-1
reset!(stop_s.pb)
@test neval_consG(stop_s.pb) == 0

testM = ex3()
stop_m = MPCCStopping(testM, MPCCAtX(zeros(3), zeros(2)), optimality_check = MStat)
stop_c = MPCCStopping(testM, MPCCAtX(zeros(3), zeros(2)), optimality_check = CStat)
fill_in!(stop_m, zeros(3))
#the sign computed by fill_in are not M-stat. optimized
update_and_stop!(stop_m, lambda = [0.75, 0.25], lambdaG = [-2.0], lambdaH = [0.0])
@test status(stop_m) == :Optimal

fill_in!(stop_c, ones(3))
stop!(stop_c)
@test status(stop_c) == :Unknown

#Unconstrained MPCC:
test_unc = MPCCNLPs(ADNLPModel(rosenbrock, zeros(6)))
stop_unc = MPCCStopping(test_unc, MPCCAtX(zeros(6), zeros(0)), optimality_check = MStat)
fill_in!(stop_unc, ones(6))
@test stop_unc.current_state.lambda == zeros(0)
@test stop_unc.current_state.lambdaG == nothing
@test stop_unc.current_state.lambdaH == nothing
@test stop_unc.current_state.mu == nothing


text:
analysis_atm = Dict(
    :U => "atm_analysis_U.nc",
)

max_stars_repo_name: meteorologytoday/CESM-diagnostic

max_issues_repo_name: meteorologytoday/CESM-diagnostic

max_forks_repo_name: meteorologytoday/CESM-diagnostic


text:
Random.rand(::Type{T}) where {T<:SafeInteger} = T(rand(baseint(T)))
Random.rand(::Type{T}, n::I) where {T<:SafeInteger, I<:Integer} = T.(rand(baseint(T), n))
Random.rand(::Type{T}, n::I) where {T<:SafeInteger, I<:SafeInteger} = T.(rand(baseint(T), baseint(n)))
Random.rand(x::T) where {S<:SafeInteger, T<:UnitRange{S}} = S(rand(baseint(x)))
Random.rand(x::T, n::I) where {S<:SafeInteger, T<:UnitRange{S}, I<:Integer} = S.(rand(baseint(x), n))
Random.rand(x::T, n::I) where {S<:SafeInteger, T<:UnitRange{S}, I<:SafeInteger} = S.(rand(baseint(x), baseint(n)))
# allocates less
Random.rand(ur::UnitRange{SI}, n::Int) where {SI<:SafeInteger} = Random.rand(SI.(Int.(ur)),n)


text:
begin
	gtp = Array{Any}(undef,24)
	dcp = Array{Any}(undef,24)
	scp = Array{Any}(undef,24)
	@inbounds for i in 1:24
		gtp[i]=convert(DIN99o,groundtruth_patches[i])
		scp[i]=convert(DIN99o,source_patches[i])
		dcp[i]=convert(DIN99o,dest_patches[i])
	end
	WPconv=convert(DIN99o,sWP)
	# create a99* and b99* vectors

	for i in 1:24

	Lgt=map(1:24) do i gtp[i].l end
	agt=map(1:24) do i gtp[i].a end
	bgt=map(1:24) do i gtp[i].b end
	Ldc=map(1:24) do i dcp[i].l end
	adc=map(1:24) do i dcp[i].a end
	bdc=map(1:24) do i dcp[i].b end
	Lsc=map(1:24) do i scp[i].l end
	asc=map(1:24) do i scp[i].a end
	bsc=map(1:24) do i scp[i].b end
	aq= map(1:24) do i agt[i], adc[i] end
	bq= map(1:24) do i bgt[i], bdc[i] end
	Lq= map(1:24) do i Lgt[i], Ldc[i] end
	aline= map(1:24) do i collect(aq[i]) end
	bline= map(1:24) do i collect(bq[i]) end
	Lline= map(1:24) do i collect(Lq[i]) end
	end

	scatter(zeros(1),zeros(1),#=zeros(1),=# color=DIN99o(60,0,0),markersize=1, shape = :hexagon,  label="neutral axis",title="Color coordinates in DIN99o color space",legend=:bottomleft, #=aspect_ratio= :equal,=#background=DIN99o(40,0,0),xaxis="a*",yaxis="b*", zaxis="L*", size=(700,700),#=xlimits=(-60,60),ylimits=(-60,60),camera=(0,0)=#)
	scatter!(gtp.a,gtp.b,gtp.l, color=gtp,markersize=2, markershape = :square, label="ground truth")
	scatter!(dcp.a,dcp.b,dcp.l, color=dcp,markersize=1, shape = :circle, label="destination color")
	plot!(aline,bline,Lline, color=:black, linewidth= 3,label=false)
	scatter!([WPconv.a],[WPconv.b],[WPconv.l],color= WPconv, markersize= 2, label="Source White Point")
	#quiver!(a99gt,b99gt,L99gt,quiver=(a99dc-a99gt,b99dc-b99gt,L99dc-L99gt),color=:black,arrowsize=5,marker=:none)
end


text:
export
		add,
		flush,
        find_position

add( idarr::IdArray, thisString::AbstractString ) = ccall( (:idarray_Add, LIB_SMILE), Int32, (Ptr{Void},Ptr{UInt8}), idarr.ptr, bytestring(thisString) )

# String Arrays
find_position( idarr::IdArray, ofThisString::AbstractString) =
    ccall( (:stringarray_FindPosition, LIB_SMILE), Int32, (Ptr{Void},Ptr{UInt8}), idarr.ptr, bytestring(ofThisString) )

Base.flush( idarr::IdArray ) = ccall( (:stringarray_Flush, LIB_SMILE), Void, (Ptr{Void},), idarr.ptr )


text:
using MockAWS

using AWS
using GitHub
using JSON
using Base64
using Mocking
using OrderedCollections: OrderedDict
using Test

Mocking.activate()

include("patches.jl")

AUTH = GitHub.OAuth2("foobar")

@testset "@patches" begin
    @testset "patch functionality" begin
        @service Secrets_Manager
        @patches Secrets_Manager

        apply(Secrets_Manager.list_secrets_1_patch) do
            @test !isempty(@mock Secrets_Manager.list_secrets())
        end
    end

    @testset "service dne" begin
        @test_throws UndefVarError @patches FakeService
    end
end

@testset "_get_sha" begin
    expected = FILES[1]["sha"]
    result = MockAWS._get_sha(FILES[1]["path"], FILES)

    @test expected == result
end

@testset "_get_example_files" begin
    apply(_get_service_and_version_patch) do
        result = MockAWS._get_example_files(FILES, AUTH)

        @test length(result) == 1
    end
end


text:
# Cuts off `str` to a maximum actual `width`. Does handle unicode strings.
# If `str` is too wide and `dots` is true, the last character will be an ellipsis.
function strcut(str, width; dots::Bool=true)
    w = strwidth(str)
    if w <= width
        return str
    elseif w == length(str)
        # No unicode-stuff to care about, should be the most common case for labels.
        if dots
            return str[1:min(end,width-1)] * "…"
        else
            return str[1:min(end,width)]
        end
    else
        # Handle unicode where a char may have any width.
        i = 1; w = 0
        cw = charwidth(str[i])
        while (w + cw < width + !dots) && nextind(str, i) <= endof(str)
            w += cw
            i = nextind(str, i)
            cw = charwidth(str[i])
        end
        return str[1:i-1] * (dots ? "…" : "")
    end
end


text:
################################
# Solving the Replicator Equator equation,
# appearing in Corrolary 2.2 of
#  https://www.biorxiv.org/content/10.1101/623330v1
################################

cd(@__DIR__)
using HighDimPDE
using Random
using Test
using Flux
using Revise
using PyPlot
using UnPack
plotting = true

tspan = (0f0,15f-2)
dt = 5f-2 # time step
μ(X,p,t) = 0f0 # advection coefficients
σ(X,p,t) = 1f-1 # diffusion coefficients
d = 5
ss0 = 5f-2#std g0
U = 25f-2
u_domain = (fill(-U, d), fill(U, d))

##############################
####### Neural Network #######
##############################
batch_size = 10000
train_steps = 2000
K = 1

hls = d + 50 #hidden layer size

nn_batch = Flux.Chain(
        # BatchNorm(d,affine = true, dim = 1),
        Dense(d, hls, tanh),
        # BatchNorm(hls,affine = true, dim = 1),
        Dense(hls,hls,tanh),
        # BatchNorm(hls, affine = true, dim = 1),
        # Dense(hls,hls,tanh),
        Dense(hls, 1, x->x^2)) # Neural network used by the scheme, with batch normalisation

opt = ADAM(1e-2)#optimiser
alg = DeepSplitting(nn_batch, K=K, opt = opt, mc_sample = NormalSampling(1f0) )

##########################
###### PDE Problem #######
##########################
g(x) = Float32((2*π)^(-d/2)) * ss0^(- Float32(d) * 5f-1) * exp.(-5f-1 *sum(x .^2f0 / ss0, dims = 1)) # initial condition
m(x) = - 5f-1 * sum(x.^2, dims=1)
vol = prod(u_domain[2] - u_domain[1])
f(y, z, v_y, v_z, ∇v_y, ∇v_z, p, t) =  v_y .* (m(y) .- vol * v_z .* m(z) ) # nonlocal nonlinear part of the

# defining the problem
prob = PIDEProblem(g, f, μ, σ, tspan,
                    u_domain = u_domain
                    )
# solving
@time xgrid,ts,sol = solve(prob,
                alg,
                dt,
                verbose = true,
                # abstol = 1f0,
                maxiters = train_steps,
                batch_size = batch_size,
                use_cuda = true
                )

###############################
######### Plotting ############
###############################
if plotting
        clf()
        fig, ax = plt.subplots(1,2, sharey = true)

        xgrid1 = collect((-U:5f-3:U))
        xgrid = [reshape(vcat(x, fill(0f0,d-1)),:,1) for x in xgrid1]

        # Analytic sol
        function _SS(x, t, p)
                d = length(x)
                MM = σ(x, p, t) * ones(d)
                SSt = MM .* ((MM .* sinh.(MM *t) .+ ss0 .* cosh.( MM * t)) ./ (MM .* cosh.(MM * t ) .+ ss0 .* sinh.(MM * t)))
                return SSt
        end

        function uanal(x, t, p)
                d = length(x)
                return (2*π)^(-d/2) * prod(_SS(x, t, p) .^(-1/2)) * exp(-0.5 *sum(x .^2 ./ _SS(x, t, p)) )
        end

        for t in collect(tspan[1]: dt : tspan[2])
                ys = uanal.(xgrid, t, Ref(Dict()))
                ax[2].plot(xgrid1, reduce(hcat,ys)[:], label = "t = $t")
        end
        ax[2].set_title("Analytical solution")
        gcf()

        #Deepsplitting sol
        for i in 1:length(sol)
                ax[1].scatter(xgrid1, reduce(vcat,sol[i].(xgrid)), s = .2, label="t = $(dt * (i-1))")
        end
        gcf()

        ax[1].set_title("DeepSplitting")

        for _a in ax[1:1]
                _a.legend()
        end
        gcf()
        savefig("hamel_$(d)d.pdf")

        #####
        # other DimensionMismatch
        #####
        if false
                dx = 0.05
                x = u_domain[1,1]:dx:u_domain[1,2]
                plt.contourf(x,x,g.(repeat(x,2)))
        end
end
ax[1].set_ylabel(L"u(t,(x_1,0,\dots,0))")
ax[1].set_xlabel(L"x_1")
ax[2].set_xlabel(L"x_1")

fig.tight_layout()
gcf()

fig.savefig("hamel_5d.pdf", dpi=800)


text:
"""
A Pure Julia Version of LLDL.
A left-looking implementation of the sparse LDL factorization
of a symmetric matrix with the possibility to compute a
limited-memory incomplete factorization.

Dominique Orban <dominique.orban@gmail.com>
Montreal, April 2015, December 2015, July 2017.

This code is strongly inspired by Lin and Moré's ICFS [1,2].
The modified version is described in [3,4].

# References
[1] C.-J. Lin and J. J. Moré. Incomplete Cholesky factorizations with limited
    memory. SIAM Journal on Scientific Computing, 21(1):24--45, 1999.
[2] http://www.mcs.anl.gov/~more/icfs
[3] D. Orban. Limited-Memory LDLT Factorization of Symmetric Quasi-Definite
    Matrices with Application to Constrained Optimization. Numerical Algorithms
    70(1):9--41, 2015. DOI 10.1007/s11075-014-9933-x
[4] https://github.com/optimizers/lldl
"""

module LimitedLDLFactorizations

export lldl

lldl(A::Array{Tv,2}; kwargs...) where Tv<:Number = lldl(sparse(A); kwargs...)

"""
    lldl(A)

Compute the limited-memory LDLᵀ factorization of A without pivoting.

# Arguments
- `A::SparseMatrixCSC{Tv,Ti}`: matrix to factorize (its strict lower triangle and
                               diagonal will be extracted)

# Keyword arguments
- `memory::Int=0`: extra amount of memory to allocate for the incomplete factor `L`.
                   The total memory allocated is nnz(T) + n * `memory`, where
                   `T` is the strict lower triangle of A and `n` is the size of `A`.
- `α::Tv=Tv(0)`: initial value of the shift in case the incomplete LDLᵀ
                 factorization of `A` is found to not exist. The shift will be
                 gradually increased from this initial value until success.
- `droptol::Tv=Tv(0)`: to further sparsify `L`, all elements with magnitude smaller
                       than `droptol` are dropped.
"""
function lldl(A::SparseMatrixCSC{Tv,Ti}; kwargs...) where {Tv<:Number, Ti<:Integer}
  lldl(tril(A, -1), diag(A); kwargs...)
end

# Here T is the strict lower triangle of A.
function lldl(T::SparseMatrixCSC{Tv,Ti},
              adiag::AbstractVector{Tv};
              memory::Int=0,
              α::Tv=Tv(0),
              droptol::Tv=Tv(0)) where {Tv<:Number, Ti<:Integer}

  memory < 0 && error("limited-memory parameter must be nonnegative")
  n = size(T, 1)
  n != size(T, 2) && error("input matrix must be square")
  n != length(adiag) && error("inconsistent size of diagonal")

  nnzT = nnz(T)
  np = n * memory

  # Make room to store L.
  nnzLmax = max(nnzT + np, div(n * (n - 1), 2))
  d = zeros(Tv, n)              # Diagonal matrix D.
  lvals = zeros(Tv, nnzLmax)    # Strict lower triangle of L.
  rowind = zeros(Ti, nnzLmax)
  colptr = zeros(Ti, n+1)

  # Compute the 2-norm of columns of A
  # and the diagonal scaling matrix.
  wa1 = zeros(Tv, n)
  s = ones(Tv, n)
  @inbounds @simd for col = 1 : n
    @inbounds @simd for k = T.colptr[col] : T.colptr[col+1] - 1
      row = T.rowval[k]
      val = T.nzval[k]
      val2 = val * val
      wa1[col] += val2  # Contribution to column col.
      wa1[row] += val2  # Contribution to column row.
    end
  end
  @inbounds @simd for col = 1 : n
    dcol = adiag[col]
    wa1[col] += dcol * dcol
    wa1[col] = sqrt(wa1[col])
    wa1[col] > 0 && (s[col] = 1 / sqrt(wa1[col]))
  end

  # Set initial shift. Keep it at zero if possible.
  α_min = 1.0e-3
  if α > 0
    α = max(α, α_min)
  end
  max_increase_α = 3
  nb_increase_α = 0
  if any(x -> x == 0, adiag)
    α = max(α, α_min)
  end

  factorized = false
  tired = false

  # Work arrays.
  w = zeros(Tv, n)     # contents of the current column of A.
  indr = zeros(Ti, n)  # row indices of the nonzeros in the current column after it's been loaded into w.
  indf = zeros(Ti, n)  # indf[col] = position in w of the next entry in column col to be used during the factorization.
  list = zeros(Ti, n)  # list[col] = linked list of columns that will update column col.

  pos = find(adiag .> Tv(0))
  neg = find(adiag .≤ Tv(0))

  while !(factorized || tired)

    # Copy the sparsity structure of A into L.
    @inbounds @simd for col = 1 : n+1
      colptr[col] = T.colptr[col]
    end
    @inbounds @simd for k = 1 : nnzT
      rowind[k] = T.rowval[k]
    end

    # Store the scaled A into L.
    # Make room to store the computed factors.
    # We could save lots of storage here by "undoing" the scaling
    # at every attempt, at the price of introducing small errors
    # every time.
    @inbounds @simd for col = 1 : n
      scol = s[col]
      d[col] = adiag[col] * scol * scol
      @inbounds @simd for k = T.colptr[col] : T.colptr[col+1] - 1
        lvals[k] = T.nzval[k] * scol * s[T.rowval[k]]  # = S A S.
      end
    end
    @inbounds @simd for col in pos
      d[col] += α
    end
    @inbounds @simd for col in neg
      d[col] -= α
    end

    # Attempt a factorization.
    factorized = attempt_lldl!(nnzT, d, lvals, rowind, colptr, w, indr, indf, list, memory=memory, droptol=droptol)

    # Increase shift if the factorization didn't succeed.
    if !factorized
      nb_increase_α += 1
      α *= 2
      tired = nb_increase_α > max_increase_α
    end
  end

  # Unscale L.
  @inbounds @simd for col = 1 : n
    scol = s[col]
    d[col] /= scol * scol
    @inbounds @simd for k = colptr[col] : colptr[col+1] - 1
      lvals[k] *= scol / s[rowind[k]]
    end
  end

  L = SparseMatrixCSC(n, n, colptr, rowind, lvals)
  return (L, d, α)
end

function attempt_lldl!(nnzT::Int, d::Vector{Tv}, lvals::Vector{Tv},
                       rowind::Vector{Ti}, colptr::Vector{Ti},
                       w::Vector{Tv}, indr::Vector{Ti},
                       indf::Vector{Ti}, list::Vector{Ti};
                       memory::Int=0,
                       droptol::Tv=Tv(0)) where {Ti<:Integer, Tv<:Number}

  n = size(d, 1)
  np = n * memory
  droptol = max(0, droptol)

  # Make room for L.
  @inbounds @simd for col = 1 : n+1
    colptr[col] += np
  end

  @inbounds @simd for k = nnzT : -1 : 1
    rowind[np + k] = rowind[k]
    lvals[np + k] = lvals[k]
  end

  # Attempt an incomplete LDL factorization.
  col_start = colptr[1]
  colptr[1] = 1

  # Scan each column in turn.
  for col = 1 : n

    # The factorization fails if the current pivot is zero.
    dcol = d[col]
    dcol == 0 && return false

    # Load column col of A into w.
    col_end = colptr[col + 1] - 1
    nzcol = 0
    @inbounds for k = col_start : col_end
      row = rowind[k]
      w[row] = lvals[k]  # w[row] = A[row, col] for each col in turn.
      nzcol += 1
      indr[nzcol] = row
      indf[row] = 1
    end

    # nzcol = number of nonzeros in current column.
    # (indr, w): sparse representation of current column:
    # - the nonzero element A[row, col] is in w[row], and
    # - the k-th nonzero element of A[:, col] is in w[indr[k]], (k = 1, ..., nzcol).

    # Update column col using previous columns.
    k = list[col]

    while k != 0
      kth_col_start = indf[k]
      kth_col_end = colptr[k + 1] - 1
      lval = lvals[kth_col_start]  # lval = L[col, k].
      dl = -d[k] * lval

      newk = list[k]
      kth_col_start += 1
      if kth_col_start < kth_col_end
        row = rowind[kth_col_start]
        indf[k] = kth_col_start
        list[k] = list[row]
        list[row] = k
      end

      # Perform the update L[row, col] <- L[row, col] - D[k, k] * L[col, k] * L[row, k].
      @inbounds for i = kth_col_start : kth_col_end
        row = rowind[i]
        dli = dl * lvals[i]
        if indf[row] != 0
          w[row] += dli  # w[row] = L[row, col], lval = L[col, k], lvals[i] = L[row, k].
        else
          indf[row] = 1
          nzcol += 1
          indr[nzcol] = row
          w[row] = dli
        end
      end

      k = newk
    end

    # Compute (incomplete) column col of L.
    @inbounds @simd for k = 1 : nzcol
      w[indr[k]] /= dcol
      # d[row] -= d[col] * w[row] * w[row];  # Variant I.
    end

    nz_to_keep = min(col_end - col_start + 1 + memory, nzcol)
    kth = nzcol - nz_to_keep + 1

    if nzcol ≥ 1
      # Determine the kth smallest elements in current column
      abspermute!(w, view(indr, 1:nzcol), kth)
      # At this point, w[indr[1:nzcol]] is partially sorted in increasing order of absolute
      # values. The kth smallest element of w in absolute value is in w[indr[kth]].

      # Sort the row indices of the nz_to_keep largest elements
      # so we can later retrieve L[i,k] from indf[k].
      sort!(indr, kth, nzcol, nz_to_keep ≤ 50 ? InsertionSort : MergeSort, Base.Order.Forward)
    end

    new_col_start = colptr[col]
    new_col_end = new_col_start + nz_to_keep - 1
    l = new_col_start
    @inbounds @simd for k = new_col_start : new_col_end
      k1 = indr[kth + k - new_col_start]
      val = w[k1]
      # record element unless it should be dropped
      if abs(val) > droptol
        lvals[l] = val
        rowind[l] = k1
        l += 1
      end
    end
    new_col_end = l - 1

    # Variant II of diagonal elements update.
    @inbounds @simd for k = kth : nzcol
      k1 = indr[k]
      wk1 = w[k1]
      d[k1] -= dcol * wk1 * wk1
    end

    if new_col_start < new_col_end
      indf[col] = new_col_start
      row1 = rowind[new_col_start]
      list[col] = list[row1]
      list[row1] = col
    end

    @inbounds @simd for k = 1 : nzcol
      indf[indr[k]] = 0
    end
    col_start = colptr[col + 1]
    colptr[col + 1] = new_col_end + 1
  end

  return true
end

"""Permute the elements of `keys` in place so that

    abs(x[keys[i]]) ≤ abs(x[keys[k]])  for i = 1, ..., k
    abs(x[keys[k]]) ≤ abs(x[keys[i]])  for i = k, ..., n,

where `n` is the length of `keys`. The length of `x` should be
at least `n`. Only `keys` is modified.

From the MINPACK2 function `dsel2` by Kastak, Lin and Moré.
"""
function abspermute!(x::Vector{Tv}, keys::AbstractVector{Ti}, k::Ti) where {Tv<:Number, Ti<:Integer}

  n = size(keys, 1)
  (n <= 1 || k < 1 || k > n) && return

  l = Ti(1)
  u = Ti(n)
  lc = Ti(n)
  lp = Ti(2 * n)

  while l < u
    p1 = div(u + 3 * l,  4)
    p2 = div(u + l, 2)
    p3 = div(3 * u + l, 4)

    if abs(x[keys[l]]) > abs(x[keys[p1]])
      swap = keys[l]
      keys[l] = keys[p1]
      keys[p1] = swap
    end

    if abs(x[keys[p2]]) > abs(x[keys[p3]])
      swap = keys[p2]
      keys[p2] = keys[p3]
      keys[p3] = swap
    end

    if abs(x[keys[p3]]) > abs(x[keys[p1]])
      swap = keys[p3]
      keys[p3] = keys[u]
      keys[u] = swap
      if abs(x[keys[p2]]) > abs(x[keys[p3]])
        swap = keys[p2]
        keys[p2] = keys[p3]
        keys[p3] = swap
      end
    else
      swap = keys[p1]
      keys[p1] = keys[u]
      keys[u] = swap
      if abs(x[keys[l]]) > abs(x[keys[p1]])
        swap = keys[l]
        keys[l] = keys[p1]
        keys[p1] = swap
      end
    end

    if abs(x[keys[p1]]) > abs(x[keys[p3]])
      if abs(x[keys[l]]) ≤ abs(x[keys[p3]])
        swap = keys[l]
        keys[l] = keys[p3]
        keys[p3] = swap
      end
    else
      if abs(x[keys[p2]]) ≤ abs(x[keys[p1]])
        swap = keys[l]
        keys[l] = keys[p1]
        keys[p1] = swap
      else
        swap = keys[l]
        keys[l] = keys[p2]
        keys[p2] = swap
      end
    end

    m = l
    absxl = abs(x[keys[l]])
    @inbounds for i = l + 1 : u
      if abs(x[keys[i]]) < absxl
        m = m + 1
        swap = keys[m]
        keys[m] = keys[i]
        keys[i] = swap
      end
    end

    swap = keys[l]
    keys[l] = keys[m]
    keys[m] = swap

    k ≥ m && (l = m + 1)
    k ≤ m && (u = m - 1)

    if (3 * (u - l) > 2 * lp) && (k > m)
      p = m
      absxm = abs(x[keys[m]])
      @inbounds for i = m + 1 : u
        if abs(x[keys[i]]) == absxm
          p = p + 1
          swap = keys[p]
          keys[p] = keys[i]
          keys[i] = swap
        end
      end

      l = p + 1
      k ≤ p && (u = p - 1)
    end

    lp = lc
    lc = u - l
  end
end

end  # Module.


text:
# This file is a part of Julia. License is MIT: https://julialang.org/license

# Like MultiSelect but adds `n`/`p` to move to next/previous
# unselected item and `N`/`P` to move to next/previous selected item.
mutable struct MultiSelectWithSkipMenu <: TerminalMenus._ConfiguredMenu{TerminalMenus.Config}
    options::Array{String,1}
    pagesize::Int
    pageoffset::Int
    selected::Set{Int}
    cursor::Base.RefValue{Int}
    config::TerminalMenus.MultiSelectConfig
end

function MultiSelectWithSkipMenu(options::Array{String,1}; pagesize::Int=10,
                                 selected=Int[], kwargs...)
    length(options) < 1 && error("MultiSelectWithSkipMenu must have at least one option")

    pagesize = pagesize == -1 ? length(options) : pagesize
    pagesize = min(length(options), pagesize)
    pagesize < 1 && error("pagesize must be >= 1")

    pageoffset = 0
    _selected = Set{Int}()
    for item in selected
        push!(_selected, item)
    end

    MultiSelectWithSkipMenu(options, pagesize, pageoffset, _selected,
                            Ref{Int}(1),
                            TerminalMenus.MultiSelectConfig(; kwargs...))
end

TerminalMenus.header(m::MultiSelectWithSkipMenu) = "[press: d=done, a=all, c=none, npNP=move with skip, $(length(m.selected)) items selected]"

TerminalMenus.options(m::MultiSelectWithSkipMenu) = m.options

TerminalMenus.cancel(m::MultiSelectWithSkipMenu) = m.selected = Set{Int}()

# Do not exit menu when a user selects one of the options
function TerminalMenus.pick(menu::MultiSelectWithSkipMenu, cursor::Int)
    if cursor in menu.selected
        delete!(menu.selected, cursor)
    else
        push!(menu.selected, cursor)
    end

    return false
end

function TerminalMenus.writeline(buf::IOBuffer,
                                 menu::MultiSelectWithSkipMenu,
                                 idx::Int, iscursor::Bool)
    if idx in menu.selected
        print(buf, menu.config.checked, " ")
    else
        print(buf, menu.config.unchecked, " ")
    end

    print(buf, replace(menu.options[idx], "\n" => "\\n"))
end

# d: Done, return from request
# a: Select all
# c: Deselect all
# n: Move to next unselected
# p: Move to previous unselected
# N: Move to next selected
# P: Move to previous selected
function TerminalMenus.keypress(menu::MultiSelectWithSkipMenu, key::UInt32)
    if key == UInt32('d') || key == UInt32('D')
        return true # break
    elseif key == UInt32('a') || key == UInt32('A')
        menu.selected = Set(1:length(menu.options))
    elseif key == UInt32('c') || key == UInt32('C')
        menu.selected = Set{Int}()
    elseif key == UInt32('n')
        move_cursor!(menu, 1, false)
    elseif key == UInt32('p')
        move_cursor!(menu, -1, false)
    elseif key == UInt32('N')
        move_cursor!(menu, 1, true)
    elseif key == UInt32('P')
        move_cursor!(menu, -1, true)
    end
    false # don't break
end

function move_cursor!(menu, direction, selected)
    c = menu.cursor[]
    while true
        c += direction
        if !(1 <= c <= length(menu.options))
            return
        end
        if (c in menu.selected) == selected
            break
        end
    end
    menu.cursor[] = c
    if menu.pageoffset >= c - 1
        menu.pageoffset = max(c - 2, 0)
    end
    if menu.pageoffset + menu.pagesize <= c
        menu.pageoffset = min(c + 1, length(menu.options)) - menu.pagesize
    end
end

# Intercept the `request` call to insert the cursor field.
function TerminalMenus.request(term::REPL.Terminals.TTYTerminal,
                               m::MultiSelectWithSkipMenu;
                               cursor::Int=1, kwargs...)
    m.cursor[] = cursor
    invoke(TerminalMenus.request, Tuple{REPL.Terminals.TTYTerminal,
                                        TerminalMenus.AbstractMenu},
           term, m; cursor=m.cursor, kwargs...)
end

# These tests are specifically designed to verify that a `RefValue`
# input to the AbstractMenu `request` function works as intended.
menu = MultiSelectWithSkipMenu(string.(1:5), selected=[2, 3])
buf = IOBuffer()
TerminalMenus.printmenu(buf, menu, 1; init=true)
@test occursin("2 items selected", String(take!(buf)))
@test simulate_input(menu, 'n', :enter, 'd') == Set([2, 3, 4])
buf = IOBuffer()
TerminalMenus.printmenu(buf, menu, 1; init=true)
@test occursin("3 items selected", String(take!(buf)))

menu = MultiSelectWithSkipMenu(string.(1:5), selected=[2, 3])
@test simulate_input(menu, 'P', :enter, 'd', cursor=5) == Set([2])

max_stars_repo_name: SmiteWindows/julia

max_issues_repo_name: SmiteWindows/julia

max_forks_repo_name: SmiteWindows/julia


text:
module Webview

using Markdown, Pkg

export
	webview, webview_init, doc

include("libwebview.jl")
include("doc.jl")

try
	webview_print_log("")
	global foundit = true
catch
	global foundit = false
end

if (!foundit)
	println("\n\nYou don't seem to have the Webview library installed and I don't currently")
	println("install it automatically, so you will have to do it yourself.")
	if (Sys.iswindows() && Sys.WORD_SIZE == 64)
		println("\nDownload from and install in a dir that is on your system's path")
		println("\t https://gmt.soest.hawaii.edu/projects/gmt/wiki/Download")
	elseif (Sys.iswindows() && Sys.WORD_SIZE == 32)
		println("I have not yet build a 32 bits version. Ping me if you do want one.")
	else
		println("For the time being you need to look at https://github.com/zserge/webview")
		println("for instructions on how to build it on *nix.")
	end
end

end # module


text:
# Automatically generated using Clang.jl wrap_c

struct float2
    x::Cfloat
    y::Cfloat
end

struct float3
    x::Cfloat
    y::Cfloat
    z::Cfloat
end


text:
@cache mutable struct AB3Cache{uType,rateType} <: OrdinaryDiffEqMutableCache
  u::uType
  uprev::uType
  fsalfirst::rateType
  k2::rateType
  k3::rateType
  ralk2::rateType
  k::rateType
  tmp::uType
  step::Int
end

@cache mutable struct AB3ConstantCache{rateType} <: OrdinaryDiffEqConstantCache
  k2::rateType
  k3::rateType
  step::Int
end

function alg_cache(alg::AB3,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{true})
  fsalfirst = zero(rate_prototype)
  k2 = zero(rate_prototype)
  k3 = zero(rate_prototype)
  ralk2 = zero(rate_prototype)
  k  = zero(rate_prototype)
  tmp = zero(u)
  AB3Cache(u,uprev,fsalfirst,k2,k3,ralk2,k,tmp,1)
end

function alg_cache(alg::AB3,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{false})
  k2 = rate_prototype
  k3 = rate_prototype
  AB3ConstantCache(k2,k3,1)
end

@cache mutable struct ABM32Cache{uType,rateType} <: OrdinaryDiffEqMutableCache
  u::uType
  uprev::uType
  fsalfirst::rateType
  k2::rateType
  k3::rateType
  ralk2::rateType
  k::rateType
  tmp::uType
  step::Int
end

@cache mutable struct ABM32ConstantCache{rateType} <: OrdinaryDiffEqConstantCache
  k2::rateType
  k3::rateType
  step::Int
end

function alg_cache(alg::ABM32,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{true})
  fsalfirst = zero(rate_prototype)
  k2 = zero(rate_prototype)
  k3 = zero(rate_prototype)
  ralk2 = zero(rate_prototype)
  k  = zero(rate_prototype)
  tmp = zero(u)
  ABM32Cache(u,uprev,fsalfirst,k2,k3,ralk2,k,tmp,1)
end

function alg_cache(alg::ABM32,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{false})
  k2 = rate_prototype
  k3 = rate_prototype
  ABM32ConstantCache(k2,k3,1)
end

@cache mutable struct AB4Cache{uType,rateType} <: OrdinaryDiffEqMutableCache
  u::uType
  uprev::uType
  fsalfirst::rateType
  k2::rateType
  k3::rateType
  k4::rateType
  ralk2::rateType
  k::rateType
  tmp::uType
  t2::rateType
  t3::rateType
  t4::rateType
  step::Int
end

@cache mutable struct AB4ConstantCache{rateType} <: OrdinaryDiffEqConstantCache
  k2::rateType
  k3::rateType
  k4::rateType
  step::Int
end

function alg_cache(alg::AB4,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{true})
  fsalfirst = zero(rate_prototype)
  k2 = zero(rate_prototype)
  k3 = zero(rate_prototype)
  k4 = zero(rate_prototype)
  ralk2 = zero(rate_prototype)
  k  = zero(rate_prototype)
  tmp = zero(u)
  t2 = zero(rate_prototype)
  t3 = zero(rate_prototype)
  t4 = zero(rate_prototype)
  AB4Cache(u,uprev,fsalfirst,k2,k3,k4,ralk2,k,tmp,t2,t3,t4,1)
end

function alg_cache(alg::AB4,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{false})
  k2 = rate_prototype
  k3 = rate_prototype
  k4 = rate_prototype
  AB4ConstantCache(k2,k3,k4,1)
end

@cache mutable struct ABM43Cache{uType,rateType} <: OrdinaryDiffEqMutableCache
  u::uType
  uprev::uType
  fsalfirst::rateType
  k2::rateType
  k3::rateType
  k4::rateType
  ralk2::rateType
  k::rateType
  tmp::uType
  t2::rateType
  t3::rateType
  t4::rateType
  t5::rateType
  t6::rateType
  t7::rateType
  step::Int
end

@cache mutable struct ABM43ConstantCache{rateType} <: OrdinaryDiffEqConstantCache
  k2::rateType
  k3::rateType
  k4::rateType
  step::Int
end

function alg_cache(alg::ABM43,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{true})
  fsalfirst = zero(rate_prototype)
  k2 = zero(rate_prototype)
  k3 = zero(rate_prototype)
  k4 = zero(rate_prototype)
  ralk2 = zero(rate_prototype)
  k  = zero(rate_prototype)
  tmp = zero(u)
  t2 = zero(rate_prototype)
  t3 = zero(rate_prototype)
  t4 = zero(rate_prototype)
  t5 = zero(rate_prototype)
  t6 = zero(rate_prototype)
  t7 = zero(rate_prototype)
  ABM43Cache(u,uprev,fsalfirst,k2,k3,k4,ralk2,k,tmp,t2,t3,t4,t5,t6,t7,1)
end

function alg_cache(alg::ABM43,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{false})
  k2 = rate_prototype
  k3 = rate_prototype
  k4 = rate_prototype
  ABM43ConstantCache(k2,k3,k4,1)
end

@cache mutable struct AB5Cache{uType,rateType} <: OrdinaryDiffEqMutableCache
  u::uType
  uprev::uType
  fsalfirst::rateType
  k2::rateType
  k3::rateType
  k4::rateType
  k5::rateType
  k::rateType
  tmp::uType
  t2::rateType
  t3::rateType
  t4::rateType
  step::Int
end

@cache mutable struct AB5ConstantCache{rateType} <: OrdinaryDiffEqConstantCache
  k2::rateType
  k3::rateType
  k4::rateType
  k5::rateType
  step::Int
end

function alg_cache(alg::AB5,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{true})
  fsalfirst = zero(rate_prototype)
  k2 = zero(rate_prototype)
  k3 = zero(rate_prototype)
  k4 = zero(rate_prototype)
  k5 = zero(rate_prototype)
  k  = zero(rate_prototype)
  tmp = zero(u)
  t2 = zero(rate_prototype)
  t3 = zero(rate_prototype)
  t4 = zero(rate_prototype)
  AB5Cache(u,uprev,fsalfirst,k2,k3,k4,k5,k,tmp,t2,t3,t4,1)
end

function alg_cache(alg::AB5,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{false})
  k2 = rate_prototype
  k3 = rate_prototype
  k4 = rate_prototype
  k5 = rate_prototype
  AB5ConstantCache(k2,k3,k4,k5,1)
end

@cache mutable struct ABM54Cache{uType,rateType} <: OrdinaryDiffEqMutableCache
  u::uType
  uprev::uType
  fsalfirst::rateType
  k2::rateType
  k3::rateType
  k4::rateType
  k5::rateType
  k::rateType
  tmp::uType
  t2::rateType
  t3::rateType
  t4::rateType
  t5::rateType
  t6::rateType
  t7::rateType
  t8::rateType
  step::Int
end

@cache mutable struct ABM54ConstantCache{rateType} <: OrdinaryDiffEqConstantCache
  k2::rateType
  k3::rateType
  k4::rateType
  k5::rateType
  step::Int
end

function alg_cache(alg::ABM54,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{true})
  fsalfirst = zero(rate_prototype)
  k2 = zero(rate_prototype)
  k3 = zero(rate_prototype)
  k4 = zero(rate_prototype)
  k5 = zero(rate_prototype)
  k  = zero(rate_prototype)
  tmp = zero(u)
  t2 = zero(rate_prototype)
  t3 = zero(rate_prototype)
  t4 = zero(rate_prototype)
  t5 = zero(rate_prototype)
  t6 = zero(rate_prototype)
  t7 = zero(rate_prototype)
  t8 = zero(rate_prototype)
  ABM54Cache(u,uprev,fsalfirst,k2,k3,k4,k5,k,tmp,t2,t3,t4,t5,t6,t7,t8,1)
end

function alg_cache(alg::ABM54,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{false})
  k2 = rate_prototype
  k3 = rate_prototype
  k4 = rate_prototype
  k5 = rate_prototype
  ABM54ConstantCache(k2,k3,k4,k5,1)
end

@cache mutable struct VCAB3ConstantCache{TabType,tArrayType,rArrayType,cArrayType,dtArrayType} <: OrdinaryDiffEqConstantCache
  dts::dtArrayType
  c::cArrayType
  g::tArrayType
  ϕ_n::rArrayType
  ϕstar_nm1::rArrayType
  ϕstar_n::rArrayType
  β::tArrayType
  order::Int
  tab::TabType
  step::Int
end

@cache mutable struct VCAB3Cache{uType,rateType,TabType,bs3Type,tArrayType,cArrayType,uNoUnitsType,coefType,dtArrayType} <: OrdinaryDiffEqMutableCache
  u::uType
  uprev::uType
  fsalfirst::rateType
  bs3cache::bs3Type
  k4::rateType
  ϕstar_nm1::coefType
  dts::dtArrayType
  c::cArrayType
  g::tArrayType
  ϕ_n::coefType
  ϕstar_n::coefType
  β::tArrayType
  order::Int
  atmp::uNoUnitsType
  tmp::uType
  utilde::uType
  tab::TabType
  step::Int
end

function alg_cache(alg::VCAB3,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{false})
  dts = fill(zero(dt),3)
  c = fill(zero(t), 3, 3)
  g = fill(zero(t), 3)
  ϕ_n = Vector{typeof(rate_prototype)}(undef, 3)
  ϕstar_nm1 = Vector{typeof(rate_prototype)}(undef, 3)
  ϕstar_n = Vector{typeof(rate_prototype)}(undef, 3)
  for i in 1:3
    ϕ_n[i] = copy(rate_prototype)
    ϕstar_nm1[i] = copy(rate_prototype)
    ϕstar_n[i] = copy(rate_prototype)
  end
  β = fill(zero(t),3)
  order = 3
  tab = BS3ConstantCache(constvalue(uBottomEltypeNoUnits),constvalue(tTypeNoUnits))
  VCAB3ConstantCache(dts,c,g,ϕ_n,ϕstar_nm1,ϕstar_n,β,order,tab,1)
end

function alg_cache(alg::VCAB3,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{true})
  tab = BS3ConstantCache(constvalue(uBottomEltypeNoUnits),constvalue(tTypeNoUnits))
  bk1 = zero(rate_prototype)
  bk2 = zero(rate_prototype)
  bk3 = zero(rate_prototype)
  bk4 = zero(rate_prototype)
  butilde = zero(u)
  batmp = similar(u,uEltypeNoUnits)
  btmp = zero(u)
  bs3cache = BS3Cache(u,uprev,bk1,bk2,bk3,bk4,butilde,btmp,batmp,tab)
  fsalfirst = zero(rate_prototype)
  k4 = zero(rate_prototype)
  dts = fill(zero(dt),3)
  c = fill(zero(t), 3, 3)
  g = fill(zero(t), 3)
  ϕ_n = Vector{typeof(rate_prototype)}(undef, 3)
  ϕstar_nm1 = Vector{typeof(rate_prototype)}(undef, 3)
  ϕstar_n = Vector{typeof(rate_prototype)}(undef, 3)
  for i in 1:3
    ϕ_n[i] = zero(rate_prototype)
    ϕstar_nm1[i] = zero(rate_prototype)
    ϕstar_n[i] = zero(rate_prototype)
  end
  β = fill(zero(t),3)
  order = 3
  atmp = similar(u,uEltypeNoUnits)
  tmp = zero(u)
  utilde = zero(u)
  VCAB3Cache(u,uprev,fsalfirst,bs3cache,k4,ϕstar_nm1,dts,c,g,ϕ_n,ϕstar_n,β,order,atmp,tmp,utilde,tab,1)
end

@cache mutable struct VCAB4ConstantCache{rk4constcache,tArrayType,rArrayType,cArrayType,dtArrayType} <: OrdinaryDiffEqConstantCache
  ϕstar_nm1::rArrayType
  dts::dtArrayType
  c::cArrayType
  g::tArrayType
  ϕ_n::rArrayType
  ϕstar_n::rArrayType
  β::tArrayType
  order::Int
  rk4constcache::rk4constcache
  step::Int
end

@cache mutable struct VCAB4Cache{uType,rateType,rk4cacheType,tArrayType,cArrayType,uNoUnitsType,coefType,dtArrayType} <: OrdinaryDiffEqMutableCache
  u::uType
  uprev::uType
  fsalfirst::rateType
  rk4cache::rk4cacheType
  k4::rateType
  ϕstar_nm1::coefType
  dts::dtArrayType
  c::cArrayType
  g::tArrayType
  ϕ_n::coefType
  ϕstar_n::coefType
  β::tArrayType
  order::Int
  atmp::uNoUnitsType
  tmp::uType
  utilde::uType
  step::Int
end

function alg_cache(alg::VCAB4,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{false})
  dts = fill(zero(dt),4)
  c = fill(zero(t), 4, 4)
  g = fill(zero(t), 4)
  ϕ_n = Vector{typeof(rate_prototype)}(undef, 4)
  ϕstar_nm1 = Vector{typeof(rate_prototype)}(undef, 4)
  ϕstar_n = Vector{typeof(rate_prototype)}(undef, 4)
  for i in 1:4
    ϕ_n[i] = copy(rate_prototype)
    ϕstar_nm1[i] = copy(rate_prototype)
    ϕstar_n[i] = copy(rate_prototype)
  end
  β = fill(zero(t),4)
  order = 4
  rk4constcache = RK4ConstantCache()
  VCAB4ConstantCache(ϕstar_nm1,dts,c,g,ϕ_n,ϕstar_n,β,order,rk4constcache,1)
end

function alg_cache(alg::VCAB4,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{true})
  rk1 = zero(rate_prototype)
  rk2 = zero(rate_prototype)
  rk3 = zero(rate_prototype)
  rk4 = zero(rate_prototype)
  rk  = zero(rate_prototype)
  rtmp = zero(u); ratmp = similar(u, uEltypeNoUnits)
  rk4cache = RK4Cache(u,uprev,rk1,rk2,rk3,rk4,rk,rtmp,ratmp)
  fsalfirst = zero(rate_prototype)
  k4 = zero(rate_prototype)
  dts = fill(zero(dt),4)
  c = fill(zero(t), 4, 4)
  g = fill(zero(t), 4)
  ϕ_n = Vector{typeof(rate_prototype)}(undef, 4)
  ϕstar_nm1 = Vector{typeof(rate_prototype)}(undef, 4)
  ϕstar_n = Vector{typeof(rate_prototype)}(undef, 4)
  for i in 1:4
    ϕ_n[i] = zero(rate_prototype)
    ϕstar_nm1[i] = zero(rate_prototype)
    ϕstar_n[i] = zero(rate_prototype)
  end
  β = fill(zero(t),4)
  order = 4
  atmp = similar(u,uEltypeNoUnits)
  tmp = zero(u)
  utilde = zero(u)
  VCAB4Cache(u,uprev,fsalfirst,rk4cache,k4,ϕstar_nm1,dts,c,g,ϕ_n,ϕstar_n,β,order,atmp,tmp,utilde,1)
end

# VCAB5

@cache mutable struct VCAB5ConstantCache{rk4constcache,tArrayType,rArrayType,cArrayType,dtArrayType} <: OrdinaryDiffEqConstantCache
  ϕstar_nm1::rArrayType
  dts::dtArrayType
  c::cArrayType
  g::tArrayType
  ϕ_n::rArrayType
  ϕstar_n::rArrayType
  β::tArrayType
  order::Int
  rk4constcache::rk4constcache
  step::Int
end

@cache mutable struct VCAB5Cache{uType,rateType,rk4cacheType,tArrayType,cArrayType,uNoUnitsType,coefType,dtArrayType} <: OrdinaryDiffEqMutableCache
  u::uType
  uprev::uType
  fsalfirst::rateType
  rk4cache::rk4cacheType
  k4::rateType
  ϕstar_nm1::coefType
  dts::dtArrayType
  c::cArrayType
  g::tArrayType
  ϕ_n::coefType
  ϕstar_n::coefType
  β::tArrayType
  order::Int
  atmp::uNoUnitsType
  tmp::uType
  utilde::uType
  step::Int
end

function alg_cache(alg::VCAB5,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{false})
  dts = fill(zero(dt),5)
  c = fill(zero(t), 5, 5)
  g = fill(zero(t), 5)
  ϕ_n = Vector{typeof(rate_prototype)}(undef, 5)
  ϕstar_nm1 = Vector{typeof(rate_prototype)}(undef, 5)
  ϕstar_n = Vector{typeof(rate_prototype)}(undef, 5)
  for i in 1:5
    ϕ_n[i] = copy(rate_prototype)
    ϕstar_nm1[i] = copy(rate_prototype)
    ϕstar_n[i] = copy(rate_prototype)
  end
  β = fill(zero(t),5)
  order = 5
  rk4constcache = RK4ConstantCache()
  VCAB5ConstantCache(ϕstar_nm1,dts,c,g,ϕ_n,ϕstar_n,β,order,rk4constcache,1)
end

function alg_cache(alg::VCAB5,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{true})
  rk1 = zero(rate_prototype)
  rk2 = zero(rate_prototype)
  rk3 = zero(rate_prototype)
  rk4 = zero(rate_prototype)
  rk  = zero(rate_prototype)
  rtmp = zero(u); ratmp = similar(u, uEltypeNoUnits)
  rk4cache = RK4Cache(u,uprev,rk1,rk2,rk3,rk4,rk,rtmp,ratmp)
  fsalfirst = zero(rate_prototype)
  k4 = zero(rate_prototype)
  dts = fill(zero(dt),5)
  c = fill(zero(t), 5, 5)
  g = fill(zero(t), 5)
  ϕ_n = Vector{typeof(rate_prototype)}(undef, 5)
  ϕstar_nm1 = Vector{typeof(rate_prototype)}(undef, 5)
  ϕstar_n = Vector{typeof(rate_prototype)}(undef, 5)
  for i in 1:5
    ϕ_n[i] = zero(rate_prototype)
    ϕstar_nm1[i] = zero(rate_prototype)
    ϕstar_n[i] = zero(rate_prototype)
  end
  β = fill(zero(t),5)
  order = 5
  atmp = similar(u,uEltypeNoUnits)
  tmp = zero(u)
  utilde = zero(u)
  VCAB5Cache(u,uprev,fsalfirst,rk4cache,k4,ϕstar_nm1,dts,c,g,ϕ_n,ϕstar_n,β,order,atmp,tmp,utilde,1)
end

# VCABM3

@cache mutable struct VCABM3ConstantCache{TabType,tArrayType,rArrayType,cArrayType,dtArrayType} <: OrdinaryDiffEqConstantCache
  dts::dtArrayType
  c::cArrayType
  g::tArrayType
  ϕ_n::rArrayType
  ϕ_np1::rArrayType
  ϕstar_nm1::rArrayType
  ϕstar_n::rArrayType
  β::tArrayType
  order::Int
  tab::TabType
  step::Int
end

@cache mutable struct VCABM3Cache{uType,rateType,TabType,bs3Type,tArrayType,cArrayType,uNoUnitsType,coefType,dtArrayType} <: OrdinaryDiffEqMutableCache
  u::uType
  uprev::uType
  fsalfirst::rateType
  bs3cache::bs3Type
  k4::rateType
  ϕstar_nm1::coefType
  dts::dtArrayType
  c::cArrayType
  g::tArrayType
  ϕ_n::coefType
  ϕ_np1::coefType
  ϕstar_n::coefType
  β::tArrayType
  order::Int
  atmp::uNoUnitsType
  tmp::uType
  utilde::uType
  tab::TabType
  step::Int
end

function alg_cache(alg::VCABM3,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{false})
  dts = fill(zero(dt),3)
  c = fill(zero(t), 4, 4)
  g = fill(zero(t), 4)
  ϕ_n = Vector{typeof(rate_prototype)}(undef, 3)
  ϕstar_nm1 = Vector{typeof(rate_prototype)}(undef, 3)
  ϕstar_n = Vector{typeof(rate_prototype)}(undef, 3)
  ϕ_np1 = Vector{typeof(rate_prototype)}(undef, 4)
  for i in 1:3
    ϕ_n[i] = copy(rate_prototype)
    ϕstar_nm1[i] = copy(rate_prototype)
    ϕstar_n[i] = copy(rate_prototype)
  end
  β = fill(zero(t),3)
  order = 3
  tab = BS3ConstantCache(constvalue(uBottomEltypeNoUnits),constvalue(tTypeNoUnits))
  VCABM3ConstantCache(dts,c,g,ϕ_n,ϕ_np1,ϕstar_nm1,ϕstar_n,β,order,tab,1)
end

function alg_cache(alg::VCABM3,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{true})
  tab = BS3ConstantCache(constvalue(uBottomEltypeNoUnits),constvalue(tTypeNoUnits))
  bk1 = zero(rate_prototype)
  bk2 = zero(rate_prototype)
  bk3 = zero(rate_prototype)
  bk4 = zero(rate_prototype)
  butilde = zero(u)
  batmp = similar(u,uEltypeNoUnits)
  btmp = zero(u)
  bs3cache = BS3Cache(u,uprev,bk1,bk2,bk3,bk4,butilde,btmp,batmp,tab)
  fsalfirst = zero(rate_prototype)
  k4 = zero(rate_prototype)
  dts = fill(zero(dt),3)
  c = fill(zero(t), 4, 4)
  g = fill(zero(t), 4)
  ϕ_n = Vector{typeof(rate_prototype)}(undef, 3)
  ϕstar_nm1 = Vector{typeof(rate_prototype)}(undef, 3)
  ϕstar_n = Vector{typeof(rate_prototype)}(undef, 3)
  ϕ_np1 = Vector{typeof(rate_prototype)}(undef, 4)
  for i in 1:3
    ϕ_n[i] = zero(rate_prototype)
    ϕstar_nm1[i] = zero(rate_prototype)
    ϕstar_n[i] = zero(rate_prototype)
  end
  for i in 1:4
    ϕ_np1[i] = zero(rate_prototype)
  end
  β = fill(zero(t),3)
  order = 3
  atmp = similar(u,uEltypeNoUnits)
  tmp = zero(u)
  utilde = zero(u)
  VCABM3Cache(u,uprev,fsalfirst,bs3cache,k4,ϕstar_nm1,dts,c,g,ϕ_n,ϕ_np1,ϕstar_n,β,order,atmp,tmp,utilde,tab,1)
end

# VCABM4

@cache mutable struct VCABM4ConstantCache{rk4constcache,tArrayType,rArrayType,cArrayType,dtArrayType} <: OrdinaryDiffEqConstantCache
  ϕstar_nm1::rArrayType
  dts::dtArrayType
  c::cArrayType
  g::tArrayType
  ϕ_n::rArrayType
  ϕ_np1::rArrayType
  ϕstar_n::rArrayType
  β::tArrayType
  order::Int
  rk4constcache::rk4constcache
  step::Int
end

@cache mutable struct VCABM4Cache{uType,rateType,rk4cacheType,tArrayType,cArrayType,uNoUnitsType,coefType,dtArrayType} <: OrdinaryDiffEqMutableCache
  u::uType
  uprev::uType
  fsalfirst::rateType
  rk4cache::rk4cacheType
  k4::rateType
  ϕstar_nm1::coefType
  dts::dtArrayType
  c::cArrayType
  g::tArrayType
  ϕ_n::coefType
  ϕ_np1::coefType
  ϕstar_n::coefType
  β::tArrayType
  order::Int
  atmp::uNoUnitsType
  tmp::uType
  utilde::uType
  step::Int
end

function alg_cache(alg::VCABM4,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{false})
  dts = fill(zero(dt),4)
  c = fill(zero(t), 5, 5)
  g = fill(zero(t), 5)
  ϕ_n = Vector{typeof(rate_prototype)}(undef, 4)
  ϕstar_nm1 = Vector{typeof(rate_prototype)}(undef, 4)
  ϕstar_n = Vector{typeof(rate_prototype)}(undef, 4)
  ϕ_np1 = Vector{typeof(rate_prototype)}(undef, 5)
  for i in 1:4
    ϕ_n[i] = copy(rate_prototype)
    ϕstar_nm1[i] = copy(rate_prototype)
    ϕstar_n[i] = copy(rate_prototype)
  end
  β = fill(zero(t),4)
  order = 4
  rk4constcache = RK4ConstantCache()
  VCABM4ConstantCache(ϕstar_nm1,dts,c,g,ϕ_n,ϕ_np1,ϕstar_n,β,order,rk4constcache,1)
end

function alg_cache(alg::VCABM4,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{true})
  rk1 = zero(rate_prototype)
  rk2 = zero(rate_prototype)
  rk3 = zero(rate_prototype)
  rk4 = zero(rate_prototype)
  rk  = zero(rate_prototype)
  rtmp = zero(u); ratmp = similar(u, uEltypeNoUnits)
  rk4cache = RK4Cache(u,uprev,rk1,rk2,rk3,rk4,rk,rtmp,ratmp)
  fsalfirst = zero(rate_prototype)
  k4 = zero(rate_prototype)
  dts = fill(zero(dt),4)
  c = fill(zero(t), 5, 5)
  g = fill(zero(t), 5)
  ϕ_n = Vector{typeof(rate_prototype)}(undef, 4)
  ϕstar_nm1 = Vector{typeof(rate_prototype)}(undef, 4)
  ϕstar_n = Vector{typeof(rate_prototype)}(undef, 4)
  ϕ_np1 = Vector{typeof(rate_prototype)}(undef, 5)
  for i in 1:4
    ϕ_n[i] = zero(rate_prototype)
    ϕstar_nm1[i] = zero(rate_prototype)
    ϕstar_n[i] = zero(rate_prototype)
  end
  for i in 1:5
    ϕ_np1[i] = zero(rate_prototype)
  end
  β = fill(zero(t),4)
  order = 4
  atmp = similar(u,uEltypeNoUnits)
  tmp = zero(u)
  utilde = zero(u)
  VCABM4Cache(u,uprev,fsalfirst,rk4cache,k4,ϕstar_nm1,dts,c,g,ϕ_n,ϕ_np1,ϕstar_n,β,order,atmp,tmp,utilde,1)
end

# VCABM5

@cache mutable struct VCABM5ConstantCache{rk4constcache,tArrayType,rArrayType,cArrayType,dtArrayType} <: OrdinaryDiffEqConstantCache
  ϕstar_nm1::rArrayType
  dts::dtArrayType
  c::cArrayType
  g::tArrayType
  ϕ_n::rArrayType
  ϕ_np1::rArrayType
  ϕstar_n::rArrayType
  β::tArrayType
  order::Int
  rk4constcache::rk4constcache
  step::Int
end

@cache mutable struct VCABM5Cache{uType,rateType,rk4cacheType,tArrayType,cArrayType,uNoUnitsType,coefType,dtArrayType} <: OrdinaryDiffEqMutableCache
  u::uType
  uprev::uType
  fsalfirst::rateType
  rk4cache::rk4cacheType
  k4::rateType
  ϕstar_nm1::coefType
  dts::dtArrayType
  c::cArrayType
  g::tArrayType
  ϕ_n::coefType
  ϕ_np1::coefType
  ϕstar_n::coefType
  β::tArrayType
  order::Int
  atmp::uNoUnitsType
  tmp::uType
  utilde::uType
  step::Int
end

function alg_cache(alg::VCABM5,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{false})
  dts = fill(zero(t),5)
  c = fill(zero(t), 6, 6)
  g = fill(zero(t), 6)
  ϕ_n = Vector{typeof(rate_prototype)}(undef, 5)
  ϕstar_nm1 = Vector{typeof(rate_prototype)}(undef, 5)
  ϕstar_n = Vector{typeof(rate_prototype)}(undef, 5)
  ϕ_np1 = Vector{typeof(rate_prototype)}(undef, 6)
  for i in 1:5
    ϕ_n[i] = copy(rate_prototype)
    ϕstar_nm1[i] = copy(rate_prototype)
    ϕstar_n[i] = copy(rate_prototype)
  end
  β = fill(zero(t),5)
  order = 5
  rk4constcache = RK4ConstantCache()
  VCABM5ConstantCache(ϕstar_nm1,dts,c,g,ϕ_n,ϕ_np1,ϕstar_n,β,order,rk4constcache,1)
end

function alg_cache(alg::VCABM5,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{true})
  rk1 = zero(rate_prototype)
  rk2 = zero(rate_prototype)
  rk3 = zero(rate_prototype)
  rk4 = zero(rate_prototype)
  rk  = zero(rate_prototype)
  rtmp = zero(u); ratmp = similar(u, uEltypeNoUnits)
  rk4cache = RK4Cache(u,uprev,rk1,rk2,rk3,rk4,rk,rtmp,ratmp)
  fsalfirst = zero(rate_prototype)
  k4 = zero(rate_prototype)
  dts = fill(zero(dt),5)
  c = fill(zero(t), 6, 6)
  g = fill(zero(t), 6)
  ϕ_n = Vector{typeof(rate_prototype)}(undef, 5)
  ϕstar_nm1 = Vector{typeof(rate_prototype)}(undef, 5)
  ϕstar_n = Vector{typeof(rate_prototype)}(undef, 5)
  ϕ_np1 = Vector{typeof(rate_prototype)}(undef, 6)
  for i in 1:5
    ϕ_n[i] = zero(rate_prototype)
    ϕstar_nm1[i] = zero(rate_prototype)
    ϕstar_n[i] = zero(rate_prototype)
  end
  for i in 1:6
    ϕ_np1[i] = zero(rate_prototype)
  end
  β = fill(zero(t),5)
  order = 5
  atmp = similar(u,uEltypeNoUnits)
  tmp = zero(u)
  utilde = zero(u)
  VCABM5Cache(u,uprev,fsalfirst,rk4cache,k4,ϕstar_nm1,dts,c,g,ϕ_n,ϕ_np1,ϕstar_n,β,order,atmp,tmp,utilde,1)
end

# VCABM

@cache mutable struct VCABMConstantCache{tArrayType,rArrayType,cArrayType,dtType,dtArrayType} <: OrdinaryDiffEqConstantCache
  ϕstar_nm1::rArrayType
  dts::dtArrayType
  c::cArrayType
  g::tArrayType
  ϕ_n::rArrayType
  ϕ_np1::rArrayType
  ϕstar_n::rArrayType
  β::tArrayType
  ξ::dtType
  ξ0::dtType
  order::Int
  max_order::Int
  step::Int
end

@cache mutable struct VCABMCache{uType,rateType,dtType,tArrayType,cArrayType,uNoUnitsType,coefType,dtArrayType} <: OrdinaryDiffEqMutableCache
  u::uType
  uprev::uType
  fsalfirst::rateType
  k4::rateType
  ϕstar_nm1::coefType
  dts::dtArrayType
  c::cArrayType
  g::tArrayType
  ϕ_n::coefType
  ϕ_np1::coefType
  ϕstar_n::coefType
  β::tArrayType
  order::Int
  max_order::Int
  atmp::uNoUnitsType
  tmp::uType
  ξ::dtType
  ξ0::dtType
  utilde::uType
  utildem1::uType
  utildem2::uType
  utildep1::uType
  atmpm1::uNoUnitsType
  atmpm2::uNoUnitsType
  atmpp1::uNoUnitsType
  step::Int
end

function alg_cache(alg::VCABM,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{false})
  dts = fill(zero(dt),13)
  c = fill(zero(t), 13, 13)
  g = fill(zero(t), 13)
  ϕ_n = Vector{typeof(rate_prototype)}(undef, 13)
  ϕstar_nm1 = Vector{typeof(rate_prototype)}(undef, 13)
  ϕstar_n = Vector{typeof(rate_prototype)}(undef, 13)
  ϕ_np1 = Vector{typeof(rate_prototype)}(undef, 14)
  for i in 1:13
    ϕ_n[i] = copy(rate_prototype)
    ϕstar_nm1[i] = copy(rate_prototype)
    ϕstar_n[i] = copy(rate_prototype)
  end
  β = fill(zero(t),13)
  ξ = zero(dt)
  ξ0 = zero(dt)
  order = 1
  max_order = 12
  VCABMConstantCache(ϕstar_nm1,dts,c,g,ϕ_n,ϕ_np1,ϕstar_n,β,ξ,ξ0,order,max_order,1)
end

function alg_cache(alg::VCABM,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{true})
  fsalfirst = zero(rate_prototype)
  k4 = zero(rate_prototype)
  dts = fill(zero(dt),13)
  c = fill(zero(t), 13, 13)
  g = fill(zero(t), 13)
  ϕ_n = Vector{typeof(rate_prototype)}(undef, 13)
  ϕstar_nm1 = Vector{typeof(rate_prototype)}(undef, 13)
  ϕstar_n = Vector{typeof(rate_prototype)}(undef, 13)
  ϕ_np1 = Vector{typeof(rate_prototype)}(undef, 14)
  for i in 1:13
    ϕ_n[i] = zero(rate_prototype)
    ϕstar_nm1[i] = zero(rate_prototype)
    ϕstar_n[i] = zero(rate_prototype)
  end
  for i in 1:14
    ϕ_np1[i] = zero(rate_prototype)
  end
  β = fill(zero(t), 13)
  order = 1
  max_order = 12
  atmp = similar(u,uEltypeNoUnits)
  tmp = zero(u)
  ξ = zero(dt)
  ξ0 = zero(dt)
  utilde = zero(u)
  utildem2 = zero(u)
  utildem1 = zero(u)
  utildep1 = zero(u)
  atmp = similar(u,uEltypeNoUnits)
  atmpm1 = similar(u,uEltypeNoUnits)
  atmpm2 = similar(u,uEltypeNoUnits)
  atmpp1 = similar(u,uEltypeNoUnits)
  VCABMCache(u,uprev,fsalfirst,k4,ϕstar_nm1,dts,c,g,ϕ_n,ϕ_np1,ϕstar_n,β,order,max_order,atmp,tmp,ξ,ξ0,utilde,utildem1,utildem2,utildep1,atmpm1,atmpm2,atmpp1,1)
end

# IMEX Multistep methods

# CNAB2

@cache mutable struct CNAB2ConstantCache{rateType,N,uType,tType} <: OrdinaryDiffEqConstantCache
  k2::rateType
  nlsolver::N
  uprev3::uType
  tprev2::tType
end

@cache mutable struct CNAB2Cache{uType,rateType,N,tType} <: OrdinaryDiffEqMutableCache
  u::uType
  uprev::uType
  uprev2::uType
  fsalfirst::rateType
  k1::rateType
  k2::rateType
  du₁::rateType
  nlsolver::N
  uprev3::uType
  tprev2::tType
end

function alg_cache(alg::CNAB2,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{false})
  γ, c = 1//2, 1
  nlsolver = build_nlsolver(alg,u,uprev,p,t,dt,f,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,γ,c,Val(false))

  k2 = rate_prototype
  uprev3 = u
  tprev2 = t

  CNAB2ConstantCache(k2,nlsolver,uprev3,tprev2)
end

function alg_cache(alg::CNAB2,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{true})
  γ, c = 1//2, 1
  nlsolver = build_nlsolver(alg,u,uprev,p,t,dt,f,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,γ,c,Val(true))
  fsalfirst = zero(rate_prototype)

  k1 = zero(rate_prototype)
  k2 = zero(rate_prototype)
  du₁ = zero(rate_prototype)
  uprev3 = zero(u)
  tprev2 = t

  CNAB2Cache(u,uprev,uprev2,fsalfirst,k1,k2,du₁,nlsolver,uprev3,tprev2)
end

# CNLF2

@cache mutable struct CNLF2ConstantCache{rateType,N,uType,tType} <: OrdinaryDiffEqConstantCache
  k2::rateType
  nlsolver::N
  uprev2::uType
  uprev3::uType
  tprev2::tType
end

@cache mutable struct CNLF2Cache{uType,rateType,N,tType} <: OrdinaryDiffEqMutableCache
  u::uType
  uprev::uType
  uprev2::uType
  fsalfirst::rateType
  k1::rateType
  k2::rateType
  du₁::rateType
  nlsolver::N
  uprev3::uType
  tprev2::tType
end

function alg_cache(alg::CNLF2,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{false})
  γ, c = 1//1, 1
  nlsolver = build_nlsolver(alg,u,uprev,p,t,dt,f,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,γ,c,Val(false))

  k2 = rate_prototype
  uprev2 = u
  uprev3 = u
  tprev2 = t

  CNLF2ConstantCache(k2,nlsolver,uprev2,uprev3,tprev2)
end

function alg_cache(alg::CNLF2,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{true})
  γ, c = 1//1, 1
  nlsolver = build_nlsolver(alg,u,uprev,p,t,dt,f,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,γ,c,Val(true))
  fsalfirst = zero(rate_prototype)

  k1 = zero(rate_prototype)
  k2 = zero(rate_prototype)
  du₁ = zero(rate_prototype)
  uprev2 = zero(u)
  uprev3 = zero(u)
  tprev2 = t

  CNLF2Cache(u,uprev,uprev2,fsalfirst,k1,k2,du₁,nlsolver,uprev3,tprev2)
end


text:
using Revise, OffsetArrays, ProgressMeter
import KitBase

begin
    cd(@__DIR__)
    D = KitBase.read_dict("poiseuille.txt")
    for key in keys(D)
        s = Symbol(key)
        @eval $s = $(D[key])
    end

    γ = KitBase.heat_capacity_ratio(inK, 1)
    set = KitBase.Setup(
        matter,
        case,
        space,
        flux,
        collision,
        nSpecies,
        interpOrder,
        limiter,
        boundary,
        cfl,
        maxTime,
    )
    pSpace = KitBase.PSpace1D(x0, x1, nx, nxg)
    vSpace = KitBase.VSpace1D(umin, umax, nu, vMeshType, nug)
    μᵣ = KitBase.ref_vhs_vis(knudsen, alphaRef, omegaRef)
    gas =
        KitBase.Gas(knudsen, mach, prandtl, inK, γ, omega, alphaRef, omegaRef, μᵣ, mass, 0)

    primL = [1.0, 0.0, -1.0, 1.0] # left wall
    primR = [1.0, 0.0, 1.0, 1.0] # right wall
    wL = KitBase.prim_conserve(primL, γ)
    wR = KitBase.prim_conserve(primR, γ)
    ib = KitBase.IB(wL, primL, primL, wR, primR, primR)

    ks = KitBase.SolverSet(set, pSpace, vSpace, gas, ib, pwd())
end

begin
    ctr = OffsetArray{KitBase.ControlVolumeParticle1D}(undef, eachindex(ks.pSpace.x))
    face = Array{KitBase.Interface1D}(undef, ks.pSpace.nx + 1)
    for i in eachindex(ctr)
        prim = [1.0, 0.0, primL[3] + 2.0 * (ks.pSpace.x[i] - ks.pSpace.x0), 1.0]

        ctr[i] = KitBase.ControlVolumeParticle1D(
            ks.pSpace.x[i],
            ks.pSpace.dx[i],
            KitBase.prim_conserve(prim, ks.gas.γ),
            prim,
            KitBase.vhs_collision_time(prim, ks.gas.μᵣ, ks.gas.ω),
        )
    end

    for i = 1:ks.pSpace.nx+1
        face[i] = KitBase.Interface1D(ks.ib.wL)
    end

    t = 0.0
    dt = KitBase.timestep(ks, ctr, t)
    res = zeros(4)
end

ptc = KitBase.init_ptc!(ks, ctr)

@showprogress for iter = 1:100
    KitBase.free_transport!(ks, ptc.x, ptc.v, ptc.flag, dt)
    KitBase.boundary!(ks, ctr, ptc, face, dt, :maxwell)
    KitBase.sort!(ks, ctr, ptc.x, ptc.idx, ptc.ref)
    KitBase.dsmc!(ks, ctr, ptc.ref, ptc.v, dt)
    KitBase.stat!(ks, ctr, ptc)
end

begin
    using Plots
    sol = zeros(ks.pSpace.nx, 4)
    for i = 1:ks.pSpace.nx
        sol[i, :] .= ctr[i].prim
    end

    plot(ks.pSpace.x[1:ks.pSpace.nx], sol[:, :])
end


text:
Pkg.add("DataFrames");
Pkg.add("XLSX");
Pkg.add("Gurobi");
Pkg.add("MathOptInterface");
Pkg.add("MathOptFormat");
Pkg.add("Distances")

using DataFrames
using Distances
using ExcelReaders
#using GLPK
using MathOptInterface, MathOptFormat
const MOI = MathOptInterface
using XLSX
using Gurobi
using JuMP

max_stars_repo_name: CUHK-IITR-EnergyTransition/CCUS

max_issues_repo_name: CUHK-IITR-EnergyTransition/CCUS

max_forks_repo_name: CUHK-IITR-EnergyTransition/CCUS


text:
using Plots

M = 10;
D = 2;

x = rand(D,M) .- 0.5;
N = ntuple(d-> 32 , D)

padding = ntuple(d-> 2 , D)
blockSize = ntuple(d-> (d==1) ? 16 : 4 , D)
blockSizePadded = ntuple(d-> blockSize[d] + 2*padding[d] , D)

numBlocks =  ntuple(d-> ceil(Int, N[d]/blockSize[d]) , D)
totalBlocks = prod(numBlocks)

nodesInBlock = [ Int[] for l in CartesianIndices(numBlocks) ]

patches = [ zeros(ComplexF64, blockSizePadded) for l in CartesianIndices(numBlocks) ]

for k=1:size(x,2)
  idx = ntuple(d->floor(Int, ((x[d,k]+0.5)*(N[d]-1))÷blockSize[d])+1, D)

  push!(nodesInBlock[idx...], k)
end

scatter(x[1,:], x[2,:])


text:
println(".... run examples and notebooks ....")

using NBInclude

function redirect_devnull(f)
    open(@static(Sys.iswindows() ? "nul" : "/dev/null"), "w") do io
        redirect_stdout(io) do
            f()
        end
    end
end

const ex_dir = "../examples/"
const nb_dir = "../examples/"
# trash = open(@static(Sys.iswindows() ? "nul" : "/dev/null"), "w")

dir = pwd()
cd(@__DIR__)

ex = [x for x in readdir(ex_dir) if occursin(r".jl", x)]
nb = [x for x in readdir(nb_dir) if occursin(r".ipynb", x)]

for x in ex
    print("... include $ex_dir$x (output suppressed) ")
    nam = string(rsplit(x, ".", limit=2)[1])
    mod = gensym(nam)
    expr = :(begin include($ex_dir*$x) end)
    redirect_devnull() do
        @eval module $mod
            using Test
            @testset $nam $expr
        end
    end
    println(" ok ...")
end

for x in nb
    print("... @nbinclude $nb_dir$x (output suppressed) ")
    nam = string(rsplit(x, ".", limit=2)[1])
    mod = gensym(nam)
    expr = :(begin @nbinclude($nb_dir*$x) end)
    redirect_devnull() do
        @eval module $mod
            using Test, NBInclude
            @testset $nam $expr
        end
    end
    println(" ok ...")
end

cd(dir)


text:
# Prepared SQL statement.

"""
Prepared SQL statement.
"""
@Base.kwdef struct SQLStatement <: AbstractString
    sql::String
    dialect::SQLDialect
    vars::Vector{Symbol}
end

Base.ncodeunits(stmt::SQLStatement) =
    ncodeunits(stmt.sql)

Base.codeunit(stmt::SQLStatement) =
    codeunit(stmt.sql)

@Base.propagate_inbounds Base.codeunit(stmt::SQLStatement, i::Integer) =
    codeunit(stmt.sql, i)

@Base.propagate_inbounds Base.isvalid(stmt::SQLStatement, i::Integer) =
    isvalid(stmt.sql, i)

@Base.propagate_inbounds Base.iterate(stmt::SQLStatement, i::Integer = 1) =
    iterate(stmt.sql, i)

Base.String(stmt::SQLStatement) =
    stmt.sql

Base.print(io::IO, stmt::SQLStatement) =
    print(io, stmt.sql)

Base.write(io::IO, stmt::SQLStatement) =
    write(io, stmt.sql)

"""
    pack(stmt::SQLStatement, vars::Union{Dict, NamedTuple}) :: Vector{Any}

Convert named parameters to positional form.
"""
function pack
end

pack(stmt::SQLStatement, d::AbstractDict{Symbol}) =
    Any[d[var] for var in stmt.vars]

pack(stmt::SQLStatement, d::AbstractDict{<:AbstractString}) =
    Any[d[String(var)] for var in stmt.vars]

pack(stmt::SQLStatement, nt::NamedTuple) =
    Any[getproperty(nt, var) for var in stmt.vars]