text:
using namespace std::string_view_literals;
using common::parser::ParserContext;
using common::parser::ContextReader;
using xziar::nailang::NailangParser;
using xziar::nailang::NailangParser;
using xziar::nailang::NailangParser;
using xziar::nailang::EmbedOps;
using xziar::nailang::SubQuery;
using xziar::nailang::LateBindVar;
using xziar::nailang::BinaryExpr;
using xziar::nailang::UnaryExpr;
using xziar::nailang::QueryExpr;
using xziar::nailang::FuncCall;
using xziar::nailang::Expr;
using xziar::nailang::Block;
using xziar::nailang::RawBlock;
using xziar::nailang::NilCheck;
using xziar::nailang::AssignExpr;

testing::AssertionResult CheckExpr(const Expr& arg, const Expr::Type type)
{
    if (arg.TypeData == type)
        return testing::AssertionSuccess();
    else
        return testing::AssertionFailure() << "rawarg is [" << WideToChar(arg.GetTypeName()) << "](" << common::enum_cast(arg.TypeData) << ")";
}

#define CHECK_DIRECT_ARG(target, type, val)             \
do                                                      \
{                                                       \
    ASSERT_TRUE(CheckExpr(target, Expr::Type::type));   \
    EXPECT_EQ(target.GetVar<Expr::Type::type>(), val);  \
} while(0)

#define CHECK_VAR_ARG(target, val, info)                    \
do                                                          \
{                                                           \
    ASSERT_TRUE(CheckExpr(target, Expr::Type::Var));        \
    const auto& _var = target.GetVar<Expr::Type::Var>();    \
    EXPECT_EQ(_var.Name, val);                              \
    EXPECT_EQ(_var.Info, LateBindVar::VarInfo::info);       \
} while(0)

#define CHECK_QUERY_SUBFIELD(r, x, i, name) CHECK_DIRECT_ARG(x.QueryPtr[i], Str, name);
#define CHECK_QUERY_SUBFIELDS(x, names) BOOST_PP_SEQ_FOR_EACH_I(CHECK_QUERY_SUBFIELD, x, names)
#define CHECK_FIELD_QUERY(target, var, info, ...)                       \
do                                                                      \
{                                                                       \
    ASSERT_EQ(target.TypeData, Expr::Type::Query);                      \
    const auto& query = *target.GetVar<Expr::Type::Query>();            \
    ASSERT_EQ(query.TypeData, QueryExpr::QueryType::Sub);               \
    constexpr size_t qcnt = BOOST_PP_VARIADIC_SIZE(__VA_ARGS__);        \
    ASSERT_EQ(query.Count, qcnt);                                       \
    CHECK_VAR_ARG(query.Target, var, info);                             \
    CHECK_QUERY_SUBFIELDS(query, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \
} while(0)

static std::u32string ReplaceNewLine(std::u32string_view txt)
{
    std::u32string ret;
    ret.reserve(txt.size());
    ParserContext context(txt);
    ContextReader reader(context);
    while (true)
    {
        const auto ch = reader.ReadNext();
        if (ch != common::parser::special::CharEnd)
            ret.push_back(ch);
        else
            break;
    }
    return ret;
}

using BinStmt = BinaryExpr*;
using UnStmt  = UnaryExpr*;
using FCall   = FuncCall*;

TEST(NailangParser, ProcStr)
{
    xziar::nailang::MemoryPool pool;
    {
        constexpr auto src = U"Hello"sv;
        const auto dst = NailangParser::ProcessString(src, pool);
        EXPECT_EQ(dst.GetVar<Expr::Type::Str>(), U"Hello"sv);
    }
    {
        constexpr auto src = U"Hello\\tWorld"sv;
        const auto dst = NailangParser::ProcessString(src, pool);
        EXPECT_EQ(dst.GetVar<Expr::Type::Str>(), U"Hello\tWorld"sv);
    }
    {
        constexpr auto src = U"Hello\tWorld\\0"sv;
        const auto dst = NailangParser::ProcessString(src, pool);
        EXPECT_EQ(dst.GetVar<Expr::Type::Str>(), U"Hello\tWorld\0"sv);
    }
}

TEST(NailangParser, ParseExpr)
{
    xziar::nailang::MemoryPool pool;
    {
        constexpr auto src = U""sv;
        ParserContext context(src);
        const auto expr = NailangParser::ParseSingleExpr(pool, context, ""sv, U""sv);
        EXPECT_FALSE(expr);
    }
    {
        constexpr auto src = U"()"sv;
        ParserContext context(src);
        const auto expr = NailangParser::ParseSingleExpr(pool, context, ""sv, U""sv);
        EXPECT_FALSE(expr);
    }
    {
        constexpr auto src = U"(((())))"sv;
        ParserContext context(src);
        const auto expr = NailangParser::ParseSingleExpr(pool, context, ""sv, U""sv);
        EXPECT_FALSE(expr);
    }
    {
        constexpr auto src = U"\"Hello\""sv;
        ParserContext context(src);
        const auto expr = NailangParser::ParseSingleExpr(pool, context, ""sv, U""sv);
        CHECK_DIRECT_ARG(expr, Str, U"Hello"sv);
    }
    {
        constexpr auto src = UR"("Hello\t\"World\"")"sv;
        ParserContext context(src);
        const auto expr = NailangParser::ParseSingleExpr(pool, context, ""sv, U""sv);
        CHECK_DIRECT_ARG(expr, Str, U"Hello\t\"World\""sv);
    }
    {
        constexpr auto src = U"val.xxx.y.len"sv;
        ParserContext context(src);
        const auto expr = NailangParser::ParseSingleExpr(pool, context, ""sv, U""sv);
        ASSERT_EQ(expr.TypeData, Expr::Type::Query);
        const auto& query = *expr.GetVar<Expr::Type::Query>();
        ASSERT_EQ(query.TypeData, QueryExpr::QueryType::Sub);
        ASSERT_EQ(query.Count, 3u);
        CHECK_VAR_ARG(query.Target, U"val"sv, Empty);
        CHECK_DIRECT_ARG(query.QueryPtr[0], Str, U"xxx"sv);
        CHECK_DIRECT_ARG(query.QueryPtr[1], Str, U"y"sv);
        CHECK_DIRECT_ARG(query.QueryPtr[2], Str, U"len"sv);
    }
    {
        constexpr auto src = U"(val[5])"sv;
        ParserContext context(src);
        const auto expr = NailangParser::ParseSingleExpr(pool, context, ""sv, U""sv);
        ASSERT_EQ(expr.TypeData, Expr::Type::Query);
        const auto& query = *expr.GetVar<Expr::Type::Query>();
        ASSERT_EQ(query.TypeData, QueryExpr::QueryType::Index);
        ASSERT_EQ(query.Count, 1u);
        CHECK_VAR_ARG(query.Target, U"val"sv, Empty);
        CHECK_DIRECT_ARG(query.QueryPtr[0], Int, 5);
    }
    {
        constexpr auto src = U"1u + 2"sv;
        ParserContext context(src);
        const auto expr = NailangParser::ParseSingleExpr(pool, context, ""sv, U""sv);
        ASSERT_EQ(expr.TypeData, Expr::Type::Binary);
        const auto& stmt = *expr.GetVar<Expr::Type::Binary>();
        CHECK_DIRECT_ARG(stmt.LeftOperand, Uint, 1u);
        EXPECT_EQ(stmt.Operator, EmbedOps::Add);
        CHECK_DIRECT_ARG(stmt.RightOperand, Int, 2);
    }
    {
        constexpr auto src = U"here??not"sv;
        ParserContext context(src);
        const auto expr = NailangParser::ParseSingleExpr(pool, context, ""sv, U""sv);
        ASSERT_EQ(expr.TypeData, Expr::Type::Binary);
        const auto& stmt = *expr.GetVar<Expr::Type::Binary>();
        CHECK_VAR_ARG(stmt.LeftOperand, U"here"sv, Empty);
        EXPECT_EQ(stmt.Operator, EmbedOps::ValueOr);
        CHECK_VAR_ARG(stmt.RightOperand, U"not"sv, Empty);
    }
    {
        constexpr auto src = U"?here"sv;
        ParserContext context(src);
        const auto expr = NailangParser::ParseSingleExpr(pool, context, ""sv, U""sv);
        ASSERT_EQ(expr.TypeData, Expr::Type::Unary);
        const auto& stmt = *expr.GetVar<Expr::Type::Unary>();
        EXPECT_EQ(stmt.Operator, EmbedOps::CheckExist);
        CHECK_VAR_ARG(stmt.Operand, U"here"sv, Empty);
    }
    {
        constexpr auto src = U"1?2:3"sv;
        ParserContext context(src);
        const auto expr = NailangParser::ParseSingleExpr(pool, context, ""sv, U""sv);
        ASSERT_EQ(expr.TypeData, Expr::Type::Ternary);
        const auto& stmt = *expr.GetVar<Expr::Type::Ternary>();
        CHECK_DIRECT_ARG(stmt.Condition,   Int, 1);
        CHECK_DIRECT_ARG(stmt.LeftOperand,  Int, 2);
        CHECK_DIRECT_ARG(stmt.RightOperand, Int, 3);
    }
    {
        constexpr auto src = U"1?:here:3"sv;
        ParserContext context(src);
        const auto expr = NailangParser::ParseSingleExpr(pool, context, ""sv, U""sv);
        ASSERT_EQ(expr.TypeData, Expr::Type::Ternary);
        const auto& stmt = *expr.GetVar<Expr::Type::Ternary>();
        CHECK_DIRECT_ARG(stmt.Condition,   Int, 1);
        CHECK_VAR_ARG(stmt.LeftOperand, U"here"sv, Local);
        CHECK_DIRECT_ARG(stmt.RightOperand, Int, 3);
    }
    {
        constexpr auto src = U"val[x+y]+ 12.8"sv;
        ParserContext context(src);
        const auto expr = NailangParser::ParseSingleExpr(pool, context, ""sv, U""sv);
        ASSERT_EQ(expr.TypeData, Expr::Type::Binary);
        const auto& stmt = *expr.GetVar<Expr::Type::Binary>();
        EXPECT_EQ(stmt.LeftOperand.TypeData, Expr::Type::Query);
        EXPECT_EQ(stmt.Operator, EmbedOps::Add);
        CHECK_DIRECT_ARG(stmt.RightOperand, FP, 12.8);

        const auto& stmt1 = *stmt.LeftOperand.GetVar<Expr::Type::Query>();
        ASSERT_EQ(stmt1.TypeData, QueryExpr::QueryType::Index);
        ASSERT_EQ(stmt1.Count, 1u);
        CHECK_VAR_ARG(stmt1.Target, U"val"sv, Empty);
        ASSERT_EQ(stmt1.QueryPtr[0].TypeData, Expr::Type::Binary);

        const auto& stmt2 = *stmt1.QueryPtr[0].GetVar<Expr::Type::Binary>();
        CHECK_VAR_ARG(stmt2.LeftOperand, U"x"sv, Empty);
        EXPECT_EQ(stmt2.Operator, EmbedOps::Add);
        CHECK_VAR_ARG(stmt2.RightOperand, U"y"sv, Empty);
    }
    {
        constexpr auto src = U"!val[x[3+4][5]]"sv;
        ParserContext context(src);
        const auto expr = NailangParser::ParseSingleExpr(pool, context, ""sv, U""sv);
        ASSERT_EQ(expr.TypeData, Expr::Type::Unary);
        const auto& stmt = *expr.GetVar<Expr::Type::Unary>();
        EXPECT_EQ(stmt.Operator, EmbedOps::Not);
        ASSERT_EQ(stmt.Operand.TypeData, Expr::Type::Query);

        const auto& stmt1 = *stmt.Operand.GetVar<Expr::Type::Query>();
        ASSERT_EQ(stmt1.TypeData, QueryExpr::QueryType::Index);
        ASSERT_EQ(stmt1.Count, 1u);
        CHECK_VAR_ARG(stmt1.Target, U"val"sv, Empty);
        ASSERT_EQ(stmt1.QueryPtr[0].TypeData, Expr::Type::Query);

        const auto& stmt2 = *stmt1.QueryPtr[0].GetVar<Expr::Type::Query>();
        ASSERT_EQ(stmt2.TypeData, QueryExpr::QueryType::Index);
        ASSERT_EQ(stmt2.Count, 2u);
        CHECK_VAR_ARG(stmt2.Target, U"x"sv, Empty);
        ASSERT_EQ(stmt2.QueryPtr[0].TypeData, Expr::Type::Binary);
        CHECK_DIRECT_ARG(stmt2.QueryPtr[1], Int, 5);

        const auto& stmt3 = *stmt2.QueryPtr[0].GetVar<Expr::Type::Binary>();
        CHECK_DIRECT_ARG(stmt3.LeftOperand, Int, 3);
        EXPECT_EQ(stmt3.Operator, EmbedOps::Add);
        CHECK_DIRECT_ARG(stmt3.RightOperand, Int, 4);
    }
    {
        constexpr auto src = U"!?here"sv;
        ParserContext context(src);
        const auto expr = NailangParser::ParseSingleExpr(pool, context, ""sv, U""sv);
        ASSERT_EQ(expr.TypeData, Expr::Type::Unary);
        const auto& stmt = *expr.GetVar<Expr::Type::Unary>();
        EXPECT_EQ(stmt.Operator, EmbedOps::Not);
        ASSERT_EQ(stmt.Operand.TypeData, Expr::Type::Unary);
        const auto& stmt1 = *stmt.Operand.GetVar<Expr::Type::Unary>();
        EXPECT_EQ(stmt1.Operator, EmbedOps::CheckExist);
        CHECK_VAR_ARG(stmt1.Operand, U"here"sv, Empty);
    }
    {
        constexpr auto src = U"1 + 2 * 3"sv;
        ParserContext context(src);
        const auto expr = NailangParser::ParseSingleExpr(pool, context, ""sv, U""sv);
        ASSERT_EQ(expr.TypeData, Expr::Type::Binary);
        const auto& stmt = *expr.GetVar<Expr::Type::Binary>();
        EXPECT_EQ(stmt.Operator, EmbedOps::Mul);
        CHECK_DIRECT_ARG(stmt.RightOperand, Int, 3);
        ASSERT_EQ(stmt.LeftOperand.TypeData, Expr::Type::Binary);
        const auto& stmt1 = *stmt.LeftOperand.GetVar<Expr::Type::Binary>();
        CHECK_DIRECT_ARG(stmt1.LeftOperand, Int, 1);
        EXPECT_EQ(stmt1.Operator, EmbedOps::Add);
        CHECK_DIRECT_ARG(stmt1.RightOperand, Int, 2);
    }
    {
        constexpr auto src = U"1 + 2 ? !a.x ?? a[3] : a + 4"sv;
        ParserContext context(src);
        const auto expr = NailangParser::ParseSingleExpr(pool, context, ""sv, U""sv);
        ASSERT_EQ(expr.TypeData, Expr::Type::Binary);
        const auto& stmt = *expr.GetVar<Expr::Type::Binary>();
        ASSERT_EQ(stmt.LeftOperand.TypeData, Expr::Type::Ternary);
        CHECK_DIRECT_ARG(stmt.RightOperand, Int, 4);

        const auto& stmt1 = *stmt.LeftOperand.GetVar<Expr::Type::Ternary>();
        ASSERT_EQ(stmt1.Condition.TypeData, Expr::Type::Binary);
        ASSERT_EQ(stmt1.LeftOperand.TypeData, Expr::Type::Binary);
        CHECK_VAR_ARG(stmt1.RightOperand, U"a"sv, Empty);

        const auto& stmt10 = *stmt1.Condition.GetVar<Expr::Type::Binary>();
        CHECK_DIRECT_ARG(stmt10.LeftOperand, Int, 1);
        EXPECT_EQ(stmt10.Operator, EmbedOps::Add);
        CHECK_DIRECT_ARG(stmt10.RightOperand, Int, 2);

        const auto& stmt11 = *stmt1.LeftOperand.GetVar<Expr::Type::Binary>();
        ASSERT_EQ(stmt11.LeftOperand.TypeData, Expr::Type::Unary);
        EXPECT_EQ(stmt11.Operator, EmbedOps::ValueOr);
        ASSERT_EQ(stmt11.RightOperand.TypeData, Expr::Type::Query);

        const auto& stmt110 = *stmt11.LeftOperand.GetVar<Expr::Type::Unary>();
        EXPECT_EQ(stmt110.Operator, EmbedOps::Not);
        CHECK_FIELD_QUERY(stmt110.Operand, U"a"sv, Empty, U"x"sv);

        const auto& stmt111 = *stmt11.RightOperand.GetVar<Expr::Type::Query>();
        ASSERT_EQ(stmt111.TypeData, QueryExpr::QueryType::Index);
        ASSERT_EQ(stmt111.Count, 1u);
        CHECK_DIRECT_ARG(stmt111.QueryPtr[0], Int, 3);
        CHECK_VAR_ARG(stmt111.Target, U"a", Empty);
    }
    {
        constexpr auto src = U"?here.xyz"sv;
        ParserContext context(src);
        const auto expr = NailangParser::ParseSingleExpr(pool, context, ""sv, U""sv);
        ASSERT_EQ(expr.TypeData, Expr::Type::Unary);
        const auto& stmt = *expr.GetVar<Expr::Type::Unary>();
        EXPECT_EQ(stmt.Operator, EmbedOps::CheckExist);
        CHECK_FIELD_QUERY(stmt.Operand, U"here"sv, Empty, U"xyz"sv);
    }
    {
        constexpr auto src = U"?here.xyz[3]"sv;
        ParserContext context(src);
        const auto expr = NailangParser::ParseSingleExpr(pool, context, ""sv, U""sv);
        ASSERT_EQ(expr.TypeData, Expr::Type::Unary);
        const auto& stmt = *expr.GetVar<Expr::Type::Unary>();
        EXPECT_EQ(stmt.Operator, EmbedOps::CheckExist);
        ASSERT_EQ(stmt.Operand.TypeData, Expr::Type::Query);
        const auto& stmt1 = *stmt.Operand.GetVar<Expr::Type::Query>();
        ASSERT_EQ(stmt1.TypeData, QueryExpr::QueryType::Index);
        ASSERT_EQ(stmt1.Count, 1u);
        CHECK_DIRECT_ARG(stmt1.QueryPtr[0], Int, 3);
        CHECK_FIELD_QUERY(stmt1.Target, U"here"sv, Empty, U"xyz"sv);
    }
}
TEST(NailangParser, ParseFuncBody)
{
    xziar::nailang::MemoryPool pool;
    {
        constexpr auto src = U"(123, -456)"sv;
        ParserContext context(src);
        const auto func = NailangParser::ParseFuncBody(U"func"sv, pool, context);
        EXPECT_EQ(*func.Name, U"func"sv);
        ASSERT_EQ(func.Args.size(), 2u);
        CHECK_DIRECT_ARG(func.Args[0], Int, 123);
        CHECK_DIRECT_ARG(func.Args[1], Int, -456);
    }
    {
        constexpr auto src = U"((123u), v._456)"sv;
        ParserContext context(src);
        const auto func = NailangParser::ParseFuncBody(U"func"sv, pool, context);
        EXPECT_EQ(*func.Name, U"func"sv);
        ASSERT_EQ(func.Args.size(), 2u);
        CHECK_DIRECT_ARG(func.Args[0], Uint, 123u);
        CHECK_FIELD_QUERY(func.Args[1], U"v"sv, Empty, U"_456"sv);
        //CHECK_VAR_ARG(func.Args[1], U"v.456"sv, Empty);
    }
    {
        constexpr auto src = U"(!false, 3.5 + var)"sv;
        ParserContext context(src);
        const auto func = NailangParser::ParseFuncBody(U"func"sv, pool, context);
        EXPECT_EQ(*func.Name, U"func"sv);
        ASSERT_EQ(func.Args.size(), 2u);
        ASSERT_EQ(func.Args[0].TypeData, Expr::Type::Unary);
        ASSERT_EQ(func.Args[1].TypeData, Expr::Type::Binary);
        {
            const auto& stmt = *func.Args[0].GetVar<Expr::Type::Unary>();
            EXPECT_EQ(stmt.Operator, EmbedOps::Not);
            CHECK_DIRECT_ARG(stmt.Operand, Bool, false);
        }
        {
            const auto& stmt = *func.Args[1].GetVar<Expr::Type::Binary>();
            CHECK_DIRECT_ARG(stmt.LeftOperand, FP, 3.5);
            EXPECT_EQ(stmt.Operator, EmbedOps::Add);
            CHECK_VAR_ARG(stmt.RightOperand, U"var"sv, Empty);
        }
    }
    {
        constexpr auto src = U"(6 >= $foo(:bar), $foo(`bar, (4-5)==9))"sv;
        ParserContext context(src);
        const auto func = NailangParser::ParseFuncBody(U"func"sv, pool, context);
        EXPECT_EQ(*func.Name, U"func"sv);
        ASSERT_EQ(func.Args.size(), 2u);
        ASSERT_EQ(func.Args[0].TypeData, Expr::Type::Binary);
        ASSERT_EQ(func.Args[1].TypeData, Expr::Type::Func);
        {
            const auto& stmt = *func.Args[0].GetVar<Expr::Type::Binary>();
            CHECK_DIRECT_ARG(stmt.LeftOperand, Int, 6);
            EXPECT_EQ(stmt.Operator, EmbedOps::GreaterEqual);
            ASSERT_EQ(stmt.RightOperand.TypeData, Expr::Type::Func);
            const auto& fcall = *stmt.RightOperand.GetVar<Expr::Type::Func>();
            EXPECT_EQ(*fcall.Name, U"foo"sv);
            ASSERT_EQ(fcall.Args.size(), 1u);
            CHECK_VAR_ARG(fcall.Args[0], U"bar", Local);
        }
        {
            const auto& fcall = *func.Args[1].GetVar<Expr::Type::Func>();
            EXPECT_EQ(*fcall.Name, U"foo"sv);
            ASSERT_EQ(fcall.Args.size(), 2u);
            CHECK_VAR_ARG(fcall.Args[0], U"bar", Root);
            ASSERT_EQ(fcall.Args[1].TypeData, Expr::Type::Binary);
            const auto& stmt = *fcall.Args[1].GetVar<Expr::Type::Binary>();
            ASSERT_EQ(stmt.LeftOperand.TypeData, Expr::Type::Binary);
            {
                const auto& stmt2 = *stmt.LeftOperand.GetVar<Expr::Type::Binary>();
                CHECK_DIRECT_ARG(stmt2.LeftOperand, Int, 4);
                EXPECT_EQ(stmt2.Operator, EmbedOps::Sub);
                CHECK_DIRECT_ARG(stmt2.RightOperand, Int, 5);
            }
            EXPECT_EQ(stmt.Operator, EmbedOps::Equal);
            CHECK_DIRECT_ARG(stmt.RightOperand, Int, 9);
        }
    }
}

TEST(NailangParser, ParseBlockBody)
{
    xziar::nailang::MemoryPool pool;
    const auto ParseAll = [&pool](std::u32string_view src)
    {
        xziar::nailang::RawBlock block;// { U""sv, U""sv, src, u"", { 0,0 } };
        block.Source = src;
        return xziar::nailang::NailangParser::ParseRawBlock(block, pool);
    };
    {
        constexpr auto src = UR"(
$func(hey);
)"sv;
        const auto block = ParseAll(src);
        ASSERT_EQ(block.Content.size(), 1u);
        const auto [meta, stmt] = block[0];
        EXPECT_EQ(stmt.TypeData, xziar::nailang::Statement::Type::FuncCall);
        EXPECT_EQ(meta.size(), 0u);
        const auto& fcall = *stmt.Get<FuncCall>();
        EXPECT_EQ(*fcall.Name, U"func"sv);
        ASSERT_EQ(fcall.Args.size(), 1u);
        CHECK_VAR_ARG(fcall.Args[0], U"hey", Empty);
    }
    {
        constexpr auto src = UR"(
@meta()
hey = 13;
)"sv;
        const auto block = ParseAll(src);
        EXPECT_EQ(block.Content.size(), 1u);
        const auto [meta, stmt] = block[0];
        EXPECT_EQ(stmt.TypeData, xziar::nailang::Statement::Type::Assign);
        ASSERT_EQ(meta.size(), 1u);
        EXPECT_EQ(*meta[0].Name, U"meta"sv);
        EXPECT_EQ(meta[0].Args.size(), 0u);
        const auto& assign = *stmt.Get<AssignExpr>();
        CHECK_VAR_ARG(assign.Target, U"hey", Empty);
        CHECK_DIRECT_ARG(assign.Statement, Int, 13);
    }
    {
        constexpr auto src = UR"(
x.y = z;
a[0][1].b[2] = ~c;
)"sv;
        const auto block = ParseAll(src);
        ASSERT_EQ(block.Content.size(), 2u);
        {
            const auto [meta, stmt] = block[0];
            EXPECT_EQ(stmt.TypeData, xziar::nailang::Statement::Type::Assign);
            ASSERT_EQ(meta.size(), 0u);
            const auto& assign = *stmt.Get<AssignExpr>();
            CHECK_FIELD_QUERY(assign.Target, U"x"sv, Empty, U"y"sv);
            CHECK_VAR_ARG(assign.Statement, U"z"sv, Empty);
        }
        {
            const auto [meta, stmt] = block[1];
            EXPECT_EQ(stmt.TypeData, xziar::nailang::Statement::Type::Assign);
            ASSERT_EQ(meta.size(), 0u);
            const auto& assign = *stmt.Get<AssignExpr>();
            ASSERT_EQ(assign.Target.TypeData, Expr::Type::Query);
            const auto& query = *assign.Target.GetVar<Expr::Type::Query>();
            ASSERT_EQ(query.TypeData, QueryExpr::QueryType::Index);
            ASSERT_EQ(query.Count, 1u);
            CHECK_DIRECT_ARG(query.QueryPtr[0], Int, 2);
            ASSERT_EQ(query.Target.TypeData, Expr::Type::Query);

            const auto& query1 = *query.Target.GetVar<Expr::Type::Query>();
            ASSERT_EQ(query1.TypeData, QueryExpr::QueryType::Sub);
            ASSERT_EQ(query1.Count, 1u);
            CHECK_DIRECT_ARG(query1.QueryPtr[0], Str, U"b");
            ASSERT_EQ(query1.Target.TypeData, Expr::Type::Query);

            const auto& query2 = *query1.Target.GetVar<Expr::Type::Query>();
            ASSERT_EQ(query2.TypeData, QueryExpr::QueryType::Index);
            ASSERT_EQ(query2.Count, 2u);
            CHECK_DIRECT_ARG(query2.QueryPtr[0], Int, 0);
            CHECK_DIRECT_ARG(query2.QueryPtr[1], Int, 1);
            CHECK_VAR_ARG(query2.Target, U"a", Empty);

            ASSERT_EQ(assign.Statement.TypeData, Expr::Type::Unary);
            const auto& stmt1 = *assign.Statement.GetVar<Expr::Type::Unary>();
            CHECK_VAR_ARG(stmt1.Operand, U"c"sv, Empty);
            ASSERT_EQ(stmt1.Operator, EmbedOps::BitNot);
        }
    }
    {
        constexpr auto src = UR"(
@meta()
#Block("13")
{
abc = 0u | 5;
}
)"sv;
        const auto block = ParseAll(src);
        ASSERT_EQ(block.Content.size(), 1u);
        const auto [meta, stmt] = block[0];
        EXPECT_EQ(stmt.TypeData, xziar::nailang::Statement::Type::Block);
        ASSERT_EQ(meta.size(), 1u);
        EXPECT_EQ(*meta[0].Name, U"meta"sv);
        EXPECT_EQ(meta[0].Args.size(), 0u);
        const auto& blk = *stmt.Get<Block>();
        EXPECT_EQ(blk.Name, U"13"sv);
        ASSERT_EQ(blk.Content.size(), 1u);
        {
            const auto [meta1, stmt1] = blk[0];
            EXPECT_EQ(stmt1.TypeData, xziar::nailang::Statement::Type::Assign);
            EXPECT_EQ(meta1.size(), 0u);
            const auto& assign = *stmt1.Get<AssignExpr>();
            CHECK_VAR_ARG(assign.Target, U"abc", Empty);

            ASSERT_EQ(assign.Statement.TypeData, Expr::Type::Binary);
            const auto& stmt2 = *assign.Statement.GetVar<Expr::Type::Binary>();
            CHECK_DIRECT_ARG(stmt2.LeftOperand, Uint, 0u);
            ASSERT_EQ(stmt2.Operator, EmbedOps::BitOr);
            CHECK_DIRECT_ARG(stmt2.RightOperand, Int, 5);
        }
    }
    {
        constexpr auto src = UR"(
hey /= 9u+1u;
$func(hey);
@meta()
#Raw.Main("block")
{
empty
}
)"sv;
        const auto block = ParseAll(src);
        ASSERT_EQ(block.Content.size(), 3u);
        {
            const auto [meta, stmt] = block[0];
            EXPECT_EQ(stmt.TypeData, xziar::nailang::Statement::Type::Assign);
            EXPECT_EQ(meta.size(), 0u);
            const auto& assign = *stmt.Get<AssignExpr>();
            CHECK_VAR_ARG(assign.Target, U"hey", Empty);
            EXPECT_TRUE(assign.IsSelfAssign);
            EXPECT_EQ(assign.GetSelfAssignOp(), EmbedOps::Div);
            const auto check = assign.GetCheck();
            EXPECT_EQ(check.WhenNull(), NilCheck::Behavior::Throw);
            EXPECT_EQ(check.WhenNotNull(), NilCheck::Behavior::Pass);
            EXPECT_EQ(assign.Statement.TypeData, Expr::Type::Binary);
            {
                const auto& stmt_ = *assign.Statement.GetVar<Expr::Type::Binary>();
                CHECK_DIRECT_ARG(stmt_.LeftOperand, Uint, 9u);
                EXPECT_EQ(stmt_.Operator, EmbedOps::Add);
                CHECK_DIRECT_ARG(stmt_.RightOperand, Uint, 1u);
            }
        }
        {
            const auto [meta, stmt] = block[1];
            EXPECT_EQ(stmt.TypeData, xziar::nailang::Statement::Type::FuncCall);
            EXPECT_EQ(meta.size(), 0u);
            const auto& fcall = *stmt.Get<FuncCall>();
            EXPECT_EQ(*fcall.Name, U"func"sv);
            ASSERT_EQ(fcall.Args.size(), 1u);
            CHECK_VAR_ARG(fcall.Args[0], U"hey", Empty);
        }
        {
            const auto [meta, stmt] = block[2];
            EXPECT_EQ(stmt.TypeData, xziar::nailang::Statement::Type::RawBlock);
            ASSERT_EQ(meta.size(), 1u);
            EXPECT_EQ(*meta[0].Name, U"meta"sv);
            EXPECT_EQ(meta[0].Args.size(), 0u);
            const auto& blk = *stmt.Get<RawBlock>();
            EXPECT_EQ(ReplaceNewLine(blk.Source), U"empty\n"sv);
        }
    }
}

TEST(NailangParser, ParseBlock)
{
    xziar::nailang::MemoryPool pool;
    {
        constexpr auto src = U"#Raw.Main(\"Hello\"){\r\n}"sv;
        ParserContext context(src);
        NailangParser Parser(pool, context);
        const auto block = Parser.GetNextRawBlock();
        EXPECT_EQ(block.Type, U"Main"sv);
        EXPECT_EQ(block.Name, U"Hello"sv);
        EXPECT_EQ(block.Source, U""sv);
        EXPECT_EQ(block.Position.first,  1u);
        EXPECT_EQ(block.Position.second, 0u);
    }

    {
        constexpr auto src = U"#Raw.Main(\"Hello\"){\r\n}\r\n#Raw.Main(\"Hello\"){\r\n}"sv;
        ParserContext context(src);
        NailangParser Parser(pool, context);

        const auto block0 = Parser.GetNextRawBlock();
        EXPECT_EQ(block0.Type, U"Main"sv);
        EXPECT_EQ(block0.Name, U"Hello"sv);
        EXPECT_EQ(block0.Source, U""sv);
        EXPECT_EQ(block0.Position.first,  1u);
        EXPECT_EQ(block0.Position.second, 0u);

        const auto block1 = Parser.GetNextRawBlock();
        EXPECT_EQ(block1.Type, U"Main"sv);
        EXPECT_EQ(block1.Name, U"Hello"sv);
        EXPECT_EQ(block1.Source, U""sv);
        EXPECT_EQ(block1.Position.first,  3u);
        EXPECT_EQ(block1.Position.second, 0u);
    }
    {
        constexpr auto src =
            UR"(
#Raw.Main("Hello")
{
Here
}

#Raw.Main("Hello")
{===+++
{Here}
===+++}
)"sv;
        ParserContext context(src);
        NailangParser Parser(pool, context);

        const auto block0 = Parser.GetNextRawBlock();
        EXPECT_EQ(block0.Type, U"Main"sv);
        EXPECT_EQ(block0.Name, U"Hello"sv);
        EXPECT_EQ(ReplaceNewLine(block0.Source), U"Here\n"sv);
        EXPECT_EQ(block0.Position.first,  2u);
        EXPECT_EQ(block0.Position.second, 0u);

        const auto block1 = Parser.GetNextRawBlock();
        EXPECT_EQ(block1.Type, U"Main"sv);
        EXPECT_EQ(block1.Name, U"Hello"sv);
        EXPECT_EQ(ReplaceNewLine(block1.Source), U"{Here}\n"sv);
        EXPECT_EQ(block1.Position.first,  7u);
        EXPECT_EQ(block1.Position.second, 0u);
    }
}

TEST(NailangParser, ParseMetaBlock)
{
    xziar::nailang::MemoryPool pool;
    {
        constexpr auto src =
            UR"(
@func()
#Raw.Main("Hello")
{
Here
}
)"sv;
        ParserContext context(src);
        NailangParser Parser(pool, context);

        const auto block = Parser.GetNextRawBlock();
        EXPECT_EQ(block.Type, U"Main"sv);
        EXPECT_EQ(block.Name, U"Hello"sv);
        EXPECT_EQ(ReplaceNewLine(block.Source), U"Here\n"sv);
        EXPECT_EQ(block.Position.first,  3u);
        EXPECT_EQ(block.Position.second, 0u);
        ASSERT_EQ(block.MetaFunctions.size(), 1u);
        const auto& meta = block.MetaFunctions[0];
        EXPECT_EQ(*meta.Name, U"func"sv);
        EXPECT_EQ(meta.Args.size(), 0u);
    }
    {
        constexpr auto src =
            UR"(
@func(1)
@func(abc, 0xff)
#Raw.Main("Hello")
{
Here
}
#Raw.Main("Hello")
{
Here
}
)"sv;
        ParserContext context(src);
        NailangParser Parser(pool, context);

        const auto block = Parser.GetNextRawBlock();
        EXPECT_EQ(block.Type, U"Main"sv);
        EXPECT_EQ(block.Name, U"Hello"sv);
        EXPECT_EQ(ReplaceNewLine(block.Source), U"Here\n"sv);
        EXPECT_EQ(block.Position.first,  4u);
        EXPECT_EQ(block.Position.second, 0u);
        ASSERT_EQ(block.MetaFunctions.size(), 2u);
        {
            const auto& meta = block.MetaFunctions[0];
            EXPECT_EQ(*meta.Name, U"func"sv);
            ASSERT_EQ(meta.Args.size(), 1u);
            CHECK_DIRECT_ARG(meta.Args[0], Int, 1);
        }
        {
            const auto& meta = block.MetaFunctions[1];
            EXPECT_EQ(*meta.Name, U"func"sv);
            EXPECT_EQ(meta.Args.size(), 2u);
            CHECK_VAR_ARG(meta.Args[0], U"abc", Empty);
            CHECK_DIRECT_ARG(meta.Args[1], Uint, 0xffu);
        }
        const auto block_ = Parser.GetNextRawBlock();
        EXPECT_EQ(block_.Type, U"Main"sv);
        EXPECT_EQ(block_.Name, U"Hello"sv);
        EXPECT_EQ(ReplaceNewLine(block_.Source), U"Here\n"sv);
        EXPECT_EQ(block_.Position.first,  8u);
        EXPECT_EQ(block_.Position.second, 0u);
        EXPECT_EQ(block_.MetaFunctions.size(), 0u);
    }
}

class Replacer : public xziar::nailang::ReplaceEngine
{
public:
    std::vector<std::u32string_view> Vars;
    std::vector<std::pair<std::u32string_view, std::vector<std::u32string_view>>> Funcs;
    std::u32string_view Target;
    Replacer(std::u32string_view target) : Target(target) {}
    ~Replacer() override {}
    void OnReplaceVariable(std::u32string& output, void*, std::u32string_view var) override
    {
        Vars.push_back(var);
        output.append(Target);
    }
    void OnReplaceFunction(std::u32string& output, void*, std::u32string_view func, common::span<const std::u32string_view> args) override
    {
        std::vector<std::u32string_view> arg(args.begin(), args.end());
        Funcs.emplace_back(func, std::move(arg));
        output.append(Target);
    }
    using ReplaceEngine::ProcessVariable;
    using ReplaceEngine::ProcessFunction;
};
TEST(NailangParser, ReplaceEngine)
{
    {
        Replacer replacer(U"l"sv);
        const auto result = replacer.ProcessVariable(U"He{1}{2}o Wor{3}d"sv, U"{"sv, U"}"sv);
        EXPECT_EQ(result, U"Hello World"sv);
        EXPECT_THAT(replacer.Vars, testing::ElementsAre(U"1"sv, U"2"sv, U"3"sv));
    }
    {
        Replacer replacer(U"l"sv);
        const auto result = replacer.ProcessVariable(U"He$$!{ab}$$!{cd}o Wor$$!{ef}d"sv, U"$$!{"sv, U"}"sv);
        EXPECT_EQ(result, U"Hello World"sv);
        EXPECT_THAT(replacer.Vars, testing::ElementsAre(U"ab"sv, U"cd"sv, U"ef"sv));
    }
    {
        Replacer replacer(U"func()"sv);
        const auto result = replacer.ProcessFunction(U"y = $$!x()"sv, U"$$!"sv, U""sv);
        EXPECT_EQ(result, U"y = func()"sv);
        ASSERT_EQ(replacer.Funcs.size(), 1u);
        EXPECT_EQ(replacer.Funcs[0].first, U"x"sv);
        EXPECT_THAT(replacer.Funcs[0].second, testing::ElementsAre());
    }
    {
        Replacer replacer(U"func()"sv);
        const auto result = replacer.ProcessFunction(UR"(y = $$!xy(""))"sv, U"$$!"sv, U""sv);
        EXPECT_EQ(result, U"y = func()"sv);
        ASSERT_EQ(replacer.Funcs.size(), 1u);
        EXPECT_EQ(replacer.Funcs[0].first, U"xy"sv);
        EXPECT_THAT(replacer.Funcs[0].second, testing::ElementsAre(UR"("")"sv));
    }
    {
        Replacer replacer(U"func()"sv);
        const auto result = replacer.ProcessFunction(UR"(y = $$!xy("1+2     ,3"))"sv, U"$$!"sv, U""sv);
        EXPECT_EQ(result, U"y = func()"sv);
        ASSERT_EQ(replacer.Funcs.size(), 1u);
        EXPECT_EQ(replacer.Funcs[0].first, U"xy"sv);
        EXPECT_THAT(replacer.Funcs[0].second, testing::ElementsAre(UR"("1+2     ,3")"sv));
    }
    {
        Replacer replacer(U"func()"sv);
        const auto result = replacer.ProcessFunction(U"y = $$!xy(1,2)"sv, U"$$!"sv, U""sv);
        EXPECT_EQ(result, U"y = func()"sv);
        ASSERT_EQ(replacer.Funcs.size(), 1u);
        EXPECT_EQ(replacer.Funcs[0].first, U"xy"sv);
        EXPECT_THAT(replacer.Funcs[0].second, testing::ElementsAre(U"1"sv, U"2"sv));
    }
    {
        Replacer replacer(U"func()"sv);
        const auto result = replacer.ProcessFunction(U"y = $$!xy((1), 2)"sv, U"$$!"sv, U""sv);
        EXPECT_EQ(result, U"y = func()"sv);
        ASSERT_EQ(replacer.Funcs.size(), 1u);
        EXPECT_EQ(replacer.Funcs[0].first, U"xy"sv);
        EXPECT_THAT(replacer.Funcs[0].second, testing::ElementsAre(U"(1)"sv, U"2"sv));
    }
    {
        Replacer replacer(U"func()"sv);
        const auto result = replacer.ProcessFunction(UR"kk(y = $$!xy((1+("(2)")), 2))kk"sv, U"$$!"sv, U""sv);
        EXPECT_EQ(result, U"y = func()"sv);
        ASSERT_EQ(replacer.Funcs.size(), 1u);
        EXPECT_EQ(replacer.Funcs[0].first, U"xy"sv);
        EXPECT_THAT(replacer.Funcs[0].second, testing::ElementsAre(UR"kk((1+("(2)")))kk"sv, U"2"sv));
    }
    {
        Replacer replacer(U"func()"sv);
        const auto result = replacer.ProcessFunction(UR"(y = $$!xy( 12, 34 )$ +$$!y(56 + "" / 7)$)"sv, U"$$!"sv, U"$"sv);
        EXPECT_EQ(result, U"y = func() +func()"sv);
        ASSERT_EQ(replacer.Funcs.size(), 2u);
        EXPECT_EQ(replacer.Funcs[0].first, U"xy"sv);
        EXPECT_THAT(replacer.Funcs[0].second, testing::ElementsAre(U"12"sv, U"34"sv));
        EXPECT_EQ(replacer.Funcs[1].first, U"y"sv);
        EXPECT_THAT(replacer.Funcs[1].second, testing::ElementsAre(UR"(56 + "" / 7)"sv));
    }
}


text:
body {
  background-color: #f7f7f7;
  background-repeat: no-repeat;
  background-attachment: fixed; }

/*
h1, h2, h3, h4, h5, h6 {
	text-align: center;
}*/
section#waves {
  background: linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), transparent url(../img/ocean.jpg) no-repeat center;
  height: 600px;
  width: 100%; }

section#main {
  margin-top: 50px; }

section#signup {
  margin-top: 50px;
  margin-bottom: 50px; }
  section#signup div.container {
    padding: 50px 50px; }

section#profile {
  margin-top: 50px; }

#tagbox {
  border-radius: 0px; }

.img-centered {
  display: block;
  margin: auto; }

ul {
  list-style-type: none; }

footer {
  width: 100%;
  margin-top: 50px;
  padding: 30px;
  background-color: white;
  border-top: 5px solid #0080ff;
  box-shadow: -1px -1px 15px #888; }

.content {
  padding-top: 125px; }

.heading {
  padding: 25px; }
  .heading div button {
    margin-top: 50px; }
  .heading h1 {
    font-size: 7rem;
    color: white;
    flex: 2;
    line-height: 1; }

.flex-row {
  display: flex;
  flex-direction: row; }

.flex-col {
  display: flex;
  flex-direction: column; }

.flex-adjust {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap; }

.flex-sp-bt {
  justify-content: space-between; }

.flex-sp-ar {
  justify-content: space-around; }

.flex-wrap {
  flex-wrap: wrap; }

.flex-1 {
  flex: 1; }

.flex-2 {
  flex: 2; }

.flex-3 {
  flex: 3; }

@media (min-width: 768px) {
  .flex-adjust {
    flex-direction: row;
    flex-wrap: nowrap; } }
.signin {
  padding-top: 25px; }

#googleMap {
  height: 500px;
  background: transparent url(../img/ajax-loader.gif) no-repeat center center; }

h1 {
  font-family: Futura, 'Trebuchet MS', Arial, sans-serif;
  font-size: 4rem;
  font-style: normal;
  font-variant: normal;
  font-weight: 500;
  line-height: 26.4px; }

h2 {
  padding: 15px;
  font-family: Futura, 'Trebuchet MS', Arial, sans-serif;
  font-size: 3rem;
  font-style: normal;
  font-variant: normal;
  font-weight: 500;
  line-height: 20px; }

h3 {
  font-family: Futura, 'Trebuchet MS', Arial, sans-serif;
  font-size: 2rem;
  font-style: normal;
  font-variant: normal;
  font-weight: 500;
  line-height: 16.4px; }

p {
  font-family: Futura, 'Trebuchet MS', Arial, sans-serif;
  font-size: 16px;
  font-weight: 400;
  padding: 10px 0px; }

.navbar-default {
  box-shadow: 1px 1px 15px #888;
  padding: 10px;
  background-color: white;
  border-bottom: 5px solid #0080ff;
  border-radius: 0px; }
  .navbar-default .navbar-brand {
    font-family: Futura, 'Trebuchet MS', Arial, sans-serif;
    font-size: 3.1rem;
    color: #99ccff;
    transition: color 0.5s; }
    .navbar-default .navbar-brand:hover, .navbar-default .navbar-brand:focus, .navbar-default .navbar-brand:active {
      color: #0061c2; }
  .navbar-default .navbar-collapse {
    border-color: fade(white, 2%); }
  .navbar-default .navbar-toggle {
    transition: color 0.3s ease-in, background-color 0.3s ease-in;
    background-color: #0080ff;
    border-color: #0080ff; }
    .navbar-default .navbar-toggle .icon-bar {
      transition: background-color 0.3s ease-in;
      background-color: white; }
    .navbar-default .navbar-toggle:focus {
      background-color: #0080ff;
      color: white; }
    .navbar-default .navbar-toggle:hover, .navbar-default .navbar-toggle:active {
      background-color: white;
      color: #0080ff; }
      .navbar-default .navbar-toggle:hover .icon-bar, .navbar-default .navbar-toggle:active .icon-bar {
        background-color: #0080ff; }
  .navbar-default .nav li ul:hover {
    background-color: white; }
  .navbar-default .nav li a {
    font-weight: 500;
    font-size: 2rem;
    letter-spacing: 1px;
    color: #0080ff;
    transition: background-color 0.5s; }
    .navbar-default .nav li a:hover, .navbar-default .nav li a:focus {
      background-color: #e0e0e0;
      border-radius: 3px;
      color: #0080ff;
      outline: none; }
    .navbar-default .nav li a .dropdown-toggle {
      background-color: #0080ff; }
  .navbar-default .navbar-nav > .active > a {
    border-radius: 0;
    color: #0080ff;
    background-color: white; }
  .navbar-default .navbar-nav > .active > a:hover,
  .navbar-default .navbar-nav > .active > a:focus {
    color: #0066cc;
    background-color: white; }

#frontbar {
  background-color: transparent;
  border: none;
  box-shadow: none; }
  #frontbar .navbar-brand {
    color: white; }
  #frontbar .nav li a {
    color: white; }
    #frontbar .nav li a:hover, #frontbar .nav li a:focus {
      background-color: transparent;
      color: #0080ff;
      outline: none; }
    #frontbar .nav li a .dropdown-toggle {
      background-color: #0080ff; }

.btn-norm {
  color: white;
  background-color: #0080ff;
  border-color: #0080ff;
  border-radius: 2px;
  transition: background-color 0.5s;
  letter-spacing: 1px;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; }
  .btn-norm:hover, .btn-norm:focus, .btn-norm.active,
  .btn-norm .open .dropdown-toggle {
    color: white;
    background-color: #0066cc;
    border-color: #0061c2; }
  .btn-norm:active, .btn-norm.active,
  .btn-norm .open .dropdown-toggle {
    background-image: none; }
  .btn-norm.disabled, .btn-norm.disabled:hover, .btn-norm.disabled:focus, .btn-norm.disabled:active, .btn-norm.disabled.active, .btn-norm[disabled], .btn-norm[disabled]:hover, .btn-norm[disabled]:focus, .btn-norm[disabled]:active, .btn-norm[disabled].active,
  .btn-norm fieldset[disabled],
  .btn-norm fieldset[disabled]:hover,
  .btn-norm fieldset[disabled]:focus,
  .btn-norm fieldset[disabled]:active,
  .btn-norm fieldset[disabled].active {
    -webkit-transition: all ease 0.3s;
    background-color: #0080ff;
    border-color: #0080ff; }
  .btn-norm .badge {
    color: #0080ff;
    background-color: white; }

.btn-larger {
  color: white;
  background-color: #0080ff;
  border-color: #0080ff;
  border-radius: 2px;
  transition: background-color 0.5s;
  letter-spacing: 1px;
  padding: 10px 25px;
  font-size: 16px;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; }
  .btn-larger:hover, .btn-larger:focus, .btn-larger.active,
  .btn-larger .open .dropdown-toggle {
    color: white;
    background-color: #0066cc;
    border-color: #0061c2; }
  .btn-larger:active, .btn-larger.active,
  .btn-larger .open .dropdown-toggle {
    background-image: none; }
  .btn-larger.disabled, .btn-larger.disabled:hover, .btn-larger.disabled:focus, .btn-larger.disabled:active, .btn-larger.disabled.active, .btn-larger[disabled], .btn-larger[disabled]:hover, .btn-larger[disabled]:focus, .btn-larger[disabled]:active, .btn-larger[disabled].active,
  .btn-larger fieldset[disabled],
  .btn-larger fieldset[disabled]:hover,
  .btn-larger fieldset[disabled]:focus,
  .btn-larger fieldset[disabled]:active,
  .btn-larger fieldset[disabled].active {
    -webkit-transition: all ease 0.3s;
    background-color: #0080ff;
    border-color: #0080ff; }
  .btn-larger .badge {
    color: #0080ff;
    background-color: white; }

.btn-cancel {
  color: #0080ff;
  background-color: white;
  border-color: #0080ff;
  font-family: Futura, 'Trebuchet MS', Arial, sans-serif; }
  .btn-cancel:hover, .btn-cancel:active, .btn-cancel:focus {
    color: #0080ff;
    background-color: #e0e0e0; }

input[type=radio] {
  transform: scale(1.5);
  margin-right: 15px; }

.rating {
  display: flex;
  justify-content: center; }

.wave {
  height: 0px; }

.rating-disabled {
  pointer-events: none; }

.active {
  font-size: 2rem;
  background-color: #0080ff;
  color: white; }

.media {
  padding: 15px; }

ul.selected-items {
  padding: 0px; }
  ul.selected-items li {
    padding: 5px;
    display: inline;
    margin: 5px;
    border-radius: 5px;
    background-color: #0080ff;
    color: white;
    box-sizing: border-box; }
    ul.selected-items li button {
      padding: 0;
      cursor: pointer;
      background: transparent;
      border: 0;
      -webkit-appearance: none; }

.closed {
  font-size: 21px;
  font-weight: bold;
  line-height: 1;
  color: #000000;
  text-shadow: 0 1px 0 #ffffff;
  opacity: 0.2;
  filter: alpha(opacity=20); }
  .closed:hover, .closed:focus {
    color: #000000;
    text-decoration: none;
    cursor: pointer;
    opacity: 0.5;
    filter: alpha(opacity=50); }

section#create {
  margin-top: 25px;
  padding-top: 50px;
  margin-bottom: 75px;
  padding-bottom: 50px;
  background-color: #4da6ff;
  color: white; }

.modaldiv {
  padding-bottom: 20px;
  background-color: #66b3ff; }

div#myModal {
  color: black; }

.modal-found {
  background-color: #66b3ff;
  padding-bottom: 20px; }

.top-icon {
  margin: 25px;
  flex: 1; }

#party-title {
  flex: 5; }

.search-half {
  flex: 1;
  flex-direction: column; }

#codeerror {
  color: red;
  display: none; }

.blurred {
  -webkit-filter: blur(5px);
  -moz-filter: blur(5px);
  -o-filter: blur(5px);
  -ms-filter: blur(5px);
  filter: blur(5px); }

.invisible {
  visibility: hidden; }

.loading {
  background: transparent url(../img/ajax-loader.gif) no-repeat center center; }

.modal-custom {
  display: none;
  position: fixed;
  z-index: 2;
  padding-top: 100px;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background-color: black;
  background-color: rgba(0, 0, 0, 0.4); }

/* Modal Content */
.modal-content {
  position: relative;
  background-color: #fefefe;
  margin: auto;
  padding: 0;
  width: 525px;
  box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
  -webkit-animation-name: animatetop;
  -webkit-animation-duration: 0.4s;
  animation-name: animatetop;
  animation-duration: 0.4s; }

/* Add Animation */
@-webkit-keyframes animatetop {
  from {
    top: -300px;
    opacity: 0; }
  to {
    top: 0;
    opacity: 1; } }
@keyframes animatetop {
  from {
    top: -300px;
    opacity: 0; }
  to {
    top: 0;
    opacity: 1; } }
.modal-close {
  color: white;
  float: right;
  font-size: 28px;
  font-weight: bold; }
  .modal-close:hover, .modal-close:focus {
    color: #b3b3b3;
    text-decoration: none;
    cursor: pointer; }

.modal-header {
  padding: 2px 16px;
  background-color: #0080ff;
  color: white; }

.modal-footer {
  padding: 10px 16px;
  color: white; }

.table tbody tr td, .table tbody tr th {
  border: none;
  vertical-align: middle; }

.valid-change, .valid-change:focus {
  border-color: #d8c817;
  outline: 0;
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px #d8c817; }

.valid-err, .valid-err:focus {
  border-color: red;
  outline: 0;
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px red; }

.pencil {
  transition: all 0.3s ease-in-out; }
  .pencil:hover, .pencil:focus {
    transform: scale(1.1);
    color: #d8c817; }

.pencil-edit {
  color: #d8b827; }

.trash-wave {
  transition: all 0.3s ease-in-out; }
  .trash-wave:hover, .trash-wave:focus {
    transform: scale(1.1);
    color: #f12713; }

.oldstyle {
  border-top: 1px solid #ddd; }

.profile-col {
  border-top-left-radius: 5px;
  border-top-right-radius: 5px; }

.prof-header {
  color: #4da6ff; }

.prof-pic {
  text-align: center;
  background-color: #f7f7f7;
  padding: 25px 0px; }
  .prof-pic img {
    height: 256px;
    width: 256px; }

.prof-carousel {
  padding: 10px 0px;
  margin-bottom: 50px;
  border: #ddd solid 3px;
  border-radius: 8px; }

.prof-recents {
  margin-bottom: 10px; }
  .prof-recents h3 {
    color: #4da6ff; }

.wavelisting img {
  margin: auto; }
.wavelisting h4 {
  margin-top: 0px; }

#ownerwaves {
  border: #ddd solid 3px;
  border-radius: 3px;
  height: 700px;
  overflow-y: scroll; }

.prof-ownerwave {
  border-bottom: #ddd solid 1px;
  height: 0px;
  transition: background-color 500ms; }
  .prof-ownerwave:hover {
    background-color: #ddd; }

.prof-sidewave {
  flex-basis: 175px;
  margin-right: auto; }

.prof-wave-desc {
  margin: auto; }

.def-carousel {
  height: 150px; }

[ng\:cloak], [ng-cloak], .ng-cloak {
  display: none !important; }

#slick-settings {
  width: 85%;
  margin: auto;
  margin-bottom: 25px; }

.form-adjust {
  transition: height 0.5s;
  overflow-y: hidden;
  height: 205px;
  padding-top: 20px;
  border-top: 1px solid #e5e5e5; }

.form-adjust.ng-hide-add,
.form-adjust.ng-hide-remove {
  transition: height 0s ease-in; }

.form-adjust.ng-hide-add-active,
.form-adjust.ng-hide-remove-active {
  transition: height 0.5s ease-in; }

.form-adjust.ng-hide {
  height: 0px; }

.wave-edit {
  transition: height 0.5s;
  overflow-y: hidden;
  height: 310px;
  border-top: 1px solid #e5e5e5;
  padding-top: 10px; }

.wave-edit.ng-hide-add,
.wave-edit.ng-hide-remove {
  transition: height 0s ease-in; }

.wave-edit.ng-hide-add-active,
.wave-edit.ng-hide-remove-active {
  transition: height 0.5s ease-in; }

.wave-edit.ng-hide {
  height: 0px; }

/*# sourceMappingURL=waves.css.map */

redpajama_set_name: RedPajamaGithub


text:
require 'spec_helper'

describe TaskMapper::Provider::Basecamp::Ticket do
  let(:project_id) { 5220065 }
  let(:ticket_id) { 133184178 }
  let(:comment_id) { 74197051 }
  let(:tm) { create_instance }
  let(:project) { tm.project project_id }
  let(:ticket) { project.ticket ticket_id }
  let(:comment_class) { TaskMapper::Provider::Basecamp::Comment }

  before do
    ActiveResource::HttpMock.respond_to do |mock|
      mock.get "/projects/#{project_id}.xml", rheaders, fixture_for('projects/5220065'), 200
      mock.get "/projects/#{project_id}/todo_lists.xml?responsible_party=", rheaders, fixture_for('todo_list_with_items'), 200
      mock.get "/todo_items/#{ticket_id}/comments.xml", rheaders, fixture_for('comments'), 200
      mock.get "/todo_items/#{ticket_id}/comments/74197051.xml", rheaders, fixture_for('comments/74197051'), 200
      mock.get "/todo_items/#{ticket_id}/comments/74197096.xml", rheaders, fixture_for('comments/74197051'), 200
      mock.get "/todo_lists/19700377/todo_items.xml", rheaders, fixture_for('todo_list_with_items'), 200
      mock.get "/todo_lists/19700382/todo_items.xml", rheaders, fixture_for('todo_list_with_items'), 200
      mock.get "/todo_lists/19700819/todo_items.xml", rheaders, fixture_for('todo_list_with_items'), 200
      mock.post "/todo_items/133184178/comments.xml", pheaders, fixture_for('comments/new_comment'), 200
    end
  end

  describe "#comments" do
    context "without arguments" do
      let(:comments) { ticket.comments }

      it "returns an array of all comments" do
        expect(comments).to be_an Array
        expect(comments.first).to be_a comment_class
      end
    end

    context "with an array of comment IDs" do
      let(:comments) { ticket.comments [comment_id] }

      it "returns an array of matching comments" do
        expect(comments).to be_an Array
        expect(comments.first).to be_a comment_class
        expect(comments.first.id).to eq comment_id
      end
    end

    context "with a hash containing a comment ID" do
      let(:comments) { ticket.comments :id => comment_id }

      it "returns an array containing the matching comment" do
        expect(comments).to be_an Array
        expect(comments.first).to be_a comment_class
        expect(comments.first.id).to eq comment_id
      end
    end
  end

  describe "#comment" do
    context "with a comment ID" do
      let(:comment) { ticket.comment comment_id}

      it "returns the matching comment" do
        expect(comment).to be_a comment_class
        expect(comment.id).to eq comment_id
      end
    end
  end

  describe "#comment!" do
    context "with a comment body" do
      let(:comment) { ticket.comment! :body => "New Comment" }

      it "creates a new comment" do
        expect(comment).to be_a comment_class
        expect(comment.body).to eq "New Comment"
      end
    end
  end
end


text:
 Load/Reload the table data from an Ajax source

            This module also handles data reloading / loading from an Ajax source:

                If you need to load data, you just have to call the function dtInstance.changeData(ajax);.

                If you need to reload the data, you just have to call the function dtInstance.reloadData();.

        <tabset>
            <tab heading="Preview">

                            <button ng-click="showCase.reloadData()" type="button" class="btn btn-info">
                                 Reload data
                            </button>
                            <button ng-click="showCase.dtInstance.changeData(showCase.newSource)" type="button" class="btn btn-info">
                                 Change data
                            </button>

            </tab>
            <tab heading="HTML">

        <button ng-click="showCase.reloadData()" type="button" class="btn btn-info">
             Reload data
        </button>
        <button ng-click="showCase.dtInstance.changeData(showCase.newSource)" type="button" class="btn btn-info">
             Change data
        </button>

            </tab>
            <tab heading="JS">

angular.module('showcase.dataReload.withAjax', ['datatables'])
.controller('DataReloadWithAjaxCtrl', DataReloadWithAjaxCtrl);

function DataReloadWithAjaxCtrl(DTOptionsBuilder, DTColumnBuilder) {
    var vm = this;
    vm.dtOptions = DTOptionsBuilder.fromSource('data.json')
        .withOption('stateSave', true)
        .withPaginationType('full_numbers');
    vm.dtColumns = [
        DTColumnBuilder.newColumn('id').withTitle('ID'),
        DTColumnBuilder.newColumn('firstName').withTitle('First name'),
        DTColumnBuilder.newColumn('lastName').withTitle('Last name').notVisible()
    ];
    vm.newSource = 'data1.json';
    vm.reloadData = reloadData;
    vm.dtInstance = {};

    function reloadData() {
        var resetPaging = false;
        vm.dtInstance.reloadData(callback, resetPaging);
    }

    function callback(json) {
        console.log(json);
    }
}

            </tab>
            <tab heading="Example data">

                    data.json

                    data1.json

[{
    "id": 860,
    "firstName": "Superman",
    "lastName": "Yoda"
}, {
    "id": 870,
    "firstName": "Foo",
    "lastName": "Whateveryournameis"
}, {
    "id": 590,
    "firstName": "Toto",
    "lastName": "Titi"
}, {
    "id": 803,
    "firstName": "Luke",
    "lastName": "Kyle"
},
...
]

            </tab>
        </tabset>


text:
using System;
#if XAMMAC2
using AppKit;
using Foundation;
using CoreGraphics;
using ObjCRuntime;
using CoreAnimation;
#else
using MonoMac.AppKit;
using MonoMac.Foundation;
using MonoMac.CoreGraphics;
using MonoMac.ObjCRuntime;
using MonoMac.CoreAnimation;
#endif

namespace Eto.Mac.Forms
{
	public static class MacCommon
	{
		public static IntPtr CopyWithZoneHandle = Selector.GetHandle("copyWithZone:");

		public static IntPtr ReleaseHandle = Selector.GetHandle("release");

		public static void SafeDispose(this NSObject obj)
		{
			if (obj != null)
			{
				var count = obj.RetainCount;
				var handle = obj.Handle;

				obj.Dispose();
				// HACK: release handle since Dispose() won't do it properly yet
				if (handle != IntPtr.Zero && ApplicationHandler.Instance != null && count > 2)
					Messaging.void_objc_msgSend(handle, ReleaseHandle);
			}
		}
	}
}


text:
<?php

abstract class PhabricatorRepositoryCommitParserWorker
  extends PhabricatorWorker {

  protected $commit;
  protected $repository;

  private function loadCommit() {
    if ($this->commit) {
      return $this->commit;
    }

    $commit_id = idx($this->getTaskData(), 'commitID');
    if (!$commit_id) {
      return false;
    }

    $commit = id(new PhabricatorRepositoryCommit())->load($commit_id);

    if (!$commit) {
      // TODO: Communicate permanent failure?
      return false;
    }

    return $this->commit = $commit;
  }

  final public function doWork() {
    if (!$this->loadCommit()) {
      return;
    }

    $repository = id(new PhabricatorRepository())->load(
      $this->commit->getRepositoryID());

    if (!$repository) {
      return;
    }

    $this->repository = $repository;

    return $this->parseCommit($repository, $this->commit);
  }

  final protected function shouldQueueFollowupTasks() {
    return !idx($this->getTaskData(), 'only');
  }

  abstract protected function parseCommit(
    PhabricatorRepository $repository,
    PhabricatorRepositoryCommit $commit);

  /**
   * This method is kind of awkward here but both the SVN message and
   * change parsers use it.
   */
  protected function getSVNLogXMLObject($uri, $revision, $verbose = false) {

    if ($verbose) {
      $verbose = '--verbose';
    }

    list($xml) = $this->repository->execxRemoteCommand(
      "log --xml {$verbose} --limit 1 %s@%d",
      $uri,
      $revision);

    // Subversion may send us back commit messages which won't parse because
    // they have non UTF-8 garbage in them. Slam them into valid UTF-8.
    $xml = phutil_utf8ize($xml);

    return new SimpleXMLElement($xml);
  }

  protected function isBadCommit($full_commit_name) {
    $repository = new PhabricatorRepository();

    $bad_commit = queryfx_one(
      $repository->establishConnection('w'),
      'SELECT * FROM %T WHERE fullCommitName = %s',
      PhabricatorRepository::TABLE_BADCOMMIT,
      $full_commit_name);

    return (bool)$bad_commit;
  }

  public function renderForDisplay() {
    $suffix = parent::renderForDisplay();
    $commit = $this->loadCommit();
    if (!$commit) {
      return $suffix;
    }

    $repository = id(new PhabricatorRepository())
      ->load($commit->getRepositoryID());
    $link = DiffusionView::linkCommit($repository,
                                      $commit->getCommitIdentifier());
    return hsprintf('%s%s', $link, $suffix);
  }
}


text:
require 'rubygems'
require 'puppet'
require 'rspec-puppet'

def param_value(subject, type, title, param)
  subject.resource(type, title).send(:parameters)[param.to_sym]
end

fixture_path = File.expand_path(File.join(File.dirname(__FILE__), 'fixtures'))

RSpec.configure do |c|
  c.module_path = File.join(fixture_path, 'modules')
  c.manifest_dir = File.join(fixture_path, 'manifests')
end


text:
package timeouts

import (
	"time"

	"github.com/mholt/caddy"
	"github.com/mholt/caddy/caddyhttp/httpserver"
)

func init() {
	caddy.RegisterPlugin("timeouts", caddy.Plugin{
		ServerType: "http",
		Action:     setupTimeouts,
	})
}

func setupTimeouts(c *caddy.Controller) error {
	config := httpserver.GetConfig(c)

	for c.Next() {
		var hasOptionalBlock bool
		for c.NextBlock() {
			hasOptionalBlock = true

			// ensure the kind of timeout is recognized
			kind := c.Val()
			if kind != "read" && kind != "header" && kind != "write" && kind != "idle" {
				return c.Errf("unknown timeout '%s': must be read, header, write, or idle", kind)
			}

			// parse the timeout duration
			if !c.NextArg() {
				return c.ArgErr()
			}
			if c.NextArg() {
				// only one value permitted
				return c.ArgErr()
			}
			var dur time.Duration
			if c.Val() != "none" {
				var err error
				dur, err = time.ParseDuration(c.Val())
				if err != nil {
					return c.Errf("%v", err)
				}
				if dur < 0 {
					return c.Err("non-negative duration required for timeout value")
				}
			}

			// set this timeout's duration
			switch kind {
			case "read":
				config.Timeouts.ReadTimeout = dur
				config.Timeouts.ReadTimeoutSet = true
			case "header":
				config.Timeouts.ReadHeaderTimeout = dur
				config.Timeouts.ReadHeaderTimeoutSet = true
			case "write":
				config.Timeouts.WriteTimeout = dur
				config.Timeouts.WriteTimeoutSet = true
			case "idle":
				config.Timeouts.IdleTimeout = dur
				config.Timeouts.IdleTimeoutSet = true
			}
		}
		if !hasOptionalBlock {
			// set all timeouts to the same value

			if !c.NextArg() {
				return c.ArgErr()
			}
			if c.NextArg() {
				// only one value permitted
				return c.ArgErr()
			}
			val := c.Val()

			config.Timeouts.ReadTimeoutSet = true
			config.Timeouts.ReadHeaderTimeoutSet = true
			config.Timeouts.WriteTimeoutSet = true
			config.Timeouts.IdleTimeoutSet = true

			if val == "none" {
				config.Timeouts.ReadTimeout = 0
				config.Timeouts.ReadHeaderTimeout = 0
				config.Timeouts.WriteTimeout = 0
				config.Timeouts.IdleTimeout = 0
			} else {
				dur, err := time.ParseDuration(val)
				if err != nil {
					return c.Errf("unknown timeout duration: %v", err)
				}
				if dur < 0 {
					return c.Err("non-negative duration required for timeout value")
				}
				config.Timeouts.ReadTimeout = dur
				config.Timeouts.ReadHeaderTimeout = dur
				config.Timeouts.WriteTimeout = dur
				config.Timeouts.IdleTimeout = dur
			}
		}
	}

	return nil
}


text:
<?php
/*
 * This file is part of the Sulu CMS.
 *
 * (c) MASSIVE ART WebServices GmbH
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace Sulu\Bundle\Sales\OrderBundle\Tests;

use Doctrine\ORM\EntityManager;
use Sulu\Bundle\ContactBundle\Entity\AccountInterface;
use Sulu\Bundle\ContactBundle\Entity\Address;
use Sulu\Bundle\Sales\CoreBundle\Entity\OrderAddressInterface;
use Sulu\Bundle\Sales\CoreBundle\Item\ItemFactoryInterface;
use Sulu\Bundle\TestBundle\Testing\SuluTestCase;
use Sulu\Component\Contact\Model\ContactInterface;
use Sulu\Component\Contact\Model\ContactRepositoryInterface;
use Symfony\Component\HttpKernel\Client;

class OrderTestBase extends SuluTestCase
{
    protected $locale = 'en';

    protected static $orderStatusEntityName = 'SuluSalesOrderBundle:OrderStatus';

    /**
     * @var OrderDataSetup
     */
    protected $data;

    /**
     * @var EntityManager
     */
    protected $em;

    /**
     * @var Client
     */
    protected $client;

    /**
     * {@inheritdoc}
     */
    public function setUp()
    {
        $this->em = $this->getEntityManager();
        $this->purgeDatabase();
        $this->setUpTestData();
        $this->client = $this->createAuthenticatedClient();
        $this->em->flush();
    }

    /**
     * Setup order test data.
     */
    protected function setUpTestData()
    {
        $this->data = new OrderDataSetup($this->em, $this->getItemFactory(), $this->getContactRepository());
    }

    /**
     * Compares an order-address response with its origin entities.
     *
     * @param OrderAddressInterface $orderAddress
     * @param Address $address
     * @param ContactInterface $contact
     * @param AccountInterface $account
     */
    protected function checkOrderAddress(
        $orderAddress,
        Address $address,
        ContactInterface $contact,
        AccountInterface $account = null
    ) {
        // Contact
        $this->assertEquals($contact->getFirstName(), $orderAddress->firstName);
        $this->assertEquals($contact->getLastName(), $orderAddress->lastName);
        if ($contact->getTitle() !== null) {
            $this->assertEquals($contact->getTitle()->getTitle(), $orderAddress->title);
        }

        // Address
        $this->assertEqualsIfExists($address->getStreet(), $orderAddress, 'street');
        $this->assertEqualsIfExists($address->getAddition(), $orderAddress, 'addition');
        $this->assertEqualsIfExists($address->getNumber(), $orderAddress, 'number');
        $this->assertEqualsIfExists($address->getCity(), $orderAddress, 'city');
        $this->assertEqualsIfExists($address->getZip(), $orderAddress, 'zip');
        $this->assertEqualsIfExists($address->getCountry()->getName(), $orderAddress, 'country');
        $this->assertEqualsIfExists($address->getPostboxNumber(), $orderAddress, 'postboxNumber');
        $this->assertEqualsIfExists($address->getPostboxCity(), $orderAddress, 'postboxCity');
        $this->assertEqualsIfExists($address->getPostboxPostcode(), $orderAddress, 'postboxPostcode');

        // Account
        if ($account) {
            $this->assertEqualsIfExists($account->getName(), $orderAddress, 'accountName');
            $this->assertEqualsIfExists($account->getUid(), $orderAddress, 'uid');
        }
    }

    /**
     * Asserts equality if object's attribute exist.
     *
     * @param mixed $firstValue
     * @param \stdClass $secondObject
     * @param string $value
     */
    protected function assertEqualsIfExists($firstValue, $secondObject, $value)
    {
        if ($firstValue !== null) {
            $this->assertEquals($firstValue, $secondObject->$value);
        }
    }

    /**
     * @return ItemFactoryInterface
     */
    protected function getItemFactory()
    {
        return $this->getContainer()->get('sulu_sales_core.item_factory');
    }

    /**
     * @return ContactRepositoryInterface
     */
    private function getContactRepository()
    {
        return $this->getContainer()->get('sulu.repository.contact');
    }
}


text:
package io.tessilab.oss.hypop.execution.stopCondition;

import io.tessilab.oss.hypop.results.ProcessResult;
import org.apache.logging.log4j.LogManager;

/**
 * A stop condition based on the number of jobs to do.
 * @author Andres BEL ALONSO
 * @param <SCORE> The score of the quality of an execution
 * @param <PROCESSRESULT> The class containing all the information about a process result
 */
public class JobsToDoStopCondition<SCORE extends Comparable<SCORE>, PROCESSRESULT extends ProcessResult<SCORE>> extends StopCondition<SCORE,PROCESSRESULT> {

    private static final org.apache.logging.log4j.Logger LOGGER = LogManager.getLogger(JobsToDoStopCondition.class);

    public static class Config<SCORE extends Comparable<SCORE>, PROCESSRESULT extends ProcessResult<SCORE>>
            extends StopCondition.Config<SCORE,PROCESSRESULT> {

        private final int nbWorksToDo;

        public Config(int nbWorksToDo) {
            this.nbWorksToDo = nbWorksToDo;
        }

        @Override
        protected StopCondition<SCORE,PROCESSRESULT> build() {
            return new JobsToDoStopCondition<>(nbWorksToDo);
        }

    }

    private final int nbWorksToDo;
    private int computedWorks =0;

    public JobsToDoStopCondition(int nbWorksToDo) {
        this.nbWorksToDo = nbWorksToDo;
    }

    @Override
    public boolean continueWork() {
        if(computedWorks<nbWorksToDo) {
            return true;
        } else {
            LOGGER.debug("The job is done is done. The {} jobs have been compute",this.nbWorksToDo);
            return false;
        }
    }

    @Override
    public int getJobsToDo() {
        return nbWorksToDo - computedWorks;
    }

    @Override
    public void updateObserver(PROCESSRESULT obj) {
        computedWorks ++;
    }

}


text:
MockServer
==========
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.byoutline.mockserver/mockserver/badge.svg?style=flat)](http://mvnrepository.com/artifact/com.byoutline.mockserver/mockserver)
 master:  [![Build Status](https://travis-ci.org/byoutline/MockServer.svg?branch=master)](https://travis-ci.org/byoutline/MockServer)
 develop: [![Build Status](https://travis-ci.org/byoutline/MockServer.svg?branch=develop)](https://travis-ci.org/byoutline/MockServer)

Simple Http server that makes simulating API easy.

You can configure what response should mock server return for each path/method/queries combination (be it a json, or different file) and simulate network delay.

To use create a config file that contains on what calls server should respond in what way and start a server:

```java
HttpMockServer.startMockApiServer(configReader, NetworkType.VPN);
```

## Config syntax
Mock server is synchronized with single json file for simplicity. At top level you can specify:

```
{
    "port" : 8000, // port at which server will be started
    "requests" :
    [
        //array of objects representing requests with responses
    ]
}
```

Request are matched top to bottom until first match is found. This allow to make specific/general approach and test e.g. success/error responses.

Each of request objects represents both request and response. Allowed fields:

### Request part

#### *method* (string) required!
HTTP method e.g. GET/PUT/POST/DELETE

```
{
    "method":"GET"
}
```

#### *path* (string/object) required!
Everything in url that stands after http://localhost:port e.g. /api/auth

String version specifies only base path. Object version allows also to specify query params i.e. everything that goes after "?".

Syntax for path object:

```
{
    "base": "/authentication/login", //path that goes before "?"
    "queries": //will be converted to ?username=user&password=pass1234
    {
        "username": "user",
        "password": "pass1234"
    }
}
```

#### *body* (string)
Optional body of request, can be used to match POST/PUT calls by exact string match

### Response part
#### *code* (int)
Html response code to be returned

#### *response* (string/object)
Response body to be returned.

#### *response file* (string)
Alternative to *response*, name of file that contains body to be returned as response. Should be stored in directory specified by *getResponseConfigFromFile()*.

#### *response headers* (string)
Allows to specify headers that should be returned in response.

```
{
    "response headers":
    {
        "Set-Cookie": "JSESSIONID=ABCDE1234567890ABCDE1234567890; HttpOnly"
    }
}
```

Example config:

```json
{
    "port": 8098,
    "requests": [
        {
            "method": "GET",
            "path": "/books",
            "response file": "books.json"
        },
        {
            "method": "POST",
            "path": {
                "base": "/authentication/login",
                "queries": {
                    "username": "user",
                    "password": "pass1234"
                }
            },
            "code": 200,
            "response": "OK",
            "response headers": {
                "Set-Cookie": "JSESSIONID=ABCDE1234567890ABCDE1234567890; HttpOnly"
            }
        },
        {
            "method": "POST",
            "path": {
                "base": "/authentication/login",
                "queries": {
                    "username": ".*",
                    "password": ".*"
                }
            },
            "code": 401,
            "response": "Auth failed."
        },
        {
            "method": "DELETE",
            "path": {
                "urlPattern": "/books/[0-9]+",
                "queries": {
                    "otp": ".*"
                }
            },
            "code": 204,
            "response": ""
        }
    ]
}
```

#### Usage on Android ####
For typical use Android take a look at AndroidStubServer.

#### Latest Changes ####
  * 1.4.2 When returning 404 also log what path was requested.
  * 1.4.1 Fix invalid response returned when ```NONE``` ```NetworkType``` was used.
  * 1.4.0 If folder is requested and it contains index.html it will be returned instead of 404.
  ConfigReader requires now implementing isFolder method.


text: a tool to get the color or size of pixals on the screen for windows OS.


text:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.igormaznitsa</groupId>
        <artifactId>mind-map</artifactId>
        <version>1.6.0-SNAPSHOT</version>
    </parent>

    <artifactId>mind-map-annotations</artifactId>
    <packaging>jar</packaging>

    <name>MMD Annotations</name>
    <description>Set of annotations to mark sources to generate MMD maps</description>

    <profiles>
        <profile>
            <id>publish</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-assembly-plugin</artifactId>
                        <executions>
                            <execution>
                                <id>make-bundle</id>
                                <phase>install</phase>
                                <goals>
                                    <goal>single</goal>
                                </goals>
                                <configuration>
                                    <descriptors>
                                        <descriptor>src/assemble/bundle.xml</descriptor>
                                    </descriptors>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-jar-plugin</artifactId>
                        <configuration>
                            <archive>
                                <manifestEntries>
                                    <Automatic-Module-Name>igormaznitsa.mmd.processor</Automatic-Module-Name>
                                </manifestEntries>
                            </archive>
                        </configuration>
                    </plugin>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-source-plugin</artifactId>
                        <executions>
                            <execution>
                                <id>generate-sources</id>
                                <phase>package</phase>
                                <goals>
                                    <goal>jar</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-javadoc-plugin</artifactId>
                    </plugin>

                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-gpg-plugin</artifactId>
                        <executions>
                            <execution>
                                <id>sign-artifacts</id>
                                <phase>verify</phase>
                                <goals>
                                    <goal>sign</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <release>8</release>
                    <source>1.8</source>
                    <target>1.8</target>
                    <showDeprecation>true</showDeprecation>
                    <showWarnings>true</showWarnings>
                    <compilerArgument>-proc:none</compilerArgument>
                    <compilerArgs>
                        <arg>-Xlint:all</arg>
                    </compilerArgs>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>


text:
namespace Subsystems {
	extern Drive_Base * drive_base;
	extern Outtake * outtake;
	void initialize();
}

#endif // SUBSYSTEMS_HPP


text:
namespace blink {

XRGripSpace::XRGripSpace(XRSession* session, XRInputSource* source)
    : XRSpace(session), input_source_(source) {}

absl::optional<TransformationMatrix> XRGripSpace::MojoFromNative() {
  // Grip is only available when using tracked pointer for input.
  if (input_source_->TargetRayMode() !=
      device::mojom::XRTargetRayMode::POINTING) {
    return absl::nullopt;
  }

  return input_source_->MojoFromInput();
}

bool XRGripSpace::EmulatedPosition() const {
  return input_source_->emulatedPosition();
}

device::mojom::blink::XRNativeOriginInformationPtr XRGripSpace::NativeOrigin()
    const {
  // Grip space's native origin is valid only when using tracked pointer for
  // input.
  if (input_source_->TargetRayMode() !=
      device::mojom::XRTargetRayMode::POINTING) {
    return nullptr;
  }

  return device::mojom::blink::XRNativeOriginInformation::
      NewInputSourceSpaceInfo(device::mojom::blink::XRInputSourceSpaceInfo::New(
          input_source_->source_id(),
          device::mojom::blink::XRInputSourceSpaceType::kGrip));
}

bool XRGripSpace::IsStationary() const {
  // Grip space is a space derived off of input source, so it is not considered
  // stationary.
  return false;
}

std::string XRGripSpace::ToString() const {
  return "XRGripSpace";
}

void XRGripSpace::Trace(Visitor* visitor) const {
  visitor->Trace(input_source_);
  XRSpace::Trace(visitor);
}

}  // namespace blink


text:
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <parent>
        <groupId>in.jlibs</groupId>
        <artifactId>jlibs-parent</artifactId>
        <version>3.0.1</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>
    <artifactId>jlibs-xml-crawler</artifactId>
    <packaging>jar</packaging>

    <name>xml-crawler</name>
    <description>Crawl XML(wsdl, xsd, xsl) documents</description>

    <properties>
        <javaModuleName>in.jlibs.xml.crawler</javaModuleName>
    </properties>

    <dependencies>
        <dependency>
            <groupId>in.jlibs</groupId>
            <artifactId>jlibs-xml</artifactId>
            <version>${project.version}</version>
        </dependency>
    </dependencies>

</project>


text:
class AddDeltaToProjects < ActiveRecord::Migration
  def change
    add_column :projects, "delta", :boolean, :default => false
  end
end


text:
/*****************************************************************************/
/**
 *  @file   VertexShader.h
 *  @author Naohisa Sakamoto
 */
/*****************************************************************************/
#pragma once
#include <kvs/ShaderObject>
#include <kvs/ShaderSource>

namespace kvs
{

/*===========================================================================*/
/**
 *  Vertex shader class.
 */
/*===========================================================================*/
class VertexShader : public kvs::ShaderObject
{
public:
    using SuperClass = kvs::ShaderObject;

public:
    VertexShader():
        kvs::ShaderObject( GL_VERTEX_SHADER ) {}

    VertexShader( const kvs::ShaderSource& source ):
        kvs::ShaderObject( GL_VERTEX_SHADER )
    {
        SuperClass::create();
        SuperClass::setSource( source );
    }
};

} // end of namespace kvs


text:
Maintenance

Pour optimiser le temps de génération des pages, Piwigo utilise des informations en cache.
 Par exemple, au lieu de compter le nombre d'éléments contenus dans chaque catégorie à
 chaque rechargement de page, cette information est stockée dans la base de données.
 En théorie, cette information doit toujours être correcte, mais parfois une erreur peut
 survenir et l'information en cache devient fausse.

Certaines informations deviennent inutiles avec le temps.
Les supprimer de la base de données libère de l'espace disque.

    Eléments non liés:
    Affiche les images qui ne sont associées à aucune catégorie virtuelle

    Fichiers portant le même nom dans plusieurs catégories physiques :
    Affiche les images ou les éventuels fichiers qui pourraient être trouvés dans plusieurs catégories.

Mettre à jour les informations des catégories :
  Pour chaque catégorie, les informations suivantes sont contrôlées, et mises à jour le cas échéant :
  liste des catégories mères, nombre d'éléments, date du dernier élément, position parmi les
  catégories soeurs, position dans l'arbre complet des catégories. Cette action vérifie
  également la cohérence des représentants.

Mettre à jour les informations des images :
Pour chaque image, les informations mises àjour sont : chemin complet vers le
fichier et note moyenne. Attention, ne pas confondre : les méta-données sont
synchronisées sur l'écran Administration, Catégories, Synchroniser
ou sur l'écran Modifier les informations d'une image (accessible depuis la page de visualisation d'une image picture.php).

Réparer et optimiser la base de données :
Effectue des opérations de ré-ordonnancement, réparation et optimisation sur  chaque table de la base de données.

Purger le détail de l'historique :
Supprime toutes les lignes de la table history. L'écran
Administration, Spéciales, Historique ne montre alors plus aucune information sur le passé.
Attention : toutes les données seront perdues, sans aucun possibilité de récupération.

Purger la synthèse de l'historique :
Supprime toutes les informations  récapitulatives (obtenues à partir du détail de l'historique).

Purger les sessions : Supprimer les sessions expirées.

Purger les flux de notification jamais utilisés

Purger l'historique des recherches

Purger les templates compilés


text:
using namespace UnitTest;
using namespace std;
using namespace lomse;

//=======================================================================================
// test for traversing the Internal Model with Visitor objects
//=======================================================================================
#define k_show_tree    0    //set to 1 for visualizing the visited tree

class MyVisitor
{
protected:
    LibraryScope& m_libraryScope;
    int m_indent;
    int m_nodesIn;
    int m_nodesOut;
    int m_maxDepth;

public:
    MyVisitor(LibraryScope& libraryScope)
        : m_libraryScope(libraryScope), m_indent(0), m_nodesIn(0)
        , m_nodesOut(0), m_maxDepth(0) {}
	virtual ~MyVisitor() {
#if (k_show_tree == 1)
	    cout << "---------------------------------------------------------" << endl;
#endif
	}

    int num_in_nodes() { return m_nodesIn; }
    int num_out_nodes() { return m_nodesOut; }
    int max_depth() { return m_maxDepth; }

    void start_visiting(ImoObj* pImo)
    {
        int type = pImo->get_obj_type();
        const string& name = pImo->get_name();
#if (k_show_tree == 0)
        if (name == "unknown")
        {
#endif
            if (pImo->has_visitable_children())
            {
                cout << indent() << "(" << name << " type " << type
                     << ", id=" << pImo->get_id() << endl;

            }
            else
            {
                cout << indent() << "(" << name << " type " << type
                     << ", id=" << pImo->get_id() << ")" << endl;
            }
#if (k_show_tree == 0)
        }
#endif

        m_indent++;
        m_nodesIn++;
        if (m_maxDepth < m_indent)
            m_maxDepth = m_indent;
    }

	void end_visiting(ImoObj* pImo)
    {
        m_indent--;
        m_nodesOut++;
        if (!pImo->has_visitable_children())
            return;
#if (k_show_tree == 1)
        cout << indent() << ")" << endl;
#endif
    }

    string indent()
    {
        string spaces = "";
        for (int i=0; i < 3*m_indent; ++i)
            spaces += " ";
        return spaces;
    }

};

//---------------------------------------------------------------------------------------
class MyObjVisitor : public Visitor<ImoObj>, public MyVisitor
{
public:
    MyObjVisitor(LibraryScope& libraryScope)
        : Visitor<ImoObj>(), MyVisitor(libraryScope) {}
	~MyObjVisitor() {}

    void start_visit(ImoObj* pImo) { start_visiting(pImo); }
    void end_visit(ImoObj* pImo) { end_visiting(pImo); }
};

//---------------------------------------------------------------------------------------
class MyParaVisitor : public Visitor<ImoParagraph>, public MyVisitor
{
public:
    MyParaVisitor(LibraryScope& libraryScope)
        : Visitor<ImoParagraph>(), MyVisitor(libraryScope) {}
	~MyParaVisitor() {}

    void start_visit(ImoParagraph* pImo) { start_visiting(pImo); }
    void end_visit(ImoParagraph* pImo) { end_visiting(pImo); }
};

//---------------------------------------------------------------------------------------
class MyHPVisitor : public Visitor<ImoParagraph>
                  , public Visitor<ImoHeading>
                  , public MyVisitor
{
public:
    MyHPVisitor(LibraryScope& libraryScope)
        : Visitor<ImoParagraph>(), Visitor<ImoHeading>()
        , MyVisitor(libraryScope) {}
	~MyHPVisitor() {}

    void start_visit(ImoParagraph* pImo) { start_visiting(pImo); }
    void start_visit(ImoHeading* pImo) { start_visiting(pImo); }
    void end_visit(ImoParagraph* pImo) { end_visiting(pImo); }
    void end_visit(ImoHeading* pImo) { end_visiting(pImo); }
};

//---------------------------------------------------------------------------------------
class MyScoreVisitor : public Visitor<ImoScore>, public MyVisitor
{
public:
    MyScoreVisitor(LibraryScope& libraryScope)
        : Visitor<ImoScore>(), MyVisitor(libraryScope) {}
	~MyScoreVisitor() {}

    void start_visit(ImoScore* pImo) { start_visiting(pImo); }
    void end_visit(ImoScore* pImo) { end_visiting(pImo); }
};

//---------------------------------------------------------------------------------------
class ImVisitorTestFixture
{
public:
    LibraryScope m_libraryScope;
    std::string m_scores_path;

    ImVisitorTestFixture()     //SetUp fixture
        : m_libraryScope(cout)
    {
        m_scores_path = TESTLIB_SCORES_PATH;
        m_libraryScope.set_default_fonts_path(TESTLIB_FONTS_PATH);
    }

    ~ImVisitorTestFixture()    //TearDown fixture
    {
    }

    inline const char* test_name()
    {
        return UnitTest::CurrentTest::Details()->testName;
    }

    inline void failure_header()
    {
        cout << endl << "*** Failure in " << test_name() << ":" << endl;
    }

    //-----------------------------------------------------------------------------------
    bool check_errormsg(const stringstream& msg, const stringstream& expected)
    {
        if (msg.str() != expected.str())
        {
            failure_header();
            cout << "     msg=[" << msg.str() << "]" << endl;
            cout << "expected=[" << expected.str() << "]" << endl;
            return false;
        }
        return true;
    }

    //-----------------------------------------------------------------------------------
    bool check_result(MyVisitor& v, int depth, int inNodes)
    {
        if (v.max_depth() != depth
            || v.num_in_nodes() != inNodes
            || v.num_out_nodes() != v.num_in_nodes()
           )
        {
            failure_header();
            if (v.max_depth() != depth)
                cout << "   max_depth=" << v.max_depth() << ", expected=" << depth << endl;
            if (v.num_in_nodes() != inNodes)
                cout << "   num_in_nodes=" << v.num_in_nodes() << ", expected=" << inNodes << endl;
            if (v.num_out_nodes() != v.num_in_nodes())
                cout << "   num_out_nodes=" << v.num_out_nodes() << ", expected=" << inNodes << endl;
            return false;
        }
        return true;
    }

};

SUITE(ImVisitorTest)
{
    TEST_FIXTURE(ImVisitorTestFixture, Document)
    {
        Document doc(m_libraryScope);
        doc.from_string("(lenmusdoc (vers 2.3) (content))" );
        ImoDocument* pRoot = doc.get_im_root();

        MyObjVisitor v(m_libraryScope);
        pRoot->accept_visitor(v);

        CHECK( check_result(v, 3, 13) );
    }

    TEST_FIXTURE(ImVisitorTestFixture, EbookExample)
    {
        Document doc(m_libraryScope);
        doc.from_file(m_scores_path + "09002-ebook-example.lms" );
        ImoDocument* pRoot = doc.get_im_root();

        MyObjVisitor v(m_libraryScope);
        pRoot->accept_visitor(v);

        CHECK( check_result(v, 9, 136) );
    }

//    TEST_FIXTURE(ImVisitorTestFixture, EbookExample2)
//    {
//        Document doc(m_libraryScope);
//        doc.from_file(m_scores_path + "60005-ebook-three-pages.lms" );
//        ImoDocument* pRoot = doc.get_im_root();
//
//        MyObjVisitor v(m_libraryScope);
//        pRoot->accept_visitor(v);
//
//        cout << "max_depth=" << v.max_depth()
//             << ", num_in_nodes=" << v.num_in_nodes()
//             << ", num_out_nodes=" << v.num_out_nodes() << endl;
//        CHECK( v.max_depth() == 9 );
//        CHECK( v.num_in_nodes() == 1321 );
//        CHECK( v.num_out_nodes() == v.num_in_nodes() );
//    }

    TEST_FIXTURE(ImVisitorTestFixture, ParagraphVisitor)
    {
        Document doc(m_libraryScope);
        doc.from_file(m_scores_path + "09002-ebook-example.lms" );
        ImoDocument* pRoot = doc.get_im_root();

        MyParaVisitor v(m_libraryScope);
        pRoot->accept_visitor(v);

        CHECK( check_result(v, 1, 4) );
    }

    TEST_FIXTURE(ImVisitorTestFixture, ParagraphHeadingVisitor)
    {
        Document doc(m_libraryScope);
        doc.from_file(m_scores_path + "09002-ebook-example.lms" );
        ImoDocument* pRoot = doc.get_im_root();

        MyHPVisitor v(m_libraryScope);
        pRoot->accept_visitor(v);

        CHECK( check_result(v, 1, 6) );
    }

};


text:
package org.surmon.pattern.detector.houghcircle;

import java.awt.Point;
import java.awt.geom.Point2D;
import java.util.Objects;
import org.surmon.pattern.api.AbstractParticle;
import org.surmon.pattern.api.Position;
import org.surmon.pattern.api.Position2D;

/**
 * Implementation of Particle which represents particle in shape of circle.
 * These particles can be detected eg. via circle HoughTransformation.
 *
 * @author palasjiri
 */
public class CircleParticle extends AbstractParticle implements Comparable<CircleParticle> {

    protected Position2D position;
    protected double radius;

    private boolean visited = false;
    private boolean deleted = false;

    public CircleParticle(long id, Point point) {
        this(id, point.x, point.y, 0);
    }

    public CircleParticle(long id, Point2D point){
        this(id, point.getX(), point.getY(), 0);
    }

    public CircleParticle(long id, double x, double y, double radius) {
        super(id);
        position = new Position2D(x, y);
        this.radius = radius;
    }

    public double getRadius() {
        return radius;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }

    @Override
    public String toString() {
        return "Circle: " + position.toString() + " " + radius;
    }

    @Override
    public int compareTo(CircleParticle o) {
        if (radius == o.radius) {
            return 0;
        } else if (radius > o.radius) {
            return 1;
        } else {
            return -1;
        }
    }

    public boolean isVisited() {
        return visited;
    }

    public void setVisited(boolean visited) {
        this.visited = visited;
    }

    public boolean isDeleted() {
        return deleted;
    }

    public void setDeleted(boolean deleted) {
        this.deleted = deleted;
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 59 * hash + (int) (this.id ^ (this.id >>> 32));
        hash = 59 * hash + Objects.hashCode(this.position);
        hash = 59 * hash + (int) (Double.doubleToLongBits(this.radius) ^ (Double.doubleToLongBits(this.radius) >>> 32));
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final CircleParticle other = (CircleParticle) obj;
        if (this.id != other.id) {
            return false;
        }
        if (!Objects.equals(this.position, other.position)) {
            return false;
        }
        if (Double.doubleToLongBits(this.radius) != Double.doubleToLongBits(other.radius)) {
            return false;
        }
        return true;
    }

    @Override
    public Position getPosition() {
        return position;
    }

    @Override
    public double getSize() {
        return radius;
    }
}


text:
package com.infinityraider.infinitylib.block;

import com.infinityraider.infinitylib.block.tile.IInfinityTileEntity;
import com.infinityraider.infinitylib.block.tile.IInfinityTileEntityType;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.EntityBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityTicker;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.common.extensions.IForgeBlock;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.function.BiFunction;

@ParametersAreNonnullByDefault
public interface IInfinityBlockWithTile<T extends BlockEntity & IInfinityTileEntity> extends IInfinityBlock, IForgeBlock, EntityBlock {
    @Override
    @Nullable
    default T newBlockEntity(@Nonnull BlockPos pos, @Nonnull BlockState state) {
        return this.getTileEntityFactory().apply(pos, state);
    }

    BiFunction<BlockPos, BlockState, T> getTileEntityFactory();

    @Nullable
    @Override
    @SuppressWarnings("unchecked")
    default <TE extends BlockEntity> BlockEntityTicker<TE> getTicker(Level level, BlockState state, BlockEntityType<TE> type) {
        if(type instanceof IInfinityTileEntityType) {
            if(((IInfinityTileEntityType) type).isTicking()) {
                return (l, p, s, t) -> {
                    if(t instanceof IInfinityTileEntity) {
                        ((IInfinityTileEntity) t).tick();
                    }
                };
            }
        }
        return EntityBlock.super.getTicker(level, state, type);
    }
}