text:
module SearchLight

import DataFrames, OrderedCollections, Distributed, Dates, Logging, Millboard, YAML
import DataFrames.DataFrame

include("constants.jl")

haskey(ENV, "SEARCHLIGHT_ENV") || (ENV["SEARCHLIGHT_ENV"] = "dev")

include("Exceptions.jl")
using .Exceptions

import Inflector

include("Configuration.jl")
using .Configuration

const config =  SearchLight.Configuration.Settings(app_env = ENV["SEARCHLIGHT_ENV"])

include("model_types.jl")
include("Migration.jl")
include("Validation.jl")
include("Serializer.jl")
include("Generator.jl")
include("Relationships.jl")
include("Transactions.jl")
include("Callbacks.jl")

export find, findone
export rand, randone
export all, count # min, max, mean, median
export findone_or_create, createwith, updateby_or_create, update_or_create
export save, save!, save!!, updatewith!, updatewith!!
export deleteall, delete

export ispersisted
export pk, table

#######################

function connect end

function disconnect end

function connection end

#########################

# internals

mutable struct UnsupportedException <: Exception
  method_name::Symbol
  adapter_name::Symbol
end

Base.showerror(io::IO, e::UnsupportedException) = print(io, "Method $(e.method_name) is not supported by $(e.adapter_name)")

#
# ORM methods
#

function DataFrames.DataFrame(m::Type{T}, q::SQLQuery, j::Union{Nothing,Vector{SQLJoin}} = nothing)::DataFrames.DataFrame where {T<:AbstractModel}
  query(sql(m, q, j))::DataFrames.DataFrame
end

function DataFrames.DataFrame(m::Type{T}; order = SQLOrder(pk(m)))::DataFrames.DataFrame where {T<:AbstractModel}
  DataFrame(m, SQLQuery(order = order))
end

function DataFrames.DataFrame(m::Type{T}, w::SQLWhereEntity; order = SQLOrder(pk(m)))::DataFrames.DataFrame where {T<:AbstractModel}
  DataFrame(m, SQLQuery(where = [w], order = order))
end

function DataFrames.DataFrame(m::Type{T}, w::Vector{SQLWhereEntity}; order = SQLOrder(pk(m)))::DataFrames.DataFrame where {T<:AbstractModel}
  DataFrame(m, SQLQuery(where = w, order = order))
end

function find(m::Type{T}, q::SQLQuery, j::Union{Nothing,Vector{SQLJoin}} = nothing)::Vector{T} where {T<:AbstractModel}
  to_models(m, DataFrame(m, q, j))
end

function find(m::Type{T}, w::SQLWhereEntity;
                      order = SQLOrder(pk(m)))::Vector{T} where {T<:AbstractModel}
  find(m, SQLQuery(where = [w], order = order))
end

function find(m::Type{T}, w::Vector{SQLWhereEntity};
                      order = SQLOrder(pk(m)))::Vector{T} where {T<:AbstractModel}
  find(m, SQLQuery(where = w, order = order))
end

function find(m::Type{T};
                      order = SQLOrder(pk(m)),
                      limit = SQLLimit(),
                      where_conditions...)::Vector{T} where {T<:AbstractModel}
  find(m, SQLQuery(where = [SQLWhereExpression("$(SQLColumn(x)) = ?", y) for (x,y) in where_conditions], order = order, limit = limit))
end

function onereduce(collection::Vector{T})::Union{Nothing,T} where {T<:AbstractModel}
  isempty(collection) ? nothing : first(collection)
end

function findone(m::Type{T}; filters...)::Union{Nothing,T} where {T<:AbstractModel}
  find(m; filters...) |> onereduce
end

function Base.one(m::Type{T}; filters...)::Union{Nothing,T} where {T<:AbstractModel}
  findone(m; filters...)
end

function randone(m::Type{T})::Union{Nothing,T} where {T<:AbstractModel}
  SearchLight.rand(m, limit = 1) |> onereduce
end

function Base.all(m::Type{T}; columns::Vector{SQLColumn} = SQLColumn[], order = SQLOrder(pk(m)), limit::Union{Int,SQLLimit,String} = SQLLimit("ALL"), offset::Int = 0)::Vector{T} where {T<:AbstractModel}
  find(m, SQLQuery(columns = columns, order = order, limit = limit, offset = offset))
end

function Base.all(m::Type{T}, query::SQLQuery)::Vector{T} where {T<:AbstractModel}
  find(m, query)
end

function Base.first(m::Type{T}; order = SQLOrder(pk(m)))::Union{Nothing,T} where {T<:AbstractModel}
  find(m, SQLQuery(order = order, limit = 1)) |> onereduce
end

function Base.last(m::Type{T}; order = SQLOrder(pk(m), :desc))::Union{Nothing,T} where {T<:AbstractModel}
  find(m, SQLQuery(order = order, limit = 1)) |> onereduce
end

# TODO: max(), min(), avg(), mean(), etc

function save(m::T; conflict_strategy::Symbol = :error, skip_validation::Bool = false, skip_callbacks::Vector{Symbol} = Symbol[])::Bool where {T<:AbstractModel}
  try
    _save!!(m, conflict_strategy = conflict_strategy, skip_validation = skip_validation, skip_callbacks = skip_callbacks)

    true
  catch ex
    @error ex

    false
  end
end

function save!(m::T; conflict_strategy::Symbol = :error, skip_validation::Bool = false, skip_callbacks::Vector{Symbol} = Symbol[])::T where {T<:AbstractModel}
  save!!(m, conflict_strategy = conflict_strategy, skip_validation = skip_validation, skip_callbacks = skip_callbacks)
end
function save!!(m::T; conflict_strategy::Symbol = :error, skip_validation::Bool = false, skip_callbacks::Vector{Symbol} = Symbol[])::T where {T<:AbstractModel}
  df::DataFrames.DataFrame = _save!!(m, conflict_strategy = conflict_strategy, skip_validation = skip_validation, skip_callbacks = skip_callbacks)

  id = if in(SearchLight.LAST_INSERT_ID_LABEL, names(df))
    df[1, SearchLight.LAST_INSERT_ID_LABEL]
  elseif in(Symbol(pk(m)), names(df))
    df[1, Symbol(pk(m))]
  elseif in(String(pk(m)), names(df))
    df[1, String(pk(m))]
  end

  id === nothing && getfield(m, Symbol(pk(m))).value !== nothing &&
    (id = getfield(m, Symbol(pk(m))).value)

  id === nothing && throw(SearchLight.Exceptions.UnretrievedModelException(typeof(m), id))

  n = findone(typeof(m); (Symbol(pk(m))=>id, )...)

  n === nothing && throw(SearchLight.Exceptions.UnretrievedModelException(typeof(m), id))

  db_fields = persistable_fields(typeof(m))
  @sync Distributed.@distributed for f in fieldnames(typeof(m))
    in(string(f), db_fields) && setfield!(m, f, getfield(n, f))
  end

  m
end

function _save!!(m::T; conflict_strategy::Symbol = :error, skip_validation::Bool = false, skip_callbacks::Vector{Symbol} = Symbol[])::DataFrames.DataFrame where {T<:AbstractModel}
  if ! skip_validation
    model_validator = Validation.validate(m)
    Validation.haserrors(model_validator) &&
      throw(SearchLight.Exceptions.InvalidModelException(m, model_validator.errors, "Model $(typeof(m)) is not valid: $(Validation.errors_to_string(model_validator))"))
  end

  ! in(:before_save, skip_callbacks) && hasmethod(Callbacks.before_save, Tuple{typeof(m)}) &&  Callbacks.before_save(m)

  result = query(to_store_sql(m, conflict_strategy = conflict_strategy))

  ! in(:after_save, skip_callbacks) && hasmethod(Callbacks.after_save, Tuple{typeof(m)}) && Callbacks.after_save(m)

  result
end

function updatewith!(m::T, w::T)::T where {T<:AbstractModel}
  for fieldname in fieldnames(typeof(m))
    string(fieldname) == pk(m) && continue
    setfield!(m, fieldname, getfield(w, fieldname))
  end

  m
end

function updatewith!(m::T, w::Dict; skip_callbacks::Vector{Symbol} = Symbol[])::T where {T<:AbstractModel}
  for fieldname in fieldnames(typeof(m))
    string(fieldname) == pk(m) && continue

    value = if haskey(w, fieldname)
              w[fieldname]
            elseif haskey(w, string(fieldname))
              w[string(fieldname)]
            else
              continue
            end

    value = if typeof(getfield(m, fieldname)) == Bool
              booltypes(value)
            else
              try
                autoconvert(convertmethod(m, fieldname, value), m, fieldname, value)
              catch ex
                if ! in(:on_exception, skip_callbacks) && hasmethod(Callbacks.on_exception, Tuple{typeof(m),TypeConversionException})
                  m::T = Callbacks.on_exception(m, TypeConversionException(m, fieldname, value, ex))::T
                  getfield(m, fieldname)
                else
                  rethrow(ex)
                end
              end
            end

    try
      setfield!(m, fieldname, autoconvert(convertmethod(m, fieldname, value), m, fieldname, value))
    catch ex
      if ! in(:on_exception, skip_callbacks) && hasmethod(Callbacks.on_exception, Tuple{typeof(m),TypeConversionException})
        m = Callbacks.on_exception(m, TypeConversionException(fieldname, value, ex))::T
        setfield!(m, fieldname, parse(typeof(getfield(m, fieldname)), value))
      else
        rethrow(ex)
      end
    end
  end

  m
end

function convertmethod(m::T, fieldname::Symbol, value::Any) where {T<:AbstractModel}
  # @show fieldname, typeof(getfield(m, fieldname)), typeof(value)
  if typeof(getfield(m, fieldname)) == typeof(value)
    identity
  elseif hasmethod(parse, Tuple{Type{typeof(getfield(m, fieldname))},typeof(value)})
    parse
  elseif hasmethod(convert, Tuple{Type{typeof(getfield(m, fieldname))},typeof(value)})
    convert
  elseif hasmethod(typeof(getfield(m, fieldname)), Tuple{typeof(value)})
    typeof(getfield(m, fieldname)) # constructor
  else
    MissingConversionMethodException
  end
end

function booltypes(value::Any) :: Bool
  if lowercase(string(value)) == "on" || value == :on || value == "1" || value == 1 || lowercase(string(value)) == "true" || value == :true
    true
  elseif lowercase(string(value)) == "off" || value == :off || value == "0" || value == 0 || lowercase(string(value)) == "false" || value == :false || value == ""
    false
  end
end

function autoconvert(mthd, m::T, fieldname::Symbol, value::Any) where {T<:AbstractModel, R}
  if Symbol(mthd) in [:convert, :parse]
    mthd(typeof(getfield(m, fieldname)), value)
  elseif occursin("MissingConversionMethodException", string(mthd))
    mthd(typeof(getfield(m, fieldname)), value) |> throw
  else
    mthd(value) # constructor
  end
end

function updatewith!!(m::T, w::Union{T,Dict})::T where {T<:AbstractModel}
  SearchLight.save!!(updatewith!(m, w))
end

const updatewith = updatewith!

function createwith(m::Type{T}, w::Dict)::T where {T<:AbstractModel}
  updatewith!(m(), w)
end

function updateby_or_create(m::T; ignore = Symbol[], skip_update = false, filters...)::T where {T<:AbstractModel}
  existing = findone(typeof(m), filters...)

  if existing !== nothing
    skip_update && return existing

    for fieldname in fieldnames(typeof(m))
      ( string(fieldname) == pk(m) || in(fieldname, ignore) ) && continue
      setfield!(existing, fieldname, getfield(m, fieldname))
    end

    return SearchLight.save!!(existing)
  else
    m.id = DbId()
    return SearchLight.save!!(m)
  end
end

function update_or_create(m::T; ignore = Symbol[], skip_update = false)::T where {T<:AbstractModel}
  updateby_or_create(m; ignore = ignore, skip_update = skip_update, NamedTuple{ (Symbol(pk(m)),) }( (getfield(m, Symbol(pk(m))),) )...)
end

function findone_or_create(m::Type{T}; filters...)::T where {T<:AbstractModel}
  lookup = findone(m; filters...)
  lookup !== nothing && return lookup

  _m::T = try
    m()
  catch ex
    isa(ex, MethodError) ? Base.invokelatest(m) : rethrow(ex)
  end

  for (property, value) in filters
    setfield!(_m, Symbol(is_fully_qualified(string(property)) ? from_fully_qualified(string(property))[end] : property), value)
  end

  _m
end

#
# Object generation
#

function to_models(m::Type{T}, df::DataFrames.DataFrame)::Vector{T} where {T<:AbstractModel}
  models = OrderedCollections.OrderedDict{DbId,T}()
  dfs = dataframes_by_table(m, df)

  row_count::Int = 1
  for row in eachrow(df)
    main_model::T = to_model!!(m, dfs[table(m)][row_count, :])

    if haskey(models, getfield(main_model, Symbol(pk(m))).value)
      main_model = models[getfield(main_model, Symbol(pk(m))).value]
    end

    if ! haskey(models, getfield(main_model, Symbol(pk(m))).value) &&
          getfield(main_model, Symbol(pk(m))).value !== nothing
      models[DbId(getfield(main_model, Symbol(pk(m))).value)] = main_model
    end

    row_count += 1
  end

  models |> values |> collect
end

function to_model(m::Type{T}, row::DataFrames.DataFrameRow; skip_callbacks::Vector{Symbol} = Symbol[])::T where {T<:AbstractModel}
  _m::T = try
    m()
  catch ex
    isa(ex, MethodError) ? Base.invokelatest(m) : rethrow(ex)
  end

  obj::T = try
    m()
  catch ex
    isa(ex, MethodError) ? Base.invokelatest(m) : rethrow(ex)
  end

  set_fields = Symbol[]

  for field in settable_fields(m, row)
    unq_field = from_fully_qualified(m, field)

    ismissing(row[field]) && continue # if it's NA we just leave the default value of the empty obj

    value = if ! in(:on_find, skip_callbacks) && hasmethod(Callbacks.on_find, Tuple{typeof(_m),Symbol,typeof(row[field])})
              try
                _m = Callbacks.on_find(_m, unq_field, row[field])

                getfield(_m, unq_field)
              catch ex
                @error ex

                row[field]
              end
            else
              row[field]
            end

    value = if in(unq_field, Serializer.serializables(m))
              Serializer.deserialize(typeof(getfield(_m, unq_field)), value)
            else
              value
            end

    try
      setfield!(obj, unq_field, oftype(getfield(_m, unq_field), value))
    catch ex
      @error ex

      ! in(:on_exception, skip_callbacks) && hasmethod(Callbacks.on_exception, Tuple{typeof(_m),TypeConversionException}) ?
        (obj = Callbacks.on_exception(obj, TypeConversionException(obj, unq_field, value, ex))::T) :
        rethrow(ex)
    end

    push!(set_fields, unq_field)
  end

  for field in fieldnames(typeof(_m))
    if ! in(field, set_fields)
      try
        setfield!(obj, field, getfield(_m, field))
      catch ex
        @error ex
        @error field
      end
    end
  end

  if ! in(:after_find, skip_callbacks) && hasmethod(Callbacks.after_find, Tuple{typeof(obj)})
    obj = Callbacks.after_find(obj)
  end

  obj
end

function to_model!!(m::Type{T}, df::DataFrames.DataFrame; row_index = 1)::T where {T<:AbstractModel}
  dfr = DataFrames.DataFrameRow(df, row_index)

  to_model(m, dfr)
end

function to_model!!(m::Type{T}, dfr::DataFrames.DataFrameRow)::T where {T<:AbstractModel}
  to_model(m, dfr)
end

function to_model(m::Type{T}, df::DataFrames.DataFrame; row_index = 1)::Union{Nothing,T} where {T<:AbstractModel}
  size(df)[1] >= row_index ? to_model!!(m, df, row_index = row_index) : nothing
end

#
# Query generation
#

function to_select_part(m::Type{T}, cols::Vector{SearchLight.SQLColumn}, joins::Union{Nothing,Vector{SQLJoin}} = nothing)::String where {T<:SearchLight.AbstractModel}
  sp = if ! isempty(cols)
    table_columns = []
    cols = vcat(cols, columns_from_joins(joins))

    for column in cols
      push!(table_columns, prepare_column_name(column, m))
    end

    join(table_columns, ", ")
  else
    tbl_cols = join(SearchLight.to_fully_qualified_sql_column_names(m, SearchLight.persistable_fields(m), escape_columns = true), ", ")
    table_columns = isempty(tbl_cols) ? String[] : vcat(tbl_cols, map(x -> prepare_column_name(x, m), columns_from_joins(joins)))

    join(table_columns, ", ")
  end

  string("SELECT ", sp)
end

function to_select_part(m::Type{T}, c::SQLColumn)::String where {T<:AbstractModel}
  to_select_part(m, [c])
end

function to_select_part(m::Type{T}, c::String)::String where {T<:AbstractModel}
  to_select_part(m, SQLColumn(c, raw = c == "*"))
end

function to_select_part(m::Type{T})::String where {T<:AbstractModel}
  to_select_part(m, SQLColumn[])
end

function to_from_part end

function to_where_part end

function to_order_part end

function to_group_part end

function to_limit_part end

function to_limit_part(l::Int)::String
  to_limit_part(SQLLimit(l))
end

function to_offset_part end

function to_having_part end

function to_join_part end

"""
  columns_from_joins(joins::Vector{SQLJoin})::Vector{SQLColumn}

Extracts columns from joins param and adds to be used for the SELECT part
"""
function columns_from_joins(joins::Union{Nothing,Vector{SQLJoin}} = nothing)::Vector{SearchLight.SQLColumn}
  jcols = SearchLight.SQLColumn[]

  joins === nothing && return jcols

  for j in joins
    jcols = vcat(jcols, j.columns)
  end

  jcols
end

function column_data_to_column_name end

function prepare_column_name(column::SearchLight.SQLColumn, m::Type{T})::String where {T<:SearchLight.AbstractModel}
  if column.raw
    column.value |> string
  else
    column_data::Dict{Symbol,Any} = SearchLight.from_literal_column_name(column.value)
    if ! haskey(column_data, :table_name)
      column_data[:table_name] = SearchLight.table(m)
    end
    if ! haskey(column_data, :alias)
      column_data[:alias] = ""
    end

    column_data_to_column_name(column, column_data)
  end
end

function columns_names_by_table(tables_names::Vector{String}, df::DataFrames.DataFrame)::Dict{String,Vector{Symbol}}
  tables_columns = Dict{String,Vector{Symbol}}()

  for t in tables_names
    tables_columns[t] = Symbol[]
  end

  for dfc in names(df)
    table_name = ""
    sdfc = string(dfc)

    ! occursin("_", sdfc) && continue

    for t in tables_names
      if startswith(sdfc, t)
        table_name = t
        break
      end
    end

    ! in(table_name, tables_names) && continue

    push!(tables_columns[table_name], dfc |> Symbol)
  end

  tables_columns
end

function dataframes_by_table(tables_names::Vector{String}, tables_columns::Dict{String,Vector{Symbol}}, df::DataFrames.DataFrame)::Dict{String,DataFrames.DataFrame}
  sub_dfs = Dict{String,DataFrames.DataFrame}()

  for t in tables_names
    sub_dfs[t] = df[:, tables_columns[t]]
  end

  sub_dfs
end
function dataframes_by_table(m::Type{T}, df::DataFrames.DataFrame)::Dict{String,DataFrames.DataFrame} where {T<:AbstractModel}
  tables_names = String[table(m)]

  dataframes_by_table(tables_names, columns_names_by_table(tables_names, df), df)
end

function to_find_sql end
const to_fetch_sql = to_find_sql

function to_store_sql end

function to_sqlinput(m::T, field::Symbol, value; skip_callbacks::Vector{Symbol} = Symbol[])::SQLInput where {T<:AbstractModel}
  value = if ! in(:on_save, skip_callbacks) && hasmethod(Callbacks.on_save, Tuple{typeof(m),Symbol,typeof(value)})
            try
              m = Callbacks.on_save(m, field, value)

              getfield(m, field)
            catch ex
              @error ex

              value
            end
          else
            value
          end

  value = if in(field, Serializer.serializables(typeof(m)))
            Serializer.serialize(value)
          else
            value
          end

  SQLInput(value)
end

#
# delete methods
#

function delete_all end;
const deleteall = delete_all

function delete end

#
# query execution
#

function query end

#
# ORM utils
#

function clone(o::T, fieldname::Symbol, value::Any)::T where {T<:SQLType}
  content = Dict{Symbol,Any}()
  for field in fieldnames(typeof(o))
    content[field] = getfield(o, field)
  end
  content[fieldname] = value

  T(; content...)
end

function clone(o::T, changes::Dict{Symbol,Any})::T where {T<:SQLType}
  content = Dict{Symbol,Any}()
  for field in fieldnames(typeof(o))
    content[field] = getfield(o, field)
  end
  content = merge(content, changes)

  T(; content...)
end

function columns end

function ispersisted(m::T)::Bool where {T<:AbstractModel}
  getfield(m, Symbol(pk(m))).value !== nothing
end

function column_field_name end

function persistable_fields(m::Type{T}; fully_qualified::Bool = false)::Vector{String} where {T<:AbstractModel}
  object_fields = [map(x -> string(x), fieldnames(m))...]
  fully_qualified ? to_fully_qualified_sql_column_names(m, object_fields) : object_fields
end

function settable_fields(m::Type{T}, row::DataFrames.DataFrameRow)::Vector{Symbol} where {T<:AbstractModel}
  df_cols::Vector{Symbol} = map(x -> Symbol(x), names(row))
  fields = is_fully_qualified(m, df_cols[1]) ? to_sql_column_names(m, fieldnames(m)) : fieldnames(m)

  intersect(fields, df_cols)
end

#
# utility functions
#

function table(m::Type{T})::String where {T<:AbstractModel}
  Inflector.to_plural(string(m) |> strip_module_name) |> lowercase
end

function pk(m::T)::String where {T<:AbstractModel}
  pk(typeof(m))
end

function pk(m::Type{T})::String where {T<:AbstractModel}
  "id"
end

const primary_key_name = pk

function strip_table_name(m::Type{T}, f::Symbol)::Symbol where {T<:AbstractModel}
  replace(string(f), Regex("^$(table(m))_") => "", count = 1) |> Symbol
end

function is_fully_qualified(m::Type{T}, f::Symbol)::Bool where {T<:AbstractModel}
  startswith(string(f), table(m)) && hasfield(m, strip_table_name(m, f))
end
function is_fully_qualified(t::Type{T})::Bool where {T<:SQLType}
  replace(t |> string, "\""=>"") |> string |> is_fully_qualified
end

function is_fully_qualified(s::String)::Bool
  ! startswith(s, ".") && occursin(".", s)
end

function from_fully_qualified(m::Type{T}, f::Symbol)::Symbol where {T<:AbstractModel}
  is_fully_qualified(m, f) ? strip_table_name(m, f) : f
end

function from_fully_qualified(s::String)::Tuple{String,String}
  ! occursin(".", s) && throw("$s is not a fully qualified SQL column name in the format table_name.column_name")

  (x,y) = split(s, ".")

  (string(x),string(y))
end
function from_fully_qualified(t::Type{T})::Tuple{String,String} where {T<:SQLType}
  replace(t |> string, "\""=>"") |> string |> from_fully_qualified
end

function strip_module_name(s::Any)::String
  split(string(s), ".") |> last
end

function to_fully_qualified(v::String, t::String)::String
  t * "." * v
end

function to_fully_qualified(m::Type{T}, v::String)::String where {T<:AbstractModel}
  to_fully_qualified(v, table(m))
end
function to_fully_qualified(m::Type{T}, c::SQLColumn)::String where {T<:AbstractModel}
  c.raw && return c.value
  to_fully_qualified(c.value, table(m))
end

function to_sql_column_names(m::Type{T}, fields::Vector{Symbol})::Vector{Symbol} where {T<:AbstractModel}
  map(x -> (to_sql_column_name(m, string(x))) |> Symbol, fields)
end
function to_sql_column_names(m::Type{T}, fields::Tuple)::Vector{Symbol} where {T<:AbstractModel}
  to_sql_column_names(m, Symbol[fields...])
end

function to_sql_column_name(v::String, t::String)::String
  str = strip_quotes(t) * "_" * strip_quotes(v)
  if isquoted(t) && isquoted(v)
    add_quotes(str)
  else
    str
  end
end
function to_sql_column_name(m::Type{T}, v::String)::String where {T<:AbstractModel}
  to_sql_column_name(v, table(m))
end
function to_sql_column_name(m::Type{T}, c::SQLColumn)::String where {T<:AbstractModel}
  to_sql_column_name(c.value, table(m))
end

function to_fully_qualified_sql_column_names(m::Type{T}, persistable_fields::Vector{String}; escape_columns::Bool = false)::Vector{String} where {T<:AbstractModel}
  map(x -> to_fully_qualified_sql_column_name(m, x, escape_columns = escape_columns), persistable_fields)
end

function to_fully_qualified_sql_column_name(m::Type{T}, f::String; escape_columns::Bool = false, alias::String = "")::String where {T<:AbstractModel}
  if escape_columns
    "$(to_fully_qualified(m, f) |> escape_column_name) AS $(isempty(alias) ? (to_sql_column_name(m, f) |> escape_column_name) : alias)"
  else
    "$(to_fully_qualified(m, f)) AS $(isempty(alias) ? to_sql_column_name(m, f) : alias)"
  end
end

function from_literal_column_name(c::String)::Dict{Symbol,String}
  result = Dict{Symbol,String}()
  result[:original_string] = c

  # has alias?
  if occursin(" AS ", c)
    parts = split(c, " AS ")
    result[:column_name] = parts[1]
    result[:alias] = parts[2]
  else
    result[:column_name] = c
  end

  # is fully qualified?
  if occursin(".", result[:column_name])
    parts = split(result[:column_name], ".")
    result[:table_name] = parts[1]
    result[:column_name] = parts[2]
  end

  result
end

function to_dict(m::Any)::Dict{String,Any}
  Dict(string(f) => getfield(m, Symbol(f)) for f in fieldnames(typeof(m)))
end

function to_string_dict(m::T; all_fields::Bool = false, all_output::Bool = false)::Dict{String,String} where {T<:AbstractModel}
  fields = all_fields ? fieldnames(typeof(m)) : persistable_fields(typeof(m))
  response = Dict{String,String}()

  for f in fields
    value = getfield(m, Symbol(f))
    response[string(f) * "::" * string(typeof(value))] = string(value)
  end

  response
end
function to_string_dict(m::Any; all_output::Bool = false)::Dict{String,String}
  to_string_dict(m, [f for f in fieldnames(typeof(m))], all_output = all_output)
end
function to_string_dict(m::Any, fields::Vector{Symbol}; all_output::Bool = false)::Dict{String,String}
  response = Dict{String,String}()
  for f in fields
    response[string(f)] = string(string(getfield(m, Symbol(f))))
  end

  response
end

function enclosure(v::Any, o::Any)::String
  in(string(o), ["IN", "in"]) ? "($(string(v)))" : string(v)
end

function update_query_part end

function escape_column_name end

function escape_value end

function index_name(table_name::Union{String,Symbol}, column_name::Union{String,Symbol}) :: String
  string(table_name) * "__" * "idx_" * string(column_name)
end

function sql(m::Type{T}, q::SQLQuery = SQLQuery(), j::Union{Nothing,Vector{SQLJoin}} = nothing)::String where {T<:AbstractModel}
  to_fetch_sql(m, q, j)
end

function sql(m::T)::String where {T<:AbstractModel}
  to_store_sql(m)
end

### UTIL ###

"""
    add_quotes(str::String) :: String

Adds quotes around `str` and escapes any previously existing quotes.
"""
function add_quotes(str::String) :: String
  if ! startswith(str, "\"")
    str = "\"$str"
  end
  if ! endswith(str, "\"")
    str = "$str\""
  end

  str
end

"""
    strip_quotes(str::String) :: String

Unquotes `str`.
"""
function strip_quotes(str::String) :: String
  isquoted(str) ? str[2:end-1] : str
end

"""
    isquoted(str::String) :: Bool

Checks weather or not `str` is quoted.
"""
function isquoted(str::String) :: Bool
  startswith(str, "\"") && endswith(str, "\"")
end

"""
    expand_nullable{T}(value::Union{Nothing,T}, default::T) :: T

Returns `value` if it is not `nothing` - otherwise `default`.
"""
function expand_nullable(value::Union{Nothing,T}, default::T)::T where T
  value === nothing ? default : value
end

function Core.NamedTuple(p::Pair) :: NamedTuple
  @eval ($(p[1]) = $(p[2]), )
end

include("QueryBuilder.jl")

end


text:
function johnsontrotter(low, high)
    function permutelevel(vec)
        if length(vec) < 2
            return [vec]
        end
        sequences = []
        endint = vec[end]
        smallersequences = permutelevel(vec[1:end-1])
        leftward = true
        for seq in smallersequences
            for pos in (leftward ? (length(seq)+1:-1:1): (1:length(seq)+1))
                push!(sequences, insert!(copy(seq), pos, endint))
            end
            leftward = !leftward
        end
        sequences
    end
    permutelevel(collect(low:high))
end

for (i, sequence) in enumerate(johnsontrotter(1,4))
    println("""$sequence, $(i & 1 == 1 ? "+1" : "-1")""")
end

ext: jl

max_stars_repo_name: ethansaxenian/RosettaDecode

max_issues_repo_name: ethansaxenian/RosettaDecode

max_forks_repo_name: ethansaxenian/RosettaDecode


text:
module TestDeprecated

using Test, DataFrames, CategoricalArrays

const ≅ = isequal

@testset "by and aggregate" begin
    @test_throws ArgumentError by()
    @test_throws ArgumentError aggregate()
end

@testset "deprecated broadcasting assignment" begin
    df = DataFrame(a=1:4, b=1, c=2)
    df.a .= 'a':'d'
    @test df == DataFrame(a=97:100, b=1, c=2)
    dfv = view(df, 2:3, 2:3)
    dfv.b .= 0
    @test df.b == [1, 0, 0, 1]
end

@testset "indicator in joins" begin
    name = DataFrame(ID = [1, 2, 3], Name = ["John Doe", "Jane Doe", "Joe Blogs"])
    job = DataFrame(ID = [1, 2, 4], Job = ["Lawyer", "Doctor", "Farmer"])

    @test outerjoin(name, job, on = :ID, indicator=:source) ≅
          outerjoin(name, job, on = :ID, source=:source)
    @test leftjoin(name, job, on = :ID, indicator=:source) ≅
          leftjoin(name, job, on = :ID, source=:source)
    @test rightjoin(name, job, on = :ID, indicator=:source) ≅
          rightjoin(name, job, on = :ID, source=:source)

    @test_throws ArgumentError outerjoin(name, job, on = :ID,
                                         indicator=:source, source=:source)
    @test_throws ArgumentError leftjoin(name, job, on = :ID,
                                       indicator=:source, source=:source)
    @test_throws ArgumentError rightjoin(name, job, on = :ID,
                                         indicator=:source, source=:source)
end

@testset "hcat with vector" begin
      df = DataFrame(x=1:3)
      x = [4, 5, 6]
      hdf = hcat(df, x)
      @test hdf[!, 1] == df[!, 1]
      @test hdf[!, 1] !== df[!, 1]
      @test hdf[!, 2] !== x
      hdf = hcat(x, df)
      @test hdf[!, 2] == df[!, 1]
      @test hdf[!, 2] !== df[!, 1]
      @test hdf[!, 1] !== x

      df = DataFrame()
      DataFrames.hcat!(df, CategoricalVector{Union{Int, Missing}}(1:10), makeunique=true)
      @test df[!, 1] == CategoricalVector(1:10)
      DataFrames.hcat!(df, 1:10, makeunique=true)
      @test df[!, 2] == collect(1:10)
      DataFrames.hcat!(df, collect(1:10), makeunique=true)
      @test df[!, 3] == collect(1:10)

      df = DataFrame()
      df2 = hcat(CategoricalVector{Union{Int, Missing}}(1:10), df, makeunique=true)
      @test isempty(df)
      @test df2[!, 1] == collect(1:10)
      @test names(df2) == ["x1"]
      ref_df = copy(df2)
      df3 = hcat(11:20, df2, makeunique=true)
      @test df2 == ref_df
      @test df3[!, 1] == collect(11:20)
      @test names(df3) == ["x1", "x1_1"]

      df1 = DataFrame(a=1:3)
      df2 = DataFrame(b=1:3)
      dfv = view(df2, :, :)
      x = [1, 2, 3]

      df3 = hcat(df1, x)
      @test propertynames(df3) == [:a, :x1]
      @test df3.a == df1.a
      @test df3.x1 == x
      @test df3.a !== df1.a
      @test df3.x1 !== x
      df3 = hcat(df1, x, copycols=true)
      @test propertynames(df3) == [:a, :x1]
      @test df3.a == df1.a
      @test df3.x1 == x
      @test df3.a !== df1.a
      @test df3.x1 !== x
      df3 = hcat(df1, x, copycols=false)
      @test propertynames(df3) == [:a, :x1]
      @test df3.a === df1.a
      @test df3.x1 === x

      df3 = hcat(x, df1)
      @test propertynames(df3) == [:x1, :a]
      @test df3.a == df1.a
      @test df3.x1 == x
      @test df3.a !== df1.a
      @test df3.x1 !== x
      df3 = hcat(x, df1, copycols=true)
      @test propertynames(df3) == [:x1, :a]
      @test df3.a == df1.a
      @test df3.x1 == x
      @test df3.a !== df1.a
      @test df3.x1 !== x
      df3 = hcat(x, df1, copycols=false)
      @test propertynames(df3) == [:x1, :a]
      @test df3.a === df1.a
      @test df3.x1 === x

      df3 = hcat(dfv, x, df1)
      @test propertynames(df3) == [:b, :x1, :a]
      @test df3.a == df1.a
      @test df3.b == dfv.b
      @test df3.x1 == x
      @test df3.a !== df1.a
      @test df3.b !== dfv.b
      @test df3.x1 !== x
      df3 = hcat(dfv, x, df1, copycols=true)
      @test propertynames(df3) == [:b, :x1, :a]
      @test df3.a == df1.a
      @test df3.b == dfv.b
      @test df3.x1 == x
      @test df3.a !== df1.a
      @test df3.b !== dfv.b
      @test df3.x1 !== x
      df3 = hcat(dfv, x, df1, copycols=false)
      @test propertynames(df3) == [:b, :x1, :a]
      @test df3.a === df1.a
      @test df3.b === dfv.b
      @test df3.x1 === x
end

end # module


text:
# CV Metrics

include("iou.jl")
include("img_quality.jl")


text:
function DecimateAsym!(var::PlmVar, alg::PlmAlg, dec::DecVar{2})

    Jmat,pseudolike = MinimizePLAsym(alg,var) #initial minimization
    score , Jtensor = ComputeScore(Jmat, var)  #initial score

    LL,N = size(dec.dmask)
    allcoup = N*LL

    while true
        SetCouplingToZeroAsym!(Jmat,  var, dec)
        nzeros = sum(!dec.dmask)
        fraczeros = nzeros/allcoup
        Jmat,pseudolike = MinimizePLAsym(alg, var, dec, Jmat, x0=Jmat)
        score, Jtensor = ComputeScore(Jmat, var)  #initial score
        fraczeros >= dec.fracmax && break
    end
    return Jmat,pseudolike
end

function SetCouplingToZeroAsym!(vecJ::Array{Float64,2}, var::PlmVar, dec::DecVar{2})

    LL,N = size(dec.dmask)
    q  = var.q
    q2 = var.q2

@compat    vecval = Tuple{Int,Int,Float64}[]
@compat    sizehint!(vecval, N*LL)
    for j=1:N,i=1:LL
        dec.dmask[i,j] && push!(vecval,(i,j,vecJ[i,j]*vecJ[i,j])) # sorting absval
    end

    lvec = length(vecval)
    idxperm = sortperm(Float64[ vecval[i][3] for i=1:lvec])
    println("ndec = ", dec.fracdec * N*(N-1)*q2 );

@compat    ndec = round(Int,dec.fracdec * N*(N-1)*q2 )

    for i=1:ndec
        sitei = vecval[idxperm[i]][1]
        sitej = vecval[idxperm[i]][2]
        dec.dmask[sitei, sitej] = false
    end
end

function MinimizePLAsym(alg::PlmAlg, var::PlmVar, dec::DecVar{2}, Jmat::Array{Float64,2}; x0 = zeros(Float64,size(Jmat)))

    LL = size(x0,1)
    psvec = SharedArray(Float64, var.N)
    Jmatnew = @parallel hcat for site=1:var.N
        function f(x::Vector, g::Vector)
            g === nothing  && (g = zeros(Float64, length(x)))
            return PLsiteAndGrad!(x, g, site,  var)
        end
        vec0 = x0[:,site]
        lb,ub = ComputeConstraintsAsym!(dec, site, var.q, var.N, vec0)
        opt = Opt(alg.method, LL)
        ftol_abs!(opt, alg.epsconv)

        lower_bounds!(opt, lb)
        upper_bounds!(opt, ub)

        maxeval!(opt, alg.maxit)
        min_objective!(opt, f)
        elapstime = @elapsed  (minf, minx, ret) = optimize(opt, vec0)
        psvec[site] = minf
        alg.verbose && @printf("site = %d\t pl = %.4f\t time = %.4f\n", site, minf, elapstime)
        minx
    end
    return Jmatnew, psvec
end

function ComputeConstraintsAsym!(decvar::DecVar{2}, site::Int, q::Int, N::Int, x0::Array{Float64,1} )

    dmask = decvar.dmask

    LL = length(x0)
    lb = -Inf * ones(Float64,LL)
    ub =  Inf * ones(Float64,LL)

    for i=1:size(decvar.dmask,1)
        if dmask[i,site] == false
            lb[ i ] = -1.0e-6
            ub[ i ] =  1.0e-6
            x0[ i ] = 0.0
        else
            x0[ i ] += (1.0 - 2.0*rand())*1e-3 # minimal pert to coupling
        end
    end
    return lb,ub
end


text:
using Unitful, Statistics

@testset "Dipoles" begin

    dips = Dipole[]

    @testset "Create" begin

        dip1 = Dipole("Talairach", 1u"m", 2u"m", 1u"m", 0, 0, 0, 1, 1, 1)
        dip2 = Dipole("Talairach", 1u"m", 2u"m", 3u"m", 0, 0, 0, 2, 2, 2)

        dips = push!(dips, dip1)
        dips = push!(dips, dip2)

        @test length(dips) == 2
    end

    @testset "Show" begin

        show(dips[1])
        show(dips)
    end

    @testset "Mean" begin

        b = Neuroimaging.mean(dips)
        @test b.x == 1.0u"m"
        @test b.y == 2.0u"m"
        @test b.z == 2.0u"m"
    end

    @testset "Std" begin

        b = Neuroimaging.std(dips)
        @test b.x == 0.0u"m"
        @test b.y == 0.0u"m"
        @test b.z == Statistics.std([1, 3])u"m"
    end

    @testset "Best" begin

        dip1 = Dipole("Talairach", 1u"mm", 2u"mm", 1u"mm", 0, 0, 0, 1, 1, 1)
        dip2 = Dipole("Talairach", 1u"mm", 2u"mm", 3u"mm", 0, 0, 0, 2, 2, 2)
        dip3 = Dipole("Talairach", 3u"mm", 2u"mm", 3u"mm", 0, 0, 0, 2, 2, 2)
        dip4 = Dipole("Talairach", 3u"mm", 4u"mm", 3u"mm", 0, 0, 0, 2, 2, 2)

        dips = Dipole[]
        dips = push!(dips, dip1)
        dips = push!(dips, dip2)
        dips = push!(dips, dip3)
        dips = push!(dips, dip4)

        # Takes the closest dipole
        bd = best_dipole(dip2, dips)
        @test bd == dip2

        # Takes a larger dipole thats further away if within specified radius
        dip5 = Dipole("Talairach", 1u"mm", 2.01u"mm", 3u"mm", 0, 0, 0, 2, 2, 20)
        dips = push!(dips, dip5)
        bd = best_dipole(dip2, dips)
        @test bd == dip5

        # Reduce radius
        bd = best_dipole(dip2, dips, maxdist = 0.00000001)
        @test bd == dip2

        # Or when nothing of appropriate size
        bd = best_dipole(
            Dipole("Talairach", 10u"mm", 2.01u"mm", 3u"mm", 0, 0, 0, 2, 2, 20),
            dips,
            min_dipole_size = 999,
        )
        @test isnan(bd)

    end
end


text:
# This file was generated, do not modify it. # hide
N=10; @show [4.0*(i-1)/(N-1) - 2.0 for i in 1:N]


text:
function TimeStampedFieldPVCoordinates(arg0::AbsoluteDate, arg1::FieldPVCoordinates)
    return TimeStampedFieldPVCoordinates((AbsoluteDate, FieldPVCoordinates), arg0, arg1)
end

function TimeStampedFieldPVCoordinates(arg0::AbsoluteDate, arg1::FieldPVCoordinates, arg2::FieldPVCoordinates)
    return TimeStampedFieldPVCoordinates((AbsoluteDate, FieldPVCoordinates, FieldPVCoordinates), arg0, arg1, arg2)
end

function TimeStampedFieldPVCoordinates(arg0::AbsoluteDate, arg1::FieldVector3D, arg2::FieldVector3D, arg3::FieldVector3D)
    return TimeStampedFieldPVCoordinates((AbsoluteDate, FieldVector3D, FieldVector3D, FieldVector3D), arg0, arg1, arg2, arg3)
end

function TimeStampedFieldPVCoordinates(arg0::AbsoluteDate, arg1::RealFieldElement, arg2::FieldPVCoordinates)
    return TimeStampedFieldPVCoordinates((AbsoluteDate, RealFieldElement, FieldPVCoordinates), arg0, arg1, arg2)
end

function TimeStampedFieldPVCoordinates(arg0::AbsoluteDate, arg1::RealFieldElement, arg2::FieldPVCoordinates, arg3::RealFieldElement, arg4::FieldPVCoordinates)
    return TimeStampedFieldPVCoordinates((AbsoluteDate, RealFieldElement, FieldPVCoordinates, RealFieldElement, FieldPVCoordinates), arg0, arg1, arg2, arg3, arg4)
end

function TimeStampedFieldPVCoordinates(arg0::AbsoluteDate, arg1::RealFieldElement, arg2::FieldPVCoordinates, arg3::RealFieldElement, arg4::FieldPVCoordinates, arg5::RealFieldElement, arg6::FieldPVCoordinates)
    return TimeStampedFieldPVCoordinates((AbsoluteDate, RealFieldElement, FieldPVCoordinates, RealFieldElement, FieldPVCoordinates, RealFieldElement, FieldPVCoordinates), arg0, arg1, arg2, arg3, arg4, arg5, arg6)
end

function TimeStampedFieldPVCoordinates(arg0::AbsoluteDate, arg1::RealFieldElement, arg2::FieldPVCoordinates, arg3::RealFieldElement, arg4::FieldPVCoordinates, arg5::RealFieldElement, arg6::FieldPVCoordinates, arg7::RealFieldElement, arg8::FieldPVCoordinates)
    return TimeStampedFieldPVCoordinates((AbsoluteDate, RealFieldElement, FieldPVCoordinates, RealFieldElement, FieldPVCoordinates, RealFieldElement, FieldPVCoordinates, RealFieldElement, FieldPVCoordinates), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
end

function TimeStampedFieldPVCoordinates(arg0::AbsoluteDate, arg1::RealFieldElement, arg2::PVCoordinates)
    return TimeStampedFieldPVCoordinates((AbsoluteDate, RealFieldElement, PVCoordinates), arg0, arg1, arg2)
end

function TimeStampedFieldPVCoordinates(arg0::AbsoluteDate, arg1::RealFieldElement, arg2::PVCoordinates, arg3::RealFieldElement, arg4::PVCoordinates)
    return TimeStampedFieldPVCoordinates((AbsoluteDate, RealFieldElement, PVCoordinates, RealFieldElement, PVCoordinates), arg0, arg1, arg2, arg3, arg4)
end

function TimeStampedFieldPVCoordinates(arg0::AbsoluteDate, arg1::RealFieldElement, arg2::PVCoordinates, arg3::RealFieldElement, arg4::PVCoordinates, arg5::RealFieldElement, arg6::PVCoordinates)
    return TimeStampedFieldPVCoordinates((AbsoluteDate, RealFieldElement, PVCoordinates, RealFieldElement, PVCoordinates, RealFieldElement, PVCoordinates), arg0, arg1, arg2, arg3, arg4, arg5, arg6)
end

function TimeStampedFieldPVCoordinates(arg0::AbsoluteDate, arg1::RealFieldElement, arg2::PVCoordinates, arg3::RealFieldElement, arg4::PVCoordinates, arg5::RealFieldElement, arg6::PVCoordinates, arg7::RealFieldElement, arg8::PVCoordinates)
    return TimeStampedFieldPVCoordinates((AbsoluteDate, RealFieldElement, PVCoordinates, RealFieldElement, PVCoordinates, RealFieldElement, PVCoordinates, RealFieldElement, PVCoordinates), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
end

function TimeStampedFieldPVCoordinates(arg0::AbsoluteDate, arg1::jdouble, arg2::FieldPVCoordinates)
    return TimeStampedFieldPVCoordinates((AbsoluteDate, jdouble, FieldPVCoordinates), arg0, arg1, arg2)
end

function TimeStampedFieldPVCoordinates(arg0::AbsoluteDate, arg1::jdouble, arg2::FieldPVCoordinates, arg3::jdouble, arg4::FieldPVCoordinates)
    return TimeStampedFieldPVCoordinates((AbsoluteDate, jdouble, FieldPVCoordinates, jdouble, FieldPVCoordinates), arg0, arg1, arg2, arg3, arg4)
end

function TimeStampedFieldPVCoordinates(arg0::AbsoluteDate, arg1::jdouble, arg2::FieldPVCoordinates, arg3::jdouble, arg4::FieldPVCoordinates, arg5::jdouble, arg6::FieldPVCoordinates)
    return TimeStampedFieldPVCoordinates((AbsoluteDate, jdouble, FieldPVCoordinates, jdouble, FieldPVCoordinates, jdouble, FieldPVCoordinates), arg0, arg1, arg2, arg3, arg4, arg5, arg6)
end

function TimeStampedFieldPVCoordinates(arg0::AbsoluteDate, arg1::jdouble, arg2::FieldPVCoordinates, arg3::jdouble, arg4::FieldPVCoordinates, arg5::jdouble, arg6::FieldPVCoordinates, arg7::jdouble, arg8::FieldPVCoordinates)
    return TimeStampedFieldPVCoordinates((AbsoluteDate, jdouble, FieldPVCoordinates, jdouble, FieldPVCoordinates, jdouble, FieldPVCoordinates, jdouble, FieldPVCoordinates), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
end

function TimeStampedFieldPVCoordinates(arg0::FieldAbsoluteDate, arg1::FieldPVCoordinates)
    return TimeStampedFieldPVCoordinates((FieldAbsoluteDate, FieldPVCoordinates), arg0, arg1)
end

function TimeStampedFieldPVCoordinates(arg0::FieldAbsoluteDate, arg1::FieldPVCoordinates, arg2::FieldPVCoordinates)
    return TimeStampedFieldPVCoordinates((FieldAbsoluteDate, FieldPVCoordinates, FieldPVCoordinates), arg0, arg1, arg2)
end

function TimeStampedFieldPVCoordinates(arg0::FieldAbsoluteDate, arg1::FieldVector3D)
    return TimeStampedFieldPVCoordinates((FieldAbsoluteDate, FieldVector3D), arg0, arg1)
end

function TimeStampedFieldPVCoordinates(arg0::FieldAbsoluteDate, arg1::FieldVector3D, arg2::FieldVector3D, arg3::FieldVector3D)
    return TimeStampedFieldPVCoordinates((FieldAbsoluteDate, FieldVector3D, FieldVector3D, FieldVector3D), arg0, arg1, arg2, arg3)
end

function TimeStampedFieldPVCoordinates(arg0::FieldAbsoluteDate, arg1::RealFieldElement, arg2::FieldPVCoordinates)
    return TimeStampedFieldPVCoordinates((FieldAbsoluteDate, RealFieldElement, FieldPVCoordinates), arg0, arg1, arg2)
end

function TimeStampedFieldPVCoordinates(arg0::FieldAbsoluteDate, arg1::RealFieldElement, arg2::FieldPVCoordinates, arg3::RealFieldElement, arg4::FieldPVCoordinates)
    return TimeStampedFieldPVCoordinates((FieldAbsoluteDate, RealFieldElement, FieldPVCoordinates, RealFieldElement, FieldPVCoordinates), arg0, arg1, arg2, arg3, arg4)
end

function TimeStampedFieldPVCoordinates(arg0::FieldAbsoluteDate, arg1::RealFieldElement, arg2::FieldPVCoordinates, arg3::RealFieldElement, arg4::FieldPVCoordinates, arg5::RealFieldElement, arg6::FieldPVCoordinates)
    return TimeStampedFieldPVCoordinates((FieldAbsoluteDate, RealFieldElement, FieldPVCoordinates, RealFieldElement, FieldPVCoordinates, RealFieldElement, FieldPVCoordinates), arg0, arg1, arg2, arg3, arg4, arg5, arg6)
end

function TimeStampedFieldPVCoordinates(arg0::FieldAbsoluteDate, arg1::RealFieldElement, arg2::FieldPVCoordinates, arg3::RealFieldElement, arg4::FieldPVCoordinates, arg5::RealFieldElement, arg6::FieldPVCoordinates, arg7::RealFieldElement, arg8::FieldPVCoordinates)
    return TimeStampedFieldPVCoordinates((FieldAbsoluteDate, RealFieldElement, FieldPVCoordinates, RealFieldElement, FieldPVCoordinates, RealFieldElement, FieldPVCoordinates, RealFieldElement, FieldPVCoordinates), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
end

function TimeStampedFieldPVCoordinates(arg0::FieldAbsoluteDate, arg1::RealFieldElement, arg2::PVCoordinates)
    return TimeStampedFieldPVCoordinates((FieldAbsoluteDate, RealFieldElement, PVCoordinates), arg0, arg1, arg2)
end

function TimeStampedFieldPVCoordinates(arg0::FieldAbsoluteDate, arg1::RealFieldElement, arg2::PVCoordinates, arg3::RealFieldElement, arg4::PVCoordinates)
    return TimeStampedFieldPVCoordinates((FieldAbsoluteDate, RealFieldElement, PVCoordinates, RealFieldElement, PVCoordinates), arg0, arg1, arg2, arg3, arg4)
end

function TimeStampedFieldPVCoordinates(arg0::FieldAbsoluteDate, arg1::RealFieldElement, arg2::PVCoordinates, arg3::RealFieldElement, arg4::PVCoordinates, arg5::RealFieldElement, arg6::PVCoordinates)
    return TimeStampedFieldPVCoordinates((FieldAbsoluteDate, RealFieldElement, PVCoordinates, RealFieldElement, PVCoordinates, RealFieldElement, PVCoordinates), arg0, arg1, arg2, arg3, arg4, arg5, arg6)
end

function TimeStampedFieldPVCoordinates(arg0::FieldAbsoluteDate, arg1::RealFieldElement, arg2::PVCoordinates, arg3::RealFieldElement, arg4::PVCoordinates, arg5::RealFieldElement, arg6::PVCoordinates, arg7::RealFieldElement, arg8::PVCoordinates)
    return TimeStampedFieldPVCoordinates((FieldAbsoluteDate, RealFieldElement, PVCoordinates, RealFieldElement, PVCoordinates, RealFieldElement, PVCoordinates, RealFieldElement, PVCoordinates), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
end

function TimeStampedFieldPVCoordinates(arg0::FieldAbsoluteDate, arg1::jdouble, arg2::FieldPVCoordinates)
    return TimeStampedFieldPVCoordinates((FieldAbsoluteDate, jdouble, FieldPVCoordinates), arg0, arg1, arg2)
end

function TimeStampedFieldPVCoordinates(arg0::FieldAbsoluteDate, arg1::jdouble, arg2::FieldPVCoordinates, arg3::jdouble, arg4::FieldPVCoordinates)
    return TimeStampedFieldPVCoordinates((FieldAbsoluteDate, jdouble, FieldPVCoordinates, jdouble, FieldPVCoordinates), arg0, arg1, arg2, arg3, arg4)
end

function TimeStampedFieldPVCoordinates(arg0::FieldAbsoluteDate, arg1::jdouble, arg2::FieldPVCoordinates, arg3::jdouble, arg4::FieldPVCoordinates, arg5::jdouble, arg6::FieldPVCoordinates)
    return TimeStampedFieldPVCoordinates((FieldAbsoluteDate, jdouble, FieldPVCoordinates, jdouble, FieldPVCoordinates, jdouble, FieldPVCoordinates), arg0, arg1, arg2, arg3, arg4, arg5, arg6)
end

function TimeStampedFieldPVCoordinates(arg0::FieldAbsoluteDate, arg1::jdouble, arg2::FieldPVCoordinates, arg3::jdouble, arg4::FieldPVCoordinates, arg5::jdouble, arg6::FieldPVCoordinates, arg7::jdouble, arg8::FieldPVCoordinates)
    return TimeStampedFieldPVCoordinates((FieldAbsoluteDate, jdouble, FieldPVCoordinates, jdouble, FieldPVCoordinates, jdouble, FieldPVCoordinates, jdouble, FieldPVCoordinates), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
end

function shifted_by(obj::TimeStampedFieldPVCoordinates, arg0::RealFieldElement)
    return jcall(obj, "shiftedBy", TimeStampedFieldPVCoordinates, (RealFieldElement,), arg0)
end

function shifted_by(obj::TimeStampedFieldPVCoordinates, arg0::jdouble)
    return jcall(obj, "shiftedBy", TimeStampedFieldPVCoordinates, (jdouble,), arg0)
end


text:
module Events

using Dates
using Discord

function on_message_create(c::Client, e::MessageCreate)
    e.message.content == "ping" && reply(c, e.message, "pong")
end

function predicate(c::Client, e::MessageCreate)
    return e.message.content == "ping"
end

function main()
    c = Client(ENV["DISCORD_TOKEN"])
    open(c)

    # This handler runs on all MessageCreate events.
    add_handler!(c, MessageCreate, on_message_create; tag=:ping)
    # We can simplify the above handler with a predicate function and do syntax.
    add_handler!(c, MessageCreate; tag=:ping, predicate=predicate) do c, e
        reply(c, e.message, "pong")
    end
    # This handler runs on events which have no non-default handler.
    add_handler!(c, FallbackEvent, (c, e) -> println("Unhandled event: $(typeof(e))"))
    # This handler runs on all events. The FallbackEvent handler will no longer run.
    add_handler!(c, AbstractEvent, (c, e) -> println("Event: $(typeof(e))"))
    # You can add counting or timed expiries. This handler runs 3 times or for 10 seconds.
    add_handler!(c, TypingStart, (c, e) -> println("Typing"); n=3, timeout=Second(10))
    # You can aggregate results with a blocking handler.
    msgs = add_handler!(c, MessageCreate, (c, e) -> e.message.content; n=3, wait=true)
    println("Received 3 messages: ", msgs)

    return c
end

end

if abspath(PROGRAM_FILE) == @__FILE__
    c = Events.main()
    wait(c)
end


text:
import JSON
import Plots

result = JSON.parsefile("build/frequency_response.json")

Plots.gr()

p = Plots.plot()

Plots.xlabel!(p, "t (s)")
Plots.ylabel!(p, "value")
Plots.plot!(p, [itr[1] for itr in result], [itr[2] for itr in result], lab="input,  ω = π rad/s")
Plots.plot!(p, [itr[1] for itr in result], [itr[3] for itr in result], lab="output, ω = π rad/s")
Plots.plot!(p, [itr[1] for itr in result], [itr[4] for itr in result], lab="input,  ω = 2π rad/s")
Plots.plot!(p, [itr[1] for itr in result], [itr[5] for itr in result], lab="output, ω = 2π rad/s")
Plots.savefig(p, "build/frequency_response.pdf")

max_stars_repo_name: Shimushushushu/etude-naive-controller

max_issues_repo_name: Shimushushushu/etude-naive-controller

max_forks_repo_name: Shimushushushu/etude-naive-controller


text:
@time @safetestset "Essentials" begin
    @time @safetestset "QuantumOperators" begin include("QuantumOperators.jl") end
    @time @safetestset "QuantumNumbers" begin include("QuantumNumbers.jl") end
    @time @safetestset "Spatials" begin include("Spatials.jl") end
    @time @safetestset "DegreesOfFreedom" begin include("DegreesOfFreedom.jl") end
    @time @safetestset "QuantumSystems" begin include("QuantumSystems.jl") end
    @time @safetestset "Frameworks" begin include("Frameworks.jl") end
end


text:
# ######################
# A DataFrame way to get file

import Base: getindex, view

export getindex

function Base.getindex(file::JDFFile, rows, col::String)
    JDF.load(file; cols = [col])[rows, 1]
end

Base.getindex(file::JDFFile, rows, cols::AbstractVector{String}) = begin
    JDF.load(file; cols = cols)[rows, :]
end

Base.view(file::JDFFile, rows, cols) = getindex(file, rows, cols)

getindex(file::JDFFile, rows, cols) = JDF.load(file)[rows, cols]


text: abstract type PythonLexer <: AbstractLexer end


text:
abstract type Camera{T<:AbstractFloat} end

Base.eltype(::Camera{T}) where T = T

mutable struct SimpleCamera{T,I<:Integer} <: Camera{T}
    pos::SVector{3,T}
    up::SVector{3,T}
    fwd::SVector{3,T}
    right::SVector{3,T}
    w::T
    h::T
    d::T
    w_px::I
    h_px::I
    dx::T
    dy::T
    x₁::SVector{3,T}
    x₂::SVector{3,T}
    y₁::SVector{3,T}
    y₂::SVector{3,T}
end

function SimpleCamera(pos::SVector{3,T},
                      up::SVector{3,T},
                      fwd::SVector{3,T},
                      w::T, h::T, d::T,
                      w_px::I, h_px::I) where {T,I}
    w/h ≈ w_px/h_px ||
        @warn "Image plane ratio $(w/h) different from pixel ratio $(w_px/h_px)"

    dx = one(T)/(w_px - 1)
    dy = one(T)/(h_px - 1)

    z = zero(T)
    zv = SVector(z, z, z)

    cam = SimpleCamera(pos, up, fwd, zv,
                       w, h, d,
                       w_px, h_px,
                       dx, dy,
                       zv, zv, zv, zv)
    recalc!(cam)
end

function recalc!(cam::SimpleCamera{T}) where T
    cam.right = cross(cam.up, cam.fwd)
    cam.up = cross(cam.fwd, cam.right)
    half = one(T)/2

    cam.x₁ = cam.d*cam.fwd - half*cam.w*cam.right
    cam.x₂ = cam.d*cam.fwd + half*cam.w*cam.right
    cam.y₁ = cam.d*cam.fwd + half*cam.h*cam.up
    cam.y₂ = cam.d*cam.fwd - half*cam.h*cam.up

    cam
end

Images.width(cam::SimpleCamera) = cam.w_px
Images.height(cam::SimpleCamera) = cam.h_px

function Base.getindex(cam::SimpleCamera, i::T, j::T) where T
    t_x = (i-1)*cam.dx
    t_y = (j-1)*cam.dy
    dir = t_x * cam.x₁ + (one(T)-t_x) * cam.x₂ + t_y * cam.y₁ + (one(T)-t_y) * cam.y₂
    Ray(cam.pos, dir)
end

function lookat!(cam::SimpleCamera{T}, target::SVector{3,T},
                 up::SVector{3,T}=SVector(zero(T), one(T), zero(T))) where T
    cam.fwd = normalize(target - cam.pos)
    cam.up = normalize(up)
    recalc!(cam)
end

function Base.show(io::IO, ::MIME"text/plain", cam::SimpleCamera{T}) where T
    write(io, "SimpleCamera{$T} @ ")
    show(io, cam.pos)
    write(io, "\nAxes:\n")
    write(io, "- up:      ")
    show(io, cam.up)
    write(io, "\n- forward: ")
    show(io, cam.fwd)
    write(io, "\n- right:   ")
    show(io, cam.right)
    write(io, "\nImage plane:\n- $(cam.w) × $(cam.h) ($(cam.w_px) × $(cam.h_px) pixels);\n- $(cam.w/cam.h) aspect ratio\n- distance to image plane: $(cam.d)")
end

export Camera, SimpleCamera, lookat!


text:
using Documenter, ChemistryFeaturization

makedocs(
    sitename = "ChemistryFeaturization.jl",
    modules = [ChemistryFeaturization],
    pages = Any[
        "Home"=>"index.md",
        "Terminology"=>"terminology.md",
        "Tutorial"=>"tutorial.md",
        "Types"=>Any[
            "Overview"=>"types/overview.md",
            "Abstract Types"=>"types/abstracttypes.md",
            "Atoms Objects"=>"types/atoms.md",
            "Feature Descriptors"=>"types/feature_descriptors.md",
            "Codec"=>"types/codecs.md",
            "Featurization"=>"types/featurizations.md",
            "Featurized Atoms"=>"types/featurizedatoms.md",
        ],
        "Utilities"=>"utils.md",
        "Contributing"=>"contributing.md",
        "Changelog"=>"changelog.md",
    ],
    format = Documenter.HTML(
        # Use clean URLs, unless built as a "local" build
        prettyurls = !("local" in ARGS),
        canonical = "https://chemellia.github.io/ChemistryFeaturization.jl/stable/",
        edit_link = "main",
    ),
    linkcheck = "linkcheck" in ARGS,
)
deploydocs(
    repo = "github.com/Chemellia/ChemistryFeaturization.jl.git",
    target = "build",
    devbranch = "main",
    branch = "gh-pages",
)

# for local build
"""
makedocs(
    sitename = "ChemistryFeaturization.jl",
    modules = [ChemistryFeaturization],
    pages = Any[
        "Home"=>"index.md",
        "Terminology"=>"terminology.md",
        "Tutorial"=>"tutorial.md",
        "Types"=>Any[
            "Abstract Types"=>"types/abstracttypes.md",
            "Atoms Objects"=>"types/atoms.md",
            "Feature Descriptors"=>"types/feature_descriptors.md",
            "Featurization"=>"types/featurizations.md",
            "Featurized Atoms"=>"types/featurizedatoms.md",
            "Codec"=>"types/codecs.md",
        ],
        "Utilities"=>"utils.md",
        "Contributing"=>"contributing.md",
        "Changelog"=>"changelog.md",
    ],
    format = Documenter.HTML(
        # Use clean URLs, unless built as a "local" build
        prettyurls = false,
        canonical = "https://chemellia.github.io/ChemistryFeaturization.jl/stable/",
        edit_link = "main",
    ),
    linkcheck = "linkcheck" in ARGS,
)
"""


text:
struct Asset <: Account

end

max_stars_repo_name: adamwillisXanax/accountingJulia

max_issues_repo_name: adamwillisXanax/accountingJulia

max_forks_repo_name: adamwillisXanax/accountingJulia


text:
################################################################################
#                       Euler Angle Axis <=> Quaternions
################################################################################

for k = 1:samples
    # Sample a vector that will be aligned with the Euler angle.
    v = [randn();randn();randn()]
    v = v/norm(v)

    # Sample a angle between (0,2π).
    a = 2*pi*rand()

    # Create the Euler Angle and Axis representation.
    angleaxis = EulerAngleAxis(a,v)

    # Convert to quaternion.
    q = angleaxis_to_quat(angleaxis)

    # Convert back to Euler Angle and Axis.
    angleaxis_conv = quat_to_angleaxis(q)

    # Notice that the returned Euler angle will be always in the interval
    # [0,π].
    s = +1
    (a > π) && (a = 2π - a; s = -1)

    # Compare.
    @test  abs(angleaxis_conv.a -   a) < 1e-10
    @test norm(angleaxis_conv.v - s*v) < 1e-10

    # Rotate a vector aligned with the Euler axis using the quaternion.
    r     = v*randn()
    r_rot = vect(q\r*q)

    # The vector representation must be the same after the rotation.
    @test norm(r-r_rot) < 1e-10
end

# Test the exceptions.
@test_throws ArgumentError angleaxis_to_quat(0, [1;2;3;4])


text:
# https://diffeqflux.sciml.ai/dev/examples/LV-Univ/

# using Revise

using DiffEqFlux, Flux, Optim, OrdinaryDiffEq, Plots
using DataInterpolations
using RoME

import DistributedFactorGraphs: getVariableLabelNumber, findFactorsBetweenNaive

using JLD2
using Dates
using Printf

# import IncrementalInference: accumulateFactorChain

# For DistributedFactorGraphs containing FluxModelsPose2Pose2.
# extract pose positions and times as well as joyveldata from flux factors.
function extractTimePoseJoyData(fg::AbstractDFG)
  poses = ls(fg, r"x\d") |> sortDFG
  fcts = lsf(fg, FluxModelsPose2Pose2) |>sortDFG

  JOYDATA = zeros(length(fcts),25,4)
  POSDATA = zeros(length(poses),3,100)
  TIMES = zeros(length(poses))

  T0 = getTimestamp(getVariable(fg, poses[1]))
  POSDATA[1,:,:] .= getVal(fg, poses[1])
  for i in 1:length(poses)-1
    POSDATA[i+1,:,:] .= getVal(fg, poses[i+1])
    JOYDATA[i,:,:] = getFactorType(fg, fcts[i]).joyVelData
    TIMES[i+1] = (getTimestamp(getVariable(fg, poses[i+1])) - T0).value * 1e-3
  end

  return TIMES, POSDATA, JOYDATA
end

##

fg = initfg()
loadDFG("/tmp/caesar/2020-05-11T02:25:53.702/fg_204_resolve.tar.gz", Main, fg)
TIMES, POSES, JOYDATA = extractTimePoseJoyData(fg)

# make sure its Float32
TIMES, POSES, JOYDATA = Float32.(TIMES), Float32.(POSES), Float32.(JOYDATA)

# get all velocities

# structure all data according to poses

##

# take in [X;u] = [x;y;ct;st;dx;dy;thr;str]
# output X
model_g = FastChain(FastDense( 8, 16, tanh),
                    FastDense(16, 16, tanh),
                    FastDense(16, 6) )
#

# The model weights are destructured into a vector of parameters
p_model = initial_params(model_g)
n_weights = length(p_model)

# # Parameters of the second equation (linear dynamics)
# p_system = Float32[0.0; 0.0, vx0, vy0]

p_all = p_model # [p_model; p_system]

## quasi-static parameters

START = 3

vx0, vy0 = JOYDATA[START,1,3], JOYDATA[START,1,4] # 0, 0
x0 = [0.0;0;1.0;0.0;vx0;vy0]
θ = Float32.(p_all)

##

STEPS = 2

tspan = (TIMES[START], TIMES[START+STEPS])
# dt = TIMES[START+1]-TIMES[START]
tsteps = range(tspan[1],tspan[2],length=size(JOYDATA,2)*STEPS)  # 0.0f0:1.0:25.0f0

joySteps = [JOYDATA[i,:,1:2] for i in START:(START+STEPS-1)]
joyStepsCat = vcat(joySteps...)

#
throttle_itp = LinearInterpolation( joyStepsCat[:,1], tsteps )
steering_itp = LinearInterpolation( joyStepsCat[:,2], tsteps )

# dx/dt = Fx + g(x,u)
function dxdt_odo!( dx, x, p, t, model_g, thr_itp, str_itp )
  # Destructure the parameters
  @assert length(p) == n_weights "dxdt_odo! model weights $(length(p)) do not match $n_weights"

  # Getting the throttle and steering inputs (from interpolators)
  thr = thr_itp(t)
  str = str_itp(t)

  # Update in place
  # Velocity model dynamics and TBD odometry model
  # The neural network outputs odometry from joystick values
  dx[1:6] .= model_g([x;thr;str], p)
  dx[1:2] .+= x[5:6] # try remove this structure later
  dx
end
# model_weights = p[1:n_weights]
# state = p[(end-3):end]

prob_odo = ODEProblem((dx,x,p,t)->dxdt_odo!(dx,x,p,t,model_g,throttle_itp,steering_itp), x0, tspan, p_all)
sol_odo = solve(prob_odo, Tsit5(), x0, p_all,
                         abstol = 1e-8, reltol = 1e-6)

function predict_univ(θ, x0_)
  # solving for both the ODE solution and network parameters
  return Array(solve(prob_odo, Tsit5(), x0_, θ,
                              saveat = tsteps))
end

function loss_univ(θ)

  # add for loop here for multiple segments
  pred = predict_univ(θ, x0)
  pred_x = pred[1,25:25:end]
  pred_y = pred[2,25:25:end]
  pred_ct = pred[3,25:25:end]
  pred_st = pred[4,25:25:end]
  pred_dxy = pred[5:6,25:25:end]
  # pred_dy = pred[6,25:25:end]

  # wait this does not derotate into relative observed values ()
  meas_x = POSES[START:(START+STEPS),1,1] |> reverse |> diff |> reverse
  meas_y = POSES[START:(START+STEPS),1,2] |> reverse |> diff |> reverse
  # FIXME, wont work beyond pi radians (must also preserve AD)
  meas_t = POSES[START:(START+STEPS),1,3] |> reverse |> diff |> reverse
  meas_ct = cos.(meas_t)
  meas_st = sin.(meas_t)

  # @show meas_x, pred_x
  ret = 0.0

  ret += sum(abs2, meas_x - pred_x)
  ret += sum(abs2, meas_y - pred_y)
  ret += sum(abs2, meas_ct - pred_ct)
  ret += sum(abs2, meas_st - pred_st)
  for i in 1:STEPS
    ret += 0.001*sum(abs2, pred[5,25*i] .- pred[5,((i-1)*25+1):(i*25-1)])
    ret += 0.001*sum(abs2, pred[6,25*i] .- pred[6,((i-1)*25+1):(i*25-1)])
  end

  return ret
end
l = predict_univ(θ)
l = loss_univ(θ)

θ

##

list_plots = []
iter = 0
callback = function (θ, l)
  global list_plots, iter

  if iter == 0
    list_plots = []
  end
  iter += 1

  @printf(stdout, "loss=%1.4E\n", l)

  pred = predict_univ(θ)

  plt = Plots.plot([pred[1];pred[1]+0.1], [pred[2];pred[2]], ylim=(-3, 3), xlim=(-1,5))
  # plt = Plots.plot(predict_univ(θ), ylim = (0, 6))
  push!(list_plots, plt)
  display(plt)
  return false
end

result_univ = DiffEqFlux.sciml_train(loss_univ, θ,
                                     ADAM(0.01),
                                     cb = callback,
                                     maxiters=500)
                                     # BFGS(initial_stepnorm = 0.01),
#

## Lest confirm all is good

result_univ.minimizer
result_univ.minimizer

 # - x0 |> norm

loss_univ(result_univ.minimizer)

####  Dev on interpose values

using RoMEPlotting
Gadfly.set_default_plot_size(35cm,20cm)

dfg = initfg()
loadDFG("/tmp/caesar/2020-05-11T02:25:53.702/fg_204_resolve.tar.gz", Main, dfg)

setNaiveFracAll!(dfg,1.0)

meas, pred = solveFactorMeasurements(dfg, :x0x1f1)

# reportFactors(dfg, FluxModelsPose2Pose2, [:x0x1f1;])

#

# function solveFactorMeasurementsChain(dfg::AbstractDFG, fsyms::Vector{Symbol})
#
#   # FCTS = getFactorType.(dfg, fsyms)
#   FCTS = solveFactorMeasurements.(dfg, fsyms)
#
# end

chords = RoME.assembleChordsDict(dfg, MAXADI=10)

plotFactorValues(chords[:x0][:x1]...)
plotFactorValues(chords[:x1][:x2]...)
plotFactorValues(chords[:x0][:x2]...)

JLD2.@save "/tmp/caesar/2020-05-11T02:25:53.702/chords_10.jld2" chords

using JSON2

str = JSON2.write(chords)
io = open("/tmp/chords10.json", "w")
println(io, str)
close(io)

str = JSON2.write(joysticks)
io = open("/tmp/joysticks10.json", "w")
println(io, str)
close(io)

io = open("/tmp/chords.json","r")
data = read(io)
close(io)

rstr = String(take!(IOBuffer(data)))

ndat = JSON2.read(rstr)

reshape(ndat[:x0][:x1][1], 3,100)

## Store joystick values in composite

joysticks = Dict{Symbol,Dict{Symbol,Matrix}}()

MAXADI = 10
vsyms = ls(dfg, r"x\d") |> sortDFG

lastPoseNum = getVariableLabelNumber(vsyms[end])
for from in vsyms[1:end-1]
  SRT = getVariableLabelNumber(from)
  joysticks[from] = Dict{Symbol, Matrix}()
  maxadi = lastPoseNum - getVariableLabelNumber(from)
  maxadi = MAXADI < maxadi ? MAXADI : maxadi
  for adi in 1:maxadi
    to = Symbol("x",getVariableLabelNumber(from)+adi)
    fsyms = findFactorsBetweenNaive(dfg, from, to)
    vecjoy = getFactorType.(dfg, fsyms) .|> x->x.joyVelData
    joysticks[from][to] = length(vecjoy)== 1 ? vecjoy[1] : vcat(vecjoy...)
  end
end

chords[:x0][:x1]
joysticks[:x0][:x1]

chords[:x0][:x9]
joysticks[:x0][:x9]

datasets = [ chords[:x0][:x1]]

#


text:
#using InvPendulum

function visualise_invpendulum(X, t, filename::String; options::Dict = Dict())
    # Find plotting limits
    xmin = minimum(X[2, :])-0.67
    xmax = maximum(X[2, :])+0.67
    fps::Int = get(options, :fps, 25)

    # Create animation
    title::String = get(options, :title, "")
    size::Tuple{Int, Int} = get(options, :size, (1280, 720))
    anim = Animation()

    # Create timestamps of the visualisation and interpolate states
    t_plot = t[1]:(1/fps):t[end]
    X_plot = Array{Float64}(4, length(t_plot))

    if haskey(options, :U)
        # Animate with U
        U = get(options, :U, zeros(length(t_plot)))
        @assert(length(U)==length(t))
        umin = minimum(U)-0.2
        umax = maximum(U)+0.2
        U_plot = Array{Float64}(length(t_plot))
        for (i, t2) = enumerate(t_plot)
            # find closest t's belonging to t_plot[i]
            j = indmin(abs.(t2-t))
            if t2 == t[j]
                @. X_plot[:, i] = X[:, j]
                U_plot[i] = U[j]
            elseif t2>t[j]
                @. X_plot[:, i] = (X[:, j+1]-X[:, j])*(t2-t[j])/(t[j+1]-t[j])
                U_plot[i] = (U[j+1]-U[j])*(t2-t[j])/(t[j+1]-t[j])
            else
                @. X_plot[:, i] = (X[:, j]-X[:, j-1])*(t2-t[j-1])/(t[j]-t[j-1])
                U_plot[i] = (U[j]-U[j-1])*(t2-t[j-1])/(t[j]-t[j-1])
            end
        end

        for (i, t2) = enumerate(t_plot)
            fig = plot(;size = size, layout = grid(2, 1, heights=[0.8,0.2]))
            plot_pendulum!(fig[1], X_plot[:, i], t2, xmin, xmax, title)
            plot!(fig[2], t_plot, vcat(U_plot[1:i], [NaN for j = i+1:length(t_plot)]), ylim = (umin, umax), lab = "u")
            frame(anim)
        end
    else
        # Animate without U
        for (i, t2) = enumerate(t_plot)
            # find closest t's belonging to t_plot[i]
            j = indmin(abs.(t2-t))
            if t2 == t[j]
                @. X_plot[:, i] = X[:, j]
            elseif t2>t[j]
                @. X_plot[:, i] = (X[:, j+1]-X[:, j])*(t2-t[j])/(t[j+1]-t[j])
            else
                @. X_plot[:, i] = (X[:, j]-X[:, j-1])*(t2-t[j-1])/(t[j]-t[j-1])
            end
        end

        for (i, t2) = enumerate(t_plot)
            fig = plot_pendulum(X_plot[:, i], t2, xmin, xmax, size, title)
            frame(anim)
        end
    end
    run(`ffmpeg -v 0 -framerate $(fps) -loop 0 -i $(anim.dir)/%06d.png -y $(filename)`)
    return nothing
end

#plotting the pendulum, xmin and xmax indicate how far the pendulum can move
function plot_pendulum!(fig, state::Array{Float64, 1}, time::Float64, xmin::Number, xmax::Number, title::String)
    l = 0.3302*2 #length of the rod
    lw = 0.015 #thickness of the rod
    basewidth = 0.2 #width of the car
    baseheight = 0.15 #height of the car

    #base plot
    Plots.plot!(fig, ratio=:equal, xlim = (xmin, xmax), ylim = (-l*1.1, l*1.1), title = title*" t=$(round(time, 1))", box=:full, grid=false)

    #plot zero line
    Plots.plot!(fig, [xmin, xmax], [0, 0], c=:black, l=:dot, lab = "", grid = false)

    #plot base
    base(x) = Plots.Shape(x+[-basewidth/2, basewidth/2, basewidth/2, -basewidth/2, -basewidth/2], [-baseheight/2, -baseheight/2, baseheight/2, baseheight/2, -baseheight/2])
    Plots.plot!(fig, base(state[2]), c=:orange, lab = "")

    #plot rod
    rot_mat = [cos(state[4]) -sin(state[4]); sin(state[4])  cos(state[4])] #rotation matrix, rotating the rod
    corners = [-lw/2 lw/2 lw/2 -lw/2 -lw/2; -l*0.03 -l*0.03 l l -l*0.03]
    corners = rot_mat*corners

    xrod = corners[1, :]
    yrod = corners[2, :]
    rod(x) = Plots.Shape(x+xrod, yrod)
    Plots.plot!(fig, rod(state[2]), c=:green, lab = "")
end
#plot_pendulum!(fig, state::Ptr{vector}, time::Float64, xmin::Number, xmax::Number) = plot_pendulum!(fig, convert(Array{Float64, 1}, state), time, xmin, xmax)

function plot_pendulum(state::Array{Float64, 1}, time::Float64, xmin::Number, xmax::Number, size::Tuple{Int, Int}, title::String)
    fig = plot(size=size)
    plot_pendulum!(fig, state, time, xmin, xmax, title)
    return fig
end

max_stars_repo_name: NikonPic/REINFORCEMENT-JULIA

max_issues_repo_name: NikonPic/REINFORCEMENT-JULIA

max_forks_repo_name: NikonPic/REINFORCEMENT-JULIA


text:
using POMDPModels

test_solver(RandomSolver(), BabyPOMDP())
test_solver(RandomSolver(), BabyPOMDP(), updater=PreviousObservationUpdater{Any}())


text:
include("euler/euler.jl")
using .BigIntegers: BigInteger
using BenchmarkTools
BenchmarkTools.DEFAULT_PARAMETERS.samples = 100

compute(n::Int, list_numbers::String)::SubString = sum(map(BigInteger, split(list_numbers, "\n")))[1:n]

str_numbers = """37107287533902102798797998220837590246510135740250
46376937677490009712648124896970078050417018260538
74324986199524741059474233309513058123726617309629
91942213363574161572522430563301811072406154908250
23067588207539346171171980310421047513778063246676
89261670696623633820136378418383684178734361726757
28112879812849979408065481931592621691275889832738
44274228917432520321923589422876796487670272189318
47451445736001306439091167216856844588711603153276
70386486105843025439939619828917593665686757934951
62176457141856560629502157223196586755079324193331
64906352462741904929101432445813822663347944758178
92575867718337217661963751590579239728245598838407
58203565325359399008402633568948830189458628227828
80181199384826282014278194139940567587151170094390
35398664372827112653829987240784473053190104293586
86515506006295864861532075273371959191420517255829
71693888707715466499115593487603532921714970056938
54370070576826684624621495650076471787294438377604
53282654108756828443191190634694037855217779295145
36123272525000296071075082563815656710885258350721
45876576172410976447339110607218265236877223636045
17423706905851860660448207621209813287860733969412
81142660418086830619328460811191061556940512689692
51934325451728388641918047049293215058642563049483
62467221648435076201727918039944693004732956340691
15732444386908125794514089057706229429197107928209
55037687525678773091862540744969844508330393682126
18336384825330154686196124348767681297534375946515
80386287592878490201521685554828717201219257766954
78182833757993103614740356856449095527097864797581
16726320100436897842553539920931837441497806860984
48403098129077791799088218795327364475675590848030
87086987551392711854517078544161852424320693150332
59959406895756536782107074926966537676326235447210
69793950679652694742597709739166693763042633987085
41052684708299085211399427365734116182760315001271
65378607361501080857009149939512557028198746004375
35829035317434717326932123578154982629742552737307
94953759765105305946966067683156574377167401875275
88902802571733229619176668713819931811048770190271
25267680276078003013678680992525463401061632866526
36270218540497705585629946580636237993140746255962
24074486908231174977792365466257246923322810917141
91430288197103288597806669760892938638285025333403
34413065578016127815921815005561868836468420090470
23053081172816430487623791969842487255036638784583
11487696932154902810424020138335124462181441773470
63783299490636259666498587618221225225512486764533
67720186971698544312419572409913959008952310058822
95548255300263520781532296796249481641953868218774
76085327132285723110424803456124867697064507995236
37774242535411291684276865538926205024910326572967
23701913275725675285653248258265463092207058596522
29798860272258331913126375147341994889534765745501
18495701454879288984856827726077713721403798879715
38298203783031473527721580348144513491373226651381
34829543829199918180278916522431027392251122869539
40957953066405232632538044100059654939159879593635
29746152185502371307642255121183693803580388584903
41698116222072977186158236678424689157993532961922
62467957194401269043877107275048102390895523597457
23189706772547915061505504953922979530901129967519
86188088225875314529584099251203829009407770775672
11306739708304724483816533873502340845647058077308
82959174767140363198008187129011875491310547126581
97623331044818386269515456334926366572897563400500
42846280183517070527831839425882145521227251250327
55121603546981200581762165212827652751691296897789
32238195734329339946437501907836945765883352399886
75506164965184775180738168837861091527357929701337
62177842752192623401942399639168044983993173312731
32924185707147349566916674687634660915035914677504
99518671430235219628894890102423325116913619626622
73267460800591547471830798392868535206946944540724
76841822524674417161514036427982273348055556214818
97142617910342598647204516893989422179826088076852
87783646182799346313767754307809363333018982642090
10848802521674670883215120185883543223812876952786
71329612474782464538636993009049310363619763878039
62184073572399794223406235393808339651327408011116
66627891981488087797941876876144230030984490851411
60661826293682836764744779239180335110989069790714
85786944089552990653640447425576083659976645795096
66024396409905389607120198219976047599490197230297
64913982680032973156037120041377903785566085089252
16730939319872750275468906903707539413042652315011
94809377245048795150954100921645863754710598436791
78639167021187492431995700641917969777599028300699
15368713711936614952811305876380278410754449733078
40789923115535562561142322423255033685442488917353
44889911501440648020369068063960672322193204149535
41503128880339536053299340368006977710650566631954
81234880673210146739058568557934581403627822703280
82616570773948327592232845941706525094512325230608
22918802058777319719839450180888072429661980811197
77158542502016545090413245809786882778948721859617
72107838435069186155435662884062257473692284509516
20849603980134001723930671666823555245252804609722
53503534226472524250874054075591789781264330331690"""

compute(10, str_numbers)

@benchmark compute(10, str_numbers)

max_stars_repo_name: Dynortice/Project-Euler

max_issues_repo_name: Dynortice/Project-Euler

max_forks_repo_name: Dynortice/Project-Euler


text:
arg_dict   = Dict{Any, Any}(

  # RK4 settings
  "run_type"           => 1,
  "delta_t"            => 0.01,
  # "t_max"              => 40.0,
  # "itermax"            => 10000,
  "t_max"              => 40.0,
  "itermax"            => 10,

  # because RK4 is selected and not steady Newton, we have to explicitly set parallel_data
  "parallel_data"      => PARALLEL_DATA_ELEMENT,

  "operator_type"      => "SBPGamma",
  # "operator_type"     => "SBPOmega",
  # "operator_type"     => "SBDiagE",
  "use_DG"             => true,
  # "delta_t"            => 5.0e-4,
  # "t_max"              => 500.0,
  "res_abstol"         => 1e-13,
  "res_reltol"         => 1e-13,
  "step_tol"           => 1e-13,
  "krylov_itermax"     => 30,
  "order"              => 1,
  "do_postproc"        => true,
  "use_staggered_grid" => false,
  "variable_type"      => :conservative,
  "dimensions"         => 2,
  "use_stagger_grid"   => false,
  "dmg_name"           => ".null",

  # "smb_name" => "/users/yanj4/Downloads/meshfiles/channel.smb",
  # "smb_name" => "/users/yanj4/Downloads/meshfiles/channel_12x12.smb",
  # "smb_name" => "/users/yanj4/Downloads/meshfiles/square128x128.smb",
  # "smb_name" => "/users/yanj4/Downloads/meshfiles/square81x81.smb",
  # "smb_name" => "/users/yanj4/Downloads/meshfiles/square64x64.smb",
  # "smb_name" => "/users/yanj4/Downloads/meshfiles/square32x32.smb",
  # "smb_name" => "/users/yanj4/Downloads/meshfiles/square8x8.smb",
  # "smb_name" => "/users/yanj4/Downloads/meshfiles/square16x16.smb",
  # "smb_name" => "/fasttmp/ashlea/jf_meshes/square16x16.smb",
  # "smb_name" => "/fasttmp/ashlea/nssolver_tests/0aa_meshes/square2_aa_par2.smb",
  # "smb_name" => "/fasttmp/ashlea/nssolver_tests/0aa_meshes/square2_aa_ser.smb",
  # "smb_name" => "/fasttmp/ashlea/nssolver_tests/0aa_meshes/square_pert/square02_pert_ser.smb",
  "smb_name" => "SRCMESHES/square02_pert_forviscous_ser.smb",

  #
  # Channel MMS: nonperiodic
  #
  "isViscous"          => true,
  "use_src_term"       => true,
  "numBC"              => 2,
  "BC1"                => [0, 2],
  "BC2"                => [1, 3],
  "BC1_name"           => "FreeStreamBC",
  "BC2_name"           => "FreeStreamBC",
  # "IC_name"            => "ICFreeStream",
  "IC_name"            => "ICPolynomial",
  # "IC_name"            => "ICPolynomial_fluxdbg",
  "perturb_ic"         => false,
  "perturb_mag"        => 0.01,
  "SRCname"            => "SRCPolynomial",
  "exact_soln_func"    => "ICPolynomial",

  "Flux_name"          => "RoeFlux",
  "SAT_type"           => "Hartman",
  "Cip"                => 1.0,
  "Ma"                 => 0.1,
  "Re"                 => 1.0e3,
  "aoa"                => 0.0,
  "sideslip_angle"     => 0.0,
  "CFL"                => 0.1,
  "jac_type"           => 3,
  "jac_method"         => 2,
  "solve"              => true,
  "write_eigs"         => false,
  "write_jac"          => false,
  "real_time"          => false,

  "write_timing"       => true,
  "physics"            => "NavierStokes",

  "output_freq"        => 1,

  "write_finalresidual" => true,
  "write_finalsolution" => true,
)


text:
"""
    variance(a)

Find the variance from a set of data.

# Arguments:
- `a`: holds the set of data

# Reference
    - According to Ronald E. Walpole, `variance` is used to measure the variability of a set of data. -- Introduction to Statistics by Ronald E. Walpole

# Contributors:
- [Aru Bhardwaj](https://github.com/arubhardwaj)
"""
function variance(a)
    avg = sum(a) / length(a)
    x = sum((a .- avg).^2)
    s_sq = x / (length(a) - 1)
    return(s_sq)
end

max_stars_repo_name: KohRongSoon/Julia

max_issues_repo_name: KohRongSoon/Julia

max_forks_repo_name: KohRongSoon/Julia


text:
# convert and promote
# ============================================================

#  convert and promote
function Base.promote_rule(::Type{MF}, ::Type{FF}) where {Tf,Ti,d, F<:Transform{Tf,d}, MF<:MapField{F,Tf,Ti,d}, FF<:FourierField{F,Tf,Ti,d}}
    return MF
end

function Base.convert(::Type{MF}, f::FourierField{F,Tf,Ti,d}) where {Tf,Ti,d, F<:Transform{Tf,d}, MF<:MapField{F,Tf,Ti,d}}
    ftran = fieldtransform(f)
    return MF(ftran, plan(ftran) \ fielddata(f))
end

function Base.convert(::Type{FF}, f::MapField{F,Tf,Ti,d}) where {Tf,Ti,d, F<:Transform{Tf,d}, FF<:FourierField{F,Tf,Ti,d}}
    ftran = fieldtransform(f)
    return FF(ftran, plan(ftran) * fielddata(f))
end

Base.convert(::Type{X}, f::X) where X<:Field = f::X

# Things that fall back to convert
# ============================================================

# convert to the corresponding dual field using FourierField or MapField
FourierField(f::X) where {X<:Field} = convert(FourierField(X),f)
MapField(f::X)     where {X<:Field} = convert(MapField(X),f)

# convert to the corresponding dual field using the explicit type
(::Type{MF})(f::Field{F,Tf,Ti,d}) where {Tf,Ti,d, F<:Transform{Tf,d}, MF<:MapField{F,Tf,Ti,d}} = convert(MF, f)
(::Type{FF})(f::Field{F,Tf,Ti,d}) where {Tf,Ti,d, F<:Transform{Tf,d}, FF<:FourierField{F,Tf,Ti,d}} = convert(FF, f)


text:
using Test
using DandelionWebSockets
using DandelionWebSockets: HTTPAdapter, HeaderList, HTTPHandshake, HTTPUpgradeResponse
import DandelionWebSockets: dohandshake, state_connecting

"FakeHTTPAdapter lets us control the handshake response in a test."
struct FakeHTTPAdapter <: HTTPAdapter
    response::HTTPUpgradeResponse
end
dohandshake(adapter::FakeHTTPAdapter, ::String, ::HeaderList) = adapter.response

"NothingWebSocketHandler is a handler that does nothing, but storing the connection. The default
implementations do nothing."
mutable struct NothingWebSocketHandler <: WebSocketHandler
    connection::Union{WebSocketConnection, Nothing}
    chanstop::Channel{Nothing}
    NothingWebSocketHandler() = new(nothing, Channel{Nothing}(0))
end
state_connecting(h::NothingWebSocketHandler, conn::WebSocketConnection) = h.connection = conn
state_closed(h::NothingWebSocketHandler) = put!(h.chanstop, nothing)
waitforclose(h::NothingWebSocketHandler) = take!(h.chanstop)

@testset "Issues                 " begin
    @testset "Issue #12: Masking frames should be done on a copy of data" begin
        # Arrange
        logic, handler, writer = makeclientlogic()

        text = "Foo"

        # Act
        handle(logic, SendTextFrame(text, true, OPCODE_TEXT))

        # Assert
        @test text == "Foo"
    end

    @testset "Issue #43: `stop`, on a WebSocketConnection that never opened, fails" begin
        # Arrange
        # Status code 200 will cause the handshake to be invalid.
        handshakeadapter = FakeHTTPAdapter(HTTPUpgradeResponse(IOBuffer(), 200, [], b""))
        handshake = HTTPHandshake(RandomDevice(), handshakeadapter)

        handler = NothingWebSocketHandler()
        client = WSClient(; handshake=handshake)

        # This connection will fail, because the handshake returned HTTP status code 200.
        wsconnect(client, "http://some/uri", handler)
        # Wait for the connection state to become closed.
        waitforclose(handler)

        # Act
        stop(handler.connection)

        # Assert
        # No assert, because the above call will throw an exception in the presence of issue #43.
    end
end


text:
"""
Parser utilities for `<XProtocol>`, presumably an internal Siemens metadata
protocol.
"""
#module XProtocol

using ParserCombinator

struct SimpleParam{T, Config<:NamedTuple}
    name::String
    config::Config
    vals::Vector{T}
end

function SimpleParam(type, name, config, vals)
    SimpleParam{type,typeof(config)}(name, config, collect(type, vals))
end

function Base.show(io::IO, param::SimpleParam{T}) where {T}
    print(io, "SimpleParam($T, $(repr(param.name)), $(param.config), $(param.vals))")
end

struct ParamMap{Config<:NamedTuple}
    name::String
    config::Config
    vals::Dict{Symbol,Any}
end

function ParamMap(name, config, vals)
    ParamMap{typeof(config)}(name, config, Dict(Symbol(p.name)=>p for p in vals))
end

function Base.show(io::IO, param::ParamMap)
    print(io, "ParamMap($(repr(param.name)), $(param.config), $(param.vals))")
end

spc = Drop(Star(Space()))
PString = E"\"" + p"[^\"]*" + E"\""
PBool = p"\"(true|false)\"" > (s -> s[2]=='t' ? true : false)

function brace_group(content)
    spc + E"{" + spc + content + spc + E"}"
end

function param_header(tag)
    Drop(Equal(string("<",tag,".\""))) + p"[^\"]*" + E"\">"
end

function param_config(type, Peltype)
    # Config elements.
    #
    # Each element is parsed as a pair `:key => val`, and the resulting list is
    # converted into a named tuple.
    Pstar_eltype = brace_group(Star(spc + Peltype)) |> make_vec(type)
    Ptwo_eltype = brace_group(Repeat(spc + Peltype, 2, 2)) |> make_vec(type)
    Pstar_any   = Peltype | PInt() | PString
    Pconfigelts =
        (
         ((E"<" + e"Default"     + E">" + spc) + Peltype)   |
         ((E"<" + e"Label"       + E">" + spc) + PString)   |
         ((E"<" + e"Visible"     + E">" + spc) + PString)   |
         ((E"<" + e"Unit"        + E">" + spc) + PString)   |
         ((E"<" + e"Comment"     + E">" + spc) + PString)   |
         ((E"<" + e"Tooltip"     + E">" + spc) + PString)   |
         ((E"<" + e"Precision"   + E">" + spc) + PInt())    |
         ((E"<" + e"MinSize"     + E">" + spc) + PInt())    |
         ((E"<" + e"MaxSize"     + E">" + spc) + PInt())    |
         ((E"<" + p"[^>]*"       + E">" + spc) + Pstar_any) >
         (n,v)->Symbol(n)=>v
        ) |
        (
         ((E"<" + e"Limit"       + E">" + spc) & Pstar_eltype) |
         ((E"<" + e"LimitRange"  + E">" + spc) & Ptwo_eltype)  |
         ((E"<" + p"[^>]*"       + E">" + spc) & Pstar_eltype) >
         (n,vs)->Symbol(n[1])=>vs[1]
        )

    Star(spc + Pconfigelts) |> a->(;a...)
end

make_vec(type) = vals->collect(type, vals)
make_simple_param(type) = function typed_param(name,config,vals...)
    SimpleParam(type, name, config, collect(type, vals))
end

simple_params = Any[]
for (prefix,type,Peltype) in [("ParamLong",   Int,     PInt()),
                              ("ParamDouble", Float64, PFloat64()),
                              ("ParamBool",   Bool,    PBool),
                              ("ParamString", String,  PString),
                              ("ParamChoice", String,  PString),
                             ]
    Pconfig = param_config(type, Peltype)

    # Name introducing the parameter
    Pname = param_header(prefix)

    # Parameter config and values
    Pvalues = brace_group(
        Pconfig +
        Star(spc + Peltype)
    )

    PParam = (Pname + Pvalues) > make_simple_param(type)
    push!(simple_params, PParam)
end

PParamMap = Delayed()
PParamMap.matcher = (param_header("ParamMap")                                   +
                     brace_group(param_config(Any, Alt(simple_params...))       +
                                 Star(spc + Alt(PParamMap, simple_params...)))) >
                    (name,config,vals...) -> ParamMap(name, config, vals)

# TODO:
#
# XProtocol
#   EVAStringTable
#   ProtocolComposer
#   Dependency
#
# PparamArray =

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

input = """
      <ParamString."atTXCalibDate">
      {
        "20090304" "20090304" "" "" "" "" "" ""
      }

<ParamLong."IdPart">
{
0 0 0 0 0 0 0 0
}
        <ParamDouble."ApplCommon_Table_Position">
        {
          13.000
        }

              <ParamDouble."aflAmplitude">
              {
                <Precision> 6
                0.000000 0.000000 0.000000 0.000000 0.000000
              }

                      <ParamLong."lInlineEvaMode">
        {
          <Default> 1
          <Limit> { 1 2 4 8 16 32 64 128 256 512 1024 }
        }

        <ParamBool."MagnitudeImages">
        {
          <LimitRange> { "false" "true" }
          "true"
        }

        <ParamChoice."ucIntensity">
        {
          <Label> "Intensity"
          <Tooltip> "Intensity of Image Filtering"
          <Visible> "true"
          <Default> "Medium"
          <Limit> { "Sharp" "Medium" "Smooth" }
        }

    <ParamMap."readout">
    {
      <Comment> "Blah blah"

      <ParamDouble."dSag">
      {
        <Precision> 6
      }

      <ParamDouble."dCor">
      {
        <Precision> 6
      }

      <ParamDouble."dTra">
      {
        <Precision> 6
      }
    }

"""

param_array = """
      <ParamArray."alCoilPATMode">
      {
        <MinSize> 1
        <MaxSize> 128
        <Default> <ParamLong."">
        {
          <MinSize> 1
          <MaxSize> 128
          0 0 0 0 0 0 0 0
        }
        { <MinSize> 1  <MaxSize> 128  0 0 0 0 0 0 0 -1 -1 -1  -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  -1 -1 -1 -1 -
1 -1 -1 -1 -1 -1  -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  -1 -1 -1 -1 -1 -1 -1 -1 -1
 -1  -1 -1 -1 -1  }
        { <MinSize> 1  <MaxSize> 128  -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  -1 -1
-1 -1 -1 -1 -1 -1 -1 -1  -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  -1 -1 -1 -1 -1 -1 -
1 -1 -1 -1  -1 -1 -1 -1  }

      }
"""

parse_one(input, Plus(spc + Alt(PParamMap, simple_params...)))

#parse_one(param_map, PParamMap)

parse_one("""
          <ProtocolComposer."root">
          {
            <InFile> "A"
            <Dll> "B"
          }
          """,
          param_header("ProtocolComposer") + brace_group(Star(spc + E"<InFile>" + spc + PString)) >
              (n,vals...) -> (tag="ProtocolComposer", name=n, InFile=String.(vals))
)

max_stars_repo_name: TRIImaging/MagneticResonanceSignals

max_issues_repo_name: TRIImaging/MagneticResonanceSignals

max_forks_repo_name: TRIImaging/MagneticResonanceSignals


text:
is_ch_type(::Val{:Nothing})  = true
result_type(::Val{:Nothing}) = Vector{Missing}

function read_col_data(sock::ClickHouseSock, num_rows::VarUInt, ::Val{:Nothing})
    chread(sock, Vector{UInt8}, num_rows) #Just seek, we not intresting on this values
    return Vector{Missing}(undef, UInt64(num_rows))
end

function write_col_data(sock::ClickHouseSock,
                                data::T,
                                ::Val{:Nothing}) where {T}

    chwrite(sock, zeros(UInt8, length(data)))
end


text:
function models(model, obj, x̄, ū, w, h, T)
	models_data = ModelData[]

	for i = 1:N
		m_data = model_data(model, obj, w[i], h, T)
		m_data.x̄ .= x̄[i]
		m_data.ū .= ū[i]

		push!(models_data, m_data)
	end

	return models_data
end

function objective(data::ModelsData; mode = :nominal)
	N = length(data)
	# J = []
	#
	# for i = 1:N
	# 	push!(J, objective(data[i], mode = mode))
	# end
	#
	# return maximum(J)
	J = 0.0

	for i = 1:N
		J += objective(data[i], mode = mode)
	end

	return J / N
end

function derivatives!(data::ModelsData)
	N = length(data)

	for i = 1:N
		derivatives!(data[i])
	end
end

function backward_pass!(p_data::PolicyData, models_data::ModelsData)
	N = length(models_data)
    T = models_data[1].T

    fx =  [m_data.dyn_deriv.fx for m_data in models_data]
    fu =  [m_data.dyn_deriv.fu for m_data in models_data]
	fw =  [m_data.dyn_deriv.fw for m_data in models_data]
    gx =  [m_data.obj_deriv.gx for m_data in models_data]
    gu =  [m_data.obj_deriv.gu for m_data in models_data]
    gxx = [m_data.obj_deriv.gxx for m_data in models_data]
    guu = [m_data.obj_deriv.guu for m_data in models_data]
    gux = [m_data.obj_deriv.gux for m_data in models_data]

	w = [m_data.w for m_data in models_data]

    # policy
    K = p_data.K
    k = p_data.k

    # value function approximation
    P = p_data.P
    p = p_data.p

    # state-action value function approximation
    Qx = p_data.Qx
    Qu = p_data.Qu
    Qxx = p_data.Qxx
    Quu = p_data.Quu
    Qux = p_data.Qux

    # terminal value function
    # P[T] = gxx[1][T] #sum([gxx[i][T] for i = 1:N]) ./ N
    # p[T] = gx[1][T] #sum([gx[i][T] for i = 1:N]) ./ N
	P[T] = sum([gxx[i][T] for i = 1:N]) ./ N
    p[T] = sum([gx[i][T] for i = 1:N]) ./ N

    for t = T-1:-1:1
        Qx[t] =  sum([gx[i][t] + fx[i][t]' * (p[t+1] + P[t+1] * fw[i][t] * w[i][t]) for i = 1:N]) ./ N
        Qu[t] =  sum([gu[i][t] + fu[i][t]' * (p[t+1] + P[t+1] * fw[i][t] * w[i][t]) for i = 1:N]) ./ N
        Qxx[t] = sum([gxx[i][t] + fx[i][t]' * P[t+1] * fx[i][t] for i = 1:N]) ./ N
        Quu[t] = sum([guu[i][t] + fu[i][t]' * P[t+1] * fu[i][t] for i = 1:N]) ./ N
        Qux[t] = sum([gux[i][t] + fu[i][t]' * P[t+1] * fx[i][t] for i = 1:N]) ./ N

		# Qx[t] = gx[1][t] + sum([fx[i][t]' * (p[t+1] + P[t+1] * fw[i][t] * w[i][t]) for i = 1:N]) ./ N
        # Qu[t] =  gu[1][t] + sum([fu[i][t]' * (p[t+1] + P[t+1] * fw[i][t] * w[i][t]) for i = 1:N]) ./ N
        # Qxx[t] = gxx[1][t] + sum([fx[i][t]' * P[t+1] * fx[i][t] for i = 1:N]) ./ N
        # Quu[t] = guu[1][t] + sum([fu[i][t]' * P[t+1] * fu[i][t] for i = 1:N]) ./ N
        # Qux[t] = gux[1][t] + sum([fu[i][t]' * P[t+1] * fx[i][t] for i = 1:N]) ./ N

        K[t] = -1.0 * Quu[t] \ Qux[t]
        k[t] = -1.0 * Quu[t] \ Qu[t]

        P[t] =  Qxx[t] + K[t]' * Quu[t] * K[t] + K[t]' * Qux[t] + Qux[t]' * K[t]
        p[t] =  Qx[t] + K[t]' * Quu[t] * k[t] + K[t]' * Qu[t] + Qux[t]' * k[t]
    end
end

function lagrangian_gradient!(s_data::SolverData, p_data::PolicyData, m_data::ModelsData)
	lagrangian_gradient!(s_data, p_data,
        m_data[1].model.n, m_data[1].model.m, m_data[1].T)
end

function forward_pass!(p_data::PolicyData, m_data::ModelsData, s_data::SolverData;
    max_iter = 100)

	N = length(m_data)

	# gradient of Lagrangian
	lagrangian_gradient!(s_data, p_data, m_data)

    # reset solver status
    s_data.status = false

    # line search with rollout
    α = 1.0
    iter = 1
    while true
        iter > max_iter && (@error "forward pass failure", break)

        J = Inf
		i = 1

		while i <= N
			iter > max_iter && (@error "forward pass failure", break)

	        try
	            rollout!(p_data, m_data[i], α = α)
				# @show objective(m_data[i].obj, m_data[i].x̄, m_data[i].ū)
	            # @show objective(m_data[i].obj, m_data[i].x, m_data[i].u)
	            Δz!(m_data[i])
				i += 1
	        catch
	            @warn "rollout failure (model $i)"
				fill!(m_data[i].z, 0.0)
				α *= 0.5
				iter += 1
				i = 1
	        end
		end

		J = objective(m_data, mode = :current)
		println("J_prev: $(s_data.obj)")
		println("J     : $(J)")
		println("iter: $iter")
		if J < s_data.obj #+ 0.001 * α * s_data.gradient' * (sum([m.z for m in models_data]) ./ N)
            # update nominal
			# set nominal trajectories
			# x_ref = [sum([m.x̄[t] for m in m_data]) ./ N for t = 1:T]
			# u_ref = [sum([m.ū[t] for m in m_data]) ./ N for t = 1:T-1]

			for i = 1:N
	            m_data[i].x̄ .= deepcopy(m_data[i].x)
	            m_data[i].ū .= deepcopy(m_data[i].u)
				# m_data[i].x̄ .= x_ref
	            # m_data[i].ū .= u_ref
			end
            s_data.obj = J
            s_data.status = true
            break
        else
            α *= 0.5
            iter += 1

			if iter >= max_iter
				for i = 1:N
		            m_data[i].x̄ .= deepcopy(m_data[i].x)
		            m_data[i].ū .= deepcopy(m_data[i].u)
					# m_data[i].x̄ .= x_ref
		            # m_data[i].ū .= u_ref
				end
	            s_data.obj = J
			end
        end
    end
end


text:
# Conversion/Promotion
Date(dt::TimeType) = convert(Date,dt)
DateTime(dt::TimeType) = convert(DateTime,dt)
Base.convert(::Type{DateTime},dt::Date) = DateTime(UTM(value(dt)*86400000))
Base.convert(::Type{Date},dt::DateTime) = Date(UTD(days(dt)))
Base.convert{R<:Real}(::Type{R},x::DateTime) = convert(R,value(x))
Base.convert{R<:Real}(::Type{R},x::Date)     = convert(R,value(x))

@vectorize_1arg DateTime Date
@vectorize_1arg Date DateTime

### External Conversions
const UNIXEPOCH = value(DateTime(1970)) #Rata Die milliseconds for 1970-01-01T00:00:00
function unix2datetime(x)
    rata = UNIXEPOCH + int64(1000*x)
    return DateTime(UTM(rata))
end
# Returns unix seconds since 1970-01-01T00:00:00
datetime2unix(dt::DateTime) = (value(dt) - UNIXEPOCH)/1000.0
function now()
    tm = TmStruct(time())
    return DateTime(tm.year+1900,tm.month+1,tm.mday,tm.hour,tm.min,tm.sec)
end
now(::Type{UTC}) = unix2datetime(time())
today() = Date(now())

rata2datetime(days) = DateTime(yearmonthday(days)...)
datetime2rata(dt::DateTime) = days(dt)

# Julian conversions
const JULIANEPOCH = value(DateTime(-4713,11,24,12))
function julian2datetime(f)
    rata = JULIANEPOCH + int64(86400000*f)
    return DateTime(UTM(rata))
end
# Returns # of julian days since -4713-11-24T12:00:00
datetime2julian(dt::DateTime) = (value(dt) - JULIANEPOCH)/86400000.0

@vectorize_1arg Real unix2datetime
@vectorize_1arg DateTime datetime2unix
@vectorize_1arg Real rata2datetime
@vectorize_1arg DateTime datetime2rata
@vectorize_1arg Real julian2datetime
@vectorize_1arg DateTime datetime2julian