// File: /workspace/github_cpp_makefile_star2_O2/xelia-it[P]mustache/src/mustache-light.cpp
// Function: mustache::Mustache::searchVariableInContext(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&)
json Mustache::searchVariableInContext(const string& key) {
        // TODO: better to use a constant
        if (key == "@index") {
                json value = currentListCounter_;
                return value;
        }
        if (key == "@first") {
                json value = (currentListCounter_ == 0);
                return value;
        }
        // Get the current context
        json top = stack_.top();
        LOG_END("SEARCH CONTEXT:");
        LOG_END(top.dump(2));
        if (top.is_null()) {
                return "null"_json;
        }

        string::size_type start;
        string::size_type stop;
        string::size_type index = string::npos;
        string newKey = key;

        if ((start = key.find_first_of("[")) != string::npos) {
                if ((stop = key.find_first_of("]")) == string::npos) {
                        error("Missing ] in array selection");
                }
                if (start + 1 == stop) {
                        error("Index is empty");
                }
                string array = key.substr(0, start);
                string indexAsString = key.substr(start + 1, stop - 1);

                newKey = array;
                index = std::stoul(indexAsString);
        }

        json::const_iterator it = top.find(newKey);
        if (it == top.end()) {
                LOG_END("NOT FOUND:");
                throw std::invalid_argument("Variable " + key + " not found");
        } else if (index == string::npos) {
                LOG_END("NORMAL USE *it:");
                json value = *it;
                return value;
        } else {
                LOG_END("USE INDEX:");
                // top exists at this point
                if (it->is_array()) {
                    LOG_END("USE ARRAY:");
                    if (index >= it->size()) {
                      LOG_END("OUT OF RANGE:");
                      throw std::out_of_range("Index " + std::to_string(index) + " is out of range");
                    } else {
                      LOG_END("IN RANGE:");
                    }
                }
                json value = (*it)[index];
                return value;
        }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xb8, %rsp
movq %rdx, %r14
movq %rsi, %r15
movq %rdi, %rbx
leaq 0x1321c(%rip), %rsi     # 0x3cd92
movq %rdx, %rdi
callq 0x27730
testb %al, %al
je 0x29b99
addq $0xf0, %r15
movq %rbx, %rdi
movq %r15, %rsi
callq 0x27410
jmp 0x29d98
leaq 0x131f9(%rip), %rsi     # 0x3cd99
movq %r14, %rdi
callq 0x27730
testb %al, %al
je 0x29bcb
cmpq $0x0, 0xf0(%r15)
leaq -0xb8(%rbp), %rsi
sete (%rsi)
movq %rbx, %rdi
callq 0x25c50
jmp 0x29d98
movq 0x128(%r15), %rsi
cmpq 0x130(%r15), %rsi
jne 0x29beb
movq 0x140(%r15), %rax
movl $0x200, %esi            # imm = 0x200
addq -0x8(%rax), %rsi
addq $-0x10, %rsi
leaq -0x78(%rbp), %r15
movq %r15, %rdi
callq 0x25190
cmpb $0x0, (%r15)
je 0x29cb9
leaq -0xb8(%rbp), %rdi
movq %r14, %rsi
callq 0x26a70
leaq 0x16e07(%rip), %rsi     # 0x40a22
movq %r14, %rdi
xorl %edx, %edx
callq 0x25890
cmpq $-0x1, %rax
je 0x29cd0
movq %rax, %r12
leaq 0x15b7b(%rip), %rsi     # 0x3f7b4
movq %r14, %rdi
xorl %edx, %edx
callq 0x25890
cmpq $-0x1, %rax
je 0x29e12
movq %rax, %r15
leaq 0x1(%r12), %r13
cmpq %rax, %r13
je 0x29e2f
leaq -0x48(%rbp), %rdi
movq %r14, %rsi
xorl %edx, %edx
movq %r12, %rcx
callq 0x26450
decq %r15
leaq -0x68(%rbp), %rdi
movq %r14, %rsi
movq %r13, %rdx
movq %r15, %rcx
callq 0x26450
leaq -0xb8(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x259e0
leaq -0x68(%rbp), %rdi
pushq $0xa
popq %rdx
xorl %esi, %esi
callq 0x25350
movq %rax, %r15
leaq -0x68(%rbp), %rdi
callq 0x27788
leaq -0x48(%rbp), %rdi
callq 0x27788
jmp 0x29cd4
leaq 0x130e0(%rip), %rsi     # 0x3cda0
pushq $0x4
popq %rdx
movq %rbx, %rdi
callq 0x25d80
jmp 0x29d8f
pushq $-0x1
popq %r15
leaq -0x68(%rbp), %rdi
leaq -0x78(%rbp), %rsi
leaq -0xb8(%rbp), %rdx
callq 0x25650
leaq -0x68(%rbp), %r12
movq (%r12), %rax
leaq -0x48(%rbp), %r13
movq %rax, (%r13)
movups 0x8(%r12), %xmm0
movups %xmm0, 0x8(%r13)
movq 0x18(%r12), %rax
movq %rax, 0x18(%r13)
leaq -0x78(%rbp), %rsi
movq %r12, %rdi
callq 0x25970
movq %r13, %rdi
movq %r12, %rsi
callq 0x26440
testb %al, %al
jne 0x29dad
cmpq $-0x1, %r15
je 0x29d6f
leaq -0x48(%rbp), %rdi
callq 0x26fd0
cmpb $0x2, (%rax)
jne 0x29d59
leaq -0x48(%rbp), %rdi
callq 0x26fd0
movq %rax, %rdi
callq 0x26da0
cmpq %rax, %r15
jae 0x29e4c
leaq -0x48(%rbp), %rdi
callq 0x258a0
movq %rax, %rdi
movq %r15, %rsi
callq 0x27120
jmp 0x29d78
leaq -0x48(%rbp), %rdi
callq 0x258a0
movq %rbx, %rdi
movq %rax, %rsi
callq 0x25190
leaq -0xb8(%rbp), %rdi
callq 0x27788
leaq -0x78(%rbp), %rdi
callq 0x26730
movq %rbx, %rax
addq $0xb8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $0x10
popq %rdi
callq 0x25840
movq %rax, %r15
leaq 0x13012(%rip), %rsi     # 0x3cdd1
leaq -0x98(%rbp), %rdi
movq %r14, %rdx
callq 0x261d0
leaq 0x13006(%rip), %rdx     # 0x3cddb
leaq -0x68(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x25300
movb $0x1, %r14b
leaq -0x68(%rbp), %rsi
movq %r15, %rdi
callq 0x27270
xorl %r14d, %r14d
movq 0x221d2(%rip), %rsi     # 0x4bfd0
movq 0x2219b(%rip), %rdx     # 0x4bfa0
movq %r15, %rdi
callq 0x27240
jmp 0x29ebf
leaq 0x12f8c(%rip), %rsi     # 0x3cda5
leaq -0x48(%rbp), %rdi
leaq -0x68(%rbp), %rdx
callq 0x25670
leaq -0x48(%rbp), %rsi
callq 0x26890
leaq 0x12f8c(%rip), %rsi     # 0x3cdc2
leaq -0x48(%rbp), %rdi
leaq -0x68(%rbp), %rdx
callq 0x25670
leaq -0x48(%rbp), %rsi
callq 0x26890
pushq $0x10
popq %rdi
callq 0x25840
movq %rax, %r14
leaq -0xd8(%rbp), %rdi
movq %r15, %rsi
callq 0x25560
leaq 0x12f79(%rip), %rsi     # 0x3cde6
leaq -0x98(%rbp), %rdi
leaq -0xd8(%rbp), %rdx
callq 0x27200
leaq 0x12f66(%rip), %rdx     # 0x3cded
leaq -0x68(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x25300
movb $0x1, %r15b
leaq -0x68(%rbp), %rsi
movq %r14, %rdi
callq 0x26dd0
xorl %r15d, %r15d
movq 0x22108(%rip), %rsi     # 0x4bfb8
movq 0x220d1(%rip), %rdx     # 0x4bf88
movq %r14, %rdi
callq 0x27240
movq %rax, %rbx
leaq -0x68(%rbp), %rdi
callq 0x27788
jmp 0x29ed3
movq %rax, %rbx
movb $0x1, %r15b
leaq -0x98(%rbp), %rdi
callq 0x27788
jmp 0x29ee7
movq %rax, %rbx
movb $0x1, %r15b
leaq -0xd8(%rbp), %rdi
callq 0x27788
testb %r15b, %r15b
jne 0x29efd
jmp 0x29f6a
movq %rax, %rbx
movq %r14, %rdi
jmp 0x29f37
movq %rax, %rbx
leaq -0x68(%rbp), %rdi
callq 0x27788
jmp 0x29f16
movq %rax, %rbx
movb $0x1, %r14b
leaq -0x98(%rbp), %rdi
callq 0x27788
testb %r14b, %r14b
jne 0x29f34
jmp 0x29f6a
jmp 0x29f40
jmp 0x29f67
jmp 0x29f40
jmp 0x29f67
movq %rax, %rbx
movq %r15, %rdi
callq 0x25d70
jmp 0x29f6a
jmp 0x29f4b
movq %rax, %rbx
jmp 0x29f5c
jmp 0x29f67
jmp 0x29f67
jmp 0x29f67
movq %rax, %rbx
jmp 0x29f76
movq %rax, %rbx
leaq -0x68(%rbp), %rdi
callq 0x27788
leaq -0x48(%rbp), %rdi
callq 0x27788
jmp 0x29f6a
movq %rax, %rbx
leaq -0xb8(%rbp), %rdi
callq 0x27788
leaq -0x78(%rbp), %rdi
callq 0x26730
movq %rbx, %rdi
callq 0x27310
nop