text:
using Pkg

dependencies = [
    "Distributions",
    "Plots"
]

Pkg.add(dependencies)


text:
module contactForceLaw_2_boxes2

using Modia3D
using Modia3D.StaticArrays
import Modia3D.ModiaMath

vmat1 = Modia3D.Material(color="LightBlue" , transparency=0.5)    # material of SolidFileMesh
vmat2 = Modia3D.Material(color="Green" , transparency=0.5)

zDim = 0.02
boxDim = 0.2
rsmall = 0.001   # 0.03    # 0.03
@assembly ThreeDFiles begin
  world = Modia3D.Object3D(visualizeFrame=true)

  boxMoving = Modia3D.ContactBox(world, scale=[boxDim,boxDim,boxDim], rsmall=rsmall,
                                 massProperties="DryWood", material=vmat1,
                                 contactMaterial = "DryWood", r=[0.3, 0.3, 2*boxDim], fixed=false)
  box     = Modia3D.Object3D(world, Modia3D.Solid(Modia3D.SolidBox(0.6,0.6,zDim) , "DryWood", vmat2; contactMaterial = "DryWood"); r=[0.3, 0.3, -zDim/2], fixed=true )
end

gravField = Modia3D.UniformGravityField(g=9.81, n=[0,0,-1])
threeD = ThreeDFiles(sceneOptions=Modia3D.SceneOptions(gravityField=gravField,visualizeFrames=false, defaultFrameLength=0.2,nz_max = 100, enableContactDetection=true, visualizeContactPoints=false, visualizeSupportPoints=false))

# Modia3D.visualizeAssembly!( threeD )

model = Modia3D.SimulationModel( threeD )
ModiaMath.print_ModelVariables(model)
result = ModiaMath.simulate!(model; stopTime=2.0, tolerance=1e-8,interval=0.001, log=true)

ModiaMath.plot(result, ["boxMoving.box.r[3]","boxMoving.box.v[3]"])

println("... success of contactForceLaw_2_boxes2.jl!")

end

ext: jl


text:
using Test
using CircularList

# TODO: using circular list
# can make it lazy if desired

function print_cups(cups, cur)
    out = ""
    for c in cups
        if c == cur
            out *= "($(c)) "
        else
            out *= "$(c) "
        end
    end
    @info("cups: $(out)")
end

function pick_up_cups(cups, cur)
end

function place_cups(cups, picked_up, dest)
    return cups
end

MAX_CUP = Int(1e6)
MAX_MOVES = Int(1e7)
# MAX_CUP = Int(9)
# MAX_MOVES = Int(100)

function run(input, version=1)
    @info "initializing list..."
    given_values = map(x -> parse(Int, x), collect(input))
    cur = given_values[1] # TODO: ideally cur will == head of the list to save effort

    cups = Nothing
    lookup = Dict() # maps from value to Node in CircularList
    for i in given_values
        if cups == Nothing
            # initialize
            cups = circularlist(i)
            lookup[i] = head(cups)
        else
            insert!(cups, i)
            lookup[i] = head(cups)
        end
    end

    max_cup = 9
    if version == 2
        max_cup = MAX_CUP
        for i in 10:max_cup
            insert!(cups, i)
            lookup[i] = head(cups)
        end
    end

    num_moves = 100
    if version == 2
        num_moves = Int(MAX_MOVES)
    end
    @info "starting..."
    for move in 1:num_moves
        # @show move
        if move % Int(1e5) == 0
            @info("-- move $(move) --")
        end
        # print_cups(cups, cur)

        # The crab picks up the three cups that are immediately clockwise of
        # the current cup. They are removed from the circle; cup spacing is
        # adjusted as necessary to maintain the circle.

        ## PICK UP CUPS
        jump!(cups, lookup[cur])
        # while head(cups).data != cur
        #     forward!(cups)
        # end

        picked_up = []
        for i in 1:3
            forward!(cups)
            push!(picked_up, current(cups).data)
            delete!(cups)
            # previous node becomes the head
            @assert cur == head(cups).data
        end
        # @show picked_up

        next_cur = next(cups).data

        # @info("pick up: $(picked_up)")

        # The crab selects a destination cup: the cup with a label equal to the
        # current cup's label minus one. If this would select one of the cups
        # that was just picked up, the crab will keep subtracting one until it
        # finds a cup that wasn't just picked up. If at any point in this
        # process the value goes below the lowest value on any cup's label, it
        # wraps around to the highest value on any cup's label instead.
        dest = cur - 1
        while dest == 0 || in(dest, picked_up)
            dest = mod(dest - 1, max_cup + 1)
        end

        # @info("destination: $(dest)")
        # @info("")

        # The crab places the cups it just picked up so that they are
        # immediately clockwise of the destination cup. They keep the same
        # order as when they were picked up.

        ## PLACE CUPS
        jump!(cups, lookup[dest])
        # while head(cups).data != dest
        #     forward!(cups)
        # end

        for p in picked_up
            insert!(cups, p)
            lookup[p] = head(cups)
        end

        cur = next_cur
    end

    jump!(cups, lookup[1])

    result = Nothing
    if version == 1
        result = join(collect(cups)[2:end]) # skip 1
    else
        forward!(cups)
        a = head(cups).data
        forward!(cups)
        b = head(cups).data
        @show a
        @show b
        result = a * b
    end

    println("Result = ", result)
    return result
end

function run2(input)
    return run(input, 2)
end

example = "389125467"
actual = "362981754"
@test run(example) == "67384529"

run(actual)

@test run2(example) == (934001 * 159792) # 149245887792

run2(actual)


text:
# Rigid-body transformation routines

import Base: vec
export RigidTransform

"""
    RigidTransform(x::Tuple{Float64,Float64},α::Float64)

Construct a rigid-body transform operator, with rotation by angle `α` and
translation specified by `x`. The translation coordinates are specified in the
target coordinate system.

The resulting transform can be used as an operator on pairs of coordinate vectors,
`x` and `y`, or on bodies. For transformation of bodies, it only overwrites the
`x` and `y` fields of the body, but leaves the `x̃` and `ỹ` (body coordinates) intact.

The translation can be provided as either a tuple `(x,y)` or as a complex number.

# Constructors

- `RigidTransform((x,y),α)`
- `RigidTransform(u::Vector{Float64})`
- `RigidTransform(u::NTuple{3,Float64})`
- `RigidTransform.(u)` where `u` is a collection of vectors or tuples.

# Example

```jldoctest
julia> body = Bodies.Ellipse(0.5,0.1,100)
Elliptical body with 100 points and semi-axes (0.5,0.1)
   Current position: (0.0,0.0)
   Current angle (rad): 0.0

julia> T = RigidTransform((1.0,1.0),π/4)
Rigid-body transform
  Translation: (1.0,1.0)
  Rotation angle (rad): 0.7853981633974483

julia> T(body)
Elliptical body with 100 points and semi-axes (0.5,0.1)
   Current position: (1.0,1.0)
   Current angle (rad): 0.7853981633974483
```
"""
struct RigidTransform
   α   :: Float64
   rot :: Matrix{Float64}
   trans  :: Tuple{Float64,Float64}
end

function RigidTransform(x::Tuple{Float64,Float64},α::Float64)
    rot = [cos(α) -sin(α)
           sin(α) cos(α)]
    RigidTransform(α,rot,x)
end

RigidTransform(x::Union{AbstractVector{T},NTuple{3,T}}) where {T<:Real} = RigidTransform((x[1],x[2]),x[3])

RigidTransform(c::ComplexF64,α::Float64) = RigidTransform((real(c),imag(c)),α)

function Base.show(io::IO, T::RigidTransform)
    name = "Rigid-body transform"
    println(io, name)
    println(io, "  Translation: ($(T.trans[1]),$(T.trans[2]))")
    println(io, "  Rotation angle (rad): $(T.α)")
end

"""
    vec(T::RigidTransform) -> Vector{Float64}

Returns a length-3 vector of the form [x,y,α] corresponding to the translation
and rotation specified by the given transform `T`.
"""
vec(T::RigidTransform) = [T.trans[1],T.trans[2],T.α]

function (T::RigidTransform)(x̃::Float64,ỹ::Float64)
    Xr = T.rot*[x̃,ỹ]
    return T.trans .+ (Xr[1],Xr[2])
end
function (T::RigidTransform)(x̃::AbstractVector{Float64},ỹ::AbstractVector{Float64})
    x = deepcopy(x̃)
    y = deepcopy(ỹ)
    for i = 1:length(x̃)
        x[i],y[i] = T(x̃[i],ỹ[i])
    end
    return x, y
end

function (T::RigidTransform)(b::Body{N}) where {N}
  b.x, b.y = T(b.x̃,b.ỹ)
  b.α = T.α
  b.cent = T.trans
  return b
end

# Things to do here:
#  - add an inverse operation
#  - should be composite operations
#  - probably should distinguish in-place and non-in-place versions


text:
abstract AbstractTest

abstract TestType <: AbstractTest
abstract TestOperation <: AbstractTest

immutable Is{T} <: TestType
 field::Symbol
 value::T
end

immutable In{T} <: TestType
 field::Symbol
 value::T
end

_test{T}(object, test::In{T}) = getfield(object, test.field) in test.value

function _test{T}(object, test::In{T})
  field = getfield(object, test.field)
  et = eltype(T)
  if isa(field, ASCIIString) && et <: Real
    return( parse(et, field) in test.value )
  end
  et(field) in test.value
end

_test{T}(object, test::Is{T}) = getfield(object, test.field) == test.value
_test(object, test::Is{Regex}) = ismatch(test.value, getfield(object, test.field))
_test(object, test::Is{Function}) = test.value(getfield(object, test.field))

immutable Not{T <: TestType} <: TestOperation
 test::T
end

_test{T}(object, test::Not{T}) = !_test(object, test.test::T)

"Returns `true` if all the tests are satisfied"
function isobject(object, tests::AbstractTest...)
  for test in tests
    if !_test(object, test)
      return(false)
    end
  end
  true
end

"""Returns a `Nullable` of the `field`.
The object is `null` if any test fails"""
function capture(object, field::Symbol, tests::AbstractTest...)
  captured = getfield(object, field)
  for test in tests
    if !_test(object, test)
      return(Nullable{typeof(captured)}())
    end
  end
  Nullable(captured)
end

"Returns a vector of the indexes for which `isobject` is true."
function findobjects(vector, tests::AbstractTest...)
  len = length(vector)
  indexes = Array(Int, len)
  n = 0
  for i in 1:len
    if isobject(vector[i], tests...)
      n += 1
      indexes[n] = i
    end
  end
  resize!(indexes, n)
end

"Returns a vector with the objects for which `isobject` is true given the Tests."
function collectobjects{T}(vector::AbstractVector{T}, tests::AbstractTest...)
  len = length(vector)
  elements = Array(T, len)
  n = 0
  for i in 1:len
    if isobject(vector[i], tests...)
      n += 1
      elements[n] = vector[i]
    end
  end
  resize!(elements, n)
end

"Returns the **type** of the `field` in the first object of the collection"
function guess_type(collection, field::Symbol)
  for object in collection
    if field in fieldnames(object)
      return(fieldtype(typeof(object), field))
    end
  end
  Any
end

"""Returns a vector of Nullables with the captures of the `field`s.
Null if any test fails or the object hasn't the `field`."""
function collectcaptures(vector, field::Symbol, tests::AbstractTest...)
  Nullable{guess_type(vector, field)}[ field in fieldnames(object) ? capture(object, field, tests...) : Nullable() for object in vector ]
end


text:
using CLIMA.PlanetParameters
export RadiationModel, NoRadiation

abstract type RadiationModel end

vars_state(::RadiationModel, FT) = @vars()
vars_aux(::RadiationModel, FT) = @vars()
vars_integrals(::RadiationModel, FT) = @vars()
vars_reverse_integrals(::RadiationModel, FT) = @vars()

function atmos_nodal_update_aux!(::RadiationModel, ::AtmosModel, state::Vars, aux::Vars, t::Real) end
function preodefun!(::RadiationModel, aux::Vars, state::Vars, t::Real) end
function integral_set_aux!(::RadiationModel, integ::Vars, state::Vars, aux::Vars) end
function integral_load_aux!(::RadiationModel, aux::Vars, integ::Vars) end
function reverse_integral_set_aux!(::RadiationModel, integ::Vars, state::Vars, aux::Vars) end
function reverse_integral_load_aux!(::RadiationModel, aux::Vars, integ::Vars) end
function flux_radiation!(::RadiationModel, atmos::AtmosModel, flux::Grad, state::Vars, aux::Vars, t::Real) end

struct NoRadiation <: RadiationModel
end

max_stars_repo_name: favba/CLIMA

max_issues_repo_name: favba/CLIMA

max_forks_repo_name: favba/CLIMA


text:
module GrayUtils

using CUDA
using ..Device: array_type, array_device, CUDADevice, CPU
using ..AtmosphericStates
using ..Fluxes

import ..Parameters as RP

export update_profile_lw!, compute_gray_heating_rate!

"""
    update_profile_lw!(
        param_set,
        t_lay,
        t_lev,
        flux_dn,
        flux_net,
        hr_lay,
        flux_grad,
        T_ex_lev,
        Δt,
        nlay,
        nlev,
        ncol,
        ::Type{FT},
    )

Updates t_lay and t_lev based on heating rate.
"""
function update_profile_lw!(
    param_set,
    t_lay,
    t_lev,
    flux_dn,
    flux_net,
    hr_lay,
    flux_grad,
    T_ex_lev,
    Δt,
    nlay,
    nlev,
    ncol,
    ::Type{FT},
) where {FT <: AbstractFloat}
    # updating t_lay and t_lev based on heating rate
    args = (t_lay, t_lev, hr_lay, flux_dn, flux_net, flux_grad, T_ex_lev, Δt, nlay, nlev)
    device = array_device(t_lev)
    if device === CUDADevice()
        max_threads = 256
        tx = min(ncol, max_threads)
        bx = cld(ncol, tx)
        @cuda threads = (tx) blocks = (bx) update_profile_lw_CUDA!(param_set, ncol, args...)
    else
        # using julia native multithreading
        Threads.@threads for gcol in 1:ncol
            update_profile_lw_kernel!(param_set, args..., gcol)
        end
    end
    #----------------------------------------
end

function update_profile_lw_CUDA!(param_set::RP.ARP, ncol, args...)
    gcol = threadIdx().x + (blockIdx().x - 1) * blockDim().x # global id
    if gcol ≤ ncol
        update_profile_lw_kernel!(param_set, args..., gcol)
    end
    return nothing
end

function update_profile_lw_kernel!(
    param_set::RP.ARP,
    t_lay,
    t_lev,
    hr_lay,
    flux_dn,
    flux_net,
    flux_grad,
    T_ex_lev,
    Δt::FT,
    nlay,
    nlev,
    gcol,
) where {FT <: AbstractFloat}
    # updating t_lay based on heating rate
    for glay in 1:nlay
        @inbounds t_lay[glay, gcol] += Δt * hr_lay[glay, gcol]
    end
    #--------compute t_lev from t_lay--------------------------------------
    for glev in 2:(nlay - 1)
        @inbounds t_lev[glev, gcol] =
            FT(1 / 3) * t_lay[glev - 1, gcol] + FT(5 / 6) * t_lay[glev, gcol] - FT(1 / 6) * t_lay[glev + 1, gcol]
    end

    @inbounds t_lev[nlay, gcol] =
        FT(1 / 3) * t_lay[nlay, gcol] + FT(5 / 6) * t_lay[nlay - 1, gcol] - FT(1 / 6) * t_lay[nlay - 2, gcol]

    @inbounds t_lev[1, gcol] = FT(2) * t_lay[1, gcol] - t_lev[2, gcol]

    @inbounds t_lev[nlay + 1, gcol] = FT(2) * t_lay[nlay, gcol] - t_lev[nlay, gcol]
    #-----------------------------------------------------------------------
    sbc = FT(RP.Stefan(param_set))
    for glev in 1:nlev
        @inbounds T_ex_lev[glev, gcol] = ((flux_dn[glev, gcol] + (flux_net[glev, gcol] / FT(2))) / sbc)^FT(0.25)
    end

    for glev in 2:nlev
        @inbounds flux_grad[glev - 1, gcol] = abs(flux_net[glev, gcol] - flux_net[glev - 1, gcol])
    end
    #-----------------------------------------------------------------------
end

"""
    compute_gray_heating_rate!(
        hr_lay,
        p_lev,
        ncol,
        nlay,
        flux_net,
        param_set,
        ::Type{FT},
    )

Computes the heating rate for the gray radiation simulation.
"""
function compute_gray_heating_rate!(hr_lay, p_lev, ncol, nlay, flux_net, param_set, ::Type{FT}) where {FT}
    cp_d_ = FT(RP.cp_d(param_set))
    grav_ = FT(RP.grav(param_set))
    args = (hr_lay, flux_net, p_lev, grav_, cp_d_, nlay)
    device = array_device(p_lev)
    if device === CUDADevice()
        max_threads = 256
        tx = min(ncol, max_threads)
        bx = cld(ncol, tx)
        @cuda threads = (tx) blocks = (bx) compute_gray_heating_rate_CUDA!(ncol, args...)
    else
        # Launcing native Julia multithreading Kernel
        Threads.@threads for gcol in 1:ncol
            compute_gray_heating_rate_kernel!(args..., gcol)
        end
    end
    return nothing
end

function compute_gray_heating_rate_CUDA!(ncol, args...)
    gcol = threadIdx().x + (blockIdx().x - 1) * blockDim().x # global id
    if gcol ≤ ncol
        compute_gray_heating_rate_kernel!(args..., gcol)
    end
    return nothing
end

function compute_gray_heating_rate_kernel!(hr_lay, flux_net, p_lev, grav_, cp_d_, nlay, gcol)
    for ilay in 1:nlay
        @inbounds hr_lay[ilay, gcol] =
            grav_ * (flux_net[ilay + 1, gcol] - flux_net[ilay, gcol]) / (p_lev[ilay + 1, gcol] - p_lev[ilay, gcol]) /
            cp_d_
    end
    return nothing
end
end

max_stars_repo_name: climate-machine/JRRTMGP

max_issues_repo_name: climate-machine/JRRTMGP

max_forks_repo_name: climate-machine/JRRTMGP


text:
const COMPATHELPER_GIT_COMMITTER_NAME = "CompatHelper Julia"
const COMPATHELPER_GIT_COMMITTER_EMAIL = "compathelper_noreply@julialang.org"

git_add() = run(`git add -A .`)
git_checkout(branch::AbstractString) = run(`git checkout $branch`)

function get_git_name_and_email(; env=ENV)
    name = if haskey(env, "GIT_COMMITTER_NAME")
        env["GIT_COMMITTER_NAME"]
    else
        COMPATHELPER_GIT_COMMITTER_NAME
    end

    email = if haskey(env, "GIT_COMMITTER_EMAIL")
        env["GIT_COMMITTER_EMAIL"]
    else
        COMPATHELPER_GIT_COMMITTER_EMAIL
    end

    return name, email
end

function git_push(
    remote::AbstractString,
    branch::AbstractString,
    pkey_filename::Union{AbstractString,Nothing}=nothing;
    force=false,
    env=ENV,
)
    force_flag = force ? ["-f"] : []
    name, email = get_git_name_and_email(; env=env)

    withenv(
        "GIT_SSH_COMMAND" => isnothing(pkey_filename) ? "ssh" : "ssh -i $pkey_filename"
    ) do
        run(
            `git -c user.name="$name" -c user.email="$email" -c committer.name="$name" -c committer.email="$email" push $force_flag $remote $branch`,
        )
    end

    return nothing
end

function git_commit(message::AbstractString=""; env=ENV)
    name, email = get_git_name_and_email(; env=env)
    cmd = `git -c user.name="$name" -c user.email="$email" commit -m $message`

    result = try
        p = pipeline(cmd; stdout=stdout, stderr=stderr)
        success(p)
    catch
        false
    end

    return result
end

function git_branch(branch::AbstractString; checkout=false)
    run(`git branch $branch`)
    checkout && git_checkout(branch)

    return nothing
end

function git_clone(
    url::AbstractString,
    local_path::AbstractString,
    pkey_filename::Union{AbstractString,Nothing}=nothing,
)
    withenv(
        "GIT_SSH_COMMAND" => isnothing(pkey_filename) ? "ssh" : "ssh -i $pkey_filename"
    ) do
        @mock run(`git clone $url $local_path`)
    end

    return nothing
end

function git_get_master_branch(master_branch::DefaultBranch)
    return string(strip(read(`git rev-parse --abbrev-ref HEAD`, String)))
end
git_get_master_branch(master_branch::AbstractString) = master_branch


text:
module IterativeLinearSolvers

# Included from https://github.com/andreasnoack/IterativeLinearSolvers.jl
# Eventually, use IterativeSolvers.jl

typealias Preconditioner{T} Union{AbstractMatrix{T}, Factorization{T}}

function cg{T<:LinAlg.BlasReal}(A::AbstractMatrix{T},
    x::AbstractVector{T},
    b::AbstractVector{T},
    M::Preconditioner{T},
    max_it::Integer,
    tol::Real)
#  -- Iterative template routine --
#     Univ. of Tennessee and Oak Ridge National Laboratory
#     October 1, 1993
#     Details of this algorithm are described in "Templates for the
#     Solution of Linear Systems: Building Blocks for Iterative
#     Methods", Barrett, Berry, Chan, Demmel, Donato, Dongarra,
#     Eijkhout, Pozo, Romine, and van der Vorst, SIAM Publications,
#     1993. (ftp netlib2.cs.utk.edu; cd linalg; get templates.ps).
#
#  [x, error, iter, flag] = cg(A, x, b, M, max_it, tol)
#
# cg.m solves the symmetric positive definite linear system Ax=b
# using the Conjugate Gradient method with preconditioning.
#
# input   A        REAL symmetric positive definite matrix
#         x        REAL initial guess vector
#         b        REAL right hand side vector
#         M        REAL preconditioner matrix
#         max_it   INTEGER maximum number of iterations
#         tol      REAL error tolerance
#
# output  x        REAL solution vector
#         error    REAL error norm
#         iter     INTEGER number of iterations performed
#         flag     INTEGER: 0 = solution found to tolerance
#                           1 = no convergence given max_it

    n = length(b)
    flag = 0                                 # initialization
    iter = 0

    bnrm2 = norm(b)
    if bnrm2 == 0.0 bnrm2 = one(T) end

    local ρ₁
    z = zeros(T, n)
    q = zeros(T, n)
    p = zeros(T, n)
    # r = copy(b)
    # A_mul_B!(-one(T),A,x,one(T),r)
    r = b - A*x
    error = norm(r)/bnrm2
    if error < tol
        return
    end

    for iter = 1:max_it                       # begin iteration

        z[:] = r
        A_ldiv_B!(M, z)
        # z[:] = M\r
        ρ = dot(r,z)

        if iter > 1                       # direction vector
            β = ρ/ρ₁
            for l = 1:n
                p[l] = z[l] + β*p[l]
            end
        else
            p[:] = z
        end

        # A_mul_B!(one(T),A,p,zero(T),q)
        q[:] = A*p
        α = ρ / dot(p,q)
        for l = 1:n
            x[l] += α*p[l]                    # update approximation vector
            r[l] -= α*q[l]                    # compute residual
        end

        error = norm(r)/bnrm2                     # check convergence
        if error <= tol break end

        ρ₁ = ρ

    end

    if error > tol flag = 1 end                 # no convergence
    return x, error, iter, flag
end

function cgs{T<:Number}(A::AbstractMatrix{T},
    x::AbstractVector{T},
    b::AbstractVector{T},
    M::Preconditioner{T},
    max_it::Integer,
    tol::Real)
#  -- Iterative template routine --
#     Univ. of Tennessee and Oak Ridge National Laboratory
#     October 1, 1993
#     Details of this algorithm are described in "Templates for the
#     Solution of Linear Systems: Building Blocks for Iterative
#     Methods", Barrett, Berry, Chan, Demmel, Donato, Dongarra,
#     Eijkhout, Pozo, Romine, and van der Vorst, SIAM Publications,
#     1993. (ftp netlib2.cs.utk.edu; cd linalg; get templates.ps).
#
#  [x, error, iter, flag] = cgs(A, x, b, M, max_it, tol)
#
# cgs.m solves the linear system Ax=b using the
# Conjugate Gradient Squared Method with preconditioning.
#
# input   A        REAL matrix
#         x        REAL initial guess vector
#         b        REAL right hand side vector
#         M        REAL preconditioner
#         max_it   INTEGER maximum number of iterations
#         tol      REAL error tolerance
#
# output  x        REAL solution vector
#         error    REAL error norm
#         iter     INTEGER number of iterations performed
#         flag     INTEGER: 0 = solution found to tolerance
#                           1 = no convergence given max_it

    iter = 0                               # initialization
    flag = 0

    n = length(b)
    bnrm2 = norm(b)
    if bnrm2 == 0
        bnrm2 = one(bnrm2)
    end

    u = zeros(T, n)
    p = zeros(T, n)
    p̂ = zeros(T, n)
    q = zeros(T, n)
    û = zeros(T, n)
    v̂ = zeros(T, n)
    ρ = zero(T)
    ρ₁ = ρ
    r = copy(b)
    A_mul_B!(-one(T), A, x, one(T), r)
    # r = b - A*x
    error = norm(r)/bnrm2

    if error < tol
        return x, error, iter, flag
    end

    r_tld = copy(r)

    for iter = 1:max_it                      # begin iteration

        ρ = dot(r_tld, r)
        if ρ == 0
            break
        end

        if iter > 1                          # direction vectors
            β = ρ/ρ₁
            for l = 1:n
                u[l] = r[l] + β*q[l]
                p[l] = u[l] + β*(q[l] + β*p[l])
            end
        else
            u[:] = r
            p[:] = u
        end

        p̂[:] = p
        A_ldiv_B!(M, p̂)
        # p̂[:] = M\p
        A_mul_B!(one(T), A, p̂, zero(T), v̂)  # adjusting scalars
        # v̂[:] = A*p̂
        α = ρ/dot(r_tld, v̂)
        for l = 1:n
            q[l] = u[l] - α*v̂[l]
            û[l] = u[l] + q[l]
        end
        A_ldiv_B!(M, û)
        # û[:] = M\û

        for l = 1:n
            x[l] += α*û[l]                  # update approximation
        end

        A_mul_B!(-α, A, û, one(T), r)
        # r[:] -= α*(A*û)
        error = norm(r)/bnrm2               # check convergence
        if error <= tol
            break
        end

        ρ₁ = ρ

    end

    if error <= tol                         # converged
        flag = 0
    elseif ρ == 0                           # breakdown
        flag = -1
    else                                    # no convergence
        flag = 1
    end
    return x, error, iter, flag
end

end


text:
function has_empty_paths(solution::Solution)
    return any(length(path) == 0 for path in solution)
end

function is_feasible(solution::Solution, mapf::MAPF)
    g = mapf.graph
    for a in 1:nb_agents(mapf)
        s = mapf.sources[a]
        d = mapf.destinations[a]
        t0 = mapf.starting_times[a]
        path = solution[a]
        if length(path) == 0
            return false
        elseif path[1] != (t0, s)
            return false
        elseif path[end][2] != d
            return false
        else
            for k in 1:(length(path) - 1)
                (t1, v1), (t2, v2) = path[k], path[k + 1]
                if t2 != t1 + 1
                    return false
                elseif !has_edge(g, v1, v2)
                    return false
                end
            end
        end
    end
    return !conflict_exists(solution, mapf)
end

function path_weight(path::Path, mapf::MAPF; edge_weights=mapf.edge_weights)
    edge_indices = mapf.edge_indices
    c = 0.
    for k in 1:(length(path) - 1)
        (_, v1), (_, v2) = path[k], path[k + 1]
        c += edge_weights[edge_indices[v1, v2]]
    end
    return c
end

function flowtime(solution::Solution, mapf::MAPF; edge_weights=mapf.edge_weights)
    return sum(path_weight(path, mapf; edge_weights=edge_weights) for path in solution)
end

is_feasible(::Nothing, ::MAPF; kwargs...) = false
flowtime(::Nothing, ::MAPF; kwargs...) = Inf

max_time(path::Path) = maximum(t for (t, v) in path)
max_time(solution::Solution) = maximum(max_time(path) for path in solution)


text:
module Util

export cattype

cattype(::Type{F}, ::Type{Tuple{T1}}) where {F, T1} = Tuple{F, T1}
cattype(::Type{F}, ::Type{Tuple{T1, T2}}) where {F, T1, T2} = Tuple{F, T1, T2}
cattype(::Type{F}, ::Type{Tuple{T1, T2, T3}}) where {F, T1, T2, T3} = Tuple{F, T1, T2, T3}
cattype(::Type{F}, ::Type{Tuple{T1, T2, T3, T4}}) where {F, T1, T2, T3, T4} = Tuple{F, T1, T2, T3, T4}
# cattype(::Type{F}, ::Type{NTuple{N, T}}) where {F, N, T} = Tuple{F, T1, T2, T3}

end


text:
using VsRecorder.Scenes: TeamPreview, TeamPreviewSelecting

function test_result(parsed::TeamPreview, expected::TeamPreview)
    for field in fieldnames(TeamPreview)
        a = getfield(parsed, field)
        b = getfield(expected, field)
        if field ≡ :team_a
            a = [a[i] for i in 1:6 if i != expected.uncertain]
            b = [b[i] for i in 1:6 if i != expected.uncertain]
        end
        @test a == b
    end
end

@testset "Team Preview" begin
    ctx = VsRecorder.default_context()

    expected1 = TeamPreview(
        0.0,
        ["corviknight", "dragapult", "arcanine", "tyranitar-old", "gastrodon-east", "grimmsnarl"],
        0,
        ["charizard", "sableye", "rhyperior", "torkoal", "gastrodon-east", "heliolisk"],
        [GENDER_FEMALE, GENDER_FEMALE, GENDER_MALE, GENDER_MALE, GENDER_FEMALE, GENDER_MALE],
        [GENDER_MALE, GENDER_MALE, GENDER_MALE, GENDER_FEMALE, GENDER_FEMALE, GENDER_MALE],
        [50, 50, 50, 50, 50, 50],
        [50, 50, 50, 50, 50, 50],
        ["leftovers", "life-orb", "mago-berry", "weakness-policy", "sitrus-berry", "iapapa-berry"],
        [],
        "露露", "Zoe"
    )
    frame1 = VsFrame(image = VsRecorder.load_data("scenes", "zhs", "team-preview.png"))
    parsed1 = vs_tryparse_scene(TeamPreview, frame1, ctx)
    test_result(parsed1, expected1)

    expected2 = TeamPreview(
        0.0,
        # The first pokemon is expected to be wrong.
        ["wishiwashi", "kingdra", "shedinja", "zacian", "indeedee-f", "landorus-therian"],
        1,
        ["mamoswine", "indeedee-f", "zamazenta", "ho-oh", "landorus-therian", "gastrodon-east"],
        [GENDER_NULL, GENDER_FEMALE, GENDER_NULL, GENDER_NULL, GENDER_FEMALE, GENDER_MALE],
        [GENDER_MALE, GENDER_FEMALE, GENDER_NULL, GENDER_NULL, GENDER_MALE, GENDER_MALE],
        [50, 50, 50, 50, 50, 50],
        [50, 50, 50, 50, 50, 50],
        ["choice-scarf", "life-orb", "focus-sash", "rusted-sword", "psychic-seed", "white-herb"],
        [175, 151, 1, 189, 177, 165],
        "", "あかつき"
    )
    frame2 = VsFrame(image = VsRecorder.load_data("scenes", "zhs", "team-preview-selecting.png"))
    parsed2 = vs_tryparse_scene(TeamPreviewSelecting, frame2, ctx)
    @test typeof(parsed2) ≡ TeamPreview
    test_result(parsed2, expected2)
end


text:
struct Dogleg end

function (dl::Dogleg)(state, B, Δ)
    p = similar(state.x)
    ∇f = state.∇f
    norm_∇f = norm(∇f)
    prod = ∇f' * B * ∇f
    pᶜ = -norm_∇f^2 / prod*∇f
    norm_pᶜ = norm(pᶜ)
    if Δ ≤ norm_pᶜ
        p .= Δ / norm_pᶜ * pᶜ
    else
        isposdef(B) || error("Dogleg method only works for positive definite B")
        pᴮ = -inv(B)*∇f
        norm_pᴮ = norm(pᴮ)
        if Δ ≥ norm_pᴮ
            p .= pᴮ
        else
            pᴮpᶜ = pᴮ⋅pᶜ
            norm_pᴮ = norm_pᴮ
            r = (norm_pᴮ^2 - pᴮpᶜ) / (norm_pᶜ^2 + norm_pᴮ^2 - 2pᴮpᶜ)
            @. p = r*pᶜ + (1-r)*pᴮ
        end
    end
    return p
end


text:
using SatelliteDynamics

# Update All data
download_all_data()


text:
# Note that this script can accept some limited command-line arguments, run
# `julia build_tarballs.jl --help` to see a usage message.
using BinaryBuilder, Pkg

name = "TinyXML"
version = v"2.6.2"

# Collection of sources required to complete build
sources = [
    ArchiveSource("https://downloads.sourceforge.net/project/tinyxml/tinyxml/$(version)/tinyxml_$(version.major)_$(version.minor)_$(version.patch).tar.gz",
                  "15bdfdcec58a7da30adc87ac2b078e4417dbe5392f3afb719f9ba6d062645593"),
]

# Bash recipe for building across all platforms
script = raw"""
cd $WORKSPACE/srcdir/tinyxml

CPPFLAGS="-DTIXML_USE_STL"
CXXFLAGS="-fPIC -Wall -Wno-unknown-pragmas -Wno-format -O3"
c++ -c "${CPPFLAGS}" ${CXXFLAGS} tinyxml.cpp -o tinyxml.o
c++ -c "${CPPFLAGS}" ${CXXFLAGS} tinyxmlparser.cpp -o tinyxmlparser.o
c++ -c "${CPPFLAGS}" ${CXXFLAGS} tinyxmlerror.cpp -o tinyxmlerror.o
c++ -c "${CPPFLAGS}" ${CXXFLAGS} tinystr.cpp -o tinystr.o
mkdir -p "${libdir}"
c++ -shared -o "${libdir}/libtinyxml.${dlext}" tinyxml.o tinyxmlparser.o tinyxmlerror.o tinystr.o

mkdir -p "${includedir}"
cp *.h "${includedir}/."

install_license readme.txt
"""

# These are the platforms we will build for by default, unless further
# platforms are passed in on the command line
platforms = expand_cxxstring_abis(supported_platforms(; experimental=true))

# The products that we will ensure are always built
products = [
    LibraryProduct("libtinyxml", :libtinyxml),
]

# Dependencies that must be installed before this package can be built
dependencies = Dependency[
]

# Build the tarballs, and possibly a `build.jl` as well.
build_tarballs(ARGS, name, version, sources, script, platforms, products, dependencies; julia_compat="1.6")

max_stars_repo_name: sharanry/Yggdrasil

max_issues_repo_name: sharanry/Yggdrasil

max_forks_repo_name: sharanry/Yggdrasil


text:
## --------------------------------------------------------------------
using ProjAssistant
quickactivate(@__DIR__, "Chemostat_Rath2017")

## --------------------------------------------------------------------
import Chemostat_Rath2017
const ChR = Chemostat_Rath2017
const H1 = ChR.Human1

## --------------------------------------------------------------------
const ZENODO_DOWNLOAD_LINK = "https://zenodo.org/record/3583004/files/Human1_Publication_Data_Scripts.zip"

cd(rawdir(H1))
println("Now at: ", pwd())

const DEST_DIT = rawdir(H1, "Human1_Publication_Data_Scripts")
const ZIP_FILE_NAME = "Human1_Publication_Data_Scripts.zip"
if isdir(DEST_DIT)
    println(relpath(DEST_DIT), " already exist, to force a re-unzip delete the folder")
elseif isfile(ZIP_FILE_NAME)
    println(relpath(ZIP_FILE_NAME), " already exist, to force a re-download delete it")
    run(`unzip $ZIP_FILE_NAME`)
else
    println("Downloading using curl ...")
    run(`curl $(ZENODO_DOWNLOAD_LINK) --output $(ZIP_FILE_NAME)`)
    run(`unzip $(ZIP_FILE_NAME)`)
end
!isdir(DEST_DIT) &&
    error("$(DEST_DIT) not found after download && unzip!!!")
println(relpath(DEST_DIT), " ready!!!")
flush(stdout)
flush(stderr)


text:
function sherman_morrison(Vinv, u, v)
    num = (Vinv*u)*transpose(transpose(Vinv)*v)
    denum = 1 + transpose(v)*Vinv*u
    return Vinv .- num / denum
end
function sherman_morrison(Vinv, u)
    Vinv_u = Vinv*u
    num = Vinv_u*transpose(Vinv_u)
    denum = 1 + transpose(u)*Vinv_u
    return Vinv .- num / denum
end

function build_gaps(arms)
    gaps = Vector{Float64}[]
    for pair in subsets(arms, 2)
        gap1 = pair[1] - pair[2]
        push!(gaps, gap1)
        gap2 = pair[2] - pair[1]
        push!(gaps, gap2)
        #@show pair
    end
    return gaps
end

struct LinearBestArm
    expfam; # common exponential family
    arms;  # array of size K of arms in R^d
end

nanswers(pep::LinearBestArm, μ) = length(pep.arms);
narms(pep::LinearBestArm, µ) = length(pep.arms);
istar(pep::LinearBestArm, μ) = argmax([arm'µ for arm in pep.arms]);
armstar(pep::LinearBestArm, μ) = pep.arms[argmax([arm'µ for arm in pep.arms])];
getexpfam(pep::LinearBestArm, k) = pep.expfam;

function alt_min(pep::LinearBestArm, w, µ, k)
    #TODO: this function assumes that expfam is Gaussian(1)
    #println("alt_min for k=$k, w=$w and µ=$µ")
    sum_w = sum(w)
    #if sum_w < 1e-10
    #    return 0, µ, k
    #end
    w = w/sum(w)  # avoid dividing by small quantities
    #println("w : $w")
    arm = pep.arms[k]
    arm_star = armstar(pep, µ)
    @assert arm != arm_star
    K = length(pep.arms)
    direction = arm .- arm_star
    #println("dir $direction")
    d = length(direction)
    # Construction of the matrix V = (sum_k w_k a_k a_k^T)^{-1}
    sum_arms_matrix = zeros(d,d)
    for j in 1:K
        sum_arms_matrix .+= w[j].* (pep.arms[j]*transpose(pep.arms[j]))
    end
    Vinv = inv(sum_arms_matrix)
    #println("Vinv $Vinv")
    # Closest point
    η = sum_w * (direction'µ) / ((direction')*Vinv*direction)
    #println("η $η; sum_w $sum_w")
    λ = µ .- η/sum_w * Vinv * direction
    # Divergence to that point
    val = .5 * sum_w * (direction'µ)^2 / ((direction')*Vinv*direction)
    #println("k $k; val $val; λ $λ")
    return val, λ, k
end

function alt_min(pep::LinearBestArm, w, µ)
    minimum(alt_min(pep, w, µ, i) for i in 1:nanswers(pep, µ) if i != istar(pep, µ))
end

function glrt(pep::LinearBestArm, w::Vector, μ)
    #println("glrt vector")
    @assert length(size(μ)) == 1
    star = istar(pep, µ)
    val, λ, k = alt_min(pep, w, µ)
    #Return: distance to closest alternative, best arm and closest λ for that alternative, best arm and vector for closest point in model
    val, (k, λ), (star, μ);
end

function glrt(pep::LinearBestArm, P::Matrix, μ)
    #println("glrt matrix")
    # P is a matrix of size nb_answers*nb_arms (both of which may be different from length(µ)).
    # In the BAI case, nb_answers = nb_arms != length(µ)
    nb_answers = size(P)[1]
    @assert length(size(μ)) == 1
    val = 0
    λs = zeros(nb_answers, length(µ))  # nb_answers * length(µ0)
    star = istar(pep, µ)
    for i in 1:nb_answers
        if i != star
            λs[i, :] = copy(µ)  # µ belongs to ¬i
        else
            val_i, λ_i, _ = alt_min(pep, P[i,:], µ)
            #println("i $i ; val_i $val_i ; λ_i $λ_i")
            λs[i, :] = λ_i
            val += val_i
        end
    end

    val, λs, (star, μ);
end

# oracle problem
function oracle(pep::LinearBestArm, μ)
    throw("Unimplemented")
end

# oracle problem for best μ in confidence interval
function optimistic_oracle(pep::LinearBestArm, hμ, N)
    throw("Unimplemented")
end

struct LinearThreshold
    expfam; # common exponential family
    arms;  # array of size K of arms in R^d
    τ;  # threshold
end

nanswers(pep::LinearThreshold, μ) = 2^length(µ);
narms(pep::LinearThreshold, µ) = length(pep.arms);
istar(pep::LinearThreshold, μ) = 1 + sum([(µ[k] > pep.τ) * 2^(k-1) for k in 1:length(µ)]);
getexpfam(pep::LinearThreshold, k) = pep.expfam;

function alt_min(pep::LinearThreshold, w, µ, k)
    #TODO: this functions assumes that expfam is Gaussian(1)
    #println("alt_min for k=$k, w=$w and µ=$µ")
    sum_w = sum(w)
    w = w/sum(w)  # avoid dividing by small quantities
    #println("w : $w")
    K = narms(pep, µ)
    # Construction of the matrix V = (sum_k w_k a_k a_k^T)^{-1}
    sum_arms_matrix = zeros(length(µ),length(µ))
    for j in 1:K
        sum_arms_matrix .+= w[j].* (pep.arms[j]*transpose(pep.arms[j]))
    end
    Vinv = inv(sum_arms_matrix)
    #println("Vinv=$Vinv")
    # Closest point
    η = (µ[k] - pep.τ) / Vinv[k,k]
    #println("η $η; sum_w $sum_w")
    λ = µ .- η * Vinv[:,k]
    # Divergence to that point
    val = .5 * sum_w * (µ[k] - pep.τ)^2 / Vinv[k,k]
    #println("k $k; val $val; λ $λ")
    return val, λ, k
end

function alt_min(pep::LinearThreshold, w, µ)
    minimum(alt_min(pep, w, µ, i) for i in 1:length(µ))
end

function glrt(pep::LinearThreshold, w::Vector, μ)
    #println("glrt vector")
    @assert length(size(μ)) == 1
    star = istar(pep, µ)
    val, λ, k = alt_min(pep, w, µ)
    answer = star
    if µ[k]>pep.τ
        answer -= 2^(k-1)
    else
        answer += 2^(k-1)
    end
    #Return: distance to closest alternative, answer and closest λ for that alternative, answer and vector for closest point in model
    val, (answer, λ), (star, μ);
end

function glrt(pep::LinearThreshold, P::Matrix, μ)
    #println("glrt matrix")
    # P is a matrix of size nb_answers*nb_arms (both of which may be different from length(µ)).
    # In the BAI case, nb_answers = nb_arms != length(µ)
    nb_answers = nanswers(pep, µ)
    @assert length(size(μ)) == 1
    val = 0
    λs = zeros(nb_answers, length(µ))
    star = istar(pep, µ)
    for i in 1:nb_answers
        if i != star
            λs[i, :] = copy(µ)  # µ belongs to ¬i
        else
            val_i, λ_i, _ = alt_min(pep, P[i,:], µ)
            #println("i $i ; val_i $val_i ; λ_i $λ_i")
            λs[i, :] = λ_i
            val += val_i
        end
    end

    val, λs, (star, μ);
end

# oracle problem
function oracle(pep::LinearThreshold, μ)
    throw("Unimplemented")
end

# oracle problem for best μ in confidence interval
function optimistic_oracle(pep::LinearThreshold, hμ, N)
    throw("Unimplemented")
end


text:
export add_cookie,back,close,create_web_element,delete_all_cookies,delete_cookie,execute,execute_async_script,execute_script,file_detector_context,find_element,find_element_by_class_name,find_element_by_css_selector,find_element_by_id,find_element_by_link_text,find_element_by_name,find_element_by_partial_link_text,find_element_by_tag_name,find_element_by_xpath,find_elements,find_elements_by_class_name,find_elements_by_css_selector,find_elements_by_id,find_elements_by_link_text,find_elements_by_name,find_elements_by_partial_link_text,find_elements_by_tag_name,find_elements_by_xpath,forward,get,get_cookie,get_cookies,get_log,get_screenshot_as_base64,get_screenshot_as_file,get_screenshot_as_png,get_window_position,get_window_size,implicitly_wait,maximize_window,quit,refresh,save_screenshot,set_page_load_timeout,set_script_timeout,set_window_position,set_window_size,start_client,start_session,stop_client,switch_to_active_element,switch_to_alert,switch_to_default_content,switch_to_frame,switch_to_window,application_cache,current_url,current_window_handle,desired_capabilities,file_detector,log_types,mobile,name,orientation,page_source,switch_to,title,window_handles

"""
Adds a cookie to your current session.
Args:
cookie_dict: A dictionary object, with required keys - "name" and "value";
optional keys - "path", "domain", "secure", "expiry"
Usage:
driver.add_cookie({"name" : "foo", "value" : "bar"}) driver.add_cookie({"name" : "foo", "value" : "bar", "path" : "/"}) driver.add_cookie({"name" : "foo", "value" : "bar", "path" : "/", "secure":True})
"""
add_cookie(driver::Driver, cookie_dict) = driver.o[:add_cookie](cookie_dict)

"""
Goes one step backward in the browser history.
Usage: driver.back()
"""
back(driver::Driver, ) = driver.o[:back]()

"""
Closes the current window.
Usage: driver.close()
"""
close(driver::Driver, ) = driver.o[:close]()

"""
Creates a web element with the specified element_id.
"""
create_web_element(driver::Driver, element_id) = driver.o[:create_web_element](element_id)

"""
Delete all cookies in the scope of the session.
Usage: driver.delete_all_cookies()
"""
delete_all_cookies(driver::Driver, ) = driver.o[:delete_all_cookies]()

"""
Deletes a single cookie with the given name.
Usage: driver.delete_cookie("my_cookie")
"""
delete_cookie(driver::Driver, name) = driver.o[:delete_cookie](name)

"""
Sends a command to be executed by a command.CommandExecutor.
Args:
driver_command: The name of the command to execute as a string.
params: A dictionary of named parameters to send with the command.
Returns:
The command"s JSON response loaded into a dictionary object.
"""
execute(driver::Driver, driver_command, params = nothing) = driver.o[:execute](driver_command, params)

"""
Asynchronously Executes JavaScript in the current window/frame.
Args:
script: The JavaScript to execute.
*args: Any applicable arguments for your JavaScript.
Usage:
driver.execute_async_script("document.title")
"""
execute_async_script(driver::Driver, script, args...) = driver.o[:execute_async_script](script, args...)

"""
Synchronously Executes JavaScript in the current window/frame.
Args:
script: The JavaScript to execute.
*args: Any applicable arguments for your JavaScript.
Usage:
driver.execute_script("document.title")
"""
execute_script(driver::Driver, script, args...) = driver.o[:execute_script](script, args...)

"""
Overrides the current file detector (if necessary) in limited context. Ensures the original file detector is set afterwards.
Example:
with webdriver.file_detector_context(UselessFileDetector):
someinput.send_keys("/etc/hosts")
Args:
file_detector_class - Class of the desired file detector. If the class is different
from the current file_detector, then the class is instantiated with args and kwargs and used as a file detector during the duration of the context manager.
args - Optional arguments that get passed to the file detector class during
instantiation.
kwargs - Keyword arguments, passed the same way as args.
"""
file_detector_context(driver::Driver, args..., ; kwds...) = driver.o[:file_detector_context](args..., ; kwds...)

"""
"Private" method used by the find_element_by_* methods.
Usage: Use the corresponding find_element_by_* instead of this.
Return type: WebElement
"""
find_element(driver::Driver, by = "id", value = nothing) = WebElement(driver.o[:find_element](by, value))

"""
Finds an element by class name.
Args:
name: The class name of the element to find.
Usage:
driver.find_element_by_class_name("foo")
"""
find_element_by_class_name(driver::Driver, name) = WebElement(driver.o[:find_element_by_class_name](name))

"""
Finds an element by css selector.
Args:
css_selector: The css selector to use when finding elements.
Usage:
driver.find_element_by_css_selector("#foo")
"""
find_element_by_css_selector(driver::Driver, css_selector) = WebElement(driver.o[:find_element_by_css_selector](css_selector))

"""
Finds an element by id.
Args:
id_ - The id of the element to be found.
Usage:
driver.find_element_by_id("foo")
"""
find_element_by_id(driver::Driver, id_) = WebElement(driver.o[:find_element_by_id](id_))

"""
Finds an element by link text.
Args:
link_text: The text of the element to be found.
Usage:
driver.find_element_by_link_text("Sign In")
"""
find_element_by_link_text(driver::Driver, link_text) = WebElement(driver.o[:find_element_by_link_text](link_text))

"""
Finds an element by name.
Args:
name: The name of the element to find.
Usage:
driver.find_element_by_name("foo")
"""
find_element_by_name(driver::Driver, name) = WebElement(driver.o[:find_element_by_name](name))

"""
Finds an element by a partial match of its link text.
Args:
link_text: The text of the element to partially match on.
Usage:
driver.find_element_by_partial_link_text("Sign")
"""
find_element_by_partial_link_text(driver::Driver, link_text) = WebElement(driver.o[:find_element_by_partial_link_text](link_text))

"""
Finds an element by tag name.
Args:
name: The tag name of the element to find.
Usage:
driver.find_element_by_tag_name("foo")
"""
find_element_by_tag_name(driver::Driver, name) = WebElement(driver.o[:find_element_by_tag_name](name))

"""
Finds an element by xpath.
Args:
xpath - The xpath locator of the element to find.
Usage:
driver.find_element_by_xpath("//div/td[1]")
"""
find_element_by_xpath(driver::Driver, xpath) = WebElement(driver.o[:find_element_by_xpath](xpath))

"""
"Private" method used by the find_elements_by_* methods.
Usage: Use the corresponding find_elements_by_* instead of this.
Return type: list of WebElement
"""
find_elements(driver::Driver, by = "id", value = nothing) = map(WebElement, driver.o[:find_elements](by, value))

"""
Finds elements by class name.
Args:
name: The class name of the elements to find.
Usage:
driver.find_elements_by_class_name("foo")
"""
find_elements_by_class_name(driver::Driver, name) = map(WebElement, driver.o[:find_elements_by_class_name](name))

"""
Finds elements by css selector.
Args:
css_selector: The css selector to use when finding elements.
Usage:
driver.find_elements_by_css_selector(".foo")
"""
find_elements_by_css_selector(driver::Driver, css_selector) = map(WebElement, driver.o[:find_elements_by_css_selector](css_selector))

"""
Finds multiple elements by id.
Args:
id_ - The id of the elements to be found.
Usage:
driver.find_elements_by_id("foo")
"""
find_elements_by_id(driver::Driver, id_) = map(WebElement, driver.o[:find_elements_by_id](id_))

"""
Finds elements by link text.
Args:
link_text: The text of the elements to be found.
Usage:
driver.find_elements_by_link_text("Sign In")
"""
find_elements_by_link_text(driver::Driver, text) = map(WebElement, driver.o[:find_elements_by_link_text](text))

"""
Finds elements by name.
Args:
name: The name of the elements to find.
Usage:
driver.find_elements_by_name("foo")
"""
find_elements_by_name(driver::Driver, name) = map(WebElement, driver.o[:find_elements_by_name](name))

"""
Finds elements by a partial match of their link text.
Args:
link_text: The text of the element to partial match on.
Usage:
driver.find_element_by_partial_link_text("Sign")
"""
find_elements_by_partial_link_text(driver::Driver, link_text) = map(WebElement, driver.o[:find_elements_by_partial_link_text](link_text))

"""
Finds elements by tag name.
Args:
name: The tag name the use when finding elements.
Usage:
driver.find_elements_by_tag_name("foo")
"""
find_elements_by_tag_name(driver::Driver, name) = map(WebElement, driver.o[:find_elements_by_tag_name](name))

"""
Finds multiple elements by xpath.
Args:
xpath - The xpath locator of the elements to be found.
Usage:
driver.find_elements_by_xpath("//div[contains(@class, "foo")]")
"""
find_elements_by_xpath(driver::Driver, xpath) = map(WebElement, driver.o[:find_elements_by_xpath](xpath))

"""
Goes one step forward in the browser history.
Usage: driver.forward()
"""
forward(driver::Driver, ) = driver.o[:forward]()

"""
Loads a web page in the current browser session.
"""
get(driver::Driver, url) = driver.o[:get](url)

"""
Get a single cookie by name. Returns the cookie if found, None if not.
Usage: driver.get_cookie("my_cookie")
"""
get_cookie(driver::Driver, name) = driver.o[:get_cookie](name)

"""
Returns a set of dictionaries, corresponding to cookies visible in the current session.
Usage: driver.get_cookies()
"""
get_cookies(driver::Driver, ) = driver.o[:get_cookies]()

"""
Gets the log for a given log type
Args:
log_type: type of log that which will be returned
Usage:
driver.get_log("browser") driver.get_log("driver") driver.get_log("client") driver.get_log("server")
"""
get_log(driver::Driver, log_type) = driver.o[:get_log](log_type)

"""
Gets the screenshot of the current window as a base64 encoded string
which is useful in embedded images in HTML.
Usage: driver.get_screenshot_as_base64()
"""
get_screenshot_as_base64(driver::Driver, ) = driver.o[:get_screenshot_as_base64]()

"""
Gets the screenshot of the current window. Returns False if there is
any IOError, else returns True. Use full paths in your filename.
Args:
filename: The full path you wish to save your screenshot to.
Usage:
driver.get_screenshot_as_file("/Screenshots/foo.png")
"""
get_screenshot_as_file(driver::Driver, filename) = driver.o[:get_screenshot_as_file](filename)

"""
Gets the screenshot of the current window as a binary data.
Usage: driver.get_screenshot_as_png()
"""
get_screenshot_as_png(driver::Driver, ) = driver.o[:get_screenshot_as_png]()

"""
Gets the x,y position of the current window.
Usage: driver.get_window_position()
"""
get_window_position(driver::Driver, windowHandle = "current") = driver.o[:get_window_position](windowHandle)

"""
Gets the width and height of the current window.
Usage: driver.get_window_size()
"""
get_window_size(driver::Driver, windowHandle = "current") = driver.o[:get_window_size](windowHandle)

"""
Sets a sticky timeout to implicitly wait for an element to be found,
or a command to complete. This method only needs to be called one time per session. To set the timeout for calls to execute_async_script, see set_script_timeout.
Args:
time_to_wait: Amount of time to wait (in seconds)
Usage:
driver.implicitly_wait(30)
"""
implicitly_wait(driver::Driver, time_to_wait) = driver.o[:implicitly_wait](time_to_wait)

"""
Maximizes the current window that webdriver is using
"""
maximize_window(driver::Driver, ) = driver.o[:maximize_window]()

"""
Quits the driver and closes every associated window.
Usage: driver.quit()
"""
quit(driver::Driver, ) = driver.o[:quit]()

"""
Refreshes the current page.
Usage: driver.refresh()
"""
refresh(driver::Driver, ) = driver.o[:refresh]()

"""
Gets the screenshot of the current window. Returns False if there is
any IOError, else returns True. Use full paths in your filename.
Args:
filename: The full path you wish to save your screenshot to.
Usage:
driver.get_screenshot_as_file("/Screenshots/foo.png")
"""
save_screenshot(driver::Driver, filename) = driver.o[:save_screenshot](filename)

"""
Set the amount of time to wait for a page load to complete
before throwing an error.
Args:
time_to_wait: The amount of time to wait
Usage:
driver.set_page_load_timeout(30)
"""
set_page_load_timeout(driver::Driver, time_to_wait) = driver.o[:set_page_load_timeout](time_to_wait)

"""
Set the amount of time that the script should wait during an
execute_async_script call before throwing an error.
Args:
time_to_wait: The amount of time to wait (in seconds)
Usage:
driver.set_script_timeout(30)
"""
set_script_timeout(driver::Driver, time_to_wait) = driver.o[:set_script_timeout](time_to_wait)

"""
Sets the x,y position of the current window. (window.moveTo)
Args:
x: the x-coordinate in pixels to set the window position
y: the y-coordinate in pixels to set the window position
Usage:
driver.set_window_position(0,0)
"""
set_window_position(driver::Driver, x, y, windowHandle = "current") = driver.o[:set_window_position](x, y, windowHandle)

"""
Sets the width and height of the current window. (window.resizeTo)
Args:
width: the width in pixels to set the window to
height: the height in pixels to set the window to
Usage:
driver.set_window_size(800,600)
"""
set_window_size(driver::Driver, width, height, windowHandle = "current") = driver.o[:set_window_size](width, height, windowHandle)

"""
Called before starting a new session. This method may be overridden to define custom startup behavior.
"""
start_client(driver::Driver, ) = driver.o[:start_client]()

"""
Creates a new session with the desired capabilities.
Args:
browser_name - The name of the browser to request.
version - Which browser version to request.
platform - Which platform to request the browser on.
javascript_enabled - Whether the new session should support JavaScript.
browser_profile - A selenium.webdriver.firefox.firefox_profile.FirefoxProfile object. Only used if Firefox is requested.
"""
start_session(driver::Driver, desired_capabilities, browser_profile = nothing) = driver.o[:start_session](desired_capabilities, browser_profile)

"""
Called after executing a quit command. This method may be overridden to define custom shutdown behavior.
"""
stop_client(driver::Driver, ) = driver.o[:stop_client]()

"""
Deprecated use driver.switch_to.active_element
"""
switch_to_active_element(driver::Driver, ) = driver.o[:switch_to_active_element]()

"""
Deprecated use driver.switch_to.alert
"""
switch_to_alert(driver::Driver, ) = driver.o[:switch_to_alert]()

"""
Deprecated use driver.switch_to.default_content
"""
switch_to_default_content(driver::Driver, ) = driver.o[:switch_to_default_content]()

"""
Deprecated use driver.switch_to.frame
"""
switch_to_frame(driver::Driver, frame_reference) = driver.o[:switch_to_frame](frame_reference)

"""
Deprecated use driver.switch_to.window
"""
switch_to_window(driver::Driver, window_name) = driver.o[:switch_to_window](window_name)

"""
Returns a ApplicationCache Object to interact with the browser app cache
"""
application_cache(driver::Driver, ) = driver.o[:application_cache]

"""
Gets the URL of the current page.
Usage: driver.current_url
"""
current_url(driver::Driver, ) = driver.o[:current_url]

"""
Returns the handle of the current window.
Usage: driver.current_window_handle
"""
current_window_handle(driver::Driver, ) = driver.o[:current_window_handle]

"""
returns the drivers current desired capabilities being used
"""
desired_capabilities(driver::Driver, ) = driver.o[:desired_capabilities]

"""

"""
file_detector(driver::Driver, ) = driver.o[:file_detector]

"""
Gets a list of the available log types
Usage: driver.log_types
"""
log_types(driver::Driver, ) = driver.o[:log_types]

"""

"""
mobile(driver::Driver, ) = driver.o[:mobile]

"""
Returns the name of the underlying browser for this instance.
Usage:
driver.name
"""
name(driver::Driver, ) = driver.o[:name]

"""
Gets the current orientation of the device
Usage: orientation = driver.orientation
"""
orientation(driver::Driver, ) = driver.o[:orientation]

"""
Gets the source of the current page.
Usage: driver.page_source
"""
page_source(driver::Driver, ) = driver.o[:page_source]

"""

"""
switch_to(driver::Driver, ) = driver.o[:switch_to]

"""
Returns the title of the current page.
Usage: driver.title
"""
title(driver::Driver, ) = driver.o[:title]

"""
Returns the handles of all windows within the current session.
Usage: driver.window_handles
"""
window_handles(driver::Driver, ) = driver.o[:window_handles]
export clear,click,find_element,find_element_by_class_name,find_element_by_css_selector,find_element_by_id,find_element_by_link_text,find_element_by_name,find_element_by_partial_link_text,find_element_by_tag_name,find_element_by_xpath,find_elements,find_elements_by_class_name,find_elements_by_css_selector,find_elements_by_id,find_elements_by_link_text,find_elements_by_name,find_elements_by_partial_link_text,find_elements_by_tag_name,find_elements_by_xpath,get_attribute,is_displayed,is_enabled,is_selected,screenshot,send_keys,submit,value_of_css_property,id,location,location_once_scrolled_into_view,parent,rect,screenshot_as_base64,screenshot_as_png,size,tag_name,text

"""
Clears the text if it"s a text entry element.
"""
clear(elem::WebElement, ) = elem.o[:clear]()

"""
Clicks the element.
"""
click(elem::WebElement, ) = elem.o[:click]()

"""

"""
find_element(elem::WebElement, by = "id", value = nothing) = WebElement(elem.o[:find_element](by, value))

"""
Finds element within this element"s children by class name.
Args:
name - class name to search for.
"""
find_element_by_class_name(elem::WebElement, name) = WebElement(elem.o[:find_element_by_class_name](name))

"""
Finds element within this element"s children by CSS selector.
Args:
css_selector - CSS selctor string, ex: "a.nav#home"
"""
find_element_by_css_selector(elem::WebElement, css_selector) = WebElement(elem.o[:find_element_by_css_selector](css_selector))

"""
Finds element within this element"s children by ID.
Args:
id_ - ID of child element to locate.
"""
find_element_by_id(elem::WebElement, id_) = WebElement(elem.o[:find_element_by_id](id_))

"""
Finds element within this element"s children by visible link text.
Args:
link_text - Link text string to search for.
"""
find_element_by_link_text(elem::WebElement, link_text) = WebElement(elem.o[:find_element_by_link_text](link_text))

"""
Finds element within this element"s children by name.
Args:
name - name property of the element to find.
"""
find_element_by_name(elem::WebElement, name) = WebElement(elem.o[:find_element_by_name](name))

"""
Finds element within this element"s children by partially visible link text.
Args:
link_text - Link text string to search for.
"""
find_element_by_partial_link_text(elem::WebElement, link_text) = WebElement(elem.o[:find_element_by_partial_link_text](link_text))

"""
Finds element within this element"s children by tag name.
Args:
name - name of html tag (eg: h1, a, span)
"""
find_element_by_tag_name(elem::WebElement, name) = WebElement(elem.o[:find_element_by_tag_name](name))

"""
Finds element by xpath.
Args: xpath - xpath of element to locate. "//input[@class="myelement"]"
Note: The base path will be relative to this element"s location.
This will select the first link under this element.
myelement.find_elements_by_xpath(".//a")
However, this will select the first link on the page.
myelement.find_elements_by_xpath("//a")
"""
find_element_by_xpath(elem::WebElement, xpath) = WebElement(elem.o[:find_element_by_xpath](xpath))

"""

"""
find_elements(elem::WebElement, by = "id", value = nothing) = map(WebElement, elem.o[:find_elements](by, value))

"""
Finds a list of elements within this element"s children by class name.
Args:
name - class name to search for.
"""
find_elements_by_class_name(elem::WebElement, name) = map(WebElement, elem.o[:find_elements_by_class_name](name))

"""
Finds a list of elements within this element"s children by CSS selector.
Args:
css_selector - CSS selctor string, ex: "a.nav#home"
"""
find_elements_by_css_selector(elem::WebElement, css_selector) = map(WebElement, elem.o[:find_elements_by_css_selector](css_selector))

"""
Finds a list of elements within this element"s children by ID.
Args:
id_ - Id of child element to find.
"""
find_elements_by_id(elem::WebElement, id_) = map(WebElement, elem.o[:find_elements_by_id](id_))

"""
Finds a list of elements within this element"s children by visible link text.
Args:
link_text - Link text string to search for.
"""
find_elements_by_link_text(elem::WebElement, link_text) = map(WebElement, elem.o[:find_elements_by_link_text](link_text))

"""
Finds a list of elements within this element"s children by name.
Args:
name - name property to search for.
"""
find_elements_by_name(elem::WebElement, name) = map(WebElement, elem.o[:find_elements_by_name](name))

"""
Finds a list of elements within this element"s children by link text.
Args:
link_text - Link text string to search for.
"""
find_elements_by_partial_link_text(elem::WebElement, link_text) = map(WebElement, elem.o[:find_elements_by_partial_link_text](link_text))

"""
Finds a list of elements within this element"s children by tag name.
Args:
name - name of html tag (eg: h1, a, span)
"""
find_elements_by_tag_name(elem::WebElement, name) = map(WebElement, elem.o[:find_elements_by_tag_name](name))

"""
Finds elements within the element by xpath.
Args:
xpath - xpath locator string.
Note: The base path will be relative to this element"s location.
This will select all links under this element.
myelement.find_elements_by_xpath(".//a")
However, this will select all links in the page itself.
myelement.find_elements_by_xpath("//a")
"""
find_elements_by_xpath(elem::WebElement, xpath) = map(WebElement, elem.o[:find_elements_by_xpath](xpath))

"""
Gets the given attribute or property of the element.
This method will first try to return the value of a property with the given name. If a property with that name doesn"t exist, it returns the value of the attribute with the same name. If there"s no attribute with that name, None is returned.
Values which are considered truthy, that is equals "true" or "false", are returned as booleans. All other non-None values are returned as strings. For attributes or properties which do not exist, None is returned.
Args:
name - Name of the attribute/property to retrieve.
Example:
# Check if the "active" CSS class is applied to an element.
is_active = "active" in target_element.get_attribute("class")
"""
get_attribute(elem::WebElement, name) = elem.o[:get_attribute](name)

"""
Whether the element is visible to a user.
"""
is_displayed(elem::WebElement, ) = elem.o[:is_displayed]()

"""
Returns whether the element is enabled.
"""
is_enabled(elem::WebElement, ) = elem.o[:is_enabled]()

"""
Returns whether the element is selected.
Can be used to check if a checkbox or radio button is selected.
"""
is_selected(elem::WebElement, ) = elem.o[:is_selected]()

"""
Gets the screenshot of the current element. Returns False if there is
any IOError, else returns True. Use full paths in your filename.
Args:
filename: The full path you wish to save your screenshot to.
Usage:
element.screenshot("/Screenshots/foo.png")
"""
screenshot(elem::WebElement, filename) = elem.o[:screenshot](filename)

"""
Simulates typing into the element.
Args:
value - A string for typing, or setting form fields. For setting
file inputs, this could be a local file path.
Use this to send simple key events or to fill out form fields:
form_textfield = driver.find_element_by_name("username")
form_textfield.send_keys("admin")
This can also be used to set file inputs.
file_input = driver.find_element_by_name("profilePic")
file_input.send_keys("path/to/profilepic.gif")
# Generally it"s better to wrap the file path in one of the methods
# in os.path to return the actual path to support cross OS testing.
# file_input.send_keys(os.path.abspath("path/to/profilepic.gif"))
"""
send_keys(elem::WebElement, value...) = elem.o[:send_keys](value...)

"""
Submits a form.
"""
submit(elem::WebElement, ) = elem.o[:submit]()

"""
The value of a CSS property.
"""
value_of_css_property(elem::WebElement, property_name) = elem.o[:value_of_css_property](property_name)

"""
Internal ID used by selenium.
This is mainly for internal use. Simple use cases such as checking if 2 webelements refer to the same element, can be done using ==:
if element1 == element2:
    print("These 2 are equal")
"""
id(elem::WebElement, ) = elem.o[:id]

"""
The location of the element in the renderable canvas.
"""
location(elem::WebElement, ) = elem.o[:location]

"""
THIS PROPERTY MAY CHANGE WITHOUT WARNING. Use this to discover where on the screen an element is so that we can click it. This method should cause the element to be scrolled into view.
Returns the top lefthand corner location on the screen, or None if the element is not visible.
"""
location_once_scrolled_into_view(elem::WebElement, ) = elem.o[:location_once_scrolled_into_view]

"""
Internal reference to the WebDriver instance this element was found from.
"""
parent(elem::WebElement, ) = elem.o[:parent]

"""
A dictionary with the size and location of the element.
"""
rect(elem::WebElement, ) = elem.o[:rect]

"""
Gets the screenshot of the current element as a base64 encoded string.
Usage: img_b64 = element.screenshot_as_base64
"""
screenshot_as_base64(elem::WebElement, ) = elem.o[:screenshot_as_base64]

"""
Gets the screenshot of the current element as a binary data.
Usage: element_png = element.screenshot_as_png
"""
screenshot_as_png(elem::WebElement, ) = elem.o[:screenshot_as_png]

"""
The size of the element.
"""
size(elem::WebElement, ) = elem.o[:size]

"""
This element"s tagName property.
"""
tag_name(elem::WebElement, ) = elem.o[:tag_name]

"""
The text of the element.
"""
text(elem::WebElement, ) = elem.o[:text]
export click,click_and_hold,context_click,double_click,drag_and_drop,drag_and_drop_by_offset,key_down,key_up,move_by_offset,move_to_element,move_to_element_with_offset,perform,release,send_keys,send_keys_to_element

"""
Clicks an element.
Args:
on_element: The element to click. If None, clicks on current mouse position.
"""
click(chain::ActionChain, on_element = nothing) = ActionChain(chain.o[:click](on_element))

click(on_element = nothing) = chain -> ActionChain(chain.o[:click](on_element))

"""
Holds down the left mouse button on an element.
Args:
on_element: The element to mouse down. If None, clicks on current mouse position.
"""
click_and_hold(chain::ActionChain, on_element = nothing) = ActionChain(chain.o[:click_and_hold](on_element))

click_and_hold(on_element = nothing) = chain -> ActionChain(chain.o[:click_and_hold](on_element))

"""
Performs a context-click (right click) on an element.
Args:
on_element: The element to context-click. If None, clicks on current mouse position.
"""
context_click(chain::ActionChain, on_element = nothing) = ActionChain(chain.o[:context_click](on_element))

context_click(on_element = nothing) = chain -> ActionChain(chain.o[:context_click](on_element))

"""
Double-clicks an element.
Args:
on_element: The element to double-click. If None, clicks on current mouse position.
"""
double_click(chain::ActionChain, on_element = nothing) = ActionChain(chain.o[:double_click](on_element))

double_click(on_element = nothing) = chain -> ActionChain(chain.o[:double_click](on_element))

"""
Holds down the left mouse button on the source element,
then moves to the target element and releases the mouse button.
Args:
source: The element to mouse down.
target: The element to mouse up.
"""
drag_and_drop(chain::ActionChain, source, target) = ActionChain(chain.o[:drag_and_drop](source, target))

drag_and_drop(source, target) = chain -> ActionChain(chain.o[:drag_and_drop](source, target))

"""
Holds down the left mouse button on the source element,
then moves to the target offset and releases the mouse button.
Args:
source: The element to mouse down.
xoffset: X offset to move to.
yoffset: Y offset to move to.
"""
drag_and_drop_by_offset(chain::ActionChain, source, xoffset, yoffset) = ActionChain(chain.o[:drag_and_drop_by_offset](source, xoffset, yoffset))

drag_and_drop_by_offset(source, xoffset, yoffset) = chain -> ActionChain(chain.o[:drag_and_drop_by_offset](source, xoffset, yoffset))

"""
Sends a key press only, without releasing it.
Should only be used with modifier keys (Control, Alt and Shift).
Args:
value: The modifier key to send. Values are defined in Keys class.
element: The element to send keys. If None, sends a key to current focused element.
Example, pressing ctrl+c:
ActionChains(driver).key_down(Keys.CONTROL).send_keys("c").key_up(Keys.CONTROL).perform()
"""
key_down(chain::ActionChain, value, element = nothing) = ActionChain(chain.o[:key_down](value, element))

key_down(value, element = nothing) = chain -> ActionChain(chain.o[:key_down](value, element))

"""
Releases a modifier key.
Args:
value: The modifier key to send. Values are defined in Keys class.
element: The element to send keys. If None, sends a key to current focused element.
Example, pressing ctrl+c:
ActionChains(driver).key_down(Keys.CONTROL).send_keys("c").key_up(Keys.CONTROL).perform()
"""
key_up(chain::ActionChain, value, element = nothing) = ActionChain(chain.o[:key_up](value, element))

key_up(value, element = nothing) = chain -> ActionChain(chain.o[:key_up](value, element))

"""
Moving the mouse to an offset from current mouse position.
Args:
xoffset: X offset to move to, as a positive or negative integer.
yoffset: Y offset to move to, as a positive or negative integer.
"""
move_by_offset(chain::ActionChain, xoffset, yoffset) = ActionChain(chain.o[:move_by_offset](xoffset, yoffset))

move_by_offset(xoffset, yoffset) = chain -> ActionChain(chain.o[:move_by_offset](xoffset, yoffset))

"""
Moving the mouse to the middle of an element.
Args:
to_element: The WebElement to move to.
"""
move_to_element(chain::ActionChain, to_element) = ActionChain(chain.o[:move_to_element](to_element))

move_to_element(to_element) = chain -> ActionChain(chain.o[:move_to_element](to_element))

"""
Move the mouse by an offset of the specified element.
Offsets are relative to the top-left corner of the element.
Args:
to_element: The WebElement to move to.
xoffset: X offset to move to.
yoffset: Y offset to move to.
"""
move_to_element_with_offset(chain::ActionChain, to_element, xoffset, yoffset) = ActionChain(chain.o[:move_to_element_with_offset](to_element, xoffset, yoffset))

move_to_element_with_offset(to_element, xoffset, yoffset) = chain -> ActionChain(chain.o[:move_to_element_with_offset](to_element, xoffset, yoffset))

"""
Performs all stored actions.
"""
perform(chain::ActionChain, ) = chain.o[:perform]()

perform() = chain -> chain.o[:perform]()

"""
Releasing a held mouse button on an element.
Args:
on_element: The element to mouse up. If None, releases on current mouse position.
"""
release(chain::ActionChain, on_element = nothing) = ActionChain(chain.o[:release](on_element))

release(on_element = nothing) = chain -> ActionChain(chain.o[:release](on_element))

"""
Sends keys to current focused element.
Args:
keys_to_send: The keys to send. Modifier keys constants can be found in the
"Keys" class.
"""
send_keys(chain::ActionChain, keys_to_send...) = ActionChain(chain.o[:send_keys](keys_to_send...))

send_keys(keys_to_send...) = chain -> ActionChain(chain.o[:send_keys](keys_to_send...))

"""
Sends keys to an element.
Args:
element: The element to send keys.
keys_to_send: The keys to send. Modifier keys constants can be found in the
"Keys" class.
"""
send_keys_to_element(chain::ActionChain, element, keys_to_send...) = ActionChain(chain.o[:send_keys_to_element](element, keys_to_send...))

send_keys_to_element(element, keys_to_send...) = chain -> ActionChain(chain.o[:send_keys_to_element](element, keys_to_send...))
export Keys
module Keys
using PyCall

export ADD,ALT,ARROW_DOWN,ARROW_LEFT,ARROW_RIGHT,ARROW_UP,BACKSPACE,BACK_SPACE,CANCEL,CLEAR,COMMAND,CONTROL,DECIMAL,DELETE,DIVIDE,DOWN,END,ENTER,EQUALS,ESCAPE,F1,F10,F11,F12,F2,F3,F4,F5,F6,F7,F8,F9,HELP,HOME,INSERT,LEFT,LEFT_ALT,LEFT_CONTROL,LEFT_SHIFT,META,MULTIPLY,NULL,NUMPAD0,NUMPAD1,NUMPAD2,NUMPAD3,NUMPAD4,NUMPAD5,NUMPAD6,NUMPAD7,NUMPAD8,NUMPAD9,PAGE_DOWN,PAGE_UP,PAUSE,RETURN,RIGHT,SEMICOLON,SEPARATOR,SHIFT,SPACE,SUBTRACT,TAB,UP

@pyimport selenium.webdriver.common.keys as ks
const ADD = ks.Keys[:ADD]
const ALT = ks.Keys[:ALT]
const ARROW_DOWN = ks.Keys[:ARROW_DOWN]
const ARROW_LEFT = ks.Keys[:ARROW_LEFT]
const ARROW_RIGHT = ks.Keys[:ARROW_RIGHT]
const ARROW_UP = ks.Keys[:ARROW_UP]
const BACKSPACE = ks.Keys[:BACKSPACE]
const BACK_SPACE = ks.Keys[:BACK_SPACE]
const CANCEL = ks.Keys[:CANCEL]
const CLEAR = ks.Keys[:CLEAR]
const COMMAND = ks.Keys[:COMMAND]
const CONTROL = ks.Keys[:CONTROL]
const DECIMAL = ks.Keys[:DECIMAL]
const DELETE = ks.Keys[:DELETE]
const DIVIDE = ks.Keys[:DIVIDE]
const DOWN = ks.Keys[:DOWN]
const END = ks.Keys[:END]
const ENTER = ks.Keys[:ENTER]
const EQUALS = ks.Keys[:EQUALS]
const ESCAPE = ks.Keys[:ESCAPE]
const F1 = ks.Keys[:F1]
const F10 = ks.Keys[:F10]
const F11 = ks.Keys[:F11]
const F12 = ks.Keys[:F12]
const F2 = ks.Keys[:F2]
const F3 = ks.Keys[:F3]
const F4 = ks.Keys[:F4]
const F5 = ks.Keys[:F5]
const F6 = ks.Keys[:F6]
const F7 = ks.Keys[:F7]
const F8 = ks.Keys[:F8]
const F9 = ks.Keys[:F9]
const HELP = ks.Keys[:HELP]
const HOME = ks.Keys[:HOME]
const INSERT = ks.Keys[:INSERT]
const LEFT = ks.Keys[:LEFT]
const LEFT_ALT = ks.Keys[:LEFT_ALT]
const LEFT_CONTROL = ks.Keys[:LEFT_CONTROL]
const LEFT_SHIFT = ks.Keys[:LEFT_SHIFT]
const META = ks.Keys[:META]
const MULTIPLY = ks.Keys[:MULTIPLY]
const NULL = ks.Keys[:NULL]
const NUMPAD0 = ks.Keys[:NUMPAD0]
const NUMPAD1 = ks.Keys[:NUMPAD1]
const NUMPAD2 = ks.Keys[:NUMPAD2]
const NUMPAD3 = ks.Keys[:NUMPAD3]
const NUMPAD4 = ks.Keys[:NUMPAD4]
const NUMPAD5 = ks.Keys[:NUMPAD5]
const NUMPAD6 = ks.Keys[:NUMPAD6]
const NUMPAD7 = ks.Keys[:NUMPAD7]
const NUMPAD8 = ks.Keys[:NUMPAD8]
const NUMPAD9 = ks.Keys[:NUMPAD9]
const PAGE_DOWN = ks.Keys[:PAGE_DOWN]
const PAGE_UP = ks.Keys[:PAGE_UP]
const PAUSE = ks.Keys[:PAUSE]
const RETURN = ks.Keys[:RETURN]
const RIGHT = ks.Keys[:RIGHT]
const SEMICOLON = ks.Keys[:SEMICOLON]
const SEPARATOR = ks.Keys[:SEPARATOR]
const SHIFT = ks.Keys[:SHIFT]
const SPACE = ks.Keys[:SPACE]
const SUBTRACT = ks.Keys[:SUBTRACT]
const TAB = ks.Keys[:TAB]
const UP = ks.Keys[:UP]
end


text:
# left.jl
# "special cases" related left vector multiplication like x = y'*A
# The subtlety is that y' is a AdjointAbsVec or a TransposeAbsVec
# which is a subtype of AbstractMatrix but it is really "vector like"
# so we want handle it like a vector (Issue#99)
# So this is an exception to the left multiplication rule by a AbstractMatrix
# that usually makes a WrappedMap.

# x = y'*A ⇐⇒ x' = (A'*y)
"""
    *(x::LinearAlgebra.AdjointAbsVec, A::LinearMap)::AdjointAbsVec

Compute the right-action of the linear map `A` on the adjoint vector `x`
and return an adjoint vector.

## Examples
```jldoctest; setup=(using LinearAlgebra, LinearMaps)
julia> A=LinearMap([1.0 2.0; 3.0 4.0]); x=[1.0, 1.0]; x'A
1×2 Adjoint{Float64,Array{Float64,1}}:
 4.0  6.0
```
"""
Base.:(*)(y::LinearAlgebra.AdjointAbsVec, A::LinearMap) = adjoint(A' * y')

"""
    *(x::LinearAlgebra.TransposeAbsVec, A::LinearMap)::TransposeAbsVec

Compute the right-action of the linear map `A` on the transpose vector `x`
and return a transpose vector.

## Examples
```jldoctest; setup=(using LinearAlgebra, LinearMaps)
julia> A=LinearMap([1.0 2.0; 3.0 4.0]); x=[1.0, 1.0]; transpose(x)*A
1×2 Transpose{Float64,Array{Float64,1}}:
 4.0  6.0
```
"""
Base.:(*)(y::LinearAlgebra.TransposeAbsVec, A::LinearMap) = transpose(transpose(A) * transpose(y))

# multiplication with vector/matrix
const TransposeAbsVecOrMat{T} = Transpose{T,<:AbstractVecOrMat}

# handles both y::AbstractMatrix and y::AdjointAbsVecOrMat
"""
    mul!(C::AbstractMatrix, A::AbstractMatrix, B::LinearMap) -> C

Calculates the matrix representation of `A*B` and stores the result in `C`,
overwriting the existing value of `C`. Note that `C` must not be aliased with
either `A` or `B`. The computation `C = A*B` is performed via `C' = B'A'`.

## Examples
```jldoctest; setup=(using LinearAlgebra, LinearMaps)
julia> A=[1.0 1.0; 1.0 1.0]; B=LinearMap([1.0 2.0; 3.0 4.0]); C = similar(A); mul!(C, A, B);

julia> C
2×2 Array{Float64,2}:
 4.0  6.0
 4.0  6.0
```
"""
function mul!(X::AbstractMatrix, Y::AbstractMatrix, A::LinearMap)
    check_dim_mul(X, Y, A)
    _unsafe_mul!(X', A', Y')
    return X
end

function mul!(X::AbstractMatrix, Y::TransposeAbsVecOrMat, A::LinearMap)
    check_dim_mul(X, Y, A)
    _unsafe_mul!(transpose(X), transpose(A), transpose(Y))
    return X
end

# commutative case, handles both the abstract and adjoint case
function mul!(X::AbstractMatrix{<:RealOrComplex}, Y::AbstractMatrix{<:RealOrComplex}, A::LinearMap{<:RealOrComplex},
                α::RealOrComplex, β::RealOrComplex)
    check_dim_mul(X, Y, A)
    _unsafe_mul!(X', A', Y', conj(α), conj(β))
    return X
end

function mul!(X::AbstractMatrix{<:RealOrComplex}, Y::TransposeAbsVecOrMat{<:RealOrComplex}, A::LinearMap{<:RealOrComplex},
                α::RealOrComplex, β::RealOrComplex)
    check_dim_mul(X, Y, A)
    _unsafe_mul!(transpose(X), transpose(A), transpose(Y), α, β)
    return X
end

# non-commutative case
function mul!(X::AbstractMatrix, Y::AbstractMatrix, A::LinearMap, α::Number, β::Number)
    check_dim_mul(X, Y, A)
    if iszero(β)
        _unsafe_mul!(X', conj(α)*A', Y')
    else
        !isone(β) && rmul!(X, β)
        _unsafe_mul!(X', conj(α)*A', Y', true, true)
    end
    return X
end


text:
struct GitCommit <: GitObject
    tree::SHA1
    parents::Vector{SHA1}
    author::String
    committer::String
    message::String
end

function GitCommit(data::Vector{UInt8})
    io = IOBuffer(data)
    fieldname = readuntil(io, ' ')
    @assert fieldname == "tree"
    tree = SHA1(readline(io))

    parents = SHA1[]
    fieldname = readuntil(io, ' ')
    while fieldname == "parent"
        push!(parents, SHA1(readline(io)))
        fieldname = readuntil(io, ' ')
    end

    @assert fieldname == "author"
    author = readline(io)

    fieldname = readuntil(io, ' ')
    @assert fieldname == "committer"
    committer = readline(io)

    empty = readline(io)
    @assert empty == ""

    message = String(read(io))
    GitCommit(tree, parents, author, committer, message)
end

function Base.sizeof(commit::GitCommit)
    4 + 1 + 2*20 + 1 +
    length(commit.parents) * (6 + 1 + 2*20 + 1) +
    6 + 1 + sizeof(commit.author) + 1 +
    9 + 1 + sizeof(commit.committer) + 1 +
    1 +
    sizeof(commit.message)
end

function oid(commit::GitCommit)
    ctx = SHA.SHA1_CTX()
    SHA.update!(ctx, Vector{UInt8}("commit $(sizeof(commit))\0"))
    SHA.update!(ctx, Vector{UInt8}("tree $(commit.tree)\n"))
    for parent in commit.parents
        SHA.update!(ctx, Vector{UInt8}("parent $(parent)\n"))
    end
    SHA.update!(ctx, Vector{UInt8}("author $(commit.author)\n"))
    SHA.update!(ctx, Vector{UInt8}("committer $(commit.committer)\n"))
    SHA.update!(ctx, Vector{UInt8}("\n"))
    SHA.update!(ctx, Vector{UInt8}(commit.message))
    return SHA1(SHA.digest!(ctx))
end

max_stars_repo_name: simonbyrne/GitX

max_issues_repo_name: simonbyrne/GitX

max_forks_repo_name: simonbyrne/GitX


text:
using LinearAlgebra

import Flux
import ZygoteRules

struct CachedDense{M <: AbstractVecOrMat, V <: AbstractVecOrMat, F, C <: AbstractVecOrMat}
   W :: M
   b :: V
   σ :: F
   cache :: C
end

Flux.trainable(m::CachedDense) = (m.W, m.b, m.σ)

Flux.@functor CachedDense

CachedDense(W, b, cache) = CachedDense(W, b, identity, cache)

function CachedDense(in::Integer, out::Integer, σ = identity; batchsize::Integer,
               initW = Flux.glorot_uniform, initb = Flux.zeros)
   return CachedDense(initW(out, in), initb(out), σ, Flux.zeros(out, batchsize))
end

function Base.show(io::IO, m::CachedDense)
   out, in = size(m.W)
   batchsize = size(m.cache, 2)
   print(io, "CachedDense($in, $out")
   m.σ == identity || print(io, ", ", m.σ)
   print(io, "; batchsize=$batchsize)")
end

function (m::CachedDense)(x::AbstractVecOrMat)
   W, b, σ, cache = m.W, m.b, m.σ, m.cache
   Wx = mul!(cache, W, x)
   return cache .= σ.(Wx .+ b)
end

# Try to avoid hitting generic matmul in some simple cases
# Base's matmul is so slow that it's worth the extra conversion to hit BLAS
(m::CachedDense{M})(x::AbstractVecOrMat{T}) where {T <: Union{Float32,Float64}, M <: AbstractVecOrMat{T}} =
   invoke(m, Tuple{AbstractVecOrMat}, x)

(m::CachedDense{M})(x::AbstractVecOrMat{<:AbstractFloat}) where {T <: Union{Float32,Float64}, M <: AbstractVecOrMat{T}} =
   m(T.(x))

max_stars_repo_name: AzamatB/CachedFluxLayers

max_issues_repo_name: AzamatB/CachedFluxLayers

max_forks_repo_name: AzamatB/CachedFluxLayers


text:
# Automatically generated using Clang.jl

@cenum sfCursorType::UInt32 begin
    sfCursorArrow = 0
    sfCursorArrowWait = 1
    sfCursorWait = 2
    sfCursorText = 3
    sfCursorHand = 4
    sfCursorSizeHorizontal = 5
    sfCursorSizeVertical = 6
    sfCursorSizeTopLeftBottomRight = 7
    sfCursorSizeBottomLeftTopRight = 8
    sfCursorSizeAll = 9
    sfCursorCross = 10
    sfCursorHelp = 11
    sfCursorNotAllowed = 12
end

@cenum sfEventType::UInt32 begin
    sfEvtClosed = 0
    sfEvtResized = 1
    sfEvtLostFocus = 2
    sfEvtGainedFocus = 3
    sfEvtTextEntered = 4
    sfEvtKeyPressed = 5
    sfEvtKeyReleased = 6
    sfEvtMouseWheelMoved = 7
    sfEvtMouseWheelScrolled = 8
    sfEvtMouseButtonPressed = 9
    sfEvtMouseButtonReleased = 10
    sfEvtMouseMoved = 11
    sfEvtMouseEntered = 12
    sfEvtMouseLeft = 13
    sfEvtJoystickButtonPressed = 14
    sfEvtJoystickButtonReleased = 15
    sfEvtJoystickMoved = 16
    sfEvtJoystickConnected = 17
    sfEvtJoystickDisconnected = 18
    sfEvtTouchBegan = 19
    sfEvtTouchMoved = 20
    sfEvtTouchEnded = 21
    sfEvtSensorChanged = 22
    sfEvtCount = 23
end

@cenum sfKeyCode::Int32 begin
    sfKeyUnknown = -1
    sfKeyA = 0
    sfKeyB = 1
    sfKeyC = 2
    sfKeyD = 3
    sfKeyE = 4
    sfKeyF = 5
    sfKeyG = 6
    sfKeyH = 7
    sfKeyI = 8
    sfKeyJ = 9
    sfKeyK = 10
    sfKeyL = 11
    sfKeyM = 12
    sfKeyN = 13
    sfKeyO = 14
    sfKeyP = 15
    sfKeyQ = 16
    sfKeyR = 17
    sfKeyS = 18
    sfKeyT = 19
    sfKeyU = 20
    sfKeyV = 21
    sfKeyW = 22
    sfKeyX = 23
    sfKeyY = 24
    sfKeyZ = 25
    sfKeyNum0 = 26
    sfKeyNum1 = 27
    sfKeyNum2 = 28
    sfKeyNum3 = 29
    sfKeyNum4 = 30
    sfKeyNum5 = 31
    sfKeyNum6 = 32
    sfKeyNum7 = 33
    sfKeyNum8 = 34
    sfKeyNum9 = 35
    sfKeyEscape = 36
    sfKeyLControl = 37
    sfKeyLShift = 38
    sfKeyLAlt = 39
    sfKeyLSystem = 40
    sfKeyRControl = 41
    sfKeyRShift = 42
    sfKeyRAlt = 43
    sfKeyRSystem = 44
    sfKeyMenu = 45
    sfKeyLBracket = 46
    sfKeyRBracket = 47
    sfKeySemicolon = 48
    sfKeyComma = 49
    sfKeyPeriod = 50
    sfKeyQuote = 51
    sfKeySlash = 52
    sfKeyBackslash = 53
    sfKeyTilde = 54
    sfKeyEqual = 55
    sfKeyHyphen = 56
    sfKeySpace = 57
    sfKeyEnter = 58
    sfKeyBackspace = 59
    sfKeyTab = 60
    sfKeyPageUp = 61
    sfKeyPageDown = 62
    sfKeyEnd = 63
    sfKeyHome = 64
    sfKeyInsert = 65
    sfKeyDelete = 66
    sfKeyAdd = 67
    sfKeySubtract = 68
    sfKeyMultiply = 69
    sfKeyDivide = 70
    sfKeyLeft = 71
    sfKeyRight = 72
    sfKeyUp = 73
    sfKeyDown = 74
    sfKeyNumpad0 = 75
    sfKeyNumpad1 = 76
    sfKeyNumpad2 = 77
    sfKeyNumpad3 = 78
    sfKeyNumpad4 = 79
    sfKeyNumpad5 = 80
    sfKeyNumpad6 = 81
    sfKeyNumpad7 = 82
    sfKeyNumpad8 = 83
    sfKeyNumpad9 = 84
    sfKeyF1 = 85
    sfKeyF2 = 86
    sfKeyF3 = 87
    sfKeyF4 = 88
    sfKeyF5 = 89
    sfKeyF6 = 90
    sfKeyF7 = 91
    sfKeyF8 = 92
    sfKeyF9 = 93
    sfKeyF10 = 94
    sfKeyF11 = 95
    sfKeyF12 = 96
    sfKeyF13 = 97
    sfKeyF14 = 98
    sfKeyF15 = 99
    sfKeyPause = 100
    sfKeyCount = 101
    sfKeyDash = 56
    sfKeyBack = 59
    sfKeyBackSlash = 53
    sfKeySemiColon = 48
    sfKeyReturn = 58
end

struct sfKeyEvent
    type::sfEventType
    code::sfKeyCode
    alt::sfBool
    control::sfBool
    shift::sfBool
    system::sfBool
end

struct sfTextEvent
    type::sfEventType
    unicode::sfUint32
end

struct sfMouseMoveEvent
    type::sfEventType
    x::Cint
    y::Cint
end

@cenum sfMouseButton::UInt32 begin
    sfMouseLeft = 0
    sfMouseRight = 1
    sfMouseMiddle = 2
    sfMouseXButton1 = 3
    sfMouseXButton2 = 4
    sfMouseButtonCount = 5
end

struct sfMouseButtonEvent
    type::sfEventType
    button::sfMouseButton
    x::Cint
    y::Cint
end

@cenum sfMouseWheel::UInt32 begin
    sfMouseVerticalWheel = 0
    sfMouseHorizontalWheel = 1
end

struct sfMouseWheelScrollEvent
    type::sfEventType
    wheel::sfMouseWheel
    delta::Cfloat
    x::Cint
    y::Cint
end

@cenum sfJoystickAxis::UInt32 begin
    sfJoystickX = 0
    sfJoystickY = 1
    sfJoystickZ = 2
    sfJoystickR = 3
    sfJoystickU = 4
    sfJoystickV = 5
    sfJoystickPovX = 6
    sfJoystickPovY = 7
end

struct sfJoystickMoveEvent
    type::sfEventType
    joystickId::UInt32
    axis::sfJoystickAxis
    position::Cfloat
end

struct sfJoystickButtonEvent
    type::sfEventType
    joystickId::UInt32
    button::UInt32
end

struct sfJoystickConnectEvent
    type::sfEventType
    joystickId::UInt32
end

struct sfSizeEvent
    type::sfEventType
    width::UInt32
    height::UInt32
end

struct sfTouchEvent
    type::sfEventType
    finger::UInt32
    x::Cint
    y::Cint
end

@cenum sfSensorType::UInt32 begin
    sfSensorAccelerometer = 0
    sfSensorGyroscope = 1
    sfSensorMagnetometer = 2
    sfSensorGravity = 3
    sfSensorUserAcceleration = 4
    sfSensorOrientation = 5
    sfSensorCount = 6
end

struct sfSensorEvent
    type::sfEventType
    sensorType::sfSensorType
    x::Cfloat
    y::Cfloat
    z::Cfloat
end

struct sfEvent
    type::sfEventType
    data::NTuple{20,UInt8}
end

@inline function unpack_union(::Type{T}, obj::S) where {T,S}
    ref = Ref{S}(obj)
    GC.@preserve ref begin
        ptr = Base.unsafe_convert(Ptr{Cvoid}, ref)
        target = unsafe_load(Ptr{T}(ptr))
    end
    return target
end

function Base.getproperty(obj::sfEvent, sym::Symbol)
    if sym === :type
        return getfield(obj, :type)
    elseif sym === :size
        return unpack_union(sfSizeEvent, obj)
    elseif sym === :key
        return unpack_union(sfKeyEvent, obj)
    elseif sym === :text
        return unpack_union(sfTextEvent, obj)
    elseif sym === :mouseMove
        return unpack_union(sfMouseMoveEvent, obj)
    elseif sym === :mouseButton
        return unpack_union(sfMouseButtonEvent, obj)
    elseif sym === :mouseWheel
        return unpack_union(sfMouseWheelEvent, obj)
    elseif sym === :mouseWheelScroll
        return unpack_union(sfMouseWheelScrollEvent, obj)
    elseif sym === :joystickMove
        return unpack_union(sfJoystickMoveEvent, obj)
    elseif sym === :joystickButton
        return unpack_union(sfJoystickButtonEvent, obj)
    elseif sym === :joystickConnect
        return unpack_union(sfJoystickConnectEvent, obj)
    elseif sym === :touch
        return unpack_union(sfTouchEvent, obj)
    elseif sym === :sensor
        return unpack_union(sfSensorEvent, obj)
    end
end

# const CSFML_WINDOW_API = CSFML_API_IMPORT

struct sfJoystickIdentification
    name::Cstring
    vendorId::UInt32
    productId::UInt32
end

const sfContext = Cvoid
const sfCursor = Cvoid
const sfWindow = Cvoid

struct sfVideoMode
    width::UInt32
    height::UInt32
    bitsPerPixel::UInt32
end

@cenum sfWindowStyle::UInt32 begin
    sfNone = 0
    sfTitlebar = 1
    sfResize = 2
    sfClose = 4
    sfFullscreen = 8
    sfDefaultStyle = 7
end

@cenum sfContextAttribute::UInt32 begin
    sfContextDefault = 0
    sfContextCore = 1
    sfContextDebug = 4
end

struct sfContextSettings
    depthBits::UInt32
    stencilBits::UInt32
    antialiasingLevel::UInt32
    majorVersion::UInt32
    minorVersion::UInt32
    attributeFlags::sfUint32
    sRgbCapable::sfBool
end

const sfWindowHandle = Ptr{Cvoid}


text:
type OPCSPBeliefMDP <: POMDP
    r::Vector{Float64}
    positions::Vector{Vector{Float64}}
    covariance::Matrix{Float64}
    distance_limit::Float64
    start::Int
    stop::Int
    distances::Matrix{Float64}
end
function OPCSPBeliefMDP(op::OPCSP)
    OPCSPBeliefMDP(op.r, op.positions, op.covariance, op.distance_limit, op.start, op.stop, op.distances)
end
length(op::OPCSPBeliefMDP) = length(op.r)

create_action(::OPCSPBeliefMDP) = OPCSPAction()

@auto_hash_equals type OPCSPBelief <: State
    i::Int
    open::IntSet
    remaining::Float64
    dist::MVN
end
OPCSPBelief(d::OPCSPDistribution) = OPCSPBelief(d.i, d.open, d.remaining, d.dist)
create_state(problem::OPCSPBeliefMDP) = OPCSPBelief(
    0,
    IntSet(),
    0.0,
    MVN(Array(Float64,length(problem)), Array(Float64, length(problem), length(problem))))
get_d(b::OPCSPBelief) = b.dist.mean

function MCTS.generate(p::OPCSPBeliefMDP, s::OPCSPBelief, a::OPCSPAction, rng::AbstractRNG)
    sp = create_state(p)
    sp.i = a.next
    copy!(sp.open, s.open)
    delete!(sp.open, a.next)
    sp.remaining = s.remaining-p.distances[s.i, a.next]
    d = rand_elem(rng, s.dist, a.next)
    sp.dist = apply_measurement(s.dist, a.next, d)
    r = reward(p, s, a, sp)
    return (sp, r)
end
initial_state(p::OPCSPBeliefMDP) = OPCSPBelief(
    p.start,
    delete!(IntSet(1:length(p)), p.start),
    p.distance_limit,
    MVN(zeros(length(p)), p.covariance)
    )
Base.mean(b::OPCSPBelief) = OPCSPState(b.i, b.open, b.remaining, b.dist.mean)

# get the reward for whichever action you pick, not whichever state you're in
function reward(p::OPCSPBeliefMDP, ::OPCSPBelief, a::OPCSPAction, sp::OPCSPBelief)
    @assert sp.dist.covariance[a.next, a.next] == 0.0
    return p.r[a.next]+sp.dist.mean[a.next]
end

discount(op::OPCSPBeliefMDP) = 1.0
isterminal(op::OPCSPBeliefMDP, s::OPCSPBelief) = op.stop == s.i


text:
const SHARDS_URL = "https://raw.githubusercontent.com/JuliaPackaging/BinaryBuilderBase.jl/master/Artifacts.toml"
const SHARDS = Dict{String,Any}()

const HOST_TRIPLE = "x86_64-linux-musl"
const GCC_SHARD_NAME = "GCCBootstrap"
const SYSTEM_SHARD_NAME = "PlatformSupport"

const JLL_ENV_PLATFORMS = [
    Platform("aarch64", "macos"),
    Platform("aarch64", "linux"),                # Tier 1
    Platform("x86_64", "linux"; libc="musl"),
    Platform("armv7l", "linux"),
    Platform("armv7l", "linux"; libc="musl"),
    Platform("i686", "linux"),                   # Tier 1
    Platform("i686", "linux"; libc="musl"),
    Platform("i686", "windows"),                 # Tier 2
    Platform("powerpc64le", "linux"),
    Platform("x86_64", "macos"),                 # Tier 1
    Platform("x86_64", "linux"),                 # Tier 1
    Platform("x86_64", "linux"; libc="musl"),
    Platform("x86_64", "freebsd"),
    Platform("x86_64", "windows"),               # Tier 1
]

get_gcc_shard_key(p::Platform, version::VersionNumber=GCC_MIN_VER) = "$GCC_SHARD_NAME-$(__triplet(p)).v$version.$HOST_TRIPLE.unpacked"
get_gcc_shard_key(triple::String, version::VersionNumber=GCC_MIN_VER) = get_gcc_shard_key(parse(Platform, triple), version)

function get_system_shard_key(p::Platform)
    platform_keys = filter(collect(keys(SHARDS))) do key
        startswith(key, "$SYSTEM_SHARD_NAME-$(__triplet(p)).") &&
        endswith(key, "$HOST_TRIPLE.unpacked")
    end
    return platform_keys[]
end
get_system_shard_key(triple::String) = get_system_shard_key(parse(Platform, triple))

function get_environment_info(p::Platform, version::VersionNumber=GCC_MIN_VER)
    gcc = SHARDS[get_gcc_shard_key(p, version)][]
    sys = SHARDS[get_system_shard_key(p)][]
    gcc_download = gcc["download"][]
    sys_download = sys["download"][]
    info = [
        (id=gcc["git-tree-sha1"], url=gcc_download["url"], chk=gcc_download["sha256"]),
        (id=sys["git-tree-sha1"], url=sys_download["url"], chk=sys_download["sha256"]),
    ]
    return info
end
get_environment_info(triple::String, version::VersionNumber=GCC_MIN_VER) = get_environment_info(parse(Platform, triple), version)


text:
# LogLinear Transformation

"""
    LogLinearFormula(df::Int64)

Returns GLM formula can be used in `glm` with `FreqTab` data frame.
`df`, is abbreviation for degrees of formula, represents degree of polynomial log-linear method.
This function works very slowly. If a fixed degree formula will be used repeatedly, define the formula as a variable.
The similer macro `@LogLinearFormula` is provided and it is faster than the function.
"""
function LogLinearFormula(df)
    fml = "@formula(freq ~ 1 +"
    @simd for d in 1:df
        fml *= "scale^$d"
        if d != df
            fml *= " + "
        else
            fml *= ")"
        end
    end
    return eval(Meta.parse(fml))
end

struct SmoothedFreqTab <: EG
    tab::DataFrame
    raw::Vector
    interval::Float64
    fit
end
"""
    presmoothing(F::FreqTab, @LogLinearFormula(df::Int64))

Returns presmoothed frequency table as `SmoothedFreqTab` and `glm` fitted object.

Preserving first C moments of original frequency data, passed `LogLinearFormula(C)` to `fml`.
C is a degree of freedom
"""
function presmoothing(F::EG, fml)
    fit1 = glm(fml, F.tab, Poisson(), LogLink())
    freq = predict(fit1, DataFrame(scale = F.tab.scale))
    tab = DataFrame(scale = F.tab.scale, freq = freq, cumfreq = cumsum(freq),
                    prob = freq ./ sum(freq), cumprob = cumsum(freq) ./ sum(freq))
    return SmoothedFreqTab(tab, F.raw, F.interval, fit1)
end

# function presmoothing(F::EG, degree::Int64)
#     AIC, BIC, AICC, DEVIANCE, LL = zeros.(Float64, fill(degree, 5))
#     for d in 1:degree
#         println("Fitting dof = $degree model.")
#         fml = LogLinearFormula(d)
#         fit = glm(fml, F.tab, Poisson(), LogLink())
#         AIC[d] = aic(fit)
#         BIC[d] = bic(fit)
#         AICC[d] = aicc(fit)
#         LL[d] = loglikelihood(fit)
#         DEVIANCE[d] = deviance(fit)
#     end
#     DataFrame(degree = [1:1:degree;], aic = AIC, aicc = IACC, bic = BIC, loglik = LL, deviance = DEVIANCE)
# end

struct SmoothedNEATFreqTab <: NEAT
    tabX
    tabV
    rawX
    rawV
    intervalX
    intervalV
    fitX
    fitV
    marginal
end
"""
    presmoothing(F::NEAT, LogLinearFormula(df::Int64), LogLinearFormula(df::Int64))

Returns presmoothed frequency table as `SmoothedNEATFreqTab` and `glm` fitted object,
but `interval` and `marginal` elements, which are returned, are not based on smoothed score.

Preserving first C moments of original frequency data, passed `LogLinearFormula(C)` to `fml`.
C is a degree of freedom
"""
function presmoothing(F::NEAT, fmlX, fmlV)
    # Smoothing X (independent part)
    fitX = glm(fmlX, F.tabX, Poisson(), LogLink())
    freqX = predict(fitX, DataFrame(scale = F.tabX.scale))
    tabX = DataFrame(scale = F.tabX.scale, freq = freqX, cumfreq = cumsum(freqX),
                    prob = freqX ./ sum(freqX), cumprob = cumsum(freqX) ./ sum(freqX))
    # Smoothing V (common part)
    fitV = glm(fmlV, F.tabV, Poisson(), LogLink())
    freqV = predict(fitV, DataFrame(scale = F.tabV.scale))
    tabV = DataFrame(scale = F.tabV.scale, freq = freqV, cumfreq = cumsum(freqV),
                    prob = freqV ./ sum(freqV), cumprob = cumsum(freqV) ./ sum(freqV))
    return SmoothedNEATFreqTab(tabX, tabV, F.rawX, F.rawV, F.intervalX, F.intervalV, fitX, fitV, F.marginal)
end

# Kernel method
function RjX(x, xⱼ, a, μ, hX)
    return (x - a * xⱼ - (1-a)*μ) / (a*hX)
end
struct KernelFreqTab <: EG
    tab::DataFrame
    raw::Vector
    interval::Float64
    Bandwidth::Float64
end
"""
    KernelSmoothing(X::SmoothedFreqTab; kernel = :Gaussian, hX = 0.622, scale = X.tab.scale)

Returns Kernel smoothed frequency table as `KernelFreqTab`.

# Arguments

- `X` the object which class is `freqtab`

## Optional Arguments

- `kernel`
- `hX` The band width.
- `newint` A new interval to depict the continuized probability line.

# Value

`KernelFreqTab`

In the kernel smoothing, the choice of bandwidth `hX` is an important consideration. When bandwidth is large, the smoothed distribution becomes linear equating fucnction. Contrary, bandwidth is small, it becomes spikye shaped distribution. We recommend to use default value `hX = 6.22` or select it by using `EstBandwidth`.
"""
function KernelSmoothing(X::EG; kernel = :Gaussian, hX = 0.622, newint = X.interval/100)
    scale = (minimum(X.tab.scale) - X.interval/2):newint:(maximum(X.tab.scale) + X.interval/2)
    # hX = bandwidth of cumulative distribution function
    N = sum(X.tab.freq)
    μ = mean(X.raw); σ² = var(X.raw)
    a² = σ² / (σ² + hX^2)
    a = sqrt(a²)
    𝒇hX = zeros(Float64, length(scale))
    FhX = zeros(Float64, length(scale))
    for (i, x) in enumerate(scale), (j, xⱼ) in enumerate(X.tab.scale)
        𝒇hX[i] += X.tab.prob[j]*pdf.(Normal(0, 1), RjX(x, xⱼ, a, μ, hX)) / (a*hX)
        FhX[i] += X.tab.prob[j]*cdf.(Normal(0, 1), RjX(x, xⱼ, a, μ, hX))
    end
    𝒇hX = 𝒇hX ./ sum(𝒇hX) # normalize
    tbl = DataFrame(scale = scale, freq = N .* 𝒇hX, cunfreq = cumsum(N .* 𝒇hX), prob = 𝒇hX, cumprob = cumsum(𝒇hX))
    return KernelFreqTab(tbl, X.raw, X.interval, hX)
end

function BandwidthPenalty(hX, X::SmoothedFreqTab, lprob, rprob, K; kernel = :Gaussian)
    hX = exp(hX[1])
    r = X.tab.prob
    μ = mean(X.raw); σ² = var(X.raw)
    a² = σ² / (σ² + hX^2)
    a =sqrt(a²)
    𝒇hX = zeros(Float64, length(X.tab.scale))
    r𝒇′hX = zeros(Float64, length(X.tab.scale))
    l𝒇′hX = zeros(Float64, length(X.tab.scale))
    for (i, x) in enumerate(X.tab.scale), (j, xⱼ) in enumerate(X.tab.scale)
        R = RjX(x, xⱼ, a, μ, hX)
        𝒇hX[i] += X.tab.prob[j]*pdf.(Normal(0, 1), R) / (a*hX)
        r𝒇′hX[i] -= rprob[j]*pdf.(Normal(0, 1), R) / (a*hX)^2 * R
        l𝒇′hX[i] -= lprob[j]*pdf.(Normal(0, 1), R) / (a*hX)^2 * R
    end
    pen1 = sum((r .- 𝒇hX) .^2)
    pen2 = sum((l𝒇′hX .< 0) .* (r𝒇′hX .> 0))
    return pen1 + K * pen2
end

"""
    EstBandwidth(X::EG; kernel = :Gaussian)

Estimate optimal bandwidth `hX` in Gaussian kernel.

# Arguments

- `X` is the object which the class is `freqtab`.

# Value

Optimize information.

"""
function EstBandwidth(X::SmoothedFreqTab; kernel = :Gaussian, K = 1)
    x = X.tab.scale
    lscore = x .- X.interval/4
    rscore = x .+ X.interval/4
    lpred = predict(X.fit, DataFrame(scale = lscore))
    rpred = predict(X.fit, DataFrame(scale = rscore))
    opt = optimize(hX -> BandwidthPenalty(hX, X, lpred, rpred, K; kernel = kernel), [0.5], method = BFGS())
    println("Minimizer sould be transformed `exp()` before interpretation. \nMinimizer (after taking `exp()`) = $(exp(opt.minimizer[1]))\n\n")
    return opt
end