text:
# AUTO GENERATED FILE - DO NOT EDIT

export ''_dashboarditemresponsive

"""
    ''_dashboarditemresponsive(;kwargs...)
    ''_dashboarditemresponsive(children::Any;kwargs...)
    ''_dashboarditemresponsive(children_maker::Function;kwargs...)

A DashboardItemResponsive component.
DashboardItemResponsive is a wrapper that is intended to be used with DraggableDashboard.
DashboardItemResponsive specify the position and size of the item on the dashboard.
Keyword arguments:
- `children` (Array of a list of or a singular dash component, string or numbers | a list of or a singular dash component, string or number; optional): The child or list of children wrapped by the component.
- `id` (String | Dict; optional): The ID used to identify this component in Dash callbacks.
- `x` (Real | Dict; optional): The position on the x axis in number of columns (by default, the  max is 12).
- `y` (Real | Dict; optional): The position on the y axis (the unit is 30px, by default)
- `w` (Real | Dict; optional): The width of the x axis (default is 6).
- `h` (Real | Dict; optional): The height on the of y axis (default is 4)
- `static` (Bool; optional): If true, equal to `isDraggable: false, isResizable: false`.
- `isDraggable` (Bool; optional): If false, will not be draggable. Overrides `static`.
- `isResizable` (Bool; optional): If false, will not be resizable. Overrides `static`.
- `isBounded` (Bool; optional)
- `maxH` (Real; optional)
- `maxW` (Real; optional)
- `minH` (Real; optional)
- `minW` (Real; optional)
- `moved` (Bool; optional)
- `resizeHandles` (String; optional)
- `__isDashboardItem` (Bool; optional): This is an internal prop used to identify the component, this property default value is True.
Setting this value to false is equivalent to not using the DashboardItem wrapper.
"""
function ''_dashboarditemresponsive(; kwargs...)
        available_props = Symbol[:children, :id, :x, :y, :w, :h, :static, :isDraggable, :isResizable, :isBounded, :maxH, :maxW, :minH, :minW, :moved, :resizeHandles, :__isDashboardItem]
        wild_props = Symbol[]
        return Component("''_dashboarditemresponsive", "DashboardItemResponsive", "dash_draggable", available_props, wild_props; kwargs...)
end

''_dashboarditemresponsive(children::Any; kwargs...) = ''_dashboarditemresponsive(;kwargs..., children = children)
''_dashboarditemresponsive(children_maker::Function; kwargs...) = ''_dashboarditemresponsive(children_maker(); kwargs...)

max_stars_repo_name: tcgvn/dash-draggable

max_issues_repo_name: tcgvn/dash-draggable

max_forks_repo_name: tcgvn/dash-draggable


text:
## Julia 1.1.0

# anonymous
println("\n\n---------------- anonymous ----------------")
for V in [(1, 2 + 2, 2im, 3.14), (1, "Julia", NaN)]
    println("$V")
end

# named
println("\n\n---------------- named ----------------")

x = (a = 1, b = 2)
println("x.a -> $(x.a)")
println("x.b -> $(x.b)")

# function multiple return values
println("\n\n---------------- function multiple return values ----------------")
f(x, y) = x + y, x * y
a = f(2, 3)
b, c = f(2, 3)
println("a = $a, b = $b, c = $c")

# argument destructring
println("\n\n---------------- argument destructring ----------------")
minmax(x, y) = (y < x) ? (y, x) : (x, y)
range((min, max)) = max - min

println("range(minmax(2, 10)) -> $(range(minmax(2, 10)))")

# varargs functions
println("\n\n---------------- varargs functions ----------------")
x = [3,4]

vararg(a, b) = a + b
println("vararg($x...) -> $(vararg(x...))")

ext: jl

max_stars_repo_name: fengyfei/sapphire

max_issues_repo_name: fengyfei/sapphire

max_forks_repo_name: fengyfei/sapphire


text:
#################################
# Forecast API                  #
#################################
# Get forecast information for a specific location.

# Contains a centralized function to make calls to the API.
include("request.jl")

function get_forecast(apikey::String, timespan::String, time::Int64, locationKey::String, language::String, details::Bool, metric::Bool)
    # Daily/Hourly forecasts for a specific location. Forecast searches require a location key. Please use the Locations API to obtain the location key for your desired location. By default, a truncated version of the hourly forecast data is returned. The full object can be obtained by passing "details=true" into the url string.

    url = "http://dataservice.accuweather.com/forecasts/v1/"

    # Add required parameters to the URL
    url = url * timespan * "ly"
    # Accepted values: day hour

    url = url * string(time) * timespan * "/"
    # Accepted values:
    # - Days: 1/5/10/15
    # - Hours: 1/12/24/72/120
    #   Example: If "timespan" is set to "day" and "time" to 10, it gets the forecast for 15 days.

    url = url * string(locationKey)
    url = url * "?apikey=" * apikey

    # Add optional parameters to the URL
    if language != Nothing url = url * "&language=" * language end
    if details == true url = url * "&details=true" end
    if metric == true url = url * "&metric=true" end

    return make_API_call(url)
end


text:
#Functions to setup the set-dictionary
"""
    setup_opt_set_tech!(ts_data::ClustData,opt_data::CEPData,config::Dict{String,Any})
Add the entry set["tech"]
"""
function setup_opt_set_tech!(set::Dict{String,Dict{String,Array}},
                            opt_data::OptDataCEP,
                            config::Dict{String,Any})
      #`techs::OptVariable`: techs[tech] - OptDataCEPTech
      techs = opt_data.techs

      set["tech"]["limit"]=Array{String,1}()
      #Loop through all techs
      for tech in axes(techs,"tech")
        #Check if the primary tech-group (first entry within the Array of tech-groups) is in config
        if config[techs[tech].tech_group[1]]
          #Add the technology to the set of all techs
          push!(set["tech"],"all", tech)
          #Loop through all tech_groups for this technology
          for tech_group_name in techs[tech].tech_group
            #Push this tech to the set: `set[tech_group_name]`
            push!(set["tech"],tech_group_name,tech)
            #Existing infrastructure
            if haskey(config["infrastructure"],"existing")
              #Add this tech to the tech-group "existing_infra" or "no_existing_infra" depending if the tech_group is a key within the dictionary `techgroups_exis_inf`
              if in(tech_group_name,config["infrastructure"]["existing"])
                push!(set["tech"],"exist_inf",tech)
              else
                push!(set["tech"],"no_exist_inf",tech)
              end
            end
            #Add this tech to the tech-group "limit", if the tech_group is a key within the dictionary `techgroups_limit_inf`
            if haskey(config["infrastructure"],"limit")
              if in(tech_group_name,config["infrastructure"]["limit"])
                push!(set["tech"],"limit",tech)
              end
            end
          end
          #Push this tech to the set: `set[tech_unit]` - the unit describes if the capacity of this tech is either setup as power or energy capacity
          push!(set["tech"],techs[tech].unit,tech)
          #Push this tech to the set: `set[tech_structure]` - the structure describes if the capacity of this tech is either setup on a node or along a line
          push!(set["tech"],techs[tech].structure,tech)
          #Push the technology as an input-carrier
          if haskey(techs[tech].input, "carrier")
            #Add this technology to the group of the carrier
            push!(set["tech"],techs[tech].input["carrier"],tech)
          end
          #Push the technology as an output-carrier
          if haskey(techs[tech].output, "carrier")
            #Add this technology to the group of the carrier
            push!(set["tech"],techs[tech].output["carrier"],tech)
          end
        end
      end
      # Test if demand exists
      if intersect(set["tech"]["demand"], set["tech"]["exist_inf"])==Array{String,1}()
        @warn "No existing demand is provided - Ensure that `run_opt` option `infrastructure` is correct and looks like:  `Dict{String,Array}(\"existing\"=>[\"demand\", ...])` or `Dict{String,Array}(\"existing\"=>[\"all\"])`"
      end
      return set
end

"""
    setup_opt_set_carrier!(ts_data::ClustData,opt_data::CEPData,config::Dict{String,Any})
Add the entry set["carrier"]
"""
function setup_opt_set_carrier!(set::Dict{String,Dict{String,Array}},
                            opt_data::OptDataCEP,
                            config::Dict{String,Any})
      #`techs::OptVariable`: techs[tech] - OptDataCEPTech
      techs = opt_data.techs
      #Loop through all `tech`s to determine the input and output carriers for each `tech`
      for tech in set["tech"]["all"]
        #Push the technology as an input-carrier
        if haskey(techs[tech].input, "carrier")
          push!(set["carrier"],tech,techs[tech].input["carrier"])
        end
        #Push the technology as an output-carrier
        if haskey(techs[tech].output, "carrier")
          push!(set["carrier"],tech,techs[tech].output["carrier"])
        end
      end
      # Add an element containing all carriers
      set["carrier"]["all"]=unique(vcat(values(set["carrier"])...))
      # Add `carrier` to the tech-group `lost_load` if the carrier is a key within `lost_load_cost`
      set["carrier"]["lost_load"]=intersect(set["carrier"]["all"],keys(config["lost_load_cost"]))
      # Add groups same to the tech_groups to the carriers
      for (k,v) in set["tech"]
        for tech in v
            for carrier in set["carrier"][tech]
              push!(set["carrier"],k,carrier)
          end
        end
      end
      return set
end

"""
    setup_cep_opt_set_impact!(ts_data::ClustData,opt_data::CEPData,config::Dict{String,Any})
Add the entry set["impact"]
"""
function setup_opt_set_impact!(set::Dict{String,Dict{String,Array}},
                            opt_data::OptDataCEP,
                            config::Dict{String,Any})
      #`costs::OptVariable`: costs[tech,node,year,account,impact] - annulized costs [USD in USD/MW_el, CO2 in kg-CO₂-eq./MW_el]`
      costs = opt_data.costs

      ## IMPACT ##
      #Ensure that group `limit` and `lost_emission` exist empty
      set["impact"]["limit"]=Array{String,1}()
      set["impact"]["lost_emission"]=Array{String,1}()
      #Loop through all impacts
      for impact in axes(costs,"impact")
        #Add impacts to the set of all impacts
        push!(set["impact"],"all",impact)
        #The first impact shall always be monetary impact
        if impact==first(axes(costs,"impact"))
          push!(set["impact"],"mon",impact)
        #All other impacts are environmental impacts
        else
          push!(set["impact"],"env",impact)
        end
        #Add impact to tech-group `limit` if impact is a key within the `limit_emission`
        if haskey(config["limit_emission"],impact)
          push!(set["impact"],"limit",impact)
        end
        # Add impact to tech-group `lost_emission` if impact is a key within the `lost_emission_cost`
        if haskey(config["lost_emission_cost"],impact)
          push!(set["impact"],"lost_emission",impact)
        end
      end
      return set
end

"""
    get_opt_set_impact!(ts_data::ClustData,opt_data::CEPData,config::Dict{String,Any})
Add the entry set["impact"]
"""
function get_opt_set_names(config::Dict{String,Any})

      #Define all set-names that are always included
      set_names=["nodes", "carrier", "tech", "impact", "year", "account", "infrastruct", "time_K", "time_T_point", "time_T_period"]
      #Add set-names that are specific for certain configurations
      if config["transmission"]
        push!(set_names,"lines")
        push!(set_names,"dir_transmission")
      end
      if config["seasonalstorage"]
        push!(set_names,"time_I_point")
        push!(set_names,"time_I_period")
      end
      return set_names
end

"""
    setup_opt_sets(ts_data::ClustData,opt_data::CEPData,config::Dict{String,Any})
fetching sets from the time series (ts_data) and capacity expansion model data (opt_data) and returning dictionary `set`
The dictionary is organized as:
- `set[tech_name][tech_group]=[elements...]`
- `tech_name` is the name of the dimension like e.g. `tech`, or `node`
- `tech_group` is the name of a group of elements within each dimension like e.g. `["all", "generation"]`. The group `'all'` always contains all elements of the dimension
- `[elements...]` is the Array with the different elements like `["pv", "wind", "gas"]`
"""
function setup_opt_set(ts_data::ClustData,
                            opt_data::OptDataCEP,
                            config::Dict{String,Any})
  #`costs::OptVariable`: costs[tech,node,year,account,impact] - annulized costs [USD in USD/MW_el, CO2 in kg-CO₂-eq./MW_el]`
  costs = opt_data.costs
  #`techs::OptVariable`: techs[tech] - OptDataCEPTech
  techs = opt_data.techs
  #`nodes::OptVariable`: nodes[tech,node] - OptDataCEPNode
  nodes = opt_data.nodes
  #`lines::OptVarible`: lines[tech,line] - OptDataCEPLine
  lines = opt_data.lines

  #Create dictionaries for each set_name
  set=Dict{String,Dict{String,Array}}()
  for set_name in get_opt_set_names(config)
    set[set_name]=Dict{String,Array}()
  end
  # tech - dimension of elements that can do generate, transmit, store, or demand
  setup_opt_set_tech!(set,opt_data,config)
  # carrier - dimension of energy-carriers like `electricity`, `hydrogen`
  setup_opt_set_carrier!(set,opt_data,config)
  # impact - dimension of impact categories (first is monetary)
  setup_opt_set_impact!(set,opt_data,config)
  # node - dimension of spacial resolution for elements with nodal resolution
  set["nodes"]["all"]=axes(nodes,"node")
  # year - annual time dimension
  set["year"]["all"]=axes(costs,"year")
  # account - dimension of cost calculation: capacity&fixed costs that do not vary with the generated power or variable costs that do vary with generated power
  set["account"]["all"]=axes(costs,"account")
  if config["transmission"]
    # lines - dimension of spacial resolution for elements along lines
    set["lines"]["all"]=axes(opt_data.lines,"line")
    # dir_transmission - dimension of directions along a transmission line
    set["dir_transmission"]["all"]=["uniform","opposite"]
  end
  # infrastruct - dimension of status of infrastructure new or existing
  set["infrastruct"]["all"]=["new","ex"]
  # time_K - dimension of clustered time-series periods
  set["time_K"]["all"]=1:ts_data.K
  # time_T - dimension of time within each clustered time-series period:
  #                                         |-----|-----|...
  # either the number of periods            |<-1->|<-2->|...
  set["time_T_period"]["all"]=1:ts_data.T
  # or the number of the points in time    <0>---<1>---<2>...
  set["time_T_point"]["all"]=0:ts_data.T
  if config["seasonalstorage"]
    # time_I - dimension of time within the original timeseries throughout original periods
    # either the number of periods
    set["time_I_period"]["all"]=1:length(ts_data.k_ids)
    # or the number of the points in time
    set["time_I_point"]["all"]=0:length(ts_data.k_ids)
  end
  return set
end


text:
# common args for all multicounts tests
testargs = Dict(:γ=>1.0, :λminratio=>0.01, :verbose=>false,:showwarnings=>true)

counts1 = counts[:,:]
counts2 = counts1[:,:]
counts2[2:end,:] += counts1[1:end-1,:]
counts3 = counts2[:,:]
counts3[3:end,:] += counts1[1:end-2,:]
multicounts = [counts1, counts2, counts3]

dmrcoefs = dmr(covars, multicounts[1]; testargs...)

Z, multicoefs = mcdmr(covars, multicounts, projdir; testargs...)

# NOTE: something about @testset in windows makes the mcdmr call fail
# if it is inside the @testset block
@testset "mcdmr" begin

coefs = coef(dmrcoefs)
@test size(coefs) == (p+1, d)
@test coef(multicoefs[1]) == coefs
@test size(coef(multicoefs[2]),2) == size(coefs,2)
@test size(coef(multicoefs[2]),1) == size(coefs,1) + 2
@test size(coef(multicoefs[3]),2) == size(coefs,2)
@test size(coef(multicoefs[3]),1) == size(coefs,1) + 4

end


text: for i = (1 + true) : 4 end

max_stars_repo_name: gabriel-doriath-dohler/pjulia

max_issues_repo_name: gabriel-doriath-dohler/pjulia

max_forks_repo_name: gabriel-doriath-dohler/pjulia


text:
using Documenter, ImageAxes, SimpleTraits

makedocs(modules  = [ImageAxes],
         format   = Documenter.HTML(prettyurls = get(ENV, "CI", nothing) == "true"),
         sitename = "ImageAxes",
         linkcheck = !("skiplinks" in ARGS),
         pages    = ["index.md", "reference.md"])

deploydocs(
           repo   = "github.com/JuliaImages/ImageAxes.jl.git",
           )


text:
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# Description
# ==============================================================================
#
#   Functions related to ANSI escape sequences.
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

# Parse the ANSI code in `code` and return the updated decoration given the
# initial `decoration`.
function _parse_ansi_code(decoration::Decoration, code::String)
    tokens = split(code, ';')
    num_tokens = length(tokens)

    # Unpack fields.
    foreground = decoration.foreground
    background = decoration.background
    bold       = decoration.bold
    underline  = decoration.underline
    reset      = decoration.reset
    reversed   = decoration.reversed

    # `reset` must not be copied to other decorations. Hence, we need to reset
    # it here.
    reset = false

    i = 1
    while i ≤ num_tokens
        code_i = tryparse(Int, tokens[i], base = 10)
        isnothing(code_i) && continue

        if code_i == 0
            # If we have a reset, neglect all the other configurations.
            return Decoration(reset = true)

        elseif code_i == 1
            bold = active

        elseif code_i == 4
            underline = active

        elseif code_i == 7
            reversed = active

        elseif code_i == 22
            bold = inactive

        elseif code_i == 24
            underline = inactive

        elseif code_i == 27
            reversed = inactive

        elseif 30 <= code_i <= 37
            foreground = string(code_i)

        # 256-color / true-color (24-bit) support for foreground.
        elseif code_i == 38
            # Check if we have 256-color or true-color (24-bit) definition.
            if i + 1 ≤ num_tokens
                color_type = tryparse(Int, tokens[i + 1], base = 10)
                isnothing(color_type) && continue

                # 256-color mode.
                if color_type == 5
                    # In this case, we must have another token for the color.
                    if i + 2 ≤ num_tokens
                        color_code = tryparse(Int, tokens[i + 2], base = 10)
                        isnothing(color_code) && continue

                        foreground = "38;5;" * string(color_code)
                        i += 2
                    end

                # True-color (24-bit) mode.
                elseif color_type == 2
                    # In this case, we must have another three tokens for the
                    # RGB color.
                    if i + 4 ≤ num_tokens
                        color_r = tryparse(Int, tokens[i + 2], base = 10)
                        isnothing(color_r) && continue

                        color_g = tryparse(Int, tokens[i + 3], base = 10)
                        isnothing(color_g) && continue

                        color_b = tryparse(Int, tokens[i + 4], base = 10)
                        isnothing(color_b) && continue

                        foreground =
                            "38;2;" *
                            string(color_r) * ";" *
                            string(color_g) * ";" *
                            string(color_b)

                        i += 4
                    end
                end
            end

        elseif code_i == 39
            foreground = "39"

        elseif 40 <= code_i <= 47
            background = string(code_i)

        # 256-color / truecolor support for background.
        elseif code_i == 48
            # Check if we have 256-color or truecolor definition.
            if i + 1 ≤ num_tokens
                color_type = tryparse(Int, tokens[i + 1], base = 10)
                isnothing(color_type) && continue

                # 256-color mode.
                if color_type == 5
                    # In this case, we must have another token for the color.
                    if i + 2 ≤ num_tokens
                        color_code = tryparse(Int, tokens[i + 2], base = 10)
                        isnothing(color_code) && continue

                        background = "48;5;" * string(color_code)
                        i += 2
                    end

                # Truecolor mode.
                elseif color_type == 2
                    # In this case, we must have another three tokens for the
                    # RGB color.
                    if i + 4 ≤ num_tokens
                        color_r = tryparse(Int, tokens[i + 2], base = 10)
                        isnothing(color_r) && continue

                        color_g = tryparse(Int, tokens[i + 3], base = 10)
                        isnothing(color_g) && continue

                        color_b = tryparse(Int, tokens[i + 4], base = 10)
                        isnothing(color_b) && continue

                        background =
                            "48;2;" *
                            string(color_r) * ";" *
                            string(color_g) * ";" *
                            string(color_b)

                        i += 4
                    end
                end
            end

        elseif code_i == 49
            background = "49"

        # Bright foreground colors defined by Aixterm.
        elseif 90 <= code_i <= 97
            foreground = string(code_i)

        # Bright background colors defined by Aixterm.
        elseif 100 <= code_i <= 107
            background = string(code_i)

        end

        i += 1
    end

    return Decoration(
        foreground,
        background,
        bold,
        underline,
        reset,
        reversed
    )
end


text:
"""
    unitcircle(ndirection; half = false, normal = [0, 0, 1])

Create `ndirection` directions unformly distributed on the unit circle defined by `normal`.

If `half` is `true`, the directions lie on a half-circle instead of the whole circle.
"""
function unitcircle(n; half = false, normal = [0, 0, 1])
    # Create directions (unformly distributed on unit circle)
    θ = 2π * collect(0:n-1)' / (1 + half)n
    directions = [
        cos.(θ)
        sin.(θ)
        zeros(1, ndirection)
    ]

    # Create rotation matrix to transform normal to e_z
    normal = normal / norm(normal)
    c = normal + [0, 0, 1]
    R = 2(c * c') / c'c - I(3)
    normal ≈ [0, 0, 1] || (directions = R'directions)

    directions
end


text:
s = "world!"
s = "Hello " * s

max_stars_repo_name: ethansaxenian/RosettaDecode

max_issues_repo_name: ethansaxenian/RosettaDecode

max_forks_repo_name: ethansaxenian/RosettaDecode


text:
using SpinMonteCarlo
using Makie

latplot(lat::Lattice) = latplot(lat, Val{dim(lat)})

function latplot(lat::Lattice, ::Type{Val{1}})
    points = Point2f0[]
    minx = Inf
    maxx = -Inf
    for site in sites(lat)
        c = sitecoordinate(site)[1]
        push!(points, Point2(c,0))
        minx = min(minx, c)
        maxx = max(maxx, c)
    end
    limits = FRect(minx-1.0, -1.0, maxx-minx+2.0, 2.0)
    segments = Pair{Point2f0, Point2f0}[]
    for bond in bonds(lat)
        src = sitecoordinate(lat, source(bond))[1]
        tgt = bonddirection(bond)[1] + src
        push!(segments, Point2f0(src,0)=>Point2f0(tgt,0))
    end
    scene = scatter(points, limits=limits)
    linesegments!(scene, segments, limits=limits)
    axis = scene[Axis]
    axis[:names, :axisnames] = ("", "")
    axis[:frame, :linewidth] = 0.0
    axis[:grid, :linewidth] = (0.0, 0.0)
    scene
end

function latplot(lat::Lattice, ::Type{Val{2}})
    points = Point2f0[]
    minx = miny = Inf
    maxx = maxy = -Inf
    for site in sites(lat)
        c = sitecoordinate(site)
        push!(points, Point2f0(c))
        minx = min(minx, c[1])
        maxx = max(maxx, c[1])
        miny = min(miny, c[2])
        maxy = max(maxy, c[2])
    end
    limits = FRect(minx-1.0, miny-1.0, maxx-minx+2.0, maxy-miny+2.0)
    segments = Pair{Point2f0, Point2f0}[]
    for bond in bonds(lat)
        src = sitecoordinate(lat, source(bond))
        tgt = bonddirection(bond) .+ src
        push!(segments, Point2f0(src)=>Point2f0(tgt))
    end
    scene = scatter(points, limits=limits)
    linesegments!(scene, segments, limits=limits)
    axis = scene[Axis]
    axis[:names, :axisnames] = ("", "")
    axis[:frame, :linewidth] = 0.0
    axis[:grid, :linewidth] = (0.0, 0.0)
    scene
end

function latplot(lat::Lattice, ::Type{Val{3}})
    points = Point3f0[]
    minx = miny = minz = Inf
    maxx = maxy = maxz = -Inf
    for site in sites(lat)
        c = sitecoordinate(site)
        push!(points, Point3f0(c))
        minx = min(minx, c[1])
        maxx = max(maxx, c[1])
        miny = min(miny, c[2])
        maxy = max(maxy, c[2])
        minz = min(minz, c[3])
        maxz = max(maxz, c[3])
    end
    segments = Pair{Point3f0, Point3f0}[]
    for bond in bonds(lat)
        src = sitecoordinate(lat, source(bond))
        tgt = bonddirection(bond) .+ src
        push!(segments, Point3f0(src)=>Point3f0(tgt))
    end
    scene = scatter(points)
    linesegments!(scene, segments)
    axis = scene[Axis]
    axis[:names, :axisnames] = ("", "", "")
    axis[:frame, :linewidth] = 0.0
    scene
end


text:
abstract type AbstractMap end
Line_Circle = Union{Line,Circle}

"""
	(type) Möbius
Representation of a Möbius or bilinear transformation.
"""
struct Möbius <: AbstractMap
	# interpreted as [a,b,c,d], where f(z)=(az+b)/(cz+d)
	coeff::SVector{4}
end

#
# Construction
#

const Mobius = Möbius   # for us lazy Americans
"""
	Möbius(a,b,c,d)
Construct the `Möbius` map ``z ↦ (az+b)/(cz+d)`` by giving its coefficients.
"""
Möbius(a::Number,b::Number,c::Number,d::Number) = Möbius(SVector(a,b,c,d))

"""
	Möbius(A::AbstractMatrix)
Construct the `Möbius` map ``z ↦ (az+b)/(cz+d)`` by giving a matrix `A==[a b;c d]`.
"""
Möbius(A::AbstractMatrix) = Möbius(SVector(A[1,1],A[1,2],A[2,1],A[2,2]))

"""
	Möbius(z::AbstractVector,w::AbstractVector)
Construct the `Möbius` map that transforms the points `z[k]` to `w[k]` for k=1,2,3.
Values of `Inf` are permitted in both vectors.
"""
function Möbius(source::AbstractVector,image::AbstractVector)
	# finds the coeffs of map from (0,1,Inf) to given points
	function standard(x,y,z)
		if isinf(x)
			return z,y-z,1,0
		elseif isinf(y)
			return -z,x,-1,1
		elseif isinf(z)
			return y-x,x,0,1
		else
			xy,yz = y-x,z-y
			return z*xy,x*yz,xy,yz
		end
	end

	za,zb,zc,zd = standard(source...)
	wa,wb,wc,wd = standard(image...)
	A = SMatrix{2,2}(wa,wc,wb,wd)*SMatrix{2,2}(zd,-zc,-zb,za)
	return Möbius(A[1,1],A[1,2],A[2,1],A[2,2])
end

"""
	Möbius(C1,C2)
Construct a `Möbius` map that transforms the curve `C1` to `C2`. Both curves must be either a `Line` or `Circle`. (These maps are not uniquely determined.)
"""
Möbius(c1::Line_Circle,c2::Line_Circle) = Möbius(point(c1,[0,0.25,0.5]),point(c2,[0,0.25,0.5]))

#
# Evaluation
#
"""
	f(z::Number)
Evaluate the `Möbius` map `f` at a real or complex value `z`.
"""
function (f::Möbius)(z::Number)
	a,b,c,d = f.coeff
	if isinf(z)
		num,den = a,c
	else
		num,den = a*z+b,c*z+d
	end
	# note: 1 over complex zero is NaN, not Inf
	iszero(den) ? complex(abs(num)/abs(den)) : num/den
end

"""
	f(C::Union{Circle,Line})
Find the image of the circle or line `C` under the `Möbius` map `f`. The result is also either a `Circle` or a `Line`.
"""
(f::Möbius)(C::Line_Circle) = Circle( f.(point(C,[0,0.25,0.5]))... )
"""
	f(C::Union{Arc,Segment})
Find the image of the arc or segment `C` under the `Möbius` map `f`. The result is also either an `Arc` or a `Segment`.
"""
(f::Möbius)(C::Union{Arc,Segment}) = Arc( f.(point(C,[0,0.5,1]))... )

"""
	f(R::Union{AbstractDisk,AbstractHalfplane})
If `R` is an `AbstractDisk` or an `AbstractHalfplane`, find its image under the `Möbius` map `f`. The result is also either an `AbstractDisk` or an `AbstractHalfplane`.
# Examples
```julia-repl
julia> f = Möbius(Line(-1,1),Circle(0,1))
Möbius transformation:

   (1.0 + 0.9999999999999999im) z + (3.666666666666666 - 1.666666666666667im)
   ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
   (1.0 + 0.9999999999999999im) z + (-1.666666666666666 + 3.6666666666666665im)

julia> f(upperhalfplane)
Disk interior to:
   Circle(-5.55112e-17+2.22045e-16im,1.0)

julia> isapprox(ans,unitdisk)
true
```
"""
(f::Möbius)(R::Union{AbstractDisk,AbstractHalfplane}) = interior(f(R.boundary))

"""
	inv(f::Möbius)
Find the inverse of a `Möbius` transformation. This is the functional inverse, not 1/f(z).
"""
inv(f::Möbius) = Möbius(f.coeff[4],-f.coeff[2],-f.coeff[3],f.coeff[1])

"""
	∘(f::Möbius,g::Möbius)
Compose two `Möbius` transformations.
"""
function ∘(f::Möbius,g::Möbius)
	A = SMatrix{2,2}(f.coeff[1],f.coeff[3],f.coeff[2],f.coeff[4])
	B = SMatrix{2,2}(g.coeff[1],g.coeff[3],g.coeff[2],g.coeff[4])
	C = A*B
	Möbius(C[1,1],C[1,2],C[2,1],C[2,2])
end

#
# Display
#

function show(io::IO,f::Möbius)
	a,b,c,d = f.coeff
	print(IOContext(io,:compact=>true),"Möbius map z --> (($a)*z + $b) / (($c)*z + $d)")
end

function show(io::IO,::MIME"text/plain",f::Möbius)
	a,b,c,d = [repr("text/plain",x) for x in f.coeff]
	numer = "("*a*") z + ("*b*")"
	denom = "("*c*") z + ("*d*")"
	hline = reduce(*,fill("–",max(length(numer),length(denom))))
	print(io,"Möbius transformation:\n\n   ",numer,"\n   ",hline,"\n   ",denom)
end


text:
"""Save all data types of one HRS site.
"""

using HydroRefStations
using CSV

hrs = HRS()

awrc_id = "410730" # Cotter River at Gingera
for (tscale, data_types) in hrs.data_types
    for data_type in data_types
        data, header = get_data(hrs, awrc_id, data_type)
        tag = join(split(data_type), "_")
        data |> CSV.write("st_$(awrc_id)_$(tag).csv")
    end
end


text:
module FixedEffectModels

##############################################################################
##
## Dependencies
##
##############################################################################
using Base
using LinearAlgebra
using Statistics
using Printf
using FillArrays
using DataFrames
using Distributions
using Reexport
@reexport using StatsBase
@reexport using StatsModels

using FixedEffects

##############################################################################
##
## Exported methods and types
##
##############################################################################

export reg,
partial_out,
fe,

FixedEffectModel,
has_iv,
has_fe,

Vcov,

#deprecated
@model,
fes

##############################################################################
##
## Load files
##
##############################################################################
include("vcov/Vcov.jl")

include("utils/fixedeffects.jl")
include("utils/basecol.jl")
include("utils/tss.jl")
include("utils/ranktest.jl")
include("utils/formula.jl")

include("FixedEffectModel.jl")
include("fit.jl")
include("partial_out.jl")

include("deprecated.jl")
# precompile script
df = DataFrame(y = [1, 1], x =[1, 2], id = [1, 1])
reg(df, @formula(y ~ x + fe(id)))
reg(df, @formula(y ~ x), Vcov.cluster(:id))

end  # module FixedEffectModels


text:
function StopOnDecreasing()
    return StopOnDecreasing(())
end

function event_occurred(obj::StopOnDecreasing, arg0::SpacecraftState, arg1::EventDetector, arg2::jboolean)
    return jcall(obj, "eventOccurred", Action, (SpacecraftState, EventDetector, jboolean), arg0, arg1, arg2)
end


text:
add_attributes!(mol, attrs::Dict{Symbol}) = (merge!(mol.attributes, attrs); return mol)
add_attributes!(mol, allattrs::Dict{Int}) = add_attributes!(mol, allattrs[parse(Int, mol.attributes[:PUBCHEM_COMPOUND_CID])])

attributes(mol::UndirectedGraph) = mol.attributes
attributes(mol::UndirectedGraph, key::Symbol) = mol.attributes[key]

Base.zeros(mol::Union{UndirectedGraph,SubgraphView}) = Dict(zip(nodeset(mol), zeros(length(nodeset(mol)))))
Base.ones(mol::Union{UndirectedGraph,SubgraphView}) = Dict(zip(nodeset(mol), ones(length(nodeset(mol)))))

const_dict(val, mol::Union{UndirectedGraph,SubgraphView}) = Dict(zip(nodeset(mol), fill(val, length(nodeset(mol)))))


text:
mutable struct hydro_vars
    U1D::Array{Float64,2}
    U1D_p::Array{Float64,2}
    U1D_c::Array{Float64,2}
    F1D::Array{Float64,2}
    G1D::Array{Float64,2}
    R1D::Array{Float64,2}
    C1D::Array{Float64,2}
    rho::Array{Float64,2}
    u::Array{Float64,2}
    T::Array{Float64,2}
    p::Array{Float64,2}
    Efield::Array{Float64,1}
    ni::Array{Float64,2}
    ne::Array{Float64,1}

    function hydro_vars(nz::Int64, nspec::Int64, neqi::Int64)
        U1D = zeros(Float64, nz, neqi+1)
        U1D_p = zeros(Float64, nz, neqi+1)
        U1D_c = zeros(Float64, nz, neqi+1)
        F1D = zeros(Float64, nz, neqi+1)
        G1D = zeros(Float64, nz, neqi+1)
        R1D = zeros(Float64, nz, neqi + 1)
        C1D = zeros(Float64, nz, neqi)
        p = zeros(Float64, nz, nspec+1)
        u = zeros(Float64, nz, nspec+1)
        rho = zeros(Float64, nz, nspec+1)
        T = zeros(Float64, nz, nspec+1)
        Efield = zeros(Float64, nz)
        ni = zeros(Float64, nz, nspec)
        ne = zeros(Float64, nz)

        new(
            U1D,
            U1D_p,
            U1D_c,
            F1D,
            G1D,
            R1D,
            C1D,
            p,
            u,
            rho,
            T,
            Efield,
            ni,
            ne
        )
    end
end

max_stars_repo_name: cbellei/JUPL

max_issues_repo_name: cbellei/JUPL

max_forks_repo_name: cbellei/JUPL


text:
mutable struct DelayDirectJumpAggregation{T,S,F1,F2,RNG,IType} <: AbstractDSSAJumpAggregator
    next_jump::Int
    prev_jump::Int
    next_jump_time::T
    end_time::T
    cur_rates::Vector{T} # cur_rates here is the cumsum of rates
    sum_rate::T
    ma_jumps::S
    rates::F1
    affects!::F2
    save_positions::Tuple{Bool,Bool}
    rng::RNG
    next_delay::Union{Nothing,Vector{Int}}
    num_next_delay::Union{Nothing,Vector{Int}}
    time_to_next_jump::T
    shadow_integrator::IType
end
mutable struct Shadow_Integrator{uType,chanType}
    u::uType
    de_chan::chanType
    delayjumpsets::DelayJumpSet
end
function DelayDirectJumpAggregation(nj::Int, njt::T, et::T, crs::Vector{T}, sr::T, maj::S, rs::F1, affs!::F2, sps::Tuple{Bool,Bool}, rng::RNG; u0, kwargs...) where {T,S,F1,F2,RNG}
    ttnj = zero(et)
    shadow_integrator = Shadow_Integrator{typeof(u0),Vector{Vector{T}}}(copy(u0),[Vector{T}()],DelayJumpSet(Dict(),Dict(),Dict()))
    nd = nothing
    nnd = [1] # in the Direct Method the number of next delay equals always 1
    DelayDirectJumpAggregation{T,S,F1,F2,RNG,typeof(shadow_integrator)}(nj, nj, njt, et, crs, sr, maj, rs, affs!, sps, rng, nd, nnd, ttnj, shadow_integrator)
end

function aggregate(aggregator::DelayDirect, u, p, t, end_time, constant_jumps,
    ma_jumps, save_positions, rng; kwargs...)

    # handle constant jumps using function wrappers
    rates, affects! = get_jump_info_fwrappers(u, p, t, constant_jumps)
    build_jump_aggregation(DelayDirectJumpAggregation, u, p, t, end_time, ma_jumps,
                           rates, affects!, save_positions, rng; u0 = copy(u), kwargs...)
end

function initialize!(p::DelayDirectJumpAggregation, integrator, u, params, t)
    p.shadow_integrator.delayjumpsets = integrator.delayjumpsets
    generate_jumps!(p, integrator, u, params, t)
    nothing
end

@inline function execute_jumps!(p::DelayDirectJumpAggregation, integrator, u, params, t)
    update_state_delay_Direct!(p, integrator, integrator.u, t)
    nothing
end

function generate_jumps!(p::DelayDirectJumpAggregation, integrator, u, params, t)
    generate_delta!(p, integrator, params, t)
    @fastmath p.next_jump_time = t + p.time_to_next_jump
    @inbounds p.next_jump = searchsortedfirst(p.cur_rates, rand(p.rng) * p.sum_rate) #
    nothing
end
"""
    Create delta based on the shawdow variable u_shadow
"""
@inline function generate_delta!(p::DelayDirectJumpAggregation, integrator, params, t)
    @unpack delay_complete = integrator.delayjumpsets
    p.shadow_integrator.u = copy(integrator.u) #TODO
    p.shadow_integrator.de_chan = deepcopy(integrator.de_chan) #TODO

    fill_cum_rates_and_sum!(p, p.shadow_integrator.u, params, t)
    r1 = rand(p.rng)
    if isempty(reduce(vcat,integrator.de_chan))
        ttnj = -log(r1)/p.sum_rate
    else
        T1, T2 = create_Tstruct(integrator.de_chan)
        prepend!(T1,zero(t))
        append!(T1,Inf)
        i = 1
        aₜ = p.sum_rate*T1[2]
        F = 1 - exp(-aₜ)
        u_ = copy(p.shadow_integrator.u)
        de_chan_ = deepcopy(p.shadow_integrator.de_chan)
        aₜ_ = zero(aₜ)
        while F < r1
            p.next_delay = [T2[i]]
            update_delay_complete!(p, p.shadow_integrator)

            # backup the u and de_chan before the next update delay complete
            u_ = copy(p.shadow_integrator.u)
            de_chan_ = deepcopy(p.shadow_integrator.de_chan)
            aₜ_ = copy(aₜ)

            sum_rate_ = calculate_sum_rate(p, u_, params, t+T1[i+1])
            aₜ += sum_rate_*(T1[i+2]-T1[i+1])
            F = 1 - exp(-aₜ)
            i += 1
        end
        p.sum_rate = calculate_sum_rate(p, u_, params, t+T1[i])
        ttnj = T1[i]+(-log(1-r1) - aₜ_)/p.sum_rate
        if i > 1
            p.shadow_integrator.u = copy(u_)
            p.shadow_integrator.de_chan = deepcopy(de_chan_)
        end
    end
    shift_delay_channel!(p.shadow_integrator.de_chan, ttnj)
    update_delay_channel!(p.shadow_integrator.de_chan)
    fill_cum_rates_and_sum!(p, p.shadow_integrator.u, params, t+ttnj)
    p.time_to_next_jump = ttnj
end

@inbounds function update_state_final_jump!(p, integrator, tgap, T1, T2)
    idx = count(x->x<=tgap, T1)
    if idx >=1
        for i in 1:idx
            p.next_delay = [T2[i]]
            update_delay_complete!(p, integrator)
        end
        deleteat!(T1, 1:idx)
        deleteat!(T2, 1:idx)
    end
    T1 .-= tgap
end

"""
    function fill_cum_rates_and_sum!(p::DelayDirectJumpAggregation, u, params, t)

This function modifies `p.cur_rates` and `p.sum_rate`
"""
function fill_cum_rates_and_sum!(p::DelayDirectJumpAggregation, u, params, t)
    prev_rate = zero(t)
    new_rate  = zero(t)
    cur_rates = p.cur_rates
    # mass action rates
    majumps   = p.ma_jumps
    idx       = get_num_majumps(majumps)
    @inbounds for i in 1:idx
        new_rate     = evalrxrate(u, i, majumps)
        cur_rates[i] = new_rate + prev_rate
        prev_rate    = cur_rates[i]
    end
    # constant jump rates
    idx  += 1
    rates = p.rates
    @inbounds for i in 1:length(p.rates)
      new_rate       = rates[i](u, params, t)
      cur_rates[idx] = new_rate + prev_rate
      prev_rate      = cur_rates[idx]
      idx           += 1
    end

    @inbounds sum_rate = cur_rates[end]
    p.sum_rate = sum_rate
    nothing
end

function calculate_sum_rate(p::DelayDirectJumpAggregation, u,  params, t)
    prev_rate = zero(t)
    new_rate  = zero(t)
    cur_rates = zeros(length(p.cur_rates))
    majumps = p.ma_jumps
    idx       = get_num_majumps(majumps)
    @inbounds for i in 1:idx
        new_rate     = evalrxrate(u, i, majumps)
        cur_rates[i] = new_rate + prev_rate
        prev_rate    = cur_rates[i]
    end
    # constant jump rates
    idx  += 1
    rates = p.rates
    @inbounds for i in 1:length(p.rates)
      new_rate       = rates[i](u, params, t)
      cur_rates[idx] = new_rate + prev_rate
      prev_rate      = cur_rates[idx]
      idx           += 1
    end
    cur_rates[end]
end
"""
    function create_Tstruct(de_chan::Vector{Vector{T}})

calculate `Tstruct` according to the de_chan.
"""
function create_Tstruct(de_chan::Vector{Vector{T}}) where {T}
    N = sum(length.(de_chan))
    Tstruct1 = Vector{T}(undef,N)
    Tstruct2 = Vector{Int64}(undef,N)
    k = 1
    @inbounds while k <= N
        for i in eachindex(de_chan)
            for j in eachindex(de_chan[i])
                Tstruct1[k] = de_chan[i][j]
                Tstruct2[k] = i
                k += 1
            end
        end
    end
    vecorder = sortperm(Tstruct1)
    Tstruct1 = Tstruct1[vecorder]
    Tstruct2 = Tstruct2[vecorder]
    Tstruct1, Tstruct2
end

@inline function update_state_delay_Direct!(p::DelayDirectJumpAggregation, integrator, u, t)
    @unpack ma_jumps, next_jump, time_to_next_jump = p
    @unpack delay_trigger_set, delay_interrupt_set = integrator.delayjumpsets

    integrator.u = copy(p.shadow_integrator.u)
    integrator.de_chan = deepcopy(p.shadow_integrator.de_chan)

    num_ma_rates = get_num_majumps(ma_jumps)
    if next_jump <= num_ma_rates # if the next jump is a mass action jump
        if u isa SVector
            integrator.u = executerx(u, next_jump, ma_jumps)
        else
            @inbounds executerx!(integrator.u, next_jump, ma_jumps)
        end
    else
        idx = next_jump - num_ma_rates
        @inbounds p.affects![idx](integrator)
    end

    if next_jump in delay_interrupt_set
        update_delay_interrupt!(p, integrator)
    elseif next_jump in delay_trigger_set
        update_delay_trigger!(p, integrator)
    end
    # save jump that was just executed
    p.prev_jump = next_jump
    nothing
end


text:
# Common Utils

function resid2DLinear(μ, mus, Lambdas; diffop::Function=-)  # '-' exploits EuclideanManifold commutativity a-b = b-a
  dμ = broadcast(diffop, μ, mus)  # mus .- μ  ## μ .\ mus
  # @show round.(dμ, digits=4)
  ret = sum( Lambdas.*dμ )
  return ret
end

function solveresid2DLinear!(res, x, mus, Lambdas; diffop::Function=-)::Nothing
  res[1] = resid2DLinear(x, mus, Lambdas, diffop=diffop)
  nothing
end

# import ApproxManifoldProducts: resid2DLinear, solveresid2DLinear
function solveresid2DLinear(res, x, mus, Lambdas; diffop::Function=-)::Float64
  solveresid2DLinear!(res, x, mus, Lambdas, diffop=diffop)
  return res[1]
end
#
# """
#     $SIGGNATURES
#
# Assemble oplus and ominus operations from given manifols.
#
# Related
#
# buildHybridManifoldCallbacks
# """
# function getManifoldOperations(manis::T) where {T <: Tuple}
#
# end
#

#


text:
using RandomVariates
using Test

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


text:
export simple_func

simple_func(x, y) = 2x + 3y;


text:
using IcanProj
using JLD2

"""
Load input variables directly from the forcing files.
"""
function load_from_forcings(watershed, resolution, res_vic, opt)

    # Path to model forcings for the given resolution

    if resolution == "1km"
        path_forcing = joinpath(opt["base_folder"])
    else
        path_forcing = joinpath(opt["target_folder"], watershed, resolution)
    end

    # Read one forcing file to get the size

    lat = @sprintf("%0.5f", res_vic.lat[1])
    lon = @sprintf("%0.5f", res_vic.lon[1])

    file_src = joinpath(path_forcing, "forcing/data_$(lat)_$(lon)")

    prec, tmin, tmax, wind = read_vic_forcing(file_src)

    # Allocate arrays

    prec_array = zeros(Float64, length(prec), length(res_vic.lat))
    tmin_array = zeros(Float64, length(prec), length(res_vic.lat))
    tmax_array = zeros(Float64, length(prec), length(res_vic.lat))
    wind_array = zeros(Float64, length(prec), length(res_vic.lat))

    # Read rest of forcing files

    for i in 1:length(res_vic.lat)

        lat = @sprintf("%0.5f", res_vic.lat[i])
        lon = @sprintf("%0.5f", res_vic.lon[i])

        file_src = joinpath(path_forcing, "forcing/data_$(lat)_$(lon)")

        prec, tmin, tmax, wind = read_vic_forcing(file_src)

        prec_array[:, i] = prec
        tmin_array[:, i] = tmin
        tmax_array[:, i] = tmax
        wind_array[:, i] = wind

    end

    return prec_array, tmin_array, tmax_array, wind_array

end

# Get settings

opt = get_options()

resolutions = opt["resolutions"]

watersheds = opt["stat_sel"]

# Process all results

for watershed in watersheds

    for resolution in resolutions

        # Load simulation results

        file = joinpath(opt["eval_folder"], watershed, "res_$(resolution).jld2")

        @load file res_vic

        # Load forcing files

        prec_input, tmin_input, tmax_input, wind_input = load_from_forcings(watershed, resolution, res_vic, opt)
        info("$(watershed) $(resolution)")

        # Compare precipitation

        iprec = find(res_vic.var_names .== "prec")

        prec_output = res_vic.data_all[:, iprec[1], :]

        check = all(round.(prec_input,2) .== round.(prec_output,2))

        info("Precipitation $(check) $(mean(prec_output))")

        # Compare air temperature (not useful to check exact match due to interpolation within mtclim)

        iair = find(res_vic.var_names .== "air_temp")

        air_output = res_vic.data_all[:, iair[1], :]

        air_input = (tmin_input + tmax_input)/2

        info("Air temperature $(round(mean(abs.(air_output-air_input)),1))")

        # Compare wind speed

        iwind = find(res_vic.var_names .== "wind")

        wind_output = res_vic.data_all[:, iwind[1], :]

        check = all(round.(wind_input,2) .== round.(wind_output,2))

        info("Wind $(watershed) $(mean(wind_output))\n\n\n")

    end

end


text:
## Excel

@info "XLSX.jl is available - including functionality to read / write Excel (xlsx) files"

using .XLSX

function read_table(::ExcelFormat, filename:: AbstractString, sheetname:: AbstractString; kwargs...)
    f = XLSX.readxlsx(filename)
    sheet = f[sheetname]
    return XLSX.eachtablerow(sheet)
end

function read_table(::ExcelFormat, filename:: AbstractString; kwargs...)
    f = XLSX.readxlsx(filename)
    sheet = first(f.workbook.sheets)
    return DataFrame(XLSX.eachtablerow(sheet); copycols=false) # this would be no valid Table.jl output if not converted to DataFrame
end

function write_table!(::ExcelFormat, filename:: AbstractString, sheetname:: AbstractString, table:: DataFrame; kwargs...)
    _checktable(table)
    XLSX.writetable(filename, table; overwrite=true, sheetname=sheetname, kwargs...)
    nothing
end

const DEFAULT_SHEETNAME = "sheet_1"
write_table!(::ExcelFormat, filename:: AbstractString, table; kwargs...) = write_table!(ExcelFormat(), filename, DEFAULT_SHEETNAME, table; kwargs...)

# XLSX supports only DataFrames, not arbitrary Tables.jl inputs. For export, the table is converted to a DataFrame first.
write_table!(::ExcelFormat, filename:: AbstractString, sheetname:: AbstractString, table; kwargs...) = write_table!(ExcelFormat(), filename:: AbstractString, sheetname:: AbstractString, DataFrame(table); kwargs...)


text:
module PoleExpansion

using JuLIP, NearestNeighbors
import JuLIPMaterials
using JuLIPMaterials: findin2

⊗(x, y) = x * y'

"""
`findin(Xsm, Xlge)`

Assuming that `Xsm ⊂ Xlge`, this function
returns `Ism, Ilge`, both `Vector{Int}` such that
* Xsm[i] == Xlge[Ism[i]]
* Xlge[i] == Xsm[Ilge[i]]  if Xlge[i] ∈ Xsm; otherwise Ilge[i] == 0
"""
function findin3(Xsm, Xlge)
   # find the nearest neighbours of Xsm points in Xlge
   tree = KDTree(Xlge)
   # construct the Xsm -> Xlge mapping
   Ism = zeros(Int, length(Xsm))
   Ilge = zeros(Int, length(Xlge))
   for (n, x) in enumerate(Xsm)
      i = inrange(tree, Xsm[n], 1e-6)
      if isempty(i)
         Ism[n] = 0         # - Ism[i] == 0   if  Xsm[i] ∉ Xlge
      elseif length(i) > 1
         error("`inrange` found two neighbours")
      else
         Ism[n] = i[1]      # - Ism[i] == j   if  Xsm[i] == Xlge[j]
         Ilge[i[1]] = n     # - Ilge[j] == i  if  Xsm[i] == Xlge[j]
      end
   end
   # - if Xlge[j] ∉ Xsm then Ilge[j] == 0
   return Ism, Ilge
end

"""
* at : unrelaxed point defect configuration
* athom : homogeneous reference configuration

at the moment it is assumed both are spherical clusters
"""
function dipole_tensor(at, athom;
   Iin = :ball, Rin = :auto, x0 = mean(positions(athom)),
   h = 1e-5, kwargs...)

   # setup
   V = calculator(at)
   X0hom = positions(athom)
   X0 = positions(at)

   # relax the defect
   minimise!(at; kwargs...)
   X = positions(at)
   U = X - X0

   # compute the at -> athom mapping ...
   Ism, Ilge = findin3(X0, X0hom)
   # ... and the relative displacement
   Uhom = zeros(JVecF, length(athom))
   for n = 1:length(Ilge)
      if Ilge[n] != 0
         Uhom[n] = U[Ilge[n]]
      end
   end

   # compute the linearised forces in athom
   Flin = ( forces(V, set_positions!(athom, X0hom + h*Uhom)) -
            forces(V, set_positions!(athom, X0hom - h*Uhom)) ) / (2*h)

   # extract the sub-domain on which to compute the tensors
   if Iin == :ball
      r = [ norm(x - x0) for x in X0hom ]
      if Rin == :auto
         Rin = 0.6 * (maximum(r) - 2*cutoff(V))
      end
      Iin = find(r .< Rin)
   end

   return  sum( Flin[Iin] ),
           sum( f * (x - x0)'   for (f, x) in zip(Flin[Iin], X0hom[Iin]) )
end

end


text:
function Base.show(io::IO, ::MIME"text/plain", t::T) where {T <: Union{Table,FlexTable}}
    showtable(io, t)
end
function Base.show(io::IO, t::T) where {T <: Union{Table,FlexTable}}
    showtable(io, t)
end

showtable(t; kwargs...) = showtable(stdout, t; kwargs...)

function showtable(io::IO, t::T;
                   allcols::Bool=true,
                   splittable::Bool=true,
                   rowlabel::Symbol=:Row,
                   compact::Bool=true,
                   allrows::Bool=false,
                   displaysummary::Bool=true) where {T<:Union{Table,FlexTable}}
    col_lengths = [length(c) for c in columns(t)]
    if length(col_lengths) > 0
        @assert all(isequal(col_lengths[1]), col_lengths) "table columns must be same length"
    end
    if compact
        io = IOContext(io, :compact=>compact)
    end
    nrows = size(t)[1]
    disp_rows, disp_cols = displaysize(io)
    disp_max_rows = allrows ? 10^6 : disp_rows - 5
    if nrows <= disp_max_rows
        rowindices1 = 1:nrows
        rowindices2 = 1:0
    else
        half_max_rows = disp_max_rows ÷ 2
        bound = min(half_max_rows - 1, nrows)
        rowindices1 = 1:bound
        rowindices2 = max(bound + 1, nrows - half_max_rows + 1):nrows
    end
    maxwidths = getmaxwidths(io, t, rowindices1, rowindices2, rowlabel)
    showrows(io,
             t,
             rowindices1,
             rowindices2,
             maxwidths,
             splittable,
             allcols,
             rowlabel,
             displaysummary)
    return
end

function showrows(io::IO,
                  t::T,
                  rowindices1::AbstractVector{Int},
                  rowindices2::AbstractVector{Int},
                  maxwidths::AbstractVector{Int},
                  splittable::Bool = true,
                  allcols::Bool = true,
                  rowlabel::Symbol = :Row,
                  displaysummary::Bool = true) where {T <: Union{Table, FlexTable}}

    if isempty(rowindices1)
        if displaysummary
            println(io, summary(t))
        end
        return
    end

    ncols = length(columnnames(t))
    labelmaxwidth = maxwidths[end]
    chunkbounds = getchunkbounds(maxwidths, splittable, displaysize(io)[2])
    nchunks = allcols ? length(chunkbounds) - 1 : min(length(chunkbounds) - 1, 1)

    # Print summary:
    if displaysummary
        println(io, summary(t))
    end

    for chunkindex in 1:nchunks
        leftcol = chunkbounds[chunkindex] + 1
        rightcol = chunkbounds[chunkindex + 1]

        # Print column names
        print(io, "│ ", rowlabel)
        padding = labelmaxwidth - ourstrwidth(rowlabel)
        print(io, " " ^ padding)
        print(io, " │")

        for c in leftcol:rightcol
            s = columnnames(t)[c]
            print(io, " ", s)
            padding = maxwidths[c] - ourstrwidth(s)
            print(io, " " ^ padding)
            if c == rightcol
                print(io, " │\n")
            else
                print(io, " │")
            end
        end

        # Print table bounding line
        print(io, '├')
        for itr in 1:(labelmaxwidth + 2)
            print(io, '─')
        end
        print(io, '┼')
        for c in leftcol:rightcol
            for itr in 1:(maxwidths[c] + 2)
                print(io, '─')
            end
            if c < rightcol
                print(io, '┼')
            else
                print(io, '┤')
            end
        end
        print(io, '\n')

        # Print main table body, potentially in two abbreviated sections
        showrowindices(io,
                       t,
                       rowindices1,
                       maxwidths,
                       leftcol,
                       rightcol)

        if !isempty(rowindices2)
            print(io, "\n⋮\n")
            showrowindices(io,
                           t,
                           rowindices2,
                           maxwidths,
                           leftcol,
                           rightcol)
        end

        # Print newlines to separate chunks
        if chunkindex < nchunks
            print(io, "\n\n")
        end
    end

    if !allcols && length(chunkbounds) > 2
        C = chunkbounds[end] - chunkbounds[2]
        s = C == 1 ? "" : "s"
        print(io, "\nNote: Omitted printing $C column$s: ")
        join(io, columnnames(t)[end-C+1:end], ", ")
        println(io)
    end

    return
end

function showrowindices(io::IO,
                        t::T,
                        rowindices::AbstractVector{Int},
                        maxwidths::Vector{Int},
                        leftcol::Int,
                        rightcol::Int) where {T <: Union{Table, FlexTable}}
    labelmaxwidth = maxwidths[end]

    rows_t = rows(t)
    for r in rowindices
        # Print row ID
        print(io, "│ ")
        padding = labelmaxwidth - ndigits(r)
        print(io, " " ^ padding)
        print(io, r)
        print(io, " │ ")

        # Print table row
        for c in leftcol:rightcol
            strlen = 0
            s = rows_t[r][c]
            str = ourstr(s)
            strlen = ourstrwidth(str)
            padding = maxwidths[c] - strlen
            if ismissing(s)
                print(io, " " ^ padding)
                printstyled(io, s, color=:light_black)
            elseif s === nothing
                strlen = 0
            elseif s isa Number
                print(io, " " ^ padding)
                print(io, str)
            else
                print(io, str)
                print(io, " " ^ padding)
            end
            if c == rightcol
                if r == rowindices[end]
                    print(io, " │")  # is this right?
                else
                    print(io, " │\n")
                end
            else
                print(io, " │ ")
            end
        end
    end
    return
end

function summary(t::Table)
    nrow = size(t)[1]
    ncol = length(columnnames(t))
    string(nrow, "x", ncol, " Table")
end

function summary(t::FlexTable)
    nrow = size(t)[1]
    ncol = length(columnnames(t))
    string(nrow, "x", ncol, " FlexTable")
end

function getmaxwidths(io::IO, t::T, rowindices1::AbstractVector{Int}, rowindices2::AbstractVector{Int}, rowlabel::Symbol)::AbstractVector{Int} where {T <: Union{Table, FlexTable}}
    ncol = length(columnnames(t))
    maxwidths = fill(0, ncol + 1)

    # columns from table:
    for (c, name) in enumerate(columnnames(t))
        # 1) consider length of column name
        maxwidth = ourstrwidth(name)
        # 2) consider length of longest entry in column
        col = getproperty(t, name)
        for indices in (rowindices1, rowindices2), idx in indices
            maxwidth = max(maxwidth, ourstrwidth(col[idx]))
        end
        maxwidths[c] = maxwidth
    end

    # Calc row index width (stored as extra entry in maxwidths)
    labelwidth = ourstrwidth(rowlabel)
    rowmaxwidth1 = isempty(rowindices1) ? 0 : ndigits(last(rowindices1))
    rowmaxwidth2 = isempty(rowindices2) ? 0 : ndigits(last(rowindices2))
    maxwidths[end] = max(labelwidth, rowmaxwidth1, rowmaxwidth2)

    return maxwidths
end

#' @description
#'
#' When rendering a Table to a REPL window in chunks, each of
#' which will fit within the width of the REPL window, this function will
#' return the indices of the columns that should be included in each chunk.
#'
#' NOTE: The resulting bounds should be interpreted as follows: the
#'       i-th chunk bound is the index MINUS 1 of the first column in the
#'       i-th chunk. The (i + 1)-th chunk bound is the EXACT index of the
#'       last column in the i-th chunk. For example, the bounds [0, 3, 5]
#'       imply that the first chunk contains columns 1-3 and the second chunk
#'       contains columns 4-5.
#'
#' @param maxwidths::Vector{Int} The maximum width needed to render each
#'        column of an Table.
#' @param splittable::Bool Should the output be split into chunks at all or
#'        should only one chunk be constructed for the entire
#'        Table?
#' @param availablewidth::Int The available width in the REPL.
#'
#' @returns chunkbounds::Vector{Int} The bounds of each chunk of columns.
#'
#' @examples
#'
#' t = Table(A = 1:3, B = ["x", "yy", "z"])
#' maxwidths = getmaxwidths(t, 1:1, 3:3, "Row")
#' chunkbounds = getchunkbounds(maxwidths, true)
function getchunkbounds(maxwidths::Vector{Int},
                        splittable::Bool,
                        availablewidth::Int=displaysize()[2])::Vector{Int}
    ncols = length(maxwidths) - 1
    labelmaxwidth = maxwidths[end]
    if splittable
        chunkbounds = [0]
        # Include 2 spaces + 2 | characters for row/col label
        totalwidth = labelmaxwidth + 4
        for c in 1:ncols
            # Include 2 spaces + | character in per-column character count
            totalwidth += maxwidths[c] + 3
            if totalwidth > availablewidth
                push!(chunkbounds, c - 1)
                totalwidth = labelmaxwidth + 4 + maxwidths[c] + 3
            end
        end
        push!(chunkbounds, ncols)
    else
        chunkbounds = [0, ncols]
    end
    return chunkbounds
end

let
    local io = IOBuffer(Vector{UInt8}(undef, 300), read=true, write=true)
    global ourstr
    function ourstr(x::Any)
        truncate(io, 0)
        ourshowcompact(io, x)
        String(take!(io))
    end
end

ourstrwidth(x::Any) = textwidth(ourstr(x))

ourshowcompact(io::IO, x::Any) = show(IOContext(io, :compact=>true), x)
ourshowcompact(io::IO, x::Integer) = print(io, x)
ourshowcompact(io::IO, x::AbstractString) = escape_string(io, x, "")
ourshowcompact(io::IO, x::Symbol) = ourshowcompact(io, string(x))
ourshowcompact(io::IO, x::Nothing) = ""


text:
using GeoData, Test, Statistics, Dates, CFTime, Plots, GeoFormatTypes
import ArchGDAL, NCDatasets
using GeoData: name, window, mode, span, sampling, val, Ordered, metadata, bounds
include(joinpath(dirname(pathof(GeoData)), "../test/test_utils.jl"))

ncexamples = "https://www.unidata.ucar.edu/software/netcdf/examples/"
ncsingle = maybedownload(joinpath(ncexamples, "tos_O1_2001-2002.nc"))
ncmulti = maybedownload(joinpath(ncexamples, "test_echam_spectral.nc"))

stackkeys = (
    :abso4, :aclcac, :aclcov, :ahfcon, :ahfice, :ahfl, :ahfliac, :ahfllac,
    :ahflwac, :ahfres, :ahfs, :ahfsiac, :ahfslac, :ahfswac, :albedo, :albedo_nir,
    :albedo_nir_dif, :albedo_nir_dir, :albedo_vis, :albedo_vis_dif, :albedo_vis_dir,
    :alsobs, :alsoi, :alsol, :alsom, :alsow, :ameltdepth, :ameltfrac, :amlcorac,
    :ao3, :apmeb, :apmegl, :aprc, :aprl, :aprs, :aps, :az0i, :az0l, :az0w,
    :barefrac, :dew2, :drain, :evap, :evapiac, :evaplac, :evapwac, :fage, :friac,
    :geosp, :glac, :gld, :hyai, :hyam, :hybi, :hybm, :lsp, :q, :qres, :qvi, :relhum,
    :runoff, :sd, :seaice, :siced, :sicepdi, :sicepdw, :sicepres, :slm, :sn, :snacl,
    :snc, :sni, :snifrac, :snmel, :sofliac, :sofllac, :soflwac, :srad0, :srad0d,
    :srad0u, :sradl, :srads, :sradsu, :sraf0, :srafl, :srafs, :st, :svo, :t2max,
    :t2min, :temp2, :thvsig, :topmax, :tpot, :trad0, :tradl, :trads, :tradsu,
    :traf0, :trafl, :trafs, :trfliac, :trfllac, :trflwac, :tropo, :tsi, :tsicepdi,
    :tslm1, :tsurf, :tsw, :u10, :ustr, :ustri, :ustrl, :ustrw, :v10, :vdis, :vdisgw,
    :vstr, :vstri, :vstrl, :vstrw, :wimax, :wind10, :wl, :ws, :wsmx, :xi, :xivi,
    :xl, :xlvi
)

@testset "NCDarray" begin
    ncarray = geoarray(ncsingle)

    @testset "open" begin
        @test all(open(A -> A[Y=1], ncarray) .=== ncarray[:, 1, :])
    end

    @testset "read" begin
        A = read(ncarray)
        @test A isa GeoArray
        @test parent(A) isa Array
    end

    @testset "array properties" begin
        @test size(ncarray) == (180, 170, 24)
        @test ncarray isa NCDarray
        @test val(dims(ncarray, Ti())) == DateTime360Day(2001, 1, 16):Month(1):DateTime360Day(2002, 12, 16)
        @test val(dims(ncarray, Y())) == -79.5:89.5
        @test val(dims(ncarray, X())) == 1.0:2:359.0
        @test bounds(ncarray) == (
            (0.0, 360.0),
            (-80.0, 90.0),
            (DateTime360Day(2001, 1, 1), DateTime360Day(2003, 1, 1)),
        )
    end

    @testset "dimensions" begin
        @test ndims(ncarray) == 3
        @test length.(dims(ncarray)) == (180, 170, 24)
        @test dims(ncarray) isa Tuple{<:X,<:Y,<:Ti}
        @test refdims(ncarray) == ()
        # TODO detect the time span, and make it Regular
        modes = (
             Mapped(Ordered(), Explicit(vcat((0.0:2.0:358.0)', (2.0:2.0:360.0)')), Intervals(Center()), EPSG(4326), EPSG(4326)),
             Mapped(Ordered(), Explicit(vcat((-80.0:89.0)', (-79.0:90.0)')), Intervals(Center()), EPSG(4326), EPSG(4326)),
             Sampled(Ordered(), Explicit(
                 vcat(permutedims(DateTime360Day(2001, 1, 1):Month(1):DateTime360Day(2002, 12, 1)),
                      permutedims(DateTime360Day(2001, 2, 1):Month(1):DateTime360Day(2003, 1, 1)))
                ), Intervals(Center())
            )
        )
        @test val.(span(ncarray)) == val.(span.(modes))
        @test typeof(mode(ncarray)) == typeof(modes)
        @test bounds(ncarray) == ((0.0, 360.0), (-80.0, 90.0), (DateTime360Day(2001, 1, 1), DateTime360Day(2003, 1, 1)))
    end

    @testset "other fields" begin
        @test ismissing(missingval(ncarray))
        @test metadata(ncarray) isa Metadata{:NCD}
        @test name(ncarray) == :tos
    end

    @testset "indexing" begin
        @test ncarray[Ti(1)] isa GeoArray{<:Any,2}
        @test ncarray[Y(1), Ti(1)] isa GeoArray{<:Any,1}
        @test ncarray[X(1), Ti(1)] isa GeoArray{<:Any,1}
        @test ncarray[X(1), Y(1), Ti(1)] isa Missing
        @test ncarray[X(30), Y(30), Ti(1)] isa Float32
        # Russia
        @test ncarray[X(50), Y(100), Ti(1)] isa Missing
        # Alaska
        @test ncarray[Y(Near(64.2008)), X(Near(149.4937)), Ti(1)] isa Missing
        @test ncarray[Ti(2), X(At(59.0)), Y(At(-50.5))] == ncarray[30, 30, 2] === 278.47168f0
    end

    @testset "indexing with reverse lat" begin
        if !haskey(ENV, "CI") # CI downloads fail. But run locally
            ncrevlat = maybedownload("ftp://ftp.cdc.noaa.gov/Datasets/noaa.ersst.v5/sst.mon.ltm.1981-2010.nc")
            ncrevlatarray = NCDarray(ncrevlat, :sst; missingval=-9.96921f36, )
            @test order(dims(ncrevlatarray, Y)) == Ordered(ReverseIndex(), ReverseArray(), ForwardRelation())
            @test ncrevlatarray[Y(At(40)), X(At(100)), Ti(1)] == missingval(ncrevlatarray)
            @test ncrevlatarray[Y(At(-40)), X(At(100)), Ti(1)] == ncrevlatarray[51, 65, 1] == 14.5916605f0
            @test val(span(ncrevlatarray, Ti)) == Month(1)
            @test val(span(ncrevlatarray, Ti)) isa Month # Not CompoundPeriod
        end
    end

    @testset "selectors" begin
        a = ncarray[X(At(21.0)), Y(Between(50, 52)), Ti(Near(DateTime360Day(2002, 12)))]
        @test bounds(a) == ((50.0, 52.0),)
        x = ncarray[X(Near(150)), Y(Near(30)), Ti(1)]
        @test x isa Float32
        # TODO make sure we are getting the right cell.
        @test size(ncarray[Y(Between(-80, 90)), X(Between(0, 360)),
            Ti(Between(DateTime360Day(2001, 1, 1), DateTime360Day(2003, 1, 1)))
        ]) == (180, 170, 24)
        nca = ncarray[Y(Between(-80, -25)), X(Between(0, 180)),
                      Ti(Near(DateTime360Day(2002, 02, 20)))]
        @test size(nca) == (90, 55)
    end
    @testset "selectors" begin
        a = ncarray[Lon(At(21.0)), Lat(Between(50, 52)), Ti(Near(DateTime360Day(2002, 12)))]
        @test bounds(a) == ((50.0, 52.0),)
        x = ncarray[Lon(Near(150)), Lat(Near(30)), Ti(1)]
        @test x isa Float32
        dimz = Lon(Between(0.0, 360)), Lat(Between(-80, 90)),
               Ti(Between(DateTime360Day(2001, 1, 1), DateTime360Day(2003, 01, 02)))
        @test size(ncarray[dimz...]) == (180, 170, 24)
        @test index(ncarray[dimz...]) == index(ncarray)
        nca = ncarray[Lat(Between(-80, -25)), Lon(Between(0, 180)), Ti(Contains(DateTime360Day(2002, 02, 20)))]
        @test size(nca) == (90, 55)
        @test index(nca, Lat) == index(ncarray[1:90, 1:55, 2], Lat)
        @test all(nca .=== ncarray[1:90, 1:55, 14])
    end

    @testset "conversion to GeoArray" begin
        geoA = ncarray[X(1:50), Y(20:20), Ti(1)]
        @test size(geoA) == (50, 1)
        @test eltype(geoA) <: Union{Missing,Float32}
        @time geoA isa GeoArray{Float32,1}
        @test dims(geoA) isa Tuple{<:X,<:Y}
        @test refdims(geoA) isa Tuple{<:Ti}
        @test metadata(geoA) == metadata(ncarray)
        @test ismissing(missingval(geoA))
        @test name(geoA) == :tos
    end

    @testset "save" begin
        @testset "to netcdf" begin
            # TODO save and load subset
            geoA = GeoArray(ncarray)
            metadata(geoA)
            @test size(geoA) == size(ncarray)
            filename = tempname() * ".nc"
            write(filename, geoA)
            saved = GeoArray(NCDarray(filename))
            @test size(saved) == size(geoA)
            @test refdims(saved) == refdims(geoA)
            @test missingval(saved) === missingval(geoA)
            @test map(metadata.(dims(saved)), metadata.(dims(geoarray))) do s, g
                all(s .== g)
            end |> all
            @test_broken metadata(saved) == metadata(geoA)
            @test_broken all(metadata.(dims(saved)) .== metadata.(dims(geoA)))
            @test GeoData.name(saved) == GeoData.name(geoA)
            @test all(mode.(dims(saved)) .!= mode.(dims(geoA)))
            @test all(order.(dims(saved)) .== order.(dims(geoA)))
            @test all(typeof.(span.(dims(saved))) .== typeof.(span.(dims(geoA))))
            @test all(val.(span.(dims(saved))) .== val.(span.(dims(geoA))))
            @test all(sampling.(dims(saved)) .== sampling.(dims(geoA)))
            @test typeof(dims(saved)) <: typeof(dims(geoA))
            @test val(dims(saved)[3]) == val(dims(geoA)[3])
            @test all(val.(dims(saved)) .== val.(dims(geoA)))
            @test all(data(saved) .=== data(geoA))
            @test saved isa typeof(geoA)
            # TODO test crs
        end
        @testset "to gdal" begin
            gdalfilename = tempname() * ".tif"
            nccleaned = replace_missing(ncarray[Ti(1)], -9999.0)
            write(gdalfilename, nccleaned)
            gdalarray = geoarray(gdalfilename)
            # gdalarray WKT is missing one AUTHORITY
            # @test_broken crs(gdalarray) == convert(WellKnownText, EPSG(4326))
            # But the Proj representation is the same
            @test convert(ProjString, crs(gdalarray)) == convert(ProjString, EPSG(4326))
            @test bounds(gdalarray) == (bounds(nccleaned)..., (1, 1))
            # Tiff locus = Start, Netcdf locus = Center
            @test reverse(val(dims(gdalarray, Y))) .+ 0.5 ≈ val(dims(nccleaned, Y))
            @test val(dims(gdalarray, X)) .+ 1.0  ≈ val(dims(nccleaned, X))
            @test reverse(GeoArray(gdalarray); dims=Y()) ≈ nccleaned
        end
        @testset "to grd" begin
            nccleaned = replace_missing(ncarray[Ti(1)], -9999.0)
            write("testgrd.gri", nccleaned)
            grdarray = GRDarray("testgrd");
            @test crs(grdarray) == convert(ProjString, EPSG(4326))
            @test bounds(grdarray) == (bounds(nccleaned)..., (1, 1))
            @test val(dims(grdarray, Y)) ≈ val(dims(nccleaned, Y)) .- 0.5
            @test val(dims(grdarray, X)) ≈ val(dims(nccleaned, X)) .- 1.0
            @test GeoArray(grdarray) ≈ reverse(nccleaned; dims=Y)
        end
    end

    @testset "show" begin
        sh = sprint(show, MIME("text/plain"), ncarray)
        # Test but don't lock this down too much
        @test occursin("NCDarray", sh)
        @test occursin("Y", sh)
        @test occursin("X", sh)
        @test occursin("Time", sh)
    end

    @testset "plot" begin
        ncarray[Ti(1:3:12)] |> plot
        ncarray[Ti(1)] |> plot
        ncarray[Y(100), Ti(1)] |> plot
    end

end

@testset "NCDstack" begin
    ncstack = stack(ncmulti)

    @testset "read" begin
        st = read(ncstack)
        @test st isa GeoStack
        @test st.data isa NamedTuple
        @test first(st.data) isa GeoArray
        @test parent(first(st.data)) isa Array
    end

    @testset "load ncstack" begin
        @test ncstack isa NCDstack{String}
        @test ismissing(missingval(ncstack))
        @test metadata(ncstack) isa Metadata{:NCD}
        @test refdims(ncstack) == ()
        # Loads child as a regular GeoArray
        @test_throws NCDatasets.NetCDFError ncstack[:not_a_key]
        @test ncstack[:albedo] isa GeoArray{<:Any,3}
        @test ncstack[:albedo, 2, 3, 1] isa Float32
        @test ncstack[:albedo, :, 3, 1] isa GeoArray{<:Any,1}
        @test dims(ncstack, :albedo) isa Tuple{<:X,<:Y,<:Ti}
        @test keys(ncstack) isa NTuple{131,Symbol}
        @test keys(ncstack) == stackkeys
        @test first(keys(ncstack)) == :abso4
        @test metadata(ncstack) isa Metadata{:NCD}
        @test metadata(ncstack)["institution"] == "Max-Planck-Institute for Meteorology"
        @test metadata(ncstack, :albedo) isa Metadata{:NCD}
        @test metadata(ncstack, :albedo)["long_name"] == "surface albedo"
        # Test some DimensionalData.jl tools work
        # Time dim should be reduced to length 1 by mean
        @test axes(mean(ncstack[:albedo, Y(1:20)] , dims=Ti)) ==
              (Base.OneTo(192), Base.OneTo(20), Base.OneTo(1))
        geoA = ncstack[:albedo][Ti(4:6), X(1), Y(2)]
        @test geoA == ncstack[:albedo, Ti(4:6), X(1), Y(2)]
        @test size(geoA) == (3,)
    end

    if VERSION > v"1.1-"
        @testset "copy" begin
            geoA = ncstack[:albedo]
            copy!(geoA, ncstack, :albedo);
            # First wrap with GeoArray() here or == loads from disk for each cell.
            # we need a general way of avoiding this in all disk-based sources
            @test geoA == GeoArray(ncstack[:albedo])
        end
    end

    @testset "indexing" begin
        ncmultistack = NCDstack(ncsingle)
        @test dims(ncmultistack, :tos) isa Tuple{<:X,<:Y,<:Ti}
        @test ncmultistack[:tos] isa GeoArray{<:Any,3}
        @test ncmultistack[:tos, Ti(1)] isa GeoArray{<:Any,2}
        @test ncmultistack[:tos, Y(1), Ti(1)] isa GeoArray{<:Any,1}
        @test ncmultistack[:tos, 8, 30, 10] isa Float32
    end

    @testset "window" begin
        windowedstack = stack(ncmulti; window=(Y(1:5), X(1:5), Ti(1)))
        @test window(windowedstack) == (Y(1:5), X(1:5), Ti(1))
        windowedarray = windowedstack[:albedo]
        @test size(windowedarray) == (5, 5)
        @test windowedarray[1:3, 2:2] == reshape([0.84936917f0, 0.8776228f0, 0.87498736f0], 3, 1)
        @test windowedarray[1:3, 2] == [0.84936917f0, 0.8776228f0, 0.87498736f0]
        @test windowedarray[1, 2] == 0.84936917f0
        windowedstack = NCDstack(ncmulti; window=(Y(1:5), X(1:5), Ti(1:1)))
        windowedarray = windowedstack[:albedo]
        @test windowedarray[1:3, 2:2, 1:1] == reshape([0.84936917f0, 0.8776228f0, 0.87498736f0], 3, 1, 1)
        @test windowedarray[1:3, 2:2, 1] == reshape([0.84936917f0, 0.8776228f0, 0.87498736f0], 3, 1)
        @test windowedarray[1:3, 2, 1] == [0.84936917f0, 0.8776228f0, 0.87498736f0]
        @test windowedarray[1, 2, 1] == 0.84936917f0
        windowedstack = NCDstack(ncmulti; window=(Ti(1),))
        windowedarray = windowedstack[:albedo]
        @test windowedarray[1:3, 2:2] == reshape([0.84936917f0, 0.8776228f0, 0.87498736f0], 3, 1)
        @test windowedarray[1:3, 2] == [0.84936917f0, 0.8776228f0, 0.87498736f0]
        @test windowedarray[1, 2] ==  0.84936917f0
    end

    @testset "conversion to GeoStack" begin
        geostack = GeoStack(ncstack)
        @test Symbol.(Tuple(keys(geostack))) == keys(ncstack)
        smallstack = GeoStack(ncstack; keys=(:albedo, :evap, :runoff))
        @test keys(smallstack) == (:albedo, :evap, :runoff)
    end

    @testset "save" begin
        geostack = GeoStack(ncstack);
        metadata(geostack)
        length(dims(geostack[:aclcac]))
        ndims(geostack[:aclcac])
        filename = tempname() * ".nc"
        write(filename, geostack);
        saved = GeoStack(NCDstack(filename))
        @test keys(saved) == keys(geostack)
        @test metadata(saved)["advection"] == "Lin & Rood"
        @test metadata(saved) == metadata(geostack) == metadata(ncstack)
        @test all(first(values(saved)) .== first(values(geostack)))
    end

end

@testset "NCD series" begin
    ncseries = series([ncmulti, ncmulti], (Ti,); child=stack)
    geoA = GeoArray(NCDarray(ncmulti, :albedo; name=:test))
    @test ncseries[Ti(1)][:albedo] == geoA
    @test typeof(ncseries[Ti(1)][:albedo]) == typeof(geoA)
    modified_series = modify(Array, ncseries)
    @test typeof(modified_series) <: GeoSeries{<:GeoStack{<:NamedTuple{stackkeys,<:Tuple{<:GeoArray{Float32,3,<:Tuple,<:Tuple,<:Array{Float32,3}},Vararg}}}}

    @testset "read" begin
        geoseries = read(ncseries)
        @test geoseries isa GeoSeries{<:GeoStack}
        @test geoseries.data isa Vector{<:GeoStack}
    end
end

nothing


text:
using CUDA
using ExaPF
using KernelAbstractions
using Test
using TimerOutputs

import ExaPF: PowerSystem
import ExaPF.PowerSystem: ParsePSSE

const PS = PowerSystem

@testset "Powerflow residuals and Jacobian" begin
    local_case = "case14.raw"
    # read data
    to = TimerOutputs.TimerOutput()
    datafile = joinpath(dirname(@__FILE__), "..", "data", local_case)
    data_raw = ParsePSSE.parse_raw(datafile)
    data = ParsePSSE.raw_to_exapf(data_raw)

    # Parsed data indexes
    BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, VA, BASE_KV, ZONE, VMAX, VMIN,
    LAM_P, LAM_Q, MU_VMAX, MU_VMIN = PS.IndexSet.idx_bus()

    # retrive required data
    bus = data["bus"]
    gen = data["gen"]
    SBASE = data["baseMVA"][1]

    bus_to_indexes = PS.get_bus_id_to_indexes(bus)
    nbus = size(bus, 1)

    # obtain V0 from raw data
    V = Array{Complex{Float64}}(undef, nbus)
    T = Vector
    for i in 1:nbus
        V[i] = bus[i, VM]*exp(1im * pi/180 * bus[i, VA])
    end
    @test V ≈ Complex{Float64}[
        1.06 + 0.0im,
        1.0410510706561686 - 0.0907616013832108im,
        0.985192522040012 - 0.22247627854771523im,
        1.0012292929704543 - 0.18218707911892243im,
        1.0075796620614788 - 0.15551162239548505im,
        1.0372102511734809 - 0.2628590779498494im,
        1.0327942548732372 - 0.24527685887754397im,
        1.0605035588701377 - 0.2518575026156106im,
        1.0202428186152266 - 0.27219984563562466im,
        1.0147053262903118 - 0.27373721193522754im,
        1.0218895875940064 - 0.26981552747562876im,
        1.0188740342304141 - 0.27444787933420284im,
        1.0138437793219441 - 0.2746250817572887im,
        0.995247767507711 - 0.286014443990015im
    ]

    # form Y matrix
    Ybus = PS.makeYbus(data, bus_to_indexes).ybus;

    Vm = abs.(V)
    Va = angle.(V)
    bus = data["bus"]
    gen = data["gen"]
    nbus = size(bus, 1)
    ngen = size(gen, 1)

    ybus_re, ybus_im = ExaPF.Spmat{T{Int}, T{Float64}}(Ybus)
    SBASE = data["baseMVA"][1]
    Sbus, Sload = PS.assembleSbus(gen, bus, SBASE, bus_to_indexes)
    pbus = real(Sbus)
    qbus = imag(Sbus)

    # Test that Sbus is correctly specified
    @test Sbus ≈ Complex{Float64}[
         2.32393 - 0.16549im,
         0.23189298795657234 + 0.3255213997211121im,
        -0.8066188947413118 + 0.028255632303189476im,
        -0.5123531308565288 + 0.035668879376258705im,
        -0.07125129097998142 - 0.02060016150325537im,
        -0.1098278333939612 + 0.07281082918372937im,
         0.0 + 0.0im,
         0.0 + 0.17623im,
        -0.24683805744186976 - 0.15824985834313557im,
        -0.08821656550979241 - 0.05553726513776928im,
        -0.038463023291667925 - 0.014532033764664084im,
        -0.05643415630748495 - 0.017413308476656675im,
        -0.11665673277410679 - 0.05281302692126483im,
        -0.13051302125309594 - 0.04527619677595794im
    ]
end

@testset "PowerNetwork object" begin
    psse_datafile = "case14.raw"
    matpower_datafile = "case9.m"

    # Test constructor
    @testset "Parsers $name" for name in [psse_datafile, matpower_datafile]
        datafile = joinpath(dirname(@__FILE__), "..", "data", name)
        pf = PS.PowerNetwork(datafile)
        @test isa(pf, PS.PowerNetwork)
    end

    # From now on, test with "case9.m"
    datafile = joinpath(dirname(@__FILE__), "..", "data", matpower_datafile)
    data = PS.import_dataset(datafile)
    pf = PS.PowerNetwork(data)

    @testset "Computing cost coefficients" begin
        coefs = PS.get_costs_coefficients(pf)
        @test size(coefs) == (3, 4)
        @test isequal(coefs[:, 1], [3.0, 2.0, 2.0])
    end

    @testset "Getters" for Attr in [
        PS.NumberOfBuses,
        PS.NumberOfPVBuses,
        PS.NumberOfPQBuses,
        PS.NumberOfSlackBuses,
        PS.NumberOfLines,
        PS.NumberOfGenerators,
    ]
        res = PS.get(pf, Attr())
        @test isa(res, Int)
    end

    @testset "Indexing" begin
        idx = PS.get(pf, PS.GeneratorIndexes())
        @test isequal(idx, [1, 2, 3])
    end

    @testset "Bounds" begin
        n_bus = PS.get(pf, PS.NumberOfBuses())
        v_min, v_max = PS.bounds(pf, PS.Buses(), PS.VoltageMagnitude())
        @test length(v_min) == n_bus
        @test length(v_max) == n_bus

        n_gen = PS.get(pf, PS.NumberOfGenerators())
        p_min, p_max = PS.bounds(pf, PS.Generators(), PS.ActivePower())
        @test length(p_min) == n_gen
        @test length(p_max) == n_gen
        q_min, q_max = PS.bounds(pf, PS.Generators(), PS.ReactivePower())
        @test length(q_min) == n_gen
        @test length(q_max) == n_gen

        n_lines = PS.get(pf, PS.NumberOfLines())
        f_min, f_max = PS.bounds(pf, PS.Lines(), PS.ActivePower())
        @test length(f_min) == n_lines
        @test length(f_max) == n_lines
    end

    @testset "Load from data" begin
        pf_original = PS.PowerNetwork(data)
        @test isa(pf_original, PS.PowerNetwork)
        n_lines = PS.get(pf_original, PS.NumberOfLines())

        pf_removed = PS.PowerNetwork(data; remove_lines=Int[1])
        @test isa(pf_removed, PS.PowerNetwork)
        n_after_removal = PS.get(pf_removed, PS.NumberOfLines())

        @test n_lines - 1 == n_after_removal
        @test pf_original.Ybus != pf_removed.Ybus
    end
end


text:
using LinearAlgebra

#
#
#
#"""
#    build_full_H(ci_vector::ClusteredState, cluster_ops, clustered_ham::ClusteredOperator)
#
#Build full TPSCI Hamiltonian matrix in space spanned by `ci_vector`. This works in serial for the full matrix
#"""
#function build_full_H2(ci_vector::ClusteredState, cluster_ops, clustered_ham::ClusteredOperator)
##={{{=#
#    dim = length(ci_vector)
#    H = zeros(dim, dim)
#
#    jobs = []
#
#    zero_fock = FermiCG.TransferConfig([(0,0) for i in ci_vector.clusters])
#    bra_idx = 0
#    for (fock_bra, configs_bra) in ci_vector.data
#        for (config_bra, coeff_bra) in configs_bra
#            bra_idx += 1
#            ket_idx = 0
#            for (fock_ket, configs_ket) in ci_vector.data
#                fock_trans = fock_bra - fock_ket
#
#                # check if transition is connected by H
#                if haskey(clustered_ham, fock_trans) == false
#                    ket_idx += length(configs_ket)
#                    continue
#                end
#
#                for (config_ket, coeff_ket) in configs_ket
#                    ket_idx += 1
#                    ket_idx <= bra_idx || continue
#
#                    push!(jobs, (bra_idx, ket_idx, fock_trans, fock_bra, config_bra, fock_ket, config_ket))
#
#                end
#            end
#        end
#    end
#
#    function do_job(job)
#        #return FermiCG.contract_matrix_element(job[3], cluster_ops, job[4:7]...)
#        me = 0.0
#        for term in clustered_ham[job[3]]
#            me += FermiCG.contract_matrix_element(term, cluster_ops, job[4:7]...)
#        end
#        return me
#    end
#
#
#    #Threads.@threads for job in jobs
#    for job in jobs
#        me = do_job(job)
#        H[job[1], job[2]] += me
#        H[job[2], job[1]] = H[job[1], job[2]]
#    end
#    return H
#end
##=}}}=#
#

max_stars_repo_name: nmayhall-vt/FermiCG

max_issues_repo_name: nmayhall-vt/FermiCG

max_forks_repo_name: nmayhall-vt/FermiCG


text:
"""
	trend1d(cmd0::String="", arg1=nothing, kwargs...)

Fit a [weighted] [robust] polynomial/Fourier model for y = f(x) to xy[w] data.

Full option list at [`trend1d`]($(GMTdoc)trend1d.html)

Parameters
----------

- **F** | **output** :: [Type => Str]   ``Arg = xymrw|p|P|c``

    Specify up to five letters from the set {x y m r w} in any order to create columns of output.
    ($(GMTdoc)trend1d.html#f)
- **N** | **n_model** :: [Type => Str]      ``Arg = [p|P|f|F|c|C|s|S|x]n[,…][+llength][+oorigin][+r]``

    Specify Specify the number of terms in the model, n_model, and append +r to do a robust fit. E.g., a robust bilinear model is -N4+r.
    ($(GMTdoc)trend1d.html#n)
- **C** | **condition_number** :: [Type => Number]   ``Arg = condition_number``

    Set the maximum allowed condition number for the matrix solution.
    ($(GMTdoc)trend1d.html#c)
- **I** | **confidence_level** :: [Type => Number | []]   ``Arg = [confidence_level]``

    Iteratively increase the number of model parameters, starting at one, until n_model is reachedx
    or the reduction in variance of the model is not significant at the confidence_level level.
    ($(GMTdoc)trend1d.html#i)
- **W** | **weights** :: [Type => Str | []]     ``Arg = [+s]``

    Weights are supplied in input column 3. Do a weighted least squares fit [or start with
    these weights when doing the iterative robust fit].
    ($(GMTdoc)trend1d.html#w)
- $(GMT.opt_V)
- $(GMT.opt_b)
- $(GMT.opt_d)
- $(GMT.opt_e)
- $(GMT.opt_f)
- $(GMT.opt_h)
- $(GMT.opt_i)
- $(GMT.opt_w)
- $(GMT.opt_swap_xy)
"""
function trend1d(cmd0::String="", arg1=nothing; kwargs...)

	length(kwargs) == 0 && return monolitic("trend1d", cmd0, arg1)

	d = init_module(false, kwargs...)[1]		# Also checks if the user wants ONLY the HELP mode

	cmd, = parse_common_opts(d, "", [:V_params :b :d :e :f :h :i :w :yx])
	cmd  = parse_these_opts(cmd, d, [[:C :condition_number], [:I :confidence_level], [:F :output],
	                                 [:N :n_model], [:W :weights]])
	common_grd(d, cmd0, cmd, "trend1d ", arg1)		# Finish build cmd and run it
end

# ---------------------------------------------------------------------------------------------------
trend1d(arg1, cmd0::String=""; kw...) = trend1d(cmd0, arg1; kw...)


text:
"""
    tip_labels(tree::Tree)

Extract the tip labels of a tree.

# Arguments
- `tree::Tree`: a `Tree`object.
"""
function tip_labels(tree::Tree)
    function aux(subtree, x)
        if length(subtree.offsprings) == 0
            pushfirst!(x,subtree.label)
        else
            aux(subtree.offsprings[2], x)
            aux(subtree.offsprings[1], x)
        end
    end

    x = Array{String,1}(undef,0)
    aux(tree, x)
    return x
end

"""
    n_tips(tree::Tree)

Get the number of tip in a tree.

# Arguments
- `tree::Tree`: a `Tree`object.
"""
function n_tips(tree::Tree)
    return Int64((tree.n_nodes + 1)/2)
end

function tips(tree::Tree)
    function aux(subtree, x)
        if length(subtree.offsprings) == 0
            pushfirst!(x,true)
        else
            aux(subtree.offsprings[2], x)
            aux(subtree.offsprings[1], x)
            pushfirst!(x,false)
        end
    end

    x = Array{Bool,1}(undef,0)
    aux(tree, x)
    return x
end

function update_rates(tree::Tree, rates::Array{T,1} ; id = 1) where {T<:Number}
    function aux(sub_tree, sub_rates)
        if sub_tree.n_nodes < 2
            root_rate = popfirst!(sub_rates)
            current_rates = sub_tree.attributes
            current_rates[id] = root_rate
            return Tree(sub_tree.offsprings, sub_tree.branch_length, current_rates, sub_tree.n_nodes, sub_tree.label)
        else
            root_rate = popfirst!(sub_rates)
            t1 = aux(sub_tree.offsprings[1], sub_rates)
            t2 = aux(sub_tree.offsprings[2], sub_rates)
            current_rates = sub_tree.attributes
            current_rates[id] = root_rate
            return Tree([t1,t2], sub_tree.branch_length, current_rates, sub_tree.n_nodes, sub_tree.label)
        end
    end

    new_rates = deepcopy(rates)
    aux(tree, new_rates)
end

function update_rates!(tree::Tree, rates::Array{T,1} ; id = 1) where {T<:Number}
    function aux(sub_tree, sub_rates)
        if sub_tree.n_nodes < 2
            root_rate = popfirst!(sub_rates)
            sub_tree.attributes[id] = root_rate
        else
            root_rate = popfirst!(sub_rates)
            sub_tree.attributes[id] = root_rate
            t1 = sub_tree.offsprings[1]
            aux(t1, sub_rates)
            t2 = sub_tree.offsprings[2]
            aux(t2, sub_rates)
            #return Tree([t1,t2], sub_tree.branch_length, root_rate, sub_tree.n_nodes)
        end
    end

    new_rates = deepcopy(rates)
    aux(tree, new_rates)
end

function update_rates!(tree::Tree, rates::Array{T,1}, edge_trees ; id = 1) where {T<:Number}
    update_rates!(tree,rates, id = id)

    for i in 1:length(edge_trees)
        edge_trees[i].tree.attributes[id] = rates[i+1]
    end

    return tree, edge_trees
end

function update_rates!(tree::Tree, rate::T ; id = 1) where {T<:Number}
    function aux(sub_tree)
        if sub_tree.n_nodes < 2
            sub_tree.attributes[id] *= rate
        else
            sub_tree.attributes[id] *= rate
            t1 = sub_tree.offsprings[1]
            aux(t1)
            t2 = sub_tree.offsprings[2]
            aux(t2)
        end
    end

    aux(tree)
end

function get_parent_edge(tree::Tree, edge_id::Int64)
    if edge_id == 0
        return NaN
    end

    function aux(subtree, edge)
        n_edges_left = subtree.offsprings[1].n_nodes + 1
        if edge == 2 || edge == (n_edges_left + 1)
            return 1
        elseif edge > (n_edges_left + 1)
            return n_edges_left + aux(subtree.offsprings[2], edge - n_edges_left)
        else
            return 1 + aux(subtree.offsprings[1], edge - 1)
        end
    end

    aux(tree, edge_id + 1) - 1
end

max_stars_repo_name: hmorlon/JPANDA

max_issues_repo_name: hmorlon/JPANDA

max_forks_repo_name: hmorlon/JPANDA


text:
precompile(Tuple{typeof(REPL.LineEdit.activate), REPL.LineEdit.TextInterface, REPL.LineEdit.MIState, REPL.Terminals.AbstractTerminal, REPL.Terminals.TextTerminal})
precompile(Tuple{typeof(REPL.LineEdit.refresh_multi_line), REPL.Terminals.UnixTerminal, Any})
precompile(Tuple{typeof(Base.:(!=)), UInt64, UInt64})
precompile(Tuple{typeof(Base.print), Base.GenericIOBuffer{Array{UInt8, 1}}, UInt16})
precompile(Tuple{typeof(Base.invokelatest), Any})
precompile(Tuple{typeof(OhMyREPL.__init__)})
precompile(Tuple{typeof(Base.getindex), Array{REPL.LineEdit.TextInterface, 1}, Int64})
precompile(Tuple{typeof(Base.getindex), Type{Base.Dict{Any, Any}}, Base.Dict{Any, Any}, Base.Dict{Char, Any}})
precompile(Tuple{typeof(Base.setindex!), Base.Dict{Any, Any}, Base.Dict{Char, Any}, Char})
precompile(Tuple{typeof(Base.setindex!), Base.Dict{Any, Any}, Base.Dict{Char, Any}, String})
precompile(Tuple{Base.Multimedia.var"#@MIME_str", LineNumberNode, Module, Any})
precompile(Tuple{Base.var"#@r_str", LineNumberNode, Module, Any, Vararg{Any, N} where N})
precompile(Tuple{typeof(REPL.LineEdit.refresh_multi_line), REPL.Terminals.TerminalBuffer, REPL.LineEdit.ModeState})
precompile(Tuple{REPL.LineEdit.var"#22#23"{OhMyREPL.Prompt.var"#2#28", String}, Any, Any})
precompile(Tuple{OhMyREPL.Prompt.var"#2#28", Any, Any, Any})
precompile(Tuple{Type{Base.IOContext{IO_t} where IO_t<:IO}, Base.GenericIOBuffer{Array{UInt8, 1}}, Base.TTY})
precompile(Tuple{typeof(Base.write), Base.IOContext{Base.GenericIOBuffer{Array{UInt8, 1}}}, String})
precompile(Tuple{typeof(Base.Unicode.textwidth), String})
precompile(Tuple{typeof(Base.unsafe_write), Base.IOContext{Base.GenericIOBuffer{Array{UInt8, 1}}}, Ptr{UInt8}, UInt64})
precompile(Tuple{OhMyREPL.Passes.SyntaxHighlighter.SyntaxHighlighterSettings, Array{Crayons.Crayon, 1}, Array{Tokenize.Tokens.Token, 1}, Int64})
precompile(Tuple{OhMyREPL.Passes.BracketHighlighter.BracketHighlighterSettings, Array{Crayons.Crayon, 1}, Array{Tokenize.Tokens.Token, 1}, Int64})
precompile(Tuple{OhMyREPL.Passes.RainbowBrackets.RainbowBracketsSettings, Array{Crayons.Crayon, 1}, Array{Tokenize.Tokens.Token, 1}, Int64})
precompile(Tuple{typeof(OhMyREPL.untokenize_with_ANSI), Base.IOContext{Base.GenericIOBuffer{Array{UInt8, 1}}}, OhMyREPL.PassHandler, Array{Tokenize.Tokens.Token, 1}, Int64})
precompile(Tuple{typeof(Base.print), Base.IOContext{Base.GenericIOBuffer{Array{UInt8, 1}}}, Int64, String, Vararg{Any, N} where N})
precompile(Tuple{typeof(Base.print), Base.IOContext{Base.GenericIOBuffer{Array{UInt8, 1}}}, UInt8})
precompile(Tuple{typeof(OhMyREPL.Prompt.refresh_multi_line), Any, Any, Any, Any, Any})
precompile(Tuple{typeof(Base.position), Base.GenericIOBuffer{Array{UInt8, 1}}})
precompile(Tuple{typeof(Base.seek), Base.GenericIOBuffer{Array{UInt8, 1}}, Int64})
precompile(Tuple{Base.var"#readline##kw", NamedTuple{(:keep,), Tuple{Bool}}, typeof(Base.readline), Base.GenericIOBuffer{Array{UInt8, 1}}})
precompile(Tuple{typeof(Base.divrem), Int64, Int64})
precompile(Tuple{typeof(Base.max), Int64, Int64})
precompile(Tuple{typeof(Tokenize.Lexers.lex_whitespace), Tokenize.Lexers.Lexer{Base.GenericIOBuffer{Array{UInt8, 1}}, Tokenize.Tokens.Token}})
precompile(Tuple{typeof(Tokenize.Lexers.lex_plus), Tokenize.Lexers.Lexer{Base.GenericIOBuffer{Array{UInt8, 1}}, Tokenize.Tokens.Token}})
precompile(Tuple{typeof(Base.ht_keyindex), Base.Dict{Tokenize.Tokens.Kind, Symbol}, Tokenize.Tokens.Kind})
precompile(Tuple{REPL.LineEdit.var"#22#23"{OhMyREPL.Prompt.var"#15#41", String}, Any, Any})
precompile(Tuple{OhMyREPL.Prompt.var"#15#41", Any, Any, Any})
precompile(Tuple{REPL.LineEdit.var"#22#23"{OhMyREPL.Prompt.var"#22#48", String}, Any, Any})
precompile(Tuple{OhMyREPL.Prompt.var"#22#48", Any, Any, Any})
precompile(Tuple{typeof(OhMyREPL._check_pass_name), OhMyREPL.PassHandler, String, Bool})
precompile(Tuple{typeof(REPL.LineEdit.move_input_end), Union{REPL.LineEdit.MIState, REPL.LineEdit.ModeState}})
precompile(Tuple{typeof(REPL.LineEdit.mode), REPL.LineEdit.MIState})
precompile(Tuple{typeof(Base.Multimedia.display), REPL.REPLDisplay{R} where R<:REPL.AbstractREPL, Any})
precompile(Tuple{typeof(Base.Multimedia.display), REPL.REPLDisplay{REPL.LineEditREPL}, Base.Multimedia.MIME{Symbol("text/plain")}, Int64})
precompile(Tuple{typeof(Base.write), Base.TTY, String, String})
precompile(Tuple{Type{Base.IOContext{IO_t} where IO_t<:IO}, Base.TTY, Base.Pair{Symbol, Bool}})
precompile(Tuple{typeof(Base.ht_keyindex), Base.Dict{UInt64, Tokenize.Tokens.Kind}, UInt64})
precompile(Tuple{typeof(Base.print_to_string), Tokenize.Tokens.Kind})
precompile(Tuple{REPL.LineEdit.var"#22#23"{OhMyREPL.BracketInserter.var"#1#8"{Array{Char, 1}, Char, Char}, String}, Any, Any})
precompile(Tuple{OhMyREPL.BracketInserter.var"#1#8"{Array{Char, 1}, Char, Char}, REPL.LineEdit.MIState, REPL.LineEditREPL, Vararg{Any, N} where N})
precompile(Tuple{typeof(Tokenize.Lexers.lex_colon), Tokenize.Lexers.Lexer{Base.GenericIOBuffer{Array{UInt8, 1}}, Tokenize.Tokens.Token}})
precompile(Tuple{REPL.LineEdit.var"#22#23"{OhMyREPL.Prompt.var"#14#40", String}, Any, Any})
precompile(Tuple{OhMyREPL.Prompt.var"#14#40", Any, Any, Any})
precompile(Tuple{typeof(Base.getproperty), REPL.LineEdit.MIState, Symbol})
precompile(Tuple{typeof(REPL.Terminals.cmove_up), REPL.Terminals.TerminalBuffer})
precompile(Tuple{REPL.LineEdit.var"#22#23"{OhMyREPL.BracketInserter.var"#6#13"{Array{Char, 1}, Array{Char, 1}}, String}, Any, Any})
precompile(Tuple{OhMyREPL.BracketInserter.var"#6#13"{Array{Char, 1}, Array{Char, 1}}, REPL.LineEdit.MIState, REPL.LineEditREPL, String})
precompile(Tuple{typeof(REPL.LineEdit.edit_backspace), REPL.LineEdit.MIState, Any})
precompile(Tuple{typeof(Base.Multimedia.display), REPL.REPLDisplay{REPL.LineEditREPL}, Base.Multimedia.MIME{Symbol("text/plain")}, Function})
precompile(Tuple{typeof(Base.show), Base.IOContext{Base.TTY}, Base.Multimedia.MIME{Symbol("text/plain")}, Function})
precompile(Tuple{typeof(Base.methods), Any})
precompile(Tuple{Core.var"#@doc", LineNumberNode, Module, Vararg{Any, N} where N})
precompile(Tuple{typeof(Base._typed_vcat), Type{Symbol}, Tuple{Array{Symbol, 1}, Array{Symbol, 1}, Array{Symbol, 1}, Array{Symbol, 1}, Array{Symbol, 1}, Array{Symbol, 1}}})
precompile(Tuple{typeof(Base.vcat), Markdown.MD})
precompile(Tuple{typeof(Base.Multimedia.display), REPL.REPLDisplay{REPL.LineEditREPL}, Base.Multimedia.MIME{Symbol("text/plain")}, Markdown.MD})
precompile(Tuple{typeof(Markdown.term), Base.IOContext{Base.TTY}, Markdown.Code, Int64})
precompile(Tuple{typeof(Base.print), Base.GenericIOBuffer{Array{UInt8, 1}}, Int64, String, Vararg{Any, N} where N})
precompile(Tuple{typeof(Base.print), Base.GenericIOBuffer{Array{UInt8, 1}}, UInt8})
precompile(Tuple{typeof(Tokenize.Lexers.lex_equal), Tokenize.Lexers.Lexer{Base.GenericIOBuffer{Array{UInt8, 1}}, Tokenize.Tokens.Token}})
precompile(Tuple{typeof(Tokenize.Lexers.lex_quote), Tokenize.Lexers.Lexer{Base.GenericIOBuffer{Array{UInt8, 1}}, Tokenize.Tokens.Token}})
precompile(Tuple{typeof(Base.print), Base.GenericIOBuffer{Array{UInt8, 1}}, Crayons.Crayon, String, Vararg{Any, N} where N})
precompile(Tuple{REPL.LineEdit.var"#22#23"{OhMyREPL.Prompt.var"#26#52", String}, Any, Any})
precompile(Tuple{OhMyREPL.Prompt.var"#26#52", Any, Any, Any})
precompile(Tuple{typeof(Base.get), Base.Dict{String, String}, String, String})
precompile(Tuple{typeof(Base.:(!=)), String, String})
precompile(Tuple{typeof(Base.getindex), Base.Dict{String, String}, String})
precompile(Tuple{typeof(Base.iterate), Base.Dict{String, String}})
precompile(Tuple{typeof(Base.iterate), Base.Dict{String, String}, Int64})
precompile(Tuple{typeof(Base.withenv), JLLWrappers.var"#2#3"{JLFzf.var"#1#2"{String, Tuple{String, String, String}}, String}, Base.Pair{String, String}, Vararg{Base.Pair{String, String}, N} where N})
precompile(Tuple{JLFzf.var"#1#2"{String, Tuple{String, String, String}}, String})
precompile(Tuple{typeof(Base.arg_gen), Tuple{String, String, String}})
precompile(Tuple{typeof(Base.setup_stdio), Base.GenericIOBuffer{Array{UInt8, 1}}, Bool})
precompile(Tuple{typeof(Base.setup_stdio), Base.PipeEndpoint, Bool})
precompile(Tuple{typeof(Base.setup_stdio), Base.TTY, Bool})
precompile(Tuple{typeof(Base.indexed_iterate), Tuple{Base.TTY, Bool}, Int64})
precompile(Tuple{typeof(Base.indexed_iterate), Tuple{Base.TTY, Bool}, Int64, Int64})
precompile(Tuple{typeof(Base.rawhandle), Base.TTY})
precompile(Tuple{typeof(Base.convert), Type{IO}, Base.PipeEndpoint})
precompile(Tuple{typeof(Base.getproperty), Base.Process, Symbol})
precompile(Tuple{typeof(Base.read), Base.PipeEndpoint})
precompile(Tuple{Base.var"#641#642"{Base.PipeEndpoint, Base.PipeEndpoint, Base.GenericIOBuffer{Array{UInt8, 1}}}})
precompile(Tuple{typeof(Base.success), Base.Process})
precompile(Tuple{typeof(JLFzf.insert_history_to_repl), REPL.LineEdit.MIState, Base.SubString{String}})
precompile(Tuple{REPL.LineEdit.var"#22#23"{OhMyREPL.Prompt.var"#21#47", String}, Any, Any})
precompile(Tuple{OhMyREPL.Prompt.var"#21#47", Any, Any, Any})
precompile(Tuple{REPL.LineEdit.var"##edit_abort#108", Any, typeof(REPL.LineEdit.edit_abort), REPL.LineEdit.MIState, Bool})
precompile(Tuple{typeof(Base.indexed_iterate), Tuple{Nothing, Int64}, Int64})
precompile(Tuple{typeof(Base.indexed_iterate), Tuple{Nothing, Int64}, Int64, Int64})
precompile(Tuple{REPL.var"#43#48"{REPL.REPLBackendRef}})

max_stars_repo_name: jondea/juliab

max_issues_repo_name: jondea/juliab

max_forks_repo_name: jondea/juliab