text:
# https://github.com/dcjones/Gadfly.jl

# ---------------------------------------------------------------------------

# immutable MissingVec <: AbstractVector{Float64} end
# Base.size(v::MissingVec) = (1,)
# Base.getindex(v::MissingVec, i::Integer) = 0.0

function createGadflyPlotObject(d::Dict)
  gplt = Gadfly.Plot()
  gplt.mapping = Dict()
  gplt.data_source = Gadfly.DataFrames.DataFrame()
  # gplt.layers = gplt.layers[1:0]
  gplt.layers = [Gadfly.layer(Gadfly.Geom.point(tag=:remove), x=zeros(1), y=zeros(1));] # x=MissingVec(), y=MissingVec());]
  gplt.guides = Gadfly.GuideElement[Gadfly.Guide.xlabel(d[:xlabel]),
                                   Gadfly.Guide.ylabel(d[:ylabel]),
                                   Gadfly.Guide.title(d[:title])]
  gplt
end

# ---------------------------------------------------------------------------

function getLineGeom(d::Dict)
  lt = d[:linetype]
  xbins, ybins = maketuple(d[:nbins])
  if lt == :hexbin
    Gadfly.Geom.hexbin(xbincount = xbins, ybincount = ybins)
  elseif lt == :heatmap
    Gadfly.Geom.histogram2d(xbincount = xbins, ybincount = ybins)
  elseif lt == :hist
    Gadfly.Geom.histogram(bincount = xbins)
  elseif lt == :path
    Gadfly.Geom.path
  elseif lt in (:bar, :sticks)
    Gadfly.Geom.bar
  elseif lt == :steppost
    Gadfly.Geom.step
  elseif lt == :steppre
    Gadfly.Geom.step(direction = :vh)
  elseif lt == :hline
    Gadfly.Geom.hline
  elseif lt == :vline
    Gadfly.Geom.vline
  elseif lt == :contour
    Gadfly.Geom.contour(levels = d[:levels])
  else
    nothing
  end
end

function get_extra_theme_args(d::Dict, k::Symbol)
  # gracefully handles old Gadfly versions
  extra_theme_args = Dict()
  try
    extra_theme_args[:line_style] = Gadfly.get_stroke_vector(d[k])
  catch err
    if string(err) == "UndefVarError(:get_stroke_vector)"
      Base.warn_once("Gadfly.get_stroke_vector failed... do you have an old version of Gadfly?")
    else
      rethrow()
    end
  end
  extra_theme_args
end

function getGadflyLineTheme(d::Dict)

  lc = convertColor(getColor(d[:linecolor]), d[:linealpha])
  # lc = getColor(d[:linecolor])
  # α = d[:linealpha]
  # if α != nothing
  #   lc = RGBA(lc, α)
  # end

  fc = convertColor(getColor(d[:fillcolor]), d[:fillalpha])
  # fc = getColor(d[:fillcolor])
  # α = d[:fillalpha]
  # if α != nothing
  #   fc = RGBA(fc, α)
  # end

  Gadfly.Theme(;
      default_color = lc,
      line_width = (d[:linetype] == :sticks ? 1 : d[:linewidth]) * Gadfly.px,
      # line_style = Gadfly.get_stroke_vector(d[:linestyle]),
      lowlight_color = x->RGB(fc),  # fill/ribbon
      lowlight_opacity = alpha(fc), # fill/ribbon
      bar_highlight = RGB(lc),      # bars
      get_extra_theme_args(d, :linestyle)...
    )
end

# add a line as a new layer
function addGadflyLine!(plt::Plot, numlayers::Int, d::Dict, geoms...)
  gplt = getGadflyContext(plt)
  gfargs = vcat(geoms...,
                getGadflyLineTheme(d))
  kwargs = Dict()
  lt = d[:linetype]

  # add a fill?
  if d[:fillrange] != nothing && lt != :contour
    fillmin, fillmax = map(makevec, maketuple(d[:fillrange]))
    nmin, nmax = length(fillmin), length(fillmax)
    kwargs[:ymin] = Float64[min(y, fillmin[mod1(i, nmin)], fillmax[mod1(i, nmax)]) for (i,y) in enumerate(d[:y])]
    kwargs[:ymax] = Float64[max(y, fillmin[mod1(i, nmin)], fillmax[mod1(i, nmax)]) for (i,y) in enumerate(d[:y])]
    push!(gfargs, Gadfly.Geom.ribbon)
  end

  if lt in (:hline, :vline)
    kwargs[lt == :hline ? :yintercept : :xintercept] = d[:y]

  else
    if lt == :sticks
      w = 0.01 * mean(diff(d[:x]))
      kwargs[:xmin] = d[:x] - w
      kwargs[:xmax] = d[:x] + w
    elseif lt == :contour
      # d[:y] = reverse(d[:y])
      kwargs[:z] = d[:z].surf
      addGadflyContColorScale(plt, d[:linecolor])
    end

    kwargs[:x] = d[lt == :hist ? :y : :x]
    kwargs[:y] = d[:y]

  end

  # # h/vlines
  # if lt == :hline
  #   kwargs[:yintercept] = d[:y]
  # elseif lt == :vline
  #   kwargs[:xintercept] = d[:y]
  # elseif lt == :sticks
  #   w = 0.01 * mean(diff(d[:x]))
  #   kwargs[:xmin] = d[:x] - w
  #   kwargs[:xmax] = d[:x] + w
  # elseif lt == :contour
  #   d[:y] = reverse(d[:y])
  #   kwargs[:z] = d[:surface]
  # end

  # if lt == :hist
  #   kwargs[:x] = kwargs[:y] = d[:y]
  # elseif lt != :hline && lt != :vline
  #   kwargs[:x] = d[:x]
  #   kwargs[:y] = d[:y]
  # end

  # # add the layer
  # x = d[d[:linetype] == :hist ? :y : :x]
  # Gadfly.layer(gfargs...; x = x, y = d[:y], order=numlayers, kwargs...)
  Gadfly.layer(gfargs...; order=numlayers, kwargs...)
end

# ---------------------------------------------------------------------------

function getMarkerGeom(d::Dict)
  shape = d[:markershape]
  gadflyshape(isa(shape, Shape) ? shape : _shapes[shape])
end

function getGadflyMarkerTheme(d::Dict, plotargs::Dict)
  c = getColor(d[:markercolor])
  α = d[:markeralpha]
  if α != nothing
    c = RGBA(RGB(c), α)
  end

  ms = d[:markersize]
  ms = if typeof(ms) <: AVec
    warn("Gadfly doesn't support variable marker sizes... using the average: $(mean(ms))")
    mean(ms) * Gadfly.px
  else
    ms * Gadfly.px
  end

  # fg = getColor(plotargs[:foreground_color])
  Gadfly.Theme(;
      default_color = c,
      default_point_size = ms,
      discrete_highlight_color = c -> RGB(getColor(d[:markerstrokecolor])),
      highlight_width = d[:markerstrokewidth] * Gadfly.px,
      # get_extra_theme_args(d, :markerstrokestyle)...
    )
end

function addGadflyContColorScale(plt::Plot{GadflyPackage}, c)
  if !isa(c, ColorGradient)
    c = colorscheme(:bluesreds)
  end
  push!(getGadflyContext(plt).scales, Gadfly.Scale.ContinuousColorScale(p -> RGB(getColorZ(c, p))))
end

function addGadflyMarker!(plt::Plot, numlayers::Int, d::Dict, plotargs::Dict, geoms...)
  gfargs = vcat(geoms...,
                getGadflyMarkerTheme(d, plotargs),
                getMarkerGeom(d))
  kwargs = Dict()

  # handle continuous color scales for the markers
  zcolor = d[:zcolor]
  if zcolor != nothing && typeof(zcolor) <: AVec
    kwargs[:color] = zcolor
    addGadflyContColorScale(plt, d[:markercolor])
    # if !isa(d[:markercolor], ColorGradient)
    #   d[:markercolor] = colorscheme(:bluesreds)
    # end
    # push!(getGadflyContext(plt).scales, Gadfly.Scale.ContinuousColorScale(p -> RGB(getColorZ(d[:markercolor], p))))
  end

  Gadfly.layer(gfargs...; x = d[:x], y = d[:y], order=numlayers, kwargs...)
end

# ---------------------------------------------------------------------------

function addToGadflyLegend(plt::Plot, d::Dict)

  # add the legend?
  if plt.plotargs[:legend]
    gplt = getGadflyContext(plt)

    # add the legend if needed
    if all(g -> !isa(g, Gadfly.Guide.ManualColorKey), gplt.guides)
      unshift!(gplt.guides, Gadfly.Guide.manual_color_key("", @compat(AbstractString)[], Color[]))
    end

    # now add the series to the legend
    for guide in gplt.guides
      if isa(guide, Gadfly.Guide.ManualColorKey)
        # TODO: there's a BUG in gadfly if you pass in the same color more than once,
        # since gadfly will call unique(colors), but doesn't also merge the rows that match
        # Should ensure from this side that colors which are the same are merged together

        c = getColor(d[d[:markershape] == :none ? :linecolor : :markercolor])
        foundit = false

        # extend the label if we found this color
        for i in 1:length(guide.colors)
          if RGB(c) == guide.colors[i]
            guide.labels[i] *= ", " * d[:label]
            foundit = true
          end
        end

        # didn't find the color, so add a new entry into the legend
        if !foundit
          push!(guide.labels, d[:label])
          push!(guide.colors, c)
        end
      end
    end

  end

end

getGadflySmoothing(smooth::Bool) = smooth ? [Gadfly.Geom.smooth(method=:lm)] : Any[]
getGadflySmoothing(smooth::Real) = [Gadfly.Geom.smooth(method=:loess, smoothing=float(smooth))]

function addGadflySeries!(plt::Plot, d::Dict)

  layers = Gadfly.Layer[]
  gplt = getGadflyContext(plt)

  # add a regression line?
  # TODO: make more flexible
  smooth = getGadflySmoothing(d[:smooth])

  # lines
  geom = getLineGeom(d)
  if geom != nothing
    prepend!(layers, addGadflyLine!(plt, length(gplt.layers), d, geom, smooth...))

    # don't add a regression for markers too
    smooth = Any[]
  end

  # special handling for ohlc and scatter
  lt = d[:linetype]
  if lt == :ohlc
    error("Haven't re-implemented after refactoring")
  elseif lt in (:heatmap, :hexbin) && (isa(d[:linecolor], ColorGradient) || isa(d[:linecolor], ColorFunction))
    push!(gplt.scales, Gadfly.Scale.ContinuousColorScale(p -> RGB(getColorZ(d[:linecolor], p))))
  elseif lt == :scatter && d[:markershape] == :none
    d[:markershape] = :ellipse
  end

  # markers
  if d[:markershape] != :none
    prepend!(layers, addGadflyMarker!(plt, length(gplt.layers), d, plt.plotargs, smooth...))
  end

  lt in (:heatmap, :hexbin, :contour) || addToGadflyLegend(plt, d)

  # now save the layers that apply to this series
  d[:gadflylayers] = layers
  prepend!(gplt.layers, layers)
end

# ---------------------------------------------------------------------------

# NOTE: I'm leaving this here and commented out just in case I want to implement again... it was hacky code to create multi-colored line segments

#   # colorgroup
#   z = d[:z]

#   # handle line segments of different colors
#   cscheme = d[:linecolor]
#   if isa(cscheme, ColorVector)
#     # create a color scale, and set the color group to the index of the color
#     push!(gplt.scales, Gadfly.Scale.color_discrete_manual(cscheme.v...))

#     # this is super weird, but... oh well... for some reason this creates n separate line segments...
#     # create a list of vertices that go: [x1,x2,x2,x3,x3, ... ,xi,xi, ... xn,xn] (same for y)
#     # then the vector passed to the "color" keyword should be a vector: [1,1,2,2,3,3,4,4, ..., i,i, ... , n,n]
#     csindices = Int[mod1(i,length(cscheme.v)) for i in 1:length(d[:y])]
#     cs = collect(repmat(csindices', 2, 1))[1:end-1]
#     grp = collect(repmat((1:length(d[:y]))', 2, 1))[1:end-1]
#     d[:x], d[:y] = map(createSegments, (d[:x], d[:y]))
#     colorgroup = [(:linecolor, cs), (:group, grp)]

# ---------------------------------------------------------------------------

function addGadflyTicksGuide(gplt, ticks, isx::Bool)
  ticks == :auto && return

  # remove the ticks?
  if ticks in (:none, false, nothing)
    return addOrReplace(gplt.guides, isx ? Gadfly.Guide.xticks : Gadfly.Guide.yticks; label=false)
  end

  ttype = ticksType(ticks)

  # just the values... put ticks here, but use standard labels
  if ttype == :ticks
    gtype = isx ? Gadfly.Guide.xticks : Gadfly.Guide.yticks
    replaceType(gplt.guides, gtype(ticks = collect(ticks)))

  # set the ticks and the labels
  elseif ttype == :ticks_and_labels
    gtype = isx ? Gadfly.Guide.xticks : Gadfly.Guide.yticks
    replaceType(gplt.guides, gtype(ticks = collect(ticks[1])))

    # TODO add xtick_label function (given tick, return label??)
    # Scale.x_discrete(; labels=nothing, levels=nothing, order=nothing)
    filterGadflyScale(gplt, isx)
    gfunc = isx ? Gadfly.Scale.x_discrete : Gadfly.Scale.y_discrete
    labelmap = Dict(zip(ticks...))
    labelfunc = val -> labelmap[val]
    push!(gplt.scales, gfunc(levels = ticks[1], labels = labelfunc))

  else
    error("Invalid input for $(isx ? "xticks" : "yticks"): ", ticks)
  end
end

continuousAndSameAxis(scale, isx::Bool) = isa(scale, Gadfly.Scale.ContinuousScale) && scale.vars[1] == (isx ? :x : :y)
filterGadflyScale(gplt, isx::Bool) = filter!(scale -> !continuousAndSameAxis(scale, isx), gplt.scales)

function getGadflyScaleFunction(d::Dict, isx::Bool)
  scalekey = isx ? :xscale : :yscale
  hasScaleKey = haskey(d, scalekey)
  if hasScaleKey
    scale = d[scalekey]
    scale == :ln && return isx ? Gadfly.Scale.x_log : Gadfly.Scale.y_log, hasScaleKey
    scale == :log2 && return isx ? Gadfly.Scale.x_log2 : Gadfly.Scale.y_log2, hasScaleKey
    scale == :log10 && return isx ? Gadfly.Scale.x_log10 : Gadfly.Scale.y_log10, hasScaleKey
    scale == :asinh && return isx ? Gadfly.Scale.x_asinh : Gadfly.Scale.y_asinh, hasScaleKey
    scale == :sqrt && return isx ? Gadfly.Scale.x_sqrt : Gadfly.Scale.y_sqrt, hasScaleKey
  end
  isx ? Gadfly.Scale.x_continuous : Gadfly.Scale.y_continuous, hasScaleKey
end

function addGadflyLimitsScale(gplt, d::Dict, isx::Bool)

  # get the correct scale function
  gfunc, hasScaleKey = getGadflyScaleFunction(d, isx)

  # do we want to add min/max limits for the axis?
  limsym = isx ? :xlims : :ylims
  limargs = Any[]

  # map :auto to nothing, otherwise add to limargs
  lims = get(d, limsym, :auto)
  # lims == :auto && return
  if lims == :auto
    lims = nothing
  else
    if limsType(lims) == :limits
      push!(limargs, (:minvalue, min(lims...)))
      push!(limargs, (:maxvalue, max(lims...)))
    else
      error("Invalid input for $(isx ? "xlims" : "ylims"): ", lims)
    end
  end

  # replace any current scales with this one
  if hasScaleKey || !isempty(limargs)
    filterGadflyScale(gplt, isx)
    push!(gplt.scales, gfunc(; limargs...))
  end

  lims
end

function updateGadflyAxisFlips(gplt, d::Dict, xlims, ylims)
  if isa(gplt.coord, Gadfly.Coord.Cartesian)
    gplt.coord = Gadfly.Coord.cartesian(
        gplt.coord.xvars,
        gplt.coord.yvars;
        xmin = xlims == nothing ? gplt.coord.xmin : minimum(xlims),
        xmax = xlims == nothing ? gplt.coord.xmax : maximum(xlims),
        ymin = ylims == nothing ? gplt.coord.ymin : minimum(ylims),
        ymax = ylims == nothing ? gplt.coord.ymax : maximum(ylims),
        xflip = get(d, :xflip, gplt.coord.xflip),
        yflip = get(d, :yflip, gplt.coord.yflip),
        fixed = gplt.coord.fixed,
        aspect_ratio = gplt.coord.aspect_ratio,
        raster = gplt.coord.raster
      )
  else
    gplt.coord = Gadfly.Coord.Cartesian(
        xflip = get(d, :xflip, false),
        yflip = get(d, :yflip, false)
      )
  end
end

function findGuideAndSet(gplt, t::DataType, args...; kw...) #s::@compat(AbstractString))
  for (i,guide) in enumerate(gplt.guides)
    if isa(guide, t)
      gplt.guides[i] = t(args...; kw...)
    end
  end
end

function updateGadflyGuides(plt::Plot, d::Dict)
  gplt = getGadflyContext(plt)
  haskey(d, :title) && findGuideAndSet(gplt, Gadfly.Guide.title, string(d[:title]))
  haskey(d, :xlabel) && findGuideAndSet(gplt, Gadfly.Guide.xlabel, string(d[:xlabel]))
  haskey(d, :ylabel) && findGuideAndSet(gplt, Gadfly.Guide.ylabel, string(d[:ylabel]))

  xlims = addGadflyLimitsScale(gplt, d, true)
  ylims = addGadflyLimitsScale(gplt, d, false)

  ticks = get(d, :xticks, :auto)
  if ticks == :none
    _remove_axis(plt, true)
  else
    addGadflyTicksGuide(gplt, ticks, true)
  end
  ticks = get(d, :yticks, :auto)
  if ticks == :none
    _remove_axis(plt, false)
  else
    addGadflyTicksGuide(gplt, ticks, false)
  end
  # haskey(d, :yticks) && addGadflyTicksGuide(gplt, d[:yticks], false)

  updateGadflyAxisFlips(gplt, d, xlims, ylims)
end

function updateGadflyPlotTheme(plt::Plot, d::Dict)
  kwargs = Dict()

  # # get the full plotargs, overriding any new settings
  # # TODO: should this be part of the main `plot` command in plot.jl???
  # d = merge!(plt.plotargs, d)

  # hide the legend?
  if !get(d, :legend, true)
    kwargs[:key_position] = :none
  end

  if !get(d, :grid, true)
    kwargs[:grid_color] = getColor(d[:background_color])
  end

  # fonts
  tfont, gfont, lfont = d[:tickfont], d[:guidefont], d[:legendfont]

  fg = getColor(d[:foreground_color])
  getGadflyContext(plt).theme = Gadfly.Theme(;
          background_color = getColor(d[:background_color]),
          minor_label_color = fg,
          minor_label_font = tfont.family,
          minor_label_font_size = tfont.pointsize * Gadfly.pt,
          major_label_color = fg,
          major_label_font = gfont.family,
          major_label_font_size = gfont.pointsize * Gadfly.pt,
          key_title_color = fg,
          key_title_font = gfont.family,
          key_title_font_size = gfont.pointsize * Gadfly.pt,
          key_label_color = fg,
          key_label_font = lfont.family,
          key_label_font_size = lfont.pointsize * Gadfly.pt,
          plot_padding = 1 * Gadfly.mm,
          kwargs...
        )
end

# ----------------------------------------------------------------

function createGadflyAnnotationObject(x, y, val::@compat(AbstractString))
  Gadfly.Guide.annotation(Compose.compose(
                              Compose.context(),
                              Compose.text(x, y, val)
                            ))
end

function createGadflyAnnotationObject(x, y, txt::PlotText)
  halign = (txt.font.halign == :hcenter ? Compose.hcenter : (txt.font.halign == :left ? Compose.hleft : Compose.hright))
  valign = (txt.font.valign == :vcenter ? Compose.vcenter : (txt.font.valign == :top ? Compose.vtop : Compose.vbottom))
  rotations = (txt.font.rotation == 0.0 ? [] : [Compose.Rotation(txt.font.rotation, Compose.Point(Compose.x_measure(x), Compose.y_measure(y)))])
  Gadfly.Guide.annotation(Compose.compose(
                              Compose.context(),
                              Compose.text(x, y, txt.str, halign, valign, rotations...),
                              Compose.font(string(txt.font.family)),
                              Compose.fontsize(txt.font.pointsize * Gadfly.pt),
                              Compose.stroke(txt.font.color),
                              Compose.fill(txt.font.color)
                            ))
end

function _add_annotations{X,Y,V}(plt::Plot{GadflyPackage}, anns::AVec{@compat(Tuple{X,Y,V})})
  for ann in anns
    push!(plt.o.guides, createGadflyAnnotationObject(ann...))
  end
end

# ---------------------------------------------------------------------------

# create a blank Gadfly.Plot object
function _create_plot(pkg::GadflyPackage; kw...)
  d = Dict(kw)
  gplt = createGadflyPlotObject(d)
  Plot(gplt, pkg, 0, d, Dict[])
end

# plot one data series
function _add_series(::GadflyPackage, plt::Plot; kw...)

  # first clear out the temporary layer
  gplt = getGadflyContext(plt)
  if gplt.layers[1].geom.tag == :remove
    gplt.layers = gplt.layers[2:end]
  end

  d = Dict(kw)
  addGadflySeries!(plt, d)
  push!(plt.seriesargs, d)
  plt
end

function _update_plot(plt::Plot{GadflyPackage}, d::Dict)
  updateGadflyGuides(plt, d)
  updateGadflyPlotTheme(plt, d)
end

# ----------------------------------------------------------------

# accessors for x/y data

# TODO: need to save all the layer indices which apply to this series
function getGadflyMappings(plt::Plot, i::Integer)
  @assert i > 0 && i <= plt.n
  mappings = [l.mapping for l in plt.seriesargs[i][:gadflylayers]]
end

function Base.getindex(plt::Plot{GadflyPackage}, i::Integer)
  mapping = getGadflyMappings(plt, i)[1]
  mapping[:x], mapping[:y]
end

function Base.setindex!(plt::Plot{GadflyPackage}, xy::Tuple, i::Integer)
  for mapping in getGadflyMappings(plt, i)
    mapping[:x], mapping[:y] = xy
  end
  plt
end

# ----------------------------------------------------------------

# create the underlying object (each backend will do this differently)
function _create_subplot(subplt::Subplot{GadflyPackage}, isbefore::Bool)
  isbefore && return false # wait until after plotting to create the subplots
  subplt.o = nothing
  true
end

function _remove_axis(plt::Plot{GadflyPackage}, isx::Bool)
  gplt = getGadflyContext(plt)
  addOrReplace(gplt.guides, isx ? Gadfly.Guide.xticks : Gadfly.Guide.yticks; label=false)
  addOrReplace(gplt.guides, isx ? Gadfly.Guide.xlabel : Gadfly.Guide.ylabel, "")
end

function _expand_limits(lims, plt::Plot{GadflyPackage}, isx::Bool)
  for l in getGadflyContext(plt).layers
    _expand_limits(lims, l.mapping[isx ? :x : :y])
  end
end

# ----------------------------------------------------------------

getGadflyContext(plt::Plot{GadflyPackage}) = plt.o
getGadflyContext(subplt::Subplot{GadflyPackage}) = buildGadflySubplotContext(subplt)

# create my Compose.Context grid by hstacking and vstacking the Gadfly.Plot objects
function buildGadflySubplotContext(subplt::Subplot)
  rows = Any[]
  row = Any[]
  for (i,(r,c)) in enumerate(subplt.layout)

    # add the Plot object to the row
    push!(row, getGadflyContext(subplt.plts[i]))

    # add the row
    if c == ncols(subplt.layout, r)
      push!(rows, Gadfly.hstack(row...))
      row = Any[]
    end
  end

  # stack the rows
  Gadfly.vstack(rows...)
end

setGadflyDisplaySize(w,h) = Compose.set_default_graphic_size(w * Compose.px, h * Compose.px)
setGadflyDisplaySize(plt::Plot) = setGadflyDisplaySize(plt.plotargs[:size]...)
setGadflyDisplaySize(subplt::Subplot) = setGadflyDisplaySize(getplotargs(subplt, 1)[:size]...)
# -------------------------------------------------------------------------

function dowritemime{P<:GadflyOrImmerse}(io::IO, func, plt::PlottingObject{P})
  gplt = getGadflyContext(plt)
  setGadflyDisplaySize(plt)
  Gadfly.draw(func(io, Compose.default_graphic_width, Compose.default_graphic_height), gplt)
end

getGadflyWriteFunc(::MIME"image/png") = Gadfly.PNG
getGadflyWriteFunc(::MIME"image/svg+xml") = Gadfly.SVG
# getGadflyWriteFunc(::MIME"text/html") = Gadfly.SVGJS
getGadflyWriteFunc(::MIME"application/pdf") = Gadfly.PDF
getGadflyWriteFunc(::MIME"application/postscript") = Gadfly.PS
getGadflyWriteFunc(::MIME"application/x-tex") = Gadfly.PGF
getGadflyWriteFunc(m::MIME) = error("Unsupported in Gadfly/Immerse: ", m)

for mime in (MIME"image/png", MIME"image/svg+xml", MIME"application/pdf", MIME"application/postscript", MIME"application/x-tex")
  @eval function Base.writemime{P<:GadflyOrImmerse}(io::IO, ::$mime, plt::PlottingObject{P})
    func = getGadflyWriteFunc($mime())
    dowritemime(io, func, plt)
  end
end

function Base.display(::PlotsDisplay, plt::Plot{GadflyPackage})
  setGadflyDisplaySize(plt.plotargs[:size]...)
  display(plt.o)
end

function Base.display(::PlotsDisplay, subplt::Subplot{GadflyPackage})
  setGadflyDisplaySize(getplotargs(subplt,1)[:size]...)
  ctx = buildGadflySubplotContext(subplt)

  # taken from Gadfly since I couldn't figure out how to do it directly

  filename = string(Gadfly.tempname(), ".html")
  output = open(filename, "w")

  plot_output = IOBuffer()
  Gadfly.draw(Gadfly.SVGJS(plot_output, Compose.default_graphic_width,
             Compose.default_graphic_height, false), ctx)
  plotsvg = takebuf_string(plot_output)

  write(output,
      """
      <!DOCTYPE html>
      <html>
        <head>
          <title>Gadfly Plot</title>
          <meta charset="utf-8">
        </head>
          <body>
          <script charset="utf-8">
              $(readall(Compose.snapsvgjs))
          </script>
          <script charset="utf-8">
              $(readall(Gadfly.gadflyjs))
          </script>
          $(plotsvg)
        </body>
      </html>
      """)
  close(output)
  Gadfly.open_file(filename)
end


text:
module SUDS
using SeisIO, SeisIO.Quake
import SeisIO: check_for_gap!, checkbuf!, checkbuf_8!, BUF, KW, sμ
import SeisIO.Formats: formats, FmtVer, FormatDesc, HistVec

include("SUDS/SUDSbuf.jl")
include("SUDS/suds_const.jl")
include("SUDS/suds_structs.jl")
include("SUDS/suds_decode.jl")
include("SUDS/suds_aux.jl")
include("SUDS/read_suds.jl")
include("SUDS/desc.jl")

# exports
export formats, readsudsevt, suds_support
end

ext: jl


text:
import Singular
import AbstractAlgebra

using Groebner

using BenchmarkTools

using Logging
global_logger(ConsoleLogger(stderr, Logging.Error))

function benchmark_system_my(system)
    system = Groebner.change_ordering(system, :degrevlex)
    Groebner.groebner([system[1]])

    gb = Groebner.groebner(system)

    @btime gb = Groebner.groebner($system, reduced=true)
end

function benchmark_system_singular(system)
    R = AbstractAlgebra.parent(system[1])
    modulo = AbstractAlgebra.characteristic(R)
    n = AbstractAlgebra.nvars(R)
    ground_s = Singular.N_ZpField(modulo)
    R_s, _ = Singular.PolynomialRing(ground_s, ["x$i" for i in 1:n], ordering=:degrevlex)

    system_s = map(
        f -> AbstractAlgebra.change_base_ring(
                    ground_s,
                    AbstractAlgebra.map_coefficients(c -> ground_s(c.d), f),
                    parent=R_s),
        system)

    ideal_s = Singular.Ideal(R_s, system_s)

    Singular.std(Singular.Ideal(R_s, [system_s[1]]))

    @btime gb = Singular.std($ideal_s, complete_reduction=true)
end

function run_f4_ff_degrevlex_benchmarks(ground)
    systems = [
        ("cyclic 12", Groebner.rootn(12, ground=ground)),
        ("cyclic 13", Groebner.rootn(13, ground=ground)),
        ("katsura 9",Groebner.katsura9(ground=ground)),
        ("katsura 10",Groebner.katsura10(ground=ground)),
        ("eco 10",Groebner.eco10(ground=ground)),
        ("eco 11",Groebner.eco11(ground=ground)),
        ("noon 7"    ,Groebner.noonn(7, ground=ground)),
        ("noon 8"    ,Groebner.noonn(8, ground=ground))
    ]

    for (name, system) in systems
        println("$name")
        println("my")
        benchmark_system_my(system)
        println("singular")
        benchmark_system_singular(system)
    end
end

ground = AbstractAlgebra.GF(2^31 - 1)
run_f4_ff_degrevlex_benchmarks(ground)

#=

=#


text:
function findMaxThroughput(SubmittedTransactions)
	sm1 = 1000; #%1000: lower part, 5000:middle
	sm2 = 10;
	mslope = 10; #%lower this number sooner it declares a max throughput!

	sTPS = DoSmooth(SubmittedTransactions, sm1);
	#%sTPS = smooth(SubmittedTransactions, sm1);
	#%sTPS = SubmittedTransactions;

	Y,I = localmax(sTPS')
	I = sort(I)
	if length(I) == 0
		tmp = []
	else
		tmp = diff(vec(DoSmooth(I,sm2)))
	end

	ind = -1

	for i=1:length(tmp)
		if tmp[i]<mslope
			ind = i
			break
		end
	end
	if ind == -1 || ind+1 > length(I)
		xMaxThroughput = [];
	else
		xMaxThroughput = I[ind + 1];
	end
	yMaxThroughput = sTPS[xMaxThroughput];
	return xMaxThroughput,yMaxThroughput

end

max_stars_repo_name: barzan/dbseer

max_issues_repo_name: barzan/dbseer

max_forks_repo_name: barzan/dbseer


text:
using DelimitedFiles
using StatsBase

function smartrange(start,stop)
    if(start>stop)
        return start:-1:stop
    end
    return start:1:stop
end
function answer1()
    input = "input"
    po,pf = 0,0
    borderSizex = -1
    borderSizey = -1
    points0 = 0
    for line in readlines(input)
        points = split(line," -> ")
        points = split.(points,",")
        points = map(x->parse.(Int,x), points)
        points = hcat(points...)
        if borderSizex < maximum(view(points,1,:))
            borderSizex = maximum(view(points,1,:))
        end
        if borderSizey < maximum(view(points,2,:))
            borderSizey = maximum(view(points,2,:))
        end
    end
    board = zeros(Int,borderSizex+1,borderSizey+1)
    for line in readlines(input)
        points = split(line," -> ")
        points = split.(points,",")
        points = map(x->parse.(Int,x), points)
        points = hcat(points...)
        points0 = copy(points)
        points = points .+ 1
        if size(unique(view(points,1,:)),1) == 1 #|| size(unique(view(points,2,:)),1) == 1
            # println(view(points,:,1))
            x = view(points,1,:)[1]
            # board[view(points,:,1)] .+= 1
            for y in smartrange(view(points,:,1)[2], view(points,:,2)[2])
                board[x,y] +=1
            end
        end
        if size(unique(view(points,2,:)),1) == 1
            # println(view(points,:,1))
            y = points[2,1]
            # board[view(points,:,1)] .+= 1
            println("x: ", view(points,:,1)[1]-1,"-", view(points,:,2)[1]-1,", y: ",y-1)
            @show points
            for x in smartrange(view(points,:,1)[1], view(points,:,2)[1])
                board[x,y] +=1
            end
        end
    end
    # board
    sum(board .>= 2)
end
# test = answer1()
@show answer1()
# points .-= 1
# sum(test .>= 2)
# show(stdout, "text/plain", test)
function direction(xo,yo,xf,yf)
    dir = [0,0]
    if xf>xo
        dir[1] = 1
    elseif xf<xo
        dir[1] = -1
    end
    if yf>yo
        dir[2] = 1
    elseif yf<yo
        dir[2] = -1
    end
    dir
end
function answer2()
    input = "input"
    po,pf = 0,0
    borderSizex = -1
    borderSizey = -1
    points0 = 0
    for line in readlines(input)
        points = split(line," -> ")
        points = split.(points,",")
        points = map(x->parse.(Int,x), points)
        points = hcat(points...)
        if borderSizex < maximum(view(points,1,:))
            borderSizex = maximum(view(points,1,:))
        end
        if borderSizey < maximum(view(points,2,:))
            borderSizey = maximum(view(points,2,:))
        end
    end
    board = zeros(Int,borderSizex+1,borderSizey+1)
    for line in readlines(input)
        points = split(line," -> ")
        points = split.(points,",")
        points = map(x->parse.(Int,x), points)
        points = hcat(points...)
        points0 = copy(points)
        points = points .+ 1

        x = points[1,1]
        xf = points[1,2]
        y = points[2,1]
        yf = points[2,2]
        dir = direction(x,y,xf,yf)
        while x != xf || y != yf
            board[x,y] +=1
            x += dir[1]
            y += dir[2]
        end
        board[xf,yf] +=1
    end
    # board
    sum(board .>= 2)
end
test = answer2()
show(stdout, "text/plain", test')
sum(test .>= 2)

@show answer2()


text:
"""
    AbstractPoint

Represents a point in space.

The following types are supported:
- `XPoint(x)`
- `YPoint(y)`
- `ZPoint(z)`
- `XYPoint(x, y)`
- `XZPoint(x, z)`
- `XYZPoint(x, y, z)`
- `LatLongPoint(lat, long)`
- `LatLongZPoint(lat, long, z)`
- `Cartesian1Point(x1)`
- `Cartesian2Point(x2)`
- `Cartesian3Point(x3)`
- `Cartesian12Point(x1, x2)`
- `Cartesian13Point(x1, x3)`
- `Cartesian123Point(x1, x2, x3)`
"""
abstract type AbstractPoint{FT} end

"""
    float_type(T)

Return the floating point type backing `T`: `T` can either be an object or a type.
"""
float_type(::Type{<:AbstractPoint{FT}}) where {FT} = FT
float_type(::AbstractPoint{FT}) where {FT} = FT

abstract type Abstract1DPoint{FT} <: AbstractPoint{FT} end
abstract type Abstract2DPoint{FT} <: AbstractPoint{FT} end
abstract type Abstract3DPoint{FT} <: AbstractPoint{FT} end

Base.show(io::IO, point::Abstract1DPoint) =
    print(io, nameof(typeof(point)), "(", component(point, 1), ")")
Base.show(io::IO, point::Abstract2DPoint) = print(
    io,
    nameof(typeof(point)),
    "(",
    component(point, 1),
    ", ",
    component(point, 2),
    ")",
)
Base.show(io::IO, point::Abstract3DPoint) = print(
    io,
    nameof(typeof(point)),
    "(",
    component(point, 1),
    ", ",
    component(point, 2),
    ", ",
    component(point, 3),
    ")",
)

"""
    @pointtype name fieldname1 ...

Define a subtype `name` of `AbstractPoint` with appropriate conversion functions.
"""
macro pointtype(name, fields...)
    if length(fields) == 1
        supertype = :(Abstract1DPoint{FT})
    elseif length(fields) == 2
        supertype = :(Abstract2DPoint{FT})
    elseif length(fields) == 3
        supertype = :(Abstract3DPoint{FT})
    end
    esc(
        quote
            struct $name{FT} <: $supertype
                $([:($field::FT) for field in fields]...)
            end
            Base.convert(::Type{$name{FT}}, pt2::$name) where {FT} =
                $name{FT}($((:(pt2.$field) for field in fields)...))
            $name{FT}(pt::$name) where {FT} = convert($name{FT}, pt)
            Base.eltype(::$name{FT}) where {FT} = FT
            Base.eltype(::Type{$name{FT}}) where {FT} = FT
            unionalltype(::$name{FT}) where {FT} = $name
            unionalltype(::Type{$name{FT}}) where {FT} = $name
            Base.promote_rule(
                ::Type{$name{FT1}},
                ::Type{$name{FT2}},
            ) where {FT1, FT2} = $name{promote_type(FT1, FT2)}
        end,
    )
end

@pointtype XPoint x
@pointtype YPoint y
@pointtype ZPoint z

@pointtype XYPoint x y
@pointtype XZPoint x z
@pointtype YZPoint y z

@pointtype XYZPoint x y z

@pointtype Cartesian1Point x1
@pointtype Cartesian2Point x2
@pointtype Cartesian3Point x3

@pointtype Cartesian12Point x1 x2
@pointtype Cartesian13Point x1 x3
@pointtype Cartesian123Point x1 x2 x3

Cartesian123Point(pt::Cartesian123Point) = pt
Cartesian123Point(pt::Cartesian1Point{FT}) where {FT} =
    Cartesian123Point(pt.x1, zero(FT), zero(FT))
Cartesian123Point(pt::Cartesian2Point{FT}) where {FT} =
    Cartesian123Point(zero(FT), pt.x2, zero(FT))
Cartesian123Point(pt::Cartesian3Point{FT}) where {FT} =
    Cartesian123Point(zero(FT), zero(FT), pt.x3)
Cartesian123Point(pt::Cartesian12Point{FT}) where {FT} =
    Cartesian123Point(pt.x1, pt.x2, zero(FT))
Cartesian123Point(pt::Cartesian13Point{FT}) where {FT} =
    Cartesian123Point(pt.x1, zero(FT), pt.x3)

@pointtype LatLongPoint lat long
@pointtype LatLongZPoint lat long z

product_coordinates(xp::XPoint, yp::YPoint) = XYPoint(promote(xp.x, yp.y)...)
product_coordinates(xp::XPoint, zp::ZPoint) = XZPoint(promote(xp.x, zp.z)...)
product_coordinates(yp::YPoint, zp::ZPoint) = YZPoint(promote(yp.y, zp.z)...)

product_coordinates(xyp::XYPoint, zp::ZPoint) =
    XYZPoint(promote(xyp.x, xyp.y, zp.z)...)

product_coordinates(latlongp::LatLongPoint, zp::ZPoint) =
    LatLongZPoint(promote(latlongp.lat, latlongp.long, zp.z)...)

component(p::AbstractPoint{FT}, i::Symbol) where {FT} = getfield(p, i)::FT
component(p::AbstractPoint{FT}, i::Integer) where {FT} = getfield(p, i)::FT

ncomponents(p::AbstractPoint) = nfields(p)
components(p::AbstractPoint) =
    SVector(ntuple(i -> component(p, i), ncomponents(p)))

_coordinate_type(ptyp::Type{Abstract1DPoint}, ::Val{1}) = ptyp
_coordinate(p::Abstract1DPoint, ::Val{1}) = p

_coordinate_type(::Type{XYPoint{FT}}, ::Val{1}) where {FT} = XPoint{FT}
_coordinate_type(::Type{XYPoint{FT}}, ::Val{2}) where {FT} = YPoint{FT}
_coordinate(p::XYPoint, ::Val{1}) = XPoint(p.x)
_coordinate(p::XYPoint, ::Val{2}) = YPoint(p.y)

_coordinate_type(::Type{XZPoint{FT}}, ::Val{1}) where {FT} = XPoint{FT}
_coordinate_type(::Type{XZPoint{FT}}, ::Val{2}) where {FT} = ZPoint{FT}
_coordinate(p::XZPoint, ::Val{1}) = XPoint(p.x)
_coordinate(p::XZPoint, ::Val{2}) = ZPoint(p.z)

_coordinate_type(::Type{YZPoint{FT}}, ::Val{1}) where {FT} = YPoint{FT}
_coordinate_type(::Type{YZPoint{FT}}, ::Val{2}) where {FT} = ZPoint{FT}
_coordinate(p::YZPoint, ::Val{1}) = YPoint(p.x)
_coordinate(p::YZPoint, ::Val{2}) = ZPoint(p.z)

_coordinate_type(::Type{XYZPoint{FT}}, ::Val{1}) where {FT} = XPoint{FT}
_coordinate_type(::Type{XYZPoint{FT}}, ::Val{2}) where {FT} = YPoint{FT}
_coordinate_type(::Type{XYZPoint{FT}}, ::Val{3}) where {FT} = ZPoint{FT}
_coordinate(p::XYZPoint, ::Val{1}) = XPoint(p.x)
_coordinate(p::XYZPoint, ::Val{2}) = YPoint(p.y)
_coordinate(p::XYZPoint, ::Val{3}) = ZPoint(p.z)

coordinate_type(ptyp::Type{<:AbstractPoint}, ax::Int) =
    _coordinate_type(ptyp, Val(ax))
coordinate_type(ptyp::Type{<:AbstractPoint}, ax::Integer) =
    _coordinate_type(ptyp, Int(ax))

coordinate(pt::AbstractPoint, ax::Int) = _coordinate(pt, Val(ax))
coordinate(pt::AbstractPoint, ax::Integer) = _coordinate(pt, Int(ax))

# TODO: we need to rationalize point operations with vectors
#Base.:(-)(p1::T, p2::T) where {T <: AbstractPoint} =
#    unionalltype(T)((components(p1) - components(p2))...)

# the following are needed for linranges to work correctly with coordinate values
Base.:(+)(p1::T, p2::T) where {T <: AbstractPoint} =
    unionalltype(T)((components(p1) + components(p2))...)
Base.:(*)(p::T, x::Number) where {T <: AbstractPoint} =
    unionalltype(T)((components(p) * x)...)
Base.:(*)(x::Number, p::AbstractPoint) = p * x
Base.:(/)(p::T, x::Number) where {T <: AbstractPoint} =
    unionalltype(T)((components(p) / x)...)

# we add our own method to this so that `BigFloat` coordinate ranges are computed accurately.
function Base.lerpi(
    j::Integer,
    d::Integer,
    a::T,
    b::T,
) where {T <: Abstract1DPoint}
    T(Base.lerpi(j, d, component(a, 1), component(b, 1)))
end
function Base.:(==)(p1::T, p2::T) where {T <: AbstractPoint}
    return components(p1) == components(p2)
end

function Base.isapprox(p1::T, p2::T; kwargs...) where {T <: AbstractPoint}
    return isapprox(components(p1), components(p2); kwargs...)
end
Base.isless(x::T, y::T) where {T <: Abstract1DPoint} =
    isless(component(x, 1), component(y, 1))

"""
    bilinear_interpolate(coords::NTuple{4}, ξ1, ξ2)

Bilinear interpolate between `coords` by parameters `ξ1, ξ2`, each in the interval `[-1,1]`.

`coords` should be a 4-tuple of coordinates in counter-clockwise order.

```
      4-------3
 ^    |       |
 |    |       |
ξ2    |       |
      1-------2

        ξ1-->
```
"""
function bilinear_interpolate(coords::NTuple{4, V}, ξ1, ξ2) where {V <: SVector}
    w1 = (1 - ξ1) * (1 - ξ2) / 4
    w2 = (1 + ξ1) * (1 - ξ2) / 4
    w3 = (1 + ξ1) * (1 + ξ2) / 4
    w4 = (1 - ξ1) * (1 + ξ2) / 4
    w1 .* coords[1] .+ w2 .* coords[2] .+ w3 .* coords[3] .+ w4 .* coords[4]
end

function bilinear_interpolate(
    coords::NTuple{4, V},
    ξ1,
    ξ2,
) where {V <: AbstractPoint}
    VV = unionalltype(V)
    c = bilinear_interpolate(map(components, coords), ξ1, ξ2)
    VV(c...)
end

"""
    interpolate(coords::NTuple{2}, ξ1)

Interpolate between `coords` by parameters `ξ1` in the interval `[-1,1]`.
The type of interpolation is determined by the element type of `coords`
"""
function linear_interpolate(
    coords::NTuple{2, V},
    ξ1,
) where {V <: Abstract1DPoint}
    VV = unionalltype(V)
    VV(
        (1 - ξ1) / 2 * component(coords[1], 1) +
        (1 + ξ1) / 2 * component(coords[2], 1),
    )
end

function spherical_bilinear_interpolate((x1, x2, x3, x4), ξ1, ξ2, radius)
    x = bilinear_interpolate((x1, x2, x3, x4), ξ1, ξ2)
    return x * (radius / norm(components(x)))
end


text:
using MTKHelpers
using Test

using DifferentialEquations, ModelingToolkit
using StaticArrays, LabelledArrays
using ForwardDiff
using NamedArrays
#push!(LOAD_PATH, expanduser("~/julia/turingtools/")) # access local package repo
using AxisArrays

#include("test/samplesystem.jl")
include("samplesystem.jl")

@testset "ProblemParSetter" begin
    include("test_problemparsetter.jl")
end

@testset "utilities" begin
    include("test_utils.jl")
end

@testset "smoothstep" begin
    include("test_smoothstep.jl")
end

@testset "cairomakie" begin
    include("test_cairomakie.jl")
end

@testset "solution" begin
    include("test_solution.jl")
end

max_stars_repo_name: bgctw/MTKHelpers

max_issues_repo_name: bgctw/MTKHelpers

max_forks_repo_name: bgctw/MTKHelpers


text:
module PointerStructs

using Static, UnPack, CloseOpenIntervals
using Static: Zero, One
using UnPack: unpack, pack!

export @pointer, @unpack, @pack!, static

include("ptrarrays.jl")
include("structmacro.jl")

end


text:
using SRCWA,Test

@testset "reflection" begin

    n1=rand()*10
    n2=rand()*10
nx,ny,dnx,dny=grid_n(0,0)
lambda=1000
theta=1E-30
phi=0
k0,Kx,Ky,kin=grid_k(nx,ny,theta,phi,lambda,100,100,n1^2)
upper=halfspace(Kx,Ky,n1^2)
lower=halfspace(Kx,Ky,n2^2)
V0,Kz0=modes_freespace(Kx,Ky)
Su=matrix_ref(upper,V0)
Sl=matrix_tra(lower,V0)
S=concatenate(Su,Sl)
a0te,a0tm=prepare_source(kin,upper.W,0,0)
cref=S.S11*a0tm#+a0tm
ctra=S.S21*a0tm
R=a2p(cref,upper,Kx,Ky,kin[3])
T=a2p(ctra,lower,Kx,Ky,kin[3])

    @test abs(((n1-n2)/(n1+n2))^2-R)<1E-6
    @test abs(1-((n1-n2)/(n1+n2))^2-T)<1E-6
end


text:
module ContentHashes

# Imports:

import Serialization
import SHA

# Public interface:

"""
    hash(object, [seed])::SHA1

Return a `SHA1` hash of the *contents* of `object`, with an optional `seed`.

!!! warn

    This `hash` implementation is *much slower* that the default `Base.hash`
    provided for `object` and as such should only be used when a hash of the exact
    contents of an object is actually required.
"""
@noinline function hash(@nospecialize(object), seed::Integer = zero(UInt))
    ctx = SHA.SHA1_CTX()
    SHA.update!(ctx, reinterpret(UInt8, [convert(UInt, seed)]))
    Serialization.serialize(CustomSerializer{HashContext}(HashContext(ctx)), object)
    return Base.SHA1(SHA.digest!(ctx))
end

# Implementation:

# A special type of IO that is actually a hash accumulator for use in the
# Serialization implementation found below.
struct HashContext <: IO
    ctx::SHA.SHA1_CTX
end

function Base.unsafe_write(io::HashContext, ptr::Ptr{UInt8}, nb::UInt)
    for _ in 1:nb
        SHA.update!(io.ctx, (unsafe_load(ptr),))
        ptr += 1
    end
    return nb
end
Base.write(io::HashContext, u::UInt8) = SHA.update!(io.ctx, (u,))

# The custom serializer used to produce a hash of an object by traversing it in
# the same way the Julia's Serialization would do, but outputting only a
# singular hash value rather than serialized data.
mutable struct CustomSerializer{I<:IO} <: Serialization.AbstractSerializer
    io::I
    counter::Int
    table::IdDict{Any,Any}
    pending_refs::Vector{Int}
    known_object_data::Dict{UInt64,Any}
    CustomSerializer{I}(io::I) where I<:IO = new(io, 0, IdDict(), Int[], Dict{UInt64,Any}())
end

function Serialization.serialize(cs::CustomSerializer, tn::Core.TypeName)
    if !Serialization.serialize_cycle(cs, tn)
        if startswith(String(tn.name), '#')
            obj = getfield(tn.module, tn.name)
            if isdefined(obj, :instance)
                for ci in code_lowered(obj.instance)
                    Serialization.serialize(cs, ci.code)
                end
                return nothing
            end
        end
        Serialization.writetag(cs.io, Serialization.TYPENAME_TAG)
        Serialization.write(cs.io, Serialization.object_number(cs, tn))
        Serialization.serialize_typename(cs, tn)
    end
    return nothing
end

# Drop line number information.
Serialization.serialize(::CustomSerializer, ::Core.LineInfoNode) = nothing
Serialization.serialize(::CustomSerializer, ::LineNumberNode) = nothing

# Remove gensym counter information.
function Serialization.serialize(cs::CustomSerializer, s::Symbol)
    str = String(s)
    s = contains(str, '#') ? Symbol(rstrip(isdigit, str)) : s # Global counter isn't needed for hashing here.
    return invoke(Serialization.serialize, Tuple{Serialization.AbstractSerializer, Symbol}, cs, s)
end
function Serialization.serialize(cs::CustomSerializer, s::Module)
    is_pluto_workspace = isdefined(s, :PlutoRunner) && isa(s.PlutoRunner, Module)
    s = is_pluto_workspace ? Main : s # Emulate `Main` in REPLS, roughly equivalent to Pluto workspace.
    return invoke(Serialization.serialize, Tuple{Serialization.AbstractSerializer, Module}, cs, s)
end
function Serialization.serialize(cs::CustomSerializer, a::A) where A<:Array
    if !Serialization.serialize_cycle(cs, a)
        Serialization.serialize(cs, A)
        for I in eachindex(a)
            Serialization.serialize(cs, isassigned(a, I) ? a[I] : undef)
        end
    end
    return nothing
end

end


text:
using PowerModels
using .PP2PM

import Cbc
import Ipopt
import Juniper
import JuMP

function run_powermodels(json_path)
    # function to run transmission network expansion optimization of powermodels.jl
    pm = PP2PM.load_pm_from_json(json_path)

    cbc_solver = JuMP.with_optimizer(Cbc.Optimizer, logLevel = 1)
    juniper_solver = JuMP.with_optimizer(Juniper.Optimizer,
    nl_solver = JuMP.with_optimizer(Ipopt.Optimizer, tol = 1e-6, print_level = 0),
                                    mip_solver = cbc_solver, log_levels = [])

    result = run_tnep(pm, ACPPowerModel, juniper_solver,
                        setting = Dict("output" => Dict("branch_flows" => true)))
    return result
end

max_stars_repo_name: Zamwell/pandapower

max_issues_repo_name: Zamwell/pandapower

max_forks_repo_name: Zamwell/pandapower


text:
using Pkg, Test

using CLIMA.TurbulenceConvection.FiniteDifferenceGrids
using CLIMA.TurbulenceConvection.StateVecs
using CLIMA.TurbulenceConvection.TriDiagSolvers

@static if haskey(Pkg.installed(), "Plots")
  using Plots
  export_plots = true
else
  export_plots = false
end

output_root = joinpath("output", "tests", "PDEs")

include("HeatEquation.jl")
include("AdvectionEquation.jl")

max_stars_repo_name: akshaysridhar/CLIMA

max_issues_repo_name: akshaysridhar/CLIMA

max_forks_repo_name: akshaysridhar/CLIMA


text:
"""
Modify an array by changing its element type on the fly to `T`, without changing
the storage of the underlying array.

Standard errors are thrown if conversion to or from `T` is not successful when
using `getindex` and `setindex!`.
"""
struct EltypeMod{T} <: ArrayModifier
end

ModStyle(::EltypeMod, ::Interface) = ModNothing()
ModStyle(::Type{<:EltypeMod}, ::IF_IndexStyle) = ModNothing()

ModStyle(::EltypeMod, ::IF_eltype) = ModFinal()
mod_eltype_final(::EltypeMod{T}) where {T} = T

ModStyle(::EltypeMod, ::IF_getindex) = ModRecursive()
mod_getindex_post(mod::EltypeMod{T}, Z, I...) where {T} = convert(T, Z)


text:
using SimJulia
using ResumableFunctions

@resumable function fibonnaci(sim::Simulation)
  a = 0
  b = 1
  while true
    println(a)
    @yield timeout(sim, 1)
    a, b = b, a+b
  end
end

@resumable function test_process(sim::Simulation, ev::AbstractEvent)
  @yield ev
end

@resumable function test_process_exception(sim::Simulation, ev::AbstractEvent)
  try
    value = @yield ev
  catch exc
    println("$exc has been thrown")
  end
end

@resumable function test_interrupter(sim::Simulation, proc::Process)
  @yield timeout(sim, 2)
  @yield interrupt(proc)
end

@resumable function test_interrupted(sim::Simulation)
  try
    @yield timeout(sim, 10)
  catch exc
    if isa(exc, SimJulia.InterruptException)
      println("$(active_process(sim)) interrupted")
    end
  end
  @yield timeout(sim, 10)
  throw(TestException())
end

sim = Simulation()
@process fibonnaci(sim)
println(sim)
run(sim, 10)

sim = Simulation()
@process test_process(sim, succeed(Event(sim)))
run(sim)

sim = Simulation()
@process test_process_exception(sim, timeout(sim, 1, value=TestException()))
try
  run(sim)
catch exc
  println("$exc has been thrown")
end

sim = Simulation()
@process test_process_exception(sim, timeout(sim, value=TestException()))
run(sim)

sim = Simulation()
proc = @process test_interrupted(sim)
@process test_interrupter(sim, proc)
try
  run(sim)
catch exc
  println("$exc has been thrown")
end


text:
const _package_version = Base.VersionNumber(
    TOML.parsefile(joinpath(dirname(@__DIR__), "Project.toml"))["version"]
)

function _initialize_download_cache()
    folder_name = "downloaded_files-$(_package_version)"
    global download_cache = Scratch.get_scratch!(@__MODULE__, folder_name)
    return nothing
end

function __init__()
    _initialize_download_cache()
    return nothing
end


text:
abstract type ConfIntMethod end

const _level = 0.95

"""
Basic Confidence Interval

```julia
BasicConfInt(0.95)
```

"""
struct BasicConfInt <: ConfIntMethod
    level::AbstractFloat
end

BasicConfInt() = BasicConfInt(_level)

"""
Percentile Confidence Interval

```julia
PercentileConfInt(0.95)
```

"""
struct PercentileConfInt <: ConfIntMethod
    level::AbstractFloat
end

PercentileConfInt() = PercentileConfInt(_level)

struct NormalConfInt <: ConfIntMethod
    level::AbstractFloat
end

"""
Normal Confidence Interval

```julia
NormalConfInt(0.95)
```

"""
NormalConfInt() = NormalConfInt(_level)

struct BCaConfInt <: ConfIntMethod
    level::AbstractFloat
    ## quantile method
end

"""
Bias-Corrected and Accelerated (BCa) Confidence Interval

```julia
BCaConfInt(0.95)
```

"""
BCaConfInt() = BCaConfInt(_level)

struct StudentConfInt <: ConfIntMethod
    level::AbstractFloat
end

"""
Student's Confidence Interval

```julia
StudentConfInt(0.95)
```

"""
StudentConfInt() = StudentConfInt(_level)

level(cim::ConfIntMethod) = cim.level

function confint(bs::BootstrapSample, cim::ConfIntMethod)
    tuple([confint(bs, cim, i) for i in 1:nvar(bs)]...)
end

## basic
function confint(bs::BootstrapSample, cim::BasicConfInt, i::Int)
    l = level(cim)
    t0 = original(bs, i)
    t1 = straps(bs, i)
    alpha = ([l, -l] .+ 1) ./ 2
    lower, upper = 2 .* t0 .- quantile(t1, alpha)
    return t0, lower, upper
end

## percentile
function confint(bs::BootstrapSample, cim::PercentileConfInt, i::Int)
    l = level(cim)
    t0 = original(bs, i)
    t1 = straps(bs, i)
    alpha = ([-l, l] .+ 1) ./ 2
    lower, upper = quantile(t1, alpha)
    return t0, lower, upper
end

## normal
function confint(bs::BootstrapSample, cim::NormalConfInt, i::Int)
    l = level(cim)
    t0 = original(bs, i)
    t0b = t0 - bias(bs, i)
    merr = stderror(bs, i) * quantile(Normal(), (1 + l) / 2)
    lower = t0b - merr
    upper = t0b + merr
    return t0, lower, upper
end

## BCa
function confint(bs::BootstrapSample, cim::BCaConfInt, i::Int)
    l = level(cim)
    t0 = original(bs, i)
    t1 = straps(bs, i)

    var(t1) == 0.0 && return (t0, t0, t0)

    n = length(t1)
    alpha = ([-l, l] .+ 1) ./ 2
    z0 = quantile(Normal(), mean(t1 .< t0))
    jkt = jack_knife_estimate(data(bs), statistic(bs), i)
    resid = (t0 .- jkt) .* (n - 1)
    a = sum(resid .^ 3) / (6 .* (sum(resid.^2)) .^ (1.5)) # TODO
    qn = quantile.(Ref(Normal()), alpha)
    z1 = z0 .+ qn
    zalpha = cdf.(Ref(Normal()), z0 .+ z1 ./ (1 .- a .* z1)) # TODO
    lower, upper = quantile(t1, zalpha)
    return t0, lower, upper
end

## student
function confint(bs::BootstrapSample, sd1::AbstractVector{Float64}, cim::StudentConfInt, i::Int)
    l = level(cim)
    t0 = original(bs, i)
    t1 = straps(bs, i)
    t0se = stderror(bs, i)
    z = (t1 .- t0) ./ sd1
    alpha = ([l, -l] .+ 1) ./ 2
    lower, upper = t0 .- t0se .* quantile(z, alpha)
    return t0, lower, upper
end


text:
"""
    Repo{T}(N::Int,C::Int)

Create a repository that organizes N elements of type T into C classes.

# Example
```jldoctest
julia> using Repos

julia> r=Repo{String}(50000,4)
Repository of 50000 objects in 4 classes
```
"""
function Repo{T}(N::Int,C::Int) where {T}
    starts=Array{Int,1}(undef,C)
    counts=Array{Int,1}(undef,C)
    ids=[1:N...]
    pos=[1:N...]
    cargo=Array{T,1}(undef,N)
    counts.=0
    starts.=N+1
    counts.=0
    counts[1]=N
    starts[1]=1
    return Repo{T}(starts,counts,ids,pos,cargo,N,C)
end

"""
    Repo(a::Array,C::Int)

Create a repository that organizes an existing array into C classes.

The repository will not copy the array, so the memory is only allocated once
and any changes you make in the array will be reflected in the repository.

# Example
```jldoctest
julia> using Repos

julia> a=["red","green","blue"];

julia> r=Repo(a,2)
Repository of 3 objects in 2 classes

julia> a[1]="cyan";

julia> print_repo(r)
Repository of 2 classes
  Class 1
    1 - 1: cyan
    2 - 2: green
    3 - 3: blue
  Class 2
```
"""
function Repo(a::Array{T,1},C::Int) where T
    starts=Array{Int,1}(undef,C)
    counts=Array{Int,1}(undef,C)
    N=length(a)
    ids::Array{Int,1}=[1:N...]
    pos::Array{Int,1}=[1:N...]
    cargo=a
    counts.=0
    starts.=N+1
    counts.=0
    counts[1]=N
    starts[1]=1
    return Repo{T}(starts,counts,ids,pos,cargo,N,C)
end


text:
"""
BulkAndTailsDist(κ₀,τ₀,ϕ₀,κ₁,τ₁,ϕ₁,ν)
The *Bulk-And-Tails (BATs) distribution* has cumulative distribution function
```math
F(x) = T_ν(H(x))
```
where T_ν is the student-t cdf with ν degrees of freedom and H is a monotone increasing function.
ϕ₀ and ϕ₁ are location parameters for the lower and upper tails.
τ₀ and τ₁ are scale parameters for the lower and upper tails.
κ₀ and κ₁ are shape parameters for the lower and upper tails.
Negative κ indicates a bounded tail. Positive κ indicates a heavy tail.
The case κ=0, defined by continuity, indicates a thin Gaussian tail.

`fitbats` provides maximum likelihood estimation for these parameters. In addition, we provide
`pdf`, `cdf`, `logpdf`, `logcdf`, `quantile`, and `rand` functions for `BulkAndTailsDist`, all of which follow the
`Distributions.jl` framework. We also provide R-friendly versions of these functions and show how to call them from R.

```julia
BulkAndTailsDist(κ₀,τ₀,ϕ₀,κ₁,τ₁,ϕ₁,ν)     # BATs distribution
params(d)        # Get the parameters
minimum(d)       # lower bound of support
maximum(d)       # upper bound of support
```
External links
* [Stein, M. L. (2021).  A parametric model for distributions with flexible behavior in both tails. Environmetrics, 32(2):Paper No. e2658, 24.](https://onlinelibrary.wiley.com/doi/abs/10.1002/env.2658)
"""
struct BulkAndTailsDist{T<:Real} <: ContinuousUnivariateDistribution
κ₀::T
τ₀::T
ϕ₀::T
κ₁::T
τ₁::T
ϕ₁::T
ν::T
end

Distributions.params(d::BulkAndTailsDist) = (d.κ₀,d.τ₀,d.ϕ₀,d.κ₁,d.τ₁,d.ϕ₁,d.ν)
Distributions.minimum(d::BulkAndTailsDist) = (d.κ₀ ≥ 0.0 ? -Inf : d.ϕ₀ - d.τ₀*iΨ(-1.0/d.κ₀))
Distributions.maximum(d::BulkAndTailsDist) = (d.κ₁ ≥ 0.0 ? Inf : d.ϕ₁ + d.τ₁*iΨ(-1.0/d.κ₁))

BulkAndTailsDist(κ₀::Real,τ₀::Real,ϕ₀::Real,κ₁::Real,τ₁::Real,ϕ₁::Real,ν::Real) = BulkAndTailsDist(promote(κ₀,τ₀,ϕ₀,κ₁,τ₁,ϕ₁,ν)...)

function BulkAndTailsDist(xv)
    @assert length(xv) == 7 "Please provide 7 arguments."
    BulkAndTailsDist(xv...)
end


text:
const _vt = (
    VolumeAmount{MOLAR,VOLUME}(),
    Temperature(),
    SingleComponent())

const _vtx = (
    VolumeAmount{MOLAR,VOLUME}(),
    Temperature(),
    MaterialCompounds{MOLAR,FRACTION}())

function ∂a∂v(mt::SingleVT,model::HelmholtzModel,v,t)
    return ForwardDiff.derivative(dv->mol_helmholtz_impl(mt,model,dv,t),v)
    #return ForwardDiff.derivative(dv->mol_helmholtzR_impl(mt,model,dv,t),v) -RGAS*t/v
end

function ∂a∂v(mt::MultiVT,model::HelmholtzModel,v,t,x)
    return ForwardDiff.derivative(dv->mol_helmholtz_impl(mt,model,dv,t,x),v)
end

function ∂²a∂v²(mt::SingleVT,model::HelmholtzModel,v,t)
    return ForwardDiff.derivative(dv->∂a∂v(mt,model,dv,t),v)
    #return ForwardDiff.derivative(dv->mol_helmholtzR_impl(mt,model,dv,t),v) -RGAS*t/v
end

function ∂²a∂v²(mt::MultiVT,model::HelmholtzModel,v,t,x)
    return ForwardDiff.derivative(dv->∂a∂v(mt,model,dv,t,x),v)
end

function ∂a∂t(mt::SingleVT,model::HelmholtzModel,v,t)
    return ForwardDiff.derivative(dt->mol_helmholtz_impl(mt,model,v,dt),t)
end

function ∂a∂t(mt::MultiVT,model::HelmholtzModel,v,t,x)
    return ForwardDiff.derivative(dt->mol_helmholtz_impl(mt,model,v,dt,x),t)
end

function ∂a(mt::SingleVT,model::HelmholtzModel,v,t)
    a(x) = mol_helmholtz_impl(mt,model,first(x),last(x))
    T = promote_type(typeof(v),typeof(t))
    _v = T(v)
    _t = T(t)
    vt_vec =   SVector(_v,_t)
    ∂result = DiffResults.GradientResult(vt_vec)
    _∂a =  ForwardDiff.gradient!(∂result, a,vt_vec)
    val_a =  DiffResults.value(_∂a)
    val_∂a = DiffResults.gradient(_∂a)
    return (val_∂a,val_a)
end

function ∂a(mt::MultiVT,model::HelmholtzModel,v,t,x)
    a(z) = mol_helmholtz_impl(mt,model,first(z),last(z),x)
    T = promote_type(typeof(v),typeof(t))
    _v = T(v)
    _t = T(t)
    vt_vec =   SVector(_v,_t)
    ∂result = DiffResults.GradientResult(vt_vec)
    _∂a =  ForwardDiff.gradient!(∂result, a,vt_vec)
    val_a =  DiffResults.value(_∂a)
    val_∂a = DiffResults.gradient(_∂a)
    return (val_∂a,val_a)
end

function pressure_impl(mt::SingleVT,model::T,v,t) where T<: HelmholtzModel
    rho = one(v)/v
    dαdrho = ForwardDiff.derivative(drho->αR_impl(mt,model,drho,t),inv(v))
    return rho*(one(rho)+rho*dαdrho)*RGAS*t
end

function pressure_impl(mt::MultiVT,model::T,v,t,x) where T<: HelmholtzModel
    ρ = one(v)/v
    dαdρ = ForwardDiff.derivative(∂ρ->αR_impl(mt,model,∂ρ,t,x),inv(v))
    return ρ*(one(ρ)+ρ*dαdρ)*RGAS*t
end

function compressibility_factor_impl(mt::SingleVT,model::HelmholtzModel,v,t)
    p = pressure_impl(mt,model,v,t)
    return p*v/(RGAS*t)
end

function compressibility_factor_impl(mt::MultiVT,model::HelmholtzModel,v,t,x)
    p = pressure_impl(mt,model,v,t,x)
    return p*v/(RGAS*t)
end

function mol_entropy_impl(mt::SingleVT,model::HelmholtzModel,v,t)
    return -∂a∂t(mt,model,v,t)
end

function mol_entropy_impl(mt::MultiVT,model::HelmholtzModel,v,t,x)
    return -∂a∂t(mt,model,v,t,x)
end

function mol_enthalpy_impl(mt::SingleVT,model::HelmholtzModel,v,t)
    _da,aa =  ∂a(mt,model,v,t)
    _dv,_dt = _da
    return aa - _dv*v - _dt*t
end

function dpdt(mt::SingleVT,model::HelmholtzModel,v,t)
    p(z) = pressure_impl(mt,model,v,z)
    return ForwardDiff.derivative(p,t)
end

function mol_enthalpy_impl(mt::MultiVT,model::HelmholtzModel,v,t,x)
    _dv,_dt,aa =  ∂a(mt,model,v,t,x)
    return aa - _dv*v - dt*t
end

function mol_internal_energy_impl(mt::SingleVT,model::HelmholtzModel,v,t)
    _da,aa =  ∂a(mt,model,v,t)
    _dv,_dt = _da
    return aa  - dt*t
end

function mol_internal_energy_impl(mt::MultiVT,model::HelmholtzModel,v,t,x)
    _da,aa =  ∂a(mt,model,v,t,x)
    _dv,_dt = _da
    return aa  - dt*t
end

function mol_gibbs_impl(mt::SingleVT,model::HelmholtzModel,v,t)
    _da,aa =  ∂a(mt,model,v,t)
    _dv,_dt = _da
    return aa - _dv*v
end

function mol_gibbs_impl(mt::MultiVT,model::HelmholtzModel,v,t,x)
    _da,aa =  ∂a(mt,model,v,t,x)
    _dv,_dt = _da
    return aa - _dv*v
end

function ∂2a(mt::SingleVT,model::HelmholtzModel,v,t)
    a(x) = mol_helmholtz_impl(mt,model,first(x),last(x))
    T = promote_type(typeof(v),typeof(t))
    _v = T(v)
    _t = T(t)
    vt_vec =   SVector(_v,_t)
    ∂result = DiffResults.HessianResult(vt_vec)
    _∂a =  ForwardDiff.hessian!(∂result, a,vt_vec)
    val_a =  DiffResults.value(_∂a)
    val_∂a = DiffResults.gradient(_∂a)
    val_∂2a = DiffResults.hessian(_∂a)
    return (val_∂2a,val_∂a,val_a)
end

function ∂2a(mt::MultiVT,model::HelmholtzModel,v,t,x)
    a(z) = mol_helmholtz_impl(mt,model,first(z),last(z),x)
    T = promote_type(typeof(v),typeof(t))
    _v = T(v)
    _t = T(t)
    vt_vec =   SVector(_v,_t)
    ∂result = DiffResults.HessianResult(vt_vec)
    _∂a =  ForwardDiff.hessian!(∂result, a,vt_vec)
    val_a =  DiffResults.value(_∂a)
    val_∂a = DiffResults.gradient(_∂a)
    val_∂2a = DiffResults.hessian(_∂a)
    return (val_∂2a,val_∂a,val_a)
end

function ∂2∂a2(mt::SingleVT,model::HelmholtzModel,v,t)
    a(x) = mol_helmholtz_impl(mt,model,first(x),last(x))
    T = promote_type(typeof(v),typeof(t))
    _v = T(v)
    _t = T(t)
    vt_vec =   SVector(_v,_t)
    return  ForwardDiff.hessian(a,vt_vec)
end

function ∂2∂a2(mt::MultiVT,model::HelmholtzModel,v,t,z)
    a(x) = mol_helmholtz_impl(mt,model,first(x),last(x),z)
    T = promote_type(typeof(v),typeof(t))
    _v = T(v)
    _t = T(t)
    vt_vec = SVector(_v,_t)
    return ForwardDiff.hessian(a,vt_vec)
end

function ∂p∂v(mt::SingleVT,model::HelmholtzModel,v,t)
return ForwardDiff.derivative(z->pressure_impl(mt,model,z,t),v)
end

function mol_isochoric_heat_capacity_impl(mt::SingleVT,model::HelmholtzModel,v,t)
    ∂2a = ∂2∂a2(mt,model,v,t)
    return -t*∂2a[2,2]
end

function mol_isochoric_heat_capacity_impl(mt::MultiVT,model::HelmholtzModel,v,t,x)
    ∂2a = ∂2∂a2(mt,model,v,t,x)
    return -t*∂2a[2,2]
end

function mol_isobaric_heat_capacity_impl(mt::SingleVT,model::HelmholtzModel,v,t)
    ∂2a = ∂2∂a2(mt,model,v,t)
    return t*(∂2a[1,2]^2/∂2a[1]-∂2a[2,2])
end

function mol_isobaric_heat_capacity_impl(mt::MultiVT,model::HelmholtzModel,v,t,x)
    ∂2a = ∂2∂a2(mt,model,v,t,x)
    return t*(∂2a[1,2]^2/∂2a[1]-∂2a[2,2])
end

function sound_speed_impl(mt::SingleVT,model::HelmholtzModel,v,t)
    ∂2a = ∂2∂a2(mt,model,v,t)
    Mr = molecular_weight(model)
    z = ThermoState.mw_div(one(MW),MW)
    return v*sqrt((∂2a[1]-∂2a[1,2]^2/∂2a[2,2])/Mr)
end

function sound_speed_impl(mt::MultiVT,model::HelmholtzModel,v,t,x)
    ∂2a = ∂2∂a2(mt,model,v,t,x)
    _MW = molecular_weight(model)
    Mr = mapreduce(ThermoState.mw_mul,+,x,_MW)
    return v*sqrt((∂2a[1]-∂2a[1,2]^2/∂2a[2,2])/Mr)
end

function isothermal_compressibility_impl(mt::SingleVT,model::HelmholtzModel,v,t)
    d2f = ∂²a∂v²(mt,model,v,t)
    return 1/v*d2f^-1
end

function isothermal_compressibility_impl(mt::MultiVT,model::HelmholtzModel,v,t,x)
    d2f = ∂²a∂v²(mt,model,v,t,x)
    return 1/v*d2f^-1
end

function pressure(model::HelmholtzModel,st::ThermodynamicState,unit = u"Pa")
    return pressure(state_type(st),model,st,unit)
end

function pressure(mt::SingleVT,model::HelmholtzModel,st::ThermodynamicState,unit = u"Pa")
    mw = molecular_weight(model)
    v = mol_volume(FromState(),st,u"m^3/mol",mw)
    t = temperature(FromState(),st)
    val = pressure_impl(mt,model,v,t)
    return convert_unit(u"Pa",unit,val)
end

function pressure(mt::MultiVT,model::HelmholtzModel,st::ThermodynamicState,unit = u"Pa")
    mw = molecular_weight(model)
    v = mol_volume(FromState(),st,u"m^3/mol",mw)
    t = temperature(FromState(),st)
    x = mol_fraction(FromState(),st,nothing,mw)
    val = pressure_impl(mt,model,v,t,x)
    return convert_unit(u"Pa",unit,val)
end

function mol_entropy(model::HelmholtzModel,st::ThermodynamicState,unit = u"J/(mol*K)")
    return mol_entropy(state_type(st),model,st,unit)
end

function mol_entropy(mt::SingleVT,model::HelmholtzModel,st::ThermodynamicState,unit = u"J/(mol*K)")
    mw = molecular_weight(model)
    v = mol_volume(FromState(),st,u"m^3/mol",mw)
    t = temperature(FromState(),st)
    val =  mol_entropy_impl(mt,model,v,t)
    return convert_unit(u"J/mol",unit,val)
end

function mol_entropy(mt::MultiVT,model::HelmholtzModel,st::ThermodynamicState,unit = u"J/(mol*K)")
    mw = molecular_weight(model)
    v = mol_volume(FromState(),st,u"m^3/mol",mw)
    t = temperature(FromState(),st,u"K")
    x = mol_fraction(FromState(),st,nothing,mw)
    val = mol_entropy_impl(mt,model,v,t,x)
    return convert_unit(u"J/(mol*K)",unit,val)
end

function mol_entropy(mt::SinglePT,model::HelmholtzModel,st::ThermodynamicState,unit = u"J/(mol*K)")
    mw = molecular_weight(model)
    p = pressure(FromState(),st)
    t = temperature(FromState(),st)
    phase = ThermoState.phase(FromState(),st)
    v = v_zero(mt,model,p,t,phase=phase)
    val =  mol_entropy_impl(mt,model,v,t)
    return convert_unit(u"J/mol",unit,val)
end

function mol_entropy(mt::MultiPT,model::HelmholtzModel,st::ThermodynamicState,unit = u"J/(mol*K)")
    mw = molecular_weight(model)
    p = pressure(FromState(),st)
    t = temperature(FromState(),st,u"K")
    phase = ThermoState.phase(FromState(),st)
    x = mol_fraction(FromState(),st,nothing,mw)
    v = v_zero(mt,model,p,t,x,phase=phase)
    val = mol_entropy_impl(mt,model,v,t,x)
    return convert_unit(u"J/(mol*K)",unit,val)
end

for mol_op in (:mol_helmholtz, :mol_gibbs, :mol_internal_energy, :mol_enthalpy)
    mol_op_impl = Symbol(mol_op,:_impl)
    @eval begin
        function $mol_op_impl(model::HelmholtzModel,args...)
            return $mol_op_impl(model_type(model),model,args...)
        end

        function $mol_op(model::HelmholtzModel,st::ThermodynamicState,unit=u"J/mol")
            return $mol_op(state_type(st),model,st,unit)
        end

        function $mol_op(mt::SingleVT,model::HelmholtzModel,st::ThermodynamicState,unit = u"J/mol")
            mw = molecular_weight(model)
            v = mol_volume(FromState(),st,u"m^3/mol",mw)
            t = temperature(FromState(),st)
            val = $mol_op_impl(mt,model,v,t)
            return convert_unit(u"J/mol",unit,val)
        end

        function $mol_op(mt::MultiVT,model::HelmholtzModel,st::ThermodynamicState,unit = u"J/mol")
            mw = molecular_weight(model)
            v = mol_volume(FromState(),st,u"m^3/mol",mw)
            t = temperature(FromState(),st)
            x = mol_fraction(FromState(),st,nothing,mw)
            val = $mol_op_impl(mt,model,v,t,x)
            return convert_unit(u"J/mol",unit,val)
        end

        function $mol_op(mt::SinglePT,model::HelmholtzModel,st::ThermodynamicState,unit = u"J/mol")
            mw = molecular_weight(model)
            p = pressure(FromState(),st)
            t = temperature(FromState(),st)
            phase = ThermoState.phase(FromState(),st)
            v = v_zero(mt,model,p,t,phase=phase)
            val = $mol_op_impl(mt,model,v,t)
            return convert_unit(u"J/mol",unit,val)
        end

        function $mol_op(mt::MultiPT,model::HelmholtzModel,st::ThermodynamicState,unit = u"J/mol")
            mw = molecular_weight(model)
            p = pressure(FromState(),st)
            t = temperature(FromState(),st)
            x = mol_fraction(FromState(),st,nothing,mw)
            phase = ThermoState.phase(FromState(),st)
            v = v_zero(mt,model,p,t,x,phase=phase)
            val = $mol_op_impl(mt,model,v,t,x)
            return convert_unit(u"J/mol",unit,val)
        end
    end
end

for (mol_op,mass_op) in zip((:mol_helmholtz, :mol_gibbs, :mol_internal_energy, :mol_enthalpy),(:mass_helmholtz, :mass_gibbs, :mass_internal_energy, :mass_enthalpy))
    @eval begin
        function $mass_op(model::HelmholtzModel,st::ThermodynamicState,unit=u"J/kg")
            mw = molecular_weight(model)
            mol_val = $mol_op(model,st)
            val = mol_val/molar_mass(FromState(),st,u"kg/mol",mw)
            return convert_unit(u"J/kg",unit,val)
        end
    end
end

for (mol_op,total_op) in zip((:mol_helmholtz, :mol_gibbs, :mol_internal_energy, :mol_enthalpy),(:total_helmholtz, :total_gibbs, :total_internal_energy, :total_enthalpy))
    @eval begin
        function $total_op(model::HelmholtzModel,st::ThermodynamicState,unit=u"J")
            mw = molecular_weight(model)
            mol_val = $mol_op(model,st)
            val = mol_val*moles(FromState(),st,u"mol",mw)
            return convert_unit(u"J",unit,val)
        end
    end
end

function total_entropy(model::HelmholtzModel,st::ThermodynamicState,unit=u"J/(kg*K)")
    mw = molecular_weight(model)
    mol_val = mol_entropy(model,st)
    val = mol_val*moles(FromState(),st,u"mol",mw)
    return convert_unit(u"J/(kg*K)",unit,val)
end

function mol_volume(model::HelmholtzModel,st::ThermodynamicState,unit = u"m^3/mol")
    return mol_volume(state_type(st),model,st,unit)
end

function mol_volume(mt::SinglePT,model::HelmholtzModel,st::ThermodynamicState,unit = u"m^3/mol")
    mw = molecular_weight(model)
    p = pressure(FromState(),st)
    t = temperature(FromState(),st)
    phase = ThermoState.phase(FromState(),st)
    v = v_zero(volume_solver_type(model),mt,model,p,t,phase=phase)
    return convert_unit(u"m^3/mol",unit,v)
end

function mol_volume(mt::MultiPT,model::HelmholtzModel,st::ThermodynamicState,unit = u"m^3/mol")
    mw = molecular_weight(model)
    p = pressure(FromState(),st)
    t = temperature(FromState(),st)
    x = mol_fraction(FromState(),st,nothing,mw)
    phase = ThermoState.phase(FromState(),st)
    v = v_zero(volume_solver_type(model),mt,model,p,t,x,phase=phase)
    return convert_unit(u"m^3/mol",unit,v)
end

function mol_density(model::HelmholtzModel,st::ThermodynamicState,unit =u"mol/(m^3)")
    v = mol_volume(model,st)
    res =  one(v)/v
    return convert_unit(u"mol/(m^3)",unit,res)
end

function total_volume(model::HelmholtzModel,st::ThermodynamicState,unit = u"m^3")
    mw = molecular_weight(model)
    v  = mol_volume(model,st)
    n = moles(FromState(),st,u"mol",mw)
    res =  v*n
    return convert_unit(u"m^3",unit,res)
end

function mass_volume(model::HelmholtzModel,st::ThermodynamicState,unit = u"m^3/kg")
    mw = molecular_weight(model)
    v  = mol_volume(model,st)
    val = v/molar_mass(FromState(),st,u"kg/mol",mw)
    return convert_unit(u"m^3/kg",unit,val)
end

function mass_density(model::HelmholtzModel,st::ThermodynamicState,unit =u"kg/(m^3)")
    v  = mass_volume(model,st)
    res =  one(v)/v
    return convert_unit(u"kg/(m^3)",unit,res)
end

function compressibility_factor(model::HelmholtzModel,st::ThermodynamicState)
    return compressibility_factor(state_type(st),model,st)
end

function compressibility_factor(mt::SingleVT,model::HelmholtzModel,st::ThermodynamicState)
    v =mol_volume(FromState(),st)
    t = temperature(FromState(),st)
    p = pressure_impl(mt,model,v,t)
    return p*v/(RGAS*t)
end

function compressibility_factor(mt::MultiVT,model::HelmholtzModel,st::ThermodynamicState)
    v =mol_volume(FromState(),st)
    t = temperature(FromState(),st)
    x = mol_fraction(FromState(),st)
    p = pressure_impl(mt,model,v,t,x)
    return p*v/(RGAS*t)
end


text:
module Terminal

using Compat, Compat.REPL, Crayons
export rawmode, clear_screen, readKey, put, terminal_screen

@compat function __init__()
    global terminal
    terminal = REPL.Terminals.TTYTerminal(get(ENV, "TERM", is_windows() ? "" : "dumb"), stdin, stdout, stderr)
end

include("rawmode.jl")
include("cursor.jl")
include("readkey.jl")

end #module


text:
"""
    function change_slack!(sys::System, new_slack_busname::String)

This function changes the current slack bus from the system data to the new slack bus and
returns the modified system.

#Arguments
- `sys::System`:                            Power system in p.u. (from PowerSystems.jl)
- `new_slack_busname::String`:              Name of the bus to be new slack/"REF

"""
function change_slack!(sys::System, new_slack_busname::String)
    # Get buses
    buses = get_components(Bus, sys)

    # Find current slack
    has_slack = false
    for bus in buses
        if get_bustype(bus) == BusTypes.REF
            has_slack = true
            set_bustype!(bus, BusTypes.PV)
        end
    end

    # Assign the new slack bus
    new_slack_bus = get_component(Bus, sys, new_slack_busname)
    set_bustype!(new_slack_bus, "REF")

    # Warns if there was no slack bus in the original system
    if !has_slack
        @warn "There was no slack bus in the original system,
            however your selected slack has been assigned"
    end

    return sys
end

max_stars_repo_name: invenia/MaximumGeneratorProfitTCRDD

max_issues_repo_name: invenia/MaximumGeneratorProfitTCRDD

max_forks_repo_name: invenia/MaximumGeneratorProfitTCRDD


text:
using Underscore
using Base.Test

@test "hello" |> (@_ string(" world")) == "hello world"

@test "world" |> (@_ string("hello ", $1)) == "hello world"

@test [1, 2, 3] |> (@_ reduce(+, 0, $1)) == 6

@test (1, 2) |> (@_ +(3, $1, $2)) == 6

andnext(x) = (x, x + 1)
sqr(x) = x^2

@test 1 |> andnext |> (@_ $1 + $2) |> sqr == 9

@test 1 |> (@_ $1 + $1) == 2

@test (1, 2) |> (@_ sqr($2)) == 4


text:
# ------------------------------------------------------------------- #
# Generic methods
# ------------------------------------------------------------------- #

# Base.size(::AbstractExogenousProcess{N}) = N

# AbstractExogenousProcess Interface
# for f in [:step]
#     @eval $(f){T<:AbstractExogenousProcess}(::T, args...) =
#         throw(NotImplementedError("$f not implemented for type $T"))
# end

# simulate a univariate exog process and return a Vector
function simulate{T<:Number}(ep::AbstractExogenousProcess{1}, x0::T,
                             capT::Int=25_000)
    out = Array(T, capT)
    out[1] = x0
    @inbounds for t=2:capT
        out[t] = step(ep, out[t-1])
    end
    return out
end

function simulate{T<:Number,N}(ep::AbstractExogenousProcess{N},
                               x0::Vector{T}=ones(N);
                               capT::Int=25_000)
    out = Array(T, N, capT)
    out[:, 1] = convert(Vector{T}, x0)
    @inbounds for t=2:capT
        out[:, t] = step(ep, out[:, t-1])
    end

    return out
end

# ------------------------------------------------------------------- #
# AR1ConstantVolatility
# ------------------------------------------------------------------- #

# special case the 1d version
immutable ConstantVolatility1 <: AbstractExogenousProcess{1}
    A::Float64
    Bv::Float64
    ϵ::Array{Float64, 1}
    Π::Array{Float64, 1}
    Πcumsum::Array{Float64, 1}
end

function ConstantVolatility1(A::Float64=0., B::Float64=1., vbar::Float64=0.004,
                             nϵ::Int=5)

    Bv = B * sqrt(vbar)
    ϵ, Π = qnwnorm(nϵ, 0., 1.)
    Πcumsum = cumsum(Π)

    ConstantVolatility1(A, Bv, ϵ, Π, Πcumsum)
end

Base.step(ep::ConstantVolatility1, x::Float64, ϵ) = ep.A*x .+ ep.Bv*ϵ
Base.step(ep::ConstantVolatility1, x::Float64) = step(ep, x, randn())

# use matrix form to represent general version
immutable ConstantVolatility{N} <: AbstractExogenousProcess{N}
    A::Matrix{Float64}
    B::Matrix{Float64}
    ϵ::Matrix{Float64}
    Π::Vector{Float64}
    Πcumsum::Vector{Float64}
end

# standard 2d case where we can scale by z1 to reduce dimensionality
function ConstantVolatility(γ::Real, v1::Real, v2::Real, nϵ1::Integer,
                            nϵ2::Integer)

    A = [γ 1-γ; 1-γ γ]
    B = [v1 0; 0 v2]
    ϵ, Π = qnwnorm([nϵ1, nϵ2], zeros(2), eye(2))
    ConstantVolatility{2}(A, B, ϵ, Π, cumsum(Π))
end

Base.step{N}(ex::ConstantVolatility{N}, x, ϵ=randn(N)) = ex.A*x .+ ex.B*ϵ

immutable StochasticVolatility{N} <: AbstractExogenousProcess{N}
    A::Float64
    B::Float64
    τ::Float64
    φv::Float64
    vbar::Float64
    ϵ::Array{Float64, 2}
    Π::Array{Float64, 1}
    Πcumsum::Array{Float64, 1}
end

function StochasticVolatility(A::Float64=0., B::Float64=1., τ::Float64=7.4e-6,
                              φv::Float64=.95, vbar::Float64=.004,
                              nϵ1::Int=5, nϵ2::Int=5)

    ϵ, Π = qnwnorm([nϵ1, nϵ2], zeros(2), eye(2))
    Πcumsum = cumsum(Π)

    StochasticVolatility{2}(A, B, τ, φ, vbar, ϵ, Π, Πcumsum, 2)
end

function Base.step(ep::StochasticVolatility{2}, xt::Float64, vt::Float64, ϵ1, ϵ2)

    xtp1 = ep.A*xt + ep.B*sqrt(vt)*ϵ1
    vtp1 = (1 - ep.φv)*ep.vbar + ep.φv*vt + ep.τ*ϵ2

    return (xtp1, vtp1)
end

Base.step(ep::StochasticVolatility{2}, xt::Float64, vt::Float64) =
    Base.step(ep, xt, vt, randn(2)...)

max_stars_repo_name: NYUEcon/GrowthModels

max_issues_repo_name: NYUEcon/GrowthModels

max_forks_repo_name: NYUEcon/GrowthModels


text:
module TestSKCrossValidator

using Test
using Random
using AutoMLPipeline
using AutoMLPipeline.EnsembleMethods
using AutoMLPipeline.SKPreprocessors
using AutoMLPipeline.SKCrossValidators
using AutoMLPipeline.DecisionTreeLearners
using AutoMLPipeline.Pipelines
using AutoMLPipeline.FeatureSelectors
using AutoMLPipeline.Utils

function crossv(ppl,X,Y,folds,verbose)
  @test crossvalidate(ppl,X,Y,"accuracy_score",folds,verbose).mean > 0.80
  @test crossvalidate(ppl,X,Y,"balanced_accuracy_score",folds,verbose).mean > 0.80
  @test crossvalidate(ppl,X,Y,"cohen_kappa_score",folds,verbose).mean > 0.80
  @test crossvalidate(ppl,X,Y,"jaccard_score","weighted",folds,verbose).mean > 0.80
  @test crossvalidate(ppl,X,Y,"matthews_corrcoef",folds,verbose).mean > 0.80
  @test crossvalidate(ppl,X,Y,"hamming_loss",folds,verbose).mean < 0.1
  @test crossvalidate(ppl,X,Y,"zero_one_loss",folds,verbose).mean < 0.1
  @test crossvalidate(ppl,X,Y,"f1_score","weighted",folds,verbose).mean > 0.80
  @test crossvalidate(ppl,X,Y,"precision_score","weighted",folds,verbose).mean > 0.80
  @test crossvalidate(ppl,X,Y,"recall_score","weighted",folds,verbose).mean > 0.80
end

function test_skcrossvalidator()
  data=getiris()
  X=data[:,1:4]
  Y=data[:,5] |> Vector{String}
  ppl1 = Pipeline(Dict(:machines=>[RandomForest()]))
  crossv(ppl1,X,Y,10,false)
  ppl2 = Pipeline(Dict(:machines=>[VoteEnsemble()]))
  crossv(ppl2,X,Y,10,false)
  cat = CatFeatureSelector()
  num = NumFeatureSelector()
  pca = SKPreprocessor("PCA")
  ptf = SKPreprocessor("PowerTransformer")
  rbc = SKPreprocessor("RobustScaler")
  ppl3=@pipeline ((cat + num) + (num |> ptf) + (num |> rbc) + (num |> pca)) |> VoteEnsemble()
  crossv(ppl3,X,Y,10,false)
end
@testset "CrossValidator" begin
  Random.seed!(123)
  test_skcrossvalidator()
end

end


text:
# Tests for Row type and associated methods

@testset "Row" begin
    @testset "Constructors" begin
        @test_throws DomainError Row(-1, [])

        a = Row(0, [1])
        b = Row(a)
        c = Row(0)
        d = Row{Int}(0, 10)
        @test a == b == c == d

        a = Row(3, [1.0,3.0,3.0,1.0])
        b = Row(a)
        c = Row(3) # different data type
        d = Row{Float64}(3, 10)
        @test a == b == c == d

        a = Row(10)
        b = Row(a)
        b.data[2] = 4
        @test a != b
    end

    @testset "Accessors" begin
        a = Row(5)
        @test rownumber(a) == 5
        @test value(a) == [1,5,10,10,5,1]
    end

    @testset "Array functions" begin
        a = Row(7)
        b = Row{Float64}(7, 8)
        @test sum(a) == 128
        @test sum(x -> x^2, a) == 3432
        @test sum(b) == 128.0
        @test sum(x -> x^2, b) == 3432.0

        @test axes(a) == axes(b) == (0:1:7,)
        @test size(a) == size(b) == (8,)

        @testset "Data access $i" for i ∈ 0:7
            @test a[i] == b[i]
        end

        @test_throws BoundsError a[-1]
        @test_throws BoundsError a[10]

        @test firstindex(a) == firstindex(b) == 0
        @test lastindex(a) == lastindex(b) == 7
    end

    @testset "Checks" begin
        a = Row(0)
        b = Row(4)
        c = Row(4, [7]) # bad data
        d = Row(4, [6.0])

        @test isfirst(a)
        @test !isfirst(b)

        @test PT.isvalid(a)
        @test !PT.isvalid(c)

        @test toarray(b) == toarray(d)
    end

    @testset "Movement" begin
        a = Row(0)
        b = Row(8)
        c = Row(9)
        d = Row(10)

        @test_throws OutOfBoundsError up!(a)
        @test_throws OutOfBoundsError up(a)
        @test_throws OutOfBoundsError prev!(a)
        @test_throws OutOfBoundsError prev(a)

        @test up(c) == prev(c) == b
        @test down(c) == next(c) == d

        e = Row(b)
        f = Row(d)

        down!(b)
        next!(e)
        up!(d)
        prev!(f)
        @test b == c == d == e == f
    end
end


text:
sanction = dataset("Zelig", "sanction")

priors = [
    Prior_Ridge(),
    Prior_Laplace(),
    Prior_Cauchy(),
    Prior_TDist(),
    Prior_Uniform(),
]

CRRao.set_rng(StableRNG(123))
model = @fitmodel((Num ~ Target + Coop + NCost), sanction, NegBinomRegression())
@test sizeof(model) > 0

for prior in priors
    CRRao.set_rng(StableRNG(123))
    model = @fitmodel((Num ~ Target + Coop + NCost), sanction, NegBinomRegression(), prior)
    @test sizeof(model) > 0
end


text:
struct ZMQTransport
    ctx::Context
    sock::Socket
    mode::Int
    bound::Bool
end
function ZMQTransport(addr::String, mode::Int, bound::Bool, ctx::Context=Context())
    sock = Socket(ctx, mode)
    if bound
        ZMQ.bind(sock, addr)
    else
        ZMQ.connect(sock, addr)
    end
    ZMQTransport(ctx, sock, mode, bound)
end
function ZMQTransport(ip, port, mode::Int, bound::Bool, ctx::Context=Context())
    ZMQTransport("tcp://$ip:$port", mode, bound, ctx)
end

"""Close connection to the socket"""
function close(conn::ZMQTransport)
    @debug("closing connection...")
    close(conn.sock)
end

"""Receive request from the socket"""
function recvreq(conn::ZMQTransport)
    reqstr = unsafe_string(ZMQ.recv(conn.sock))
    @debug("received request: ", reqstr)
    reqstr
end

"""Send response to the socket"""
function sendresp(conn::ZMQTransport, msgstr)
    @debug("sending response: ", msgstr)
    ZMQ.send(conn.sock, JSON.json(msgstr))
end

function process!(env::AbstractEnvironment, msg::Dict{String, T}) where T
    if "cmd" in keys(msg)
        if msg["cmd"] == "obs_dimensions"
            respmsg = Dict("obs_dim"=>obs_dimensions(env))
        elseif msg["cmd"] == "n_actions"
            respmsg = Dict("n_actions"=>length(actions(env)))
        elseif msg["cmd"] == "render"
            render(env)
        elseif msg["cmd"] == "reset"
            obs = reset!(env)
            respmsg = Dict("obs"=> obs)
        elseif msg["cmd"] == "step"
            act_idx = msg["args"]
            act = actions(env)[act_idx]
            obs, rew, done, info = step!(env, act)
            respmsg = Dict("obs"=> obs, "rew"=> rew, "done"=>done, "info"=>info)
        else
            respmsg = Dict("error"=>"no known "+msg["cmd"]+" cmd found")
        end
    end
    respmsg
end

"""Run the ZMQ server with the environment

By default we wrap an MDP problem into an MDP environment
and a POMDP problem into a POMDP environment.
"""
function run_env_server end

function run_env_server(ip, port, prob::MDP)
    env = MDPEnvironment(prob)
    run_env_server(ip, port, env)
end

function run_env_server(ip, port, prob::POMDP)
    env = POMDPEnvironment(prob)
    run_env_server(ip, port, env)
end

function run_env_server(ip, port, env::AbstractEnvironment)
    conn = ZMQTransport(ip, port, ZMQ.REP, true)
    @info("running server...")
    while true
        msg = JSON.parse(recvreq(conn))
        @info("received request: ", msg)
        respmsg = process!(env, msg)
        sendresp(conn, respmsg)
    end
    close(conn)
end


text:
"""
        vikor(decisionMat, weights, fns; v = 0.5)

Apply VIKOR (VlseKriterijumska Optimizcija I Kaompromisno Resenje in Serbian) method for a given matrix and weights.

# Arguments:
 - `decisionMat::DataFrame`: n × m matrix of objective values for n candidate (or strategy) and m criteria
 - `weights::Array{Float64, 1}`: m-vector of weights that sum up to 1.0. If the sum of weights is not 1.0, it is automatically normalized.
 - `fns::Array{Function, 1}`: m-vector of function that are either maximum or minimum.
 - `v::Float64`: Optional algorithm parameter. Default is 0.5.

# Description
vikor() applies the VIKOR method to rank n strategies subject to m criteria which are supposed to be either maximized or minimized.

# Output
- `::VikorResult`: VikorResult object that holds multiple outputs including scores and best index.

# Examples
```julia-repl
julia> Amat = [
             100 92 10 2 80 70 95 80 ;
             80  70 8  4 100 80 80 90 ;
             90 85 5 0 75 95 70 70 ;
             70 88 20 18 60 90 95 85
           ];

julia> dmat = makeDecisionMatrix(Amat)
4×8 DataFrame
 Row │ Crt1     Crt2     Crt3     Crt4     Crt5     Crt6     Crt7     Crt8
     │ Float64  Float64  Float64  Float64  Float64  Float64  Float64  Float64
─────┼────────────────────────────────────────────────────────────────────────
   1 │   100.0     92.0     10.0      2.0     80.0     70.0     95.0     80.0
   2 │    80.0     70.0      8.0      4.0    100.0     80.0     80.0     90.0
   3 │    90.0     85.0      5.0      0.0     75.0     95.0     70.0     70.0
   4 │    70.0     88.0     20.0     18.0     60.0     90.0     95.0     85.0

julia> fns = makeminmax([maximum, maximum, maximum, maximum, maximum, maximum, maximum, maximum]);

julia> result = vikor(dmat, w, fns);

julia> result.scores
4-element Array{Float64,1}:
  0.1975012087551764
  0.2194064473270817
  0.3507643203516215
 -0.16727341435277993

julia> result.bestIndex
4

```

# References
Celikbilek Yakup, Cok Kriterli Karar Verme Yontemleri, Aciklamali ve Karsilastirmali
Saglik Bilimleri Uygulamalari ile. Editor: Muhlis Ozdemir, Nobel Kitabevi, Ankara, 2018
"""
function vikor(decisionMat::DataFrame, weights::Array{Float64,1}, fns::Array{Function,1}; v::Float64=0.5)::VikorResult
    w = unitize(weights)

    nalternatives, ncriteria = size(decisionMat)

    # col_max = colmaxs(decisionMat)
    # col_min = colmins(decisionMat)
    col_max = apply_columns(fns, decisionMat)
    col_min = apply_columns(reverseminmax(fns), decisionMat)

    A = similar(decisionMat)

    for i in 1:nalternatives
        for j in 1:ncriteria
            if fns[j] == maximum
                @inbounds A[i, j] = abs((col_max[j] - decisionMat[i, j]) / (col_max[j] - col_min[j]))
            elseif fns[j] == minimum
                @inbounds A[i, j] = abs((decisionMat[i, j] - col_min[j]) / (col_max[j] - col_min[j]))
            else
                @warn fns[j]
                error("Function must be either maximum or minimum.")
            end
        end
    end

    weightedA = w * A

    s = Array{Float64,1}(undef, nalternatives)
    r = similar(s)
    q = similar(s)

    for i in 1:nalternatives
        s[i] = sum(weightedA[i,:])
        r[i] = maximum(weightedA[i,:])
    end

    smin = minimum(s)
    smax = maximum(s)
    rmin = minimum(r)
    rmax = maximum(r)
    q = v .* ((s .- smin ./ (smax .- smin))) + (1 - v) .* ((r .- rmin ./ (rmax .- rmin)))

    scores = q

    # select the one with minimum score
    best_index = sortperm(q) |> first

    result = VikorResult(
        decisionMat,
        w,
        weightedA,
        best_index,
        scores
    )
    return result
end

max_stars_repo_name: bahadirfyildirim/JMcDM

max_issues_repo_name: bahadirfyildirim/JMcDM

max_forks_repo_name: bahadirfyildirim/JMcDM


text:
module GLMakie

using ModernGL, GLFW, FixedPointNumbers, Colors, GeometryTypes
using AbstractPlotting, StaticArrays
using ..Makie
using AbstractPlotting: Scene, Lines, Text, Image, Heatmap, Scatter, @key_str, Key, broadcast_foreach
using AbstractPlotting: convert_attribute, @extractvalue, LineSegments, to_ndim, NativeFont
using AbstractPlotting: @get_attribute, to_value, to_colormap, extrema_nan
using Base: RefValue
import Base: push!, isopen, show
using FileIO
using ImageCore
import IntervalSets
using IntervalSets: ClosedInterval, (..)
using Base.Iterators: repeated, drop
using FreeType, FreeTypeAbstraction, FixedPointNumbers

for name in names(AbstractPlotting)
    @eval import AbstractPlotting: $(name)
end

include("GLAbstraction/GLAbstraction.jl")
using .GLAbstraction

const atlas_texture_cache = Dict{GLFW.Window, Tuple{Texture{Float16, 2}, Function}}()

function get_texture!(atlas)
    # clean up dead context!
    filter!(atlas_texture_cache) do (ctx, tex_func)
        if GLAbstraction.context_alive(ctx)
            true
        else
            AbstractPlotting.remove_font_render_callback!(tex_func[2])
            false
        end
    end
    tex, func = get!(atlas_texture_cache, GLAbstraction.current_context()) do
        tex = Texture(
                atlas.data,
                minfilter = :linear,
                magfilter = :linear,
                anisotropic = 16f0,
        )
        # update the texture, whenever a new font is added to the atlas
        function callback(distance_field, rectangle)
            ctx = tex.context
            if GLAbstraction.context_alive(ctx)
                prev_ctx = GLAbstraction.current_context()
                GLAbstraction.switch_context!(ctx)
                tex[rectangle] = distance_field
                GLAbstraction.switch_context!(prev_ctx)
            end
        end
        AbstractPlotting.font_render_callback!(callback)
        return (tex, callback)
    end
    tex
end

include("GLVisualize/GLVisualize.jl")
using .GLVisualize

include("glwindow.jl")
include("screen.jl")
include("rendering.jl")
include("events.jl")
include("drawing_primitives.jl")

struct GLBackend <: AbstractPlotting.AbstractBackend
end
function AbstractPlotting.backend_display(x::GLBackend, scene::Scene)
    screen = global_gl_screen()
    # This should only get called if inline display false, so we display the window
    GLFW.set_visibility!(to_native(screen), true)
    display(screen, scene)
end

colorbuffer(screen) = error("Color buffer retrieval not implemented for $(typeof(screen))")

"""
    scene2image(scene::Scene)

Buffers the `scene` in an image buffer.
"""
function scene2image(scene::Scene)
    screen = global_gl_screen()
    display(screen, scene)
    colorbuffer(screen)
end

function AbstractPlotting.backend_show(::GLBackend, io::IO, m::MIME"image/png", scene::Scene)
    img = scene2image(scene)
    GLFW.set_visibility!(to_native(global_gl_screen()), !AbstractPlotting.use_display[])
    FileIO.save(FileIO.Stream(FileIO.format"PNG", io), img)
end

function __init__()
    AbstractPlotting.register_backend!(GLBackend())
end

end


text:
module IdMap

function getIDmap(IDfile)
    columns = [:Database_Identifier,
               :Node_Name,
               :Node_Type,
               :Display_Name,
               :Reference_Entity_Name,
               :Reference_Entity_Identifier,
               :Instance_Class]

    idMap = Dict()
    open(IDfile, "r") do file
        header = readline(file)
        for line in eachline(file)
            lineParts = split(chomp(line), "\t")
            row = Dict(zip(columns, lineParts))
            dbID = row[:Database_Identifier]
            if haskey(idMap, dbID) == false
                idMap[dbID] = []
            end
            push!(idMap[dbID], row)

            nodeName = row[:Node_Name]
            if haskey(idMap, nodeName) == false
                idMap[nodeName] = []
            end
            push!(idMap[nodeName], row)

            refName = row[:Reference_Entity_Name]
            if refName != "N/A"
                if haskey(idMap, refName) == false
                    idMap[refName] = []
                end
                push!(idMap[refName], row)
            end

            refID = row[:Reference_Entity_Identifier]
            if refID != "N/A"
                if haskey(idMap, refID) == false
                    idMap[refID] = []
                end
                push!(idMap[refID], row)
            end
        end
    end

    return idMap
end

function idToNodes(idMap, id, entityType="generic")
   if entityType == "generic"
       println("need to finish this")
   end

   return 1
end

function allGeneReferenceProduct(dbidfile)
    genes = []
    header = true
    for line in readlines(dbidfile)
        if header == false
            lineparts = split(chomp(line), "\t")
            node = String(lineparts[2])
            if contains(lineparts[6], "Reference") == true
                push!(genes, node)
            end
        end
        header = false
    end

    return genes
end

function geneToNodes(dbidfile)
    genetonodes = Dict()
    header = true
    for line in readlines(dbidfile)
        if header == false
            lineparts = split(chomp(line), "\t")
            node = String(lineparts[2])
            gene = String(lineparts[3])
            if haskey(genetonodes, gene)
                nodes = genetonodes[gene]
                push!(nodes, node)
            else
                genetonodes[gene] = [node]
            end
        end
        header = false
    end

    return genetonodes
end

function nodeToGene(dbidfile)
   genetonodes = geneToNodes(dbidfile)

   nodetogene = Dict()
   for (gene, nodes) in genetonodes
       for node in nodes
           nodetogene[node] = gene
       end
   end

   return nodetogene
end

function geneToRootNodes(pinodes, dbidfile)
    genetonodes = Dict()
    header = true
    for line in readlines(dbidfile)
        if header == false
            lineparts = split(chomp(line), "\t")
            node = String(lineparts[2])
            gene = String(lineparts[3])
            if haskey(pinodes, node) && pinodes[node].relation == "ROOT"
                if haskey(genetonodes, gene)
                    nodes = genetonodes[gene]
                    push!(nodes, node)
                else
                    genetonodes[gene] = [node]
                end
            end
        end
        header = false
    end

    return genetonodes
end

end

max_stars_repo_name: OICR/mp-biopath

max_issues_repo_name: OICR/mp-biopath

max_forks_repo_name: OICR/mp-biopath


text:
using Documenter, Hooks

makedocs(;
    modules=[Hooks],
    format=Documenter.HTML(),
    pages=[
        "Home" => "index.md",
    ],
    repo="https://github.com/ssfrr/Hooks.jl/blob/{commit}{path}#L{line}",
    sitename="Hooks.jl",
    authors="Spencer Russell",
    assets=[],
)

deploydocs(;
    repo="github.com/ssfrr/Hooks.jl",
)


text:
export
  addVariable,
  addFactor,
  addOdometry2D,
  addLandmark2D,
  addFactorBearingRangeNormal,
  ls,
  getVert,
  setSolvable,
  solveTree!,
  # per variable
  setVarKDE, # needed for workaround on bad autoinit
  getVarMAPKDE, # marginal belief points (KDE)
  getVarMAPMax, # Future, how many maxes should you get?
  getVarMAPMean,
  # fancy future stuff
  getVarMAPFit # defaul=Normal

okResponse = Dict{String, Any}("status" => "OK")

function addVariable(configDict, fg, requestDict)::Dict{String, Any}
  varRequest = Unmarshal.unmarshal(VariableRequest, requestDict["payload"])
  varLabel = Symbol(varRequest.label)
  varType = nothing # TODO type instability here is slow
  try
      varType = getfield(RoME, Symbol(varRequest.variableType))
  catch ex
      io = IOBuffer()
      showerror(io, ex, catch_backtrace())
      err = String(take!(io))
      error("addVariable: Unable to locate variable type '$(varRequest.variableType)'. Please check that it exists in main context. Stack trace = $err")
  end

  @info "Adding variable of type '$(varRequest.variableType)' with id '$(varRequest.label)'..."

  vnext = addVariable!(fg, varLabel, varType, N=(varRequest.N==nothing ? 100 : varRequest.N), solvable=0, tags=Symbol.([varRequest.labels; "VARIABLE"]))
  return Dict{String, Any}("status" => "OK", "id" => vnext.label)
end

function addFactor(configDict, fg, requestDict)::Dict{String, Any}
    if !haskey(requestDict, "payload")
        error("A factor body is required in the request as 'payload' field.")
    end
    factorRequest = requestDict["payload"]
    vars = factorRequest["variables"]
    packedFactor = factorRequest["factor"]
    @info "Adding factor of type '$(factorRequest["factorType"])' to variables '$(vars)'..."

    # Right, carrying on...
    factor = nothing
    try
        # FIXME, use appropriate new DFG method rather than _evalType
        factType = _evalType(factorRequest["factorType"])
        factor = convert(factType, packedFactor)
    catch ex
        io = IOBuffer()
        showerror(io, ex, catch_backtrace())
        err = String(take!(io))
        error("addFactor: Unable to convert packed factor data to type '$(factorRequest["factorType"])'. Please check that a converter exists to deserialize '$(factorRequest["factorType"])'. Stack trace = $err")
    end
    f = addFactor!(fg, Symbol.(vars), factor)
    return Dict{String, Any}("status" => "OK", "id" => f.label)
end

function addOdometry2D(configDict, fg, requestDict)::Dict{String, Any}
  @show requestDict
  # odoFg = Unmarshal.unmarshal(AddOdoFgRequest, requestDict)
  error("Not implemented yet!")
end

function addLandmark2D(configDict, fg, requestDict)::Dict{String, Any}
  @show requestDict
  # odoFg = Unmarshal.unmarshal(AddOdoFgRequest, requestDict)
  error("Not implemented yet!")
end

function addFactorBearingRangeNormal(configDict, fg::AbstractDFG, requestDict)::Dict{String, Any}
  @show requestDict
  # odoFg = Unmarshal.unmarshal(AddOdoFgRequest, requestDict)
  error("Not implemented yet!")
end

function ls(configDict, fg::AbstractDFG, requestDict::Dict)::Dict{String, Any}
    @show requestDict
    if !haskey(requestDict, "payload")
        error("The request does not contain a filter in 'payload' field and this is required for the command")
    end
    lsr = Unmarshal.unmarshal(lsRequest, requestDict["payload"])

    resp = Dict{String, Any}()
    if lsr.variables == "true"
        vars = DistributedFactorGraphs.ls(fg)
        resp["variables"] = map(v -> Dict{String, Any}("id" => v), vars)
    end
    if lsr.factors == "true"
        # Variables
        for vDict in resp["variables"]
            factors = DistributedFactorGraphs.ls(fg, Symbol(vDict["id"]))
            vDict["factors"] = String.(factors)
        end
    end
    return resp
end

function getVariable(configDict, fg::AbstractDFG, requestDict::Dict)::Dict{String, Any}
    variable = DistributedFactorGraphs.getVariable(fg, Symbol(requestDict["payload"]))
    return packVariable(fg, variable)
    # return JSON.parse(JSON.json(variable))
end

function getFactor(configDict, fg::AbstractDFG, requestDict::Dict)::Dict{String, Any}
    factor = DistributedFactorGraphs.getFactor(fg, Symbol(requestDict["payload"]))
    return packFactor(fg,factor)
    # return JSON.parse(JSON.json(factor))
end

function setSolvable(configDict, fg::AbstractDFG, requestDict::Dict)::Dict{String, Any}
    if !haskey(requestDict, "payload")
        error("Request must contain a solvableRequest in a field called 'payload'")
    end
    solvableRequest = requestDict["payload"]
    # Validation of payload
    if !(typeof(solvableRequest["isSolvable"]) <: Int)
        error("setsolvable request must set to solvable to either 0 or 1.")
    end
    if !(solvableRequest["isSolvable"] in [0, 1])
        error("setsolvable request must set to solvable to either 0 or 1.")
    end

    # Action
    if solvableRequest["variables"]!=nothing
        error("setSolvable does not support a request list yet.")
        #TODO: Fix to use getVariable/getFactor for requestDict["variables"]...
    end
    # Do specific variables
    for varLabel in DistributedFactorGraphs.ls(fg)
        v = DistributedFactorGraphs.getVariable(fg, varLabel)
        v.solvable = solvableRequest["isSolvable"]
    end
    for varLabel in DistributedFactorGraphs.lsf(fg)
        v = DistributedFactorGraphs.getFactor(fg, varLabel)
        v.solvable = solvableRequest["isSolvable"]
    end

    # Generate return payload
    return okResponse
end

function solveTree(configDict, fg, requestDict)::Dict{String, Any}
    resp = Dict{String, Any}("startTime" => now())
    # Call solve
    solveTree!(fg)
    resp["endTime"] = now()
    resp["durationSec"] = Dates.value(resp["endTime"] - resp["startTime"])/1000.0
    resp["status"] = "OK"
    return resp
end

function setVarKDE(configDict, fg, requestDict)::Dict{String, Any}
  @show requestDict
  # odoFg = Unmarshal.unmarshal(AddOdoFgRequest, requestDict)
  error("Not implemented yet!")
end

function getVarMAPKDE(configDict, fg, requestDict)::Dict{String, Any}
    map = KDE.getKDEMax(getBelief(fg, Symbol(Symbol(requestDict["payload"]))))
    return Dict{String, Any}("MAP" => JSON.parse(JSON.json(map)))
end

function getVarMAPMax(configDict, fg, requestDict)::Dict{String, Any}
    # KDE.getKDEMax(getBelief(fg, :x0))
  @show requestDict
  # odoFg = Unmarshal.unmarshal(AddOdoFgRequest, requestDict)
  error("Get all KDE modes - Not implemented yet!")
end

function getVarMAPMean(configDict, fg, requestDict)::Dict{String, Any}
    map = KDE.getKDEMean(getBelief(fg, Symbol(Symbol(requestDict["payload"]))))
    return Dict{String, Any}("MAP" => JSON.parse(JSON.json(map)))
end

# Fancy future stuff
function getVarMAPFit(configDict, fg, requestDict)::Dict{String, Any}
  @show requestDict
  # odoFg = Unmarshal.unmarshal(AddOdoFgRequest, requestDict)
  error("Not implemented yet!")
end