text:
function JSONRPC.parse_params(::Type{Val{Symbol("textDocument/didOpen")}}, params)
    return DidOpenTextDocumentParams(params)
end

function process(r::JSONRPC.Request{Val{Symbol("textDocument/didOpen")},DidOpenTextDocumentParams}, server)
    server.isrunning = true
    uri = r.params.textDocument.uri
    if URI2(uri) in keys(server.documents)
        doc = server.documents[URI2(uri)]
        doc._content = r.params.textDocument.text
    else
        server.documents[URI2(uri)] = Document(uri, r.params.textDocument.text, false, server)
        doc = server.documents[URI2(uri)]
        if any(i->startswith(uri, filepath2uri(i)), server.workspaceFolders)
            doc._workspace_file = true
        end
        set_open_in_editor(doc, true)
        if is_ignored(uri, server)
            doc._runlinter = false
        end
    end
    parse_all(doc, server)
end

function JSONRPC.parse_params(::Type{Val{Symbol("textDocument/didClose")}}, params)
    return DidCloseTextDocumentParams(params)
end

function process(r::JSONRPC.Request{Val{Symbol("textDocument/didClose")},DidCloseTextDocumentParams}, server)
    uri = r.params.textDocument.uri
    !haskey(server.documents, URI2(uri)) && return
    doc = server.documents[URI2(uri)]
    empty!(doc.diagnostics)
    publish_diagnostics(doc, server)
    if !is_workspace_file(doc)
        delete!(server.documents, URI2(uri))
    else
        set_open_in_editor(doc, false)
    end
end

function JSONRPC.parse_params(::Type{Val{Symbol("textDocument/didChange")}}, params)
    return DidChangeTextDocumentParams(params)
end

function process(r::JSONRPC.Request{Val{Symbol("textDocument/didChange")},DidChangeTextDocumentParams}, server)
    if !haskey(server.documents, URI2(r.params.textDocument.uri))
        server.documents[URI2(r.params.textDocument.uri)] = Document(r.params.textDocument.uri, "", true, server)
    end
    doc = server.documents[URI2(r.params.textDocument.uri)]
    doc._version = r.params.textDocument.version
    isempty(r.params.contentChanges) && return

    doc._content = last(r.params.contentChanges).text
    doc._line_offsets = nothing
    parse_all(doc, server)
end

function JSONRPC.parse_params(::Type{Val{Symbol("textDocument/didSave")}}, params)
    return DidSaveTextDocumentParams(params)
end

function process(r::JSONRPC.Request{Val{Symbol("textDocument/didSave")},DidSaveTextDocumentParams}, server)
    uri = r.params.textDocument.uri
    doc = server.documents[URI2(uri)]
    parse_all(doc, server)
end

function JSONRPC.parse_params(::Type{Val{Symbol("textDocument/willSave")}}, params)
    return WillSaveTextDocumentParams(params)
end

function process(r::JSONRPC.Request{Val{Symbol("textDocument/willSave")},WillSaveTextDocumentParams}, server)
end

function JSONRPC.parse_params(::Type{Val{Symbol("textDocument/willSaveWaitUntil")}}, params)
    return WillSaveTextDocumentParams(params)
end

function process(r::JSONRPC.Request{Val{Symbol("textDocument/willSaveWaitUntil")},WillSaveTextDocumentParams}, server)
    response = JSONRPC.Response(r.id, TextEdit[])
    send(response, server)
end

function JSONRPC.parse_params(::Type{Val{Symbol("textDocument/codeAction")}}, params)
    return CodeActionParams(params)
end

function process(r::JSONRPC.Request{Val{Symbol("textDocument/codeAction")},CodeActionParams}, server)
    # if !haskey(server.documents, URI2(r.params.textDocument.uri))
    #     send(JSONRPC.Response(r.id, CancelParams(r.id)), server)
    #     return
    # end
    # doc = server.documents[URI2(r.params.textDocument.uri)]
    commands = Command[]
    # range = r.params.range
    # range_loc = get_offset(doc, range.start.line + 1, range.start.character):get_offset(doc, range.stop.line + 1, range.stop.character)

    # tde = TextDocumentEdit(VersionedTextDocumentIdentifier(doc._uri, doc._version), [])
    # action_type = Any
    # tdeall = TextDocumentEdit(VersionedTextDocumentIdentifier(doc._uri, doc._version), [])
    # for d in doc.diagnostics
    #     if first(d.loc) <= first(range_loc) <= last(range_loc) <= last(d.loc) && typeof(d).parameters[1] isa LintCodes && !isempty(d.actions)
    #         action_type = typeof(d).parameters[1]
    #         for a in d.actions
    #             start_l, start_c = get_position_at(doc, first(a.range))
    #             end_l, end_c = get_position_at(doc, last(a.range))
    #             push!(tde.edits, TextEdit(Range(start_l - 1, start_c, end_l - 1, end_c), a.text))
    #         end
    #     end
    # end
    # file_actions = []
    # for d in doc.diagnostics
    #     if typeof(d).parameters[1] == action_type && !isempty(d.actions)
    #         for a in d.actions
    #             push!(file_actions, a)

    #         end
    #     end
    # end
    # sort!(file_actions, lt = (a, b) -> last(b.range) < first(a.range))
    # for a in file_actions
    #     start_l, start_c = get_position_at(doc, first(a.range))
    #     end_l, end_c = get_position_at(doc, last(a.range))
    #     push!(tdeall.edits, TextEdit(Range(start_l - 1, start_c, end_l - 1, end_c), a.text))
    # end

    # if !isempty(tde.edits)
    #     push!(commands, Command("Fix deprecation", "language-julia.applytextedit", [WorkspaceEdit(nothing, [tde])]))
    # end
    # if !isempty(tdeall.edits)
    #     push!(commands, Command("Fix all similar deprecations in file", "language-julia.applytextedit", [WorkspaceEdit(nothing, [tdeall])]))
    # end
    response = JSONRPC.Response(r.id, commands)
    send(response, server)
end

function get_partial_completion(doc, offset)
    ppt, pt, t = toks = get_toks(doc, offset)
    is_at_end = offset == t.endbyte + 1
    partial = nothing
    for ref in doc.code.uref
        if offset == ref.loc.offset + ref.val.span
            partial = ref
            break
        end
    end
    if partial == nothing
        for rref in doc.code.rref
            if offset == rref.r.loc.offset + rref.r.val.span
                partial = rref.r
                break
            end
        end
    end
    return partial, ppt, pt, t, is_at_end
end

function latex_completions(doc, offset, toks, CIs)
    ppt, pt, t = toks
    partial = string("\\", CSTParser.Tokens.untokenize(t))
    for (k, v) in REPL.REPLCompletions.latex_symbols
        if startswith(string(k), partial)
            t1 = TextEdit(Range(doc, offset-length(partial)+1:offset), "")
            t2 = TextEdit(Range(doc, offset-length(partial):offset-length(partial)+1), v)
            push!(CIs, CompletionItem(k[2:end], 6, v, t1, TextEdit[t2], 1))
        end
    end
end

function kw_completion(doc, spartial, ppt, pt, t, offsets, stack, CIs, offset)
    length(spartial) == 0 && return
    fc = first(spartial)
    if startswith("abstract", spartial)
    elseif fc == 'b'
        if startswith("baremodule", spartial)
            push!(CIs, CompletionItem("baremodule", 14, "baremodule", TextEdit(Range(doc, offset:offset), "baremodule \$0\nend"[length(spartial) + 1:end]), TextEdit[], 2))
        end
        if startswith("begin", spartial)
            push!(CIs, CompletionItem("begin", 14, "begin", TextEdit(Range(doc, offset:offset), "begin\n    \$0\nend"[length(spartial) + 1:end]), TextEdit[], 2))
        end
        if startswith("break", spartial)
            push!(CIs, CompletionItem("break", 14, "break", TextEdit(Range(doc, offset:offset), "break"[length(spartial) + 1:end]), TextEdit[], 1))
        end
    elseif fc == 'c'
        if startswith("catch", spartial)
            push!(CIs, CompletionItem("catch", 14, "catch", TextEdit(Range(doc, offset:offset), "catch"[length(spartial) + 1:end]), TextEdit[], 1))
        end
        if startswith("const", spartial)
            push!(CIs, CompletionItem("const", 14, "const", TextEdit(Range(doc, offset:offset), "const \$0"[length(spartial) + 1:end]), TextEdit[], 2))
        end
        if startswith("continue", spartial)
            push!(CIs, CompletionItem("continue", 14, "continue", TextEdit(Range(doc, offset:offset), "continue"[length(spartial) + 1:end]), TextEdit[], 1))
        end
    elseif startswith("do", spartial)
        push!(CIs, CompletionItem("do", 14, "do", TextEdit(Range(doc, offset:offset), "do \$0\n end"[length(spartial) + 1:end]), TextEdit[], 2))
    elseif fc == 'e'
        if startswith("else", spartial)
            push!(CIs, CompletionItem("else", 14, "else", TextEdit(Range(doc, offset:offset), "else"[length(spartial) + 1:end]), TextEdit[], 1))
        end
        if startswith("elseif", spartial)
            push!(CIs, CompletionItem("elseif", 14, "elseif", TextEdit(Range(doc, offset:offset), "elseif"[length(spartial) + 1:end]), TextEdit[], 1))
        end
        if startswith("end", spartial)
            push!(CIs, CompletionItem("end", 14, "end", TextEdit(Range(doc, offset:offset), "end"[length(spartial) + 1:end]), TextEdit[], 1))
        end
        if startswith("export", spartial)
            push!(CIs, CompletionItem("export", 14, "export", TextEdit(Range(doc, offset:offset), "export \$0"[length(spartial) + 1:end]), TextEdit[], 2))
        end
    elseif fc == 'f'
        if startswith("finally", spartial)
            push!(CIs, CompletionItem("finally", 14, "finally", TextEdit(Range(doc, offset:offset), "finally"[length(spartial) + 1:end]), TextEdit[], 1))
        end
        if startswith("for", spartial)
            push!(CIs, CompletionItem("for", 14, "for", TextEdit(Range(doc, offset:offset), "for \$1 in \$2\n    \$0\nend"[length(spartial) + 1:end]), TextEdit[], 2))
        end
        if startswith("function", spartial)
            push!(CIs, CompletionItem("function", 14, "function", TextEdit(Range(doc, offset:offset), "function \$1(\$2)\n    \$0\nend"[length(spartial) + 1:end]), TextEdit[], 2))
        end
    elseif startswith("global", spartial)
        push!(CIs, CompletionItem("global", 14, "global", TextEdit(Range(doc, offset:offset), "global \$0\n"[length(spartial) + 1:end]), TextEdit[], 2))
    elseif fc == 'i'
        if startswith("if", spartial)
            push!(CIs, CompletionItem("if", 14, "if", TextEdit(Range(doc, offset:offset), "if \$0\nend"[length(spartial) + 1:end]), TextEdit[], 2))
        end
        if startswith("import", spartial)
            push!(CIs, CompletionItem("import", 14, "import", TextEdit(Range(doc, offset:offset), "import \$0\n"[length(spartial) + 1:end]), TextEdit[], 2))
        end
        if startswith("importall", spartial)
            push!(CIs, CompletionItem("importall", 14, "importall", TextEdit(Range(doc, offset:offset), "importall \$0\n"[length(spartial) + 1:end]), TextEdit[], 2))
        end
    elseif fc == 'l'
        if startswith("let", spartial)
            push!(CIs, CompletionItem("let", 14, "let", TextEdit(Range(doc, offset:offset), "let \$1\n   \$0\nend"[length(spartial) + 1:end]), TextEdit[], 2))
        end
        if startswith("local", spartial)
            push!(CIs, CompletionItem("local", 14, "local", TextEdit(Range(doc, offset:offset), "local \$0\n"[length(spartial) + 1:end]), TextEdit[], 2))
        end
    elseif fc == 'm'
        if startswith("macro", spartial)
            push!(CIs, CompletionItem("macro", 14, "macro", TextEdit(Range(doc, offset:offset), "macro \$1(\$2)\n    \$0\nend"[length(spartial) + 1:end]), TextEdit[], 2))
        end
        if startswith("module", spartial)
            push!(CIs, CompletionItem("module", 14, "module", TextEdit(Range(doc, offset:offset), "module \$0\nend"[length(spartial) + 1:end]), TextEdit[], 2))
        end
        if startswith("mutable", spartial)
            push!(CIs, CompletionItem("mutable", 14, "mutable", TextEdit(Range(doc, offset:offset), "mutable struct \$1\n   \$0\nend"[length(spartial) + 1:end]), TextEdit[], 2))
        end
    elseif startswith("outer", spartial)
        push!(CIs, CompletionItem("outer", 14, "outer", TextEdit(Range(doc, offset:offset), "outer"[length(spartial) + 1:end]), TextEdit[], 2))
    elseif startswith("primitive", spartial)
        push!(CIs, CompletionItem("primitive", 14, "primitive", TextEdit(Range(doc, offset:offset), "primitive type \$1\n   \$0\nend"[length(spartial) + 1:end]), TextEdit[], 2))
    elseif startswith("quote", spartial)
        push!(CIs, CompletionItem("quote", 14, "quote", TextEdit(Range(doc, offset:offset), "quote\n    \$0\nend"[length(spartial) + 1:end]), TextEdit[], 2))
    elseif startswith("return", spartial)
        push!(CIs, CompletionItem("return", 14, "return", TextEdit(Range(doc, offset:offset), "return \$0\n"[length(spartial) + 1:end]), TextEdit[], 2))
    elseif startswith("struct", spartial)
        push!(CIs, CompletionItem("struct", 14, "struct", TextEdit(Range(doc, offset:offset), "struct \$1\n    \$0\nend"[length(spartial) + 1:end]), TextEdit[], 2))
    elseif fc == 't'
        if startswith("try", spartial)
            push!(CIs, CompletionItem("try", 14, "try", TextEdit(Range(doc, offset:offset), "try \$1\n    \$0\ncatch\nend"[length(spartial) + 1:end]), TextEdit[], 2))
        end
    elseif startswith("using", spartial)
        push!(CIs, CompletionItem("using", 14, "using", TextEdit(Range(doc, offset:offset), "using \$0\n"[length(spartial) + 1:end]), TextEdit[], 2))
    elseif startswith("while", spartial)
        push!(CIs, CompletionItem("while", 14, "while", TextEdit(Range(doc, offset:offset), "while \$1\n    \$0\nend"[length(spartial) + 1:end]), TextEdit[], 2))
    end
end

function JSONRPC.parse_params(::Type{Val{Symbol("textDocument/completion")}}, params)
    return CompletionParams(params)
end

function process(r::JSONRPC.Request{Val{Symbol("textDocument/completion")},CompletionParams}, server)
    if !haskey(server.documents, URI2(r.params.textDocument.uri))
        send(JSONRPC.Response(r.id, CancelParams(r.id)), server)
        return
    end

    CIs = CompletionItem[]
    doc = server.documents[URI2(r.params.textDocument.uri)]
    rootdoc = find_root(doc, server)
    state = StaticLint.build_bindings(rootdoc.code)
    offset = get_offset(doc, r.params.position.line + 1, r.params.position.character)
    partial, ppt, pt, t, is_at_end  = get_partial_completion(doc, offset)
    toks = ppt, pt, t
    stack, offsets = StaticLint.get_stack(doc.code.cst, offset)

    if pt isa CSTParser.Tokens.Token && pt.kind == CSTParser.Tokenize.Tokens.BACKSLASH
        #latex completion
        latex_completions(doc, offset, toks, CIs)
    elseif t isa CSTParser.Tokens.Token && t.kind == CSTParser.Tokenize.Tokens.STRING
        #path completion
        path, partial = splitdir(t.val[2:prevind(t.val, length(t.val))])
        if !startswith(path, "/")
            path = joinpath(dirname(uri2filepath(doc._uri)), path)
        end
        if ispath(path)
            fs = readdir(path)
            for f in fs
                if startswith(f, partial)
                    if isdir(joinpath(path, f))
                        f = string(f, "/")
                    end
                    push!(CIs, CompletionItem(f, 6, f, TextEdit(Range(doc, offset:offset), f[length(partial) + 1:end]), TextEdit[], 1))
                end
            end
        end
    elseif length(stack) > 1 && (stack[end-1] isa CSTParser.EXPR{CSTParser.Using} ||
        stack[end-1] isa CSTParser.EXPR{CSTParser.Import} || stack[end-1] isa CSTParser.EXPR{CSTParser.ImportAll})
        #import completion
        import_statement = stack[end-1]
        if (t.kind == Tokens.WHITESPACE && pt.kind ∈ (Tokens.USING,Tokens.IMPORT,Tokens.IMPORTALL,Tokens.COMMA)) ||
            (t.kind == Tokens.COMMA)
            #no partial, no dot
            for (n,m) in server.packages
                startswith(n, ".") && continue
                push!(CIs, CompletionItem(n, 6, MarkupContent(m.doc), TextEdit(Range(doc, offset:offset), n), TextEdit[], 1))
            end
        elseif t.kind == Tokens.DOT && pt.kind == Tokens.IDENTIFIER
            #no partial, dot
            if haskey(server.packages, pt.val)
                rootmod = server.packages[pt.val]
                for (n,m) in rootmod.vals
                    startswith(n, ".") && continue
                    push!(CIs, CompletionItem(n, 6, MarkupContent(m isa SymbolServer.SymStore ? m.doc : n), TextEdit(Range(doc, offset:offset), n[nextind(n,sizeof(t.val)):end]), TextEdit[], 1))
                end
            end
        elseif t.kind == Tokens.IDENTIFIER && is_at_end
            #partial
            if pt.kind == Tokens.DOT && ppt.kind == Tokens.IDENTIFIER
                if haskey(server.packages, ppt.val)
                    rootmod = server.packages[ppt.val]
                    for (n,m) in rootmod.vals
                        if startswith(n, t.val)
                            push!(CIs, CompletionItem(n, 6, MarkupContent(m isa SymbolServer.SymStore ? m.doc : n), TextEdit(Range(doc, offset:offset), n[length(t.val) + 1:end]), TextEdit[], 1))
                        end
                    end
                end
            else
                for (n,m) in server.packages
                    if startswith(n, t.val)
                        push!(CIs, CompletionItem(n, 6, MarkupContent(m isa SymbolServer.SymStore ? m.doc : n), TextEdit(Range(doc, offset:offset), n[nextind(n,sizeof(t.val)):end]), TextEdit[], 1))
                    end
                end
            end
        end
    elseif t isa CSTParser.Tokens.Token && t.kind == CSTParser.Tokens.DOT && pt isa CSTParser.Tokens.Token && pt.kind == CSTParser.Tokens.IDENTIFIER
        #getfield completion, no partial
        offset1 = offset - (1 + t.endbyte - t.startbyte) - (1 + pt.endbyte - pt.startbyte)
        ref = find_ref(doc, offset1)
        if ref != nothing && ref.b.val isa StaticLint.SymbolServer.ModuleStore # check we've got a Module
            for (n,v) in ref.b.val.vals
                startswith(n, ".") && continue
                push!(CIs, CompletionItem(n, 6, MarkupContent(n), TextEdit(Range(doc, offset:offset), n), TextEdit[], 1))
            end
        end
    elseif t isa CSTParser.Tokens.Token && t.kind == CSTParser.Tokens.IDENTIFIER && pt isa CSTParser.Tokens.Token && pt.kind == CSTParser.Tokens.DOT && ppt isa CSTParser.Tokens.Token && ppt.kind == CSTParser.Tokens.IDENTIFIER
        #getfield completion, partial
        offset1 = offset - (1 + t.endbyte - t.startbyte) - (1 + pt.endbyte - pt.startbyte) - (1 + ppt.endbyte - ppt.startbyte) # get offset 2 tokens back
        ref = find_ref(doc, offset1)
        if ref != nothing && ref.b.val isa StaticLint.SymbolServer.ModuleStore # check we've got a Module
            for (n,v) in ref.b.val.vals
                if startswith(n, t.val)
                    push!(CIs, CompletionItem(n, 6, MarkupContent(v isa SymbolServer.SymStore ? v.doc : n), TextEdit(Range(doc, offset:offset), n[nextind(n,sizeof(t.val)):end]), TextEdit[], 1))
                end
            end
        end
    elseif t isa CSTParser.Tokens.Token && t.kind == CSTParser.Tokens.IDENTIFIER
        #token completion
        if is_at_end && partial != nothing
            if pt isa CSTParser.Tokens.Token && pt.kind == CSTParser.Tokens.AT_SIGN
                spartial = string("@", t.val)
            else
                spartial = t.val
            end
            kw_completion(doc, spartial, ppt, pt, t, offsets, stack, CIs, offset)
            lbsi = StaticLint.get_lbsi(partial, state).i
            si = partial.si.i

            while length(si) >= length(lbsi)
                if haskey(state.bindings, si)
                    for (n,B) in state.bindings[si]
                        if startswith(n, spartial)
                            push!(CIs, CompletionItem(n, 6, MarkupContent(n), TextEdit(Range(doc, offset:offset), n[nextind(n,sizeof(spartial)):end]), TextEdit[], 1))
                        end
                    end
                end
                if length(si) == 0
                    break
                else
                    si = StaticLint.shrink_tuple(si)
                end
            end
            for m in state.used_modules #iterate over imported modules
                for sym in m.val.exported
                    if startswith(string(sym), spartial)
                        comp = string(sym)
                        !haskey(m.val.vals, comp) && continue
                        x = m.val.vals[comp]
                        docs = x isa StaticLint.SymbolServer.SymStore ? x.doc : ""
                        push!(CIs, CompletionItem(comp, 6, MarkupContent(docs), TextEdit(Range(doc, offset:offset), comp[nextind(comp, sizeof(spartial)):end]), TextEdit[], 1))
                    end
                end
            end
        end
    end

    send(JSONRPC.Response(r.id, CompletionList(true, unique(CIs))), server)
end

# temp fix for user defined sigs
function get_sig_args(sig)
    while sig isa CSTParser.WhereOpCall
        sig = sig.arg1
    end
    state, s = StaticLint.State(), StaticLint.Scope()
    StaticLint.get_fcall_bindings(sig, state, s)
    out = Tuple{Int,String}[]
    if haskey(state.bindings, ())
        for (n,B) in state.bindings[()]
            b = last(B)
            push!(out, (b.si.n, n))
        end
    end
    sort!(out, lt = (a,b)->a[1]<b[1])
    return [o[2] for o in out]
end

function get_signatures(x::StaticLint.ResolvedRef, state, sigs = SignatureInformation[])
    if x.b.val isa StaticLint.SymbolServer.FunctionStore || x.b.val isa StaticLint.SymbolServer.structStore
        for m in x.b.val.methods
            p_sigs = [join(string.(p), "::") for p in m.args]
            PI = map(ParameterInformation, p_sigs)
            push!(sigs, SignatureInformation("$(CSTParser.str_value(x.r.val))($(join(p_sigs, ",")))", "", PI))
        end
    elseif CSTParser.defines_function(x.b.val)
        for m in StaticLint.get_methods(x, state)
            !(m.val isa CSTParser.AbstractEXPR) && continue
            sig = CSTParser.get_sig(m.val)
            args = get_sig_args(sig)
            PI = map(p->ParameterInformation(string(p)), args)
            push!(sigs, SignatureInformation(string(Expr(sig)), "", PI))
        end
    end
    return sigs
end

function JSONRPC.parse_params(::Type{Val{Symbol("textDocument/signatureHelp")}}, params)
    return TextDocumentPositionParams(params)
end

function process(r::JSONRPC.Request{Val{Symbol("textDocument/signatureHelp")},TextDocumentPositionParams}, server)
    if !haskey(server.documents, URI2(r.params.textDocument.uri))
        send(JSONRPC.Response(r.id, CancelParams(r.id)), server)
        return
    end
    doc = server.documents[URI2(r.params.textDocument.uri)]
    rootdoc = find_root(doc, server)
    state = StaticLint.build_bindings(rootdoc.code)
    offset = get_offset(doc, r.params.position.line + 1, r.params.position.character)
    sigs = SignatureInformation[]
    arg = 0
    stack, offsets = StaticLint.get_stack(doc.code.cst, offset)

    if length(stack)>1 && stack[end-1] isa CSTParser.EXPR{CSTParser.Call}
        call_ex = stack[end-1]
        fname = call_ex.args[1]
        if fname isa CSTParser.EXPR{CSTParser.Curly}
            fname = fname.args[1]
        end
        fname_offset = offsets[end-1]
        if fname isa CSTParser.BinarySyntaxOpCall && fname.op.kind == CSTParser.Tokens.DOT
            fname_offset += fname.arg1.fullspan + fname.op.fullspan
        end

        x = find_ref(doc, fname_offset)
        if x isa Nothing
            send(JSONRPC.Response(r.id, CancelParams(Dict("id" => r.id))), server)
            return
        end
        sigs = get_signatures(x, state, sigs)
        if isempty(sigs)
            send(JSONRPC.Response(r.id, CancelParams(Dict("id" => r.id))), server)
            return
        end
        if CSTParser.is_lparen(last(stack))
            arg = 0
        elseif CSTParser.is_rparen(last(stack)) && offset > last(offsets)
            return send(JSONRPC.Response(r.id, CancelParams(Dict("id" => r.id))), server)
        else
            arg = sum(!(a isa PUNCTUATION) for a in call_ex.args) - 2
        end
    else
        return send(JSONRPC.Response(r.id, CancelParams(Dict("id" => r.id))), server)
    end

    send(JSONRPC.Response(r.id, SignatureHelp(filter(s -> length(s.parameters) > arg, sigs), 0, arg)), server)
end

function JSONRPC.parse_params(::Type{Val{Symbol("textDocument/definition")}}, params)
    return TextDocumentPositionParams(params)
end

function process(r::JSONRPC.Request{Val{Symbol("textDocument/definition")},TextDocumentPositionParams}, server)
    if !haskey(server.documents, URI2(r.params.textDocument.uri))
        send(JSONRPC.Response(r.id, CancelParams(r.id)), server)
        return
    end
    locations = Location[]

    doc = server.documents[URI2(r.params.textDocument.uri)]
    rootdoc = find_root(doc, server)
    state = StaticLint.build_bindings(rootdoc.code)
    offset = get_offset(doc, r.params.position.line + 1, r.params.position.character)
    stack, offsets = StaticLint.get_stack(doc.code.cst, offset)
    if length(stack)>2 && stack[end] isa CSTParser.LITERAL && stack[end].kind == CSTParser.Tokens.STRING && stack[end-1] isa CSTParser.EXPR{CSTParser.Call} && length(stack[end-1]) == 4 && stack[end-1].args[1] isa CSTParser.IDENTIFIER && stack[end-1].args[1].val == "include"
        path = (joinpath(dirname(doc._uri), stack[end].val))
        if haskey(server.documents, URI2(path))
            push!(locations, Location(path, 1))
        end
    else
        for rref in doc.code.rref
            if rref.r.loc.offset <= offset <= rref.r.loc.offset + rref.r.val.fullspan
                get_locations(rref, state, locations, server)
                break
            end
        end
    end

    send(JSONRPC.Response(r.id, locations), server)
end

function JSONRPC.parse_params(::Type{Val{Symbol("textDocument/formatting")}}, params)
    return DocumentFormattingParams(params)
end

function process(r::JSONRPC.Request{Val{Symbol("textDocument/formatting")},DocumentFormattingParams}, server)
    if !haskey(server.documents, URI2(r.params.textDocument.uri))
        send(JSONRPC.Response(r.id, CancelParams(r.id)), server)
        return
    end
    doc = server.documents[URI2(r.params.textDocument.uri)]
    newcontent = DocumentFormat.format(doc._content)
    end_l, end_c = get_position_at(doc, sizeof(doc._content))
    lsedits = TextEdit[TextEdit(Range(0, 0, end_l - 1, end_c), newcontent)]

    send(JSONRPC.Response(r.id, lsedits), server)
end

function JSONRPC.parse_params(::Type{Val{Symbol("textDocument/hover")}}, params)
    return TextDocumentPositionParams(params)
end

function process(r::JSONRPC.Request{Val{Symbol("textDocument/hover")},TextDocumentPositionParams}, server)
    if !haskey(server.documents, URI2(r.params.textDocument.uri))
        send(JSONRPC.Response(r.id, CancelParams(r.id)), server)
        return
    end
    documentation = Any[]
    doc = server.documents[URI2(r.params.textDocument.uri)]
    rootdoc = find_root(doc, server)
    state = StaticLint.build_bindings(rootdoc.code)
    offset = get_offset(doc, r.params.position.line + 1, r.params.position.character)
    stack, offsets = StaticLint.get_stack(doc.code.cst, offset)

    if last(stack) isa CSTParser.KEYWORD && last(stack).kind == CSTParser.Tokens.END && length(stack) > 1
        push!(documentation, MarkedString("Closes `$(Expr(stack[end-1].args[1]))` expression"))
    elseif CSTParser.is_rparen(last(stack)) && length(stack) > 1
        if stack[end-1] isa EXPR{CSTParser.Call}
            push!(documentation, MarkedString("Closes `$(Expr(stack[end-1].args[1]))` call"))
        elseif stack[end-1] isa EXPR{CSTParser.Tuple}
            push!(documentation, MarkedString("Closes a tuple"))
        end
    else
        for rref in doc.code.rref
            if rref.r.loc.offset <= offset <= rref.r.loc.offset + rref.r.val.fullspan
                if rref.b.val isa CSTParser.AbstractEXPR
                    if rref.b.t == server.packages["Core"].vals["Function"]
                        ms = StaticLint.get_methods(rref, state)
                        for m in ms
                            if m.val isa StaticLint.SymbolServer.FunctionStore || m.val isa StaticLint.SymbolServer.structStore
                                fname = CSTParser.str_value(rref.r.val)
                                for m1 in m.val.methods
                                    push!(documentation, MarkedString(string(fname, "(", join((a->string(a[1], "::", a[2])).(m1.args), ", "),")")))
                                end
                            elseif m.t == server.packages["Core"].vals["DataType"]
                                push!(documentation, MarkedString(string(Expr(m.val))))
                            else
                                push!(documentation, MarkedString(string(Expr(CSTParser.get_sig(m.val)))))
                            end
                        end
                    elseif rref.b.t == server.packages["Core"].vals["DataType"]
                        push!(documentation, MarkedString(string(Expr(rref.b.val))))
                    elseif rref.b.t != nothing
                        if rref.b.t isa CSTParser.AbstractEXPR
                            push!(documentation, MarkedString(string(Expr(rref.b.t) )))
                        elseif rref.b.t isa StaticLint.SymbolServer.SymStore
                            push!(documentation, MarkedString(replace(replace(rref.b.t.doc, "```"=>""), "\n\n" => "\n")))
                        end
                    else
                        push!(documentation, MarkedString(string(Expr(rref.b.val))))
                    end
                elseif rref.b.val isa StaticLint.SymbolServer.SymStore
                    push!(documentation, MarkedString(replace(replace(rref.b.val.doc, "```"=>""), "\n\n" => "\n")))
                end
            end
        end
    end

    send(JSONRPC.Response(r.id, Hover(unique(documentation))), server)
end

function JSONRPC.parse_params(::Type{Val{Symbol("textDocument/documentLink")}}, params)
    return DocumentLinkParams(params)
end

function process(r::JSONRPC.Request{Val{Symbol("textDocument/documentLink")},DocumentLinkParams}, server)
    if !haskey(server.documents, URI2(r.params.textDocument.uri))
        send(JSONRPC.Response(r.id, CancelParams(r.id)), server)
        return
    end
    links = Tuple{String,UnitRange{Int}}[]
    # uri = r.params.textDocument.uri
    # doc = server.documents[URI2(uri)]
    # # get_links(doc.code.ast, 0, uri, server, links)
    # doclinks = DocumentLink[]
    # for (uri2, loc) in links
    #     rng = Range(Position(get_position_at(doc, first(loc))..., one_based = true), Position(get_position_at(doc, last(loc))..., one_based = true))
    #     push!(doclinks, DocumentLink(rng, uri2))
    # end

    send(JSONRPC.Response(r.id, links), server)
end

function find_references(textDocument::TextDocumentIdentifier, position::Position, server)
    locations = Location[]
    doc = server.documents[URI2(textDocument.uri)]
    rootdoc = find_root(doc, server)
    state = StaticLint.build_bindings(rootdoc.code)
    refs = StaticLint.cat_references(rootdoc.code)
    rrefs, urefs = StaticLint.resolve_refs(refs, state, [], [])
    offset = get_offset(doc, position.line + 1, position.character)
    for rref in doc.code.rref
        if rref.r.loc.offset <= offset <= rref.r.loc.offset + rref.r.val.fullspan
            rref.b isa StaticLint.ImportBinding && continue
            if rref.b.t in (server.packages["Core"].vals["Function"], server.packages["Core"].vals["DataType"])
                bs = StaticLint.get_methods(rref, state)
            else
                bs = StaticLint.Binding[rref.b]
            end
            for rref1 in rrefs
                if rref1.b in bs
                    uri2 = filepath2uri(rref1.r.loc.file)
                    doc2 = server.documents[URI2(uri2)]
                    rng = rref1.r.loc.offset .+ (0:rref1.r.val.span)
                    push!(locations, Location(uri2, Range(doc2, rng)))
                end
            end
            break
        end
    end
    return locations
end

function JSONRPC.parse_params(::Type{Val{Symbol("textDocument/references")}}, params)
    return ReferenceParams(params)
end

function process(r::JSONRPC.Request{Val{Symbol("textDocument/references")},ReferenceParams}, server)
    if !haskey(server.documents, URI2(r.params.textDocument.uri))
        send(JSONRPC.Response(r.id, CancelParams(r.id)), server)
        return
    end
    locations = find_references(r.params.textDocument, r.params.position, server)
    send(JSONRPC.Response(r.id, locations), server)
end

function JSONRPC.parse_params(::Type{Val{Symbol("textDocument/rename")}}, params)
    return RenameParams(params)
end

function process(r::JSONRPC.Request{Val{Symbol("textDocument/rename")},RenameParams}, server)
    if !haskey(server.documents, URI2(r.params.textDocument.uri))
        send(JSONRPC.Response(r.id, CancelParams(r.id)), server)
        return
    end
    tdes = Dict{String,TextDocumentEdit}()
    locations = find_references(r.params.textDocument, r.params.position, server)

    for loc in locations
        if loc.uri in keys(tdes)
            push!(tdes[loc.uri].edits, TextEdit(loc.range, r.params.newName))
        else
            tdes[loc.uri] = TextDocumentEdit(VersionedTextDocumentIdentifier(loc.uri, server.documents[URI2(loc.uri)]._version), [TextEdit(loc.range, r.params.newName)])
        end
    end

    send(JSONRPC.Response(r.id, WorkspaceEdit(nothing, collect(values(tdes)))), server)
end

function JSONRPC.parse_params(::Type{Val{Symbol("textDocument/documentSymbol")}}, params)
    return DocumentSymbolParams(params)
end

function process(r::JSONRPC.Request{Val{Symbol("textDocument/documentSymbol")},DocumentSymbolParams}, server)
    if !haskey(server.documents, URI2(r.params.textDocument.uri))
        send(JSONRPC.Response(r.id, CancelParams(r.id)), server)
        return
    end
    syms = SymbolInformation[]
    uri = r.params.textDocument.uri
    doc = server.documents[URI2(uri)]

    for (s, S) in doc.code.state.bindings
        for (name, B) in S
            isempty(name) && continue
            for b in B
                push!(syms, SymbolInformation(name, 1, false, Location(doc._uri, Range(doc, b.loc.offset .+ (0:b.val.span))), nothing))
            end
        end
    end
    send(JSONRPC.Response(r.id, syms), server)
end


text:
# Autogenerated wrapper script for BiCePS_jll for x86_64-w64-mingw32-cxx11
export libbcps

using CoinUtils_jll
using Osi_jll
using Clp_jll
using Cgl_jll
using ALPS_jll
using CompilerSupportLibraries_jll
JLLWrappers.@generate_wrapper_header("BiCePS")
JLLWrappers.@declare_library_product(libbcps, "libBcps-1.dll")
function __init__()
    JLLWrappers.@generate_init_header(CoinUtils_jll, Osi_jll, Clp_jll, Cgl_jll, ALPS_jll, CompilerSupportLibraries_jll)
    JLLWrappers.@init_library_product(
        libbcps,
        "bin\\libBcps-1.dll",
        RTLD_LAZY | RTLD_DEEPBIND,
    )

    JLLWrappers.@generate_init_footer()
end  # __init__()

ext: jl


text: using Revise, Flux, DiffEqFlux, Kinnosuke


text:
module CLEARSWI

using MriResearchTools
using Statistics

include("tissue.jl")
include("utility.jl")
include("functions.jl")
include("magnitude_processing.jl")
include("phase_processing.jl")
include("simulate_single_echo.jl")

export calculateSWI,
        createMIP,
        createIntensityProjection,
        saveconfiguration,
        Data,
        Options,
        savenii,
        readmag,
        readphase

"""
    CLEARSWI.dir(path...)
Construct a path relative to SWI root.
# Example
```julia
julia> CLEARSWI.dir("test","testData","small","Mag.nii")
"/home/korbinian90/.julia/dev/CLEARSWI/test/testData/small/Mag.nii"
```
"""
dir(path...) = joinpath(dirname(@__DIR__),path...)

end


text:
beta_a_from_mv(m::Float64, v::Float64) = (m*(1-m)/v-1)*m

beta_b_from_mv(m::Float64, v::Float64) = (m*(1-m)/v-1)*(1-m)

function beta_pars_from_mv(m::Float64, v::Float64)
  c = m*(1-m)/v-1
  return c*m, c*(1-m)
end


text:
using Test
using Markdown
using ComoniconTypes
using ComoniconCast
# using Comonicon: split_docstring, has_docstring, read_arguments,
#     read_flags, read_options, read_description, read_section, read_content,
#     read_item, rm_format, docstring, md_to_string, split_option, split_hint,
#     JLMDOption, JLMDFlag

@testset "read_arguments" begin
    doc = Markdown.parse("""
        command <args>

    description of the command.

    # Args

    - `arg1`: argument 1.
    - `arg2`: argument 2.
    - `arg3`: argument 3.
    - `arg4`: argument 4.
    """)

    @test read_description(doc) == "description of the command."

    args = read_arguments(doc)
    @test args["arg1"] == "argument 1."
    @test args["arg2"] == "argument 2."
    @test args["arg3"] == "argument 3."
    @test args["arg4"] == "argument 4."

    doc = Markdown.parse("""
    description of the command.

    # Arguments

    - `arg1`: argument 1.
    - `arg2`: argument 2.
    - `arg3`: argument 3.
    - `arg4`: argument 4.
    """)

    @test read_description(doc) == "description of the command."

    args = read_arguments(doc)
    @test args["arg1"] == "argument 1."
    @test args["arg2"] == "argument 2."
    @test args["arg3"] == "argument 3."
    @test args["arg4"] == "argument 4."
end

@testset "split_hint" begin
    @test split_hint("long") == ("long", nothing)
    @test split_hint("long <value>") == ("long", "value")
    @test split_hint("long=<value>") == ("long", "value")
    @test split_hint("s") == ("s", nothing)
    @test split_hint("s=<value>") == ("s", "value")
    @test split_hint("s <value>") == ("s", "value")
    @test_throws Meta.ParseError split_hint("s=s")
    @test_throws Meta.ParseError split_hint("s=s=s")
end

@testset "split_option" begin
    @test split_option("--long") == ("long", nothing, nothing)
    @test split_option("--long <value>") == ("long", nothing, "value")
    @test split_option("--long=<value>") == ("long", nothing, "value")
    @test split_option("--short, -s") == ("short", "s", nothing)
    @test split_option("--short, -s <value>") == ("short", "s", "value")
    @test split_option("--short, -s=<value>") == ("short", "s", "value")
    @test_throws Meta.ParseError split_option("--short, -ss, -st")
    @test_throws Meta.ParseError split_option("--short, -ss")
    @test_throws Meta.ParseError split_option("--short, -ss=<value>")
    @test_throws Meta.ParseError split_option("--short, -t=<value>")
end

@testset "read_options" begin
    doc = Markdown.parse("""
    description of the command.

    # Options

    - `--short, -s`: short option using default hint.
    - `--short-space, -s <value>`: short option using given hint.
    - `--short-assign, -s=<value>`: short option using given hint.
    - `--long`: long option using default hint.
    - `--long-space <value>`: long option using given hint.
    - `--long-assign=<value>`: long option using given hint.
    - `--short_underscore, -s <value>`: short option with underscore.
    """)

    options = read_options(doc)
    @test options["short"] == JLMDOption(nothing, "short option using default hint.", true)
    @test options["short-space"] == JLMDOption("value", "short option using given hint.", true)
    @test options["short-assign"] == JLMDOption("value", "short option using given hint.", true)
    @test options["long"] == JLMDOption(nothing, "long option using default hint.", false)
    @test options["long-space"] == JLMDOption("value", "long option using given hint.", false)
    @test options["long-assign"] == JLMDOption("value", "long option using given hint.", false)
    @test options["short-underscore"] == JLMDOption("value", "short option with underscore.", true)
end

@testset "read_flags" begin
    doc = Markdown.parse("""
    description of the command.

    # Flags

    - `--short, -s`: short flag.
    - `--short-space, -s`: short flag with dash.
    - `--long`: long flag.
    - `--long-space`: long flag with dash.
    """)

    flags = read_flags(doc)
    @test flags["short"] == JLMDFlag("short flag.", true)
    @test flags["short-space"] == JLMDFlag("short flag with dash.", true)
    @test flags["long"] == JLMDFlag("long flag.", false)
    @test flags["long-space"] == JLMDFlag("long flag with dash.", false)
end

@testset "split_docstring" begin
    content = Markdown.parse("""
    description of the command.

    # Args

    - `arg1`: argument 1.
    - `arg2`: argument 2.
    - `arg3`: argument 3.
    - `arg4`: argument 4.

    # Options

    - `--short, -s`: short option using default hint.
    - `--short-space, -s <value>`: short option using given hint.
    - `--short-assign, -s=<value>`: short option using given hint.
    - `--long`: long option using default hint.
    - `--long-space <value>`: long option using given hint.
    - `--long-assign=<value>`: long option using given hint.
    - `--short_underscore, -s <value>`: short option with underscore.

    # Flags

    - `--short, -s`: short flag.
    - `--short-space, -s`: short flag with dash.
    - `--long`: long flag.
    - `--long-space`: long flag with dash.
    """)

    doc = split_docstring(content)
    @test doc.desc == "description of the command."
    @test doc.arguments["arg1"] == "argument 1."
    @test doc.flags["long"] == JLMDFlag("long flag.", false)
    @test doc.options["long"] == JLMDOption(nothing, "long option using default hint.", false)
end


text:
module Quadrature

function simps(func::Function, a::Real, b::Real, n::Int)::Float64
    if n % 2 !=0
         throw(ArgumentError("The number of intervals n must be even! You have choosen $n"))
     end
    dx = (b-a)/n
    res = func(a)

    w = 4
    x = 0.
    for i in 1:(n-1)
        x = a + dx*i
        res += func(x)*w
        w = 6 - w
    end
    res += func(b)
    return res * dx/3
end

function simps(func::Function, a::Real, b::Real; tol=1e-5, limit=100)::Float64
    n = 2
    iter=0
    res=0.

    while true
        res=simps(func, a, b, n)
        res1=simps(func, a, b, n*2)
        if abs(res1-res)<tol
            res=res1
            return res, n*2
        end
        n*=2
        iter+=1
        if iter>limit
            print("limit reached!")
            return NaN
        end
    end
    return NaN
end

function gauss_3(func::Function, a::Real, b::Real)::Float64
    w_ = [8 // 9, 5 // 9, 5 // 9]
    x_ = [0., sqrt(3// 5), -sqrt(3//5)]
    res = 0.
    c1 = (b - a) / 2
    c2 = (a + b) / 2

    for i in 1:3
        res += w_[i] * func(c1 * x_[i] + c2)
    end
    res *= c1;
    return res;
end

function gauss(func::Function, a::Real, b::Real, n::Int)::Float64
    dx = (b - a) / n
    res = 0.;
    xa = 0.;
    xb = 0;
    for i in 0:(n-1)
        xa = a + i * dx
        xb = xa + dx
        res += gauss_3(func, xa, xb)
    end
    return res;
end

function gauss(func::Function, a::Real, b::Real; tol=1e-5, verbose=false)::Float64
    n = 2
    while true
        res = gauss(func, a, b, n);
        res1 = gauss(func, a, b, n * 2);

        if abs(res1 - res) < tol
            if verbose == true
                print("n iter: $(n*2)\n")
            end
            return res1
        end

        n *= 2;
    end
end

export gauss
#end module
end

max_stars_repo_name: aurelio-amerio/corso-cpp


text:
test = """
    1-3 a: abcde
    1-3 b: cdefg
    2-9 c: ccccccccc
    """

function policy(spec::AbstractString)::Tuple{Int, Int, Char, String}
    (a, b, chr, pwd) = split(spec, r"[- :]+")
    return (parse.(Int, (a, b))..., only(chr), pwd)
end

q1((min, max, chr, pwd)) = min <= count(==(chr), pwd) <= max
q2((a, b, chr, pwd)) = count(==(chr), pwd[[a, b]]) == 1

let policies = IOBuffer(test) |> readlines .|> policy
    @assert count(q1, policies) == 2
    @assert count(q2, policies) == 1
end

policies = readlines("day02.in") .|> policy
println("Q1: ", count(q1, policies))
println("Q2: ", count(q2, policies))

max_stars_repo_name: dhanak/competitive-coding

max_issues_repo_name: dhanak/competitive-coding

max_forks_repo_name: dhanak/competitive-coding


text:
isdefined(Base, :__precompile__) && __precompile__()

module PowerModelsACDC

# using Compat
using JuMP
using PowerModels
using InfrastructureModels
using Memento

# import Compat: @__MODULE__

# using Compat.LinearAlgebra
# using Compat.SparseArrays
#
# PMs = PowerModels

import JuMP: with_optimizer
export with_optimizer

include("prob/acdcopf.jl")
include("prob/acdcpf.jl")
include("prob/acdcopf_bf.jl")
include("core/solution.jl")
include("core/data.jl")
include("core/variabledcgrid.jl")
include("core/variableconv.jl")
include("core/base.jl")
include("core/constraint.jl")
include("core/objective.jl")
include("core/relaxation_scheme.jl")

include("formdcgrid/acp.jl")
include("formdcgrid/dcp.jl")
include("formdcgrid/wr.jl")
include("formdcgrid/wrm.jl")
include("formdcgrid/bf.jl")
include("formdcgrid/lpac.jl")
include("formdcgrid/shared.jl")

include("formconv/acp.jl")
include("formconv/dcp.jl")
include("formconv/wr.jl")
include("formconv/wrm.jl")
include("formconv/bf.jl")
include("formconv/lpac.jl")
include("formconv/shared.jl")

include("core/constraint_template.jl")
end


text:
# Isomap
# ------
# A Global Geometric Framework for Nonlinear Dimensionality Reduction,
# J. B. Tenenbaum, V. de Silva and J. C. Langford, Science 290 (5500): 2319-2323, 22 December 2000

#### Isomap type
struct Isomap{T <: AbstractFloat} <: SpectralResult
    k::Int
    proj::Projection{T}
    component::AbstractVector{Int}

    Isomap{T}(k::Int, proj::Projection{T})  where T = new(k, proj)
    Isomap{T}(k::Int, proj::Projection{T}, cc::AbstractVector{Int})  where T = new(k, proj, cc)
end

## properties
outdim(M::Isomap) = size(M.proj, 1)
projection(M::Isomap) = M.proj

neighbors(M::Isomap) = M.k
ccomponent(M::Isomap) = M.component

## show & dump
function show(io::IO, M::Isomap)
    print(io, "Isomap(outdim = $(outdim(M)), neighbors = $(neighbors(M)))")
end

function dump(io::IO, M::Isomap)
    show(io, M)
    # try # Print largest connected component
    #     lcc = ccomponent(M)
    #     println(io, "connected component: ")
    #     Base.showarray(io, transpose(lcc), header=false, repr=false)
    #     println(io)
    # end
    println(io, "eigenvalues: ")
    Base.showarray(io, transpose(M.λ), header=false, repr=false)
    println(io)
    println(io, "projection:")
    Base.showarray(io, M.proj, header=false, repr=false)
end

## interface functions
function transform(::Type{Isomap}, X::DenseMatrix{T};
                   k::Int=12, d::Int=2) where T <: AbstractFloat
    # Construct NN graph
    D, E = find_nn(X, k, excluding=true)

    # Select largest connected component
    CC = components(E)
    if length(CC) == 1
        C = CC[1]
        Dc = D
        Ec = E
    else
        C = CC[argmax(map(size, CC))]
        Dc = D[:,C]

        # renumber edges
        R = Dict(zip(C, 1:length(C)))
        Ec = zeros(Int,k,length(C))
        for i = 1 : length(C)
            Ec[:,i] = map(i->get(R,i,0), E[:,C[i]])
        end
    end

    # Compute shortest path for every point
    n = size(Dc,2)
    DD = zeros(n, n)
    for i=1:n
        P, PD = dijkstra(Dc, Ec, i)
        DD[i,:] = PD
    end

    # Perform MDS
    Y = classical_mds(DD, d)

    return Isomap{T}(k, Y, C)
end


text:
if Sys.isapple()
    function _font_paths()
        [
            "/Library/Fonts", # Additional fonts that can be used by all users. This is generally where fonts go if they are to be used by other applications.
            joinpath(homedir(), "Library/Fonts"), # Fonts specific to each user.
            "/Network/Library/Fonts", # Fonts shared for users on a network
        ]
    end
elseif Sys.iswindows()
    _font_paths() = [joinpath(get(ENV, "SYSTEMROOT", "C:\\Windows"), "Fonts")]
else
    function add_recursive(result, path)
        for p in readdir(path)
            pabs = joinpath(path, p)
            if isdir(pabs)
                push!(result, pabs)
                add_recursive(result, pabs)
            end
        end
    end
    function _font_paths()
        result = String[]
	for p in ("/usr/share/fonts", joinpath(homedir(), ".fonts"), joinpath(homedir(), ".local/share/fonts"), "/usr/local/share/fonts",)
            if isdir(p)
                push!(result, p)
                add_recursive(result, p)
            end
        end
        result
    end
end

function family_name(x::FTFont)
    lowercase(x.family_name)
end

function style_name(x::FTFont)
    lowercase(x.style_name)
end

const REGULAR_STYLES = ("regular", "normal", "medium", "standard", "roman", "book")

"""
Match a font using the user-specified search string. Each part of the search string
is searched in the family name first which has to match once to include the font
in the candidate list. For fonts with a family match the style
name is matched next. For fonts with the same family and style name scores, regular
fonts are preferred (any font that is "regular", "normal", "medium", "standard" or "roman")
and as a last tie-breaker, shorter overall font names are preferred.

Example:

If we had only four fonts:
- Helvetica Italic
- Helvetica Regular
- Helvetica Neue Regular
- Helvetica Neue Light

Then this is how this function would match different search strings:
- "helvetica"           => Helvetica Regular
- "helv"                => Helvetica Regular
- "HeLvEtIcA"           => Helvetica Regular
- "helvetica italic"    => Helvetica Italic
- "helve ita"           => Helvetica Italic
- "helvetica neue"      => Helvetica Neue Regular
- "tica eue"            => Helvetica Neue Regular
- "helvetica light"     => Helvetica Neue Light
- "light"               => Helvetica Neue Light
- "helvetica bold"      => Helvetica Regular
- "helvetica neue bold" => Helvetica Neue Regular
- "times"               => no match
- "arial"               => no match
"""
function match_font(face::FTFont, searchparts)::Tuple{Int, Int, Bool, Int}

    fname = family_name(face)
    sname = style_name(face)
    is_regular_style = any(occursin(s, sname) for s in REGULAR_STYLES)

    fontlength_penalty = -(length(fname) + length(sname))

    family_matches = any(occursin(part, fname) for part in searchparts)

    # return early if family name doesn't have a match
    family_matches || return (0, 0, is_regular_style, fontlength_penalty)

    family_score = sum(length(part) for part in searchparts if occursin(part, fname))

    # now enhance the score with style information
    remaining_parts = filter(part -> !occursin(part, fname), searchparts)

    if isempty(remaining_parts)
        return (family_score, 0, is_regular_style, fontlength_penalty)
    end

    # check if any parts match the style name, otherwise return early
    if !any(occursin(part, sname) for part in remaining_parts)
        return (family_score, 0, is_regular_style, fontlength_penalty)
    end

    style_score = sum(length(part) for part in remaining_parts if occursin(part, sname))

    (family_score, style_score, is_regular_style, fontlength_penalty)
end

function try_load(fpath)
    try
        return FTFont(fpath)
    catch e
        return nothing
    end
end

fontname(ft::FTFont) = "$(family_name(ft)) $(style_name(ft))"

function findfont(
        searchstring::String;
        italic::Bool=false, # this is unused in the new implementation
        bold::Bool=false, # and this as well
        additional_fonts::String=""
    )
    font_folders = copy(fontpaths())

    isempty(additional_fonts) || pushfirst!(font_folders, additional_fonts)

    # \W splits at all groups of non-word characters (like space, -, ., etc)
    searchparts = unique(split(lowercase(searchstring), r"\W+", keepempty=false))

    candidates = Pair{FTFont, Tuple{Int, Int}}[]

    best_score_so_far = (0, 0, false, typemin(Int))
    best_font = nothing

    for folder in font_folders
        for font in readdir(folder)
            fpath = joinpath(folder, font)
            face = try_load(fpath)
            face === nothing && continue

            score = match_font(face, searchparts)

            # we can compare all four tuple elements of the score at once
            # in order of importance:

            # 1. number of family match characters
            # 2. number of style match characters
            # 3. is font a "regular" style variant?
            # 4. the negative length of the font name, the shorter the better

            family_match_score = score[1]
            if family_match_score > 0 && score > best_score_so_far
                # finalize previous best font to close the font file
                if !isnothing(best_font)
                    finalize(best_font)
                end

                # new candidate
                best_font = face
                best_score_so_far = score
            else
                finalize(face)
            end
        end
    end

    best_font
end


text:
@testset "Chaining and Piping" begin
    # `orig` should never be imputed as it is used as a reference for checking that the
    # `data` isn't being mutated below
    orig = Impute.dataset("test/table/neuro") |> DataFrame
    data = deepcopy(orig)

    @testset "DataFrame" begin
        # Less effecient, but a chain should produce the same results as manual
        # piping the functional outputs.
        result = Impute.interp(data) |> Impute.locf! |> Impute.nocb!

        @test size(result) == size(orig)
        # Confirm that we don't have any more missing values
        @test all(!ismissing, Matrix(result))
        # Test we haven't mutated the data
        @test isequal(orig, data)

        # We can also use the Chain type with explicit Imputor types
        C = Impute.Interpolate() ∘ Impute.LOCF() ∘ Impute.NOCB()
        result2 = C(data)
        @test result == result2
        # Test we haven't mutated the data
        @test isequal(orig, data)

        @testset "GroupedDataFrame" begin
            T = NamedTuple{(:hod, :obj, :val), Tuple{Int, Int, Union{Float64, Missing}}}

            df = map(Iterators.product(1:24, 1:8, 0:19)) do t
                hod, obj, x = t
                # Deterministically return some `missing`s per hod/obj pair
                return if x in (0, 5, 12, 19)
                    T((hod, obj, missing))
                else
                    T((hod, obj, sin(hod) * cos(x) + obj))
                end
            end |> DataFrame

            gdf1 = groupby(deepcopy(df), [:hod, :obj])
            gdf2 = groupby(df, [:hod, :obj])

            C = Impute.Interpolate() ∘ Impute.LOCF() ∘ Impute.NOCB()

            result = mapreduce(C, vcat, gdf1)
            # Check that the result isn't the same as the source dataframe
            @test df != result
            # Check that the size is still the same since we didn't drop any rows
            @test size(result) == size(df)
            # Check that there are no remaining missing values
            @test all(!ismissing, Tables.matrix(result))
            # Double check that our source dataframe still contains missings
            @test any(ismissing, Tables.matrix(df))
        end
    end

    @testset "Column Table" begin
        result = Tables.columntable(data) |>
            Impute.interp |>
            Impute.locf! |>
            Impute.nocb! |>
            Tables.matrix

        @test size(result) == size(orig)
        # Confirm that we don't have any more missing values
        @test all(!ismissing, result)
        # Test we haven't mutated the data
        @test isequal(orig, data)
    end

    @testset "Row Table" begin
        result = Tables.rowtable(data) |>
            Impute.interp |>
            Impute.locf! |>
            Impute.nocb! |>
            Tables.matrix

        @test size(result) == size(orig)
        # Confirm that we don't have any more missing values
        @test all(!ismissing, result)
        # Test we haven't mutated the data
        @test isequal(orig, data)
    end

    @testset "Matrix" begin
        input = Matrix(data)
        C = Impute.Interpolate() ∘ Impute.LOCF() ∘ Impute.NOCB()
        result = C(input; dims=:cols)

        @test size(result) == size(input)
        # Confirm that we don't have any more missing values
        @test all(!ismissing, result)
        # Test we haven't mutated the data
        @test isequal(orig, data)
    end

    @testset "AxisArray" begin
        input = AxisArray(
            Matrix(orig),
            Axis{:row}(1:size(orig, 1)),
            Axis{:V}(names(orig)),
        )
        C = Impute.Interpolate() ∘ Impute.LOCF() ∘ Impute.NOCB()
        result = C(input; dims=:cols)

        @test size(result) == size(input)
        # Confirm that we don't have any more missing values
        @test all(!ismissing, result)
        # Test we haven't mutated the data
        @test isequal(orig, data)
    end

    @testset "KeyedArray" begin
        input = KeyedArray(Matrix(orig); row=1:size(orig, 1), V=names(orig))
        C = Impute.Interpolate() ∘ Impute.LOCF() ∘ Impute.NOCB()
        result = C(input; dims=:cols)

        @test size(result) == size(input)
        # Confirm that we don't have any more missing values
        @test all(!ismissing, result)
        # Test we haven't mutated the data
        @test isequal(orig, data)
    end

    @testset "Multi-type" begin
        input = Tables.matrix(data)
        @test any(ismissing, input)
        # Filter out colunns with more than 400 missing values, Fill with 0, and check that
        # everything was replaced
        C = Chain(
            Impute.DeclareMissings(; values=(NaN, Inf, -Inf)),
            Impute.Filter(c -> count(ismissing, c) < 400),
            Impute.Replace(; values=0.0),
            Impute.Threshold(),
        )

        result = C(input; dims=:cols)
        @test size(result, 1) == size(input, 1)
        # We should have filtered out 1 column
        @test size(result, 2) < size(input, 2)
        @test all(!ismissing, result)
        # Test we haven't mutated the data
        @test isequal(orig, data)
    end
end


text:
########## Cave ##########

mutable struct Cave
    name::String
    is_big::Bool
    connections::Vector{Cave}
    n_visits::Int
end
name(cave::Cave) = cave.name
is_big(cave) = cave.is_big
connections(cave::Cave) = cave.connections
n_visits(cave::Cave) = cave.n_visits

Cave(name::String) = Cave(name, isuppercase(name[1]), Cave[], 0)

visit!(cave::Cave) = cave.n_visits += 1

cancel_visit!(cave::Cave) = cave.n_visits -= 1

valid_connections(cave::Cave, n_visits_allowed_if_small_cave::Int)::Vector{Cave} =
    [connected_cave for connected_cave in connections(cave)
    if is_big(connected_cave) || n_visits(connected_cave) < n_visits_allowed_if_small_cave]

########## functions ##########

function find(caves::Vector{Cave}, ref_name::String)::Union{Cave, Missing}
    for cave in caves
        name(cave) == ref_name && return cave
    end
    return missing
end

function add_cave!(caves::Vector{Cave}, name::String)::Cave
    cave = find(caves, name)
    if ismissing(cave)
        cave = Cave(name)
        append!(caves, [cave])
    end
    return cave
end

function add_path!(caves::Vector{Cave}, entry::String)
    name1, name2 = String.(split(entry, "-"))
    cave1 = add_cave!(caves, name1)
    cave2 = add_cave!(caves, name2)
    append!(connections(cave1), [cave2])
    append!(connections(cave2), [cave1])
end

function try_paths!(caves::Vector{Cave}, allow_two_visits_in_a_single_small_cave::Bool)::Int
    # constants
    start_cave = find(caves, "start")
    visit!(start_cave)
    end_cave = find(caves, "end")

    # part 1 vs part 2
    allow_two_visits_in_a_single_small_cave ?
        n_visits_allowed_in_small_caves = 2 :
        n_visits_allowed_in_small_caves = 1
    special_small_cave = nothing

    # init complete current path, un-tried caves state and next caves
    n_paths = 0
    path = [start_cave]
    visit!(path[end])
    next_caves = valid_connections(path[end], n_visits_allowed_in_small_caves)
    tries = [length(next_caves)]

    # step forward and back in caves until all possible paths have been tried
    while !(path[end] == start_cave && tries[end] == 0)

        # end or dead-end case => step back to previous path state (end => add 1 to n_paths)
        if path[end] == end_cave || tries[end] == 0

            if path[end] == end_cave
                n_paths += 1
            end

            # erase every recordings since that point in time
            cancel_visit!(path[end])
            pop!(tries)
            if pop!(path) == special_small_cave
                special_small_cave = nothing
                n_visits_allowed_in_small_caves = 2
            end

            # possible next caves (regardless od the current tries state)
            next_caves = valid_connections(path[end], n_visits_allowed_in_small_caves)

        # normal case => step forward in the next un-tried possible cave for the current complete path state (tries)
        else

            append!(path, [next_caves[tries[end]]])
            visit!(path[end])
            if allow_two_visits_in_a_single_small_cave && !is_big(path[end]) && path[end] in path[1:(end - 1)]
                special_small_cave = path[end]
                n_visits_allowed_in_small_caves = 1
            end

            # mark current cave as already tried for the complete path previous state
            tries[end] -= 1

            # possible next caves (regardless od the current tries state)
            next_caves = valid_connections(path[end], n_visits_allowed_in_small_caves)

            # setup a new state of un-tried caves for the complete path
            append!(tries, [length(next_caves)])

        end
    end

    return n_paths
end

########## Script ##########

function main(input_name::String)

    # open file and store content into an input string
    input = open(join(["inputs//", input_name]), "r") do io
        read(io, String)
    end

    # split input into a data vector
    data = String.(split(input, "\r\n"))

    # use data to generate a vector of all caves
    caves = Cave[]
    for entry in data
        add_path!(caves, entry)
    end

    # part 1
    println("Part 1: ", try_paths!(caves, false))
    # part 2
    println("Part 2: ", try_paths!(caves, true))

end

main("day12.txt");


text:
# Solve the KS equation over a short period, then check against high-order solution

include("kuramoto-sivashinsky.jl")
using .kuramoto_sivashinsky

# define integrand functions needed for time averages
function ident(val)
    return val
end
function square(val)
    return val*val
end

function Print3DArray(file, arr::AbstractArray{Float64,3})
    for i = 1:size(arr,1)
        for j = 1:size(arr,2)
            for k = 1:size(arr,3)
                print(file, arr[i,j,k], " ")
            end
            println(file)
        end
    end
end

# set the parameters
tp = Float64            # floating point type to use
#num_nodes = 255         # number of (interior) nodes to use
#num_steps = 5000        # number of time steps to use
Lx = convert(tp, 128)   # domain size
#order = 2               # order of accuracy
Time = convert(tp, 5) # time period for simulation

#-------------------------------------------------------------------------------
# first, obtain the high-order benchmark solution
num_nodes = 1023 # 511 # <-- used for verification
order = 8
num_steps = 20000

# set initial condition and set-up the KSData structure
dx = Lx/(num_nodes+1)
x = Array{tp}(dx:dx:Lx-dx)
#u = sin.(8*pi*x/128).^2
u = exp.(x/128).*sin.(16*pi*x/128).^2
#u = exp.(-((x-64).^2)./512)
ks = kuramoto_sivashinsky.buildKSData(order, num_nodes, tp)

# solve the problem and get the time averages
sol = kuramoto_sivashinsky.solveUsingMidpoint(ks, Time, num_steps, u)
u_avg_ref = kuramoto_sivashinsky.calcSolutionAverage(order, sol, ident)
u2_avg_ref = kuramoto_sivashinsky.calcSolutionAverage(order, sol, square)
println("u averaged = ", u_avg_ref)
println("u^2 averaged = ", u2_avg_ref)

# output to file for plotting
file = open("verify_ks_solution.dat", "w")
for n = 1:num_steps+1
    for val in sol[:,n]
        print(file, val, " ")
    end
    println(file)
end
close(file)

order = [2, 4, 6]  # [2, 4, 8, 16]
num_nodes = Array{Int}(64:64:512) .- 1   # [63, 127, 255, 511] #    Array{Int}(64:16:256) - 1 #    [63, 127, 255, 511]
num_steps = [250, 500, 1000]

dx = zeros(Float64, (size(order,1), size(num_nodes,1), size(num_steps,1)))
dt = zeros(size(dx))
err_avg = zeros(size(dx))
err_sqavg = zeros(size(dx))
cputime = zeros(size(dx))

for k = 1:size(num_steps,1)
    for n = 1:size(num_nodes,1)
        for p = 1:size(order,1)
             # set initial condition and set-up the KSData structure
            dx[p,n,k] = Lx/(num_nodes[n]+1)
            dt[p,n,k] = Time/num_steps[k]
            local x = Array{tp}(dx[p,n,k]:dx[p,n,k]:Lx-dx[p,n,k])
            #u = sin.(8*pi*x/128).^2
            local u = exp.(x/128).*sin.(16*pi*x/128).^2
            local ks = kuramoto_sivashinsky.buildKSData(order[p], num_nodes[n], tp)
            # solve the problem and get the time averages
            cputime[p,n,k] = @elapsed begin
                local sol = kuramoto_sivashinsky.solveUsingMidpoint(ks, Time,
                                                              num_steps[k], u)
            end
            u_avg = kuramoto_sivashinsky.calcSolutionAverage(order[p], sol,
                                                             ident)
            u2_avg = kuramoto_sivashinsky.calcSolutionAverage(order[p], sol,
                                                              square)
            err_avg[p,n,k] = abs(u_avg - u_avg_ref)/abs(u_avg_ref)
            err_sqavg[p,n,k] = abs(u2_avg - u2_avg_ref)/abs(u2_avg_ref)
        end
    end
end

# write the data
data = open("accuracy_ks.dat", "w")
Print3DArray(data, dx)
Print3DArray(data, dt)
Print3DArray(data, err_avg)
Print3DArray(data, err_sqavg)
Print3DArray(data, cputime)
close(data)

max_stars_repo_name: jehicken/high-order-and-chaos

max_issues_repo_name: jehicken/high-order-and-chaos

max_forks_repo_name: jehicken/high-order-and-chaos


text:
using Test

examples_dir = joinpath(@__DIR__, "..", "examples")
@assert ispath(examples_dir)
example_filenames = readdir(examples_dir)
@assert "ft01_poisson.jl" in example_filenames

@testset "$(filename)" for filename in example_filenames
    path = joinpath(examples_dir, filename)
    @test (include(path) ;true)
end


text:
quad_params = (m=0.5,
             J=SMatrix{3,3}(Diagonal([0.0023, 0.0023, 0.004])),
             Jinv=SMatrix{3,3}(Diagonal(1.0./[0.0023, 0.0023, 0.004])),
             gravity=SVector(0,0,-9.81),
             motor_dist=0.1750,
             kf=1.0,
             km=0.0245)

include("quaternions.jl")
function quadrotor_dynamics!(ẋ::AbstractVector,x::AbstractVector,u::AbstractVector,params) where T
      #TODO change concatentations to make faster!
      # Quaternion representation
      # Modified from D. Mellinger, N. Michael, and V. Kumar,
      # "Trajectory generation and control for precise aggressive maneuvers with quadrotors",
      # In Proceedings of the 12th International Symposium on Experimental Robotics (ISER 2010), 2010.

      ## States: X ∈ R^13; q = [s;v]
      # x
      # y
      # z
      # q0
      # q1
      # q2
      # q3
      # xdot
      # ydot
      # zdot
      # omega1
      # omega2
      # omega3

      # x = X[1:3]
      q = normalize(Quaternion(view(x,4:7)))
      # q = view(x,4:7)
      # normalize!(q)
      v = view(x,8:10)
      omega = view(x,11:13)

      # Parameters
      m = params[:m] # mass
      J = params[:J] # inertia matrix
      Jinv = params[:Jinv] # inverted inertia matrix
      g = params[:gravity] # gravity
      L = params[:motor_dist] # distance between motors

      w1 = u[1]
      w2 = u[2]
      w3 = u[3]
      w4 = u[4]

      kf = params[:kf]; # 6.11*10^-8;
      F1 = kf*w1;
      F2 = kf*w2;
      F3 = kf*w3;
      F4 = kf*w4;
      F = @SVector [0., 0., F1+F2+F3+F4] #total rotor force in body frame

      km = params[:km]
      M1 = km*w1;
      M2 = km*w2;
      M3 = km*w3;
      M4 = km*w4;
      tau = @SVector [L*(F2-F4), L*(F3-F1), (M1-M2+M3-M4)] #total rotor torque in body frame

      ẋ[1:3] = v # velocity in world frame
      # ẋ[4:7] = 0.5*qmult(q,[0;omega]) #quaternion derivative
      ẋ[4:7] = SVector(0.5*q*Quaternion(zero(x[1]), omega...))
      ẋ[8:10] = g + (1/m)*(q*F) #acceleration in world frame
      ẋ[11:13] = Jinv*(tau - cross(omega,J*omega)) #Euler's equation: I*ω + ω x I*ω = constraint_decrease_ratio
      return tau, omega, J, Jinv
end

quadrotor = Model(quadrotor_dynamics!, 13, 4, quad_params)

max_issues_repo_name: MehrdadZareian/GMARA

max_forks_repo_name: MehrdadZareian/GMARA


text:
###
### Janzen-Connell Model
### (c) Daniel Vedder, MIT license
###

"""
A cons cell to implement a double linked list for the forest
(Boy, do I miss Lisp :-/ )
"""
mutable struct Cons
    car::Union{Tree,Nothing}   # The Tree object held by this cell
    cdr::Union{Cons,Nothing}   # A pointer to the next cell down the line
    prev::Union{Cons,Nothing}  # A pointer to the previous cell
end

# The first cons cells in the forest list, and the number of trees
const forest = Cons(nothing,nothing,nothing)
forestlen = 0 #XXX do I actually need this?

"""
Insert a new tree object at the correct position in the forest list.
(Sorted by ascending x values.)
"""
function planttree!(tree::Tree,cons::Cons=forest)
    #FIXME sometimes doesn't insert trees into the forest list
    # (at least when called from initworld()
    while cons != nothing
        if !isa(cons.car, Tree)
            # If we have an empty cons cell, plant the tree here
            cons.car = tree
            global forestlen += 1
            @debug "Planted tree $(tree.uid) @$(tree.position.x)/$(tree.position.y)"
            return
        elseif tree.position.x < cons.car.position.x
            # If the next tree in the list is further east, insert a new cons cell
            if cons.prev != nothing #inserting in the middle
                newcons = Cons(tree,cons,cons.prev)
                cons.prev.cdr = newcons
                cons.prev = newcons
            else #if we're inserting before the first cell
                newcons = Cons(cons.car, cons.cdr, cons)
                cons.car = tree
                cons.cdr = newcons
            end
            global forestlen += 1
            @debug "Planted tree $(tree.uid) @$(tree.position.x)/$(tree.position.y)"
            return
        elseif cons.cdr == nothing
            # If we're at the end of the list, append a new cons cell
            cons.cdr = Cons(nothing,nothing,cons)
        end
        cons = cons.cdr
    end
end

"""
Remove a tree from the forest list.
(Don't let Idefix see this function :D )
"""
function killtree!(tree::Tree,cons::Cons=forest,reason::String="malice aforethought")
    while cons != nothing
        if cons.car == tree
            if cons.prev != nothing #excise a cons cell from the list
                cons.prev.cdr = cons.cdr
                cons.cdr != nothing && (cons.cdr.prev = cons.prev)
                cons = nothing
            else
                #removing the first tree is a bit more tricky, because the
                #first cons cell (global variable `forest`) mustn't be deleted
                if cons.cdr != nothing
                    cons.car = cons.cdr.car
                    cons.cdr.cdr != nothing && (cons.cdr.cdr.prev = cons)
                    cons.cdr = cons.cdr.cdr
                else
                    cons.car = nothing
                end
            end
            #cleanup and decrease the tree count
            global forestlen -= 1
            @debug "Killed tree $(tree.uid) @$(tree.position.x)/$(tree.position.y) because of $(reason)"
            tree = nothing
            return
        end
        cons = cons.cdr
    end
    @warn "Attempted to remove nonexistent tree."
end

"""
Produce seeds and disperse them in the landscape, planting them where possible
"""
function disperse!(cons::Cons=forest)
    i::Int16 = 1
    while cons != nothing
        tree = cons.car
        if !tree.mature
            i += 1
            cons = cons.cdr
            continue
        end
        @debug "Reproducing tree $(tree.uid)"
        dx = tree.species.dispersal_distance
        # Each tree produces multiple seeds
        for s in 1:tree.species.seed_production
            #TODO implement a proper dispersal kernel
            # Find a random location in a circle around the tree
            sx = tree.position.x + rand(-dx:dx)
            #FIXME sqrt() was called with an argument of -32768.0?
            # (only happens in scenarios with variance?)
            dy = convert(Int16, round(sqrt(abs(dx^2-(sx-tree.position.x)^2))))
            sy = tree.position.y + rand(-dy:dy)
            if sx >= -settings["worldsize"] && sx <= settings["worldsize"] &&
                sy >= -settings["worldsize"] && sy <= settings["worldsize"]
                seed = Tree(tree.species, sx, sy)
                planttree!(seed)
            end
        end
        i += 1
        cons = cons.cdr
    end
end

"""
Test whether the trees in two cons cells intersect, and if so, kill the
smaller tree. The integer return value indicates the outcome:
0 - no intersection (no tree killed)
1 - the first tree is larger (second tree killed)
2 - the second tree is larger (first tree killed)
Needed by `compete_individual!()`
"""
function compete_pair!(cons1::Cons, cons2::Cons)::UInt8
    tree1 = cons1.car
    tree2 = cons2.car
    (tree1 == nothing || tree2 == nothing) && return
    mindist = (tree1.size + tree2.size)/2
    dx = abs(tree1.position.x - tree2.position.x)
    dy = abs(tree1.position.y - tree2.position.y)
    if  dx >= mindist || dy >= mindist || hypot(dx,dy) >= mindist
        return 0
    elseif tree1.size > tree2.size
        killtree!(tree2, cons2, "competition")
        return 1
    else
        killtree!(tree1, cons1, "competition")
        return 2
    end
end

"""
Check whether the tree in this cons cell conflicts with trees in the
vicinity and, if so, kill the smaller one.
Needed by `compete!()`
"""
function compete_individual!(cons::Cons)
    tree = cons.car
    # go right until we're sure we won't find any more conflicts
    next = cons.cdr
    while next != nothing && abs(next.car.position.x - tree.position.x) < (tree.size/2)+2^7
        next2 = next.cdr # We have to save the coming step already, in case `next` is killed
        conflict = compete_pair!(cons, next)
        if conflict == 2
            return # This tree was killed, so we can break off
        else # otherwise, keep going
            next = next2
        end
    end
    # then go left and repeat
    next = cons.prev
    while next != nothing && abs(next.car.position.x - tree.position.x) < (tree.size/2)+2^7
        next2 = next.prev
        conflict = compete_pair!(cons, next)
        if conflict == 2
            return
        else
            next = next2
        end
    end
end

"""
Go through the landscape and check each tree for space conflicts
"""
function compete!(cons::Cons=forest)
    while cons != nothing
        compete_individual!(cons)
        cons = cons.cdr
    end
end

"""
All saplings grow until they reach maturity, then eventually die of old age.
"""
function grow!(cons::Cons=forest)
    while cons != nothing
        tree = cons.car
        next = cons.cdr
        if !tree.mature
            tree.size += tree.species.growth_rate
            tree.size >= tree.species.max_size && (tree.mature = true)
        elseif tree.age >= tree.species.max_age
            killtree!(tree, cons, "old age")
            cons = next
            continue
        end
        tree.age += 1
        cons = next
        recordindividual(tree)
    end
end

"""
An infected tree in the given cons cell spreads its infection
"""
function spread_infection(cons::Cons)
    tree = cons.car
    pathogen = tree.infection
    maxdist = pathogen.infection_radius
    # go right until we're sure we're out of the infection range
    next = cons.cdr
    while next != nothing && abs(next.car.position.x - tree.position.x) < maxdist
        tree2 = next.car
        dist = hypot(abs(tree.position.x-tree2.position.x),
                     abs(tree.position.y-tree2.position.y))
        prob = (pathogen.infection_rate-tree2.species.pathogen_resistance)*((maxdist-dist)/maxdist)
        #A tree is infected if...
        if dist <= maxdist && #... it's within range
            tree2.infection == nothing && #... it isn't infected anyway
            tree2.species.id == tree.species.id && #... it belongs to the same species
            prob > rand(Float16) #... it passes a random draw dependent on its resistance and distance
            tree2.infection = Pathogen(pathogen.host)
            @debug "Infected tree $(tree.uid) @$(tree2.position.x)/$(tree2.position.y)"
        end
        next = next.cdr
    end
    # then go left and repeat
    next = cons.prev
    while next != nothing && abs(next.car.position.x - tree.position.x) < maxdist
        tree2 = next.car
        dist = hypot(abs(tree.position.x-tree2.position.x),
                     abs(tree.position.y-tree2.position.y))
        prob = (pathogen.infection_rate-tree2.species.pathogen_resistance)*((maxdist-dist)/maxdist)
        if dist <= maxdist &&
            tree2.infection == nothing &&
            tree2.species.id == tree.species.id &&
            prob > rand(Float16)
            tree2.infection = Pathogen(pathogen.host)
            @debug "Infected tree $(tree.uid) @$(tree2.position.x)/$(tree2.position.y)"
        end
        next = next.prev
    end
end

"""
Carry out the pathogen spread phase and check for mortality
"""
function infect!(cons::Cons=forest)
    while cons != nothing
        tree = cons.car
        next = cons.cdr
        if tree.infection != nothing
            pathogen = tree.infection
            # pathogens have a one-update incubation period
            pathogen.infectious ? spread_infection(cons) : pathogen.infectious = true
            if pathogen.lethality > rand(Float16)
                killtree!(tree, cons, "disease")
            end
        end
        cons = next
    end
end

max_stars_repo_name: veddox/jcm

max_issues_repo_name: veddox/jcm

max_forks_repo_name: veddox/jcm


text:
using DrWatson, Test
cd(@__DIR__)
T = 1000
N = 50 # spatial extent
Δt = 0.05 # resolution of integration
every = 10
seed = 1111

simulation = @ntuple T N Δt every seed

function f(simulation)
    @test typeof(simulation.T) <: Real
    a = rand(10); b = [rand(10) for _ in 1:10]
    return @strdict a b simulation
end

################################################################################
#                                 tagsave                                      #
################################################################################
t = f(simulation)
tagsave(savename(simulation, "bson"), t, gitpath=findproject())
file = load(savename(simulation, "bson"))
@test "gitcommit" ∈ keys(file)
@test file["gitcommit"] |> typeof == String
rm(savename(simulation, "bson"))

t = f(simulation)
@tagsave(savename(simulation, "bson"), t, safe=false, gitpath=findproject())
file = load(savename(simulation, "bson"))
@test "gitcommit" ∈ keys(file)
@test file["gitcommit"] |> typeof == String
@test "script" ∈ keys(file)
@test file["script"] |> typeof == String
@test file["script"] == joinpath("test", "savefiles_tests.jl#29")

t = f(simulation)
@tagsave(savename(simulation, "bson"), t, safe=true, gitpath=findproject())
sn = savename(simulation, "bson")[1:end-5]*"_#1"*".bson"
@test isfile(sn)
rm(sn)

t = f(simulation)
tagsave(savename(simulation, "bson"), t, safe=true, gitpath=findproject())
sn = savename(simulation, "bson")[1:end-5]*"_#1"*".bson"
@test isfile(sn)
rm(sn)

t = f(simulation)
t["gitcommit"] = ""
@test @tagsave(savename(simulation, "bson"), t, safe=true, gitpath=findproject())["gitcommit"] == ""
@test isfile(sn)
rm(sn)
@test @tagsave(savename(simulation, "bson"), t, safe=true, force=true, gitpath=findproject())["gitcommit"] != ""
@test isfile(sn)
rm(sn)

rm(savename(simulation, "bson"))
@test !isfile(savename(simulation, "bson"))

ex = @macroexpand @tagsave("testname.bson", (@dict a b c ), storepatch=false; safe=true)
ex2 = @macroexpand @tagsave("testname.bson", @dict a b c; storepatch=false, safe=true)
@test ex.args[1:end-1] == ex2.args[1:end-1]

# Remove leftover

################################################################################
#                              produce or load                                 #
################################################################################
for ending ∈ ("bson", "jld2")
    @test !isfile(savename(simulation, ending))
    sim, path = produce_or_load(simulation, f; suffix = ending)
    @test isfile(savename(simulation, ending))
    @test sim["simulation"].T == T
    @test path == savename(simulation, ending)
    sim, path = produce_or_load(simulation, f; suffix = ending)
    @test sim["simulation"].T == T
    rm(savename(simulation, ending))
    @test !isfile(savename(simulation, ending))

    p = String(@__DIR__)
    pre = "pre"
    expected = joinpath(p, savename(pre, simulation, ending))
    @test !isfile(expected)
    sim, path = produce_or_load(p, simulation, f; suffix = ending, prefix = pre)
    @test path == expected
    @test isfile(path)
    rm(path)
end

@test produce_or_load(simulation, f; loadfile = false)[1] == nothing
rm(savename(simulation, "bson"))
@test !isfile(savename(simulation, "bson"))

################################################################################
#                          Backup files before saving                          #
################################################################################
filepath = "test.#backup.jld2"
data = [Dict( "a" => i, "b" => rand(rand(1:10))) for i = 1:3]
for i = 1:3
    safesave(filepath, data[i])
    @test data[i] == load(filepath)
end
@test data[2] == load("test.#backup_#1.jld2")
@test data[1] == load("test.#backup_#2.jld2")
@test data[3] == load("test.#backup.jld2")
rm("test.#backup.jld2")
rm("test.#backup_#1.jld2")
rm("test.#backup_#2.jld2")


text:
using GPLikelihoods
using AbstractGPs
using Test
using Random
using Functors
using Distributions
using StatsFuns

@testset "GPLikelihoods.jl" begin
    include("test_utils.jl")
    include("inverse.jl")
    include("links.jl")
    @testset "likelihoods" begin
        include("likelihoods/bernoulli.jl")
        include("likelihoods/categorical.jl")
        include("likelihoods/gaussian.jl")
        include("likelihoods/poisson.jl")
        include("likelihoods/gamma.jl")
        include("likelihoods/exponential.jl")
    end
end


text:
"""
Update pa.w
"""
function wfwi!(pa::Param; store_trace::Bool=true, extended_trace::Bool=false, time_limit=Float64=2.0*60.,
	       f_tol::Float64=1e-8, g_tol::Float64=1e-8, x_tol::Float64=1e-8)

	# convert initial model to the inversion variable
	x = zeros(wfwi_ninv(pa));
	last_x = rand(size(x)) # reset last_x

	println("updating w...")
	println("> wfwi: number of inversion variables:\t", length(x))

	# initial w to x
	Coupling_x!(x, pa, 1)

	(iszero(pa.paTD.y)) && error("dcal zero wfwi")

	f=x->func_grad_Coupling!(nothing, x,  pa)
	g! =(storage,x)->func_grad_Coupling!(storage, x,  pa)

	"""
	Unbounded LBFGS inversion, only for testing
	"""
	res = optimize(f, g!, x,
		       LBFGS(),
		       Optim.Options(g_tol = g_tol, f_tol=f_tol, x_tol=x_tol,
		       iterations = 1000, store_trace = store_trace,
		       extended_trace=extended_trace, show_trace = true))
	"testing gradient using auto-differentiation"
#	res = optimize(f, x,
#		       LBFGS(),
#		       Optim.Options(g_tol = 1e-12,
#	 	       iterations = 10, store_trace = true,
#		       extended_trace=true, show_trace = true))

	pa.verbose ? println(res) : nothing
	# update w in pa

	Coupling_x!(Optim.minimizer(res), pa, -1)

	f = Optim.minimum(res)
	return f
end # wfwi

#=

function xwfwi!(pa; max_roundtrips=100, max_reroundtrips=10, ParamAM_func=nothing, roundtrip_tol=1e-6,
		     optim_tols=[1e-6, 1e-6])

	if(ParamAM_func===nothing)
		ParamAM_func=x->ParamAM(x, optim_tols=optim_tols,name="FWI with Source Wavelet Estimation",
				    roundtrip_tol=roundtrip_tol, max_roundtrips=max_roundtrips,
				    max_reroundtrips=max_reroundtrips,
				    min_roundtrips=10,
				    reinit_func=x->initialize!(pa),
				    after_reroundtrip_func=x->(err!(pa); update_calsave!(pa);),
				    )
	end

	# create alternating minimization parameters
	f1=x->FWI.wfwi!(pa, extended_trace=false)
	f2=x->FWI.xfwi!(pa, extended_trace=false)
	paam=ParamAM_func([f1, f2])

	# do inversion
	go(paam)

	# print errors
	err!(pa)
	println(" ")
end

=#


text:
import Base.getindex, Base.setindex!, Base.length, Base.lastindex, Base.copy

struct Path
  tg::TimeGrid
  values::Vector{Float64}
  # TODO ensure values size is the same as tg size
end

Path(tg::TimeGrid) = Path(tg, Vector{Float64}(undef, length(tg.times)))

getindex(p::Path, i::Int) = p.values[i]
setindex!(p::Path, x::Float64, i::Int) = p.values[i] = x
length(p::Path) = length(p.tg.times)
lastindex(p::Path) = lastindex(p.values)

copy(p::Path) = Path(p.tg, copy(p.values))


text:
module Materials

using Images
using FileIO

using ..GfxBase

export Material, Texture
export ShadingModel, Flat, Normal
export PhysicalShadingModel, Lambertian, BlinnPhong

export get_diffuse

## Texture struct definition ##
mutable struct Texture
    image_data::Array{Vec3,2}
    repeat::Bool
end

""" Texture constructor - loads image data from a file"""
function Texture(image_fn::String, repeat::Bool)
    image_data = load(image_fn)
    Texture(image_data, repeat)
end

## Material struct definition ##
mutable struct Material
    mirror_coeff::Float32
    transparent_coeff::Float32
    diffuse_color::Union{Vec3,Nothing}
end

""" Get the diffuse Vec3 of a material; if the material is textured,
provide the uv coordinate on the object of that material. """
function get_diffuse(material::Material, uv::Union{Vec2,Nothing})
    material.diffuse_color
end

""" Look up a texture value given the uv coordinates """
function get_texture_value(texture::Texture, uv::Vec2)
    width, height = size(texture.image_data)
    texture.image_data[trunc(Int, (1 - uv[2]) * (height - 1)) + 1,
                       trunc(Int, uv[1] * (width - 1)) + 1]
end

end # module Materials

max_stars_repo_name: aedans/raytracer

max_issues_repo_name: aedans/raytracer

max_forks_repo_name: aedans/raytracer


text:
include("const.jl")
include("helpers.jl")


text:
export iauZpv
"""
**  Zero a pv-vector.
**
**  This function is part of the International Astronomical Union's
**  SOFA (Standards Of Fundamental Astronomy) software collection.
**
**  Status:  vector/matrix support function.
**
**  Returned:
**     pv       double[2][3]      pv-vector
**
**  Called:
**     iauZp        zero p-vector
**
**  This revision:  2013 June 18
**
**  SOFA release 2018-01-30
**
**  Copyright (C) 2018 IAU SOFA Board.  See notes at end.
"""

# void iauZpv(double pv[2][3])

function iauZpv()
   pv = zeros(Float64, 3, 2)

   ccall((:iauZpv, libsofa_c), Cvoid,
           (Ptr{Cdouble},),
           pv)

   # Transpose since C call return row-major operation
   return SMatrix{2,3}(pv')
end


text:
module ImPlot
import LibCImGui
for i in instances(LibCImGui.ImGuiCond_)
    @eval import LibCImGui: $(Symbol(i))
end
import LibCImGui: libcimgui

const ImPlotData = Union{Float32,Float64,Int8,UInt8,Int16,UInt16,Int32,UInt32,Int64,UInt64}

include("libcimplot.jl")

function BeginPlot(title_id::String, x_label = C_NULL, y_label = C_NULL, size::ImVec2 = ImVec2(-1,0);
                    flags = ImPlotFlags_None,
                    x_flags = ImPlotAxisFlags_None,
                    y_flags = ImPlotAxisFlags_None,
                    y2_flags = ImPlotAxisFlags_None,
                    y3_flags = ImPlotAxisFlags_None)::Bool

    BeginPlot(title_id, x_label, y_label, size,
                         flags, x_flags, y_flags, y2_flags, y3_flags)
end

include("constructors.jl")
include("lines.jl")
include("stairs.jl")
include("shaded.jl")
include("scatter.jl")
include("heatmap.jl")
include("digital.jl")
include("barchart.jl")
include("piechart.jl")
include("errorbars.jl")
include("stems.jl")
#include("other.jl")
include("util.jl")
#include("color.jl")
#include("styling.jl")

end # module


text:
struct Holtz end
struct Solei end

"""
    interval_merging(onset::BitVector, offset::BitVector)

Given two BitVectors signalling offsets and onsets, this function merges the two
to create one indicator signal.
"""
function interval_merging(onset::BitVector, offset::BitVector)
    out = falses(length(onset))
    if any(onset)
        for i in findall(onset)
            ind = findnext(offset, i)
            if !isnothing(ind)
                out[i:ind] .= true
            end
        end
    end
    return out
end

"""
    window_sizes(x::AbstractVector, w_max=300, thresh=100)

Function to calculate window sizes based on location of peaks in a combined PSM signal.

# Arguments:
 - `w_max=300` : Maximum window size.
 - `thresh=100` : Minimum peak magnitude threshold.
"""
function window_sizes(x::AbstractVector, w_max=300, thresh=100)
    windows = fill(w_max, length(x))
    inds = argmaxima(x, 20)
    filter!(i -> x[i] > thresh, inds)
    diffs = diff(inds)

    for i in 2:length(inds)-1
        val = min(diffs[i-1], w_max)
        new_w = @view windows[inds[i]:inds[i+1]]
        fill!(new_w, val)
    end
    return windows
end

"""
    move_detect(::Holtz, x::AbstractVector; kwargs...)

Implements movement detection from Identifying Movement Onset Times for a Bed-Based
Pressure Sensor Array - 2006, Holtzman.

# Arguments:
 - `L` : Length of window for moving moving_stats.
 - `κ` : Magnitude of the control signal.
 - `min_samples` : The minimum number of samples that a movement is allowed to be.

"""
function move_detect(::Holtz, x::AbstractVector; L=300, κ=3, min_samples=3)
    # Movement detection from Holtzman, 2006
    onset = falses(length(x))
    offset = falses(length(x))
    # Handle empty beds

    moving_avg, moving_var = moving_stats(x, L)
    mvar_diff = diff(moving_var) # diff([0; mvar]) optionally
    control = κ .* sqrt.(moving_var)

    ucl = moving_avg .+ control
    lcl = moving_avg .- control

    @views for i in 300:length(x)-(min_samples+1)
        val = x[i:i+min_samples-1]
        if all((val .< lcl[i:i+min_samples-1]) .| (val .> ucl[i:i+min_samples-1]))
            onset[i] = true
        end
    end

    # Flag offsets
    for i in findall(onset) # location of trues
        ind = findfirst(x -> x < 0.1, @view mvar_diff[i:end])
        !isnothing(ind) ? offset[i + ind] = true : nothing
    end

    return interval_merging(onset, offset)
end

function move_detect(x::AbstractMatrix; L=300, κ=3, min_samples=3)
    out = falses(size(x))
    if mean(occupancy_detection(x)) > 0.75
        for (i, col) in enumerate(eachcol(x))
        # Apply detection on each column/sensor
            out[:, i] = move_detect(Holtz(), col, L=L, κ=κ, min_samples=min_samples)
        end
    end
    return vec(sum(out, dims=2)) .>= 2
end

"""
    move_detect(::Solei, x::AbstractVector; kwargs...)

Implements movement detection from Movement Detection with Adaptive Window Length for
Unobtrusive Bed-based Pressure-Sensor Array - 2017, Soleimani

# Arguments:
 - `L` : Length of window for moving moving_stats.
 - `α=-0.029` : Threshold of first differences for the offset
 - `κ=3` : Magnitude of the control signal.
 - `min_samples=2` : The minimum number of samples that a movement is allowed to be.
 - `height=50` : Subject height in cm. Default to cancel out weight in ρ calculation.
 - `weight=50` : Subject weight in kg. Default to cancel out height in ρ calculation.

"""
function move_detect(::Solei, x::AbstractVector; α=-0.029, κ=3, min_samples=2, height=50, weight=50)
    # Movement detection from Soleimani, 2017
    # Expects reference sensor that is band-pass filtered
    # Set height and weight to 50 to ignore the last threshold
    onset = falses(length(x))
    offset = falses(length(x))

    windows = window_sizes(x)
    ρ = 3 * (weight + height - 100)
    moving_avg, moving_var = moving_stats(x, windows)
    control = κ .* sqrt.(moving_var)

    ucl = moving_avg .+ control
    ucl_diff = diff([0; ucl])
    lcl = moving_avg .- control

    @views for i in 300:length(x)-(min_samples+1)
        val = x[i:i+min_samples-1]
        if all((val .< lcl[i:i+min_samples-1]) .| (val .> ucl[i:i+min_samples-1]))
            onset[i] = true
        end
    end

#     Flag offsets
    @views for i in findall(onset) # location of trues
        for j in i:length(onset)-2
            if all(ucl_diff[j:j+2] .< α)
                offset[j] = true
                break
            end
        end
    end

    indicator = interval_merging(onset, offset)
    return indicator .& (moving_var .> ρ)
end

move_detect(x; kwargs...) = move_detect(Holtz(), x; kwargs...)


text:
module TestSeDuMi

using Test
using MathOptInterface
import SeDuMi

const MOI = MathOptInterface

function runtests()
    for name in names(@__MODULE__; all = true)
        if startswith("$(name)", "test_")
            @testset "$(name)" begin
                getfield(@__MODULE__, name)()
            end
        end
    end
    return
end

function test_solver_name()
    @test MOI.get(SeDuMi.Optimizer(), MOI.SolverName()) == "SeDuMi"
end

function test_runtests()
    model = MOI.instantiate(SeDuMi.Optimizer, with_bridge_type=Float64)
    MOI.set(model, MOI.Silent(), true)
    MOI.Test.runtests(
        model,
        MOI.Test.Config(
            rtol = 1e-4,
            atol = 1e-4,
            exclude = Any[
                MOI.ConstraintFunction, # The bridge does not implement this
                MOI.ConstraintBasisStatus,
                MOI.VariableBasisStatus,
                MOI.ConstraintName,
                MOI.VariableName,
                MOI.ObjectiveBound,
            ],
        ),
        exclude = String[
            # Expected test failures:
            #   ArgumentError: The number of constraints must be greater than 0
            "test_attribute_RawStatusString",
            "test_attribute_SolveTimeSec",
            "test_objective_ObjectiveFunction_blank",
            "test_solve_TerminationStatus_DUAL_INFEASIBLE",
            ##   Problem is a nonconvex QP
            "test_basic_ScalarQuadraticFunction_EqualTo",
            "test_basic_ScalarQuadraticFunction_GreaterThan",
            "test_basic_ScalarQuadraticFunction_Interval",
            "test_basic_VectorQuadraticFunction_",
            "test_quadratic_SecondOrderCone_basic",
            "test_quadratic_nonconvex_",
            ##   MathOptInterface.jl issue #1431
            "test_model_LowerBoundAlreadySet",
            "test_model_UpperBoundAlreadySet",
            # FIXME
            #  Expression: ≈(MOI.get(model, MOI.ConstraintPrimal(), c2), 0, atol = atol, rtol = rtol)
            #  Evaluated: 1.7999998823840366 ≈ 0 (atol=0.0001, rtol=0.0001)
            "test_linear_FEASIBILITY_SENSE",
            # FIXME
            #  Error using pretransfo (line 149)
            #  Size b mismatch
            "test_conic_SecondOrderCone_negative_post_bound_ii",
            "test_conic_SecondOrderCone_negative_post_bound_iii",
            "test_conic_SecondOrderCone_no_initial_bound",
            # TODO investigate
            "test_conic_GeometricMeanCone_VectorAffineFunction_2",
            "test_conic_GeometricMeanCone_VectorOfVariables_2",
        ],
    )
    return
end

end  # module

TestSeDuMi.runtests()


text:
module Niquita

str = "hello this is a string!"
str = 'hello this is a string!'
str = """hello this is a string!"""
str = '''hello this is a string!'''

type Point
  x::Float32
  y::Float32
  Point(x,y) = new(x,y)
end

x->begin
   c = A + B;
end

macro sayhello()
           return :( println("Hello, world!") )
end

ex = quote
           x = 1
           y = 2
           x + y
end

 if startswith(msg, "say:")
     println("EMITTING MESSAGE: $msg")
     for (k,v) in connections
         if k != client.id
             write(v, (usernames[client.id] * ": " * msg[5: end]))
         end
     end
 end

function makePoint(x::Float32, y::Float32)
    # this is a useless Function to make a Point
    point = Point(x,y)
    return point
end

struct Foo
           bar
           baz::Int
           qux::Float64
end
# package code goes here

if something
  c = a + b # Some coment
elseif somethingelse
  c = a * b
else
  c = a - b
end

end


text:
let
    parser = AnnotaionParser("$testdir/data/gene_association.goa_human")
    annots = Array(AnnotationRecord, 0)
    for annot in eachannot(parser)
        push!(annots, annot)
    end
    @test isa(annots[1], AnnotationRecord)
    @test string(annots[1]) == "AnnotationRecord(\"UniProtKB\", \"A0A183\", \"GO:0031424\")"
end


text:
function maximumpoly(poly::arb_poly,
                     (lower, upper)::Tuple{arb, arb};
                     absmax::Bool = false)
    x = setinterval(lower, upper)
    maybeabs = ifelse(absmax, abs, identity)

    # Enclose the zeros of the derivative of the polynomial
    deriv = derivative(poly)

    roots = isolateroots(deriv, lower, upper)[1]

    # Evaluate the polynomial on the zeros and the endpoints and take
    # the maximum
    m = max(maybeabs(evaluate(poly, lower)),
            maybeabs(evaluate(poly, upper)))

    # FIXME: If lower and upper are not tight then it can happen that
    # we find a root which is contained in x but not in the true
    # interval. If the maximum occurs at this root we would get wrong
    # results.
    for root in roots
        m = max(m,
                maybeabs(evaluate(poly, setinterval(root...))))
    end

    m
end


text:
using Base: @deprecate, depwarn

function ismocked(pe::PatchEnv, func_name::Symbol, args::Tuple)
    m = @__MODULE__
    depwarn("`$m.ismocked` is no longer used and can be safely removed.", :ismocked)
    return false
end

# Note: Very similar to using `@deprecate` but displays fully qualified function names
function enable(; force=false)
    m = @__MODULE__
    depwarn("`$m.enable(; force=$force)` is deprecated, use `$m.activate()` instead.", :enable)
    activate()
end