text:
# This file is a part of SearchModels.jl

using Test

using SearchModels
import SearchModels: combine, mutate

mutable struct RosenbrockSpace <: AbstractSolutionSpace
    xrange
    yrange
end

RosenbrockSpace() = RosenbrockSpace(-3.0:0.1:10.0, -10.0:0.1:3.0)

const RoseParams = Tuple{Float64, Float64}

Base.eltype(::RosenbrockSpace) = RoseParams

function Base.rand(space::RosenbrockSpace)
    rand(space.xrange), rand(space.yrange)
end

function combine(a::RoseParams, b::RoseParams)
    if rand() < 0.5
        a[1], b[2]
    else
        (a[1] + b[1])/2, (a[2] + b[2])/2
    end
end

function mutate(space::RosenbrockSpace, c::RoseParams, iter)
    if rand() < 0.5
        c[1], rand(space.yrange)
    else
        rand(space.xrange), c[2]
    end
end

function rosenbrock(x)::Float64
    (1-x[1])^2+100*(x[2]-x[1]^2)^2
end

@testset "SearchModels.jl" begin
    function inspect_population(space, params, population)
        xmin = ymin = typemax(Float64)
        xmax = ymax = typemin(Float64)

        for p in population
            c = p[1]
            xmin = min(xmin, c[1])
            ymin = min(ymin, c[2])
            xmax = max(xmax, c[1])
            ymax = max(ymax, c[2])
        end

        st = 0.1
        e = 10
        space.xrange = xmin-st*e:st:xmax+st*e
        space.yrange = ymin-st*e:st:ymax+st*e
    end

    println("===== RoseParams without inspect_population")

    space = RosenbrockSpace()
    params = SearchParams(
        bsize=32,
        mutbsize=100,
        crossbsize=100,
        tol=0.0,
        maxiters=300,
        verbose=true
    )

    B = search_models(rosenbrock, space, 1000, params)

    for (i, p) in enumerate(B[1:15])
        println(stderr, i => p)
    end

    println("===== RoseParams using inspect_population")

    space = RosenbrockSpace()

    B = search_models(rosenbrock, space, 1000, params, inspect_population=inspect_population)

    for (i, p) in enumerate(B[1:15])
        println(stderr, i => p)
    end
end


text:
using Test
using UAPIC
using FFTW
using LinearAlgebra

include("test_efd.jl")
include("test_poisson.jl")
include("test_particles.jl")
include("bupdate.jl")

ext: jl


text:
using SparseArrays, DiffEqOperators, LinearAlgebra, Random,
      Test, BandedMatrices, FillArrays

# Analytic solutions to higher order operators.
# Do not modify unless you are completely certain of the changes.

# 4th derivative, 4th order
function fourth_deriv_approx_stencil(N)
    A = zeros(N,N+2)
    A[1,1:8] = [3.5 -56/3 42.5 -54.0 251/6 -20.0 5.5 -2/3]
    A[2,1:8] = [2/3 -11/6 0.0 31/6 -22/3 4.5 -4/3 1/6]

    A[N-1,N-5:end] = reverse([2/3 -11/6 0.0 31/6 -22/3 4.5 -4/3 1/6], dims=2)
    A[N,N-5:end] = reverse([3.5 -56/3 42.5 -54.0 251/6 -20.0 5.5 -2/3], dims=2)

    for i in 3:N-2
        A[i,i-2:i+4] = [-1/6 2.0 -13/2 28/3 -13/2 2.0 -1/6]
    end
    return A
end

function second_deriv_fourth_approx_stencil(N)
    A = zeros(N,N+2)
    A[1,1:6] = [5/6 -15/12 -1/3 7/6 -6/12 5/60]
    A[N,N-3:end] = [1/12 -6/12 14/12 -4/12 -15/12 10/12]
    for i in 2:N-1
        A[i,i-1:i+3] = [-1/12 4/3 -5/2 4/3 -1/12]
    end
    return A
end

function second_derivative_stencil(N)
  A = zeros(N,N+2)
  for i in 1:N, j in 1:N+2
      (j-i==0 || j-i==2) && (A[i,j]=1)
      j-i==1 && (A[i,j]=-2)
  end
  A
end

# analytically derived central difference operators for the irregular grid:
# [0.0, 0.08, 0.1, 0.15, 0.19, 0.26, 0.29], and spacing:
# dx = [0.08, 0.02, 0.05, 0.04, 0.07, 0.03]
# with convention that the first number is the derivative order
# and the second is the approximation order

function analyticCtrOneTwoIrr()
    A = zeros(5,7)
    A[1,1:3] = [-5. / 2., -75. / 2., 40.]
    A[2,2:4] = [-250. / 7., 30., 40. / 7.]
    A[3,3:5] = [-80. / 9., -5., 125. / 9.]
    A[4,4:6] = [-1225. / 77., 825. / 77., 400. / 77.]
    A[5,5:7] = [-30. / 7., -400. / 21., 70. / 3.]
    A
end

function analyticCtrTwoTwoIrr()
    A = zeros(5,7)
    A[1,1:3] = [250., -1250., 1000.]
    A[2,2:4] = [10000. / 7., -2000., 4000. / 7.]
    A[3,3:5] = [4000. / 9., -1000., 5000. / 9.]
    A[4,4:6] = [454. + 42. / 77., -5000. / 7., 20000. / 77.]
    A[5,5:7] = [6000. / 21., -20000. / 21., 2000. / 3.]
    A
end

function analyticCtrTwoFourIrr()
    A = zeros(3,7)
    A[1,1:5] = [14. + 12012. / 13167., 1542. + 2736. / 13167.,
                -2288. - 11704. / 13167., 838. + 1254. / 13167.,
                -106. - 4298. / 13167.]
    A[2,2:6] = [-223. - 461. / 693., 847. + 154. / 693.,
                -1311. - 477. / 693., 699. + 593. / 693.,
                -11. - 502. / 693.]
    A[3,3:7] = [2. + 12166. / 13167., 538. + 12654. / 13167.,
                -912. - 9196. / 13167., 508. + 8664. / 13167.,
                -137. - 11121. / 13167.]
    A
end

function analyticCtrFourTwoIrr()
    A = zeros(3,7)
    A[1,1:5] = [462000000. / 4389.,
                -8550000000. / 4389.,
                11704000000. / 4389.,
                -5016000000. / 4389.,
                1400000000. / 4389.]
    A[2,2:6] = [200000000. / 231.,
                -385000000. / 231.,
                360000000. / 231.,
                -200000000. / 231.,
                25000000. / 231.]
    A[3,3:7] = [770000000. / 4389.,
                -3420000000. / 4389.,
                4180000000. / 4389.,
                -2850000000. / 4389.,
                1320000000 / 4389.]
    A
end

function convert_by_multiplication(::Type{Array}, A::AbstractDerivativeOperator{T}, N::Int=A.dimension) where T
    @assert N >= A.stencil_length # stencil must be able to fit in the matrix
    mat = zeros(T, (N, N+2))
    v = zeros(T, N+2)
    for i=1:N+2
        v[i] = one(T)
        #=
            calculating the effect on a unit vector to get the matrix of transformation
            to get the vector in the new vector space.
        =#
        mul!(view(mat,:,i), A, v)
        v[i] = zero(T)
    end
    return mat
end

# Tests the corrrectness of stencils, along with concretization.
# Do not modify the following test-set unless you are completely certain of your changes.
@testset "Correctness of Uniform Stencils" begin
    N = 20
    L = CenteredDifference(4,4, 1.0, N)
    correct = fourth_deriv_approx_stencil(N)

    # Check that stencils (according to convert_by_multiplication) agree with correct
    @test convert_by_multiplication(Array, L, N) ≈ correct

    # Check that concretization agrees correct
    @test Array(L) ≈ correct
    @test sparse(L) ≈ correct
    @test BandedMatrix(L) ≈ correct

    L = CenteredDifference(2,4, 1.0, N)
    correct = second_deriv_fourth_approx_stencil(N)

    # Check that stencils (according to convert_by_multiplication) agree with correct
    @test convert_by_multiplication(Array, L, N) ≈ correct

    # Check that concretization agrees correct
    @test Array(L) ≈ correct
    @test sparse(L) ≈ correct
    @test BandedMatrix(L) ≈ correct
end

@testset "Correctness of Non-Uniform Stencils" begin
    x = [0., 0.08, 0.1, 0.15, 0.19, 0.26, 0.29]
    nx = length(x)
    dx = diff(x)

    # Second-Order First Derivative
    L = CenteredDifference(1, 2, dx, nx-2)
    correct = analyticCtrOneTwoIrr()

    # Check that stencils agree with correct
    for (i,coefs) in enumerate(L.stencil_coefs)
        @test Array(coefs) ≈ correct[i,correct[i,:] .!= 0.]
    end
    @test Array(L) ≈ correct
    @test sparse(L) ≈ correct
    @test BandedMatrix(L) ≈ correct

    # Second-Order Second Derivative
    L = CenteredDifference(2, 2, dx, nx-2)
    correct = analyticCtrTwoTwoIrr()

    # Check that stencils agree with correct
    for (i,coefs) in enumerate(L.stencil_coefs)
        @test Array(coefs) ≈ correct[i,correct[i,:] .!= 0.]
    end
    @test Array(L) ≈ correct
    @test sparse(L) ≈ correct
    @test BandedMatrix(L) ≈ correct

    # Fourth-Order Second Derivative
    L = CenteredDifference(2, 4, dx, nx-2)
    correct = analyticCtrTwoFourIrr()

    # Check that stencils agree with correct
    for (i,coefs) in enumerate(L.stencil_coefs)
        @test Array(coefs) ≈ correct[i,correct[i,:] .!= 0.]
    end
    @test Array(L)[2:end-1,:] ≈ correct
    @test sparse(L)[2:end-1,:] ≈ correct
    @test BandedMatrix(L)[2:end-1,:] ≈ correct

    # Second-Order Fourth Derivative
    L = CenteredDifference(4, 2, dx, nx-2)
    correct = analyticCtrFourTwoIrr()

    # Check that stencils agree with correct
    for (i,coefs) in enumerate(L.stencil_coefs)
        @test Array(coefs) ≈ correct[i,correct[i,:] .!= 0.]
    end
    @test Array(L)[2:end-1,:] ≈ correct
    @test sparse(L)[2:end-1,:] ≈ correct
    @test BandedMatrix(L)[2:end-1,:] ≈ correct
end

# tests for full and sparse function
@testset "Full and Sparse functions:" begin
    N = 10
    d_order = 2
    approx_order = 2
    correct = second_derivative_stencil(N)
    A = CenteredDifference(d_order,approx_order,1.0,N)

    @test convert_by_multiplication(Array,A,N) == correct
    @test Array(A) == second_derivative_stencil(N)
    @test sparse(A) == second_derivative_stencil(N)
    @test BandedMatrix(A) == second_derivative_stencil(N)
    @test opnorm(A, Inf) == opnorm(correct, Inf)

    # testing higher derivative and approximation concretization
    N = 20
    d_order = 4
    approx_order = 4
    A = CenteredDifference(d_order,approx_order,1.0,N)
    correct = convert_by_multiplication(Array,A,N)

    @test Array(A) ≈ correct
    @test sparse(A) ≈ correct
    @test BandedMatrix(A) ≈ correct

    N = 26
    d_order = 8
    approx_order = 8
    A = CenteredDifference(d_order,approx_order,1.0,N)
    correct = convert_by_multiplication(Array,A,N)

    @test Array(A) ≈ correct
    @test sparse(A) ≈ correct
    @test BandedMatrix(A) ≈ correct

    # testing correctness of multiplication
    N = 1000
    d_order = 4
    approx_order = 10
    y = collect(1:1.0:N+2).^4 - 2*collect(1:1.0:N+2).^3 + collect(1:1.0:N+2).^2;
    y = convert(Array{BigFloat, 1}, y)

    A = CenteredDifference(d_order,approx_order,one(BigFloat),N)
    correct = convert_by_multiplication(Array,A,N)
    @test Array(A) ≈ correct
    @test sparse(A) ≈ correct
    @test BandedMatrix(A) ≈ correct
    @test A*y ≈ Array(A)*y
end

@testset "Indexing tests" begin
    N = 1000
    d_order = 4
    approx_order = 10

    A = CenteredDifference(d_order,approx_order,1.0,N)
    @test A[1,1] == Array(A)[1,1]
    @test A[10,20] == 0

    correct = Array(A)
    for i in 1:N
        @test A[i,i] == correct[i,i]
    end

    # Indexing Tests
    N = 1000
    d_order = 2
    approx_order = 2

    A = CenteredDifference(d_order,approx_order,1.0,N)
    M = Array(A,1000)
    @test A[1,1] == M[1,1]
    @test A[1:4,1] == M[1:4,1]
    @test A[5,2:10] == M[5,2:10]
    @test A[60:100,500:600] == M[60:100,500:600]
end

@testset "Operations on matrices" begin
    N = 51
    M = 101
    d_order = 2
    approx_order = 2

    xarrs = Vector{Union{Array,StepRangeLen}}(undef,0)
    yarrs = Vector{Union{Array,StepRangeLen}}(undef,0)
    push!(xarrs, range(0,stop=1,length=N))
    push!(yarrs, range(0,stop=1,length=M))
    push!(xarrs, vcat(xarrs[1][1:floor(Int,N/2)].^0.2020, xarrs[1][ceil(Int,N/2):end].^2.015))
    push!(yarrs, vcat(yarrs[1][1:floor(Int,M/2)].^1.793, yarrs[1][ceil(Int,M/2):end].^2.019))

    for (i,xarr,yarr) in zip(1:2,xarrs,yarrs)
        if i == 1
            dx = xarr[2] - xarr[1]
            dy = yarr[2] - yarr[1]
        elseif i == 2
            dx = diff(xarr)
            dy = diff(yarr)
        end
        F = [x^2+y for x = xarr, y = yarr]

        A = CenteredDifference(d_order,approx_order,dx,length(xarr)-2)
        B = i == 1 ? CenteredDifference(d_order,approx_order,dy,length(yarr)) :
            CenteredDifference(d_order,approx_order,dy,length(yarr)-2)

        @test A*F ≈ 2*ones(N-2,M) atol=1e-9

        # Operators are defined such that
        # B must be applied to F from the left
        @test all(abs.(B * F') .<= 1e-8)
        @test all(abs.(A * (B * F')') .<= 1e-4)

        G = [x^2+y^2 for x = xarr, y = yarr]

        @test A*G ≈ 2*ones(N-2,M) atol=1e-9
        @test B * G' ≈ 2 * ones(M-2,N) atol=1e-8
        @test all(abs.(A * (B * G')') .<= 1e-4)
    end
end

@testset "Scalar multiplication with operators" begin
    A = CenteredDifference(2, 2, 10., 3)

    scalar_ans = [0.033 -0.066 0.033  0.     0.;
                  0.    0.033  -0.066 0.033  0.;
                  0.    0.     0.033  -0.066 0.033]
    @test Array(3.3 * A) ≈ scalar_ans
end

@testset "Left-multiplying operators with a vector of coefficients" begin
    A = CenteredDifference(2, 2, 1., 3)
    B = UpwindDifference(1, 1, 1., 3, 1.)
    C = UpwindDifference(1, 1, 1., 3, [2., 3., 4.])
    c = [1., 1., 3.]
    cA =  c * A
    cB =  c * B
    cC =  c * C

    @test cA.coefficients == c
    @test cB.coefficients == c
    @test cC.coefficients == [2., 3., 12.]

    x = [1., 2., 3., 4., 5.]
    @test (A * x) .* c ≈ cA * x
    @test (B * x) .* c ≈ cB * x
    @test (C * x) .* c ≈ cC * x

    @test_throws DimensionMismatch ones(10) * A
    @test_throws DimensionMismatch ones(10) * cA
    @test_throws DimensionMismatch ones(10) * B
    @test_throws DimensionMismatch ones(10) * C
end

# These tests are broken due to the implementation 2.2*LD creating a DerivativeOperator
# rather than an Array
#=
@testset "Linear combinations of operators" begin
    N = 10
    Random.seed!(0); LA = DiffEqArrayOperator(rand(N,N+2))
    LD = CenteredDifference(2,2,1.0,N)
    L = 1.1*LA - 2.2*LD + 3.3*Eye(N,N+2)
    # Builds convert(L) the brute-force way
    fullL = zeros(N,N+2)
    v = zeros(N+2)
    for i = 1:N+2
        v[i] = 1.0
        fullL[:,i] = L*v
        v[i] = 0.0
    end
    @test_broken convert(AbstractMatrix,L) ≈ fullL
    for p in [1,2,Inf]
        @test_broken opnorm(L,p) ≈ opnorm(fullL,p)
    end
end
=#


text:
# This file was generated by the Julia Swagger Code Generator
# Do not modify this file directly. Modify the swagger specification instead.

mutable struct ApplicationGatewayAvailableSslOptionsPropertiesFormat <: SwaggerModel
    predefinedPolicies::Any # spec type: Union{ Nothing, Vector{SubResource} } # spec name: predefinedPolicies
    defaultPolicy::Any # spec type: Union{ Nothing, PolicyNameEnum } # spec name: defaultPolicy
    availableCipherSuites::Any # spec type: Union{ Nothing, Vector{CipherSuitesEnum} } # spec name: availableCipherSuites
    availableProtocols::Any # spec type: Union{ Nothing, Vector{ProtocolsEnum} } # spec name: availableProtocols

    function ApplicationGatewayAvailableSslOptionsPropertiesFormat(;predefinedPolicies=nothing, defaultPolicy=nothing, availableCipherSuites=nothing, availableProtocols=nothing)
        o = new()
        validate_property(ApplicationGatewayAvailableSslOptionsPropertiesFormat, Symbol("predefinedPolicies"), predefinedPolicies)
        setfield!(o, Symbol("predefinedPolicies"), predefinedPolicies)
        validate_property(ApplicationGatewayAvailableSslOptionsPropertiesFormat, Symbol("defaultPolicy"), defaultPolicy)
        setfield!(o, Symbol("defaultPolicy"), defaultPolicy)
        validate_property(ApplicationGatewayAvailableSslOptionsPropertiesFormat, Symbol("availableCipherSuites"), availableCipherSuites)
        setfield!(o, Symbol("availableCipherSuites"), availableCipherSuites)
        validate_property(ApplicationGatewayAvailableSslOptionsPropertiesFormat, Symbol("availableProtocols"), availableProtocols)
        setfield!(o, Symbol("availableProtocols"), availableProtocols)
        o
    end
end # type ApplicationGatewayAvailableSslOptionsPropertiesFormat

const _property_map_ApplicationGatewayAvailableSslOptionsPropertiesFormat = Dict{Symbol,Symbol}(Symbol("predefinedPolicies")=>Symbol("predefinedPolicies"), Symbol("defaultPolicy")=>Symbol("defaultPolicy"), Symbol("availableCipherSuites")=>Symbol("availableCipherSuites"), Symbol("availableProtocols")=>Symbol("availableProtocols"))
const _property_types_ApplicationGatewayAvailableSslOptionsPropertiesFormat = Dict{Symbol,String}(Symbol("predefinedPolicies")=>"Vector{SubResource}", Symbol("defaultPolicy")=>"PolicyNameEnum", Symbol("availableCipherSuites")=>"Vector{CipherSuitesEnum}", Symbol("availableProtocols")=>"Vector{ProtocolsEnum}")
Base.propertynames(::Type{ ApplicationGatewayAvailableSslOptionsPropertiesFormat }) = collect(keys(_property_map_ApplicationGatewayAvailableSslOptionsPropertiesFormat))
Swagger.property_type(::Type{ ApplicationGatewayAvailableSslOptionsPropertiesFormat }, name::Symbol) = Union{Nothing,eval(Base.Meta.parse(_property_types_ApplicationGatewayAvailableSslOptionsPropertiesFormat[name]))}
Swagger.field_name(::Type{ ApplicationGatewayAvailableSslOptionsPropertiesFormat }, property_name::Symbol) =  _property_map_ApplicationGatewayAvailableSslOptionsPropertiesFormat[property_name]

function check_required(o::ApplicationGatewayAvailableSslOptionsPropertiesFormat)
    true
end

function validate_property(::Type{ ApplicationGatewayAvailableSslOptionsPropertiesFormat }, name::Symbol, val)
end


text:
function _togem(visited, A::Tensor{T}) where T<:Number
    return gem.Literal(A.value)
end

function _togem(visited, A::Tensor{T,0}) where T
    return togem(A.value, visited)
end

function _togem(visited, A::Tensor{T}) where T
    shape = size(A.value)
    gems = PermutedDimsArray((x -> togem(x, visited)).(A.value), reverse([i for i in 1:length(shape)]))
    for i in reverse(shape)
        gems = [gem.ListTensor(gems[(i*(j-1)+1):i*j]) for j in 1:div(length(gems), i)]
    end
    return gems[1]
end

function _togem(visited, A::ConstantTensor{T}) where T<:Number
    # TODO this does not work if any vector space has unknown dimension
    return gem.Literal(fill(A.value, tuple([dim(V) for V in A.shape]...)))
end

function _togem(visited, A::DeltaTensor)
    if length(A.shape) == 2
        return gem.Identity(dim(A.shape[1]))
    else
        throw(DomainError("Cannot convert generalised deltas to Gem yet."))
    end
end

function _togem(visited, A::ZeroTensor)
    return gem.Zero(tuple([dim(V) for V in A.shape]...))
end

function _togem(visited, A::VariableTensor)
    for V in A.shape
        if dim(V) === nothing
            throw(DomainError(A.shape, "The tensor must have a known shape."))
        end
    end
    return gem.Variable(A.name, tuple([dim(V) for V in A.shape]...))
end

GemIndexTypes = Union{Int, PyObject}

function _togem(visited, in::IndexingOperation, A::PyObject, indices::Tuple{Vararg{GemIndexTypes}})
    return gem.Indexed(A, indices)
end

freeIndices = Dict{FreeIndex, PyObject}()

function _togem(visited, i::FreeIndex)
    global freeIndices
    # Gem gives indices their owns ids, and we want them to be consistent
    if haskey(freeIndices, i)
        return freeIndices[i]
    elseif haskey(freeIndices, i')
        return freeIndices[i']
    else
        gemindex = gem.Index(i.name, dim(i.V))
        freeIndices[i] = gemindex
        return gemindex
    end
end

function _togem(visited, i::FixedIndex)
    # Python starts indexing from 0 and Julia from 1
    return i.value - 1
end

function _togem(visited, indices::Indices)
    return tuple([_togem(visited, i) for i in indices.indices]...)
end

```Helper function that indexes tensors. Returns the tensors and the indices.
```
function _toscalar(tensors::Tuple{Vararg{PyObject}})
    indices = []
    for i in 1:length(tensors[1].shape)
        push!(indices, gem.Index(nothing, tensors[1].shape[i]))
    end
    return [gem.Indexed(tensor, indices) for tensor in tensors], tuple(indices...)
end

function _toscalar(tensor::PyObject)
    scalars, indices = _toscalar((tensor,))
    return scalars[1], indices
end

function _togem(visited, add::AddOperation, children::Vararg{PyObject})
    indexed, indices = _toscalar(children)
    sum = indexed[1]
    for expr in indexed[2:end]
        sum += expr
    end
    return gem.ComponentTensor(sum, tuple(indices...))
end

function _togem(visited, ou::OuterProductOperation, A::PyObject, B::PyObject)
    exprA, indicesA = _toscalar(A)
    exprB, indicesB = _toscalar(B)
    return gem.ComponentTensor(gem.Product(exprA, exprB), (indicesA..., indicesB...))
end

function _togem(visited, div::DivisionOperation, A::PyObject, B::PyObject)
    expr, indices = _toscalar(A)
    return gem.ComponentTensor(gem.Division(expr, B), indices)
end

function _togem(visited, comp::ComponentTensorOperation, expr::PyObject, indices::Tuple{Vararg{PyObject}})
    if expr.shape != ()
        expr, new_indices = _toscalar(expr)
        return gem.ComponentTensor(expr, (new_indices..., indices...))
    else
        return gem.ComponentTensor(expr, indices)
    end
end

function _togem(visited, is::IndexSumOperation, expr::PyObject, indices::Tuple{Vararg{PyObject}})
    indexed, new_indices = _toscalar(expr)
    return gem.ComponentTensor(gem.IndexSum(indexed, indices), new_indices)
end

function _togem(visited, po::PowerOperation, expr::PyObject, pow::PyObject)
    return gem.Power(expr, pow)
end

function _togem(visited, sin::SineOperation, expr::PyObject)
    return gem.MathFunction("sin", expr)
end

function _togem(visited, cos::CosineOperation, expr::PyObject)
    return gem.MathFunction("cos", expr)
end

function _togem(visited, tan::TangentOperation, expr::PyObject)
    return gem.MathFunction("tan", expr)
end

function _togem(visited, asin::ArcsineOperation, expr::PyObject)
    return gem.MathFunction("asin", expr)
end

function _togem(visited, acos::ArccosineOperation, expr::PyObject)
    return gem.MathFunction("acos", expr)
end

function _togem(visited, atan::ArctangentOperation, expr::PyObject)
    return gem.MathFunction("atan", expr)
end

function _togem(visited, root::RootNode, node)
    return RootNode(node)
end

function togem(node::Union{Node}, visited::Union{Dict, Nothing})
    return traversal(node, x-> x, _togem, nothing, nothing, visited)
end

function togem(node::Union{Node})
    return togem(node, nothing)
end

function togem(i::Number, visited)
    return gem.Literal(i)
end

max_stars_repo_name: Sohva/TensorDSL

max_issues_repo_name: Sohva/TensorDSL

max_forks_repo_name: Sohva/TensorDSL


text:
function AngularRadioRefractionModifier(arg0::AtmosphericRefractionModel)
    return AngularRadioRefractionModifier((AtmosphericRefractionModel,), arg0)
end

function get_parameters_drivers(obj::AngularRadioRefractionModifier)
    return jcall(obj, "getParametersDrivers", List, ())
end

function modify(obj::AngularRadioRefractionModifier, arg0::EstimatedMeasurement)
    return jcall(obj, "modify", void, (EstimatedMeasurement,), arg0)
end


text:
using SignedDistanceFunction
using Test
using DelimitedFiles
include("../src/utils/utils.jl")
using .Utils

@testset "SignedDistanceFunction.jl" begin
    # @test signedDistance2D("mock_csv_data/interface.csv", 100) == readdlm("result/interface_result_n100.csv", ',', Float64)
    @test signedDistance2D("mock_csv_data/interface.csv", 300) == readdlm("result/interface_result_n300.csv", ',', Float64)
    # @test signedDistance2D("mock_csv_data/interface.csv", 300, "multi") == readdlm("result/interface_floodfill_result_n300.csv", ',', Float64)
    # @test signedDistance2D("mock_csv_data/multiple_curves.csv", 100, "multi") == readdlm("result/multiple_curves_result_n100.csv", ',', Float64)
    # @test signedDistance2D("mock_csv_data/multiple_curves.csv", 500, "multi") == readdlm("result/multiple_curves_result_n500.csv", ',', Float64)
end

@testset "utils.jl" begin
    @test remove_same_point([1 2; 2 3; 3 2; 3 2; 3 2; 1 2; 1 2]) == [1 2; 2 3; 3 2; 1 2]
end

max_stars_repo_name: jabelic/Signed-distance-function

max_issues_repo_name: jabelic/Signed-distance-function

max_forks_repo_name: jabelic/Signed-distance-function


text:
if haskey(ENV, "JULIA_NUM_THREADS")
    nw = parse(Int, ENV["JULIA_NUM_THREADS"])
    addprocs(nw)
end

using VortexCollisions

include("test_functions.jl")

function run_timings()
    M = 64
    N = 64

    ℳcut = M
    𝒩cut = N

    grid = Grid2d(M,N)
    ft   = FourierTransform(grid; ℳcut=ℳcut, 𝒩cut=𝒩cut)
    op   = FokkerPlanckOperator(grid, ft)
    D    = get_gradient(ft)
    Δ⁻¹  = get_inverse_laplacian(ft)

    u = get_field(grid)
    û = get_trans(ft)

    Δ⁻¹û = zero(û)
    Dû   = [zero(û), zero(û)]

    Δ⁻¹u = zero(u)
    divJ = zero(u)

    u₀ = zero(u)
    u₁ = zero(u)

    evaluate_function_on_grid(grid, u_test, u)

    u₀ .= u

    frfft!(ft, u, û)
    prfft!(ft, u, û)
    apply_operator!(Δ⁻¹, û, Δ⁻¹û)
    apply_operator!(D, û, Dû)
    irfft!(ft, Δ⁻¹û, Δ⁻¹u)
    fourier_quadrature(û, û, ft.μ, grid)
    collision_operator!(op, u, divJ)
    timestep!(op, u₀, u₁, 1E-3)

    print(" frfft!:     ")
    @time frfft!(ft, u, û)

    print(" prfft!:     ")
    @time prfft!(ft, u, û)

    print(" Δ⁻¹:        ")
    @time apply_operator!(Δ⁻¹, û, Δ⁻¹û)

    print(" D:          ")
    @time apply_operator!(D, û, Dû)

    print(" irfft!:     ")
    @time irfft!(ft, Δ⁻¹û, Δ⁻¹u)

    print(" quadrature: ")
    @time fourier_quadrature(û, û, ft.μ, grid)

    print(" collisions: ")
    @time collision_operator!(op, u, divJ)

    print(" time step:  ")
    @time timestep!(op, u₀, u₁, 1E-3)

    print(" 3 steps:    ")
    @time for i in 1:3 timestep!(op, u₀, u₁, 1E-3) end

end

run_timings()


text:
@testset "Sparse logistic small ($T)" for T in [Float32, Float64]

    using ProximalOperators
    using ProximalAlgorithms
    using LinearAlgebra
    using Random

    Random.seed!(0)

    A = T[  1.0  -2.0   3.0  -4.0  5.0;
           2.0  -1.0   0.0  -1.0  3.0;
          -1.0   0.0   4.0  -3.0  2.0;
          -1.0  -1.0  -1.0   1.0  3.0]
    b = T[1.0, 2.0, 3.0, 4.0]

    m, n = size(A)

    R = real(T)

    f = Translate(LogisticLoss(ones(R, m), R(1)), -b)
    lam = R(0.1)
    g = NormL1(lam)

    x_star = T[0, 0, 2.114635341704963e-01, 0, 2.845881348733116e+00]

    TOL = R(1e-6)

    # Nonfast/Adaptive

    x0 = zeros(T, n)
    solver = ProximalAlgorithms.ForwardBackward{R}(tol=TOL, adaptive=true, fast=false)
    x, it = solver(x0, f=f, A=A, g=g)
    @test eltype(x) == T
    @test norm(x - x_star, Inf) <= 1e-4
    @test it < 1100

    # Fast/Adaptive

    x0 = zeros(T, n)
    solver = ProximalAlgorithms.ForwardBackward{R}(tol=TOL, adaptive=true, fast=true)
    x, it = solver(x0, f=f, A=A, g=g)
    @test eltype(x) == T
    @test norm(x - x_star, Inf) <= 1e-4
    @test it < 500

    # ZeroFPR/Adaptive

    x0 = zeros(T, n)
    solver = ProximalAlgorithms.ZeroFPR{R}(adaptive=true, tol=TOL)
    x, it = solver(x0, f=f, A=A, g=g)
    @test eltype(x) == T
    @test norm(x - x_star, Inf) <= 1e-4
    @test it < 25

    # PANOC/Adaptive

    x0 = zeros(T, n)
    solver = ProximalAlgorithms.PANOC{R}(adaptive=true, tol=TOL)
    x, it = solver(x0, f=f, A=A, g=g)
    @test eltype(x) == T
    @test norm(x - x_star, Inf) <= 1e-4
    @test it < 50

end


text:
"""
    read_drifters(pth,lst;chnk=Inf,rng=(missing,missing))

Read near-surface [drifter data](https://doi.org/10.1002/2016JC011716) from the
[Global Drifter Program](https://doi.org/10.25921/7ntx-z961) into a DataFrame.

Note: need to use NetCDF.jl as NCDatasets.jl errors when TIME = Inf
```
pth,list=drifter_files()
df=read_drifters( pth*lst[end],chnk=1000,rng=(2014.1,2014.2) )
#sort!(df, [:t, :lat])
#CSV.write(pth*"Drifter_hourly_2005_2019.csv", df)
```
"""
function read_drifters(fil::String;chnk=Inf,rng=(missing,missing))
   t=ncread(fil,"TIME")
   t_u=ncgetatt(fil,"TIME","units")
   lo=ncread(fil,"LON")
   la=ncread(fil,"LAT")
   ID=ncread(fil,"ID")

   ii=findall(isfinite.(lo.*la.*t))
   t_ii=t[ii]
   t_ii=timedecode.(t_ii, t_u)
   tmp=dayofyear.(t_ii)+(hour.(t_ii) + minute.(t_ii)/60 ) /24
   t_ii=year.(t_ii)+tmp./daysinyear.(t_ii)
   isfinite(rng[1]) ? jj=findall( (t_ii.>rng[1]).&(t_ii.<=rng[2])) : jj=1:length(ii)

   ii=ii[jj]
   t=t_ii[jj]
   lo=lo[ii]
   la=la[ii]
   ID=ID[ii]

   df = DataFrame(ID=Int[], lon=Float64[], lat=Float64[], t=Float64[])

   !isinf(chnk) ? nn=Int(ceil(length(ii)/chnk)) : nn=1
   for jj=1:nn
      #println([jj nn])
      !isinf(chnk) ? i=(jj-1)*chnk.+(1:chnk) : i=(1:length(ii))
      i=i[findall(i.<length(ii))]
      append!(df,DataFrame(lon=lo[i], lat=la[i], t=t[i], ID=Int.(ID[i])))
   end

   return df
end

"""
    read_drifters( pth, lst )

Read near-surface [hourly drifter data](https://doi.org/10.1002/2016JC011716) from the
[Global Drifter Program](https://doi.org/10.25921/7ntx-z961) into a DataFrame.

Note: need to use NetCDF.jl as NCDatasets.jl errors when TIME = Inf

```
pth,list=drifter_files()
df=read_drifters( pth, lst)
```
"""
function read_drifters( pth, lst )
   df = DataFrame([fill(Int, 1) ; fill(Float64, 3)], [:ID, :lon, :lat, :t])
   for fil in lst
      println(fil)
      append!(df,read_drifters( pth*fil,chnk=10000,rng=(2005.0,2020.0) ))
      #println(size(df))
   end
   return df
end

function drifter_files()
   pth="Drifter_hourly_v013/"
   lst=["driftertrajGPS_1.03.nc","driftertrajWMLE_1.02_block1.nc","driftertrajWMLE_1.02_block2.nc",
      "driftertrajWMLE_1.02_block3.nc","driftertrajWMLE_1.02_block4.nc","driftertrajWMLE_1.02_block5.nc",
      "driftertrajWMLE_1.02_block6.nc","driftertrajWMLE_1.03_block7.nc"]
   return pth,list
end

"""
    read_velocities(γ::gcmgrid,t::Int,pth::String)

Read velocity components `u,v` from files in `pth`for time `t`
"""
function read_velocities(γ::gcmgrid,t::Int,pth::String)
    u=read_nctiles("$pth"*"UVELMASS/UVELMASS","UVELMASS",γ,I=(:,:,:,t))
    v=read_nctiles("$pth"*"VVELMASS/VVELMASS","VVELMASS",γ,I=(:,:,:,t))
    return u,v
end

"""
    read_mds(filRoot::String,x::MeshArray)

Read a gridded variable from 2x2 tile files. This is used
in `example2_setup()` with `flt_example/`
"""
function read_mds(filRoot::String,x::MeshArray)
   prec=eltype(x)
   prec==Float64 ? reclen=8 : reclen=4;

   (n1,n2)=Int64.(x.grid.ioSize ./ 2);
   fil=filRoot*".001.001.data"
   tmp1=stat(fil);
   n3=Int64(tmp1.size/n1/n2/reclen);

   v00=x.grid.write(x)
   for ii=1:2; for jj=1:2;
      fid = open(filRoot*".00$ii.00$jj.data")
      fld = Array{prec,1}(undef,(n1*n2*n3))
      read!(fid,fld)
      fld = hton.(fld)

      n3>1 ? s=(n1,n2,n3) : s=(n1,n2)
      v00[1+(ii-1)*n1:ii*n1,1+(jj-1)*n2:jj*n2,:]=reshape(fld,s)
   end; end;

   return x.grid.read(v00,x)
end

"""
    read_uvetc(k::Int,Γ::Dict,pth::String)

Define `uvetc` given the grid variables `Γ` and a vertical level choice `k`
including velocities obtained from files in `pth`

**deprecated: use set_up_𝑃 and update_𝑃! instead -- only still used in GlobalOceanNotebooks ?**
"""
function read_uvetc(k::Int,Γ::Dict,pth::String)
    𝑃 = dict_to_nt(IndividualDisplacements.NeighborTileIndices_cs(Γ))
    Γ = dict_to_nt( Γ )
    nt=12; msk=(Γ.hFacC[:,k] .> 0.) #select depth

    u=0. ./Γ.DXC; v=0. ./Γ.DYC;
    for t=1:nt
        (U,V)=read_velocities(Γ.XC.grid,t,pth)
        for i=1:size(u,1)
            u[i]=u[i] + U[i,k]
            v[i]=v[i] + V[i,k]
        end
    end
    u=u ./ nt
    v=v ./ nt #time average

    u[findall(isnan.(u))]=0.0; v[findall(isnan.(v))]=0.0 #mask with 0s rather than NaNs
    u=u./Γ.DXC; v=v./Γ.DYC; #normalize to grid units

    (u,v)=exchange(u,v,1) #add 1 point at each edge for u and v
    XC=exchange(Γ.XC) #add 1 lon point at each edge
    YC=exchange(Γ.YC) #add 1 lat point at each edge

    t0=0.0; t1=86400*366*10.0; dt=10*86400.0;
    tmp = (u0=u, u1=u, v0=v, v1=v, t0=t0, t1=t1, dt=dt, msk=msk, XC=XC, YC=YC)

    return merge(𝑃,tmp)
end

"""
    get_ecco_velocity_if_needed()

Download `MITgcm` transport output to `examples/nctiles_climatology` if needed
"""
function get_ecco_velocity_if_needed()
    p=dirname(pathof(OceanStateEstimation))
    lst=joinpath(p,"../examples/nctiles_climatology.csv")
    pth=ECCOclim_path
    !isdir(pth*"UVELMASS") ? get_from_dataverse(lst,"UVELMASS",pth) : nothing
    !isdir(pth*"VVELMASS") ? get_from_dataverse(lst,"VVELMASS",pth) : nothing
    !isdir(pth*"WVELMASS") ? get_from_dataverse(lst,"WVELMASS",pth) : nothing
end

"""
    get_occa_velocity_if_needed()

Download `MITgcm` transport output to `examples/OCCA_climatology` if needed
"""
function get_occa_velocity_if_needed()
    p=dirname(pathof(OceanStateEstimation))
    lst=joinpath(p,"../examples/OCCA_climatology.csv")
    pth=OCCAclim_path
    nams = ("DDuvel.0406clim.nc","DDvvel.0406clim.nc","DDwvel.0406clim.nc","DDtheta.0406clim.nc","DDsalt.0406clim.nc")
    if !isfile("$pth"*"DDuvel.0406clim.nc")
        tmp=joinpath(pth,"tmp/")
        !isdir(tmp) ? mkdir(tmp) : nothing
        [get_from_dataverse(lst,nam,tmp) for nam in nams]
        [mv(joinpath(tmp,nam,nam),joinpath(pth,nam)) for nam in nams]
    end
end


text:
# compiler driver and main interface

# (::CompilerContext)
const compile_hook = Ref{Union{Nothing,Function}}(nothing)

"""
    compile(agent::HSAAgent, f, tt; kwargs...)

Compile a function `f` invoked with types `tt` for agent `agent`, returning
the compiled module and function, respectively of type `ROCModule` and
`ROCFunction`.

For a list of supported keyword arguments, refer to the documentation of
[`rocfunction`](@ref).
"""
function compile(agent::HSAAgent, @nospecialize(f::Core.Function), @nospecialize(tt);
                 kernel=true, kwargs...)
    AMDGPUnative.configured || error("AMDGPUnative.jl has not been configured; cannot JIT code.")

    ctx = CompilerContext(f, tt, agent, kernel; kwargs...)
    module_asm, module_entry = compile(ctx)

    # enable debug options based on Julia's debug setting
    jit_options = Dict{Any,Any}()
    roc_mod = ROCModule(module_asm, jit_options)
    roc_fun = ROCFunction(roc_mod, module_entry)

    return roc_mod, roc_fun
end

function compile(ctx::CompilerContext)
    if compile_hook[] != nothing
        hook = compile_hook[]
        compile_hook[] = nothing

        global globalUnique
        previous_globalUnique = globalUnique

        hook(ctx)

        globalUnique = previous_globalUnique
        compile_hook[] = hook
    end

    ## high-level code generation (Julia AST)

    @debug "(Re)compiling function" ctx

    check_method(ctx)

    ## low-level code generation (LLVM IR)

    mod, entry = irgen(ctx)

    need_library(lib) = any(f -> isdeclaration(f) &&
                                 intrinsic_id(f) == 0 &&
                                 haskey(functions(lib), LLVM.name(f)),
                            functions(mod))

    device_libs = load_device_libs(ctx.agent)
    for lib in device_libs
        if need_library(lib)
            link_device_lib!(ctx, mod, lib)
        end
    end
    link_oclc_defaults!(ctx, mod)

    # optimize the IR
    entry = optimize!(ctx, mod, entry)

    runtime = load_runtime(ctx.agent)
    if need_library(runtime)
        link_library!(ctx, mod, runtime)
    end

    prepare_execution!(ctx, mod)

    check_invocation(ctx, entry)

    # check generated IR
    check_ir(ctx, mod)
    verify(mod)

    ## machine code generation (GCN assembly)
    module_asm = mcgen(ctx, mod, entry)

    return module_asm, LLVM.name(entry)
end


text:
module TidalDischargeModels

using Reexport

@reexport using Base.Dates, StatsBase, Optim, TidalFluxQuantities

export estfun, estfun!, evalfun, evalmodel, BoonModel, LTIModel, RegularizedLTIModel, VolterraModel, RegularizedVolterraModel, kMeansModel, ThresholdModel, nash_sutcliffe, flatness, ρ, c_p

include("dischargemodels.jl")
include("utils.jl")
include("constants.jl")

end # module end


text:
using Test

@time @testset "Potentials.jl" begin
    include("lj_test.jl")
    include("SNAP/snap_test_single_element.jl")
    include("SNAP/snap_test_multi_element.jl")
end


text:
export GithubEditLink

struct GithubEditLink
  template::String
  reponame::String
  function GithubEditLink(reponame::String)
    default_template = """

    Edit This Page

    """
    return new(default_template,reponame)
  end
end

function process_html(G::GithubEditLink,
                      html::AbstractString,
                      fileinfo::FileInfo;
                      args...)
  link = "https://github.com/$(G.reponame)/edit/master/"*fileinfo["source_filename"]
  lhtml = replace(G.template,r"{github_link}" => link)
  return html*lhtml
end


text:
module ShaleDrillingLikelihood_tauchen

using ShaleDrillingLikelihood
using StatsFuns
using Test
using Statistics
using SparseArrays
using Random
using Base: product
using LinearAlgebra

using ShaleDrillingLikelihood: ar,
    simulate,
    mu,
    sigsq,
    condvar,
    lrvar,
    lrmean,
    MakeGrid,
    zero_out_small_probs

@testset "tauchen approximations to ar1" begin

    Random.seed!(1234)

    ar1 = AR1process(1.0, 0.6, 1.5)

    y = simulate(ar1, 100_000)

    @test mean(y) - lrmean(ar1) < 0.02
    @test var(y) - lrvar(ar1) < 0.02

    @test mean(y[2:end] .- ar(ar1).*y[1:end-1]) - mu(ar1) < 0.01
    @test var(y[2:end] .- ar(ar1).*y[1:end-1]) - condvar(ar1) < 0.01

    ngridpts = 21
    P = tauchen_1d(ar1, ngridpts)
    @test all(sum(P, dims=2) .≈ 1)
    xgrid = MakeGrid(ar1, ngridpts)

    num_outside = length(y) - sum(first(xgrid) .<= y .<= last(xgrid) )
    @test num_outside / length(y) - normcdf(-3.0)*2 < 0.0002

    Q = zero_out_small_probs(P, 1e-5)
    @test all(sum(Q, dims=2) .≈ 1)

    Qsp = sparse(Q)
    @test length(nonzeros(Qsp)) < length(Q)
end

@testset "random walk" begin
    rw = RandomWalk(1.0)
    y = simulate(rw, 1000)
    @test var(y) > var(y[1:100])
end

@testset "tauchen 2d tests" begin

    num_y_nodes = 21
    num_yy_nodes = num_y_nodes^2
    ylim = 3.0

    yspace = range(-abs(ylim); stop=abs(ylim), length=num_y_nodes)
    yyspace = product(yspace,yspace)
    Q = Matrix{Float64}(undef, num_y_nodes, num_y_nodes)
    P = Matrix{Float64}(undef, num_yy_nodes, num_yy_nodes)
    P2 = copy(P)

    μ(x) = x
    Σ = [1.0 0.5; 0.5 1.0]

    Q .= 0.0
    tauchen_1d!(Q, yspace, μ, 1.0)
    @test all(sum(Q, dims=2) .≈ 1.0)
    tauchen_2d!(P, yyspace, μ, Matrix{Float64}(1.0I,2,2))
    @test all(sum(P, dims=2) .≈ 1.0)

    @test P ≈ kron(Q,Q)

    tauchen_2d!(P, yyspace, μ, Σ)
    @test all(sum(P, dims=2) .≈ 1.0)
    P3 = copy(P)
    tauchen_2d!(P, product(yspace.*sqrt2, yspace.*sqrt2), μ, Σ.*2)
    @test P ≈ P3

    @test all(sum(P, dims=2) .≈ 1.0)
end

end # module


text:
# export colored

# types
type Colored
  color::Symbol
end

type Coat
  color::Symbol
  indexfunc::Function
end

type Coating
  color::Symbol
  data
end

immutable ANSIEscaped
  color::Symbol
  data
  ANSIEscaped(c, d) = isa(d, ANSIEscaped) ? new(c, d.data) : new(c, d)
end

immutable ANSIEscapedString
  data::String
  strwidth::Int
  length::Int
end

# colored
colored(color::Symbol) = check_have_color() && Colored(color)
colored(color::Symbol, indexfunc::Function) = check_have_color() && Coat(color, indexfunc)
colored(color::Symbol, indexfunc::Function, data) = check_have_color() && (Coat(color, indexfunc))(data)
colored(color::Symbol, data) = check_have_color() && (Coat(color, identity))(data)

function normal_color()
  is_windows() ? Base.text_colors[:bold] : Base.answer_color()
end

function check_have_color()
  if Base.have_color
    print(normal_color())
    true
  else
    throw(ArgumentError("run julia with --color=yes"))
    false
  end
end

# Coating : getindex
Base.endof(c::Coating) = endof(c.data)
Base.ndims(c::Coating) = ndims(c.data)
Base.size(c::Coating, row::Int) = size(c.data, row)

function Base.SubString{T<:Coating}(s::T, i::Int, j::Int)
  pre = i>1 ? s.data[1:i-1] : ""
  post = j<Base.length(s.data) ? s.data[j+1:end] : ""
  normal = normal_color()
  str = s.data[i:j]
  ANSIEscapedString(string(normal, pre, ANSIEscaped(s.color, str), normal, post), strwidth(s.data), length(s.data))
end

function escape_precell(el::Any)
  el
end
function escape_precell(el::AbstractArray)
  precel = precell(el)
  join(map(precel.data) do x
    lpad(x, precel.width)
  end, "\n")
end

Base.getindex{T<:Coating}(a::T) = getindex(a, 1)
function Base.getindex{T<:Coating}(a::T, ind::Int)
  if isa(a.data, String)
    a.data = SubString(a, ind, ind)
  else
    m,n = arraysize(a.data)
    A = Array{Any}(m,n)
    A[:] = a.data
    A[ind] = ANSIEscaped(a.color, escape_precell(a.data[ind]))
    a.data = A
  end
end

function Base.getindex{T<:Coating}(a::T, ::Colon)
  if isa(a.data, String)
    a.data = ANSIEscaped(a.color, a.data)
  else
    a.data = map(a.data[:]) do el
      ANSIEscaped(a.color, escape_precell(el))
    end
  end
end

function Base.getindex{T<:Coating}(a::T, rang::UnitRange)
  if isa(a.data, String)
    a.data = SubString(a, rang.start, rang.stop)
  else
    m,n = arraysize(a.data)
    A = Array{Any}(m,n)
    A[:] = a.data
    A[rang] = map(a.data[rang]) do el
      ANSIEscaped(a.color, escape_precell(el))
    end
    a.data = A
  end
end

function Base.getindex{T<:Coating}(a::T, row, col)
  m,n = arraysize(a.data)
  A = Array{Any}(m,n)
  A[:] = a.data
  sub = map(a.data[row,col]) do el
    ANSIEscaped(a.color, escape_precell(el))
  end
  if !isa(sub, AbstractArray)
    sub = [sub][:,:]
  end
  q,r = arraysize(sub)
  if 1==q && 1==r
    A[row,col] = sub[q,r]
  else
    A[row,col] = sub
  end
  a.data = A
end

function Base.show(io::IO, c::Coating)
  print(io, c.data)
end

coating(c::Coating, ::Type{AbstractArray}) = (a->a[:,:])(c)
coating(c::Coating, ::Any) = ANSIEscaped(c.color, c.data)

# Coat
identityfunc(::AbstractArray) = a->a[:,:]
identityfunc(::Any) = a->a

(coat::Coat)(data::Function) = coating(Coating(coat.color, data), typeof(data))
(coat::Coat)(input::Tuple) = (coat)(rotl90(collect(input)[:,:]))
function (coat::Coat)(input)
  c = Coating(coat.color, input)
  coated = coat.indexfunc(c)
  if c==coated
    isa(input, AbstractArray) ? identityfunc(input)(c) : coating(c, typeof(input))
  else
    coated
  end
end

# Colored
(c::Colored)(data::Tuple) = (c)(rotl90(collect(data)[:,:]))
(c::Colored)(data::AbstractArray) = (Coat(c.color, identityfunc(data)))(data)
(c::Colored)(data::Any) = coating(Coating(c.color, data), typeof(data))

function (c::Colored)(func::Function)
  Coat(c.color, func)
end

function (c::Colored)(func::Function, data)
  (c)(func)(data)
end

# ANSIEscaped
Base.endof(ansi::ANSIEscaped) = endof(ansi.data)
Base.start(ansi::ANSIEscaped) = start(ansi.data)
Base.next(ansi::ANSIEscaped, b::Bool) = next(ansi.data, b)
Base.done(ansi::ANSIEscaped, b::Bool) = done(ansi.data, b)
Base.strwidth(ansi::ANSIEscaped) = strwidth(string(ansi.data))
Base.length(ansi::ANSIEscaped) = length(string(ansi.data))
Base.repr(ansi::ANSIEscaped) = ansi

function Base.show(io::IO, a::AbstractArray{ANSIEscaped,1})
  for ansi in a
    print_with_color(ansi.color, io, ansi.data)
  end
end

function Base.show(io::IO, ansi::ANSIEscaped)
  print_with_color(ansi.color, io, string(ansi.data))
  print(io, normal_color())
end

function precell(el::ANSIEscaped)
  s = string(el.data)
  if contains(s, "\n")
    a = AbstractArray{ANSIEscaped}([])
    widths = AbstractArray{Int}([])
    for x in split(s, "\n")
       width = strwidth(x)
       str = string(" ", x, repeat(" ", width-length(x)))
       push!(widths, width)
       push!(a, ANSIEscaped(el.color, str))
    end
    m,n = arraysize(a)
    PreCell(a, maximum(widths), m)
  else
    width = strwidth(s)
    PreCell(isa(el.data, AbstractArray) ? el : [el], width, 1)
  end
end

# ANSIEscapedString
Base.endof(ansi::ANSIEscapedString) = endof(ansi.data)
Base.next(ansi::ANSIEscapedString, i::Int) = next(ansi.data, i)
Base.strwidth(ansi::ANSIEscapedString) = ansi.strwidth
Base.length(ansi::ANSIEscapedString) = ansi.length
Base.repr(ansi::ANSIEscapedString) = ansi
function Base.show(io::IO, ansi::ANSIEscapedString)
  print(io, ansi.data)
end


text:
using PlayGround
using Test

@testset "PlayGround.jl" begin
    # Write your own tests here.
end


text:
# Submit a data request to OOINet.
#
# @return A queryable response object if the request is successful.
#
# @param url A request URL string generated from ooi_create_url or by hand.
# @param user Your OOINet username.
# @param token Your OOINet token.

function ooi_submit_request(url,user,token)
    response = HTTP.get(url)  #Get the response from OOINet.
    if response.status == 200 #If the response says successful (200)
        println("Request successful.")
        return response #Return the response object.
    elseif response.status == 401
        println("Unauthorized request. Recommend checking user and token.")
    elseif response.status == 404
        println("No data available for the requested window.")
    else
        println(string("Unanticipated error code (",response.status,")."))
    end  #End of elif ladder.
end #End of function.

max_stars_repo_name: lstoltz/ooi-data-explorations

max_issues_repo_name: lstoltz/ooi-data-explorations

max_forks_repo_name: lstoltz/ooi-data-explorations


text:
using Gadfly, Compose

set_default_plot_size(4inch,9inch)

p=plot(y=[1,2,3], Geom.line)
c=Compose.context()
vstack(p,c,p,c,p)


text:
using Documenter

makedocs(
    format = Documenter.HTML(prettyurls = get(ENV, "CI", nothing) == "true"),
    sitename = "DiscreteEventsCompanion.jl",
    authors  = "Paul Bayer",
    pages = [
        "index.md",
        "approach.md",
        "timer.md",
        "performance.md",
        "parallel.md",
        "benchmarks.md"
    ]
)

deploydocs(
    repo   = "github.com/pbayer/DiscreteEventsCompanion.jl.git",
    target = "build",
    deps   = nothing,
    make   = nothing,
    devbranch = "master",
    devurl = "dev",
    versions = ["stable" => "v^", "v#.#", "dev" => "dev"]
)