text:
# Unstable Bickley jet

using Printf

ENV["GKSwstype"] = "nul"
using Plots
using Revise
using CUDA
using ClimateMachine

ClimateMachine.init()

using ClimateMachine.Ocean
using ClimateMachine.Ocean.Domains
using ClimateMachine.Ocean.Fields

using ClimateMachine.Mesh.Grids: DiscontinuousSpectralElementGrid
using ClimateMachine.GenericCallbacks: EveryXSimulationTime
using ClimateMachine.GenericCallbacks: EveryXSimulationSteps
using ClimateMachine.Ocean: current_step, Δt, current_time
using ClimateMachine.Ocean: JLD2Writer, OutputTimeSeries, write!
using CLIMAParameters: AbstractEarthParameterSet, Planet

struct NonDimensionalParameters <: AbstractEarthParameterSet end
Planet.grav(::NonDimensionalParameters) = 10
c = sqrt(Planet.grav(NonDimensionalParameters())) # gravity wave speed for unit depth

include("Bickley.jl")
using .Bickley

# Low-p assumption:
effective_node_spacing(Ne, Np, Lx=4π) = Lx / (Ne * (Np + 1))

Ne = 4
Np = 7
ν = 0
time_step = 0.1 * effective_node_spacing(Ne, Np) / c
array_type = Array
output_time_interval = 2
stabilizing_dissipation = nothing
stop_time = 200

name = @sprintf("climate_machine_unstable_bickley_jet_Ne%d_Np%d_ν%.1e_no_rotation", Ne, Np, ν)

ClimateMachine.Settings.array_type = array_type

# Domain

domain = RectangularDomain(Ne = (Ne, Ne, 1), Np = Np,
                           x = (-2π, 2π), y = (-2π, 2π), z = (0, 1),
                           periodicity = (true, true, false))

# Physical parameters:
g = Planet.grav(NonDimensionalParameters())

# Non-dimensional parameters
ϵ = 0.1 # Perturbation amplitude
ℓ = 0.5 # Perturbation width
k = 0.5 # Perturbation wavenumber

# Initial conditions: Jet/tracer + perturbations
uᵢ(x, y, z) = Bickley.U(y, domain.L.y) + ϵ * Bickley.ũ(x, y, ℓ, k)
vᵢ(x, y, z) = ϵ * Bickley.ṽ(x, y, ℓ, k)
θᵢ(x, y, z) = Bickley.C(y, domain.L.y)

initial_conditions = InitialConditions(u=uᵢ, v=vᵢ, θ=θᵢ)

model = Ocean.HydrostaticBoussinesqSuperModel(
    domain = domain,
    time_step = time_step,
    initial_conditions = initial_conditions,
    parameters = NonDimensionalParameters(),
    turbulence_closure = (νʰ = ν, κʰ = ν, νᶻ = ν, κᶻ = ν),
    rusanov_wave_speeds = (cʰ = sqrt(g * domain.L.z), cᶻ = 1e-2),
    stabilizing_dissipation = stabilizing_dissipation,
    coriolis = (f₀ = 0, β = 0),
    buoyancy = (αᵀ = 0,),
    boundary_tags = ((0, 0), (1, 1), (1, 2)),
    boundary_conditions = (OceanBC(Impenetrable(FreeSlip()), Insulating()),
                           OceanBC(Penetrable(FreeSlip()), Insulating()))
)

name = @sprintf("climate_machine_unstable_bickley_jet_Ne%d_Np%d_ν%.1e_no_rotation", Ne, Np, ν)

ClimateMachine.Settings.array_type = array_type

# Domain

domain = RectangularDomain(Ne = (Ne, Ne, 1), Np = Np,
                           x = (-2π, 2π), y = (-2π, 2π), z = (0, 1),
                           periodicity = (true, true, false))

# Physical parameters:
g = Planet.grav(NonDimensionalParameters())

# Non-dimensional parameters
ϵ = 0.1 # Perturbation amplitude
ℓ = 0.5 # Perturbation width
k = 0.5 # Perturbation wavenumber

# Initial conditions: Jet/tracer + perturbations
uᵢ(x, y, z) = Bickley.U(y, domain.L.y) + ϵ * Bickley.ũ(x, y, ℓ, k)
vᵢ(x, y, z) = ϵ * Bickley.ṽ(x, y, ℓ, k)
θᵢ(x, y, z) = Bickley.C(y, domain.L.y)

initial_conditions = InitialConditions(u=uᵢ, v=vᵢ, θ=θᵢ)

model = Ocean.HydrostaticBoussinesqSuperModel(
    domain = domain,
    time_step = time_step,
    initial_conditions = initial_conditions,
    parameters = NonDimensionalParameters(),
    turbulence_closure = (νʰ = ν, κʰ = ν, νᶻ = ν, κᶻ = ν),
    rusanov_wave_speeds = (cʰ = sqrt(g * domain.L.z), cᶻ = 1e-2),
    stabilizing_dissipation = stabilizing_dissipation,
    state_filter_order = Np-1,
    coriolis = (f₀ = 0, β = 0),
    buoyancy = (αᵀ = 0,),
    boundary_tags = ((0, 0), (1, 1), (1, 2)),
    boundary_conditions = (OceanBC(Impenetrable(FreeSlip()), Insulating()),
                           OceanBC(Penetrable(FreeSlip()), Insulating()))
)

# We prepare a callback that periodically fetches the horizontal velocity and
# tracer concentration for later animation,

writer = JLD2Writer(model, filepath = name * ".jld2", overwrite_existing = true)
cpu_grid = DiscontinuousSpectralElementGrid(domain, array_type=Array)

start_time = time_ns()

data_fetcher = EveryXSimulationTime(output_time_interval) do
    write!(writer)

    cpu_data = convert(Array, model.state.realdata)
    u = SpectralElementField(domain, cpu_grid, view(cpu_data, :, 1, :))

    # Print a helpful message
    step = @sprintf("Step: %d", current_step(model))
    time = @sprintf("time: %.2f", current_time(model))
    max_u = @sprintf("max|u|: %.6f", maximum(abs, u))

    elapsed = (time_ns() - start_time) * 1e-9
    wall_time = @sprintf("elapsed wall time: %.2f min", elapsed / 60)

    isnan(maximum(abs, u)) && error("NaNs.")

    @info "$step, $time, $max_u, $wall_time"
end

# and then run the simulation.

model.solver_configuration.timeend = 200

total_steps = ceil(Int, stop_time / time_step)
@info @sprintf("Running a simulation of the instability of the Bickley jet (Δt=%.2e, steps=%d)", time_step, total_steps)

try
    result = ClimateMachine.invoke!(model.solver_configuration;
                                    user_callbacks = [data_fetcher])
catch err
    @warn "Simulation ended prematurely because $(sprint(showerror, err))"
end


text:
@testset "get_project_deps" begin
    @testset "no jll" begin
        apply([git_clone_patch, project_toml_patch, cd_patch]) do
            options = CompatHelper.Options()
            subdir = only(options.subdirs)
            deps = CompatHelper.get_project_deps(
                GitForge.GitHub.GitHubAPI(; token=GitHub.Token("token")),
                GitHubActions(),
                GitHub.Repo(; full_name="foobar");
                options=options,
                subdir=subdir,
            )

            @test length(deps) == 1
        end
    end

    @testset "include_jll" begin
        apply([git_clone_patch, project_toml_patch, cd_patch]) do
            options = CompatHelper.Options(; include_jll=true)
            subdir = only(options.subdirs)
            deps = CompatHelper.get_project_deps(
                GitForge.GitHub.GitHubAPI(; token=GitHub.Token("token")),
                GitHubActions(),
                GitHub.Repo(; full_name="foobar");
                options=options,
                subdir=subdir,
            )

            @test length(deps) == 2
        end
    end
end

@testset "clone_all_registries" begin
    registry_1_name = "foobar"
    registry_2_name = "bizbaz"

    apply([mktempdir_patch, git_clone_patch]) do
        CompatHelper.clone_all_registries([
            Pkg.RegistrySpec(; name=registry_1_name, url=""),
            Pkg.RegistrySpec(; name=registry_2_name, url=""),
        ]) do resp
            @test length(resp) == 2

            @test contains(resp[1], registry_1_name)
            @test contains(resp[2], registry_2_name)
        end
    end
end

@testset "get_latest_version_from_registries!" begin
    packageA = "PackageA"
    packageB = "PackageB"
    packageC = "PackageC"

    deps = Set{CompatHelper.DepInfo}([
        # No version specified
        CompatHelper.DepInfo(CompatHelper.Package(packageA, UUID(0))),

        # Version is less than what is in registry
        CompatHelper.DepInfo(
            CompatHelper.Package(packageB, UUID(1)); latest_version=VersionNumber(1)
        ),

        # Version is greater than what is in registry
        CompatHelper.DepInfo(
            CompatHelper.Package(packageC, UUID(2)); latest_version=VersionNumber("3")
        ),
    ])

    apply([clone_all_registries_patch, rm_patch]) do
        result = CompatHelper.get_latest_version_from_registries!(
            deps, Vector{Pkg.RegistrySpec}(); options=CompatHelper.Options()
        )

        @test length(result) == 3

        for res in result
            if res.package.name == packageA
                @test res.latest_version == VersionNumber("1")
            elseif res.package.name == packageB
                @test res.latest_version == VersionNumber("2")
            elseif res.package.name == packageC
                @test res.latest_version == VersionNumber("3")
            end
        end
    end
end

@testset "get_existing_registries!" begin
    packageA = "PackageA"
    packageB = "PackageB"
    packageC = "PackageC"

    deps = Set{CompatHelper.DepInfo}([
        # No version specified
        CompatHelper.DepInfo(CompatHelper.Package(packageA, UUID(0))),

        # Version is less than what is in registry
        CompatHelper.DepInfo(
            CompatHelper.Package(packageB, UUID(1)); latest_version=VersionNumber(1)
        ),

        # Version is greater than what is in registry
        CompatHelper.DepInfo(
            CompatHelper.Package(packageC, UUID(2)); latest_version=VersionNumber("3")
        ),
    ])

    result = CompatHelper.get_existing_registries!(
        deps, joinpath(@__DIR__, "deps"); options=CompatHelper.Options()
    )

    @test length(result) == 3

    for res in result
        if res.package.name == packageA
            @test res.latest_version == VersionNumber("1")
        elseif res.package.name == packageB
            @test res.latest_version == VersionNumber("2")
        elseif res.package.name == packageC
            @test res.latest_version == VersionNumber("3")
        end
    end
end

ext: jl


text:
@testset "workspace" begin
    using Atom: workspace

    items = workspace("Main.Junk")[1][:items]

    # basics
    let items = filter(i -> i[:name] == :useme, items)
        @test !isempty(items)
        @test items[1][:type] == "function"
        @test items[1][:icon] == "λ"
        @test items[1][:nativetype] == "Function"
    end

    let items = filter(i -> i[:name] == Symbol("@immacro"), items)
        @test !isempty(items)
        @test items[1][:type] == "snippet"
        @test items[1][:icon] == "icon-mention"
        @test items[1][:nativetype] == "Function"
    end

    # recoginise submodule
    let items = filter(i -> i[:name] == :SubJunk, items)
        @test !isempty(items)
        @test items[1][:type] == "module"
        @test items[1][:icon] == "icon-package"
        @test items[1][:nativetype] == "Module"
    end

    # handle undefs
    let items = filter(i -> i[:name] == :imnotdefined, items)
        @test !isempty(items)
        @test items[1][:type] == "ignored"
        @test items[1][:icon] == "icon-circle-slash"
        @test items[1][:nativetype] == "Undefined"
    end

    # add variables dynamically
    @eval Main.Junk imadded = 100
    items = workspace("Main.Junk")[1][:items]
    let items = filter(i -> i[:name] == :imadded, items)
        @test !isempty(items)
        @test items[1][:type] == "variable"
        @test items[1][:icon] == "n"
        @test items[1][:nativetype] == "Int64"
    end
end


text:
module KeywordCalls

using Compat
using Tricks

export @kwcall

@generated _sort(nt::NamedTuple{K}) where {K} = :(NamedTuple{($(QuoteNode.(sort(collect(K)))...),)}(nt))

@inline alias(f,::Val{k}) where {k} = k

alias(f, tup::Tuple) = alias.(f, tup)

function alias(f, nt::NamedTuple{K}) where {K}
    newnames = alias(f, Val.(K))
    NamedTuple{newnames}(values(nt))
end

function has_kwargs end
function build end

function _call_in_default_order end

# Thanks to @simeonschaub for this implementation
"""
    @kwcall f(b,a,c=0)

Declares that any call `f(::NamedTuple{N})` with `sort(N) == (:a,:b,:c)`
should be dispatched to the method already defined on
`f(::NamedTuple{(:b,:a,:c)})`

Note that in the example `@kwcall f(b,a,c=0)`, the macro checks for existence of
`f(::NamedTuple)` and `f(; kwargs...)` methods, and only creates new ones if
these don't already exist.
"""
macro kwcall(ex)
    _kwcall(__module__, ex).q
end

function _kwcall(__module__, ex)
    @assert Meta.isexpr(ex, :call)
    f_sym = ex.args[1]
    f_esc = esc(f_sym)
    args, defaults = _parse_args(ex.args[2:end])

    @assert isdefined(__module__, f_sym)

    f = getproperty(__module__, f_sym)

    argnames = QuoteNode.(args)
    sorted_argnames = QuoteNode.(sort(args))

    alias = KeywordCalls.alias
    _sort = KeywordCalls._sort
    instance_type = KeywordCalls.instance_type

    inst = instance_type(f)
    q = quote
        function KeywordCalls._call_in_default_order(::$inst, nt::NamedTuple{($(sorted_argnames...),)})
            return $f_esc(NamedTuple{($(argnames...),)}(nt))
        end
    end

    if !static_hasmethod(has_kwargs, Tuple{inst})
        namedtuplemethod = quote
            @inline function $f_esc(nt::NamedTuple)
                aliased = $alias($f, nt)
                merged = merge($defaults, aliased)
                sorted = $_sort(merged)
                return $_call_in_default_order($f, sorted)
            end
        end

        push!(q.args, namedtuplemethod)

        kwmethod = quote
            $f_esc(;kw...) = $f_esc(NamedTuple(kw))
            KeywordCalls.has_kwargs(::$inst) = true
        end

        push!(q.args, kwmethod)
    end

    return (f_sym=f_sym, args=args, defaults=defaults, sorted_argnames=sorted_argnames, q=q)
end

function _parse_args(args)
    # get args dropping the tail of any expressions
    _args = map(_get_arg, args)
    # get the `key = val` defaults as a NamedTuple quote
    _defaults = :((;$(filter(a -> a isa Expr, args)...)))
    return _args, _defaults
end

_get_arg(ex::Expr) = ex.args[1]
_get_arg(s::Symbol) = s

export @kwstruct

"""
    @kwstruct Foo(b,a,c)

Equivalent to `@kwcall Foo(b,a,c)` plus a definition

    Foo(nt::NamedTuple{(:b, :a, :c), T}) where {T} = Foo{(:b, :a, :c), T}(nt)

Note that this assumes existence of a `Foo` struct of the form

    Foo{N,T} [<: SomeAbstractTypeIfYouLike]
        someFieldName :: NamedTuple{N,T}
    end

NOTE: Default values (as in `@kwcall`) currently do not work for `@kwstruct`.
They can work at the REPL, but this seems to be because of a world age issue.
This feature may be supported again in a future release.
"""
macro kwstruct(ex)
    _kwstruct(__module__, ex)
end

function _kwstruct(__module__, ex)
    setup = _kwcall(__module__, ex)
    (f_sym, args, defaults, q) = setup.f_sym, setup.args, setup.defaults,  setup.q
    f_esc = esc(f_sym)
    f = getproperty(__module__, f_sym)

    # `Tricks.static_hasmethod` currently doesn't work on constructors
    # (see https://github.com/oxinabox/Tricks.jl/issues/17)
    # But we can fake it by creating a `build` method that's defined iff the
    # constructor has the corresponding method. Then we can check for presence
    # of the `build` method and know whether the constructor method is defined.
    if !static_hasmethod(build, Tuple{instance_type(f), Tuple{NamedTuple{((args...),)}}})
        argnames = QuoteNode.(args)

        inst = instance_type(f)
        new_method = quote
            $f_esc(nt::NamedTuple{($(argnames...),),T}) where {T} = $f_esc{($(argnames...),), T}(nt)
            KeywordCalls.build(::$inst, ::NamedTuple{($(argnames...),),T}) where {T} = true
        end

        push!(q.args, new_method)
    end

    return q
end

export @kwalias

"""
    @kwalias f [
        alpha => a
        beta => b
    ]

declare that for the function `f`, we should consider `alpha` to be an alias for
`a`, and `beta` to be an alias for `b`. In a call, the names will be mapped
accordingly as a pre-processing step.
"""
macro kwalias(f, aliasmap)
    _kwalias(__module__, f, aliasmap)
end

function _kwalias(__module__, fsym, aliasmap)
    f_esc = esc(fsym)
    f = getproperty(__module__, fsym)
    q = quote end
    for pair in aliasmap.args
        # Each entry should look like `:(a => b)`
        @assert pair.head == :call
        @assert pair.args[1] == :(=>)
        (a,b) = QuoteNode.(pair.args[2:3])

        inst = instance_type(f)
        newmethod = quote
            KeywordCalls.alias(::$inst, ::Val{$a}) = $b
        end

        push!(q.args, newmethod)
    end
    return q
end

# See https://github.com/cscherrer/KeywordCalls.jl/issues/22
@inline instance_type(f::F) where {F<:Function} = F
@inline instance_type(f::UnionAll) = Type{f}

end # module


text:
using IntervalSets

"""

    PeriodicDomain( left, right, ncells)
    PeriodicDomain( left..right, ncells)
    PeriodicDomain( points )

    Regular cartesian 2D mesh for 1D1V simulation

"""
mutable struct PeriodicDomain

    left   :: Float64
    right  :: Float64
    ncells :: Int
    points :: Vector{Float64}
    delta  :: Float64
    bc     :: Symbol
    axis   :: Int

    function PeriodicDomain(points::Vector{Float64})

        left, right, ncells = points[1], points[end], size(x)-1
	  delta = (right - left) / ncells
        new(left, right, ncells, points, delta)
	  bc = :periodic

    end

    function PeriodicDomain(left, right, ncells::Int)

        points = range(left, stop=right, length=ncells+1)[1:end-1]
	  delta  = (right - left) / ncells
	  new(left, right, ncells, points, delta, :periodic, 1)

    end

    function PeriodicDomain(interval::ClosedInterval{Int64}, ncells::Int)

	  left  = interval.left
	  right = interval.right
        points = range(left, stop=right, length=ncells+1)[1:end-1]
	  delta  = (right - left) / ncells
        new(left, right, ncells, points, delta, :periodic, 1)

    end

    function PeriodicDomain(s::StepRangeLen)

	  left   = s.offset
	  ncells = s.len-1
	  delta  = s.step
	  right  = left + ncells * delta
	  points = collect(s)
        new(left, right, ncells, points, delta, :periodic, 1)

    end

end

import LinearAlgebra
import LinearAlgebra.transpose

LinearAlgebra.:transpose(d::PeriodicDomain) = begin

    d.axis = (d.axis+2)%2+1
    d

end


text:
using MPI, Test
include("../testhelpers.jl")

@testset "Driver" begin
    tests = [
        (1, "driver_test.jl"),
    ]

    runmpi(tests, @__FILE__)
end

max_stars_repo_name: trontrytel/CLIMA

max_issues_repo_name: trontrytel/CLIMA

max_forks_repo_name: trontrytel/CLIMA


text:
using SpecialFunctions, Roots
const sf = SpecialFunctions

"""
    x_uv_x(x, λ_u, w)

Momentum density of u valence component.
Beta function
    A_u x^λ_u (1-x)^K_u
A_u and K_u are set by the passed weight,
`w`.
"""
function x_uv_x(x::Float64, λ_u::Float64, w::Float64)

    f(K_u) = w - 2 * (sf.beta(λ_u + 1, K_u + 1) / sf.beta(λ_u, K_u + 1))

    K_u = find_zero(f, (-1.1, 100))

    A_u = 2 / sf.beta(λ_u, K_u + 1)

    return A_u * x^λ_u * (1 - x)^K_u

end

"""
    x_dv_x(x, λ_d, w)

Momentum density of d valence component.
Beta function
    A_d x^λ_d (1 - x)^K_d
A_d and K_d are set by the passed weight,
`w`
"""
function x_dv_x(x::Float64, λ_d::Float64, w::Float64)

    f(K_d) = w - (sf.beta(λ_d + 1, K_d + 1) / sf.beta(λ_d, K_d + 1))

    K_d = find_zero(f, 1)

    A_d = 1 / sf.beta(λ_d, K_d + 1)

    return A_d * x^λ_d * (1 - x)^K_d

end

"""
        x_g_x(x, λ_g1, λ_g2, K_g, w1, w2)

Momentum density of gluon component.
    A_g1 x^λ_g1 (1 - x)^K_g + A_g2 x^λ_g2
Amplitudes are set by weights `w1` and `w2`.
"""
function x_g_x(x::Float64, λ_g1::Float64, λ_g2::Float64, K_g::Float64,
               w1::Float64, w2::Float64)

    A_g1 = w1 / sf.beta(λ_g1 + 1, K_g + 1)

    x_g1_x = A_g1 * x^λ_g1 * (1 - x)^K_g

    A_g2 = w2 / sf.beta(λ_g2 + 1, 5 + 1)

    x_g2_x = A_g2 * x^λ_g2 * (1 - x)^5

    return x_g1_x + x_g2_x

end

"""
    x_q_x(x, λ_q, w)

Momentum density of non-valence
quark component.
    A_q x^λ_q
Amplitude is set by weight `w`
"""
function x_q_x(x::Float64, λ_q::Float64, w::Float64)

    A_q = (w / 2) / sf.beta(λ_q + 1, 5 + 1)

    return A_q * x^λ_q * (1 - x)^5

end

"""
    x_total_x(x, λ_u, λ_d, λ_g1, λ_g2, K_g, λ_q, θ)

Total momentum density.
"""
function xtotx(x::Float64, λ_u::Float64, λ_d::Float64, λ_g1::Float64, λ_g2::Float64,
               K_g::Float64, λ_q::Float64, θ::Array{Float64})

    xuvx = x_uv_x(x, λ_u, θ[1])

    xdvx = x_dv_x(x, λ_d, θ[2])

    xgx = x_g_x(x, λ_g1, λ_g2, K_g, θ[3], θ[4])

    xubarx = x_q_x(x, λ_q, θ[5])

    xdbarx = x_q_x(x, λ_q, θ[6])

    xsx = x_q_x(x, λ_q, θ[7])

    xcx = x_q_x(x, λ_q, θ[8])

    xbx = x_q_x(x, λ_q, θ[9])

    return xuvx + xdvx + xgx + xubarx + xdbarx + xsx + xcx + xbx

end

"""
        int_xtotx(λ_u, λ_d, λ_g1, λ_g2, K_g, λ_q, θ)

Total integrated momentum density. Should equal 1.
"""
function int_xtotx(λ_u::Float64, λ_d::Float64, λ_g1::Float64, λ_g2::Float64,
                            K_g::Float64, λ_q::Float64, θ::Array{Float64})

    # Amplitudes
    fu(K_u) = θ[1] - 2 * (sf.beta(λ_u + 1, K_u + 1) / sf.beta(λ_u, K_u + 1))
    K_u = find_zero(fu, 1)
    A_u = 2 / sf.beta(λ_u, K_u + 1)

    fd(K_d) = θ[2] - (sf.beta(λ_d + 1, K_d + 1) / sf.beta(λ_d, K_d + 1))
    K_d = find_zero(fd, 1)
    A_d = 1 / sf.beta(λ_d, K_d + 1)

    A_g1 = θ[3] / sf.beta(λ_g1 + 1, K_g + 1)
    A_g2 = θ[4] / sf.beta(λ_g2 + 1, 5 + 1)

    A_ubar = (θ[5] / 2) / sf.beta(λ_q + 1, 5 + 1)

    A_dbar = (θ[6] / 2) / sf.beta(λ_q + 1, 5 + 1)

    A_s = (θ[7] / 2) / sf.beta(λ_q + 1, 5 + 1)

    A_c = (θ[8] / 2) / sf.beta(λ_q + 1, 5 + 1)

    A_b = (θ[9] / 2) / sf.beta(λ_q + 1, 5 + 1)

    # Integrate
    I_u = A_u * sf.beta(λ_u+1, K_u+1)

    I_d = A_d * sf.beta(λ_d+1, K_d+1)

    I_g = A_g1 * sf.beta(λ_g1 + 1, K_g + 1) + A_g2 * sf.beta(λ_g2 + 1, 5 + 1)

    I_q = 2 * (A_ubar + A_dbar + A_s + A_c + A_b) * sf.beta(λ_q + 1, 5 + 1)

    I_tot = I_u + I_d + I_g + I_q

    I_tot
end


text:
using Colors, Compose
set_default_graphic_size(10cm, 10cm)

include("Disk_Old.jl")

"""
    disk_compose_single(root, origin, leaf_only::Int)
"""
function disk_compose_single(root, origin, leaf_only::Int)
    leafs = []
    center = (origin[1] + (root.location[1] * cosd(root.location[2])), origin[2] + (root.location[1] * sind(root.location[2])))
    if isempty(root.parameters)
        return [draw_disk(root, origin, leaf_only)]
    else
        for i in root.parameters
            leafs = [leafs; disk_compose_single(i, center, leaf_only)]
        end

        if leaf_only != 2
            leafs = [leafs; [draw_disk(root, origin, leaf_only)]]
        end
    end
    return leafs
end

"""
    disk_compose_single_base(root, leaf_only::Int)
"""
function disk_compose_single_base(root, leaf_only::Int)
    leafs = []
    center = (0.5, 0.5)
    for i in root.parameters
        leafs = [leafs; disk_compose_single(i, center, leaf_only)]
    end

    return (context(),
    leafs...,
    (context(), circle(center[1] + (root.location[1] * cosd(root.location[2])), center[2] + (root.location[1] * sind(root.location[2])), root.radius),  fill("bisque")),
    (context(), rectangle()), fill("tomato"))
end

function main()
    root = Disk_old("a", "bisque",(0, 0), 0.45, [])
    add_disk(root, "a", Disk_old("b", s"orange", (0.235, 45), 0.2, []))
    add_disk(root, "a", Disk_old("c", "red", (0.20, 225), 0.225, []))
    add_disk(root, "b", Disk_old("d", "black", (0.04, 45), 0.1, []))
    add_disk(root, "c", Disk_old("e", "yellow", (0.1, 0), 0.1, []))
    add_disk(root, "c", Disk_old("e", "lime", (0.1, 180), 0.05, []))
    compose(context(), disk_compose_single_base(root,0))
end

main()

max_stars_repo_path: src/Old Code/Disk_Only.jl

max_issues_repo_path: src/Old Code/Disk_Only.jl

max_forks_repo_path: src/Old Code/Disk_Only.jl


text:
#
# Autogenerated by Thrift Compiler (0.11.0)
#
# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING

module PAR2

using Thrift
import Thrift.process, Thrift.meta, Thrift.distribute

export meta
export _Type # enum
export ConvertedType # enum
export FieldRepetitionType # enum
export Encoding # enum
export CompressionCodec # enum
export PageType # enum
export BoundaryOrder # enum
export Statistics # struct
export StringType # struct
export UUIDType # struct
export MapType # struct
export ListType # struct
export EnumType # struct
export DateType # struct
export NullType # struct
export DecimalType # struct
export MilliSeconds # struct
export MicroSeconds # struct
export NanoSeconds # struct
export TimeUnit # struct
export TimestampType # struct
export TimeType # struct
export IntType # struct
export JsonType # struct
export BsonType # struct
export LogicalType # struct
export SchemaElement # struct
export DataPageHeader # struct
export IndexPageHeader # struct
export DictionaryPageHeader # struct
export DataPageHeaderV2 # struct
export SplitBlockAlgorithm # struct
export BloomFilterAlgorithm # struct
export XxHash # struct
export BloomFilterHash # struct
export Uncompressed # struct
export BloomFilterCompression # struct
export BloomFilterHeader # struct
export PageHeader # struct
export KeyValue # struct
export SortingColumn # struct
export PageEncodingStats # struct
export ColumnMetaData # struct
export EncryptionWithFooterKey # struct
export EncryptionWithColumnKey # struct
export ColumnCryptoMetaData # struct
export ColumnChunk # struct
export RowGroup # struct
export TypeDefinedOrder # struct
export ColumnOrder # struct
export PageLocation # struct
export OffsetIndex # struct
export ColumnIndex # struct
export AesGcmV1 # struct
export AesGcmCtrV1 # struct
export EncryptionAlgorithm # struct
export FileMetaData # struct
export FileCryptoMetaData # struct

include("PAR2_constants.jl")
include("PAR2_types.jl")
include("PAR2_impl.jl")  # server methods to be hand coded

end # module PAR2


text:
@testset "Abstract flowpipe interface" begin
    prob, dt = harmonic_oscillator()
    sol = solve(prob, tspan=dt)
    fp = flowpipe(sol)

    # base, numeric, set and reach-set types
    FT = typeof(fp)
    @test basetype(FT) == basetype(fp) == Flowpipe
    N = ReachabilityAnalysis.numtype(fp)
    @test N == Float64
    ZT = Zonotope{N, Vector{N}, Matrix{N}}
    @test setrep(FT) == ZT
    @test rsetrep(fp) == ReachSet{N, ZT}

    # ambient dimension
    @test dim(fp) == 2

    # indexing
    @test first(fp) == fp[1] === fp.Xk[1]
    @test last(fp) == fp[end] === fp.Xk[end]
    @test length(fp) == length(fp.Xk) == numrsets(fp)
    @test set(fp, 3) === set(fp[3])
    @test set(fp, 3:5) isa UnionSetArray
    @test set(fp) isa UnionSetArray
    @test array(fp) === fp.Xk

    # time domain interface
    @test tstart(fp) ≈ 0.0 && dt[1] ≈ 0.0
    @test tend(fp) ≈ 20.0 && dt[2] ≈ 20.0
    @test RA._isapprox(tspan(fp), 0 .. 20)
    @test vars(fp) == (1, 2)
end

@testset "Flowpipe set operations interface" begin
    prob, dt = harmonic_oscillator()
    sol = solve(prob, tspan=dt)
    fp = flowpipe(sol)

    # support function and support vector
    d = ones(2)
    @test ρ(d, fp) < 2.0
    @test σ(d, fp) ≈ [0.7329355092, 0.7092773487]

    # disjointness
    H = HalfSpace(d, 2.0)
    Hc = complement(H)

    # inclusion

    # membership

end

@testset begin "Flowpipe inclusion"
    # Projectile problem
    A = [0. 0.5 0. 0. ; 0. 0. 0. 0. ; 0. 0. 0. 0.7 ; 0. 0. 0. 0.]
    X0 = Singleton([0.,5.,100.,0])
    U = Singleton([0.,0.,0.,-9.81])
    prob = @ivp(x' = A * x + Matrix(1.0I, 4, 4) * u,  x(0) ∈ X0, u ∈ U, x ∈ Universe(4))
    cons = LinearConstraint([24., 0., 1, 0], 375.)
    sol = solve(prob, T=20.0, δ=1e-2)

    # equivalent ways
    @test all(set(R) ⊆ cons for R in sol)
    @test all(R ⊆ cons for R in sol)
    @test sol ⊆ cons
end

@testset "Flowpipe constructors" begin
    # uninitialized array constructor
    # if the set type is passed, then a ReachSet is used by default
    fp = Flowpipe(undef, Singleton{Float64, Vector{Float64}}, 3)
    @test length(fp) == 3
    @test_throws UndefRefError dim(fp) # fp is not empty but its dimension is not defined
    @test setrep(fp) == Singleton{Float64, Vector{Float64}}

    # the reach-set type can be passed directly
    fpr = Flowpipe(undef, ReachSet{Float64, Singleton{Float64, Vector{Float64}}}, 3)
    @test length(fpr) == 3
    @test typeof(fpr) == typeof(fp)
    @test setrep(fpr) == Singleton{Float64, Vector{Float64}}

    # try another reach-set type
    RSP = SparseReachSet{Float64, Singleton{Float64, Vector{Float64}}, 2}
    fp = Flowpipe(undef, RSP, 3)
    @test length(fp) == 3
    @test dim(fp) == 2 # in this set type, the dimension is known
    @test setrep(fp) == Singleton{Float64, Vector{Float64}}
end

@testset "Hybrid flowpipe time evaluation" begin
    X = Interval(0 .. 1)
    δ = 0.1
    F1 = Flowpipe([ReachSet(X, (0 .. δ) + k*δ) for k in 0:10])
    F2 = Flowpipe([ReachSet(X, (0 .. δ) + k*δ) for k in 9:20])
    F2′ = Flowpipe([ReachSet(X, (0 .. δ) + k*δ*0.9) for k in 9:20])
    H = HybridFlowpipe([F1, F2])
    H′ = HybridFlowpipe([F1, F2′])

    times = 0:0.01:1.9
    values = [[x] for x in (@. 1 - exp(-times))]
    @test all(vi ∈ H(ti) for (ti, vi) in zip(times, values))
    @test all(vi ∈ H′(ti) for (ti, vi) in zip(times, values))
end

@testset "Flowpipe clustering" begin
    X = Interval(0 .. 1)
    δ = 0.1
    F1 = Flowpipe([ReachSet(X, (0 .. δ) + k*δ) for k in 0:10])

    #= FIXME requires LazySets#2157
    N = eltype(X)
    U1 = cluster(F1, 8:10, UnionClustering())
    @test U1 isa Vector{ReachSet{N, UnionSetArray{N,Interval{N, IA.Interval{N}}}}}
    @test set(first(U1)) == UnionSetArray([set(Fi) for Fi in F1[8:10]])

    # Test ReachabilityAnalysis#347
    prob, dt = vanderpol()
    sol = solve(prob, tspan=(0.0, 3.0));
    fp = flowpipe(sol)
    cl = cluster(fp, [1, 2, 3], UnionClustering());
    @test length(cl) == 1 && typeof(set(first(cl))) <: UnionSetArray
    =#
end


text:
module DLagrangianFESpaces

using Gridap
using Gridap.Helpers
using Gridap.CellValuesGallery
using Gridap.CLagrangianFESpaces: _setup_reffe
using Gridap.CLagrangianFESpaces: _setup_cellbasis
using Gridap.CLagrangianFESpaces: _S
using Gridap.CLagrangianFESpaces: _compute_comp_to_dof
using Gridap.CLagrangianFESpaces: _setup_grid
using Gridap.CLagrangianFESpaces: _setup_masks
using Gridap.CLagrangianFESpaces: _eval
using Gridap.CLagrangianFESpaces: _eval_bc
using Gridap.ConformingFESpaces: _CellField
using Gridap.BoundaryGrids: _setup_tags

export DLagrangianFESpace

import Gridap: num_free_dofs
import Gridap: num_diri_dofs
import Gridap: diri_tags
import Gridap: apply_constraints
import Gridap: apply_constraints_rows
import Gridap: apply_constraints_cols
import Gridap: celldofids
import Gridap: interpolate_values
import Gridap: interpolate_diri_values
import Gridap: CellField
import Gridap: CellBasis
import Gridap: Triangulation

struct DLagrangianFESpace{D,Z,T,B} <: FESpace{D,Z,T}
  grid::Grid{D,Z}
  node_to_label::Vector{Int}
  tag_to_labels::Vector{Vector{Int}}
  diritags::Vector{Int}
  dirimasks::Vector{B}
  nfreedofs::Int
  ndiridofs::Int
  cell_to_dofs::CellVector{Int}
  reffe::LagrangianRefFE{Z,T}
  cellbasis::CellBasis{Z,T}
  diricells::Vector{Int}
end

function DLagrangianFESpace(
  ::Type{T},
  grid::Grid{D,Z},
  node_to_label::AbstractVector{<:Integer},
  tag_to_labels::Vector{Vector{Int}},
  diritags::Vector{Int},
  dirimasks::Vector{B}) where {D,Z,T,B}

  cell_to_nodes = cells(grid)
  reffe = _setup_reffe(T,celltypes(grid),cellorders(grid))
  cellbasis = _setup_cellbasis(reffe,grid)

  lnode_and_comp_to_ldof = reffe.dofbasis.node_and_comp_to_dof

  cell_to_dofs, nfreedofs, ndiridofs, diricells = _setup_cell_to_dofs(
    cell_to_nodes,
    node_to_label,
    tag_to_labels,
    diritags,
    dirimasks,
    lnode_and_comp_to_ldof,
    T)

  DLagrangianFESpace{D,Z,T,B}(
    grid,
    node_to_label,
    tag_to_labels,
    diritags,
    dirimasks,
    nfreedofs,
    ndiridofs,
    cell_to_dofs,
    reffe,
    cellbasis,
    diricells)

end

function DLagrangianFESpace(
  ::Type{T},
  model::DiscreteModel,
  order::Integer,
  diritags=Int[],
  dirimasks=nothing) where T
  DLagrangianFESpace(T,model,FaceLabels(model),order,diritags,dirimasks)
end

function DLagrangianFESpace(
  ::Type{T},
  model::DiscreteModel,
  facelabels::FaceLabels,
  order::Integer,
  diritags=Int[],
  dirimasks=nothing) where T

  _diri_tags = _setup_tags(facelabels,diritags)
  _diri_masks = _setup_masks(T,_diri_tags,dirimasks)

  grid, node_to_label, tag_to_labels = _setup_grid(model,facelabels,order)

  DLagrangianFESpace(
    T,grid,node_to_label,tag_to_labels,_diri_tags,_diri_masks)

end

num_free_dofs(fesp::DLagrangianFESpace) = fesp.nfreedofs

num_diri_dofs(fesp::DLagrangianFESpace) = fesp.ndiridofs

diri_tags(fesp::DLagrangianFESpace) = fesp.diritags

apply_constraints(
  ::DLagrangianFESpace, cellvec::CellVector, cellids::CellNumber) = cellvec

apply_constraints_rows(
  ::DLagrangianFESpace, cellmat::CellMatrix, cellids::CellNumber) = cellmat

apply_constraints_cols(
  ::DLagrangianFESpace, cellmat::CellMatrix, cellids::CellNumber) = cellmat

celldofids(fesp::DLagrangianFESpace) = fesp.cell_to_dofs

function CellField(
  fesp::DLagrangianFESpace{D,Z,T},
  free_dofs::AbstractVector{E},
  diri_dofs::AbstractVector{E}) where {D,Z,T,E}

  _CellField(fesp, free_dofs, diri_dofs, T, E)
end

function interpolate_values(fesp::DLagrangianFESpace,fun::Function)
  _interpolate_values(fesp,fun)
end

function interpolate_values(fesp::DLagrangianFESpace{D,Z,T},val::T) where {D,Z,T}
  _interpolate_values(fesp,val)
end

function _interpolate_values(fesp::DLagrangianFESpace,fun)

  zh = zero(fesp)
  fdof_to_val = free_dofs(zh)
  ddof_to_val = diri_dofs(zh)
  node_to_coords = points(fesp.grid)
  lnode_and_comp_to_ldof = fesp.reffe.dofbasis.node_and_comp_to_dof
  cell_to_dofs = fesp.cell_to_dofs
  cell_to_nodes = cells(fesp.grid)
  node_comp_to_val = _eval_bc(fun,node_to_coords)

  _fill_interpolated_vals!(
    fdof_to_val,
    ddof_to_val,
    node_comp_to_val,
    cell_to_nodes,
    cell_to_dofs,
    lnode_and_comp_to_ldof)

  (fdof_to_val, ddof_to_val)
end

function interpolate_diri_values(fesp::DLagrangianFESpace, funs::Vector{<:Function})
  _interpolate_diri_values(fesp, funs)
end

function interpolate_diri_values(fesp::DLagrangianFESpace{D,Z,T}, vals::Vector{T}) where {D,Z,T}
  _interpolate_diri_values(fesp, vals)
end

function _interpolate_diri_values(fesp::DLagrangianFESpace, funs)

  T = value_type(fesp)
  E = eltype(T)
  ndiri = num_diri_dofs(fesp)
  ddof_to_val = zeros(E,ndiri)
  node_to_label = fesp.node_to_label
  tag_to_labels = fesp.tag_to_labels
  diricells = fesp.diricells
  lnode_and_comp_to_ldof = fesp.reffe.dofbasis.node_and_comp_to_dof
  cell_to_dofs = fesp.cell_to_dofs
  cell_to_nodes = cells(fesp.grid)
  node_to_coords = points(fesp.grid)

  for (fun,diritag,dirimask) in zip(funs,fesp.diritags,fesp.dirimasks)
    _fill_diri_values!(
      ddof_to_val,
      fun,
      diritag,
      dirimask,
      diricells,
      node_to_label,
      tag_to_labels,
      node_to_coords,
      cell_to_nodes,
      cell_to_dofs,
      lnode_and_comp_to_ldof)
  end

  ddof_to_val

end

CellBasis(fesp::DLagrangianFESpace{D,Z,T}) where {D,Z,T} = fesp.cellbasis

Triangulation(fesp::DLagrangianFESpace) = Triangulation(fesp.grid)

# Helpers

function _fill_diri_values!(
  ddof_to_val,
  fun,
  diritag,
  dirimask,
  diricells,
  node_to_label,
  tag_to_labels,
  node_to_coords,
  cell_to_nodes,
  cell_to_dofs,
  lnode_and_comp_to_ldof)

  for cell in diricells

    lnode_to_node = cell_to_nodes[cell]
    ldof_to_dof = cell_to_dofs[cell]

    for (lnode,node) in enumerate(lnode_to_node)
      label = node_to_label[node]
      if label in tag_to_labels[diritag]

        coords = node_to_coords[node]
        comp_to_val = _eval(fun,coords)

        for comp in eachindex(dirimask)
          mask = dirimask[comp]
          if mask
            val = comp_to_val[comp]
            ldof = lnode_and_comp_to_ldof[lnode,comp]
            dof = ldof_to_dof[ldof]
            ddof = -dof
            ddof_to_val[ddof] = val
          end
        end

      end
    end

  end

end

function  _fill_interpolated_vals!(
  fdof_to_val,
  ddof_to_val,
  node_comp_to_val,
  cell_to_nodes,
  cell_to_dofs,
  lnode_and_comp_to_ldof)

  ncells = length(cell_to_nodes)

  nlnodes, ncomps = size(lnode_and_comp_to_ldof)

  for cell in 1:ncells

    lnode_to_node = cell_to_nodes[cell]
    ldof_to_dof = cell_to_dofs[cell]

    for (lnode,node) in enumerate(lnode_to_node)
      comp_to_val = node_comp_to_val[node]
      for comp in 1:ncomps
        ldof = lnode_and_comp_to_ldof[lnode,comp]
        dof = ldof_to_dof[ldof]
        val = comp_to_val[comp]
        if dof > 0
          fdof_to_val[dof] = val
        elseif dof < 0
          ddof_to_val[-dof] = val
        else
          @unreachable
        end
      end
    end

  end

end

function _setup_cell_to_dofs(
  cell_to_nodes,
  node_to_label,
  tag_to_labels,
  diritags,
  dirimasks,
  lnode_and_comp_to_ldof,
  ::Type{T}) where T

  ncells = length(cell_to_nodes)
  nlnodes, ncomp = size(lnode_and_comp_to_ldof)
  nldofs = nlnodes * ncomp

  ndata = ncells*nldofs

  cell_to_dofs_data = zeros(Int,ndata)
  diricells = Int[]

  nfreedofs, ndiridofs = _fill_cell_to_dofs!(
    cell_to_dofs_data,
    diricells,
    cell_to_nodes,
    node_to_label,
    tag_to_labels,
    diritags,
    dirimasks,
    lnode_and_comp_to_ldof,
    T)

  cell_to_dofs = CellVectorFromDataAndStride(cell_to_dofs_data,nldofs)

  (cell_to_dofs, nfreedofs, ndiridofs, diricells)
end

function _fill_cell_to_dofs!(
  cell_to_dofs_data,
  diricells,
  cell_to_nodes,
  node_to_label,
  tag_to_labels,
  diritags,
  dirimasks,
  lnode_and_comp_to_ldof,
  ::Type{T}) where T

  ncells = length(cell_to_nodes)
  nlnodes, ncomp = size(lnode_and_comp_to_ldof)
  nldofs = nlnodes * ncomp
  S = _S(T)

  fdof = 1
  ddof = -1
  k = 0

  for cell in 1:ncells

    nodes = cell_to_nodes[cell]
    isdiricell = false

    for (lnode,node) in enumerate(nodes)

      label = node_to_label[node]
      comp_to_dof, fdof, ddof, isdirinode =
        _compute_comp_to_dof(
        S,label,tag_to_labels,diritags,dirimasks,fdof,ddof)

      for comp in eachindex(comp_to_dof)
        ldof = lnode_and_comp_to_ldof[lnode,comp]
        dof = comp_to_dof[comp]
        cell_to_dofs_data[k+ldof] = dof
      end

      if isdirinode
        isdiricell = true
      end

    end

    if isdiricell
      push!(diricells,cell)
    end

    k += nldofs

  end

  (fdof-1, -(ddof+1))

end

end # module


text:
# A component for an emissions pulse to be used in social cost calculations. Computes the `output` vector by adding
#   `add` to `input`. This is similar to the Mimi.adder component, except that it allows missing values to be passed through.

@defcomp emissionspulse begin
    add    = Parameter(index=[time])
    input  = Parameter(index=[time])
    output = Variable(index=[time])

    function run_timestep(p, v, d, t)
        v.output[t] = Mimi.@allow_missing(p.input[t]) + p.add[t]
    end
end

function create_marginal_fundfair162_model(m; year::Int64, pulse_size = 1e7, gas::Symbol = :CO2)

    if gas == :CO2

        mm = Mimi.create_marginal_model(m, pulse_size)

        # Add additional emissions to mm.modified
        add_comp!(mm.modified, emissionspulse, after = :emissions)
        nyears = length(Mimi.time_labels(m))
        addem = zeros(nyears)
        baseyear = 1750
        # if year != nothing
        #     # pulse is spread over ten years, and emissions components is in Mt so divide by 1e7, and convert from CO2 to C if gas==:CO2 because emissions component is in MtC
            addem[(year - baseyear + 1):(year - baseyear + 1) + 9] .= pulse_size / 1e7 * (gas == :CO2 ? 12/44 : 1)
            # addem[(year - baseyear + 1):(year - baseyear + 1)] .= pulse_size / 1e6 * (gas == :CO2 ? 12/44 : 1) # 1-year pulse
        # end
        set_param!(mm.modified, :emissionspulse, :add, addem)

        # Reconnect the appropriate emissions in m
        connect_param!(mm.modified, :emissionspulse, :input, :emissions, :mco2, zeros(nyears), backup_offset = 1)
        connect_param!(mm.modified, :multiplier, :input, :emissionspulse, :output)
    elseif gas == :CH4

        mm = Mimi.create_marginal_model(m, pulse_size/10) # only a 1 year pulse

        pulse_year_index = findall((in)([year]), collect(1750:2300))

        # perturb CH4 emissions
        new_emissions = deepcopy(mm.base[:ch4_cycle, :fossil_emiss_CH₄])
        new_emissions[pulse_year_index] = new_emissions[pulse_year_index] .+ (pulse_size/1e7) # 1MtCH4 pulse

        # update emissions parameter
        Mimi.set_param!(mm.modified, :fossil_emiss_CH₄, new_emissions)

    elseif gas == :N2O

        mm = Mimi.create_marginal_model(m, pulse_size/10) # 1 year pulse

        pulse_year_index = findall((in)([year]), collect(1750:2300))

        # perturb N2O emissions
        new_emissions = deepcopy(mm.base[:n2o_cycle, :fossil_emiss_N₂O])
        new_emissions[pulse_year_index] = new_emissions[pulse_year_index] .+ (pulse_size/1e7 * 28/44) # N2O emissions are in MtN2, multiply by 28/44 to make it a 1MtN2O pulse

        # update emissions parameter
        Mimi.set_param!(mm.modified, :fossil_emiss_N₂O, new_emissions)

    end

    run(mm)

    return(mm)

end

function compute_fundfair162_sc(mm; rate::Float64, year::Int64, start_year::Int64 = 1750, end_year::Int64 = 2300)

    marginaldamage = mm[:impactaggregation, :loss]

    # calculate discount factors
    new_years = collect(start_year:1:end_year)
    year_index = findfirst(isequal(year), new_years)

    df = zeros(length(new_years), 16)
    for i in 1:length(new_years)
        if i >= year_index
            df[i,:] .= 1/(1+rate)^(i-year_index)
        end
    end

    # calculate SCGHG
    sc = sum(skipmissing(marginaldamage .* df))
    return(sc)

end


text:
using Pkg

Pkg.activate(@__DIR__)
Pkg.instantiate()

using PackageCompiler

cd(@__DIR__)

create_sysimage([:RoME,:Gadfly,:GraphPlot,:DistributedFactorGraphs,:Compose], sysimage_path="RoMEGadflySysimage.so", precompile_execution_file="precompile_triggers_gadfly.jl")

## to use RoME Gadfly and the associated Pkgs with the newly created sysimage, start julia with:
# julia -J RoMEGadflySysimage.so


text:
import ..Filter
import ..Wirreducible  #remove all polarization subdiagrams
import ..Girreducible  #remove all self-energy inseration
import ..NoHatree
import ..NoFock
import ..NoBubble  # true to remove all bubble subdiagram
import ..Proper  #ver4, ver3, and polarization diagrams may require to be irreducible along the transfer momentum/frequency

import ..DiagramType
import ..GreenDiag
import ..SigmaDiag
import ..PolarDiag
import ..Ver3Diag
import ..Ver4Diag

import ..Composite
import ..ChargeCharge
import ..SpinSpin
import ..UpUp
import ..UpDown
import ..Response

import ..Instant
import ..Dynamic
import ..D_Instant
import ..D_Dynamic
import ..AnalyticProperty

import ..symbol
import ..short

import ..Interaction
import ..GenericPara
import ..innerTauNum

import ..Diagram

import ..DiagramId
import ..Ver4Id
import ..Ver3Id
import ..GreenId
import ..SigmaId
import ..PolarId
import ..BareInteractionId
import ..BareGreenId

import ..TwoBodyChannel
import ..Alli
import ..PHr
import ..PHEr
import ..PPr
import ..AnyChan

import ..Permutation
import ..Di
import ..Ex
import ..DiEx

import ..uidreset
import ..toDataFrame
import ..mergeby


text:
function unwrap(coord::Vector{Vector{Vector{Vector{Float64}}}})
    @assert length(coord) == 1
    @assert length(coord[1]) == 1
    segcoord = coord[1][1];
end

function unwrap(coord::Vector{Vector{Vector{Float64}}})
    @assert length(coord) == 1
    segcoord = coord[1];
end

function gshhg(io::IO)
    handle = read(io, Shapefile.Handle)

    segments = NTuple{2,Vector{Float64}}[]
    #Channel(ctype = NTuple{2,Vector{Float64}}) do channel
    for i = 1:length(handle.shapes)
        segcoord = unwrap(GeoInterface.coordinates(handle.shapes[i]))

        seglen = length(segcoord)

        segment = (Vector{Float64}(undef,seglen),Vector{Float64}(undef,seglen))
        for l = 1:seglen
            segment[1][l] = segcoord[l][1]
            segment[2][l] = segcoord[l][2]
        end

        push!(segments,segment)
        #put!(channel,segment)
    end
    #end
    return segments
end

function findfile(dir::ZipFile.Reader, name)
    for f in dir.files
        if f.name == name
            return f
        end
    end
    nothing
end

function gshhgload(fname::AbstractString)
    @debug "fname $fname"
    @RemoteFile(gshhg_shp, "http://www.soest.hawaii.edu/pwessel/gshhg/gshhg-shp-2.3.7.zip")
    download(gshhg_shp)
    zip = ZipFile.Reader(path(gshhg_shp))

    io = findfile(zip,fname)
    if io == nothing
        error("Shapefile $fname is not found in $(path(gshhg_shp))")
    end
    # does not work
    # tmp = gshhg(io)
    data = read(io);
    close(zip)
    return gshhg(IOBuffer(data))
end

"""
    segments = GeoDatasets.gshhg(res,level::Integer)
    segments = GeoDatasets.gshhg(res,levels::AbstractArray{<:Integer})

Extract a list of coastlines from the [Global Self-consistent, Hierarchical, High-resolution Geography Database](https://www.soest.hawaii.edu/pwessel/gshhg/) (about 150 Mb) at the resolution `res` (`'f'`,`'h'`,`'i'`,`'l'` or `'c'`) and the level `level` (see below). An array of multiple levels can also be provided as the parameter `levels`. `segments` is a vector of tuples representing a closed shoreline. Each tuple is composed by a longitude and latitude vector.

The GSHHG is released under the [GNU Lesser General Public License (Version 3)](http://www.gnu.org/licenses/lgpl.html) and is described in
Wessel, P., and W. H. F. Smith, [A Global Self-consistent, Hierarchical, High-resolution Shoreline Database](https://www.soest.hawaii.edu/pwessel/gshhg/Wessel+Smith_1996_JGR.pdf), J. Geophys. Res., 101, 8741-8743, 1996.

The GSHHG database integrates the [CIA World Data Bank II (WDBII)](http://www.evl.uic.edu/pape/data/WDB) for political borders and rivers.

Resolution is one of the following:

| `res` | Resolution               |
|-------|--------------------------|
|   f   | Full resolution          |
|   h   | High resolution          |
|   i   | Intermediate resolution  |
|   l   | Low resolution           |
|   c   | Crude resolution         |

The shoreline data are distributed in 6 levels:

| `level` |                                                              |
|---------|:-------------------------------------------------------------|
|       1 | Continental land masses and ocean islands, except Antarctica |
|       2 | Lakes                                                        |
|       3 | Islands in lakes                                             |
|       4 | Ponds in islands within lakes                                |
|       5 | Antarctica based on ice front boundary                       |
|       6 | Antarctica based on grounding line boundary                  |

If the 2nd parameter `levels` is ommited, then level 1 and 5 are loaded.

"""
gshhg(res,level::Integer) = gshhgload("GSHHS_shp/$(res)/GSHHS_$(res)_L$(level).shp")
# load multiple levels
gshhg(res,levels::AbstractArray{<:Integer} = [1,5]) = reduce(vcat,gshhg.(res,levels))

"""
    segments = GeoDatasets.WDBII_river(res,level::Integer)
    segments = GeoDatasets.WDBII_river(res,levels::AbstractArray{<:Integer})

Extract rivers from the WDBII database. See `GeoDatasets.gshhg` for more information.

The river database comes with 11 levels:

| `level` |                                   |
|---------|:----------------------------------|
|       1 | Double-lined rivers (river-lakes) |
|       2 | Permanent major rivers            |
|       3 | Additional major rivers           |
|       4 | Additional rivers                 |
|       5 | Minor rivers                      |
|       6 | Intermittent rivers - major       |
|       7 | Intermittent rivers - additional  |
|       8 | Intermittent rivers - minor       |
|       9 | Major canals                      |
|      10 | Minor canals                      |
|      11 | Irrigation canals                 |
"""
WDBII_river(res,level::Integer) = gshhgload("WDBII_shp/$(res)/WDBII_river_$(res)_L$(@sprintf("%02d",level)).shp")
WDBII_river(res,levels::AbstractArray{<:Integer}) = reduce(vcat,WDBII_river.(res,levels))

"""
    segments = GeoDatasets.WDBII_border(res,level::Integer)
    segments = GeoDatasets.WDBII_border(res,levels::AbstractArray{<:Integer})

Extract borders from the WDBII database. See `GeoDatasets.gshhg` for more information.

The political boundary data come in 3 levels:

| `level` |                                                              |
|---------|--------------------------------------------------------------|
|       1 | National boundaries                                          |
|       2 | Internal (state) boundaries for the 8 largest countries only |
|       3 | Maritime boundaries                                          |

If the 2nd parameter `level` is ommited, then level 1 (National boundaries) are loaded.
"""
WDBII_border(res,level::Integer = 1) = gshhgload("WDBII_shp/$(res)/WDBII_border_$(res)_L$(level).shp")
WDBII_border(res,levels::AbstractArray{<:Integer}) = reduce(vcat,WDBII_border.(res,levels))

max_stars_repo_name: JuliaGeo/GeoDatasets

max_issues_repo_name: JuliaGeo/GeoDatasets

max_forks_repo_name: JuliaGeo/GeoDatasets


text:
# This file was generated, do not modify it. # hide
X = [1 2; 3 4; 5 6]
@show X[1, 2]
@show X[:, 1]
@show X[1, :]
@show X[[1, 2], [1, 2]]


text:
# using DataStructures
# using Graphs
# using Statistics
# using Combinatorics

# lines = readlines("inputs/11-15/11ex.txt")
lines = readlines("inputs/11-15/11.txt")
nums = [[parse(Int, x) for x in line] for line in lines]

# 2D list
getat = function(x,y, M, default=-1)
  h = length(M)
  w = length(M[1])
  if x < 1 || y < 1 || x > h || y > w
    return default
  end
  return M[x][y]
end

incv! = function(x,y, M)
  h = length(M)
  w = length(M[1])
  if x < 1 || y < 1 || x > h || y > w
    return M
  end
  M[x][y] += 1
  return M
end

setat! = function(x,y,M,b)
  h = length(M)
  w = length(M[1])
  if x < 1 || y < 1 || x > h || y > w
    return M
  end
  M[x][y] = b
  return M
end

function day11()
  t = 0
  p2 = 0
  for step in 1:500
    # inc all by 1
    for r in 1:10
      for c in 1:10
        nums[r][c] += 1
      end
    end
    flashed = [[false for _ in 1:10] for _ in 1:10]
    for _ in 1:100
      for r in 1:10
        for c in 1:10
          if getat(r,c,nums) > 9
            for dr in [-1,0,1], dc in [-1,0,1]
              incv!(r+dr,c+dc,nums)
            end
            t += 1
            setat!(r,c,flashed,true)
          end
        end
      end

      for r in 1:10
        for c in 1:10
          if flashed[r][c]
            nums[r][c] = 0
          end
        end
      end
    end
    allf = true
    for r in 1:10
      for c in 1:10
        if !flashed[r][c]
          allf = false
        end
      end
    end
    if allf
      p2 = step
      return step
      break
    end
  end
end

function octopus_step!(model)
  # increase agent energys
  for agent in allagents(model)
    agent.energy += 1
  end
  while true
    update = false
    for agent in allagents(model)
      if !agent.flashed && agent.energy > 9
        update = true
        agent.flashed = true
        for neighbor in nearby_agents(agent, model)
          neighbor.energy += 1
        end
      end
    end
    for agent in allagents(model)
      agent.flashed = false
    end
    if !update
      break
    end
  end
  for agent in allagents(model)
    if agent.flashed
      agent.flashed = false
      agent.energy = 0
    end
  end
end


text:
using Kalman
using Test
using StaticArrays
using Random, LinearAlgebra
using Distributions
using GaussianDistributions
using DynamicIterators
using Trajectories

#include(joinpath("..", "docs", "make.jl"))

Random.seed!(1)

include("testevolution.jl")
include("testobservation.jl")

include("testkalman1.jl")
include("testkalman2.jl")
include("testsmoother.jl")

include("../example/readme.jl")

# include("testmisc.jl") fixed on master


text:
using Poly
using MacroTools

export get_best_nesting_order

"""
return the striding level of iter in ex
if i is the first dimension (i.e A[i, j], with i), returns 0
    etc for larger dimensions

ex: A[i, j] doesn't stride in i and strides in dimension 1 with j
"""
function striding_level(ex::Expr, iter::Symbol)::Int
    level = 0
    if ex.head == :ref
        for (i, sym) in enumerate(ex.args[2:end])
            if sym == iter
                level += i-1
            elseif typeof(sym) == Expr
                if inexpr(sym, iter)
                    level += i-1
                end
            end
        end
    else
        for arg in ex.args
            level += striding_level(arg, iter)
        end
    end
    return level
end

function striding_level(ex, iter::Symbol)::Int
    return 0
end

"""
Returns the overall striding level of domains for grouping of domains
"""
function get_loop_stride_counts(kernel::LoopKernel)::Dict{Symbol, Int}
    stride_counts = Dict{Symbol, Int}()
    for domain in kernel.domains
        stride_counts[domain.iname] = 0
        for instruction in kernel.instructions
            if typeof(instruction) == Instruction
                stride_counts[domain.iname] += striding_level(instruction.body, domain.iname)
            end
        end
    end
    return stride_counts
end

"""
Determines if domain can be inserted given list of already inserted domains
"""
function can_insert_domain(domain::Domain, order::Vector{Symbol}, kernel::LoopKernel)::Bool
    symbols = get_all_symbols(domain.lowerbound)
    union!(symbols, get_all_symbols(domain.upperbound))
    union!(symbols, get_all_symbols(domain.step))
    for sym in symbols
        if !(sym in order || sym in kernel.consts)
            return false
        end
    end
    return true
end

"""
helper for nesting order, returns nesting order for a grouping of domains starting at parent domain
"""
function get_best_nesting_order_on_domains(parent_domain::Domain, stride_order::Vector{Symbol}, kernel::LoopKernel)::Vector{Symbol}
    nesting_order = Symbol[]
    # first domain
    parent = parent_domain
    child = :none
    for instruction in parent.instructions
        if typeof(instruction) == Domain
            # found sub domain child
            child = instruction
            break
        end
    end
    # keep track of domains that can be reordered
    can_reorder = Set{Domain}()
    # add parent to right place
    if length(parent.instructions) == 1 && child != :none
        # can reorder later
        push!(can_reorder, parent)
    else
        # add in order now
        push!(nesting_order, parent.iname)
    end
    # keep reordering while sub domains exist
    while child != :none
        # can reorder if only one child
        if length(parent.instructions) == 1 # just one child domain
            push!(can_reorder, child)
        else # cannot reorder
            while length(can_reorder) > 0
                # find first in stride order and can reorder that can be added
                i = findfirst(stride_order) do item
                  good = false
                  for domain in can_reorder
                      if domain.iname == item && can_insert_domain(domain, nesting_order, kernel)
                          good = true
                          delete!(can_reorder, domain)
                          break
                      end
                  end
                  good
                end

                push!(nesting_order, stride_order[i])
            end
            # add children in right order
            for sub in parent.instructions
                if typeof(sub) == Domain
                    push!(nesting_order, sub.iname)
                end
            end
        end
        # get next parent and child
        parent = child
        child = :none
        for instruction in parent.instructions
            if typeof(instruction) == Domain
                child = instruction
                break
            end
        end
    end
    # done, add remaining parent and rest in reorder set
    while length(can_reorder) > 0
        # find first in stride order and can reorder that can be added
        i = findfirst(stride_order) do item
          good = false
          for domain in can_reorder
              if domain.iname == item && can_insert_domain(domain, nesting_order, kernel)
                  good = true
                  delete!(can_reorder, domain)
                  break
              end
          end
          good
        end

        if i == nothing
            break
        end

        push!(nesting_order, stride_order[i])
    end
    # add last domain
    if !(parent.iname in nesting_order)
        push!(nesting_order, parent.iname)
    end
    return nesting_order
end

"""
determines the best valid loop nesting order for groupings of domains (all in continuous nest (one sub domain per domain))
"valid" if loops have no other instructions between them
"best" if innermost loop has the least amount of striding
"""
function get_best_nesting_orders(kernel::LoopKernel)::Set{Vector{Symbol}}
    stride_counts = get_loop_stride_counts(kernel)
    stride_order = sort(collect(keys(stride_counts)), by=(x -> stride_counts[x]), rev=true) # sort least to most striding
    visited = Symbol[]
    nesting_orders = Set{Vector{Symbol}}()
    for domain in kernel.domains
        if !(domain.iname in visited)
            count = 0
            for child in domain.instructions
                if typeof(child) == Domain
                    count += 1
                end
            end
            if count == 1
                order = get_best_nesting_order_on_domains(domain, stride_order, kernel)
                append!(visited, order)
                push!(nesting_orders, order)
            end
        end
    end
    return nesting_orders
end

"""
reorder the loops of a band node's partial schedule
"""
function reorder_band(band::Ptr{ISL.API.isl_schedule_node}, loop_ordering::Set{Vector{Symbol}}, context::Ptr{ISL.API.isl_ctx})
    # get schedule of band
    sched = ISL.API.isl_schedule_node_band_get_partial_schedule(band)
    # make a copy of the schedule (isl_copy does not return a copy but the actual reference)
    sched_str = ISL.API.isl_multi_union_pw_aff_to_str(sched)
    sched_str = Base.unsafe_convert(Ptr{Cchar}, sched_str)
    sched_str = Base.unsafe_string(sched_str)
    sched_copy = ISL.API.isl_multi_union_pw_aff_read_from_str(context, sched_str)
    # number of upa in sched
    n = ISL.API.isl_multi_union_pw_aff_dim(sched_copy, ISL.API.isl_dim_type(3))
    count = 0
    upas = []
    for i=0:n-1
        # read from copy
        upa = ISL.API.isl_multi_union_pw_aff_get_union_pw_aff(sched_copy, i)
        push!(upas, (false, upa))
    end

    # warm up
    # this is messy, but there is no way to set a partial schedule of a band
    # this sets the first element so that there are no more references known to the mupa
    # then, we can modify the mupa of the band directly
    upa_str = ISL.API.isl_union_pw_aff_to_str(upas[1][2])
    upa_str = Base.unsafe_convert(Ptr{Cchar}, upa_str)
    upa_str = Base.unsafe_string(upa_str)
    new_upa = ISL.API.isl_union_pw_aff_read_from_str(context, upa_str)
    ISL.API.isl_multi_union_pw_aff_set_union_pw_aff(sched, 0, new_upa)

    # add upas in order of loop orderings
    for ordering in loop_ordering
        for iname in ordering
            for (i, val) in enumerate(upas)
                used = val[1]
                upa = val[2]
                if used
                    continue
                end

                upa_str = ISL.API.isl_union_pw_aff_to_str(upa)
                upa_str = Base.unsafe_convert(Ptr{Cchar}, upa_str)
                upa_str = Base.unsafe_string(upa_str)
                # which iterator it is is between the -> and :
                # name[i0, i1, ...] -> [(i0)] : conditions...
                upa_iname_str = Base.split(upa_str, "->")[end]
                upa_iname_str = Base.split(upa_iname_str, ":")[1]
                # determine if iname in upa
                if occursin(sym_to_str(iname), upa_iname_str)
                    # make new upa (to avoid copying issues)
                    new_upa = ISL.API.isl_union_pw_aff_read_from_str(context, upa_str)
                    # set count location to upa in new schedule
                    ISL.API.isl_multi_union_pw_aff_set_union_pw_aff(sched, count, new_upa)
                    # increment count
                    count += 1
                    upas[i] = (true, upa)
                end
            end
        end
    end

    # add remaining upas
    for val in upas
        used = val[1]
        upa = val[2]
        if used
            continue
        end
        upa_str = ISL.API.isl_union_pw_aff_to_str(upa)
        upa_str = Base.unsafe_convert(Ptr{Cchar}, upa_str)
        upa_str = Base.unsafe_string(upa_str)
        # make new upa (to avoid copying issues)
        new_upa = ISL.API.isl_union_pw_aff_read_from_str(context, upa_str)
        # set count location to upa in new schedule
        ISL.API.isl_multi_union_pw_aff_set_union_pw_aff(sched, count, new_upa)
        # increment count
        count += 1
    end

end

"""
reorder the loops in a schedule

input:
    - kernel: kernel to reorder
    - schedule: ISL schedule of kernel
    - context: ISL context
    - loop_ordering: orderings of loops to use

modifies schedule to support new loop orderings if able
"""
function reorder_schedule_loops(kernel::LoopKernel, schedule::Ptr{ISL.API.isl_schedule}, context::Ptr{ISL.API.isl_ctx}, loop_ordering::Set{Vector{Symbol}})

    n = get_tile_dim(kernel)
    root = ISL.API.isl_schedule_get_root(schedule)
    node = root
    next_nodes = Set()
    # search for the outermost band node to reorder
    # (only band nodes can be reordered)
    while ISL.API.isl_schedule_node_n_children(node) > 0
        # go through all children of current node
        for i=0:ISL.API.isl_schedule_node_n_children(node)-1
            band = ISL.API.isl_schedule_node_get_child(node, i)
            if ISL.API.isl_schedule_node_get_type(band) == ISL.API.isl_schedule_node_type(0) # band node
                # in a band node, tile band with dimension n
                reorder_band(band, loop_ordering, context)
                # need to add child of band, since split band
                push!(next_nodes, ISL.API.isl_schedule_node_get_child(band, 0))
                break
            else
                # add to next nodes
                push!(next_nodes, band)
            end
        end

        if length(next_nodes) == 0
            break # done, no children left
        end
        node = pop!(next_nodes) # get next node
    end

end


text:
function decodeuri(str::AbstractString)

    out = IOBuffer()

    status = 1
    strlen = sizeof(str)

    while status < strlen
        c = str[status]
        if c == '%'
            cn = str[status+1]
            cv = str[status+2]
            write(out, parse(UInt8, string(cn, cv); base=16))
            status = status+3
        else
            write(out, c)
            status = status+1
        end
    end

    return String(take!(out))
end

function parsekey(parser::Function, key::AbstractString, str::AbstractString)

    keyrange = findfirst(key, str)
    if keyrange == nothing
        return nothing
    end

    state::Int = keyrange[end] + 2
    endq::Int = findnext(isequal('\"'), str, state + 1)

    return parser(str[state+1:endq-1])
end

function splitkey(parser::Function, key::AbstractString, str::AbstractString,
        result::AbstractVector = [], pushindex::Integer = 1)

    keyrange = findfirst(key, str)
    if keyrange == nothing
        return nothing
    end

    brk(c) = (c == ',' || c == '\"')
    state::Int = keyrange[end] + 2
    endq::Int = findnext(isequal('\"'), str, state + 1)

    if endq - state == 1
        return result
    end

    if (length(result) == 0)
        while state != endq
            nextbrk::Int = findnext(brk, str, state + 1)
            push!(result, parser(str[state+1:nextbrk-1]))
            state = nextbrk
        end
    else
        while state != endq
            nextbrk::Int = findnext(brk, str, state + 1)
            result[pushindex] = parser(str[state+1:nextbrk-1])
            pushindex = pushindex + 1
            state = nextbrk
        end
    end

    return result
end

@inline function tileget(c::Int)
    return Tile(
        (c == 16 || c == 52 || c == 88) ? (赤) :
            c < 108 ? Rank(c % 36 ÷ 4 + 1) :
                Rank(c % 36 ÷ 4 + 10),
                    Suit(c ÷ 36)
    )
end

@inline function tileget(s::Int, b::Int, t::Int)
    return tileget(36s + 4b + t)
end

const Wall = Dict("$c" => tileget(c) for c = 0:135)

@inline function chi(code::Int, who::Int, from::Int)

    base, call = divrem(code >> 10, 3)
    suit, base = divrem(base, 7)

    tile = tileget(suit, base + call, code >> (3 + 2*call) & 0x3)
    tiles = Tile[]; for i = 0:2
        shift = (code >> (3 + 2*i) & 0x3)
        (i != call) && push!(tiles, tileget(suit, base + i, shift))
    end

    Meld(チー, Seat(from-1), tile, tiles)
end

@inline function pon(code::Int, who::Int, from::Int)

    base, call = divrem(code >> 9, 3)
    suit, base = divrem(base, 9)

    except = code >> 5 & 0x3
    if (call == except)
        call = call + 1
    end

    tile = tileget(suit, base, call)
    tiles = Tile[]; for i = 0:3
        if (i != call) && (i != except)
            push!(tiles, tileget(suit, base, i))
        end
    end

    Meld(ポン, Seat(from-1), tile, tiles)
end

@inline function pei(code::Int, who::Int, from::Int)

    Meld(キタ, Seat(from-1), Tile(北, 字牌), Tile[])
end

@inline function kkn(code::Int, who::Int, from::Int)

    base, call = div(code >> 9, 3), 3
    suit, base = divrem(base, 9)

    tile = tileget(suit, base, code >> 5 & 0x3)

    Meld(小明槓, Seat(from-1), tile, Tile[])
end

@inline function kan(code::Int, who::Int, from::Int)

    base, call = divrem(code >> 8, 4)
    suit, base = divrem(base, 9)

    tile = tileget(suit, base, call)
    tiles = Tile[]; for i = 0:3
        (i != call) && push!(tiles, tileget(suit, base, i))
    end

    Meld((who == from) ? 暗槓 : 大明槓,
        Seat(from-1), tile, tiles)
end


text:
# This was copied from Debugger.jl and then modified

using TerminalRegressionTests, Rebugger, Revise, CodeTracking
using HeaderREPLs, REPL
using Test

includet("my_gcd.jl")

function run_terminal_test(cmd, validation, commands)
    function compare_replace(em, target; replace=nothing)
        # Compare two buffer, skipping over the equivalent of key=>rep replacement
        # However, because of potential differences in wrapping we don't explicitly
        # perform the replacement; instead, we make the comparison tolerant of difference
        # `\n`.
        buf = IOBuffer()
        decoratorbuf = IOBuffer()
        TerminalRegressionTests.VT100.dump(buf, decoratorbuf, em)
        outbuf = take!(buf)
        success = true
        if replace !== nothing
            output = String(outbuf)
            key, rep = replace
            idxkey = findfirst(key, target)
            iout, itgt = firstindex(output), firstindex(target)
            outlast, tgtlast = lastindex(output), lastindex(target)
            lrep = length(rep)
            while success && iout <= outlast && itgt <= tgtlast
                if itgt == first(idxkey)
                    itgt += length(key)
                    for c in rep
                        cout = output[iout]
                        while c != cout && cout == '\n'
                            iout = nextind(output, iout)
                            cout = output[iout]
                        end
                        if c != cout
                            success = false
                            break
                        end
                        iout = nextind(output, iout)
                    end
                else
                    cout, ctgt = output[iout], target[itgt]
                    success = cout == ctgt
                    iout, itgt = nextind(output, iout), nextind(target, itgt)
                end
            end
            success && iout > outlast && itgt > tgtlast && return true
        end
        outbuf == codeunits(target) && return true
        open("failed.out","w") do f
            write(f, output)
        end
        open("expected.out","w") do f
            write(f, target)
        end
        error("Test failed. Expected result written to expected.out,
            actual result written to failed.out")
    end

    dirpath = joinpath(@__DIR__, "ui", "v$(VERSION.major).$(VERSION.minor)")
    isdir(dirpath) || mkpath(dirpath)
    filepath = joinpath(dirpath, validation)
    # Fix the path of gcd to match the current running version of Julia
    gcdfile, gcdline = whereis(@which my_gcd(10, 20))
    cmp(a, b, decorator) = compare_replace(a, b; replace="****" => gcdfile*':'*string(gcdline))
    TerminalRegressionTests.automated_test(cmp, filepath, commands) do emuterm
    # TerminalRegressionTests.create_automated_test(filepath, commands) do emuterm
        main_repl = REPL.LineEditREPL(emuterm, true)
        main_repl.interface = REPL.setup_interface(main_repl)
        main_repl.specialdisplay = REPL.REPLDisplay(main_repl)
        main_repl.mistate = REPL.LineEdit.init_state(REPL.terminal(main_repl), main_repl.interface)
        iprompt, eprompt = Rebugger.rebugrepl_init(main_repl, true)
        repl = iprompt.repl
        s = repl.mistate
        s.current_mode = iprompt
        repl.t = emuterm
        REPL.LineEdit.edit_clear(s)
        REPL.LineEdit.edit_insert(s, cmd)
        Rebugger.interpret(s)
    end
end

CTRL_C = "\x3"
EOT = "\x4"
UP_ARROW = "\e[A"

run_terminal_test("my_gcd(10, 20)",
                  "gcd.multiout",
                  ['\n'])
run_terminal_test("__gcdval__ = my_gcd(10, 20);",
                  "gcdsc.multiout",
                  ['\n'])
@test __gcdval__ == gcd(10, 20)


text:
# Julia wrapper for header: /Users/bieler/Desktop/tmp/SDL2-2.0.8/include/libsdl2_image.h
# Automatically generated using Clang.jl wrap_c, version 0.0.0
include("SDL_image_h.jl")

function IMG_Linked_Version()
    ccall((:IMG_Linked_Version, libsdl2_image), Ptr{SDL_version}, ())
end

function IMG_Init(flags::Cint)
    ccall((:IMG_Init, libsdl2_image), Cint, (Cint,), flags)
end

function IMG_Quit()
    ccall((:IMG_Quit, libsdl2_image), Cvoid, ())
end

function IMG_LoadTyped_RW(src, freesrc::Cint, _type)
    ccall((:IMG_LoadTyped_RW, libsdl2_image), Ptr{Surface}, (Ptr{RWops}, Cint, Cstring), src, freesrc, _type)
end

function IMG_Load(file)
    ccall((:IMG_Load, libsdl2_image), Ptr{Surface}, (Cstring,), file)
end

function IMG_Load_RW(src, freesrc::Cint)
    ccall((:IMG_Load_RW, libsdl2_image), Ptr{Surface}, (Ptr{RWops}, Cint), src, freesrc)
end

function IMG_LoadTexture(renderer, file)
    ccall((:IMG_LoadTexture, libsdl2_image), Ptr{Texture}, (Ptr{Renderer}, Cstring), renderer, file)
end

function IMG_LoadTexture_RW(renderer, src, freesrc::Cint)
    ccall((:IMG_LoadTexture_RW, libsdl2_image), Ptr{Texture}, (Ptr{Renderer}, Ptr{RWops}, Cint), renderer, src, freesrc)
end

function IMG_LoadTextureTyped_RW(renderer, src, freesrc::Cint, _type)
    ccall((:IMG_LoadTextureTyped_RW, libsdl2_image), Ptr{Texture}, (Ptr{Renderer}, Ptr{RWops}, Cint, Cstring), renderer, src, freesrc, _type)
end

function IMG_isICO(src)
    ccall((:IMG_isICO, libsdl2_image), Cint, (Ptr{RWops},), src)
end

function IMG_isCUR(src)
    ccall((:IMG_isCUR, libsdl2_image), Cint, (Ptr{RWops},), src)
end

function IMG_isBMP(src)
    ccall((:IMG_isBMP, libsdl2_image), Cint, (Ptr{RWops},), src)
end

function IMG_isGIF(src)
    ccall((:IMG_isGIF, libsdl2_image), Cint, (Ptr{RWops},), src)
end

function IMG_isJPG(src)
    ccall((:IMG_isJPG, libsdl2_image), Cint, (Ptr{RWops},), src)
end

function IMG_isLBM(src)
    ccall((:IMG_isLBM, libsdl2_image), Cint, (Ptr{RWops},), src)
end

function IMG_isPCX(src)
    ccall((:IMG_isPCX, libsdl2_image), Cint, (Ptr{RWops},), src)
end

function IMG_isPNG(src)
    ccall((:IMG_isPNG, libsdl2_image), Cint, (Ptr{RWops},), src)
end

function IMG_isPNM(src)
    ccall((:IMG_isPNM, libsdl2_image), Cint, (Ptr{RWops},), src)
end

function IMG_isSVG(src)
    ccall((:IMG_isSVG, libsdl2_image), Cint, (Ptr{RWops},), src)
end

function IMG_isTIF(src)
    ccall((:IMG_isTIF, libsdl2_image), Cint, (Ptr{RWops},), src)
end

function IMG_isXCF(src)
    ccall((:IMG_isXCF, libsdl2_image), Cint, (Ptr{RWops},), src)
end

function IMG_isXPM(src)
    ccall((:IMG_isXPM, libsdl2_image), Cint, (Ptr{RWops},), src)
end

function IMG_isXV(src)
    ccall((:IMG_isXV, libsdl2_image), Cint, (Ptr{RWops},), src)
end

function IMG_isWEBP(src)
    ccall((:IMG_isWEBP, libsdl2_image), Cint, (Ptr{RWops},), src)
end

function IMG_LoadICO_RW(src)
    ccall((:IMG_LoadICO_RW, libsdl2_image), Ptr{Surface}, (Ptr{RWops},), src)
end

function IMG_LoadCUR_RW(src)
    ccall((:IMG_LoadCUR_RW, libsdl2_image), Ptr{Surface}, (Ptr{RWops},), src)
end

function IMG_LoadBMP_RW(src)
    ccall((:IMG_LoadBMP_RW, libsdl2_image), Ptr{Surface}, (Ptr{RWops},), src)
end

function IMG_LoadGIF_RW(src)
    ccall((:IMG_LoadGIF_RW, libsdl2_image), Ptr{Surface}, (Ptr{RWops},), src)
end

function IMG_LoadJPG_RW(src)
    ccall((:IMG_LoadJPG_RW, libsdl2_image), Ptr{Surface}, (Ptr{RWops},), src)
end

function IMG_LoadLBM_RW(src)
    ccall((:IMG_LoadLBM_RW, libsdl2_image), Ptr{Surface}, (Ptr{RWops},), src)
end

function IMG_LoadPCX_RW(src)
    ccall((:IMG_LoadPCX_RW, libsdl2_image), Ptr{Surface}, (Ptr{RWops},), src)
end

function IMG_LoadPNG_RW(src)
    ccall((:IMG_LoadPNG_RW, libsdl2_image), Ptr{Surface}, (Ptr{RWops},), src)
end

function IMG_LoadPNM_RW(src)
    ccall((:IMG_LoadPNM_RW, libsdl2_image), Ptr{Surface}, (Ptr{RWops},), src)
end

function IMG_LoadSVG_RW(src)
    ccall((:IMG_LoadSVG_RW, libsdl2_image), Ptr{Surface}, (Ptr{RWops},), src)
end

function IMG_LoadTGA_RW(src)
    ccall((:IMG_LoadTGA_RW, libsdl2_image), Ptr{Surface}, (Ptr{RWops},), src)
end

function IMG_LoadTIF_RW(src)
    ccall((:IMG_LoadTIF_RW, libsdl2_image), Ptr{Surface}, (Ptr{RWops},), src)
end

function IMG_LoadXCF_RW(src)
    ccall((:IMG_LoadXCF_RW, libsdl2_image), Ptr{Surface}, (Ptr{RWops},), src)
end

function IMG_LoadXPM_RW(src)
    ccall((:IMG_LoadXPM_RW, libsdl2_image), Ptr{Surface}, (Ptr{RWops},), src)
end

function IMG_LoadXV_RW(src)
    ccall((:IMG_LoadXV_RW, libsdl2_image), Ptr{Surface}, (Ptr{RWops},), src)
end

function IMG_LoadWEBP_RW(src)
    ccall((:IMG_LoadWEBP_RW, libsdl2_image), Ptr{Surface}, (Ptr{RWops},), src)
end

function IMG_ReadXPMFromArray(xpm)
    ccall((:IMG_ReadXPMFromArray, libsdl2_image), Ptr{Surface}, (Ptr{Cstring},), xpm)
end

function IMG_SavePNG(surface, file)
    ccall((:IMG_SavePNG, libsdl2_image), Cint, (Ptr{Surface}, Cstring), surface, file)
end

function IMG_SavePNG_RW(surface, dst, freedst::Cint)
    ccall((:IMG_SavePNG_RW, libsdl2_image), Cint, (Ptr{Surface}, Ptr{RWops}, Cint), surface, dst, freedst)
end

function IMG_SaveJPG(surface, file, quality::Cint)
    ccall((:IMG_SaveJPG, libsdl2_image), Cint, (Ptr{Surface}, Cstring, Cint), surface, file, quality)
end

function IMG_SaveJPG_RW(surface, dst, freedst::Cint, quality::Cint)
    ccall((:IMG_SaveJPG_RW, libsdl2_image), Cint, (Ptr{Surface}, Ptr{RWops}, Cint, Cint), surface, dst, freedst, quality)
end

max_stars_repo_name: Kyjor/julia-game

max_stars_repo_licenses: MIT Unlicense

max_issues_repo_name: Kyjor/julia-game

max_issues_repo_licenses: MIT Unlicense

max_forks_repo_name: Kyjor/julia-game

max_forks_repo_licenses: MIT Unlicense


text:
using Mimi
using Test

@defcomp c begin
end

m = Model()
set_dimension!(m, :time, 1:2)
add_comp!(m, c)

function post_trial(sim_inst::SimulationInstance, trialnum::Int, ntimesteps::Int, tup::Union{Nothing, Tuple})
    data = Mimi.payload(sim_inst)
    data[trialnum] = trialnum
end

sim_def = @defsim begin
end

trials = 10

original_payload = zeros(trials)
Mimi.set_payload!(sim_def, original_payload)

sim_inst = run(sim_def, m, trials, post_trial_func = post_trial)

@test Mimi.payload(sim_def) == original_payload   # in the original defintion, it's still zeros
@test Mimi.payload(sim_inst) == collect(1:trials) # in the instance, it's now 1:10
@test Mimi.payload(sim_inst.sim_def) == original_payload  # the definition stored in the instance still holds the unmodified payload object


text:
module SetBoolParameterTrigger

using ..Ahorn, Maple

@mapdef Trigger "ShaderHelper/SetBoolParameterTrigger" SetBoolParameterTrigger(x::Integer, y::Integer, width::Integer=Maple.defaultTriggerWidth, height::Integer=Maple.defaultTriggerHeight, shader::String="shaderhelper/testshader", value::Bool=true, key::String="key")

const placements = Ahorn.PlacementDict(
    "Set Bool Parameter Trigger (Shader Helper)" => Ahorn.EntityPlacement(
        SetBoolParameterTrigger,
        "rectangle"
    )
)

end

max_stars_repo_name: lordseanington/ShaderHelper

max_issues_repo_name: lordseanington/ShaderHelper

max_forks_repo_name: lordseanington/ShaderHelper


text:
using  Statistics,StatsBase,Distributions,DataFrames,CSV,Plots,Match
pyplot()

# Helper functions:
include("routines.jl")

## TEST SET CONSTRUCTION AND ANALYSIS
df=CSV.read("20NewsPred.csv",DataFrame;delim=",")
dfm=Matrix(df)
Ntest=size(df,1)
c_pred=zeros(Int,Ntest)
for n=1:Ntest
    val,ind=findmax(dfm[n,:])
    if ind==1
        c_pred[n]=1
    end
end
p1_pred = dfm[:,1] # prediction probabiltiies of class 1 for each testpoint
df2=CSV.read("20NewsTrue.csv",DataFrame;delim=",")
c_true = Int.(df2[:,1].==1) #  true class for each testpoint

global true_positive=sum((c_pred.==1) .& (c_true.==1))
global false_positive=sum((c_pred.==1) .& (c_true.==0))
global false_negative=sum((c_pred.==0) .& (c_true.==1))
global true_negative=sum((c_pred.==0) .& (c_true.==0))
global F1Test_true=true_positive/(true_positive + 0.5*(false_positive+false_negative))
global SpecTest_true=true_negative/(true_negative + false_positive)

# Bernoulli Sampling approximation:
lambda=0.9
p1_true_guess = lambda*p1_pred .+ (1-lambda)*0.5 # guess of the true label on test set

# Define the parameters for the Optimal Sampling Distribution:
htilde = happroxFn(c_pred,p1_true_guess;metric="F",metric_par=0.5)

Mvals=LinRange(100,Ntest,10) # expected number of samples

percent=zeros(length(Mvals))

spec_mean=zeros(length(Mvals))
spec_lower=zeros(length(Mvals))
spec_upper=zeros(length(Mvals))
acc_mean=zeros(length(Mvals))
acc_lower=zeros(length(Mvals))
acc_upper=zeros(length(Mvals))
precision_mean=zeros(length(Mvals))
precision_lower=zeros(length(Mvals))
precision_upper=zeros(length(Mvals))
recall_mean=zeros(length(Mvals))
recall_lower=zeros(length(Mvals))
recall_upper=zeros(length(Mvals))
f1_mean=zeros(length(Mvals))
f1_lower=zeros(length(Mvals))
f1_upper=zeros(length(Mvals))

# run multiple experiments for increasing number of samples:
for experiment=1:length(Mvals)

    global M = Mvals[experiment] # average number of elements in each test set replicate
    global b = optimalb(htilde,M)
    global s = (rand(Ntest) .< b)
    global total_samples_used = sum(s)

    ToLabel=findall(s.==1)

    Fhat_acc_mean, Fhat_acc_var = FhatBS(c_pred[ToLabel],c_true[ToLabel],b[ToLabel];metric="Accuracy")

    F1hat_mean, F1hat_var = FhatBS(c_pred[ToLabel],c_true[ToLabel],b[ToLabel];metric="F",metric_par=0.5)

    Fhat_precision_mean, Fhat_precision_var = FhatBS(c_pred[ToLabel],c_true[ToLabel],b[ToLabel];metric="F",metric_par=1)

    Fhat_recall_mean, Fhat_recall_var = FhatBS(c_pred[ToLabel],c_true[ToLabel],b[ToLabel];metric="F",metric_par=0)

    Fhat_spec_mean, Fhat_spec_var = FhatBS(c_pred[ToLabel],c_true[ToLabel],b[ToLabel];metric="Specificity")

    # convert this to confidence bounds by fitting this to say a beta distribution:

    global confidence_level=0.9

    println("-----------------------------------------")
    println("total samples used  = $total_samples_used")
    println("% of test data      = $(total_samples_used/Ntest)")
    percent[experiment]=total_samples_used/Ntest

    println("true accuracy       = $(mean(c_true .== c_pred))")
    mn,lower,upper = confidenceBeta(Fhat_acc_mean,Fhat_acc_var,confidence_level)
    println("estimated accuracy  = $mn [$lower,$upper]")

    acc_mean[experiment]=Fhat_acc_mean
    acc_lower[experiment]=lower
    acc_upper[experiment]=upper

    println("")

    println("true precision      = $(true_positive/(true_positive+false_positive))")
    local mn,lower,upper = confidenceBeta(Fhat_precision_mean,Fhat_precision_var,confidence_level)
    println("estimated precision = $mn [$lower,$upper]")

    precision_mean[experiment]=Fhat_precision_mean
    precision_lower[experiment]=lower
    precision_upper[experiment]=upper

    println("")

    println("true recall         = $(true_positive/(true_positive+false_negative))")
    local mn,lower,upper = confidenceBeta(Fhat_recall_mean,Fhat_recall_var,confidence_level)
    println("estimated recall    = $mn [$lower,$upper]")

    recall_mean[experiment]=Fhat_recall_mean
    recall_lower[experiment]=lower
    recall_upper[experiment]=upper

    println("")

    println("true F1             = $(F1Test_true)")
    local mn,lower,upper = confidenceBeta(F1hat_mean,F1hat_var,confidence_level)
    println("estimated F1        = $mn [$lower,$upper]")

    f1_mean[experiment]=F1hat_mean
    f1_lower[experiment]=lower
    f1_upper[experiment]=upper

    println("")

    println("true specificity             = $(SpecTest_true)")
    local mn,lower,upper = confidenceBeta(Fhat_spec_mean,Fhat_spec_var,confidence_level)
    println("estimated specificity        = $mn [$lower,$upper]")

    spec_mean[experiment]=Fhat_spec_mean
    spec_lower[experiment]=lower
    spec_upper[experiment]=upper

end

mp=maximum(percent)

acc_true = (mean(c_true .== c_pred))
ribbon_upper=acc_upper - acc_mean
ribbon_lower=acc_mean - acc_lower
plot(reuse=false,show=true)
plot_acc=plot!(percent,acc_mean,ribbon=(ribbon_lower,ribbon_upper),label="$(confidence_level) confidence interval",framestyle = :box,minorgrid=true)
plot!([0,mp],[acc_true,acc_true],label="true value",legend=:bottomright,ylims=[0.9*acc_true,1.1*acc_true])
title!("Accuracy")
xlabel!("fraction of test data labelled")

precision_true = true_positive/(true_positive+false_positive)
ribbon_upper=precision_upper - precision_mean
ribbon_lower=precision_mean - precision_lower
plot(reuse=false,show=true)
plot_precision=plot!(percent,precision_mean,ribbon=(ribbon_lower,ribbon_upper),label="$(confidence_level) confidence interval",framestyle = :box,minorgrid=true)
plot!(plot_precision)
plot!([0,mp],[precision_true,precision_true],label="true value",legend=:bottomright)
title!("Precision")
xlabel!("fraction of test data labelled")

recall_true = true_positive/(true_positive+false_negative)
ribbon_upper=recall_upper - recall_mean
ribbon_lower=recall_mean - recall_lower
plot(reuse=false,show=true)
plot_recall=plot!(percent,recall_mean,ribbon=(ribbon_lower,ribbon_upper),label="$(confidence_level) confidence interval",framestyle = :box,minorgrid=true)
plot!(plot_recall)
plot!([0,mp],[recall_true,recall_true],label="true value",legend=:bottomright)
title!("Recall")
xlabel!("fraction of test data labelled")

f1_true = F1Test_true
ribbon_upper=f1_upper - f1_mean
ribbon_lower=f1_mean - f1_lower
plot(reuse=false,show=true)
plot_f1=plot!(percent,f1_mean,ribbon=(ribbon_lower,ribbon_upper),label="$(confidence_level) confidence interval",framestyle = :box,minorgrid=true)
plot!(plot_f1)
plot!([0,mp],[f1_true,f1_true],label="true value",legend=:bottomright)
title!("F1")
xlabel!("fraction of test data labelled")

spec_true = SpecTest_true
ribbon_upper=spec_upper - spec_mean
ribbon_lower=spec_mean - spec_lower
plot(reuse=false,show=true)
plot_spec=plot!(percent,spec_mean,ribbon=(ribbon_lower,ribbon_upper),label="$(confidence_level) confidence interval",framestyle = :box,minorgrid=true)
plot!(plot_spec)
plot!([0,mp],[spec_true,spec_true],label="true value",legend=:bottomright)
title!("Specificity")
xlabel!("fraction of test data labelled")

max_stars_repo_name: davidbarber/TestEstimationPublic

max_issues_repo_name: davidbarber/TestEstimationPublic

max_forks_repo_name: davidbarber/TestEstimationPublic


text:
# using Pkg
# Pkg.activate("/home/gkraemer/progs/julia/BTCParser")
# using Revise
# using BTCParser

@testset "BCIterator" begin
    for i in 0:100
        b = BTCParser.BCIterator(i)
        @test BTCParser.get_file_num(b) == i
        close(b)
    end

    n_files = BTCParser.get_num_block_chain_files()
    b = BTCParser.BCIterator(n_files - 1)
    @test BTCParser.is_last_file(b)
    close(b)

    b = BTCParser.BCIterator()
    i = 0
    @test BTCParser.get_file_num(b) == i
    while !BTCParser.is_last_file(b)
        i += 1
        BTCParser.open_next_file(b)
        @test i == BTCParser.get_file_num(b)
    end
    close(b)

    b = BTCParser.BCIterator()
    BTCParser.check_magic_bytes(b)
    @test BTCParser.get_file_pos(b) == 4

    b2 = BTCParser.BCIterator()

    @test b  >  b2
    @test b  >= b2
    @test b2 <= b
    @test b2 <  b

    BTCParser.check_magic_bytes(b2)
    @test b == b2

    close(b)
    close(b2)

end


text:
# Linear programming in matrix
# Version: 5.1
# Author: Edward J. Xu, edxu96@outlook.com
# Date: April 5th, 2019
# ----------------------------------------------------------------------------------------------------------------------
# using JuMP
# using GLPKMathProgInterface
function lp(n_x, vec_c, vec_b, mat_a)
    # Linear Programming in Matrix Form
    # vec_c: [column vector] coefficient vector in objective function
    # vec_b: [column vector] right-hand-side coefficient vector in constraint
    # mat_a:
    # Edward J. Xu, 190405
    println("-------------------------------------------------------------------------\n",
            "------------------------ 1/2. Begin Optimization ------------------------\n",
            "-------------------------------------------------------------------------\n")
    model = Model(solver = GLPKSolverLP())
    @variable(model, vec_x[1: n_x] >= 0)
    @objective(model, Min, (transpose(vec_c) * vec_x)[1])
    constraintsForDual = @constraint(model, mat_a * vec_x .>= vec_b)
    solve(model)
    vec_result_u = getdual(constraintsForDual)
    obj = getobjectivevalue(model)
    vec_result_x = getvalue(vec_x)
    println("-------------------------------------------------------------------------\n",
            "-------------------------- 2/2. Nominal Ending --------------------------\n",
            "-------------------------------------------------------------------------\n")
    return (obj, vec_result_x, vec_result_u)
end

max_stars_repo_name: eitt/BendersDecomposition


text:
# -------- Status ------------------------------------------------------------ #

const Status = Int # for code readability

"""
    Status()
    Status(val)

Create a representation of the game status. Calling the function without
arguments stands for a game status that is still undecided. Calling it with
argument `val`, which can be 1, -1, or 0, indicates a game won by the first or
second player, or a draw.
"""
function Status end

Status(value :: Int) = value
Status() = 42

is_over(s :: Status) = (s != 42)
with_default(s :: Status, default :: Int) = is_over(s) ? s : default

# -------- Game -------------------------------------------------------------- #

const ActionIndex = Int # for code readability

"""
A Game with two competing players that play alternately.

The game can only end by victory of the first or second player, or by draw.
Concrete subtypes of `Game` must implement a number of functions that allow
to find out the current player, the game status, or the legal actions.
"""
abstract type Game end

Broadcast.broadcastable(game :: Game) = Ref(game)

Base.copy(:: Game) = error("unimplemented")
Base.size(:: Type{Game}) = error("unimplemented") # must be a 3-tuple
Base.size(:: G) where {G <: Game} = size(G)

"""
    status(game)

Status of `game`.
"""
status(game :: Game) = error("unimplemented")

"""
    current_player(game)

Current player of `game`. 1 stands for the first player and -1 for
the second.
"""
current_player(game :: Game) = error("unimplemented")

"""
    legal_actions(game)

Vector of legal actions of `game`.
"""
legal_actions(:: Game) :: Vector{ActionIndex} = error("unimplemented")

"""
    apply_action!(game, action)

Modify `game` by applying `action`.
"""
apply_action!(:: Game, :: ActionIndex) :: Game   = error("unimplemented")

"""
    is_over(game)

Returns whether a game is finished or not.
"""
is_over(game :: Game) = is_over(status(game))

# Data representation of the game as layered 2d image from the perspective of
# the active player (active player plays with 1, other with -1)
"""
    representation(game)
    representation(games)

Data representation of `game` as three-dimensional array. If a vector
of `games` is given, a four-dimensional array is returned.
"""
representation(:: Game) = error("unimplemented")

function representation(games :: Vector{G}) where G <: Game

  @assert !isempty(games) "Invalid representation of empty game vector"

  results = zeros(Float32, (size(games[1])..., length(games)))

  for i in 1:length(games)
    results[:,:,:,i] = representation(games[i])
  end

  results

end

"""
    policy_length(game)
    policy_length(gametype)

Maximal number of legal actions.
"""
policy_length(:: Type{Game}) :: Int = error("unimplemented")
policy_length(:: G) where {G <: Game} = policy_length(G)

"""
    random_action(game)

Random legal action for `game`.
"""
random_action(game :: Game) = rand(legal_actions(game))

"""
    random_turn!(game)

Modify `game` by taking a single random action if the game is not finished yet.
"""
function random_turn!(game :: Game)
  is_over(game) ? game : apply_action!(game, random_action(game))
end

"""
    random_turns!(game, steps)
    random_turns!(game, steprange)

Modify `game` by taking several random actions.
"""
function random_turns!(game :: Game, steps :: Int)
  for _ in 1:steps
    random_turn!(game)
  end
  game
end

function random_turns!(game :: Game, range)
  steps = rand(range) :: Int
  random_turns!(game, steps)
end

"""
    random_playout!(game)

Play off `game` with random actions by both players.
"""
function random_playout!(game :: Game)

  while !is_over(game)
    random_turn!(game)
  end

  game

end

"""
    random_playout(game)

Random playout with initial state `game` without modifying it.
"""
function random_playout(game :: Game)

  random_playout!(copy(game))

end

"""
    is_action_legal(game, action)

Check if `action` is a legal action for `game`.
"""
function is_action_legal(game :: Game, action :: ActionIndex)

  action in legal_actions(game)

end

"""
    augment(game, label)

Returns a tuple `(games, labels)` that are augmented versions of `game` and
`label` via the game's symmetry group.
"""
function augment(game :: Game, label :: Array{Float32})
  @warn "Augmentation not implemented for type $(typeof(game))" maxlog = 1
  [game], [label]
end

"""
    draw(game)

Draw a unicode representation of `game`.
"""
draw(:: Game) :: Nothing = error("drawing $(typeof(game)) not implemented.")

max_stars_repo_name: roSievers/jtac


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

# Wine is a bit of a pain to build; it requires a two-and-a-half step process;
# we first build the 64-bit version of Wine part-way, use its BUILD DIRECTORY
# (not the result of `make install`, the result of `make`!) to build 32-bit
# Wine, install and bundle that version up, then resume the 64-bit build.

# We also don't support passing explicit targets in
SAFE_ARGS = [a for a in ARGS if startswith(a, "-")]

version = v"3.21"
sources = [
    GitSource("https://github.com/wine-mirror/wine.git", "ea9253d6d3c9bb60d98b0d917292fc0b4babb3dd"),
]

# The products that we will ensure are always built
products = Product[
    ExecutableProduct("wine64", :wine64),
]

# Dependencies that must be installed before this package can be built
dependencies = [
    Dependency("Zlib_jll"),
    Dependency("libpng_jll"),
    Dependency("JpegTurbo_jll"),
    Dependency("GnuTLS_jll"),
]

platform32 = Platform("i686", "linux"; libc="musl")
platform64 = Platform("x86_64", "linux"; libc="musl")

wine64_build_script = raw"""
# First, build wine64, making the actual build directory itself the thing we will install.
mkdir $WORKSPACE/destdir/wine64
cd $WORKSPACE/destdir/wine64
$WORKSPACE/srcdir/wine/configure --prefix=${prefix} --build=${MACHTYPE} --host=${target} --without-x --without-freetype --enable-win64
make -j${nproc}
"""

# package up the wine64 build directory itself:
product_hashes = build_tarballs(copy(SAFE_ARGS), "Wine64Build", version, sources, wine64_build_script, [platform64], products, dependencies; skip_audit=true)

# Include that tarball as one of the sources we need to include:
wine64_build_path, wine64_build_hash = product_hashes[triplet(platform64)]
push!(sources, joinpath("products", wine64_build_path) => wine64_build_hash)

# Next, build wine32, without wine64, then use those tools to build wine32 WITH wine64
wine32_script = raw"""
# Next, build wine32, linking against the previously included wine64 stuff:
mkdir $WORKSPACE/srcdir/wine32_only
cd $WORKSPACE/srcdir/wine32_only
$WORKSPACE/srcdir/wine/configure --host=${target}  --without-x --without-freetype
make -j${nproc}

mkdir $prefix/wine32
cd $prefix/wine32
$WORKSPACE/srcdir/wine/configure --prefix=${prefix}/wine32 --host=${target} --without-x --without-freetype --with-wine64=$WORKSPACE/srcdir/wine64 --with-wine-tools=$WORKSPACE/srcdir/wine32_only
make -j${nproc}
make install
"""

product_hashes = build_tarballs(copy(SAFE_ARGS), "Wine32", version, sources, wine32_script, [platform32], products, dependencies; skip_audit=true)
wine32_path, wine32_hash = product_hashes[triplet(platform32)]
push!(sources, joinpath("products", wine32_path) => wine32_hash)

# Finally, install both:
script = raw"""
cp -r $WORKSPACE/srcdir/wine32/* ${prefix}/
cd $WORKSPACE/srcdir/wine64
make install
"""

build_tarballs(copy(SAFE_ARGS), "Wine", version, sources, script, [platform64], products, dependencies)

max_stars_repo_name: waralex/Yggdrasil

max_issues_repo_name: waralex/Yggdrasil

max_forks_repo_name: waralex/Yggdrasil


text:
immutable DateLocale
    months::Vector{String}
    months_abbr::Vector{String}
    days_of_week::Vector{String}
    days_of_week_abbr::Vector{String}
    month_value::Dict{String, Int}
    month_abbr_value::Dict{String, Int}
    day_of_week_value::Dict{String, Int}
    day_of_week_abbr_value::Dict{String, Int}
end

function locale_dict{S<:AbstractString}(names::Vector{S})
    result = Dict{String, Int}()

    # Keep both the common case-sensitive version of the name and an all lowercase
    # version for case-insensitive matches. Storing both allows us to avoid using the
    # lowercase function during parsing.
    for i in 1:length(names)
        name = names[i]
        result[name] = i
        result[lowercase(name)] = i
    end
    return result
end

"""
    DateLocale(["January", "February",...], ["Jan", "Feb",...],
               ["Monday", "Tuesday",...], ["Mon", "Tue",...])

Create a locale for parsing or printing textual month names.

Arguments:

- `months::Vector`: 12 month names
- `months_abbr::Vector`: 12 abbreviated month names
- `days_of_week::Vector`: 7 days of week
- `days_of_week_abbr::Vector`: 7 days of week abbreviated

This object is passed as the last argument to `tryparsenext` and `format`
methods defined for each `AbstractDateToken` type.
"""
function DateLocale(months::Vector, months_abbr::Vector,
                    days_of_week::Vector, days_of_week_abbr::Vector)
    DateLocale(
        months, months_abbr, days_of_week, days_of_week_abbr,
        locale_dict(months), locale_dict(months_abbr),
        locale_dict(days_of_week), locale_dict(days_of_week_abbr),
    )
end

const ENGLISH = DateLocale(
    ["January", "February", "March", "April", "May", "June",
     "July", "August", "September", "October", "November", "December"],
    ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
    ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
    ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
)

const LOCALES = Dict{String, DateLocale}("english" => ENGLISH)

for (fn, field) in zip(
    [:dayname_to_value, :dayabbr_to_value, :monthname_to_value, :monthabbr_to_value],
    [:day_of_week_value, :day_of_week_abbr_value, :month_value, :month_abbr_value],
)
    @eval @inline function $fn(word::AbstractString, locale::DateLocale)
        # Maximize performance by attempting to avoid the use of `lowercase` and trying
        # a case-sensitive lookup first
        value = get(locale.$field, word, 0)
        if value == 0
            value = get(locale.$field, lowercase(word), 0)
        end
        value
    end
end