Full Code of llakssz/CIAngel for AI

master ffc34fb04d7d cached
26 files
1.9 MB
863.8k tokens
313 symbols
1 requests
Download .txt
Showing preview only (1,950K chars total). Download the full file or copy to clipboard to get everything.
Repository: llakssz/CIAngel
Branch: master
Commit: ffc34fb04d7d
Files: 26
Total size: 1.9 MB

Directory structure:
gitextract_gw48o2es/

├── .gitmodules
├── Makefile
├── README.md
└── source/
    ├── cia.c
    ├── cia.h
    ├── config.cpp
    ├── config.h
    ├── data.h
    ├── font.h
    ├── fts_fuzzy_match.h
    ├── json/
    │   ├── json-forwards.h
    │   └── json.h
    ├── jsoncpp.cpp
    ├── lib.h
    ├── main.cpp
    ├── menu.cpp
    ├── menu.h
    ├── svchax/
    │   ├── svchax.c
    │   └── svchax.h
    ├── types.h
    ├── utf8proc/
    │   ├── LICENSE.md
    │   ├── utf8proc.c
    │   ├── utf8proc.h
    │   └── utf8proc_data.h
    ├── utils.cpp
    └── utils.h

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitmodules
================================================
[submodule "buildtools"]
	path = buildtools
	url = https://github.com/Steveice10/buildtools.git


================================================
FILE: Makefile
================================================
# TARGET #

TARGET := 3DS
LIBRARY := 0

ifeq ($(TARGET),3DS)
    ifeq ($(strip $(DEVKITPRO)),)
        $(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>devkitPro")
    endif

    ifeq ($(strip $(DEVKITARM)),)
        $(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
    endif
endif

# COMMON CONFIGURATION #

NAME := CIAngel

BUILD_DIR := build
OUTPUT_DIR := output
INCLUDE_DIRS := include
SOURCE_DIRS := source

BUILD_FILTER := source/svchax/test/test.c

EXTRA_OUTPUT_FILES :=

LIBRARY_DIRS := $(DEVKITPRO)/libctru
LIBRARIES := ctru m

BUILD_FLAGS := -DVERSION_STRING="\"`git describe --tags --abbrev=0`\"" -DREVISION_STRING="\"`git rev-parse --short HEAD`\""
RUN_FLAGS :=

# 3DS CONFIGURATION #

TITLE := $(NAME)
DESCRIPTION := CIA Downloader using Nintendo CDN
AUTHOR := _____
PRODUCT_CODE := CTR-H-ANGEL
UNIQUE_ID := 0xA617

SYSTEM_MODE := 64MB
SYSTEM_MODE_EXT := Legacy

ICON_FLAGS :=

ROMFS_DIR := romfs
BANNER_AUDIO := audio.wav
BANNER_IMAGE := banner.png
ICON := icon.png

# INTERNAL #

include buildtools/make_base


================================================
FILE: README.md
================================================
# CIAngel

# Archived, CDN access is not available anymore. RIP.


Now we can get games directly on the 3DS!
Using a Title ID and an encrypted title key, or searching for a title by name, GOOD CIAs will be produced or directly installed that can be redownloaded from eshop and updated from eshop if new content comes out. These CIAs will not interfere with content from eshop.

You can choose to create a CIA, install the game directly, or install only the ticket.



Many thanks for machinamentum and FirmwareDownloader! Thanks to make_cdn_cia!

License is GPL to comply with the usage of make_cdn_cia code.


This will be improved, updated, I look forward to people contributing to this project!

# Latest Version
You can scan the following QRCode in FBI to install the latest version of CIAngel, this will always point at the latest release's CIAngel.cia file:  
![CIAngel.cia](https://thedgtl.net/3ds/CIAngel.php?cachebust=2)

# Usage
## Search by name
CIAngel utilizes HBKBlib to search for titles by name. Data is read from /CIAngel/wings.json (Which is downloaded automatically on first launch) to search for the name entered.

## Download queue
When viewing the search result list, you can press X to add the title to the download queue. Selecting "Process download queue" will allow you to then download or install all of the queued titles one after another. This uses the currently selected download/install mode.

## Input.txt support
CIAngel can read a text file (sd:/CIAngel/input.txt) that has 2 lines.

The first line must be the title id.
The second line must be the encrypted title key.

# Thanks!
CIAngel has been developed with many contributions from the community, both ideas and code contributions. Many thanks to the following (non-exhaustive) list of contributors!
* Cearp
* Drakia
* superbudvar
* mysamdog
* cerea1killer
* machinamentum for the original FirmwareDownload code
* Steveice10 for many insights into CIA handling in FBI

# Building
CIAngel has a few dependencies required to build, as well as a git submodule that will need to be fetched.

When initially fetching the project, the easiest way to get the code and submodules for building is the following:

`git clone --recursive https://github.com/llakssz/CIAngel.git`

If you have already checked out the code without the submodules, you can run the following command in the project directory to fetch the submodule data:

`git submodule update --init --recursive`

CIAngel depends on the following projects:
- The latest version of [libctru](https://github.com/smealum/ctrulib)
- The latest version of [hbkb](https://gbatemp.net/threads/hbkblib-a-3ds-keyboard-library.397568/)

## Building and installing HBKB
HBKB doesn't currently have a 'make install' command, and has to be manually installed once built.

1. You will need to modify the Makefile to remove the DEVKITARM define at the top
2. Once you have run 'make', you will need to copy the resulting lib and header to your DEVKITARM directory:

   `cp hbkb/lib/libhbkb.a $DEVKITPRO/libctru/lib`  
   `cp hbkb_include_header/hbkb.h $DEVKITPRO/libctru/include/`  
3. Hopefully CIAngel now builds for you!


================================================
FILE: source/cia.c
================================================
/**
Copyright 2013 3DSGuy

This file is part of make_cdn_cia.

make_cdn_cia is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

make_cdn_cia is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with make_cdn_cia.  If not, see <http://www.gnu.org/licenses/>.
**/
#include "lib.h"
#include "cia.h"
#include <3ds.h>
#define TRUE 1
#define FALSE 0

int generate_cia(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context, FILE *output)
{
	write_cia_header(tmd_context,tik_context,output);
	write_cert_chain(tmd_context,tik_context,output);
	write_tik(tmd_context,tik_context,output);
	write_tmd(tmd_context,tik_context,output);
	Result res = write_content(tmd_context,tik_context,output);
	fclose(output);
	fclose(tik_context.tik);
	fclose(tmd_context.tmd);
	free(tmd_context.content_struct);
	
	return res;
}

int install_cia(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context)
{
	Handle handle;
	Result res;
	u64 titleId = get_title_id(tmd_context);
	FS_MediaType dest = ((titleId >> 32) & 0x8010) != 0 ? MEDIATYPE_NAND : MEDIATYPE_SD;

	// Make sure this isn't a N3DS only title being installed on an O3DS
	bool n3ds = false;
	if(R_SUCCEEDED(APT_CheckNew3DS(&n3ds)) && !n3ds)
	{
		// 28 bits shift = 2 is a system title for N3ds
		// 24 bits shift = F is a N3DS exclusive game (Seems to always have 0xF7 in the titleid)
		if (((titleId >> 28) & 0xF) == 2 || ((titleId >> 24) & 0xF) == 0xF)
		{
			printf("Title requires a N3DS.\n");
			return -1;
		}
	}

	// Remove the ticket and title content, incase a bad one already exists on the system
	AM_DeleteTitle(dest, titleId);
	AM_DeleteTicket(titleId);

	if(dest == MEDIATYPE_SD) {
		AM_QueryAvailableExternalTitleDatabase(NULL);
	}

	res = AM_StartCiaInstall(dest, &handle);
	if (R_FAILED(res))
	{
		printf("Error starting CIA install: %ld.\n", res);
		return res;
	}

	u32 offset = 0;

	install_cia_header(tmd_context, tik_context, &offset, handle);
	install_cert_chain(tmd_context, tik_context, &offset, handle);
	install_tik(tmd_context, tik_context, &offset, handle);
	install_tmd(tmd_context, tik_context, &offset, handle);
	res = install_content(tmd_context, tik_context, &offset, handle);
	fclose(tik_context.tik);
	fclose(tmd_context.tmd);
	free(tmd_context.content_struct);

	if (R_FAILED(res))
	{
		printf("Error installing CIA.\n");
		AM_CancelCIAInstall(handle);
		return res;
	}

	res = AM_FinishCiaInstall(handle);
	if (R_FAILED(res))
	{
		printf("Error finishing CIA install.\n");
	}

	return res;
}

TIK_CONTEXT process_tik(FILE *tik)
{
	TIK_CONTEXT tik_context;
	memset(&tik_context,0x0,sizeof(tik_context));
	
	tik_context.tik = tik;
	
	u32 sig_size = get_sig_size(0x0,tik);
	if(sig_size == ERR_UNRECOGNISED_SIG){
		printf("[!] The CETK signature could not be recognised\n");
		tik_context.result = ERR_UNRECOGNISED_SIG;
		return tik_context;
	}
	
	TIK_STRUCT tik_struct = get_tik_struct(sig_size,tik);
	tik_context.tik_size = get_tik_size(sig_size);
	tik_context.title_version = u8_to_u16(tik_struct.title_version,BIG_ENDIAN);
	
	if(tik_context.tik_size == ERR_UNRECOGNISED_SIG){
		tik_context.result = ERR_UNRECOGNISED_SIG;
		return tik_context;
	}
	
	tik_context.cert_offset[0] = tik_context.tik_size;
	tik_context.cert_size[0] = get_cert_size(tik_context.tik_size,tik);
	tik_context.cert_offset[1] = tik_context.tik_size + tik_context.cert_size[0];
	tik_context.cert_size[1] = get_cert_size(tik_context.cert_offset[1],tik);
	
	if(tik_context.cert_size[0] == ERR_UNRECOGNISED_SIG || tik_context.cert_size[1] == ERR_UNRECOGNISED_SIG){
		printf("[!] One or both of the signatures in the CETK 'Cert Chain' are unrecognised\n");
		tik_context.result = ERR_UNRECOGNISED_SIG;
		return tik_context;
	}
	memcpy(tik_context.title_id,tik_struct.title_id,8);
	
	//printf("[+] CETK Title ID: "); u8_hex_print_be(tik_context.title_id,0x8); printf("\n");
	//printf("[+] CETK Size:     0x%x\n",tik_context.tik_size);
	//printf("[+] CERT Size:     0x%x\n",tik_context.cert_size);
	
	return tik_context;
}

TMD_CONTEXT process_tmd(FILE *tmd)
{
	TMD_CONTEXT tmd_context;
	memset(&tmd_context,0x0,sizeof(tmd_context));
	
	tmd_context.tmd = tmd;
	
	u32 sig_size = get_sig_size(0x0,tmd);
	if(sig_size == ERR_UNRECOGNISED_SIG){
		printf("[!] The TMD signature could not be recognised\n");
		tmd_context.result = ERR_UNRECOGNISED_SIG;
		return tmd_context;
	}
	
	
	TMD_STRUCT tmd_struct = get_tmd_struct(sig_size,tmd);
	tmd_context.content_count = u8_to_u16(tmd_struct.content_count,BIG_ENDIAN);
	tmd_context.tmd_size = get_tmd_size(sig_size,tmd_context.content_count);
	tmd_context.title_version = u8_to_u16(tmd_struct.title_version,BIG_ENDIAN);
	
	tmd_context.cert_offset[0] = tmd_context.tmd_size;
	tmd_context.cert_size[0] = get_cert_size(tmd_context.tmd_size,tmd);
	tmd_context.cert_offset[1] = tmd_context.tmd_size + tmd_context.cert_size[0];
	tmd_context.cert_size[1] = get_cert_size(tmd_context.cert_offset[1],tmd);
	
	if(tmd_context.cert_size[0] == ERR_UNRECOGNISED_SIG || tmd_context.cert_size[1] == ERR_UNRECOGNISED_SIG){
		printf("[!] One or both of the signatures in the TMD 'Cert Chain' are unrecognised\n");
		tmd_context.result = ERR_UNRECOGNISED_SIG;
		return tmd_context;
	}
	memcpy(tmd_context.title_id,tmd_struct.title_id,8);
	
	tmd_context.content_struct = malloc(sizeof(TMD_CONTENT_CHUNK_STRUCT)*tmd_context.content_count);
	for(u8 i = 0; i < tmd_context.content_count; i++){
		tmd_context.content_struct[i] = get_tmd_content_struct(sig_size,i,tmd);
	}
	return tmd_context;
}

CIA_HEADER set_cia_header(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context)
{
	CIA_HEADER cia_header;
	memset(&cia_header,0,sizeof(cia_header));
	cia_header.header_size = sizeof(CIA_HEADER);
	cia_header.type = 0;
	cia_header.version = 0;
	cia_header.cert_size = get_total_cert_size(tmd_context,tik_context);
	cia_header.tik_size = tik_context.tik_size;
	cia_header.tmd_size = tmd_context.tmd_size;
	cia_header.meta_size = 0;
	cia_header.content_size = get_content_size(tmd_context);
	for(int i = 0; i < tmd_context.content_count; i++) {
		u16 index = u8_to_u16(tmd_context.content_struct[i].content_index, BIG_ENDIAN);
		cia_header.content_index[index / 8] |= 0x80 >> (index & 7);
	}
	return cia_header;
}

u32 get_tik_size(u32 sig_size)
{
	return (0x4 + sig_size + sizeof(TIK_STRUCT));
}

u32 get_tmd_size(u32 sig_size, u16 content_count)
{
	return (0x4 + sig_size + sizeof(TMD_STRUCT) + sizeof(TMD_CONTENT_CHUNK_STRUCT)*content_count);
}

u32 get_sig_size(u32 offset, FILE *file)
{
	fseek(file,offset,SEEK_SET);
	u32 sig_type;
	fread(&sig_type,0x4,1,file);
	switch(sig_type){
		/**
		case(RSA_4096_SHA1): return 0x200;
		case(RSA_2048_SHA1): return 0x100;
		case(Elliptic_Curve_0): return 0x3C;
		**/
		case(RSA_4096_SHA256): return 0x200;
		case(RSA_2048_SHA256): return 0x100;
		//case(Elliptic_Curve_1): return 0x3C;
	}
	return ERR_UNRECOGNISED_SIG;
}

u32 get_cert_size(u32 offset, FILE *file)
{
	u32 sig_size = get_sig_size(offset,file);
	if(sig_size == ERR_UNRECOGNISED_SIG)
		return ERR_UNRECOGNISED_SIG;
	return (0x4+sig_size+sizeof(CERT_2048KEY_DATA_STRUCT));
}

u32 get_total_cert_size(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context)
{
	return (tik_context.cert_size[1] + tik_context.cert_size[0] + tmd_context.cert_size[0]);
}

u64 get_content_size(TMD_CONTEXT tmd_context)
{
	u64 content_size = 0x0;
	for(int i = 0; i < tmd_context.content_count; i++)
		content_size += read_content_size(tmd_context.content_struct[i]);
	return content_size;
}

u64 read_content_size(TMD_CONTENT_CHUNK_STRUCT content_struct)
{
	return u8_to_u64(content_struct.content_size,BIG_ENDIAN);
}

u32 get_content_id(TMD_CONTENT_CHUNK_STRUCT content_struct)
{
	return u8_to_u32(content_struct.content_id,BIG_ENDIAN);
}

u64 get_title_id(TMD_CONTEXT content_struct)
{
	return u8_to_u64(content_struct.title_id,BIG_ENDIAN);
}

int write_cia_header(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context, FILE *output)
{
	CIA_HEADER cia_header = set_cia_header(tmd_context,tik_context);
	fseek(output,0x0,SEEK_SET);
	fwrite(&cia_header,sizeof(cia_header),1,output);

	// Make sure we end on a 64-byte boundry
	write_align_padding(output, 64);

	return 0;
}

int write_cert_chain(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context, FILE *output)
{
	u8 cert[0x1000];
	//The order of Certs in CIA goes, Root Cert, Cetk Cert, TMD Cert. In CDN format each file has it's own cert followed by a Root cert
	
	//Taking Root Cert from Cetk Cert chain(can be taken from TMD Cert Chain too)
	memset(cert,0x0,tik_context.cert_size[1]);
	fseek(tik_context.tik,tik_context.cert_offset[1],SEEK_SET);
	fread(&cert,tik_context.cert_size[1],1,tik_context.tik);
	fwrite(&cert,tik_context.cert_size[1],1,output);
	
	//Writing Cetk Cert
	memset(cert,0x0,tik_context.cert_size[0]);
	fseek(tik_context.tik,tik_context.cert_offset[0],SEEK_SET);
	fread(&cert,tik_context.cert_size[0],1,tik_context.tik);
	fwrite(&cert,tik_context.cert_size[0],1,output);
	
	//Writing TMD Cert
	memset(cert,0x0,tmd_context.cert_size[0]);
	fseek(tmd_context.tmd,tmd_context.cert_offset[0],SEEK_SET);
	fread(&cert,tmd_context.cert_size[0],1,tmd_context.tmd);
	fwrite(&cert,tmd_context.cert_size[0],1,output);

	// Make sure we end on a 64-byte boundry
	write_align_padding(output, 64);
	
	return 0;
}

int write_tik(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context, FILE *output)
{
	u8 tik[tik_context.tik_size];
	
	memset(tik,0x0,tik_context.tik_size);
	fseek(tik_context.tik,0x0,SEEK_SET);
	fread(&tik,tik_context.tik_size,1,tik_context.tik);
	fwrite(&tik,tik_context.tik_size,1,output);
	
	// Make sure we end on a 64-byte boundry
	write_align_padding(output, 64);

	return 0;
}

int write_tmd(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context, FILE *output)
{
	u8 tmd[tmd_context.tmd_size];
	memset(tmd,0x0,tmd_context.tmd_size);
	fseek(tmd_context.tmd,0x0,SEEK_SET);
	fread(&tmd,tmd_context.tmd_size,1,tmd_context.tmd);
	fwrite(&tmd,tmd_context.tmd_size,1,output);
	
	// Make sure we end on a 64-byte boundry
	write_align_padding(output, 64);

	return 0;
}

int write_content(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context, FILE *output)
{
	Result res = 0;
	for(int i = 0; i < tmd_context.content_count; i++) {
		printf("Downloading content %d of %d\n", i + 1, tmd_context.content_count);
		char content_id[16];
		char title_id[32];
		sprintf(content_id,"%08lx",get_content_id(tmd_context.content_struct[i]));
		sprintf(title_id,"%016llx",get_title_id(tmd_context));

		char *url = malloc(48 + strlen(NUS_URL) + 1);
		sprintf(url, "%s%s/%s", NUS_URL, title_id, content_id);
		res = DownloadFile(url, output, true);
		free(url);

		if (R_FAILED(res))
		{
			break;
		}

	}
	return res;
}


int install_cia_header(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context, u32* offset, Handle handle)
{
	u32 bytesWritten;
	CIA_HEADER cia_header = set_cia_header(tmd_context,tik_context);

	FSFILE_Write(handle, &bytesWritten, *offset, &cia_header, sizeof(cia_header), 0);
	*offset += bytesWritten;

	// Make sure we end on a 64-byte boundry
	install_write_align_padding(handle, offset, 64);

	return 0;
}

int install_cert_chain(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context, u32* offset, Handle handle)
{
	u32 bytesWritten;
	u8 cert[0x1000];
	//The order of Certs in CIA goes, Root Cert, Cetk Cert, TMD Cert. In CDN format each file has it's own cert followed by a Root cert
	
	//Taking Root Cert from Cetk Cert chain(can be taken from TMD Cert Chain too)
	memset(cert,0x0,tik_context.cert_size[1]);
	fseek(tik_context.tik,tik_context.cert_offset[1],SEEK_SET);
	fread(&cert,tik_context.cert_size[1],1,tik_context.tik);
	FSFILE_Write(handle, &bytesWritten, *offset, &cert, tik_context.cert_size[1], 0);
	*offset += bytesWritten;
	
	//Writing Cetk Cert
	memset(cert,0x0,tik_context.cert_size[0]);
	fseek(tik_context.tik,tik_context.cert_offset[0],SEEK_SET);
	fread(&cert,tik_context.cert_size[0],1,tik_context.tik);
	FSFILE_Write(handle, &bytesWritten, *offset, &cert, tik_context.cert_size[0], 0);
	*offset += bytesWritten;
	
	//Writing TMD Cert
	memset(cert,0x0,tmd_context.cert_size[0]);
	fseek(tmd_context.tmd,tmd_context.cert_offset[0],SEEK_SET);
	fread(&cert,tmd_context.cert_size[0],1,tmd_context.tmd);
	FSFILE_Write(handle, &bytesWritten, *offset, &cert, tmd_context.cert_size[0], 0);
	*offset += bytesWritten;

	// Make sure we end on a 64-byte boundry
	install_write_align_padding(handle, offset, 64);
	
	return 0;
}

int install_tik(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context, u32* offset, Handle handle)
{
	u32 bytesWritten;
	u8 tik[tik_context.tik_size];
	
	memset(tik,0x0,tik_context.tik_size);
	fseek(tik_context.tik,0x0,SEEK_SET);
	fread(&tik,tik_context.tik_size,1,tik_context.tik);
	FSFILE_Write(handle, &bytesWritten, *offset, &tik, tik_context.tik_size, 0);
	*offset += bytesWritten;
	
	// Make sure we end on a 64-byte boundry
	install_write_align_padding(handle, offset, 64);

	return 0;
}

int install_tmd(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context, u32* offset, Handle handle)
{
	u32 bytesWritten;
	u8 tmd[tmd_context.tmd_size];
	memset(tmd,0x0,tmd_context.tmd_size);
	fseek(tmd_context.tmd,0x0,SEEK_SET);
	fread(&tmd,tmd_context.tmd_size,1,tmd_context.tmd);
	FSFILE_Write(handle, &bytesWritten, *offset, &tmd, tmd_context.tmd_size, 0);
	*offset += bytesWritten;
	
	// Make sure we end on a 64-byte boundry
	install_write_align_padding(handle, offset, 64);

	return 0;
}

Result install_content(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context, u32* offset, Handle handle)
{
	Result res = 0;
	for(int i = 0; i < tmd_context.content_count; i++) {
		printf("Installing content %d of %d\n", i + 1, tmd_context.content_count);
		char content_id[16];
		char title_id[32];
		sprintf(content_id,"%08lx",get_content_id(tmd_context.content_struct[i]));
		sprintf(title_id,"%016llx",get_title_id(tmd_context));

		char *url = malloc(48 + strlen(NUS_URL) + 1);
		sprintf(url, "%s%s/%s", NUS_URL, title_id, content_id);

		res = DownloadFileInstall(url, &handle, offset);
		free(url);

		if (R_FAILED(res))
		{
			break;
		}
	}

	return res;
}

void install_write_align_padding(Handle handle, u32* offset, size_t alignment)
{
	long int usedbytes = *offset & (alignment - 1);
	if (usedbytes)
	{
		u32 bytesWritten;
		// Create the padding strings
		long int padbytes = (alignment - usedbytes);
		char* pad = (char*)malloc(padbytes);
		memset(pad, 0, padbytes);

		// Write it, and increase the offset
		FSFILE_Write(handle, &bytesWritten, *offset, pad, padbytes, 0);
		*offset += bytesWritten;
		free(pad);
	}
}


TIK_STRUCT get_tik_struct(u32 sig_size, FILE *tik)
{
	TIK_STRUCT tik_struct;
	fseek(tik,(0x4+sig_size),SEEK_SET);
	fread(&tik_struct,sizeof(tik_struct),1,tik);
	return tik_struct;
}

TMD_STRUCT get_tmd_struct(u32 sig_size, FILE *tmd)
{
	TMD_STRUCT tmd_struct;
	fseek(tmd,(0x4+sig_size),SEEK_SET);
	fread(&tmd_struct,sizeof(tmd_struct),1,tmd);
	return tmd_struct;
}

TMD_CONTENT_CHUNK_STRUCT get_tmd_content_struct(u32 sig_size, u8 index, FILE *tmd)
{
	fseek(tmd,(0x4+sig_size+sizeof(TMD_STRUCT)+sizeof(TMD_CONTENT_CHUNK_STRUCT)*index),SEEK_SET);
	TMD_CONTENT_CHUNK_STRUCT content_struct;
	fread(&content_struct,sizeof(content_struct),1,tmd);
	return content_struct;
}

void print_content_chunk_info(TMD_CONTENT_CHUNK_STRUCT content_struct)
{
	printf("\n[+] Content ID:    %08lx\n",u8_to_u32(content_struct.content_id,BIG_ENDIAN));
	printf("[+] Content Index: %d\n",u8_to_u16(content_struct.content_index,BIG_ENDIAN));
	printf("[+] Content Type:  %d\n",u8_to_u16(content_struct.content_type,BIG_ENDIAN));
	printf("[+] Content Size:  0x%llx\n",u8_to_u64(content_struct.content_size,BIG_ENDIAN));
	printf("[+] SHA-256 Hash:  "); u8_hex_print_be(content_struct.sha_256_hash,0x20); printf("\n");
}

int check_tid(u8 *tid_0, u8 *tid_1)
{
	for(int i = 0; i < 8; i++){
		if(tid_0[i] != tid_1[i])
			return FALSE;
	}
	return TRUE;
}


================================================
FILE: source/cia.h
================================================
/**
Copyright 2013 3DSGuy

This file is part of make_cdn_cia.

make_cdn_cia is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

make_cdn_cia is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with make_cdn_cia.  If not, see <http://www.gnu.org/licenses/>.
**/

#include <3ds.h>

#ifdef __cplusplus
extern "C" {
#endif
//Sig Types
#define Elliptic_Curve_1 0x05000100
#define RSA_2048_SHA256 0x04000100
#define RSA_4096_SHA256 0x03000100
#define Elliptic_Curve_0 0x02000100
#define RSA_2048_SHA1 0x01000100
#define RSA_4096_SHA1 0x00000100
//Errors
#define ERR_UNRECOGNISED_SIG 2

typedef struct
{
	u8 modulus[0x100];
	u8 exponent[0x4];
} __attribute__((__packed__))
RSA_2048_PUB_KEY;

typedef struct
{
	u8 padding_0[0x3c];
	u8 issuer[0x40];
	u8 tag_0[4];
	u8 name[0x40];
	u8 tag_1[0x4];
	RSA_2048_PUB_KEY pubk;
	u8 padding_1[0x34];
} __attribute__((__packed__))
CERT_2048KEY_DATA_STRUCT;

typedef struct
{
	u8 padding_0[0x3c];
	u8 issuer[0x40];
	u8 version;
	u8 ca_crl_version;
	u8 signer_crl_version;
	u8 padding_1;
} __attribute__((__packed__))
TMD_SIG_STRUCT;

typedef struct
{
	u8 content_id[4];
	u8 content_index[2];
	u8 content_type[2];
	u8 content_size[8];
	u8 sha_256_hash[0x20];
} __attribute__((__packed__))
TMD_CONTENT_CHUNK_STRUCT;

typedef struct
{
	TMD_SIG_STRUCT tmd_sig;
	u8 system_version[8];
	u8 title_id[8];
	u8 title_type[4];
	u8 reserved[0x40];
	u8 access_rights[4];
	u8 title_version[2];
	u8 content_count[2];
	u8 boot_content[2];
	u8 padding[2];
	u8 sha_256_hash[0x20];
	u8 content_info_records[0x900];
} __attribute__((__packed__)) 
TMD_STRUCT;

typedef struct
{
	u8 padding_0[0x3c];
	u8 issuer[0x40];
	u8 ECDH[0x3c];
	u8 unknown[3];
} __attribute__((__packed__))
TIK_SIG_STRUCT;

typedef struct
{
	TIK_SIG_STRUCT tik_sig;
	u8 encrypted_title_key[0x10];
	u8 unknown_0;
	u8 ticket_id[8];
	u8 ticket_consoleID[4];
	u8 title_id[8];
	u8 unknown_1[2];
	u8 title_version[2];
	u8 unused_0[8];
	u8 unused_1;
	u8 common_key_index;
	u8 unknown_2[0x15e];
} __attribute__((__packed__)) 
TIK_STRUCT;

typedef struct
{
	u8 result;

	FILE *tmd;
	u8 title_id[8];
	u16 title_version;
	u32 tmd_size;
	u32 cert_offset[2];
	u32 cert_size[2];
	u16 content_count;
	TMD_CONTENT_CHUNK_STRUCT *content_struct;
	
	u16 *title_index;
} __attribute__((__packed__)) 
TMD_CONTEXT;

typedef struct
{
	u8 result;
	
	FILE *tik;
	u8 title_id[8];
	u16 title_version;
	u32 tik_size;
	u32 cert_offset[2];
	u32 cert_size[2];
} __attribute__((__packed__)) 
TIK_CONTEXT;

typedef struct
{
	u32 header_size;
	u16 type;
	u16 version;
	u32 cert_size;
	u32 tik_size;
	u32 tmd_size;
	u32 meta_size;
	u64 content_size;
	u8 content_index[0x2000];
} CIA_HEADER;

// Main Functions
int generate_cia(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context, FILE *output);
int install_cia(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context);

//Processing Functions
TIK_CONTEXT process_tik(FILE *tik);
TMD_CONTEXT process_tmd(FILE *tmd);
CIA_HEADER set_cia_header(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context);

//Reading/Calc Functions
u32 get_tik_size(u32 sig_size);
u32 get_tmd_size(u32 sig_size, u16 content_count);
u32 get_sig_size(u32 offset, FILE *file);
u32 get_cert_size(u32 offset, FILE *file);
u64 get_content_size(TMD_CONTEXT tmd_context);
u64 read_content_size(TMD_CONTENT_CHUNK_STRUCT content_struct);
u32 get_total_cert_size(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context);
u32 get_content_id(TMD_CONTENT_CHUNK_STRUCT content_struct);
u64 get_title_id(TMD_CONTEXT content_struct);

//Writing functions
int write_cia_header(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context, FILE *output);
int write_cert_chain(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context, FILE *output);
int write_tik(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context, FILE *output);
int write_tmd(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context, FILE *output);
int write_content(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context, FILE *output);

// Install functions
int install_cia_header(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context, u32* offset, Handle handle);
int install_cert_chain(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context, u32* offset, Handle handle);
int install_tik(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context, u32* offset, Handle handle);
int install_tmd(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context, u32* offset, Handle handle);
Result install_content(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context, u32* offset, Handle handle);
void install_write_align_padding(Handle handle, u32* offset, size_t alignment);

//Get Struct Functions
TIK_STRUCT get_tik_struct(u32 sig_size, FILE *tik);
TMD_STRUCT get_tmd_struct(u32 sig_size, FILE *tmd);
TMD_CONTENT_CHUNK_STRUCT get_tmd_content_struct(u32 sig_size, u8 index, FILE *tmd);

//Printing Functions
void print_content_chunk_info(TMD_CONTENT_CHUNK_STRUCT content_struct);

//Checking Functions
int check_tid(u8 *tid_0, u8 *tid_1);

#ifdef __cplusplus
}
#endif


================================================
FILE: source/config.cpp
================================================
#include <string>
#include <fstream>
#include "config.h"
#include "json/json.h"

using namespace std;

CConfig::CConfig()
{
    // Empty
}

void CConfig::LoadConfig(string sConfigPath)
{
    // Store the config path so we can save it later
    m_sConfigPath = sConfigPath;

    std::ifstream ifs(m_sConfigPath);
    if (ifs.is_open()) {
        ifs >> m_Json;
    }

    // Mode defaults to Install CIA
    m_eMode = (Mode)m_Json.get("Mode", (int)Mode::INSTALL_CIA).asInt();
    m_sRegionFilter = m_Json.get("RegionFilter", "off").asString();
}

bool CConfig::SaveConfig()
{
    // Update the config
    m_Json["Mode"] = (int)m_eMode;
    m_Json["RegionFilter"] = m_sRegionFilter;

    // Write to file
    std::ofstream ofs(m_sConfigPath, std::ofstream::trunc);
    if (ofs.is_open())
    {
        ofs << m_Json;
        return true;
    }

    return false;
}

CConfig::Mode CConfig::GetMode()
{
    return m_eMode;
}

void CConfig::SetMode(CConfig::Mode mode)
{
    m_eMode = mode;
    SaveConfig();
}

std::string CConfig::GetRegionFilter()
{
    return m_sRegionFilter;
}

void CConfig::SetRegionFilter(std::string region)
{
    m_sRegionFilter = region;
    SaveConfig();
}

================================================
FILE: source/config.h
================================================
#pragma once
#include <string>
#include "json/json.h"

class CConfig {
public:
    CConfig();
    void LoadConfig(std::string sConfigPath);
    bool SaveConfig();

    enum Mode {
        DOWNLOAD_CIA, 
        INSTALL_CIA, 
        INSTALL_TICKET
    };

    Mode GetMode();
    void SetMode(Mode mode);
    std::string GetRegionFilter();
    void SetRegionFilter(std::string region);

private:
    std::string m_sConfigPath;

    // Config options
    Mode m_eMode;
    std::string m_sRegionFilter;

    Json::Value m_Json;
};


================================================
FILE: source/data.h
================================================
#define TICKET_SIZE 0xA50
const char tikTemp[TICKET_SIZE] = {
    0x00, 0x01, 0x00, 0x04, 0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0,
    0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0,
    0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0,
    0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0,
    0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0,
    0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0,
    0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0,
    0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0,
    0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0,
    0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0,
    0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0,
    0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0,
    0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0,
    0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0,
    0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0,
    0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0,
    0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0,
    0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0,
    0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0,
    0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0,
    0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0,
    0xD1, 0x5E, 0xA5, 0xE0, 0xD1, 0x5E, 0xA5, 0xE0, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x6F, 0x6F, 0x74,
    0x2D, 0x43, 0x41, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x2D,
    0x58, 0x53, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x63, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0xFE, 0xED, 0xFA, 0xCE, 0xFE, 0xED, 0xFA, 0xCE, 0xFE, 0xED, 0xFA, 0xCE,
    0xFE, 0xED, 0xFA, 0xCE, 0xFE, 0xED, 0xFA, 0xCE, 0xFE, 0xED, 0xFA, 0xCE,
    0xFE, 0xED, 0xFA, 0xCE, 0xFE, 0xED, 0xFA, 0xCE, 0xFE, 0xED, 0xFA, 0xCE,
    0xFE, 0xED, 0xFA, 0xCE, 0xFE, 0xED, 0xFA, 0xCE, 0xFE, 0xED, 0xFA, 0xCE,
    0xFE, 0xED, 0xFA, 0xCE, 0xFE, 0xED, 0xFA, 0xCE, 0xFE, 0xED, 0xFA, 0xCE,
    0x01, 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
    0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA,
    0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x14, 0x00, 0x00, 0x00, 0xAC,
    0x00, 0x00, 0x00, 0x14, 0x00, 0x01, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x84,
    0x00, 0x00, 0x00, 0x84, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04,
    0x91, 0x9E, 0xBE, 0x46, 0x4A, 0xD0, 0xF5, 0x52, 0xCD, 0x1B, 0x72, 0xE7,
    0x88, 0x49, 0x10, 0xCF, 0x55, 0xA9, 0xF0, 0x2E, 0x50, 0x78, 0x96, 0x41,
    0xD8, 0x96, 0x68, 0x3D, 0xC0, 0x05, 0xBD, 0x0A, 0xEA, 0x87, 0x07, 0x9D,
    0x8A, 0xC2, 0x84, 0xC6, 0x75, 0x06, 0x5F, 0x74, 0xC8, 0xBF, 0x37, 0xC8,
    0x80, 0x44, 0x40, 0x95, 0x02, 0xA0, 0x22, 0x98, 0x0B, 0xB8, 0xAD, 0x48,
    0x38, 0x3F, 0x6D, 0x28, 0xA7, 0x9D, 0xE3, 0x96, 0x26, 0xCC, 0xB2, 0xB2,
    0x2A, 0x0F, 0x19, 0xE4, 0x10, 0x32, 0xF0, 0x94, 0xB3, 0x9F, 0xF0, 0x13,
    0x31, 0x46, 0xDE, 0xC8, 0xF6, 0xC1, 0xA9, 0xD5, 0x5C, 0xD2, 0x8D, 0x9E,
    0x1C, 0x47, 0xB3, 0xD1, 0x1F, 0x4F, 0x54, 0x26, 0xC2, 0xC7, 0x80, 0x13,
    0x5A, 0x27, 0x75, 0xD3, 0xCA, 0x67, 0x9B, 0xC7, 0xE8, 0x34, 0xF0, 0xE0,
    0xFB, 0x58, 0xE6, 0x88, 0x60, 0xA7, 0x13, 0x30, 0xFC, 0x95, 0x79, 0x17,
    0x93, 0xC8, 0xFB, 0xA9, 0x35, 0xA7, 0xA6, 0x90, 0x8F, 0x22, 0x9D, 0xEE,
    0x2A, 0x0C, 0xA6, 0xB9, 0xB2, 0x3B, 0x12, 0xD4, 0x95, 0xA6, 0xFE, 0x19,
    0xD0, 0xD7, 0x26, 0x48, 0x21, 0x68, 0x78, 0x60, 0x5A, 0x66, 0x53, 0x8D,
    0xBF, 0x37, 0x68, 0x99, 0x90, 0x5D, 0x34, 0x45, 0xFC, 0x5C, 0x72, 0x7A,
    0x0E, 0x13, 0xE0, 0xE2, 0xC8, 0x97, 0x1C, 0x9C, 0xFA, 0x6C, 0x60, 0x67,
    0x88, 0x75, 0x73, 0x2A, 0x4E, 0x75, 0x52, 0x3D, 0x2F, 0x56, 0x2F, 0x12,
    0xAA, 0xBD, 0x15, 0x73, 0xBF, 0x06, 0xC9, 0x40, 0x54, 0xAE, 0xFA, 0x81,
    0xA7, 0x14, 0x17, 0xAF, 0x9A, 0x4A, 0x06, 0x6D, 0x0F, 0xFC, 0x5A, 0xD6,
    0x4B, 0xAB, 0x28, 0xB1, 0xFF, 0x60, 0x66, 0x1F, 0x44, 0x37, 0xD4, 0x9E,
    0x1E, 0x0D, 0x94, 0x12, 0xEB, 0x4B, 0xCA, 0xCF, 0x4C, 0xFD, 0x6A, 0x34,
    0x08, 0x84, 0x79, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x43, 0x41, 0x30,
    0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
    0x58, 0x53, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x63, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x13, 0x7A, 0x08, 0x94, 0xAD, 0x50, 0x5B, 0xB6,
    0xC6, 0x7E, 0x2E, 0x5B, 0xDD, 0x6A, 0x3B, 0xEC, 0x43, 0xD9, 0x10, 0xC7,
    0x72, 0xE9, 0xCC, 0x29, 0x0D, 0xA5, 0x85, 0x88, 0xB7, 0x7D, 0xCC, 0x11,
    0x68, 0x0B, 0xB3, 0xE2, 0x9F, 0x4E, 0xAB, 0xBB, 0x26, 0xE9, 0x8C, 0x26,
    0x01, 0x98, 0x5C, 0x04, 0x1B, 0xB1, 0x43, 0x78, 0xE6, 0x89, 0x18, 0x1A,
    0xAD, 0x77, 0x05, 0x68, 0xE9, 0x28, 0xA2, 0xB9, 0x81, 0x67, 0xEE, 0x3E,
    0x10, 0xD0, 0x72, 0xBE, 0xEF, 0x1F, 0xA2, 0x2F, 0xA2, 0xAA, 0x3E, 0x13,
    0xF1, 0x1E, 0x18, 0x36, 0xA9, 0x2A, 0x42, 0x81, 0xEF, 0x70, 0xAA, 0xF4,
    0xE4, 0x62, 0x99, 0x82, 0x21, 0xC6, 0xFB, 0xB9, 0xBD, 0xD0, 0x17, 0xE6,
    0xAC, 0x59, 0x04, 0x94, 0xE9, 0xCE, 0xA9, 0x85, 0x9C, 0xEB, 0x2D, 0x2A,
    0x4C, 0x17, 0x66, 0xF2, 0xC3, 0x39, 0x12, 0xC5, 0x8F, 0x14, 0xA8, 0x03,
    0xE3, 0x6F, 0xCC, 0xDC, 0xCC, 0xDC, 0x13, 0xFD, 0x7A, 0xE7, 0x7C, 0x7A,
    0x78, 0xD9, 0x97, 0xE6, 0xAC, 0xC3, 0x55, 0x57, 0xE0, 0xD3, 0xE9, 0xEB,
    0x64, 0xB4, 0x3C, 0x92, 0xF4, 0xC5, 0x0D, 0x67, 0xA6, 0x02, 0xDE, 0xB3,
    0x91, 0xB0, 0x66, 0x61, 0xCD, 0x32, 0x88, 0x0B, 0xD6, 0x49, 0x12, 0xAF,
    0x1C, 0xBC, 0xB7, 0x16, 0x2A, 0x06, 0xF0, 0x25, 0x65, 0xD3, 0xB0, 0xEC,
    0xE4, 0xFC, 0xEC, 0xDD, 0xAE, 0x8A, 0x49, 0x34, 0xDB, 0x8E, 0xE6, 0x7F,
    0x30, 0x17, 0x98, 0x62, 0x21, 0x15, 0x5D, 0x13, 0x1C, 0x6C, 0x3F, 0x09,
    0xAB, 0x19, 0x45, 0xC2, 0x06, 0xAC, 0x70, 0xC9, 0x42, 0xB3, 0x6F, 0x49,
    0xA1, 0x18, 0x3B, 0xCD, 0x78, 0xB6, 0xE4, 0xB4, 0x7C, 0x6C, 0x5C, 0xAC,
    0x0F, 0x8D, 0x62, 0xF8, 0x97, 0xC6, 0x95, 0x3D, 0xD1, 0x2F, 0x28, 0xB7,
    0x0C, 0x5B, 0x7D, 0xF7, 0x51, 0x81, 0x9A, 0x98, 0x34, 0x65, 0x26, 0x25,
    0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03,
    0x70, 0x41, 0x38, 0xEF, 0xBB, 0xBD, 0xA1, 0x6A, 0x98, 0x7D, 0xD9, 0x01,
    0x32, 0x6D, 0x1C, 0x94, 0x59, 0x48, 0x4C, 0x88, 0xA2, 0x86, 0x1B, 0x91,
    0xA3, 0x12, 0x58, 0x7A, 0xE7, 0x0E, 0xF6, 0x23, 0x7E, 0xC5, 0x0E, 0x10,
    0x32, 0xDC, 0x39, 0xDD, 0xE8, 0x9A, 0x96, 0xA8, 0xE8, 0x59, 0xD7, 0x6A,
    0x98, 0xA6, 0xE7, 0xE3, 0x6A, 0x0C, 0xFE, 0x35, 0x2C, 0xA8, 0x93, 0x05,
    0x82, 0x34, 0xFF, 0x83, 0x3F, 0xCB, 0x3B, 0x03, 0x81, 0x1E, 0x9F, 0x0D,
    0xC0, 0xD9, 0xA5, 0x2F, 0x80, 0x45, 0xB4, 0xB2, 0xF9, 0x41, 0x1B, 0x67,
    0xA5, 0x1C, 0x44, 0xB5, 0xEF, 0x8C, 0xE7, 0x7B, 0xD6, 0xD5, 0x6B, 0xA7,
    0x57, 0x34, 0xA1, 0x85, 0x6D, 0xE6, 0xD4, 0xBE, 0xD6, 0xD3, 0xA2, 0x42,
    0xC7, 0xC8, 0x79, 0x1B, 0x34, 0x22, 0x37, 0x5E, 0x5C, 0x77, 0x9A, 0xBF,
    0x07, 0x2F, 0x76, 0x95, 0xEF, 0xA0, 0xF7, 0x5B, 0xCB, 0x83, 0x78, 0x9F,
    0xC3, 0x0E, 0x3F, 0xE4, 0xCC, 0x83, 0x92, 0x20, 0x78, 0x40, 0x63, 0x89,
    0x49, 0xC7, 0xF6, 0x88, 0x56, 0x5F, 0x64, 0x9B, 0x74, 0xD6, 0x3D, 0x8D,
    0x58, 0xFF, 0xAD, 0xDA, 0x57, 0x1E, 0x95, 0x54, 0x42, 0x6B, 0x13, 0x18,
    0xFC, 0x46, 0x89, 0x83, 0xD4, 0xC8, 0xA5, 0x62, 0x8B, 0x06, 0xB6, 0xFC,
    0x5D, 0x50, 0x7C, 0x13, 0xE7, 0xA1, 0x8A, 0xC1, 0x51, 0x1E, 0xB6, 0xD6,
    0x2E, 0xA5, 0x44, 0x8F, 0x83, 0x50, 0x14, 0x47, 0xA9, 0xAF, 0xB3, 0xEC,
    0xC2, 0x90, 0x3C, 0x9D, 0xD5, 0x2F, 0x92, 0x2A, 0xC9, 0xAC, 0xDB, 0xEF,
    0x58, 0xC6, 0x02, 0x18, 0x48, 0xD9, 0x6E, 0x20, 0x87, 0x32, 0xD3, 0xD1,
    0xD9, 0xD9, 0xEA, 0x44, 0x0D, 0x91, 0x62, 0x1C, 0x7A, 0x99, 0xDB, 0x88,
    0x43, 0xC5, 0x9C, 0x1F, 0x2E, 0x2C, 0x7D, 0x9B, 0x57, 0x7D, 0x51, 0x2C,
    0x16, 0x6D, 0x6F, 0x7E, 0x1A, 0xAD, 0x4A, 0x77, 0x4A, 0x37, 0x44, 0x7E,
    0x78, 0xFE, 0x20, 0x21, 0xE1, 0x4A, 0x95, 0xD1, 0x12, 0xA0, 0x68, 0xAD,
    0xA0, 0x19, 0xF4, 0x63, 0xC7, 0xA5, 0x56, 0x85, 0xAA, 0xBB, 0x68, 0x88,
    0xB9, 0x24, 0x64, 0x83, 0xD1, 0x8B, 0x9C, 0x80, 0x6F, 0x47, 0x49, 0x18,
    0x33, 0x17, 0x82, 0x34, 0x4A, 0x4B, 0x85, 0x31, 0x33, 0x4B, 0x26, 0x30,
    0x32, 0x63, 0xD9, 0xD2, 0xEB, 0x4F, 0x4B, 0xB9, 0x96, 0x02, 0xB3, 0x52,
    0xF6, 0xAE, 0x40, 0x46, 0xC6, 0x9A, 0x5E, 0x7E, 0x8E, 0x4A, 0x18, 0xEF,
    0x9B, 0xC0, 0xA2, 0xDE, 0xD6, 0x13, 0x10, 0x41, 0x70, 0x12, 0xFD, 0x82,
    0x4C, 0xC1, 0x16, 0xCF, 0xB7, 0xC4, 0xC1, 0xF7, 0xEC, 0x71, 0x77, 0xA1,
    0x74, 0x46, 0xCB, 0xDE, 0x96, 0xF3, 0xED, 0xD8, 0x8F, 0xCD, 0x05, 0x2F,
    0x0B, 0x88, 0x8A, 0x45, 0xFD, 0xAF, 0x2B, 0x63, 0x13, 0x54, 0xF4, 0x0D,
    0x16, 0xE5, 0xFA, 0x9C, 0x2C, 0x4E, 0xDA, 0x98, 0xE7, 0x98, 0xD1, 0x5E,
    0x60, 0x46, 0xDC, 0x53, 0x63, 0xF3, 0x09, 0x6B, 0x2C, 0x60, 0x7A, 0x9D,
    0x8D, 0xD5, 0x5B, 0x15, 0x02, 0xA6, 0xAC, 0x7D, 0x3C, 0xC8, 0xD8, 0xC5,
    0x75, 0x99, 0x8E, 0x7D, 0x79, 0x69, 0x10, 0xC8, 0x04, 0xC4, 0x95, 0x23,
    0x50, 0x57, 0xE9, 0x1E, 0xCD, 0x26, 0x37, 0xC9, 0xC1, 0x84, 0x51, 0x51,
    0xAC, 0x6B, 0x9A, 0x04, 0x90, 0xAE, 0x3E, 0xC6, 0xF4, 0x77, 0x40, 0xA0,
    0xDB, 0x0B, 0xA3, 0x6D, 0x07, 0x59, 0x56, 0xCE, 0xE7, 0x35, 0x4E, 0xA3,
    0xE9, 0xA4, 0xF2, 0x72, 0x0B, 0x26, 0x55, 0x0C, 0x7D, 0x39, 0x43, 0x24,
    0xBC, 0x0C, 0xB7, 0xE9, 0x31, 0x7D, 0x8A, 0x86, 0x61, 0xF4, 0x21, 0x91,
    0xFF, 0x10, 0xB0, 0x82, 0x56, 0xCE, 0x3F, 0xD2, 0x5B, 0x74, 0x5E, 0x51,
    0x94, 0x90, 0x6B, 0x4D, 0x61, 0xCB, 0x4C, 0x2E, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x6F, 0x6F, 0x74,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x43, 0x41, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
    0x30, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7B, 0xE8, 0xEF, 0x6C,
    0xB2, 0x79, 0xC9, 0xE2, 0xEE, 0xE1, 0x21, 0xC6, 0xEA, 0xF4, 0x4F, 0xF6,
    0x39, 0xF8, 0x8F, 0x07, 0x8B, 0x4B, 0x77, 0xED, 0x9F, 0x95, 0x60, 0xB0,
    0x35, 0x82, 0x81, 0xB5, 0x0E, 0x55, 0xAB, 0x72, 0x11, 0x15, 0xA1, 0x77,
    0x70, 0x3C, 0x7A, 0x30, 0xFE, 0x3A, 0xE9, 0xEF, 0x1C, 0x60, 0xBC, 0x1D,
    0x97, 0x46, 0x76, 0xB2, 0x3A, 0x68, 0xCC, 0x04, 0xB1, 0x98, 0x52, 0x5B,
    0xC9, 0x68, 0xF1, 0x1D, 0xE2, 0xDB, 0x50, 0xE4, 0xD9, 0xE7, 0xF0, 0x71,
    0xE5, 0x62, 0xDA, 0xE2, 0x09, 0x22, 0x33, 0xE9, 0xD3, 0x63, 0xF6, 0x1D,
    0xD7, 0xC1, 0x9F, 0xF3, 0xA4, 0xA9, 0x1E, 0x8F, 0x65, 0x53, 0xD4, 0x71,
    0xDD, 0x7B, 0x84, 0xB9, 0xF1, 0xB8, 0xCE, 0x73, 0x35, 0xF0, 0xF5, 0x54,
    0x05, 0x63, 0xA1, 0xEA, 0xB8, 0x39, 0x63, 0xE0, 0x9B, 0xE9, 0x01, 0x01,
    0x1F, 0x99, 0x54, 0x63, 0x61, 0x28, 0x70, 0x20, 0xE9, 0xCC, 0x0D, 0xAB,
    0x48, 0x7F, 0x14, 0x0D, 0x66, 0x26, 0xA1, 0x83, 0x6D, 0x27, 0x11, 0x1F,
    0x20, 0x68, 0xDE, 0x47, 0x72, 0x14, 0x91, 0x51, 0xCF, 0x69, 0xC6, 0x1B,
    0xA6, 0x0E, 0xF9, 0xD9, 0x49, 0xA0, 0xF7, 0x1F, 0x54, 0x99, 0xF2, 0xD3,
    0x9A, 0xD2, 0x8C, 0x70, 0x05, 0x34, 0x82, 0x93, 0xC4, 0x31, 0xFF, 0xBD,
    0x33, 0xF6, 0xBC, 0xA6, 0x0D, 0xC7, 0x19, 0x5E, 0xA2, 0xBC, 0xC5, 0x6D,
    0x20, 0x0B, 0xAF, 0x6D, 0x06, 0xD0, 0x9C, 0x41, 0xDB, 0x8D, 0xE9, 0xC7,
    0x20, 0x15, 0x4C, 0xA4, 0x83, 0x2B, 0x69, 0xC0, 0x8C, 0x69, 0xCD, 0x3B,
    0x07, 0x3A, 0x00, 0x63, 0x60, 0x2F, 0x46, 0x2D, 0x33, 0x80, 0x61, 0xA5,
    0xEA, 0x6C, 0x91, 0x5C, 0xD5, 0x62, 0x35, 0x79, 0xC3, 0xEB, 0x64, 0xCE,
    0x44, 0xEF, 0x58, 0x6D, 0x14, 0xBA, 0xAA, 0x88, 0x34, 0x01, 0x9B, 0x3E,
    0xEB, 0xEE, 0xD3, 0x79, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};


================================================
FILE: source/font.h
================================================
/*
  This file was autogenerated by raw2c.
Visit http://www.devkitpro.org
*/

//---------------------------------------------------------------------------------
#ifndef _font_h_
#define _font_h_
//---------------------------------------------------------------------------------
static const unsigned char font[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e,
    0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e, 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00,
    0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x3c, 0x3c, 0x18, 0xff, 0xe7, 0x18, 0x3c, 0x00,
    0x10, 0x38, 0x7c, 0xfe, 0xee, 0x10, 0x38, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00,
    0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00,
    0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78,
    0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x08, 0x0c, 0x0a, 0x0a, 0x08, 0x78, 0xf0, 0x00,
    0x18, 0x14, 0x1a, 0x16, 0x72, 0xe2, 0x0e, 0x1c, 0x10, 0x54, 0x38, 0xee, 0x38, 0x54, 0x10, 0x00,
    0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00, 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00,
    0x18, 0x3c, 0x5a, 0x18, 0x5a, 0x3c, 0x18, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00,
    0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x00, 0x1c, 0x22, 0x38, 0x44, 0x44, 0x38, 0x88, 0x70,
    0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00, 0x18, 0x3c, 0x5a, 0x18, 0x5a, 0x3c, 0x18, 0x7e,
    0x18, 0x3c, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x5a, 0x3c, 0x18, 0x00,
    0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00,
    0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x24, 0x42, 0xff, 0x42, 0x24, 0x00, 0x00,
    0x00, 0x10, 0x38, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, 0x00,
    0x6c, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00,
    0x10, 0x7c, 0xd0, 0x7c, 0x16, 0xfc, 0x10, 0x00, 0x00, 0x66, 0xac, 0xd8, 0x36, 0x6a, 0xcc, 0x00,
    0x38, 0x4c, 0x38, 0x78, 0xce, 0xcc, 0x7a, 0x00, 0x30, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00,
    0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x10, 0x20, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x00,
    0x7c, 0xce, 0xde, 0xf6, 0xe6, 0xe6, 0x7c, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x7e, 0x00,
    0x7c, 0xc6, 0x06, 0x1c, 0x70, 0xc6, 0xfe, 0x00, 0x7c, 0xc6, 0x06, 0x3c, 0x06, 0xc6, 0x7c, 0x00,
    0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00, 0xfe, 0xc0, 0xfc, 0x06, 0x06, 0xc6, 0x7c, 0x00,
    0x7c, 0xc6, 0xc0, 0xfc, 0xc6, 0xc6, 0x7c, 0x00, 0xfe, 0xc6, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00,
    0x7c, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0x7e, 0x06, 0xc6, 0x7c, 0x00,
    0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x10, 0x20,
    0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00,
    0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00,
    0x7c, 0x82, 0x9e, 0xa6, 0x9e, 0x80, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00,
    0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00,
    0xfc, 0x66, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00,
    0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00, 0x7c, 0xc6, 0xc6, 0xc0, 0xce, 0xc6, 0x7e, 0x00,
    0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,
    0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, 0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00,
    0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x82, 0xc6, 0xee, 0xfe, 0xd6, 0xc6, 0xc6, 0x00,
    0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00,
    0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x06,
    0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xe6, 0x00, 0x7c, 0xc6, 0xc0, 0x7c, 0x06, 0xc6, 0x7c, 0x00,
    0x7e, 0x5a, 0x5a, 0x18, 0x18, 0x18, 0x3c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00,
    0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x82, 0x00,
    0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x3c, 0x00,
    0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00, 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00,
    0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00,
    0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
    0x30, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00,
    0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc6, 0x7c, 0x00,
    0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00,
    0x1c, 0x36, 0x30, 0x78, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x78,
    0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00,
    0x00, 0x0c, 0x00, 0x1c, 0x0c, 0x0c, 0xcc, 0x78, 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00,
    0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0xcc, 0xfe, 0xd6, 0xd6, 0xd6, 0x00,
    0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00,
    0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0, 0x00, 0x00, 0x7c, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e,
    0x00, 0x00, 0xde, 0x76, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x7c, 0xc0, 0x7c, 0x06, 0x7c, 0x00,
    0x10, 0x30, 0xfc, 0x30, 0x30, 0x34, 0x18, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00,
    0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00,
    0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8,
    0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00, 0x0e, 0x18, 0x18, 0x30, 0x18, 0x18, 0x0e, 0x00,
    0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, 0xe0, 0x30, 0x30, 0x18, 0x30, 0x30, 0xe0, 0x00,
    0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00,
    0x7c, 0xc6, 0xc0, 0xc0, 0xc6, 0x7c, 0x18, 0x70, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00,
    0x0e, 0x10, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00, 0x7c, 0x82, 0x38, 0x0c, 0x7c, 0xcc, 0x76, 0x00,
    0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, 0xe0, 0x10, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00,
    0x30, 0x30, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x7c, 0xc0, 0xc0, 0x7c, 0x18, 0x70,
    0x7c, 0x82, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00,
    0xe0, 0x10, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00,
    0x7c, 0x82, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, 0xe0, 0x10, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00,
    0xc6, 0x00, 0x7c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x38, 0x38, 0x7c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00,
    0x0e, 0x10, 0xfe, 0x60, 0x78, 0x60, 0xfe, 0x00, 0x00, 0x00, 0x7c, 0x12, 0x7e, 0xd0, 0x7e, 0x00,
    0x7e, 0xc8, 0xc8, 0xfe, 0xc8, 0xc8, 0xce, 0x00, 0x7c, 0x82, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00,
    0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0xe0, 0x10, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00,
    0x7c, 0x82, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0xe0, 0x10, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00,
    0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00,
    0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x18, 0x7c, 0xd6, 0xd0, 0xd6, 0x7c, 0x18, 0x00,
    0x38, 0x6c, 0x60, 0xf0, 0x60, 0xf2, 0xdc, 0x00, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x00,
    0xf8, 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0x06, 0x0e, 0x1b, 0x18, 0x3c, 0x18, 0x18, 0xd8, 0x70,
    0x0e, 0x10, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, 0x0e, 0x10, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00,
    0x0e, 0x10, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x0e, 0x10, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00,
    0x66, 0x98, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x98, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0x00,
    0x38, 0x0c, 0x3c, 0x34, 0x00, 0x7e, 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00,
    0x30, 0x00, 0x30, 0x60, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0c, 0x00, 0x00, 0xc0, 0xc8, 0xd0, 0xfe, 0x46, 0x8c, 0x1e, 0x00,
    0xc0, 0xc8, 0xd0, 0xec, 0x5c, 0xbe, 0x0c, 0x00, 0x18, 0x00, 0x18, 0x18, 0x3c, 0x3c, 0x18, 0x00,
    0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00,
    0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
    0xdb, 0x77, 0xdb, 0xee, 0xdb, 0x77, 0xdb, 0xee, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
    0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18,
    0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36,
    0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36,
    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36,
    0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00,
    0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18,
    0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18,
    0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18,
    0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36,
    0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36,
    0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36,
    0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
    0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
    0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18,
    0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00,
    0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18,
    0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36,
    0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
    0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x74, 0xcc, 0xc8, 0xdc, 0x76, 0x00, 0x78, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xdc, 0x40,
    0xfe, 0x62, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x02, 0x7e, 0xec, 0x6c, 0x6c, 0x48, 0x00,
    0xfe, 0x62, 0x30, 0x18, 0x30, 0x62, 0xfe, 0x00, 0x00, 0x00, 0x7e, 0xd0, 0xc8, 0xc8, 0x70, 0x00,
    0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xf8, 0x80, 0x00, 0x00, 0x7e, 0xd8, 0x18, 0x18, 0x10, 0x00,
    0x38, 0x10, 0x7c, 0xd6, 0xd6, 0x7c, 0x10, 0x38, 0x7c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x7c, 0x00,
    0x7c, 0xc6, 0xc6, 0xc6, 0x6c, 0x28, 0xee, 0x00, 0x3c, 0x22, 0x18, 0x7c, 0xcc, 0xcc, 0x78, 0x00,
    0x00, 0x00, 0x66, 0x99, 0x99, 0x66, 0x00, 0x00, 0x00, 0x06, 0x7c, 0x9e, 0xf2, 0x7c, 0xc0, 0x00,
    0x00, 0x00, 0x7c, 0xc0, 0xf8, 0xc0, 0x7c, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00,
    0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x7e, 0x00,
    0x30, 0x18, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0x00, 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0x7c, 0x00,
    0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70,
    0x00, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00,
    0x38, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x00,
    0xd8, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x30, 0xc0, 0xf0, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

};
const int font_size = sizeof(font);
//---------------------------------------------------------------------------------
#endif //_font_h_
//---------------------------------------------------------------------------------

================================================
FILE: source/fts_fuzzy_match.h
================================================
// LICENSE
//
//   This software is dual-licensed to the public domain and under the following
//   license: you are granted a perpetual, irrevocable license to copy, modify,
//   publish, and distribute this file as you see fit.

// VERSION 0.1.0

#ifndef FTS_FUZZY_MATCH_H
#define FTS_FUZZY_MATCH_H

#include <ctype.h> // ::tolower, ::toupper

namespace fts {
    
    // Returns true if each character in pattern is found sequentially within str
    static bool fuzzy_match(char const * pattern, char const * str) 
    {
        while (*pattern != '\0' && *str != '\0')  {
            if (tolower(*pattern) == tolower(*str))
                ++pattern;
            ++str;
        }

        return *pattern == '\0' ? true : false;
    }

    // Returns true if each character in pattern is found sequentially within str
    // iff found then outScore is also set. Score value has no intrinsic meaning. Range varies with pattern. 
    // Can only compare scores with same search pattern.
    static bool fuzzy_match(char const * pattern, char const * str, int & outScore) 
    {
        // Score consts
        const int adjacency_bonus = 5;              // bonus for adjacent matches
        const int separator_bonus = 10;             // bonus if match occurs after a separator
        const int camel_bonus = 10;                 // bonus if match is uppercase and prev is lower
        
        const int leading_letter_penalty = -3;      // penalty applied for every letter in str before the first match
        const int max_leading_letter_penalty = -9;  // maximum penalty for leading letters
        const int unmatched_letter_penalty = -1;    // penalty for every letter that doesn't matter


        // Loop variables
        int score = 0;
        char const * patternIter = pattern;
        char const * strIter = str;
        bool prevMatched = false;
        bool prevLower = false;
        bool prevSeparator = true;                  // true so if first letter match gets separator bonus

        // Use "best" matched letter if multiple string letters match the pattern
        char const * bestLetter = NULL;
        int bestLetterScore = 0;

        // Loop over strings
        while (*strIter != '\0') 
        {
            const char patternLetter = *patternIter;
            const char strLetter = *strIter;

            bool nextMatch = *patternIter != '\0' && tolower(patternLetter) == tolower(strLetter);
            bool rematch = bestLetter && tolower(*bestLetter) == tolower(strLetter);

            bool advanced = nextMatch && bestLetter;
            bool patternRepeat = bestLetter && patternIter != '\0' && tolower(*bestLetter) == tolower(patternLetter);

            if (advanced || patternRepeat) 
            {
                score += bestLetterScore;
                bestLetter = NULL;
                bestLetterScore = 0;
            }

            if (nextMatch || rematch)
            {
                int newScore = 0;

                // Apply penalty for each letter before the first pattern match
                // Note: std::max because penalties are negative values. So max is smallest penalty.
                if (patternIter == pattern)
                {
                    int count = int(strIter - str);
                    int penalty = leading_letter_penalty * count;
                    if (penalty < max_leading_letter_penalty)
                        penalty = max_leading_letter_penalty;

                    score += penalty;
                } 

                // Apply bonus for consecutive bonuses
                if (prevMatched)
                    newScore += adjacency_bonus;

                // Apply bonus for matches after a separator
                if (prevSeparator)
                    newScore += separator_bonus;

                // Apply bonus across camel case boundaries
                if (prevLower && isupper(strLetter))
                    newScore += camel_bonus;

                // Update pattern iter IFF the next pattern letter was matched
                if (nextMatch)
                    ++patternIter;

                // Update best letter in str which may be for a "next" letter or a rematch
                if (newScore >= bestLetterScore) 
                {
                    // Apply penalty for now skipped letter
                    if (bestLetter != NULL)
                        score += unmatched_letter_penalty;

                    bestLetter = strIter;
                    bestLetterScore = newScore;
                }

                prevMatched = true;
            }
            else
            {
                score += unmatched_letter_penalty;
                prevMatched = false;
            }

            // Separators should be more easily defined
            prevLower = islower(strLetter) != 0;
            prevSeparator = strLetter == '_' || strLetter == ' ';

            ++strIter;
        }

        // Apply score for last match
        if (bestLetter) 
            score += bestLetterScore;

        // Did not match full pattern
        if (*patternIter != '\0')
            return false;

        outScore = score;
        return true;
    }

} // namespace fts

#endif // FTS_FUZZY_MATCH_H


================================================
FILE: source/json/json-forwards.h
================================================
/// Json-cpp amalgated forward header (http://jsoncpp.sourceforge.net/).
/// It is intended to be used with #include "json/json-forwards.h"
/// This header provides forward declaration for all JsonCpp types.

// //////////////////////////////////////////////////////////////////////
// Beginning of content of file: LICENSE
// //////////////////////////////////////////////////////////////////////

/*
The JsonCpp library's source code, including accompanying documentation, 
tests and demonstration applications, are licensed under the following
conditions...

The author (Baptiste Lepilleur) explicitly disclaims copyright in all 
jurisdictions which recognize such a disclaimer. In such jurisdictions, 
this software is released into the Public Domain.

In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is
released under the terms of the MIT License (see below).

In jurisdictions which recognize Public Domain property, the user of this 
software may choose to accept it either as 1) Public Domain, 2) under the 
conditions of the MIT License (see below), or 3) under the terms of dual 
Public Domain/MIT License conditions described here, as they choose.

The MIT License is about as close to Public Domain as a license can get, and is
described in clear, concise terms at:

   http://en.wikipedia.org/wiki/MIT_License
   
The full text of the MIT License follows:

========================================================================
Copyright (c) 2007-2010 Baptiste Lepilleur

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
========================================================================
(END LICENSE TEXT)

The MIT license is compatible with both the GPL and commercial
software, affording one all of the rights of Public Domain with the
minor nuisance of being required to keep the above copyright notice
and license text in the source code. Note also that by accepting the
Public Domain "license" you can re-license your copy using whatever
license you like.

*/

// //////////////////////////////////////////////////////////////////////
// End of content of file: LICENSE
// //////////////////////////////////////////////////////////////////////





#ifndef JSON_FORWARD_AMALGATED_H_INCLUDED
# define JSON_FORWARD_AMALGATED_H_INCLUDED
/// If defined, indicates that the source file is amalgated
/// to prevent private header inclusion.
#define JSON_IS_AMALGAMATION

// //////////////////////////////////////////////////////////////////////
// Beginning of content of file: include/json/config.h
// //////////////////////////////////////////////////////////////////////

// Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE

#ifndef JSON_CONFIG_H_INCLUDED
#define JSON_CONFIG_H_INCLUDED
#include <stddef.h>
#include <string> //typdef String

/// If defined, indicates that json library is embedded in CppTL library.
//# define JSON_IN_CPPTL 1

/// If defined, indicates that json may leverage CppTL library
//#  define JSON_USE_CPPTL 1
/// If defined, indicates that cpptl vector based map should be used instead of
/// std::map
/// as Value container.
//#  define JSON_USE_CPPTL_SMALLMAP 1

// If non-zero, the library uses exceptions to report bad input instead of C
// assertion macros. The default is to use exceptions.
#ifndef JSON_USE_EXCEPTION
#define JSON_USE_EXCEPTION 1
#endif

/// If defined, indicates that the source file is amalgated
/// to prevent private header inclusion.
/// Remarks: it is automatically defined in the generated amalgated header.
// #define JSON_IS_AMALGAMATION

#ifdef JSON_IN_CPPTL
#include <cpptl/config.h>
#ifndef JSON_USE_CPPTL
#define JSON_USE_CPPTL 1
#endif
#endif

#ifdef JSON_IN_CPPTL
#define JSON_API CPPTL_API
#elif defined(JSON_DLL_BUILD)
#if defined(_MSC_VER) || defined(__MINGW32__)
#define JSON_API __declspec(dllexport)
#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
#endif // if defined(_MSC_VER)
#elif defined(JSON_DLL)
#if defined(_MSC_VER) || defined(__MINGW32__)
#define JSON_API __declspec(dllimport)
#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
#endif // if defined(_MSC_VER)
#endif // ifdef JSON_IN_CPPTL
#if !defined(JSON_API)
#define JSON_API
#endif

// If JSON_NO_INT64 is defined, then Json only support C++ "int" type for
// integer
// Storages, and 64 bits integer support is disabled.
// #define JSON_NO_INT64 1

#if defined(_MSC_VER) // MSVC
#  if _MSC_VER <= 1200 // MSVC 6
    // Microsoft Visual Studio 6 only support conversion from __int64 to double
    // (no conversion from unsigned __int64).
#    define JSON_USE_INT64_DOUBLE_CONVERSION 1
    // Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255'
    // characters in the debug information)
    // All projects I've ever seen with VS6 were using this globally (not bothering
    // with pragma push/pop).
#    pragma warning(disable : 4786)
#  endif // MSVC 6

#  if _MSC_VER >= 1500 // MSVC 2008
    /// Indicates that the following function is deprecated.
#    define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
#  endif

#endif // defined(_MSC_VER)

#if defined(_MSC_VER) && _MSC_VER <= 1600 // MSVC <= 2010
# define JSONCPP_OVERRIDE
#else
# define JSONCPP_OVERRIDE override
#endif // MSVC <= 2010


#ifndef JSON_HAS_RVALUE_REFERENCES

#if defined(_MSC_VER) && _MSC_VER >= 1600 // MSVC >= 2010
#define JSON_HAS_RVALUE_REFERENCES 1
#endif // MSVC >= 2010

#ifdef __clang__
#if __has_feature(cxx_rvalue_references)
#define JSON_HAS_RVALUE_REFERENCES 1
#endif  // has_feature

#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L)
#define JSON_HAS_RVALUE_REFERENCES 1
#endif  // GXX_EXPERIMENTAL

#endif // __clang__ || __GNUC__

#endif // not defined JSON_HAS_RVALUE_REFERENCES

#ifndef JSON_HAS_RVALUE_REFERENCES
#define JSON_HAS_RVALUE_REFERENCES 0
#endif

#ifdef __clang__
#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
#  if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
#    define JSONCPP_DEPRECATED(message)  __attribute__ ((deprecated(message)))
#  elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
#    define JSONCPP_DEPRECATED(message)  __attribute__((__deprecated__))
#  endif  // GNUC version
#endif // __clang__ || __GNUC__

#if !defined(JSONCPP_DEPRECATED)
#define JSONCPP_DEPRECATED(message)
#endif // if !defined(JSONCPP_DEPRECATED)

#if __GNUC__ >= 6
#  define JSON_USE_INT64_DOUBLE_CONVERSION 1
#endif

#if !defined(JSON_IS_AMALGAMATION)

# include "version.h"

# if JSONCPP_USING_SECURE_MEMORY
#  include "allocator.h" //typedef Allocator
# endif

#endif // if !defined(JSON_IS_AMALGAMATION)

namespace Json {
typedef int Int;
typedef unsigned int UInt;
#if defined(JSON_NO_INT64)
typedef int LargestInt;
typedef unsigned int LargestUInt;
#undef JSON_HAS_INT64
#else                 // if defined(JSON_NO_INT64)
// For Microsoft Visual use specific types as long long is not supported
#if defined(_MSC_VER) // Microsoft Visual Studio
typedef __int64 Int64;
typedef unsigned __int64 UInt64;
#else                 // if defined(_MSC_VER) // Other platforms, use long long
typedef long long int Int64;
typedef unsigned long long int UInt64;
#endif // if defined(_MSC_VER)
typedef Int64 LargestInt;
typedef UInt64 LargestUInt;
#define JSON_HAS_INT64
#endif // if defined(JSON_NO_INT64)
#if JSONCPP_USING_SECURE_MEMORY
#define JSONCPP_STRING        std::basic_string<char, std::char_traits<char>, Json::SecureAllocator<char> >
#define JSONCPP_OSTRINGSTREAM std::basic_ostringstream<char, std::char_traits<char>, Json::SecureAllocator<char> >
#define JSONCPP_OSTREAM       std::basic_ostream<char, std::char_traits<char>>
#define JSONCPP_ISTRINGSTREAM std::basic_istringstream<char, std::char_traits<char>, Json::SecureAllocator<char> >
#define JSONCPP_ISTREAM       std::istream
#else
#define JSONCPP_STRING        std::string
#define JSONCPP_OSTRINGSTREAM std::ostringstream
#define JSONCPP_OSTREAM       std::ostream
#define JSONCPP_ISTRINGSTREAM std::istringstream
#define JSONCPP_ISTREAM       std::istream
#endif // if JSONCPP_USING_SECURE_MEMORY
} // end namespace Json

#endif // JSON_CONFIG_H_INCLUDED

// //////////////////////////////////////////////////////////////////////
// End of content of file: include/json/config.h
// //////////////////////////////////////////////////////////////////////






// //////////////////////////////////////////////////////////////////////
// Beginning of content of file: include/json/forwards.h
// //////////////////////////////////////////////////////////////////////

// Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE

#ifndef JSON_FORWARDS_H_INCLUDED
#define JSON_FORWARDS_H_INCLUDED

#if !defined(JSON_IS_AMALGAMATION)
#include "config.h"
#endif // if !defined(JSON_IS_AMALGAMATION)

namespace Json {

// writer.h
class FastWriter;
class StyledWriter;

// reader.h
class Reader;

// features.h
class Features;

// value.h
typedef unsigned int ArrayIndex;
class StaticString;
class Path;
class PathArgument;
class Value;
class ValueIteratorBase;
class ValueIterator;
class ValueConstIterator;

} // namespace Json

#endif // JSON_FORWARDS_H_INCLUDED

// //////////////////////////////////////////////////////////////////////
// End of content of file: include/json/forwards.h
// //////////////////////////////////////////////////////////////////////





#endif //ifndef JSON_FORWARD_AMALGATED_H_INCLUDED


================================================
FILE: source/json/json.h
================================================
/// Json-cpp amalgated header (http://jsoncpp.sourceforge.net/).
/// It is intended to be used with #include "json/json.h"

// //////////////////////////////////////////////////////////////////////
// Beginning of content of file: LICENSE
// //////////////////////////////////////////////////////////////////////

/*
The JsonCpp library's source code, including accompanying documentation, 
tests and demonstration applications, are licensed under the following
conditions...

The author (Baptiste Lepilleur) explicitly disclaims copyright in all 
jurisdictions which recognize such a disclaimer. In such jurisdictions, 
this software is released into the Public Domain.

In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is
released under the terms of the MIT License (see below).

In jurisdictions which recognize Public Domain property, the user of this 
software may choose to accept it either as 1) Public Domain, 2) under the 
conditions of the MIT License (see below), or 3) under the terms of dual 
Public Domain/MIT License conditions described here, as they choose.

The MIT License is about as close to Public Domain as a license can get, and is
described in clear, concise terms at:

   http://en.wikipedia.org/wiki/MIT_License
   
The full text of the MIT License follows:

========================================================================
Copyright (c) 2007-2010 Baptiste Lepilleur

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
========================================================================
(END LICENSE TEXT)

The MIT license is compatible with both the GPL and commercial
software, affording one all of the rights of Public Domain with the
minor nuisance of being required to keep the above copyright notice
and license text in the source code. Note also that by accepting the
Public Domain "license" you can re-license your copy using whatever
license you like.

*/

// //////////////////////////////////////////////////////////////////////
// End of content of file: LICENSE
// //////////////////////////////////////////////////////////////////////





#ifndef JSON_AMALGATED_H_INCLUDED
# define JSON_AMALGATED_H_INCLUDED
/// If defined, indicates that the source file is amalgated
/// to prevent private header inclusion.
#define JSON_IS_AMALGAMATION

// //////////////////////////////////////////////////////////////////////
// Beginning of content of file: include/json/version.h
// //////////////////////////////////////////////////////////////////////

// DO NOT EDIT. This file (and "version") is generated by CMake.
// Run CMake configure step to update it.
#ifndef JSON_VERSION_H_INCLUDED
# define JSON_VERSION_H_INCLUDED

# define JSONCPP_VERSION_STRING "1.7.2"
# define JSONCPP_VERSION_MAJOR 1
# define JSONCPP_VERSION_MINOR 7
# define JSONCPP_VERSION_PATCH 2
# define JSONCPP_VERSION_QUALIFIER
# define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8))

#ifdef JSONCPP_USING_SECURE_MEMORY
#undef JSONCPP_USING_SECURE_MEMORY
#endif
#define JSONCPP_USING_SECURE_MEMORY 0
// If non-zero, the library zeroes any memory that it has allocated before
// it frees its memory.

#endif // JSON_VERSION_H_INCLUDED

// //////////////////////////////////////////////////////////////////////
// End of content of file: include/json/version.h
// //////////////////////////////////////////////////////////////////////






// //////////////////////////////////////////////////////////////////////
// Beginning of content of file: include/json/config.h
// //////////////////////////////////////////////////////////////////////

// Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE

#ifndef JSON_CONFIG_H_INCLUDED
#define JSON_CONFIG_H_INCLUDED
#include <stddef.h>
#include <string> //typdef String

/// If defined, indicates that json library is embedded in CppTL library.
//# define JSON_IN_CPPTL 1

/// If defined, indicates that json may leverage CppTL library
//#  define JSON_USE_CPPTL 1
/// If defined, indicates that cpptl vector based map should be used instead of
/// std::map
/// as Value container.
//#  define JSON_USE_CPPTL_SMALLMAP 1

// If non-zero, the library uses exceptions to report bad input instead of C
// assertion macros. The default is to use exceptions.
#ifndef JSON_USE_EXCEPTION
#define JSON_USE_EXCEPTION 1
#endif

/// If defined, indicates that the source file is amalgated
/// to prevent private header inclusion.
/// Remarks: it is automatically defined in the generated amalgated header.
// #define JSON_IS_AMALGAMATION

#ifdef JSON_IN_CPPTL
#include <cpptl/config.h>
#ifndef JSON_USE_CPPTL
#define JSON_USE_CPPTL 1
#endif
#endif

#ifdef JSON_IN_CPPTL
#define JSON_API CPPTL_API
#elif defined(JSON_DLL_BUILD)
#if defined(_MSC_VER) || defined(__MINGW32__)
#define JSON_API __declspec(dllexport)
#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
#endif // if defined(_MSC_VER)
#elif defined(JSON_DLL)
#if defined(_MSC_VER) || defined(__MINGW32__)
#define JSON_API __declspec(dllimport)
#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
#endif // if defined(_MSC_VER)
#endif // ifdef JSON_IN_CPPTL
#if !defined(JSON_API)
#define JSON_API
#endif

// If JSON_NO_INT64 is defined, then Json only support C++ "int" type for
// integer
// Storages, and 64 bits integer support is disabled.
// #define JSON_NO_INT64 1

#if defined(_MSC_VER) // MSVC
#  if _MSC_VER <= 1200 // MSVC 6
    // Microsoft Visual Studio 6 only support conversion from __int64 to double
    // (no conversion from unsigned __int64).
#    define JSON_USE_INT64_DOUBLE_CONVERSION 1
    // Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255'
    // characters in the debug information)
    // All projects I've ever seen with VS6 were using this globally (not bothering
    // with pragma push/pop).
#    pragma warning(disable : 4786)
#  endif // MSVC 6

#  if _MSC_VER >= 1500 // MSVC 2008
    /// Indicates that the following function is deprecated.
#    define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
#  endif

#endif // defined(_MSC_VER)

#if defined(_MSC_VER) && _MSC_VER <= 1600 // MSVC <= 2010
# define JSONCPP_OVERRIDE
#else
# define JSONCPP_OVERRIDE override
#endif // MSVC <= 2010


#ifndef JSON_HAS_RVALUE_REFERENCES

#if defined(_MSC_VER) && _MSC_VER >= 1600 // MSVC >= 2010
#define JSON_HAS_RVALUE_REFERENCES 1
#endif // MSVC >= 2010

#ifdef __clang__
#if __has_feature(cxx_rvalue_references)
#define JSON_HAS_RVALUE_REFERENCES 1
#endif  // has_feature

#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L)
#define JSON_HAS_RVALUE_REFERENCES 1
#endif  // GXX_EXPERIMENTAL

#endif // __clang__ || __GNUC__

#endif // not defined JSON_HAS_RVALUE_REFERENCES

#ifndef JSON_HAS_RVALUE_REFERENCES
#define JSON_HAS_RVALUE_REFERENCES 0
#endif

#ifdef __clang__
#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
#  if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
#    define JSONCPP_DEPRECATED(message)  __attribute__ ((deprecated(message)))
#  elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
#    define JSONCPP_DEPRECATED(message)  __attribute__((__deprecated__))
#  endif  // GNUC version
#endif // __clang__ || __GNUC__

#if !defined(JSONCPP_DEPRECATED)
#define JSONCPP_DEPRECATED(message)
#endif // if !defined(JSONCPP_DEPRECATED)

#if __GNUC__ >= 6
#  define JSON_USE_INT64_DOUBLE_CONVERSION 1
#endif

#if !defined(JSON_IS_AMALGAMATION)

# include "version.h"

# if JSONCPP_USING_SECURE_MEMORY
#  include "allocator.h" //typedef Allocator
# endif

#endif // if !defined(JSON_IS_AMALGAMATION)

namespace Json {
typedef int Int;
typedef unsigned int UInt;
#if defined(JSON_NO_INT64)
typedef int LargestInt;
typedef unsigned int LargestUInt;
#undef JSON_HAS_INT64
#else                 // if defined(JSON_NO_INT64)
// For Microsoft Visual use specific types as long long is not supported
#if defined(_MSC_VER) // Microsoft Visual Studio
typedef __int64 Int64;
typedef unsigned __int64 UInt64;
#else                 // if defined(_MSC_VER) // Other platforms, use long long
typedef long long int Int64;
typedef unsigned long long int UInt64;
#endif // if defined(_MSC_VER)
typedef Int64 LargestInt;
typedef UInt64 LargestUInt;
#define JSON_HAS_INT64
#endif // if defined(JSON_NO_INT64)
#if JSONCPP_USING_SECURE_MEMORY
#define JSONCPP_STRING        std::basic_string<char, std::char_traits<char>, Json::SecureAllocator<char> >
#define JSONCPP_OSTRINGSTREAM std::basic_ostringstream<char, std::char_traits<char>, Json::SecureAllocator<char> >
#define JSONCPP_OSTREAM       std::basic_ostream<char, std::char_traits<char>>
#define JSONCPP_ISTRINGSTREAM std::basic_istringstream<char, std::char_traits<char>, Json::SecureAllocator<char> >
#define JSONCPP_ISTREAM       std::istream
#else
#define JSONCPP_STRING        std::string
#define JSONCPP_OSTRINGSTREAM std::ostringstream
#define JSONCPP_OSTREAM       std::ostream
#define JSONCPP_ISTRINGSTREAM std::istringstream
#define JSONCPP_ISTREAM       std::istream
#endif // if JSONCPP_USING_SECURE_MEMORY
} // end namespace Json

#endif // JSON_CONFIG_H_INCLUDED

// //////////////////////////////////////////////////////////////////////
// End of content of file: include/json/config.h
// //////////////////////////////////////////////////////////////////////






// //////////////////////////////////////////////////////////////////////
// Beginning of content of file: include/json/forwards.h
// //////////////////////////////////////////////////////////////////////

// Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE

#ifndef JSON_FORWARDS_H_INCLUDED
#define JSON_FORWARDS_H_INCLUDED

#if !defined(JSON_IS_AMALGAMATION)
#include "config.h"
#endif // if !defined(JSON_IS_AMALGAMATION)

namespace Json {

// writer.h
class FastWriter;
class StyledWriter;

// reader.h
class Reader;

// features.h
class Features;

// value.h
typedef unsigned int ArrayIndex;
class StaticString;
class Path;
class PathArgument;
class Value;
class ValueIteratorBase;
class ValueIterator;
class ValueConstIterator;

} // namespace Json

#endif // JSON_FORWARDS_H_INCLUDED

// //////////////////////////////////////////////////////////////////////
// End of content of file: include/json/forwards.h
// //////////////////////////////////////////////////////////////////////






// //////////////////////////////////////////////////////////////////////
// Beginning of content of file: include/json/features.h
// //////////////////////////////////////////////////////////////////////

// Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE

#ifndef CPPTL_JSON_FEATURES_H_INCLUDED
#define CPPTL_JSON_FEATURES_H_INCLUDED

#if !defined(JSON_IS_AMALGAMATION)
#include "forwards.h"
#endif // if !defined(JSON_IS_AMALGAMATION)

namespace Json {

/** \brief Configuration passed to reader and writer.
 * This configuration object can be used to force the Reader or Writer
 * to behave in a standard conforming way.
 */
class JSON_API Features {
public:
  /** \brief A configuration that allows all features and assumes all strings
   * are UTF-8.
   * - C & C++ comments are allowed
   * - Root object can be any JSON value
   * - Assumes Value strings are encoded in UTF-8
   */
  static Features all();

  /** \brief A configuration that is strictly compatible with the JSON
   * specification.
   * - Comments are forbidden.
   * - Root object must be either an array or an object value.
   * - Assumes Value strings are encoded in UTF-8
   */
  static Features strictMode();

  /** \brief Initialize the configuration like JsonConfig::allFeatures;
   */
  Features();

  /// \c true if comments are allowed. Default: \c true.
  bool allowComments_;

  /// \c true if root must be either an array or an object value. Default: \c
  /// false.
  bool strictRoot_;

  /// \c true if dropped null placeholders are allowed. Default: \c false.
  bool allowDroppedNullPlaceholders_;

  /// \c true if numeric object key are allowed. Default: \c false.
  bool allowNumericKeys_;
};

} // namespace Json

#endif // CPPTL_JSON_FEATURES_H_INCLUDED

// //////////////////////////////////////////////////////////////////////
// End of content of file: include/json/features.h
// //////////////////////////////////////////////////////////////////////






// //////////////////////////////////////////////////////////////////////
// Beginning of content of file: include/json/value.h
// //////////////////////////////////////////////////////////////////////

// Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE

#ifndef CPPTL_JSON_H_INCLUDED
#define CPPTL_JSON_H_INCLUDED

#if !defined(JSON_IS_AMALGAMATION)
#include "forwards.h"
#endif // if !defined(JSON_IS_AMALGAMATION)
#include <string>
#include <vector>
#include <exception>

#ifndef JSON_USE_CPPTL_SMALLMAP
#include <map>
#else
#include <cpptl/smallmap.h>
#endif
#ifdef JSON_USE_CPPTL
#include <cpptl/forwards.h>
#endif

//Conditional NORETURN attribute on the throw functions would:
// a) suppress false positives from static code analysis 
// b) possibly improve optimization opportunities.
#if !defined(JSONCPP_NORETURN)
#  if defined(_MSC_VER)
#    define JSONCPP_NORETURN __declspec(noreturn)
#  elif defined(__GNUC__)
#    define JSONCPP_NORETURN __attribute__ ((__noreturn__))
#  else
#    define JSONCPP_NORETURN
#  endif
#endif

// Disable warning C4251: <data member>: <type> needs to have dll-interface to
// be used by...
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
#pragma warning(push)
#pragma warning(disable : 4251)
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)

/** \brief JSON (JavaScript Object Notation).
 */
namespace Json {

/** Base class for all exceptions we throw.
 *
 * We use nothing but these internally. Of course, STL can throw others.
 */
class JSON_API Exception : public std::exception {
public:
  Exception(JSONCPP_STRING const& msg);
  ~Exception() throw() JSONCPP_OVERRIDE;
  char const* what() const throw() JSONCPP_OVERRIDE;
protected:
  JSONCPP_STRING msg_;
};

/** Exceptions which the user cannot easily avoid.
 *
 * E.g. out-of-memory (when we use malloc), stack-overflow, malicious input
 * 
 * \remark derived from Json::Exception
 */
class JSON_API RuntimeError : public Exception {
public:
  RuntimeError(JSONCPP_STRING const& msg);
};

/** Exceptions thrown by JSON_ASSERT/JSON_FAIL macros.
 *
 * These are precondition-violations (user bugs) and internal errors (our bugs).
 * 
 * \remark derived from Json::Exception
 */
class JSON_API LogicError : public Exception {
public:
  LogicError(JSONCPP_STRING const& msg);
};

/// used internally
JSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const& msg);
/// used internally
JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg);

/** \brief Type of the value held by a Value object.
 */
enum ValueType {
  nullValue = 0, ///< 'null' value
  intValue,      ///< signed integer value
  uintValue,     ///< unsigned integer value
  realValue,     ///< double value
  stringValue,   ///< UTF-8 string value
  booleanValue,  ///< bool value
  arrayValue,    ///< array value (ordered list)
  objectValue    ///< object value (collection of name/value pairs).
};

enum CommentPlacement {
  commentBefore = 0,      ///< a comment placed on the line before a value
  commentAfterOnSameLine, ///< a comment just after a value on the same line
  commentAfter, ///< a comment on the line after a value (only make sense for
  /// root value)
  numberOfCommentPlacement
};

//# ifdef JSON_USE_CPPTL
//   typedef CppTL::AnyEnumerator<const char *> EnumMemberNames;
//   typedef CppTL::AnyEnumerator<const Value &> EnumValues;
//# endif

/** \brief Lightweight wrapper to tag static string.
 *
 * Value constructor and objectValue member assignement takes advantage of the
 * StaticString and avoid the cost of string duplication when storing the
 * string or the member name.
 *
 * Example of usage:
 * \code
 * Json::Value aValue( StaticString("some text") );
 * Json::Value object;
 * static const StaticString code("code");
 * object[code] = 1234;
 * \endcode
 */
class JSON_API StaticString {
public:
  explicit StaticString(const char* czstring) : c_str_(czstring) {}

  operator const char*() const { return c_str_; }

  const char* c_str() const { return c_str_; }

private:
  const char* c_str_;
};

/** \brief Represents a <a HREF="http://www.json.org">JSON</a> value.
 *
 * This class is a discriminated union wrapper that can represents a:
 * - signed integer [range: Value::minInt - Value::maxInt]
 * - unsigned integer (range: 0 - Value::maxUInt)
 * - double
 * - UTF-8 string
 * - boolean
 * - 'null'
 * - an ordered list of Value
 * - collection of name/value pairs (javascript object)
 *
 * The type of the held value is represented by a #ValueType and
 * can be obtained using type().
 *
 * Values of an #objectValue or #arrayValue can be accessed using operator[]()
 * methods.
 * Non-const methods will automatically create the a #nullValue element
 * if it does not exist.
 * The sequence of an #arrayValue will be automatically resized and initialized
 * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue.
 *
 * The get() methods can be used to obtain default value in the case the
 * required element does not exist.
 *
 * It is possible to iterate over the list of a #objectValue values using
 * the getMemberNames() method.
 *
 * \note #Value string-length fit in size_t, but keys must be < 2^30.
 * (The reason is an implementation detail.) A #CharReader will raise an
 * exception if a bound is exceeded to avoid security holes in your app,
 * but the Value API does *not* check bounds. That is the responsibility
 * of the caller.
 */
class JSON_API Value {
  friend class ValueIteratorBase;
public:
  typedef std::vector<JSONCPP_STRING> Members;
  typedef ValueIterator iterator;
  typedef ValueConstIterator const_iterator;
  typedef Json::UInt UInt;
  typedef Json::Int Int;
#if defined(JSON_HAS_INT64)
  typedef Json::UInt64 UInt64;
  typedef Json::Int64 Int64;
#endif // defined(JSON_HAS_INT64)
  typedef Json::LargestInt LargestInt;
  typedef Json::LargestUInt LargestUInt;
  typedef Json::ArrayIndex ArrayIndex;

  static const Value& null;  ///< We regret this reference to a global instance; prefer the simpler Value().
  static const Value& nullRef;  ///< just a kludge for binary-compatibility; same as null
  /// Minimum signed integer value that can be stored in a Json::Value.
  static const LargestInt minLargestInt;
  /// Maximum signed integer value that can be stored in a Json::Value.
  static const LargestInt maxLargestInt;
  /// Maximum unsigned integer value that can be stored in a Json::Value.
  static const LargestUInt maxLargestUInt;

  /// Minimum signed int value that can be stored in a Json::Value.
  static const Int minInt;
  /// Maximum signed int value that can be stored in a Json::Value.
  static const Int maxInt;
  /// Maximum unsigned int value that can be stored in a Json::Value.
  static const UInt maxUInt;

#if defined(JSON_HAS_INT64)
  /// Minimum signed 64 bits int value that can be stored in a Json::Value.
  static const Int64 minInt64;
  /// Maximum signed 64 bits int value that can be stored in a Json::Value.
  static const Int64 maxInt64;
  /// Maximum unsigned 64 bits int value that can be stored in a Json::Value.
  static const UInt64 maxUInt64;
#endif // defined(JSON_HAS_INT64)

private:
#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
  class CZString {
  public:
    enum DuplicationPolicy {
      noDuplication = 0,
      duplicate,
      duplicateOnCopy
    };
    CZString(ArrayIndex index);
    CZString(char const* str, unsigned length, DuplicationPolicy allocate);
    CZString(CZString const& other);
#if JSON_HAS_RVALUE_REFERENCES
    CZString(CZString&& other);
#endif
    ~CZString();
    CZString& operator=(CZString other);
    bool operator<(CZString const& other) const;
    bool operator==(CZString const& other) const;
    ArrayIndex index() const;
    //const char* c_str() const; ///< \deprecated
    char const* data() const;
    unsigned length() const;
    bool isStaticString() const;

  private:
    void swap(CZString& other);

    struct StringStorage {
      unsigned policy_: 2;
      unsigned length_: 30; // 1GB max
    };

    char const* cstr_;  // actually, a prefixed string, unless policy is noDup
    union {
      ArrayIndex index_;
      StringStorage storage_;
    };
  };

public:
#ifndef JSON_USE_CPPTL_SMALLMAP
  typedef std::map<CZString, Value> ObjectValues;
#else
  typedef CppTL::SmallMap<CZString, Value> ObjectValues;
#endif // ifndef JSON_USE_CPPTL_SMALLMAP
#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION

public:
  /** \brief Create a default Value of the given type.

    This is a very useful constructor.
    To create an empty array, pass arrayValue.
    To create an empty object, pass objectValue.
    Another Value can then be set to this one by assignment.
This is useful since clear() and resize() will not alter types.

    Examples:
\code
Json::Value null_value; // null
Json::Value arr_value(Json::arrayValue); // []
Json::Value obj_value(Json::objectValue); // {}
\endcode
  */
  Value(ValueType type = nullValue);
  Value(Int value);
  Value(UInt value);
#if defined(JSON_HAS_INT64)
  Value(Int64 value);
  Value(UInt64 value);
#endif // if defined(JSON_HAS_INT64)
  Value(double value);
  Value(const char* value); ///< Copy til first 0. (NULL causes to seg-fault.)
  Value(const char* begin, const char* end); ///< Copy all, incl zeroes.
  /** \brief Constructs a value from a static string.

   * Like other value string constructor but do not duplicate the string for
   * internal storage. The given string must remain alive after the call to this
   * constructor.
   * \note This works only for null-terminated strings. (We cannot change the
   *   size of this class, so we have nowhere to store the length,
   *   which might be computed later for various operations.)
   *
   * Example of usage:
   * \code
   * static StaticString foo("some text");
   * Json::Value aValue(foo);
   * \endcode
   */
  Value(const StaticString& value);
  Value(const JSONCPP_STRING& value); ///< Copy data() til size(). Embedded zeroes too.
#ifdef JSON_USE_CPPTL
  Value(const CppTL::ConstString& value);
#endif
  Value(bool value);
  /// Deep copy.
  Value(const Value& other);
#if JSON_HAS_RVALUE_REFERENCES
  /// Move constructor
  Value(Value&& other);
#endif
  ~Value();

  /// Deep copy, then swap(other).
  /// \note Over-write existing comments. To preserve comments, use #swapPayload().
  Value& operator=(Value other);
  /// Swap everything.
  void swap(Value& other);
  /// Swap values but leave comments and source offsets in place.
  void swapPayload(Value& other);

  ValueType type() const;

  /// Compare payload only, not comments etc.
  bool operator<(const Value& other) const;
  bool operator<=(const Value& other) const;
  bool operator>=(const Value& other) const;
  bool operator>(const Value& other) const;
  bool operator==(const Value& other) const;
  bool operator!=(const Value& other) const;
  int compare(const Value& other) const;

  const char* asCString() const; ///< Embedded zeroes could cause you trouble!
#if JSONCPP_USING_SECURE_MEMORY
  unsigned getCStringLength() const; //Allows you to understand the length of the CString
#endif
  JSONCPP_STRING asString() const; ///< Embedded zeroes are possible.
  /** Get raw char* of string-value.
   *  \return false if !string. (Seg-fault if str or end are NULL.)
   */
  bool getString(
      char const** begin, char const** end) const;
#ifdef JSON_USE_CPPTL
  CppTL::ConstString asConstString() const;
#endif
  Int asInt() const;
  UInt asUInt() const;
#if defined(JSON_HAS_INT64)
  Int64 asInt64() const;
  UInt64 asUInt64() const;
#endif // if defined(JSON_HAS_INT64)
  LargestInt asLargestInt() const;
  LargestUInt asLargestUInt() const;
  float asFloat() const;
  double asDouble() const;
  bool asBool() const;

  bool isNull() const;
  bool isBool() const;
  bool isInt() const;
  bool isInt64() const;
  bool isUInt() const;
  bool isUInt64() const;
  bool isIntegral() const;
  bool isDouble() const;
  bool isNumeric() const;
  bool isString() const;
  bool isArray() const;
  bool isObject() const;

  bool isConvertibleTo(ValueType other) const;

  /// Number of values in array or object
  ArrayIndex size() const;

  /// \brief Return true if empty array, empty object, or null;
  /// otherwise, false.
  bool empty() const;

  /// Return isNull()
  bool operator!() const;

  /// Remove all object members and array elements.
  /// \pre type() is arrayValue, objectValue, or nullValue
  /// \post type() is unchanged
  void clear();

  /// Resize the array to size elements.
  /// New elements are initialized to null.
  /// May only be called on nullValue or arrayValue.
  /// \pre type() is arrayValue or nullValue
  /// \post type() is arrayValue
  void resize(ArrayIndex size);

  /// Access an array element (zero based index ).
  /// If the array contains less than index element, then null value are
  /// inserted
  /// in the array so that its size is index+1.
  /// (You may need to say 'value[0u]' to get your compiler to distinguish
  ///  this from the operator[] which takes a string.)
  Value& operator[](ArrayIndex index);

  /// Access an array element (zero based index ).
  /// If the array contains less than index element, then null value are
  /// inserted
  /// in the array so that its size is index+1.
  /// (You may need to say 'value[0u]' to get your compiler to distinguish
  ///  this from the operator[] which takes a string.)
  Value& operator[](int index);

  /// Access an array element (zero based index )
  /// (You may need to say 'value[0u]' to get your compiler to distinguish
  ///  this from the operator[] which takes a string.)
  const Value& operator[](ArrayIndex index) const;

  /// Access an array element (zero based index )
  /// (You may need to say 'value[0u]' to get your compiler to distinguish
  ///  this from the operator[] which takes a string.)
  const Value& operator[](int index) const;

  /// If the array contains at least index+1 elements, returns the element
  /// value,
  /// otherwise returns defaultValue.
  Value get(ArrayIndex index, const Value& defaultValue) const;
  /// Return true if index < size().
  bool isValidIndex(ArrayIndex index) const;
  /// \brief Append value to array at the end.
  ///
  /// Equivalent to jsonvalue[jsonvalue.size()] = value;
  Value& append(const Value& value);

  /// Access an object value by name, create a null member if it does not exist.
  /// \note Because of our implementation, keys are limited to 2^30 -1 chars.
  ///  Exceeding that will cause an exception.
  Value& operator[](const char* key);
  /// Access an object value by name, returns null if there is no member with
  /// that name.
  const Value& operator[](const char* key) const;
  /// Access an object value by name, create a null member if it does not exist.
  /// \param key may contain embedded nulls.
  Value& operator[](const JSONCPP_STRING& key);
  /// Access an object value by name, returns null if there is no member with
  /// that name.
  /// \param key may contain embedded nulls.
  const Value& operator[](const JSONCPP_STRING& key) const;
  /** \brief Access an object value by name, create a null member if it does not
   exist.

   * If the object has no entry for that name, then the member name used to store
   * the new entry is not duplicated.
   * Example of use:
   * \code
   * Json::Value object;
   * static const StaticString code("code");
   * object[code] = 1234;
   * \endcode
   */
  Value& operator[](const StaticString& key);
#ifdef JSON_USE_CPPTL
  /// Access an object value by name, create a null member if it does not exist.
  Value& operator[](const CppTL::ConstString& key);
  /// Access an object value by name, returns null if there is no member with
  /// that name.
  const Value& operator[](const CppTL::ConstString& key) const;
#endif
  /// Return the member named key if it exist, defaultValue otherwise.
  /// \note deep copy
  Value get(const char* key, const Value& defaultValue) const;
  /// Return the member named key if it exist, defaultValue otherwise.
  /// \note deep copy
  /// \note key may contain embedded nulls.
  Value get(const char* begin, const char* end, const Value& defaultValue) const;
  /// Return the member named key if it exist, defaultValue otherwise.
  /// \note deep copy
  /// \param key may contain embedded nulls.
  Value get(const JSONCPP_STRING& key, const Value& defaultValue) const;
#ifdef JSON_USE_CPPTL
  /// Return the member named key if it exist, defaultValue otherwise.
  /// \note deep copy
  Value get(const CppTL::ConstString& key, const Value& defaultValue) const;
#endif
  /// Most general and efficient version of isMember()const, get()const,
  /// and operator[]const
  /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30
  Value const* find(char const* begin, char const* end) const;
  /// Most general and efficient version of object-mutators.
  /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30
  /// \return non-zero, but JSON_ASSERT if this is neither object nor nullValue.
  Value const* demand(char const* begin, char const* end);
  /// \brief Remove and return the named member.
  ///
  /// Do nothing if it did not exist.
  /// \return the removed Value, or null.
  /// \pre type() is objectValue or nullValue
  /// \post type() is unchanged
  /// \deprecated
  Value removeMember(const char* key);
  /// Same as removeMember(const char*)
  /// \param key may contain embedded nulls.
  /// \deprecated
  Value removeMember(const JSONCPP_STRING& key);
  /// Same as removeMember(const char* begin, const char* end, Value* removed),
  /// but 'key' is null-terminated.
  bool removeMember(const char* key, Value* removed);
  /** \brief Remove the named map member.

      Update 'removed' iff removed.
      \param key may contain embedded nulls.
      \return true iff removed (no exceptions)
  */
  bool removeMember(JSONCPP_STRING const& key, Value* removed);
  /// Same as removeMember(JSONCPP_STRING const& key, Value* removed)
  bool removeMember(const char* begin, const char* end, Value* removed);
  /** \brief Remove the indexed array element.

      O(n) expensive operations.
      Update 'removed' iff removed.
      \return true iff removed (no exceptions)
  */
  bool removeIndex(ArrayIndex i, Value* removed);

  /// Return true if the object has a member named key.
  /// \note 'key' must be null-terminated.
  bool isMember(const char* key) const;
  /// Return true if the object has a member named key.
  /// \param key may contain embedded nulls.
  bool isMember(const JSONCPP_STRING& key) const;
  /// Same as isMember(JSONCPP_STRING const& key)const
  bool isMember(const char* begin, const char* end) const;
#ifdef JSON_USE_CPPTL
  /// Return true if the object has a member named key.
  bool isMember(const CppTL::ConstString& key) const;
#endif

  /// \brief Return a list of the member names.
  ///
  /// If null, return an empty list.
  /// \pre type() is objectValue or nullValue
  /// \post if type() was nullValue, it remains nullValue
  Members getMemberNames() const;

  //# ifdef JSON_USE_CPPTL
  //      EnumMemberNames enumMemberNames() const;
  //      EnumValues enumValues() const;
  //# endif

  /// \deprecated Always pass len.
  JSONCPP_DEPRECATED("Use setComment(JSONCPP_STRING const&) instead.")
  void setComment(const char* comment, CommentPlacement placement);
  /// Comments must be //... or /* ... */
  void setComment(const char* comment, size_t len, CommentPlacement placement);
  /// Comments must be //... or /* ... */
  void setComment(const JSONCPP_STRING& comment, CommentPlacement placement);
  bool hasComment(CommentPlacement placement) const;
  /// Include delimiters and embedded newlines.
  JSONCPP_STRING getComment(CommentPlacement placement) const;

  JSONCPP_STRING toStyledString() const;

  const_iterator begin() const;
  const_iterator end() const;

  iterator begin();
  iterator end();

  // Accessors for the [start, limit) range of bytes within the JSON text from
  // which this value was parsed, if any.
  void setOffsetStart(ptrdiff_t start);
  void setOffsetLimit(ptrdiff_t limit);
  ptrdiff_t getOffsetStart() const;
  ptrdiff_t getOffsetLimit() const;

private:
  void initBasic(ValueType type, bool allocated = false);

  Value& resolveReference(const char* key);
  Value& resolveReference(const char* key, const char* end);

  struct CommentInfo {
    CommentInfo();
    ~CommentInfo();

    void setComment(const char* text, size_t len);

    char* comment_;
  };

  // struct MemberNamesTransform
  //{
  //   typedef const char *result_type;
  //   const char *operator()( const CZString &name ) const
  //   {
  //      return name.c_str();
  //   }
  //};

  union ValueHolder {
    LargestInt int_;
    LargestUInt uint_;
    double real_;
    bool bool_;
    char* string_;  // actually ptr to unsigned, followed by str, unless !allocated_
    ObjectValues* map_;
  } value_;
  ValueType type_ : 8;
  unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
                               // If not allocated_, string_ must be null-terminated.
  CommentInfo* comments_;

  // [start, limit) byte offsets in the source JSON text from which this Value
  // was extracted.
  ptrdiff_t start_;
  ptrdiff_t limit_;
};

/** \brief Experimental and untested: represents an element of the "path" to
 * access a node.
 */
class JSON_API PathArgument {
public:
  friend class Path;

  PathArgument();
  PathArgument(ArrayIndex index);
  PathArgument(const char* key);
  PathArgument(const JSONCPP_STRING& key);

private:
  enum Kind {
    kindNone = 0,
    kindIndex,
    kindKey
  };
  JSONCPP_STRING key_;
  ArrayIndex index_;
  Kind kind_;
};

/** \brief Experimental and untested: represents a "path" to access a node.
 *
 * Syntax:
 * - "." => root node
 * - ".[n]" => elements at index 'n' of root node (an array value)
 * - ".name" => member named 'name' of root node (an object value)
 * - ".name1.name2.name3"
 * - ".[0][1][2].name1[3]"
 * - ".%" => member name is provided as parameter
 * - ".[%]" => index is provied as parameter
 */
class JSON_API Path {
public:
  Path(const JSONCPP_STRING& path,
       const PathArgument& a1 = PathArgument(),
       const PathArgument& a2 = PathArgument(),
       const PathArgument& a3 = PathArgument(),
       const PathArgument& a4 = PathArgument(),
       const PathArgument& a5 = PathArgument());

  const Value& resolve(const Value& root) const;
  Value resolve(const Value& root, const Value& defaultValue) const;
  /// Creates the "path" to access the specified node and returns a reference on
  /// the node.
  Value& make(Value& root) const;

private:
  typedef std::vector<const PathArgument*> InArgs;
  typedef std::vector<PathArgument> Args;

  void makePath(const JSONCPP_STRING& path, const InArgs& in);
  void addPathInArg(const JSONCPP_STRING& path,
                    const InArgs& in,
                    InArgs::const_iterator& itInArg,
                    PathArgument::Kind kind);
  void invalidPath(const JSONCPP_STRING& path, int location);

  Args args_;
};

/** \brief base class for Value iterators.
 *
 */
class JSON_API ValueIteratorBase {
public:
  typedef std::bidirectional_iterator_tag iterator_category;
  typedef unsigned int size_t;
  typedef int difference_type;
  typedef ValueIteratorBase SelfType;

  bool operator==(const SelfType& other) const { return isEqual(other); }

  bool operator!=(const SelfType& other) const { return !isEqual(other); }

  difference_type operator-(const SelfType& other) const {
    return other.computeDistance(*this);
  }

  /// Return either the index or the member name of the referenced value as a
  /// Value.
  Value key() const;

  /// Return the index of the referenced Value, or -1 if it is not an arrayValue.
  UInt index() const;

  /// Return the member name of the referenced Value, or "" if it is not an
  /// objectValue.
  /// \note Avoid `c_str()` on result, as embedded zeroes are possible.
  JSONCPP_STRING name() const;

  /// Return the member name of the referenced Value. "" if it is not an
  /// objectValue.
  /// \deprecated This cannot be used for UTF-8 strings, since there can be embedded nulls.
  JSONCPP_DEPRECATED("Use `key = name();` instead.")
  char const* memberName() const;
  /// Return the member name of the referenced Value, or NULL if it is not an
  /// objectValue.
  /// \note Better version than memberName(). Allows embedded nulls.
  char const* memberName(char const** end) const;

protected:
  Value& deref() const;

  void increment();

  void decrement();

  difference_type computeDistance(const SelfType& other) const;

  bool isEqual(const SelfType& other) const;

  void copy(const SelfType& other);

private:
  Value::ObjectValues::iterator current_;
  // Indicates that iterator is for a null value.
  bool isNull_;

public:
  // For some reason, BORLAND needs these at the end, rather
  // than earlier. No idea why.
  ValueIteratorBase();
  explicit ValueIteratorBase(const Value::ObjectValues::iterator& current);
};

/** \brief const iterator for object and array value.
 *
 */
class JSON_API ValueConstIterator : public ValueIteratorBase {
  friend class Value;

public:
  typedef const Value value_type;
  //typedef unsigned int size_t;
  //typedef int difference_type;
  typedef const Value& reference;
  typedef const Value* pointer;
  typedef ValueConstIterator SelfType;

  ValueConstIterator();
  ValueConstIterator(ValueIterator const& other);

private:
/*! \internal Use by Value to create an iterator.
 */
  explicit ValueConstIterator(const Value::ObjectValues::iterator& current);
public:
  SelfType& operator=(const ValueIteratorBase& other);

  SelfType operator++(int) {
    SelfType temp(*this);
    ++*this;
    return temp;
  }

  SelfType operator--(int) {
    SelfType temp(*this);
    --*this;
    return temp;
  }

  SelfType& operator--() {
    decrement();
    return *this;
  }

  SelfType& operator++() {
    increment();
    return *this;
  }

  reference operator*() const { return deref(); }

  pointer operator->() const { return &deref(); }
};

/** \brief Iterator for object and array value.
 */
class JSON_API ValueIterator : public ValueIteratorBase {
  friend class Value;

public:
  typedef Value value_type;
  typedef unsigned int size_t;
  typedef int difference_type;
  typedef Value& reference;
  typedef Value* pointer;
  typedef ValueIterator SelfType;

  ValueIterator();
  explicit ValueIterator(const ValueConstIterator& other);
  ValueIterator(const ValueIterator& other);

private:
/*! \internal Use by Value to create an iterator.
 */
  explicit ValueIterator(const Value::ObjectValues::iterator& current);
public:
  SelfType& operator=(const SelfType& other);

  SelfType operator++(int) {
    SelfType temp(*this);
    ++*this;
    return temp;
  }

  SelfType operator--(int) {
    SelfType temp(*this);
    --*this;
    return temp;
  }

  SelfType& operator--() {
    decrement();
    return *this;
  }

  SelfType& operator++() {
    increment();
    return *this;
  }

  reference operator*() const { return deref(); }

  pointer operator->() const { return &deref(); }
};

} // namespace Json


namespace std {
/// Specialize std::swap() for Json::Value.
template<>
inline void swap(Json::Value& a, Json::Value& b) { a.swap(b); }
}


#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
#pragma warning(pop)
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)

#endif // CPPTL_JSON_H_INCLUDED

// //////////////////////////////////////////////////////////////////////
// End of content of file: include/json/value.h
// //////////////////////////////////////////////////////////////////////






// //////////////////////////////////////////////////////////////////////
// Beginning of content of file: include/json/reader.h
// //////////////////////////////////////////////////////////////////////

// Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE

#ifndef CPPTL_JSON_READER_H_INCLUDED
#define CPPTL_JSON_READER_H_INCLUDED

#if !defined(JSON_IS_AMALGAMATION)
#include "features.h"
#include "value.h"
#endif // if !defined(JSON_IS_AMALGAMATION)
#include <deque>
#include <iosfwd>
#include <stack>
#include <string>
#include <istream>

// Disable warning C4251: <data member>: <type> needs to have dll-interface to
// be used by...
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
#pragma warning(push)
#pragma warning(disable : 4251)
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)

namespace Json {

/** \brief Unserialize a <a HREF="http://www.json.org">JSON</a> document into a
 *Value.
 *
 * \deprecated Use CharReader and CharReaderBuilder.
 */
class JSON_API Reader {
public:
  typedef char Char;
  typedef const Char* Location;

  /** \brief An error tagged with where in the JSON text it was encountered.
   *
   * The offsets give the [start, limit) range of bytes within the text. Note
   * that this is bytes, not codepoints.
   *
   */
  struct StructuredError {
    ptrdiff_t offset_start;
    ptrdiff_t offset_limit;
    JSONCPP_STRING message;
  };

  /** \brief Constructs a Reader allowing all features
   * for parsing.
   */
  Reader();

  /** \brief Constructs a Reader allowing the specified feature set
   * for parsing.
   */
  Reader(const Features& features);

  /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
   * document.
   * \param document UTF-8 encoded string containing the document to read.
   * \param root [out] Contains the root value of the document if it was
   *             successfully parsed.
   * \param collectComments \c true to collect comment and allow writing them
   * back during
   *                        serialization, \c false to discard comments.
   *                        This parameter is ignored if
   * Features::allowComments_
   *                        is \c false.
   * \return \c true if the document was successfully parsed, \c false if an
   * error occurred.
   */
  bool
  parse(const std::string& document, Value& root, bool collectComments = true);

  /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
   document.
   * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the
   document to read.
   * \param endDoc Pointer on the end of the UTF-8 encoded string of the
   document to read.
   *               Must be >= beginDoc.
   * \param root [out] Contains the root value of the document if it was
   *             successfully parsed.
   * \param collectComments \c true to collect comment and allow writing them
   back during
   *                        serialization, \c false to discard comments.
   *                        This parameter is ignored if
   Features::allowComments_
   *                        is \c false.
   * \return \c true if the document was successfully parsed, \c false if an
   error occurred.
   */
  bool parse(const char* beginDoc,
             const char* endDoc,
             Value& root,
             bool collectComments = true);

  /// \brief Parse from input stream.
  /// \see Json::operator>>(std::istream&, Json::Value&).
  bool parse(JSONCPP_ISTREAM& is, Value& root, bool collectComments = true);

  /** \brief Returns a user friendly string that list errors in the parsed
   * document.
   * \return Formatted error message with the list of errors with their location
   * in
   *         the parsed document. An empty string is returned if no error
   * occurred
   *         during parsing.
   * \deprecated Use getFormattedErrorMessages() instead (typo fix).
   */
  JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.")
  JSONCPP_STRING getFormatedErrorMessages() const;

  /** \brief Returns a user friendly string that list errors in the parsed
   * document.
   * \return Formatted error message with the list of errors with their location
   * in
   *         the parsed document. An empty string is returned if no error
   * occurred
   *         during parsing.
   */
  JSONCPP_STRING getFormattedErrorMessages() const;

  /** \brief Returns a vector of structured erros encounted while parsing.
   * \return A (possibly empty) vector of StructuredError objects. Currently
   *         only one error can be returned, but the caller should tolerate
   * multiple
   *         errors.  This can occur if the parser recovers from a non-fatal
   *         parse error and then encounters additional errors.
   */
  std::vector<StructuredError> getStructuredErrors() const;

  /** \brief Add a semantic error message.
   * \param value JSON Value location associated with the error
   * \param message The error message.
   * \return \c true if the error was successfully added, \c false if the
   * Value offset exceeds the document size.
   */
  bool pushError(const Value& value, const JSONCPP_STRING& message);

  /** \brief Add a semantic error message with extra context.
   * \param value JSON Value location associated with the error
   * \param message The error message.
   * \param extra Additional JSON Value location to contextualize the error
   * \return \c true if the error was successfully added, \c false if either
   * Value offset exceeds the document size.
   */
  bool pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra);

  /** \brief Return whether there are any errors.
   * \return \c true if there are no errors to report \c false if
   * errors have occurred.
   */
  bool good() const;

private:
  enum TokenType {
    tokenEndOfStream = 0,
    tokenObjectBegin,
    tokenObjectEnd,
    tokenArrayBegin,
    tokenArrayEnd,
    tokenString,
    tokenNumber,
    tokenTrue,
    tokenFalse,
    tokenNull,
    tokenArraySeparator,
    tokenMemberSeparator,
    tokenComment,
    tokenError
  };

  class Token {
  public:
    TokenType type_;
    Location start_;
    Location end_;
  };

  class ErrorInfo {
  public:
    Token token_;
    JSONCPP_STRING message_;
    Location extra_;
  };

  typedef std::deque<ErrorInfo> Errors;

  bool readToken(Token& token);
  void skipSpaces();
  bool match(Location pattern, int patternLength);
  bool readComment();
  bool readCStyleComment();
  bool readCppStyleComment();
  bool readString();
  void readNumber();
  bool readValue();
  bool readObject(Token& token);
  bool readArray(Token& token);
  bool decodeNumber(Token& token);
  bool decodeNumber(Token& token, Value& decoded);
  bool decodeString(Token& token);
  bool decodeString(Token& token, JSONCPP_STRING& decoded);
  bool decodeDouble(Token& token);
  bool decodeDouble(Token& token, Value& decoded);
  bool decodeUnicodeCodePoint(Token& token,
                              Location& current,
                              Location end,
                              unsigned int& unicode);
  bool decodeUnicodeEscapeSequence(Token& token,
                                   Location& current,
                                   Location end,
                                   unsigned int& unicode);
  bool addError(const JSONCPP_STRING& message, Token& token, Location extra = 0);
  bool recoverFromError(TokenType skipUntilToken);
  bool addErrorAndRecover(const JSONCPP_STRING& message,
                          Token& token,
                          TokenType skipUntilToken);
  void skipUntilSpace();
  Value& currentValue();
  Char getNextChar();
  void
  getLocationLineAndColumn(Location location, int& line, int& column) const;
  JSONCPP_STRING getLocationLineAndColumn(Location location) const;
  void addComment(Location begin, Location end, CommentPlacement placement);
  void skipCommentTokens(Token& token);

  typedef std::stack<Value*> Nodes;
  Nodes nodes_;
  Errors errors_;
  JSONCPP_STRING document_;
  Location begin_;
  Location end_;
  Location current_;
  Location lastValueEnd_;
  Value* lastValue_;
  JSONCPP_STRING commentsBefore_;
  Features features_;
  bool collectComments_;
};  // Reader

/** Interface for reading JSON from a char array.
 */
class JSON_API CharReader {
public:
  virtual ~CharReader() {}
  /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
   document.
   * The document must be a UTF-8 encoded string containing the document to read.
   *
   * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the
   document to read.
   * \param endDoc Pointer on the end of the UTF-8 encoded string of the
   document to read.
   *        Must be >= beginDoc.
   * \param root [out] Contains the root value of the document if it was
   *             successfully parsed.
   * \param errs [out] Formatted error messages (if not NULL)
   *        a user friendly string that lists errors in the parsed
   * document.
   * \return \c true if the document was successfully parsed, \c false if an
   error occurred.
   */
  virtual bool parse(
      char const* beginDoc, char const* endDoc,
      Value* root, JSONCPP_STRING* errs) = 0;

  class JSON_API Factory {
  public:
    virtual ~Factory() {}
    /** \brief Allocate a CharReader via operator new().
     * \throw std::exception if something goes wrong (e.g. invalid settings)
     */
    virtual CharReader* newCharReader() const = 0;
  };  // Factory
};  // CharReader

/** \brief Build a CharReader implementation.

Usage:
\code
  using namespace Json;
  CharReaderBuilder builder;
  builder["collectComments"] = false;
  Value value;
  JSONCPP_STRING errs;
  bool ok = parseFromStream(builder, std::cin, &value, &errs);
\endcode
*/
class JSON_API CharReaderBuilder : public CharReader::Factory {
public:
  // Note: We use a Json::Value so that we can add data-members to this class
  // without a major version bump.
  /** Configuration of this builder.
    These are case-sensitive.
    Available settings (case-sensitive):
    - `"collectComments": false or true`
      - true to collect comment and allow writing them
        back during serialization, false to discard comments.
        This parameter is ignored if allowComments is false.
    - `"allowComments": false or true`
      - true if comments are allowed.
    - `"strictRoot": false or true`
      - true if root must be either an array or an object value
    - `"allowDroppedNullPlaceholders": false or true`
      - true if dropped null placeholders are allowed. (See StreamWriterBuilder.)
    - `"allowNumericKeys": false or true`
      - true if numeric object keys are allowed.
    - `"allowSingleQuotes": false or true`
      - true if '' are allowed for strings (both keys and values)
    - `"stackLimit": integer`
      - Exceeding stackLimit (recursive depth of `readValue()`) will
        cause an exception.
      - This is a security issue (seg-faults caused by deeply nested JSON),
        so the default is low.
    - `"failIfExtra": false or true`
      - If true, `parse()` returns false when extra non-whitespace trails
        the JSON value in the input string.
    - `"rejectDupKeys": false or true`
      - If true, `parse()` returns false when a key is duplicated within an object.
    - `"allowSpecialFloats": false or true`
      - If true, special float values (NaNs and infinities) are allowed 
        and their values are lossfree restorable.

    You can examine 'settings_` yourself
    to see the defaults. You can also write and read them just like any
    JSON Value.
    \sa setDefaults()
    */
  Json::Value settings_;

  CharReaderBuilder();
  ~CharReaderBuilder() JSONCPP_OVERRIDE;

  CharReader* newCharReader() const JSONCPP_OVERRIDE;

  /** \return true if 'settings' are legal and consistent;
   *   otherwise, indicate bad settings via 'invalid'.
   */
  bool validate(Json::Value* invalid) const;

  /** A simple way to update a specific setting.
   */
  Value& operator[](JSONCPP_STRING key);

  /** Called by ctor, but you can use this to reset settings_.
   * \pre 'settings' != NULL (but Json::null is fine)
   * \remark Defaults:
   * \snippet src/lib_json/json_reader.cpp CharReaderBuilderDefaults
   */
  static void setDefaults(Json::Value* settings);
  /** Same as old Features::strictMode().
   * \pre 'settings' != NULL (but Json::null is fine)
   * \remark Defaults:
   * \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode
   */
  static void strictMode(Json::Value* settings);
};

/** Consume entire stream and use its begin/end.
  * Someday we might have a real StreamReader, but for now this
  * is convenient.
  */
bool JSON_API parseFromStream(
    CharReader::Factory const&,
    JSONCPP_ISTREAM&,
    Value* root, std::string* errs);

/** \brief Read from 'sin' into 'root'.

 Always keep comments from the input JSON.

 This can be used to read a file into a particular sub-object.
 For example:
 \code
 Json::Value root;
 cin >> root["dir"]["file"];
 cout << root;
 \endcode
 Result:
 \verbatim
 {
 "dir": {
     "file": {
     // The input stream JSON would be nested here.
     }
 }
 }
 \endverbatim
 \throw std::exception on parse error.
 \see Json::operator<<()
*/
JSON_API JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM&, Value&);

} // namespace Json

#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
#pragma warning(pop)
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)

#endif // CPPTL_JSON_READER_H_INCLUDED

// //////////////////////////////////////////////////////////////////////
// End of content of file: include/json/reader.h
// //////////////////////////////////////////////////////////////////////






// //////////////////////////////////////////////////////////////////////
// Beginning of content of file: include/json/writer.h
// //////////////////////////////////////////////////////////////////////

// Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE

#ifndef JSON_WRITER_H_INCLUDED
#define JSON_WRITER_H_INCLUDED

#if !defined(JSON_IS_AMALGAMATION)
#include "value.h"
#endif // if !defined(JSON_IS_AMALGAMATION)
#include <vector>
#include <string>
#include <ostream>

// Disable warning C4251: <data member>: <type> needs to have dll-interface to
// be used by...
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
#pragma warning(push)
#pragma warning(disable : 4251)
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)

namespace Json {

class Value;

/**

Usage:
\code
  using namespace Json;
  void writeToStdout(StreamWriter::Factory const& factory, Value const& value) {
    std::unique_ptr<StreamWriter> const writer(
      factory.newStreamWriter());
    writer->write(value, &std::cout);
    std::cout << std::endl;  // add lf and flush
  }
\endcode
*/
class JSON_API StreamWriter {
protected:
  JSONCPP_OSTREAM* sout_;  // not owned; will not delete
public:
  StreamWriter();
  virtual ~StreamWriter();
  /** Write Value into document as configured in sub-class.
      Do not take ownership of sout, but maintain a reference during function.
      \pre sout != NULL
      \return zero on success (For now, we always return zero, so check the stream instead.)
      \throw std::exception possibly, depending on configuration
   */
  virtual int write(Value const& root, JSONCPP_OSTREAM* sout) = 0;

  /** \brief A simple abstract factory.
   */
  class JSON_API Factory {
  public:
    virtual ~Factory();
    /** \brief Allocate a CharReader via operator new().
     * \throw std::exception if something goes wrong (e.g. invalid settings)
     */
    virtual StreamWriter* newStreamWriter() const = 0;
  };  // Factory
};  // StreamWriter

/** \brief Write into stringstream, then return string, for convenience.
 * A StreamWriter will be created from the factory, used, and then deleted.
 */
JSONCPP_STRING JSON_API writeString(StreamWriter::Factory const& factory, Value const& root);


/** \brief Build a StreamWriter implementation.

Usage:
\code
  using namespace Json;
  Value value = ...;
  StreamWriterBuilder builder;
  builder["commentStyle"] = "None";
  builder["indentation"] = "   ";  // or whatever you like
  std::unique_ptr<Json::StreamWriter> writer(
      builder.newStreamWriter());
  writer->write(value, &std::cout);
  std::cout << std::endl;  // add lf and flush
\endcode
*/
class JSON_API StreamWriterBuilder : public StreamWriter::Factory {
public:
  // Note: We use a Json::Value so that we can add data-members to this class
  // without a major version bump.
  /** Configuration of this builder.
    Available settings (case-sensitive):
    - "commentStyle": "None" or "All"
    - "indentation":  "<anything>"
    - "enableYAMLCompatibility": false or true
      - slightly change the whitespace around colons
    - "dropNullPlaceholders": false or true
      - Drop the "null" string from the writer's output for nullValues.
        Strictly speaking, this is not valid JSON. But when the output is being
        fed to a browser's Javascript, it makes for smaller output and the
        browser can handle the output just fine.
    - "useSpecialFloats": false or true
      - If true, outputs non-finite floating point values in the following way:
        NaN values as "NaN", positive infinity as "Infinity", and negative infinity
        as "-Infinity".

    You can examine 'settings_` yourself
    to see the defaults. You can also write and read them just like any
    JSON Value.
    \sa setDefaults()
    */
  Json::Value settings_;

  StreamWriterBuilder();
  ~StreamWriterBuilder() JSONCPP_OVERRIDE;

  /**
   * \throw std::exception if something goes wrong (e.g. invalid settings)
   */
  StreamWriter* newStreamWriter() const JSONCPP_OVERRIDE;

  /** \return true if 'settings' are legal and consistent;
   *   otherwise, indicate bad settings via 'invalid'.
   */
  bool validate(Json::Value* invalid) const;
  /** A simple way to update a specific setting.
   */
  Value& operator[](JSONCPP_STRING key);

  /** Called by ctor, but you can use this to reset settings_.
   * \pre 'settings' != NULL (but Json::null is fine)
   * \remark Defaults:
   * \snippet src/lib_json/json_writer.cpp StreamWriterBuilderDefaults
   */
  static void setDefaults(Json::Value* settings);
};

/** \brief Abstract class for writers.
 * \deprecated Use StreamWriter. (And really, this is an implementation detail.)
 */
class JSON_API Writer {
public:
  virtual ~Writer();

  virtual JSONCPP_STRING write(const Value& root) = 0;
};

/** \brief Outputs a Value in <a HREF="http://www.json.org">JSON</a> format
 *without formatting (not human friendly).
 *
 * The JSON document is written in a single line. It is not intended for 'human'
 *consumption,
 * but may be usefull to support feature such as RPC where bandwith is limited.
 * \sa Reader, Value
 * \deprecated Use StreamWriterBuilder.
 */
class JSON_API FastWriter : public Writer {

public:
  FastWriter();
  ~FastWriter() JSONCPP_OVERRIDE {}

  void enableYAMLCompatibility();

  /** \brief Drop the "null" string from the writer's output for nullValues.
   * Strictly speaking, this is not valid JSON. But when the output is being
   * fed to a browser's Javascript, it makes for smaller output and the
   * browser can handle the output just fine.
   */
  void dropNullPlaceholders();

  void omitEndingLineFeed();

public: // overridden from Writer
  JSONCPP_STRING write(const Value& root) JSONCPP_OVERRIDE;

private:
  void writeValue(const Value& value);

  JSONCPP_STRING document_;
  bool yamlCompatiblityEnabled_;
  bool dropNullPlaceholders_;
  bool omitEndingLineFeed_;
};

/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a
 *human friendly way.
 *
 * The rules for line break and indent are as follow:
 * - Object value:
 *     - if empty then print {} without indent and line break
 *     - if not empty the print '{', line break & indent, print one value per
 *line
 *       and then unindent and line break and print '}'.
 * - Array value:
 *     - if empty then print [] without indent and line break
 *     - if the array contains no object value, empty array or some other value
 *types,
 *       and all the values fit on one lines, then print the array on a single
 *line.
 *     - otherwise, it the values do not fit on one line, or the array contains
 *       object or non empty array, then print one value per line.
 *
 * If the Value have comments then they are outputed according to their
 *#CommentPlacement.
 *
 * \sa Reader, Value, Value::setComment()
 * \deprecated Use StreamWriterBuilder.
 */
class JSON_API StyledWriter : public Writer {
public:
  StyledWriter();
  ~StyledWriter() JSONCPP_OVERRIDE {}

public: // overridden from Writer
  /** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format.
   * \param root Value to serialize.
   * \return String containing the JSON document that represents the root value.
   */
  JSONCPP_STRING write(const Value& root) JSONCPP_OVERRIDE;

private:
  void writeValue(const Value& value);
  void writeArrayValue(const Value& value);
  bool isMultineArray(const Value& value);
  void pushValue(const JSONCPP_STRING& value);
  void writeIndent();
  void writeWithIndent(const JSONCPP_STRING& value);
  void indent();
  void unindent();
  void writeCommentBeforeValue(const Value& root);
  void writeCommentAfterValueOnSameLine(const Value& root);
  bool hasCommentForValue(const Value& value);
  static JSONCPP_STRING normalizeEOL(const JSONCPP_STRING& text);

  typedef std::vector<JSONCPP_STRING> ChildValues;

  ChildValues childValues_;
  JSONCPP_STRING document_;
  JSONCPP_STRING indentString_;
  unsigned int rightMargin_;
  unsigned int indentSize_;
  bool addChildValues_;
};

/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a
 human friendly way,
     to a stream rather than to a string.
 *
 * The rules for line break and indent are as follow:
 * - Object value:
 *     - if empty then print {} without indent and line break
 *     - if not empty the print '{', line break & indent, print one value per
 line
 *       and then unindent and line break and print '}'.
 * - Array value:
 *     - if empty then print [] without indent and line break
 *     - if the array contains no object value, empty array or some other value
 types,
 *       and all the values fit on one lines, then print the array on a single
 line.
 *     - otherwise, it the values do not fit on one line, or the array contains
 *       object or non empty array, then print one value per line.
 *
 * If the Value have comments then they are outputed according to their
 #CommentPlacement.
 *
 * \param indentation Each level will be indented by this amount extra.
 * \sa Reader, Value, Value::setComment()
 * \deprecated Use StreamWriterBuilder.
 */
class JSON_API StyledStreamWriter {
public:
  StyledStreamWriter(JSONCPP_STRING indentation = "\t");
  ~StyledStreamWriter() {}

public:
  /** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format.
   * \param out Stream to write to. (Can be ostringstream, e.g.)
   * \param root Value to serialize.
   * \note There is no point in deriving from Writer, since write() should not
   * return a value.
   */
  void write(JSONCPP_OSTREAM& out, const Value& root);

private:
  void writeValue(const Value& value);
  void writeArrayValue(const Value& value);
  bool isMultineArray(const Value& value);
  void pushValue(const JSONCPP_STRING& value);
  void writeIndent();
  void writeWithIndent(const JSONCPP_STRING& value);
  void indent();
  void unindent();
  void writeCommentBeforeValue(const Value& root);
  void writeCommentAfterValueOnSameLine(const Value& root);
  bool hasCommentForValue(const Value& value);
  static JSONCPP_STRING normalizeEOL(const JSONCPP_STRING& text);

  typedef std::vector<JSONCPP_STRING> ChildValues;

  ChildValues childValues_;
  JSONCPP_OSTREAM* document_;
  JSONCPP_STRING indentString_;
  unsigned int rightMargin_;
  JSONCPP_STRING indentation_;
  bool addChildValues_ : 1;
  bool indented_ : 1;
};

#if defined(JSON_HAS_INT64)
JSONCPP_STRING JSON_API valueToString(Int value);
JSONCPP_STRING JSON_API valueToString(UInt value);
#endif // if defined(JSON_HAS_INT64)
JSONCPP_STRING JSON_API valueToString(LargestInt value);
JSONCPP_STRING JSON_API valueToString(LargestUInt value);
JSONCPP_STRING JSON_API valueToString(double value);
JSONCPP_STRING JSON_API valueToString(bool value);
JSONCPP_STRING JSON_API valueToQuotedString(const char* value);

/// \brief Output using the StyledStreamWriter.
/// \see Json::operator>>()
JSON_API JSONCPP_OSTREAM& operator<<(JSONCPP_OSTREAM&, const Value& root);

} // namespace Json

#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
#pragma warning(pop)
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)

#endif // JSON_WRITER_H_INCLUDED

// //////////////////////////////////////////////////////////////////////
// End of content of file: include/json/writer.h
// //////////////////////////////////////////////////////////////////////






// //////////////////////////////////////////////////////////////////////
// Beginning of content of file: include/json/assertions.h
// //////////////////////////////////////////////////////////////////////

// Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE

#ifndef CPPTL_JSON_ASSERTIONS_H_INCLUDED
#define CPPTL_JSON_ASSERTIONS_H_INCLUDED

#include <stdlib.h>
#include <sstream>

#if !defined(JSON_IS_AMALGAMATION)
#include "config.h"
#endif // if !defined(JSON_IS_AMALGAMATION)

/** It should not be possible for a maliciously designed file to
 *  cause an abort() or seg-fault, so these macros are used only
 *  for pre-condition violations and internal logic errors.
 */
#if JSON_USE_EXCEPTION

// @todo <= add detail about condition in exception
# define JSON_ASSERT(condition)                                                \
  {if (!(condition)) {Json::throwLogicError( "assert json failed" );}}

# define JSON_FAIL_MESSAGE(message)                                            \
  {                                                                            \
    JSONCPP_OSTRINGSTREAM oss; oss << message;                                    \
    Json::throwLogicError(oss.str());                                          \
    abort();                                                                   \
  }

#else // JSON_USE_EXCEPTION

# define JSON_ASSERT(condition) assert(condition)

// The call to assert() will show the failure message in debug builds. In
// release builds we abort, for a core-dump or debugger.
# define JSON_FAIL_MESSAGE(message)                                            \
  {                                                                            \
    JSONCPP_OSTRINGSTREAM oss; oss << message;                                    \
    assert(false && oss.str().c_str());                                        \
    abort();                                                                   \
  }


#endif

#define JSON_ASSERT_MESSAGE(condition, message)                                \
  if (!(condition)) {                                                          \
    JSON_FAIL_MESSAGE(message);                                                \
  }

#endif // CPPTL_JSON_ASSERTIONS_H_INCLUDED

// //////////////////////////////////////////////////////////////////////
// End of content of file: include/json/assertions.h
// //////////////////////////////////////////////////////////////////////





#endif //ifndef JSON_AMALGATED_H_INCLUDED


================================================
FILE: source/jsoncpp.cpp
================================================
/// Json-cpp amalgated source (http://jsoncpp.sourceforge.net/).
/// It is intended to be used with #include "json/json.h"

// //////////////////////////////////////////////////////////////////////
// Beginning of content of file: LICENSE
// //////////////////////////////////////////////////////////////////////

/*
The JsonCpp library's source code, including accompanying documentation, 
tests and demonstration applications, are licensed under the following
conditions...

The author (Baptiste Lepilleur) explicitly disclaims copyright in all 
jurisdictions which recognize such a disclaimer. In such jurisdictions, 
this software is released into the Public Domain.

In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is
released under the terms of the MIT License (see below).

In jurisdictions which recognize Public Domain property, the user of this 
software may choose to accept it either as 1) Public Domain, 2) under the 
conditions of the MIT License (see below), or 3) under the terms of dual 
Public Domain/MIT License conditions described here, as they choose.

The MIT License is about as close to Public Domain as a license can get, and is
described in clear, concise terms at:

   http://en.wikipedia.org/wiki/MIT_License
   
The full text of the MIT License follows:

========================================================================
Copyright (c) 2007-2010 Baptiste Lepilleur

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
========================================================================
(END LICENSE TEXT)

The MIT license is compatible with both the GPL and commercial
software, affording one all of the rights of Public Domain with the
minor nuisance of being required to keep the above copyright notice
and license text in the source code. Note also that by accepting the
Public Domain "license" you can re-license your copy using whatever
license you like.

*/

// //////////////////////////////////////////////////////////////////////
// End of content of file: LICENSE
// //////////////////////////////////////////////////////////////////////






#include "json/json.h"

#ifndef JSON_IS_AMALGAMATION
#error "Compile with -I PATH_TO_JSON_DIRECTORY"
#endif


// //////////////////////////////////////////////////////////////////////
// Beginning of content of file: src/lib_json/json_tool.h
// //////////////////////////////////////////////////////////////////////

// Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE

#ifndef LIB_JSONCPP_JSON_TOOL_H_INCLUDED
#define LIB_JSONCPP_JSON_TOOL_H_INCLUDED

/* This header provides common string manipulation support, such as UTF-8,
 * portable conversion from/to string...
 *
 * It is an internal header that must not be exposed.
 */

namespace Json {

/// Converts a unicode code-point to UTF-8.
static inline JSONCPP_STRING codePointToUTF8(unsigned int cp) {
  JSONCPP_STRING result;

  // based on description from http://en.wikipedia.org/wiki/UTF-8

  if (cp <= 0x7f) {
    result.resize(1);
    result[0] = static_cast<char>(cp);
  } else if (cp <= 0x7FF) {
    result.resize(2);
    result[1] = static_cast<char>(0x80 | (0x3f & cp));
    result[0] = static_cast<char>(0xC0 | (0x1f & (cp >> 6)));
  } else if (cp <= 0xFFFF) {
    result.resize(3);
    result[2] = static_cast<char>(0x80 | (0x3f & cp));
    result[1] = static_cast<char>(0x80 | (0x3f & (cp >> 6)));
    result[0] = static_cast<char>(0xE0 | (0xf & (cp >> 12)));
  } else if (cp <= 0x10FFFF) {
    result.resize(4);
    result[3] = static_cast<char>(0x80 | (0x3f & cp));
    result[2] = static_cast<char>(0x80 | (0x3f & (cp >> 6)));
    result[1] = static_cast<char>(0x80 | (0x3f & (cp >> 12)));
    result[0] = static_cast<char>(0xF0 | (0x7 & (cp >> 18)));
  }

  return result;
}

/// Returns true if ch is a control character (in range [1,31]).
static inline bool isControlCharacter(char ch) { return ch > 0 && ch <= 0x1F; }

enum {
  /// Constant that specify the size of the buffer that must be passed to
  /// uintToString.
  uintToStringBufferSize = 3 * sizeof(LargestUInt) + 1
};

// Defines a char buffer for use with uintToString().
typedef char UIntToStringBuffer[uintToStringBufferSize];

/** Converts an unsigned integer to string.
 * @param value Unsigned interger to convert to string
 * @param current Input/Output string buffer.
 *        Must have at least uintToStringBufferSize chars free.
 */
static inline void uintToString(LargestUInt value, char*& current) {
  *--current = 0;
  do {
    *--current = static_cast<char>(value % 10U + static_cast<unsigned>('0'));
    value /= 10;
  } while (value != 0);
}

/** Change ',' to '.' everywhere in buffer.
 *
 * We had a sophisticated way, but it did not work in WinCE.
 * @see https://github.com/open-source-parsers/jsoncpp/pull/9
 */
static inline void fixNumericLocale(char* begin, char* end) {
  while (begin < end) {
    if (*begin == ',') {
      *begin = '.';
    }
    ++begin;
  }
}

} // namespace Json {

#endif // LIB_JSONCPP_JSON_TOOL_H_INCLUDED

// //////////////////////////////////////////////////////////////////////
// End of content of file: src/lib_json/json_tool.h
// //////////////////////////////////////////////////////////////////////






// //////////////////////////////////////////////////////////////////////
// Beginning of content of file: src/lib_json/json_reader.cpp
// //////////////////////////////////////////////////////////////////////

// Copyright 2007-2011 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE

#if !defined(JSON_IS_AMALGAMATION)
#include <json/assertions.h>
#include <json/reader.h>
#include <json/value.h>
#include "json_tool.h"
#endif // if !defined(JSON_IS_AMALGAMATION)
#include <utility>
#include <cstdio>
#include <cassert>
#include <cstring>
#include <istream>
#include <sstream>
#include <memory>
#include <set>
#include <limits>

#if defined(_MSC_VER)
#if !defined(WINCE) && defined(__STDC_SECURE_LIB__) && _MSC_VER >= 1500 // VC++ 9.0 and above 
#define snprintf sprintf_s
#elif _MSC_VER >= 1900 // VC++ 14.0 and above
#define snprintf std::snprintf
#else
#define snprintf _snprintf
#endif
#elif defined(__ANDROID__) || defined(__QNXNTO__)
#define snprintf snprintf
#elif __cplusplus >= 201103L
#if !defined(__MINGW32__) && !defined(__CYGWIN__)
//#define snprintf std::snprintf
#endif
#endif

#if defined(__QNXNTO__)
#define sscanf std::sscanf
#endif

#if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0
// Disable warning about strdup being deprecated.
#pragma warning(disable : 4996)
#endif

static int const stackLimit_g = 1000;
static int       stackDepth_g = 0;  // see readValue()

namespace Json {

#if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520)
typedef std::unique_ptr<CharReader> CharReaderPtr;
#else
typedef std::auto_ptr<CharReader>   CharReaderPtr;
#endif

// Implementation of class Features
// ////////////////////////////////

Features::Features()
    : allowComments_(true), strictRoot_(false),
      allowDroppedNullPlaceholders_(false), allowNumericKeys_(false) {}

Features Features::all() { return Features(); }

Features Features::strictMode() {
  Features features;
  features.allowComments_ = false;
  features.strictRoot_ = true;
  features.allowDroppedNullPlaceholders_ = false;
  features.allowNumericKeys_ = false;
  return features;
}

// Implementation of class Reader
// ////////////////////////////////

static bool containsNewLine(Reader::Location begin, Reader::Location end) {
  for (; begin < end; ++begin)
    if (*begin == '\n' || *begin == '\r')
      return true;
  return false;
}

// Class Reader
// //////////////////////////////////////////////////////////////////

Reader::Reader()
    : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),
      lastValue_(), commentsBefore_(), features_(Features::all()),
      collectComments_() {}

Reader::Reader(const Features& features)
    : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),
      lastValue_(), commentsBefore_(), features_(features), collectComments_() {
}

bool
Reader::parse(const std::string& document, Value& root, bool collectComments) {
  JSONCPP_STRING documentCopy(document.data(), document.data() + document.capacity());
  std::swap(documentCopy, document_);
  const char* begin = document_.c_str();
  const char* end = begin + document_.length();
  return parse(begin, end, root, collectComments);
}

bool Reader::parse(std::istream& sin, Value& root, bool collectComments) {
  // std::istream_iterator<char> begin(sin);
  // std::istream_iterator<char> end;
  // Those would allow streamed input from a file, if parse() were a
  // template function.

  // Since JSONCPP_STRING is reference-counted, this at least does not
  // create an extra copy.
  JSONCPP_STRING doc;
  std::getline(sin, doc, (char)EOF);
  return parse(doc.data(), doc.data() + doc.size(), root, collectComments);
}

bool Reader::parse(const char* beginDoc,
                   const char* endDoc,
                   Value& root,
                   bool collectComments) {
  if (!features_.allowComments_) {
    collectComments = false;
  }

  begin_ = beginDoc;
  end_ = endDoc;
  collectComments_ = collectComments;
  current_ = begin_;
  lastValueEnd_ = 0;
  lastValue_ = 0;
  commentsBefore_ = "";
  errors_.clear();
  while (!nodes_.empty())
    nodes_.pop();
  nodes_.push(&root);

  stackDepth_g = 0;  // Yes, this is bad coding, but options are limited.
  bool successful = readValue();
  Token token;
  skipCommentTokens(token);
  if (collectComments_ && !commentsBefore_.empty())
    root.setComment(commentsBefore_, commentAfter);
  if (features_.strictRoot_) {
    if (!root.isArray() && !root.isObject()) {
      // Set error location to start of doc, ideally should be first token found
      // in doc
      token.type_ = tokenError;
      token.start_ = beginDoc;
      token.end_ = endDoc;
      addError(
          "A valid JSON document must be either an array or an object value.",
          token);
      return false;
    }
  }
  return successful;
}

bool Reader::readValue() {
  // This is a non-reentrant way to support a stackLimit. Terrible!
  // But this deprecated class has a security problem: Bad input can
  // cause a seg-fault. This seems like a fair, binary-compatible way
  // to prevent the problem.
  if (stackDepth_g >= stackLimit_g) throwRuntimeError("Exceeded stackLimit in readValue().");
  ++stackDepth_g;

  Token token;
  skipCommentTokens(token);
  bool successful = true;

  if (collectComments_ && !commentsBefore_.empty()) {
    currentValue().setComment(commentsBefore_, commentBefore);
    commentsBefore_ = "";
  }

  switch (token.type_) {
  case tokenObjectBegin:
    successful = readObject(token);
    currentValue().setOffsetLimit(current_ - begin_);
    break;
  case tokenArrayBegin:
    successful = readArray(token);
    currentValue().setOffsetLimit(current_ - begin_);
    break;
  case tokenNumber:
    successful = decodeNumber(token);
    break;
  case tokenString:
    successful = decodeString(token);
    break;
  case tokenTrue:
    {
    Value v(true);
    currentValue().swapPayload(v);
    currentValue().setOffsetStart(token.start_ - begin_);
    currentValue().setOffsetLimit(token.end_ - begin_);
    }
    break;
  case tokenFalse:
    {
    Value v(false);
    currentValue().swapPayload(v);
    currentValue().setOffsetStart(token.start_ - begin_);
    currentValue().setOffsetLimit(token.end_ - begin_);
    }
    break;
  case tokenNull:
    {
    Value v;
    currentValue().swapPayload(v);
    currentValue().setOffsetStart(token.start_ - begin_);
    currentValue().setOffsetLimit(token.end_ - begin_);
    }
    break;
  case tokenArraySeparator:
  case tokenObjectEnd:
  case tokenArrayEnd:
    if (features_.allowDroppedNullPlaceholders_) {
      // "Un-read" the current token and mark the current value as a null
      // token.
      current_--;
      Value v;
      currentValue().swapPayload(v);
      currentValue().setOffsetStart(current_ - begin_ - 1);
      currentValue().setOffsetLimit(current_ - begin_);
      break;
    } // Else, fall through...
  default:
    currentValue().setOffsetStart(token.start_ - begin_);
    currentValue().setOffsetLimit(token.end_ - begin_);
    return addError("Syntax error: value, object or array expected.", token);
  }

  if (collectComments_) {
    lastValueEnd_ = current_;
    lastValue_ = &currentValue();
  }

  --stackDepth_g;
  return successful;
}

void Reader::skipCommentTokens(Token& token) {
  if (features_.allowComments_) {
    do {
      readToken(token);
    } while (token.type_ == tokenComment);
  } else {
    readToken(token);
  }
}

bool Reader::readToken(Token& token) {
  skipSpaces();
  token.start_ = current_;
  Char c = getNextChar();
  bool ok = true;
  switch (c) {
  case '{':
    token.type_ = tokenObjectBegin;
    break;
  case '}':
    token.type_ = tokenObjectEnd;
    break;
  case '[':
    token.type_ = tokenArrayBegin;
    break;
  case ']':
    token.type_ = tokenArrayEnd;
    break;
  case '"':
    token.type_ = tokenString;
    ok = readString();
    break;
  case '/':
    token.type_ = tokenComment;
    ok = readComment();
    break;
  case '0':
  case '1':
  case '2':
  case '3':
  case '4':
  case '5':
  case '6':
  case '7':
  case '8':
  case '9':
  case '-':
    token.type_ = tokenNumber;
    readNumber();
    break;
  case 't':
    token.type_ = tokenTrue;
    ok = match("rue", 3);
    break;
  case 'f':
    token.type_ = tokenFalse;
    ok = match("alse", 4);
    break;
  case 'n':
    token.type_ = tokenNull;
    ok = match("ull", 3);
    break;
  case ',':
    token.type_ = tokenArraySeparator;
    break;
  case ':':
    token.type_ = tokenMemberSeparator;
    break;
  case 0:
    token.type_ = tokenEndOfStream;
    break;
  default:
    ok = false;
    break;
  }
  if (!ok)
    token.type_ = tokenError;
  token.end_ = current_;
  return true;
}

void Reader::skipSpaces() {
  while (current_ != end_) {
    Char c = *current_;
    if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
      ++current_;
    else
      break;
  }
}

bool Reader::match(Location pattern, int patternLength) {
  if (end_ - current_ < patternLength)
    return false;
  int index = patternLength;
  while (index--)
    if (current_[index] != pattern[index])
      return false;
  current_ += patternLength;
  return true;
}

bool Reader::readComment() {
  Location commentBegin = current_ - 1;
  Char c = getNextChar();
  bool successful = false;
  if (c == '*')
    successful = readCStyleComment();
  else if (c == '/')
    successful = readCppStyleComment();
  if (!successful)
    return false;

  if (collectComments_) {
    CommentPlacement placement = commentBefore;
    if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin)) {
      if (c != '*' || !containsNewLine(commentBegin, current_))
        placement = commentAfterOnSameLine;
    }

    addComment(commentBegin, current_, placement);
  }
  return true;
}

static JSONCPP_STRING normalizeEOL(Reader::Location begin, Reader::Location end) {
  JSONCPP_STRING normalized;
  normalized.reserve(static_cast<size_t>(end - begin));
  Reader::Location current = begin;
  while (current != end) {
    char c = *current++;
    if (c == '\r') {
      if (current != end && *current == '\n')
         // convert dos EOL
         ++current;
      // convert Mac EOL
      normalized += '\n';
    } else {
      normalized += c;
    }
  }
  return normalized;
}

void
Reader::addComment(Location begin, Location end, CommentPlacement placement) {
  assert(collectComments_);
  const JSONCPP_STRING& normalized = normalizeEOL(begin, end);
  if (placement == commentAfterOnSameLine) {
    assert(lastValue_ != 0);
    lastValue_->setComment(normalized, placement);
  } else {
    commentsBefore_ += normalized;
  }
}

bool Reader::readCStyleComment() {
  while (current_ != end_) {
    Char c = getNextChar();
    if (c == '*' && *current_ == '/')
      break;
  }
  return getNextChar() == '/';
}

bool Reader::readCppStyleComment() {
  while (current_ != end_) {
    Char c = getNextChar();
    if (c == '\n')
      break;
    if (c == '\r') {
      // Consume DOS EOL. It will be normalized in addComment.
      if (current_ != end_ && *current_ == '\n')
        getNextChar();
      // Break on Moc OS 9 EOL.
      break;
    }
  }
  return true;
}

void Reader::readNumber() {
  const char *p = current_;
  char c = '0'; // stopgap for already consumed character
  // integral part
  while (c >= '0' && c <= '9')
    c = (current_ = p) < end_ ? *p++ : 0;
  // fractional part
  if (c == '.') {
    c = (current_ = p) < end_ ? *p++ : 0;
    while (c >= '0' && c <= '9')
      c = (current_ = p) < end_ ? *p++ : 0;
  }
  // exponential part
  if (c == 'e' || c == 'E') {
    c = (current_ = p) < end_ ? *p++ : 0;
    if (c == '+' || c == '-')
      c = (current_ = p) < end_ ? *p++ : 0;
    while (c >= '0' && c <= '9')
      c = (current_ = p) < end_ ? *p++ : 0;
  }
}

bool Reader::readString() {
  Char c = 0;
  while (current_ != end_) {
    c = getNextChar();
    if (c == '\\')
      getNextChar();
    else if (c == '"')
      break;
  }
  return c == '"';
}

bool Reader::readObject(Token& tokenStart) {
  Token tokenName;
  JSONCPP_STRING name;
  Value init(objectValue);
  currentValue().swapPayload(init);
  currentValue().setOffsetStart(tokenStart.start_ - begin_);
  while (readToken(tokenName)) {
    bool initialTokenOk = true;
    while (tokenName.type_ == tokenComment && initialTokenOk)
      initialTokenOk = readToken(tokenName);
    if (!initialTokenOk)
      break;
    if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object
      return true;
    name = "";
    if (tokenName.type_ == tokenString) {
      if (!decodeString(tokenName, name))
        return recoverFromError(tokenObjectEnd);
    } else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_) {
      Value numberName;
      if (!decodeNumber(tokenName, numberName))
        return recoverFromError(tokenObjectEnd);
      name = JSONCPP_STRING(numberName.asCString());
    } else {
      break;
    }

    Token colon;
    if (!readToken(colon) || colon.type_ != tokenMemberSeparator) {
      return addErrorAndRecover(
          "Missing ':' after object member name", colon, tokenObjectEnd);
    }
    Value& value = currentValue()[name];
    nodes_.push(&value);
    bool ok = readValue();
    nodes_.pop();
    if (!ok) // error already set
      return recoverFromError(tokenObjectEnd);

    Token comma;
    if (!readToken(comma) ||
        (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator &&
         comma.type_ != tokenComment)) {
      return addErrorAndRecover(
          "Missing ',' or '}' in object declaration", comma, tokenObjectEnd);
    }
    bool finalizeTokenOk = true;
    while (comma.type_ == tokenComment && finalizeTokenOk)
      finalizeTokenOk = readToken(comma);
    if (comma.type_ == tokenObjectEnd)
      return true;
  }
  return addErrorAndRecover(
      "Missing '}' or object member name", tokenName, tokenObjectEnd);
}

bool Reader::readArray(Token& tokenStart) {
  Value init(arrayValue);
  currentValue().swapPayload(init);
  currentValue().setOffsetStart(tokenStart.start_ - begin_);
  skipSpaces();
  if (*current_ == ']') // empty array
  {
    Token endArray;
    readToken(endArray);
    return true;
  }
  int index = 0;
  for (;;) {
    Value& value = currentValue()[index++];
    nodes_.push(&value);
    bool ok = readValue();
    nodes_.pop();
    if (!ok) // error already set
      return recoverFromError(tokenArrayEnd);

    Token token;
    // Accept Comment after last item in the array.
    ok = readToken(token);
    while (token.type_ == tokenComment && ok) {
      ok = readToken(token);
    }
    bool badTokenType =
        (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd);
    if (!ok || badTokenType) {
      return addErrorAndRecover(
          "Missing ',' or ']' in array declaration", token, tokenArrayEnd);
    }
    if (token.type_ == tokenArrayEnd)
      break;
  }
  return true;
}

bool Reader::decodeNumber(Token& token) {
  Value decoded;
  if (!decodeNumber(token, decoded))
    return false;
  currentValue().swapPayload(decoded);
  currentValue().setOffsetStart(token.start_ - begin_);
  currentValue().setOffsetLimit(token.end_ - begin_);
  return true;
}

bool Reader::decodeNumber(Token& token, Value& decoded) {
  // Attempts to parse the number as an integer. If the number is
  // larger than the maximum supported value of an integer then
  // we decode the number as a double.
  Location current = token.start_;
  bool isNegative = *current == '-';
  if (isNegative)
    ++current;
  // TODO: Help the compiler do the div and mod at compile time or get rid of them.
  Value::LargestUInt maxIntegerValue =
      isNegative ? Value::LargestUInt(Value::maxLargestInt) + 1
                 : Value::maxLargestUInt;
  Value::LargestUInt threshold = maxIntegerValue / 10;
  Value::LargestUInt value = 0;
  while (current < token.end_) {
    Char c = *current++;
    if (c < '0' || c > '9')
      return decodeDouble(token, decoded);
    Value::UInt digit(static_cast<Value::UInt>(c - '0'));
    if (value >= threshold) {
      // We've hit or exceeded the max value divided by 10 (rounded down). If
      // a) we've only just touched the limit, b) this is the last digit, and
      // c) it's small enough to fit in that rounding delta, we're okay.
      // Otherwise treat this number as a double to avoid overflow.
      if (value > threshold || current != token.end_ ||
          digit > maxIntegerValue % 10) {
        return decodeDouble(token, decoded);
      }
    }
    value = value * 10 + digit;
  }
  if (isNegative && value == maxIntegerValue)
    decoded = Value::minLargestInt;
  else if (isNegative)
    decoded = -Value::LargestInt(value);
  else if (value <= Value::LargestUInt(Value::maxInt))
    decoded = Value::LargestInt(value);
  else
    decoded = value;
  return true;
}

bool Reader::decodeDouble(Token& token) {
  Value decoded;
  if (!decodeDouble(token, decoded))
    return false;
  currentValue().swapPayload(decoded);
  currentValue().setOffsetStart(token.start_ - begin_);
  currentValue().setOffsetLimit(token.end_ - begin_);
  return true;
}

bool Reader::decodeDouble(Token& token, Value& decoded) {
  double value = 0;
  JSONCPP_STRING buffer(token.start_, token.end_);
  JSONCPP_ISTRINGSTREAM is(buffer);
  if (!(is >> value))
    return addError("'" + JSONCPP_STRING(token.start_, token.end_) +
                        "' is not a number.",
                    token);
  decoded = value;
  return true;
}

bool Reader::decodeString(Token& token) {
  JSONCPP_STRING decoded_string;
  if (!decodeString(token, decoded_string))
    return false;
  Value decoded(decoded_string);
  currentValue().swapPayload(decoded);
  currentValue().setOffsetStart(token.start_ - begin_);
  currentValue().setOffsetLimit(token.end_ - begin_);
  return true;
}

bool Reader::decodeString(Token& token, JSONCPP_STRING& decoded) {
  decoded.reserve(static_cast<size_t>(token.end_ - token.start_ - 2));
  Location current = token.start_ + 1; // skip '"'
  Location end = token.end_ - 1;       // do not include '"'
  while (current != end) {
    Char c = *current++;
    if (c == '"')
      break;
    else if (c == '\\') {
      if (current == end)
        return addError("Empty escape sequence in string", token, current);
      Char escape = *current++;
      switch (escape) {
      case '"':
        decoded += '"';
        break;
      case '/':
        decoded += '/';
        break;
      case '\\':
        decoded += '\\';
        break;
      case 'b':
        decoded += '\b';
        break;
      case 'f':
        decoded += '\f';
        break;
      case 'n':
        decoded += '\n';
        break;
      case 'r':
        decoded += '\r';
        break;
      case 't':
        decoded += '\t';
        break;
      case 'u': {
        unsigned int unicode;
        if (!decodeUnicodeCodePoint(token, current, end, unicode))
          return false;
        decoded += codePointToUTF8(unicode);
      } break;
      default:
        return addError("Bad escape sequence in string", token, current);
      }
    } else {
      decoded += c;
    }
  }
  return true;
}

bool Reader::decodeUnicodeCodePoint(Token& token,
                                    Location& current,
                                    Location end,
                                    unsigned int& unicode) {

  if (!decodeUnicodeEscapeSequence(token, current, end, unicode))
    return false;
  if (unicode >= 0xD800 && unicode <= 0xDBFF) {
    // surrogate pairs
    if (end - current < 6)
      return addError(
          "additional six characters expected to parse unicode surrogate pair.",
          token,
          current);
    unsigned int surrogatePair;
    if (*(current++) == '\\' && *(current++) == 'u') {
      if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) {
        unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF);
      } else
        return false;
    } else
      return addError("expecting another \\u token to begin the second half of "
                      "a unicode surrogate pair",
                      token,
                      current);
  }
  return true;
}

bool Reader::decodeUnicodeEscapeSequence(Token& token,
                                         Location& current,
                                         Location end,
                                         unsigned int& ret_unicode) {
  if (end - current < 4)
    return addError(
        "Bad unicode escape sequence in string: four digits expected.",
        token,
        current);
  int unicode = 0;
  for (int index = 0; index < 4; ++index) {
    Char c = *current++;
    unicode *= 16;
    if (c >= '0' && c <= '9')
      unicode += c - '0';
    else if (c >= 'a' && c <= 'f')
      unicode += c - 'a' + 10;
    else if (c >= 'A' && c <= 'F')
      unicode += c - 'A' + 10;
    else
      return addError(
          "Bad unicode escape sequence in string: hexadecimal digit expected.",
          token,
          current);
  }
  ret_unicode = static_cast<unsigned int>(unicode);
  return true;
}

bool
Reader::addError(const JSONCPP_STRING& message, Token& token, Location extra) {
  ErrorInfo info;
  info.token_ = token;
  info.message_ = message;
  info.extra_ = extra;
  errors_.push_back(info);
  return false;
}

bool Reader::recoverFromError(TokenType skipUntilToken) {
  size_t const errorCount = errors_.size();
  Token skip;
  for (;;) {
    if (!readToken(skip))
      errors_.resize(errorCount); // discard errors caused by recovery
    if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream)
      break;
  }
  errors_.resize(errorCount);
  return false;
}

bool Reader::addErrorAndRecover(const JSONCPP_STRING& message,
                                Token& token,
                                TokenType skipUntilToken) {
  addError(message, token);
  return recoverFromError(skipUntilToken);
}

Value& Reader::currentValue() { return *(nodes_.top()); }

Reader::Char Reader::getNextChar() {
  if (current_ == end_)
    return 0;
  return *current_++;
}

void Reader::getLocationLineAndColumn(Location location,
                                      int& line,
                                      int& column) const {
  Location current = begin_;
  Location lastLineStart = current;
  line = 0;
  while (current < location && current != end_) {
    Char c = *current++;
    if (c == '\r') {
      if (*current == '\n')
        ++current;
      lastLineStart = current;
      ++line;
    } else if (c == '\n') {
      lastLineStart = current;
      ++line;
    }
  }
  // column & line start at 1
  column = int(location - lastLineStart) + 1;
  ++line;
}

JSONCPP_STRING Reader::getLocationLineAndColumn(Location location) const {
  int line, column;
  getLocationLineAndColumn(location, line, column);
  char buffer[18 + 16 + 16 + 1];
  snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column);
  return buffer;
}

// Deprecated. Preserved for backward compatibility
JSONCPP_STRING Reader::getFormatedErrorMessages() const {
  return getFormattedErrorMessages();
}

JSONCPP_STRING Reader::getFormattedErrorMessages() const {
  JSONCPP_STRING formattedMessage;
  for (Errors::const_iterator itError = errors_.begin();
       itError != errors_.end();
       ++itError) {
    const ErrorInfo& error = *itError;
    formattedMessage +=
        "* " + getLocationLineAndColumn(error.token_.start_) + "\n";
    formattedMessage += "  " + error.message_ + "\n";
    if (error.extra_)
      formattedMessage +=
          "See " + getLocationLineAndColumn(error.extra_) + " for detail.\n";
  }
  return formattedMessage;
}

std::vector<Reader::StructuredError> Reader::getStructuredErrors() const {
  std::vector<Reader::StructuredError> allErrors;
  for (Errors::const_iterator itError = errors_.begin();
       itError != errors_.end();
       ++itError) {
    const ErrorInfo& error = *itError;
    Reader::StructuredError structured;
    structured.offset_start = error.token_.start_ - begin_;
    structured.offset_limit = error.token_.end_ - begin_;
    structured.message = error.message_;
    allErrors.push_back(structured);
  }
  return allErrors;
}

bool Reader::pushError(const Value& value, const JSONCPP_STRING& message) {
  ptrdiff_t const length = end_ - begin_;
  if(value.getOffsetStart() > length
    || value.getOffsetLimit() > length)
    return false;
  Token token;
  token.type_ = tokenError;
  token.start_ = begin_ + value.getOffsetStart();
  token.end_ = end_ + value.getOffsetLimit();
  ErrorInfo info;
  info.token_ = token;
  info.message_ = message;
  info.extra_ = 0;
  errors_.push_back(info);
  return true;
}

bool Reader::pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra) {
  ptrdiff_t const length = end_ - begin_;
  if(value.getOffsetStart() > length
    || value.getOffsetLimit() > length
    || extra.getOffsetLimit() > length)
    return false;
  Token token;
  token.type_ = tokenError;
  token.start_ = begin_ + value.getOffsetStart();
  token.end_ = begin_ + value.getOffsetLimit();
  ErrorInfo info;
  info.token_ = token;
  info.message_ = message;
  info.extra_ = begin_ + extra.getOffsetStart();
  errors_.push_back(info);
  return true;
}

bool Reader::good() const {
  return !errors_.size();
}

// exact copy of Features
class OurFeatures {
public:
  static OurFeatures all();
  bool allowComments_;
  bool strictRoot_;
  bool allowDroppedNullPlaceholders_;
  bool allowNumericKeys_;
  bool allowSingleQuotes_;
  bool failIfExtra_;
  bool rejectDupKeys_;
  bool allowSpecialFloats_;
  int stackLimit_;
};  // OurFeatures

// exact copy of Implementation of class Features
// ////////////////////////////////

OurFeatures OurFeatures::all() { return OurFeatures(); }

// Implementation of class Reader
// ////////////////////////////////

// exact copy of Reader, renamed to OurReader
class OurReader {
public:
  typedef char Char;
  typedef const Char* Location;
  struct StructuredError {
    ptrdiff_t offset_start;
    ptrdiff_t offset_limit;
    JSONCPP_STRING message;
  };

  OurReader(OurFeatures const& features);
  bool parse(const char* beginDoc,
             const char* endDoc,
             Value& root,
             bool collectComments = true);
  JSONCPP_STRING getFormattedErrorMessages() const;
  std::vector<StructuredError> getStructuredErrors() const;
  bool pushError(const Value& value, const JSONCPP_STRING& message);
  bool pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra);
  bool good() const;

private:
  OurReader(OurReader const&);  // no impl
  void operator=(OurReader const&);  // no impl

  enum TokenType {
    tokenEndOfStream = 0,
    tokenObjectBegin,
    tokenObjectEnd,
    tokenArrayBegin,
    tokenArrayEnd,
    tokenString,
    tokenNumber,
    tokenTrue,
    tokenFalse,
    tokenNull,
    tokenNaN,
    tokenPosInf,
    tokenNegInf,
    tokenArraySeparator,
    tokenMemberSeparator,
    tokenComment,
    tokenError
  };

  class Token {
  public:
    TokenType type_;
    Location start_;
    Location end_;
  };

  class ErrorInfo {
  public:
    Token token_;
    JSONCPP_STRING message_;
    Location extra_;
  };

  typedef std::deque<ErrorInfo> Errors;

  bool readToken(Token& token);
  void skipSpaces();
  bool match(Location pattern, int patternLength);
  bool readComment();
  bool readCStyleComment();
  bool readCppStyleComment();
  bool readString();
  bool readStringSingleQuote();
  bool readNumber(bool checkInf);
  bool readValue();
  bool readObject(Token& token);
  bool readArray(Token& token);
  bool decodeNumber(Token& token);
  bool decodeNumber(Token& token, Value& decoded);
  bool decodeString(Token& token);
  bool decodeString(Token& token, JSONCPP_STRING& decoded);
  bool decodeDouble(Token& token);
  bool decodeDouble(Token& token, Value& decoded);
  bool decodeUnicodeCodePoint(Token& token,
                              Location& current,
                              Location end,
                              unsigned int& unicode);
  bool decodeUnicodeEscapeSequence(Token& token,
                                   Location& current,
                                   Location end,
                                   unsigned int& unicode);
  bool addError(const JSONCPP_STRING& message, Token& token, Location extra = 0);
  bool recoverFromError(TokenType skipUntilToken);
  bool addErrorAndRecover(const JSONCPP_STRING& message,
                          Token& token,
                          TokenType skipUntilToken);
  void skipUntilSpace();
  Value& currentValue();
  Char getNextChar();
  void
  getLocationLineAndColumn(Location location, int& line, int& column) const;
  JSONCPP_STRING getLocationLineAndColumn(Location location) const;
  void addComment(Location begin, Location end, CommentPlacement placement);
  void skipCommentTokens(Token& token);

  typedef std::stack<Value*> Nodes;
  Nodes nodes_;
  Errors errors_;
  JSONCPP_STRING document_;
  Location begin_;
  Location end_;
  Location current_;
  Location lastValueEnd_;
  Value* lastValue_;
  JSONCPP_STRING commentsBefore_;
  int stackDepth_;

  OurFeatures const features_;
  bool collectComments_;
};  // OurReader

// complete copy of Read impl, for OurReader

OurReader::OurReader(OurFeatures const& features)
    : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),
      lastValue_(), commentsBefore_(),
      stackDepth_(0),
      features_(features), collectComments_() {
}

bool OurReader::parse(const char* beginDoc,
                   const char* endDoc,
                   Value& root,
                   bool collectComments) {
  if (!features_.allowComments_) {
    collectComments = false;
  }

  begin_ = beginDoc;
  end_ = endDoc;
  collectComments_ = collectComments;
  current_ = begin_;
  lastValueEnd_ = 0;
  lastValue_ = 0;
  commentsBefore_ = "";
  errors_.clear();
  while (!nodes_.empty())
    nodes_.pop();
  nodes_.push(&root);

  stackDepth_ = 0;
  bool successful = readValue();
  Token token;
  skipCommentTokens(token);
  if (features_.failIfExtra_) {
    if (token.type_ != tokenError && token.type_ != tokenEndOfStream) {
      addError("Extra non-whitespace after JSON value.", token);
      return false;
    }
  }
  if (collectComments_ && !commentsBefore_.empty())
    root.setComment(commentsBefore_, commentAfter);
  if (features_.strictRoot_) {
    if (!root.isArray() && !root.isObject()) {
      // Set error location to start of doc, ideally should be first token found
      // in doc
      token.type_ = tokenError;
      token.start_ = beginDoc;
      token.end_ = endDoc;
      addError(
          "A valid JSON document must be either an array or an object value.",
          token);
      return false;
    }
  }
  return successful;
}

bool OurReader::readValue() {
  if (stackDepth_ >= features_.stackLimit_) throwRuntimeError("Exceeded stackLimit in readValue().");
  ++stackDepth_;
  Token token;
  skipCommentTokens(token);
  bool successful = true;

  if (collectComments_ && !commentsBefore_.empty()) {
    currentValue().setComment(commentsBefore_, commentBefore);
    commentsBefore_ = "";
  }

  switch (token.type_) {
  case tokenObjectBegin:
    successful = readObject(token);
    currentValue().setOffsetLimit(current_ - begin_);
    break;
  case tokenArrayBegin:
    successful = readArray(token);
    currentValue().setOffsetLimit(current_ - begin_);
    break;
  case tokenNumber:
    successful = decodeNumber(token);
    break;
  case tokenString:
    successful = decodeString(token);
    break;
  case tokenTrue:
    {
    Value v(true);
    currentValue().swapPayload(v);
    currentValue().setOffsetStart(token.start_ - begin_);
    currentValue().setOffsetLimit(token.end_ - begin_);
    }
    break;
  case tokenFalse:
    {
    Value v(false);
    currentValue().swapPayload(v);
    currentValue().setOffsetStart(token.start_ - begin_);
    currentValue().setOffsetLimit(token.end_ - begin_);
    }
    break;
  case tokenNull:
    {
    Value v;
    currentValue().swapPayload(v);
    currentValue().setOffsetStart(token.start_ - begin_);
    currentValue().setOffsetLimit(token.end_ - begin_);
    }
    break;
  case tokenNaN:
    {
    Value v(std::numeric_limits<double>::quiet_NaN());
    currentValue().swapPayload(v);
    currentValue().setOffsetStart(token.start_ - begin_);
    currentValue().setOffsetLimit(token.end_ - begin_);
    }
    break;
  case tokenPosInf:
    {
    Value v(std::numeric_limits<double>::infinity());
    currentValue().swapPayload(v);
    currentValue().setOffsetStart(token.start_ - begin_);
    currentValue().setOffsetLimit(token.end_ - begin_);
    }
    break;
  case tokenNegInf:
    {
    Value v(-std::numeric_limits<double>::infinity());
    currentValue().swapPayload(v);
    currentValue().setOffsetStart(token.start_ - begin_);
    currentValue().setOffsetLimit(token.end_ - begin_);
    }
    break;
  case tokenArraySeparator:
  case tokenObjectEnd:
  case tokenArrayEnd:
    if (features_.allowDroppedNullPlaceholders_) {
      // "Un-read" the current token and mark the current value as a null
      // token.
      current_--;
      Value v;
      currentValue().swapPayload(v);
      currentValue().setOffsetStart(current_ - begin_ - 1);
      currentValue().setOffsetLimit(current_ - begin_);
      break;
    } // else, fall through ...
  default:
    currentValue().setOffsetStart(token.start_ - begin_);
    currentValue().setOffsetLimit(token.end_ - begin_);
    return addError("Syntax error: value, object or array expected.", token);
  }

  if (collectComments_) {
    lastValueEnd_ = current_;
    lastValue_ = &currentValue();
  }

  --stackDepth_;
  return successful;
}

void OurReader::skipCommentTokens(Token& token) {
  if (features_.allowComments_) {
    do {
      readToken(token);
    } while (token.type_ == tokenComment);
  } else {
    readToken(token);
  }
}

bool OurReader::readToken(Token& token) {
  skipSpaces();
  token.start_ = current_;
  Char c = getNextChar();
  bool ok = true;
  switch (c) {
  case '{':
    token.type_ = tokenObjectBegin;
    break;
  case '}':
    token.type_ = tokenObjectEnd;
    break;
  case '[':
    token.type_ = tokenArrayBegin;
    break;
  case ']':
    token.type_ = tokenArrayEnd;
    break;
  case '"':
    token.type_ = tokenString;
    ok = readString();
    break;
  case '\'':
    if (features_.allowSingleQuotes_) {
    token.type_ = tokenString;
    ok = readStringSingleQuote();
    break;
    } // else continue
  case '/':
    token.type_ = tokenComment;
    ok = readComment();
    break;
  case '0':
  case '1':
  case '2':
  case '3':
  case '4':
  case '5':
  case '6':
  case '7':
  case '8':
  case '9':
    token.type_ = tokenNumber;
    readNumber(false);
    break;
  case '-':
    if (readNumber(true)) {
      token.type_ = tokenNumber;
    } else {
      token.type_ = tokenNegInf;
      ok = features_.allowSpecialFloats_ && match("nfinity", 7);
    }
    break;
  case 't':
    token.type_ = tokenTrue;
    ok = match("rue", 3);
    break;
  case 'f':
    token.type_ = tokenFalse;
    ok = match("alse", 4);
    break;
  case 'n':
    token.type_ = tokenNull;
    ok = match("ull", 3);
    break;
  case 'N':
    if (features_.allowSpecialFloats_) {
      token.type_ = tokenNaN;
      ok = match("aN", 2);
    } else {
      ok = false;
    }
    break;
  case 'I':
    if (features_.allowSpecialFloats_) {
      token.type_ = tokenPosInf;
      ok = match("nfinity", 7);
    } else {
      ok = false;
    }
    break;
  case ',':
    token.type_ = tokenArraySeparator;
    break;
  case ':':
    token.type_ = tokenMemberSeparator;
    break;
  case 0:
    token.type_ = tokenEndOfStream;
    break;
  default:
    ok = false;
    break;
  }
  if (!ok)
    token.type_ = tokenError;
  token.end_ = current_;
  return true;
}

void OurReader::skipSpaces() {
  while (current_ != end_) {
    Char c = *current_;
    if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
      ++current_;
    else
      break;
  }
}

bool OurReader::match(Location pattern, int patternLength) {
  if (end_ - current_ < patternLength)
    return false;
  int index = patternLength;
  while (index--)
    if (current_[index] != pattern[index])
      return false;
  current_ += patternLength;
  return true;
}

bool OurReader::readComment() {
  Location commentBegin = current_ - 1;
  Char c = getNextChar();
  bool successful = false;
  if (c == '*')
    successful = readCStyleComment();
  else if (c == '/')
    successful = readCppStyleComment();
  if (!successful)
    return false;

  if (collectComments_) {
    CommentPlacement placement = commentBefore;
    if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin)) {
      if (c != '*' || !containsNewLine(commentBegin, current_))
        placement = commentAfterOnSameLine;
    }

    addComment(commentBegin, current_, placement);
  }
  return true;
}

void
OurReader::addComment(Location begin, Location end, CommentPlacement placement) {
  assert(collectComments_);
  const JSONCPP_STRING& normalized = normalizeEOL(begin, end);
  if (placement == commentAfterOnSameLine) {
    assert(lastValue_ != 0);
    lastValue_->setComment(normalized, placement);
  } else {
    commentsBefore_ += normalized;
  }
}

bool OurReader::readCStyleComment() {
  while (current_ != end_) {
    Char c = getNextChar();
    if (c == '*' && *current_ == '/')
      break;
  }
  return getNextChar() == '/';
}

bool OurReader::readCppStyleComment() {
  while (current_ != end_) {
    Char c = getNextChar();
    if (c == '\n')
      break;
    if (c == '\r') {
      // Consume DOS EOL. It will be normalized in addComment.
      if (current_ != end_ && *current_ == '\n')
        getNextChar();
      // Break on Moc OS 9 EOL.
      break;
    }
  }
  return true;
}

bool OurReader::readNumber(bool checkInf) {
  const char *p = current_;
  if (checkInf && p != end_ && *p == 'I') {
    current_ = ++p;
    return false;
  }
  char c = '0'; // stopgap for already consumed character
  // integral part
  while (c >= '0' && c <= '9')
    c = (current_ = p) < end_ ? *p++ : 0;
  // fractional part
  if (c == '.') {
    c = (current_ = p) < end_ ? *p++ : 0;
    while (c >= '0' && c <= '9')
      c = (current_ = p) < end_ ? *p++ : 0;
  }
  // exponential part
  if (c == 'e' || c == 'E') {
    c = (current_ = p) < end_ ? *p++ : 0;
    if (c == '+' || c == '-')
      c = (current_ = p) < end_ ? *p++ : 0;
    while (c >= '0' && c <= '9')
      c = (current_ = p) < end_ ? *p++ : 0;
  }
  return true;
}
bool OurReader::readString() {
  Char c = 0;
  while (current_ != end_) {
    c = getNextChar();
    if (c == '\\')
      getNextChar();
    else if (c == '"')
      break;
  }
  return c == '"';
}


bool OurReader::readStringSingleQuote() {
  Char c = 0;
  while (current_ != end_) {
    c = getNextChar();
    if (c == '\\')
      getNextChar();
    else if (c == '\'')
      break;
  }
  return c == '\'';
}

bool OurReader::readObject(Token& tokenStart) {
  Token tokenName;
  JSONCPP_STRING name;
  Value init(objectValue);
  currentValue().swapPayload(init);
  currentValue().setOffsetStart(tokenStart.start_ - begin_);
  while (readToken(tokenName)) {
    bool initialTokenOk = true;
    while (tokenName.type_ == tokenComment && initialTokenOk)
      initialTokenOk = readToken(tokenName);
    if (!initialTokenOk)
      break;
    if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object
      return true;
    name = "";
    if (tokenName.type_ == tokenString) {
      if (!decodeString(tokenName, name))
        return recoverFromError(tokenObjectEnd);
    } else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_) {
      Value numberName;
      if (!decodeNumber(tokenName, numberName))
        return recoverFromError(tokenObjectEnd);
      name = numberName.asString();
    } else {
      break;
    }

    Token colon;
    if (!readToken(colon) || colon.type_ != tokenMemberSeparator) {
      return addErrorAndRecover(
          "Missing ':' after object member name", colon, tokenObjectEnd);
    }
    if (name.length() >= (1U<<30)) throwRuntimeError("keylength >= 2^30");
    if (features_.rejectDupKeys_ && currentValue().isMember(name)) {
      JSONCPP_STRING msg = "Duplicate key: '" + name + "'";
      return addErrorAndRecover(
          msg, tokenName, tokenObjectEnd);
    }
    Value& value = currentValue()[name];
    nodes_.push(&value);
    bool ok = readValue();
    nodes_.pop();
    if (!ok) // error already set
      return recoverFromError(tokenObjectEnd);

    Token comma;
    if (!readToken(comma) ||
        (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator &&
         comma.type_ != tokenComment)) {
      return addErrorAndRecover(
          "Missing ',' or '}' in object declaration", comma, tokenObjectEnd);
    }
    bool finalizeTokenOk = true;
    while (comma.type_ == tokenComment && finalizeTokenOk)
      finalizeTokenOk = readToken(comma);
    if (comma.type_ == tokenObjectEnd)
      return true;
  }
  return addErrorAndRecover(
      "Missing '}' or object member name", tokenName, tokenObjectEnd);
}

bool OurReader::readArray(Token& tokenStart) {
  Value init(arrayValue);
  currentValue().swapPayload(init);
  currentValue().setOffsetStart(tokenStart.start_ - begin_);
  skipSpaces();
  if (*current_ == ']') // empty array
  {
    Token endArray;
    readToken(endArray);
    return true;
  }
  int index = 0;
  for (;;) {
    Value& value = currentValue()[index++];
    nodes_.push(&value);
    bool ok = readValue();
    nodes_.pop();
    if (!ok) // error already set
      return recoverFromError(tokenArrayEnd);

    Token token;
    // Accept Comment after last item in the array.
    ok = readToken(token);
    while (token.type_ == tokenComment && ok) {
      ok = readToken(token);
    }
    bool badTokenType =
        (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd);
    if (!ok || badTokenType) {
      return addErrorAndRecover(
          "Missing ',' or ']' in array declaration", token, tokenArrayEnd);
    }
    if (token.type_ == tokenArrayEnd)
      break;
  }
  return true;
}

bool OurReader::decodeNumber(Token& token) {
  Value decoded;
  if (!decodeNumber(token, decoded))
    return false;
  currentValue().swapPayload(decoded);
  currentValue().setOffsetStart(token.start_ - begin_);
  currentValue().setOffsetLimit(token.end_ - begin_);
  return true;
}

bool OurReader::decodeNumber(Token& token, Value& decoded) {
  // Attempts to parse the number as an integer. If the number is
  // larger than the maximum supported value of an integer then
  // we decode the number as a double.
  Location current = token.start_;
  bool isNegative = *current == '-';
  if (isNegative)
    ++current;
  // TODO: Help the compiler do the div and mod at compile time or get rid of them.
  Value::LargestUInt maxIntegerValue =
      isNegative ? Value::LargestUInt(-Value::minLargestInt)
                 : Value::maxLargestUInt;
  Value::LargestUInt threshold = maxIntegerValue / 10;
  Value::LargestUInt value = 0;
  while (current < token.end_) {
    Char c = *current++;
    if (c < '0' || c > '9')
      return decodeDouble(token, decoded);
    Value::UInt digit(static_cast<Value::UInt>(c - '0'));
    if (value >= threshold) {
      // We've hit or exceeded the max value divided by 10 (rounded down). If
      // a) we've only just touched the limit, b) this is the last digit, and
      // c) it's small enough to fit in that rounding delta, we're okay.
      // Otherwise treat this number as a double to avoid overflow.
      if (value > threshold || current != token.end_ ||
          digit > maxIntegerValue % 10) {
        return decodeDouble(token, decoded);
      }
    }
    value = value * 10 + digit;
  }
  if (isNegative)
    decoded = -Value::LargestInt(value);
  else if (value <= Value::LargestUInt(Value::maxInt))
    decoded = Value::LargestInt(value);
  else
    decoded = value;
  return true;
}

bool OurReader::decodeDouble(Token& token) {
  Value decoded;
  if (!decodeDouble(token, decoded))
    return false;
  currentValue().swapPayload(decoded);
  currentValue().setOffsetStart(token.start_ - begin_);
  currentValue().setOffsetLimit(token.end_ - begin_);
  return true;
}

bool OurReader::decodeDouble(Token& token, Value& decoded) {
  double value = 0;
  const int bufferSize = 32;
  int count;
  ptrdiff_t const length = token.end_ - token.start_;

  // Sanity check to avoid buffer overflow exploits.
  if (length < 0) {
    return addError("Unable to parse token length", token);
  }
  size_t const ulength = static_cast<size_t>(length);

  // Avoid using a string constant for the format control string given to
  // sscanf, as this can cause hard to debug crashes on OS X. See here for more
  // info:
  //
  //     http://developer.apple.com/library/mac/#DOCUMENTATION/DeveloperTools/gcc-4.0.1/gcc/Incompatibilities.html
  char format[] = "%lf";

  if (length <= bufferSize) {
    Char buffer[bufferSize + 1];
    memcpy(buffer, token.start_, ulength);
    buffer[length] = 0;
    count = sscanf(buffer, format, &value);
  } else {
    JSONCPP_STRING buffer(token.start_, token.end_);
    count = sscanf(buffer.c_str(), format, &value);
  }

  if (count != 1)
    return addError("'" + JSONCPP_STRING(token.start_, token.end_) +
                        "' is not a number.",
                    token);
  decoded = value;
  return true;
}

bool OurReader::decodeString(Token& token) {
  JSONCPP_STRING decoded_string;
  if (!decodeString(token, decoded_string))
    return false;
  Value decoded(decoded_string);
  currentValue().swapPayload(decoded);
  currentValue().setOffsetStart(token.start_ - begin_);
  currentValue().setOffsetLimit(token.end_ - begin_);
  return true;
}

bool OurReader::decodeString(Token& token, JSONCPP_STRING& decoded) {
  decoded.reserve(static_cast<size_t>(token.end_ - token.start_ - 2));
  Location current = token.start_ + 1; // skip '"'
  Location end = token.end_ - 1;       // do not include '"'
  while (current != end) {
    Char c = *current++;
    if (c == '"')
      break;
    else if (c == '\\') {
      if (current == end)
        return addError("Empty escape sequence in string", token, current);
      Char escape = *current++;
      switch (escape) {
      case '"':
        decoded += '"';
        break;
      case '/':
        decoded += '/';
        break;
      case '\\':
        decoded += '\\';
        break;
      case 'b':
        decoded += '\b';
        break;
      case 'f':
        decoded += '\f';
        break;
      case 'n':
        decoded += '\n';
        break;
      case 'r':
        decoded += '\r';
        break;
      case 't':
        decoded += '\t';
        break;
      case 'u': {
        unsigned int unicode;
        if (!decodeUnicodeCodePoint(token, current, end, unicode))
          return false;
        decoded += codePointToUTF8(unicode);
      } break;
      default:
        return addError("Bad escape sequence in string", token, current);
      }
    } else {
      decoded += c;
    }
  }
  return true;
}

bool OurReader::decodeUnicodeCodePoint(Token& token,
                                    Location& current,
                                    Location end,
                                    unsigned int& unicode) {

  if (!decodeUnicodeEscapeSequence(token, current, end, unicode))
    return false;
  if (unicode >= 0xD800 && unicode <= 0xDBFF) {
    // surrogate pairs
    if (end - current < 6)
      return addError(
          "additional six characters expected to parse unicode surrogate pair.",
          token,
          current);
    unsigned int surrogatePair;
    if (*(current++) == '\\' && *(current++) == 'u') {
      if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) {
        unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF);
      } else
        return false;
    } else
      return addError("expecting another \\u token to begin the second half of "
                      "a unicode surrogate pair",
                      token,
                      current);
  }
  return true;
}

bool OurReader::decodeUn
Download .txt
gitextract_gw48o2es/

├── .gitmodules
├── Makefile
├── README.md
└── source/
    ├── cia.c
    ├── cia.h
    ├── config.cpp
    ├── config.h
    ├── data.h
    ├── font.h
    ├── fts_fuzzy_match.h
    ├── json/
    │   ├── json-forwards.h
    │   └── json.h
    ├── jsoncpp.cpp
    ├── lib.h
    ├── main.cpp
    ├── menu.cpp
    ├── menu.h
    ├── svchax/
    │   ├── svchax.c
    │   └── svchax.h
    ├── types.h
    ├── utf8proc/
    │   ├── LICENSE.md
    │   ├── utf8proc.c
    │   ├── utf8proc.h
    │   └── utf8proc_data.h
    ├── utils.cpp
    └── utils.h
Download .txt
SYMBOL INDEX (313 symbols across 15 files)

FILE: source/cia.c
  function generate_cia (line 25) | int generate_cia(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context, FILE ...
  function install_cia (line 40) | int install_cia(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context)
  function TIK_CONTEXT (line 102) | TIK_CONTEXT process_tik(FILE *tik)
  function TMD_CONTEXT (line 144) | TMD_CONTEXT process_tmd(FILE *tmd)
  function CIA_HEADER (line 183) | CIA_HEADER set_cia_header(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context)
  function u32 (line 202) | u32 get_tik_size(u32 sig_size)
  function u32 (line 207) | u32 get_tmd_size(u32 sig_size, u16 content_count)
  function u32 (line 212) | u32 get_sig_size(u32 offset, FILE *file)
  function u32 (line 230) | u32 get_cert_size(u32 offset, FILE *file)
  function u32 (line 238) | u32 get_total_cert_size(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context)
  function u64 (line 243) | u64 get_content_size(TMD_CONTEXT tmd_context)
  function u64 (line 251) | u64 read_content_size(TMD_CONTENT_CHUNK_STRUCT content_struct)
  function u32 (line 256) | u32 get_content_id(TMD_CONTENT_CHUNK_STRUCT content_struct)
  function u64 (line 261) | u64 get_title_id(TMD_CONTEXT content_struct)
  function write_cia_header (line 266) | int write_cia_header(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context, F...
  function write_cert_chain (line 278) | int write_cert_chain(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context, F...
  function write_tik (line 307) | int write_tik(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context, FILE *ou...
  function write_tmd (line 322) | int write_tmd(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context, FILE *ou...
  function write_content (line 336) | int write_content(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context, FILE...
  function install_cia_header (line 361) | int install_cia_header(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context,...
  function install_cert_chain (line 375) | int install_cert_chain(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context,...
  function install_tik (line 408) | int install_tik(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context, u32* o...
  function install_tmd (line 425) | int install_tmd(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context, u32* o...
  function Result (line 441) | Result install_content(TMD_CONTEXT tmd_context, TIK_CONTEXT tik_context,...
  function install_write_align_padding (line 466) | void install_write_align_padding(Handle handle, u32* offset, size_t alig...
  function TIK_STRUCT (line 485) | TIK_STRUCT get_tik_struct(u32 sig_size, FILE *tik)
  function TMD_STRUCT (line 493) | TMD_STRUCT get_tmd_struct(u32 sig_size, FILE *tmd)
  function TMD_CONTENT_CHUNK_STRUCT (line 501) | TMD_CONTENT_CHUNK_STRUCT get_tmd_content_struct(u32 sig_size, u8 index, ...
  function print_content_chunk_info (line 509) | void print_content_chunk_info(TMD_CONTENT_CHUNK_STRUCT content_struct)
  function check_tid (line 518) | int check_tid(u8 *tid_0, u8 *tid_1)

FILE: source/cia.h
  type RSA_2048_PUB_KEY (line 35) | typedef struct
  type CERT_2048KEY_DATA_STRUCT (line 42) | typedef struct
  type TMD_SIG_STRUCT (line 54) | typedef struct
  type TMD_CONTENT_CHUNK_STRUCT (line 65) | typedef struct
  type TMD_STRUCT (line 75) | typedef struct
  type TIK_SIG_STRUCT (line 92) | typedef struct
  type TIK_STRUCT (line 101) | typedef struct
  type TMD_CONTEXT (line 118) | typedef struct
  type TIK_CONTEXT (line 135) | typedef struct
  type CIA_HEADER (line 148) | typedef struct

FILE: source/config.h
  function class (line 5) | class CConfig {

FILE: source/fts_fuzzy_match.h
  function namespace (line 14) | namespace fts {

FILE: source/json/json-forwards.h
  function namespace (line 223) | namespace Json {
  function namespace (line 285) | namespace Json {

FILE: source/json/json.h
  function namespace (line 256) | namespace Json {
  function namespace (line 318) | namespace Json {
  function namespace (line 369) | namespace Json {
  function namespace (line 474) | namespace Json {
  function namespace (line 1281) | namespace std {
  function namespace (line 1332) | namespace Json {
  function namespace (line 1747) | namespace Json {

FILE: source/jsoncpp.cpp
  type Json (line 101) | namespace Json {
    function JSONCPP_STRING (line 104) | static inline JSONCPP_STRING codePointToUTF8(unsigned int cp) {
    function isControlCharacter (line 133) | static inline bool isControlCharacter(char ch) { return ch > 0 && ch <...
    function uintToString (line 149) | static inline void uintToString(LargestUInt value, char*& current) {
    function fixNumericLocale (line 162) | static inline void fixNumericLocale(char* begin, char* end) {
    function Features (line 252) | Features Features::all() { return Features(); }
    function Features (line 254) | Features Features::strictMode() {
    function containsNewLine (line 266) | static bool containsNewLine(Reader::Location begin, Reader::Location e...
    function JSONCPP_STRING (line 559) | static JSONCPP_STRING normalizeEOL(Reader::Location begin, Reader::Loc...
    function Value (line 969) | Value& Reader::currentValue() { return *(nodes_.top()); }
    function JSONCPP_STRING (line 1000) | JSONCPP_STRING Reader::getLocationLineAndColumn(Location location) con...
    function JSONCPP_STRING (line 1009) | JSONCPP_STRING Reader::getFormatedErrorMessages() const {
    function JSONCPP_STRING (line 1013) | JSONCPP_STRING Reader::getFormattedErrorMessages() const {
    class OurFeatures (line 1084) | class OurFeatures {
    function OurFeatures (line 1101) | OurFeatures OurFeatures::all() { return OurFeatures(); }
    class OurReader (line 1107) | class OurReader {
      type StructuredError (line 1111) | struct StructuredError {
      type TokenType (line 1132) | enum TokenType {
      class Token (line 1152) | class Token {
      class ErrorInfo (line 1159) | class ErrorInfo {
    function Value (line 1975) | Value& OurReader::currentValue() { return *(nodes_.top()); }
    function JSONCPP_STRING (line 2006) | JSONCPP_STRING OurReader::getLocationLineAndColumn(Location location) ...
    function JSONCPP_STRING (line 2014) | JSONCPP_STRING OurReader::getFormattedErrorMessages() const {
    class OurCharReader (line 2085) | class OurCharReader : public CharReader {
      method OurCharReader (line 2089) | OurCharReader(
      method parse (line 2095) | bool parse(
    function CharReader (line 2112) | CharReader* CharReaderBuilder::newCharReader() const
    function getValidReaderKeys (line 2127) | static void getValidReaderKeys(std::set<JSONCPP_STRING>* valid_keys)
    function Value (line 2158) | Value& CharReaderBuilder::operator[](JSONCPP_STRING key)
    function parseFromStream (line 2197) | bool parseFromStream(
    function JSONCPP_ISTREAM (line 2211) | JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM& sin, Value& root) {
    function Value (line 2265) | Value& ValueIteratorBase::deref() const {
    function Value (line 2317) | Value ValueIteratorBase::key() const {
    function UInt (line 2327) | UInt ValueIteratorBase::index() const {
    function JSONCPP_STRING (line 2334) | JSONCPP_STRING ValueIteratorBase::name() const {
    function ValueConstIterator (line 2374) | ValueConstIterator& ValueConstIterator::
    function ValueIterator (line 2401) | ValueIterator& ValueIterator::operator=(const SelfType& other) {
    function InRange (line 2477) | static inline bool InRange(double d, T min, U max) {
    function integerToDouble (line 2484) | static inline double integerToDouble(Json::UInt64 value) {
    function integerToDouble (line 2488) | static inline double integerToDouble(T value) {
    function InRange (line 2493) | static inline bool InRange(double d, T min, U max) {
    function decodePrefixedString (line 2547) | inline static void decodePrefixedString(
    function releasePrefixedStringValue (line 2562) | static inline void releasePrefixedStringValue(char* value) {
    function releaseStringValue (line 2570) | static inline void releaseStringValue(char* value, unsigned length) {
    function releasePrefixedStringValue (line 2577) | static inline void releasePrefixedStringValue(char* value) {
    function releaseStringValue (line 2580) | static inline void releaseStringValue(char* value, unsigned) {
    function JSONCPP_NORETURN (line 2616) | JSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const& msg)
    function JSONCPP_NORETURN (line 2620) | JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg)
    function ArrayIndex (line 2734) | ArrayIndex Value::CZString::index() const { return index_; }
    function Value (line 2917) | Value& Value::operator=(Value other) {
    function ValueType (line 2939) | ValueType Value::type() const { return type_; }
    function JSONCPP_STRING (line 3080) | JSONCPP_STRING Value::asString() const {
    function LargestInt (line 3204) | LargestInt Value::asLargestInt() const {
    function LargestUInt (line 3212) | LargestUInt Value::asLargestUInt() const {
    function ArrayIndex (line 3318) | ArrayIndex Value::size() const {
    function Value (line 3384) | Value& Value::operator[](ArrayIndex index) {
    function Value (line 3400) | Value& Value::operator[](int index) {
    function Value (line 3407) | const Value& Value::operator[](ArrayIndex index) const {
    function Value (line 3420) | const Value& Value::operator[](int index) const {
    function Value (line 3438) | Value& Value::resolveReference(const char* key) {
    function Value (line 3457) | Value& Value::resolveReference(char const* key, char const* cend)
    function Value (line 3476) | Value Value::get(ArrayIndex index, const Value& defaultValue) const {
    function Value (line 3483) | Value const* Value::find(char const* key, char const* cend) const
    function Value (line 3494) | const Value& Value::operator[](const char* key) const
    function Value (line 3500) | Value const& Value::operator[](JSONCPP_STRING const& key) const
    function Value (line 3507) | Value& Value::operator[](const char* key) {
    function Value (line 3511) | Value& Value::operator[](const JSONCPP_STRING& key) {
    function Value (line 3515) | Value& Value::operator[](const StaticString& key) {
    function Value (line 3520) | Value& Value::operator[](const CppTL::ConstString& key) {
    function Value (line 3523) | Value const& Value::operator[](CppTL::ConstString const& key) const
    function Value (line 3531) | Value& Value::append(const Value& value) { return (*this)[size()] = va...
    function Value (line 3533) | Value Value::get(char const* key, char const* cend, Value const& defau...
    function Value (line 3538) | Value Value::get(char const* key, Value const& defaultValue) const
    function Value (line 3542) | Value Value::get(JSONCPP_STRING const& key, Value const& defaultValue)...
    function Value (line 3569) | Value Value::removeMember(const char* key)
    function Value (line 3580) | Value Value::removeMember(const JSONCPP_STRING& key)
    function Value (line 3609) | Value Value::get(const CppTL::ConstString& key,
    function IsIntegral (line 3677) | static bool IsIntegral(double d) {
    function JSONCPP_STRING (line 3796) | JSONCPP_STRING Value::getComment(CommentPlacement placement) const {
    function JSONCPP_STRING (line 3810) | JSONCPP_STRING Value::toStyledString() const {
    function Value (line 3947) | const Value& Path::resolve(const Value& root) const {
    function Value (line 3970) | Value Path::resolve(const Value& root, const Value& defaultValue) const {
    function Value (line 3989) | Value& Path::make(Value& root) const {
    function containsControlCharacter (line 4106) | static bool containsControlCharacter(const char* str) {
    function containsControlCharacter0 (line 4114) | static bool containsControlCharacter0(const char* str, unsigned len) {
    function JSONCPP_STRING (line 4124) | JSONCPP_STRING valueToString(LargestInt value) {
    function JSONCPP_STRING (line 4140) | JSONCPP_STRING valueToString(LargestUInt value) {
    function JSONCPP_STRING (line 4150) | JSONCPP_STRING valueToString(Int value) {
    function JSONCPP_STRING (line 4154) | JSONCPP_STRING valueToString(UInt value) {
    function JSONCPP_STRING (line 4160) | JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsi...
    function JSONCPP_STRING (line 4190) | JSONCPP_STRING valueToString(double value) { return valueToString(valu...
    function JSONCPP_STRING (line 4192) | JSONCPP_STRING valueToString(bool value) { return value ? "true" : "fa...
    function JSONCPP_STRING (line 4194) | JSONCPP_STRING valueToQuotedString(const char* value) {
    function JSONCPP_STRING (line 4271) | static JSONCPP_STRING valueToQuotedStringN(const char* value, unsigned...
    function JSONCPP_STRING (line 4351) | JSONCPP_STRING FastWriter::write(const Value& root) {
    function JSONCPP_STRING (line 4419) | JSONCPP_STRING StyledWriter::write(const Value& root) {
    type CommentStyle (line 4845) | struct CommentStyle {
      type Enum (line 4847) | enum Enum {
    type BuiltStyledStreamWriter (line 4854) | struct BuiltStyledStreamWriter : public StreamWriter
    function StreamWriter (line 5148) | StreamWriter* StreamWriterBuilder::newStreamWriter() const
    function getValidWriterKeys (line 5180) | static void getValidWriterKeys(std::set<JSONCPP_STRING>* valid_keys)
    function Value (line 5207) | Value& StreamWriterBuilder::operator[](JSONCPP_STRING key)
    function JSONCPP_STRING (line 5224) | JSONCPP_STRING writeString(StreamWriter::Factory const& builder, Value...
    function JSONCPP_OSTREAM (line 5231) | JSONCPP_OSTREAM& operator<<(JSONCPP_OSTREAM& sout, Value const& root) {
  type Json (line 237) | namespace Json {
    function JSONCPP_STRING (line 104) | static inline JSONCPP_STRING codePointToUTF8(unsigned int cp) {
    function isControlCharacter (line 133) | static inline bool isControlCharacter(char ch) { return ch > 0 && ch <...
    function uintToString (line 149) | static inline void uintToString(LargestUInt value, char*& current) {
    function fixNumericLocale (line 162) | static inline void fixNumericLocale(char* begin, char* end) {
    function Features (line 252) | Features Features::all() { return Features(); }
    function Features (line 254) | Features Features::strictMode() {
    function containsNewLine (line 266) | static bool containsNewLine(Reader::Location begin, Reader::Location e...
    function JSONCPP_STRING (line 559) | static JSONCPP_STRING normalizeEOL(Reader::Location begin, Reader::Loc...
    function Value (line 969) | Value& Reader::currentValue() { return *(nodes_.top()); }
    function JSONCPP_STRING (line 1000) | JSONCPP_STRING Reader::getLocationLineAndColumn(Location location) con...
    function JSONCPP_STRING (line 1009) | JSONCPP_STRING Reader::getFormatedErrorMessages() const {
    function JSONCPP_STRING (line 1013) | JSONCPP_STRING Reader::getFormattedErrorMessages() const {
    class OurFeatures (line 1084) | class OurFeatures {
    function OurFeatures (line 1101) | OurFeatures OurFeatures::all() { return OurFeatures(); }
    class OurReader (line 1107) | class OurReader {
      type StructuredError (line 1111) | struct StructuredError {
      type TokenType (line 1132) | enum TokenType {
      class Token (line 1152) | class Token {
      class ErrorInfo (line 1159) | class ErrorInfo {
    function Value (line 1975) | Value& OurReader::currentValue() { return *(nodes_.top()); }
    function JSONCPP_STRING (line 2006) | JSONCPP_STRING OurReader::getLocationLineAndColumn(Location location) ...
    function JSONCPP_STRING (line 2014) | JSONCPP_STRING OurReader::getFormattedErrorMessages() const {
    class OurCharReader (line 2085) | class OurCharReader : public CharReader {
      method OurCharReader (line 2089) | OurCharReader(
      method parse (line 2095) | bool parse(
    function CharReader (line 2112) | CharReader* CharReaderBuilder::newCharReader() const
    function getValidReaderKeys (line 2127) | static void getValidReaderKeys(std::set<JSONCPP_STRING>* valid_keys)
    function Value (line 2158) | Value& CharReaderBuilder::operator[](JSONCPP_STRING key)
    function parseFromStream (line 2197) | bool parseFromStream(
    function JSONCPP_ISTREAM (line 2211) | JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM& sin, Value& root) {
    function Value (line 2265) | Value& ValueIteratorBase::deref() const {
    function Value (line 2317) | Value ValueIteratorBase::key() const {
    function UInt (line 2327) | UInt ValueIteratorBase::index() const {
    function JSONCPP_STRING (line 2334) | JSONCPP_STRING ValueIteratorBase::name() const {
    function ValueConstIterator (line 2374) | ValueConstIterator& ValueConstIterator::
    function ValueIterator (line 2401) | ValueIterator& ValueIterator::operator=(const SelfType& other) {
    function InRange (line 2477) | static inline bool InRange(double d, T min, U max) {
    function integerToDouble (line 2484) | static inline double integerToDouble(Json::UInt64 value) {
    function integerToDouble (line 2488) | static inline double integerToDouble(T value) {
    function InRange (line 2493) | static inline bool InRange(double d, T min, U max) {
    function decodePrefixedString (line 2547) | inline static void decodePrefixedString(
    function releasePrefixedStringValue (line 2562) | static inline void releasePrefixedStringValue(char* value) {
    function releaseStringValue (line 2570) | static inline void releaseStringValue(char* value, unsigned length) {
    function releasePrefixedStringValue (line 2577) | static inline void releasePrefixedStringValue(char* value) {
    function releaseStringValue (line 2580) | static inline void releaseStringValue(char* value, unsigned) {
    function JSONCPP_NORETURN (line 2616) | JSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const& msg)
    function JSONCPP_NORETURN (line 2620) | JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg)
    function ArrayIndex (line 2734) | ArrayIndex Value::CZString::index() const { return index_; }
    function Value (line 2917) | Value& Value::operator=(Value other) {
    function ValueType (line 2939) | ValueType Value::type() const { return type_; }
    function JSONCPP_STRING (line 3080) | JSONCPP_STRING Value::asString() const {
    function LargestInt (line 3204) | LargestInt Value::asLargestInt() const {
    function LargestUInt (line 3212) | LargestUInt Value::asLargestUInt() const {
    function ArrayIndex (line 3318) | ArrayIndex Value::size() const {
    function Value (line 3384) | Value& Value::operator[](ArrayIndex index) {
    function Value (line 3400) | Value& Value::operator[](int index) {
    function Value (line 3407) | const Value& Value::operator[](ArrayIndex index) const {
    function Value (line 3420) | const Value& Value::operator[](int index) const {
    function Value (line 3438) | Value& Value::resolveReference(const char* key) {
    function Value (line 3457) | Value& Value::resolveReference(char const* key, char const* cend)
    function Value (line 3476) | Value Value::get(ArrayIndex index, const Value& defaultValue) const {
    function Value (line 3483) | Value const* Value::find(char const* key, char const* cend) const
    function Value (line 3494) | const Value& Value::operator[](const char* key) const
    function Value (line 3500) | Value const& Value::operator[](JSONCPP_STRING const& key) const
    function Value (line 3507) | Value& Value::operator[](const char* key) {
    function Value (line 3511) | Value& Value::operator[](const JSONCPP_STRING& key) {
    function Value (line 3515) | Value& Value::operator[](const StaticString& key) {
    function Value (line 3520) | Value& Value::operator[](const CppTL::ConstString& key) {
    function Value (line 3523) | Value const& Value::operator[](CppTL::ConstString const& key) const
    function Value (line 3531) | Value& Value::append(const Value& value) { return (*this)[size()] = va...
    function Value (line 3533) | Value Value::get(char const* key, char const* cend, Value const& defau...
    function Value (line 3538) | Value Value::get(char const* key, Value const& defaultValue) const
    function Value (line 3542) | Value Value::get(JSONCPP_STRING const& key, Value const& defaultValue)...
    function Value (line 3569) | Value Value::removeMember(const char* key)
    function Value (line 3580) | Value Value::removeMember(const JSONCPP_STRING& key)
    function Value (line 3609) | Value Value::get(const CppTL::ConstString& key,
    function IsIntegral (line 3677) | static bool IsIntegral(double d) {
    function JSONCPP_STRING (line 3796) | JSONCPP_STRING Value::getComment(CommentPlacement placement) const {
    function JSONCPP_STRING (line 3810) | JSONCPP_STRING Value::toStyledString() const {
    function Value (line 3947) | const Value& Path::resolve(const Value& root) const {
    function Value (line 3970) | Value Path::resolve(const Value& root, const Value& defaultValue) const {
    function Value (line 3989) | Value& Path::make(Value& root) const {
    function containsControlCharacter (line 4106) | static bool containsControlCharacter(const char* str) {
    function containsControlCharacter0 (line 4114) | static bool containsControlCharacter0(const char* str, unsigned len) {
    function JSONCPP_STRING (line 4124) | JSONCPP_STRING valueToString(LargestInt value) {
    function JSONCPP_STRING (line 4140) | JSONCPP_STRING valueToString(LargestUInt value) {
    function JSONCPP_STRING (line 4150) | JSONCPP_STRING valueToString(Int value) {
    function JSONCPP_STRING (line 4154) | JSONCPP_STRING valueToString(UInt value) {
    function JSONCPP_STRING (line 4160) | JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsi...
    function JSONCPP_STRING (line 4190) | JSONCPP_STRING valueToString(double value) { return valueToString(valu...
    function JSONCPP_STRING (line 4192) | JSONCPP_STRING valueToString(bool value) { return value ? "true" : "fa...
    function JSONCPP_STRING (line 4194) | JSONCPP_STRING valueToQuotedString(const char* value) {
    function JSONCPP_STRING (line 4271) | static JSONCPP_STRING valueToQuotedStringN(const char* value, unsigned...
    function JSONCPP_STRING (line 4351) | JSONCPP_STRING FastWriter::write(const Value& root) {
    function JSONCPP_STRING (line 4419) | JSONCPP_STRING StyledWriter::write(const Value& root) {
    type CommentStyle (line 4845) | struct CommentStyle {
      type Enum (line 4847) | enum Enum {
    type BuiltStyledStreamWriter (line 4854) | struct BuiltStyledStreamWriter : public StreamWriter
    function StreamWriter (line 5148) | StreamWriter* StreamWriterBuilder::newStreamWriter() const
    function getValidWriterKeys (line 5180) | static void getValidWriterKeys(std::set<JSONCPP_STRING>* valid_keys)
    function Value (line 5207) | Value& StreamWriterBuilder::operator[](JSONCPP_STRING key)
    function JSONCPP_STRING (line 5224) | JSONCPP_STRING writeString(StreamWriter::Factory const& builder, Value...
    function JSONCPP_OSTREAM (line 5231) | JSONCPP_OSTREAM& operator<<(JSONCPP_OSTREAM& sout, Value const& root) {
  type Json (line 2247) | namespace Json {
    function JSONCPP_STRING (line 104) | static inline JSONCPP_STRING codePointToUTF8(unsigned int cp) {
    function isControlCharacter (line 133) | static inline bool isControlCharacter(char ch) { return ch > 0 && ch <...
    function uintToString (line 149) | static inline void uintToString(LargestUInt value, char*& current) {
    function fixNumericLocale (line 162) | static inline void fixNumericLocale(char* begin, char* end) {
    function Features (line 252) | Features Features::all() { return Features(); }
    function Features (line 254) | Features Features::strictMode() {
    function containsNewLine (line 266) | static bool containsNewLine(Reader::Location begin, Reader::Location e...
    function JSONCPP_STRING (line 559) | static JSONCPP_STRING normalizeEOL(Reader::Location begin, Reader::Loc...
    function Value (line 969) | Value& Reader::currentValue() { return *(nodes_.top()); }
    function JSONCPP_STRING (line 1000) | JSONCPP_STRING Reader::getLocationLineAndColumn(Location location) con...
    function JSONCPP_STRING (line 1009) | JSONCPP_STRING Reader::getFormatedErrorMessages() const {
    function JSONCPP_STRING (line 1013) | JSONCPP_STRING Reader::getFormattedErrorMessages() const {
    class OurFeatures (line 1084) | class OurFeatures {
    function OurFeatures (line 1101) | OurFeatures OurFeatures::all() { return OurFeatures(); }
    class OurReader (line 1107) | class OurReader {
      type StructuredError (line 1111) | struct StructuredError {
      type TokenType (line 1132) | enum TokenType {
      class Token (line 1152) | class Token {
      class ErrorInfo (line 1159) | class ErrorInfo {
    function Value (line 1975) | Value& OurReader::currentValue() { return *(nodes_.top()); }
    function JSONCPP_STRING (line 2006) | JSONCPP_STRING OurReader::getLocationLineAndColumn(Location location) ...
    function JSONCPP_STRING (line 2014) | JSONCPP_STRING OurReader::getFormattedErrorMessages() const {
    class OurCharReader (line 2085) | class OurCharReader : public CharReader {
      method OurCharReader (line 2089) | OurCharReader(
      method parse (line 2095) | bool parse(
    function CharReader (line 2112) | CharReader* CharReaderBuilder::newCharReader() const
    function getValidReaderKeys (line 2127) | static void getValidReaderKeys(std::set<JSONCPP_STRING>* valid_keys)
    function Value (line 2158) | Value& CharReaderBuilder::operator[](JSONCPP_STRING key)
    function parseFromStream (line 2197) | bool parseFromStream(
    function JSONCPP_ISTREAM (line 2211) | JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM& sin, Value& root) {
    function Value (line 2265) | Value& ValueIteratorBase::deref() const {
    function Value (line 2317) | Value ValueIteratorBase::key() const {
    function UInt (line 2327) | UInt ValueIteratorBase::index() const {
    function JSONCPP_STRING (line 2334) | JSONCPP_STRING ValueIteratorBase::name() const {
    function ValueConstIterator (line 2374) | ValueConstIterator& ValueConstIterator::
    function ValueIterator (line 2401) | ValueIterator& ValueIterator::operator=(const SelfType& other) {
    function InRange (line 2477) | static inline bool InRange(double d, T min, U max) {
    function integerToDouble (line 2484) | static inline double integerToDouble(Json::UInt64 value) {
    function integerToDouble (line 2488) | static inline double integerToDouble(T value) {
    function InRange (line 2493) | static inline bool InRange(double d, T min, U max) {
    function decodePrefixedString (line 2547) | inline static void decodePrefixedString(
    function releasePrefixedStringValue (line 2562) | static inline void releasePrefixedStringValue(char* value) {
    function releaseStringValue (line 2570) | static inline void releaseStringValue(char* value, unsigned length) {
    function releasePrefixedStringValue (line 2577) | static inline void releasePrefixedStringValue(char* value) {
    function releaseStringValue (line 2580) | static inline void releaseStringValue(char* value, unsigned) {
    function JSONCPP_NORETURN (line 2616) | JSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const& msg)
    function JSONCPP_NORETURN (line 2620) | JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg)
    function ArrayIndex (line 2734) | ArrayIndex Value::CZString::index() const { return index_; }
    function Value (line 2917) | Value& Value::operator=(Value other) {
    function ValueType (line 2939) | ValueType Value::type() const { return type_; }
    function JSONCPP_STRING (line 3080) | JSONCPP_STRING Value::asString() const {
    function LargestInt (line 3204) | LargestInt Value::asLargestInt() const {
    function LargestUInt (line 3212) | LargestUInt Value::asLargestUInt() const {
    function ArrayIndex (line 3318) | ArrayIndex Value::size() const {
    function Value (line 3384) | Value& Value::operator[](ArrayIndex index) {
    function Value (line 3400) | Value& Value::operator[](int index) {
    function Value (line 3407) | const Value& Value::operator[](ArrayIndex index) const {
    function Value (line 3420) | const Value& Value::operator[](int index) const {
    function Value (line 3438) | Value& Value::resolveReference(const char* key) {
    function Value (line 3457) | Value& Value::resolveReference(char const* key, char const* cend)
    function Value (line 3476) | Value Value::get(ArrayIndex index, const Value& defaultValue) const {
    function Value (line 3483) | Value const* Value::find(char const* key, char const* cend) const
    function Value (line 3494) | const Value& Value::operator[](const char* key) const
    function Value (line 3500) | Value const& Value::operator[](JSONCPP_STRING const& key) const
    function Value (line 3507) | Value& Value::operator[](const char* key) {
    function Value (line 3511) | Value& Value::operator[](const JSONCPP_STRING& key) {
    function Value (line 3515) | Value& Value::operator[](const StaticString& key) {
    function Value (line 3520) | Value& Value::operator[](const CppTL::ConstString& key) {
    function Value (line 3523) | Value const& Value::operator[](CppTL::ConstString const& key) const
    function Value (line 3531) | Value& Value::append(const Value& value) { return (*this)[size()] = va...
    function Value (line 3533) | Value Value::get(char const* key, char const* cend, Value const& defau...
    function Value (line 3538) | Value Value::get(char const* key, Value const& defaultValue) const
    function Value (line 3542) | Value Value::get(JSONCPP_STRING const& key, Value const& defaultValue)...
    function Value (line 3569) | Value Value::removeMember(const char* key)
    function Value (line 3580) | Value Value::removeMember(const JSONCPP_STRING& key)
    function Value (line 3609) | Value Value::get(const CppTL::ConstString& key,
    function IsIntegral (line 3677) | static bool IsIntegral(double d) {
    function JSONCPP_STRING (line 3796) | JSONCPP_STRING Value::getComment(CommentPlacement placement) const {
    function JSONCPP_STRING (line 3810) | JSONCPP_STRING Value::toStyledString() const {
    function Value (line 3947) | const Value& Path::resolve(const Value& root) const {
    function Value (line 3970) | Value Path::resolve(const Value& root, const Value& defaultValue) const {
    function Value (line 3989) | Value& Path::make(Value& root) const {
    function containsControlCharacter (line 4106) | static bool containsControlCharacter(const char* str) {
    function containsControlCharacter0 (line 4114) | static bool containsControlCharacter0(const char* str, unsigned len) {
    function JSONCPP_STRING (line 4124) | JSONCPP_STRING valueToString(LargestInt value) {
    function JSONCPP_STRING (line 4140) | JSONCPP_STRING valueToString(LargestUInt value) {
    function JSONCPP_STRING (line 4150) | JSONCPP_STRING valueToString(Int value) {
    function JSONCPP_STRING (line 4154) | JSONCPP_STRING valueToString(UInt value) {
    function JSONCPP_STRING (line 4160) | JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsi...
    function JSONCPP_STRING (line 4190) | JSONCPP_STRING valueToString(double value) { return valueToString(valu...
    function JSONCPP_STRING (line 4192) | JSONCPP_STRING valueToString(bool value) { return value ? "true" : "fa...
    function JSONCPP_STRING (line 4194) | JSONCPP_STRING valueToQuotedString(const char* value) {
    function JSONCPP_STRING (line 4271) | static JSONCPP_STRING valueToQuotedStringN(const char* value, unsigned...
    function JSONCPP_STRING (line 4351) | JSONCPP_STRING FastWriter::write(const Value& root) {
    function JSONCPP_STRING (line 4419) | JSONCPP_STRING StyledWriter::write(const Value& root) {
    type CommentStyle (line 4845) | struct CommentStyle {
      type Enum (line 4847) | enum Enum {
    type BuiltStyledStreamWriter (line 4854) | struct BuiltStyledStreamWriter : public StreamWriter
    function StreamWriter (line 5148) | StreamWriter* StreamWriterBuilder::newStreamWriter() const
    function getValidWriterKeys (line 5180) | static void getValidWriterKeys(std::set<JSONCPP_STRING>* valid_keys)
    function Value (line 5207) | Value& StreamWriterBuilder::operator[](JSONCPP_STRING key)
    function JSONCPP_STRING (line 5224) | JSONCPP_STRING writeString(StreamWriter::Factory const& builder, Value...
    function JSONCPP_OSTREAM (line 5231) | JSONCPP_OSTREAM& operator<<(JSONCPP_OSTREAM& sout, Value const& root) {
  type Json (line 2444) | namespace Json {
    function JSONCPP_STRING (line 104) | static inline JSONCPP_STRING codePointToUTF8(unsigned int cp) {
    function isControlCharacter (line 133) | static inline bool isControlCharacter(char ch) { return ch > 0 && ch <...
    function uintToString (line 149) | static inline void uintToString(LargestUInt value, char*& current) {
    function fixNumericLocale (line 162) | static inline void fixNumericLocale(char* begin, char* end) {
    function Features (line 252) | Features Features::all() { return Features(); }
    function Features (line 254) | Features Features::strictMode() {
    function containsNewLine (line 266) | static bool containsNewLine(Reader::Location begin, Reader::Location e...
    function JSONCPP_STRING (line 559) | static JSONCPP_STRING normalizeEOL(Reader::Location begin, Reader::Loc...
    function Value (line 969) | Value& Reader::currentValue() { return *(nodes_.top()); }
    function JSONCPP_STRING (line 1000) | JSONCPP_STRING Reader::getLocationLineAndColumn(Location location) con...
    function JSONCPP_STRING (line 1009) | JSONCPP_STRING Reader::getFormatedErrorMessages() const {
    function JSONCPP_STRING (line 1013) | JSONCPP_STRING Reader::getFormattedErrorMessages() const {
    class OurFeatures (line 1084) | class OurFeatures {
    function OurFeatures (line 1101) | OurFeatures OurFeatures::all() { return OurFeatures(); }
    class OurReader (line 1107) | class OurReader {
      type StructuredError (line 1111) | struct StructuredError {
      type TokenType (line 1132) | enum TokenType {
      class Token (line 1152) | class Token {
      class ErrorInfo (line 1159) | class ErrorInfo {
    function Value (line 1975) | Value& OurReader::currentValue() { return *(nodes_.top()); }
    function JSONCPP_STRING (line 2006) | JSONCPP_STRING OurReader::getLocationLineAndColumn(Location location) ...
    function JSONCPP_STRING (line 2014) | JSONCPP_STRING OurReader::getFormattedErrorMessages() const {
    class OurCharReader (line 2085) | class OurCharReader : public CharReader {
      method OurCharReader (line 2089) | OurCharReader(
      method parse (line 2095) | bool parse(
    function CharReader (line 2112) | CharReader* CharReaderBuilder::newCharReader() const
    function getValidReaderKeys (line 2127) | static void getValidReaderKeys(std::set<JSONCPP_STRING>* valid_keys)
    function Value (line 2158) | Value& CharReaderBuilder::operator[](JSONCPP_STRING key)
    function parseFromStream (line 2197) | bool parseFromStream(
    function JSONCPP_ISTREAM (line 2211) | JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM& sin, Value& root) {
    function Value (line 2265) | Value& ValueIteratorBase::deref() const {
    function Value (line 2317) | Value ValueIteratorBase::key() const {
    function UInt (line 2327) | UInt ValueIteratorBase::index() const {
    function JSONCPP_STRING (line 2334) | JSONCPP_STRING ValueIteratorBase::name() const {
    function ValueConstIterator (line 2374) | ValueConstIterator& ValueConstIterator::
    function ValueIterator (line 2401) | ValueIterator& ValueIterator::operator=(const SelfType& other) {
    function InRange (line 2477) | static inline bool InRange(double d, T min, U max) {
    function integerToDouble (line 2484) | static inline double integerToDouble(Json::UInt64 value) {
    function integerToDouble (line 2488) | static inline double integerToDouble(T value) {
    function InRange (line 2493) | static inline bool InRange(double d, T min, U max) {
    function decodePrefixedString (line 2547) | inline static void decodePrefixedString(
    function releasePrefixedStringValue (line 2562) | static inline void releasePrefixedStringValue(char* value) {
    function releaseStringValue (line 2570) | static inline void releaseStringValue(char* value, unsigned length) {
    function releasePrefixedStringValue (line 2577) | static inline void releasePrefixedStringValue(char* value) {
    function releaseStringValue (line 2580) | static inline void releaseStringValue(char* value, unsigned) {
    function JSONCPP_NORETURN (line 2616) | JSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const& msg)
    function JSONCPP_NORETURN (line 2620) | JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg)
    function ArrayIndex (line 2734) | ArrayIndex Value::CZString::index() const { return index_; }
    function Value (line 2917) | Value& Value::operator=(Value other) {
    function ValueType (line 2939) | ValueType Value::type() const { return type_; }
    function JSONCPP_STRING (line 3080) | JSONCPP_STRING Value::asString() const {
    function LargestInt (line 3204) | LargestInt Value::asLargestInt() const {
    function LargestUInt (line 3212) | LargestUInt Value::asLargestUInt() const {
    function ArrayIndex (line 3318) | ArrayIndex Value::size() const {
    function Value (line 3384) | Value& Value::operator[](ArrayIndex index) {
    function Value (line 3400) | Value& Value::operator[](int index) {
    function Value (line 3407) | const Value& Value::operator[](ArrayIndex index) const {
    function Value (line 3420) | const Value& Value::operator[](int index) const {
    function Value (line 3438) | Value& Value::resolveReference(const char* key) {
    function Value (line 3457) | Value& Value::resolveReference(char const* key, char const* cend)
    function Value (line 3476) | Value Value::get(ArrayIndex index, const Value& defaultValue) const {
    function Value (line 3483) | Value const* Value::find(char const* key, char const* cend) const
    function Value (line 3494) | const Value& Value::operator[](const char* key) const
    function Value (line 3500) | Value const& Value::operator[](JSONCPP_STRING const& key) const
    function Value (line 3507) | Value& Value::operator[](const char* key) {
    function Value (line 3511) | Value& Value::operator[](const JSONCPP_STRING& key) {
    function Value (line 3515) | Value& Value::operator[](const StaticString& key) {
    function Value (line 3520) | Value& Value::operator[](const CppTL::ConstString& key) {
    function Value (line 3523) | Value const& Value::operator[](CppTL::ConstString const& key) const
    function Value (line 3531) | Value& Value::append(const Value& value) { return (*this)[size()] = va...
    function Value (line 3533) | Value Value::get(char const* key, char const* cend, Value const& defau...
    function Value (line 3538) | Value Value::get(char const* key, Value const& defaultValue) const
    function Value (line 3542) | Value Value::get(JSONCPP_STRING const& key, Value const& defaultValue)...
    function Value (line 3569) | Value Value::removeMember(const char* key)
    function Value (line 3580) | Value Value::removeMember(const JSONCPP_STRING& key)
    function Value (line 3609) | Value Value::get(const CppTL::ConstString& key,
    function IsIntegral (line 3677) | static bool IsIntegral(double d) {
    function JSONCPP_STRING (line 3796) | JSONCPP_STRING Value::getComment(CommentPlacement placement) const {
    function JSONCPP_STRING (line 3810) | JSONCPP_STRING Value::toStyledString() const {
    function Value (line 3947) | const Value& Path::resolve(const Value& root) const {
    function Value (line 3970) | Value Path::resolve(const Value& root, const Value& defaultValue) const {
    function Value (line 3989) | Value& Path::make(Value& root) const {
    function containsControlCharacter (line 4106) | static bool containsControlCharacter(const char* str) {
    function containsControlCharacter0 (line 4114) | static bool containsControlCharacter0(const char* str, unsigned len) {
    function JSONCPP_STRING (line 4124) | JSONCPP_STRING valueToString(LargestInt value) {
    function JSONCPP_STRING (line 4140) | JSONCPP_STRING valueToString(LargestUInt value) {
    function JSONCPP_STRING (line 4150) | JSONCPP_STRING valueToString(Int value) {
    function JSONCPP_STRING (line 4154) | JSONCPP_STRING valueToString(UInt value) {
    function JSONCPP_STRING (line 4160) | JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsi...
    function JSONCPP_STRING (line 4190) | JSONCPP_STRING valueToString(double value) { return valueToString(valu...
    function JSONCPP_STRING (line 4192) | JSONCPP_STRING valueToString(bool value) { return value ? "true" : "fa...
    function JSONCPP_STRING (line 4194) | JSONCPP_STRING valueToQuotedString(const char* value) {
    function JSONCPP_STRING (line 4271) | static JSONCPP_STRING valueToQuotedStringN(const char* value, unsigned...
    function JSONCPP_STRING (line 4351) | JSONCPP_STRING FastWriter::write(const Value& root) {
    function JSONCPP_STRING (line 4419) | JSONCPP_STRING StyledWriter::write(const Value& root) {
    type CommentStyle (line 4845) | struct CommentStyle {
      type Enum (line 4847) | enum Enum {
    type BuiltStyledStreamWriter (line 4854) | struct BuiltStyledStreamWriter : public StreamWriter
    function StreamWriter (line 5148) | StreamWriter* StreamWriterBuilder::newStreamWriter() const
    function getValidWriterKeys (line 5180) | static void getValidWriterKeys(std::set<JSONCPP_STRING>* valid_keys)
    function Value (line 5207) | Value& StreamWriterBuilder::operator[](JSONCPP_STRING key)
    function JSONCPP_STRING (line 5224) | JSONCPP_STRING writeString(StreamWriter::Factory const& builder, Value...
    function JSONCPP_OSTREAM (line 5231) | JSONCPP_OSTREAM& operator<<(JSONCPP_OSTREAM& sout, Value const& root) {
  type Json (line 2599) | namespace Json {
    function JSONCPP_STRING (line 104) | static inline JSONCPP_STRING codePointToUTF8(unsigned int cp) {
    function isControlCharacter (line 133) | static inline bool isControlCharacter(char ch) { return ch > 0 && ch <...
    function uintToString (line 149) | static inline void uintToString(LargestUInt value, char*& current) {
    function fixNumericLocale (line 162) | static inline void fixNumericLocale(char* begin, char* end) {
    function Features (line 252) | Features Features::all() { return Features(); }
    function Features (line 254) | Features Features::strictMode() {
    function containsNewLine (line 266) | static bool containsNewLine(Reader::Location begin, Reader::Location e...
    function JSONCPP_STRING (line 559) | static JSONCPP_STRING normalizeEOL(Reader::Location begin, Reader::Loc...
    function Value (line 969) | Value& Reader::currentValue() { return *(nodes_.top()); }
    function JSONCPP_STRING (line 1000) | JSONCPP_STRING Reader::getLocationLineAndColumn(Location location) con...
    function JSONCPP_STRING (line 1009) | JSONCPP_STRING Reader::getFormatedErrorMessages() const {
    function JSONCPP_STRING (line 1013) | JSONCPP_STRING Reader::getFormattedErrorMessages() const {
    class OurFeatures (line 1084) | class OurFeatures {
    function OurFeatures (line 1101) | OurFeatures OurFeatures::all() { return OurFeatures(); }
    class OurReader (line 1107) | class OurReader {
      type StructuredError (line 1111) | struct StructuredError {
      type TokenType (line 1132) | enum TokenType {
      class Token (line 1152) | class Token {
      class ErrorInfo (line 1159) | class ErrorInfo {
    function Value (line 1975) | Value& OurReader::currentValue() { return *(nodes_.top()); }
    function JSONCPP_STRING (line 2006) | JSONCPP_STRING OurReader::getLocationLineAndColumn(Location location) ...
    function JSONCPP_STRING (line 2014) | JSONCPP_STRING OurReader::getFormattedErrorMessages() const {
    class OurCharReader (line 2085) | class OurCharReader : public CharReader {
      method OurCharReader (line 2089) | OurCharReader(
      method parse (line 2095) | bool parse(
    function CharReader (line 2112) | CharReader* CharReaderBuilder::newCharReader() const
    function getValidReaderKeys (line 2127) | static void getValidReaderKeys(std::set<JSONCPP_STRING>* valid_keys)
    function Value (line 2158) | Value& CharReaderBuilder::operator[](JSONCPP_STRING key)
    function parseFromStream (line 2197) | bool parseFromStream(
    function JSONCPP_ISTREAM (line 2211) | JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM& sin, Value& root) {
    function Value (line 2265) | Value& ValueIteratorBase::deref() const {
    function Value (line 2317) | Value ValueIteratorBase::key() const {
    function UInt (line 2327) | UInt ValueIteratorBase::index() const {
    function JSONCPP_STRING (line 2334) | JSONCPP_STRING ValueIteratorBase::name() const {
    function ValueConstIterator (line 2374) | ValueConstIterator& ValueConstIterator::
    function ValueIterator (line 2401) | ValueIterator& ValueIterator::operator=(const SelfType& other) {
    function InRange (line 2477) | static inline bool InRange(double d, T min, U max) {
    function integerToDouble (line 2484) | static inline double integerToDouble(Json::UInt64 value) {
    function integerToDouble (line 2488) | static inline double integerToDouble(T value) {
    function InRange (line 2493) | static inline bool InRange(double d, T min, U max) {
    function decodePrefixedString (line 2547) | inline static void decodePrefixedString(
    function releasePrefixedStringValue (line 2562) | static inline void releasePrefixedStringValue(char* value) {
    function releaseStringValue (line 2570) | static inline void releaseStringValue(char* value, unsigned length) {
    function releasePrefixedStringValue (line 2577) | static inline void releasePrefixedStringValue(char* value) {
    function releaseStringValue (line 2580) | static inline void releaseStringValue(char* value, unsigned) {
    function JSONCPP_NORETURN (line 2616) | JSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const& msg)
    function JSONCPP_NORETURN (line 2620) | JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg)
    function ArrayIndex (line 2734) | ArrayIndex Value::CZString::index() const { return index_; }
    function Value (line 2917) | Value& Value::operator=(Value other) {
    function ValueType (line 2939) | ValueType Value::type() const { return type_; }
    function JSONCPP_STRING (line 3080) | JSONCPP_STRING Value::asString() const {
    function LargestInt (line 3204) | LargestInt Value::asLargestInt() const {
    function LargestUInt (line 3212) | LargestUInt Value::asLargestUInt() const {
    function ArrayIndex (line 3318) | ArrayIndex Value::size() const {
    function Value (line 3384) | Value& Value::operator[](ArrayIndex index) {
    function Value (line 3400) | Value& Value::operator[](int index) {
    function Value (line 3407) | const Value& Value::operator[](ArrayIndex index) const {
    function Value (line 3420) | const Value& Value::operator[](int index) const {
    function Value (line 3438) | Value& Value::resolveReference(const char* key) {
    function Value (line 3457) | Value& Value::resolveReference(char const* key, char const* cend)
    function Value (line 3476) | Value Value::get(ArrayIndex index, const Value& defaultValue) const {
    function Value (line 3483) | Value const* Value::find(char const* key, char const* cend) const
    function Value (line 3494) | const Value& Value::operator[](const char* key) const
    function Value (line 3500) | Value const& Value::operator[](JSONCPP_STRING const& key) const
    function Value (line 3507) | Value& Value::operator[](const char* key) {
    function Value (line 3511) | Value& Value::operator[](const JSONCPP_STRING& key) {
    function Value (line 3515) | Value& Value::operator[](const StaticString& key) {
    function Value (line 3520) | Value& Value::operator[](const CppTL::ConstString& key) {
    function Value (line 3523) | Value const& Value::operator[](CppTL::ConstString const& key) const
    function Value (line 3531) | Value& Value::append(const Value& value) { return (*this)[size()] = va...
    function Value (line 3533) | Value Value::get(char const* key, char const* cend, Value const& defau...
    function Value (line 3538) | Value Value::get(char const* key, Value const& defaultValue) const
    function Value (line 3542) | Value Value::get(JSONCPP_STRING const& key, Value const& defaultValue)...
    function Value (line 3569) | Value Value::removeMember(const char* key)
    function Value (line 3580) | Value Value::removeMember(const JSONCPP_STRING& key)
    function Value (line 3609) | Value Value::get(const CppTL::ConstString& key,
    function IsIntegral (line 3677) | static bool IsIntegral(double d) {
    function JSONCPP_STRING (line 3796) | JSONCPP_STRING Value::getComment(CommentPlacement placement) const {
    function JSONCPP_STRING (line 3810) | JSONCPP_STRING Value::toStyledString() const {
    function Value (line 3947) | const Value& Path::resolve(const Value& root) const {
    function Value (line 3970) | Value Path::resolve(const Value& root, const Value& defaultValue) const {
    function Value (line 3989) | Value& Path::make(Value& root) const {
    function containsControlCharacter (line 4106) | static bool containsControlCharacter(const char* str) {
    function containsControlCharacter0 (line 4114) | static bool containsControlCharacter0(const char* str, unsigned len) {
    function JSONCPP_STRING (line 4124) | JSONCPP_STRING valueToString(LargestInt value) {
    function JSONCPP_STRING (line 4140) | JSONCPP_STRING valueToString(LargestUInt value) {
    function JSONCPP_STRING (line 4150) | JSONCPP_STRING valueToString(Int value) {
    function JSONCPP_STRING (line 4154) | JSONCPP_STRING valueToString(UInt value) {
    function JSONCPP_STRING (line 4160) | JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsi...
    function JSONCPP_STRING (line 4190) | JSONCPP_STRING valueToString(double value) { return valueToString(valu...
    function JSONCPP_STRING (line 4192) | JSONCPP_STRING valueToString(bool value) { return value ? "true" : "fa...
    function JSONCPP_STRING (line 4194) | JSONCPP_STRING valueToQuotedString(const char* value) {
    function JSONCPP_STRING (line 4271) | static JSONCPP_STRING valueToQuotedStringN(const char* value, unsigned...
    function JSONCPP_STRING (line 4351) | JSONCPP_STRING FastWriter::write(const Value& root) {
    function JSONCPP_STRING (line 4419) | JSONCPP_STRING StyledWriter::write(const Value& root) {
    type CommentStyle (line 4845) | struct CommentStyle {
      type Enum (line 4847) | enum Enum {
    type BuiltStyledStreamWriter (line 4854) | struct BuiltStyledStreamWriter : public StreamWriter
    function StreamWriter (line 5148) | StreamWriter* StreamWriterBuilder::newStreamWriter() const
    function getValidWriterKeys (line 5180) | static void getValidWriterKeys(std::set<JSONCPP_STRING>* valid_keys)
    function Value (line 5207) | Value& StreamWriterBuilder::operator[](JSONCPP_STRING key)
    function JSONCPP_STRING (line 5224) | JSONCPP_STRING writeString(StreamWriter::Factory const& builder, Value...
    function JSONCPP_OSTREAM (line 5231) | JSONCPP_OSTREAM& operator<<(JSONCPP_OSTREAM& sout, Value const& root) {
  type Json (line 4098) | namespace Json {
    function JSONCPP_STRING (line 104) | static inline JSONCPP_STRING codePointToUTF8(unsigned int cp) {
    function isControlCharacter (line 133) | static inline bool isControlCharacter(char ch) { return ch > 0 && ch <...
    function uintToString (line 149) | static inline void uintToString(LargestUInt value, char*& current) {
    function fixNumericLocale (line 162) | static inline void fixNumericLocale(char* begin, char* end) {
    function Features (line 252) | Features Features::all() { return Features(); }
    function Features (line 254) | Features Features::strictMode() {
    function containsNewLine (line 266) | static bool containsNewLine(Reader::Location begin, Reader::Location e...
    function JSONCPP_STRING (line 559) | static JSONCPP_STRING normalizeEOL(Reader::Location begin, Reader::Loc...
    function Value (line 969) | Value& Reader::currentValue() { return *(nodes_.top()); }
    function JSONCPP_STRING (line 1000) | JSONCPP_STRING Reader::getLocationLineAndColumn(Location location) con...
    function JSONCPP_STRING (line 1009) | JSONCPP_STRING Reader::getFormatedErrorMessages() const {
    function JSONCPP_STRING (line 1013) | JSONCPP_STRING Reader::getFormattedErrorMessages() const {
    class OurFeatures (line 1084) | class OurFeatures {
    function OurFeatures (line 1101) | OurFeatures OurFeatures::all() { return OurFeatures(); }
    class OurReader (line 1107) | class OurReader {
      type StructuredError (line 1111) | struct StructuredError {
      type TokenType (line 1132) | enum TokenType {
      class Token (line 1152) | class Token {
      class ErrorInfo (line 1159) | class ErrorInfo {
    function Value (line 1975) | Value& OurReader::currentValue() { return *(nodes_.top()); }
    function JSONCPP_STRING (line 2006) | JSONCPP_STRING OurReader::getLocationLineAndColumn(Location location) ...
    function JSONCPP_STRING (line 2014) | JSONCPP_STRING OurReader::getFormattedErrorMessages() const {
    class OurCharReader (line 2085) | class OurCharReader : public CharReader {
      method OurCharReader (line 2089) | OurCharReader(
      method parse (line 2095) | bool parse(
    function CharReader (line 2112) | CharReader* CharReaderBuilder::newCharReader() const
    function getValidReaderKeys (line 2127) | static void getValidReaderKeys(std::set<JSONCPP_STRING>* valid_keys)
    function Value (line 2158) | Value& CharReaderBuilder::operator[](JSONCPP_STRING key)
    function parseFromStream (line 2197) | bool parseFromStream(
    function JSONCPP_ISTREAM (line 2211) | JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM& sin, Value& root) {
    function Value (line 2265) | Value& ValueIteratorBase::deref() const {
    function Value (line 2317) | Value ValueIteratorBase::key() const {
    function UInt (line 2327) | UInt ValueIteratorBase::index() const {
    function JSONCPP_STRING (line 2334) | JSONCPP_STRING ValueIteratorBase::name() const {
    function ValueConstIterator (line 2374) | ValueConstIterator& ValueConstIterator::
    function ValueIterator (line 2401) | ValueIterator& ValueIterator::operator=(const SelfType& other) {
    function InRange (line 2477) | static inline bool InRange(double d, T min, U max) {
    function integerToDouble (line 2484) | static inline double integerToDouble(Json::UInt64 value) {
    function integerToDouble (line 2488) | static inline double integerToDouble(T value) {
    function InRange (line 2493) | static inline bool InRange(double d, T min, U max) {
    function decodePrefixedString (line 2547) | inline static void decodePrefixedString(
    function releasePrefixedStringValue (line 2562) | static inline void releasePrefixedStringValue(char* value) {
    function releaseStringValue (line 2570) | static inline void releaseStringValue(char* value, unsigned length) {
    function releasePrefixedStringValue (line 2577) | static inline void releasePrefixedStringValue(char* value) {
    function releaseStringValue (line 2580) | static inline void releaseStringValue(char* value, unsigned) {
    function JSONCPP_NORETURN (line 2616) | JSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const& msg)
    function JSONCPP_NORETURN (line 2620) | JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg)
    function ArrayIndex (line 2734) | ArrayIndex Value::CZString::index() const { return index_; }
    function Value (line 2917) | Value& Value::operator=(Value other) {
    function ValueType (line 2939) | ValueType Value::type() const { return type_; }
    function JSONCPP_STRING (line 3080) | JSONCPP_STRING Value::asString() const {
    function LargestInt (line 3204) | LargestInt Value::asLargestInt() const {
    function LargestUInt (line 3212) | LargestUInt Value::asLargestUInt() const {
    function ArrayIndex (line 3318) | ArrayIndex Value::size() const {
    function Value (line 3384) | Value& Value::operator[](ArrayIndex index) {
    function Value (line 3400) | Value& Value::operator[](int index) {
    function Value (line 3407) | const Value& Value::operator[](ArrayIndex index) const {
    function Value (line 3420) | const Value& Value::operator[](int index) const {
    function Value (line 3438) | Value& Value::resolveReference(const char* key) {
    function Value (line 3457) | Value& Value::resolveReference(char const* key, char const* cend)
    function Value (line 3476) | Value Value::get(ArrayIndex index, const Value& defaultValue) const {
    function Value (line 3483) | Value const* Value::find(char const* key, char const* cend) const
    function Value (line 3494) | const Value& Value::operator[](const char* key) const
    function Value (line 3500) | Value const& Value::operator[](JSONCPP_STRING const& key) const
    function Value (line 3507) | Value& Value::operator[](const char* key) {
    function Value (line 3511) | Value& Value::operator[](const JSONCPP_STRING& key) {
    function Value (line 3515) | Value& Value::operator[](const StaticString& key) {
    function Value (line 3520) | Value& Value::operator[](const CppTL::ConstString& key) {
    function Value (line 3523) | Value const& Value::operator[](CppTL::ConstString const& key) const
    function Value (line 3531) | Value& Value::append(const Value& value) { return (*this)[size()] = va...
    function Value (line 3533) | Value Value::get(char const* key, char const* cend, Value const& defau...
    function Value (line 3538) | Value Value::get(char const* key, Value const& defaultValue) const
    function Value (line 3542) | Value Value::get(JSONCPP_STRING const& key, Value const& defaultValue)...
    function Value (line 3569) | Value Value::removeMember(const char* key)
    function Value (line 3580) | Value Value::removeMember(const JSONCPP_STRING& key)
    function Value (line 3609) | Value Value::get(const CppTL::ConstString& key,
    function IsIntegral (line 3677) | static bool IsIntegral(double d) {
    function JSONCPP_STRING (line 3796) | JSONCPP_STRING Value::getComment(CommentPlacement placement) const {
    function JSONCPP_STRING (line 3810) | JSONCPP_STRING Value::toStyledString() const {
    function Value (line 3947) | const Value& Path::resolve(const Value& root) const {
    function Value (line 3970) | Value Path::resolve(const Value& root, const Value& defaultValue) const {
    function Value (line 3989) | Value& Path::make(Value& root) const {
    function containsControlCharacter (line 4106) | static bool containsControlCharacter(const char* str) {
    function containsControlCharacter0 (line 4114) | static bool containsControlCharacter0(const char* str, unsigned len) {
    function JSONCPP_STRING (line 4124) | JSONCPP_STRING valueToString(LargestInt value) {
    function JSONCPP_STRING (line 4140) | JSONCPP_STRING valueToString(LargestUInt value) {
    function JSONCPP_STRING (line 4150) | JSONCPP_STRING valueToString(Int value) {
    function JSONCPP_STRING (line 4154) | JSONCPP_STRING valueToString(UInt value) {
    function JSONCPP_STRING (line 4160) | JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsi...
    function JSONCPP_STRING (line 4190) | JSONCPP_STRING valueToString(double value) { return valueToString(valu...
    function JSONCPP_STRING (line 4192) | JSONCPP_STRING valueToString(bool value) { return value ? "true" : "fa...
    function JSONCPP_STRING (line 4194) | JSONCPP_STRING valueToQuotedString(const char* value) {
    function JSONCPP_STRING (line 4271) | static JSONCPP_STRING valueToQuotedStringN(const char* value, unsigned...
    function JSONCPP_STRING (line 4351) | JSONCPP_STRING FastWriter::write(const Value& root) {
    function JSONCPP_STRING (line 4419) | JSONCPP_STRING StyledWriter::write(const Value& root) {
    type CommentStyle (line 4845) | struct CommentStyle {
      type Enum (line 4847) | enum Enum {
    type BuiltStyledStreamWriter (line 4854) | struct BuiltStyledStreamWriter : public StreamWriter
    function StreamWriter (line 5148) | StreamWriter* StreamWriterBuilder::newStreamWriter() const
    function getValidWriterKeys (line 5180) | static void getValidWriterKeys(std::set<JSONCPP_STRING>* valid_keys)
    function Value (line 5207) | Value& StreamWriterBuilder::operator[](JSONCPP_STRING key)
    function JSONCPP_STRING (line 5224) | JSONCPP_STRING writeString(StreamWriter::Factory const& builder, Value...
    function JSONCPP_OSTREAM (line 5231) | JSONCPP_OSTREAM& operator<<(JSONCPP_OSTREAM& sout, Value const& root) {

FILE: source/main.cpp
  type find_game_item (line 48) | struct find_game_item {
    method find_game_item (line 50) | find_game_item(std::string titleid) : titleid(titleid) {}
  function compareByScore (line 59) | bool compareByScore(const game_item &a, const game_item &b)
  function Result (line 64) | Result ProcessCIA(std::string dir, std::string titleName)
  function u32_to_hex_string (line 122) | std::string u32_to_hex_string(u32 i)
  function mkpath (line 129) | int mkpath(std::string s,mode_t mode)
  function parse_hex (line 151) | char parse_hex(char c)
  function get_file_contents (line 167) | std::string get_file_contents(const char *filename)
  function CreateTicket (line 177) | void CreateTicket(std::string titleId, std::string encTitleKey, char* ti...
  function InstallTicket (line 206) | void InstallTicket(std::string FullPath, std::string TitleId)
  function Result (line 227) | Result DownloadTitle(std::string titleId, std::string encTitleKey, std::...
  function ProcessGameQueue (line 379) | void ProcessGameQueue()
  function removeForbiddenChar (line 412) | void removeForbiddenChar(std::string* s)
  function ToHex (line 450) | std::string ToHex(const std::string& s)
  function load_JSON_data (line 461) | void load_JSON_data()
  function loadConfig (line 477) | void loadConfig()
  function menu_search_keypress (line 489) | bool menu_search_keypress(int selected, u32 key, void* data)
  function search_by_name (line 566) | bool search_by_name(std::string &searchString, Json::Value &gameData, in...
  function search_by_serial (line 572) | bool search_by_serial(std::string &searchString, Json::Value &gameData, ...
  function action_search (line 585) | void action_search(bool (*match)(std::string &searchString, Json::Value ...
  function action_prompt_queue (line 711) | void action_prompt_queue()
  function action_manual_entry (line 757) | void action_manual_entry()
  function action_input_txt (line 820) | void action_input_txt()
  function action_toggle_install (line 836) | void action_toggle_install()
  function action_toggle_region (line 867) | void action_toggle_region()
  function action_about (line 885) | void action_about()
  function action_exit (line 904) | void action_exit()
  function action_download_json (line 909) | void action_download_json()
  function menu_main_keypress (line 918) | bool menu_main_keypress(int selected, u32 key, void*)
  function menu_main (line 974) | void menu_main()
  function main (line 1013) | int main(int argc, const char* argv[])

FILE: source/menu.cpp
  function init_menu (line 14) | void init_menu(gfxScreen_t screen)
  function menu_draw_string (line 25) | void menu_draw_string(const char* str, int pos_x, int pos_y, const char*...
  function menu_draw_string_full (line 34) | void menu_draw_string_full(const char* str, int pos_y, const char* color)
  function menu_draw_info (line 53) | void menu_draw_info(PrintConsole &console, const game_item &game)
  function titles_multkey_draw (line 67) | void titles_multkey_draw(const char *title, const char* footer, int back...
  function menu_multkey_draw (line 171) | void menu_multkey_draw(const char *title, const char* footer, int back, ...

FILE: source/menu.h
  type ConsoleMenu (line 23) | typedef struct ConsoleMenu {
  type game_item (line 27) | typedef struct {

FILE: source/svchax/svchax.c
  type u32 (line 24) | typedef u32(*backdoor_fn)(u32 arg0, u32 arg1);
  function u32 (line 26) | __attribute((naked))
  function k_enable_all_svcs (line 48) | static void k_enable_all_svcs(u32 isNew3DS)
  function u32 (line 57) | static u32 k_read_kaddr(u32* kaddr)
  function u32 (line 62) | static u32 read_kaddr(u32 kaddr)
  function u32 (line 67) | static u32 k_write_kaddr(u32* kaddr, u32 val)
  function write_kaddr (line 73) | static void write_kaddr(u32 kaddr, u32 val)
  function u32 (line 78) | __attribute__((naked))
  type mch2_thread_args_t (line 92) | typedef struct
  type mch2_thread_t (line 100) | typedef struct
  type mch2_vars_t (line 108) | typedef struct
  function alloc_thread_entry (line 131) | static void alloc_thread_entry(mch2_vars_t* mch2)
  function dummy_thread_entry (line 139) | static void dummy_thread_entry(Handle lock)
  function check_tls_thread_entry (line 145) | static void check_tls_thread_entry(bool* keep)
  function target_thread_entry (line 151) | static void target_thread_entry(mch2_thread_args_t* args)
  function u32 (line 162) | static u32 get_first_free_basemem_page(bool isNew3DS)
  function u32 (line 181) | static u32 get_threads_limit(void)
  function do_memchunkhax2 (line 199) | static void do_memchunkhax2(void)
  function gspwn (line 378) | static void gspwn(u32 dst, u32 src, u32 size, u8* flush_buffer)
  function memchunkhax1_write_pair (line 404) | static void memchunkhax1_write_pair(u32 val1, u32 val2)
  function do_memchunkhax1 (line 451) | static void do_memchunkhax1(void)
  function Result (line 461) | Result svchax_init(bool patch_srv)

FILE: source/types.h
  type _boolean (line 22) | typedef enum
  type return_basic (line 28) | typedef enum
  type errors (line 34) | typedef enum
  type endianness_flag (line 42) | typedef enum

FILE: source/utf8proc/utf8proc.c
  function UTF8PROC_DLLEXPORT (line 91) | UTF8PROC_DLLEXPORT const char *utf8proc_version(void) {
  function UTF8PROC_DLLEXPORT (line 95) | UTF8PROC_DLLEXPORT const char *utf8proc_errmsg(utf8proc_ssize_t errcode) {
  function UTF8PROC_DLLEXPORT (line 113) | UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_iterate(
  function UTF8PROC_DLLEXPORT (line 161) | UTF8PROC_DLLEXPORT utf8proc_bool utf8proc_codepoint_valid(utf8proc_int32...
  function UTF8PROC_DLLEXPORT (line 165) | UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_encode_char(utf8proc_int32_...
  function utf8proc_ssize_t (line 192) | static utf8proc_ssize_t unsafe_encode_char(utf8proc_int32_t uc, utf8proc...
  function utf8proc_property_t (line 223) | static const utf8proc_property_t *unsafe_get_property(utf8proc_int32_t u...
  function UTF8PROC_DLLEXPORT (line 232) | UTF8PROC_DLLEXPORT const utf8proc_property_t *utf8proc_get_property(utf8...
  function utf8proc_bool (line 237) | static utf8proc_bool grapheme_break(int lbc, int tbc) {
  function UTF8PROC_DLLEXPORT (line 263) | UTF8PROC_DLLEXPORT utf8proc_bool utf8proc_grapheme_break(utf8proc_int32_...
  function UTF8PROC_DLLEXPORT (line 268) | UTF8PROC_DLLEXPORT utf8proc_int32_t utf8proc_tolower(utf8proc_int32_t c)
  function UTF8PROC_DLLEXPORT (line 274) | UTF8PROC_DLLEXPORT utf8proc_int32_t utf8proc_toupper(utf8proc_int32_t c)
  function UTF8PROC_DLLEXPORT (line 282) | UTF8PROC_DLLEXPORT int utf8proc_charwidth(utf8proc_int32_t c) {
  function UTF8PROC_DLLEXPORT (line 286) | UTF8PROC_DLLEXPORT utf8proc_category_t utf8proc_category(utf8proc_int32_...
  function UTF8PROC_DLLEXPORT (line 290) | UTF8PROC_DLLEXPORT const char *utf8proc_category_string(utf8proc_int32_t...
  function UTF8PROC_DLLEXPORT (line 299) | UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_decompose_char(utf8proc_int...
  function UTF8PROC_DLLEXPORT (line 403) | UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_decompose(
  function UTF8PROC_DLLEXPORT (line 466) | UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_reencode(utf8proc_int32_t *...
  function UTF8PROC_DLLEXPORT (line 588) | UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_map(
  function UTF8PROC_DLLEXPORT (line 617) | UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFD(const utf8proc_uint8_t...
  function UTF8PROC_DLLEXPORT (line 624) | UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFC(const utf8proc_uint8_t...
  function UTF8PROC_DLLEXPORT (line 631) | UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFKD(const utf8proc_uint8_...
  function UTF8PROC_DLLEXPORT (line 638) | UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFKC(const utf8proc_uint8_...

FILE: source/utf8proc/utf8proc.h
  type utf8proc_int8_t (line 81) | typedef signed char utf8proc_int8_t;
  type utf8proc_uint8_t (line 82) | typedef unsigned char utf8proc_uint8_t;
  type utf8proc_int16_t (line 83) | typedef short utf8proc_int16_t;
  type utf8proc_uint16_t (line 84) | typedef unsigned short utf8proc_uint16_t;
  type utf8proc_int32_t (line 85) | typedef int utf8proc_int32_t;
  type utf8proc_uint32_t (line 86) | typedef unsigned int utf8proc_uint32_t;
  type __int64 (line 88) | typedef __int64 utf8proc_ssize_t;
  type utf8proc_size_t (line 89) | typedef unsigned __int64 utf8proc_size_t;
  type utf8proc_ssize_t (line 91) | typedef int utf8proc_ssize_t;
  type utf8proc_size_t (line 92) | typedef unsigned int utf8proc_size_t;
  type utf8proc_bool (line 95) | typedef unsigned char utf8proc_bool;
  type utf8proc_bool (line 98) | typedef bool utf8proc_bool;
  type utf8proc_int8_t (line 103) | typedef int8_t utf8proc_int8_t;
  type utf8proc_uint8_t (line 104) | typedef uint8_t utf8proc_uint8_t;
  type utf8proc_int16_t (line 105) | typedef int16_t utf8proc_int16_t;
  type utf8proc_uint16_t (line 106) | typedef uint16_t utf8proc_uint16_t;
  type utf8proc_int32_t (line 107) | typedef int32_t utf8proc_int32_t;
  type utf8proc_uint32_t (line 108) | typedef uint32_t utf8proc_uint32_t;
  type utf8proc_size_t (line 109) | typedef size_t utf8proc_size_t;
  type utf8proc_ssize_t (line 110) | typedef ssize_t utf8proc_ssize_t;
  type utf8proc_bool (line 111) | typedef bool utf8proc_bool;
  type utf8proc_option_t (line 142) | typedef enum {
  type utf8proc_int16_t (line 225) | typedef utf8proc_int16_t utf8proc_propval_t;
  type utf8proc_property_t (line 228) | typedef struct utf8proc_property_struct {
  type utf8proc_category_t (line 272) | typedef enum {
  type utf8proc_bidi_class_t (line 306) | typedef enum {
  type utf8proc_decomp_type_t (line 333) | typedef enum {
  type utf8proc_boundclass_t (line 353) | typedef enum {

FILE: source/utils.cpp
  function char_to_int_array (line 30) | void char_to_int_array(unsigned char destination[], char source[], int s...
  function endian_memcpy (line 60) | void endian_memcpy(u8 *destination, u8 *source, u32 size, u32 endianness)
  function u8_hex_print_be (line 74) | void u8_hex_print_be(u8 *array, int len)
  function u8_hex_print_le (line 80) | void u8_hex_print_le(u8 *array, int len)
  function u32 (line 86) | u32 align_value(u32 value, u32 alignment)
  function resolve_flag (line 94) | void resolve_flag(unsigned char flag, unsigned char *flag_bool)
  function resolve_flag_u16 (line 107) | void resolve_flag_u16(u16 flag, unsigned char *flag_bool)
  function diff_ms (line 121) | int diff_ms(timeval t1, timeval t2)
  function PrintProgress (line 127) | void PrintProgress(PrintConsole *console, u32 nSize, u32 nCurrent)
  function WriteBuffer (line 181) | void WriteBuffer(void *buffer, u64 size, u64 offset, FILE *output)
  function write_align_padding (line 187) | void write_align_padding(FILE *output, size_t alignment)
  function u64 (line 201) | u64 GetFileSize_u64(char *filename)
  function TruncateFile_u64 (line 220) | int TruncateFile_u64(char *filename, u64 filelen)
  function fseek_64 (line 248) | int fseek_64(FILE *fp, u64 file_pos, int whence)
  function makedir (line 258) | int makedir(const char* dir)
  function FileExists (line 276) | bool FileExists (const char *name){
  function DownloadFile_InternalSave (line 281) | void DownloadFile_InternalSave(void* out, unsigned char* buffer, u32 rea...
  function DownloadFile_InternalInstall (line 288) | void DownloadFile_InternalInstall(void* out, unsigned char* buffer, u32 ...
  function Result (line 298) | Result DownloadFile_Internal(const char *url, void *out, bool bProgress,
  function Result (line 396) | Result DownloadFile(const char *url, FILE *os, bool bProgress)
  function Result (line 402) | Result DownloadFileInstall(const char *url, Handle *handle, u32* offset)
  function Result (line 413) | Result InstallSeed(u64 titleId, const void* seed) {
  function u16 (line 431) | u16 u8_to_u16(u8 *value, u32 endianness)
  function u32 (line 441) | u32 u8_to_u32(u8 *value, u32 endianness)
  function u64 (line 452) | u64 u8_to_u64(u8 *value, u32 endianness)
  function u16_to_u8 (line 482) | int u16_to_u8(u8 *out_value, u16 in_value, u32 endianness)
  function u32_to_u8 (line 497) | int u32_to_u8(u8 *out_value, u32 in_value, u32 endianness)
  function u64_to_u8 (line 516) | int u64_to_u8(u8 *out_value, u64 in_value, u32 endianness)
  function memdump (line 544) | void memdump(FILE* fout, const char* prefix, const u8* data, u32 size)
  function u32 (line 573) | u32 wait_key()
  function u32 (line 591) | u32 wait_key_specific(const char* message, u32 key)
  function clear_screen (line 605) | void clear_screen(gfxScreen_t screen)
  function download_JSON (line 644) | bool download_JSON() {
  function check_JSON (line 666) | bool check_JSON() {
  function GetSerialType (line 704) | std::string GetSerialType(std::string sSerial)
  function upperCase (line 734) | std::string upperCase(std::string input) {
  function getJsonUrl (line 740) | std::string getJsonUrl()
Condensed preview — 26 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,980K chars).
[
  {
    "path": ".gitmodules",
    "chars": 96,
    "preview": "[submodule \"buildtools\"]\n\tpath = buildtools\n\turl = https://github.com/Steveice10/buildtools.git\n"
  },
  {
    "path": "Makefile",
    "chars": 1092,
    "preview": "# TARGET #\n\nTARGET := 3DS\nLIBRARY := 0\n\nifeq ($(TARGET),3DS)\n    ifeq ($(strip $(DEVKITPRO)),)\n        $(error \"Please s"
  },
  {
    "path": "README.md",
    "chars": 3149,
    "preview": "# CIAngel\n\n# Archived, CDN access is not available anymore. RIP.\n\n\nNow we can get games directly on the 3DS!\nUsing a Tit"
  },
  {
    "path": "source/cia.c",
    "chars": 16145,
    "preview": "/**\nCopyright 2013 3DSGuy\n\nThis file is part of make_cdn_cia.\n\nmake_cdn_cia is free software: you can redistribute it an"
  },
  {
    "path": "source/cia.h",
    "chars": 5309,
    "preview": "/**\nCopyright 2013 3DSGuy\n\nThis file is part of make_cdn_cia.\n\nmake_cdn_cia is free software: you can redistribute it an"
  },
  {
    "path": "source/config.cpp",
    "chars": 1180,
    "preview": "#include <string>\n#include <fstream>\n#include \"config.h\"\n#include \"json/json.h\"\n\nusing namespace std;\n\nCConfig::CConfig("
  },
  {
    "path": "source/config.h",
    "chars": 529,
    "preview": "#pragma once\n#include <string>\n#include \"json/json.h\"\n\nclass CConfig {\npublic:\n    CConfig();\n    void LoadConfig(std::s"
  },
  {
    "path": "source/data.h",
    "chars": 16784,
    "preview": "#define TICKET_SIZE 0xA50\nconst char tikTemp[TICKET_SIZE] = {\n    0x00, 0x01, 0x00, 0x04, 0xD1, 0x5E, 0xA5, 0xE0, 0xD1, "
  },
  {
    "path": "source/font.h",
    "chars": 13342,
    "preview": "/*\n  This file was autogenerated by raw2c.\nVisit http://www.devkitpro.org\n*/\n\n//----------------------------------------"
  },
  {
    "path": "source/fts_fuzzy_match.h",
    "chars": 5221,
    "preview": "// LICENSE\n//\n//   This software is dual-licensed to the public domain and under the following\n//   license: you are gra"
  },
  {
    "path": "source/json/json-forwards.h",
    "chars": 10847,
    "preview": "/// Json-cpp amalgated forward header (http://jsoncpp.sourceforge.net/).\n/// It is intended to be used with #include \"js"
  },
  {
    "path": "source/json/json.h",
    "chars": 69862,
    "preview": "/// Json-cpp amalgated header (http://jsoncpp.sourceforge.net/).\n/// It is intended to be used with #include \"json/json."
  },
  {
    "path": "source/jsoncpp.cpp",
    "chars": 153428,
    "preview": "/// Json-cpp amalgated source (http://jsoncpp.sourceforge.net/).\n/// It is intended to be used with #include \"json/json."
  },
  {
    "path": "source/lib.h",
    "chars": 1033,
    "preview": "/**\nCopyright 2013 3DSGuy\n\nThis file is part of make_cdn_cia.\n\nmake_cdn_cia is free software: you can redistribute it an"
  },
  {
    "path": "source/main.cpp",
    "chars": 30242,
    "preview": "#include <string>\n#include <vector>\n#include <sstream>\n#include <iomanip>\n#include <fstream>\n#include <cstdlib>\n#include"
  },
  {
    "path": "source/menu.cpp",
    "chars": 8846,
    "preview": "/* Code borrowed from https://github.com/mid-kid/CakesForeveryWan/blob/master/source/menu.c and tortured until it bent t"
  },
  {
    "path": "source/menu.h",
    "chars": 1271,
    "preview": "#pragma once\n\n#ifndef __MENU_H_INCLUDED__\n#define __MENU_H_INCLUDED__\n#include <3ds.h>\n#include <string>\n#include <vecto"
  },
  {
    "path": "source/svchax/svchax.c",
    "chars": 14966,
    "preview": "#include <3ds.h>\n#include <stdio.h>\n#include <string.h>\n#include <malloc.h>\n#include \"svchax.h\"\n\n#define CURRENT_KTHREAD"
  },
  {
    "path": "source/svchax/svchax.h",
    "chars": 1270,
    "preview": "#ifndef __SVCHAX_H__\n#define _SVCHAX_H__\n\n/*\n * for 3DSX builds, svchax_init expects that:\n *\n * - gfxInit was already c"
  },
  {
    "path": "source/types.h",
    "chars": 948,
    "preview": "/**\nCopyright 2013 3DSGuy\n\nThis file is part of make_cdn_cia.\n\nmake_cdn_cia is free software: you can redistribute it an"
  },
  {
    "path": "source/utf8proc/LICENSE.md",
    "chars": 5129,
    "preview": "## utf8proc license ##\n\n**utf8proc** is a software package originally developed\nby Jan Behrens and the rest of the Publi"
  },
  {
    "path": "source/utf8proc/utf8proc.c",
    "chars": 24120,
    "preview": "/* -*- mode: c; c-basic-offset: 2; tab-width: 2; indent-tabs-mode: nil -*- */\n/*\n *  Copyright (c) 2015 Steven G. Johnso"
  },
  {
    "path": "source/utf8proc/utf8proc.h",
    "chars": 24455,
    "preview": "/*\n * Copyright (c) 2015 Steven G. Johnson, Jiahao Chen, Peter Colberg, Tony Kelman, Scott P. Jones, and other contribut"
  },
  {
    "path": "source/utf8proc/utf8proc_data.h",
    "chars": 1515789,
    "preview": "const utf8proc_int32_t utf8proc_sequences[] = {\n  97, -1, 98, -1, 99, -1, 100, \n  -1, 101, -1, 102, -1, 103, -1, 104, \n "
  },
  {
    "path": "source/utils.cpp",
    "chars": 17771,
    "preview": "/**\nCopyright 2013 3DSGuy\n\nThis file is part of make_cdn_cia.\n\nmake_cdn_cia is free software: you can redistribute it an"
  },
  {
    "path": "source/utils.h",
    "chars": 3039,
    "preview": "/**\nCopyright 2013 3DSGuy\n\nThis file is part of make_cdn_cia.\n\nmake_cdn_cia is free software: you can redistribute it an"
  }
]

About this extraction

This page contains the full source code of the llakssz/CIAngel GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 26 files (1.9 MB), approximately 863.8k tokens, and a symbol index with 313 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!