text:
include("Token.jl")

istype(tk::Token)      = tk.id == TYPE
isident(tk::Token)     = tk.id == IDENTIFIER
issemicolon(tk::Token) = tk.id == PUNCTUATION && tk.text == ";"
isio(tk::Token)        = tk.id == RESERVED_WORD && (tk.text == "escreva" || tk.text == "leia")

global const T = "    "

function type_p2c(typestr::AbstractString)::String
    if typestr == "int" || typestr == "char"
        return typestr
    elseif typestr == "real"
        return "double"
    elseif typestr == "boleano"
        return "bool"
    elseif typestr == "texto"
        return "char*"
    end # if
end # type_p2c

function type2fmt(typestr)::String
    if typestr == "int"
        return "%d"
    elseif typestr == "real"
        return "%lf"
    elseif typestr == "boleano"
        return "%d"
    elseif typestr == "char"
        return "%c"
    elseif typestr == "texto"
        return "%s"
    else
        return "%p"
    end # if
end # type2fmt

function hasio(tks::Tokens)::Bool
    for tk in tks.tokens
        if isio(tk)
            return true
        end # if
    end # for
    false
end # hasio

function transpile(tks::Tokens, env::Dict, fname)
    txt = headers(tks)
    next!(tks)
    programm_name = next!(tks).text
    txt *= bloco2str!(tks, env, ["fimprog"], T)

    txt *= "\n}\n"
    write(fname, txt)
end # transpile

function bloco2str!(tokens::Tokens, env, expected_end, initial_char="")
    t = next!(tokens)
    text = ""
    if t.id==RESERVED_WORD && t.text=="declare"
        text = declare2str!(tokens, env, initial_char)

    elseif t.id==RESERVED_WORD && (t.text=="leia" || t.text=="escreva")
        text = cmd_io2str!(tokens, env, t.text, initial_char)

    elseif t.id==IDENTIFIER
        text = cmd_attr2atr!(tokens, env, initial_char)

    elseif t.id==CFLUX
        text = control_flux_parser2str!(tokens, env, initial_char)
    end

    if !any(x->x==t.text, expected_end)
        return text * bloco2str!(tokens, env, expected_end, initial_char)
    else
        return text
    end

end

function declare2str!(tks::Tokens, env, init_char)
    arr_ident = []
    type = ""
    txt = ""

    t = next!(tks)
    while !issemicolon(t)
        if isident(t)
            push!(arr_ident, t.text)
        end # if
        if istype(t)
            type = t.text
        end # if
        t = next!(tks)
    end # while

    txt *= init_char * type_p2c(type)*" "
    txt *= join(arr_ident, ", ") * ";\n"
    return txt
end

function headers(tks::Tokens)
    text = "#include <stdbool.h>\n"
    if hasio(tks)
        text *= "#include <stdio.h>\n\n"
    end # if
    text *= "int main(void) {\n"
    return text
end

function cmd_io2str!(tokens::Tokens, env, io, initial_char)
    text = ""
    next!(tokens) #(
    var = next!(tokens);
    if io == "leia"
        text *= initial_char*"scanf(\"$(type2fmt(type(env, var)))\", &$(var.text));\n"
    else # escreva
        if var.id==STRING
            text *= initial_char*"printf($(var.text));\n"
        else
            text *= initial_char*"printf(\"$(type2fmt(type(env, var)))\", $(var.text));\n"
        end
    end
    next!(tokens); next!(tokens); # );
    return text
end

function cmd_attr2atr!(tokens::Tokens, env, initial_char)
    var =  current(tokens);
    next!(tokens) #:=
    expr = expr2str!(tokens, env)

    text = initial_char*"$(var.text) = $expr;\n"
    return text
end

function expr2str!(tokens, env)
    expr = ""
    t = next!(tokens)

    if t.text==";"
        return expr
    elseif t.line!=previous(tokens).line
        roll_back(tokens)
        return expr
    end

    w = next(tokens).text==";" || t.line != next(tokens).line ? "" : " "

    text = t.text
    if t.id==BOOL
        text = text=="V" ? "true" : "false"
    end
    return expr * text * w * expr2str!(tokens, env)
end

function control_flux_parser2str!(tokens::Tokens, env, initial_char)
    text = ""
    t = current(tokens)
    if t.text == "se"
        text *= se2txt!(tokens, env, initial_char)
    elseif t.text == "enquanto"
        text *= enquanto2str!(tokens, env, initial_char)
    elseif t.text == "faca"
        text *= parse_faca!(tokens, env, initial_char)
    end
    return text
end

function se2txt!(tokens, env, initial_char)
    expr = expr2str!(tokens, env)

    text = initial_char*"if ($expr) {\n"

    text *= bloco2str!(tokens, env, ["fimse", "senao"], initial_char*T)

    if current(tokens).text == "senao"
        text *= initial_char*"} else {\n"
        text *= bloco2str!(tokens, env, ["fimse"], initial_char*T)
    end
    return text * initial_char*"}\n"
end

function enquanto2str!(tokens::Tokens, env, initial_char)
    expr = expr2str!(tokens, env)
    blk = bloco2str!(tokens, env, ["fimenq"], initial_char*T)
    text = initial_char*"while ($expr) {\n$blk"
    return text * initial_char*"}\n"
end

function parse_faca!(tokens, env, initial_char)
    blk = bloco2str!(tokens, env, ["durante"], initial_char*T)
    expr = expr2str!(tokens, env)
    return initial_char*"do {\n $blk$initial_char} while ($expr);\n"
end

max_stars_repo_name: GabrielTrettel/Portran

max_issues_repo_name: GabrielTrettel/Portran

max_forks_repo_name: GabrielTrettel/Portran


text:
"""
    Weibull(α,θ)

The *Weibull distribution* with shape `α` and scale `θ` has probability density function

```math
f(x; \\alpha, \\theta) = \\frac{\\alpha}{\\theta} \\left( \\frac{x}{\\theta} \\right)^{\\alpha-1} e^{-(x/\\theta)^\\alpha},
    \\quad x \\ge 0
```

```julia
Weibull()        # Weibull distribution with unit shape and unit scale, i.e. Weibull(1, 1)
Weibull(α)       # Weibull distribution with shape α and unit scale, i.e. Weibull(α, 1)
Weibull(α, θ)    # Weibull distribution with shape α and scale θ

params(d)        # Get the parameters, i.e. (α, θ)
shape(d)         # Get the shape parameter, i.e. α
scale(d)         # Get the scale parameter, i.e. θ
```

External links

* [Weibull distribution on Wikipedia](http://en.wikipedia.org/wiki/Weibull_distribution)

"""
struct Weibull{T<:Real} <: ContinuousUnivariateDistribution
    α::T   # shape
    θ::T   # scale

    function Weibull{T}(α::T, θ::T) where {T <: Real}
        new{T}(α, θ)
    end
end

function Weibull(α::T, θ::T; check_args::Bool=true) where {T <: Real}
    check_args && @check_args(Weibull, α > zero(α) && θ > zero(θ))
    return Weibull{T}(α, θ)
end

Weibull(α::Real, θ::Real; check_args::Bool=true) = Weibull(promote(α, θ)...; check_args=check_args)
Weibull(α::Integer, θ::Integer; check_args::Bool=true) = Weibull(float(α), float(θ); check_args=check_args)
Weibull(α::Real=1.0) = Weibull(α, one(α); check_args=false)

@distr_support Weibull 0.0 Inf

#### Conversions

convert(::Type{Weibull{T}}, α::Real, θ::Real) where {T<:Real} = Weibull(T(α), T(θ))
convert(::Type{Weibull{T}}, d::Weibull{S}) where {T <: Real, S <: Real} = Weibull(T(d.α), T(d.θ), check_args=false)

#### Parameters

shape(d::Weibull) = d.α
scale(d::Weibull) = d.θ

params(d::Weibull) = (d.α, d.θ)
partype(::Weibull{T}) where {T<:Real} = T

#### Statistics

mean(d::Weibull) = d.θ * gamma(1 + 1/d.α)
median(d::Weibull) = d.θ * logtwo ^ (1/d.α)
mode(d::Weibull{T}) where {T<:Real} = d.α > 1 ? (iα = 1 / d.α; d.θ * (1 - iα)^iα) : zero(T)

var(d::Weibull) = d.θ^2 * gamma(1 + 2/d.α) - mean(d)^2

function skewness(d::Weibull)
    μ = mean(d)
    σ2 = var(d)
    σ = sqrt(σ2)
    r = μ / σ
    gamma(1 + 3/d.α) * (d.θ/σ)^3 - 3r - r^3
end

function kurtosis(d::Weibull)
    α, θ = params(d)
    μ = mean(d)
    σ = std(d)
    γ = skewness(d)
    r = μ / σ
    r2 = r^2
    r4 = r2^2
    (θ/σ)^4 * gamma(1 + 4/α) - 4γ*r - 6r2 - r4 - 3
end

function entropy(d::Weibull)
    α, θ = params(d)
    0.5772156649015328606 * (1 - 1/α) + log(θ/α) + 1
end

#### Evaluation

function pdf(d::Weibull{T}, x::Real) where T<:Real
    if x >= 0
        α, θ = params(d)
        z = x / θ
        (α / θ) * z^(α - 1) * exp(-z^α)
    else
        zero(T)
    end
end

function logpdf(d::Weibull{T}, x::Real) where T<:Real
    if x >= 0
        α, θ = params(d)
        z = x / θ
        log(α / θ) + (α - 1) * log(z) - z^α
    else
        -T(Inf)
    end
end

zval(d::Weibull, x::Real) = (max(x, 0) / d.θ) ^ d.α
xval(d::Weibull, z::Real) = d.θ * z ^ (1 / d.α)

cdf(d::Weibull, x::Real) = -expm1(- zval(d, x))
ccdf(d::Weibull, x::Real) = exp(- zval(d, x))
logcdf(d::Weibull, x::Real) = log1mexp(- zval(d, x))
logccdf(d::Weibull, x::Real) = - zval(d, x)

quantile(d::Weibull, p::Real) = xval(d, -log1p(-p))
cquantile(d::Weibull, p::Real) = xval(d, -log(p))
invlogcdf(d::Weibull, lp::Real) = xval(d, -log1mexp(lp))
invlogccdf(d::Weibull, lp::Real) = xval(d, -lp)

function gradlogpdf(d::Weibull{T}, x::Real) where T<:Real
    if insupport(Weibull, x)
        α, θ = params(d)
        (α - 1) / x - α * x^(α - 1) / (θ^α)
    else
        zero(T)
    end
end

#### Sampling

rand(rng::AbstractRNG, d::Weibull) = xval(d, randexp(rng))

#### Fit model

"""
    fit_mle(::Type{<:Weibull}, x::AbstractArray{<:Real};
    alpha0::Real = 1, maxiter::Int = 1000, tol::Real = 1e-16)

Compute the maximum likelihood estimate of the [`Weibull`](@ref) distribution with Newton's method.
"""
function fit_mle(::Type{<:Weibull}, x::AbstractArray{<:Real};
    alpha0::Real = 1, maxiter::Int = 1000, tol::Real = 1e-16)

    N = 0

    lnx = map(log, x)
    lnxsq = lnx.^2
    mean_lnx = mean(lnx)

    # first iteration outside loop, prevents type instabililty in α, ϵ

    xpow0 = x.^alpha0
    sum_xpow0 = sum(xpow0)
    dot_xpowlnx0 = dot(xpow0, lnx)

    fx = dot_xpowlnx0 / sum_xpow0 - mean_lnx - 1 / alpha0
    ∂fx = (-dot_xpowlnx0^2 + sum_xpow0 * dot(lnxsq, xpow0)) / (sum_xpow0^2) + 1 / alpha0^2

    Δα = fx / ∂fx
    α = alpha0 - Δα

    ϵ = abs(Δα)
    N += 1

    while ϵ > tol && N < maxiter

        xpow = x.^α
        sum_xpow = sum(xpow)
        dot_xpowlnx = dot(xpow, lnx)

        fx = dot_xpowlnx / sum_xpow - mean_lnx - 1 / α
        ∂fx = (-dot_xpowlnx^2 + sum_xpow * dot(lnxsq, xpow)) / (sum_xpow^2) + 1 / α^2

        Δα = fx / ∂fx
        α -= Δα

        ϵ = abs(Δα)
        N += 1
    end

    θ = mean(x.^α)^(1 / α)
    return Weibull(α, θ)
end

ext: jl


text:
"""
    VarCoefDerivativeOperator

A dissipation operator on a nonperiodic finite difference grid.
"""
struct VarCoefDerivativeOperator{T,CoefficientCache,ExecutionMode,SourceOfCoefficients,Grid} <: AbstractVariableCoefficientNonperiodicDerivativeOperator{T}
    coefficients::VarCoefDerivativeCoefficients{T,CoefficientCache,ExecutionMode,SourceOfCoefficients}
    grid::Grid
    Δx::T
    factor::T
    b::Vector{T}

    function VarCoefDerivativeOperator(coefficients::VarCoefDerivativeCoefficients{T,CoefficientCache,ExecutionMode,SourceOfCoefficients},
                                       grid::Grid, b::Vector{T}) where {T,CoefficientCache,ExecutionMode,SourceOfCoefficients,Grid}
        @argcheck checkbounds(Bool, grid, coefficients.coefficient_cache) DimensionMismatch
        @argcheck length(grid) == length(b)

        Δx = step(grid)
        factor = inv(Δx^derivative_order(coefficients))
        new{T,CoefficientCache,ExecutionMode,SourceOfCoefficients,Grid}(
            coefficients, grid, Δx, factor, b)
    end
end

function Base.show(io::IO, D::VarCoefDerivativeOperator{T}) where {T}
    print(io, "SBP variable coefficient ")
    if  derivative_order(D) == 1
        print(io, "1st")
    elseif  derivative_order(D) == 2
        print(io, "2nd")
    elseif  derivative_order(D) == 3
        print(io, "3rd")
    else
        print(io, derivative_order(D), "th")
    end
    print(io, "derivative operator with order of accuracy ")
    print(io, accuracy_order(D), " {T=", T, ", ExecutionMode=", typeof(D.coefficients.mode), "} \n")
    print(io, "on a grid in [", first(grid(D)), ", ", last(grid(D)),
                "] using ", length(grid(D)), " nodes \n")
    print(io, "and coefficients given in \n")
    print(io, source_of_coefficients(D))
end

# Compute `α*D*u + β*dest` and store the result in `dest`.
Base.@propagate_inbounds function mul!(dest::AbstractVector, D::VarCoefDerivativeOperator,
                                        u::AbstractVector, α, β)
    @boundscheck begin
        @argcheck size(D, 2) == length(u) DimensionMismatch
        @argcheck size(D, 1) == length(dest) DimensionMismatch
    end
    @inbounds mul!(dest, D.coefficients, u, D.b, D.factor*α, β)
end

# Compute `α*D*u` and store the result in `dest`.
Base.@propagate_inbounds function mul!(dest::AbstractVector, D::VarCoefDerivativeOperator,
                                        u::AbstractVector, α)
    @boundscheck begin
        @argcheck size(D, 2) == length(u) DimensionMismatch
        @argcheck size(D, 1) == length(dest) DimensionMismatch
    end
    @inbounds mul!(dest, D.coefficients, u, D.b, D.factor*α)
end

"""
    var_coef_derivative_operator(source_of_coefficients, derivative_order, accuracy_order,
                                 xmin, xmax, N, left_weights, right_weights, bfunc,
                                 mode=FastMode())

Create a `VarCoefDerivativeOperator` approximating a `derivative_order`-th
derivative with variable coefficients `bfunc` on a grid between `xmin` and
`xmax` with `N` grid points up to order of accuracy `accuracy_order` with
coefficients given by `source_of_coefficients`.
The evaluation of the derivative can be parallized using threads by chosing
`mode=ThreadedMode()`.
"""
function var_coef_derivative_operator(source_of_coefficients, derivative_order, accuracy_order,
                                        xmin, xmax, N, bfunc, mode=FastMode())
    if mode === Val(:serial) || mode === Val(:threads)
        # TODO: deprecated in v0.5
        Base.depwarn("Providing the argument `parallel` is deprecated." *
                     "Use `mode` instead.", :var_coef_derivative_operator)
        mode = _parallel_to_mode(mode)
    end
    grid = construct_grid(source_of_coefficients, accuracy_order, xmin, xmax, N)
    coefficients = var_coef_derivative_coefficients(source_of_coefficients,
        derivative_order, accuracy_order, grid, mode)
    VarCoefDerivativeOperator(coefficients, grid, bfunc.(grid))
end

"""
    mass_matrix(D::Union{DerivativeOperator,VarCoefDerivativeOperator})

Create the diagonal mass matrix for the SBP derivative operator `D`.
"""
function mass_matrix(D::Union{DerivativeOperator,VarCoefDerivativeOperator})
    m = fill(one(eltype(D)), length(grid(D)))
    @unpack left_weights, right_weights = D.coefficients

    m[1:length(left_weights)] = left_weights
    m[end:-1:end-length(right_weights)+1] = right_weights
    Diagonal(D.Δx * m)
end

function scale_by_mass_matrix!(u::AbstractVector, D::Union{DerivativeOperator,VarCoefDerivativeOperator}, factor=true)
    @unpack Δx = D
    @unpack left_weights, right_weights = D.coefficients
    N, _ = size(D)
    @boundscheck begin
        @argcheck N == length(u)
    end

    @simd for i in eachindex(left_weights)
        @inbounds u[i] = factor * u[i] * (Δx * left_weights[i])
    end
    @simd for i in length(left_weights)+1:N-length(right_weights)
        @inbounds u[i] = factor * u[i] * Δx
    end
    @simd for i in eachindex(right_weights)
        @inbounds u[end-i+1] = factor * u[end-i+1] * (Δx * right_weights[i])
    end

    u
end

function scale_by_inverse_mass_matrix!(u::AbstractVector, D::Union{DerivativeOperator,VarCoefDerivativeOperator}, factor=true)
    @unpack Δx = D
    @unpack left_weights, right_weights = D.coefficients
    N, _ = size(D)
    @boundscheck begin
        @argcheck N == length(u)
    end

    @simd for i in eachindex(left_weights)
        @inbounds u[i] = factor * u[i] / (Δx * left_weights[i])
    end
    @simd for i in length(left_weights)+1:N-length(right_weights)
        @inbounds u[i] = factor * u[i] / Δx
    end
    @simd for i in eachindex(right_weights)
        @inbounds u[end-i+1] = factor * u[end-i+1] / (Δx * right_weights[i])
    end

    u
end

function get_weight(D::Union{DerivativeOperator,VarCoefDerivativeOperator}, i::Int)
    @unpack Δx = D
    @unpack left_weights, right_weights = D.coefficients
    N, _ = size(D)
    @boundscheck begin
        @argcheck 1 <= i <= N
    end
    @inbounds if i <= length(left_weights)
        ω = Δx * left_weights[i]
    elseif i > N - length(right_weights)
        ω = Δx * right_weights[N - i + 1]
    else
        ω = Δx
    end
    ω
end


text:
#ДАНО: На ограниченном внешней прямоугольной рамкой поле имеется ровно одна внутренняя перегородка в форме прямоугольника.
#Робот - в произвольной клетке поля между внешней и внутренней перегородками.
#РЕЗУЛЬТАТ: Робот - в исходном положении и по всему периметру внутренней перегородки поставлены маркеры.

function moves!(r,side) #двигает робота и возвращает количество шагов
    num = 0
    while isborder(r,side) == false
        move!(r,side)
        num+=1
    end
    return num
end

function reverse(side)
    for i=0:3
        if side == HorizonSide(i)
            return HorizonSide(mod(i+2, 4))
        end
    end
end

function next_side(side)
    for i=0:3
        if side == HorizonSide(i)
            return HorizonSide(mod(i+3,4))
        end
    end
end

function obvod(r)
    actions = []
    while ((isborder(r,Sud))&&(isborder(r,West))) == false
        push!(actions,moves!(r,West))
        push!(actions,moves!(r,Sud))
    end
    side = Nord
    while isborder(r,Ost) == false
        while isborder(r,side) == false
            move!(r,side)
            if isborder(r,Ost) == true
                break
            end
        end
        if isborder(r,Ost) == false
            move!(r,Ost)
        end
        side = reverse(side)
    end
    while isborder(r,Ost)==true
        move!(r,Sud)
    end
    side = Nord
    for i in 1:4
        putmarker!(r)
        move!(r,side)
        while isborder(r,next_side(side)) == true
            putmarker!(r)
            move!(r,side)
        end
        side = next_side(side)
    end
    moves!(r,Sud)
    moves!(r,West)
    for i in 1:actions[2]
            move!(r,Nord)
    end
    for i in 1:actions[1]
         move!(r,Ost)
    end
end

max_stars_repo_name: gardend/mirea-progs

max_issues_repo_name: gardend/mirea-progs

max_forks_repo_name: gardend/mirea-progs


text:
# run.jl
# Example script to run three-stage chemostat experiment
# July 2020, Nadanai Laohakunakorn (nadanai.laohakunakorn@ed.ac.uk)

using DelimitedFiles
using Plots
using DifferentialEquations
using ProgressBars
using Statistics
using PyCall

include("./models.jl");
include("./callbacks.jl");
include("./solve.jl");

# Global settings: paths and plot
Plots.pyplot()
PATH_OUT = "../output/"
FN="script_titration_plot.pdf" # Filename
fntsm = Plots.font("sans-serif", pointsize=round(14.0))
fntlg = Plots.font("sans-serif", pointsize=round(18.0))
default(titlefont=fntlg, guidefont=fntlg, tickfont=fntlg, legendfont=fntsm)

# Global simulation settings
TMAX = 30.0*60 # in minutes
INTERVAL_DIL = 15.0 # in minutes
DIL_FRAC = 0.2;
NSPECIES = 7
SWITCHTIMES = [4.0,16.0] # Time to swap between experimental stages

# 1. Define names for species indices
idx_R=1;
idx_dT=2;
idx_dG=3;
idx_mT=4;
idx_mG=5;
idx_pT=6;
idx_pG=7;
idx_TX = 8;
idx_TL = 9;

# 2. Set up simulation and plot
CONCS = [0.001,0.01,1]
LABELS = ["SR low", "SR medium", "SR high"]
COLOURS = ["#afb1b6","#aec7e8","#1f77b4"]
p1 = plot(grid=:false,legend=:false)#,legend=:outertopright)
vspan!([4,16],fill=:black,alpha=:0.1); vline!([4,16],color=:black,linestyle=:dot,linewidth=2);

# 3. Set initial conditions and parameters
R0=100.0;
dT0=0.0;
dG0=2.0;
mT0=0.0;
mG0=0.0;
pT0=1.0;
pG0=0.0;
alpha=0.7;
beta=0.07;
K=1.0;
u0 = [R0,dT0,dG0,mT0,mG0,pT0,pG0];
params = [alpha,beta,K];

# 4. Solve
#TSAVE = 0.0:5.0:TMAX # either array or range can be passed
TSAVE = collect(0:15:TMAX).+1

# Positive control
solU,solDU=solvemodel(grads,u0,params,TMAX,INTERVAL_DIL,TSAVE,DIL_FRAC,NSPECIES,SWITCHTIMES,"PC");
t = solU.t/60;
pGPC = [datum for subarr in solU.u for datum in subarr[idx_pG]];

# Negative control
solU,solDU=solvemodel(grads,u0,params,TMAX,INTERVAL_DIL,TSAVE,DIL_FRAC,NSPECIES,SWITCHTIMES,"NC");
pGNC = [datum for subarr in solU.u for datum in subarr[idx_pG]];

plot!(t,pGPC,label="PC",color="#2ca02c",xaxis="time (h)",yaxis="GFP",lw=4);
plot!(t,pGNC,label="NC",color="#ffbb78",lw=4)

# T7RNAP DNA titration
for j in (1:size(CONCS)[1])
    dT0=CONCS[j]
    u0 = [R0,dT0,dG0,mT0,mG0,pT0,pG0];
    params = [alpha,beta,K];
    solU,solDU=solvemodel(grads,u0,params,TMAX,INTERVAL_DIL,TSAVE,DIL_FRAC,NSPECIES,SWITCHTIMES,"SR");
    pG = [datum for subarr in solU.u for datum in subarr[idx_pG]];
    plot!(t,pG,label=LABELS[j],color=COLOURS[j],lw=4)
end

p1 # Show plot
savefig(PATH_OUT*FN) # Save plot


text:
export Geometry, ridge_wg, ridge_wg_partial_etch, circ_wg, demo_shapes, εs, fεs, fεs!, fnn̂gs, nn̂gs, fnĝvds, nĝvds, matinds
export εₘₐₓ, nₘₐₓ, materials, plot_shapes, k_guess, ridge_wg_partial_etch3D #TODO: generalize these methods for materials and ε data

# Geometry(s::Vector{S}) where S<:Shape{N} where N = Geometry{N}(s)
# materials(geom::Geometry) = materials(geom.shapes)#geom.materials
# εs(geom::Geometry) = getfield.(materials(geom),:ε)
# fεs(geom::Geometry) = getfield.(materials(geom),:fε)
# εs(geom::Geometry,lm::Real) = map(f->f(lm),fεs(geom))
# fεs(geom::Geometry) = build_function(εs(geom),λ;expression=Val{false})[1]
# fεs!(geom::Geometry) = build_function(εs(geom),λ;expression=Val{false})[2]

# matinds(geom::Vector{<:Shape}) = vcat((matinds0 = map(s->findfirst(m->isequal(ε(Material(s.data)),ε(m)), materials(geom)),geom); matinds0),maximum(matinds0)+1)
matinds(geom::Vector{<:Shape}) = vcat((matinds0 = map(s->findfirst(m->isequal(get_model(Material(s.data),:ε,:λ),get_model(m,:ε,:λ)), materials(geom)),geom); matinds0),maximum(matinds0)+1)
matinds(shapes,mats) = vcat(map(s->findfirst(m->isequal(get_model(Material(s.data),:ε,:λ),get_model(m,:ε,:λ)),mats),shapes),length(mats)+1)

materials(shapes::AbstractVector{<:GeometryPrimitives.Shape}) = Zygote.@ignore(unique(Material.(getfield.(shapes,:data)))) # # unique!(getfield.(shapes,:data))
# εs(shapes::AbstractVector{<:GeometryPrimitives.Shape}) = getfield.(materials(shapes),:ε)
# fεs(shapes::AbstractVector{<:GeometryPrimitives.Shape}) = Zygote.@ignore(ε_fn.(materials(shapes)) )
# fεs(mats::AbstractVector{<:AbstractMaterial}) = [(ff=(ε_fn(mat)); lm->ff(lm)) for mat in mats]
# εs(shapes::AbstractVector{<:GeometryPrimitives.Shape},lm::Real) = map(f->SMatrix{3,3}(f(lm)),fεs(shapes))
#
# fnn̂gs(shapes::AbstractVector{<:GeometryPrimitives.Shape}) =  Zygote.@ignore( nn̂g_fn.(materials(shapes)) )
# fnn̂gs(mats::AbstractVector{<:AbstractMaterial}) =   [(ff=(nn̂g_fn(mat)); lm->ff(lm)) for mat in mats]
# nn̂gs(shapes::AbstractVector{<:GeometryPrimitives.Shape},lm::Real) = [SMatrix{3,3}(f(lm)) for f in nn̂g_fn.(materials(shapes))  ] #map(f->SMatrix{3,3}(f(lm)),fnn̂gs(shapes))
#
# fnĝvds(shapes::AbstractVector{<:GeometryPrimitives.Shape}) = Zygote.@ignore( nĝvd_fn.(materials(shapes)) )
# fnĝvds(mats::AbstractVector{<:AbstractMaterial}) =  [(ff=(nĝvd_fn(mat)); lm->ff(lm)) for mat in mats]
# nĝvds(shapes::AbstractVector{<:GeometryPrimitives.Shape},lm::Real) = map(f->SMatrix{3,3}(f(lm)),fnĝvds(shapes))
#
# fχ⁽²⁾s(shapes::AbstractVector{<:GeometryPrimitives.Shape}) = Zygote.@ignore( χ⁽²⁾_fn.(materials(shapes)) )
# fχ⁽²⁾s(mats::AbstractVector{<:AbstractMaterial}) =  [(ff=(χ⁽²⁾_fn(mat)); lm->ff(lm)) for mat in mats]

# function f_χ⁽²⁾_vac = SArray{Tuple{3,3,3}}(zeros(Float64,(3,3,3)))
fεs(mats::AbstractVector{<:NumMat})	   =  vcat( getproperty.(mats,(:fε,)) 	 , x->εᵥ	   )
fnn̂gs(mats::AbstractVector{<:NumMat})	=  vcat( getproperty.(mats,(:fnng,))  , x->εᵥ	 	)
fnĝvds(mats::AbstractVector{<:NumMat}) =  vcat( getproperty.(mats,(:fngvd,)) , x->zero(εᵥ) )
fχ⁽²⁾s(mats::AbstractVector{<:NumMat}) =  vcat( getproperty.(mats,(:fχ⁽²⁾,)) , (x1,x2,x3)->zeros(eltype(εᵥ),3,3,3) )#χ⁽²⁾_vac )

# fεs(mats)	   =  ( getproperty.(mats,(:fε,))... 	 , x->εᵥ	   )
# fnn̂gs(mats)	=  ( getproperty.(mats,(:fnng,))...  , x->εᵥ	 	)
# fnĝvds(mats)   =  ( getproperty.(mats,(:fngvd,))... , x->zero(εᵥ) )
# fχ⁽²⁾s(mats)   =  ( getproperty.(mats,(:fχ⁽²⁾,))... , x->χ⁽²⁾_vac )

struct Geometry
	shapes::Vector #{<:Shape{N}}
	materials::Vector #{AbstractMaterial}
	material_inds::Vector #{Int}
	fεs #{Function}
	fnn̂gs #{Function}
	fnĝvds #{Function}
	fχ⁽²⁾s #{Function}
	# material_props::Vector{Symbol}
	# material_fns::Vector{Function}
end

# function Geometry(shapes)  #where S<:Shape{N} where N
# 	mats =  materials(shapes)
# 	fes = fεs(mats)
# 	fnngs = fnn̂gs(mats)
# 	fngvds = fnĝvds(mats)
# 	fchi2s = fχ⁽²⁾s(mats)
# 	return Geometry(
# 		shapes,
# 		mats,
# 		matinds(shapes,mats),
# 		fes,
# 		fnngs,
# 		fngvds,
# 		fchi2s,
# 	)
# end

function Geometry(shapes)  #where S<:Shape{N} where N
	mats =  materials(shapes)
	fes = fεs(mats)
	fnngs = fnn̂gs(mats)
	fngvds = fnĝvds(mats)
	fchi2s = fχ⁽²⁾s(mats)
	return Geometry(
		shapes,
		mats,
		matinds(shapes),
		fes,
		fnngs,
		fngvds,
		fchi2s,
	)
end

# matinds(geom::Geometry) = vcat((matinds0 = map(s->findfirst(m->isequal(get_model(Material(s.data),:ε,:λ),get_model(m,:ε,:λ)), materials(geom)),geom.shapes); matinds0),maximum(matinds0)+1)
# matinds(geom::Geometry) = vcat(map(s->findfirst(m->isequal(s.data,m), materials(geom.shapes)),geom.shapes),length(geom.shapes)+1)

# fngs(shapes::AbstractVector{<:GeometryPrimitives.Shape}) = getfield.(materials(shapes),:fng)
# ngs(shapes::AbstractVector{<:GeometryPrimitives.Shape},lm::Real) = map(f->f(lm),fngs(shapes))

# εs(shapes::AbstractVector{<:GeometryPrimitives.Shape},lm::Real) = map(fεs(shapes)) do f
# 		ee = f(lm)
# 		eeH = ( ee + ee' ) / 2
# 	end

"""
################################################################################
#																			   #
#							    Utility methods					   			   #
#																			   #
################################################################################
"""

function εₘₐₓ(ω::T,shapes::AbstractVector{<:GeometryPrimitives.Shape}) where T<:Real
    maximum(vcat(diag.(εs(shapes,inv(ω)))...))
end
function εₘₐₓ(ω::T,geom::Geometry) where T<:Real
    maximum(vcat(diag.(εs(geom.shapes,inv(ω)))...))
end

function nₘₐₓ(ω::T,shapes::AbstractVector{<:GeometryPrimitives.Shape}) where T<:Real
    sqrt( εₘₐₓ(ω,shapes) )
end
function nₘₐₓ(ω::T,geom::Geometry) where T<:Real
    sqrt( εₘₐₓ(ω,geom.shapes) )
end

k_guess(ω,geom) = nₘₐₓ(ω,geom) * ω

k_guess(ω,ε⁻¹::AbstractArray{<:Real,4}) = ( kg = Zygote.@ignore ( first(ω) * sqrt(1/minimum([minimum(ε⁻¹[a,a,:,:]) for a=1:3])) ); kg  )
k_guess(ω,ε⁻¹::AbstractArray{<:Real,5}) = ( kg = Zygote.@ignore ( first(ω) * sqrt(1/minimum([minimum(ε⁻¹[a,a,:,:,:]) for a=1:3])) ); kg  )
k_guess(ω,shapes::Vector{<:Shape}) = ( kg = Zygote.@ignore ( first(ω) * √εₘₐₓ(shapes) ); kg  )
k_guess(ω,geom::Geometry) = ( kg = Zygote.@ignore ( first(ω) * √εₘₐₓ(geom.shapes) ); kg  )

# fεs(shapes::AbstractVector{<:GeometryPrimitives.Shape}) = build_function(εs(shapes),λ;expression=Val{false})[1]
# fεs!(shapes::AbstractVector{<:GeometryPrimitives.Shape}) = build_function(εs(shapes),λ;expression=Val{false})[2]

# fes = map(fε,mats)
# feis = map(fε⁻¹,mats)
# εs = [fe(lm) for fe in fes]
# ε⁻¹s = [fei(lm) for fei in feis]

#
"""
################################################################################
#																			   #
#					      Parametric Geometry Methods					  	   #
#																			   #
################################################################################
"""

function ridge_wg(wₜₒₚ::Real,t_core::Real,θ::Real,edge_gap::Real,mat_core,mat_subs,Δx::Real,Δy::Real) #::Geometry{2}
    t_subs = (Δy -t_core - edge_gap )/2.
    c_subs_y = -Δy/2. + edge_gap/2. + t_subs/2.
    # ε_core = ε_tensor(n_core)
    # ε_subs = ε_tensor(n_subs)
    wt_half = wₜₒₚ / 2
    wb_half = wt_half + ( t_core * tan(θ) )
    tc_half = t_core / 2
    # verts =     [   wt_half     -wt_half     -wb_half    wb_half
    #                 tc_half     tc_half    -tc_half      -tc_half    ]'
	# verts = [   wt_half     tc_half
	# 			-wt_half    tc_half
	# 			-wb_half    -tc_half
	# 			wb_half     -tc_half    ]
	verts = SMatrix{4,2}(   wt_half,     -wt_half,     -wb_half,    wb_half, tc_half,     tc_half,    -tc_half,      -tc_half )
    core = GeometryPrimitives.Polygon(					                        # Instantiate 2D polygon, here a trapazoid
                    # SMatrix{4,2}(verts),			                            # v: polygon vertices in counter-clockwise order
					verts,
					mat_core,					                                    # data: any type, data associated with box shape
                )
    ax = [      1.     0.
                0.     1.      ]
    b_subs = GeometryPrimitives.Box(			# Instantiate N-D box, here N=2 (rectangle)
                    [0. , c_subs_y],           	# c: center
                    [Δx - edge_gap, t_subs ],	# r: "radii" (half span of each axis)
                    ax,	    		        	# axes: box axes
                    mat_subs,					 # data: any type, data associated with box shape
                )
    # return Geometry{2}([core,b_subs])
	return Geometry([core,b_subs])
end

function ridge_wg_partial_etch(wₜₒₚ::Real,t_core::Real,etch_frac::Real,θ::Real,edge_gap::Real,mat_core,mat_subs,Δx::Real,Δy::Real) #::Geometry{2}
    t_subs = (Δy -t_core - edge_gap )/2.
    c_subs_y = -Δy/2. + edge_gap/2. + t_subs/2.
    # ε_core = ε_tensor(n_core)
    # ε_subs = ε_tensor(n_subs)
    wt_half = wₜₒₚ / 2
    wb_half = wt_half + ( t_core * tan(θ) )
    tc_half = t_core / 2

	t_unetch = t_core * ( 1. - etch_frac	)	# unetched thickness remaining of top layer
	c_unetch_y = -Δy/2. + edge_gap/2. + t_subs + t_unetch/2.
    # verts =     [   wt_half     -wt_half     -wb_half    wb_half
    #                 tc_half     tc_half    -tc_half      -tc_half    ]'
	# verts = [   wt_half     tc_half
	# 			-wt_half    tc_half
	# 			-wb_half    -tc_half
	# 			wb_half     -tc_half    ]
	verts = SMatrix{4,2}(   wt_half,     -wt_half,     -wb_half,    wb_half, tc_half,     tc_half,    -tc_half,      -tc_half )
    core = GeometryPrimitives.Polygon(					                        # Instantiate 2D polygon, here a trapazoid
                    # SMatrix{4,2}(verts),			                            # v: polygon vertices in counter-clockwise order
					verts,
					mat_core,					                                    # data: any type, data associated with box shape
                )
    ax = [      1.     0.
                0.     1.      ]

	b_unetch = GeometryPrimitives.Box(			# Instantiate N-D box, here N=2 (rectangle)
                    [0. , c_unetch_y],           	# c: center
                    [Δx - edge_gap, t_unetch ],	# r: "radii" (half span of each axis)
                    ax,	    		        	# axes: box axes
                    mat_core,					 # data: any type, data associated with box shape
                )

	b_subs = GeometryPrimitives.Box(			# Instantiate N-D box, here N=2 (rectangle)
                    [0. , c_subs_y],           	# c: center
                    [Δx - edge_gap, t_subs ],	# r: "radii" (half span of each axis)
                    ax,	    		        	# axes: box axes
                    mat_subs,					 # data: any type, data associated with box shape
                )
	# # return [core,b_unetch,b_subs]
	# return Geometry([core,b_unetch,b_subs])
	## add horizontal isosceles trianges of vacuum on top of slab and substrate dielectrics
	## near edges of the simulated region. These act as notches to prevent FP modes in the
	## slab and substrate. Kind of hacky.
	# vacuum = NumMat(1.0)
	# t_unetch_r = GeometryPrimitives.isosceles(
	# 				( 	SVector((Δx-edge_gap)/2.,c_unetch_y-t_unetch/2.),	# notch triangle base
	# 					SVector((Δx-edge_gap)/2.,c_unetch_y+t_unetch/2.),
	# 						),
	# 				edge_gap/4.,				# sideways isoceles triangle "height"
	# 				vacuum,  # vacuum permitivity
	# 			)
	# t_unetch_l = GeometryPrimitives.isosceles(
	# 				( 	SVector(-(Δx-edge_gap)/2.,c_unetch_y+t_unetch/2.),	# notch triangle base
	# 					SVector(-(Δx-edge_gap)/2.,c_unetch_y-t_unetch/2.),
	# 						),
	# 				edge_gap/4.,				# sideways isosceles triangle "height"
	# 				vacuum,  # vacuum permitivity
	# 			)
	# t_subs_r = GeometryPrimitives.isosceles(
	# 				( 	SVector((Δx-edge_gap)/2.,c_subs_y-t_subs/2.),	# notch triangle base
	# 					SVector((Δx-edge_gap)/2.,c_subs_y+t_subs/2.),
	# 						),
	# 				edge_gap/4.,				# sideways isosceles triangle "height"
	# 				vacuum,  # vacuum permitivity
	# 			)
	# t_subs_l = GeometryPrimitives.isosceles(
	# 				( 	SVector(-(Δx-edge_gap)/2.,c_subs_y+t_subs/2.),	# notch triangle base
	# 					SVector(-(Δx-edge_gap)/2.,c_subs_y-t_subs/2.),
	# 						),
	# 				edge_gap/4.,				# sideways isosceles triangle "height"
	# 				vacuum,  # vacuum permitivity
	# 			)
	# return Geometry([t_unetch_r,t_unetch_l,t_subs_r,t_subs_l,core,b_unetch,b_subs])
	return Geometry([core,b_unetch,b_subs])

end

function ridge_wg_partial_etch3D(wₜₒₚ::Real,t_core::Real,etch_frac::Real,θ::Real,edge_gap::Real,mat_core,mat_subs,Δx::Real,Δy::Real,Δz::Real) #::Geometry{2}

	t_subs = (Δy -t_core - edge_gap )/2.
    c_subs_y = -Δy/2. + edge_gap/2. + t_subs/2.
    # ε_core = ε_tensor(n_core)
    # ε_subs = ε_tensor(n_subs)
    wt_half = wₜₒₚ / 2
    wb_half = wt_half + ( t_core * tan(θ) )
    tc_half = t_core / 2

	t_unetch = t_core * ( 1. - etch_frac	)	# unetched thickness remaining of top layer
	c_unetch_y = -Δy/2. + edge_gap/2. + t_subs + t_unetch/2.
    # verts =     [   wt_half     -wt_half     -wb_half    wb_half
    #                 tc_half     tc_half    -tc_half      -tc_half    ]'
	# verts = [   wt_half     tc_half
	# 			-wt_half    tc_half
	# 			-wb_half    -tc_half
	# 			wb_half     -tc_half    ]
	verts = SMatrix{4,2}(   wt_half,     -wt_half,     -wb_half,    wb_half, tc_half,     tc_half,    -tc_half,      -tc_half )
    core = GeometryPrimitives.PolygonalPrism(					                        # Instantiate 2D polygon, here a trapazoid
					SVector(0.,0.,0.),
					verts,			                            # v: polygon vertices in counter-clockwise order
					Δz,
					[0.,0.,1.],
					mat_core,					                                    # data: any type, data associated with box shape
                )
    ax = [      1.     0.		0.
                0.     1.      	0.
				0.		0.		1.		]

	b_unetch = GeometryPrimitives.Box(			# Instantiate N-D box, here N=2 (rectangle)
                    [0. , c_unetch_y, 0.],           	# c: center
                    [Δx - edge_gap, t_unetch, Δz ],	# r: "radii" (half span of each axis)
                    ax,	    		        	# axes: box axes
                    mat_core,					 # data: any type, data associated with box shape
                )

	b_subs = GeometryPrimitives.Box(			# Instantiate N-D box, here N=2 (rectangle)
                    [0. , c_subs_y, 0.],           	# c: center
                    [Δx - edge_gap, t_subs, Δz ],	# r: "radii" (half span of each axis)
                    ax,	    		        	# axes: box axes
                    mat_subs,					 # data: any type, data associated with box shape
                )

	# etched pattern in slab cladding
	# vacuum = NumMat(1.0)
	# ax_cyl = SVector(0.,1.,0.)
	# dx_sw_cyl = 0.5	# distance of etched cylinder centers from sidewalls
	# r_cyl = 0.1
	# z_cyl = 0.0
	# c_cyl1 = SVector(wb_half+dx_sw_cyl, c_unetch_y, z_cyl)
	# c_cyl2 = SVector(-wb_half-dx_sw_cyl, c_unetch_y, z_cyl)
	# cyl1 = GeometryPrimitives.Cylinder(c_cyl1,r_cyl,t_unetch,SVector(0.,1.,0.),vacuum)
	# cyl2 = GeometryPrimitives.Cylinder(c_cyl2,r_cyl,t_unetch,SVector(0.,1.,0.),vacuum)

	return Geometry([core,b_unetch,b_subs])
	# return Geometry([cyl1,cyl2,core,b_unetch,b_subs])
end

function demo_shapes(p::T) where T<:Real
    ε₁, ε₂, ε₃ = test_εs(1.42,2.2,3.5)
    ax1b,ax2b = GeometryPrimitives.normalize.(([1.,0.2], [0.,1.]))
    b = Box(					# Instantiate N-D box, here N=2 (rectangle)
        [0,0],					# c: center
        [3.0, 3.0],				# r: "radii" (half span of each axis)
        [ax1b ax2b],			# axes: box axes
        ε₁,						# data: any type, data associated with box shape
        )

    s = Sphere(					# Instantiate N-D sphere, here N=2 (circle)
        [0,0],					# c: center
        p,						# r: "radii" (half span of each axis)
        ε₂,						# data: any type, data associated with circle shape
        )

    t = regpoly(				# triangle::Polygon using regpoly factory method
        3,						# k: number of vertices
        0.8,					# r: distance from center to vertices
        π/2,					# θ: angle of first vertex
        [0,0],					# c: center
        ε₃,						# data: any type, data associated with triangle
        )

    # return Geometry([ t, s, b ])
	return Geometry([ t, s, b ])
end

function circ_wg(w::T,t_core::T,edge_gap::T,n_core::T,n_subs::T,Δx::T,Δy::T)::Vector{<:GeometryPrimitives.Shape} where T<:Real
    t_subs = (Δy -t_core - edge_gap )/2.
    c_subs_y = -Δy/2. + edge_gap/2. + t_subs/2.
    ε_core = ε_tensor(n_core)
    ε_subs = ε_tensor(n_subs)
    ax = [      1.     0.
                0.     1.      ]
    b_core = GeometryPrimitives.Sphere(					# Instantiate N-D sphere, here N=2 (circle)
                    SVector(0.,t_core),			# c: center
                    w,						# r: "radii" (half span of each axis)
                    ε_core,					        # data: any type, data associated with box shape
                )
    b_subs = GeometryPrimitives.Box(					                # Instantiate N-D box, here N=2 (rectangle)
                    [0. , c_subs_y],            # c: center
                    [Δx - edge_gap, t_subs ],	# r: "radii" (half span of each axis)
                    ax,	    		        	# axes: box axes
                    ε_subs,					        # data: any type, data associated with box shape
                )
    # return Geometry([b_core,b_subs])
	return Geometry([b_core,b_subs])
end

"""
################################################################################
#																			   #
#							   Plotting methods					   			   #
#																			   #
################################################################################
"""

################################################################################
#                Plotting conversions for geometry components                  #
################################################################################
import Base: convert
using Makie: lines, lines!, scatterlines, scatterlines!, GeometryBasics, Point, PointBased
import Makie: convert_arguments
# polygon
convert(::Type{GeometryBasics.Polygon},x::GeometryPrimitives.Polygon) = GeometryBasics.Polygon(vcat([Point2f0(x.v[i,:]) for i=1:size(x.v)[1]], [Point2f0(x.v[1,:]),]))
Makie.convert_arguments(P::Type{<:Poly}, x::GeometryPrimitives.Polygon) = (convert(GeometryBasics.Polygon,x),)
Makie.convert_arguments(P::PointBased, x::GeometryPrimitives.Polygon) = (decompose(Point, convert(GeometryBasics.Polygon,x)),)
# box
convert(::Type{GeometryBasics.Rect2D},x::GeometryPrimitives.Box) = GeometryBasics.Rect((x.c-x.r)..., 2*x.r...)
convert(::Type{<:GeometryBasics.HyperRectangle},x::GeometryPrimitives.Box) = GeometryBasics.Rect((x.c-x.r)..., 2*x.r...)
convert(::Type{<:GeometryBasics.Polygon},x::GeometryPrimitives.Box) = (pts=decompose(Point,convert(GeometryBasics.Rect2D,x));GeometryBasics.Polygon(vcat(pts,[pts[1],])))
Makie.convert_arguments(P::Type{<:Poly}, x::GeometryPrimitives.Box) = (convert(GeometryBasics.Rect2D,x),) #(GeometryBasics.Polygon(Point2f0.(coordinates(GeometryBasics.Rect2D((x.c-x.r)..., 2*x.r...)))),)
Makie.convert_arguments(P::PointBased, x::GeometryPrimitives.Box) = (decompose(Point,convert(GeometryBasics.Rect2D,x)),)

# function plot_data(geom::Geometry)
# 	n_shapes 	= 	size(geom.shapes,1)
# 	n_mats		=	size(geom.materials,1)
# 	mat_colors 	=	getfield.(geom.materials,(:color,))
# 	shape_colors 	= [mat_colors[geom.material_inds[i]] for i=1:n_shapes]
# 	return Dict()
# end

function plot_shapes(geom::Geometry,ax;bg_color=:black,strokecolor=:white, strokewidth=2,mat_legend=true)
    ax.backgroundcolor=bg_color
	n_shapes 	= 	size(geom.shapes,1)
	n_mats		=	size(geom.materials,1)
	mat_colors 	=	getfield.(geom.materials,(:color,))
	shape_colors = [mat_colors[geom.material_inds[i]] for i=1:n_shapes]
	plys = [ poly!(
				geom.shapes[i],
				color=shape_colors[i],
				axis=ax;
				strokecolor,
				strokewidth,
			) for i=1:n_shapes ]
	if mat_legend
		mat_leg = axislegend(
			ax,
			[PolyElement(color = c, strokecolor = :black) for c in mat_colors],
			String.(nameof.(geom.materials)),
			valign=:top,
			halign=:right,
		)
	end
end

# function plot_model(geom::Geometry)
# 	[lines!(ax_disp[1], 1.2..1.7, fn; label=lbl) for (fn,lbl) in zip(plot_data(geom.materials)...)]
# end

# Makie.convert_arguments(x::Polygon) = (GeometryBasics.Polygon([Point2f0(x.v[i,:]) for i=1:size(x.v)[1]]),) #(GeometryBasics.Polygon([Point2f0(x.v[i,:]) for i=1:size(x.v)[1]]),)
# plottype(::Polygon) = Poly
# Makie.convert_arguments(x::Box) = (GeometryBasics.Rect2D((x.c-x.r)..., 2*x.r...),) #(GeometryBasics.Polygon(Point2f0.(coordinates(GeometryBasics.Rect2D((x.c-x.r)..., 2*x.r...)))),)
# plottype(::Box) = Poly

# function shape(b::Box)
#     xc,yc = b.c
#     r1,r2 = b.r
#     A = inv(b.p) .* b.r'
#     e1 = A[:,1] / √sum([a^2 for a in A[:,1]])
#     e2 = A[:,2] / √sum([a^2 for a in A[:,2]])
#     pts = [  r1*e1 + r2*e2,
#              r1*e1 - r2*e2,
#             -r1*e1 - r2*e2,
#             -r1*e1 + r2*e2,
#         ]
#     b_shape = Plots.Shape([Tuple(pt) for pt in pts])
# end
# shape(p::GeometryPrimitives.Polygon) = Plots.Shape([Tuple(p.v[i,:]) for i in range(1,length(p.v[:,1]),step=1)])
# shape(s::GeometryPrimitives.Sphere) = Plots.partialcircle(0, 2π, 100, s.r)


text:
using FactCheck
FactCheck.setstyle(:compact)
FactCheck.onlystats(true)

println("")

facts("macro calls to base methods work") do

    src = Pkg.dir("Tuxedo/src/src.jl")

    context("Julia version is a minimum of 0.4") do
        @fact match(r"[0-9]", string(VERSION), 2).match >= "4" --> true
    end

    context("pipeline works") do
        @fact typeof(run(pipeline(`cat $src`, pipeline(`tail -0`)))) --> Void
    end
end

println("")

max_stars_repo_name: milktrader/Tuxedo

max_issues_repo_name: milktrader/Tuxedo

max_forks_repo_name: milktrader/Tuxedo


text:
using Dates, Gadfly

set_default_plot_size(25cm, 35cm)

# simple Integrate and Fire Synapse Mode
type Synapse
    τ::Real     # membrane time constant [ms]
    dt::DateTime # time stamp of last update
    v::Real # tracks current voltage
    function Synapse(v::Real;τ::Real=10., dt::DateTime=now())
        new(τ, dt, v)
    end
end

nextDt(dt::DateTime, addMs::Int64) = dt + Millisecond(addMs)

function update!(s::Synapse, iV::Real, dt::DateTime)
    Δdt = int(dt - s.dt)
    s.v += Δdt*(1.0/s.τ)*(-s.v + iV)
    return s.v
end

function getResponse(V::Vector{Float64}, Δτ::Vector{Int64})
    n = length(V)
    data = zeros(n)
    tm = zeros(Int64,n)
    s = Synapse(0,τ=10)
#     tm = ones(n)
    for i = 1:n
        v = update!(s, V[i], nextDt(s.dt, Δτ[i]))
        data[i] = v
        tm[i] = i == 1? 0 : tm[i-1] + Δτ[i]
    end
    return data,tm
end

n = 20
Δτ = rand(1:1,n)
# V = ones(n) - .0
# V = max(randn(n) * 2 .+ 0.,0)
V = randn(n) * 2
response, tm = getResponse(V, Δτ)
vstack(plot(x = tm, y=V, Geom.line), plot(x=tm, y=response, Geom.point))

response[1]
tm[1]


text:
using MixedModels, Test

@testset "linear" begin
    m1 = fit(MixedModel, @formula(yield ~ 1 + (1|batch)), MixedModels.dataset(:dyestuff); progress=false)
    @test first(m1.θ) ≈ 0.7525806757718846 rtol=1.0e-5
end

@testset "generalized" begin
    gm1 = fit(MixedModel, @formula(use ~ 1 + urban + livch + age + abs2(age) + (1|dist)),
              MixedModels.dataset(:contra), Bernoulli(); progress=false)
    @test deviance(gm1) ≈ 2372.7286 atol=1.0e-3
end

@testset "Normal-IdentityLink" begin
    @test isa(fit(MixedModel, @formula(yield ~ 1 + (1|batch)), MixedModels.dataset(:dyestuff), Normal(); progress=false),
              LinearMixedModel)
    @test_throws(ArgumentError("use LinearMixedModel for Normal distribution with IdentityLink"),
                 fit(GeneralizedLinearMixedModel,
                     @formula(yield ~ 1 + (1|batch)),
                     MixedModels.dataset(:dyestuff); progress=false))
end

@testset "Normal Distribution GLMM" begin
    @test isa(fit(MixedModel, @formula(yield ~ 1 + (1|batch)), MixedModels.dataset(:dyestuff),
                         Normal(), SqrtLink(); progress=false),
                     GeneralizedLinearMixedModel)
end


text:
# This file is auto-generated by AWSMetadata.jl
using AWS
using AWS.AWSServices: amplify
using AWS.Compat
using AWS.UUIDs
"""
    CreateApp()

 Creates a new Amplify app.

# Required Parameters
- `name`:  The name for the Amplify app.

# Optional Parameters
- `accessToken`:  The personal access token for a third-party source control system for an Amplify app. The personal access token is used to create a webhook and a read-only deploy key. The token is not stored.
- `autoBranchCreationConfig`:  The automated branch creation configuration for the Amplify app.
- `autoBranchCreationPatterns`:  The automated branch creation glob patterns for the Amplify app.
- `basicAuthCredentials`:  The credentials for basic authorization for an Amplify app.
- `buildSpec`:  The build specification (build spec) for an Amplify app.
- `customRules`:  The custom rewrite and redirect rules for an Amplify app.
- `description`:  The description for an Amplify app.
- `enableAutoBranchCreation`:  Enables automated branch creation for the Amplify app.
- `enableBasicAuth`:  Enables basic authorization for an Amplify app. This will apply to all branches that are part of this app.
- `enableBranchAutoBuild`:  Enables the auto building of branches for an Amplify app.
- `enableBranchAutoDeletion`:  Automatically disconnects a branch in the Amplify Console when you delete a branch from your Git repository.
- `environmentVariables`:  The environment variables map for an Amplify app.
- `iamServiceRoleArn`:  The AWS Identity and Access Management (IAM) service role for an Amplify app.
- `oauthToken`:  The OAuth token for a third-party source control system for an Amplify app. The OAuth token is used to create a webhook and a read-only deploy key. The OAuth token is not stored.
- `platform`:  The platform or framework for an Amplify app.
- `repository`:  The repository for an Amplify app.
- `tags`:  The tag for an Amplify app.
"""

create_app(name; aws_config::AWSConfig=global_aws_config()) = amplify("POST", "/apps", Dict{String, Any}("name"=>name); aws_config=aws_config)
create_app(name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("POST", "/apps", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("name"=>name), args)); aws_config=aws_config)

"""
    CreateBackendEnvironment()

 Creates a new backend environment for an Amplify app.

# Required Parameters
- `appId`:  The unique ID for an Amplify app.
- `environmentName`:  The name for the backend environment.

# Optional Parameters
- `deploymentArtifacts`:  The name of deployment artifacts.
- `stackName`:  The AWS CloudFormation stack name of a backend environment.
"""

create_backend_environment(appId, environmentName; aws_config::AWSConfig=global_aws_config()) = amplify("POST", "/apps/$(appId)/backendenvironments", Dict{String, Any}("environmentName"=>environmentName); aws_config=aws_config)
create_backend_environment(appId, environmentName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("POST", "/apps/$(appId)/backendenvironments", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("environmentName"=>environmentName), args)); aws_config=aws_config)

"""
    CreateBranch()

 Creates a new branch for an Amplify app.

# Required Parameters
- `appId`:  The unique ID for an Amplify app.
- `branchName`:  The name for the branch.

# Optional Parameters
- `backendEnvironmentArn`:  The Amazon Resource Name (ARN) for a backend environment that is part of an Amplify app.
- `basicAuthCredentials`:  The basic authorization credentials for the branch.
- `buildSpec`:  The build specification (build spec) for the branch.
- `description`:  The description for the branch.
- `displayName`:  The display name for a branch. This is used as the default domain prefix.
- `enableAutoBuild`:  Enables auto building for the branch.
- `enableBasicAuth`:  Enables basic authorization for the branch.
- `enableNotification`:  Enables notifications for the branch.
- `enablePerformanceMode`:  Performance mode optimizes for faster hosting performance by keeping content cached at the edge for a longer interval. Enabling performance mode will mean that hosting configuration or code changes can take up to 10 minutes to roll out.
- `enablePullRequestPreview`:  Enables pull request preview for this branch.
- `environmentVariables`:  The environment variables for the branch.
- `framework`:  The framework for the branch.
- `pullRequestEnvironmentName`:  The Amplify environment name for the pull request.
- `stage`:  Describes the current stage for the branch.
- `tags`:  The tag for the branch.
- `ttl`:  The content Time To Live (TTL) for the website in seconds.
"""

create_branch(appId, branchName; aws_config::AWSConfig=global_aws_config()) = amplify("POST", "/apps/$(appId)/branches", Dict{String, Any}("branchName"=>branchName); aws_config=aws_config)
create_branch(appId, branchName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("POST", "/apps/$(appId)/branches", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("branchName"=>branchName), args)); aws_config=aws_config)

"""
    CreateDeployment()

 Creates a deployment for a manually deployed Amplify app. Manually deployed apps are not connected to a repository.

# Required Parameters
- `appId`:  The unique ID for an Amplify app.
- `branchName`:  The name for the branch, for the job.

# Optional Parameters
- `fileMap`:  An optional file map that contains the file name as the key and the file content md5 hash as the value. If this argument is provided, the service will generate a unique upload URL per file. Otherwise, the service will only generate a single upload URL for the zipped files.
"""

create_deployment(appId, branchName; aws_config::AWSConfig=global_aws_config()) = amplify("POST", "/apps/$(appId)/branches/$(branchName)/deployments"; aws_config=aws_config)
create_deployment(appId, branchName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("POST", "/apps/$(appId)/branches/$(branchName)/deployments", args; aws_config=aws_config)

"""
    CreateDomainAssociation()

 Creates a new domain association for an Amplify app. This action associates a custom domain with the Amplify app

# Required Parameters
- `appId`:  The unique ID for an Amplify app.
- `domainName`:  The domain name for the domain association.
- `subDomainSettings`:  The setting for the subdomain.

# Optional Parameters
- `autoSubDomainCreationPatterns`:  Sets the branch patterns for automatic subdomain creation.
- `autoSubDomainIAMRole`:  The required AWS Identity and Access Management (IAM) service role for the Amazon Resource Name (ARN) for automatically creating subdomains.
- `enableAutoSubDomain`:  Enables the automated creation of subdomains for branches.
"""

create_domain_association(appId, domainName, subDomainSettings; aws_config::AWSConfig=global_aws_config()) = amplify("POST", "/apps/$(appId)/domains", Dict{String, Any}("domainName"=>domainName, "subDomainSettings"=>subDomainSettings); aws_config=aws_config)
create_domain_association(appId, domainName, subDomainSettings, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("POST", "/apps/$(appId)/domains", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("domainName"=>domainName, "subDomainSettings"=>subDomainSettings), args)); aws_config=aws_config)

"""
    CreateWebhook()

 Creates a new webhook on an Amplify app.

# Required Parameters
- `appId`:  The unique ID for an Amplify app.
- `branchName`:  The name for a branch that is part of an Amplify app.

# Optional Parameters
- `description`:  The description for a webhook.
"""

create_webhook(appId, branchName; aws_config::AWSConfig=global_aws_config()) = amplify("POST", "/apps/$(appId)/webhooks", Dict{String, Any}("branchName"=>branchName); aws_config=aws_config)
create_webhook(appId, branchName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("POST", "/apps/$(appId)/webhooks", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("branchName"=>branchName), args)); aws_config=aws_config)

"""
    DeleteApp()

 Deletes an existing Amplify app specified by an app ID.

# Required Parameters
- `appId`:  The unique ID for an Amplify app.

"""

delete_app(appId; aws_config::AWSConfig=global_aws_config()) = amplify("DELETE", "/apps/$(appId)"; aws_config=aws_config)
delete_app(appId, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("DELETE", "/apps/$(appId)", args; aws_config=aws_config)

"""
    DeleteBackendEnvironment()

 Deletes a backend environment for an Amplify app.

# Required Parameters
- `appId`:  The unique ID of an Amplify app.
- `environmentName`:  The name of a backend environment of an Amplify app.

"""

delete_backend_environment(appId, environmentName; aws_config::AWSConfig=global_aws_config()) = amplify("DELETE", "/apps/$(appId)/backendenvironments/$(environmentName)"; aws_config=aws_config)
delete_backend_environment(appId, environmentName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("DELETE", "/apps/$(appId)/backendenvironments/$(environmentName)", args; aws_config=aws_config)

"""
    DeleteBranch()

 Deletes a branch for an Amplify app.

# Required Parameters
- `appId`:  The unique ID for an Amplify app.
- `branchName`:  The name for the branch.

"""

delete_branch(appId, branchName; aws_config::AWSConfig=global_aws_config()) = amplify("DELETE", "/apps/$(appId)/branches/$(branchName)"; aws_config=aws_config)
delete_branch(appId, branchName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("DELETE", "/apps/$(appId)/branches/$(branchName)", args; aws_config=aws_config)

"""
    DeleteDomainAssociation()

 Deletes a domain association for an Amplify app.

# Required Parameters
- `appId`:  The unique id for an Amplify app.
- `domainName`:  The name of the domain.

"""

delete_domain_association(appId, domainName; aws_config::AWSConfig=global_aws_config()) = amplify("DELETE", "/apps/$(appId)/domains/$(domainName)"; aws_config=aws_config)
delete_domain_association(appId, domainName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("DELETE", "/apps/$(appId)/domains/$(domainName)", args; aws_config=aws_config)

"""
    DeleteJob()

 Deletes a job for a branch of an Amplify app.

# Required Parameters
- `appId`:  The unique ID for an Amplify app.
- `branchName`:  The name for the branch, for the job.
- `jobId`:  The unique ID for the job.

"""

delete_job(appId, branchName, jobId; aws_config::AWSConfig=global_aws_config()) = amplify("DELETE", "/apps/$(appId)/branches/$(branchName)/jobs/$(jobId)"; aws_config=aws_config)
delete_job(appId, branchName, jobId, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("DELETE", "/apps/$(appId)/branches/$(branchName)/jobs/$(jobId)", args; aws_config=aws_config)

"""
    DeleteWebhook()

 Deletes a webhook.

# Required Parameters
- `webhookId`:  The unique ID for a webhook.

"""

delete_webhook(webhookId; aws_config::AWSConfig=global_aws_config()) = amplify("DELETE", "/webhooks/$(webhookId)"; aws_config=aws_config)
delete_webhook(webhookId, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("DELETE", "/webhooks/$(webhookId)", args; aws_config=aws_config)

"""
    GenerateAccessLogs()

 Returns the website access logs for a specific time range using a presigned URL.

# Required Parameters
- `appId`:  The unique ID for an Amplify app.
- `domainName`:  The name of the domain.

# Optional Parameters
- `endTime`:  The time at which the logs should end. The time range specified is inclusive of the end time.
- `startTime`:  The time at which the logs should start. The time range specified is inclusive of the start time.
"""

generate_access_logs(appId, domainName; aws_config::AWSConfig=global_aws_config()) = amplify("POST", "/apps/$(appId)/accesslogs", Dict{String, Any}("domainName"=>domainName); aws_config=aws_config)
generate_access_logs(appId, domainName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("POST", "/apps/$(appId)/accesslogs", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("domainName"=>domainName), args)); aws_config=aws_config)

"""
    GetApp()

 Returns an existing Amplify app by appID.

# Required Parameters
- `appId`:  The unique ID for an Amplify app.

"""

get_app(appId; aws_config::AWSConfig=global_aws_config()) = amplify("GET", "/apps/$(appId)"; aws_config=aws_config)
get_app(appId, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("GET", "/apps/$(appId)", args; aws_config=aws_config)

"""
    GetArtifactUrl()

 Returns the artifact info that corresponds to an artifact id.

# Required Parameters
- `artifactId`:  The unique ID for an artifact.

"""

get_artifact_url(artifactId; aws_config::AWSConfig=global_aws_config()) = amplify("GET", "/artifacts/$(artifactId)"; aws_config=aws_config)
get_artifact_url(artifactId, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("GET", "/artifacts/$(artifactId)", args; aws_config=aws_config)

"""
    GetBackendEnvironment()

 Returns a backend environment for an Amplify app.

# Required Parameters
- `appId`:  The unique id for an Amplify app.
- `environmentName`:  The name for the backend environment.

"""

get_backend_environment(appId, environmentName; aws_config::AWSConfig=global_aws_config()) = amplify("GET", "/apps/$(appId)/backendenvironments/$(environmentName)"; aws_config=aws_config)
get_backend_environment(appId, environmentName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("GET", "/apps/$(appId)/backendenvironments/$(environmentName)", args; aws_config=aws_config)

"""
    GetBranch()

 Returns a branch for an Amplify app.

# Required Parameters
- `appId`:  The unique ID for an Amplify app.
- `branchName`:  The name for the branch.

"""

get_branch(appId, branchName; aws_config::AWSConfig=global_aws_config()) = amplify("GET", "/apps/$(appId)/branches/$(branchName)"; aws_config=aws_config)
get_branch(appId, branchName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("GET", "/apps/$(appId)/branches/$(branchName)", args; aws_config=aws_config)

"""
    GetDomainAssociation()

 Returns the domain information for an Amplify app.

# Required Parameters
- `appId`:  The unique id for an Amplify app.
- `domainName`:  The name of the domain.

"""

get_domain_association(appId, domainName; aws_config::AWSConfig=global_aws_config()) = amplify("GET", "/apps/$(appId)/domains/$(domainName)"; aws_config=aws_config)
get_domain_association(appId, domainName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("GET", "/apps/$(appId)/domains/$(domainName)", args; aws_config=aws_config)

"""
    GetJob()

 Returns a job for a branch of an Amplify app.

# Required Parameters
- `appId`:  The unique ID for an Amplify app.
- `branchName`:  The branch name for the job.
- `jobId`:  The unique ID for the job.

"""

get_job(appId, branchName, jobId; aws_config::AWSConfig=global_aws_config()) = amplify("GET", "/apps/$(appId)/branches/$(branchName)/jobs/$(jobId)"; aws_config=aws_config)
get_job(appId, branchName, jobId, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("GET", "/apps/$(appId)/branches/$(branchName)/jobs/$(jobId)", args; aws_config=aws_config)

"""
    GetWebhook()

 Returns the webhook information that corresponds to a specified webhook ID.

# Required Parameters
- `webhookId`:  The unique ID for a webhook.

"""

get_webhook(webhookId; aws_config::AWSConfig=global_aws_config()) = amplify("GET", "/webhooks/$(webhookId)"; aws_config=aws_config)
get_webhook(webhookId, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("GET", "/webhooks/$(webhookId)", args; aws_config=aws_config)

"""
    ListApps()

 Returns a list of the existing Amplify apps.

# Optional Parameters
- `maxResults`:  The maximum number of records to list in a single response.
- `nextToken`:  A pagination token. If non-null, the pagination token is returned in a result. Pass its value in another request to retrieve more entries.
"""

list_apps(; aws_config::AWSConfig=global_aws_config()) = amplify("GET", "/apps"; aws_config=aws_config)
list_apps(args::AbstractDict{String, Any}; aws_config::AWSConfig=global_aws_config()) = amplify("GET", "/apps", args; aws_config=aws_config)

"""
    ListArtifacts()

 Returns a list of artifacts for a specified app, branch, and job.

# Required Parameters
- `appId`:  The unique ID for an Amplify app.
- `branchName`:  The name of a branch that is part of an Amplify app.
- `jobId`:  The unique ID for a job.

# Optional Parameters
- `maxResults`:  The maximum number of records to list in a single response.
- `nextToken`:  A pagination token. Set to null to start listing artifacts from start. If a non-null pagination token is returned in a result, pass its value in here to list more artifacts.
"""

list_artifacts(appId, branchName, jobId; aws_config::AWSConfig=global_aws_config()) = amplify("GET", "/apps/$(appId)/branches/$(branchName)/jobs/$(jobId)/artifacts"; aws_config=aws_config)
list_artifacts(appId, branchName, jobId, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("GET", "/apps/$(appId)/branches/$(branchName)/jobs/$(jobId)/artifacts", args; aws_config=aws_config)

"""
    ListBackendEnvironments()

 Lists the backend environments for an Amplify app.

# Required Parameters
- `appId`:  The unique ID for an Amplify app.

# Optional Parameters
- `environmentName`:  The name of the backend environment
- `maxResults`:  The maximum number of records to list in a single response.
- `nextToken`:  A pagination token. Set to null to start listing backend environments from the start. If a non-null pagination token is returned in a result, pass its value in here to list more backend environments.
"""

list_backend_environments(appId; aws_config::AWSConfig=global_aws_config()) = amplify("GET", "/apps/$(appId)/backendenvironments"; aws_config=aws_config)
list_backend_environments(appId, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("GET", "/apps/$(appId)/backendenvironments", args; aws_config=aws_config)

"""
    ListBranches()

 Lists the branches of an Amplify app.

# Required Parameters
- `appId`:  The unique ID for an Amplify app.

# Optional Parameters
- `maxResults`:  The maximum number of records to list in a single response.
- `nextToken`:  A pagination token. Set to null to start listing branches from the start. If a non-null pagination token is returned in a result, pass its value in here to list more branches.
"""

list_branches(appId; aws_config::AWSConfig=global_aws_config()) = amplify("GET", "/apps/$(appId)/branches"; aws_config=aws_config)
list_branches(appId, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("GET", "/apps/$(appId)/branches", args; aws_config=aws_config)

"""
    ListDomainAssociations()

 Returns the domain associations for an Amplify app.

# Required Parameters
- `appId`:  The unique ID for an Amplify app.

# Optional Parameters
- `maxResults`:  The maximum number of records to list in a single response.
- `nextToken`:  A pagination token. Set to null to start listing apps from the start. If non-null, a pagination token is returned in a result. Pass its value in here to list more projects.
"""

list_domain_associations(appId; aws_config::AWSConfig=global_aws_config()) = amplify("GET", "/apps/$(appId)/domains"; aws_config=aws_config)
list_domain_associations(appId, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("GET", "/apps/$(appId)/domains", args; aws_config=aws_config)

"""
    ListJobs()

 Lists the jobs for a branch of an Amplify app.

# Required Parameters
- `appId`:  The unique ID for an Amplify app.
- `branchName`:  The name for a branch.

# Optional Parameters
- `maxResults`:  The maximum number of records to list in a single response.
- `nextToken`:  A pagination token. Set to null to start listing steps from the start. If a non-null pagination token is returned in a result, pass its value in here to list more steps.
"""

list_jobs(appId, branchName; aws_config::AWSConfig=global_aws_config()) = amplify("GET", "/apps/$(appId)/branches/$(branchName)/jobs"; aws_config=aws_config)
list_jobs(appId, branchName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("GET", "/apps/$(appId)/branches/$(branchName)/jobs", args; aws_config=aws_config)

"""
    ListTagsForResource()

 Returns a list of tags for a specified Amazon Resource Name (ARN).

# Required Parameters
- `resourceArn`:  The Amazon Resource Name (ARN) to use to list tags.

"""

list_tags_for_resource(resourceArn; aws_config::AWSConfig=global_aws_config()) = amplify("GET", "/tags/$(resourceArn)"; aws_config=aws_config)
list_tags_for_resource(resourceArn, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("GET", "/tags/$(resourceArn)", args; aws_config=aws_config)

"""
    ListWebhooks()

 Returns a list of webhooks for an Amplify app.

# Required Parameters
- `appId`:  The unique ID for an Amplify app.

# Optional Parameters
- `maxResults`:  The maximum number of records to list in a single response.
- `nextToken`:  A pagination token. Set to null to start listing webhooks from the start. If non-null,the pagination token is returned in a result. Pass its value in here to list more webhooks.
"""

list_webhooks(appId; aws_config::AWSConfig=global_aws_config()) = amplify("GET", "/apps/$(appId)/webhooks"; aws_config=aws_config)
list_webhooks(appId, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("GET", "/apps/$(appId)/webhooks", args; aws_config=aws_config)

"""
    StartDeployment()

 Starts a deployment for a manually deployed app. Manually deployed apps are not connected to a repository.

# Required Parameters
- `appId`:  The unique ID for an Amplify app.
- `branchName`:  The name for the branch, for the job.

# Optional Parameters
- `jobId`:  The job ID for this deployment, generated by the create deployment request.
- `sourceUrl`:  The source URL for this deployment, used when calling start deployment without create deployment. The source URL can be any HTTP GET URL that is publicly accessible and downloads a single .zip file.
"""

start_deployment(appId, branchName; aws_config::AWSConfig=global_aws_config()) = amplify("POST", "/apps/$(appId)/branches/$(branchName)/deployments/start"; aws_config=aws_config)
start_deployment(appId, branchName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("POST", "/apps/$(appId)/branches/$(branchName)/deployments/start", args; aws_config=aws_config)

"""
    StartJob()

 Starts a new job for a branch of an Amplify app.

# Required Parameters
- `appId`:  The unique ID for an Amplify app.
- `branchName`:  The branch name for the job.
- `jobType`:  Describes the type for the job. The job type RELEASE starts a new job with the latest change from the specified branch. This value is available only for apps that are connected to a repository. The job type RETRY retries an existing job. If the job type value is RETRY, the jobId is also required.

# Optional Parameters
- `commitId`:  The commit ID from a third-party repository provider for the job.
- `commitMessage`:  The commit message from a third-party repository provider for the job.
- `commitTime`:  The commit date and time for the job.
- `jobId`:  The unique ID for an existing job. This is required if the value of jobType is RETRY.
- `jobReason`:  A descriptive reason for starting this job.
"""

start_job(appId, branchName, jobType; aws_config::AWSConfig=global_aws_config()) = amplify("POST", "/apps/$(appId)/branches/$(branchName)/jobs", Dict{String, Any}("jobType"=>jobType); aws_config=aws_config)
start_job(appId, branchName, jobType, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("POST", "/apps/$(appId)/branches/$(branchName)/jobs", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("jobType"=>jobType), args)); aws_config=aws_config)

"""
    StopJob()

 Stops a job that is in progress for a branch of an Amplify app.

# Required Parameters
- `appId`:  The unique ID for an Amplify app.
- `branchName`:  The name for the branch, for the job.
- `jobId`:  The unique id for the job.

"""

stop_job(appId, branchName, jobId; aws_config::AWSConfig=global_aws_config()) = amplify("DELETE", "/apps/$(appId)/branches/$(branchName)/jobs/$(jobId)/stop"; aws_config=aws_config)
stop_job(appId, branchName, jobId, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("DELETE", "/apps/$(appId)/branches/$(branchName)/jobs/$(jobId)/stop", args; aws_config=aws_config)

"""
    TagResource()

 Tags the resource with a tag key and value.

# Required Parameters
- `resourceArn`:  The Amazon Resource Name (ARN) to use to tag a resource.
- `tags`:  The tags used to tag the resource.

"""

tag_resource(resourceArn, tags; aws_config::AWSConfig=global_aws_config()) = amplify("POST", "/tags/$(resourceArn)", Dict{String, Any}("tags"=>tags); aws_config=aws_config)
tag_resource(resourceArn, tags, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("POST", "/tags/$(resourceArn)", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("tags"=>tags), args)); aws_config=aws_config)

"""
    UntagResource()

 Untags a resource with a specified Amazon Resource Name (ARN).

# Required Parameters
- `resourceArn`:  The Amazon Resource Name (ARN) to use to untag a resource.
- `tagKeys`:  The tag keys to use to untag a resource.

"""

untag_resource(resourceArn, tagKeys; aws_config::AWSConfig=global_aws_config()) = amplify("DELETE", "/tags/$(resourceArn)", Dict{String, Any}("tagKeys"=>tagKeys); aws_config=aws_config)
untag_resource(resourceArn, tagKeys, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("DELETE", "/tags/$(resourceArn)", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("tagKeys"=>tagKeys), args)); aws_config=aws_config)

"""
    UpdateApp()

 Updates an existing Amplify app.

# Required Parameters
- `appId`:  The unique ID for an Amplify app.

# Optional Parameters
- `accessToken`:  The personal access token for a third-party source control system for an Amplify app. The token is used to create webhook and a read-only deploy key. The token is not stored.
- `autoBranchCreationConfig`:  The automated branch creation configuration for the Amplify app.
- `autoBranchCreationPatterns`:  Describes the automated branch creation glob patterns for the Amplify app.
- `basicAuthCredentials`:  The basic authorization credentials for an Amplify app.
- `buildSpec`:  The build specification (build spec) for an Amplify app.
- `customRules`:  The custom redirect and rewrite rules for an Amplify app.
- `description`:  The description for an Amplify app.
- `enableAutoBranchCreation`:  Enables automated branch creation for the Amplify app.
- `enableBasicAuth`:  Enables basic authorization for an Amplify app.
- `enableBranchAutoBuild`:  Enables branch auto-building for an Amplify app.
- `enableBranchAutoDeletion`:  Automatically disconnects a branch in the Amplify Console when you delete a branch from your Git repository.
- `environmentVariables`:  The environment variables for an Amplify app.
- `iamServiceRoleArn`:  The AWS Identity and Access Management (IAM) service role for an Amplify app.
- `name`:  The name for an Amplify app.
- `oauthToken`:  The OAuth token for a third-party source control system for an Amplify app. The token is used to create a webhook and a read-only deploy key. The OAuth token is not stored.
- `platform`:  The platform for an Amplify app.
- `repository`:  The name of the repository for an Amplify app
"""

update_app(appId; aws_config::AWSConfig=global_aws_config()) = amplify("POST", "/apps/$(appId)"; aws_config=aws_config)
update_app(appId, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("POST", "/apps/$(appId)", args; aws_config=aws_config)

"""
    UpdateBranch()

 Updates a branch for an Amplify app.

# Required Parameters
- `appId`:  The unique ID for an Amplify app.
- `branchName`:  The name for the branch.

# Optional Parameters
- `backendEnvironmentArn`:  The Amazon Resource Name (ARN) for a backend environment that is part of an Amplify app.
- `basicAuthCredentials`:  The basic authorization credentials for the branch.
- `buildSpec`:  The build specification (build spec) for the branch.
- `description`:  The description for the branch.
- `displayName`:  The display name for a branch. This is used as the default domain prefix.
- `enableAutoBuild`:  Enables auto building for the branch.
- `enableBasicAuth`:  Enables basic authorization for the branch.
- `enableNotification`:  Enables notifications for the branch.
- `enablePerformanceMode`:  Performance mode optimizes for faster hosting performance by keeping content cached at the edge for a longer interval. Enabling performance mode will mean that hosting configuration or code changes can take up to 10 minutes to roll out.
- `enablePullRequestPreview`:  Enables pull request preview for this branch.
- `environmentVariables`:  The environment variables for the branch.
- `framework`:  The framework for the branch.
- `pullRequestEnvironmentName`:  The Amplify environment name for the pull request.
- `stage`:  Describes the current stage for the branch.
- `ttl`:  The content Time to Live (TTL) for the website in seconds.
"""

update_branch(appId, branchName; aws_config::AWSConfig=global_aws_config()) = amplify("POST", "/apps/$(appId)/branches/$(branchName)"; aws_config=aws_config)
update_branch(appId, branchName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("POST", "/apps/$(appId)/branches/$(branchName)", args; aws_config=aws_config)

"""
    UpdateDomainAssociation()

 Creates a new domain association for an Amplify app.

# Required Parameters
- `appId`:  The unique ID for an Amplify app.
- `domainName`:  The name of the domain.
- `subDomainSettings`:  Describes the settings for the subdomain.

# Optional Parameters
- `autoSubDomainCreationPatterns`:  Sets the branch patterns for automatic subdomain creation.
- `autoSubDomainIAMRole`:  The required AWS Identity and Access Management (IAM) service role for the Amazon Resource Name (ARN) for automatically creating subdomains.
- `enableAutoSubDomain`:  Enables the automated creation of subdomains for branches.
"""

update_domain_association(appId, domainName, subDomainSettings; aws_config::AWSConfig=global_aws_config()) = amplify("POST", "/apps/$(appId)/domains/$(domainName)", Dict{String, Any}("subDomainSettings"=>subDomainSettings); aws_config=aws_config)
update_domain_association(appId, domainName, subDomainSettings, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("POST", "/apps/$(appId)/domains/$(domainName)", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("subDomainSettings"=>subDomainSettings), args)); aws_config=aws_config)

"""
    UpdateWebhook()

 Updates a webhook.

# Required Parameters
- `webhookId`:  The unique ID for a webhook.

# Optional Parameters
- `branchName`:  The name for a branch that is part of an Amplify app.
- `description`:  The description for a webhook.
"""

update_webhook(webhookId; aws_config::AWSConfig=global_aws_config()) = amplify("POST", "/webhooks/$(webhookId)"; aws_config=aws_config)
update_webhook(webhookId, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = amplify("POST", "/webhooks/$(webhookId)", args; aws_config=aws_config)


text:
function axis_angle_to_quaternion(x)
    @assert length(x) == 3
    θ = norm(x)
    if θ > 0.0
        r = x ./ θ
        q = Quaternion(cos(0.5 * θ), sin(0.5 * θ) * r)
    else
        q = Quaternion(1.0, 0.0, 0.0, 0.0)
    end
    return q
end

function daxis_angle_to_quaterniondx(x)
    θ = norm(x)
    if θ > 0.0
        r = x ./ θ

        ∂qw∂x = -0.5 * sin(0.5 * θ) * transpose(x) ./ θ
        ∂qx∂x = 0.5 * cos(0.5 * θ) * transpose(x) ./ θ * r[1] + [sin(0.5 * θ) / θ 0.0 0.0] - sin(0.5 * θ) * x[1] / θ^2 * transpose(x) ./ θ
        ∂qy∂x = 0.5 * cos(0.5 * θ) * transpose(x) ./ θ * r[2] + [0.0 sin(0.5 * θ) / θ 0.0] - sin(0.5 * θ) * x[2] / θ^2 * transpose(x) ./ θ
        ∂qz∂x = 0.5 * cos(0.5 * θ) * transpose(x) ./ θ * r[3] + [0.0 0.0 sin(0.5 * θ) / θ] - sin(0.5 * θ) * x[3] / θ^2 * transpose(x) ./ θ

        return [
                ∂qw∂x;
                ∂qx∂x;
                ∂qy∂x;
                ∂qz∂x;
               ]
    else
        return [
                    0.0  0.0  0.0;
                    0.5  0.0  0.0;
                    0.0  0.5  0.0;
                    0.0  0.0  0.5;
                ]
    end
end


text:
@testset "icd10" begin
    icd10_add_dots    = DiagnosisClassification.icd10_add_dots
    icd10_remove_dots = DiagnosisClassification.icd10_remove_dots

    @testset "icd10_add_dots" begin
        test_cases = [
            # Input is too short for a dot
            "W55"      => "W55",
            "Z67"      => "Z67",

            # Input contains a dot
            "W55.2"    => "W55.2",
            "W55.29"   => "W55.29",
            "W55.29X"  => "W55.29X",
            "W55.29XA" => "W55.29XA",
            "Z67.4"    => "Z67.4",
            "Z67.41"   => "Z67.41",

            # Input does not contain a dot
            "W552"     => "W55.2",
            "W5529"    => "W55.29",
            "W5529X"   => "W55.29X",
            "W5529XA"  => "W55.29XA",
            "Z674"     => "Z67.4",
            "Z6741"    => "Z67.41",
        ]
        for test_case in test_cases
            input           = test_case[1]
            expected_output = test_case[2]
            @test icd10_add_dots(input) == expected_output
        end
        @test_throws ErrorException icd10_add_dots("")
    end

    @testset "icd10_remove_dots" begin
        test_cases = [
            # Input is too short for a dot
            "W55"      => "W55",
            "Z67"      => "Z67",

            # Input contains a dot
            "W55.2"    => "W552",
            "W55.29"   => "W5529",
            "W55.29X"  => "W5529X",
            "W55.29XA" => "W5529XA",
            "Z67.4"    => "Z674",
            "Z67.41"   => "Z6741",

            # Input does not contain a dot
            "W552"     => "W552",
            "W5529"    => "W5529",
            "W5529X"   => "W5529X",
            "W5529XA"  => "W5529XA",

            "Z674"     => "Z674",
            "Z6741"    => "Z6741",
        ]
        for test_case in test_cases
            input           = test_case[1]
            expected_output = test_case[2]
            @test icd10_remove_dots(input) == expected_output
        end
        @test_throws ErrorException icd10_remove_dots("")
    end

    @testset "Roundtrip icd10_add_dots" begin
        test_cases = [
            # Input is too short for a dot
            "W55"      => "W55",
            "Z67"      => "Z67",

            # Input contains a dot
            "W55.2"    => "W552",
            "W55.29"   => "W5529",
            "W55.29X"  => "W5529X",
            "W55.29XA" => "W5529XA",
            "Z67.4"    => "Z674",
            "Z67.41"   => "Z6741",

            # Input does not contain a dot
            "W552"     => "W552",
            "W5529"    => "W5529",
            "W5529X"   => "W5529X",
            "W5529XA"  => "W5529XA",
            "Z674"     => "Z674",
            "Z6741"    => "Z6741",
        ]
        for test_case in test_cases
            input           = test_case[1]
            expected_output = test_case[2]
            @test icd10_remove_dots(icd10_add_dots(input)) == expected_output
        end
    end

    @testset "Roundtrip icd10_remove_dots" begin
        test_cases = [
            # Input is too short for a dot
            "W55"      => "W55",
            "Z67"      => "Z67",

            # Input contains a dot
            "W55.2"    => "W55.2",
            "W55.29"   => "W55.29",
            "W55.29X"  => "W55.29X",
            "W55.29XA" => "W55.29XA",
            "Z67.4"    => "Z67.4",
            "Z67.41"   => "Z67.41",

            # Input does not contain a dot
            "W552"     => "W55.2",
            "W5529"    => "W55.29",
            "W5529X"   => "W55.29X",
            "W5529XA"  => "W55.29XA",
            "Z674"     => "Z67.4",
            "Z6741"    => "Z67.41",
        ]
        for test_case in test_cases
            input           = test_case[1]
            expected_output = test_case[2]
            @test icd10_add_dots(icd10_remove_dots(input)) == expected_output
        end
    end
end


text:
function higibbs(Y, T, mu0 = 50.0, gamma20 = 25.0, nu0 = 1.0, sigma2 = 100.0, eta0 = 1.0, tau20 = 100.0)
    m = size(unique(Y[:,1]), 1)
    # starting value
    ybar = ones(m)
    sv = ones(m)
    n = ones(m)
    for j = 1:m
        yj = Y[ [Y[i,1] == j for i = 1:end], 2]
        ybar[j] = mean(yj)
        sv[j] = var(yj)
        n[j] = size(yj, 1)
    end
    theta = ybar
    sigma2 = mean(sv)
    mu = mean(theta)
    tau2 = var(theta)

    THETA = ones(T, m)
    # sigma2 mu tau2
    SMT = ones(T, 3)

    for t = 1:T
        # sample theta
        for j = 1:m
            vartheta = 1 / (n[j] / sigma2 + 1 / tau2)
            meantheta = vartheta * ( n[j] * ybar[j]) / sigma2 + mu / tau2)
            rnorm = Normal(meantheta, sqrt(vartheta))
            theta[j] = rand(rnorm, 1)[1]
        end
        THETA[t, :] .= theta

        # sample new sigma2
        nun = nu0 + sum(n)
        ss = nu0 * s20
        for j = 1:m
            ss += sum((Y[ [Y[i, 1] == j for i = 1:end], 2] .- theta[j]).^2)
        end
        rgamma = Gamma(nun/2, 2/ss)
        sigma2 = 1 / rand(rgamma, 1)[1]

        # sample mu
        varmu = 1 / (m / tau2 + 1 / gamma20)
        meanmu = varmu * (m * mean(theta) / tau2 + mu0 / gamma20)
        rnorm = Normal(meanmu, sqrt(varmu))
        mu = rand(rnorm, 1)[1]

        # sample 1/tau2
        shapetau = (eta0 + m) / 2
        ratetau = ( eta0 * tau20 + sum((theta .- mu).^2) ) / 2
        rgamma = Gamma(shapetau, 1/ratetau)
        tau2 = 1 / rand(rgamma, 1)[1]

        # store results
        SMT[t, :] .= [sigma2, mu, tau2]
    end
    return THETA, SMT
end

# run
Y = readdlm("math-score-Y.csv")
THETA, SMT = higibbs(Y, 5000)

max_stars_repo_name: szcf-weiya/MCMC

max_issues_repo_name: szcf-weiya/MCMC

max_forks_repo_name: szcf-weiya/MCMC


text:
using DiffEqBase, MATLABDiffEq, ParameterizedFunctions, Test

f = @ode_def_bare LotkaVolterra begin
  dx = a*x - b*x*y
  dy = -c*y + d*x*y
end a b c d
p = [1.5,1,3,1]
tspan = (0.0,10.0)
u0 = [1.0,1.0]
prob = ODEProblem(f,u0,tspan,p)
sol = solve(prob,MATLABDiffEq.ode45())

function lorenz(du,u,p,t)
 du[1] = 10.0(u[2]-u[1])
 du[2] = u[1]*(28.0-u[3]) - u[2]
 du[3] = u[1]*u[2] - (8/3)*u[3]
end
u0 = [1.0;0.0;0.0]
tspan = (0.0,100.0)
prob = ODEProblem(lorenz,u0,tspan)
sol = solve(prob,MATLABDiffEq.ode45())

algs = [MATLABDiffEq.ode23
        MATLABDiffEq.ode45
        MATLABDiffEq.ode113
        MATLABDiffEq.ode23s
        MATLABDiffEq.ode23t
        MATLABDiffEq.ode23tb
        MATLABDiffEq.ode15s]

for alg in algs
  sol = solve(prob,alg())
end

max_stars_repo_name: JuliaDiffEq/MATLABDiffEq

max_issues_repo_name: JuliaDiffEq/MATLABDiffEq

max_forks_repo_name: JuliaDiffEq/MATLABDiffEq


text:
using HDF5
using Random
include("./karger.jl")
using .Karger

# USAGE: julia src/julia/calculate_potential.jl filename N
# where N is the number of samples to use and filename just the name (without path or .h5).
# The file has to be an HDF5 file with fields n, edges, weights and seeds. The output
# will be written in a file with the same name in the "potentials" directory

Random.seed!(0)

graph_path = "results/graphs/" * ARGS[1] * ".h5"
result_path = "results/karger_potentials/" * ARGS[1] * ".h5"

n = h5read(graph_path, "n")
edges = h5read(graph_path, "edges")
weights = h5read(graph_path, "weights")
seeds = h5read(graph_path, "seeds")
g = Graph(n, transpose(edges) .+ 1, weights)
mkpath(dirname(result_path))
cp(graph_path, result_path, force=true)
h5write(result_path, "potential", potential(g, parse(Int, ARGS[2]), seeds)[1])


text:
using Compat
#import BinDeps.library_dependency
#import BinDeps.BuildProcess
#import BinDeps.Sources
#import BinDeps.URI
using BinDeps
@BinDeps.setup
print("before wrapper")
using CMakeWrapper

print("after wrapper")
AMAC=library_dependency("libAMAC",aliases=["libAMAC","libAMAC.so","libAMAC.dylib","libAMAC.dll"])

print("after AMAC")

print(pwd())
print("\nafter pwd")
run(`$cmake_executable ./CMakeLists.txt`)
print("\nafter read CMakelists.txt")
run(`$cmake_executable --build .`)
print("\nafter build")


text:
function U1_strip_harper_hofstadter(width;flux=pi/2,Jx=1,Jy=1,periodic=false,filling=1)
    #we change the charge of the first site (c - filling), imposing a filling/width
    ps1 = Rep[U₁](-filling=>1,(1-filling)=>1);
    ps2 = Rep[U₁](0=>1,1=>1);

    ou = oneunit(ps1);

    #pspaces[i] = physical space at location i
    pspaces = [ps1;fill(ps2,width-1)];

    hop_y_1 = map(pspaces) do ps
        TensorMap(ones,ComplexF64,ou*ps,Rep[U₁](1=>1,-1=>1)*ps);
    end
    hop_y_2 = map(pspaces) do ps
        TensorMap(ones,ComplexF64,Rep[U₁](1=>1,-1=>1)*ps,ou*ps);
    end

    hop_x_1 = map(enumerate(hop_y_1)) do (y,h)
        nh = copy(h);

        upcharge = (y == 1) ? U₁(1-filling) : U₁(1);
        downcharge = (y == 1) ? U₁(-filling) : U₁(0);

        blocks(nh)[upcharge].*=exp(1im*y*flux)
        blocks(nh)[downcharge].*=exp(-1im*y*flux)

        nh
    end
    hop_x_2 = hop_y_2;

    passthrough = map(pspaces) do ps
        complex(isomorphism(Rep[U₁](1=>1,-1=>1)*ps,Rep[U₁](1=>1,-1=>1)*ps));
    end

    #the actual mpo - hamiltonian
    mpot = Array{Any,3}(missing,width,width+3+periodic,width+3+periodic)

    for y in 1:width
        mpot[y,1,1] = 1.0;
        mpot[y,end,end] = 1.0;

        #pass the previously created - anihilated particle through
        for cy in [1:y-1;y+1:width]
            mpot[y,cy+1,cy+1] = passthrough[y]
        end

        #create/anihilate particles along the x direction
        mpot[y,1,y+1] = -hop_x_1[y]*Jx;
        mpot[y,y+1,end] = hop_x_2[y];

        #create/anihilated along the y direction
        mpot[y,1,2+width] = -hop_y_1[y]*Jy

        if y!=1
            mpot[y,2+width,end] = hop_y_2[y];
        end

        #if it's periodic we need to create/anihilate on the endpoints as well
        if periodic
            if y == 1
                mpot[y,1,3+width] = - hop_y_1[y]*Jy
            elseif y == width
                mpot[y,3+width,end] = hop_y_2[y];
            else
                mpot[y,3+width,3+width] = passthrough[y]
            end
        end

    end

    MPOHamiltonian(mpot)

end


text:
export spectral!

"""
`spectral!(X::GraphEmbedding)` gives the graph held in `X` an
embedding based on the eigenvectors of the Laplacian matrix of the
graph. Specifically, the `x`-coordinates come from the eigenvector
associated with the second smallest eigenvalue, and the
`y`-coordinates come from the eigenveector associated with the third
smallest.

This may also be invoked as `spectral!(X,xcol,ycol)` to choose other
eigenvectors to use for the x and y coordinates of the embedding.
"""
function spectral!(X::GraphEmbedding,xcol::Int=2,ycol::Int=3)
    L = laplace(X.G)
    EV = eigvecs(L)
    x = EV[:,xcol]
    y = EV[:,ycol]

    VV = vlist(X.G)
    n = length(VV)

    for k=1:n
        v = VV[k]
        X.xy[v] = [x[k],y[k]]
    end
    rescale!(X)
    return X
end


text:
#-------------------------------------------------------------------------------
# Logger configuration
# TODO: Lots of design work to do here.  Presumably there should be a standard
# textural log system config system like the python one.

parse_level(level) = level
parse_level(level::String) = parse_level(Symbol(lowercase(level)))
function parse_level(level::Symbol)
    if      level == :belowminlevel  return  BelowMinLevel
    elseif  level == :debug          return  Debug
    elseif  level == :info           return  Info
    elseif  level == :warn           return  Warn
    elseif  level == :error          return  Error
    elseif  level == :abovemaxlevel  return  AboveMaxLevel
    else
        throw(ArgumentError("Unknown log level $level"))
    end
end

"""
    configure_logging(args...; kwargs...)

Call `configure_logging` with the current logger, and update cached log
filtering information.
"""
function configure_logging(args...; kwargs...)
    logger = configure_logging(current_logger(), args...; kwargs...)::AbstractLogger
    # FIXME: Tools for setting this should be in Base.
    if current_task().logstate != nothing
        current_task().logstate = LogState(logger)
    else
        global_logger(logger)
    end
    logger
end

configure_logging(::AbstractLogger, args...; kwargs...) =
    throw(ArgumentError("No configure_logging method matches the provided arguments."))

function configure_logging(logger::SimpleLogger, args...; min_level=Info, kwargs...)
    SimpleLogger(logger.stream, parse_level(min_level))
end

function configure_logging(logger::ConsoleLogger, _module=nothing;
                           min_level=Info)
    min_level = parse_level(min_level)
    #=
    # TODO: Re-add per-module limits as in InteractiveLogger?
    if _module == nothing
        empty!(logger.module_limits)
        logger.min_level = min_level
    else
        # Per-module log limiting
        logger.module_limits[_module] = min_level
    end
    =#
    ConsoleLogger(logger.stream, min_level, logger.meta_formatter,
                  logger.show_limited, logger.right_justify, logger.message_limits,
                  logger.sticky_messages)
end

# NB: ConsoleLogger and Logging.ConsoleLogger are different!!
function configure_logging(logger::Logging.ConsoleLogger; min_level=Info)
    min_level = parse_level(min_level)
    Logging.ConsoleLogger(logger.stream, min_level, logger.meta_formatter,
                  logger.show_limited, logger.right_justify, logger.message_limits)
end

disable_logging(level) = disable_logging(parse_level(level))

import Test: TestLogger
function configure_logging(logger::TestLogger; min_level=Info)
    logger.min_level = min_level
    logger
end


text:
# Check the interactions of different Containers via `convert`

using TypeClasses
using Test
using Suppressor
using DataTypesBasic
splitln(str) = split(strip(str), "\n")

load_square(x, prefix="") = @ContextManager function (cont)
  println("$(prefix)before $x")
  result = cont(x*x)
  println("$(prefix)after $x")
  result
end

# Multiple Combinations
# =====================

# unfortunately this does not work, as the typeinference does not work
# and hence an Array of Any is constructed instead of an Array of ContextManager

# the version without the Array component works like a charm

h2() = @syntax_flatmap begin
  (a, b) = [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
  c = iftrue(a % 2 == 0) do
    a + b
  end
  d = load_square(c) # c*c
  @pure d
end

@test @suppress(h2()) == [25, 81]
@test splitln(@capture_out h2()) == ["before 5", "after 5", "before 9", "after 9"]

# Try
# ---

mytry(x) = x == 4 ? error("error") : x

h3() = @syntax_flatmap begin
  (a, b) = [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
  c = iftrue(a % 2 == 0) do
    a + b
  end
  d = load_square(c)  # c*c
  e = @Try mytry(d / a)
  @pure e + 1
end
@test @suppress(h3()) == [(2+3)^2/2 + 1, (4+5)^2/4 + 1]  # TODO not working because of bad type-inference
@test splitln(@capture_out h3()) == [
  "before 5",
  "after 5",
  "before 9",
  "after 9",
]

# Either
# ------

h4() = @syntax_flatmap begin
  (a, b) = [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
  c = iftrue(a % 2 == 0) do
    a + b
  end
  d = load_square(c) # c*c
  f = either("left", d > 4, :right)
  e = @Try "$a, $b, $c, $d, $f"
end
@test @suppress(h4()) == ["2, 3, 5, 25, right", "4, 5, 9, 81, right"]
@test splitln(@capture_out h4()) == [
  "before 5",
  "after 5",
  "before 9",
  "after 9",
]

# Writer + ContextManager
# ---------------------

writer_cm() = @syntax_flatmap begin
  i = Writer("hi", 4)
  l = load_square(i)
  Writer(" $l yes", l+i)
end

# importantly, writer does not work smoothly with other Contexts, but only by forgetting its accumulator
@test @suppress(writer_cm()) != Writer("hi 4 yes", 4*4+4)
@test @suppress(writer_cm()) == Writer("hi", 4*4+4)
@test splitln(@capture_out writer_cm()) == [
  "before 4",
  "after 4"
]

# combining ContextManager with other monads
# ------------------------------------------

# ContextManager as main Monad

cm2 = @syntax_flatmap begin
  i = load_square(4)
  v = [i, i+1, i+3]
  @pure v + 2
end
@test_throws MethodError @suppress(cm2(x -> x).value) == [6,7,9]
@test_throws MethodError splitln(@capture_out cm2(x -> x)) == ["before 4", "after 4"]

# ContextManager as sub monad

vector2() = @syntax_flatmap begin
  i = [1,2,3]
  c = load_square(i)
  @pure c + 2
end
@test @suppress(vector2()) == [1*1+2, 2*2+2, 3*3+2]
@test splitln(@capture_out vector2()) == [
  "before 1", "after 1", "before 2", "after 2", "before 3", "after 3"]

# alternating contextmanager and vector does not work, as there is no way to convert a vector to a contextmanager

multiplecm() = @syntax_flatmap begin
  i = [1,2,3]
  c = load_square(i, "i ")
  j = [c, c*c]
  c2 = load_square(j, "j ")
  @pure c + c2
end

@test_throws MethodError @suppress(multiplecm()) == [2, 2, 4, 6, 6, 12]
@test_throws MethodError splitln(@capture_out multiplecm()) == ["i before 1",
  "j before 1",
  "j after 1",
  "j before 1",
  "j after 1",
  "i after 1",
  "i before 2",
  "j before 2",
  "j after 2",
  "j before 4",
  "j after 4",
  "i after 2",
  "i before 3",
  "j before 3",
  "j after 3",
  "j before 9",
  "j after 9",
  "i after 3"]


text:
using CSV
using DataFrames
using Distributions
using StatsPlots
using PyCall
using Random
using Transits
using Turing

exo = pyimport("exoplanet")
fits = pyimport("astropy.io.fits")

rootdir(args...) = joinpath(@__DIR__, args...)
datadir(args...) = rootdir("data", args...)

rng = Random.seed!(8462852)

##

t = 0:0.02:80

function exo_to_arr(input)
    X = input[1].eval()
    Y = input[2].eval()
    return @. sqrt(X^2 + Y^2)
end

@model function transit_model(flux, fluxerr)
    logP ~ Normal(log(13), 0.1)
    period = exp(logP)

    t0 ~ Normal()

    us ~ Kipping13()
    r ~ Uniform(0.01, 0.1)
    b ~ Uniform(0, r)

    # define orbit
    orbit = exo.orbits.KeplerianOrbit(;period, t0, b)
    bs = exo_to_arr(orbit.get_relative_position(t))

    law = QuadLimbDark(us)
    y = @. law(bs, r)
    flux ~ MvNormal(y, fluxerr)
    return (;period, t0, us, r, b, flux, fluxerr)
end

function generate_data(yerr)
    err = yerr .* randn(rng, length(t))
    prior = transit_model(missing, err)
    return prior()
end

data = generate_data(5e-4)

phases = @. (t - data.t0 + data.period / 2) % data.period - data.period / 2
scatter(phases, data.flux, yerr=data.fluxerr, xlims=(-0.3, 0.3), c=:black, ms=3)

fits.writeto(datadir("simulated_data_0.fits"), [t data.flux data.fluxerr])
DataFrame(
    snr=5e-4,
    period=data.period,
    t0=data.t0,
    u1=data.us[1],
    u2=data.us[2],
    r=data.r,
    b=data.b,
) |> CSV.write(datadir("params_0.csv"))

max_stars_repo_name: mileslucas/yeehaw

max_issues_repo_name: mileslucas/yeehaw

max_forks_repo_name: mileslucas/yeehaw


text:
using HTTP
using JSON

const headers = [
    "Authorization" => "Bearer " * ENV["ZOOM_JWT_TOKEN"],
    "Content-Type" => "application/json"
]

function create_meeting(userId)
    result = HTTP.request(
        "POST",
        "https://api.zoom.us/v2/users/$userId/meetings",
        headers,
        "{\"topic\": \"test meeting\"}"
    )
    return JSON.parse(String(result.body))["join_url"]
end

max_stars_repo_name: MLH-Fellowship/ZoomCord

max_issues_repo_name: MLH-Fellowship/ZoomCord

max_forks_repo_name: MLH-Fellowship/ZoomCord