text:
include("utils.jl")
using MPI
using .utils

# export rfft3, irfft3, real_shape, complex_shape, r2c
export *

# Spectral transformation of three dimensional data aligned
# such that the last component is parallelized across processes
type r2c{T<:Real}
    # Global shape
    N::Array{Int, 1}
    # Global size of domain
    L::Array{T, 1}
    # Communicator
    comm::MPI.Comm
    num_processes::Int
    rank::Int
    chunk::Int    # Amount of data to be send by MPI

    # Plans
    plan12::FFTW.rFFTWPlan{T}
    plan3::FFTW.cFFTWPlan
    # Work arrays for transformations
    vT::Array{Complex{T}, 3}
    vT_view::Array{Complex{T}, 4}
    v::Array{Complex{T}, 3}
    v_view::Array{Complex{T}, 4}
    v_recv::Array{Complex{T}, 3}
    v_recv_view::Array{Complex{T}, 4}
    dealias::Array{Int, 1}

    # Constructor
    function r2c(N, L, comm)
        # Verify input
        Nh = N[1]÷2+1
        p = MPI.Comm_size(comm)
        Np = N÷p

        # Allocate work arrays
        vT, v = Array{Complex{T}}(Nh, N[2], Np[3]), Array{Complex{T}}(Nh, Np[2], N[3])
        vT_view, v_view = reshape(vT, (Nh, Np[2], p, Np[3])), reshape(v, (Nh, Np[2], Np[3], p))
        # For MPI.Alltoall! preallocate the receiving buffer
        v_recv = similar(v); v_recv_view = reshape(v_recv, (Nh, Np[2], Np[3], p))

        # Plan Fourier transformations
        A = zeros(T, (N[1], N[2], Np[3]))
        if p > 1
            plan12 = plan_rfft(A, (1, 2), flags=FFTW.MEASURE)
            plan3 = plan_fft!(v, (3, ), flags=FFTW.MEASURE)
        else  # Use only plan12 to do entire transform
            plan12 = plan_rfft(A, (1, 2, 3), flags=FFTW.MEASURE)
            plan3 = plan_fft!(zeros(Complex{Float64}, 2,2,2), (1, 2, 3), flags=FFTW.MEASURE)
        end

        # Compute the inverse plans
        inv(plan12)
        if p > 1 inv(plan3) end

        chunk = Nh*Np[2]*Np[3]
        # Now we are ready
        new(N, L, comm, p, MPI.Comm_rank(comm), chunk,
            plan12, plan3,
            vT, vT_view, v, v_view, v_recv, v_recv_view)
    end
end

# Constructor
r2c{T<:Real}(N::Array{Int, 1}, L::Array{T, 1}, comm::Any) = r2c{T}(N, L, comm)

# Transform real to complex as complex = T o real
function rfft3{T<:Real}(F::r2c{T}, fu::AbstractArray{Complex{T}, 3}, u::AbstractArray{T})
    if F.num_processes > 1
        A_mul_B!(F.vT, F.plan12, u)
        permutedims!(F.v_view, F.vT_view, [1, 2, 4, 3])
        MPI.Alltoall!(F.v_recv_view, F.v_view, F.chunk, F.comm)
        F.plan3*F.v_recv; fu[:] = F.v_recv
    else
        A_mul_B!(fu, F.plan12, u)
    end
end

# Transform complex to real as real = T o complex
function irfft3{T<:Real}(F::r2c{T}, u::AbstractArray{T}, fu::AbstractArray{Complex{T}, 3}, dealias_fu::Int=0)
    if F.num_processes > 1
        F.v[:] = fu
        if dealias_fu == 1
            dealias(F, F.v)
        elseif dealias_fu == 2
            dealias2(F, F.v)
        end
        F.plan3.pinv*F.v
        MPI.Alltoall!(F.v_recv_view, F.v_view, F.chunk, F.comm)
        permutedims!(F.vT_view, F.v_recv_view, [1, 2, 4, 3])
        A_mul_B!(u, F.plan12.pinv, F.vT)
    else
        A_mul_B!(u, F.plan12.pinv, fu)
    end
end

function real_shape{T<:Real}(F::r2c{T})
    (F.N[1], F.N[2], F.N[3]÷F.num_processes)
end

function complex_shape{T<:Real}(F::r2c{T})
    (F.N[1]÷2+1, F.N[2]÷F.num_processes, F.N[3])
end

function complex_shape_T{T<:Real}(F::r2c{T})
    (F.N[1]÷2+1, F.N[2], F.N[3]÷F.num_processes)
end

function complex_local_slice{T<:Real}(F::r2c{T})
    ((1, F.N[1]÷2+1),
     (F.rank*F.N[2]÷F.num_processes+1, (F.rank+1)*F.N[2]÷F.num_processes),
     (1, F.N[3]))
end

function complex_local_wavenumbers{T<:Real}(F::r2c{T})
    (rfftfreq(F.N[1], 1.0/F.N[1]),
     fftfreq(F.N[2], 1.0/F.N[2])[F.rank*div(F.N[2], F.num_processes)+1:(F.rank+1)*div(F.N[2], F.num_processes)],
     fftfreq(F.N[3], 1.0/F.N[3]))
end

function get_local_wavenumbermesh{T<:Real}(F::r2c{T})
    K = Array{Int}(tuple(push!([complex_shape(F)...], 3)...))
    k = complex_local_wavenumbers(F)
    for (i, Ki) in enumerate(ndgrid(k[1], k[2], k[3])) K[view(i)...] = Ki end
    K
end

function get_local_mesh{T<:Real}(F::r2c{T})
    # Real grid
    x = collect(0:F.N[1]-1)*F.L[1]/F.N[1]
    y = collect(0:F.N[2]-1)*F.L[2]/F.N[2]
    z = collect(0:F.N[3]-1)*F.L[3]/F.N[3]
    X = Array{T}(tuple(push!([real_shape(F)...], 3)...))
    for (i, Xi) in enumerate(ndgrid(x, y, z[F.rank*F.N[3]÷F.num_processes+1:(F.rank+1)*F.N[3]÷F.num_processes])) X[view(i)...] = Xi end
    X
end

function dealias{T<:Real}(F::r2c{T}, fu::AbstractArray{Complex{T}, 3})
    kk = complex_local_wavenumbers(F)
    for (k, kz) in enumerate(kk[3])
        x = false
        if abs(kz) > div(F.N[3], 3)
        @inbounds fu[:, :, k] = 0.0
            continue
        end
        for (j, ky) in enumerate(kk[2])
            if abs(ky) > div(F.N[2], 3)
               @inbounds fu[:, j, k] = 0
                continue
            end
            for (i, kx) in enumerate(kk[1])
                if (abs(kx) > div(F.N[1], 3))
                    @inbounds fu[i, j, k] = 0.0
                end
            end
        end
    end
end

function dealias2{T<:Real}(F::r2c{T}, fu::AbstractArray{Complex{T}, 3})
    if  !isdefined(F, :dealias)
        const kmax_dealias = F.N/3
        K = get_local_wavenumbermesh(F)
        (kx, ky, kz) = K[:,:,:,1], K[:,:,:,2], K[:,:,:,3]
        indices = []
        i = 1
        for (x,y,z) in zip(kx, ky, kz)
            if abs(x) > div(F.N[1], 3) || abs(y) > div(F.N[2], 3) || abs(z) > div(F.N[3], 3)
                push!(indices, i)
            end
            i += 1
        end
        F.dealias = indices
    end
    for i in F.dealias
      @inbounds  fu[i] = 0.0
    end
end


text:
function guesswithfeedback(n::Integer)
    number = rand(1:n)
    print("I choose a number between 1 and $n\nYour guess? ")
    while (guess = readline()) != dec(number)
        if all(isdigit, guess)
            print("Too ", parse(Int, guess) < number ? "small" : "big")
        else
            print("Enter an integer please")
        end
        print(", new guess? ")
    end
    println("You guessed right!")
end

guesswithfeedback(10)

ext: jl

max_stars_repo_name: ethansaxenian/RosettaDecode

max_issues_repo_name: ethansaxenian/RosettaDecode

max_forks_repo_name: ethansaxenian/RosettaDecode


text:
"""credits:
the Julia programming team:
@KristofferC
@IanButterworth
@00vareladavid
@timholy
@GunnarFarneback
@fredrikekre
@DilumAluthge
@devmotion
@aviatesk

inspired by file: manifest.jl

"""

function safe_uuid(uuid::String)::UUID
    try
        uuid = UUID(uuid)
    catch err
        err isa ArgumentError || rethrow()
        pkgerror("Could not parse `uuid` field as a UUID.")
    end
    return uuid
end

function safe_bool(bool::String)
    try
        bool = parse(Bool, bool)
    catch err
        err isa ArgumentError || rethrow()
        pkgerror("Could not parse `pinned` field as a Bool.")
    end
    return bool
end

# note: returns raw version *not* parsed version
function safe_version(version::String)::VersionNumber
    try
        version = VersionNumber(version)
    catch err
        err isa ArgumentError || rethrow()
        pkgerror("Could not parse `version` as a `VersionNumber`.")
    end
    return version
end

# turn /-paths into \-paths on Windows
function safe_path(path::String)
    if Sys.iswindows() && !isabspath(path)
        path = joinpath(split(path, "/")...)
    end
    return path
end

read_deps(::Nothing) = Dict{String,UUID}()
read_deps(deps) = pkgerror("Expected `deps` field to be either a list or a table.")
function read_deps(deps::AbstractVector)
    ret = String[]
    for dep in deps
        dep isa String || pkgerror("Expected `dep` entry to be a String.")
        push!(ret, dep)
    end
    return ret
end
function read_deps(raw::Dict{String,Any})::Dict{String,UUID}
    deps = Dict{String,UUID}()
    for (name, uuid) in raw
        deps[name] = safe_uuid(uuid)
    end
    return deps
end

using Test
@test safe_version("0.2.0")

max_stars_repo_name: adamwillisMastery/DeepLearner

max_issues_repo_name: adamwillisMastery/DeepLearner

max_forks_repo_name: adamwillisXanax/DeepLearner


text:
using Soss
using Test
using Weave

function buildREADME()
    weave("../README.jmd", doctype= "github", throw_errors=true, cache=:refresh, args=Dict(:seed => 6))
    return true
end

# write your own tests here
@testset "README" begin
    @test buildREADME()
end


text:
# activate the test environment if needed
using Pkg
if ! ("Plots" ∈ keys(Pkg.project().dependencies))
    using TestEnv; TestEnv.activate()
end

using KiteModels
using KitePodModels
using KiteUtils
using Plots
using LinearAlgebra

const kcu = KCU(se())
const kps4 = KPS3(kcu)

include("plot_initial_state.jl")


text:
using SequentialMonteCarlo
using RNGPool
import SMCExamples.LinearGaussian: defaultLGModel, makeLGLOPModel,
  makeLGAPFModel, kalmanlogZ, makelM
using Test

setRNGs(0)

N = 32768
n = 10
nt = Threads.nthreads()
model, theta, ys, ko = defaultLGModel(n)

@test ko.logZhats[end] ≈ kalmanlogZ(theta, ys)

smcio = SMCIO{model.particle, model.pScratch}(N, n, nt, false)
smc!(model, smcio)
@test smcio.logZhats ≈ ko.logZhats atol=0.1

lM = makelM(theta)
p1 = smcio.internal.zetaAncs[1]
p2 = smcio.zetas[1]
lM(n, p1, p2, smcio.internal.particleScratch)

modelLOP = makeLGLOPModel(theta, ys)
smcio = SMCIO{modelLOP.particle, modelLOP.pScratch}(N, n, nt, false)
smc!(modelLOP, smcio)
@test smcio.logZhats ≈ ko.logZhats atol=0.1

modelAPF = makeLGAPFModel(theta, ys)
smcio = SMCIO{modelAPF.particle, modelAPF.pScratch}(N, n, nt, false, 2.0)
smc!(modelAPF, smcio)
@test smcio.logZhats[1:n-1] ≈ ko.logZhats[2:n] atol=0.1


text:
# This file was generated, do not modify it. # hide
V' * V ≈ I

max_stars_repo_name: cscherrer/InformativePrior

max_issues_repo_name: cscherrer/InformativePrior

max_forks_repo_name: cscherrer/InformativePrior


text:
"""
Entity that manages windows.
"""
abstract type AbstractWindowManager end

"""
Abstract window type.
"""
abstract type AbstractWindow end

"Provide information about key modifier state (shift, control, alt and the OS key)."
Base.@kwdef struct KeyModifierState
    shift::Bool = false
    ctrl::Bool = false
    alt::Bool = false
    super::Bool = false
end

"Key binding associated to a character and a key modifier state."
struct KeyCombination
    key::String
    state::KeyModifierState
    KeyCombination(key, state) = new(key ∈ keys(fkeys) ? fkeys[key] : string(key), state)
end

"State of the keyboard, with regards to numlock and caps states."
struct KeyContext
    numlock::Bool
    caps::Bool
end

abstract type Event end
abstract type KeyAction <: Event end
abstract type MouseAction <: Event end
abstract type PointerEvent <: Event end

struct KeyReleased <: KeyAction end
struct KeyPressed <: KeyAction end

struct ButtonReleased <: MouseAction end
struct ButtonPressed <: MouseAction end
struct WindowHasFocus <: Event end
struct PointerEntersWindow <: PointerEvent end
struct PointerMoves <: PointerEvent end
struct PointerLeavesWindow <: PointerEvent end
struct Resize <: Event end
struct Expose <: Event end

abstract type EventData end

"""
Representation of a symbol that may be bound to a key, depending on a keyboard layout.
It differs from the physical representation of a key, denoted by names such as `AD01` which represent physical keys (in this case, `q` on a US keyboard).
A key symbol is sent when a physical key is pressed, even if no input character is bound to the key.
This structure provides a friendly `symbol` field, and a prettier `repr` field (mostly used for printing).
For example, the right arrow, with symbol `:right_arrow` (resp. `:kp_right_arrow` for keypad input), is represented by `"→"` (resp. `"→ (keypad)"`).

There is no consistent representation, so the one provided here may differ from windowing API implementations.
"""
struct KeySymbol
    symbol::Symbol
    repr::String
end

KeySymbol(symbol::Symbol) = is_key_symbol_defined(symbol) ? key_symbol(symbol) : KeySymbol(symbol, string(symbol))

"""
Event data regarding a keystroke.
"""
struct KeyEvent{A <: KeyAction} <: EventData
    """
    The name of the physical key.
    """
    key_name::Symbol
    """
    The symbol associated to the keystroke.
    """
    key::KeySymbol
    """
    Printable input (can be the empty string).
    """
    input::Char
    """
    Modifier state.
    """
    modifiers::KeyModifierState
    """
    Action, representing whether the key was pressed or released.
    """
    action::A
end

abstract type MouseButton end
struct ButtonLeft <: MouseButton end
struct ButtonMiddle <: MouseButton end
struct ButtonRight <: MouseButton end
struct ButtonScrollUp <: MouseButton end
struct ButtonScrollDown <: MouseButton end

"""
Store mouse input events, including clicking buttons and scrolling.
"""
Base.@kwdef struct MouseState
    left::Bool = false
    middle::Bool = false
    right::Bool = false
    scroll_up::Bool = false
    scroll_down::Bool = false
    any::Bool = false
end

struct MouseEvent{A <: MouseAction, B <: MouseButton} <: EventData
    button::B
    state::MouseState
    action::A
end

struct ResizeEvent <: EventData
    new_dimensions::Tuple{Int,Int}
end

struct ExposeEvent <: EventData
    exposed_dimensions::Tuple{Int,Int}
    count::Int
end

struct PointerMovesEvent <: EventData
    state::MouseState
    modifiers::KeyModifierState
end

struct PointerLeavesWindowEvent <: EventData end
struct PointerEntersWindowEvent <: EventData end

"""
Generic event structure holding data as an `EventData` member.
"""
struct EventDetails{T <: EventData, W <: AbstractWindow, F <: AbstractFloat}
    data::T
    location::Tuple{Int,Int}
    time::F
    win::W
end

"""
Exception attached to a specific [`AbstractWindow`](@ref) instance.
"""
abstract type WindowException <: Exception end

"""
Signals that the window must be closed.
"""
struct CloseWindow <: WindowException
    win::AbstractWindow
    msg::String
end

"""
Exception to be raised when a window is deemed invalid.
The conditions for tagging a window as invalid depend on the windowing API used. It is typically used to signal that a window crashed or does not exist, but for which an event was reported. It may however not possible to know exactly why or when a window becomes invalid. For example, the X11 protocol does not offer a way to check for window validity, since the window may get invalidated by the time the X server answer comes back.
Windows that are tagged invalid should be terminated.
"""
struct InvalidWindow <: WindowException
    win::AbstractWindow
    msg::String
end

"""
Abstract type for callback structures.
Callback structures should possess function fields
with names coherent with the corresponding callback type.
"""
abstract type Callbacks end

"""
Set of common window callbacks, in response to specific window events.

The callbacks `on_close` and `on_invalid` take respectively a [`CloseWindow`](@ref) and an [`InvalidWindow`](@ref) as argument, while other callbacks take an [`EventDetails`](@ref) as argument parametrized according to the event.

Each field documents when and in which context the callback may be called.
"""
Base.@kwdef struct WindowCallbacks <: Callbacks
    """
    The window is closing normally upon raising an exception of type [`CloseWindow`](@ref).
    """
    on_close                 = default_on_close
    """
    The window is detected as invalid (for example, when closed externally) through an exception of type [`InvalidWindow`](@ref).
    """
    on_invalid               = default_on_invalid
    """
    The window was resized.
    """
    on_resize                = nothing
    """
    A mouse button was pressed.
    """
    on_mouse_button_pressed  = nothing
    """
    A mouse button was released.
    """
    on_mouse_button_released = nothing
    """
    The pointer moves in the window.
    """
    on_pointer_move          = nothing
    """
    The pointer enters the window area.
    """
    on_pointer_enter         = nothing
    """
    The pointer leaves the window area.
    """
    on_pointer_leave         = nothing
    """
    A key was pressed. Note that some key combinations can be reserved by the OS, so they don't trigger the corresponding event. On Ubuntu 20.04, this is for example the case with some combinations of the form alt+fkey such as alt+f4.
    """
    on_key_pressed           = nothing
    """
    A key was released.
    """
    on_key_released          = nothing
    """
    A window was exposed to the screen; either right after creation, or when it was previously hidden and then visible again.
    """
    on_expose                = nothing
end

"""
Abstract execution mode. Controls the execution of the event loop attached to a [`AbstractWindowManager`](@ref)
"""
abstract type ExecutionMode end

struct Asynchronous <: ExecutionMode end
struct Synchronous <: ExecutionMode end


text:
struct MinimizerTable{K,M}
    nbins::UInt32 # Number of parts onto which the kmer space will be subdivided.
    minimizer_table::Vector{UInt32} # The number of times each minimizer has been seen.
    bin_map::Vector{UInt32} # Indexing a minimizer returns the bin it belongs to.
end

function MinimizerTable{K,M}(nbins::Integer) where {K,M}
    @assert K > M
    return MinimizerTable{K,M}(
        convert(UInt32, nbins),
        zeros(UInt32, (1 << (2 * M)) + 1),
        Vector{UInt32}()
    )
end

Base.copy(mt::M) where {M<:MinimizerTable} = M(mt.nbins, copy(mt.minimizer_table), copy(mt.bin_map))

@inline function merge_tables(vec::Vector{M}) where {M<:MinimizerTable}
    mt = copy(vec[1])
    @inbounds for i in 2:lastindex(vec)
        tbl = vec[i]
        mt.minimizer_table .+= tbl.minimizer_table
    end
    return mt
end

function minimizer(::Type{DNAMer{J}}, mer::DNAMer{K}) where {J,K}
    mask = (one(UInt64) << (2 * J)) - 1
    mer_data = BioSequences.encoded_data(mer)
    min_bits = mer_data & mask
    for i in (K - J + 1):-1:1
        new_bits = mer_data & mask
        min_bits = ifelse(new_bits < min_bits, new_bits, min_bits)
        mer_data = mer_data >> 2
    end
    return DNAMer{J}(min_bits)
end

@inline function count_minimizers!(mt::MinimizerTable{K,M}, count_mode::CountMode, seq::LongSequence{A}) where {K,M,A<:DNAAlphabet}
    tbl = mt.minimizer_table
    @inbounds for elem in each(DNAMer{K}, seq)
        mer = count_mode(elem)
        mmer = BioSequences.encoded_data(minimizer(DNAMer{M}, mer))
        tbl[mmer] = tbl[mmer] + 1
    end
end

function initialize_minimizer_table!(mt::MinimizerTable, count_mode::CountMode, datastore::DatastoreBuffer{<:ReadDatastore}, part::AbstractRange)
    seq = eltype(datastore)()
    for i in part
        load_sequence!(datastore, i, seq)
        count_minimizers!(mt, count_mode, seq)
    end
    return mt
end

function calculate_bins!(mt::MinimizerTable)
    minicounts = mt.minimizer_table
    binmap = mt.bin_map
    resize!(binmap, length(minicounts))
    sorted_minimers = sortperm(mt.minimizer_table, rev = true)
    binsums = zeros(Int, mt.nbins)
    for minimer in sorted_minimers
        selected_bin = argmin(binsums)
        minimer_count = minicounts[minimer]
        binsums[selected_bin] += minimer_count
        binmap[minimer] = selected_bin
    end
    return mt
end

function minimizer_table_maker(::Type{M}, ::Type{D}, filename::String, count_mode::CountMode, nbins::Int) where {M<:MinimizerTable,D<:ReadDatastore}
    mt = M(nbins)
    ds = buffer(open(D, filename))
    part = myid():nprocs():length(ds)
    initialize_minimizer_table!(mt, count_mode, ds, part)
    close(ds)
    return mt
end

function calculate_minimizer_distribution(::Type{M}, ::Type{D}, filename::String, count_mode::CountMode, nbins::Int) where {M<:MinimizerTable,D<:ReadDatastore}
    local_tables = Vector{M}(undef, nprocs())
    @sync for p in procs()
        @async local_tables[p] = remotecall_fetch(minimizer_table_maker, p, M, D, filename, count_mode, nbins)
    end
    global_table = merge_tables(local_tables)
    return calculate_bins!(global_table)
end


text:
# Localization strings for Yahoo RSS feed
# source: https://developer.yahoo.com/boss/search/boss_api_guide/supp_regions_lang.html

Argentina_Spanish = "es-AR"
Austria_German = "de-AT"
Australia_English = "en-AU"
Belgium_Dutch = "nl-BE"
Brazil_Portuguese = "pt-BR"
Bulgaria_Bulgarian = "bg-BG"
Canada_English = "en-CA"
Canada_French = "fr-CA"
Chile_Spanish = "es-CL"
Colombia_Spanish = "es-CO"
Croatia_Croatian = "hr-HR"
Czech_Republic = "cs-CZ"
Denmark_Danish = "da-DK"
Estonia_Estonian = "et-EE"
Finland_Finnish = "fi-FI"
France_French = "fr-FR"
Germany_German = "de-DE"
Greece_Greek = "el-GR"
HongKong_SimplifiedChinese = "zh-hant-HK"
Hungary_Hungarian = "hu-HU"
Indonesia_English = "id-EN"
Indonesia_Indonesian = "id-ID"
India_English = "en-IN"
Ireland_English = "en-IE"
Israel_Hebrew = "he-IL"
Italy_Italian = "it-IT"
Japan_Japanese = "ja-JP"
Korea_Korean = "ko-KR"
Latvia_Latvian = "lv-LV"
Lithuania_Lithuanian = "lt-LT"
Malaysia_English = "en-MY"
Malaysia_Malaysian = "ms-MY"
Mexico_Spanish = "es-MX"
Netherlands_Dutch = "nl-NL"
NewZealand_English = "en-NZ"
Norway_Norwegian = "no-NO"
Peru_Spanish = "es-PE"
Philippines_Filipino = "tl-PH"
Philippines_English = "en-PH"
Poland_Polish = "pl-PL"
Romania_Romanian = "ro-RO"
RussiaFederation_Russian = "ru-RU"
SaudiArabia_Arabic = "ar-XA"
Singapore_English = "en-SG"
Slovakia_Slovak = "sk-SK"
Slovenia_Slovenian = "sl-SI"
Spain_Catalan = "ca-ES"
Spain_Spanish = "es-ES"
Sweden_Swedish = "sv-SE"
Switzerland_French = "fr-CH"
Switzerland_German = "de-CH"
Switzerland_Italian = "it-CH"
Thailand_Thai = "th-TH"
Taiwan_TraditionalChinese = "zh-hant-TW"
Turkey_Turkish = "tr-TR"
UnitedKingdom_English = "en-GB"
UnitedStates_English = "en-US"
UnitedStates_Spanish = "es-US"
Venezuela_Spanish = "es-VE"
Vietnam_Vietnamese = "vi-VN"


text:
################################################################################
## Problem Definition -- neural ODE
struct NODE{D,S,N,L,A,K}

    dudt::D
    solver::S
    neural_model::N
    latent_dim_in::L
    latent_dim_out::L
    augment_dim::A
    kwargs::K

    function NODE(latent_dim_in; hidden_dim=200, augment_dim=0, device=cpu, kwargs...)
        dudt = Chain(Dense(latent_dim_in+augment_dim, hidden_dim, relu),
                        Dense(hidden_dim, hidden_dim, relu),
                        Dense(hidden_dim, latent_dim_in+augment_dim)) |> device
        solver = Tsit5()
        neural_model = NeuralODE
        # sensalg = BacksolveAdjoint(autojacvec=ReverseDiffVJP(true))

        latent_dim_out = latent_dim_in + augment_dim

        D = typeof(dudt)
        S = typeof(solver)
        N = typeof(neural_model)
        L = typeof(latent_dim_in)
        A = typeof(augment_dim)
        K = typeof(kwargs)
        new{D,S,N,L,A,K}(dudt, solver, neural_model,latent_dim_in,
                            latent_dim_out, augment_dim, kwargs)
    end

end


text:
include("util.jl")
include("../../src/CGPO.jl")

function PerformCGFor(
    A::AbstractMatrix,
    b::AbstractVecOrMat;
    epsilon=1e-2,
    exact::Bool=true,
    partial_ortho=nothing,
)
    cg = CGPO(A, b)

    if exact

    else
        if partial_ortho === nothing
            cg |> TurnOffReorthgonalize!
        else
            StorageLimit!(cg, partial_ortho)
        end
    end

    ẋ = A\b
    ė = ẋ - cg.x
    ėAė = dot(ė, A*ė)
    E = Vector{Float64}()
    push!(E, 1)
    RelErr = 1
    while RelErr > epsilon
        cg()
        e = ẋ - cg.x
        RelErr = (dot(e, A*e)/ėAė)|>sqrt
        push!(E, RelErr)
    end
    return E
end

E = PerformCGFor(Diagonal(rand(10)), rand(10))

function PerformExperiment1(filename, p=0.9)
    N = 256
    A = GetNastyPSDMatrix(N, p)
    b = rand(N)
    A = convert(Matrix{Float16}, A)
    b = convert(Vector{Float16}, b)
    # TODO: Make the plot distinguishable without colors.

    # ==========================================================================
    # The exact computations
    # ==========================================================================

    RelErr = PerformCGFor(A, b, epsilon=1e-3, exact=true)
    k = length(RelErr)
    fig1 = plot(
        RelErr,
        label="Relative Energy (exact)",
        legend=:bottomleft,
        yaxis=:log10,
        xlabel="iterations: k",
        ylabel="\$\\frac{\\Vert e_k \\Vert_A}{\\Vert e_0\\Vert_A}\$",
        title="CG Rel Energy Error \$\\rho = $(p)\$",
        size=(750, 500), dpi=300,
        left_margin = 10Plots.mm
    )

    # ==========================================================================
    # No-Orthogonalizations
    # ==========================================================================

    RelErr = PerformCGFor(A, b, exact=false, epsilon=1e-3)
    k = length(RelErr)
    plot!(
        fig1,
        RelErr,
        label="Relative Energy (floats)",
        linestyle=:dash#, markershape=:+
    )

    # ==========================================================================
    # Theoretical Bounds
    # ==========================================================================
    ErrorsBound = [TheoreticalErrorBound(A, idx) for idx in 1: k]
    plot!(
        fig1,
        ErrorsBound,
        label="Theoretical Bound (exact)",
        linestyle=:dot
    )

    # ==========================================================================
    # Floating Points Partially Orthogonalized
    # ==========================================================================
    RelErr = PerformCGFor(A, b, exact=false, epsilon=1e-3, partial_ortho=div(N, 8))
    k = length(RelErr)
    plot!(
        fig1,
        RelErr,
        label="Relative Energy (partial)",
        legend=:bottomleft,
        linestyle=:dashdot # ,  markershape=:x
    )

    display(fig1)
    SaveFigToCurrentScriptDir(fig1, "$(filename).png")

return end

PerformExperiment1("cg_convergence_0.9")
PerformExperiment1("cg_convergence_1", 1)


text:
using GAFramework, GAFramework.MagnaGA
using LightGraphs, SparseArrays
using Random
using Statistics
using DelimitedFiles
#GAFramework.setthreads(false)

"""
Return line after skipping if pred(line) is true
Default pred: after skipping empty lines and commented lines
"""
function readskipping(fd::IO,
    pred=line -> length(line)==0 || line[1]=='#' || line[1]=='%')
    while !eof(fd)
        line = strip(readline(fd))
        if pred(line); continue; end
        return line
    end
    return ""
end

"""
    readgw(fd::IO)
    readgw(file::AbstractString) -> SparseMatrixCSC, node list
Reads LEDA format file describing a network. Outputs an undirected network.
An example of a LEDA file is in the examples/ directory.
"""
function readgw(fd::IO)
    line = readskipping(fd)
    strip(line)=="LEDA.GRAPH" || error("Error in line: $line")
    for i = 1:3; readskipping(fd); end
    nverts = parse(Int,readskipping(fd))
    vertices = Array{String}(undef, nverts)
    for i = 1:nverts
        line = readskipping(fd)
        vertices[i] = match(r"\|{(.*?)}\|",line).captures[1]
    end
    nedges = parse(Int,readskipping(fd))
    I = Vector{Int}(undef, nedges)
    J = Vector{Int}(undef, nedges)
    for i = 1:nedges
        line = readskipping(fd)
        caps = match(r"(\d+) (\d+) 0 \|{.*}\|",line).captures
        n1 = parse(Int,caps[1])
        n2 = parse(Int,caps[2])
        n1==n2 && continue
        I[i] = n1
        J[i] = n2
    end
    G = sparse(vcat(I,J), vcat(J,I), 1, nverts, nverts, max)
    return G, vertices
end
readgw(file::AbstractString, args...) = open(fd -> readgw(fd,args...), file, "r")

function main()
    n1 = ARGS[1]
    n2 = ARGS[2]
    sim = ARGS[3]
    alpha = parse(Float64, ARGS[4])
    npop = parse(Int, ARGS[5])
    ngen = parse(Int, ARGS[6])
    elite_fraction = parse(Float64, ARGS[7])
    out = ARGS[8]

    G1,verts1 = readgw(n1)
    G2,verts2 = readgw(n2)

    S,_ = readdlm(sim, header=true)

    model = MagnaModel(G1,G2,S,alpha)
    st = GAState(model, ngen=2, npop=2, elite_fraction=0.5)
    ga!(st)

    model = MagnaModel(G1,G2,S,alpha)
    st = GAState(model, ngen=ngen, npop=npop, elite_fraction=elite_fraction)
    @time ga!(st)

    r = st.pop[1]
    verts2map = verts2[r.f]
    correctness = mean(verts1 .== verts2map[1:length(verts1)])
    open("$(out)_final_alignment.txt", "w") do fd
        for i in 1:length(verts1)
            println(fd, "$(verts1[i]) $(verts2map[i])")
        end
    end
    function print_stats(fd)
        println(fd, "generation final")
        println(fd, "score $(r.score)")
        println(fd, "node_score $(r.node_score)")
        println(fd, "S3_score $(r.edge_score)")
        println(fd, "node_correctness $(correctness)")
    end
    print_stats(stdout)
    open(print_stats, "$(out)_final_stats.txt", "w")
end

main()


text:
# ---
# title: 1020. Number of Enclaves
# id: problem1020
# author: zhwang
# date: 2022-02-12
# difficulty: Medium
# categories: Depth-first Search
# link: <https://leetcode.com/problems/number-of-enclaves/description/>
# hidden: true
# ---
#
# Given a 2D array `A`, each cell is 0 (representing sea) or 1 (representing
# land)
#
# A move consists of walking from one land square 4-directionally to another
# land square, or off the boundary of the grid.
#
# Return the number of land squares in the grid for which we **cannot** walk off
# the boundary of the grid in any number of moves.
#
#
#
# **Example 1:**
#
#
#
#     Input: [[0,0,0,0],[1,0,1,0],[0,1,1,0],[0,0,0,0]]
#     Output: 3
#     Explanation:
#     There are three 1s that are enclosed by 0s, and one 1 that isn't enclosed because its on the boundary.
#
# **Example 2:**
#
#
#
#     Input: [[0,1,1,0],[0,0,1,0],[0,0,1,0],[0,0,0,0]]
#     Output: 0
#     Explanation:
#     All 1s are either on the boundary or can reach the boundary.
#
#
#
#
# **Note:**
#
#   1. `1 <= A.length <= 500`
#   2. `1 <= A[i].length <= 500`
#   3. `0 <= A[i][j] <= 1`
#   4. All rows have the same size.
#
#
## @lc code=start
using LeetCode

## BFS algorithm
function num_of_enclaves_bfs(grid::Vector{Vector{Int}})::Int
    m, n, queue = length(grid), length(grid[1]), Tuple{Int,Int}[]
    (m <= 2 || n <= 2) && return 0
    for i in 1:m ## left and right border
        grid[i][1] == 1 && push!(queue, (i, 1))
        grid[i][n] == 1 && push!(queue, (i, n))
    end
    for i in 2:(n - 1)
        grid[1][i] == 1 && push!(queue, (1, i))
        grid[m][i] == 1 && push!(queue, (m, i))
    end
    walkoff = copy(queue)
    while length(queue) != 0
        i, j = popfirst!(queue)
        for (a, b) in [(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)]
            if a >= 1 &&
                b >= 1 &&
                a <= m &&
                b <= n &&
                grid[a][b] != 0 &&
                !((a, b) in walkoff)
                push!(walkoff, (a, b))
                push!(queue, (a, b))
            end
        end
    end
    return sum(sum(line) for line in grid) - length(walkoff)
end
## @lc code=end


text:
@testset "1109.corporate-flight-bookings.jl" begin
    @test corp_flight_bookings([[1, 2, 10], [2, 3, 20], [2, 5, 25]], 5) ==
          [10, 55, 45, 25, 25]
    @test corp_flight_bookings([[1, 2, 10], [2, 2, 15]], 2) == [10, 25]
end


text:
"""
    share_labor!(d::Dict, set::Dict)
"""
function share_labor!(d::Dict, set::Dict)
    println("  Calculating labor(yr,r,s), labor share")

    !(:region in collect(keys(d))) && share_region!(d, set)
    _share_lshr0!(d, set)

    cols = propertynames(d[:region])

    df = copy(d[:gsp])
    df[!,:value] .= df[:,:cmp] ./ df[:,:comp]
    df = dropnan(df[:,cols])

    # Begin summary DataFrame.
    df = indexjoin([df, d[:region], d[:lshr0]]; id=[:value,:region,:lshr0])

    # Use the national average labor share (calculated when partitioning)
    # in cases where the labor share is zero (e.g. banking, finance, etc.).
    ii = .&(df[:,:value] .== 0.0, df[:,:region] .> 0.0)
    df[ii,:value] .= df[ii,:lshr0]
    df = fill_zero(df)

    # d[:labor_temp] = copy(d[:labor])
    # Save labor to input in functions to calculate annual and regional average wage shares.
    df[!,:labor_shr_pre_avg] .= df[:,:value]
    d[:labor] = df[:,cols]

    df[!,:wg] .= _share_wg!(d, set)[:,:value]
    df[!,:hw] .= _share_hw!(d, set)[:,:value]
    df[!,:avg_wg] = _share_avg_wg!(d)[:,:value]
    df[!,:sec_labor] = _share_sec_labor!(d)[:,:value]

    wg = .&(df[:,:wg], df[:,:avg_wg] .!== 0.0)
    df[wg,:value] .= df[wg,:avg_wg]
    df[df[:,:hw],:value] .= df[df[:,:hw],:sec_labor]
    d[:labor] = dropnan(df[:, cols])
    d[:labor_calc] = df
    return d[:labor]
end

"""
`region(yr,r,s)`: Regional share of value added

```math
\\alpha_{yr,r,s}^{gsp}
=
\\begin{cases}
\\dfrac{           \\bar{gdp}_{yr,r,s}}
       {\\sum_{s'} \\bar{gdp}_{yr,r,s'}}      & \\sum_{s'} \\bar{gdp}_{yr,r,s'} \\neq 0
\\\\
\\dfrac{\\sum_{s}    \\bar{gdp}_{yr,r ,s}}
       {\\sum_{r',s} \\bar{gdp}_{yr,r',s}}    & \\sum_{s'} \\bar{gdp}_{yr,r,s'} = 0
\\end{cases}
```
"""
function share_region!(d::Dict, set::Dict)
    println("  Calculating region(yr,r,s), regional share of value added")
    :gdpcat in propertynames(d[:gsp]) && _share_gsp!(d, set)

    cols = [findindex(d[:gsp]); :value]
    df = edit_with(copy(d[:gsp]), Rename(:gdp, :value))[:,cols]
    df = df / transform_over(df, :r)

    # JUST IN CASE we switch back to g here..
    s = intersect(cols, [:s,:g])[1]

    # Let the used and scrap sectors be an average of other sectors.
    # These are the only sectors that have NaN values.
    df = df[.!isnan.(df[:,:value]),:]
    df_s  = combine_over(df, s)
    df_s /= transform_over(df_s, :r)

    df_s = crossjoin(DataFrame(s => set[:oth,:use]), df_s)

    d[:region] = dropnan(dropmissing(sort([df; df_s])))
    verify_over(d[:region], :r) !== true && @error("Regional shares don't sum to 1.")
    return d[:region]
end

"""
`gsp`: Calculated gross state product.

Calculate factor totals:
```math
\\begin{aligned}
\\bar{sudo}_{yr,r,s} &= \\bar{gdp}_{yr,r,s} - \\bar{taxsbd}_{yr,r,s}
\\\\
\\bar{comp}_{yr,r,s} &= \\bar{cmp}_{yr,r,s} - \\bar{gos}_{yr,r,s}
\\end{aligned}
```
"""
function _share_gsp!(d::Dict, set::Dict)
    df = copy(d[:gsp])
    :gdpcat in propertynames(d[:gsp]) && (df = unstack(dropzero(d[:gsp]), :gdpcat, :value))

    df = edit_with(df, Replace.(Symbol.(set[:gdpcat]), missing, 0.0))

    df[!,:sudo] .= df[:,:gdp] - df[:,:taxsbd]
    df[!,:comp] .= df[:,:cmp] + df[:,:gos]

    df[!,:calc] .= df[:,:cmp] + df[:,:gos] + df[:,:taxsbd]
    df[!,:diff] .= df[:,:calc] - df[:,:gdp]

    d[:gsp] = df
end

"`lshr0`: Labor share of value added"
function _share_lshr0!(d::Dict, set::Dict)
    va0 = edit_with(unstack(copy(d[:va0]), :va, :value),
        Replace.(Symbol.(set[:va]), missing, 0.0))
    idx = findindex(va0)

    d[:lshr0] = va0[:,[idx;:compen]]
    d[:lshr0] /= (va0[:,[idx;:compen]] + va0[:,[idx;:surplus]])

    d[:lshr0][va0[:,:surplus] .< 0,:value] .= 1.0
    return dropmissing!(dropnan!(d[:lshr0]))
end

"`wg(yr,r,s)`: Index pairs with high wage shares (>1)"
function _share_wg!(d::Dict, set::Dict)
    d[:wg] = copy(d[:labor])
    d[:wg][!,:value] .= d[:wg][:,:value] .> 1
    set[:wg] = values.(eachrow(d[:wg][d[:wg][:,:value], find_oftype(d[:wg], Not(Bool))]))
    return d[:wg] # must return the DataFrame
end

"`hw(r,s)`: (region,sector) pairings with ALL wage shares > 1"
function _share_hw!(d::Dict, set::Dict)
    # (!!!!) When WiNDC calculates this, years with all wage shares = 0 are included.
    # So I'm ok with this difference.
    !(:wg in collect(keys(d))) && _share_wg!(d, set)

    df = copy(d[:wg])
    d[:hw] = combine_over(df, :yr; fun=prod)
    set[:hw] = values.(eachrow(d[:hw][d[:hw][:,:value], find_oftype(d[:hw], String)]))
    return transform_over(df, :yr; fun=prod) # must return the DataFrame
end

"""
"""
function _share_avg_wg!(d::Dict)
    # Here, WiNDC uses .!wg, which DOES include labor = 1.
    !(:wg in collect(keys(d))) && _share_wg!(d, set)
    not_wg = edit_with(copy(d[:wg]), Replace(:value, Bool, Not))

    df = copy(d[:labor]) * not_wg
    d[:avg_wg] = edit_with(combine_over(df, :yr) / combine_over(not_wg, :yr), Replace(:value, NaN, 0.0))
    return edit_with(transform_over(df, :yr) / transform_over(not_wg, :yr), Replace(:value, NaN, 0.0))
end

"""
"""
function _share_sec_labor!(d::Dict)
    # Cannot use .!wg because this will include labor = 1.
    not_wg = copy(d[:labor])
    not_wg[!,:value] .= not_wg[:,:value] .< 1

    df = copy(d[:labor]) * not_wg
    d[:sec_labor] = combine_over(df, :r) / combine_over(not_wg, :r)
    return transform_over(df, :r) / transform_over(not_wg, :r)
end

max_stars_repo_name: NREL/SLiDE

max_issues_repo_name: NREL/SLiDE

max_forks_repo_name: NREL/SLiDE


text:
using BenchmarkTools
using Random
using VPTrees

Random.seed!(1)
function hamming(a::Integer, b::Integer)
    count_ones(xor(a, b))
end
randints = [rand(UInt) for _ in 1:10000]
@benchmark VPTree(randints, hamming)
# BenchmarkTools.Trial:
#   memory estimate:  36.16 MiB
#   allocs estimate:  96189
#   --------------
#   minimum time:     14.749 ms (10.84% GC)
#   median time:      17.335 ms (21.43% GC)
#   mean time:        17.348 ms (20.07% GC)
#   maximum time:     63.897 ms (73.87% GC)
#   --------------
#   samples:          288
#   evals/sample:     1
randints = [rand(UInt) for _ in 1:40000]
vptree = VPTree(randints, hamming);
query = rand(UInt)
radius = 20
@benchmark find(vptree, query, radius)

# BenchmarkTools.Trial:
#   memory estimate:  2.22 KiB
#   allocs estimate:  8
#   --------------
#   minimum time:     230.819 μs (0.00% GC)
#   median time:      253.774 μs (0.00% GC)
#   mean time:        276.296 μs (0.40% GC)
#   maximum time:     11.471 ms (97.37% GC)
#   --------------
#   samples:          10000
#   evals/sample:     1
@benchmark find_nearest(vptree, query, 20)
# BenchmarkTools.Trial:
#   memory estimate:  1.38 KiB
#   allocs estimate:  9
#   --------------
#   minimum time:     321.168 μs (0.00% GC)
#   median time:      343.786 μs (0.00% GC)
#   mean time:        360.818 μs (0.00% GC)
#   maximum time:     1.245 ms (0.00% GC)
#   --------------
#   samples:          10000
#   evals/sample:     1

using StringDistances
using Statistics

metric(a::AbstractString, b::AbstractString) = evaluate(Levenshtein(), a,b)
prefixes = readlines("resources/benchmark_data.csv")

Random.seed!(2)
t = VPTree(prefixes, metric)
rng = Random.MersenneTwister(1)
@benchmark find(t, prefixes[rand(rng, 1:length(prefixes))], 2)
rng = Random.MersenneTwister(1)
@benchmark findall(a -> metric(prefixes[rand(rng, 1:length(prefixes))], a) <= 2, prefixes)


text:
# Try to register an already existing version with different content.
with_empty_registry() do registry_dir, packages_dir
    prepare_package(packages_dir, "Flux24.toml")
    register(joinpath(packages_dir, "Flux"),
             registry = registry_dir,
             gitconfig = TEST_GITCONFIG,
             push = false)
    prepare_package(packages_dir, "Flux30.toml")
    @test_throws ErrorException register(joinpath(packages_dir, "Flux"),
                                         registry = registry_dir,
                                         gitconfig = TEST_GITCONFIG,
                                         push = false)
    # This should do nothing more than give an informational message.
    @test do_register(joinpath(packages_dir, "Flux"), registry_dir,
                      gitconfig = TEST_GITCONFIG, push = false,
                      ignore_reregistration = true) == false
end

# Parse error in compat section.
with_empty_registry() do registry_dir, packages_dir
    prepare_package(packages_dir, "Broken1.toml")
    if VERSION < v"1.2"
        @test_throws ErrorException register(joinpath(packages_dir, "Broken"),
                                             registry = registry_dir,
                                             gitconfig = TEST_GITCONFIG,
                                             push = false)
    else
        @test_throws Pkg.Types.PkgError register(joinpath(packages_dir, "Broken"),
                                                 registry = registry_dir,
                                                 gitconfig = TEST_GITCONFIG,
                                                 push = false)
    end
end

# Try to change name (UUID remains).
with_empty_registry() do registry_dir, packages_dir
    prepare_package(packages_dir, "Flux1.toml")
    register(joinpath(packages_dir, "Flux"),
             registry = registry_dir,
             gitconfig = TEST_GITCONFIG,
             push = false)
    prepare_package(packages_dir, "Fluxx1.toml")
    @test_throws ErrorException register(joinpath(packages_dir, "Fluxx"),
                                         registry = registry_dir,
                                         gitconfig = TEST_GITCONFIG,
                                         push = false)
end

# Try to change UUID.
with_empty_registry() do registry_dir, packages_dir
    prepare_package(packages_dir, "Flux1.toml")
    register(joinpath(packages_dir, "Flux"),
             registry = registry_dir,
             gitconfig = TEST_GITCONFIG,
             push = false)
    prepare_package(packages_dir, "Flux31.toml")
    @test_throws ErrorException register(joinpath(packages_dir, "Flux"),
                                         registry = registry_dir,
                                         gitconfig = TEST_GITCONFIG,
                                         push = false)
end

# Depends on itself.
with_empty_registry() do registry_dir, packages_dir
    prepare_package(packages_dir, "Broken2.toml")
    @test_throws ErrorException register(joinpath(packages_dir, "Broken"),
                                         registry = registry_dir,
                                         gitconfig = TEST_GITCONFIG,
                                         push = false)
end

# Incorrect name of dependency.
with_empty_registry() do registry_dir, packages_dir
    prepare_package(packages_dir, "Flux1.toml")
    register(joinpath(packages_dir, "Flux"),
             registry = registry_dir,
             gitconfig = TEST_GITCONFIG,
             push = false)
    prepare_package(packages_dir, "Broken3.toml")
    @test_throws ErrorException register(joinpath(packages_dir, "Broken"),
                                         registry = registry_dir,
                                         gitconfig = TEST_GITCONFIG,
                                         push = false)
end

# TODO: This should really be an error but RegistryTools 1.3.0 doesn't catch it.
# Incorrect UUID of dependency.
with_empty_registry() do registry_dir, packages_dir
    prepare_package(packages_dir, "Broken4.toml")
    register(joinpath(packages_dir, "Broken"), registry = registry_dir,
             gitconfig = TEST_GITCONFIG, push = false)
end

# Incorrect UUID of stdlib.
with_empty_registry() do registry_dir, packages_dir
    prepare_package(packages_dir, "Broken5.toml")
    @test_throws ErrorException register(joinpath(packages_dir, "Broken"),
                                         registry = registry_dir,
                                         gitconfig = TEST_GITCONFIG,
                                         push = false)
end

with_empty_registry() do registry_dir, packages_dir
    prepare_package(packages_dir, "Flux1.toml")
    register(joinpath(packages_dir, "Flux"),
             registry = registry_dir,
             gitconfig = TEST_GITCONFIG,
             push = false)
    # Change the git remote before registration and verify that the
    # registered repo is not changed.
    prepare_package(packages_dir, "Flux32.toml")
    package_dir = joinpath(packages_dir, "Flux")
    git = gitcmd(package_dir, TEST_GITCONFIG)
    package_file = joinpath(registry_dir, "F", "Flux", "Package.toml")
    old_repo = TOML.parsefile(package_file)["repo"]
    new_repo = "https://example.com/Julia/Flux.jl.git"
    run(`$git remote set-url origin $(new_repo)`)
    register(joinpath(packages_dir, "Flux"), registry = registry_dir,
             gitconfig = TEST_GITCONFIG, push = false)
    @test TOML.parsefile(package_file)["repo"] == old_repo

    # Register with explicit repo argument and verify that the registered
    # repo is updated.
    prepare_package(packages_dir, "Flux33.toml")
    register(joinpath(packages_dir, "Flux"), registry = registry_dir,
             repo = new_repo, gitconfig = TEST_GITCONFIG, push = false)
    @test TOML.parsefile(package_file)["repo"] == new_repo
end

# Register a package in a subdirectory of a git repository. Also add
# some dirt outside the subdirectory to verify that it is ignored.
with_empty_registry() do registry_dir, packages_dir
    prepare_package(packages_dir, "SubdirTest1.toml", "subdir")
    write(joinpath(packages_dir, "SubdirTest", "README.md"), "dirty")
    register(joinpath(packages_dir, "SubdirTest", "subdir"),
             registry = registry_dir, gitconfig = TEST_GITCONFIG, push = false)
    package_file = joinpath(registry_dir, "S", "SubdirTest", "Package.toml")
    @test TOML.parsefile(package_file)["subdir"] == "subdir"
end

# Register a package with a JuliaProject.toml rather than a Project.toml.
with_empty_registry() do registry_dir, packages_dir
    prepare_package(packages_dir, "JuliaProjectTest1.toml",
                    use_julia_project = true)
    register(joinpath(packages_dir, "JuliaProjectTest"), registry = registry_dir,
             gitconfig = TEST_GITCONFIG, push = false)
    @test isfile(joinpath(registry_dir, "J", "JuliaProjectTest", "Package.toml"))
end

# Remove Project.toml from a package and try to register.
with_empty_registry() do registry_dir, packages_dir
    prepare_package(packages_dir, "Flux1.toml")
    rm(joinpath(packages_dir, "Flux", "Project.toml"))
    @test_throws ErrorException register(joinpath(packages_dir, "Flux"),
                                         registry = registry_dir,
                                         gitconfig = TEST_GITCONFIG,
                                         push = false)
end

# Dirty the package repository and try to register the package.
with_empty_registry() do registry_dir, packages_dir
    prepare_package(packages_dir, "Flux1.toml")
    readme = joinpath(packages_dir, "Flux", "README.md")
    open(readme, "a") do io
        write(io, "\n")
    end
    @test_throws ErrorException register(joinpath(packages_dir, "Flux"),
                                         registry = registry_dir,
                                         gitconfig = TEST_GITCONFIG,
                                         push = false)
end

# Dirty the registry repository and try to register a package.
with_empty_registry() do registry_dir, packages_dir
    prepare_package(packages_dir, "Flux1.toml")
    filename = joinpath(registry_dir, "Registry.toml")
    open(filename, "a") do io
        write(io, "\n")
    end
    @test_throws ErrorException register(joinpath(packages_dir, "Flux"),
                                         registry = registry_dir,
                                         gitconfig = TEST_GITCONFIG,
                                         push = false)
    # Allowed with `commit = false`.
    register(joinpath(packages_dir, "Flux"), registry = registry_dir,
             gitconfig = TEST_GITCONFIG, push = false,  commit = false)
end

# Test automatic push functionality. The sequence of events is:
# 1. Create a bare "upstream" repository.
# 2. Create a new registry with the upstream as repo and `push = true`.
# 3. Register a package with `push = true`.
# 4. Verify that the registry and the upstream repo has the same two commits.
with_testdir() do testdir
    upstream_dir = joinpath(testdir, "upstream")
    mkpath(upstream_dir)
    upstream_git = gitcmd(upstream_dir, TEST_GITCONFIG)
    run(`$(upstream_git) init --bare`)
    registry_push_dir = joinpath(testdir, "TestRegistryPush")
    create_registry(registry_push_dir, "file://$(upstream_dir)", push = true,
                    gitconfig = TEST_GITCONFIG)
    downstream_git = gitcmd(registry_push_dir, TEST_GITCONFIG)
    packages_dir = joinpath(testdir, "packages")
    prepare_package(packages_dir, "FirstTest1.toml")
    register(joinpath(packages_dir, "FirstTest"), registry = registry_push_dir,
             push = true, gitconfig = TEST_GITCONFIG)
    @test readchomp(`$(downstream_git) log`) == readchomp(`$(upstream_git) log`)
    @test length(readlines(`$(upstream_git) log --format=oneline`)) == 2

    # Now duplicate the upstream repo. Then register the same package
    # * like before via downstream repo with push,
    # * directly against the second upstream, internally using a
    #   temporary clone.
    upstream2_dir = joinpath(testdir, "upstream2")
    mkpath(upstream2_dir)
    upstream2_git = gitcmd(upstream2_dir, TEST_GITCONFIG)
    run(`$(upstream2_git) clone --bare file://$(upstream_dir) .`)
    prepare_package(packages_dir, "Flux1.toml")
    register(joinpath(packages_dir, "Flux"), registry = registry_push_dir,
             push = true, gitconfig = TEST_GITCONFIG)
    # Can't have `push = false` when using a temporary git clone.
    @test_throws ErrorException register(joinpath(packages_dir, "Flux"),
                                         registry = "file://$(upstream2_dir)",
                                         push = false,
                                         gitconfig = TEST_GITCONFIG)
    register(joinpath(packages_dir, "Flux"), registry = "file://$(upstream2_dir)",
             push = true, gitconfig = TEST_GITCONFIG)
    @test readchomp(`$(downstream_git) log`) == readchomp(`$(upstream_git) log`)
    # Can't use standard log format here since the time stamps will be different.
    @test readchomp(`$(downstream_git) log --format=%T:%s`) == readchomp(`$(upstream2_git) log --format=%T:%s`)
    @test length(readlines(`$(upstream2_git) log --format=%T:%s`)) == 3

    # Register one more package, this time using a branch.
    prepare_package(packages_dir, "Images1.toml")
    register(joinpath(packages_dir, "Images"), registry = registry_push_dir,
             push = true, branch = "images", gitconfig = TEST_GITCONFIG)
    register(joinpath(packages_dir, "Images"),
             registry = "file://$(upstream2_dir)",
             push = true, branch = "images", gitconfig = TEST_GITCONFIG)
    @test readchomp(`$(downstream_git) log`) == readchomp(`$(upstream_git) log`)
    # Can't use standard log format here since the time stamps will be different.
    @test readchomp(`$(upstream_git) log --format=%T:%s images`) == readchomp(`$(upstream2_git) log --format=%T:%s images`)
    @test length(readlines(`$(upstream2_git) log --format=%T:%s images`)) == 4
end


text:
module SparseDiffTools

export CGraph, add_vertex!, add_edge!, neighbors, vertices, has_edge, num_edges, has_vertex, rem_edge!, rem_vertex!,
colorGraph, num_vertices, max_degree_vertex, non_neighbors, length_common_neighbor, vertex_degree, contract!,
greedy_d1

include("custom_graph.jl")
include("contraction_algo.jl")
include("greedy_dist1_coloring.jl")

end # module