text:
"""
    Enumerate{Unenumerated}

"Sees through" most iterators into their `parent`.

```jldoctest
julia> using LightQuery

julia> using Test: @inferred

julia> @inferred collect(Enumerate(when([4, 3, 2, 1], iseven)))
2-element Array{Tuple{Int64,Int64},1}:
 (1, 4)
 (3, 2)
```
"""
struct Enumerate{Unenumerated}
    unenumerated::Unenumerated
end

@inline function IteratorEltype(::Type{Enumerate{Unenumerated}}) where {Unenumerated}
    EltypeUnknown()
end
@inline function IteratorSize(::Type{Enumerate{Unenumerated}}) where {Unenumerated}
    IteratorSize(Unenumerated)
end
@inline function length(enumerated::Enumerate)
    length(enumerated.unenumerated)
end
@inline function size(enumerated::Enumerate)
    size(enumerated.unenumerated)
end
@inline function axes(enumerated::Enumerate)
    axes(enumerated.unenumerated)
end

@inline function iterate(enumerated::Enumerate)
    item, state = @ifsomething iterate(enumerated.unenumerated)
    (make_index(enumerated.unenumerated, state), item), state
end
@inline function iterate(enumerated::Enumerate, state)
    item, state = @ifsomething iterate(enumerated.unenumerated, state)
    (make_index(enumerated.unenumerated, state), item), state
end
export Enumerate

struct OrderView{Element, Dimensions, Unordered, IndexKeys} <: AbstractArray{Element, Dimensions}
    unordered::Unordered
    index_keys::IndexKeys
end

@inline function OrderView(unordered::Unordered, index_keys::IndexKeys) where {Unordered, IndexKeys}
    OrderView{eltype(Unordered), ndims(IndexKeys), Unordered, IndexKeys}(
        unordered, index_keys
    )
end

@inline function parent(order_view::OrderView)
    order_view.index_keys
end

@inline function axes(order_view::OrderView, dimensions...)
    axes(order_view.index_keys, dimensions...)
end
@inline function size(order_view::OrderView, dimensions...)
    size(order_view.index_keys, dimensions...)
end

@inline function getindex(order_view::OrderView, index::Int...)
    order_view.unordered[key(order_view.index_keys[index...])]
end

"""
    order(unordered, key_function; keywords...)

Generalized sort. `keywords` will be passed to `sort!`; see the documentation there for options. Use [`By`](@ref) to mark that an object has been sorted. If the results of `key_function` are type unstable, consider using `hash ∘ key_function` instead.

```jldoctest
julia> using LightQuery

julia> using Test: @inferred

julia> collect(@inferred order([-2, 1], abs))
2-element Array{Int64,1}:
  1
 -2
```
"""
@inline function order(unordered, key_function; keywords...)
    index_keys = collect(Enumerate(over(unordered, key_function)))
    sort!(index_keys, by = value; keywords...)
    OrderView(unordered, index_keys)
end
export order

"""
    Backwards(something)

Reverse sorting order.

```jldoctest
julia> using LightQuery

julia> using Test: @inferred

julia> collect(@inferred order([1, -2], Backwards))
2-element Array{Int64,1}:
  1
 -2
```
"""
struct Backwards{Increasing}
    increasing::Increasing
end

export Backwards

@inline function show(io::IO, descending::Backwards)
    print(io, "Backwards($(descending.increasing))")
end

@inline function isless(descending_1::Backwards, descending_2::Backwards)
    isless(descending_2.increasing, descending_1.increasing)
end

struct Indexed{Key, Value, Unindexed, KeyToIndex} <: AbstractDict{Key, Value}
    unindexed::Unindexed
    key_to_index::KeyToIndex
end

@inline function Indexed{Key, Value}(unindexed::Unindexed, key_to_index::KeyToIndex) where {Key, Value, Unindexed, KeyToIndex}
    Indexed{Key, Value, Unindexed, KeyToIndex}(unindexed, key_to_index)
end

@inline function getindex(indexed::Indexed, a_key)
    indexed.unindexed[indexed.key_to_index[a_key]]
end

@inline function get(indexed::Indexed, a_key, default)
    index = get(indexed.key_to_index, a_key, nothing)
    if index === nothing
        default
    else
        indexed.unindexed[index]
    end
end

@inline function haskey(indexed::Indexed, a_key)
    haskey(indexed.key_to_index, a_key)
end

@inline function iterate(indexed::Indexed, state...)
    key_index, next_state = @ifsomething iterate(indexed.key_to_index, state...)
    (key(key_index) => indexed.unindexed[value(key_index)]), next_state
end

@inline function IteratorSize(::Type{Indexed{Unindexed, KeyToIndex}}) where {Unindexed, KeyToIndex}
    IteratorSize(KeyToIndex)
end
@inline function length(indexed::Indexed)
    length(indexed.key_to_index)
end
@inline function size(indexed::Indexed)
    size(indexed.key_to_index)
end
@inline function axes(indexed::Indexed)
    axes(indexed.key_to_index)
end

@inline function IteratorEltype(::Type{Indexed{Unindexed, KeyToIndex}}) where {Unindexed, KeyToIndex}
    combine_iterator_eltype(IteratorEltype(Unindexed), IteratorEltype(KeyToIndex))
end
@inline function eltype(::Type{Indexed{Unindexed, KeyToIndex}}) where {Unindexed, KeyToIndex}
    Pair{keytype(KeyToIndex), eltype(Unindexed)}
end

@inline function key_index(key_function, (index, item))
    key_function(item) => index
end

"""
    index(unindexed, key_function)

Index `unindexed` by the results of `key_function`. Results of `key_function` must be unique.

```jldoctest
julia> using LightQuery

julia> using Test: @inferred

julia> result = @inferred index([-2, 1], abs)
LightQuery.Indexed{Int64,Int64,Array{Int64,1},Dict{Int64,Int64}} with 2 entries:
  2 => -2
  1 => 1

julia> @inferred result[2]
-2
```
"""
@inline function index(unindexed, key_function)
    key_to_index = collect_similar(
        Dict{Union{}, Union{}}(),
        Generator(let key_function = key_function
            @inline function key_index_capture(index_item)
                key_index(key_function, index_item)
            end
        end, Enumerate(unindexed))
    )
    Indexed{keytype(key_to_index), eltype(unindexed)}(unindexed, key_to_index)
end
export index

"""
    By(sorted, key_function)

Mark that `sorted` has been pre-sorted by `key_function`. Use with
[`Group`](@ref), or [`mix`](@ref).

```jldoctest
julia> using LightQuery

julia> using Test: @inferred

julia> @inferred By([1, -2], abs)
By{Array{Int64,1},typeof(abs)}([1, -2], abs)
```
"""
struct By{Iterator, Key}
    sorted::Iterator
    key_function::Key
end
export By

struct Group{Iterator, Key}
    ungrouped::Iterator
    key_function::Key
end

"""
    Group(ungrouped::By)

Group consecutive keys in `ungrouped`.

```jldoctest
julia> using LightQuery

julia> using Test: @inferred

julia> @inferred collect(Group(By([1, -1, -2, 2, 3, -3], abs)))
3-element Array{Tuple{Int64,SubArray{Int64,1,Array{Int64,1},Tuple{UnitRange{Int64}},true}},1}:
 (1, [1, -1])
 (2, [-2, 2])
 (3, [3, -3])

julia> @inferred collect(Group(By(Int[], abs)))
0-element Array{Tuple{Int64,SubArray{Int64,1,Array{Int64,1},Tuple{UnitRange{Int64}},true}},1}
```

Requires a presorted object (see [`By`](@ref)); [`order`](@ref) first if not.

```jldoctest
julia> using LightQuery

julia> using Test: @inferred

julia> first_group =
        @> [2, 1, 2, 1] |>
        order(_, identity) |>
        Group(By(_, identity)) |>
        first;

julia> key(first_group)
1

julia> collect(value(first_group))
2-element Array{Int64,1}:
 1
 1
```
"""
@inline function Group(sorted::By)
    Group(sorted.sorted, sorted.key_function)
end

@inline function IteratorSize(::Type{<: Group})
    SizeUnknown()
end
@inline function IteratorEltype(::Type{<: Group})
    EltypeUnknown()
end

@inline function get_group(group, state, old_key_result, old_left_index,
    right_index = last_index(group.ungrouped),
    new_left_index = old_left_index,
    new_key_result = old_key_result,
    is_last = true
)
    (old_key_result, (@inbounds view(
        group.ungrouped,
        old_left_index:right_index,
    ))), (state, new_left_index, new_key_result, is_last)
end

@inline function iterate(group::Group, (state, old_left_index, old_key_result, is_last))
    if is_last
        nothing
    else
        item_state = iterate(group.ungrouped, state)
        if item_state === nothing
            return get_group(group, state, old_key_result, old_left_index)
        end
        item, state = item_state
        new_key_result = group.key_function(item)
        while isequal(new_key_result, old_key_result)
            item_state = iterate(group.ungrouped, state)
            if item_state === nothing
                return get_group(group, state, old_key_result, old_left_index)
            end
            item, state = item_state
            new_key_result = group.key_function(item)
        end
        new_left_index = make_index(group.ungrouped, state)
        get_group(group, state, old_key_result, old_left_index,
            previous_index(group.ungrouped, new_left_index),
            new_left_index,
            new_key_result,
            false
        )
    end
end
@inline function iterate(group::Group)
    item, state = @ifsomething iterate(group.ungrouped)
    iterate(group, (
        state,
        make_index(group.ungrouped, state),
        group.key_function(item),
        false
    ))
end
export Group

abstract type Mix{Left <: By, Right <: By} end

@inline function combine_iterator_eltype(::HasEltype, ::HasEltype)
    HasEltype()
end
@inline function combine_iterator_eltype(x, y)
    EltypeUnknown()
end

@inline function next_history(side)
    item, state = @ifsomething iterate(side.sorted)
    (state, item, side.key_function(item))
end
@inline function next_history(side, (state, item, key_result))
    new_item, new_state = @ifsomething iterate(side.sorted, state)
    (new_state, new_item, side.key_function(new_item))
end

struct InnerMix{Left <: By, Right <: By} <: Mix{Left, Right}
    left::Left
    right::Right
end

@inline function IteratorEltype(::Type{InnerMix{By{LeftIterator, LeftKey}, By{RightIterator, RightKey}}}) where {LeftIterator, LeftKey, RightIterator, RightKey}
    combine_iterator_eltype(IteratorEltype(LeftIterator), IteratorEltype(RightIterator))
end
@inline function eltype(::Type{InnerMix{By{LeftIterator, LeftKey}, By{RightIterator, RightKey}}}) where {LeftIterator, LeftKey, RightIterator, RightKey}
    Tuple{eltype(LeftIterator), eltype(RightIterator)}
end

@inline function compare(mixed::InnerMix, ::Nothing, ::Nothing)
    nothing
end

struct LeftMix{Left <: By, Right <: By} <: Mix{Left, Right}
    left::Left
    right::Right
end

@inline function IteratorEltype(::Type{LeftMix{By{LeftIterator, LeftKey}, By{RightIterator, RightKey}}}) where {LeftIterator, LeftKey, RightIterator, RightKey}
    combine_iterator_eltype(IteratorEltype(LeftIterator), IteratorEltype(RightIterator))
end
@inline function eltype(::Type{LeftMix{By{LeftIterator, LeftKey}, By{RightIterator, RightKey}}}) where {LeftIterator, LeftKey, RightIterator, RightKey}
    Tuple{eltype(LeftIterator), Union{Missing, eltype(RightIterator)}}
end

@inline function IteratorSize(::Type{LeftMix{By{LeftIterator, LeftKey}, By{RightIterator, RightKey}}}) where {LeftIterator, LeftKey, RightIterator, RightKey}
    IteratorSize(LeftIterator)
end
@inline function size(mixed::LeftMix)
    size(mixed.left.sorted)
end
@inline function length(mixed::LeftMix)
    length(mixed.left.sorted)
end
@inline function axes(mixed::LeftMix)
    axes(mixed.left.sorted)
end

@inline function compare(mixed::LeftMix, ::Nothing, ::Nothing)
    nothing
end

struct RightMix{Left <: By, Right <: By} <: Mix{Left, Right}
    left::Left
    right::Right
end

@inline function IteratorEltype(::Type{RightMix{By{LeftIterator, LeftKey}, By{RightIterator, RightKey}}}) where {LeftIterator, LeftKey, RightIterator, RightKey}
    combine_iterator_eltype(IteratorEltype(LeftIterator), IteratorEltype(RightIterator))
end
@inline function eltype(::Type{RightMix{By{LeftIterator, LeftKey}, By{RightIterator, RightKey}}}) where {LeftIterator, LeftKey, RightIterator, RightKey}
    Tuple{Union{Missing, eltype(LeftIterator)}, eltype(RightIterator)}
end

@inline function IteratorSize(::Type{RightMix{By{LeftIterator, LeftKey}, By{RightIterator, RightKey}}}) where {LeftIterator, LeftKey, RightIterator, RightKey}
    IteratorSize(RightIterator)
end
@inline function size(mixed::RightMix)
    size(mixed.right.sorted)
end
@inline function length(mixed::RightMix)
    length(mixed.right.sorted)
end
@inline function axes(mixed::RightMix)
    axes(mixed.right.sorted)
end

@inline function compare(mixed::RightMix, ::Nothing, ::Nothing)
    nothing
end

struct OuterMix{Left <: By, Right <: By} <: Mix{Left, Right}
    left::Left
    right::Right
end

@inline function IteratorEltype(::Type{OuterMix{By{LeftIterator, LeftKey}, By{RightIterator, RightKey}}}) where {LeftIterator, LeftKey, RightIterator, RightKey}
    combine_iterator_eltype(IteratorEltype(LeftIterator), IteratorEltype(RightIterator))
end
@inline function eltype(::Type{OuterMix{By{LeftIterator, LeftKey}, By{RightIterator, RightKey}}}) where {LeftIterator, LeftKey, RightIterator, RightKey}
    Tuple{Union{Missing, eltype(LeftIterator)}, Union{Missing, eltype(RightIterator)}}
end

@inline function compare(mixed::OuterMix, ::Nothing, ::Nothing)
    nothing
end

function IteratorSize(::Type{AType}) where {AType <: Union{InnerMix, OuterMix}}
    SizeUnknown()
end

@inline function next_left(mixed::Union{InnerMix, RightMix}, left_history, right_history)
    iterate(mixed, (left_history, right_history, true, false))
end
@inline function next_left(mixed::Union{LeftMix, OuterMix}, left_history, right_history)
    left_state, left_item, left_key_result = left_history
    (left_item, missing), (left_history, right_history, true, false)
end

@inline function next_right(mixed::Union{InnerMix, LeftMix}, left_history, right_history)
    iterate(mixed, (left_history, right_history, false, true))
end
@inline function next_right(mixed::Union{RightMix, OuterMix}, left_history, right_history)
    right_state, right_item, right_key_result = right_history
    (missing, right_item), (left_history, right_history, false, true)
end

@inline function compare(mixed::Union{InnerMix, LeftMix}, ::Nothing, right_history)
    nothing
end
@inline function compare(mixed::Union{LeftMix, OuterMix}, left_history, ::Nothing)
    left_state, left_item, left_key_result = left_history
    (left_item, missing), (left_history, nothing, true, false)
end

@inline function compare(mixed::Union{InnerMix, RightMix}, left_history, ::Nothing)
    nothing
end
@inline function compare(mixed::Union{RightMix, OuterMix}, ::Nothing, right_history)
    right_state, right_item, right_key_result = right_history
    (missing, right_item), (nothing, right_history, false, true)
end

@inline function compare(mixed, left_history, right_history)
    left_state, left_item, left_key_result = left_history
    right_state, right_item, right_key_result = right_history
    if isless(left_key_result, right_key_result)
        next_left(mixed, left_history, right_history)
    elseif isless(right_key_result, left_key_result)
        next_right(mixed, left_history, right_history)
    else
        (left_item, right_item), (left_history, right_history, true, true)
    end
end

@inline function iterate(::Mix, ::Nothing)
    nothing
end
@inline function iterate(mixed::Mix)
    compare(mixed,
        next_history(mixed.left),
        next_history(mixed.right)
    )
end
@inline function iterate(mixed::Mix, (left_history, right_history, next_left, next_right))
    if next_left
        if next_right
            compare(mixed,
                next_history(mixed.left, left_history),
                next_history(mixed.right, right_history)
            )
        else
            compare(mixed,
                next_history(mixed.left, left_history),
                right_history
            )
        end
    else
        if next_right
            compare(mixed,
                left_history,
                next_history(mixed.right, right_history)
            )
        else
            compare(mixed, left_history, right_history)
        end
    end
end

"""
    mix(::Name{:inner},  left::By, right::By)

Find all pairs where `isequal(left.key_function(left.sorted), right.key_function(right.sorted))`.
Assumes `left` and `right` are both strictly sorted (no repeats). If there are
repeats, [`Group`](@ref) first. See [`By`](@ref).

```jldoctest
julia> using LightQuery

julia> using Test: @inferred

julia> @name @inferred collect(mix(:inner, By([1, -2, 5, -6], abs), By([-1, 3, -4, 6], abs)))
2-element Array{Tuple{Int64,Int64},1}:
 (1, -1)
 (-6, 6)

julia> @name @inferred collect(mix(:inner, By(Int[], abs), By(Int[], abs)))
0-element Array{Tuple{Int64,Int64},1}

julia> @name @inferred collect(mix(:inner, By([1], abs), By(Int[], abs)))
0-element Array{Tuple{Int64,Int64},1}

julia> @name @inferred collect(mix(:inner, By(Int[], abs), By([1], abs)))
0-element Array{Tuple{Int64,Int64},1}
```
"""
@inline function mix(::Name{:inner}, left, right)
    InnerMix(left, right)
end

"""
    mix(::Name{:left}, left::By, right::By)

Find all pairs where `isequal(left.key_function(left.sorted), right.key_function(right.sorted))`,
using `missing` when there is no right match. Assumes `left` and `right` are
both strictly sorted (no repeats). If there are repeats, [`Group`](@ref) first.
See [`By`](@ref).

```jldoctest
julia> using LightQuery

julia> @name collect(mix(:left, By([1, -2, 5, -6], abs), By([-1, 3, -4, 6], abs)))
4-element Array{Tuple{Int64,Union{Missing, Int64}},1}:
 (1, -1)
 (-2, missing)
 (5, missing)
 (-6, 6)

julia> @name collect(mix(:left, By(Int[], abs), By(Int[], abs)))
0-element Array{Tuple{Int64,Union{Missing, Int64}},1}

julia> @name collect(mix(:left, By([1], abs), By(Int[], abs)))
1-element Array{Tuple{Int64,Union{Missing, Int64}},1}:
 (1, missing)

julia> @name collect(mix(:left, By(Int[], abs), By([1], abs)))
0-element Array{Tuple{Int64,Union{Missing, Int64}},1}
```
"""
@inline function mix(::Name{:left}, left, right)
    LeftMix(left, right)
end

"""
    mix(::Name{:right}, left::By, right::By)

Find all pairs where `isequal(left.key_function(left.sorted), right.key_function(right.sorted))`,
using `missing` when there is no left match. Assumes `left` and `right` are both
strictly sorted (no repeats). If there are repeats, [`Group`](@ref) first. See
[`By`](@ref).

```jldoctest
julia> using LightQuery

julia> @name collect(mix(:right, By([1, -2, 5, -6], abs), By([-1, 3, -4, 6], abs)))
4-element Array{Tuple{Union{Missing, Int64},Int64},1}:
 (1, -1)
 (missing, 3)
 (missing, -4)
 (-6, 6)

julia> @name collect(mix(:right, By(Int[], abs), By(Int[], abs)))
0-element Array{Tuple{Union{Missing, Int64},Int64},1}

julia> @name collect(mix(:right, By([1], abs), By(Int[], abs)))
0-element Array{Tuple{Union{Missing, Int64},Int64},1}

julia> @name collect(mix(:right, By(Int[], abs), By([1], abs)))
1-element Array{Tuple{Union{Missing, Int64},Int64},1}:
 (missing, 1)
```
"""
@inline function mix(::Name{:right}, left, right)
    RightMix(left, right)
end

"""
    mix(::Name{:outer}, left::By, right::By)

Find all pairs where `isequal(left.key_function(left.sorted), right.key_function(right.sorted))`,
using `missing` when there is no left or right match. Assumes `left` and `right`
are both strictly sorted (no repeats). If there are repeats, [`Group`](@ref)
first. See [`By`](@ref).

```jldoctest
julia> using LightQuery

julia> @name collect(mix(:outer, By([1, -2, 5, -6], abs), By([-1, 3, -4, 6], abs)))
6-element Array{Tuple{Union{Missing, Int64},Union{Missing, Int64}},1}:
 (1, -1)
 (-2, missing)
 (missing, 3)
 (missing, -4)
 (5, missing)
 (-6, 6)

julia> @name collect(mix(:outer, By(Int[], abs), By(Int[], abs)))
0-element Array{Tuple{Union{Missing, Int64},Union{Missing, Int64}},1}

julia> @name collect(mix(:outer, By([1], abs), By(Int[], abs)))
1-element Array{Tuple{Union{Missing, Int64},Union{Missing, Int64}},1}:
 (1, missing)

julia> @name collect(mix(:outer, By(Int[], abs), By([1], abs)))
1-element Array{Tuple{Union{Missing, Int64},Union{Missing, Int64}},1}:
 (missing, 1)
```
"""
@inline function mix(::Name{:outer}, left, right)
    OuterMix(left, right)
end

export mix

@inline function setindex_pair!(dictionary, (a_key, a_value))
    dictionary[a_key] = a_value
end

# piracy
@inline function copyto!(dictionary::Dict{Key, Value}, pairs::AbstractVector{Tuple{Key, Value}}) where {Key, Value}
    foreach(let dictionary = dictionary
        function setindex_pair!(pair)
            setindex_pair!(dictionary, pair)
        end
    end, dictionary)
    nothing
end
@inline function similar(old::Dict, ::Type{Tuple{Key, Value}}) where {Key, Value}
    Dict{Key, Value}(old)
end

"""
    Length(iterator, new_length)

Allow optimizations based on length.

```jldoctest
julia> using LightQuery

julia> collect(Length(when(1:4, iseven), 2))
2-element Array{Int64,1}:
 2
 4
```
"""
struct Length{Iterator}
    iterator::Iterator
    new_length::Int
end
@inline IteratorEltype(::Type{Length{Iterator}}) where {Iterator} =
    IteratorEltype(Iterator)
@inline eltype(::Type{Length{Iterator}}) where {Iterator} = eltype(Iterator)
@inline IteratorLength(::Type{T}) where {T <: Length} = HasLength()
@inline length(fixed::Length) = fixed.new_length
@inline iterate(fixed::Length) = iterate(fixed.iterator)
@inline iterate(fixed::Length, state) = iterate(fixed.iterator, state)
export Length


text:
function conference()
  """
      var conference = function(config) {
        var self = {
            userToken: uniqueToken()
        };
        var channels = '--', isbroadcaster;
        var isGetNewRoom = true;
        var sockets = [];
        var defaultSocket = { };

        function openDefaultSocket() {
            defaultSocket = config.openSocket({
                onmessage: onDefaultSocketResponse,
                callback: function(socket) {
                    defaultSocket = socket;
                }
            });
        }

        function onDefaultSocketResponse(response) {
            if (response.userToken == self.userToken) return;

            if (isGetNewRoom && response.roomToken && response.broadcaster) config.onRoomFound(response);

            if (response.newParticipant && self.joinedARoom && self.broadcasterid == response.userToken) onNewParticipant(response.newParticipant);

            if (response.userToken && response.joinUser == self.userToken && response.participant && channels.indexOf(response.userToken) == -1) {
                channels += response.userToken + '--';
                openSubSocket({
                    isofferer: true,
                    channel: response.channel || response.userToken
                });
            }

            // to make sure room is unlisted if owner leaves
            if (response.left && config.onRoomClosed) {
                config.onRoomClosed(response);
            }
        }

        function openSubSocket(_config) {
            if (!_config.channel) return;
            var socketConfig = {
                channel: _config.channel,
                onmessage: socketResponse,
                onopen: function() {
                    if (isofferer && !peer) initPeer();
                    sockets[sockets.length] = socket;
                }
            };

            socketConfig.callback = function(_socket) {
                socket = _socket;
                this.onopen();
            };

            var socket = config.openSocket(socketConfig),
                isofferer = _config.isofferer,
                gotstream,
                video = document.createElement('video'),
                inner = { },
                peer;

            var peerConfig = {
                attachStream: config.attachStream,
                onICE: function(candidate) {
                    socket.send({
                        userToken: self.userToken,
                        candidate: {
                            sdpMLineIndex: candidate.sdpMLineIndex,
                            candidate: JSON.stringify(candidate.candidate)
                        }
                    });
                },
                onRemoteStream: function(stream) {
                    if (!stream) return;

                    video[moz ? 'mozSrcObject' : 'src'] = moz ? stream : webkitURL.createObjectURL(stream);
                    video.play();

                    _config.stream = stream;
                    onRemoteStreamStartsFlowing();
                },
                onRemoteStreamEnded: function(stream) {
                    if (config.onRemoteStreamEnded)
                        config.onRemoteStreamEnded(stream, video);
                }
            };

            function initPeer(offerSDP) {
                if (!offerSDP) {
                    peerConfig.onOfferSDP = sendsdp;
                } else {
                    peerConfig.offerSDP = offerSDP;
                    peerConfig.onAnswerSDP = sendsdp;
                }

                peer = RTCPeerConnection(peerConfig);
            }

            function afterRemoteStreamStartedFlowing() {
                gotstream = true;

                if (config.onRemoteStream)
                    config.onRemoteStream({
                        video: video,
                        stream: _config.stream
                    });

                if (isbroadcaster && channels.split('--').length > 3) {
                    /* broadcasting newly connected participant for video-conferencing! */
                    defaultSocket.send({
                        newParticipant: socket.channel,
                        userToken: self.userToken
                    });
                }
            }

            function onRemoteStreamStartsFlowing() {
                if(navigator.userAgent.match(/Android|iPhone|iPad|iPod|BlackBerry|IEMobile/i)) {
                    // if mobile device
                    return afterRemoteStreamStartedFlowing();
                }

                if (!(video.readyState <= HTMLMediaElement.HAVE_CURRENT_DATA || video.paused || video.currentTime <= 0)) {
                    afterRemoteStreamStartedFlowing();
                } else setTimeout(onRemoteStreamStartsFlowing, 50);
            }

            function sendsdp(sdp) {
                socket.send({
                    userToken: self.userToken,
                    sdp: JSON.stringify(sdp)
                });
            }

            function socketResponse(response) {
                if (response.userToken == self.userToken) return;
                if (response.sdp) {
                    inner.sdp = JSON.parse(response.sdp);
                    selfInvoker();
                }

                if (response.candidate && !gotstream) {
                    if (!peer) console.error('missed an ice', response.candidate);
                    else
                        peer.addICE({
                            sdpMLineIndex: response.candidate.sdpMLineIndex,
                            candidate: JSON.parse(response.candidate.candidate)
                        });
                }

                if (response.left) {
                    if (peer && peer.peer) {
                        peer.peer.close();
                        peer.peer = null;
                    }
                }
            }

            var invokedOnce = false;

            function selfInvoker() {
                if (invokedOnce) return;

                invokedOnce = true;

                if (isofferer) peer.addAnswerSDP(inner.sdp);
                else initPeer(inner.sdp);
            }
        }

        function leave() {
            var length = sockets.length;
            for (var i = 0; i < length; i++) {
                var socket = sockets[i];
                if (socket) {
                    socket.send({
                        left: true,
                        userToken: self.userToken
                    });
                    delete sockets[i];
                }
            }

            // if owner leaves; try to remove his room from all other users side
            if (isbroadcaster) {
                defaultSocket.send({
                    left: true,
                    userToken: self.userToken,
                    roomToken: self.roomToken
                });
            }

            if (config.attachStream) config.attachStream.stop();
        }

        window.addEventListener('beforeunload', function () {
            leave();
        }, false);

        window.addEventListener('keyup', function (e) {
            if (e.keyCode == 116)
                leave();
        }, false);

        function startBroadcasting() {
            defaultSocket && defaultSocket.send({
                roomToken: self.roomToken,
                roomName: self.roomName,
                broadcaster: self.userToken
            });
            setTimeout(startBroadcasting, 3000);
        }

        function onNewParticipant(channel) {
            if (!channel || channels.indexOf(channel) != -1 || channel == self.userToken) return;
            channels += channel + '--';

            var new_channel = uniqueToken();
            openSubSocket({
                channel: new_channel
            });

            defaultSocket.send({
                participant: true,
                userToken: self.userToken,
                joinUser: channel,
                channel: new_channel
            });
        }

        function uniqueToken() {
            var s4 = function() {
                return Math.floor(Math.random() * 0x10000).toString(16);
            };
            return s4() + s4() + "-" + s4() + "-" + s4() + "-" + s4() + "-" + s4() + s4() + s4();
        }

        openDefaultSocket();
        return {
            createRoom: function(_config) {
                self.roomName = _config.roomName || 'Anonymous';
                self.roomToken = uniqueToken();

                isbroadcaster = true;
                isGetNewRoom = false;
                startBroadcasting();
            },
            joinRoom: function(_config) {
                self.roomToken = _config.roomToken;
                isGetNewRoom = false;

                self.joinedARoom = true;
                self.broadcasterid = _config.joinUser;

                openSubSocket({
                    channel: self.userToken
                });

                defaultSocket.send({
                    participant: true,
                    userToken: self.userToken,
                    joinUser: _config.joinUser
                });
            },
            leaveRoom: leave
        };
    };
  """
end

ext: jl


text:
module SemanticSimilarity

using ..CrypticCrosswords: normalize

using WordNet
using ProgressMeter: @showprogress
using Statistics: mean

export similarity, WuPalmer, SimilarityDepth

include("cache.jl")

const CACHE = Cache()

include("metrics.jl")

end # module


text:
function real_main()
    n = length(ARGS) > 0 ? ARGS[1] : ""
    str = "Hello world $(n)!"
    println(str)
end

if abspath(PROGRAM_FILE) == @__FILE__
    real_main()
end


text:
# Autogenerated wrapper script for Libksba_jll for armv7l-linux-musleabihf
export libksba

using Libgpg_error_jll
JLLWrappers.@generate_wrapper_header("Libksba")
JLLWrappers.@declare_library_product(libksba, "libksba.so.8")
function __init__()
    JLLWrappers.@generate_init_header(Libgpg_error_jll)
    JLLWrappers.@init_library_product(
        libksba,
        "lib/libksba.so",
        RTLD_LAZY | RTLD_DEEPBIND,
    )

    JLLWrappers.@generate_init_footer()
end  # __init__()


text:
# Used by Interpolations.jl

"""
Given a type `T`, an integer `n` and `m` tuples of the form (i, j, v), build
sparse matrices `rows`, `vals`, `cols` such that the product
`out = rows * vals * cols` is equivalent to:

```julia
out = zeros(T, n, n)

for (i, j, v) in args
    out[i, j] = v
end
```

The first two components (`i` and `j`) of each tuple should be integers
whereas the third component should be of type `T`

Example:

```
julia> r, v, c = WoodburyMatrices.sparse_factors(Float64, 3,
                                                 (1, 1, 2.0),
                                                 (2, 2, 3.0),
                                                 (3, 3, 4.0));

julia> r*c*v - Diagonal([2.0, 3.0, 4.0])
3x3 sparse matrix with 0 Float64 entries:
```

"""
function sparse_factors(::Type{T}, n::Int, args::Tuple{Int, Int, Any}...) where {T}
    m = length(args)
    rows = spzeros(T, n, m)
    cols = spzeros(T, m, n)
    vals = zeros(T, m, m)

    ix = 1
    for (i, (row, col, val)) in enumerate(args)
        rows[row, ix] = 1
        cols[ix, col] = 1
        vals[ix, ix] = val
        ix += 1
    end

    rows, vals, cols
end


text:
function delete_genes(experiment_id::String)

end

function delete_proteins(experiment_id::String)

end

function delete_drugs(experiment_id::String)

end

function delete_cell_lines(experiment_id::String)

end

function delete_pathways(experiment_id::String)

end

function delete_outcomes(experiment_id::String)

end

function delete_gene(experiment_id::String, id::Union{String, Int64})

end


text:
using RiskyCommunity
using Test

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


text:
using Test, YaoBlocks, YaoArrayRegister, LuxurySparse, BitBasis
using YaoBlocks.ConstGate

U = mat(X)
⊗ = kron

@testset "construct" begin
    @test_throws DimensionMismatch control(3, 2, 1 => swap(2, 1, 2))
    @test_throws MethodError control(3, 1, 2:3 => rand(4, 4))
    @test_throws LocationConflictError control(3, 2, (1, 2) => swap(2, 1, 2))

    @test cnot(4, (1, 2), 3) == control(4, (1, 2), 3 => X)
    @test cnot((1, 2), 3)(4) == cnot(4, (1, 2), 3) # curried version

    @test cz(4, (1, 2), 3) == control(4, (1, 2), 3 => Z)
    @test cz((1, 2), 3)(4) == cz(4, (1, 2), 3)

    @test control((1, 2), 3 => X)(4) == control(4, (1, 2), 3 => X)
end

@testset "single control" begin
    g = ControlBlock(2, (1,), X, (2,))
    @test nqubits(g) == 2
    m = IMatrix(U) ⊗ mat(P0) + U ⊗ mat(P1)
    @test mat(g) == m
end

@testset "single control with inferred size" begin
    g = ControlBlock(3, (2,), X, (3,))
    @test nqubits(g) == 3
    m = (IMatrix(U) ⊗ mat(P0) + U ⊗ mat(P1)) ⊗ mat(I2)
    @test mat(g) == m
end

@testset "control with fixed size" begin
    g = ControlBlock(4, (2,), X, (3,))
    @test nqubits(g) == 4
    m = mat(I2) ⊗ (IMatrix(U) ⊗ mat(P0) + U ⊗ mat(P1)) ⊗ mat(I2)
    @test mat(g) == m
end

@testset "control with blank" begin
    g = ControlBlock(4, (3,), X, (2,))
    @test nqubits(g) == 4

    m = mat(I2) ⊗ (mat(P0) ⊗ IMatrix(U) + mat(P1) ⊗ U) ⊗ mat(I2)
    @test mat(g) == m
end

@testset "multi control" begin
    g = ControlBlock(4, (2, 3), X, (4,))
    @test nqubits(g) == 4

    op = IMatrix(U) ⊗ mat(P0) + U ⊗ mat(P1)
    op = IMatrix(op) ⊗ mat(P0) + op ⊗ mat(P1)
    op = op ⊗ mat(I2)
    @test mat(g) == op
end

@testset "multi control with blank" begin
    g = ControlBlock(7, (6, 4, 2), X, (3,)) # -> [2, 4, 6]
    @test nqubits(g) == 7
    @test occupied_locs(g) == (6, 4, 2, 3)

    op = IMatrix(U) ⊗ mat(P0) + U ⊗ mat(P1) # 2, 3
    op = mat(P0) ⊗ IMatrix(op) + mat(P1) ⊗ op # 2, 3, 4
    op = mat(P0) ⊗ mat(I2) ⊗ IMatrix(op) + mat(P1) ⊗ mat(I2) ⊗ op # 2, 3, 4, blank, 6
    op = op ⊗ mat(I2) # blank, 2, 3, blank, 4, 6
    op = mat(I2) ⊗ op # blnak, 2, 3, blank, 4, 6, blank

    @test mat(g) == op
end

@testset "inverse control" begin
    g = ControlBlock(2, (1,), (0,), X, (2,))
    op = U ⊗ mat(P0) + IMatrix(U) ⊗ mat(P1)
    @test mat(g) ≈ op
end

@testset "control two-bit gate" begin
    @test_throws DimensionMismatch ControlBlock(3, (1,), CNOT, (2,))
    g = ControlBlock(3, (1,), CNOT, (2, 3))
    @test applymatrix(g) ≈ mat(Toffoli)
    @test occupied_locs(g) == (1, 2, 3)
    g = ControlBlock(3, (3,), CNOT, (2, 1))
    @test applymatrix(g) ≈ mat(Toffoli) |> invorder
    @test occupied_locs(g) == (3, 2, 1)
    g = ControlBlock(3, (2,), CNOT, (3, 1))
    g2 = PutBlock(3, Toffoli, (2, 3, 1))
    g3 = ControlBlock(3, (3, 2), X, (1,))
    @test applymatrix(g) == applymatrix(g2) == applymatrix(g3)
    @test mat(g) == mat(g2)
    @test mat(g) == mat(g3)
end

@testset "push tests" begin
    @test !iscommute(control(5, 1, 2=>X), control(5, 1, 2=>Y))
    @test iscommute(control(5, 1, 2=>X), control(5, 1, 3=>Y))
    @test !iscommute(control(5, 1, 2=>X), control(5, 2, 3=>Y))

    c = control((2,3), 1=>X)(5)
    @test c == control(5, (2,3), 1=>X)
    @test copy(c) == c
end


text:
################################################################################
# Upwind advection
#
# Original code from Christopher Blanton (cjb47@psu.edu)
# Modified by Alex Pletzer (alexander@gokliya.net)

using LinearAlgebra

include("saveVTK.jl")

mutable struct Upwind

    # Number of space dimensions
    ndims::Int

    # Constant advection velocity
    velocity::Array

    # Domain length
    lengths::Array

    # Number of cells along each direction
    numCells::Array

    #
    # Internal variables (derived from the above)
    #

    # Grid size along each direction
    deltas::Array
    # Direction of upwind
    upDirection::Array
    # Total number of cells
    ntot::Int
    # Product of the dimensions, used to go from flat index to index set
    dimProd::Array
    # Field
    f::Array

    function Upwind(ndims::Int, velocity::Array, lengths::Array, numCells::Array)
        """
        Internal constructor
        @param ndims number of space dimensions
        @param velocity velocity array of size ndims
        @param lengths domain lengths array of size ndims
        @param numCells number of cells, array of size ndims
        """
        this = new(ndims, velocity, lengths, numCells)

        this.deltas = zeros(Float64, ndims::Integer)

        this.upDirection = zeros(Integer, ndims::Integer)
        this.ntot = 1
        for i in 1:ndims
            this.upDirection[i] = -1
            if this.velocity[i] < 0.0
                this.upDirection[i] = +1
            end
            this.deltas[i] = lengths[i]/numCells[i]
            this.ntot *= numCells[i]
        end
        this.dimProd = ones(Integer, ndims::Integer)
        for i = 2:ndims
            this.dimProd[i] = this.dimProd[i-1] * this.numCells[i-1]
        end

        #
        # Set the initial field
        #
        this.f = zeros(this.ntot)
        this.f[1] = 1.0

        return this
    end
end

function advect!(this::Upwind, deltaTime::Float64)
    """
    Advance the solution by one time step
    @param this instance
    @param deltaTime time increment
    """
    oldF = deepcopy(this.f)
    for j = 1:this.ndims
        c = deltaTime * this.velocity[j] * this.upDirection[j] / this.deltas[j]
        for i = 1:this.ntot
            inds = getIndexSet(up, i)
            oldIndex = inds[j]
            #periodic BCs
            inds[j] += this.upDirection[j]
            inds[j] = mod1(inds[j], this.numCells[j])
            upI = getFlatIndex(up, inds)
            this.f[i] -= c * (oldF[upI] - oldF[i])
            inds[j] = oldIndex
        end
    end
end

function getFlatIndex(this::Upwind, inds::Array)
    """
    Get the flat index from an index set
    @param this instance
    @param inds index set, eg [i, j, k]
    @return integer index of field array
    """
    return dot(this.dimProd, inds .- 1) + 1
end

function getIndexSet(this::Upwind, flatIndex::Integer)
    """
    Get the index set of a falt index
    @param this instance
    @param flatIndex flat index
    @return index set, eg [i, j, k]
    """
    res = zeros(Integer, this.ndims)
    for i = 1:this.ndims
        res[i] = mod(div((flatIndex - 1), this.dimProd[i]), this.numCells[i]) + 1
    end
    return res
end

function save2VTK(this::Upwind, fname::AbstractString)
    """
    Save data in VTK file
    @param this instance
    @param fname file name
    """
    xAxis = linspace(0.0, this.lengths[1], this.numCells[1] + 1)
    yAxis = linspace(0.0, this.lengths[2], this.numCells[2] + 1)
    zAxis = linspace(0.0, this.lengths[3], this.numCells[3] + 1)
    saveVTK.rectilinear(fname, xAxis, yAxis, zAxis, this.f)

end

# Beginning of main program

ndims = 3

# Parse command line arguments
if length(ARGS) < 1
    println("Must specify number of cells in each direction.")
    println("Usage: ", basename(Base.source_path()), " numCells [numTimeSteps]")
    exit(1)
end
ncells = parse(Int, ARGS[1])

numTimeSteps = 100
if length(ARGS) > 1
    numTimeSteps = parse(Int, ARGS[2])
end

# Same resolution in each direction.
numCells = [ncells,ncells,ncells]
println("number of cells: ", numCells)
println("number of time steps: ", numTimeSteps)

# Initalizing vector velocity and lengths
velocity = ones(Float64, ndims)
lengths   = ones(Float64, ndims)

# Compute time step
courant = 0.1
dt = Inf
for i = 1:ndims
    dx = lengths[i]/float(numCells[i])
    global dt = min((courant*dx)/velocity[i], dt)
end

# Create Upwind instance
up = Upwind(ndims,velocity,lengths,numCells)

# Advect
for i = 1:numTimeSteps
   advect!(up, dt)
end

# Do the checksum
println("check sum: ", sum(up.f))

if length(ARGS) > 2 && ARGS[3] == "vtk"
   save2VTK(up, "upwind.vtk")
end

max_stars_repo_name: pletzer/fidibench

max_issues_repo_name: pletzer/fidibench

max_forks_repo_name: pletzer/fidibench


text:
using DataFrames
using CSV
using Plots
#%%
file = open("./lezione6/random.dat")
df=CSV.read(file, header=false, delim=" ")

scatter(df[1],df[2])

max_stars_repo_name: aurelio-amerio/corso-cpp


text:
using ArrayViews, Test, LinearAlgebra

#### diagview
println("    -- testing diagview")

a = rand(5, 6)
@test diagview(a) == diag(a)
a = rand(6, 6)
@test diagview(a) == diag(a)
a = rand(6, 5)
@test diagview(a) == diag(a)

#### flatten_view
println("    -- testing flatten_view")

a = rand(5, 6)
@test flatten_view(a) == vec(a)

#### rowvec_view
println("    -- testing rowvec_view")

a = rand(4, 5)
for i = 1:size(a,1)
    @test rowvec_view(a, i) == vec(a[i,:])
end

a = rand(6, 8)
b = aview(a, 2:6, 2:7)
for i = 1:size(b,1)
    @test rowvec_view(b,i) == vec(a[1+i, 2:7])
end

#### reshape_view
println("    -- testing reshape_view")

a = rand(3, 6)
v1 = reshape_view(a, (2, 9))
@test size(v1) == (2, 9)
@test v1 == reshape(a, (2, 9))
v2 = reshape_view(a, (6, 3))
@test size(v2) == (6, 3)
@test v2 == reshape(a, (6, 3))

#### ellipview
println("    -- testing ellipview_view")

a = rand(10)
@test isequal(aview(a, 5), ellipview(a, 5))
@test isequal(aview(a, 2:3), ellipview(a, 2:3))
a = rand(10,20)
@test isequal(aview(a, :, 5), ellipview(a, 5))
@test isequal(aview(a, :, 2:3), ellipview(a, 2:3))
a = rand(10,20,30)
@test isequal(aview(a, :, :, 5), ellipview(a, 5))
@test isequal(aview(a, :, :, 2:3), ellipview(a, 2:3))
a = rand(10,20,30,40)
@test isequal(aview(a, :, :, :, 5), ellipview(a, 5))
@test isequal(aview(a, :, :, :, 2:3), ellipview(a,2:3))


text:
module Test17

import Automa
import Automa.RegExp: @re_str
using Test

@testset "Test17" begin
    re1 = re"[a\-c]"
    re1.actions[:enter] = [:enter]
    re1.actions[:exit] = [:exit]
    machine1 = Automa.compile(re1)
    @test occursin(r"^Automa.Machine\(<.*>\)$", repr(machine1))

    for generator in (:table, :inline, :goto), checkbounds in (true, false), clean in (true, false)
        ctx = Automa.CodeGenContext(generator=generator, checkbounds=checkbounds, clean=clean)
        init_code = Automa.generate_init_code(ctx, machine1)
        exec_code = Automa.generate_exec_code(ctx, machine1, :debug)
        validate = @eval function (data)
            logger = Symbol[]
            $(init_code)
            p_end = p_eof = lastindex(data)
            $(exec_code)
            return cs == 0, logger
        end

        @test validate(b"-") == (true, [:enter, :exit])
        @test validate(b"b") == (false, Symbol[])
    end

    re2 = re"[a-c]"
    re2.actions[:enter] = [:enter]
    re2.actions[:exit] = [:exit]
    machine2 = Automa.compile(re2)
    @test occursin(r"^Automa.Machine\(<.*>\)$", repr(machine2))

    for generator in (:table, :inline, :goto), checkbounds in (true, false), clean in (true, false)
        ctx = Automa.CodeGenContext(generator=generator, checkbounds=checkbounds, clean=clean)
        init_code = Automa.generate_init_code(ctx, machine2)
        exec_code = Automa.generate_exec_code(ctx, machine2, :debug)
        validate = @eval function (data)
            logger = Symbol[]
            $(init_code)
            p_end = p_eof = lastindex(data)
            $(exec_code)
            return cs == 0, logger
        end

        @test validate(b"-") == (false, [])
        @test validate(b"b") == (true, Symbol[:enter, :exit])
    end
end

end


text:
export reflect_data
export julia_binfile, julia_sysimage

"""
    unsafe_peek(a::Array, T::Type, n::Integer)

Return a Vector{T} of n memory locations starting at the address of `a`.
"""
function unsafe_peek(obj::Any, T::Type, n::Integer)
    isimmutable(obj) && throw(ArgumentError("obj is not mutable"))
    unsafe_wrap(Vector{T}, reinterpret(Ptr{T}, pointer_from_objref(obj)), n)
end

"""
    reflect_data(::Array{<:Any,N}) where N

Return a named tuple detailing the internal representation of a standard array.
The fields vary depending on `N`.
"""
function reflect_data(obj::Array)
    p = unsafe_peek(obj, Int, 5)
    data = UInt(p[1])
    length = Int(p[2])
    flags = reinterpret(UInt16, p[3:3])[1]
    elsize = Int32(reinterpret(UInt16, p[3:3])[2])
    offset = reinterpret(UInt32, p[3:3])[2]
    how = UInt8(flags & 0x0003)
    ndims = UInt16((flags>>2) & 0x01ff)
    pooled = Bool((flags>>11) & 0x0001)
    ptrarray = Bool((flags>>12) & 0x0001)
    hasptr = Bool((flags>>13) & 0x0001)
    isshared = Bool((flags>>14) & 0x0001)
    isaligned = Bool((flags>>15) & 0x0001)
    nrows = Int(p[4])
    maxsize = Int(p[5])
    @assert ndims == 1 && obj isa(Vector) || !(obj isa Vector)
    if obj isa Vector
        (data=data, length=length, how=how, ndims=ndims,
        pooled=pooled, ptrarray=ptrarray, hasptr=hasptr, isshared=isshared,
        isaligned=isaligned,
        elsize=elsize, offset=offset, nrows=nrows, maxsize=maxsize)
    elseif ndims == 2
        (data=data, length=length, how=how, ndims=ndims,
        pooled=pooled, ptrarray=ptrarray, hasptr=hasptr, isshared=isshared,
        isaligned=isaligned,
        elsize=elsize, offset=offset, nrows=nrows, ncols=maxsize)
    elseif ndims == 0
        (data=data, length=length, how=how, ndims=ndims,
        pooled=pooled, ptrarray=ptrarray, hasptr=hasptr, isshared=isshared,
        isaligned=isaligned,
        elsize=elsize, offset=offset, nrows=1, ncols=1)
    else
        dims = unsafe_peek(obj, Int, ndims + 3)[4:end]
        (data=data, length=length, how=how, ndims=ndims,
        pooled=pooled, ptrarray=ptrarray, hasptr=hasptr, isshared=isshared,
        isaligned=isaligned,
        elsize=elsize, offset=offset, nrows=dims[1], ncols=dims[2], dims=dims)
    end
end

# string
function reflect_data(s::String)
    sl = Int(unsafe_wrap(Vector{Int}, reinterpret(Ptr{Int}, pointer_from_objref(s)), 1)[1])
    pdata = reinterpret(Ptr{UInt8}, pointer_from_objref(s))
    (data=pdata, length=sl, content=unsafe_wrap(Vector{UInt8}, pdata + sizeof(Int), sl))
end

# convert Symbol to String
function sstring(a::Symbol)
   pname = Base.unsafe_convert(Ptr{UInt8}, a)
   slen = Int(ccall(:strlen, Csize_t, (Cstring,), pname))
   v = unsafe_wrap(Vector{UInt8}, pname, slen)
   String(v)
end

# Convert Symbol to String (further optimized)
function ssstring(a::Symbol)
   pname = Base.unsafe_convert(Ptr{UInt8}, a)
   unsafe_string(pname)
end

"""
    julia_binfile(), julia_sysimage()

Return the name of the julia executable and system image file (shared library).
"""
function julia_binfile()
    unsafe_string(Base.JLOptions().julia_bin)
end
function julia_sysimage()
    unsafe_string(Base.JLOptions().image_file)
end

function tweak_commandline()
    o = Base.JLOptions()
    o′ = Base.JLOptions((x === :depwarn ? Int8(1) :
    getfield(o, x) for x in fieldnames(Base.JLOptions))...)
    unsafe_store!(cglobal(:jl_options, Base.JLOptions), o′)
end


text:
# PooledString is an internal-only type for efficiently tracking string data + length
# all strings indexed from a column/row will always be a full String
# specifically, it allows avoiding materializing full Strings for pooled string columns while parsing
# and allows a fastpath for materializing a full String when no escaping is needed
export PooledString
struct PooledString <: AbstractString end

struct PointerString <: AbstractString
    ptr::Ptr{UInt8}
    len::Int
end

function Base.hash(s::PointerString, h::UInt)
    h += Base.memhash_seed
    ccall(Base.memhash, UInt, (Ptr{UInt8}, Csize_t, UInt32), s.ptr, s.len, h % UInt32) + h
end

import Base: ==
function ==(x::String, y::PointerString)
    sizeof(x) == y.len && ccall(:memcmp, Cint, (Ptr{UInt8}, Ptr{UInt8}, Csize_t), pointer(x), y.ptr, y.len) == 0
end
==(y::PointerString, x::String) = x == y

Base.ncodeunits(s::PointerString) = s.len
@inline function Base.codeunit(s::PointerString, i::Integer)
    @boundscheck checkbounds(s, i)
    GC.@preserve s unsafe_load(s.ptr + i - 1)
end
Base.String(x::PointerString) = unsafe_string(x.ptr, x.len)

# TypeCode is a compact type encoding of types CSV.jl supports parsing from files
# it allows avoiding the dynamic nature of full Julia `Type` in hot parsing loops
# and is generally efficient for the limited # of type operations required
const TypeCode = Int8

# default value to signal that parsing should try to detect a type
const EMPTY       = 0b00000000 % TypeCode

# MISSING is a mask that can be combined w/ any other TypeCode for Union{T, Missing}
const MISSING     = 0b10000000 % TypeCode
missingtype(x::TypeCode) = (x & MISSING) == MISSING
usermissing(x::TypeCode) = x == (MISSING | USER)

# MISSINGTYPE is for a column like `Vector{Missing}`
# if we're trying to detect a column type and the 1st value of a column is `missing`
# we basically want to still treat it like EMPTY and try parsing other types on each row
const MISSINGTYPE = 0b00000001 % TypeCode

# enum-like type codes for basic supported types
const INT         = 0b00000010 % TypeCode
const FLOAT       = 0b00000011 % TypeCode
const DATE        = 0b00000100 % TypeCode
const DATETIME    = 0b00000101 % TypeCode
const TIME        = 0b00000110 % TypeCode
const BOOL        = 0b00000111 % TypeCode
const STRING      = 0b00001000 % TypeCode
stringtype(x::TypeCode) = (x & STRING) == STRING
const POOL        = 0b00010000 % TypeCode
pooled(x::TypeCode) = (x & POOL) == POOL

# a user-provided type; a mask that can be combined w/ basic types
const USER     = 0b00100000 % TypeCode
user(x::TypeCode) = (x & USER) == USER

const TYPEBITS = 0b00011111 % TypeCode
typebits(x::TypeCode) = x & TYPEBITS

typecode(::Type{Missing}) = MISSING
typecode(::Type{<:Integer}) = INT
typecode(::Type{<:AbstractFloat}) = FLOAT
typecode(::Type{Date}) = DATE
typecode(::Type{DateTime}) = DATETIME
typecode(::Type{Time}) = TIME
typecode(::Type{Bool}) = BOOL
typecode(::Type{<:AbstractString}) = STRING
typecode(::Type{PooledString}) = POOL
typecode(::Type{CategoricalValue{String, UInt32}}) = POOL
typecode(::Type{Union{}}) = EMPTY
typecode(::Type{Union{T, Missing}}) where {T} = typecode(T) | MISSING
typecode(::Type{T}) where {T} = EMPTY
typecode(x::T) where {T} = typecode(T)

const TYPECODES = Dict(
    EMPTY => Missing,
    MISSINGTYPE => Missing,
    MISSING => Missing,
    INT => Int64,
    FLOAT => Float64,
    DATE => Date,
    DATETIME => DateTime,
    TIME => Time,
    BOOL => Bool,
    POOL => PooledString,
    STRING => String,
    INT | MISSING => Union{Int64, Missing},
    FLOAT | MISSING => Union{Float64, Missing},
    DATE | MISSING => Union{Date, Missing},
    DATETIME | MISSING => Union{DateTime, Missing},
    TIME | MISSING => Union{Time, Missing},
    BOOL | MISSING => Union{Bool, Missing},
    POOL | MISSING => Union{PooledString, Missing},
    STRING | MISSING => Union{String, Missing}
)

gettype(x::TypeCode) = TYPECODES[x & ~USER]

@inline function promote_typecode(T, S)
    if T == EMPTY || T == S || user(T) || (T & ~MISSING) == (S & ~MISSING)
        return T | S
    elseif T == MISSINGTYPE
        return S | MISSING
    elseif S == MISSINGTYPE
        return T | MISSING
    elseif T == INT
        return S == FLOAT ? S : S == (FLOAT | MISSING) ? S : missingtype(S) ? (STRING | MISSING) : STRING
    elseif T == (INT | MISSING)
        return S == FLOAT || S == (FLOAT | MISSING) ? (FLOAT | MISSING) : (STRING | MISSING)
    elseif T == FLOAT
        return S == INT ? FLOAT : S == (INT | MISSING) ? T | MISSING : missingtype(S) ? (STRING | MISSING) : STRING
    elseif T == (FLOAT | MISSING)
        return S == INT || S == (INT | MISSING) ? (FLOAT | MISSING) : (STRING | MISSING)
    elseif missingtype(T) || missingtype(S)
        return STRING | MISSING
    else
        return STRING
    end
end

gettypecodes(x::Dict) = Dict(typecode(k)=>typecode(v) for (k, v) in x)
gettypecodes(x::Dict{TypeCode, TypeCode}) = x

# bit patterns for missing value, int value, escaped string, position and len in tape parsing
const MISSING_BIT = 0x8000000000000000
missingvalue(x::UInt64) = (x & MISSING_BIT) == MISSING_BIT
sentinelvalue(::Type{Float64}) = Core.bitcast(UInt64, NaN) | MISSING_BIT
sentinelvalue(::Type{T}) where {T} = MISSING_BIT
const INT_SENTINEL = -8899831978349840752
sentinelvalue(::Type{Int64}) = rand(typemin(Int64):div(typemin(Int64), 1000)) * ifelse(rand(Bool), 1, -1)

const ESCAPE_BIT = 0x4000000000000000
escapedvalue(x::UInt64) = (x & ESCAPE_BIT) == ESCAPE_BIT

getpos(x::UInt64) = (x & 0x3ffffffffff00000) >> 20
getlen(x::UInt64) = x & 0x00000000000fffff

# utilities to convert values to raw UInt64 and back for tape writing
int64(x::UInt64) = Core.bitcast(Int64, x)
float64(x::UInt64) = Core.bitcast(Float64, x)
bool(x::UInt64) = x == 0x0000000000000001
date(x::UInt64) = Date(Dates.UTD(int64(x)))
datetime(x::UInt64) = DateTime(Dates.UTM(int64(x)))
time(x::UInt64) = Time(Nanosecond(int64(x)))
ref(x::UInt64) = unsafe_trunc(UInt32, x)

uint64(x::Int64) = Core.bitcast(UInt64, x)
uint64(x::Float64) = Core.bitcast(UInt64, x)
uint64(x::Bool) = UInt64(x)
uint64(x::Union{Date, DateTime, Time}) = uint64(Dates.value(x))
uint64(x::UInt32) = UInt64(x)

reinterp_func(::Type{Int64}) = int64
reinterp_func(::Type{Float64}) = float64
reinterp_func(::Type{Date}) = date
reinterp_func(::Type{DateTime}) = datetime
reinterp_func(::Type{Time}) = time
reinterp_func(::Type{Bool}) = bool

# one-liner suggested from ScottPJones
consumeBOM(buf) = (length(buf) >= 3 && buf[1] == 0xef && buf[2] == 0xbb && buf[3] == 0xbf) ? 4 : 1

function slurp(source)
    N = 2^22 # 4 mb increments
    ms = Tuple{Vector{UInt8}, Int}[]
    tot = 0
    while true
        m = Mmap.mmap(Vector{UInt8}, N)
        n = readbytes!(source, m, N)
        tot += n
        push!(ms, (m, n))
        n < N && break
    end
    final = Mmap.mmap(Vector{UInt8}, tot)
    pos = 1
    for (m, n) in ms
        copyto!(final, pos, m, 1, n)
        pos += n
    end
    return final
end

getsource(source::Vector{UInt8}, ::Any) = source
getsource(source::Cmd, ::Any) = Base.read(source)
getsource(source::AbstractPath, ::Any) = Base.read(open(source))
getsource(source::IO, ::Any) = slurp(source)
getsource(source::SystemPath, use_mmap) = getsource(string(source), use_mmap)
function getsource(source, use_mmap)
    m = Mmap.mmap(source)
    if use_mmap
        return m
    end
    m2 = Mmap.mmap(Vector{UInt8}, length(m))
    copyto!(m2, 1, m, 1, length(m))
    finalize(m)
    return m2
end

getname(buf::Vector{UInt8}) = "<raw buffer>"
getname(cmd::Cmd) = string(cmd)
getname(str) = string(str)
getname(io::I) where {I <: IO} = string("<", I, ">")

# normalizing column name utilities
const RESERVED = Set(["local", "global", "export", "let",
    "for", "struct", "while", "const", "continue", "import",
    "function", "if", "else", "try", "begin", "break", "catch",
    "return", "using", "baremodule", "macro", "finally",
    "module", "elseif", "end", "quote", "do"])

normalizename(name::Symbol) = name
function normalizename(name::String)::Symbol
    uname = strip(Unicode.normalize(name))
    id = Base.isidentifier(uname) ? uname : map(c->Base.is_id_char(c) ? c : '_', uname)
    cleansed = string((isempty(id) || !Base.is_id_start_char(id[1]) || id in RESERVED) ? "_" : "", id)
    return Symbol(replace(cleansed, r"(_)\1+"=>"_"))
end

function makeunique(names)
    set = Set(names)
    length(set) == length(names) && return Symbol[Symbol(x) for x in names]
    nms = Symbol[]
    for nm in names
        if nm in nms
            k = 1
            newnm = Symbol("$(nm)_$k")
            while newnm in set || newnm in nms
                k += 1
                newnm = Symbol("$(nm)_$k")
            end
            nm = newnm
        end
        push!(nms, nm)
    end
    return nms
end

initialtypes(T, x::AbstractDict{String}, names) = TypeCode[haskey(x, string(nm)) ? typecode(x[string(nm)]) | USER : T for nm in names]
initialtypes(T, x::AbstractDict{Symbol}, names) = TypeCode[haskey(x, nm) ? typecode(x[nm]) | USER : T for nm in names]
initialtypes(T, x::AbstractDict{Int}, names)    = TypeCode[haskey(x, i) ? typecode(x[i]) | USER : T for i = 1:length(names)]

# given a DateFormat, is it meant for parsing Date, DateTime, or Time?
function timetype(df::Dates.DateFormat)
    date = false
    time = false
    for token in df.tokens
        T = typeof(token)
        if T in (Dates.DatePart{'H'}, Dates.DatePart{'I'}, Dates.DatePart{'M'}, Dates.DatePart{'S'}, Dates.DatePart{'s'})
            time = true
        elseif T in (Dates.DatePart{'y'}, Dates.DatePart{'Y'}, Dates.DatePart{'m'}, Dates.DatePart{'d'}, Dates.DatePart{'u'}, Dates.DatePart{'U'})
            date = true
        end
    end
    return ifelse(date & time, DateTime, ifelse(time, Time, Date))
end

# if a cell value of a csv file has escape characters, we need to unescape it
function unescape(s, e)
    n = ncodeunits(s)
    buf = Base.StringVector(n)
    len = 1
    i = 1
    @inbounds begin
        while i <= n
            b = codeunit(s, i)
            if b == e
                i += 1
                b = codeunit(s, i)
            end
            @inbounds buf[len] = b
            len += 1
            i += 1
        end
    end
    resize!(buf, len - 1)
    return String(buf)
end

"""
    CSV.detect(str::String)

Use the same logic used by `CSV.File` to detect column types, to parse a value from a plain string.
This can be useful in conjunction with the `CSV.Rows` type, which returns each cell of a file as a String.
The order of types attempted is: `Int64`, `Float64`, `Date`, `DateTime`, `Bool`, and if all fail, the input String is returned.
No errors are thrown.
For advanced usage, you can pass your own `Parsers.Options` type as a keyword argument `option=ops` for sentinel value detection.
"""
function detect end

detect(str::String; options=Parsers.OPTIONS) = something(detect(codeunits(str), 1, sizeof(str), options), str)

function detect(buf, pos, len, options)
    int, code, vpos, vlen, tlen = Parsers.xparse(Int64, buf, pos, len, options)
    if Parsers.sentinel(code) && code > 0
        return missing
    end
    if Parsers.ok(code) && vpos + vlen - 1 == len
        return int
    end
    float, code, vpos, vlen, tlen = Parsers.xparse(Float64, buf, pos, len, options)
    if Parsers.ok(code) && vpos + vlen - 1 == len
        return float
    end
    if options.dateformat === nothing
        try
            date, code, vpos, vlen, tlen = Parsers.xparse(Date, buf, pos, len, options)
            if Parsers.ok(code) && vpos + vlen - 1 == len
                return date
            end
        catch e
        end
        try
            datetime, code, vpos, vlen, tlen = Parsers.xparse(DateTime, buf, pos, len, options)
            if Parsers.ok(code) && vpos + vlen - 1 == len
                return datetime
            end
        catch e
        end
    else
        try
            # use user-provided dateformat
            DT = timetype(options.dateformat)
            dt, code, vpos, vlen, tlen = Parsers.xparse(DT, buf, pos, len, options)
            if Parsers.ok(code) && vpos + vlen - 1 == len
                return dt
            end
        catch e
        end
    end
    bool, code, vpos, vlen, tlen = Parsers.xparse(Bool, buf, pos, len, options)
    if Parsers.ok(code) && vpos + vlen - 1 == len
        return bool
    end
    return nothing
end

struct ReversedBuf <: AbstractVector{UInt8}
    buf::Vector{UInt8}
end

Base.size(a::ReversedBuf) = size(a.buf)
Base.IndexStyle(::Type{ReversedBuf}) = Base.IndexLinear()
Base.getindex(a::ReversedBuf, i::Int) = a.buf[end + 1 - i]

function unset!(A::Vector, i::Int, row, x)
    finalize(A[i])
    ccall(:jl_arrayunset, Cvoid, (Array, Csize_t), A, i - 1)
    # println("deleting col = $i on thread = $(Threads.threadid()), row = $row, id = $x")
    return
end

memcpy!(d, doff, s, soff, n) = ccall(:memcpy, Cvoid, (Ptr{UInt8}, Ptr{UInt8}, Int), d + doff - 1, s + soff - 1, n)


text:
using MinFEM

function parabolic(;T::Float64, tsteps::Int, theta=1.0)
  mesh = unit_square(100)

  boundary = union(mesh.Boundaries[1001].Nodes,
                   mesh.Boundaries[1002].Nodes,
                   mesh.Boundaries[1003].Nodes,
                   mesh.Boundaries[1004].Nodes)

  L = asmLaplacian(mesh)
  M = asmMassMatrix(mesh)

  # time increment assuming that t0=0
  dt = (T-0)/tsteps

  source(x) = 1.0
  f = evaluateMeshFunction(mesh, source)

  initial_condition(x) = 0.0
  u = evaluateMeshFunction(mesh, initial_condition)

  for i=1:tsteps

    # in first timestep additional output of u0
    if i==1
      vtkfile = open_vtk_file(mesh, "parabolic_"*lpad(string(0), 3, '0')*".vtu")
      write_point_data(vtkfile, u, "u")
      save_vtk_file(vtkfile)
    end

    # we have to solve the following equation depending on theta
    # with the prescribed Dirichlet conditions
    # M*(u_new - u)/dt + L(theta*u_new + (1.0-theta)*u) = M*f
    pde = PDESystem(A=(M + theta*dt*L), b=(M - (1.0-theta)*dt*L)*u + dt*M*f, bc=zeros(mesh.nnodes), DI=boundary)
    solve(pde)

    u = copy(pde.state)

    vtkfile = open_vtk_file(mesh, "parabolic_"*lpad(string(i), 3, '0')*".vtu")
    write_point_data(vtkfile, u, "u")
    save_vtk_file(vtkfile)
  end

end
parabolic(T=0.001, tsteps=10, theta=1.0)


text:
# unused file

struct CrystalsPhantomCrystal{T}
    data::Set{T}
    rm::Set{T}
    add::Set{T}
end
function Base.show(io::IO, cr::CrystalsPhantomCrystal{T}) where T
    s::Set{T} = union(setdiff(cr.data, cr.rm), cr.add)
    print(io, "(crystals.phantomcrystal "*join([aetherlang_repr(x) for x in s], ' ')*")")
end

max_stars_repo_name: Aetherlang/aetherlang

max_issues_repo_name: gojakuch/aetherlang

max_forks_repo_name: gojakuch/aetherlang


text:
local_sense_states(n) = RecordArrays.fill(true, n; align = 64)

struct CentralizedBarrier <: SyncBarriers.CentralizedBarrier
    n::Int
    count::Threads.Atomic{Int}
    _count_pads::NTuple{ATOMICS_NPADS,Threads.Atomic{Int}}
    sense::Threads.Atomic{Bool}
    _sense_pads::NTuple{ATOMICS_NPADS,Threads.Atomic{Bool}}
    local_sense::typeof(local_sense_states(1))
    waiters::Matrix{OneWayCondition}
end

function CentralizedBarrier(n::Integer)
    count, _count_pads = cache_aligned_atomic(0)
    sense, _sense_pads = cache_aligned_atomic(true)
    return CentralizedBarrier(
        n,
        count,
        _count_pads,
        sense,
        _sense_pads,
        local_sense_states(n),
        [OneWayCondition() for _ in 1:n, _ in 1:2],
    )
end

@inline waiters_for(barrier::CentralizedBarrier, sense::Bool) =
    @view barrier.waiters[:, Int(sense) + 1]

@inline function waiter_for(handle::BarrierHandle{CentralizedBarrier})
    barrier = handle.barrier
    s = barrier.local_sense[handle.i]
    return barrier.waiters[handle.i, Int(s) + 1]
end

function SyncBarriers.arrive!(handle::BarrierHandle{CentralizedBarrier})
    barrier = handle.barrier
    s = !barrier.local_sense[handle.i]
    barrier.local_sense[handle.i] = s
    if Threads.atomic_add!(barrier.count, 1) == barrier.n - 1
        barrier.count[] = 0
        barrier.sense[] = s
        for (j, waiter) in pairs(waiters_for(barrier, s))
            if j != handle.i
                notify(waiter)
            end
        end
        return true
    else
        return false
    end
end

function SyncBarriers.depart!(
    handle::BarrierHandle{CentralizedBarrier},
    spin::Union{Integer,Nothing} = nothing,
)
    barrier = handle.barrier
    s = barrier.local_sense[handle.i]
    waiter = waiter_for(handle)
    sense = barrier.sense
    waitif(() -> sense[] != s, waiter, spin)
    return
end


text:
#
# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher
# Licensed under the MIT license. See LICENSE file in the project root for details.
#

t_start = 0.0
t_stop = 8.0

pathToFMU = joinpath(dirname(@__FILE__), "..", "model", ENV["EXPORTINGTOOL"], "SpringFrictionPendulum1D.fmu")

myFMU = fmiLoad(pathToFMU)

comp = fmiInstantiate!(myFMU; loggingOn=false)
@test comp != 0

# choose FMU or FMUComponent
fmuStruct = nothing
envFMUSTRUCT = ENV["FMUSTRUCT"]
if envFMUSTRUCT == "FMU"
    fmuStruct = myFMU
elseif envFMUSTRUCT == "FMUCOMPONENT"
    fmuStruct = comp
end
@assert fmuStruct != nothing "Unknwon fmuStruct, environment variable `FMUSTRUCT` = `$envFMUSTRUCT`"

solution = fmiSimulateME(fmuStruct, t_start, t_stop)
@test length(solution.u) > 0
@test length(solution.t) > 0

@test solution.t[1] == t_start
@test solution.t[end] == t_stop

# reference values from Simulation in Dymola2020x (Dassl)
@test solution.u[1] == [0.5, 0.0]
@test sum(abs.(solution.u[end] - [1.06736, -1.03552e-10])) < 0.01

fmiUnload(myFMU)


text:
# Model
include_model("quadruped")
model_ft = free_time_model(model)

# Horizon
T = 26

# Time step
tf = 1.0
h = tf / (T - 1)

# Visualize
# - Pkg.add any external deps from visualize.jl
include(joinpath(pwd(), "models/visualize.jl"))
vis = Visualizer()
render(vis)

# Configurations
θ = pi / 3.25
q1 = initial_configuration(model_ft,  θ)
qM = copy(q1)
qM[2] += 2.5
qM[3] += pi
qM[4] += pi
qM[5] += pi
qM[6] += pi
qM[7] += pi
qM[8] += pi
qM[9] += pi
qM[10] += pi
qM[11] += pi
qT = copy(q1)
qT[1] -= model_ft.l_torso
qT[3] += 2.0 * pi
qT[4] += 2.0 * pi
qT[5] += 2.0 * pi
qT[6] += 2.0 * pi
qT[7] += 2.0 * pi
qT[8] += 2.0 * pi
qT[9] += 2.0 * pi
qT[10] += 2.0 * pi
qT[11] += 2.0 * pi

visualize!(vis, model_ft, [q1])
visualize!(vis, model_ft, [qM])
visualize!(vis, model_ft, [qT])

q_ref = [linear_interpolation(q1, qM, 14)[1:end-1]...,
    linear_interpolation(qM, qT, 13)...]

visualize!(vis, model_ft, q_ref)

# Bounds

# control
# u = (τ1..4, λ1..2, β1..4, ψ1..2, η1...4, s1)
# ul <= u <= uu
_uu = Inf * ones(model_ft.m)
_uu[model_ft.idx_u] .= Inf
_uu[end] = 2.0 * h

_ul = zeros(model_ft.m)
_ul[model_ft.idx_u] .= -Inf
_ul[end] = 0.5 * h
ul, uu = control_bounds(model_ft, T, _ul, _uu)

xl, xu = state_bounds(model_ft, T,
    x1 = [q1; q1],
    xT = [Inf * ones(model.nq); qT])

# Objective
include_objective(["velocity", "nonlinear_stage"])

x0 = configuration_to_state(q_ref)

# penalty on slack variable
obj_penalty = PenaltyObjective(1.0e5, model_ft.m - 1)

# quadratic tracking objective
# Σ (x - xref)' Q (x - x_ref) + (u - u_ref)' R (u - u_ref)
obj_control = quadratic_time_tracking_objective(
    [zeros(model_ft.n, model_ft.n) for t = 1:T],
    [Diagonal([0.1 * ones(model_ft.nu)..., zeros(model_ft.m - model_ft.nu)...]) for t = 1:T-1],
    [zeros(model_ft.n) for t = 1:T],
    [zeros(model_ft.m) for t = 1:T],
    1.0)

# quadratic velocity penalty
# Σ v' Q v
obj_velocity = velocity_objective(
    [Diagonal(10.0 * ones(model_ft.nq)) for t = 1:T-1],
    model_ft.nq,
    h = h,
    idx_angle = collect([3, 4, 5, 6, 7, 8, 9, 10, 11]))

# torso height
q2_idx = (12:22)
t_h = kinematics_1(model_ft, qM, body = :torso, mode = :com)[2]
l_stage_torso_h(x, u, t) = 1000.0 * (kinematics_1(model_ft, view(x, q2_idx), body = :torso, mode = :com)[2] - t_h)^2.0
l_terminal_torso_h(x) = 0.0 * (kinematics_1(model_ft, view(x, q2_idx), body = :torso, mode = :com)[2] - t_h)^2.0
obj_torso_h = nonlinear_stage_objective(l_stage_torso_h, l_terminal_torso_h)
#
# # torso lateral
# l_stage_torso_lat(x, u, t) = (1.0 * (kinematics_1(model_ft, view(x, q2_idx), body = :torso, mode = :com)[1] - kinematics_1(model_ft, view(x0[t], q2_idx), body = :torso, mode = :com)[1])^2.0)
# l_terminal_torso_lat(x) = (0.0 * (kinematics_1(model_ft, view(x, q2_idx), body = :torso, mode = :com)[1] - kinematics_1(model_ft, view(x0[T], q2_idx), body = :torso, mode = :com)[1])^2.0)
# obj_torso_lat = nonlinear_stage_objective(l_stage_torso_lat, l_terminal_torso_lat)
#
# foot 1 height
l_stage_fh1(x, u, t) = 1000.0 * (kinematics_2(model_ft, view(x, q2_idx), body = :calf_1, mode = :ee)[2] - 0.5)^2.0
l_terminal_fh1(x) = 0.0 * (kinematics_2(model_ft, view(x, q2_idx), body = :calf_1, mode = :ee)[2])^2.0
obj_fh1 = nonlinear_stage_objective(l_stage_fh1, l_terminal_fh1)

# foot 2 height
l_stage_fh2(x, u, t) = 1000.0 * (kinematics_2(model_ft, view(x, q2_idx), body = :calf_2, mode = :ee)[2] - 0.5)^2.0
l_terminal_fh2(x) = 0.0 * (kinematics_2(model_ft, view(x, q2_idx), body = :calf_2, mode = :ee)[2])^2.0
obj_fh2 = nonlinear_stage_objective(l_stage_fh2, l_terminal_fh2)

# foot 3 height
l_stage_fh3(x, u, t) = 100.0 * (kinematics_3(model_ft, view(x, q2_idx), body = :calf_3, mode = :ee)[2] - 0.5)^2.0
l_terminal_fh3(x) = 0.0 * (kinematics_3(model_ft, view(x, q2_idx), body = :calf_3, mode = :ee)[2])^2.0
obj_fh3 = nonlinear_stage_objective(l_stage_fh3, l_terminal_fh3)

# foot 4 height
l_stage_fh4(x, u, t) = 100.0 * (kinematics_3(model_ft, view(x, q2_idx), body = :calf_4, mode = :ee)[2] - 0.5)^2.0
l_terminal_fh4(x) = 0.0 * (kinematics_3(model_ft, view(x, q2_idx), body = :calf_4, mode = :ee)[2])^2.0
obj_fh4 = nonlinear_stage_objective(l_stage_fh4, l_terminal_fh4)

obj = MultiObjective([obj_penalty,
                      obj_control,
                      obj_velocity,
                      obj_torso_h,
                      # obj_torso_lat,
                      obj_fh1,
                      obj_fh2,
                      obj_fh3,
                      obj_fh4])

# Constraints
include_constraints(["contact", "free_time"])
con_contact = contact_constraints(model_ft, T)
con_free_time = free_time_constraints(T)
con = multiple_constraints([con_contact, con_free_time])

# Problem
prob = trajectory_optimization_problem(model_ft,
               obj,
               T,
               # h = h,
               xl = xl,
               xu = xu,
               ul = ul,
               uu = uu,
               con = con)

# trajectory initialization
u0 = [[1.0e-3 * rand(model_ft.m - 1); h] for t = 1:T-1] # random controls

# Pack trajectories into vector
z0 = pack(x0, u0, prob)
z0 .+= 1.0e-3 * randn(prob.num_var)

# Solve
include_snopt()

@time z̄ , info = solve(prob, copy(z0),
    nlp = :SNOPT7,
    tol = 1.0e-3, c_tol = 1.0e-3,
    time_limit = 60 * 3, mapl = 5)

# @time z̄ , info = solve(prob, copy(z̄ .+ 1.0e-3 * rand(prob.num_var)),
#     nlp = :SNOPT7,
#     tol = 1.0e-3, c_tol = 1.0e-3,
#     time_limit = 60 * 30, mapl = 5)

check_slack(z̄, prob)
x̄, ū = unpack(z̄, prob)
tf, t, h̄ = get_time(ū)

@save joinpath(pwd(), "examples/trajectories/quadruped_backflip.jld2") x̄ ū h̄

# Visualize
visualize!(vis, model_ft, state_to_configuration(x̄), Δt = h̄[1])

visualize!(vis, model_ft,
	[[state_to_configuration(x̄)[1] for i = 1:10]..., state_to_configuration(x̄)..., [state_to_configuration(x̄)[end] for i = 1:10]...],
	Δt = ū[1][end])
open(vis)
using Plots
plot(t[1:end-1], hcat(ū...)[model_ft.idx_u, :]', linetype = :steppost,
	width = 2.0, label = "", xlabel= "time (s)", ylabel = "control")


text:
#
# Public API
#

Client(host::String, port::Int) = Client(URI("mongodb://$host:$port"))
Client(uri::String) = Client(URI(uri))
Client() = Client("localhost", 27017)

"""
    set_appname!(client::Client, appname::String)

Sets the application name for this client.

This string, along with other internal driver details,
is sent to the server as part of the initial connection handshake.

# C API

* [`mongoc_client_set_appname`](http://mongoc.org/libmongoc/current/mongoc_client_set_appname.html).
"""
function set_appname!(client::Client, appname::String)
    ok = mongoc_client_set_appname(client.handle, appname)
    if !ok
        error("Couldn't set appname=$appname for client $client.")
    end
    nothing
end

"""
    command_simple(database::Database, command::Union{String, BSON}) :: BSON

Executes a `command` given by a JSON string or a BSON instance.

It returns the first document from the result cursor.

# Example

```julia
julia> client = Mongoc.Client() # connects to localhost at port 27017
Client(URI("mongodb://localhost:27017"))

julia> bson_result = Mongoc.command_simple(client[\"admin\"], "{ \"ping\" : 1 }")
BSON("{ "ok" : 1.0 }")
```

# C API

* [`mongoc_database_command_simple`](http://mongoc.org/libmongoc/current/mongoc_database_command_simple.html)

"""
function command_simple(database::Database, command::BSON) :: BSON
    reply = BSON()
    err = BSONError()
    ok = mongoc_database_command_simple(database.handle, command.handle, C_NULL, reply.handle, err)
    if !ok
        error("$err.")
    end
    return reply
end

function command_simple(collection::Collection, command::BSON) :: BSON
    reply = BSON()
    err = BSONError()
    ok = mongoc_collection_command_simple(collection.handle, command.handle, C_NULL, reply.handle, err)
    if !ok
        error("$err.")
    end
    return reply
end

function ping(client::Client) :: BSON
    return command_simple(client["admin"], BSON("""{ "ping" : 1 }"""))
end

"Queries the version for the MongoDB server instance."
function get_server_mongodb_version(client::Client) :: VersionNumber
    bson_server_status = command_simple(client["admin"], BSON("""{ "serverStatus" : 1 }"""))
    return VersionNumber(bson_server_status["version"])
end

function find_databases(client::Client; options::Union{Nothing, BSON}=nothing) :: Cursor
    options_handle = options == nothing ? C_NULL : options.handle
    cursor_handle = mongoc_client_find_databases_with_opts(client.handle, options_handle)
    if cursor_handle == C_NULL
        error("Couldn't execute query.")
    end
    return Cursor(client, cursor_handle)
end

function get_database_names(client::Client; options::Union{Nothing, BSON}=nothing) :: Vector{String}
    result = Vector{String}()
    for bson_database in find_databases(client, options=options)
        push!(result, bson_database["name"])
    end
    return result
end

function has_database(client::Client, database_name::String; options::Union{Nothing, BSON}=nothing) :: Bool
    for bson_database in find_databases(client, options=options)
        if bson_database["name"] == database_name
            return true
        end
    end
    return false
end

"""
    add_user(database::Database, username::String, password::String, roles::Union{Nothing, BSON}, custom_data::Union{Nothing, BSON}=nothing)

This function shall create a new user with access to database.

Warning: Do not call this function without TLS.
"""
function add_user(database::Database, username::String, password::String, roles::Union{Nothing, BSON}, custom_data::Union{Nothing, BSON}=nothing)
    err = BSONError()
    roles_handle = roles == nothing ? C_NULL : roles.handle
    custom_data_handle = custom_data == nothing ? C_NULL : custom_data.handle
    ok = mongoc_database_add_user(database.handle, username, password, roles_handle, custom_data_handle, err)
    if !ok
        error("$err")
    end
    nothing
end

"""
    remove_user(database::Database, username::String)

Removes a user from database.
"""
function remove_user(database::Database, username::String)
    err = BSONError()
    ok = mongoc_database_remove_user(database.handle, username, err)
    if !ok
        error("$err")
    end
    nothing
end

"""
    has_user(database::Database, user_name::String) :: Bool

Checks if `database` has a user named `user_name`.
"""
function has_user(database::Database, user_name::String) :: Bool
    cmd_result = command_simple(database, BSON("""{ "usersInfo": "$user_name" }"""))
    return !isempty(cmd_result["users"])
end

function find_collections(database::Database; options::Union{Nothing, BSON}=nothing) :: Cursor
    options_handle = options == nothing ? C_NULL : options.handle
    cursor_handle = mongoc_database_find_collections_with_opts(database.handle, options_handle)
    if cursor_handle == C_NULL
        error("Couldn't execute query.")
    end
    return Cursor(database, cursor_handle)
end

function get_collection_names(database::Database; options::Union{Nothing, BSON}=nothing) :: Vector{String}
    result = Vector{String}()
    for bson_collection in find_collections(database, options=options)
        push!(result, bson_collection["name"])
    end
    return result
end

# Aux function to add _id field to document if it does not exist.
function _new_id(document::BSON)
    if haskey(document, "_id")
        return document, nothing
    else
        inserted_oid = BSONObjectId()
        document = deepcopy(document) # copies it so this function doesn't have side effects
        document["_id"] = inserted_oid
        return document, inserted_oid
    end
end

function insert_one(collection::Collection, document::BSON; options::Union{Nothing, BSON}=nothing) :: InsertOneResult
    document, inserted_oid = _new_id(document)
    reply = BSON()
    err = BSONError()
    options_handle = options == nothing ? C_NULL : options.handle
    ok = mongoc_collection_insert_one(collection.handle, document.handle, options_handle, reply.handle, err)
    if !ok
        error("$err.")
    end
    return InsertOneResult(reply, (inserted_oid==nothing ? nothing : string(inserted_oid)))
end

function delete_one(collection::Collection, selector::BSON; options::Union{Nothing, BSON}=nothing)
    reply = BSON()
    err = BSONError()
    options_handle = options == nothing ? C_NULL : options.handle
    ok = mongoc_collection_delete_one(collection.handle, selector.handle, options_handle, reply.handle, err)
    if !ok
        error("$err.")
    end
    return reply
end

function delete_many(collection::Collection, selector::BSON; options::Union{Nothing, BSON}=nothing)
    reply = BSON()
    err = BSONError()
    options_handle = options == nothing ? C_NULL : options.handle
    ok = mongoc_collection_delete_many(collection.handle, selector.handle, options_handle, reply.handle, err)
    if !ok
        error("$err.")
    end
    return reply
end

function update_one(collection::Collection, selector::BSON, update::BSON; options::Union{Nothing, BSON}=nothing)
    reply = BSON()
    err = BSONError()
    options_handle = options == nothing ? C_NULL : options.handle
    ok = mongoc_collection_update_one(collection.handle, selector.handle, update.handle, options_handle, reply.handle, err)
    if !ok
        error("$err.")
    end
    return reply
end

function update_many(collection::Collection, selector::BSON, update::BSON; options::Union{Nothing, BSON}=nothing)
    reply = BSON()
    err = BSONError()
    options_handle = options == nothing ? C_NULL : options.handle
    ok = mongoc_collection_update_many(collection.handle, selector.handle, update.handle, options_handle, reply.handle, err)
    if !ok
        error("$err.")
    end
    return reply
end

BulkOperationResult(reply::BSON, server_id::UInt32) = BulkOperationResult(reply, server_id, Vector{Union{Nothing, BSONObjectId}}())

function execute!(bulk_operation::BulkOperation) :: BulkOperationResult
    if bulk_operation.executed
        error("Bulk operation was already executed.")
    end

    try
        reply = BSON()
        err = BSONError()
        bulk_operation_result = mongoc_bulk_operation_execute(bulk_operation.handle, reply.handle, err)
        if bulk_operation_result == 0
            error("Bulk operation execution failed. $err.")
        end
        return BulkOperationResult(reply, bulk_operation_result)
    finally
        destroy!(bulk_operation)
    end
end

function bulk_insert!(bulk_operation::BulkOperation, document::BSON; options::Union{Nothing, BSON}=nothing)
    err = BSONError()
    options_handle = options == nothing ? C_NULL : options.handle
    ok = mongoc_bulk_operation_insert_with_opts(bulk_operation.handle, document.handle, options_handle, err)
    if !ok
        error("Bulk insert failed. $err.")
    end
    nothing
end

function insert_many(collection::Collection, documents::Vector{BSON}; bulk_options::Union{Nothing, BSON}=nothing, insert_options::Union{Nothing, BSON}=nothing)
    inserted_oids = Vector{Union{Nothing, String}}()

    bulk_operation = BulkOperation(collection, options=bulk_options)
    for doc in documents
        doc, inserted_oid = _new_id(doc)
        bulk_insert!(bulk_operation, doc, options=insert_options)
        push!(inserted_oids, (inserted_oid==nothing ? nothing : string(inserted_oid)))
    end
    result = execute!(bulk_operation)
    append!(result.inserted_oids, inserted_oids)
    return result
end

function find(collection::Collection, bson_filter::BSON=BSON(); options::Union{Nothing, BSON}=nothing) :: Cursor
    options_handle = options == nothing ? C_NULL : options.handle
    cursor_handle = mongoc_collection_find_with_opts(collection.handle, bson_filter.handle, options_handle, C_NULL)
    if cursor_handle == C_NULL
        error("Couldn't execute query.")
    end
    return Cursor(collection, cursor_handle)
end

function count_documents(collection::Collection, bson_filter::BSON=BSON(); options::Union{Nothing, BSON}=nothing)
    err = BSONError()
    options_handle = options == nothing ? C_NULL : options.handle
    len = mongoc_collection_count_documents(collection.handle, bson_filter.handle, options_handle, C_NULL, C_NULL, err)
    if len == -1
        error("Couldn't count number of elements in $collection. $err.")
    end
    return Int(len)
end

function set_limit!(cursor::Cursor, limit::Int)
    ok = mongoc_cursor_set_limit(cursor.handle, limit)
    if !ok
        error("Couldn't set cursor limit to $limit.")
    end
    nothing
end

"""
    find_one(collection::Collection, bson_filter::BSON=BSON(); options::Union{Nothing, BSON}=nothing) :: Union{Nothing, BSON}

Execute a query to a collection and returns the first element of the result set.

Returns `nothing` if the result set is empty.
"""
function find_one(collection::Collection, bson_filter::BSON=BSON(); options::Union{Nothing, BSON}=nothing) :: Union{Nothing, BSON}
    cursor = find(collection, bson_filter, options=options)
    set_limit!(cursor, 1)
    next = _iterate(cursor)
    if next == nothing
        return nothing
    else
        bson_document, _state = next
        return bson_document
    end
end

function aggregate(collection::Collection, bson_pipeline::BSON; flags::QueryFlags=QUERY_FLAG_NONE, options::Union{Nothing, BSON}=nothing) :: Cursor
    options_handle = options == nothing ? C_NULL : options.handle
    cursor_handle = mongoc_collection_aggregate(collection.handle, flags, bson_pipeline.handle, options_handle, C_NULL)
    if cursor_handle == C_NULL
        error("Couldn't execute aggregate command.")
    end
    return Cursor(collection, cursor_handle)
end

#
# High-level API
#

function _iterate(cursor::Cursor, state::Nothing=nothing)
    bson_handle_ref = Ref{Ptr{Cvoid}}()
    has_next = mongoc_cursor_next(cursor.handle, bson_handle_ref)

    if has_next
        # The bson document is valid only until the next call to mongoc_cursor_next.
        # So we should return a deepcopy.
        return deepcopy(BSON(bson_handle_ref[], enable_finalizer=false)), nothing
    else
        err = BSONError()
        if mongoc_cursor_error(cursor.handle, err)
            error("$err")
        end

        return nothing
    end
end

Base.iterate(cursor::Cursor, state::Nothing=nothing) = _iterate(cursor, state)

function Base.iterate(coll::Collection)
    cursor = find(coll)
    return iterate(coll, cursor)
end

function Base.iterate(coll::Collection, state::Cursor)
    next = _iterate(state)
    if next == nothing
        return nothing
    else
        doc, _ = next
        return doc, state
    end
end

Base.show(io::IO, uri::URI) = print(io, "URI(\"", uri.uri, "\")")
Base.show(io::IO, client::Client) = print(io, "Client(URI(\"", client.uri, "\"))")
Base.show(io::IO, db::Database) = print(io, "Database($(db.client), \"", db.name, "\")")
Base.show(io::IO, coll::Collection) = print(io, "Collection($(coll.database), \"", coll.name, "\")")

Base.getindex(client::Client, database::String) = Database(client, database)
Base.getindex(database::Database, collection_name::String) = Collection(database, collection_name)

Base.push!(collection::C, document::BSON; options::Union{Nothing, BSON}=nothing) where {C<:AbstractCollection} = insert_one(collection, document; options=options)
Base.append!(collection::C, documents::Vector{BSON}; bulk_options::Union{Nothing, BSON}=nothing, insert_options::Union{Nothing, BSON}=nothing) where {C<:AbstractCollection}= insert_many(collection, documents; bulk_options=bulk_options, insert_options=insert_options)

Base.length(collection::C, bson_filter::BSON=BSON(); options::Union{Nothing, BSON}=nothing) where {C<:AbstractCollection} = count_documents(collection, bson_filter; options=options)
Base.isempty(collection::C, bson_filter::BSON=BSON(); options::Union{Nothing, BSON}=nothing) where {C<:AbstractCollection} = count_documents(collection, bson_filter; options=options) == 0
Base.empty!(collection::C) where {C<:AbstractCollection} = delete_many(collection, BSON())

function Base.collect(cursor::Cursor) :: Vector{BSON}
    result = Vector{BSON}()
    for doc in cursor
        push!(result, doc)
    end
    return result
end

Base.collect(collection::C, bson_filter::BSON=BSON()) where {C<:AbstractCollection} = collect(find(collection, bson_filter))


text:
using go

if length(ARGS) < 2
    println(STDERR, "usage: extract.jl {cgs|kgs} output_file.hf5 {optional filename regex} {max_files}")
    exit()
end

DATASOURCE = ARGS[1]
OUTPUT_NAME = ARGS[2]

# Set the feature extractors
feats = go.LIBERTIES

println(STDERR, "Finding SGF files...")
files = go.find_sgf("../data/$(DATASOURCE)/");
println(STDERR, "Found $(length(files)) sgf files")

# Filter to filenames containing regex (e.g. month/year)
if length(ARGS) == 3
    matcher = Regex(ARGS[3])
    filtered = Vector{AbstractString}()
    for filename in files
        if match(matcher, filename) != nothing
            push!(filtered, filename)
        end
    end
    files = filtered
    println(STDERR, "Contains filtered down to $(length(files))")
end

println(STDERR, "SGF games with highly ranked players...")
if DATASOURCE == "cgs"
    files =  filter(x -> go.players_over_rating(x, 2000), files)
#elseif contains(DATASOURCE, "kgs")
#    files =  filter(x -> go.players_over_rating(x, 7, dan=true), files)
end

if length(ARGS) == 4
    maxfiles = parse(Int, ARGS[4])
    if maxfiles < length(files)
        files = files[randperm(length(files))][1:maxfiles]
    end
end

println("Found $(length(files)) matching sgf files")

files = files[randperm(length(files))]

println(STDERR, "Extracting features from $(length(files)) games...")
go.extract_to_hdf5(OUTPUT_NAME, files, feats, nlabels = go.N*go.N)


text:
using VortexFilaments
using Test

const GROUP = get(ENV, "GROUP", "All")

ENV["GKSwstype"] = "nul"

include("vortexfilament.jl")


text:
function ll_obj(params;xs=X,ys=Y)
    n = size(X)[1]
    k = Integer(size(X)[2]/2) + 1

    #case 1, y2 comes first
    util11 = params[1] .+ xs[:,1].*params[2]  .+ ys[:,2].*params[3]
    util21 = params[4] .+ xs[:,2].*params[5]

    ll_game1 = exp.(util11).^(ys[:,1])./(1 .+ exp.(util11))
    ll_game1 = ll_game1 .* exp.(util21).^(ys[:,2])./(1 .+ exp.(util21))

    #case 2, y1 comes first
    util12 = params[1] .+ xs[:,1].*params[2]
    util22 = params[4] .+ xs[:,2].*params[5] .+ ys[:,1].*params[6]

    ll_game2 = exp.(util12).^(ys[:,1])./(1 .+ exp.(util12))
    ll_game2 = ll_game2 .* exp.(util22).^(ys[:,2])./(1 .+ exp.(util22))

    lambda = exp(params[7])/(1+exp(params[7]))

    #need to adjust for 11?
    util13 = params[1] .+ xs[:,1].*params[2]  .+ ys[:,2].*params[3]
    util23 = params[4] .+ xs[:,2].*params[5] .+ ys[:,1].*params[6]
    ll_game3 = exp.(util13).^(ys[:,1])./(1 .+ exp.(util13))
    ll_game3 = ll_game3 .* exp.(util23).^(ys[:,2])./(1 .+ exp.(util23))

    ll = (1 .- ys[:,1].*ys[:,2]) .* (lambda .* ll_game1 + (1-lambda) .* ll_game2) + ys[:,1].*ys[:,2] .*ll_game3

    return -sum(log.(ll))
end

function ll_obj(params;xs=X,ys=Y)
    n = size(X)[1]
    k = Integer(size(X)[2]/2) + 1

    p = []

    for bound=[[0,0],[1,1],[0,1],[1,0]]
        util1 = params[1] .+ xs[:,1].*params[2]  .+ bound[2].*params[3]
        util2 = params[4] .+ xs[:,2].*params[5]  .+ bound[1].*params[6]
        bound = exp.(util1).^(bound[1])./(1 .+ exp.(util1))
        bound = bound .* exp.(util2).^(bound[2])./(1 .+ exp.(util2))
        append!(p,[bound])
    end

    p00 = (1 .- ys[:,1]).*(1 .- ys[:,2])
    p11 = ys[:,1].*ys[:,2]
    p10 = ys[:,1].* (1 .- ys[:,2])
    p01 = (1 .- ys[:,1]) .* ys[:,2]

    lambda = exp(params[7])/(1+exp(params[7]))

    ll = p00 .* log.(p[1]) .+ p11 .* log.(p[2])
    ll = ll .+ p01 .* log.( lambda .* p[3] .+ (1 .-lambda) .* p[4] )
    ll = ll .+ p10 .* log. ( lambda .* p[3] .+ (1 .-lambda) .* p[4])
    return -sum(ll)
end

function ll_obj(params;xs=X,ys=Y)
    n = size(X)[1]
    k = Integer(size(X)[2]/2) + 1

    p = []

    for bound=[[0,0],[1,1],[0,1],[1,0]]
        util1 = params[1] .+ xs[:,1].*params[2]  .+ bound[2].*params[3]
        util2 = params[4] .+ xs[:,2].*params[5]  .+ bound[1].*params[6]
        bound = exp.(util1).^(bound[1])./(1 .+ exp.(util1))
        bound = bound .* exp.(util2).^(bound[2])./(1 .+ exp.(util2))
        append!(p,[bound])
    end

    p00 = (1 .- ys[:,1]).*(1 .- ys[:,2])
    p11 = ys[:,1].*ys[:,2]
    p10 = ys[:,1].* (1 .- ys[:,2])
    p01 = (1 .- ys[:,1]) .* ys[:,2]

    lambda = exp(params[7])/(1+exp(params[7]))
    #println(1 .- p[1] .- p[2] .- p[4])
    ll = p00 .* log.(p[1]) + p11 .* log.(p[2])
    ll = p01 .* log.(lambda .* p[3] + (1-lambda).*(1 .- p[1] .- p[2] .- p[4] ) )
    ll = p10 .* log.((1-lambda) .* p[4] + lambda.*(1 .- p[1] .- p[2] .- p[3] ) )
    return -sum(ll)
end

max_stars_repo_name: ericschulman/nash

max_issues_repo_name: ericschulman/nash

max_forks_repo_name: ericschulman/nash


text:
@inline function set_vars!(sol::R1, p::R2, Y::R3, YP::R3, t::R4, run::R5, opts::R6, bounds::R7;
    modify!::R8=set_var!,
    init_all::Bool=false,
    SOC::Number = (@inbounds sol.SOC[end])
    ) where {
        R1<:solution,
        R2<:model,
        R3<:Vector{Float64},
        R4<:Float64,
        R5<:AbstractRun,
        R6<:options_simulation_immutable,
        R7<:boundary_stop_conditions_immutable,
        R8<:Function,
        }
    """
    Sets all the outputs for the sol. There are three kinds of variable outputs:

    1. `keep.x = true`: The variable is calculated and saved on every iteration

    2. `keep.x = false` WITHOUT the check `if keep.x ... end`: These variables  MUST be
        calculated to ensure that `check_simulation_stop!` works properly (e.g., check if
        `t > tf` or `SOC > SOC_max`), but they are not saved on every iteration

    3. `keep.x = false` WITH the check `if keep.x ... end`: These variables are not
        evaluated at all and may not even be calculable (e.g., `T` if there is no
        temperature enabled)
    """
    keep = opts.var_keep

    # these variables must be calculated, but they may not necessarily be kept
    modify!(sol.SOC, isempty(sol.SOC) ? SOC : calc_SOC(SOC, Y, t + run.t0, sol, p), (keep.SOC || init_all))
    modify!(sol.t,   t + run.t0, (keep.t || init_all))

    # these variables do not need to be calculated
    if keep.YP      modify!(sol.YP,      copy(YP)           ) end
    if keep.I       modify!(sol.I,       calc_I(Y, p)       ) end
    if keep.V       modify!(sol.V,       calc_V(Y, p)       ) end
    if keep.P       modify!(sol.P,       calc_P(Y, p)       ) end
    if keep.c_e     modify!(sol.c_e,     calc_c_e(Y, p)     ) end
    if keep.c_s_avg modify!(sol.c_s_avg, calc_c_s_avg(Y, p) ) end
    if keep.j       modify!(sol.j,       calc_j(Y, p)       ) end
    if keep.Φ_e     modify!(sol.Φ_e,     calc_Φ_e(Y, p)     ) end
    if keep.Φ_s     modify!(sol.Φ_s,     calc_Φ_s(Y, p)     ) end

    # exist as an optional output if the sol uses them
    if ( p.numerics.temperature == true           && keep.T    ) modify!(sol.T,    calc_T(Y,p)    ) end
    if ( p.numerics.aging == :SEI                 && keep.film ) modify!(sol.film, calc_film(Y,p) ) end
    if ( p.numerics.aging == :SEI                 && keep.SOH  ) modify!(sol.SOH,  calc_SOH(Y, p) ) end
    if ( !(p.numerics.aging == false)             && keep.j_s  ) modify!(sol.j_s,  calc_j_s(Y,p)  ) end
    if ( p.numerics.solid_diffusion == :quadratic && keep.Q    ) modify!(sol.Q,    calc_Q(Y,p)    ) end

    return nothing
end

@inline set_var!(x, x_val) = push!(x, x_val)
@inline function set_var!(x::T1, x_val::T2, keep::Bool) where {T1<:Vector{Float64},T2<:Number}
    keep ? push!(x, x_val) : (@inbounds x[1] = x_val)
end
@inline function set_var!(x::T1, x_val::T2, keep::Bool) where {T1<:VectorOfArray{Float64,2,Array{Array{Float64,1},1}},T2<:AbstractVector{Float64}}
    keep ? push!(x, x_val) : (@inbounds x[1] .= x_val)
end

@inline function set_var_last!(x::T1, x_val::T2, keep=true) where {T1<:Vector{Float64},T2<:Number}
    @inbounds x[end] = x_val
end
@inline function set_var_last!(x::T1, x_val::T2, keep=true) where {T1<:VectorOfArray{Float64,2,Array{Array{Float64,1},1}},T2<:AbstractVector{Float64}}
    @inbounds x[end] .= x_val
end

@inline function (sol::solution)(tspan::Union{Number,AbstractVector}; interp_bc::Symbol=:interpolate, k::Int64=1,kw...)
    if tspan isa UnitRange
        t = collect(tspan)
    elseif tspan isa Number
        t = Float64[Float64(tspan)]
    else
        t = tspan
    end

    var_keep = @inbounds @views sol.results[end].opts.var_keep
    function f(field)
        x = getproperty(sol, field)
        if field == :t
            return t
        elseif x isa AbstractArray{Float64} && getproperty(var_keep, field) && length(x) > 1
            return interpolate_variable(x, sol, t, interp_bc; k=k, kw...)
        else
            return x
        end
    end

    states_tot = @inbounds (f(field) for field in fieldnames(solution))

    sol = solution(states_tot...)

    return sol
end
@inline interpolate_variable(x::Any,y...;kw...) = x
@inline function interpolate_variable(x::R1, sol::R2, tspan::T1, interp_bc::Symbol;kw...) where {R1<:AbstractVector{Float64},R2<:solution,T1<:Union{Real,AbstractArray}}
    spl = Spline1D(sol.t, x; bc = (interp_bc == :interpolate ? "nearest" : (interp_bc == :extrapolate ? "extrapolate" : error("Invalid interp_bc method."))),kw...)
    out = spl(tspan)

    return out
end
@inline function interpolate_variable(x::R1,y...;kw...) where {R1<:Union{VectorOfArray{Float64,2,Array{Array{Float64,1},1}},Vector{Vector{Float64}}}}
    out = @inbounds @views hcat([interpolate_variable(x[i,:],y...;kw...) for i in 1:size(x,1)]...)

    return @inbounds VectorOfArray([out[i,:] for i in 1:size(out,1)])
end


text:
module JuliaPackageTest

using Distributions

# Write your package code here.

export sum_values
include("simple_function.jl")
end


text:
kilo = 1_000
mega = 1_000_000
giga = 1_000_000_000
tera = 1_000_000_000_000
peta = 1_000_000_000_000_000

max_stars_repo_name: mccg/dotfiles

max_issues_repo_name: mccg/dotfiles

max_forks_repo_name: mccgit/dotfiles


text:
rm(joinpath(dirname(@__FILE__), "deps.jl"); force=true)
rm(joinpath(dirname(@__FILE__), "usr"); force=true, recursive=true)
rm(joinpath(dirname(@__FILE__), "src"); force=true, recursive=true)

include("build.jl")


text:
@testset "Basic arrays generators" begin
  @testset "ket" begin
    #standard tests
    @test ket(1, 2) == [1;0]
    #error tests
    @test_throws AssertionError ket(4, 2)
    @test_throws ArgumentError ket(-4, -2)
  end

  @testset "bra" begin
    #standard tests
    @test bra(1, 2) == [1 0 ]
    #error tests
    @test_throws AssertionError bra(4, 2)
    @test_throws ArgumentError bra(-4, -2)
  end

  @testset "ketbra" begin
    #standard tests
    @test ketbra(1, 2, 3) == [0 1 0; 0 0 0; 0 0 0]
    #error tests
    @test_throws AssertionError ketbra(3, 2, 2)
    @test_throws AssertionError ketbra(2, 3, 2)
    @test_throws ArgumentError ketbra(-4, -2, -1)
  end

  @testset "proj" begin
    #standard tests#
    result = [0.0+0.0im 0.0+0.0im 0.0+0.0im;
              0.0+0.0im 1.0+0.0im 0.0+0.0im;
              0.0+0.0im 0.0+0.0im 0.0+0.0im]
    @test proj(2, 3) == result
    @test proj(1/sqrt(2) * (ket(1, 3)+ket(3, 3))) ≈
                         [0.5+0.0im 0.0+0.0im 0.5+0.0im;
                          0.0+0.0im 0.0+0.0im 0.0+0.0im;
                          0.5+0.0im 0.0+0.0im 0.5+0.0im]
    #error tests
    @test_throws ArgumentError proj(2, -1)
    @test_throws AssertionError proj(3, 2)
  end
end

@testset "Array reshuffles" begin
  @testset "res and unres" begin
    #standard tests
    M = Matrix{Float64}(reshape(1:9, (3, 3))')
    v = Vector{Float64}(collect(1:9))
    A = Complex{Float64}[0.354177+0.0im 0.0891553-0.0251879im 0.0702961+0.0516828im 0.0708664+0.0767941im; 0.0891553+0.0251879im 0.336055+0.0im 0.0420202-0.0109173im 0.0683605-0.00692846im; 0.0702961-0.0516828im 0.0420202+0.0109173im 0.212401+0.0im 0.0939615+0.0553555im; 0.0708664-0.0767941im 0.0683605+0.00692846im 0.0939615-0.0553555im 0.0973671+0.0im]
    @test res(M) == v
    @test unres(v) == M
    @test unres(res(M)) == M
    @test res(unres(v)) == v
    @test unres(res(A)) == A
    #error tests
    @test_throws ArgumentError unres(collect(1:8)*1.)
  end
end