text:
# ic.jl
# Needed to initialize a problem.
# TODO: doc these
function ICConstant(mesh::AbstractMesh, sbp::AbstractOperator, eqn::AdvectionData, opts,
                    u0::AbstractArray)

  for i=1:length(u0)
    u0[i] =  2
  end

  return nothing
end

@doc """
### AdvectionEquationMod.ICx5plusy5

Computes the initial conditions for the state variable
    u = x^5 + y^5 + z^5; z is omitted it 2d

**Inputs**

*  `mesh` : AbstractMesh type
*  `sbp`  : Summation-by-parts operator
*  `eqn`  : Advection equation object
*  `opts` : Options dictionary
*  `u0`   : Array that stores inital state variables

**Outputs**

*  None

"""->

function ICx5plusy5(mesh::AbstractMesh{Tmsh},
sbp::AbstractOperator{Tsbp}, eqn::AdvectionData{Tsol, Tres, 2},
opts, u0::AbstractArray{Tsol}) where {Tmsh, Tsbp, Tsol, Tres}

  for i = 1:mesh.numEl
    for j = 1:mesh.numNodesPerElement
      dofnums_j = sview(mesh.dofs, :, j, i)
      x = mesh.coords[1,j,i]
      y = mesh.coords[2,j,i]
      u0[dofnums_j] = x^5 + y^5
    end
  end

  return nothing
end # end function ICx5plusy5

function ICx5plusy5(mesh::AbstractMesh{Tmsh},
sbp::AbstractOperator{Tsbp}, eqn::AdvectionData{Tsol, Tres, 3},
opts, u0::AbstractArray{Tsol}) where {Tmsh, Tsbp, Tsol, Tres}

  for i = 1:mesh.numEl
    for j = 1:mesh.numNodesPerElement
      dofnums_j = sview(mesh.dofs, :, j, i)
      x = mesh.coords[1,j,i]
      y = mesh.coords[2,j,i]
      u0[dofnums_j] = x^5 + y^5 + z^5
    end
  end

  return nothing
end # end function ICx5plusy5

@doc """
### AdvectionEquationMod.ICexp_xplusy

Computes the initial conditions for the state variable
    u = exp(x + y + z), z is omitted in 2d

**Inputs**

*  `mesh` : AbstractMesh type
*  `sbp`  : Summation-by-parts operator
*  `eqn`  : Advection equation object
*  `opts` : Options dictionary
*  `u0`   : Array that stores inital state variables

**Outputs**

*  None

"""->

function ICexp_xplusy(mesh::AbstractMesh{Tmsh},
                    sbp::AbstractOperator{Tsbp}, eqn::AdvectionData{Tsol, Tres, 2},
                    opts, u0::AbstractArray{Tsol}) where {Tmsh, Tsbp, Tsol, Tres}

  for i = 1:mesh.numEl
    for j = 1:mesh.numNodesPerElement
      dofnums_j = sview(mesh.dofs, :, j, i)
      x = mesh.coords[1,j,i]
      y = mesh.coords[2,j,i]
      u0[dofnums_j] = exp(x + y)
    end
  end

  return nothing
end # end function exp_xplusy

function ICexp_xplusy(mesh::AbstractMesh{Tmsh},
                    sbp::AbstractOperator{Tsbp}, eqn::AdvectionData{Tsol, Tres, 3},
                    opts, u0::AbstractArray{Tsol}) where {Tmsh, Tsbp, Tsol, Tres}

  for i = 1:mesh.numEl
    for j = 1:mesh.numNodesPerElement
      dofnums_j = sview(mesh.dofs, :, j, i)
      x = mesh.coords[1,j,i]
      y = mesh.coords[2,j,i]
          z = mesh.coords[3,j,i]
      u0[dofnums_j] = exp(x + y + z)
    end
  end

  return nothing
end # end function exp_xplusy

function ICsinwave(mesh::AbstractMesh{Tmsh},
  sbp::AbstractOperator{Tsbp}, eqn::AdvectionData{Tsol},
  opts, u0::AbstractArray{Tsol}) where {Tmsh, Tsbp, Tsol}

  for i = 1:mesh.numEl
    for j = 1:mesh.numNodesPerElement
      dofnums_j = sview(mesh.dofs, :, j, i)
      u0[dofnums_j] = calc_sinwave(eqn.params, mesh.coords[:, j, i], eqn.t)
    end
  end

  return nothing
end # end function exp_xplusy

function ICsinwavey(mesh::AbstractMesh{Tmsh},
  sbp::AbstractOperator{Tsbp}, eqn::AdvectionData{Tsol},
  opts, u0::AbstractArray{Tsol}) where {Tmsh, Tsbp, Tsol}

  for i = 1:mesh.numEl
    for j = 1:mesh.numNodesPerElement
      dofnums_j = sview(mesh.dofs, :, j, i)
      u0[dofnums_j] = calc_sinwavey(eqn.params, mesh.coords[:, j, i], eqn.t)
    end
  end

  return nothing
end # end function exp_xplusy

function ICsinwavey_pert(mesh::AbstractMesh{Tmsh},
                    sbp::AbstractOperator{Tsbp}, eqn::AdvectionData{Tsol},
                    opts, u0::AbstractArray{Tsol}) where {Tmsh, Tsbp, Tsol}

  for i = 1:mesh.numEl
    for j = 1:mesh.numNodesPerElement
      dofnums_j = sview(mesh.dofs, :, j, i)
      u0[dofnums_j] = calc_sinwavey_pert(eqn.params, mesh.coords[:, j, i], eqn.t)
    end
  end

  return nothing
end # end function exp_xplusy

function ICsinwavexy(mesh::AbstractMesh{Tmsh},
  sbp::AbstractOperator{Tsbp}, eqn::AdvectionData{Tsol},
  opts, u0::AbstractArray{Tsol}) where {Tmsh, Tsbp, Tsol}

  n = 1  # number of sin waves
  for i = 1:mesh.numEl
    for j = 1:mesh.numNodesPerElement
      dofnums_j = mesh.dofs[1, j, i]
      coords = sview(mesh.coords, :, j, i)
      u0[dofnums_j] = sin(2*pi*n*coords[1]) + sin(2*pi*n*coords[2])
      if mesh.dim == 3
        u0[dofnums_j] += sin(2*pi*n*coords[3])
      end
    end
  end

  return nothing
end

function ICsinwave_ampl(mesh::AbstractMesh{Tmsh},
                    sbp::AbstractOperator{Tsbp}, eqn::AdvectionData{Tsol},
                    opts, u0::AbstractArray{Tsol}) where {Tmsh, Tsbp, Tsol}

  for i = 1:mesh.numEl
    for j = 1:mesh.numNodesPerElement
      dofnums_j = sview(mesh.dofs, :, j, i)
      u0[dofnums_j] = calc_sinwave_ampl(eqn.params, mesh.coords[:, j, i], eqn.t)
    end
  end

  return nothing
end # end function ICsinwave_ampl

function ICmms1(mesh::AbstractMesh{Tmsh},
  sbp::AbstractOperator{Tsbp}, eqn::AdvectionData{Tsol},
  opts, u0::AbstractArray{Tsol}) where {Tmsh, Tsbp, Tsol}

  for i = 1:mesh.numEl
    for j = 1:mesh.numNodesPerElement
      dofnums_j = sview(mesh.dofs, :, j, i)
      u0[dofnums_j] = calc_mms1(eqn.params, mesh.coords[:, j, i], eqn.t)
    end
  end

  return nothing
end # end function exp_xplusy

function ICx4(mesh::AbstractMesh{Tmsh},
  sbp::AbstractOperator{Tsbp}, eqn::AdvectionData{Tsol},
  opts, u0::AbstractArray{Tsol}) where {Tmsh, Tsbp, Tsol}

  for i = 1:mesh.numEl
    for j = 1:mesh.numNodesPerElement
      dofnums_j = sview(mesh.dofs, :, j, i)
      u0[dofnums_j] = calc_x4(eqn.params, mesh.coords[:, j, i], eqn.t)
    end
  end

  return nothing
end # end function exp_xplusy

function ICp0(mesh::AbstractMesh{Tmsh},
  sbp::AbstractOperator{Tsbp}, eqn::AdvectionData{Tsol},
  opts, u0::AbstractArray{Tsol}) where {Tmsh, Tsbp, Tsol}

  for i = 1:mesh.numEl
  	for j = 1:mesh.numNodesPerElement
  	  dofnums_j = sview(mesh.dofs, :, j, i)
  	  u0[dofnums_j] = calc_p0(eqn.params, mesh.coords[:, j, i], eqn.t)
  	end
  end

  return nothing
end # end function exp_xplusy

function ICp1(mesh::AbstractMesh{Tmsh},
  sbp::AbstractOperator{Tsbp}, eqn::AdvectionData{Tsol},
  opts, u0::AbstractArray{Tsol}) where {Tmsh, Tsbp, Tsol}

  for i = 1:mesh.numEl
    for j = 1:mesh.numNodesPerElement
      dofnums_j = sview(mesh.dofs, :, j, i)
      u0[dofnums_j] = calc_p1(eqn.params, mesh.coords[:, j, i], eqn.t)
    end
  end

  return nothing
end # end function exp_xplusy

function ICp2(mesh::AbstractMesh{Tmsh},
  sbp::AbstractOperator{Tsbp}, eqn::AdvectionData{Tsol},
  opts, u0::AbstractArray{Tsol}) where {Tmsh, Tsbp, Tsol}

  for i = 1:mesh.numEl
    for j = 1:mesh.numNodesPerElement
      dofnums_j = sview(mesh.dofs, :, j, i)
      u0[dofnums_j] = calc_p2(eqn.params, mesh.coords[:, j, i], eqn.t)
    end
  end

  return nothing
end # end function exp_xplusy

function ICp3(mesh::AbstractMesh{Tmsh},
  sbp::AbstractOperator{Tsbp}, eqn::AdvectionData{Tsol},
  opts, u0::AbstractArray{Tsol}) where {Tmsh, Tsbp, Tsol}

  for i = 1:mesh.numEl
    for j = 1:mesh.numNodesPerElement
      dofnums_j = sview(mesh.dofs, :, j, i)
      u0[dofnums_j] = calc_p3(eqn.params, mesh.coords[:, j, i], eqn.t)
    end
  end

  return nothing
end # end function exp_xplusy

function ICp4(mesh::AbstractMesh{Tmsh},
  sbp::AbstractOperator{Tsbp}, eqn::AdvectionData{Tsol},
  opts, u0::AbstractArray{Tsol}) where {Tmsh, Tsbp, Tsol}

  for i = 1:mesh.numEl
    for j = 1:mesh.numNodesPerElement
      dofnums_j = sview(mesh.dofs, :, j, i)
      u0[dofnums_j] = calc_p4(eqn.params, mesh.coords[:, j, i], eqn.t)
    end
  end

  return nothing
end # end function exp_xplusy

function ICp5(mesh::AbstractMesh{Tmsh},
  sbp::AbstractOperator{Tsbp}, eqn::AdvectionData{Tsol},
  opts, u0::AbstractArray{Tsol}) where {Tmsh, Tsbp, Tsol}

  for i = 1:mesh.numEl
    for j = 1:mesh.numNodesPerElement
      dofnums_j = sview(mesh.dofs, :, j, i)
      u0[dofnums_j] = calc_p5(eqn.params, mesh.coords[:, j, i], eqn.t)
    end
  end

  return nothing
end # end function exp_xplusy

function ICexp5xplus4yplus2(mesh::AbstractMesh{Tmsh},
          sbp::AbstractOperator{Tsbp}, eqn::AdvectionData{Tsol},
          opts, u0::AbstractArray{Tsol}) where {Tmsh, Tsbp, Tsol}

  for i = 1:mesh.numEl
    for j = 1:mesh.numNodesPerElement
      dofnums_j = sview(mesh.dofs, :, j, i)
      u0[dofnums_j] = calc_exp5xplus4yplus2(eqn.params, mesh.coords[:, j, i], eqn.t)
    end
  end

  return nothing
end

function ICexp5xplusy(mesh::AbstractMesh{Tmsh},
          sbp::AbstractOperator{Tsbp}, eqn::AdvectionData{Tsol},
          opts, u0::AbstractArray{Tsol}) where {Tmsh, Tsbp, Tsol}

  for i = 1:mesh.numEl
    for j = 1:mesh.numNodesPerElement
      dofnums_j = sview(mesh.dofs, :, j, i)
      u0[dofnums_j] = calc_exp5xplusy(eqn.params, mesh.coords[:, j, i],
                                      eqn.t)
    end
  end

  return nothing
end

function ICexp3xplusy(mesh::AbstractMesh{Tmsh},
          sbp::AbstractOperator{Tsbp}, eqn::AdvectionData{Tsol},
          opts, u0::AbstractArray{Tsol}) where {Tmsh, Tsbp, Tsol}

  for i = 1:mesh.numEl
    for j = 1:mesh.numNodesPerElement
      dofnums_j = sview(mesh.dofs, :, j, i)
      u0[dofnums_j] = calc_exp3xplusy(eqn.params, mesh.coords[:, j, i],
                                      eqn.t)
    end
  end

  return nothing
end

function ICexp2xplus2y(mesh::AbstractMesh{Tmsh},
          sbp::AbstractOperator{Tsbp}, eqn::AdvectionData{Tsol},
          opts, u0::AbstractArray{Tsol}) where {Tmsh, Tsbp, Tsol}

  for i = 1:mesh.numEl
    for j = 1:mesh.numNodesPerElement
      dofnums_j = sview(mesh.dofs, :, j, i)
      u0[dofnums_j] = calc_exp2xplus2y(eqn.params, mesh.coords[:, j, i],
                                       eqn.t)
    end
  end

  return nothing
end

function ICexp_xy(mesh::AbstractMesh{Tmsh},
          sbp::AbstractOperator{Tsbp}, eqn::AdvectionData{Tsol},
          opts, u0::AbstractArray{Tsol}) where {Tmsh, Tsbp, Tsol}

  for i = 1:mesh.numEl
    for j = 1:mesh.numNodesPerElement
      dofnums_j = sview(mesh.dofs, :, j, i)
      u0[dofnums_j] = calc_exp_xy(eqn.params, mesh.coords[:, j, i], eqn.t)
    end
  end

  return nothing
end

function ICxplusy(mesh::AbstractMesh{Tmsh},
          sbp::AbstractOperator{Tsbp}, eqn::AdvectionData{Tsol},
          opts, u0::AbstractArray{Tsol}) where {Tmsh, Tsbp, Tsol}

  for i = 1:mesh.numEl
    for j = 1:mesh.numNodesPerElement
      dofnums_j = sview(mesh.dofs, :, j, i)
      u0[dofnums_j] = calc_xplusy(eqn.params, mesh.coords[:, j, i], eqn.t)
    end
  end

  return nothing
end

function ICunsteadymms(mesh::AbstractMesh{Tmsh},
          sbp::AbstractOperator{Tsbp}, eqn::AdvectionData{Tsol},
          opts, u0::AbstractArray{Tsol}) where {Tmsh, Tsbp, Tsol}

  for i = 1:mesh.numEl
    for j = 1:mesh.numNodesPerElement
      dofnums_j = sview(mesh.dofs, :, j, i)
      u0[dofnums_j] = calc_unsteadymms(eqn.params, mesh.coords[:, j, i], eqn.t)
    end
  end

  return nothing
end

function ICunsteadypoly(mesh::AbstractMesh{Tmsh},
          sbp::AbstractOperator{Tsbp}, eqn::AdvectionData{Tsol},
          opts, u0::AbstractArray{Tsol}) where {Tmsh, Tsbp, Tsol}

  for i = 1:mesh.numEl
    for j = 1:mesh.numNodesPerElement
      dofnums_j = sview(mesh.dofs, :, j, i)
      u0[dofnums_j] = calc_unsteadypoly(eqn.params, mesh.coords[:, j, i], eqn.t)
    end
  end

  return nothing
end

@doc """
### AdvectionEquationMod.ICFile

This function reads a vector from a file on disk and set the solution to it.
The vector must contain the same number of entries as there are degrees of
freedom in the mesh.

This function is useful for things like warm-starting the solver.
In this case, the file should be the output of `writeSolutionFiles`. The degree
of freedom number must be the same for both simulations for this to work (the
file contains no degree of freedom number information).

**Inputs**

*  `mesh`
*  `sbp`
*  `eqn`
*  `opts`

**Inputs/Outputs**

*  `u0`: vector to populate with the solution

  Aliasing restrictions: none.

"""->
function ICFile(mesh::AbstractMesh{Tmsh},
                sbp::AbstractOperator{Tsbp}, eqn::AdvectionData{Tsol},
                opts, u0::AbstractVector{Tsol}) where {Tmsh, Tsbp, Tsol}
# populate u0 with initial values from a disk file
# the file name comes from opts["ICfname"]

  readSolutionFiles(mesh, sbp, eqn, opts, opts["ICfname"], u0)
end

"""
  Dictionary that maps IC names to functions.  Every new IC should be added
  to the list
"""
global const ICDict = Dict{Any, Function}(
"ICConstant" => ICConstant,
"ICx5plusy5" => ICx5plusy5,
"ICexp_xplusy" => ICexp_xplusy,
"ICsinwave" => ICsinwave,
"ICsinwavey" => ICsinwavey,
"ICsinwavey_pert" => ICsinwavey_pert,
"ICsinwavexy" => ICsinwavexy,
"ICsinwave_ampl" => ICsinwave_ampl,
"ICmms1" => ICmms1,
"ICx4" => ICx4,
"ICp0" => ICp0,
"ICp1" => ICp1,
"ICp2" => ICp2,
"ICp3" => ICp3,
"ICp4" => ICp4,
"ICp5" => ICp5,
"ICexp5xplus4yplus2" => ICexp5xplus4yplus2,
"ICexp5xplusy" => ICexp5xplusy,
"ICexp3xplusy" => ICexp3xplusy,
"ICexp2xplus2y" => ICexp2xplus2y,
"ICexp_xy" => ICexp_xy,
"ICxplusy" => ICxplusy,
"ICunsteadymms" => ICunsteadymms,
"ICunsteadypoly" => ICunsteadypoly,
"ICFile" => ICFile,
)


text:
#
println("Fa) Symbolic evaluation by means of special values & recursion relations of the Wigner n-j symbols.")
#
using SymEngine

if  false
    # Test for special values of the Wigner 3-j symbols
    w3j = RacahAlgebra.selectW3j(17);                    println("w3j-original      = $w3j")
    rex = RacahAlgebra.equivalentForm(w3j);             println("rex-equivalent    = $rex")
    wa  = RacahAlgebra.evaluate(rex, special=true);     println("\nwa-special value  = $wa")
elseif  true
    # Test for special values of the Wigner 6-j symbols
    w6j = RacahAlgebra.selectW6j(17);                   println("w6j-original      = $w6j")
    rex = RacahAlgebra.equivalentForm(w6j);             println("rex-equivalent    = $rex")
    wa  = RacahAlgebra.evaluate(rex, special=true);     println("\nwa-special value  = $wa")
    ## ws  = [:ja => 2//1, :jb => 2, :jc => 1]
    ##wb  = RacahAlgebra.subs(w6j, ws);                   println("\nw6j-substitution  = $wb")
    ##wc  = RacahAlgebra.subs(wa, ws);                    println("\nrhs-substitution  = $wc")
    ##wd  = RacahAlgebra.evaluateNumerical(wb);           println("\nlhs-numerical     = $wd")
    ##we  = RacahAlgebra.evaluateNumerical(wc);           println("\nrhs-numerical     = $we")
elseif  false
    # Test for special values of the Wigner 9-j symbols
    w9j = RacahAlgebra.selectW9j(1);                    println("w9j-original      = $w9j")
    rex = RacahAlgebra.equivalentForm(w9j);             println("rex-equivalent    = $rex")
    wa  = RacahAlgebra.evaluate(rex, special=true);     println("\nwa-special value  = $wa")
elseif  false
    # Test for recursion relations of the Wigner 3-j symbols
    # RecursionW3jMagnetic(), RecursionW3jOneStep(), RecursionW3jHalfStep(), RecursionW3jLouck()
    w3j = RacahAlgebra.W9j(1,2,3, -1,-2, 3);                            println("w3j-original      = $w3j")
    wa  = RacahAlgebra.recursionW3j(w3j, RecursionW3jMagnetic());       println("wa-special value  = $wa")
    wb  = RacahAlgebra.evaluateNumerical(w3j);                          println("lhs-numerical     = $wb")
    wc  = RacahAlgebra.evaluateNumerical(wa);                           println("rhs-numerical     = $wc")  ## Array{RacahExpression,1}
end

ext: jl


text:
export write_trace

function write_trace(s::IO, block::SeisBlock, t::Int)

    ##000
    # Write Header
    for field in fieldnames(typeof(block.traceheaders[t]))
        write(s, bswap(getfield(block.traceheaders[t], field)))
    end

    ##240
    # Write trace
    write(s, bswap.(Float32.(block.data[:,t])))
end


text:
struct SRTM <: RasterDataSource end

# SRTM Mirror with 5x5 degree tiles
const SRTM_URI = URI(scheme = "https", host = "srtm.csi.cgiar.org", path = "/wp-content/uploads/files/srtm_5x5/TIFF")

function _raster_tile_stem(tile_index::CartesianIndex)
    y, x = tile_index.I
    "srtm_$(lpad(x, 2, '0'))_$(lpad(y, 2, '0'))"
end

_rastername(::Type{SRTM}, tile_index::CartesianIndex{2}) = _raster_tile_stem(tile_index) * ".tif"
_rasterpath(T::Type{SRTM}, tile_index::CartesianIndex{2}) = joinpath(rasterpath(), "SRTM", _rastername(T, tile_index))

_zipname(::Type{SRTM}, tile_index::CartesianIndex{2}) = _raster_tile_stem(tile_index) * ".zip"
_zipurl(T::Type{SRTM}, tile_index::CartesianIndex{2}) = joinpath(SRTM_URI, _zipname(T, tile_index))
_zippath(T::Type{SRTM}, tile_index::CartesianIndex{2}) = joinpath(rasterpath(), "SRTM", "zips", _zipname(T, tile_index))

function _getraster(T::Type{SRTM}, tile_index::CartesianIndex{2})
    raster_path = _rasterpath(T, tile_index)
    if !isfile(raster_path)
        zip_path = _zippath(T, tile_index)
        _maybe_download(_zipurl(T, tile_index), zip_path)
        mkpath(dirname(raster_path))
        raster_name = _rastername(T, tile_index)
        zf = ZipFile.Reader(zip_path)
        write(raster_path, read(_zipfile_to_read(raster_name, zf)))
        close(zf)
    end
    return raster_path
end

# Adapted from https://github.com/centreborelli/srtm4/blob/master/src/srtm4.c#L87-L117
function _wgs84_to_tile_index(x, y)
    y = clamp(y, -60, 60)
    # tiles longitude indexes go from 1 to 72,
    # covering the range from -180 to +180
    tile_x = (1 + floor(Int, (x + 180) / 5)) % 72
    tile_x = tile_x == 0 ? 72 : tile_x

    tile_y = 1 + floor(Int, (60 - y) / 5)
    tile_y = tile_y == 25 ? 24 : tile_y
    CartesianIndex(tile_y, tile_x)
end

function bounds_to_tile_indices(::Type{SRTM}, bounds::NTuple{4,Real})
    minx, miny, maxx, maxy = bounds
    _min = _wgs84_to_tile_index(minx, miny)
    _max = _wgs84_to_tile_index(maxx, maxy)
    _min:_max
end

for op in (:getraster, :rastername, :rasterpath, :zipname, :zipurl, :zippath)
    _op = Symbol('_', op) # Name of internal function
    @eval begin
        # Broadcasting function dispatch
        $_op(T::Type{SRTM}, tile_index::CartesianIndices) = $(_op).(T, tile_index)
        # Bounds to tile indices dispatch
        $_op(T::Type{SRTM}, bounds::NTuple{4,Real}) = $_op(T, bounds_to_tile_indices(T, bounds))

        # Public function definition with key-word arguments
        function $op(T::Type{SRTM}; bounds=nothing, tile_index=nothing)
            if isnothing(bounds) & isnothing(tile_index)
                :op === :getraster || return joinpath(rasterpath(), "SRTM")
                throw(ArgumentError("One of `bounds` or `tile_index` kwarg must be specified"))
            elseif !isnothing(bounds) & !isnothing(tile_index)
                throw(ArgumentError("Only one of `bounds` or `tile_index` should be specified. " *
                                    "found `bounds`=$bounds and `tile_index`=$tile_index"))
            else
                # Call the internal function without key-word arguments
                return $_op(T, isnothing(tile_index) ? bounds : tile_index)
            end
        end
    end
end


text:
#=
Given an array of numbers, find the maximum sum of any contiguous subarray of the array.

For example, given the array [34, -50, 42, 14, -5, 86], the maximum sum would be 137, since we would take elements 42, 14, -5, and 86.

Given the array [-5, -1, -8, -9], the maximum sum would be 0, since we would not take any elements.

Do this in O(N) time.
=#

using Test
include("Solutions/problem49_maximum_sum_contiguous_subarray.jl")

@test maximum_contiguous_sum([34, -50, 42, 14, -5, 86]) == 137
@test maximum_contiguous_sum([-5, -1, -8, -9]) == 0

max_stars_repo_name: DominiqueCaron/daily-coding-problem

max_issues_repo_name: DominiqueCaron/daily-coding-problem

max_forks_repo_name: DominiqueCaron/daily-coding-problem


text:
typealias ILenum		Cuint
typealias ILboolean		Cuchar
typealias ILbitfield	Cuint
typealias ILbyte		Cchar
typealias ILshort		Cshort
typealias ILint			Cint
typealias ILsizei		Csize_t
typealias ILubyte		Cuchar
typealias ILushort		Cushort
typealias ILuint		Cuint
typealias ILfloat		Cfloat
typealias ILclampf		Cfloat
typealias ILdouble		Cdouble
typealias ILclampd		Cdouble
typealias ILint64		Int64
typealias ILuint64		UInt64

typealias ILchar 			Cchar
typealias ILstring 			Ptr{Cchar}
typealias ILconst_string 	Ptr{Cchar}

export ILenum, ILboolean, ILbitfield, ILbyte, ILshort, ILint, ILsizei, ILubyte, ILushort, ILuint, ILfloat, ILclampf, ILdouble, ILclampd, ILint64, ILuint64, ILchar, ILstring, ILconst_string

@ilConst IL_FALSE				= 0
@ilConst IL_TRUE				= 1

#  Matches OpenGL's right now.
#! Data formats \link Formats Formats\endlink
@ilConst IL_COLOUR_INDEX     = 0x1900
@ilConst IL_COLOR_INDEX      = 0x1900
@ilConst IL_ALPHA			  = 0x1906
@ilConst IL_RGB              = 0x1907
@ilConst IL_RGBA             = 0x1908
@ilConst IL_BGR              = 0x80E0
@ilConst IL_BGRA             = 0x80E1
@ilConst IL_LUMINANCE        = 0x1909
@ilConst IL_LUMINANCE_ALPHA  = 0x190A

#! Data types \link Types Types\endlink
@ilConst IL_BYTE           = 0x1400
@ilConst IL_UNSIGNED_BYTE  = 0x1401
@ilConst IL_SHORT          = 0x1402
@ilConst IL_UNSIGNED_SHORT = 0x1403
@ilConst IL_INT            = 0x1404
@ilConst IL_UNSIGNED_INT   = 0x1405
@ilConst IL_FLOAT          = 0x1406
@ilConst IL_DOUBLE         = 0x140A
@ilConst IL_HALF           = 0x140B

@ilConst IL_MAX_BYTE		  		= typemax(Cchar)
@ilConst IL_MAX_UNSIGNED_BYTE  	= typemax(Cuchar)
@ilConst IL_MAX_SHORT	  			= typemax(Cshort)
@ilConst IL_MAX_UNSIGNED_SHORT 	= typemax(Cushort)
@ilConst IL_MAX_INT		  		= typemax(Cint)
@ilConst IL_MAX_UNSIGNED_INT   	= typemax(Cuint)

@ilConst IL_VENDOR   = 0x1F00
@ilConst IL_LOAD_EXT = 0x1F01
@ilConst IL_SAVE_EXT = 0x1F02

#
# IL-specific @ilConst's
#

@ilConst IL_VERSION_1_7_8 = 1
@ilConst IL_VERSION       = 178

# Attribute Bits
@ilConst IL_ORIGIN_BIT          = 0x00000001
@ilConst IL_FILE_BIT            = 0x00000002
@ilConst IL_PAL_BIT             = 0x00000004
@ilConst IL_FORMAT_BIT          = 0x00000008
@ilConst IL_TYPE_BIT            = 0x00000010
@ilConst IL_COMPRESS_BIT        = 0x00000020
@ilConst IL_LOADFAIL_BIT        = 0x00000040
@ilConst IL_FORMAT_SPECIFIC_BIT = 0x00000080
@ilConst IL_ALL_ATTRIB_BITS     = 0x000FFFFF

# Palette types
@ilConst IL_PAL_NONE   = 0x0400
@ilConst IL_PAL_RGB24  = 0x0401
@ilConst IL_PAL_RGB32  = 0x0402
@ilConst IL_PAL_RGBA32 = 0x0403
@ilConst IL_PAL_BGR24  = 0x0404
@ilConst IL_PAL_BGR32  = 0x0405
@ilConst IL_PAL_BGRA32 = 0x0406

# Image types
@ilConst IL_TYPE_UNKNOWN = 0x0000
@ilConst IL_BMP          = 0x0420  #!< Microsoft Windows Bitmap - .bmp extension
@ilConst IL_CUT          = 0x0421  #!< Dr. Halo - .cut extension
@ilConst IL_DOOM         = 0x0422  #!< DooM walls - no specific extension
@ilConst IL_DOOM_FLAT    = 0x0423  #!< DooM flats - no specific extension
@ilConst IL_ICO          = 0x0424  #!< Microsoft Windows Icons and Cursors - .ico and .cur extensions
@ilConst IL_JPG          = 0x0425  #!< JPEG - .jpg, .jpe and .jpeg extensions
@ilConst IL_JFIF         = 0x0425  #!<
@ilConst IL_ILBM         = 0x0426  #!< Amiga IFF (FORM ILBM) - .iff, .ilbm, .lbm extensions
@ilConst IL_PCD          = 0x0427  #!< Kodak PhotoCD - .pcd extension
@ilConst IL_PCX          = 0x0428  #!< ZSoft PCX - .pcx extension
@ilConst IL_PIC          = 0x0429  #!< PIC - .pic extension
@ilConst IL_PNG          = 0x042A  #!< Portable Network Graphics - .png extension
@ilConst IL_PNM          = 0x042B  #!< Portable Any Map - .pbm, .pgm, .ppm and .pnm extensions
@ilConst IL_SGI          = 0x042C  #!< Silicon Graphics - .sgi, .bw, .rgb and .rgba extensions
@ilConst IL_TGA          = 0x042D  #!< TrueVision Targa File - .tga, .vda, .icb and .vst extensions
@ilConst IL_TIF          = 0x042E  #!< Tagged Image File Format - .tif and .tiff extensions
@ilConst IL_CHEAD        = 0x042F  #!< C-Style Header - .h extension
@ilConst IL_RAW          = 0x0430  #!< Raw Image Data - any extension
@ilConst IL_MDL          = 0x0431  #!< Half-Life Model Texture - .mdl extension
@ilConst IL_WAL          = 0x0432  #!< Quake 2 Texture - .wal extension
@ilConst IL_LIF          = 0x0434  #!< Homeworld Texture - .lif extension
@ilConst IL_MNG          = 0x0435  #!< Multiple-image Network Graphics - .mng extension
@ilConst IL_JNG          = 0x0435  #!<
@ilConst IL_GIF          = 0x0436  #!< Graphics Interchange Format - .gif extension
@ilConst IL_DDS          = 0x0437  #!< DirectDraw Surface - .dds extension
@ilConst IL_DCX          = 0x0438  #!< ZSoft Multi-PCX - .dcx extension
@ilConst IL_PSD          = 0x0439  #!< Adobe PhotoShop - .psd extension
@ilConst IL_EXIF         = 0x043A  #!<
@ilConst IL_PSP          = 0x043B  #!< PaintShop Pro - .psp extension
@ilConst IL_PIX          = 0x043C  #!< PIX - .pix extension
@ilConst IL_PXR          = 0x043D  #!< Pixar - .pxr extension
@ilConst IL_XPM          = 0x043E  #!< X Pixel Map - .xpm extension
@ilConst IL_HDR          = 0x043F  #!< Radiance High Dynamic Range - .hdr extension
@ilConst IL_ICNS			= 0x0440  #!< Macintosh Icon - .icns extension
@ilConst IL_JP2			= 0x0441  #!< Jpeg 2000 - .jp2 extension
@ilConst IL_EXR			= 0x0442  #!< OpenEXR - .exr extension
@ilConst IL_WDP			= 0x0443  #!< Microsoft HD Photo - .wdp and .hdp extension
@ilConst IL_VTF			= 0x0444  #!< Valve Texture Format - .vtf extension
@ilConst IL_WBMP			= 0x0445  #!< Wireless Bitmap - .wbmp extension
@ilConst IL_SUN			= 0x0446  #!< Sun Raster - .sun, .ras, .rs, .im1, .im8, .im24 and .im32 extensions
@ilConst IL_IFF			= 0x0447  #!< Interchange File Format - .iff extension
@ilConst IL_TPL			= 0x0448  #!< Gamecube Texture - .tpl extension
@ilConst IL_FITS			= 0x0449  #!< Flexible Image Transport System - .fit and .fits extensions
@ilConst IL_DICOM		= 0x044A  #!< Digital Imaging and Communications in Medicine (DICOM) - .dcm and .dicom extensions
@ilConst IL_IWI			= 0x044B  #!< Call of Duty Infinity Ward Image - .iwi extension
@ilConst IL_BLP			= 0x044C  #!< Blizzard Texture Format - .blp extension
@ilConst IL_FTX			= 0x044D  #!< Heavy Metal: FAKK2 Texture - .ftx extension
@ilConst IL_ROT			= 0x044E  #!< Homeworld 2 - Relic Texture - .rot extension
@ilConst IL_TEXTURE		= 0x044F  #!< Medieval II: Total War Texture - .texture extension
@ilConst IL_DPX			= 0x0450  #!< Digital Picture Exchange - .dpx extension
@ilConst IL_UTX			= 0x0451  #!< Unreal (and Unreal Tournament) Texture - .utx extension
@ilConst IL_MP3			= 0x0452  #!< MPEG-1 Audio Layer 3 - .mp3 extension

@ilConst IL_JASC_PAL     = 0x0475  #!< PaintShop Pro Palette

# Error Types
@ilConst IL_NO_ERROR             = 0x0000
@ilConst IL_INVALID_ENUM         = 0x0501
@ilConst IL_OUT_OF_MEMORY        = 0x0502
@ilConst IL_FORMAT_NOT_SUPPORTED = 0x0503
@ilConst IL_INTERNAL_ERROR       = 0x0504
@ilConst IL_INVALID_VALUE        = 0x0505
@ilConst IL_ILLEGAL_OPERATION    = 0x0506
@ilConst IL_ILLEGAL_FILE_VALUE   = 0x0507
@ilConst IL_INVALID_FILE_HEADER  = 0x0508
@ilConst IL_INVALID_PARAM        = 0x0509
@ilConst IL_COULD_NOT_OPEN_FILE  = 0x050A
@ilConst IL_INVALID_EXTENSION    = 0x050B
@ilConst IL_FILE_ALREADY_EXISTS  = 0x050C
@ilConst IL_OUT_FORMAT_SAME      = 0x050D
@ilConst IL_STACK_OVERFLOW       = 0x050E
@ilConst IL_STACK_UNDERFLOW      = 0x050F
@ilConst IL_INVALID_CONVERSION   = 0x0510
@ilConst IL_BAD_DIMENSIONS       = 0x0511
@ilConst IL_FILE_READ_ERROR      = 0x0512  # 05/12/2002: Addition by Sam.
@ilConst IL_FILE_WRITE_ERROR     = 0x0512

@ilConst IL_LIB_GIF_ERROR  = 0x05E1
@ilConst IL_LIB_JPEG_ERROR = 0x05E2
@ilConst IL_LIB_PNG_ERROR  = 0x05E3
@ilConst IL_LIB_TIFF_ERROR = 0x05E4
@ilConst IL_LIB_MNG_ERROR  = 0x05E5
@ilConst IL_LIB_JP2_ERROR  = 0x05E6
@ilConst IL_LIB_EXR_ERROR  = 0x05E7
@ilConst IL_UNKNOWN_ERROR  = 0x05FF

# Origin Definitions
@ilConst IL_ORIGIN_SET        = 0x0600
@ilConst IL_ORIGIN_LOWER_LEFT = 0x0601
@ilConst IL_ORIGIN_UPPER_LEFT = 0x0602
@ilConst IL_ORIGIN_MODE       = 0x0603

# Format and Type Mode Definitions
@ilConst IL_FORMAT_SET  = 0x0610
@ilConst IL_FORMAT_MODE = 0x0611
@ilConst IL_TYPE_SET    = 0x0612
@ilConst IL_TYPE_MODE   = 0x0613

# File definitions
@ilConst IL_FILE_OVERWRITE	= 0x0620
@ilConst IL_FILE_MODE		= 0x0621

# Palette definitions
@ilConst IL_CONV_PAL			= 0x0630

# Load fail definitions
@ilConst IL_DEFAULT_ON_FAIL	= 0x0632

# Key colour and alpha definitions
@ilConst IL_USE_KEY_COLOUR	= 0x0635
@ilConst IL_USE_KEY_COLOR	= 0x0635
@ilConst IL_BLIT_BLEND		= 0x0636

# Interlace definitions
@ilConst IL_SAVE_INTERLACED	= 0x0639
@ilConst IL_INTERLACE_MODE		= 0x063A

# Quantization definitions
@ilConst IL_QUANTIZATION_MODE = 0x0640
@ilConst IL_WU_QUANT          = 0x0641
@ilConst IL_NEU_QUANT         = 0x0642
@ilConst IL_NEU_QUANT_SAMPLE  = 0x0643
@ilConst IL_MAX_QUANT_INDEXS  = 0x0644 #XIX : ILint : Maximum number of colors to reduce to, default of 256. and has a range of 2-256
@ilConst IL_MAX_QUANT_INDICES = 0x0644 # Redefined, since the above @ilConst is misspelled

# Hints
@ilConst IL_FASTEST          = 0x0660
@ilConst IL_LESS_MEM         = 0x0661
@ilConst IL_DONT_CARE        = 0x0662
@ilConst IL_MEM_SPEED_HINT   = 0x0665
@ilConst IL_USE_COMPRESSION  = 0x0666
@ilConst IL_NO_COMPRESSION   = 0x0667
@ilConst IL_COMPRESSION_HINT = 0x0668

# Compression
@ilConst IL_NVIDIA_COMPRESS	= 0x0670
@ilConst IL_SQUISH_COMPRESS	= 0x0671

# Subimage types
@ilConst IL_SUB_NEXT   = 0x0680
@ilConst IL_SUB_MIPMAP = 0x0681
@ilConst IL_SUB_LAYER  = 0x0682

# Compression definitions
@ilConst IL_COMPRESS_MODE = 0x0700
@ilConst IL_COMPRESS_NONE = 0x0701
@ilConst IL_COMPRESS_RLE  = 0x0702
@ilConst IL_COMPRESS_LZO  = 0x0703
@ilConst IL_COMPRESS_ZLIB = 0x0704

# File format-specific values
@ilConst IL_TGA_CREATE_STAMP        = 0x0710
@ilConst IL_JPG_QUALITY             = 0x0711
@ilConst IL_PNG_INTERLACE           = 0x0712
@ilConst IL_TGA_RLE                 = 0x0713
@ilConst IL_BMP_RLE                 = 0x0714
@ilConst IL_SGI_RLE                 = 0x0715
@ilConst IL_TGA_ID_STRING           = 0x0717
@ilConst IL_TGA_AUTHNAME_STRING     = 0x0718
@ilConst IL_TGA_AUTHCOMMENT_STRING  = 0x0719
@ilConst IL_PNG_AUTHNAME_STRING     = 0x071A
@ilConst IL_PNG_TITLE_STRING        = 0x071B
@ilConst IL_PNG_DESCRIPTION_STRING  = 0x071C
@ilConst IL_TIF_DESCRIPTION_STRING  = 0x071D
@ilConst IL_TIF_HOSTCOMPUTER_STRING = 0x071E
@ilConst IL_TIF_DOCUMENTNAME_STRING = 0x071F
@ilConst IL_TIF_AUTHNAME_STRING     = 0x0720
@ilConst IL_JPG_SAVE_FORMAT         = 0x0721
@ilConst IL_CHEAD_HEADER_STRING     = 0x0722
@ilConst IL_PCD_PICNUM              = 0x0723
@ilConst IL_PNG_ALPHA_INDEX 		 = 0x0724 #XIX : ILint : the color in the palette at this index value (0-255) is considered transparent, -1 for no trasparent color
@ilConst IL_JPG_PROGRESSIVE         = 0x0725
@ilConst IL_VTF_COMP                = 0x0726

# DXTC definitions
@ilConst IL_DXTC_FORMAT      = 0x0705
@ilConst IL_DXT1             = 0x0706
@ilConst IL_DXT2             = 0x0707
@ilConst IL_DXT3             = 0x0708
@ilConst IL_DXT4             = 0x0709
@ilConst IL_DXT5             = 0x070A
@ilConst IL_DXT_NO_COMP      = 0x070B
@ilConst IL_KEEP_DXTC_DATA   = 0x070C
@ilConst IL_DXTC_DATA_FORMAT = 0x070D
@ilConst IL_3DC              = 0x070E
@ilConst IL_RXGB             = 0x070F
@ilConst IL_ATI1N            = 0x0710
@ilConst IL_DXT1A            = 0x0711  # Normally the same as IL_DXT1, except for nVidia Texture Tools.

# Environment map definitions
@ilConst IL_CUBEMAP_POSITIVEX = 0x00000400
@ilConst IL_CUBEMAP_NEGATIVEX = 0x00000800
@ilConst IL_CUBEMAP_POSITIVEY = 0x00001000
@ilConst IL_CUBEMAP_NEGATIVEY = 0x00002000
@ilConst IL_CUBEMAP_POSITIVEZ = 0x00004000
@ilConst IL_CUBEMAP_NEGATIVEZ = 0x00008000
@ilConst IL_SPHEREMAP         = 0x00010000

# Values
@ilConst IL_VERSION_NUM           = 0x0DE2
@ilConst IL_IMAGE_WIDTH           = 0x0DE4
@ilConst IL_IMAGE_HEIGHT          = 0x0DE5
@ilConst IL_IMAGE_DEPTH           = 0x0DE6
@ilConst IL_IMAGE_SIZE_OF_DATA    = 0x0DE7
@ilConst IL_IMAGE_BPP             = 0x0DE8
@ilConst IL_IMAGE_BYTES_PER_PIXEL = 0x0DE8
@ilConst IL_IMAGE_BITS_PER_PIXEL  = 0x0DE9
@ilConst IL_IMAGE_FORMAT          = 0x0DEA
@ilConst IL_IMAGE_TYPE            = 0x0DEB
@ilConst IL_PALETTE_TYPE          = 0x0DEC
@ilConst IL_PALETTE_SIZE          = 0x0DED
@ilConst IL_PALETTE_BPP           = 0x0DEE
@ilConst IL_PALETTE_NUM_COLS      = 0x0DEF
@ilConst IL_PALETTE_BASE_TYPE     = 0x0DF0
@ilConst IL_NUM_FACES             = 0x0DE1
@ilConst IL_NUM_IMAGES            = 0x0DF1
@ilConst IL_NUM_MIPMAPS           = 0x0DF2
@ilConst IL_NUM_LAYERS            = 0x0DF3
@ilConst IL_ACTIVE_IMAGE          = 0x0DF4
@ilConst IL_ACTIVE_MIPMAP         = 0x0DF5
@ilConst IL_ACTIVE_LAYER          = 0x0DF6
@ilConst IL_ACTIVE_FACE           = 0x0E00
@ilConst IL_CUR_IMAGE             = 0x0DF7
@ilConst IL_IMAGE_DURATION        = 0x0DF8
@ilConst IL_IMAGE_PLANESIZE       = 0x0DF9
@ilConst IL_IMAGE_BPC             = 0x0DFA
@ilConst IL_IMAGE_OFFX            = 0x0DFB
@ilConst IL_IMAGE_OFFY            = 0x0DFC
@ilConst IL_IMAGE_CUBEFLAGS       = 0x0DFD
@ilConst IL_IMAGE_ORIGIN          = 0x0DFE
@ilConst IL_IMAGE_CHANNELS        = 0x0DFF

@ilConst IL_SEEK_SET	= 0
@ilConst IL_SEEK_CUR	= 1
@ilConst IL_SEEK_END	= 2
@ilConst IL_EOF		= -1

# Functions to export julia callbacks to DevIL with the proper signature

# Callback functions for file reading
typealias ILHANDLE Ptr{Void}
export ILHANDLE

fCloseRProc(f::Function) 	= cfunction(f, Void, (ILHANDLE,))
fEofProc(f::Function) 		= cfunction(f, ILboolean, (ILHANDLE,))
fGetcProc(f::Function) 		= cfunction(f, ILint, (ILHANDLE,))
fOpenRProc(f::Function) 	= cfunction(f, ILHANDLE, (ILconst_string,))
fReadProc(f::Function) 		= cfunction(f, ILint, (Ptr{Void}, ILuint, ILuint, ILHANDLE))
fSeekRProc(f::Function) 	= cfunction(f, ILint, (ILHANDLE, ILint, ILint))
fTellRProc(f::Function) 	= cfunction(f, ILint, (ILHANDLE,))

# Callback functions for file writing
fCloseWProc(f::Function)	= cfunction(f, Void, (ILHANDLE,))
fOpenWProc(f::Function)		= cfunction(f, ILHANDLE, (ILconst_string,))
fPutcProc(f::Function)      = cfunction(f, ILint, (ILubyte, ILHANDLE))
fSeekWProc(f::Function)     = cfunction(f, ILint, (ILHANDLE, ILint, ILint))
fTellWProc(f::Function)     = cfunction(f, ILint, (ILHANDLE,))
fWriteProc(f::Function)     = cfunction(f, ILint, (Ptr{Void}, ILuint, ILuint, ILHANDLE))

# Callback functions for allocation and deallocation
mAlloc(f::Function)         = cfunction(f, Ptr{Void}, (ILsizei,))
mFree(f::Function)          = cfunction(f, Void, (Ptr{Void},))

# Registered format procedures
IL_LOADPROC(f::Function)	= cfunction(f, ILenum, (ILconst_string,))
IL_SAVEPROC(f::Function)	= cfunction(f, ILenum, (ILconst_string,))

# ImageLib Functions
@ilFunc ilActiveFace(Number::ILuint)::ILboolean
@ilFunc ilActiveImage(Number::ILuint)::ILboolean
@ilFunc ilActiveLayer(Number::ILuint)::ILboolean
@ilFunc ilActiveMipmap(Number::ILuint)::ILboolean
@ilFunc ilApplyPal(FileName::ILconst_string)::ILboolean
@ilFunc ilApplyProfile(InProfile::ILstring, OutProfile::ILstring)::ILboolean
@ilFunc ilBindImage(Image::ILuint)::Void
@ilFunc ilBlit(Source::ILuint, DestX::ILint, DestY::ILint, DestZ::ILint, SrcX::ILuint, SrcY::ILuint, SrcZ::ILuint, Width::ILuint, Height::ILuint, Depth::ILuint)::ILboolean
@ilFunc ilClampNTSC()::ILboolean
@ilFunc ilClearColour(Red::ILclampf, Green::ILclampf, Blue::ILclampf, Alpha::ILclampf)::Void
@ilFunc ilClearImage()::ILboolean
@ilFunc ilCloneCurImage()::ILuint
@ilFunc ilCompressDXT(Data::Ptr{ILubyte}, Width::ILuint, Height::ILuint, Depth::ILuint, DXTCFormat::ILenum, DXTCSize::Ptr{ILuint})::Ptr{ILubyte}
@ilFunc ilCompressFunc(Mode::ILenum)::ILboolean
@ilFunc ilConvertImage(DestFormat::ILenum , DestType::ILenum)::ILboolean
@ilFunc ilConvertPal(DestFormat::ILenum)::ILboolean
@ilFunc ilCopyImage(Src::ILuint)::ILboolean
@ilFunc ilCopyPixels(XOff::ILuint, YOff::ILuint, ZOff::ILuint, Width::ILuint, Height::ILuint, Depth::ILuint, Format::ILenum, Type::ILenum, Data::Ptr{Void})::ILuint
@ilFunc ilCreateSubImage(Type::ILenum, Num::ILuint)::ILuint
@ilFunc ilDefaultImage()::ILboolean
@ilFunc ilDeleteImage(Num::ILuint)::Void
@ilFunc ilDeleteImages(Num::ILsizei, Images::Ptr{ILuint})::Void
@ilFunc ilDetermineType(FileName::ILconst_string)::ILenum
@ilFunc ilDetermineTypeF(File::ILHANDLE)::ILenum
@ilFunc ilDetermineTypeL(Lump::Ptr{Void}, Size::ILuint)::ILenum
@ilFunc ilDisable(Mode::ILenum)::ILboolean
@ilFunc ilDxtcDataToImage()::ILboolean
@ilFunc ilDxtcDataToSurface()::ILboolean
@ilFunc ilEnable(Mode::ILenum)::ILboolean
@ilFunc ilFlipSurfaceDxtcData()::Void
@ilFunc ilFormatFunc(Mode::ILenum)::ILboolean
@ilFunc ilGenImages(Num::ILsizei, Images::Ptr{ILuint})::Void
@ilFunc ilGenImage()::ILuint
@ilFunc ilGetAlpha(Type::ILenum)::Ptr{ILubyte}
@ilFunc ilGetBoolean(Mode::ILenum)::ILboolean
@ilFunc ilGetBooleanv(Mode::ILenum, Param::Ptr{ILboolean})::Void
@ilFunc ilGetData()::Ptr{ILubyte}
@ilFunc ilGetDXTCData(Buffer::Ptr{Void}, BufferSize::ILuint, DXTCFormat::ILenum)::ILuint
@ilFunc ilGetError()::ILenum
@ilFunc ilGetInteger(Mode::ILenum)::ILint
@ilFunc ilGetIntegerv(Mode::ILenum, Param::Ptr{ILint})::Void
@ilFunc ilGetLumpPos()::ILuint
@ilFunc ilGetPalette()::Ptr{ILubyte}
@ilFunc ilGetString(StringName::ILenum)::ILconst_string
@ilFunc ilHint(Target::ILenum, Mode::ILenum)::Void
@ilFunc ilInvertSurfaceDxtcDataAlpha()::ILboolean
@ilFunc ilInit()::Void
@ilFunc ilImageToDxtcData(Format::ILenum)::ILboolean
@ilFunc ilIsDisabled(Mode::ILenum)::ILboolean
@ilFunc ilIsEnabled(Mode::ILenum)::ILboolean
@ilFunc ilIsImage(Image::ILuint)::ILboolean
@ilFunc ilIsValid(Type::ILenum, FileName::ILconst_string)::ILboolean
@ilFunc ilIsValidF(Type::ILenum, File::ILHANDLE)::ILboolean
@ilFunc ilIsValidL(Type::ILenum, Lump::Ptr{Void}, Size::ILuint)::ILboolean
@ilFunc ilKeyColour(Red::ILclampf, Green::ILclampf, Blue::ILclampf, Alpha::ILclampf)::Void
@ilFunc ilLoad(Type::ILenum, FileName::ILconst_string)::ILboolean
@ilFunc ilLoadF(Type::ILenum, File::ILHANDLE)::ILboolean
@ilFunc ilLoadImage(FileName::ILconst_string)::ILboolean
@ilFunc ilLoadL(Type::ILenum, Lump::Ptr{Void}, Size::ILuint)::ILboolean
@ilFunc ilLoadPal(FileName::ILconst_string)::ILboolean
@ilFunc ilModAlpha(AlphaValue::ILdouble)::Void
@ilFunc ilOriginFunc(Mode::ILenum)::ILboolean
@ilFunc ilOverlayImage(Source::ILuint, XCoord::ILint, YCoord::ILint, ZCoord::ILint)::ILboolean
@ilFunc ilPopAttrib()::Void
@ilFunc ilPushAttrib(Bits::ILuint)::Void
@ilFunc ilRegisterFormat(Format::ILenum)::Void
@ilFunc ilRegisterMipNum(Num::ILuint)::ILboolean
@ilFunc ilRegisterNumFaces(Num::ILuint)::ILboolean
@ilFunc ilRegisterNumImages(Num::ILuint)::ILboolean
@ilFunc ilRegisterOrigin(Origin::ILenum)::Void
@ilFunc ilRegisterPal(Pal::Ptr{Void}, Size::ILuint, Type::ILenum)::Void
@ilFunc ilRegisterType(Type::ILenum)::Void
@ilFunc ilRemoveLoad(Ext::ILconst_string)::ILboolean
@ilFunc ilRemoveSave(Ext::ILconst_string)::ILboolean
@ilFunc ilResetMemory()::Void  # Deprecated
@ilFunc ilResetRead()::Void
@ilFunc ilResetWrite()::Void
@ilFunc ilSave(Type::ILenum, FileName::ILconst_string)::ILboolean
@ilFunc ilSaveF(Type::ILenum, File::ILHANDLE)::ILuint
@ilFunc ilSaveImage(FileName::ILconst_string)::ILboolean
@ilFunc ilSaveL(Type::ILenum, Lump::Ptr{Void}, Size::ILuint)::ILuint
@ilFunc ilSavePal(FileName::ILconst_string)::ILboolean
@ilFunc ilSetAlpha(AlphaValue::ILdouble)::ILboolean
@ilFunc ilSetData(Data::Ptr{Void})::ILboolean
@ilFunc ilSetDuration(Duration::ILuint)::ILboolean
@ilFunc ilSetInteger(Mode::ILenum, Param::ILint)::Void
@ilFunc ilSetPixels(XOff::ILint, YOff::ILint, ZOff::ILint, Width::ILuint, Height::ILuint, Depth::ILuint, Format::ILenum, Type::ILenum, Data::Ptr{Void})::Void
@ilFunc ilSetString(Mode::ILenum, String::Ptr{Cchar})::Void
@ilFunc ilShutDown()::Void
@ilFunc ilSurfaceToDxtcData(Format::ILenum)::ILboolean
@ilFunc ilTexImage(Width::ILuint, Height::ILuint, Depth::ILuint, NumChannels::ILubyte, Format::ILenum, Type::ILenum, Data::Ptr{Void})::ILboolean
@ilFunc ilTexImageDxtc(w::ILint, h::ILint, d::ILint, DxtFormat::ILenum, data::Ptr{ILubyte})::ILboolean
@ilFunc ilTypeFromExt(FileName::ILconst_string)::ILenum
@ilFunc ilTypeFunc(Mode::ILenum)::ILboolean
@ilFunc ilLoadData(FileName::ILconst_string, Width::ILuint, Height::ILuint, Depth::ILuint, Bpp::ILubyte)::ILboolean
@ilFunc ilLoadDataF(File::ILHANDLE, Width::ILuint, Height::ILuint, Depth::ILuint, Bpp::ILubyte)::ILboolean
@ilFunc ilLoadDataL(Lump::Ptr{Void}, Size::ILuint, Width::ILuint, Height::ILuint, Depth::ILuint, Bpp::ILubyte)::ILboolean
@ilFunc ilSaveData(FileName::ILconst_string)::ILboolean

@ilFunc ilRegisterLoad(Ext::ILconst_string, Load::Ptr{Void})::ILboolean
@ilFunc ilRegisterSave(Ext::ILconst_string, Save::Ptr{Void})::ILboolean
@ilFunc ilSetMemory(Alloc::Ptr{Void}, Free::Ptr{Void})::Void
@ilFunc ilSetRead(Open::Ptr{Void}, Close::Ptr{Void}, Eof::Ptr{Void}, Getc::Ptr{Void}, Read::Ptr{Void}, Seek::Ptr{Void}, Tell::Ptr{Void})::Void
@ilFunc ilSetWrite(Open::Ptr{Void}, Close::Ptr{Void}, Putc::Ptr{Void}, Seek::Ptr{Void}, Tell::Ptr{Void}, Write::Ptr{Void})::Void

ilRegisterLoad(Ext::ILconst_string, Load::Function) = ilRegisterLoad(Ext, IL_LOADPROC(Load))
ilRegisterSave(Ext::ILconst_string, Save::Function) = ilRegisterSave(Ext, IL_SAVEPROC(Save))
ilSetMemory(Alloc::Function, Free::Function) = ilSetMemory(mAlloc(Alloc), mFree(Free))
ilSetRead(Open::Function, Close::Function, Eof::Function, Getc::Function, Read::Function, Seek::Function, Tell::Function) = ilSetRead(fOpenRProc(Open), fCloseRProc(Close), fEofProc(Eof), fGetcProc(Getc), fReadProc(Read), fSeekRProc(Seek), fTellRProc(Tell))
ilSetWrite(Open::Function, Close::Function, Putc::Function, Seek::Function, Tell::Function, Write::Function) = ilSetWrite(fOpenWProc(Open), fCloseWProc()Close, fPutcProc(Putc), fSeekWProc(Seek), fTellWProc(Tell), fWriteProc(Write))

# For all those weirdos that spell "colour" without the 'u'.
ilClearColor(r, g, b, a) = ilClearColour(r, g, b, a)
ilKeyColor(r, g, b, a) = ilKeyColour(r, g, b, a)

export ilClearColor, ilKeyColor


text:
using LCMCore
using CaesarLCMTypes

lcm=LCM()
function generate_example_msg()
  msg = example_t()
  msg.timestamp = 0
  msg.position = (1, 2, 3)
  msg.orientation = (1, 0, 0, 0)
  msg.ranges = randn(15)
  msg.num_ranges = length(msg.ranges)
  msg.name = "example string"
  msg.enabled = true
  return msg
end

msg = generate_example_msg()

data=encode(msg)

publish(lcm,"TEST_CHANNEL",data)


text:
"Collection of functions for Mahler expansion"
module Mahler
export bin, fac, mfill, mcoeff, mexpansion, mval

"Returns +1 for even and -1 for odd numbers"
sgn(n::Integer)::Integer = n % 2 == 0 ? 1 : -1

"Factorial. Automatically switches from factorial(n) to factorial(big(n))"
fac(n::Integer)::Integer = n < 21 ? factorial(n) : factorial(big(n))

"Binomial coefficient. Automatically switches from binomial(n,k) to binomial(big(n),big(k))"
bin(n::Integer, k::Integer)::Integer = (n+k) < 96 ? binomial(n,k) : Base.binomial(big(n),big(k))

"Binomial coefficient with Real first argument"
bin(x::Real, k::Integer)::Real = prod((i) -> x-i, 0:(k-1), init=1.0)/fac(k)

"Creates vector of values of function f in the first n integers"
mfill(f::Function, n::Integer)::Vector = f.(collect(0:(n-1)))

"Calculates Mahler coefficient from vector v"
mcoeff(v::Vector)::Number = mcoeff(v, length(v))

"Calculates Mahler coefficient from the first n+1 elements of vector v,; n=0,1,2,..."
mcoeff(v::Vector, n::Integer)::Number = sum((k) -> sgn(n-k)*bin(n,k)*v[k+1], 0:n, init=0)

"Calculates the n-th Mahler coefficient of function f"
mcoeff(f::Function, n::Integer)::Number = mcoeff(f.(collect(0:n)))

"Calculates Mahler expansion of function f of length n"
mexpansion(f::Function, n::Integer)::Vector = mexpansion(f.(collect(0:(n-1))))

"Calculates Mahler expansion of a function values stored in vector v"
mexpansion(v::Vector)::Vector = mexpansion(v, length(v))

"Calculates Mahler expansion of length n of a function values stored in vector v"
mexpansion(v::Vector, n::Integer)::Vector = ((i) -> mcoeff(v, i)).(collect(0:(n-1)))

"Calculates value of function represented as a vector of Mahler coefficients"
mval(x::Number, v::Vector)::Number = mval(x, v, length(v))

"Calculates value of function represented as a vector of Mahler coefficients; uses only first n coefficients"
mval(x::Number, v::Vector, n::Integer)::Number = sum((k) -> bin(x,k)*v[k+1], 0:(n-1), init=0)

# Some functions
"p-adic logarithm"
lnp(x::Real, k::Integer)::Real = sum((n) -> sgn(n+1)*(x-1)^n/n, 1:k, init=0.0)
lnp(x::Real)::Real = Base.log(x)

end # module

# include("./src/Mahler.jl")
# or
# pkg> activate .
# and then
# using Mahler

max_stars_repo_name: ayarodionov/Mahler

max_issues_repo_name: ayarodionov/Mahler

max_forks_repo_name: ayarodionov/Mahler


text:
using Test
using Base: catch_stack

@testset "Basic exception stack handling" begin
    # Exiting the catch block normally pops the exception
    try
        error("A")
    catch
        @test length(catch_stack()) == 1
    end
    @test length(catch_stack()) == 0
    # Exiting via a finally block does not pop the exception
    try
        try
            error("A")
        finally
            @test length(catch_stack()) == 1
        end
    catch
        @test length(catch_stack()) == 1
    end
    # The combined try-catch-finally form obeys the same rules as above
    try
        error("A")
    catch
        @test length(catch_stack()) == 1
    finally
        @test length(catch_stack()) == 0
    end
    @test length(catch_stack()) == 0
    # Errors are pushed onto the stack according to catch block nesting
    try
        error("RootCause")
    catch
        @test length(catch_stack()) == 1
        try
            error("B")
        catch
            stack = catch_stack()
            @test length(stack) == 2
            @test stack[1][1].msg == "RootCause"
            @test stack[2][1].msg == "B"
        end
        # Stack pops correctly
        stack = catch_stack()
        @test length(stack) == 1
        @test stack[1][1].msg == "RootCause"
    end
end

@testset "Exception stack lowering special cases" begin
    # try block in value position
    val = try
        error("A")
    catch
        @test length(catch_stack()) == 1
        1
    end
    @test val == 1
    function test_exc_stack_tailpos()
        # try block in tail position
        try
            error("A")
        catch
            length(catch_stack())
        end
    end
    @test test_exc_stack_tailpos() == 1
    @test length(catch_stack()) == 0
end

@testset "Exception stacks - early exit from try or catch" begin
    # Exiting a catch block early with normal control flow — break, continue,
    # return, goto — will result in popping of the exception stack.
    function test_exc_stack_catch_return()
        try
            error("A")
        catch
            @test length(catch_stack()) == 1
            return
        end
    end
    test_exc_stack_catch_return()
    for i=1:1
        try
            error("A")
        catch
            @test length(catch_stack()) == 1
            break
        end
    end
    for i=1:1
        try
            error("A")
        catch
            @test length(catch_stack()) == 1
            continue
        end
    end
    try
        error("A")
    catch
        @test length(catch_stack()) == 1
        @goto outofcatch
    end
    @label outofcatch
    @test length(catch_stack()) == 0

    # Exiting from a try block in various ways should not affect the exception
    # stack state.
    try
        error("ExceptionInOuterTry")
    catch
        @test length(catch_stack()) == 1
        function test_exc_stack_try_return()
            try
                return
            catch
            end
        end
        test_exc_stack_try_return()
        for i=1:1
            try
                break
            catch
            end
        end
        for i=1:1
            try
                continue
            catch
            end
        end
        try
            @goto outoftry
        catch
        end
        @label outoftry
        @test length(catch_stack()) == 1
        @test catch_stack()[1][1] == ErrorException("ExceptionInOuterTry")
    end
end

@testset "Deep exception stacks" begin
    # Generate deep exception stack with recursive handlers Note that if you
    # let this overflow the program stack (not the exception stack) julia will
    # crash. See #28577
    function test_exc_stack_deep(n)
        n != 1 || error("RootCause")
        try
            test_exc_stack_deep(n-1)
        catch
            error("n==$n")
        end
    end
    @test try
        test_exc_stack_deep(100)
    catch
        @test catch_stack()[1][1] == ErrorException("RootCause")
        length(catch_stack())
    end == 100
    @test length(catch_stack()) == 0
end

@testset "Exception stacks and Tasks" begin
    # Task switching should not affect exception state. See #12485.
    try
        error("A")
    catch
        t = @task try
            error("B")
        catch exc
            exc
        end
        yield(t)
        @test t.state == :done
        @test t.result == ErrorException("B")
        # Task exception state is preserved around task switches
        @test length(catch_stack()) == 1
        @test catch_stack()[1][1] == ErrorException("A")
    end
    @test length(catch_stack()) == 0
    # test rethrow() rethrows correct state
    bt = []
    try
        try
            error("A")
        catch
            bt = catch_backtrace()
            t = @task try
                error("B")
            catch exc
                exc
            end
            yield(t)
            @test t.state == :done
            @test t.result == ErrorException("B")
            @test bt == catch_backtrace()
            rethrow()
        end
    catch exc
        @test exc == ErrorException("A")
        @test bt == catch_backtrace()
    end
    @test length(catch_stack()) == 0
    # test rethrow with argument
    bt = []
    try
        try
            error("A")
        catch
            t = @task try
                error("B")
            catch exc
                exc
            end
            yield(t)
            @test t.state == :done
            @test t.result == ErrorException("B")
            bt = catch_backtrace()
            rethrow(ErrorException("C"))
        end
    catch exc
        @test exc == ErrorException("C")
        @test bt == catch_backtrace()
    end
    @test length(catch_stack()) == 0
    # Exception stacks on other tasks
    t = @task try
        error("A")
    catch
        error("B")
    end
    yield(t)
    @test t.state == :failed
    @test t.result == ErrorException("B")
    @test catch_stack(t, include_bt=false) == [ErrorException("A"), ErrorException("B")]
    # Exception stacks for tasks which never get the chance to start
    t = @task nothing
    @test try
        @async Base.throwto(t, ErrorException("expected"))
        wait(t)
    catch e
        e
    end == ErrorException("expected")
    @test length(catch_stack(t)) == 1
    @test length(catch_stack(t)[1][2]) > 0 # backtrace is nonempty
end

@testset "rethrow" begin
    @test try
        rethrow()
    catch exc
        exc
    end == ErrorException("rethrow() not allowed outside a catch block")
    @test try
        rethrow(ErrorException("A"))
    catch exc
        exc
    end == ErrorException("rethrow(exc) not allowed outside a catch block")
end

max_issues_repo_name: chenminacm/julia

max_forks_repo_name: chenminacm/julia


text:
# Write your package code here.

include("./utotal_naive.jl")
include("./DATA.jl")
include("./wrap_cell.jl")
include("./pbcseparation.jl")
include("./linkedlist.jl")
include("./initial-point.jl")
include("./upair.jl")
include("./utotal.jl")

data = Data();
box = initial_point(data);
nc, fatm, natm = linkedlist(box,data);

println(utotal(box, data, fatm, natm, nc))
println(utotal(box,data))


text:
###########################################################
### Manifold Gradient
###########################################################
@with_kw struct ManifoldGradient <: ManifoldUpdate
    linesearch::ManifoldLinesearch = Armijo()
end
Base.summary(o::ManifoldGradient) = "ManGradient"

@with_kw mutable struct ManifoldGradientState <: AbstractUpdateState
    norm_∇fgₘ::Float64 = -1.0
    ls_niter::Int64 = -1
end

initial_state(::ManifoldGradient, x, reg) = ManifoldGradientState()

str_updatelog(o::ManifoldGradient, t::ManifoldGradientState) = @sprintf "ls-nit %2i\t\t||gradₘ f+g|| %.3e" t.ls_niter t.norm_∇fgₘ

function update_iterate!(state::PartlySmoothOptimizerState, pb, o::ManifoldGradient)
    grad_fgₖ = state.tempvec_man
    M = state.M
    x = state.x.man_repr

    @assert state.x.repr == manifold_repr
    @assert is_manifold_point(M, x)

    # TODO: remove intermediate alloc from .+= op.
    grad_fgₖ = egrad_to_rgrad(M, x, state.∇f_x) + ∇M_g(pb, M, x)
    state.ncalls_gradₘF += 1

    state.update_to_updatestate[o].norm_∇fgₘ = norm(M, x, grad_fgₖ)

    # TODO: make linesearch inplace for x, return status.
    hist_ls = Dict()
    x_ls = linesearch(o.linesearch, state, nothing, pb, M, x, grad_fgₖ, -grad_fgₖ, hist=hist_ls)

    state.x.man_repr = x_ls
    state.update_to_updatestate[o].ls_niter = hist_ls[:niter]
    return
end


text:
using HANSsolver, NLsolve, Optim
include("subfiles/load_parameters.jl")

include("subfiles/load_AddPrices.jl")
include("subfiles/load_AltReturn.jl")
include("subfiles/load_GridDef.jl")
include("subfiles/load_HAconstraintAlt.jl")
include("subfiles/load_HAconstraint.jl")
include("subfiles/load_MC.jl")

include("subfiles/load_Utility.jl")
include("subfiles/load_VFafterprocess.jl")

prices = Vector{Float64}( [ 0.8177568860700106, 0.8130278740954832 ] )
mdl_init = ModelInit(  prices
, additional_prices
, grid_def
, λ
, β
, utility
, budget_constraint
, alt_constraint
, nonnaivebanks
, alt_return
, clear_marketing
, initialize_paremeters
);

mdl = modeltest(mdl_init);
# hans_solver(mdl_init)

print("DONE")


text:
"""
# start at line 394

"""
function isWithinBounds(obj::Object)::Bool
function clicked(click::Union{Click, Nothing}, object::Object)::Bool
function clicked(click::Union{Click, Nothing}, objects::AbstractArray)::Bool
function objClicked(click::Union{Click, Nothing}, objects::AbstractArray)::Object
function clicked(click::Union{Click, Nothing}, x::Int, y::Int)::Bool
function clicked(click::Union{Click, Nothing}, pos::Position)::Bool
function intersects(obj1::Object, obj2::Object)::Bool
function intersects(obj1::Object, obj2::Array{<:Object})::Bool
function intersects(list1, list2)::Bool
function intersects(object::Object)::Bool
function addObj(list::Array{<:Object}, obj::Object)
function addObj(list::Array{<:Object}, objs::Array{<:Object})
function removeObj(list::Array{<:Object}, obj::Object)
function removeObj(list::Array{<:Object}, fn)::Object
function removeObj(obj::Object)::Object
function updateObj(obj::Object, field::String, value)::Object
function filter_fallback(obj::Object)
function updateObj(list::Array{<:Object}, map_fn, filter_fn=filter_fallback)
function adjPositions(position::Position)::Array{Position}
function isWithinBounds(position::Position)::Bool
function isFree(position::Position)::Bool
function isFree(click::Union{Click, Nothing})::Bool
function unitVector(position1::Position, position2::Position)::Position
function unitVector(object1::Object, object2::Object)::Position
function unitVector(object::Object, position::Position)::Position
function unitVector(position::Position, object::Object)::Position
function unitVector(position::Position)::Position
function displacement(position1::Position, position2::Position)::Position
function displacement(cell1::Cell, cell2::Cell)::Position
function adjacent(position1::Position, position2::Position)::Bool
function adjacent(cell1::Cell, cell2::Cell)::Bool
function adjacent(cell::Cell, cells::Array{Cell})
function rotate(object::Object)::Object
function rotate(position::Position)::Position
function rotateNoCollision(object::Object)::Object
function move(position1::Position, position2::Position)
function move(cell::Cell, position::Position)
function move(object::Object, position::Position)::Object
function move(object::Object, x::Int, y::Int)::Object
function moveLeft(object::Object)::Object
function moveRight(object::Object)::Object
function moveUp(object::Object)::Object
function moveDown(object::Object)::Object
function moveNoCollision(object::Object, position::Position)::Object
function moveNoCollision(object::Object, x::Int, y::Int)
function moveLeftNoCollision(object::Object)::Object
function moveRightNoCollision(object::Object)::Object
function moveUpNoCollision(object::Object)::Object
function moveDownNoCollision(object::Object)::Object
function moveWrap(object::Object, position::Position)::Object
function moveWrap(cell::Cell, position::Position)
function moveWrap(position::Position, cell::Cell)
function moveWrap(object::Object, x::Int, y::Int)::Object
function moveWrap(position1::Position, position2::Position)::Position
function moveWrap(position::Position, x::Int, y::Int)::Position
function moveLeftWrap(object::Object)::Object
function moveRightWrap(object::Object)::Object
function moveUpWrap(object::Object)::Object
function moveDownWrap(object::Object)::Object
function randomPositions(GRID_SIZE::Int, n::Int)::Array{Position}
function distance(position1::Position, position2::Position)::Int
function distance(object1::Object, object2::Object)::Int
function distance(object::Object, position::Position)::Int
function closest(object::Object, type::DataType)::Position
function mapPositions(constructor, GRID_SIZE::Int, filterFunction, args...)::Union{Object, Array{<:Object}}
function allPositions(GRID_SIZE::Int)
function updateOrigin(object::Object, new_origin::Position)::Object
function updateAlive(object::Object, new_alive::Bool)::Object
function nextLiquid(object::Object)::Object
function nextSolid(object::Object)::Object
function allPositions()


text:
# adapted from https://github.com/FluxML/MacroTools.jl/blob/master/src/utils.jl
module ExprPrettify

export prettify

walk(x, inner, outer) = outer(x)
walk(x::Expr, inner, outer) = outer(Expr(x.head, map(inner, x.args)...))

"""
    postwalk(f, expr)

Applies `f` to each node in the given expression tree, returning the result.
`f` sees expressions *after* they have been transformed by the walk.

See also: [`prewalk`](@ref).
"""
postwalk(f, x) = walk(x, x -> postwalk(f, x), f)

"""
    prewalk(f, expr)

Applies `f` to each node in the given expression tree, returning the result.
`f` sees expressions *before* they have been transformed by the walk, and the
walk will be applied to whatever `f` returns.

This makes `prewalk` somewhat prone to infinite loops; you probably want to try
[`postwalk`](@ref) first.
"""
prewalk(f, x) = walk(f(x), x -> prewalk(f, x), identity)

"""
    isexpr(x, ts...)

Convenient way to test the type of a Julia expression.
Expression heads and types are supported, so for example
you can call

    isexpr(expr, String, :string)

to pick up on all string-like expressions.
"""
isexpr(x::Expr) = true
isexpr(x) = false
isexpr(x::Expr, ts...) = x.head in ts
isexpr(x, ts...) = any(T -> isa(T, Type) && isa(x, T), ts)

isline(ex) = isexpr(ex, :line) || isa(ex, LineNumberNode)

rmlines(x) = x
function rmlines(x::Expr)
    # Do not strip the first argument to a macrocall, which is
    # required.
    if x.head == :macrocall && length(x.args) >= 2
        Expr(x.head, x.args[1], nothing, filter(x -> !isline(x), x.args[3:end])...)
    else
        Expr(x.head, filter(x -> !isline(x), x.args)...)
    end
end

striplines(ex) = prewalk(rmlines, ex)

function flatten1(ex)
    isexpr(ex, :block) || return ex
    #ex′ = :(;)
    ex′ = Expr(:block)
    for x in ex.args
        isexpr(x, :block) ? append!(ex′.args, x.args) : push!(ex′.args, x)
    end
    # Don't use `unblock` to preserve line nos
    return length(ex′.args) == 1 ? ex′.args[1] : ex′
end

"""
    flatten(ex)

Flatten any redundant blocks into a single block, over the whole expression.
"""
flatten(ex) = postwalk(flatten1, ex)

"""
    prettify(ex)

Makes generated code generaly nicer to look at.
"""
prettify(ex; lines = false) = ex |> (lines ? identity : striplines) |> flatten

end


text:
"""
    ElementalFieldModule

Module for elemental fields.
"""
module ElementalFieldModule

using FinEtools.FTypesModule: FInt, FFlt, FCplxFlt, FFltVec, FIntVec, FFltMat, FIntMat, FMat, FVec, FDataDict
import FinEtools.FieldModule: Field, nents
import FinEtools.FieldModule.@add_Field_fields

"""
    ElementalField{T<:Number}

Elemental field.

The values in the field are indexed by the element number.  This means  that
there needs to be one field per finite element set.
"""
mutable struct ElementalField{T<:Number} <: Field
  @add_Field_fields()
end

"""
   ElementalField(data::FMat{T}=[]) where {T<:Number}

Constructor of elemental field.
"""
function ElementalField(data::FMat{T}=[]) where {T<:Number}
  values = deepcopy(data)
  dofnums = 0*similar(values,FInt)
  is_fixed = similar(values,Bool)
  fill!(is_fixed, 0)
  fixed_values = zeros(T,size(values))
  nfreedofs = 0
  return ElementalField(values, dofnums, is_fixed, fixed_values, nfreedofs)
end

function ElementalField(data::FVec{T}) where {T<:Number}
    return ElementalField(reshape(data, length(data), 1))
end

"""
    nelems(self::ElementalField)::FInt = nents(self)

Provide the number of elements  in the elemental field.
"""
nelems(self::ElementalField)::FInt = nents(self)

end


text:
# Methods to interpret string representations of OrgComponents

struct OrgComponentParseError <: Exception
    element::DataType
    msg::AbstractString
end

function Base.showerror(io::IO, ex::OrgComponentParseError)
    print(io, "Org parse error")
    print(io, " for component $(ex.element): ")
    print(io, ex.msg)
    Base.Experimental.show_error_hints(io, ex)
end

macro parseassert(elem, expr::Expr, msg)
    function matchp(e::Expr)
        if e.head == :call && e.args[1] == :match
            e = :(!(isnothing($e)))
        else
            e.args = map(matchp, e.args)
        end
        e
    end
    matchp(e::Any) = e
    expr = matchp(expr)
    quote
        if !($(esc(expr)))
            throw(OrgComponentParseError($(esc(elem)), $(esc(msg))))
        end
    end
end

include("config.jl")
include("matchers.jl")
include("operations.jl")
include("parser.jl")
include("consumers.jl")

import Base.parse

function parse(component::Type{<:OrgComponent}, content::AbstractString)
    result = consume(component, content)
    if isnothing(result)
        throw(OrgComponentParseError(component, "\"$content\" does not start with any recognised form of $(component)"))
    else
        len, obj = result
        @parseassert(component, len == ncodeunits(content),
                     "\"$content\" is not just a $component")
        obj
    end
end

# ---------------------
# Org
# ---------------------

include("postprocess.jl")

function parse(::Type{Org}, content::AbstractString)
    o = Org(Vector{Union{Heading, Section}}(parseorg(content, [Heading, Section])))
    postprocess!(o)
    o
end

# ---------------------
# Sections
# ---------------------

function Heading(components::Vector{Union{Nothing, SubString{String}}})
    stars, keyword, priority, title, tags, section = components
    level = length(stars)
    tagsvec = if isnothing(tags); [] else split(tags[2:end-1], ':') end
    planning, properties = nothing, nothing
    if !isnothing(section)
        plan = consume(Planning, section)
        if !isnothing(plan)
            section = @inbounds SubString(section.string,
                                          section.offset + plan[1],
                                          section.offset + lastindex(section))
            planning = plan[2]
        end
        props = consume(PropertyDrawer, section)
        if !isnothing(props)
            section = @inbounds SubString(section.string,
                                          section.offset + props[1] + 1,
                                          section.offset + lastindex(section))
            properties = props[2]
        end
        if ncodeunits(section) == 0
            section = nothing
        end
    end
    Heading(level, keyword, priority,
            parseobjects(Heading, title), tagsvec,
            if !isnothing(section) && isnothing(match(r"^[ \t\r\n]*$", section))
                parse(Section, section) end,
            planning, properties)
end

function Section(components::Vector{Union{Nothing, SubString{String}}})
    content = rstrip(components[1])
    Section(parseorg(content, org_element_matchers, org_element_fallbacks))
end

# ---------------------
# Greater Elements
# ---------------------

function GreaterBlock(components::Vector{Union{Nothing, SubString{String}}})
    name, parameters, contents = components
    name = ensurelowercase(name)
    containedelem = parseorg(contents, org_element_matchers, org_element_fallbacks)
    if name == "center"
        CenterBlock(parameters, containedelem)
    elseif name == "quote"
        QuoteBlock(parameters, containedelem)
    else
        SpecialBlock(name, parameters, containedelem)
    end
end

function Drawer(components::Vector{Union{Nothing,SubString{String}}})
    # When a draw by the same name is inside, it should be treated as a paragraph
    name, content = components
    Drawer(name, if !isnothing(content)
               parse(Section, content).contents
           else
               Element[]
           end)
end

function DynamicBlock(components::Vector{Union{Nothing, SubString{String}}})
    name, parameters, contents = components
    containedelem = parseorg(contents, org_element_matchers, org_element_fallbacks)
    DynamicBlock(name, parameters, containedelem)
end

# FootnoteDefinition has a custom consumer

# InlineTask

# Item has a custom consumer
# List has a custom consumer

function PropertyDrawer(components::Vector{Union{Nothing, SubString{String}}})
    nodetext = components[1]
    nodes = parseorg(nodetext, [NodeProperty])
    PropertyDrawer(Vector{NodeProperty}(nodes))
end

function Table(components::Vector{Union{Nothing, SubString{String}}})
    table, tblfms = components
    rows = map(row -> if !isnothing(match(r"^[ \t]*\|[\-\+]+\|*$", row))
                   TableHrule() else parse(TableRow, row) end,
               split(table, '\n'))
    # fill rows to same number of columns
    ncolumns = maximum(r -> if r isa TableRow length(r.cells) else 0 end, rows)
    for row in rows
        if row isa TableRow && length(row.cells) < ncolumns
            push!(row.cells, repeat([TableCell("")], ncolumns - length(row.cells))...)
        end
    end
    # formulas
    formulas = if isnothing(tblfms); [] else
        replace.(split(strip(tblfms), '\n'), r"\s*#\+TBLFM:\s*" => "")
    end
    Table(rows, formulas)
end

# ---------------------
# Elements
# ---------------------

function BabelCall(components::Vector{Union{Nothing, SubString{String}}})
    BabelCall(components[1])
end

function Block(components::Vector{Union{Nothing, SubString{String}}})
    name, data, contents = components
    lines = if !isnothing(contents)
        split(contents, '\n')
    else
        String[]
    end
    for i in 1:length(lines)
        if startswith(lines[i], ",*")
            lines[i] = @inbounds SubString(lines[i].string, 2 + lines[i].offset,
                                           lines[i].offset + lastindex(lines[i]))
        end
    end
    if name == "src"
        local lang, arguments
        if isnothing(data)
            lang, arguments = nothing, nothing
        else
            lang, arguments = match(r"^(\S+)( [^\n]+)?$", data).captures
        end
        SourceBlock(lang, arguments, lines)
    elseif name == "example"
        ExampleBlock(lines)
    end
end

# Clock has a custom consumer

function DiarySexp(components::Vector{Union{Nothing, SubString{String}}})
    DiarySexp(components[1])
end

# Planning has a custom consumer

function Comment(components::Vector{Union{Nothing, SubString{String}}})
    content = components[1]
    lines = split(content, '\n') .|> l ->
        @inbounds SubString(l.string, 1 + l.offset + ncodeunits(match(r"^[ \t]*# ?", l).match),
                            l.offset + lastindex(l))
    Comment(lines)
end

function FixedWidth(components::Vector{Union{Nothing, SubString{String}}})
    content = components[1]
    lines = split(content, '\n') .|> l ->
        @inbounds SubString(l.string, 1 + l.offset + ncodeunits(match(r"^[ \t]*: ?", l).match),
                            l.offset + lastindex(l))
    FixedWidth(lines)
end

HorizontalRule(_::Vector{Union{Nothing, SubString{String}}}) = HorizontalRule()

function Keyword(components::Vector{Union{Nothing, SubString{String}}})
    key, value = components
    key = ensurelowercase(key)
    if haskey(org_keyword_translations, key)
        key = org_keyword_translations[key]
    end
    if key in org_parsed_keywords && !isnothing(value)
        value = parseobjects(Keyword, value)
    end
    Keyword(key, value)
end

function LaTeXEnvironment(components::Vector{Union{Nothing, SubString{String}}})
    indent, name, content = components
    lines = map(split(content, '\n')) do line
        if startswith(line, indent)
            @inbounds @view line[1+ncodeunits(indent):end]
        else
            line
        end
    end
    LaTeXEnvironment(name, lines)
end

function NodeProperty(components::Vector{Union{Nothing, SubString{String}}})
    name, additive, value = components
    NodeProperty(name, !isnothing(additive), strip(value))
end

function Paragraph(components::Vector{Union{Nothing, SubString{String}}})
    Paragraph(parseobjects(Paragraph, components[1]))
end

function TableRow(components::Vector{Union{Nothing, SubString{String}}})
    TableRow(split(strip(components[1], '|'), '|') .|> strip .|>
        c -> TableCell(parseobjects(TableCell, c)))
end

# ---------------------
# Objects
# ---------------------

# Entity has a custom consumer

function LaTeXFragment(components::Vector{Union{Nothing, SubString{String}}})
    command, delimitedform = components
    if isnothing(delimitedform)
        LaTeXFragment(command, nothing)
    else
        LaTeXFragment(delimitedform[3:end-2],
                      (delimitedform[1:2], delimitedform[end-1:end]))
    end
end

function ExportSnippet(components::Vector{Union{Nothing, SubString{String}}})
    backend, snippet = components
    ExportSnippet(backend, snippet)
end

function FootnoteReference(components::Vector{Union{Nothing, SubString{String}}})
    label, definition = components
    FootnoteReference(label, definition)
end

function InlineBabelCall(components::Vector{Union{Nothing, SubString{String}}})
    name, header1, arguments, header2 = components
    InlineBabelCall(name, if isnothing(header1) header2 else header1 end, arguments)
end

# InlineSourceBlock has a custom consumer

function LineBreak(::Vector{Union{Nothing, SubString{String}}})
    LineBreak()
end

function parse(::Type{LinkPath}, content::AbstractString, verify::Bool=true)
    protocolmatch = match(r"^([^:#*<>()\[\]{}\s]+):(?://)?(.*)$", content)
    if isnothing(protocolmatch)
        verify && @parseassert(LinkPath, !occursin(r"\\[\[\]]", content),
                               "\"$content\" cannot contain unescapesquare brackets")
        if content[1] == '(' && content[end] == ')'
            LinkPath(:coderef, content[2:end-1])
        elseif content[1] == '#'
            LinkPath(:custom_id, content[2:end])
        elseif content[1] == '*'
            LinkPath(:heading, content[2:end])
        else
            LinkPath(:fuzzy, content)
        end
    else
        protocol, path = protocolmatch.captures
        verify && @parseassert(LinkPath, !occursin(r"\\[\[\]]", content),
                               "\"$content\" cannot contain unescaped square brackets")
        LinkPath(protocol, path)
    end
end

# RadioLink is handled in a post-processing step

function PlainLink(components::Vector{Union{Nothing, SubString{String}}})
    path = components[1]
    PlainLink(parse(LinkPath, path))
end

function AngleLink(components::Vector{Union{Nothing, SubString{String}}})
    path = components[1]
    AngleLink(parse(LinkPath, path))
end

# RegularLink has a custom consumer

function Macro(components::Vector{Union{Nothing, SubString{String}}})
    name, arguments = components
    Macro(name, if isnothing(arguments) || length(arguments) == 0; []
          else split(arguments, r"(?<!\\), ?") end)
end

function RadioTarget(components::Vector{Union{Nothing, SubString{String}}})
    target = components[1]
    @parseassert(RadioTarget, match(r"^[^<>\n]*$", target),
                 "\"$target\" cannot contain <, >, or \\n")
    @parseassert(RadioTarget, !match(r"^\s|\s$", target),
                 "\"$target\" cannot start or end with whitespace")
    RadioTarget(parseobjects(RadioTarget, target))
end

function Target(components::Vector{Union{Nothing, SubString{String}}})
    target = components[1]
    @parseassert(Target, match(r"^[^<>\n]*$", target),
                 "\"$target\" cannot contain <, >, or \\n")
    @parseassert(Target, !match(r"^\s|\s$", target),
                 "\"$target\" cannot start or end with whitespace")
    Target(target)
end

function StatisticsCookie(components::Vector{Union{Nothing, SubString{String}}})
    percent, numerator, denominator = components
    if isnothing(percent)
        StatisticsCookieFraction(if !isnothing(numerator) parse(Int, numerator) end,
                                 if !isnothing(denominator) parse(Int, denominator) end)
    else
        StatisticsCookiePercent(percent)
    end
end

function Script(components::Vector{Union{Nothing, SubString{String}}})
    char, type, script = components
    if type == "^"
        Superscript(char[1], script)
    else
        Subscript(char[1], script)
    end
end

function TableCell(components::Vector{Union{Nothing, SubString{String}}})
    content = components[1]
    @parseassert(TableCell, !occursin("|", content),
                 "\"$content\" cannot contain \"|\"")
    TableCell(parseobjects(TableCell, strip(content)))
end


text:
using DataFrames

function parse_numbers(s)
    pieces = split(s, ' ', keepempty=false)
    map(pieces) do piece
        parse(Float64, piece)
    end
end

"""
    load_H(path)

Load a homography matrix from path `path`
"""
function load_H(path)
    lines = readlines(path)
    H = Array{Float64}(undef, (3,3))
    for (k, line) in zip(1:3, lines)
        H[k,:] = parse_numbers(line)
    end
    return H
end

"""
    make_flow_from_H(H, size)

Make a flow of size `size` from the homography matrix `H`.
"""
function make_flow_from_H(H, size)
    warp_perspective(x, y) = (H[1,1]*x + H[1,2]*y + H[1,3])/(H[3,1]*x + H[3,2]*y + H[3,3]),
                             (H[2,1]*x + H[2,2]*y + H[2,3])/(H[3,1]*x + H[3,2]*y + H[3,3])
    flow = Array{Complex{Float64},2}(undef, size)
    X = ones(size[1]) * collect(range(0,1,length=size[2]))'
    Y = collect(range(0,1,length=size[1])) * ones(size[2])'

    X = ones(size[1]) * collect(1:size[2])'
    Y = collect(1:size[1]) * ones(size[2])'
    for ind in CartesianIndices(flow)
        calc = [X[ind], Y[ind]] .- warp_perspective(X[ind], Y[ind])
        flow[ind] = calc[1] + im*calc[2]
    end
    return flow
end

"""
    gen_rand_points(flow, point_count, mode; max_skew_const=4)

Generate `point_count` random indices over `flow` depending on selection `mode`.
"""
function gen_rand_points(flow, point_count, mode; max_skew_const=4)
    if mode == "Random_points"
        ret_inds = rand(CartesianIndices(flow), point_count)
    elseif mode == "Gridded"
        points_in_dim = round(Int64, sqrt(point_count))
        point_spacing = floor.(size(flow) ./ points_in_dim)

        ret_inds = Array{CartesianIndex{2}, 1}(undef, 0)
        for ind in CartesianIndices(flow)
            if all((Tuple(ind)) .% point_spacing .== 0)
                add_ind = CartesianIndex(Tuple(ind) .- floor.(Int64, point_spacing ./ 2))
                push!(ret_inds, add_ind)
            end
        end
    elseif mode == "Semigridded"
        points_in_dim = round(Int64, sqrt(point_count))
        point_spacing = floor.(size(flow) ./ points_in_dim)

        ret_inds = Array{CartesianIndex{2}, 1}(undef, 0)
        for ind in CartesianIndices(flow)
            if all((Tuple(ind)) .% point_spacing .== 0)
                skew = (rand((-floor(Int64, point_spacing[1]/max_skew_const):floor(Int64, point_spacing[1]/max_skew_const))),
                        rand((-floor(Int64, point_spacing[1]/max_skew_const):floor(Int64, point_spacing[2]/max_skew_const))))
                add_ind = CartesianIndex(Tuple(ind) .- floor.(Int64, point_spacing ./ 2) .+ skew)
                @assert add_ind in CartesianIndices(flow)

                push!(ret_inds, add_ind)
            end
        end
    end
    return ret_inds
end

function save_shift_landmarks(source_landmarks_path, flow, args_dict)
    source_landmarks_df = CSV.read(source_landmarks_path) |> DataFrame
    locations = [source_landmarks_df[:, "Y"] source_landmarks_df[:, "X"]]
    shifted_landmarks = LAP_julia.move_landmarks(locations, flow)
    shifted_landmarks_df = DataFrame(Column1 = 0:(size(locations,1)-1), X = shifted_landmarks[:,2], Y = shifted_landmarks[:,1])
    save_path = joinpath(args_dict["output_path"], args_dict["land_warped_fname"])
    CSV.write(save_path, shifted_landmarks_df)
end

function save_shift_landmarks(source_landmarks_path, flow, save_path::String)
    source_landmarks_df = CSV.read(source_landmarks_path) |> DataFrame
    locations = [source_landmarks_df[:, "Y"] source_landmarks_df[:, "X"]]
    shifted_landmarks = LAP_julia.move_landmarks(locations, flow)
    shifted_landmarks_df = DataFrame(Column1 = 0:(size(locations,1)-1), X = shifted_landmarks[:,2], Y = shifted_landmarks[:,1])
    save_path = joinpath(save_path)
    CSV.write(save_path, shifted_landmarks_df)
end

function save_landmarks(inds::Array{CartesianIndex{2},1}, save_path::String)
    points = transpose(inds_to_points(inds))
    shifted_landmarks_df = DataFrame(Column1 = 0:(size(points,1)-1), X = points[:,2], Y = points[:,1])
    save_path = joinpath(save_path)
    CSV.write(save_path, shifted_landmarks_df)
end

function save_landmarks(points, save_path::String)
    shifted_landmarks_df = DataFrame(Column1 = 0:(size(points,1)-1), X = points[:,2], Y = points[:,1])
    save_path = joinpath(save_path)
    CSV.write(save_path, shifted_landmarks_df)
end

function get_valid_landmarks(flow, orig_inds)
    rng = extrema.(indices_spatial(flow))
    orig_points = transpose(LAP_julia.inds_to_points(orig_inds))
    moved_points = LAP_julia.move_landmarks(orig_points, flow)
    stayed_in_mask = is_in_bounds.(moved_points[:,1], rng[1]...) .& is_in_bounds.(moved_points[:,2], rng[2]...)
    filtered_orig_points = orig_points[stayed_in_mask, :]
    filtered_orig_inds = points_to_inds(transpose(filtered_orig_points))
    return filtered_orig_inds
end


text:
include("stop_conditions.jl")
include("hooks.jl")


text:
using HTTP
using JSON

# Working, gets PR details
# r = HTTP.request("GET", "https://api.github.com/repos/adamslc/JuliaGHA.jl/pulls/5")
# println(r.status)
# j = JSON.parse(String(r.body))

gha_token = "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"
sha = "0bdc0deb86e53136e3fc1c914adb6df54d744bf0"

# Working, posts issue comment on PR
# params = Dict("body" => "Hello world!")
# r = HTTP.request("POST", "https://api.github.com/repos/adamslc/JuliaGHA.jl/issues/5/comments",
#                  ["Content-Type" => "application/json", "Authorization" => "token $gha_token"],
#                  JSON.json(params))
# println(r.status)
# body = String(r.body)
# println(body)
# j = JSON.parse(body)

# Working, post a comment on a line in a PR
body = " ```suggestion
function poorly_formatted(x, y)
    return add(mul(x, x), mul(x, x))
end
```"
params = Dict(
    "body" => "asdf",
    "path" => "src/JuliaGHA.jl",
    # "start_line" => 1, "start_side" => "RIGHT",
    "line" => 12,
    "side" => "RIGHT",
    "commit_id" => sha,
)
r = HTTP.request(
    "POST",
    "https://api.github.com/repos/adamslc/JuliaGHA.jl/pulls/5/comments",
    [
        "Accept" => "application/vnd.github.comfort-fade-preview+json",
        "Content-Type" => "application/json",
        "Authorization" => "token $gha_token",
    ],
    JSON.json(params),
)
println(r.status)
body = String(r.body)
j = JSON.parse(body)

# Get files changed
# params = Dict("per_page" => 10, "page" => 1)
# r = HTTP.request("GET", "https://api.github.com/repos/adamslc/JuliaGHA.jl/pulls/5",
#                  ["Accept" => "application/vnd.github.comfort-fade-preview+json",
#                   "Content-Type" => "application/json", "Authorization" => "token $gha_token"],
#                  JSON.json(params))
# println(r.status)
# body = String(r.body)
# j = JSON.parse(body)

# raw_url      = "https://github.com/adamslc/JuliaGHA.jl/raw/2ef47e1356d0eee289b447074b4efe0655f4230a/src/JuliaGHA.jl"
# blob_url     = "https://github.com/adamslc/JuliaGHA.jl/blob/2ef47e1356d0eee289b447074b4efe0655f4230a/src/JuliaGHA.jl"
# contents_url = "https://api.github.com/repos/adamslc/JuliaGHA.jl/contents/src/JuliaGHA.jl?ref=2ef47e1356d0eee289b447074b4efe0655f4230a"

# diff_url = "https://github.com/adamslc/JuliaGHA.jl/pull/5.diff"

# r = HTTP.request("GET", diff_url)
# println(r.status)
# body = String(r.body)
# println(body)
# j = JSON.parse(body)


text:
UNIFORM_TESTDATA = [
    0.1 0.2;
    0.1 0.4;
    0.8 0.9;
    0.3 0.5;
    0.5 0.1
];

GAUSSIAN_TESTDATA = [
    -0.1 1.2;
    0.1 2.4;
    0.8 -0.9;
    -2.3 0.5;
    -0.5 0.1
];


text:
# Test SortedVector
v = SortedVector(collect([1.; 10.; 10:15.]))
A = AxisArray(reshape(1:16, 8, 2), v, [:a, :b])
@test A[ClosedInterval(8.,12.), :] == A[2:5, :]
@test A[1. .. 1., :] == A[1:1, :]
@test A[10. .. 10., :] == A[2:3, :]
@test size(v) == (8,)
@test size(v, 1) == 8
@test size(v, 2) == 1
# test StepRange indexing
@test v[1:2:8] == [1.0; 10.0; 12.0; 14.0]

# Test SortedVector with a hierarchical index (indexed using Tuples)
data = reshape(1.:40., 20, 2)
# v = collect(zip([:a, :b, :c][rand(1:3,20)], [:x,:y][rand(1:2,20)], [:x,:y][rand(1:2,20)]))
v = [(:b, :x, :y), (:c, :y, :y), (:b, :x, :y), (:a, :y, :y), (:b, :y, :y),
     (:c, :y, :y), (:b, :x, :x), (:c, :x, :y), (:c, :y, :y), (:a, :y, :y),
     (:a, :y, :y), (:b, :x, :y), (:c, :x, :y), (:c, :y, :y), (:b, :x, :y),
     (:a, :x, :x), (:c, :x, :x), (:c, :y, :y), (:b, :y, :x), (:b, :y, :y)]
idx = sortperm(v)
A = AxisArray(data[idx,:], SortedVector(v[idx]), [:a, :b])
@test A[:b, :] == A[5:12, :]
@test A[[:a,:c], :] == A[[1:4;13:end], :]
@test A[(:a,:y), :] == A[2:4, :]
@test A[(:c,:y,:y), :] == A[16:end, :]
@test A[ClosedInterval(:a,:b), :] == A[1:12, :]
@test A[ClosedInterval((:a,:x),(:b,:x)), :] ==  A[1:9, :]
@test A[[ClosedInterval((:a,:x),(:b,:x)),:c], :] ==  A[[1:9;13:end], :]


text:
mutable struct PlateFixUpdateState{T,U,V,W}
    kernel::T
    score::Float64
    weight::Float64
    isempty::Bool
    args::U
    nodes::V
    deltas::W
    discard::DynamicAssignment
end

function fix_update_existing_trace!(key::Int, state::PlateFixUpdateState, subtraces, retvals)
    node = haskey(state.nodes, key) ? state.nodes[key] : EmptyAssignment()
    if haskey(state.deltas, key)
        kernel_delta = state.deltas[key]
    else
        kernel_delta = nothing
    end
    subtrace = state.subtraces[key]
    prev_call = get_call_record(subtrace)
    kernel_args = get_args_for_key(state.args, key)
    (subtrace, kernel_weight, kernel_discard) = fix_update(
        state.kernel, kernel_args, kernel_delta, subtrace, node)
    set_internal_node(state.discard, kernel_discard)
    state.weight += kernel_weight
    call = get_call_record(subtrace)
    state.score += (call.score - prev_call.score)
    subtraces = assoc(trace, key, subtrace)
    retvals = assoc(retvals, key, call.retval)
    state.is_empty = state.is_empty && !has_choices(subtraces)
    (subtraces, retvals)
end

function simulate_new_trace!(key::Int, state::PlateFixUpdateState, subtraces, retvals, kernel)
    kernel_args = get_args_for_key(state.args, key)
    subtrace  = simulate(gen.kernel, kernel_args)
    subtraces = push(subtraces, subtrace)
    call = get_call_record(subtrace)
    state.score += call.score
    retvals = push(retvals, call.retval)
    (subtraces, retvals)
end

function fix_update_process_constraints!(nodes, key::Int, node, prev_length, new_length)
    if key > min(prev_length, new_length)
        error("fix_update cannot constrain new or deleted addresses; offending key: $key, prev_len: $prev_length, new_len: $new_len")
    end
    if key <= new_length
        push!(to_visit, key)
        nodes[key] = node
    else
        error("Update did not consume constraints at key $key")
    end
end

function fix_update_process_constraints!(nodes, key, node, prev_length, new_length)
    # key is something other than an Int
    error("Update did not consume constraints at key $key")
end

"""
Update with argument delta information
"""
function fix_update(gen::Plate, args, delta::PlateDelta{T}, trace::VectorTrace, constraints) where {T}

    (new_length, prev_length) = get_prev_and_new_lengths(args, trace)

    # calculate which existing applications to visit
    to_visit = Set{Int}()
    deltas = Dict{Int, T}()
    for (i, kernel_delta) in zip(delta.changed_args, delta.sub_deltas)
        if i <= new_length
            push!(to_visit, i)
            deltas[i] = kernel_delta
        end
    end

    _fix_update(gen, args, delta, trace, constraints, to_visit, deltas)
end

"""
Update without argument delta information
"""
function fix_update(gen::Plate, args, delta::Nothing, trace::VectorTrace, constraints)

    (new_length, prev_length) = get_prev_and_new_lengths(args, trace)

    # visit all existing applications that are preserved
    to_visit = 1:min(prev_length, new_length)
    deltas = Dict{Int, Any}() # not used

    _fix_update(gen, args, delta, trace, constraints, to_visit, deltas)
end

function _fix_update(gen::Plate, args, delta::Nothing, trace::VectorTrace, constraints, to_visit, deltas)

    (new_length, prev_length) = get_prev_and_new_lengths(args, trace)

    # collect constraints, indexed by key
    nodes = Dict{Int, Any}()
    for (key, node) in get_internal_nodes(constraints)
        fix_update_process_constraints!(nodes, key, node, prev_length, new_length)
    end

    # collect initial state
    discard = DynamicAssignment()
    state = PlateFixUpdateState(gen.kernel, trace.call.score, 0., trace.is_empty, args, nodes, deltas, discard)
    subtraces = trace.subtraces
    retvals = trace.call.retvals

    # visit existing applications
    for key in to_visit
        (subtraces, retvals) = fix_update_existing_trace!(key, state, subtraces, retvals)
    end

    # visit each new application and run simulate on it
    for key=prev_length+1:new_length
        (subtraces, retvals) = simulate_new_trace!(key, state, subtraces, retvals)
    end

    trace = VectorTrace(subtraces, CallRecord(state.score, retvals, args), state.is_empty)
    (trace, state.weight, discard)
end

max_stars_repo_name: BoltzmannBrain/Gen

max_issues_repo_name: BoltzmannBrain/Gen

max_forks_repo_name: BoltzmannBrain/Gen


text:
mutable struct JointEstimationMMLEModel
    parameters::Vector{<:AbstractParameters}
    latents::Vector{<:AbstractLatent}
    responses_per_item::Vector{Vector{Float64}}
    responses_per_examinee::Vector{Vector{Float64}}
    n_index::Vector{Vector{Int64}}
    i_index::Vector{Vector{Int64}}
    dist::Distributions.DiscreteUnivariateDistribution
    metric::Vector{Float64}
    rescale_latent::Bool
    ext_opt_settings::Vector{Float64}
    int_opt_settings::Vector{Float64}

    JointEstimationMMLEModel(parameters, latents, responses_per_item, responses_per_examinee, n_index, i_index, dist, metric, rescale_latent, ext_opt_settings, int_opt_settings) =
     new(parameters, latents, responses_per_item, responses_per_examinee, n_index, i_index, dist, metric, rescale_latent, ext_opt_settings, int_opt_settings)
end


text:
include("config_library.jl")

####################### Example script #######################
# Read a configuration from a specified file
print("Reading YAML file...\n\n")
configuration = YAML.load(open("example_configuration.yml"))

# Load configuration and
# 1) Assert consistency of the specified yml file
# 2) Instantiate the component types
# 3) Set up the file system enabling each component (export using setup)
# 4) Open component specific IOStream objects stored in IO_Object.file_handles
# 5) Store objects in a list where they are accessed as
print("Loading configuration...\n\n")
IO_Objects = load_configuration(configuration)

# Now pins may be read and written to by the simple command
ID = 7         # A specific unique integer ID assigned to each component (HERE ADC channel 0)
operation = 1  # An operation specific to each component
print("\n\nRunning example...\n\n")
write(IO_Objects[ID].file_handles[operation], "Hello world");

# Retreiving the handle by accessing known elements in two small arrays (fast)
# and the operation is designed to acces a specific file of a specific pin, where
# for instance in the PWM pins (here ID = {5,6} as specified in the
#example_configuration yaml file) we could have
#
# operation ||     explanation
# =========================================
#     1     || read/write duty cycle
#     2     || read/write carrier frequency
#     3     || read/write polariy
#     4     || read/write enable


text:
include("lib_for_robot.jl")
function task15(r)
    x,y=tostart(r)
    side=Nord
    for i in 0:3
        while isborder(r,side)==false
            putmarker!(r)
            move!(r,side)
        end
        side=reverseside(side)
    end
    todefault(r,Ost,x)
    todefault(r,Nord,y)

end


text:
# Passing global variables around fixes performance issue
# Why?  functions are specialized by argument types.

using BenchmarkTools

# using global variable
variable = 10
function add_by_passing_global_variable(x, v)
    return x + v
end

@btime add_by_passing_global_variable(10, $variable);
#=
julia> @btime add_by_passing_global_variable(10, $variable);
  0.032 ns (0 allocations: 0 bytes)
=#

const constant = 10
function add_by_passing_global_constant(x, v)
    return x + v
end
@btime add_by_passing_global_constant(10, $constant);
#=
julia> @btime add_by_passing_global_constant(10, $constant);
  0.032 ns (0 allocations: 0 bytes)
=#


text:
# This file is a part of BAT.jl, licensed under the MIT License (MIT).

struct DensityProduct{
    N,
    D<:NTuple{N,AbstractDensity},
    B<:AbstractVarBounds
} <: AbstractDensity
    densities::D
    bounds::B

    # ToDo: Check for equal number of parameters in DensityProduct ctor.

    DensityProduct(densities::D, bounds::B) where {N,D<:NTuple{N,AbstractDensity},B<:AbstractVarBounds} =
        new{N,D,B}(densities, bounds)

end

Base.parent(density::DensityProduct) = density.densities

var_bounds(density::DensityProduct) = density.bounds

ValueShapes.varshape(density::DensityProduct) = ArrayShape{Real}(totalndof(density.bounds))

import Base.*
function *(a::AbstractDensity, b::AbstractDensity)
    totalndof(a) != totalndof(b) && throw(ArgumentError("Can't multiply densities with different number of arguments"))
    new_bounds = var_bounds(a) ∩ var_bounds(b)
    _unsafe_prod(a, b, new_bounds)
end

_unsafe_prod(a::AbstractDensity, b::AbstractDensity, new_bounds::AbstractVarBounds) =
    DensityProduct((a,b), new_bounds)

_unsafe_prod(a::AbstractDensity, b::DensityProduct, new_bounds::AbstractVarBounds) =
    DensityProduct((a, b.densities...), new_bounds)

_unsafe_prod(a::DensityProduct, b::DensityProduct, new_bounds::AbstractVarBounds) =
    DensityProduct((a.densities..., b.densities...), new_bounds)

_unsafe_prod(a::DensityProduct, b::AbstractDensity, new_bounds::AbstractVarBounds) =
    DensityProduct((a.densities...,b), new_bounds)

function eval_logval_unchecked(density::DensityProduct, v::AbstractVector{<:Real})
    ds = density.densities
    isempty(ds) && throw(ArgumentError("Can't evaluate empty DensityProduct"))
    sum(map(d -> eval_logval_unchecked(d, v), ds))
end


text:
using PlotlyJS, DataFrames, CSV

function table1()
    values = [
        "Salaries" 1200000 1300000 1300000 1400000
        "Office" 20000 20000 20000 20000
        "Merchandise" 80000 70000 120000 90000
        "Legal" 2000 2000 2000 2000
        "TOTAL" 12120000 130902000 131222000 14102000
    ]

    trace = table(
        header=attr(
            values=["Expenses", "Q1", "Q2", "Q3", "Q4"],
            align="center", line=attr(width=1, color="black"),
            fill_color="grey", font=attr(family="Arial", size=12, color="white")
        ),
        cells=attr(
            values=values, align="center", line=attr(color="black", width=1),
            font=attr(family="Arial", size=11, color="black")
        )
    )
    plot(trace)

end

function table2()
    values = [
        "Salaries" 1200000 1300000 1300000 1400000
        "Office" 20000 20000 20000 20000
        "Merchandise" 80000 70000 120000 90000
        "Legal" 2000 2000 2000 2000
        "TOTAL" 12120000 130902000 131222000 14102000
    ]

    trace = table(
        header=attr(
            values=["EXPENSES", "Q1", "Q2", "Q3", "Q4"],
            align=["left", "center"], line=attr(width=1, color="#506784"),
            fill_color="#119DFF",
            font=attr(family="Arial", size=12, color="white")
        ),
        cells=attr(
            values=values, align=["left", "center"],
            line=attr(color="#506784", width=1),
            font=attr(family="Arial", size=11, color="#506784"),
            fill_color=["#25FEFD", "white"]
        )
    )
    plot(trace)

end

function table2a()
    p1 = table1()
    restyle!(p1,
        header=attr(
            align=["left", "center"], line_color="#506784", fill_color="#119DFF"
        ),
        cells=attr(
            align=["left", "center"], line_color="#506784",
            fill_color=["#25FEFD", "white"], font_color="#506784"
        )
    )
    p1
end

function table3()
    nm = tempname()
    url = "https://raw.githubusercontent.com/plotly/datasets/master/Mining-BTC-180.csv"
    download(url, nm)
    df = CSV.read(nm)
    rm(nm)

    data = Array(df)

    trace = table(
        columnwidth=[200, 500, 600, 600, 400, 400, 600, 600, 600],
        # columnorder=0:9,
        header=attr(
            values=map(x-> replace(string(x), '_' => '-'), names(df)),
            align="center",
            line=attr(width=1, color="rgb(50, 50, 50)"),
            fill_color=["rgb(235, 100, 230)"],
            font=attr(family="Arial", size=12, color="white")
        ),
        cells=attr(
            values=Array(df),
            align=["center", "center"],
            line=attr(width=1, color="black"),
            fill_color=["rgba(228, 222, 249, 0.65)", "rgb(235, 193, 238)", "rgba(228, 222, 249, 0.65)"],
            font=attr(family="Arial", size=10, color="black")
        )
    )

    layout = Layout(
        title="Bitcoin mining stats for 180 days",
        width=1200
    )
    plot(trace, layout)
end


text:
function (+){G1<:Grasp,G2<:Grasp,R<:Real}(a::Rvl{G1,R}, b::Rvl{G2,R})
    aLoIsOpen, aHiIsOpen = boundaries(G1)
    bLoIsOpen, bHiIsOpen = boundaries(G2)

    abGrasp = boundaries( (aLoIsOpen|bLoIsOpen), (aHiIsOpen|bHiIsOpen) )

    lo = (+)(a.lo, b.lo, RoundDown)
    hi = (+)(a.hi, b.hi, RoundUp)

    Rvl{abGrasp,R}(lo, hi)
end

(+){G<:Grasp,R<:Real}(a::Rvl{G,R}, b::R) = (+)(a, Rvl{G,R}(b))
(+){G<:Grasp,R<:Real}(a::R, b::Rvl{G,R}) = (+)(Rvl{G,R}(a), b)

(+){G<:Grasp,I<:WorkInt}(a::Rvl{G,Float64}, b::I) = (+)(a, Rvl{G,Float64}(convert(Float64,b)))
(+){G<:Grasp,I<:WorkInt}(a::I, b::Rvl{G,Float64}) = (+)(Rvl{G,Float64}(convert(Float64,a)), b)
(+){G<:Grasp,I<:WorkInt}(a::Rvl{G,Float32}, b::I) = (+)(a, Rvl{G,Float32}(convert(Float32,b)))
(+){G<:Grasp,I<:WorkInt}(a::I, b::Rvl{G,Float32}) = (+)(Rvl{G,Float32}(convert(Float32,a)), b)